CCF
Loading...
Searching...
No Matches
encryptor.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
5#include "ccf/crypto/hmac.h"
6#include "kv/kv_types.h"
7
8#include <algorithm>
9#include <map>
10
11namespace ccf::kv
12{
13 template <typename T, typename S>
15 {
16 private:
17 std::shared_ptr<T> ledger_secrets;
18
19 void set_iv(S& hdr, TxID tx_id, EntryType entry_type = EntryType::WriteSet)
20 {
21 // IV is function of seqno, term and snapshot so that:
22 // - Same seqno across rollbacks does not reuse IV
23 // - Snapshots do not reuse IV
24 // - If all nodes execute the _same_ tx (or generate the same snapshot),
25 // the same IV will be used
26
27 // Note that only the first 31 bits of the term are used for the IV which
28 // is acceptable for a live CCF as 2^31 elections will take decades, even
29 // with an election timeout as low as 1 sec.
30
31 hdr.set_iv_seq(tx_id.version);
32 hdr.set_iv_term(tx_id.term);
33 if (entry_type == EntryType::Snapshot)
34 {
35 hdr.set_iv_is_snapshot();
36 }
37 }
38
39 public:
40 TxEncryptor(const std::shared_ptr<T>& secrets) : ledger_secrets(secrets) {}
41
42 size_t get_header_length() override
43 {
44 return S::serialised_size();
45 }
46
47 uint64_t get_term(const uint8_t* data, size_t size) override
48 {
49 S s;
50 s.deserialise(data, size);
51 return s.get_term();
52 }
53
72 bool encrypt(
73 const std::vector<uint8_t>& plain,
74 const std::vector<uint8_t>& additional_data,
75 std::vector<uint8_t>& serialised_header,
76 std::vector<uint8_t>& cipher,
77 const TxID& tx_id,
78 EntryType entry_type = EntryType::WriteSet,
79 bool historical_hint = false) override
80 {
81 S hdr;
82
83 set_iv(hdr, tx_id, entry_type);
84
85 auto key =
86 ledger_secrets->get_encryption_key_for(tx_id.version, historical_hint);
87 if (key == nullptr)
88 {
89 return false;
90 }
91
92 key->encrypt(hdr.get_iv(), plain, additional_data, cipher, hdr.tag);
93
94 serialised_header = hdr.serialise();
95
96 return true;
97 }
98
116 const std::vector<uint8_t>& cipher,
117 const std::vector<uint8_t>& additional_data,
118 const std::vector<uint8_t>& serialised_header,
119 std::vector<uint8_t>& plain,
120 Version version,
121 Term& term,
122 bool historical_hint = false) override
123 {
124 S hdr;
125 hdr.deserialise(serialised_header);
126 term = hdr.get_term();
127
128 auto key =
129 ledger_secrets->get_encryption_key_for(version, historical_hint);
130 if (key == nullptr)
131 {
132 return false;
133 }
134
135 auto ret =
136 key->decrypt(hdr.get_iv(), hdr.tag, cipher, additional_data, plain);
137 if (!ret)
138 {
139 plain.resize(0);
140 }
141
142 return ret;
143 }
144
146 const TxID& tx_id, bool historical_hint = false) override
147 {
148 auto secret =
149 ledger_secrets->get_secret_for(tx_id.version, historical_hint);
150 if (secret == nullptr)
151 {
152 throw std::logic_error("Failed to get encryption key");
153 }
154 auto txid_str = tx_id.str();
155 std::vector<uint8_t> txid = {
156 txid_str.data(), txid_str.data() + txid_str.size()};
157
158 auto commit_nonce = ccf::crypto::hmac(
159 ccf::crypto::MDType::SHA256, secret->get_commit_secret(), txid);
160 return commit_nonce;
161 }
162
163 void rollback(Version version) override
164 {
165 // Rolls back all encryption keys more recent than version.
166 // Note: Because the store is not locked while the serialisation (and
167 // encryption) of a transaction occurs, if a rollback occurs after a
168 // transaction is committed but not yet serialised, it is possible that
169 // the transaction is serialised with the wrong encryption key (i.e. the
170 // latest one after rollback). This is OK as the transaction replication
171 // will fail.
172 ledger_secrets->rollback(version);
173 }
174 };
175}
Definition kv_types.h:547
Definition encryptor.h:15
size_t get_header_length() override
Definition encryptor.h:42
uint64_t get_term(const uint8_t *data, size_t size) override
Definition encryptor.h:47
bool encrypt(const std::vector< uint8_t > &plain, const std::vector< uint8_t > &additional_data, std::vector< uint8_t > &serialised_header, std::vector< uint8_t > &cipher, const TxID &tx_id, EntryType entry_type=EntryType::WriteSet, bool historical_hint=false) override
Definition encryptor.h:72
TxEncryptor(const std::shared_ptr< T > &secrets)
Definition encryptor.h:40
void rollback(Version version) override
Definition encryptor.h:163
ccf::crypto::HashBytes get_commit_nonce(const TxID &tx_id, bool historical_hint=false) override
Definition encryptor.h:145
bool decrypt(const std::vector< uint8_t > &cipher, const std::vector< uint8_t > &additional_data, const std::vector< uint8_t > &serialised_header, std::vector< uint8_t > &plain, Version version, Term &term, bool historical_hint=false) override
Definition encryptor.h:115
HashBytes hmac(MDType type, const std::vector< uint8_t > &key, const std::vector< uint8_t > &data)
Definition hmac.cpp:43
std::vector< uint8_t > HashBytes
Definition hash_bytes.h:10
Definition app_interface.h:19
uint64_t Term
Definition kv_types.h:48
EntryType
Definition kv_types.h:269
uint64_t Version
Definition version.h:8
Definition kv_types.h:52
std::string str() const
Definition kv_types.h:73
Version version
Definition kv_types.h:54
Term term
Definition kv_types.h:53