@@ -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
645664bool 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+
772800bool 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