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-tokens-private.h"
21 #include "mongocrypt-buffer-private.h"
22 #include "mongocrypt-crypto-private.h"
23 #include "mongocrypt-status-private.h"
24 
25 /*
26  * FLE2IndexedEqualityEncryptedValueV2 and FLE2IndexedRangeEncryptedValueV2
27  * share a common internal implementation. Accessors such as add/get_[SK]_Key
28  * may be called for either type and produce appropriate results,
29  * however the _parse() method is unique per type.
30  *
31  * Lifecycle:
32  * 1. mc_FLE2IndexedEncryptedValueV2_init
33  * 2. mc_FLE2Indexed(Equality|Range)EncryptedValueV2_parse
34  * 3. mc_FLE2IndexedEncryptedValueV2_get_S_KeyId
35  * 4. mc_FLE2IndexedEncryptedValueV2_add_S_Key
36  * 5. mc_FLE2IndexedEncryptedValueV2_get_K_KeyId
37  * 6. mc_FLE2IndexedEncryptedValueV2_add_K_Key
38  * 7. mc_FLE2IndexedEncryptedValueV2_get_ClientValue
39  * 8. mc_FLE2IndexedEncryptedValueV2_destroy
40  */
41 
42 typedef struct _mc_FLE2IndexedEncryptedValueV2_t mc_FLE2IndexedEncryptedValueV2_t;
43 
44 mc_FLE2IndexedEncryptedValueV2_t *mc_FLE2IndexedEncryptedValueV2_new(void);
45 
46 bool mc_FLE2IndexedEncryptedValueV2_parse(mc_FLE2IndexedEncryptedValueV2_t *iev,
47  const _mongocrypt_buffer_t *buf,
48  mongocrypt_status_t *status);
49 
50 bson_type_t mc_FLE2IndexedEncryptedValueV2_get_bson_value_type(const mc_FLE2IndexedEncryptedValueV2_t *iev,
51  mongocrypt_status_t *status);
52 
53 const _mongocrypt_buffer_t *mc_FLE2IndexedEncryptedValueV2_get_S_KeyId(const mc_FLE2IndexedEncryptedValueV2_t *iev,
54  mongocrypt_status_t *status);
55 
56 bool mc_FLE2IndexedEncryptedValueV2_add_S_Key(_mongocrypt_crypto_t *crypto,
57  mc_FLE2IndexedEncryptedValueV2_t *iev,
58  const _mongocrypt_buffer_t *S_Key,
59  mongocrypt_status_t *status);
60 
61 const _mongocrypt_buffer_t *
62 mc_FLE2IndexedEncryptedValueV2_get_ClientEncryptedValue(const mc_FLE2IndexedEncryptedValueV2_t *iev,
63  mongocrypt_status_t *status);
64 
65 const _mongocrypt_buffer_t *mc_FLE2IndexedEncryptedValueV2_get_K_KeyId(const mc_FLE2IndexedEncryptedValueV2_t *iev,
66  mongocrypt_status_t *status);
67 
68 bool mc_FLE2IndexedEncryptedValueV2_add_K_Key(_mongocrypt_crypto_t *crypto,
69  mc_FLE2IndexedEncryptedValueV2_t *iev,
70  const _mongocrypt_buffer_t *K_Key,
71  mongocrypt_status_t *status);
72 
73 const _mongocrypt_buffer_t *mc_FLE2IndexedEncryptedValueV2_get_ClientValue(const mc_FLE2IndexedEncryptedValueV2_t *iev,
74  mongocrypt_status_t *status);
75 
76 void mc_FLE2IndexedEncryptedValueV2_destroy(mc_FLE2IndexedEncryptedValueV2_t *iev);
77 
78 /*
79  * FLE2IndexedEqualityEncryptedValueV2 has the following data layout:
80  *
81  * struct FLE2IndexedEqualityEncryptedValueV2 {
82  * uint8_t fle_blob_subtype = 14;
83  * uint8_t S_KeyId[16];
84  * uint8_t original_bson_type;
85  * uint8_t ServerEncryptedValue[ServerEncryptedValue.length];
86  * FLE2TagAndEncryptedMetadataBlock metadata;
87  * }
88  *
89  * ServerEncryptedValue :=
90  * EncryptCTR(ServerEncryptionToken, K_KeyId || ClientEncryptedValue)
91  * ClientEncryptedValue := EncryptCBCAEAD(K_Key, clientValue, AD=K_KeyId)
92  *
93  * The MetadataBlock is ignored by libmongocrypt,
94  * but has the following structure and a fixed size of 96 octets:
95  *
96  * struct FLE2TagAndEncryptedMetadataBlock {
97  * uint8_t encryptedCount[32]; // EncryptCTR(countEncryptionToken,
98  * // count || contentionFactor)
99  * uint8_t tag[32]; // HMAC-SHA256(count, edcTwiceDerived)
100  * uint8_t encryptedZeros[32]; // EncryptCTR(zerosEncryptionToken, 0*)
101  * }
102  */
103 
104 bool mc_FLE2IndexedEqualityEncryptedValueV2_parse(mc_FLE2IndexedEncryptedValueV2_t *iev,
105  const _mongocrypt_buffer_t *buf,
106  mongocrypt_status_t *status);
107 
108 /*
109  * FLE2IndexedRangeEncryptedValueV2 has the following data layout:
110  *
111  * struct FLE2IndexedRangeEncryptedValueV2 {
112  * uint8_t fle_blob_subtype = 15;
113  * uint8_t S_KeyId[16];
114  * uint8_t original_bson_type;
115  * uint8_t edge_count;
116  * uint8_t ServerEncryptedValue[ServerEncryptedValue.length];
117  * FLE2TagAndEncryptedMetadataBlock metadata[edge_count];
118  * }
119  *
120  * Note that this format differs from FLE2IndexedEqualityEncryptedValueV2
121  * in only two ways:
122  * 1/ `edge_count` is introduced as an octet following `original_bson_type`.
123  * 2/ Rather than a single metadata block, we have {edge_count} blocks.
124  *
125  * Since libmongocrypt ignores metadata blocks, we can ignore most all
126  * differences between Equality and Range types for IndexedEncrypted data.
127  */
128 
129 bool mc_FLE2IndexedRangeEncryptedValueV2_parse(mc_FLE2IndexedEncryptedValueV2_t *iev,
130  const _mongocrypt_buffer_t *buf,
131  mongocrypt_status_t *status);
132 
133 #endif /* MONGOCRYPT_INDEXED_ENCRYPTED_VALUE_PRIVATE_V2_H */
struct _mongocrypt_status_t mongocrypt_status_t
Definition: mongocrypt.h:152