libmongocrypt
Loading...
Searching...
No Matches
mc-fle2-payload-iev-private-v2.h
1/*
2 * Copyright 2023-present MongoDB, Inc.
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17#ifndef MONGOCRYPT_INDEXED_ENCRYPTED_VALUE_PRIVATE_V2_H
18#define MONGOCRYPT_INDEXED_ENCRYPTED_VALUE_PRIVATE_V2_H
19
20#include "mc-fle2-tag-and-encrypted-metadata-block-private.h"
21#include "mc-tokens-private.h"
22#include "mongocrypt-buffer-private.h"
23#include "mongocrypt-crypto-private.h"
24#include "mongocrypt-status-private.h"
25
26/*
27 * FLE2IndexedEqualityEncryptedValueV2, FLE2IndexedRangeEncryptedValueV2, and FLEIndexedTextEncryptedValue
28 * share a common internal implementation.
29 *
30 * Lifecycle:
31 * 1. mc_FLE2IndexedEncryptedValueV2_init
32 * 2. mc_FLE2IndexedEncryptedValueV2_parse
33 * 3. mc_FLE2IndexedEncryptedValueV2_get_S_KeyId
34 * 4. mc_FLE2IndexedEncryptedValueV2_add_S_Key
35 * 5. mc_FLE2IndexedEncryptedValueV2_get_K_KeyId
36 * 6. mc_FLE2IndexedEncryptedValueV2_add_K_Key
37 * 7. mc_FLE2IndexedEncryptedValueV2_get_ClientValue
38 * 8. mc_FLE2IndexedEncryptedValueV2_serialize
39 * 9. mc_FLE2IndexedEncryptedValueV2_destroy
40 *
41 *
42 * FLE2IndexedEqualityEncryptedValueV2 has the following data layout:
43 *
44 * struct FLE2IndexedEqualityEncryptedValueV2 {
45 * uint8_t fle_blob_subtype = 14;
46 * uint8_t S_KeyId[16];
47 * uint8_t original_bson_type;
48 * uint8_t ServerEncryptedValue[ServerEncryptedValue.length];
49 * FLE2TagAndEncryptedMetadataBlock metadata;
50 * }
51 *
52 * ServerEncryptedValue :=
53 * EncryptCTR(ServerEncryptionToken, K_KeyId || ClientEncryptedValue)
54 * ClientEncryptedValue := EncryptCBCAEAD(K_Key, clientValue, AD=K_KeyId)
55 *
56 *
57 * struct FLE2TagAndEncryptedMetadataBlock {
58 * uint8_t encryptedCount[32]; // EncryptCTR(countEncryptionToken,
59 * // count || contentionFactor)
60 * uint8_t tag[32]; // HMAC-SHA256(count, edcTwiceDerived)
61 * uint8_t encryptedZeros[32]; // EncryptCTR(zerosEncryptionToken, 0*)
62 * }
63 *
64 *
65 * FLE2IndexedRangeEncryptedValueV2 has the following data layout:
66 *
67 * struct FLE2IndexedRangeEncryptedValueV2 {
68 * uint8_t fle_blob_subtype = 15;
69 * uint8_t S_KeyId[16];
70 * uint8_t original_bson_type;
71 * uint8_t edge_count;
72 * uint8_t ServerEncryptedValue[ServerEncryptedValue.length];
73 * FLE2TagAndEncryptedMetadataBlock metadata[edge_count];
74 * }
75 *
76 * Note that this format differs from FLE2IndexedEqualityEncryptedValueV2
77 * in only two ways:
78 * 1/ `edge_count` is introduced as a 8 bit int following `original_bson_type`.
79 * 2/ Rather than a single metadata block, we have {edge_count} blocks.
80 *
81 * FLE2IndexedTextEncryptedValue has the following data layout:
82 *
83 * struct FLE2IndexedTextEncryptedValue {
84 * uint8_t fle_blob_subtype = 17;
85 * uint8_t S_KeyId[16];
86 * uint8_t original_bson_type;
87 * uint32_t edge_count;
88 * uint32_t substr_tag_count;
89 * uint32_t suffix_tag_count;
90 * uint8_t ServerEncryptedValue[ServerEncryptedValue.length];
91 * FLE2TagAndEncryptedMetadataBlock exact_metadata;
92 * FLE2TagAndEncryptedMetadataBlock substr_metadata[substr_tag_count];
93 * FLE2TagAndEncryptedMetadataBlock suffix_metadata[suffix_tag_count];
94 * FLE2TagAndEncryptedMetadataBlock prefix_metadata[edge_count - suffix_tag_count - substr_tag_count - 1];
95 * }
96 * The main difference in this format is that we split `metadata` into 4
97 * sections, one for each text search index type. We expand edge_count
98 * to be a 32 bit integer rather than 8 bit. We add two 32 bit ints,
99 * `substr_tag_count` and `suffix_tag_count`, following `edge_count`
100 * in order to track the delineation of the metadata. Similarly to
101 * FLE2IndexedEqualityEncryptedValueV2, we have `edge_count` total
102 * blocks.
103 */
104
105typedef enum {
106 kFLE2IEVTypeInitV2,
107 kFLE2IEVTypeEqualityV2,
108 kFLE2IEVTypeRangeV2,
109 kFLE2IEVTypeText,
110} _mc_fle2_iev_v2_type;
111
113 // Raw payload values
114 uint8_t fle_blob_subtype;
115 uint8_t bson_value_type;
116 uint32_t edge_count;
117 uint32_t substr_tag_count;
118 uint32_t suffix_tag_count;
119 _mongocrypt_buffer_t S_KeyId;
120 _mongocrypt_buffer_t ServerEncryptedValue;
121
122 // Decode State
123 _mc_fle2_iev_v2_type type;
124 bool ClientEncryptedValueDecoded;
125 bool ClientValueDecoded;
126
127 // Populated during _add_S_Key
128 // DecryptedServerEncryptedValue := DecryptCTR(S_Key, ServerEncryptedValue)
129 _mongocrypt_buffer_t DecryptedServerEncryptedValue;
130
131 // Views on DecryptedServerEncryptedValue (DSEV)
132 _mongocrypt_buffer_t K_KeyId; // First 16 octets, UUID
133 _mongocrypt_buffer_t ClientEncryptedValue; // Remainder of DSEV
134
135 // Populated during _add_K_Key
136 // ClientValue := DecryptCBCAEAD(K_Key, ClientEncryptedValue, AD=K_KeyId)
137 _mongocrypt_buffer_t ClientValue;
138
139 mc_FLE2TagAndEncryptedMetadataBlock_t *metadata;
141
142mc_FLE2IndexedEncryptedValueV2_t *mc_FLE2IndexedEncryptedValueV2_new(void);
143bson_type_t mc_FLE2IndexedEncryptedValueV2_get_bson_value_type(const mc_FLE2IndexedEncryptedValueV2_t *iev,
144 mongocrypt_status_t *status);
145
146/*
147 * Populates an mc_FLE2IndexedEncryptedValueV2_t from a buffer.
148 *
149 * Input buffer must take the form of:
150 * fle_blob_subtype (8u)
151 * S_KeyId (8u * 16u)
152 * original_bson_type (8u)
153 * if (range)
154 * edge_count(8u)
155 * if (text)
156 * edge_count(32u)
157 * substr_tag_count(32u)
158 * suffix_tag_count(32u)
159 * ServerEncryptedValue (8u * SEV_len)
160 * metadata (96u * {range || text ? edge_count : 1u})
161 *
162 * Returns an error if the input buffer is not valid.
163 */
164bool mc_FLE2IndexedEncryptedValueV2_parse(mc_FLE2IndexedEncryptedValueV2_t *iev,
165 const _mongocrypt_buffer_t *buf,
166 mongocrypt_status_t *status);
167
168/*
169 * Serializes an mc_FLE2IndexedEncryptedValueV2_t into a buffer.
170 *
171 * The serialized output follows the same layout as the input `buf` to
172 * mc_FLE2IndexedEncryptedValueV2_parse, allowing for round-trip
173 * conversions between the serialized and parsed forms.
174 *
175 * Returns an error if the input structure is not valid, or if the buffer
176 * provided is insufficient to hold the serialized data.
177 */
178bool mc_FLE2IndexedEncryptedValueV2_serialize(const mc_FLE2IndexedEncryptedValueV2_t *iev,
179 _mongocrypt_buffer_t *buf,
180 mongocrypt_status_t *status);
181
186bool mc_FLE2IndexedEncryptedValueV2_validate(const mc_FLE2IndexedEncryptedValueV2_t *iev, mongocrypt_status_t *status);
187
188const _mongocrypt_buffer_t *mc_FLE2IndexedEncryptedValueV2_get_S_KeyId(const mc_FLE2IndexedEncryptedValueV2_t *iev,
189 mongocrypt_status_t *status);
190
191bool mc_FLE2IndexedEncryptedValueV2_add_S_Key(_mongocrypt_crypto_t *crypto,
193 const _mongocrypt_buffer_t *S_Key,
194 mongocrypt_status_t *status);
195
196const _mongocrypt_buffer_t *
197mc_FLE2IndexedEncryptedValueV2_get_ClientEncryptedValue(const mc_FLE2IndexedEncryptedValueV2_t *iev,
198 mongocrypt_status_t *status);
199
200const _mongocrypt_buffer_t *mc_FLE2IndexedEncryptedValueV2_get_K_KeyId(const mc_FLE2IndexedEncryptedValueV2_t *iev,
201 mongocrypt_status_t *status);
202
203bool mc_FLE2IndexedEncryptedValueV2_add_K_Key(_mongocrypt_crypto_t *crypto,
205 const _mongocrypt_buffer_t *K_Key,
206 mongocrypt_status_t *status);
207
208const _mongocrypt_buffer_t *mc_FLE2IndexedEncryptedValueV2_get_ClientValue(const mc_FLE2IndexedEncryptedValueV2_t *iev,
209 mongocrypt_status_t *status);
210
211uint32_t mc_FLE2IndexedEncryptedValueV2_get_edge_count(const mc_FLE2IndexedEncryptedValueV2_t *iev,
212 mongocrypt_status_t *status);
213
214bool mc_FLE2IndexedEncryptedValueV2_get_substr_tag_count(const mc_FLE2IndexedEncryptedValueV2_t *iev,
215 uint32_t *count,
216 mongocrypt_status_t *status);
217
218bool mc_FLE2IndexedEncryptedValueV2_get_suffix_tag_count(const mc_FLE2IndexedEncryptedValueV2_t *iev,
219 uint32_t *count,
220 mongocrypt_status_t *status);
221
222bool mc_FLE2IndexedEncryptedValueV2_get_prefix_tag_count(const mc_FLE2IndexedEncryptedValueV2_t *iev,
223 uint32_t *count,
224 mongocrypt_status_t *status);
225
226bool mc_FLE2IndexedEncryptedValueV2_get_edge(const mc_FLE2IndexedEncryptedValueV2_t *iev,
227 mc_FLE2TagAndEncryptedMetadataBlock_t *out,
228 const uint32_t edge_index,
229 mongocrypt_status_t *status);
230
231bool mc_FLE2IndexedEncryptedValueV2_get_metadata(const mc_FLE2IndexedEncryptedValueV2_t *iev,
232 mc_FLE2TagAndEncryptedMetadataBlock_t *out,
233 mongocrypt_status_t *status);
234
235bool mc_FLE2IndexedEncryptedValueV2_get_exact_metadata(const mc_FLE2IndexedEncryptedValueV2_t *iev,
236 mc_FLE2TagAndEncryptedMetadataBlock_t *out,
237 mongocrypt_status_t *status);
238
239bool mc_FLE2IndexedEncryptedValueV2_get_substr_metadata(const mc_FLE2IndexedEncryptedValueV2_t *iev,
240 mc_FLE2TagAndEncryptedMetadataBlock_t *out,
241 const uint32_t block_index,
242 mongocrypt_status_t *status);
243
244bool mc_FLE2IndexedEncryptedValueV2_get_suffix_metadata(const mc_FLE2IndexedEncryptedValueV2_t *iev,
245 mc_FLE2TagAndEncryptedMetadataBlock_t *out,
246 const uint32_t block_index,
247 mongocrypt_status_t *status);
248
249bool mc_FLE2IndexedEncryptedValueV2_get_prefix_metadata(const mc_FLE2IndexedEncryptedValueV2_t *iev,
250 mc_FLE2TagAndEncryptedMetadataBlock_t *out,
251 const uint32_t block_index,
252 mongocrypt_status_t *status);
253
254void mc_FLE2IndexedEncryptedValueV2_destroy(mc_FLE2IndexedEncryptedValueV2_t *iev);
255
256#endif /* MONGOCRYPT_INDEXED_ENCRYPTED_VALUE_PRIVATE_V2_H */
struct _mongocrypt_status_t mongocrypt_status_t
Definition mongocrypt.h:152
Definition mc-fle2-payload-iev-private-v2.h:112