Skip to content

Commit

Permalink
MONGOCRYPT-758 Implement FLE2IndexedTextEncryptedValue parse & decrypt (
Browse files Browse the repository at this point in the history
  • Loading branch information
marksg07 authored Jan 24, 2025
1 parent a98c8bf commit 0a62533
Show file tree
Hide file tree
Showing 7 changed files with 559 additions and 50 deletions.
5 changes: 4 additions & 1 deletion src/mc-fle-blob-subtype-private.h
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,10 @@ typedef enum {
MC_SUBTYPE_FLE2FindRangePayloadV2 = 13,
MC_SUBTYPE_FLE2IndexedEqualityEncryptedValueV2 = 14,
MC_SUBTYPE_FLE2IndexedRangeEncryptedValueV2 = 15,
MC_SUBTYPE_FLE2UnindexedEncryptedValueV2 = 16
MC_SUBTYPE_FLE2UnindexedEncryptedValueV2 = 16,

/* Text Search Subtypes */
MC_SUBTYPE_FLE2IndexedTextEncryptedValue = 17,
} mc_fle_blob_subtype_t;

#endif /* MC_FLE_BLOB_SUBTYPE_PRIVATE_H */
57 changes: 56 additions & 1 deletion src/mc-fle2-payload-iev-private-v2.h
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@
#include "mongocrypt-status-private.h"

/*
* FLE2IndexedEqualityEncryptedValueV2 and FLE2IndexedRangeEncryptedValueV2
* FLE2IndexedEqualityEncryptedValueV2, FLE2IndexedRangeEncryptedValueV2, and FLEIndexedTextEncryptedValue
* share a common internal implementation.
*
* Lifecycle:
Expand Down Expand Up @@ -78,19 +78,43 @@
* 1/ `edge_count` is introduced as an octet following `original_bson_type`.
* 2/ Rather than a single metadata block, we have {edge_count} blocks.
*
* FLE2IndexedTextEncryptedValue has the following data layout:
*
* struct FLE2IndexedTextEncryptedValue {
* uint8_t fle_blob_subtype = 17;
* uint8_t S_KeyId[16];
* uint8_t original_bson_type;
* uint8_t edge_count;
* uint8_t substr_tag_count;
* uint8_t suffix_tag_count;
* uint8_t ServerEncryptedValue[ServerEncryptedValue.length];
* FLE2TagAndEncryptedMetadataBlock exact_metadata;
* FLE2TagAndEncryptedMetadataBlock substr_metadata[substr_tag_count];
* FLE2TagAndEncryptedMetadataBlock suffix_metadata[suffix_tag_count];
* FLE2TagAndEncryptedMetadataBlock prefix_metadata[edge_count - suffix_tag_count - substr_tag_count - 1];
* }
* The main difference in this format is that we split `metadata` into 4
* sections, one for each text search index type. We add two octets,
* `substr_tag_count` and `suffix_tag_count`, following `edge_count`
* in order to track the delineation of the metadata. Similarly to
* FLE2IndexedEqualityEncryptedValueV2, we have `edge_count` total
* blocks.
*/

typedef enum {
kFLE2IEVTypeInitV2,
kFLE2IEVTypeEqualityV2,
kFLE2IEVTypeRangeV2,
kFLE2IEVTypeText,
} _mc_fle2_iev_v2_type;

typedef struct _mc_FLE2IndexedEncryptedValueV2_t {
// Raw payload values
uint8_t fle_blob_subtype;
uint8_t bson_value_type;
uint8_t edge_count;
uint8_t substr_tag_count;
uint8_t suffix_tag_count;
_mongocrypt_buffer_t S_KeyId;
_mongocrypt_buffer_t ServerEncryptedValue;

Expand Down Expand Up @@ -182,6 +206,18 @@ const _mongocrypt_buffer_t *mc_FLE2IndexedEncryptedValueV2_get_ClientValue(const
uint8_t mc_FLE2IndexedEncryptedValueV2_get_edge_count(const mc_FLE2IndexedEncryptedValueV2_t *iev,
mongocrypt_status_t *status);

bool mc_FLE2IndexedEncryptedValueV2_get_substr_tag_count(const mc_FLE2IndexedEncryptedValueV2_t *iev,
uint8_t *count,
mongocrypt_status_t *status);

bool mc_FLE2IndexedEncryptedValueV2_get_suffix_tag_count(const mc_FLE2IndexedEncryptedValueV2_t *iev,
uint8_t *count,
mongocrypt_status_t *status);

bool mc_FLE2IndexedEncryptedValueV2_get_prefix_tag_count(const mc_FLE2IndexedEncryptedValueV2_t *iev,
uint8_t *count,
mongocrypt_status_t *status);

bool mc_FLE2IndexedEncryptedValueV2_get_edge(const mc_FLE2IndexedEncryptedValueV2_t *iev,
mc_FLE2TagAndEncryptedMetadataBlock_t *out,
const uint8_t edge_index,
Expand All @@ -191,6 +227,25 @@ bool mc_FLE2IndexedEncryptedValueV2_get_metadata(const mc_FLE2IndexedEncryptedVa
mc_FLE2TagAndEncryptedMetadataBlock_t *out,
mongocrypt_status_t *status);

bool mc_FLE2IndexedEncryptedValueV2_get_exact_metadata(const mc_FLE2IndexedEncryptedValueV2_t *iev,
mc_FLE2TagAndEncryptedMetadataBlock_t *out,
mongocrypt_status_t *status);

bool mc_FLE2IndexedEncryptedValueV2_get_substr_metadata(const mc_FLE2IndexedEncryptedValueV2_t *iev,
mc_FLE2TagAndEncryptedMetadataBlock_t *out,
const uint8_t block_index,
mongocrypt_status_t *status);

bool mc_FLE2IndexedEncryptedValueV2_get_suffix_metadata(const mc_FLE2IndexedEncryptedValueV2_t *iev,
mc_FLE2TagAndEncryptedMetadataBlock_t *out,
const uint8_t block_index,
mongocrypt_status_t *status);

bool mc_FLE2IndexedEncryptedValueV2_get_prefix_metadata(const mc_FLE2IndexedEncryptedValueV2_t *iev,
mc_FLE2TagAndEncryptedMetadataBlock_t *out,
const uint8_t block_index,
mongocrypt_status_t *status);

void mc_FLE2IndexedEncryptedValueV2_destroy(mc_FLE2IndexedEncryptedValueV2_t *iev);

#endif /* MONGOCRYPT_INDEXED_ENCRYPTED_VALUE_PRIVATE_V2_H */
Loading

0 comments on commit 0a62533

Please sign in to comment.