diff options
author | sergey.galtsev <sergey.galtsev@mongodb.com> | 2022-03-11 23:28:59 +0000 |
---|---|---|
committer | Evergreen Agent <no-reply@evergreen.mongodb.com> | 2022-03-11 23:57:56 +0000 |
commit | 2d3589491b2d0bb93d44219018a175d4a9ac0b76 (patch) | |
tree | d7139b8b73a6f4fd4f4e0301abe24486c1118ea3 /src/mongo/crypto/aead_encryption.cpp | |
parent | 5fdcb5bc400b55da24c736a5837122f6c6b64430 (diff) | |
download | mongo-2d3589491b2d0bb93d44219018a175d4a9ac0b76.tar.gz |
SERVER-63780 Switch FLE 2 crypto code to CTR and CTR-AEAD
Diffstat (limited to 'src/mongo/crypto/aead_encryption.cpp')
-rw-r--r-- | src/mongo/crypto/aead_encryption.cpp | 70 |
1 files changed, 64 insertions, 6 deletions
diff --git a/src/mongo/crypto/aead_encryption.cpp b/src/mongo/crypto/aead_encryption.cpp index b7640a1ca78..892fd4ae950 100644 --- a/src/mongo/crypto/aead_encryption.cpp +++ b/src/mongo/crypto/aead_encryption.cpp @@ -206,6 +206,10 @@ size_t fle2AeadCipherOutputLength(size_t plainTextLen) { return plainTextLen + aesCTRIVSize + kHmacOutSize; } +size_t fle2CipherOutputLength(size_t plainTextLen) { + return plainTextLen + aesCTRIVSize; +} + Status aeadEncryptLocalKMS(const SymmetricKey& key, ConstDataRange in, DataRange out) { if (key.getKeySize() != kFieldLevelEncryptionKeySize) { return Status(ErrorCodes::BadValue, @@ -313,8 +317,8 @@ Status aeadEncryptWithIV(ConstDataRange key, ivProvided = true; } - const auto* macKey = reinterpret_cast<const std::uint8_t*>(key.data()); - const auto* encKey = reinterpret_cast<const std::uint8_t*>(key.data() + sym256KeySize); + const auto* macKey = key.data<uint8_t>(); + const auto* encKey = key.data<uint8_t>() + sym256KeySize; SymmetricKey symEncKey(encKey, sym256KeySize, aesAlgorithm, "aesKey", 1); std::size_t aesOutLen = out.length() - kHmacOutSize; @@ -375,8 +379,8 @@ Status fle2AeadEncrypt(ConstDataRange key, ivProvided = true; } - auto encKey = reinterpret_cast<const std::uint8_t*>(key.data()); - auto macKey = reinterpret_cast<const std::uint8_t*>(key.data() + sym256KeySize); + auto encKey = key.data<uint8_t>(); + auto macKey = key.data<uint8_t>() + sym256KeySize; SymmetricKey symEncKey(encKey, sym256KeySize, aesAlgorithm, "aesKey", 1); std::size_t aesOutLen = out.length() - kHmacOutSize; @@ -401,6 +405,41 @@ Status fle2AeadEncrypt(ConstDataRange key, return Status::OK(); } +Status fle2Encrypt(ConstDataRange key, ConstDataRange in, ConstDataRange iv, DataRange out) { + if (key.length() != sym256KeySize) { + return Status(ErrorCodes::BadValue, "Invalid key size."); + } + + if (!in.length()) { + return Status(ErrorCodes::BadValue, "Invalid buffer length."); + } + + if (0 != iv.length() && aesCTRIVSize != iv.length()) { + return Status(ErrorCodes::BadValue, "Invalid IV length."); + } + + if (out.length() != fle2CipherOutputLength(in.length())) { + return Status(ErrorCodes::BadValue, "Invalid output buffer size."); + } + + bool ivProvided = false; + if (iv.length() != 0) { + invariant(iv.length() == aesCTRIVSize); + out.write(iv); + ivProvided = true; + } + + auto encKey = key.data<uint8_t>(); + SymmetricKey symEncKey(encKey, sym256KeySize, aesAlgorithm, "aesKey", 1); + + auto swEncrypt = _aesEncrypt(symEncKey, aesMode::ctr, in, out, ivProvided); + if (!swEncrypt.isOK()) { + return swEncrypt.getStatus(); + } + + return Status::OK(); +} + StatusWith<std::size_t> aeadDecrypt(const SymmetricKey& key, ConstDataRange in, ConstDataRange associatedData, @@ -487,8 +526,8 @@ StatusWith<std::size_t> fle2AeadDecrypt(ConstDataRange key, << kMaxAssociatedDataLength << " bytes."); } - auto encKey = reinterpret_cast<const std::uint8_t*>(key.data()); - auto macKey = reinterpret_cast<const std::uint8_t*>(key.data() + sym256KeySize); + auto encKey = key.data<uint8_t>(); + auto macKey = key.data<uint8_t>() + sym256KeySize; auto [ivAndCipherText, hmacRange] = in.split(in.length() - kHmacOutSize); SHA256Block hmacOutput = @@ -503,6 +542,25 @@ StatusWith<std::size_t> fle2AeadDecrypt(ConstDataRange key, return _aesDecrypt(symEncKey, aesMode::ctr, ivAndCipherText, out); } +StatusWith<std::size_t> fle2Decrypt(ConstDataRange key, ConstDataRange in, DataRange out) { + if (key.length() != sym256KeySize) { + return Status(ErrorCodes::BadValue, "Invalid key size."); + } + + if (in.length() <= aesCTRIVSize) { + return Status(ErrorCodes::BadValue, "Ciphertext is not long enough."); + } + + size_t expectedPlainTextSize = uassertStatusOK(fle2GetPlainTextLength(in.length())); + if (out.length() != expectedPlainTextSize) { + return Status(ErrorCodes::BadValue, "Output buffer must be as long as the cipherText."); + } + + auto encKey = key.data<uint8_t>(); + SymmetricKey symEncKey(encKey, sym256KeySize, aesAlgorithm, "aesKey", 1); + return _aesDecrypt(symEncKey, aesMode::ctr, in, out); +} + Status aeadDecryptDataFrame(FLEDecryptionFrame& dataframe) { auto ciphertext = dataframe.getCiphertext(); auto associatedData = dataframe.getAssociatedData(); |