Skip to content

Commit ecd1cf2

Browse files
marksg07MongoDB Bot
authored andcommitted
SERVER-100488 Correctly set a random IV for encryption in test client (#32061)
GitOrigin-RevId: aeffb6d
1 parent 71bd25d commit ecd1cf2

File tree

3 files changed

+63
-39
lines changed

3 files changed

+63
-39
lines changed

src/mongo/crypto/fle_crypto.cpp

Lines changed: 45 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -400,42 +400,12 @@ StatusWith<std::vector<uint8_t>> encryptDataWithAssociatedData(ConstDataRange ke
400400
return {out};
401401
}
402402

403-
StatusWith<std::vector<uint8_t>> encryptData(ConstDataRange key, ConstDataRange plainText) {
404-
MongoCryptStatus status;
405-
auto* fle2alg = _mcFLE2Algorithm();
406-
auto ciphertextLen = fle2alg->get_ciphertext_len(plainText.length(), status);
407-
if (!status.isOK()) {
408-
return status.toStatus();
409-
}
410-
MongoCryptBuffer out;
411-
out.resize(ciphertextLen);
412-
413-
MongoCryptBuffer iv;
414-
iv.resize(MONGOCRYPT_IV_LEN);
415-
416-
uint32_t written;
417-
418-
if (!fle2alg->do_encrypt(getGlobalMongoCrypt()->crypto,
419-
iv.get() /* iv */,
420-
NULL /* aad */,
421-
MongoCryptBuffer::borrow(key).get(),
422-
MongoCryptBuffer::borrow(plainText).get(),
423-
out.get(),
424-
&written,
425-
status)) {
426-
return status.toStatus();
427-
}
428-
429-
auto cdr = out.toCDR();
430-
return std::vector<uint8_t>(cdr.data(), cdr.data() + cdr.length());
431-
}
432-
433403
StatusWith<std::vector<uint8_t>> encryptData(ConstDataRange key, uint64_t value) {
434404

435405
std::array<char, sizeof(uint64_t)> bufValue;
436406
DataView(bufValue.data()).write<LittleEndian<uint64_t>>(value);
437407

438-
return encryptData(key, bufValue);
408+
return FLEUtil::encryptData(key, bufValue);
439409
}
440410

441411
StatusWith<std::vector<uint8_t>> decryptDataWithAssociatedData(ConstDataRange key,
@@ -499,7 +469,7 @@ StatusWith<std::vector<uint8_t>> packAndEncrypt(std::tuple<T1, T2> tuple, const
499469
}
500470

501471
dassert(builder.getCursor().length() == (sizeof(T1) + sizeof(T2)));
502-
return encryptData(token.toCDR(), builder.getCursor());
472+
return FLEUtil::encryptData(token.toCDR(), builder.getCursor());
503473
}
504474

505475

@@ -2226,10 +2196,10 @@ StateCollectionTokensV2::Encrypted StateCollectionTokensV2::encrypt(const ECOCTo
22262196
DataBuilder builder(sizeof(PrfBlock) + 1);
22272197
uassertStatusOK(builder.writeAndAdvance(_esc.toCDR()));
22282198
uassertStatusOK(builder.writeAndAdvance(*_isLeaf));
2229-
encryptedTokens = uassertStatusOK(encryptData(token.toCDR(), builder.getCursor()));
2199+
encryptedTokens = uassertStatusOK(FLEUtil::encryptData(token.toCDR(), builder.getCursor()));
22302200
} else {
22312201
// Equality
2232-
encryptedTokens = uassertStatusOK(encryptData(token.toCDR(), _esc.toCDR()));
2202+
encryptedTokens = uassertStatusOK(FLEUtil::encryptData(token.toCDR(), _esc.toCDR()));
22332203
}
22342204

22352205
return StateCollectionTokensV2::Encrypted(std::move(encryptedTokens));
@@ -3019,7 +2989,8 @@ StatusWith<std::vector<uint8_t>> FLE2TagAndEncryptedMetadataBlock::serialize(
30192989
return swEncryptedCount;
30202990
}
30212991

3022-
auto swEncryptedZeros = encryptData(zerosEncryptionToken.toCDR(), ConstDataRange(zeros));
2992+
auto swEncryptedZeros =
2993+
FLEUtil::encryptData(zerosEncryptionToken.toCDR(), ConstDataRange(zeros));
30232994
if (!swEncryptedZeros.isOK()) {
30242995
return swEncryptedZeros;
30252996
}
@@ -3168,8 +3139,8 @@ FLE2IndexedEqualityEncryptedValueV2 FLE2IndexedEqualityEncryptedValueV2::fromUne
31683139
FLE2IndexedEqualityEncryptedValueV2 value;
31693140
mc_FLE2IndexedEncryptedValueV2_t* iev = value._value.get();
31703141

3171-
auto swServerEncryptedValue =
3172-
encryptData(serverEncryptionToken.toCDR(), ConstDataRange(clientEncryptedValueParam));
3142+
auto swServerEncryptedValue = FLEUtil::encryptData(serverEncryptionToken.toCDR(),
3143+
ConstDataRange(clientEncryptedValueParam));
31733144
uassertStatusOK(swServerEncryptedValue);
31743145

31753146
auto swSerializedMetadata = metadataBlockParam.serialize(serverDataDerivedToken);
@@ -3511,7 +3482,7 @@ StatusWith<std::vector<uint8_t>> FLE2IndexedRangeEncryptedValueV2::serialize(
35113482
uint8_t edgeCount = static_cast<uint8_t>(metadataBlocks.size());
35123483

35133484
auto swEncryptedData =
3514-
encryptData(serverEncryptionToken.toCDR(), ConstDataRange(clientEncryptedValue));
3485+
FLEUtil::encryptData(serverEncryptionToken.toCDR(), ConstDataRange(clientEncryptedValue));
35153486
if (!swEncryptedData.isOK()) {
35163487
return swEncryptedData;
35173488
}
@@ -3642,7 +3613,7 @@ FLE2IndexedTextEncryptedValue FLE2IndexedTextEncryptedValue::fromUnencrypted(
36423613

36433614
auto keyId = payload.getIndexKeyId().toCDR();
36443615

3645-
auto serverEncryptedValue = uassertStatusOK(encryptData(
3616+
auto serverEncryptedValue = uassertStatusOK(FLEUtil::encryptData(
36463617
payload.getServerEncryptionToken().toCDR(), ConstDataRange(clientEncryptedValue)));
36473618

36483619
if (!_mongocrypt_buffer_copy_from_data_and_size(
@@ -4835,6 +4806,41 @@ StatusWith<std::vector<uint8_t>> FLEUtil::decryptData(ConstDataRange key,
48354806
return {out};
48364807
}
48374808

4809+
StatusWith<std::vector<uint8_t>> FLEUtil::encryptData(ConstDataRange key,
4810+
ConstDataRange plainText) {
4811+
MongoCryptStatus status;
4812+
// AES-256-CTR
4813+
auto* fle2alg = _mcFLE2Algorithm();
4814+
auto ciphertextLen = fle2alg->get_ciphertext_len(plainText.length(), status);
4815+
if (!status.isOK()) {
4816+
return status.toStatus();
4817+
}
4818+
MongoCryptBuffer out;
4819+
out.resize(ciphertextLen);
4820+
4821+
MongoCryptBuffer iv;
4822+
iv.resize(MONGOCRYPT_IV_LEN);
4823+
auto* crypto = getGlobalMongoCrypt()->crypto;
4824+
if (!_mongocrypt_random(crypto, iv.get(), MONGOCRYPT_IV_LEN, status)) {
4825+
return status.toStatus();
4826+
}
4827+
4828+
uint32_t written;
4829+
if (!fle2alg->do_encrypt(crypto,
4830+
iv.get() /* iv */,
4831+
NULL /* aad */,
4832+
MongoCryptBuffer::borrow(key).get(),
4833+
MongoCryptBuffer::borrow(plainText).get(),
4834+
out.get(),
4835+
&written,
4836+
status)) {
4837+
return status.toStatus();
4838+
}
4839+
4840+
auto cdr = out.toCDR();
4841+
return std::vector<uint8_t>(cdr.data(), cdr.data() + cdr.length());
4842+
}
4843+
48384844
template class ESCCollectionCommon<ESCTwiceDerivedTagToken, ESCTwiceDerivedValueToken>;
48394845
template class ESCCollectionCommon<AnchorPaddingKeyToken, AnchorPaddingValueToken>;
48404846
} // namespace mongo

src/mongo/crypto/fle_crypto.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1300,6 +1300,10 @@ class FLEUtil {
13001300
*/
13011301
static StatusWith<std::vector<uint8_t>> decryptData(ConstDataRange key,
13021302
ConstDataRange cipherText);
1303+
1304+
// Encrypt data with AES-256-CTR. Exposed for testing.
1305+
static StatusWith<std::vector<uint8_t>> encryptData(ConstDataRange key,
1306+
ConstDataRange plainText);
13031307
};
13041308

13051309
/**

src/mongo/crypto/fle_crypto_test.cpp

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5786,4 +5786,18 @@ TEST_F(AnchorPaddingFixture, generatePaddingDocument) {
57865786
}
57875787
}
57885788

5789+
TEST_F(ServiceContextTest, fleEncryptAndDecrypt) {
5790+
PrfBlock key;
5791+
uassertStatusOK(crypto::engineRandBytes(DataRange(key)));
5792+
std::vector<uint8_t> plaintext{'a', 'b', 'c', 'd', 'e', 'f'};
5793+
auto encrypt1 = uassertStatusOK(FLEUtil::encryptData(key, plaintext));
5794+
auto encrypt2 = uassertStatusOK(FLEUtil::encryptData(key, plaintext));
5795+
// Ensure that we are correctly generating random IVs in encryptData.
5796+
ASSERT_NE(encrypt1, encrypt2);
5797+
auto decrypt1 = uassertStatusOK(FLEUtil::decryptData(key, encrypt1));
5798+
auto decrypt2 = uassertStatusOK(FLEUtil::decryptData(key, encrypt2));
5799+
ASSERT_EQ(decrypt1, decrypt2);
5800+
ASSERT_EQ(decrypt1, plaintext);
5801+
}
5802+
57895803
} // namespace mongo

0 commit comments

Comments
 (0)