libmongocrypt
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 
105 typedef 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 
142 mc_FLE2IndexedEncryptedValueV2_t *mc_FLE2IndexedEncryptedValueV2_new(void);
143 bson_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  */
164 bool 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  */
178 bool mc_FLE2IndexedEncryptedValueV2_serialize(const mc_FLE2IndexedEncryptedValueV2_t *iev,
179  _mongocrypt_buffer_t *buf,
180  mongocrypt_status_t *status);
181 
186 bool mc_FLE2IndexedEncryptedValueV2_validate(const mc_FLE2IndexedEncryptedValueV2_t *iev, mongocrypt_status_t *status);
187 
188 const _mongocrypt_buffer_t *mc_FLE2IndexedEncryptedValueV2_get_S_KeyId(const mc_FLE2IndexedEncryptedValueV2_t *iev,
189  mongocrypt_status_t *status);
190 
191 bool mc_FLE2IndexedEncryptedValueV2_add_S_Key(_mongocrypt_crypto_t *crypto,
193  const _mongocrypt_buffer_t *S_Key,
194  mongocrypt_status_t *status);
195 
196 const _mongocrypt_buffer_t *
197 mc_FLE2IndexedEncryptedValueV2_get_ClientEncryptedValue(const mc_FLE2IndexedEncryptedValueV2_t *iev,
198  mongocrypt_status_t *status);
199 
200 const _mongocrypt_buffer_t *mc_FLE2IndexedEncryptedValueV2_get_K_KeyId(const mc_FLE2IndexedEncryptedValueV2_t *iev,
201  mongocrypt_status_t *status);
202 
203 bool mc_FLE2IndexedEncryptedValueV2_add_K_Key(_mongocrypt_crypto_t *crypto,
205  const _mongocrypt_buffer_t *K_Key,
206  mongocrypt_status_t *status);
207 
208 const _mongocrypt_buffer_t *mc_FLE2IndexedEncryptedValueV2_get_ClientValue(const mc_FLE2IndexedEncryptedValueV2_t *iev,
209  mongocrypt_status_t *status);
210 
211 uint32_t mc_FLE2IndexedEncryptedValueV2_get_edge_count(const mc_FLE2IndexedEncryptedValueV2_t *iev,
212  mongocrypt_status_t *status);
213 
214 bool mc_FLE2IndexedEncryptedValueV2_get_substr_tag_count(const mc_FLE2IndexedEncryptedValueV2_t *iev,
215  uint32_t *count,
216  mongocrypt_status_t *status);
217 
218 bool mc_FLE2IndexedEncryptedValueV2_get_suffix_tag_count(const mc_FLE2IndexedEncryptedValueV2_t *iev,
219  uint32_t *count,
220  mongocrypt_status_t *status);
221 
222 bool mc_FLE2IndexedEncryptedValueV2_get_prefix_tag_count(const mc_FLE2IndexedEncryptedValueV2_t *iev,
223  uint32_t *count,
224  mongocrypt_status_t *status);
225 
226 bool 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 
231 bool mc_FLE2IndexedEncryptedValueV2_get_metadata(const mc_FLE2IndexedEncryptedValueV2_t *iev,
232  mc_FLE2TagAndEncryptedMetadataBlock_t *out,
233  mongocrypt_status_t *status);
234 
235 bool mc_FLE2IndexedEncryptedValueV2_get_exact_metadata(const mc_FLE2IndexedEncryptedValueV2_t *iev,
236  mc_FLE2TagAndEncryptedMetadataBlock_t *out,
237  mongocrypt_status_t *status);
238 
239 bool 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 
244 bool 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 
249 bool 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 
254 void 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