0
0
mirror of https://github.com/mongodb/mongo.git synced 2024-11-24 00:17:37 +01:00

SERVER-97041 Remove ECC Tokens (#29127)

GitOrigin-RevId: 92835988d5c0da10b06d97a1490202f40690326b
This commit is contained in:
Joshua Siegel 2024-11-19 12:19:53 -06:00 committed by MongoDB Bot
parent 44cb5319fc
commit ef5e7f785b
16 changed files with 15 additions and 558 deletions

View File

@ -36,7 +36,5 @@ assert.eq(ef.ecocCollection, "enxcol_.basic.ecoc");
assert.commandFailedWithCode(
db.adminCommand({shardCollection: 'shard_state.enxcol_.basic.esc', key: {_id: 1}}), 6464401);
assert.commandFailedWithCode(
db.adminCommand({shardCollection: 'shard_state.enxcol_.basic.ecc', key: {_id: 1}}), 6464401);
assert.commandFailedWithCode(
db.adminCommand({shardCollection: 'shard_state.enxcol_.basic.ecoc', key: {_id: 1}}), 6464401);

View File

@ -18,7 +18,6 @@ export const denylistedNamespaces = [
// TODO SERVER-84406 create a new list for the case unsplittable collection. The
// below nss should now be allowed in case of unsplittable.
/enxcol_\..*\.esc/,
/enxcol_\..*\.ecc/,
/enxcol_\..*\.ecoc/,
];

View File

@ -108,10 +108,8 @@ const testCases = [
]
}
}));
// Explicitly create dummy instances of the ecc and ecoc.compact collections
// Explicitly create dummy instances of the ecoc.compact collection
encryptedClient.runEncryptionOperation(() => {
assert.commandWorked(
encryptedClient.getDB().createCollection("enxcol_.testColl.ecc"));
assert.commandWorked(
encryptedClient.getDB().createCollection("enxcol_.testColl.ecoc.compact"));
});
@ -120,7 +118,6 @@ const testCases = [
{nsToMove: "testDbWithFLE.enxcol_.testColl.esc"},
{nsToMove: "testDbWithFLE.enxcol_.testColl.ecoc"},
{nsToMove: "testDbWithFLE.enxcol_.testColl.ecoc.compact"},
{nsToMove: "testDbWithFLE.enxcol_.testColl.ecc"}
]
},
{

View File

@ -72,7 +72,6 @@ export function ValidationTest(conn, _dbName) {
{dbName: dbName, collName: "system.profile"},
// Cannot analyze a shard key or queries for an FLE state collection.
{dbName: dbName, collName: "enxcol_.basic.esc"},
{dbName: dbName, collName: "enxcol_.basic.ecc"},
{dbName: dbName, collName: "enxcol_.basic.ecoc"},
// Cannot analyze a shard key or queries for a collection with FLE enabled.
{dbName: dbName, collName: "testFLEColl"},

View File

@ -143,15 +143,12 @@ constexpr uint64_t kLevelServerDataEncryption = 3;
constexpr uint64_t kEDC = 1;
constexpr uint64_t kESC = 2;
constexpr uint64_t kECC = 3;
constexpr uint64_t kECOC = 4;
constexpr uint64_t kTwiceDerivedTokenFromEDC = 1;
constexpr uint64_t kTwiceDerivedTokenFromESCTag = 1;
constexpr uint64_t kTwiceDerivedTokenFromESCValue = 2;
constexpr uint64_t kTwiceDerivedTokenFromECCTag = 1;
constexpr uint64_t kTwiceDerivedTokenFromECCValue = 2;
constexpr uint64_t kServerCountAndContentionFactorEncryption = 1;
constexpr uint64_t kServerZerosEncryption = 2;
@ -165,10 +162,6 @@ constexpr uint64_t kAnchorPaddingValueToken = 2;
constexpr int32_t kEncryptionInformationSchemaVersion = 1;
constexpr auto kECCNullId = 0;
constexpr auto kECCNonNullId = 1;
constexpr uint64_t kECCompactionRecordValue = std::numeric_limits<uint64_t>::max();
constexpr uint64_t kESCNullId = 0;
constexpr uint64_t kESCNonNullId = 1;
@ -1958,10 +1951,6 @@ ESCToken FLECollectionTokenGenerator::generateESCToken(CollectionsLevel1Token to
return FLEUtil::prf(token.data, kESC);
}
ECCToken FLECollectionTokenGenerator::generateECCToken(CollectionsLevel1Token token) {
return FLEUtil::prf(token.data, kECC);
}
ECOCToken FLECollectionTokenGenerator::generateECOCToken(CollectionsLevel1Token token) {
return FLEUtil::prf(token.data, kECOC);
}
@ -1977,11 +1966,6 @@ ESCDerivedFromDataToken FLEDerivedFromDataTokenGenerator::generateESCDerivedFrom
return FLEUtil::prf(token.data, value);
}
ECCDerivedFromDataToken FLEDerivedFromDataTokenGenerator::generateECCDerivedFromDataToken(
ECCToken token, ConstDataRange value) {
return FLEUtil::prf(token.data, value);
}
ServerDerivedFromDataToken FLEDerivedFromDataTokenGenerator::generateServerDerivedFromDataToken(
ServerTokenDerivationLevel1Token token, ConstDataRange value) {
return FLEUtil::prf(token.data, value);
@ -2001,14 +1985,6 @@ FLEDerivedFromDataTokenAndContentionFactorTokenGenerator::
return FLEUtil::prf(token.data, counter);
}
ECCDerivedFromDataTokenAndContentionFactorToken
FLEDerivedFromDataTokenAndContentionFactorTokenGenerator::
generateECCDerivedFromDataTokenAndContentionFactorToken(ECCDerivedFromDataToken token,
FLECounter counter) {
return FLEUtil::prf(token.data, counter);
}
EDCTwiceDerivedToken FLETwiceDerivedTokenGenerator::generateEDCTwiceDerivedToken(
EDCDerivedFromDataTokenAndContentionFactorToken token) {
return FLEUtil::prf(token.data, kTwiceDerivedTokenFromEDC);
@ -2024,16 +2000,6 @@ ESCTwiceDerivedValueToken FLETwiceDerivedTokenGenerator::generateESCTwiceDerived
return FLEUtil::prf(token.data, kTwiceDerivedTokenFromESCValue);
}
ECCTwiceDerivedTagToken FLETwiceDerivedTokenGenerator::generateECCTwiceDerivedTagToken(
ECCDerivedFromDataTokenAndContentionFactorToken token) {
return FLEUtil::prf(token.data, kTwiceDerivedTokenFromECCTag);
}
ECCTwiceDerivedValueToken FLETwiceDerivedTokenGenerator::generateECCTwiceDerivedValueToken(
ECCDerivedFromDataTokenAndContentionFactorToken token) {
return FLEUtil::prf(token.data, kTwiceDerivedTokenFromECCValue);
}
ServerCountAndContentionFactorEncryptionToken
FLEServerMetadataEncryptionTokenGenerator::generateServerCountAndContentionFactorEncryptionToken(
ServerDerivedFromDataToken token) {
@ -2071,12 +2037,12 @@ StatusWith<EncryptedStateCollectionTokens> EncryptedStateCollectionTokens::decry
auto value = swUnpack.getValue();
return EncryptedStateCollectionTokens{
ESCDerivedFromDataTokenAndContentionFactorToken(std::get<0>(value)),
ECCDerivedFromDataTokenAndContentionFactorToken(std::get<1>(value))};
ESCDerivedFromDataTokenAndContentionFactorToken(std::get<0>(value))};
}
StatusWith<std::vector<uint8_t>> EncryptedStateCollectionTokens::serialize(ECOCToken token) {
return packAndEncrypt(std::tie(esc.data, ecc.data), token);
constexpr uint64_t dummy{0};
return packAndEncrypt(std::tie(esc.data, dummy), token);
}
StateCollectionTokensV2 StateCollectionTokensV2::Encrypted::decrypt(const ECOCToken& token) const
@ -2724,104 +2690,6 @@ std::vector<std::vector<FLEEdgeCountInfo>> ESCCollection::getTags(
return countInfoSets;
}
PrfBlock ECCCollection::generateId(ECCTwiceDerivedTagToken tagToken,
boost::optional<uint64_t> index) {
if (index.has_value()) {
return prf(tagToken.data, kECCNonNullId, index.value());
} else {
return prf(tagToken.data, kECCNullId, 0);
}
}
BSONObj ECCCollection::generateNullDocument(ECCTwiceDerivedTagToken tagToken,
ECCTwiceDerivedValueToken valueToken,
uint64_t count) {
auto block = ECCCollection::generateId(tagToken, boost::none);
auto swCipherText = packAndEncrypt(std::tie(count, count), valueToken);
uassertStatusOK(swCipherText);
BSONObjBuilder builder;
toBinData(kId, block, &builder);
toBinData(kValue, swCipherText.getValue(), &builder);
#ifdef FLE2_DEBUG_STATE_COLLECTIONS
builder.append(kDebugId, "NULL DOC");
builder.append(kDebugValueCount, static_cast<int64_t>(count));
#endif
return builder.obj();
}
BSONObj ECCCollection::generateDocument(ECCTwiceDerivedTagToken tagToken,
ECCTwiceDerivedValueToken valueToken,
uint64_t index,
uint64_t start,
uint64_t end) {
auto block = ECCCollection::generateId(tagToken, index);
auto swCipherText = packAndEncrypt(std::tie(start, end), valueToken);
uassertStatusOK(swCipherText);
BSONObjBuilder builder;
toBinData(kId, block, &builder);
toBinData(kValue, swCipherText.getValue(), &builder);
#ifdef FLE2_DEBUG_STATE_COLLECTIONS
builder.append(kDebugId, static_cast<int64_t>(index));
builder.append(kDebugValueStart, static_cast<int64_t>(start));
builder.append(kDebugValueEnd, static_cast<int64_t>(end));
#endif
return builder.obj();
}
BSONObj ECCCollection::generateDocument(ECCTwiceDerivedTagToken tagToken,
ECCTwiceDerivedValueToken valueToken,
uint64_t index,
uint64_t count) {
return generateDocument(tagToken, valueToken, index, count, count);
}
BSONObj ECCCollection::generateCompactionDocument(ECCTwiceDerivedTagToken tagToken,
ECCTwiceDerivedValueToken valueToken,
uint64_t index) {
auto block = ECCCollection::generateId(tagToken, index);
auto swCipherText =
packAndEncrypt(std::tie(kECCompactionRecordValue, kECCompactionRecordValue), valueToken);
uassertStatusOK(swCipherText);
BSONObjBuilder builder;
toBinData(kId, block, &builder);
toBinData(kValue, swCipherText.getValue(), &builder);
#ifdef FLE2_DEBUG_STATE_COLLECTIONS
builder.append(kDebugId, static_cast<int64_t>(index));
builder.append(kDebugValueStart, static_cast<int64_t>(kECCompactionRecordValue));
builder.append(kDebugValueEnd, static_cast<int64_t>(kECCompactionRecordValue));
#endif
return builder.obj();
}
StatusWith<ECCNullDocument> ECCCollection::decryptNullDocument(ECCTwiceDerivedValueToken valueToken,
const BSONObj& doc) {
BSONElement encryptedValue;
auto status = bsonExtractTypedField(doc, kValue, BinData, &encryptedValue);
if (!status.isOK()) {
return status;
}
auto swUnpack = decryptAndUnpack<uint64_t, uint64_t>(binDataToCDR(encryptedValue), valueToken);
if (!swUnpack.isOK()) {
return swUnpack.getStatus();
}
auto& value = swUnpack.getValue();
return ECCNullDocument{std::get<0>(value)};
}
FLE2FindEqualityPayloadV2 FLEClientCrypto::serializeFindPayloadV2(FLEIndexKeyAndId indexKey,
FLEUserKeyAndId userKey,
@ -2918,36 +2786,6 @@ FLE2FindRangePayloadV2 FLEClientCrypto::serializeFindRangeStubV2(const FLE2Range
return payload;
}
StatusWith<ECCDocument> ECCCollection::decryptDocument(ECCTwiceDerivedValueToken valueToken,
const BSONObj& doc) {
BSONElement encryptedValue;
auto status = bsonExtractTypedField(doc, kValue, BinData, &encryptedValue);
if (!status.isOK()) {
return status;
}
auto swUnpack = decryptAndUnpack<uint64_t, uint64_t>(binDataToCDR(encryptedValue), valueToken);
if (!swUnpack.isOK()) {
return swUnpack.getStatus();
}
auto& value = swUnpack.getValue();
return ECCDocument{std::get<0>(value) != kECCompactionRecordValue
? ECCValueType::kNormal
: ECCValueType::kCompactionPlaceholder,
std::get<0>(value),
std::get<1>(value)};
}
boost::optional<uint64_t> ECCCollection::emuBinary(const FLEStateCollectionReader& reader,
ECCTwiceDerivedTagToken tagToken,
ECCTwiceDerivedValueToken valueToken) {
return emuBinaryCommon<ECCCollection, ECCTwiceDerivedTagToken, ECCTwiceDerivedValueToken>(
reader, tagToken, valueToken);
}
ECOCCompactionDocumentV2 ECOCCompactionDocumentV2::parseAndDecrypt(const BSONObj& doc,
const ECOCToken& token) {
IDLParserContext ctx("root");
@ -4533,14 +4371,6 @@ PrfBlock FLEUtil::prf(ConstDataRange key, uint64_t value) {
return prf(key, bufValue);
}
void FLEUtil::checkEFCForECC(const EncryptedFieldConfig& efc) {
uassert(7568300,
str::stream()
<< "Queryable Encryption version 2 collections must not contain the eccCollection"
<< " in EncryptedFieldConfig",
!efc.getEccCollection());
}
StatusWith<std::vector<uint8_t>> FLEUtil::decryptData(ConstDataRange key,
ConstDataRange cipherText) {
auto plainTextLength = fle2GetPlainTextLength(cipherText.length());

View File

@ -110,11 +110,6 @@ public:
*/
static ESCToken generateESCToken(CollectionsLevel1Token token);
/**
* ECCToken = HMAC(CollectionsLevel1Token, 3) = K^{ecc}_f
*/
static ECCToken generateECCToken(CollectionsLevel1Token token);
/**
* ECOCToken = HMAC(CollectionsLevel1Token, 4) = K^{ecoc}_f
*/
@ -139,12 +134,6 @@ public:
static ESCDerivedFromDataToken generateESCDerivedFromDataToken(ESCToken token,
ConstDataRange value);
/**
* ECCDerivedFromDataToken = HMAC(ECCToken, v) = K^{ecc}_{f,v}
*/
static ECCDerivedFromDataToken generateECCDerivedFromDataToken(ECCToken token,
ConstDataRange value);
/**
* ServerDerivedFromDataToken = HMAC(ServerTokenDerivationLevel1Token, v)
*/
@ -170,13 +159,6 @@ public:
static ESCDerivedFromDataTokenAndContentionFactorToken
generateESCDerivedFromDataTokenAndContentionFactorToken(ESCDerivedFromDataToken token,
FLECounter counter);
/**
* ECCDerivedFromDataTokenAndContentionFactorToken = HMAC(ECCDerivedFromDataToken, u)
*/
static ECCDerivedFromDataTokenAndContentionFactorToken
generateECCDerivedFromDataTokenAndContentionFactorToken(ECCDerivedFromDataToken token,
FLECounter counter);
};
/**
@ -201,18 +183,6 @@ public:
*/
static ESCTwiceDerivedValueToken generateESCTwiceDerivedValueToken(
ESCDerivedFromDataTokenAndContentionFactorToken token);
/**
* ECCTwiceDerivedTagToken = HMAC(ECCDerivedFromDataTokenAndContentionFactorToken, 1)
*/
static ECCTwiceDerivedTagToken generateECCTwiceDerivedTagToken(
ECCDerivedFromDataTokenAndContentionFactorToken token);
/**
* ECCTwiceDerivedValueToken = HMAC(ECCDerivedFromDataTokenAndContentionFactorToken, 2)
*/
static ECCTwiceDerivedValueToken generateECCTwiceDerivedValueToken(
ECCDerivedFromDataTokenAndContentionFactorToken token);
};
/**
@ -636,169 +606,6 @@ public:
uint64_t apos);
};
/**
* ECC Collection
* - a record of deleted documents
*
* {
* _id : HMAC(ECCTwiceDerivedTagToken, type || pos )
* value : Encrypt(ECCTwiceDerivedValueToken, (count || count) OR (start || end))
* }
*
* where
* type = uint64_t
* pos = uint64_t
* value is either:
* count, count = uint64_t // Null records
* OR
* start = uint64_t // Other records
* end = uint64_t
*
* where type:
* 0 - null record
* 1 - regular record or compaction record
*
* where start and end:
* [1..UINT_64_MAX) - regular start and end
* UINT64_MAX - compaction placeholder
*
* Record types:
*
* Document Counts
* Null: 0 or 1
* Regular: 0 or more
* Compaction: 0 or 1
*
* Null record:
* {
* _id : HMAC(ECCTwiceDerivedTagToken, null )
* value : Encrypt(ECCTwiceDerivedValueToken, count || count)
* }
*
* Regular record:
* {
* _id : HMAC(ECCTwiceDerivedTagToken, pos )
* value : Encrypt(ECCTwiceDerivedValueToken, start || end)
* }
*
* Compaction placeholder record:
* {
* _id : HMAC(ECCTwiceDerivedTagToken, pos )
* value : Encrypt(ECCTwiceDerivedValueToken, UINT64_MAX || UINT64_MAX)
* }
*
* PlainText of tag
* struct {
* uint64_t type;
* uint64_t pos;
* }
*
* PlainText of value for null records
* struct {
* uint64_t count;
* uint64_t ignored;
* }
*
* PlainText of value for non-null records
* struct {
* uint64_t start;
* uint64_t end;
* }
*/
enum class ECCValueType : uint64_t {
kNormal = 0,
kCompactionPlaceholder = 1,
};
struct ECCNullDocument {
// Id is not included as it HMAC generated and cannot be reversed
uint64_t position;
};
struct ECCDocument {
// Id is not included as it HMAC generated and cannot be reversed
ECCValueType valueType;
uint64_t start;
uint64_t end;
};
inline bool operator==(const ECCDocument& left, const ECCDocument& right) {
return (left.valueType == right.valueType && left.start == right.start &&
left.end == right.end);
}
inline bool operator<(const ECCDocument& left, const ECCDocument& right) {
if (left.start == right.start) {
if (left.end == right.end) {
return left.valueType < right.valueType;
}
return left.end < right.end;
}
return left.start < right.start;
}
class ECCCollection {
public:
/**
* Generate the _id value
*/
static PrfBlock generateId(ECCTwiceDerivedTagToken tagToken, boost::optional<uint64_t> index);
/**
* Generate a null document which will be the "first" document for a given field.
*/
static BSONObj generateNullDocument(ECCTwiceDerivedTagToken tagToken,
ECCTwiceDerivedValueToken valueToken,
uint64_t count);
/**
* Generate a regular ECC document for (count).
*
* Note: it is stored as (count, count)
*/
static BSONObj generateDocument(ECCTwiceDerivedTagToken tagToken,
ECCTwiceDerivedValueToken valueToken,
uint64_t index,
uint64_t count);
/**
* Generate a regular ECC document for (start, end)
*/
static BSONObj generateDocument(ECCTwiceDerivedTagToken tagToken,
ECCTwiceDerivedValueToken valueToken,
uint64_t index,
uint64_t start,
uint64_t end);
/**
* Generate a compaction ECC document.
*/
static BSONObj generateCompactionDocument(ECCTwiceDerivedTagToken tagToken,
ECCTwiceDerivedValueToken valueToken,
uint64_t index);
/**
* Decrypt the null document.
*/
static StatusWith<ECCNullDocument> decryptNullDocument(ECCTwiceDerivedValueToken valueToken,
const BSONObj& doc);
/**
* Decrypt a regular document.
*/
static StatusWith<ECCDocument> decryptDocument(ECCTwiceDerivedValueToken valueToken,
const BSONObj& doc);
/**
* Search for the highest document id for a given field/value pair based on the token.
*/
static boost::optional<uint64_t> emuBinary(const FLEStateCollectionReader& reader,
ECCTwiceDerivedTagToken tagToken,
ECCTwiceDerivedValueToken valueToken);
};
/**
* Type safe abstraction over the key vault to support unit testing. Used by the various decryption
* routines to retrieve the correct keys.
@ -866,10 +673,8 @@ public:
* {
* d : EDCDerivedFromDataTokenAndContentionFactorToken
* s : ESCDerivedFromDataTokenAndContentionFactorToken
* c : ECCDerivedFromDataTokenAndContentionFactorToken
* p : Encrypt(ECOCToken, ESCDerivedFromDataTokenAndContentionFactorToken ||
* ECCDerivedFromDataTokenAndContentionFactorToken) v : Encrypt(K_KeyId, value),
* e : ServerDataEncryptionLevel1Token,
* p : Encrypt(ECOCToken, ESCDerivedFromDataTokenAndContentionFactorToken) v :
* Encrypt(K_KeyId, value), e : ServerDataEncryptionLevel1Token,
* }
*/
static BSONObj transformPlaceholders(const BSONObj& obj, FLEKeyVault* keyVault);
@ -907,26 +712,21 @@ public:
/*
* Values of ECOC documents
*
* Encrypt(ECOCToken, ESCDerivedFromDataTokenAndContentionFactorToken ||
* ECCDerivedFromDataTokenAndContentionFactorToken)
* Encrypt(ECOCToken, ESCDerivedFromDataTokenAndContentionFactorToken)
*
* struct {
* uint8_t[32] esc;
* uint8_t[32] ecc;
* }
*/
struct EncryptedStateCollectionTokens {
public:
EncryptedStateCollectionTokens(ESCDerivedFromDataTokenAndContentionFactorToken s,
ECCDerivedFromDataTokenAndContentionFactorToken c)
: esc(s), ecc(c) {}
EncryptedStateCollectionTokens(ESCDerivedFromDataTokenAndContentionFactorToken s) : esc(s) {}
static StatusWith<EncryptedStateCollectionTokens> decryptAndParse(ECOCToken token,
ConstDataRange cdr);
StatusWith<std::vector<uint8_t>> serialize(ECOCToken token);
ESCDerivedFromDataTokenAndContentionFactorToken esc;
ECCDerivedFromDataTokenAndContentionFactorToken ecc;
};
struct ECOCCompactionDocumentV2 {
@ -1124,7 +924,6 @@ struct FLE2UnindexedEncryptedValueV2 {
struct FLEEdgeToken {
EDCDerivedFromDataTokenAndContentionFactorToken edc;
ESCDerivedFromDataTokenAndContentionFactorToken esc;
ECCDerivedFromDataTokenAndContentionFactorToken ecc;
};
/**
@ -1353,7 +1152,7 @@ public:
const BSONObj& encryptedFields);
/**
* Get a schema from EncryptionInformation and ensure the esc/ecc/ecoc are setup correctly.
* Get a schema from EncryptionInformation and ensure the esc/ecoc are setup correctly.
*/
static EncryptedFieldConfig getAndValidateSchema(const NamespaceString& nss,
const EncryptionInformation& ei);
@ -1557,8 +1356,6 @@ public:
static PrfBlock prf(ConstDataRange key, uint64_t value);
static void checkEFCForECC(const EncryptedFieldConfig& efc);
/**
* Decrypt AES-256-CTR encrypted data. Exposed for benchmarking purposes.
*/

View File

@ -276,10 +276,6 @@ TEST(FLETokens, TestVectors) {
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));
@ -303,12 +299,6 @@ TEST(FLETokens, TestVectors) {
"DE6A1AC292BC62094C33E94647B044B9B10514317B75F4128DDA2E0FB686704F"_sd)),
escDataToken);
auto eccDataToken =
FLEDerivedFromDataTokenGenerator::generateECCDerivedFromDataToken(eccToken, sampleValue);
ASSERT_EQUALS(ECCDerivedFromDataToken(decodePrf(
"9A95D4F44734447E3F0266D1629513A0B7698CCE8C1524F329CE7970627FFD06"_sd)),
eccDataToken);
ASSERT_EQUALS(ServerCountAndContentionFactorEncryptionToken(decodePrf(
"2F30DBCC06B722B60BC1FF018FC28D5FAEE2F222496BE34A264EF3267E811DA0"_sd)),
FLEServerMetadataEncryptionTokenGenerator::
@ -333,14 +323,6 @@ TEST(FLETokens, TestVectors) {
"8AAF04CBA6DC16BFB37CADBA43DCA66C183634CB3DA278DE174556AE6E17CEBB"_sd)),
escDataCounterToken);
auto eccDataCounterToken = FLEDerivedFromDataTokenAndContentionFactorTokenGenerator::
generateECCDerivedFromDataTokenAndContentionFactorToken(eccDataToken, counter);
ASSERT_EQUALS(ECCDerivedFromDataTokenAndContentionFactorToken(decodePrf(
"E9580F805E0D07AF384EBA185384F28A49C3DB93AFA4A187A1F4DA129271D82C"_sd)),
eccDataCounterToken);
// Level 5
auto edcTwiceToken =
FLETwiceDerivedTokenGenerator::generateEDCTwiceDerivedToken(edcDataCounterToken);
@ -359,19 +341,6 @@ TEST(FLETokens, TestVectors) {
"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);
// Anchor Padding
auto anchorPaddingTokenRoot =
FLEAnchorPaddingGenerator::generateAnchorPaddingRootToken(escToken);
@ -443,35 +412,6 @@ TEST(FLETokens, TestVectorESCCollectionDecryptDocument) {
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;
@ -550,61 +490,6 @@ TEST(FLE_ESC, RoundTrip) {
}
}
TEST(FLE_ECC, RoundTrip) {
TestKeyVault keyVault;
ConstDataRange value(testValue);
auto c1 = FLELevel1TokenGenerator::generateCollectionsLevel1Token(getIndexKey());
auto token = FLECollectionTokenGenerator::generateECCToken(c1);
ECCDerivedFromDataToken datakey =
FLEDerivedFromDataTokenGenerator::generateECCDerivedFromDataToken(token, value);
ECCDerivedFromDataTokenAndContentionFactorToken dataCounterkey =
FLEDerivedFromDataTokenAndContentionFactorTokenGenerator::
generateECCDerivedFromDataTokenAndContentionFactorToken(datakey, 0);
auto twiceTag = FLETwiceDerivedTokenGenerator::generateECCTwiceDerivedTagToken(dataCounterkey);
auto twiceValue =
FLETwiceDerivedTokenGenerator::generateECCTwiceDerivedValueToken(dataCounterkey);
{
BSONObj doc = ECCCollection::generateNullDocument(twiceTag, twiceValue, 123456789);
auto swDoc = ECCCollection::decryptNullDocument(twiceValue, doc);
ASSERT_OK(swDoc.getStatus());
ASSERT_EQ(swDoc.getValue().position, 123456789);
}
{
BSONObj doc = ECCCollection::generateDocument(twiceTag, twiceValue, 123, 123456789);
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);
}
{
BSONObj doc =
ECCCollection::generateDocument(twiceTag, twiceValue, 123, 123456789, 983456789);
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, 983456789);
}
{
BSONObj doc = ECCCollection::generateCompactionDocument(twiceTag, twiceValue, 123456789);
auto swDoc = ECCCollection::decryptDocument(twiceValue, doc);
ASSERT_OK(swDoc.getStatus());
ASSERT(swDoc.getValue().valueType == ECCValueType::kCompactionPlaceholder);
}
}
class TestDocumentCollection : public FLEStateCollectionReader {
public:
void insert(BSONObj& obj) {
@ -2324,7 +2209,6 @@ EncryptedFieldConfig getTestEncryptedFieldConfig() {
constexpr auto schema = R"({
"escCollection": "enxcol_.coll.esc",
"eccCollection": "enxcol_.coll.ecc",
"ecocCollection": "enxcol_.coll.ecoc",
"fields": [
{
@ -2401,13 +2285,6 @@ TEST(EncryptionInformation, MissingStateCollection) {
DBException,
6371207);
}
{
EncryptedFieldConfig efc = getTestEncryptedFieldConfig();
efc.setEccCollection(boost::none);
auto obj = EncryptionInformationHelpers::encryptionInformationSerialize(ns, efc);
ASSERT_DOES_NOT_THROW(EncryptionInformationHelpers::getAndValidateSchema(
ns, EncryptionInformation::parse(IDLParserContext("foo"), obj)));
}
{
EncryptedFieldConfig efc = getTestEncryptedFieldConfig();
efc.setEcocCollection(boost::none);
@ -2985,16 +2862,6 @@ TEST(CompactionHelpersTest, validateCompactionTokensTest) {
CompactionHelpers::validateCompactionTokens(efc, builder.obj());
}
std::vector<ECCDocument> pairsToECCDocuments(
const std::vector<std::pair<uint64_t, uint64_t>>& pairs) {
std::vector<ECCDocument> output;
std::transform(pairs.begin(), pairs.end(), std::back_inserter(output), [](auto& pair) {
return ECCDocument{ECCValueType::kNormal, pair.first, pair.second};
});
return output;
}
TEST(EDCServerCollectionTest, GenerateEDCTokens) {
auto doc = BSON("sample" << 123456);

View File

@ -44,7 +44,7 @@ structs:
default: 0
ECStats:
description: "Stats about records in ECC & ESC compact touched"
description: "Stats about records in ESC compact touched"
fields:
read:
type: exactInt64

View File

@ -55,25 +55,19 @@ using PrfBlock = std::array<std::uint8_t, 32>;
*
* EDCToken = HMAC(CollectionsLevel1Token, 1) = K^{edc}_f = Fs[f,1,1]
* ESCToken = HMAC(CollectionsLevel1Token, 2) = K^{esc}_f = Fs[f,1,2]
* ECCToken = HMAC(CollectionsLevel1Token, 3) = K^{ecc}_f = Fs[f,1,3]
* ECOCToken = HMAC(CollectionsLevel1Token, 4) = K^{ecoc}_f = Fs[f,1,4]
*
* EDCDerivedFromDataToken = HMAC(EDCToken, v) = K^{edc}_{f,v} = Fs[f,1,1,v]
* ESCDerivedFromDataToken = HMAC(ESCToken, v) = K^{esc}_{f,v} = Fs[f,1,2,v]
* ECCDerivedFromDataToken = HMAC(ECCToken, v) = K^{ecc}_{f,v} = Fs[f,1,3,v]
*
* EDCDerivedFromDataTokenAndContentionFactorToken = HMAC(EDCDerivedFromDataToken, u) =
* Fs[f,1,1,v,u]
* ESCDerivedFromDataTokenAndContentionFactorToken = HMAC(ESCDerivedFromDataToken, u) =
* Fs[f,1,2,v,u]
* ECCDerivedFromDataTokenAndContentionFactorToken = HMAC(ECCDerivedFromDataToken, u) =
* Fs[f,1,3,v,u]
*
* EDCTwiceDerivedToken = HMAC(EDCDerivedFromDataTokenAndContentionFactorToken, 1) = Fs_edc(1)
* ESCTwiceDerivedTagToken = HMAC(ESCDerivedFromDataTokenAndContentionFactorToken, 1) = Fs_esc(1)
* ESCTwiceDerivedValueToken = HMAC(ESCDerivedFromDataTokenAndContentionFactorToken, 2) = Fs_esc(2)
* ECCTwiceDerivedTagToken = HMAC(ECCDerivedFromDataTokenAndContentionFactorToken, 1) = Fs_ecc(1)
* ECCTwiceDerivedValueToken = HMAC(ECCDerivedFromDataTokenAndContentionFactorToken, 2) = Fs_ecc(2)
*
* ServerTokenDerivationLevel1Token = HMAC(IndexKey, 2) = K_{f,2}
* ServerDerivedFromDataToken = HMAC(ServerTokenDerivationLevel1Token, v) = K_{f,2,v} = Fs[f,2,v]
@ -92,22 +86,17 @@ enum class FLETokenType {
EDCToken,
ESCToken,
ECCToken,
ECOCToken,
EDCDerivedFromDataToken,
ESCDerivedFromDataToken,
ECCDerivedFromDataToken,
EDCDerivedFromDataTokenAndContentionFactorToken,
ESCDerivedFromDataTokenAndContentionFactorToken,
ECCDerivedFromDataTokenAndContentionFactorToken,
EDCTwiceDerivedToken,
ESCTwiceDerivedTagToken,
ESCTwiceDerivedValueToken,
ECCTwiceDerivedTagToken,
ECCTwiceDerivedValueToken,
// v2 tokens
ServerTokenDerivationLevel1Token,
@ -164,22 +153,16 @@ using CollectionsLevel1Token = FLEToken<FLETokenType::CollectionsLevel1Token>;
using ServerDataEncryptionLevel1Token = FLEToken<FLETokenType::ServerDataEncryptionLevel1Token>;
using EDCToken = FLEToken<FLETokenType::EDCToken>;
using ESCToken = FLEToken<FLETokenType::ESCToken>;
using ECCToken = FLEToken<FLETokenType::ECCToken>;
using ECOCToken = FLEToken<FLETokenType::ECOCToken>;
using EDCDerivedFromDataToken = FLEToken<FLETokenType::EDCDerivedFromDataToken>;
using ESCDerivedFromDataToken = FLEToken<FLETokenType::ESCDerivedFromDataToken>;
using ECCDerivedFromDataToken = FLEToken<FLETokenType::ECCDerivedFromDataToken>;
using EDCDerivedFromDataTokenAndContentionFactorToken =
FLEToken<FLETokenType::EDCDerivedFromDataTokenAndContentionFactorToken>;
using ESCDerivedFromDataTokenAndContentionFactorToken =
FLEToken<FLETokenType::ESCDerivedFromDataTokenAndContentionFactorToken>;
using ECCDerivedFromDataTokenAndContentionFactorToken =
FLEToken<FLETokenType::ECCDerivedFromDataTokenAndContentionFactorToken>;
using EDCTwiceDerivedToken = FLEToken<FLETokenType::EDCTwiceDerivedToken>;
using ESCTwiceDerivedTagToken = FLEToken<FLETokenType::ESCTwiceDerivedTagToken>;
using ESCTwiceDerivedValueToken = FLEToken<FLETokenType::ESCTwiceDerivedValueToken>;
using ECCTwiceDerivedTagToken = FLEToken<FLETokenType::ECCTwiceDerivedTagToken>;
using ECCTwiceDerivedValueToken = FLEToken<FLETokenType::ECCTwiceDerivedValueToken>;
using ServerTokenDerivationLevel1Token = FLEToken<FLETokenType::ServerTokenDerivationLevel1Token>;
using ServerDerivedFromDataToken = FLEToken<FLETokenType::ServerDerivedFromDataToken>;

View File

@ -358,9 +358,6 @@ public:
"type rangePreview, as it is deprecated",
!hasQueryType(cmd.getEncryptedFields().get(),
QueryTypeEnum::RangePreviewDeprecated));
FLEUtil::checkEFCForECC(cmd.getEncryptedFields().get());
}
if (auto timeseries = cmd.getTimeseries()) {

View File

@ -207,7 +207,7 @@ CompactStats compactEncryptedCompactionCollection(OperationContext* opCtx,
}
// Step 2: for each encrypted field in compactionTokens, get distinct set of entries 'C'
// from ECOC, and for each entry in 'C', compact ESC and ECC.
// from ECOC, and for each entry in 'C', compact ESC.
{
// acquire IS lock on the ecocRenameNss to prevent it from being dropped during compact
AutoGetCollection tempEcocColl(opCtx, namespaces.ecocRenameNss, MODE_IS);

View File

@ -785,7 +785,6 @@ protected:
auto s = getTestESCDataToken(obj);
auto d = getTestEDCDataToken(obj);
auto nssEsc = NamespaceString::createNamespaceString_forTest("test.enxcol_.coll.esc");
auto nssEcc = NamespaceString::createNamespaceString_forTest("test.enxcol_.coll.ecc");
return mongo::fle::readTags(_queryImpl.get(), nssEsc, s, d, cm);
}
@ -1569,7 +1568,6 @@ TEST_F(FleTagsTest, InsertAndUpdate) {
TEST_F(FleTagsTest, ContentionFactor) {
auto efc = EncryptedFieldConfig::parse(IDLParserContext("root"), fromjson(R"({
"escCollection": "enxcol_.coll.esc",
"eccCollection": "enxcol_.coll.ecc",
"ecocCollection": "enxcol_.coll.ecoc",
"fields": [{
"keyId": { "$uuid": "12345678-1234-9876-1234-123456789012"},

View File

@ -52,7 +52,6 @@ constexpr auto dropPendingNSPrefix = "system.drop."_sd;
constexpr auto fle2Prefix = "enxcol_."_sd;
constexpr auto fle2EscSuffix = ".esc"_sd;
constexpr auto fle2EccSuffix = ".ecc"_sd;
constexpr auto fle2EcocSuffix = ".ecoc"_sd;
constexpr auto fle2EcocCompactSuffix = ".ecoc.compact"_sd;
@ -353,14 +352,13 @@ bool NamespaceString::isConfigTransactionsCollection() const {
bool NamespaceString::isFLE2StateCollection() const {
return coll().startsWith(fle2Prefix) &&
(coll().endsWith(fle2EscSuffix) || coll().endsWith(fle2EccSuffix) ||
coll().endsWith(fle2EcocSuffix) || coll().endsWith(fle2EcocCompactSuffix));
(coll().endsWith(fle2EscSuffix) || coll().endsWith(fle2EcocSuffix) ||
coll().endsWith(fle2EcocCompactSuffix));
}
bool NamespaceString::isFLE2StateCollection(StringData coll) {
return coll.startsWith(fle2Prefix) &&
(coll.endsWith(fle2EscSuffix) || coll.endsWith(fle2EccSuffix) ||
coll.endsWith(fle2EcocSuffix));
(coll.endsWith(fle2EscSuffix) || coll.endsWith(fle2EcocSuffix));
}
bool NamespaceString::isOplogOrChangeCollection() const {

View File

@ -568,7 +568,7 @@ public:
bool isConfigTransactionsCollection() const;
/**
* Returns whether the specified namespace is <database>.enxcol_.<.+>.(esc|ecc|ecoc).
* Returns whether the specified namespace is <database>.enxcol_.<.+>.(esc|ecoc).
*/
bool isFLE2StateCollection() const;

View File

@ -118,9 +118,6 @@ structs:
escNss:
description: "Collection containing insertions metadata"
type: namespacestring
eccNss:
description: "Collection containing deletions metadata"
type: namespacestring
ecocNss:
description: "Collection containing compaction metadata to perform compact with"
type: namespacestring

View File

@ -1670,8 +1670,6 @@ DB.prototype.createEncryptedCollection = function(name, opts) {
assert.commandWorked(
this.createCollection(ef.escCollection, {clusteredIndex: {key: {_id: 1}, unique: true}}));
assert.commandWorked(
this.createCollection(ef.eccCollection, {clusteredIndex: {key: {_id: 1}, unique: true}}));
assert.commandWorked(
this.createCollection(ef.ecocCollection, {clusteredIndex: {key: {_id: 1}, unique: true}}));
@ -1690,7 +1688,6 @@ DB.prototype.dropEncryptedCollection = function(name) {
}
this.getCollection(ef.escCollection).drop();
this.getCollection(ef.eccCollection).drop();
this.getCollection(ef.ecocCollection).drop();
return this.getCollection(name).drop();
};