summaryrefslogtreecommitdiff
path: root/src/mongo/crypto
diff options
context:
space:
mode:
authorMark Benvenuto <mark.benvenuto@mongodb.com>2019-07-24 14:27:00 -0400
committerMark Benvenuto <mark.benvenuto@mongodb.com>2019-07-24 14:27:00 -0400
commit260a0ced5d3754f375fee6e220855e722c4b72b8 (patch)
treed683fd51d63973a3e6c74faca0a295d1f84912fb /src/mongo/crypto
parentbaaa7c25fadcbe4f544a885be4734a0d50ad20d2 (diff)
downloadmongo-260a0ced5d3754f375fee6e220855e722c4b72b8.tar.gz
SERVER-42318 Tighten bounds on AEAD Decrypt output length
Diffstat (limited to 'src/mongo/crypto')
-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
3 files changed, 24 insertions, 7 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(),