diff options
author | Mark Benvenuto <mark.benvenuto@mongodb.com> | 2022-05-05 14:53:32 -0400 |
---|---|---|
committer | Evergreen Agent <no-reply@evergreen.mongodb.com> | 2022-05-09 18:58:58 +0000 |
commit | 9707fb81cb07eee5d3fe2ae3289826b97b4d4408 (patch) | |
tree | d6495011c3b2c89661711aca2cb16ff2e7d36221 | |
parent | 2cfe1b9e8e8e9038f521628847f8d0e1ca2f00bc (diff) | |
download | mongo-9707fb81cb07eee5d3fe2ae3289826b97b4d4408.tar.gz |
SERVER-66186 Optimize ECC null document storage
(cherry picked from commit 64ebed9cddb3a7c59c26f1d7d4035ebbf1d73cbd)
-rw-r--r-- | src/mongo/crypto/fle_crypto.cpp | 18 | ||||
-rw-r--r-- | src/mongo/crypto/fle_crypto.h | 19 |
2 files changed, 14 insertions, 23 deletions
diff --git a/src/mongo/crypto/fle_crypto.cpp b/src/mongo/crypto/fle_crypto.cpp index 100ff5d06a1..002d99e3f1c 100644 --- a/src/mongo/crypto/fle_crypto.cpp +++ b/src/mongo/crypto/fle_crypto.cpp @@ -379,18 +379,6 @@ StatusWith<std::vector<uint8_t>> decryptData(ConstDataRange key, ConstDataRange return {out}; } -StatusWith<uint64_t> decryptUInt64(ConstDataRange key, ConstDataRange cipherText) { - auto swPlainText = decryptData(key, cipherText); - if (!swPlainText.isOK()) { - return swPlainText.getStatus(); - } - - ConstDataRange cdr(swPlainText.getValue()); - - return cdr.readNoThrow<LittleEndian<uint64_t>>(); -} - - template <typename T> struct FLEStoragePackTypeHelper; @@ -1627,7 +1615,7 @@ BSONObj ECCCollection::generateNullDocument(ECCTwiceDerivedTagToken tagToken, uint64_t count) { auto block = ECCCollection::generateId(tagToken, boost::none); - auto swCipherText = encryptData(valueToken.data, count); + auto swCipherText = packAndEncrypt(std::tie(count, count), valueToken); uassertStatusOK(swCipherText); BSONObjBuilder builder; @@ -1700,7 +1688,7 @@ StatusWith<ECCNullDocument> ECCCollection::decryptNullDocument(ECCTwiceDerivedVa return status; } - auto swUnpack = decryptUInt64(valueToken.data, binDataToCDR(encryptedValue)); + auto swUnpack = decryptAndUnpack<uint64_t, uint64_t>(binDataToCDR(encryptedValue), valueToken); if (!swUnpack.isOK()) { return swUnpack.getStatus(); @@ -1708,7 +1696,7 @@ StatusWith<ECCNullDocument> ECCCollection::decryptNullDocument(ECCTwiceDerivedVa auto& value = swUnpack.getValue(); - return ECCNullDocument{value}; + return ECCNullDocument{std::get<0>(value)}; } diff --git a/src/mongo/crypto/fle_crypto.h b/src/mongo/crypto/fle_crypto.h index 48d18dd5837..5d8285f5790 100644 --- a/src/mongo/crypto/fle_crypto.h +++ b/src/mongo/crypto/fle_crypto.h @@ -65,7 +65,7 @@ using FLECounter = std::uint64_t; /** * There are two types of keys that are user supplied. * 1. Index, aka S - this encrypts the index structures - * 2. User, aka K - this encrypts the user data. It can be the same as Index. + * 2. User, aka K - this encrypts the user data. * * These keys only exist on the client, they are never on the server-side. */ @@ -128,7 +128,10 @@ using FLEUserKeyAndId = FLEKeyAndId<FLEKeyType::User>; * Terminology * f = field * v = value - * u == 0 if field has no contention otherwise u = random secure sample {1, .. max contention}. + * u = + * - For non-contentious fields, we select the partition number, u, to be equal to 0. + * - For contentious fields, with a contention factor, p, we pick the partition number, u, + * uniformly at random from the set {0, ..., p}. * * CollectionsLevel1Token = HMAC(IndexKey, 1) = K_{f,1} * ServerDataEncryptionLevel1Token = HMAC(IndexKey, 3) = K_{f,3} = Fs[f,3] @@ -376,6 +379,7 @@ public: * pos = uint64_t * count_type = uint64_t * count = uint64_t + * - Note: There is a lifetime limit of 2^64 - 1 count of a value/pairs for an index * * where type * 0 - null record @@ -456,8 +460,6 @@ public: /** * Get a count of documents in the collection. - * - * TODO - how perfect does it need to be ? Is too high or too low ok if it is just an estimate? */ virtual uint64_t getDocumentCount() const = 0; @@ -537,14 +539,14 @@ public: * * { * _id : HMAC(ECCTwiceDerivedTagToken, type || pos ) - * value : Encrypt(ECCTwiceDerivedValueToken, count OR start || end) + * value : Encrypt(ECCTwiceDerivedValueToken, (count || count) OR (start || end)) * } * * where * type = uint64_t * pos = uint64_t * value is either: - * count = uint64_t // Null records + * count, count = uint64_t // Null records * OR * start = uint64_t // Other records * end = uint64_t @@ -554,7 +556,7 @@ public: * 1 - regular record or compaction record * * where start and end: - * [0..UINT_64_MAX) - regular start and end + * [1..UINT_64_MAX) - regular start and end * UINT64_MAX - compaction placeholder * * Record types: @@ -567,7 +569,7 @@ public: * Null record: * { * _id : HMAC(ECCTwiceDerivedTagToken, null ) - * value : Encrypt(ECCTwiceDerivedValueToken, count) + * value : Encrypt(ECCTwiceDerivedValueToken, count || count) * } * * Regular record: @@ -591,6 +593,7 @@ public: * PlainText of value for null records * struct { * uint64_t count; + * uint64_t ignored; * } * * PlainText of value for non-null records |