From 67c6ad2f9856b1adf001aed573d87cb8f62c86b5 Mon Sep 17 00:00:00 2001 From: Sara Golemon Date: Wed, 3 Jul 2019 20:28:52 +0000 Subject: SERVER-42061 Validate decrypted payload in AEAD decrypt (cherry picked from commit 7eab0b598578261829a7adce6330ae7eff2894a1) --- src/mongo/crypto/aead_encryption.cpp | 19 +++++++++++++++++++ src/mongo/crypto/aead_encryption_test.cpp | 11 +++++++++++ 2 files changed, 30 insertions(+) diff --git a/src/mongo/crypto/aead_encryption.cpp b/src/mongo/crypto/aead_encryption.cpp index f5d1f679dd1..3f898c48ff1 100644 --- a/src/mongo/crypto/aead_encryption.cpp +++ b/src/mongo/crypto/aead_encryption.cpp @@ -154,6 +154,25 @@ Status _aesDecrypt(const SymmetricKey& key, << *resultLen}; } + /* Check that padding was removed. + * + * PKCS7 padding guarantees that the encrypted payload has + * between 1 and blocksize bytes of padding which should be + * removed during the decrypt process. + * + * If resultLen is the same as the payload len, + * that means no padding was removed. + * + * macOS CommonCrypto will return such payloads when either the + * key or ciphertext are corrupted and its unable to find any + * expected padding. It fails open by returning whatever it can. + */ + if (*resultLen >= dataSize) { + return {ErrorCodes::BadValue, + "Decrypt error, plaintext is as large or larger than " + "the ciphertext. This usually indicates an invalid key."}; + } + return Status::OK(); } catch (const AssertionException& ex) { return ex.toStatus(); diff --git a/src/mongo/crypto/aead_encryption_test.cpp b/src/mongo/crypto/aead_encryption_test.cpp index 28177f05b82..febc8d137c0 100644 --- a/src/mongo/crypto/aead_encryption_test.cpp +++ b/src/mongo/crypto/aead_encryption_test.cpp @@ -147,6 +147,17 @@ TEST(AEAD, EncryptAndDecrypt) { &plainTextDecryptLen)); ASSERT_EQ(0, std::memcmp(plainText.data(), plainTextTest.data(), 128)); + + // Decrypt should fail if we alter the key. + (*aesVector)[0] ^= 1; + key = SymmetricKey(aesVector, aesAlgorithm, "aeadEncryptDecryptTest"); + ASSERT_NOT_OK(crypto::aeadDecrypt(key, + cryptoBuffer.data(), + cryptoBuffer.size(), + associatedData.data(), + dataLen, + plainText.data(), + &plainTextDecryptLen)); } } // namespace } // namespace mongo -- cgit v1.2.1