CCF
Loading...
Searching...
No Matches
ledger_secret.h
Go to the documentation of this file.
1// Copyright (c) Microsoft Corporation. All rights reserved.
2// Licensed under the Apache 2.0 License.
3#pragma once
4
6#include "ccf/crypto/hmac.h"
8#include "kv/kv_types.h"
11
12#include <openssl/crypto.h>
13
14namespace ccf
15{
16 // Unique label for deriving commit secrets from ledger secrets.
17 // See logic in get_commit_secret() below for derivation implementation.
18 // It is important that this label is _not_ re-used for other purposes,
19 // nor changed during the lifetime of a ledger, to preserve the semantics of
20 // commit evidence (i.e. their reveal implies an entry is committed).
21 static constexpr uint8_t commit_secret_label_[] = {
22 'C', 'o', 'm', 'm', 'i', 't', ' ', 'S'};
23 static std::span<const uint8_t> commit_secret_label{
24 commit_secret_label_, sizeof(commit_secret_label_)};
26 {
27 std::vector<uint8_t> raw_key;
28 std::shared_ptr<ccf::crypto::KeyAesGcm> key;
29 std::optional<ccf::kv::Version> previous_secret_stored_version =
30 std::nullopt;
31 std::optional<ccf::crypto::HashBytes> commit_secret = std::nullopt;
32
34 {
35 if (!commit_secret.has_value())
36 {
38 ccf::crypto::MDType::SHA256, raw_key, commit_secret_label);
39 }
40 return commit_secret.value();
41 }
42
43 bool operator==(const LedgerSecret& other) const
44 {
45 return raw_key == other.raw_key &&
47 }
48
49 LedgerSecret() = default;
50
52 {
53 OPENSSL_cleanse(raw_key.data(), raw_key.size());
54 }
55
56 // The copy constructor is used for serialising a LedgerSecret. However,
57 // only the raw_key is serialised and other.key is nullptr so use raw_key to
58 // seed key.
59 LedgerSecret(const LedgerSecret& other) :
60 raw_key(other.raw_key),
61 key(ccf::crypto::make_key_aes_gcm(other.raw_key)),
63 {}
64
66 std::vector<uint8_t>&& raw_key_,
67 std::optional<ccf::kv::Version> previous_secret_stored_version_ =
68 std::nullopt) :
69 raw_key(raw_key_),
70 key(ccf::crypto::make_key_aes_gcm(std::move(raw_key_))),
71 previous_secret_stored_version(previous_secret_stored_version_)
72 {}
73 };
74
76 DECLARE_JSON_REQUIRED_FIELDS(LedgerSecret, raw_key)
77 DECLARE_JSON_OPTIONAL_FIELDS(LedgerSecret, previous_secret_stored_version)
78
79 using LedgerSecretPtr = std::shared_ptr<LedgerSecret>;
80
82 {
83 return std::make_shared<LedgerSecret>(
85 }
86
87 inline std::vector<uint8_t> decrypt_previous_ledger_secret_raw(
88 const LedgerSecretPtr& ledger_secret,
89 const std::vector<uint8_t>& encrypted_previous_secret_raw)
90 {
91 ccf::crypto::GcmCipher encrypted_ls;
92 encrypted_ls.deserialise(encrypted_previous_secret_raw);
93 std::vector<uint8_t> decrypted_ls_raw;
94
95 if (!ledger_secret->key->decrypt(
96 encrypted_ls.hdr.get_iv(),
97 encrypted_ls.hdr.tag,
98 encrypted_ls.cipher,
99 {},
100 decrypted_ls_raw))
101 {
102 throw std::logic_error("Decryption of previous ledger secret failed");
103 }
104
105 return decrypted_ls_raw;
106 }
107}
108
109namespace nlohmann
110{
111 template <>
112 struct adl_serializer<ccf::LedgerSecretPtr>
113 {
114 static void to_json(json& j, const ccf::LedgerSecretPtr& s)
115 {
116 if (s.get() != nullptr)
117 {
118 j = *s;
119 }
120 else
121 {
122 j = nullptr;
123 }
124 }
125
126 static void from_json(const json& j, ccf::LedgerSecretPtr& s)
127 {
128 if (j.is_null())
129 {
130 s = nullptr;
131 }
132 else
133 {
134 ccf::LedgerSecret ls = j;
135 s = std::make_shared<ccf::LedgerSecret>(ls);
136 }
137 }
138 };
139}
#define DECLARE_JSON_REQUIRED_FIELDS(TYPE,...)
Definition json.h:718
#define DECLARE_JSON_TYPE_WITH_OPTIONAL_FIELDS(TYPE)
Definition json.h:694
#define DECLARE_JSON_OPTIONAL_FIELDS(TYPE,...)
Definition json.h:790
HashBytes hmac(MDType type, const std::span< const uint8_t > &key, const std::span< const uint8_t > &data)
Definition hmac.cpp:43
std::vector< uint8_t > HashBytes
Definition hash_bytes.h:10
EntropyPtr get_entropy()
Definition entropy.cpp:10
constexpr size_t GCM_DEFAULT_KEY_SIZE
Definition symmetric_key.h:12
Definition app_interface.h:14
LedgerSecretPtr make_ledger_secret()
Definition ledger_secret.h:81
std::shared_ptr< LedgerSecret > LedgerSecretPtr
Definition ledger_secret.h:79
std::vector< uint8_t > decrypt_previous_ledger_secret_raw(const LedgerSecretPtr &ledger_secret, const std::vector< uint8_t > &encrypted_previous_secret_raw)
Definition ledger_secret.h:87
Definition json_schema.h:15
Definition ledger_secret.h:110
STL namespace.
Definition ledger_secret.h:26
LedgerSecret(const LedgerSecret &other)
Definition ledger_secret.h:59
LedgerSecret(std::vector< uint8_t > &&raw_key_, std::optional< ccf::kv::Version > previous_secret_stored_version_=std::nullopt)
Definition ledger_secret.h:65
LedgerSecret()=default
std::optional< ccf::crypto::HashBytes > commit_secret
Definition ledger_secret.h:31
const ccf::crypto::HashBytes & get_commit_secret()
Definition ledger_secret.h:33
std::optional< ccf::kv::Version > previous_secret_stored_version
Definition ledger_secret.h:29
std::shared_ptr< ccf::crypto::KeyAesGcm > key
Definition ledger_secret.h:28
~LedgerSecret()
Definition ledger_secret.h:51
bool operator==(const LedgerSecret &other) const
Definition ledger_secret.h:43
std::vector< uint8_t > raw_key
Definition ledger_secret.h:27
Definition symmetric_key.h:58
void deserialise(const std::vector< uint8_t > &serial)
Definition symmetric_key.cpp:93
StandardGcmHeader hdr
Definition symmetric_key.h:59
std::vector< uint8_t > cipher
Definition symmetric_key.h:60
uint8_t tag[GCM_SIZE_TAG]
Definition symmetric_key.h:18
std::span< const uint8_t > get_iv() const
Definition symmetric_key.cpp:34
static void to_json(json &j, const ccf::LedgerSecretPtr &s)
Definition ledger_secret.h:114
static void from_json(const json &j, ccf::LedgerSecretPtr &s)
Definition ledger_secret.h:126