summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/mongo/crypto/aead_encryption.cpp21
-rw-r--r--src/mongo/crypto/aead_encryption.h6
-rw-r--r--src/mongo/crypto/aead_encryption_test.cpp4
-rw-r--r--src/mongo/shell/encrypted_dbclient_base.cpp6
-rw-r--r--src/mongo/shell/kms_local.cpp3
5 files changed, 30 insertions, 10 deletions
diff --git a/src/mongo/crypto/aead_encryption.cpp b/src/mongo/crypto/aead_encryption.cpp
index 3f898c48ff1..030758850c1 100644
--- a/src/mongo/crypto/aead_encryption.cpp
+++ b/src/mongo/crypto/aead_encryption.cpp
@@ -191,6 +191,14 @@ size_t aeadCipherOutputLength(size_t plainTextLen) {
return aesOutLen + kHmacOutSize;
}
+StatusWith<size_t> aeadGetMaximumPlainTextLength(size_t cipherTextLen) {
+ if (cipherTextLen > (aesCBCIVSize + kHmacOutSize)) {
+ return cipherTextLen - aesCBCIVSize - kHmacOutSize;
+ }
+
+ return Status(ErrorCodes::BadValue, "Invalid cipher text length");
+}
+
Status aeadEncrypt(const SymmetricKey& key,
const uint8_t* in,
const size_t inLen,
@@ -336,7 +344,12 @@ Status aeadDecrypt(const SymmetricKey& key,
return Status(ErrorCodes::BadValue, "Invalid AEAD parameters.");
}
- if ((*outLen) != cipherLen) {
+ if (cipherLen < kHmacOutSize) {
+ return Status(ErrorCodes::BadValue, "Ciphertext is not long enough.");
+ }
+
+ size_t expectedMaximumPlainTextSize = uassertStatusOK(aeadGetMaximumPlainTextLength(cipherLen));
+ if ((*outLen) != expectedMaximumPlainTextSize) {
return Status(ErrorCodes::BadValue, "Output buffer must be as long as the cipherText.");
}
@@ -351,9 +364,6 @@ Status aeadDecrypt(const SymmetricKey& key,
const uint8_t* macKey = key.getKey();
const uint8_t* encKey = key.getKey() + sym256KeySize;
- if (cipherLen < kHmacOutSize) {
- return Status(ErrorCodes::BadValue, "Ciphertext is not long enough.");
- }
size_t aesLen = cipherLen - kHmacOutSize;
// According to the rfc on AES encryption, the associatedDataLength is defined as the
@@ -378,7 +388,8 @@ Status aeadDecrypt(const SymmetricKey& key,
SymmetricKey symEncKey(encKey, sym256KeySize, aesAlgorithm, key.getKeyId(), 1);
- auto sDecrypt = _aesDecrypt(symEncKey, ConstDataRange(cipherText, aesLen), out, aesLen, outLen);
+ auto sDecrypt =
+ _aesDecrypt(symEncKey, ConstDataRange(cipherText, aesLen), out, *outLen, outLen);
if (!sDecrypt.isOK()) {
return sDecrypt;
}
diff --git a/src/mongo/crypto/aead_encryption.h b/src/mongo/crypto/aead_encryption.h
index c5fb79479e6..134e83bff08 100644
--- a/src/mongo/crypto/aead_encryption.h
+++ b/src/mongo/crypto/aead_encryption.h
@@ -53,6 +53,12 @@ size_t aeadCipherOutputLength(size_t plainTextLen);
/**
+ * Returns the length of the plaintext output given the ciphertext length. Only for AEAD.
+ */
+StatusWith<size_t> aeadGetMaximumPlainTextLength(size_t cipherTextLen);
+
+
+/**
* Encrypts the plaintext using following the AEAD_AES_256_CBC_HMAC_SHA_512 encryption
* algorithm. Writes output to out.
*/
diff --git a/src/mongo/crypto/aead_encryption_test.cpp b/src/mongo/crypto/aead_encryption_test.cpp
index febc8d137c0..f0417cec23e 100644
--- a/src/mongo/crypto/aead_encryption_test.cpp
+++ b/src/mongo/crypto/aead_encryption_test.cpp
@@ -136,8 +136,8 @@ TEST(AEAD, EncryptAndDecrypt) {
ASSERT_EQ(0, std::memcmp(cryptoBuffer.data(), cryptoBufferTest.data(), 192));
- std::array<uint8_t, 192> plainText = {};
- size_t plainTextDecryptLen = 192;
+ std::array<uint8_t, 144> plainText = {};
+ size_t plainTextDecryptLen = 144;
ASSERT_OK(crypto::aeadDecrypt(key,
cryptoBuffer.data(),
cryptoBuffer.size(),
diff --git a/src/mongo/shell/encrypted_dbclient_base.cpp b/src/mongo/shell/encrypted_dbclient_base.cpp
index c8858f8a9f3..bec5bb8ae5e 100644
--- a/src/mongo/shell/encrypted_dbclient_base.cpp
+++ b/src/mongo/shell/encrypted_dbclient_base.cpp
@@ -188,7 +188,8 @@ void EncryptedDBClientBase::decryptPayload(ConstDataRange data,
UUID uuid = UUID::fromCDR(uuidCdr);
auto key = getDataKey(uuid);
- std::vector<uint8_t> out(data.length() - kAssociatedDataLength);
+ std::vector<uint8_t> out(uassertStatusOK(
+ crypto::aeadGetMaximumPlainTextLength(data.length() - kAssociatedDataLength)));
size_t outLen = out.size();
uassertStatusOK(
@@ -499,7 +500,8 @@ void EncryptedDBClientBase::decrypt(mozjs::MozJSImplScope* scope,
UUID uuid = UUID::fromCDR(uuidCdr);
auto key = getDataKey(uuid);
- std::vector<uint8_t> out(binData.size() - kAssociatedDataLength);
+ std::vector<uint8_t> out(uassertStatusOK(
+ crypto::aeadGetMaximumPlainTextLength(binData.size() - kAssociatedDataLength)));
size_t outLen = out.size();
auto decryptStatus = crypto::aeadDecrypt(*key,
diff --git a/src/mongo/shell/kms_local.cpp b/src/mongo/shell/kms_local.cpp
index e7a090211b3..628ea9ed9c2 100644
--- a/src/mongo/shell/kms_local.cpp
+++ b/src/mongo/shell/kms_local.cpp
@@ -93,7 +93,8 @@ BSONObj LocalKMSService::encryptDataKey(ConstDataRange cdr, StringData keyId) {
}
SecureVector<uint8_t> LocalKMSService::decrypt(ConstDataRange cdr, BSONObj masterKey) {
- SecureVector<uint8_t> plaintext(cdr.length());
+ SecureVector<uint8_t> plaintext(
+ uassertStatusOK(crypto::aeadGetMaximumPlainTextLength(cdr.length())));
size_t outLen = plaintext->size();
uassertStatusOK(crypto::aeadDecrypt(_key,