Skip to content

Commit fb3ecc4

Browse files
committed
implement IEV
1 parent 27f120d commit fb3ecc4

3 files changed

Lines changed: 40 additions & 7 deletions

File tree

src/mc-fle-blob-subtype-private.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,8 @@ typedef enum {
4747
/* Text Search Subtypes */
4848
MC_SUBTYPE_FLE2IndexedTextEncryptedValue = 17,
4949
MC_SUBTYPE_FLE2FindTextPayload = 18,
50+
MC_SUBTYPE_FLE2IndexedKeywordEncryptedValue = 19,
51+
MC_SUBTYPE_FLE2FindKeywordPayload = 20,
5052
} mc_fle_blob_subtype_t;
5153

5254
#endif /* MC_FLE_BLOB_SUBTYPE_PRIVATE_H */

src/mc-fle2-payload-iev-private-v2.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -107,6 +107,7 @@ typedef enum {
107107
kFLE2IEVTypeEqualityV2,
108108
kFLE2IEVTypeRangeV2,
109109
kFLE2IEVTypeText,
110+
kFLE2IEVTypeKeyword,
110111
} _mc_fle2_iev_v2_type;
111112

112113
typedef struct _mc_FLE2IndexedEncryptedValueV2_t {

src/mc-fle2-payload-iev-v2.c

Lines changed: 37 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -289,7 +289,7 @@ uint32_t mc_FLE2IndexedEncryptedValueV2_get_edge_count(const mc_FLE2IndexedEncry
289289
return 0;
290290
}
291291

292-
if (!(iev->type == kFLE2IEVTypeRangeV2 || iev->type == kFLE2IEVTypeText)) {
292+
if (!(iev->type == kFLE2IEVTypeRangeV2 || iev->type == kFLE2IEVTypeText || iev->type == kFLE2IEVTypeKeyword)) {
293293
CLIENT_ERR("mc_FLE2IndexedEncryptedValueV2_get_edge_count must be called with type range or text");
294294
return 0;
295295
}
@@ -377,8 +377,8 @@ bool mc_FLE2IndexedEncryptedValueV2_get_edge(const mc_FLE2IndexedEncryptedValueV
377377
return false;
378378
}
379379

380-
if (iev->type != kFLE2IEVTypeRangeV2 && iev->type != kFLE2IEVTypeText) {
381-
CLIENT_ERR("mc_FLE2IndexedEncryptedValueV2_get_edge must be called with type range");
380+
if (iev->type != kFLE2IEVTypeRangeV2 && iev->type != kFLE2IEVTypeText && iev->type != kFLE2IEVTypeKeyword) {
381+
CLIENT_ERR("mc_FLE2IndexedEncryptedValueV2_get_edge must be called with type range or text or keyword");
382382
return false;
383383
}
384384

@@ -550,6 +550,8 @@ bool mc_FLE2IndexedEncryptedValueV2_parse(mc_FLE2IndexedEncryptedValueV2_t *iev,
550550
iev->type = kFLE2IEVTypeRangeV2;
551551
} else if (iev->fle_blob_subtype == MC_SUBTYPE_FLE2IndexedTextEncryptedValue) {
552552
iev->type = kFLE2IEVTypeText;
553+
} else if (iev->fle_blob_subtype == MC_SUBTYPE_FLE2IndexedKeywordEncryptedValue) {
554+
iev->type = kFLE2IEVTypeKeyword;
553555
} else {
554556
CLIENT_ERR("mc_FLE2IndexedEncryptedValueV2_parse expected "
555557
"fle_blob_subtype MC_SUBTYPE_FLE2Indexed(Equality|Range|Text)EncryptedValue[V2] got: %" PRIu8,
@@ -581,6 +583,15 @@ bool mc_FLE2IndexedEncryptedValueV2_parse(mc_FLE2IndexedEncryptedValueV2_t *iev,
581583
return false;
582584
}
583585
iev->edge_count = (uint32_t)ec;
586+
} else if (iev->type == kFLE2IEVTypeKeyword) {
587+
uint32_t ec;
588+
CHECK_AND_RETURN(mc_reader_read_u32(&reader, &ec, status));
589+
if (ec == 0) {
590+
CLIENT_ERR("mc_FLE2IndexedEncryptedValueV2_parse edge count must not be 0 for type "
591+
"keyword, but found edge count is 0.");
592+
return false;
593+
}
594+
iev->edge_count = ec;
584595
} else if (iev->type == kFLE2IEVTypeText) {
585596
CHECK_AND_RETURN(mc_reader_read_u32(&reader, &iev->edge_count, status));
586597
CHECK_AND_RETURN(mc_reader_read_u32(&reader, &iev->substr_tag_count, status));
@@ -638,8 +649,16 @@ static inline uint32_t mc_FLE2IndexedEncryptedValueV2_serialized_length(const mc
638649
// if text: edge + tag counts: 12 bytes
639650
// ServerEncryptedValue: ServerEncryptedValue.len bytes
640651
// metadata: edge_count * kMetadataLen bytes
641-
return iev->ServerEncryptedValue.len + 1 + UUID_LEN + 1 + (iev->type == kFLE2IEVTypeRangeV2 ? 1 : 0)
642-
+ (iev->type == kFLE2IEVTypeText ? 12 : 0) + iev->edge_count * kMetadataLen;
652+
uint32_t counters_len = 0;
653+
if (iev->type == kFLE2IEVTypeRangeV2) {
654+
counters_len = sizeof(uint8_t);
655+
} else if (iev->type == kFLE2IEVTypeKeyword) {
656+
counters_len = sizeof(uint32_t);
657+
} else if (iev->type == kFLE2IEVTypeText) {
658+
counters_len = 3 * sizeof(uint32_t);
659+
}
660+
661+
return iev->ServerEncryptedValue.len + 1 + UUID_LEN + 1 + counters_len + iev->edge_count * kMetadataLen;
643662
}
644663

645664
bool mc_FLE2IndexedEncryptedValueV2_serialize(const mc_FLE2IndexedEncryptedValueV2_t *iev,
@@ -648,7 +667,8 @@ bool mc_FLE2IndexedEncryptedValueV2_serialize(const mc_FLE2IndexedEncryptedValue
648667
BSON_ASSERT_PARAM(iev);
649668
BSON_ASSERT_PARAM(buf);
650669

651-
if (iev->type != kFLE2IEVTypeRangeV2 && iev->type != kFLE2IEVTypeEqualityV2 && iev->type != kFLE2IEVTypeText) {
670+
if (iev->type != kFLE2IEVTypeRangeV2 && iev->type != kFLE2IEVTypeEqualityV2 && iev->type != kFLE2IEVTypeText
671+
&& iev->type != kFLE2IEVTypeKeyword) {
652672
CLIENT_ERR("mc_FLE2IndexedEncryptedValueV2_serialize must be called with type equality, range, or text");
653673
return false;
654674
}
@@ -675,6 +695,8 @@ bool mc_FLE2IndexedEncryptedValueV2_serialize(const mc_FLE2IndexedEncryptedValue
675695
CHECK_AND_RETURN(mc_writer_write_u32(&writer, iev->edge_count, status));
676696
CHECK_AND_RETURN(mc_writer_write_u32(&writer, iev->substr_tag_count, status));
677697
CHECK_AND_RETURN(mc_writer_write_u32(&writer, iev->suffix_tag_count, status));
698+
} else if (iev->type == kFLE2IEVTypeKeyword) {
699+
CHECK_AND_RETURN(mc_writer_write_u32(&writer, iev->edge_count, status));
678700
}
679701

680702
// Serialize encrypted value
@@ -769,6 +791,12 @@ static bool validate_for_text(const mc_FLE2IndexedEncryptedValueV2_t *iev, mongo
769791
return true;
770792
}
771793

794+
static bool validate_for_keyword(const mc_FLE2IndexedEncryptedValueV2_t *iev, mongocrypt_status_t *status) {
795+
CHECK(iev->fle_blob_subtype == MC_SUBTYPE_FLE2IndexedKeywordEncryptedValue, "fle_blob_subtype does not match type");
796+
CHECK(is_fle2_text_indexed_supported_type(iev->bson_value_type), "bson_value_type is invalid");
797+
return true;
798+
}
799+
772800
bool mc_FLE2IndexedEncryptedValueV2_validate(const mc_FLE2IndexedEncryptedValueV2_t *iev, mongocrypt_status_t *status) {
773801
BSON_ASSERT_PARAM(iev);
774802
CHECK(iev->type == kFLE2IEVTypeEqualityV2 || iev->type == kFLE2IEVTypeRangeV2 || iev->type == kFLE2IEVTypeText,
@@ -778,8 +806,10 @@ bool mc_FLE2IndexedEncryptedValueV2_validate(const mc_FLE2IndexedEncryptedValueV
778806
validate_for_equality(iev, status);
779807
} else if (iev->type == kFLE2IEVTypeRangeV2) {
780808
validate_for_range(iev, status);
781-
} else {
809+
} else if (iev->type == kFLE2IEVTypeText) {
782810
validate_for_text(iev, status);
811+
} else {
812+
validate_for_keyword(iev, status);
783813
}
784814

785815
if (!mongocrypt_status_ok(status)) {

0 commit comments

Comments
 (0)