diff --git a/include/ccf/crypto/symmetric_key.h b/include/ccf/crypto/symmetric_key.h index e6f37fe46..8cc1f5639 100644 --- a/include/ccf/crypto/symmetric_key.h +++ b/include/ccf/crypto/symmetric_key.h @@ -77,7 +77,7 @@ namespace crypto std::span iv, std::span plain, std::span aad, - uint8_t* cipher, + std::vector& cipher, uint8_t tag[GCM_SIZE_TAG]) const = 0; // AES-GCM decryption @@ -86,7 +86,7 @@ namespace crypto const uint8_t tag[GCM_SIZE_TAG], std::span cipher, std::span aad, - uint8_t* plain) const = 0; + std::vector& plain) const = 0; // Key size in bits virtual size_t key_size() const = 0; diff --git a/src/crypto/openssl/symmetric_key.cpp b/src/crypto/openssl/symmetric_key.cpp index 7c1f5a5ef..89edda87a 100644 --- a/src/crypto/openssl/symmetric_key.cpp +++ b/src/crypto/openssl/symmetric_key.cpp @@ -51,10 +51,10 @@ namespace crypto std::span iv, std::span plain, std::span aad, - uint8_t* cipher, + std::vector& cipher, uint8_t tag[GCM_SIZE_TAG]) const { - std::vector cb(plain.size() + GCM_SIZE_TAG); + std::vector cb(plain.size()); int len = 0; Unique_EVP_CIPHER_CTX ctx; CHECK1(EVP_EncryptInit_ex(ctx, evp_cipher, NULL, key.data(), NULL)); @@ -68,7 +68,9 @@ namespace crypto EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_GCM_GET_TAG, GCM_SIZE_TAG, &tag[0])); if (!plain.empty()) - memcpy(cipher, cb.data(), plain.size()); + { + cipher = std::move(cb); + } } bool KeyAesGcm_OpenSSL::decrypt( @@ -76,9 +78,9 @@ namespace crypto const uint8_t tag[GCM_SIZE_TAG], std::span cipher, std::span aad, - uint8_t* plain) const + std::vector& plain) const { - std::vector pb(cipher.size() + GCM_SIZE_TAG); + std::vector pb(cipher.size()); int len = 0; Unique_EVP_CIPHER_CTX ctx; @@ -95,7 +97,9 @@ namespace crypto int r = EVP_DecryptFinal_ex(ctx, pb.data() + len, &len) > 0; if (r == 1 && !cipher.empty()) - memcpy(plain, pb.data(), cipher.size()); + { + plain = std::move(pb); + } return r == 1; } diff --git a/src/crypto/openssl/symmetric_key.h b/src/crypto/openssl/symmetric_key.h index 8fb4b9aed..4f1fb7f13 100644 --- a/src/crypto/openssl/symmetric_key.h +++ b/src/crypto/openssl/symmetric_key.h @@ -31,7 +31,7 @@ namespace crypto std::span iv, std::span plain, std::span aad, - uint8_t* cipher, + std::vector& cipher, uint8_t tag[GCM_SIZE_TAG]) const override; virtual bool decrypt( @@ -39,7 +39,7 @@ namespace crypto const uint8_t tag[GCM_SIZE_TAG], std::span cipher, std::span aad, - uint8_t* plain) const override; + std::vector& plain) const override; // @brief RFC 5649 AES key wrap with padding (CKM_AES_KEY_WRAP_PAD) // @param plain Plaintext key to wrap diff --git a/src/crypto/symmetric_key.cpp b/src/crypto/symmetric_key.cpp index 81a01094c..f2e36e8e4 100644 --- a/src/crypto/symmetric_key.cpp +++ b/src/crypto/symmetric_key.cpp @@ -107,10 +107,10 @@ namespace crypto { check_supported_aes_key_size(key.size() * 8); - std::vector r(plaintext.size()); + std::vector r; std::vector tag(GCM_SIZE_TAG); auto k = make_key_aes_gcm(key); - k->encrypt(iv, plaintext, aad, r.data(), tag.data()); + k->encrypt(iv, plaintext, aad, r, tag.data()); r.insert(r.end(), tag.begin(), tag.end()); return r; } @@ -127,14 +127,14 @@ namespace crypto throw std::runtime_error("Not enough ciphertext"); size_t ciphertext_length = ciphertext.size() - GCM_SIZE_TAG; - std::vector r(ciphertext_length); + std::vector r; auto k = make_key_aes_gcm(key); k->decrypt( iv, ciphertext.data() + ciphertext_length, std::span(ciphertext.data(), ciphertext_length), aad, - r.data()); + r); return r; } } diff --git a/src/crypto/test/crypto.cpp b/src/crypto/test/crypto.cpp index 8e0cf3afa..21ae25e6c 100644 --- a/src/crypto/test/crypto.cpp +++ b/src/crypto/test/crypto.cpp @@ -435,10 +435,10 @@ static const vector& get_raw_key() TEST_CASE("ExtendedIv0") { auto k = crypto::make_key_aes_gcm(get_raw_key()); + // setup plain text - unsigned char rawP[100]; - memset(rawP, 'x', sizeof(rawP)); - const std::span p{rawP, sizeof(rawP)}; + std::vector plain(100); + std::iota(plain.begin(), plain.end(), 0); // test large IV using LargeIVGcmHeader = FixedSizeGcmHeader<1234>; @@ -451,10 +451,13 @@ TEST_CASE("ExtendedIv0") h.set_random_iv(); } - k->encrypt(h.get_iv(), p, {}, rawP, h.tag); + std::vector cipher; + k->encrypt(h.get_iv(), plain, {}, cipher, h.tag); auto k2 = crypto::make_key_aes_gcm(get_raw_key()); - REQUIRE(k2->decrypt(h.get_iv(), h.tag, p, {}, rawP)); + std::vector decrypted_plain; + REQUIRE(k2->decrypt(h.get_iv(), h.tag, cipher, {}, decrypted_plain)); + REQUIRE(plain == decrypted_plain); } TEST_CASE("AES Key wrap with padding") diff --git a/src/indexing/enclave_lfs_access.h b/src/indexing/enclave_lfs_access.h index ec701835c..6dc21a85e 100644 --- a/src/indexing/enclave_lfs_access.h +++ b/src/indexing/enclave_lfs_access.h @@ -38,9 +38,8 @@ namespace ccf::indexing plaintext = gcm.cipher; auto success = true; #else - plaintext.resize(gcm.cipher.size()); auto success = encryption_key.decrypt( - gcm.hdr.get_iv(), gcm.hdr.tag, gcm.cipher, {}, plaintext.data()); + gcm.hdr.get_iv(), gcm.hdr.tag, gcm.cipher, {}, plaintext); #endif // Check key prefix in plaintext @@ -110,7 +109,7 @@ namespace ccf::indexing gcm.hdr.set_random_iv(); encryption_key->encrypt( - gcm.hdr.get_iv(), contents, {}, gcm.cipher.data(), gcm.hdr.tag); + gcm.hdr.get_iv(), contents, {}, gcm.cipher, gcm.hdr.tag); #ifdef PLAINTEXT_CACHE gcm.cipher = contents; diff --git a/src/kv/encryptor.h b/src/kv/encryptor.h index 4262e92e2..70744a7a5 100644 --- a/src/kv/encryptor.h +++ b/src/kv/encryptor.h @@ -75,7 +75,6 @@ namespace kv EntryType entry_type = EntryType::WriteSet) override { S hdr; - cipher.resize(plain.size()); set_iv(hdr, tx_id, entry_type); @@ -85,8 +84,7 @@ namespace kv return false; } - key->encrypt( - hdr.get_iv(), plain, additional_data, cipher.data(), hdr.tag); + key->encrypt(hdr.get_iv(), plain, additional_data, cipher, hdr.tag); serialised_header = hdr.serialise(); @@ -121,7 +119,6 @@ namespace kv S hdr; hdr.deserialise(serialised_header); term = hdr.get_term(); - plain.resize(cipher.size()); auto key = ledger_secrets->get_encryption_key_for(version, historical_hint); @@ -130,8 +127,8 @@ namespace kv return false; } - auto ret = key->decrypt( - hdr.get_iv(), hdr.tag, cipher, additional_data, plain.data()); + auto ret = + key->decrypt(hdr.get_iv(), hdr.tag, cipher, additional_data, plain); if (!ret) { plain.resize(0); diff --git a/src/node/channels.h b/src/node/channels.h index 56c5d6807..c4ec89da8 100644 --- a/src/node/channels.h +++ b/src/node/channels.h @@ -188,11 +188,11 @@ namespace ccf std::array local_recv_nonce = {{}}; - bool verify_or_decrypt( + bool decrypt( const GcmHdr& header, std::span aad, - std::span cipher = {}, - std::span plain = {}) + std::span cipher, + std::vector& plain) { status.expect(ESTABLISHED); @@ -216,7 +216,7 @@ namespace ccf } CHANNEL_RECV_TRACE( - "verify_or_decrypt({} bytes, {} bytes) (nonce={})", + "decrypt({} bytes, {} bytes) (nonce={})", aad.size(), cipher.size(), (size_t)recv_nonce.nonce); @@ -238,8 +238,8 @@ namespace ccf return false; } - auto ret = recv_key->decrypt( - header.get_iv(), header.tag, cipher, aad, plain.data()); + auto ret = + recv_key->decrypt(header.get_iv(), header.tag, cipher, aad, plain); if (ret) { // Set local recv nonce to received nonce only if verification is @@ -262,6 +262,12 @@ namespace ccf return ret; } + bool verify(const GcmHdr& header, std::span aad) + { + std::vector empty_plaintext; + return decrypt(header, aad, {}, empty_plaintext); + } + void send_key_exchange_init() { std::vector payload; @@ -866,10 +872,9 @@ namespace ccf const auto nonce_n = nonce.get_val(); gcm_hdr.set_iv((const uint8_t*)&nonce_n, sizeof(nonce_n)); - std::vector cipher(plain.size()); + std::vector cipher; assert(send_key); - send_key->encrypt( - gcm_hdr.get_iv(), plain, aad, cipher.data(), gcm_hdr.tag); + send_key->encrypt(gcm_hdr.get_iv(), plain, aad, cipher, gcm_hdr.tag); const auto gcm_hdr_serialised = gcm_hdr.serialise(); @@ -908,7 +913,7 @@ namespace ccf GcmHdr hdr; hdr.deserialise(data, size); - if (!verify_or_decrypt(hdr, aad)) + if (!verify(hdr, aad)) { CHANNEL_RECV_FAIL("Failed to verify node"); return false; @@ -942,7 +947,7 @@ namespace ccf hdr.deserialise(data_, size_); size -= hdr.serialised_size(); - if (!verify_or_decrypt(hdr, std::span(data, size))) + if (!verify(hdr, std::span(data, size))) { CHANNEL_RECV_FAIL("Failed to verify node message with payload"); return false; @@ -969,9 +974,8 @@ namespace ccf GcmHdr hdr; hdr.deserialise(data, size); - std::vector plain(size); - if (!verify_or_decrypt( - hdr, aad, std::span(data, size), plain)) + std::vector plain; + if (!decrypt(hdr, aad, std::span(data, size), plain)) { CHANNEL_RECV_FAIL("Failed to decrypt node message"); return std::nullopt; diff --git a/src/node/ledger_secret.h b/src/node/ledger_secret.h index c3b17583d..b855e3b52 100644 --- a/src/node/ledger_secret.h +++ b/src/node/ledger_secret.h @@ -85,14 +85,14 @@ namespace ccf { crypto::GcmCipher encrypted_ls; encrypted_ls.deserialise(encrypted_previous_secret_raw); - std::vector decrypted_ls_raw(encrypted_ls.cipher.size()); + std::vector decrypted_ls_raw; if (!ledger_secret->key->decrypt( encrypted_ls.hdr.get_iv(), encrypted_ls.hdr.tag, encrypted_ls.cipher, {}, - decrypted_ls_raw.data())) + decrypted_ls_raw)) { throw std::logic_error("Decryption of previous ledger secret failed"); } diff --git a/src/node/share_manager.h b/src/node/share_manager.h index fdbecd18c..d61b487aa 100644 --- a/src/node/share_manager.h +++ b/src/node/share_manager.h @@ -64,7 +64,7 @@ namespace ccf // key is never re-used for encryption ledger_secret->raw_key, {}, - encrypted_ls.cipher.data(), + encrypted_ls.cipher, encrypted_ls.hdr.tag); has_wrapped = true; @@ -77,14 +77,14 @@ namespace ccf { crypto::GcmCipher encrypted_ls; encrypted_ls.deserialise(wrapped_latest_ledger_secret); - std::vector decrypted_ls(encrypted_ls.cipher.size()); + std::vector decrypted_ls; if (!crypto::make_key_aes_gcm(data)->decrypt( encrypted_ls.hdr.get_iv(), encrypted_ls.hdr.tag, encrypted_ls.cipher, {}, - decrypted_ls.data())) + decrypted_ls)) { throw std::logic_error("Unwrapping latest ledger secret failed"); } @@ -201,7 +201,7 @@ namespace ccf encrypted_previous_ls.hdr.get_iv(), previous_ledger_secret->second->raw_key, {}, - encrypted_previous_ls.cipher.data(), + encrypted_previous_ls.cipher, encrypted_previous_ls.hdr.tag); encrypted_previous_secret = encrypted_previous_ls.serialise(); @@ -231,7 +231,7 @@ namespace ccf encrypted_submitted_share.hdr.get_iv(), submitted_share, {}, - encrypted_submitted_share.cipher.data(), + encrypted_submitted_share.cipher, encrypted_submitted_share.hdr.tag); return encrypted_submitted_share.serialise(); @@ -243,14 +243,14 @@ namespace ccf { crypto::GcmCipher encrypted_share; encrypted_share.deserialise(encrypted_submitted_share); - std::vector decrypted_share(encrypted_share.cipher.size()); + std::vector decrypted_share; current_ledger_secret->key->decrypt( encrypted_share.hdr.get_iv(), encrypted_share.hdr.tag, encrypted_share.cipher, {}, - decrypted_share.data()); + decrypted_share); return decrypted_share; }