summaryrefslogtreecommitdiff
path: root/src/mongo/crypto
diff options
context:
space:
mode:
authorsergey.galtsev <sergey.galtsev@mongodb.com>2022-04-08 01:00:11 +0000
committerEvergreen Agent <no-reply@evergreen.mongodb.com>2022-04-08 01:27:22 +0000
commite6cce2875f3efa0c9b1443cf66efab95d5325a8f (patch)
tree066dbdda0ceb7d62d00bdbf9507fc025234c432d /src/mongo/crypto
parent0e7af76ae586749bf71928963c857cb50f760b9b (diff)
downloadmongo-e6cce2875f3efa0c9b1443cf66efab95d5325a8f.tar.gz
SERVER-63594 Add EDC, ESC, ECC, and ECOC test vectors
Diffstat (limited to 'src/mongo/crypto')
-rw-r--r--src/mongo/crypto/fle_crypto_test.cpp330
1 files changed, 213 insertions, 117 deletions
diff --git a/src/mongo/crypto/fle_crypto_test.cpp b/src/mongo/crypto/fle_crypto_test.cpp
index 376ac0db6fd..0dce8b2c99f 100644
--- a/src/mongo/crypto/fle_crypto_test.cpp
+++ b/src/mongo/crypto/fle_crypto_test.cpp
@@ -171,119 +171,214 @@ KeyMaterial TestKeyVault::getKey(const UUID& uuid) {
}
}
-// TODO (SERVER-63594) - regenerate test vectors and reimplement test
-//
-// TEST(FLETokens, TestVectors) {
-
-// // Level 1
-// auto collectionToken =
-// FLELevel1TokenGenerator::generateCollectionsLevel1Token(getIndexKey());
-
-// ASSERT_EQUALS(CollectionsLevel1Token(decodePrf(
-// "ff2103ff205a36f39704f643c270c129919f008c391d9589a6d2c86a7429d0d3"_sd)),
-// collectionToken);
-
-// ASSERT_EQUALS(ServerDataEncryptionLevel1Token(decodePrf(
-// "d915ccc1eb81687fb5fc5b799f48c99fbe17e7a011a46a48901b9ae3d790656b"_sd)),
-// FLELevel1TokenGenerator::generateServerDataEncryptionLevel1Token(getIndexKey()));
-
-// // Level 2
-// auto edcToken = FLECollectionTokenGenerator::generateEDCToken(collectionToken);
-// ASSERT_EQUALS(
-// EDCToken(decodePrf("167d2d2ff8e4144df37ff759db593fde0ecc7d9636f96d62dacad672eccad349"_sd)),
-
-// edcToken);
-// auto escToken = FLECollectionTokenGenerator::generateESCToken(collectionToken);
-// ASSERT_EQUALS(
-// ESCToken(decodePrf("bfd480f1658f49f48985734737bc07d0bc36b88210277605c55ff3c9c3ef50b0"_sd)),
-// escToken);
-// auto eccToken = FLECollectionTokenGenerator::generateECCToken(collectionToken);
-// ASSERT_EQUALS(
-// ECCToken(decodePrf("9d34f9c182d75a5a3347c2f903e3e647105c651d52cf9555c9420ba07ddd3aa2"_sd)),
-// eccToken);
-// ASSERT_EQUALS(
-// ECOCToken(decodePrf("e354e3b05e81e08b970ca061cb365163fd33dec2f982ddf9440e742ed288a8f8"_sd)),
-// FLECollectionTokenGenerator::generateECOCToken(collectionToken));
-
-
-// // Level 3
-// std::vector<uint8_t> sampleValue = {0xc0, 0x7c, 0x0d, 0xf5, 0x12, 0x57, 0x94, 0x8e,
-// 0x1a, 0x0f, 0xc7, 0x0d, 0xd4, 0x56, 0x8e, 0x3a,
-// 0xf9, 0x9b, 0x23, 0xb3, 0x43, 0x4c, 0x98, 0x58,
-// 0x23, 0x7c, 0xa7, 0xdb, 0x62, 0xdb, 0x97, 0x66};
-
-// auto edcDataToken =
-// FLEDerivedFromDataTokenGenerator::generateEDCDerivedFromDataToken(edcToken, sampleValue);
-// ASSERT_EQUALS(EDCDerivedFromDataToken(decodePrf(
-// "53eaa4c23a3ff65e6b7c7dbc4b1389cf0a6151b1ede5383a0673ff9c67855ff9"_sd)),
-// edcDataToken);
-
-// auto escDataToken =
-// FLEDerivedFromDataTokenGenerator::generateESCDerivedFromDataToken(escToken, sampleValue);
-// ASSERT_EQUALS(ESCDerivedFromDataToken(decodePrf(
-// "acb3fab332131bbeaf112814f29ae0f2b10e97dc94b62db56c594661248e7467"_sd)),
-// escDataToken);
-
-// auto eccDataToken =
-// FLEDerivedFromDataTokenGenerator::generateECCDerivedFromDataToken(eccToken, sampleValue);
-// ASSERT_EQUALS(ECCDerivedFromDataToken(decodePrf(
-// "826cfd35c35dcc7d4fbe13f33a3520749853bd1ea4c47919482252fba3a70cec"_sd)),
-// eccDataToken);
-
-// // Level 4
-// FLECounter counter = 1234567890;
-
-// auto edcDataCounterToken = FLEDerivedFromDataTokenAndContentionFactorTokenGenerator::
-// generateEDCDerivedFromDataTokenAndContentionFactorToken(edcDataToken, counter);
-// ASSERT_EQUALS(EDCDerivedFromDataTokenAndContentionFactorToken(decodePrf(
-// "70fb9a3f760996f2f1438c5bf2a4d52bcba01b0badc3596276f49ffb2f0b136e"_sd)),
-// edcDataCounterToken);
-
-
-// auto escDataCounterToken = FLEDerivedFromDataTokenAndContentionFactorTokenGenerator::
-// generateESCDerivedFromDataTokenAndContentionFactorToken(escDataToken, counter);
-// ASSERT_EQUALS(ESCDerivedFromDataTokenAndContentionFactorToken(decodePrf(
-// "7076c7b05fb4be4fe585eed930b852a6d088a0c55f3c96b50069e8a26ebfb347"_sd)),
-// escDataCounterToken);
-
-
-// auto eccDataCounterToken = FLEDerivedFromDataTokenAndContentionFactorTokenGenerator::
-// generateECCDerivedFromDataTokenAndContentionFactorToken(eccDataToken, counter);
-// ASSERT_EQUALS(ECCDerivedFromDataTokenAndContentionFactorToken(decodePrf(
-// "6c6a349956c19f9c5e638e612011a71fbb71921edb540310c17cd0208b7f548b"_sd)),
-// eccDataCounterToken);
-
-
-// // Level 5
-// auto edcTwiceToken =
-// FLETwiceDerivedTokenGenerator::generateEDCTwiceDerivedToken(edcDataCounterToken);
-// ASSERT_EQUALS(EDCTwiceDerivedToken(decodePrf(
-// "3643fd370e2719c03234cdeec787dfdc7d8fceecafa8a992e3c1f9d4d53449fe"_sd)),
-// edcTwiceToken);
-
-// auto escTwiceTagToken =
-// FLETwiceDerivedTokenGenerator::generateESCTwiceDerivedTagToken(escDataCounterToken);
-// ASSERT_EQUALS(ESCTwiceDerivedTagToken(decodePrf(
-// "c73bc4ff5e70222c653140b2b4998b4d62db973f20f116f66ff811a9a907a78f"_sd)),
-// escTwiceTagToken);
-// auto escTwiceValueToken =
-// FLETwiceDerivedTokenGenerator::generateESCTwiceDerivedValueToken(escDataCounterToken);
-// ASSERT_EQUALS(ESCTwiceDerivedValueToken(decodePrf(
-// "34150c6f5ab56dc39ddb935accb7f53e5276322fa937650b76a4dda9723d6fba"_sd)),
-// escTwiceValueToken);
-
-
-// auto eccTwiceTagToken =
-// FLETwiceDerivedTokenGenerator::generateECCTwiceDerivedTagToken(eccDataCounterToken);
-// ASSERT_EQUALS(ECCTwiceDerivedTagToken(decodePrf(
-// "0bc36f73062f5182c2403bffd155ec06eccfde0df8de5facaca4cc1cb320a385"_sd)),
-// eccTwiceTagToken);
-// auto eccTwiceValueToken =
-// FLETwiceDerivedTokenGenerator::generateECCTwiceDerivedValueToken(eccDataCounterToken);
-// ASSERT_EQUALS(ECCTwiceDerivedValueToken(decodePrf(
-// "2d7e08d58afa9f5ad215636e566d38584cbb48467d1bc9ff376eeca01fbfda6f"_sd)),
-// eccTwiceValueToken);
-// }
+TEST(FLETokens, TestVectors) {
+
+ // Level 1
+ auto collectionToken = FLELevel1TokenGenerator::generateCollectionsLevel1Token(getIndexKey());
+
+ ASSERT_EQUALS(CollectionsLevel1Token(decodePrf(
+ "BD53ACAC665EDD01E0CA30CB648B2B8F4967544047FD4E7D12B1A9BF07339928"_sd)),
+ collectionToken);
+
+ ASSERT_EQUALS(ServerDataEncryptionLevel1Token(decodePrf(
+ "EB9A73F7912D86A4297E81D2F675AF742874E4057E3A890FEC651A23EEE3F3EC"_sd)),
+ FLELevel1TokenGenerator::generateServerDataEncryptionLevel1Token(getIndexKey()));
+
+ // Level 2
+ auto edcToken = FLECollectionTokenGenerator::generateEDCToken(collectionToken);
+ ASSERT_EQUALS(
+ EDCToken(decodePrf("82B0AB0F8F1D31AEB6F4DBC915EF17CBA2FE21E36EC436984EB63BECEC173831"_sd)),
+ edcToken);
+ auto escToken = FLECollectionTokenGenerator::generateESCToken(collectionToken);
+ ASSERT_EQUALS(
+ ESCToken(decodePrf("279C575B52B73677EEF07D9C1126EBDF08C35369570A9B75E44A9AFDCCA96B6D"_sd)),
+ escToken);
+ auto eccToken = FLECollectionTokenGenerator::generateECCToken(collectionToken);
+ ASSERT_EQUALS(
+ ECCToken(decodePrf("C58F671F04A8CFDD8FB1F718F563139F1286D7950E97C0C4A94EDDF0EDB127FE"_sd)),
+ eccToken);
+ ASSERT_EQUALS(
+ ECOCToken(decodePrf("9E837ED3926CB8ED680E0E7DCB2A481A3E398BE7851FA1CE4D738FA5E67FFCC9"_sd)),
+ FLECollectionTokenGenerator::generateECOCToken(collectionToken));
+
+
+ // Level 3
+ std::vector<uint8_t> sampleValue = {0xc0, 0x7c, 0x0d, 0xf5, 0x12, 0x57, 0x94, 0x8e,
+ 0x1a, 0x0f, 0xc7, 0x0d, 0xd4, 0x56, 0x8e, 0x3a,
+ 0xf9, 0x9b, 0x23, 0xb3, 0x43, 0x4c, 0x98, 0x58,
+ 0x23, 0x7c, 0xa7, 0xdb, 0x62, 0xdb, 0x97, 0x66};
+
+ auto edcDataToken =
+ FLEDerivedFromDataTokenGenerator::generateEDCDerivedFromDataToken(edcToken, sampleValue);
+ ASSERT_EQUALS(EDCDerivedFromDataToken(decodePrf(
+ "CEA098AA664E578D4E9CE05B50ADD15DF2F0316CD5CCB08E720C61D8C7580E2A"_sd)),
+ edcDataToken);
+
+ auto escDataToken =
+ FLEDerivedFromDataTokenGenerator::generateESCDerivedFromDataToken(escToken, sampleValue);
+ ASSERT_EQUALS(ESCDerivedFromDataToken(decodePrf(
+ "DE6A1AC292BC62094C33E94647B044B9B10514317B75F4128DDA2E0FB686704F"_sd)),
+ escDataToken);
+
+ auto eccDataToken =
+ FLEDerivedFromDataTokenGenerator::generateECCDerivedFromDataToken(eccToken, sampleValue);
+ ASSERT_EQUALS(ECCDerivedFromDataToken(decodePrf(
+ "9A95D4F44734447E3F0266D1629513A0B7698CCE8C1524F329CE7970627FFD06"_sd)),
+ eccDataToken);
+
+ // Level 4
+ FLECounter counter = 1234567890;
+
+ auto edcDataCounterToken = FLEDerivedFromDataTokenAndContentionFactorTokenGenerator::
+ generateEDCDerivedFromDataTokenAndContentionFactorToken(edcDataToken, counter);
+ ASSERT_EQUALS(EDCDerivedFromDataTokenAndContentionFactorToken(decodePrf(
+ "D8CC38AE6A64BD1BF195A2D35734C13AF2B1729AD1052A81BE00BF29C67A696E"_sd)),
+ edcDataCounterToken);
+
+
+ auto escDataCounterToken = FLEDerivedFromDataTokenAndContentionFactorTokenGenerator::
+ generateESCDerivedFromDataTokenAndContentionFactorToken(escDataToken, counter);
+ ASSERT_EQUALS(ESCDerivedFromDataTokenAndContentionFactorToken(decodePrf(
+ "8AAF04CBA6DC16BFB37CADBA43DCA66C183634CB3DA278DE174556AE6E17CEBB"_sd)),
+ escDataCounterToken);
+
+
+ auto eccDataCounterToken = FLEDerivedFromDataTokenAndContentionFactorTokenGenerator::
+ generateECCDerivedFromDataTokenAndContentionFactorToken(eccDataToken, counter);
+ ASSERT_EQUALS(ECCDerivedFromDataTokenAndContentionFactorToken(decodePrf(
+ "E9580F805E0D07AF384EBA185384F28A49C3DB93AFA4A187A1F4DA129271D82C"_sd)),
+ eccDataCounterToken);
+
+
+ // Level 5
+ auto edcTwiceToken =
+ FLETwiceDerivedTokenGenerator::generateEDCTwiceDerivedToken(edcDataCounterToken);
+ ASSERT_EQUALS(EDCTwiceDerivedToken(decodePrf(
+ "B39A7EC33FD976EFB8EEBBBF3A265A933E2128D709BB88C77E3D42AA735F697C"_sd)),
+ edcTwiceToken);
+
+ auto escTwiceTagToken =
+ FLETwiceDerivedTokenGenerator::generateESCTwiceDerivedTagToken(escDataCounterToken);
+ ASSERT_EQUALS(ESCTwiceDerivedTagToken(decodePrf(
+ "D6F76A9D4767E0889B709517C8CF0412D81874AEB6E6CEBFBDDFF7B013EB7154"_sd)),
+ escTwiceTagToken);
+ auto escTwiceValueToken =
+ FLETwiceDerivedTokenGenerator::generateESCTwiceDerivedValueToken(escDataCounterToken);
+ ASSERT_EQUALS(ESCTwiceDerivedValueToken(decodePrf(
+ "53F0A51A43447B9881D5E79BA4C5F78E80BC2BC6AA42B00C81079EBF4C9D5A7C"_sd)),
+ escTwiceValueToken);
+
+
+ auto eccTwiceTagToken =
+ FLETwiceDerivedTokenGenerator::generateECCTwiceDerivedTagToken(eccDataCounterToken);
+ ASSERT_EQUALS(ECCTwiceDerivedTagToken(decodePrf(
+ "5DD9F09757BE35BB33FFAF6FC5CDFC649248E59AEA9FF7D9E2A9F36B6F5A6152"_sd)),
+ eccTwiceTagToken);
+ auto eccTwiceValueToken =
+ FLETwiceDerivedTokenGenerator::generateECCTwiceDerivedValueToken(eccDataCounterToken);
+ ASSERT_EQUALS(ECCTwiceDerivedValueToken(decodePrf(
+ "EFA5746DB796DAC6FAACB7E5F28DB53B333588A43131F0C026B19D2B1215EAE2"_sd)),
+ eccTwiceValueToken);
+
+ // Unindexed field decryption
+ // Encryption can not be generated using test vectors because IV is random
+
+ TestKeyVault keyVault;
+ const std::string uxCiphertext = hexblob::decode(
+ "06ABCDEFAB12349876123412345678901202F2CE7FDD0DECD5442CC98C10B9138741785173E323132982740496768877A3BA46581CED4A34031B1174B5C524C15BAAE687F88C29FC71F40A32BCD53D63CDA0A6646E8677E167BB3A933529F5B519CFE255BBC323D943B4F105"_sd);
+ auto [uxBsonType, uxPlaintext] =
+ FLE2UnindexedEncryptedValue::deserialize(&keyVault, ConstDataRange(uxCiphertext));
+ ASSERT_EQUALS(uxBsonType, BSONType::String);
+ ASSERT_EQUALS(
+ hexblob::encode(uxPlaintext.data(), uxPlaintext.size()),
+ "260000004C6F7279207761732061206D6F75736520696E2061206269672062726F776E20686F75736500");
+
+ // Equality indexed field decryption
+ // Encryption can not be generated using test vectors because IV is random
+
+ const std::string ixCiphertext = hexblob::decode(
+ "000000000000000000000000000000000297044B8E1B5CF4F9052EDB50236A343597C418A74352F98357A77E0D4299C04151CBEC24A5D5349A5A5EAA1FE334154FEEB6C8E7BD636089904F76950B2184D146792CBDF9179FFEDDB7D90FC257BB13DCB3E731182A447E2EF1BE7A2AF13DC9362701BABDE0B5E78CF4A92227D5B5D1E1556E75BAB5B4E9F5CEFEA3BA3E3D5D31D11B20619437A30550EFF5B602357567CF05058E4F84A103293F70302F3A50667642DD0325D194A197"_sd);
+ ServerDataEncryptionLevel1Token serverEncryptToken(
+ decodePrf("EB9A73F7912D86A4297E81D2F675AF742874E4057E3A890FEC651A23EEE3F3EC"_sd));
+
+ auto swServerPayload = FLE2IndexedEqualityEncryptedValue::decryptAndParse(
+ serverEncryptToken, ConstDataRange(ixCiphertext));
+ ASSERT_OK(swServerPayload.getStatus());
+
+ auto cdrEqualHex = [](ConstDataRange cdr, const StringData hex) -> bool {
+ const std::string s = hexblob::decode(hex);
+ return cdr.length() == s.size() && std::equal(s.begin(), s.end(), cdr.data<char>());
+ };
+
+ auto sp = swServerPayload.getValue();
+ ASSERT(cdrEqualHex(sp.edc.toCDR(),
+ "97C8DFE394D80A4EE335E3F9FDC024D18BE4B92F9444FCA316FF9896D7BF455D"_sd));
+ ASSERT(cdrEqualHex(sp.esc.toCDR(),
+ "EBB22F74BE0FA4AD863188D3F33AF0B95CB4CA4ED0091E1A43513DB20E9D59AE"_sd));
+ ASSERT(cdrEqualHex(sp.ecc.toCDR(),
+ "A1DF0BB04C977BD4BC0B487FFFD2E3BBB96078354DE9F204EE5872BB10F01971"_sd));
+ ASSERT_EQ(sp.count, 123456);
+ ASSERT(cdrEqualHex(
+ sp.clientEncryptedValue,
+ "260000004C6F7279207761732061206D6F75736520696E2061206269672062726F776E20686F75736500"_sd));
+}
+
+TEST(FLETokens, TestVectorESCCollectionDecryptDocument) {
+ ESCTwiceDerivedTagToken escTwiceTag(
+ decodePrf("B1C4E1C67F4AB83DE7632B801BDD198D65401B17EC633EB4D608DE97FAFCE02B"_sd));
+ ESCTwiceDerivedValueToken escTwiceValue(
+ decodePrf("E2E3F08343FD16BCB36927FFA39C7BCC6AA1E33E6E553DF9FE445ABB988D30D1"_sd));
+
+ BSONObj doc = fromjson(R"({
+ "_id": {
+ "$binary": {
+ "base64": "bdK0MLySL7lEaje7JHIWvvpx/AQWZID2kW47M1XLFUg=",
+ "subType": "0"
+ }
+ },
+ "value": {
+ "$binary": {
+ "base64": "+17srnmE1l+T1np0IJxoeLRzD1ac5st9k/a0YHxeqk0=",
+ "subType": "0"
+ }
+ }
+ })");
+
+ auto swDoc = ESCCollection::decryptDocument(escTwiceValue, doc);
+ ASSERT_OK(swDoc.getStatus());
+ ASSERT_EQ(swDoc.getValue().compactionPlaceholder, false);
+ ASSERT_EQ(swDoc.getValue().position, 0);
+ ASSERT_EQ(swDoc.getValue().count, 123456789);
+}
+
+TEST(FLETokens, TestVectorECCCollectionDecryptDocument) {
+ ECCTwiceDerivedTagToken twiceTag(
+ decodePrf("8879748219186CAC6B5E77D664A05C4BA2C7690F09ACC16B8E9910B80FF4B5AB"_sd));
+ ECCTwiceDerivedValueToken twiceValue(
+ decodePrf("F868EB46AA38963658E453DE05B2955225CB00C96B72975DACF9D837C8189FA2"_sd));
+
+ BSONObj doc = fromjson(R"({
+ "_id": {
+ "$binary": {
+ "base64": "TTB8rMJipFwpSMbWMf3Rpx8RuRP4Fnc6bJl1tdMc84A=",
+ "subType": "0"
+ }
+ },
+ "value": {
+ "$binary": {
+ "base64": "anHlFVy/XbIDENbKPUVf5OgPv2fkt3JBxYAUGTStAj4=",
+ "subType": "0"
+ }
+ }
+ })");
+
+ auto swDoc = ECCCollection::decryptDocument(twiceValue, doc);
+
+ ASSERT_OK(swDoc.getStatus());
+ ASSERT(swDoc.getValue().valueType == ECCValueType::kNormal);
+ ASSERT_EQ(swDoc.getValue().start, 123456789);
+ ASSERT_EQ(swDoc.getValue().end, 123456789);
+}
TEST(FLE_ESC, RoundTrip) {
TestKeyVault keyVault;
@@ -1000,9 +1095,7 @@ TEST(FLE_EDC, ServerSide_Payloads) {
EncryptedStateCollectionTokens(escDataCounterkey, eccDataCounterkey).serialize(ecocToken);
uassertStatusOK(swEncryptedTokens);
iupayload.setEncryptedTokens(swEncryptedTokens.getValue());
-
- std::vector<uint8_t> cipherText = {0x1, 0x2, 0x3, 0x4, 0x5};
- iupayload.setValue(cipherText);
+ iupayload.setValue(value);
iupayload.setType(element.type());
FLE2IndexedEqualityEncryptedValue serverPayload(iupayload, 123456);
@@ -1020,7 +1113,10 @@ TEST(FLE_EDC, ServerSide_Payloads) {
ASSERT_EQ(sp.ecc, serverPayload.ecc);
ASSERT_EQ(sp.count, serverPayload.count);
ASSERT(sp.clientEncryptedValue == serverPayload.clientEncryptedValue);
- ASSERT(cipherText == serverPayload.clientEncryptedValue);
+ ASSERT_EQ(serverPayload.clientEncryptedValue.size(), value.length());
+ ASSERT(std::equal(serverPayload.clientEncryptedValue.begin(),
+ serverPayload.clientEncryptedValue.end(),
+ value.data<uint8_t>()));
}
TEST(FLE_EDC, DuplicateSafeContent_CompatibleType) {