summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMark Benvenuto <mark.benvenuto@mongodb.com>2022-05-05 14:53:32 -0400
committerEvergreen Agent <no-reply@evergreen.mongodb.com>2022-05-09 18:58:58 +0000
commit9707fb81cb07eee5d3fe2ae3289826b97b4d4408 (patch)
treed6495011c3b2c89661711aca2cb16ff2e7d36221
parent2cfe1b9e8e8e9038f521628847f8d0e1ca2f00bc (diff)
downloadmongo-9707fb81cb07eee5d3fe2ae3289826b97b4d4408.tar.gz
SERVER-66186 Optimize ECC null document storage
(cherry picked from commit 64ebed9cddb3a7c59c26f1d7d4035ebbf1d73cbd)
-rw-r--r--src/mongo/crypto/fle_crypto.cpp18
-rw-r--r--src/mongo/crypto/fle_crypto.h19
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