libmongocrypt-helper 1.7.4.0.1002 → 1.11.0.0.1001

Sign up to get free protection for your applications and to get access to all the features.
Files changed (600) hide show
  1. checksums.yaml +4 -4
  2. data/ext/libmongocrypt/libmongocrypt/CHANGELOG.md +40 -5
  3. data/ext/libmongocrypt/libmongocrypt/CMakeLists.txt +29 -24
  4. data/ext/libmongocrypt/libmongocrypt/CODEOWNERS +1 -4
  5. data/ext/libmongocrypt/libmongocrypt/Earthfile +522 -0
  6. data/ext/libmongocrypt/libmongocrypt/README.md +36 -40
  7. data/ext/libmongocrypt/libmongocrypt/bindings/cs/CMakeLists.txt +1 -0
  8. data/ext/libmongocrypt/libmongocrypt/bindings/cs/MongoDB.Driver.snk +0 -0
  9. data/ext/libmongocrypt/libmongocrypt/bindings/cs/MongoDB.Libmongocrypt/AssemblyInfo.cs +2 -2
  10. data/ext/libmongocrypt/libmongocrypt/bindings/cs/MongoDB.Libmongocrypt/Binary.cs +16 -2
  11. data/ext/libmongocrypt/libmongocrypt/bindings/cs/MongoDB.Libmongocrypt/CryptClient.cs +25 -6
  12. data/ext/libmongocrypt/libmongocrypt/bindings/cs/MongoDB.Libmongocrypt/CryptClientFactory.cs +8 -4
  13. data/ext/libmongocrypt/libmongocrypt/bindings/cs/MongoDB.Libmongocrypt/Library.cs +35 -3
  14. data/ext/libmongocrypt/libmongocrypt/bindings/cs/MongoDB.Libmongocrypt/LibraryLoader.cs +81 -44
  15. data/ext/libmongocrypt/libmongocrypt/bindings/cs/MongoDB.Libmongocrypt/MongoDB.Libmongocrypt.csproj +2 -1
  16. data/ext/libmongocrypt/libmongocrypt/bindings/cs/MongoDB.Libmongocrypt.Example/MongoDB.Libmongocrypt.Example.csproj +1 -1
  17. data/ext/libmongocrypt/libmongocrypt/bindings/cs/MongoDB.Libmongocrypt.Test/BasicTests.cs +1 -1
  18. data/ext/libmongocrypt/libmongocrypt/bindings/cs/MongoDB.Libmongocrypt.Test/MongoDB.Libmongocrypt.Test.csproj +2 -0
  19. data/ext/libmongocrypt/libmongocrypt/bindings/cs/MongoDB.Libmongocrypt.Test32/MongoDB.Libmongocrypt.Test32.csproj +2 -0
  20. data/ext/libmongocrypt/libmongocrypt/bindings/cs/README.md +3 -0
  21. data/ext/libmongocrypt/libmongocrypt/bindings/cs/Scripts/build.cake +22 -26
  22. data/ext/libmongocrypt/libmongocrypt/bindings/cs/Scripts/build.config +3 -0
  23. data/ext/libmongocrypt/libmongocrypt/bindings/cs/Scripts/build.sh +0 -0
  24. data/ext/libmongocrypt/libmongocrypt/bindings/java/mongocrypt/benchmarks/build.gradle.kts +28 -0
  25. data/ext/libmongocrypt/libmongocrypt/bindings/java/mongocrypt/benchmarks/src/main/java/com/mongodb/crypt/benchmark/BenchmarkRunner.java +217 -0
  26. data/ext/libmongocrypt/libmongocrypt/bindings/java/mongocrypt/benchmarks/src/main/resources/keyDocument.json +24 -0
  27. data/ext/libmongocrypt/libmongocrypt/bindings/java/mongocrypt/build.gradle.kts +22 -7
  28. data/ext/libmongocrypt/libmongocrypt/bindings/java/mongocrypt/gradle/wrapper/gradle-wrapper.jar +0 -0
  29. data/ext/libmongocrypt/libmongocrypt/bindings/java/mongocrypt/gradle/wrapper/gradle-wrapper.properties +1 -1
  30. data/ext/libmongocrypt/libmongocrypt/bindings/java/mongocrypt/gradlew +154 -108
  31. data/ext/libmongocrypt/libmongocrypt/bindings/java/mongocrypt/gradlew.bat +7 -18
  32. data/ext/libmongocrypt/libmongocrypt/bindings/java/mongocrypt/settings.gradle.kts +1 -0
  33. data/ext/libmongocrypt/libmongocrypt/bindings/java/mongocrypt/src/main/java/com/mongodb/crypt/capi/CAPI.java +41 -6
  34. data/ext/libmongocrypt/libmongocrypt/bindings/java/mongocrypt/src/main/java/com/mongodb/crypt/capi/CAPIHelper.java +5 -5
  35. data/ext/libmongocrypt/libmongocrypt/bindings/java/mongocrypt/src/main/java/com/mongodb/crypt/capi/CipherCallback.java +27 -1
  36. data/ext/libmongocrypt/libmongocrypt/bindings/java/mongocrypt/src/main/java/com/mongodb/crypt/capi/MongoCryptImpl.java +34 -19
  37. data/ext/libmongocrypt/libmongocrypt/bindings/java/mongocrypt/src/main/java/com/mongodb/crypt/capi/MongoExplicitEncryptOptions.java +6 -4
  38. data/ext/libmongocrypt/libmongocrypt/bindings/java/mongocrypt/src/main/resources/META-INF/native-image/jni-config.json +180 -0
  39. data/ext/libmongocrypt/libmongocrypt/bindings/java/mongocrypt/src/main/resources/META-INF/native-image/reflect-config.json +134 -0
  40. data/ext/libmongocrypt/libmongocrypt/bindings/java/mongocrypt/src/test/java/com/mongodb/crypt/capi/MongoCryptTest.java +50 -6
  41. data/ext/libmongocrypt/libmongocrypt/bindings/java/mongocrypt/src/test/resources/fle2-find-range-explicit-v2/int32/encrypted-payload.json +26 -0
  42. data/ext/libmongocrypt/libmongocrypt/bindings/{python/test/data/fle2-find-range-explicit → java/mongocrypt/src/test/resources/fle2-find-range-explicit-v2}/int32/rangeopts.json +3 -0
  43. data/ext/libmongocrypt/libmongocrypt/bindings/node/README.md +4 -771
  44. data/ext/libmongocrypt/libmongocrypt/bindings/python/CHANGELOG.rst +86 -0
  45. data/ext/libmongocrypt/libmongocrypt/bindings/python/README.rst +41 -20
  46. data/ext/libmongocrypt/libmongocrypt/bindings/python/RELEASE.rst +6 -24
  47. data/ext/libmongocrypt/libmongocrypt/bindings/python/build-manylinux-wheel.sh +4 -13
  48. data/ext/libmongocrypt/libmongocrypt/bindings/python/hatch_build.py +36 -0
  49. data/ext/libmongocrypt/libmongocrypt/bindings/python/libmongocrypt-version.txt +1 -0
  50. data/ext/libmongocrypt/libmongocrypt/bindings/python/pymongocrypt/__init__.py +2 -2
  51. data/ext/libmongocrypt/libmongocrypt/bindings/python/pymongocrypt/asynchronous/auto_encrypter.py +61 -0
  52. data/ext/libmongocrypt/libmongocrypt/bindings/python/pymongocrypt/asynchronous/credentials.py +156 -0
  53. data/ext/libmongocrypt/libmongocrypt/bindings/python/pymongocrypt/asynchronous/explicit_encrypter.py +156 -0
  54. data/ext/libmongocrypt/libmongocrypt/bindings/python/pymongocrypt/asynchronous/state_machine.py +149 -0
  55. data/ext/libmongocrypt/libmongocrypt/bindings/python/pymongocrypt/auto_encrypter.py +2 -46
  56. data/ext/libmongocrypt/libmongocrypt/bindings/python/pymongocrypt/binary.py +14 -17
  57. data/ext/libmongocrypt/libmongocrypt/bindings/python/pymongocrypt/binding.py +232 -296
  58. data/ext/libmongocrypt/libmongocrypt/bindings/python/pymongocrypt/compat.py +6 -31
  59. data/ext/libmongocrypt/libmongocrypt/bindings/python/pymongocrypt/credentials.py +2 -121
  60. data/ext/libmongocrypt/libmongocrypt/bindings/python/pymongocrypt/crypto.py +31 -20
  61. data/ext/libmongocrypt/libmongocrypt/bindings/python/pymongocrypt/errors.py +2 -2
  62. data/ext/libmongocrypt/libmongocrypt/bindings/python/pymongocrypt/explicit_encrypter.py +2 -233
  63. data/ext/libmongocrypt/libmongocrypt/bindings/python/pymongocrypt/mongocrypt.py +168 -254
  64. data/ext/libmongocrypt/libmongocrypt/bindings/python/pymongocrypt/options.py +265 -0
  65. data/ext/libmongocrypt/libmongocrypt/bindings/python/pymongocrypt/state_machine.py +2 -141
  66. data/ext/libmongocrypt/libmongocrypt/bindings/python/pymongocrypt/synchronous/auto_encrypter.py +61 -0
  67. data/ext/libmongocrypt/libmongocrypt/bindings/python/pymongocrypt/synchronous/credentials.py +156 -0
  68. data/ext/libmongocrypt/libmongocrypt/bindings/python/pymongocrypt/synchronous/explicit_encrypter.py +156 -0
  69. data/ext/libmongocrypt/libmongocrypt/bindings/python/pymongocrypt/synchronous/state_machine.py +149 -0
  70. data/ext/libmongocrypt/libmongocrypt/bindings/python/pymongocrypt/version.py +2 -2
  71. data/ext/libmongocrypt/libmongocrypt/bindings/python/pyproject.toml +118 -0
  72. data/ext/libmongocrypt/libmongocrypt/bindings/python/release.sh +97 -61
  73. data/ext/libmongocrypt/libmongocrypt/bindings/python/requirements-test.txt +7 -0
  74. data/ext/libmongocrypt/libmongocrypt/bindings/python/requirements.txt +4 -0
  75. data/ext/libmongocrypt/libmongocrypt/bindings/python/sbom.json +76 -0
  76. data/ext/libmongocrypt/libmongocrypt/bindings/python/strip_header.py +6 -7
  77. data/ext/libmongocrypt/libmongocrypt/bindings/python/synchro.py +64 -0
  78. data/ext/libmongocrypt/libmongocrypt/bindings/python/test/__init__.py +2 -10
  79. data/ext/libmongocrypt/libmongocrypt/bindings/python/test/data/collection-info.json +1 -1
  80. data/ext/libmongocrypt/libmongocrypt/bindings/python/test/data/command.json +1 -1
  81. data/ext/libmongocrypt/libmongocrypt/bindings/python/test/data/compact/success/encrypted-payload.json +21 -21
  82. data/ext/libmongocrypt/libmongocrypt/bindings/python/test/data/encrypted-command-reply.json +1 -1
  83. data/ext/libmongocrypt/libmongocrypt/bindings/python/test/data/encrypted-field-config-map.json +1 -1
  84. data/ext/libmongocrypt/libmongocrypt/bindings/python/test/data/fle2-find-range-explicit-v2/int32/encrypted-payload.json +26 -0
  85. data/ext/libmongocrypt/libmongocrypt/bindings/python/test/data/fle2-find-range-explicit-v2/int32/rangeopts.json +14 -0
  86. data/ext/libmongocrypt/libmongocrypt/bindings/python/test/data/key-document-azure.json +1 -1
  87. data/ext/libmongocrypt/libmongocrypt/bindings/python/test/data/key-document-gcp.json +1 -1
  88. data/ext/libmongocrypt/libmongocrypt/bindings/python/test/data/key-document.json +1 -1
  89. data/ext/libmongocrypt/libmongocrypt/bindings/python/test/data/key-filter.json +1 -1
  90. data/ext/libmongocrypt/libmongocrypt/bindings/python/test/data/list-collections-filter.json +1 -1
  91. data/ext/libmongocrypt/libmongocrypt/bindings/python/test/data/mongocryptd-command.json +1 -1
  92. data/ext/libmongocrypt/libmongocrypt/bindings/python/test/data/mongocryptd-reply.json +1 -1
  93. data/ext/libmongocrypt/libmongocrypt/bindings/python/test/data/schema-map.json +1 -1
  94. data/ext/libmongocrypt/libmongocrypt/bindings/python/test/performance/keyDocument.json +24 -0
  95. data/ext/libmongocrypt/libmongocrypt/bindings/python/test/performance/perf_test.py +165 -0
  96. data/ext/libmongocrypt/libmongocrypt/bindings/python/test/test_binding.py +8 -12
  97. data/ext/libmongocrypt/libmongocrypt/bindings/python/test/test_crypto.py +9 -11
  98. data/ext/libmongocrypt/libmongocrypt/bindings/python/test/test_mongocrypt.py +991 -343
  99. data/ext/libmongocrypt/libmongocrypt/bindings/python/update-sbom.sh +14 -0
  100. data/ext/libmongocrypt/libmongocrypt/cmake/FetchMongoC.cmake +19 -1
  101. data/ext/libmongocrypt/libmongocrypt/cmake/ImportBSON.cmake +31 -6
  102. data/ext/libmongocrypt/libmongocrypt/cmake/IntelDFP.cmake +20 -227
  103. data/ext/libmongocrypt/libmongocrypt/cmake/Patch.cmake +54 -0
  104. data/ext/libmongocrypt/libmongocrypt/cmake/Platform.cmake +50 -0
  105. data/ext/libmongocrypt/libmongocrypt/cmake/mongocrypt-config.cmake +21 -0
  106. data/ext/libmongocrypt/libmongocrypt/doc/img/cli-icon.png +0 -0
  107. data/ext/libmongocrypt/libmongocrypt/doc/img/reference-targets.png +0 -0
  108. data/ext/libmongocrypt/libmongocrypt/doc/releasing.md +153 -0
  109. data/ext/libmongocrypt/libmongocrypt/etc/c6-vault.repo +39 -0
  110. data/ext/libmongocrypt/libmongocrypt/etc/calc_release_version.py +61 -28
  111. data/ext/libmongocrypt/libmongocrypt/etc/calc_release_version_selftest.sh +73 -0
  112. data/ext/libmongocrypt/libmongocrypt/etc/cyclonedx.sbom.json +108 -0
  113. data/ext/libmongocrypt/libmongocrypt/etc/fle2_aead_generate_tests.py +15 -24
  114. data/ext/libmongocrypt/libmongocrypt/etc/fle2_crypto.py +66 -54
  115. data/ext/libmongocrypt/libmongocrypt/etc/fle2_generate_tests.py +14 -23
  116. data/ext/libmongocrypt/libmongocrypt/etc/fle2v2_aead_generate_tests.py +32 -0
  117. data/ext/libmongocrypt/libmongocrypt/etc/format-all.sh +12 -0
  118. data/ext/libmongocrypt/libmongocrypt/etc/format.sh +16 -0
  119. data/ext/libmongocrypt/libmongocrypt/etc/install-package.sh +48 -0
  120. data/ext/libmongocrypt/libmongocrypt/etc/libbson-remove-GCC-diagnostic-pragma.patch +27 -0
  121. data/ext/libmongocrypt/libmongocrypt/etc/mongo-inteldfp-alpine-arm-fix.patch +17 -0
  122. data/ext/libmongocrypt/libmongocrypt/etc/mongo-inteldfp-libmongocrypt-pr-625.patch +13 -0
  123. data/ext/libmongocrypt/libmongocrypt/etc/packager.py +120 -91
  124. data/ext/libmongocrypt/libmongocrypt/etc/purls.txt +14 -0
  125. data/ext/libmongocrypt/libmongocrypt/etc/repo_config.yaml +56 -0
  126. data/ext/libmongocrypt/libmongocrypt/etc/silk-create-asset-group.sh +70 -0
  127. data/ext/libmongocrypt/libmongocrypt/etc/ssdlc_compliance_report.md +37 -0
  128. data/ext/libmongocrypt/libmongocrypt/etc/third_party_vulnerabilities.md +42 -0
  129. data/ext/libmongocrypt/libmongocrypt/integrating.md +18 -1
  130. data/ext/libmongocrypt/libmongocrypt/kms-message/CMakeLists.txt +11 -3
  131. data/ext/libmongocrypt/libmongocrypt/kms-message/src/kms_gcp_request.c +1 -1
  132. data/ext/libmongocrypt/libmongocrypt/kms-message/src/kms_kmip_reader_writer.c +17 -0
  133. data/ext/libmongocrypt/libmongocrypt/kms-message/src/kms_kmip_reader_writer_private.h +6 -0
  134. data/ext/libmongocrypt/libmongocrypt/kms-message/src/kms_kmip_request.c +211 -1
  135. data/ext/libmongocrypt/libmongocrypt/kms-message/src/kms_kmip_response.c +163 -0
  136. data/ext/libmongocrypt/libmongocrypt/kms-message/src/kms_kmip_tag_type_private.h +2 -1
  137. data/ext/libmongocrypt/libmongocrypt/kms-message/src/kms_message/kms_kmip_request.h +17 -0
  138. data/ext/libmongocrypt/libmongocrypt/kms-message/src/kms_message/kms_kmip_response.h +6 -0
  139. data/ext/libmongocrypt/libmongocrypt/kms-message/src/kms_port.c +3 -2
  140. data/ext/libmongocrypt/libmongocrypt/kms-message/src/kms_request.c +4 -2
  141. data/ext/libmongocrypt/libmongocrypt/kms-message/src/kms_request_str.c +2 -2
  142. data/ext/libmongocrypt/libmongocrypt/kms-message/test/test_kmip_reader_writer.c +23 -2
  143. data/ext/libmongocrypt/libmongocrypt/src/crypto/cng.c +381 -436
  144. data/ext/libmongocrypt/libmongocrypt/src/crypto/commoncrypto.c +162 -227
  145. data/ext/libmongocrypt/libmongocrypt/src/crypto/libcrypto.c +183 -248
  146. data/ext/libmongocrypt/libmongocrypt/src/crypto/none.c +33 -55
  147. data/ext/libmongocrypt/libmongocrypt/src/csfle-markup.cpp +175 -205
  148. data/ext/libmongocrypt/libmongocrypt/src/mc-array-private.h +10 -21
  149. data/ext/libmongocrypt/libmongocrypt/src/mc-array.c +44 -56
  150. data/ext/libmongocrypt/libmongocrypt/src/mc-check-conversions-private.h +4 -8
  151. data/ext/libmongocrypt/libmongocrypt/src/mc-dec128.h +351 -463
  152. data/ext/libmongocrypt/libmongocrypt/src/mc-dec128.test.cpp +59 -66
  153. data/ext/libmongocrypt/libmongocrypt/src/mc-efc-private.h +21 -11
  154. data/ext/libmongocrypt/libmongocrypt/src/mc-efc.c +175 -99
  155. data/ext/libmongocrypt/libmongocrypt/src/mc-fle-blob-subtype-private.h +18 -10
  156. data/ext/libmongocrypt/libmongocrypt/src/mc-fle2-encryption-placeholder-private.h +69 -70
  157. data/ext/libmongocrypt/libmongocrypt/src/mc-fle2-encryption-placeholder.c +445 -439
  158. data/ext/libmongocrypt/libmongocrypt/src/mc-fle2-find-equality-payload-private-v2.h +41 -0
  159. data/ext/libmongocrypt/libmongocrypt/src/mc-fle2-find-equality-payload-private.h +11 -18
  160. data/ext/libmongocrypt/libmongocrypt/src/mc-fle2-find-equality-payload-v2.c +135 -0
  161. data/ext/libmongocrypt/libmongocrypt/src/mc-fle2-find-equality-payload.c +109 -126
  162. data/ext/libmongocrypt/libmongocrypt/src/mc-fle2-find-range-payload-private-v2.h +103 -0
  163. data/ext/libmongocrypt/libmongocrypt/src/mc-fle2-find-range-payload-private.h +28 -31
  164. data/ext/libmongocrypt/libmongocrypt/src/mc-fle2-find-range-payload-v2.c +173 -0
  165. data/ext/libmongocrypt/libmongocrypt/src/mc-fle2-find-range-payload.c +106 -125
  166. data/ext/libmongocrypt/libmongocrypt/src/mc-fle2-insert-update-payload-private-v2.h +130 -0
  167. data/ext/libmongocrypt/libmongocrypt/src/mc-fle2-insert-update-payload-private.h +36 -44
  168. data/ext/libmongocrypt/libmongocrypt/src/mc-fle2-insert-update-payload-v2.c +382 -0
  169. data/ext/libmongocrypt/libmongocrypt/src/mc-fle2-insert-update-payload.c +237 -278
  170. data/ext/libmongocrypt/libmongocrypt/src/mc-fle2-payload-iev-private-v2.h +133 -0
  171. data/ext/libmongocrypt/libmongocrypt/src/mc-fle2-payload-iev-private.h +67 -56
  172. data/ext/libmongocrypt/libmongocrypt/src/mc-fle2-payload-iev-v2.c +437 -0
  173. data/ext/libmongocrypt/libmongocrypt/src/mc-fle2-payload-iev.c +454 -325
  174. data/ext/libmongocrypt/libmongocrypt/src/mc-fle2-payload-uev-common-private.h +69 -0
  175. data/ext/libmongocrypt/libmongocrypt/src/mc-fle2-payload-uev-common.c +182 -0
  176. data/ext/libmongocrypt/libmongocrypt/src/mc-fle2-payload-uev-private.h +23 -31
  177. data/ext/libmongocrypt/libmongocrypt/src/mc-fle2-payload-uev-v2-private.h +85 -0
  178. data/ext/libmongocrypt/libmongocrypt/src/mc-fle2-payload-uev-v2.c +142 -0
  179. data/ext/libmongocrypt/libmongocrypt/src/mc-fle2-payload-uev.c +104 -231
  180. data/ext/libmongocrypt/libmongocrypt/src/mc-fle2-range-operator-private.h +8 -7
  181. data/ext/libmongocrypt/libmongocrypt/src/mc-fle2-rfds-private.h +56 -56
  182. data/ext/libmongocrypt/libmongocrypt/src/mc-fle2-rfds.c +520 -580
  183. data/ext/libmongocrypt/libmongocrypt/src/mc-optional-private.h +47 -66
  184. data/ext/libmongocrypt/libmongocrypt/src/mc-range-edge-generation-private.h +67 -76
  185. data/ext/libmongocrypt/libmongocrypt/src/mc-range-edge-generation.c +201 -190
  186. data/ext/libmongocrypt/libmongocrypt/src/mc-range-encoding-private.h +55 -42
  187. data/ext/libmongocrypt/libmongocrypt/src/mc-range-encoding.c +809 -558
  188. data/ext/libmongocrypt/libmongocrypt/src/mc-range-mincover-generator.template.h +177 -201
  189. data/ext/libmongocrypt/libmongocrypt/src/mc-range-mincover-private.h +54 -53
  190. data/ext/libmongocrypt/libmongocrypt/src/mc-range-mincover.c +188 -240
  191. data/ext/libmongocrypt/libmongocrypt/src/mc-rangeopts-private.h +43 -35
  192. data/ext/libmongocrypt/libmongocrypt/src/mc-rangeopts.c +484 -337
  193. data/ext/libmongocrypt/libmongocrypt/src/mc-reader-private.h +36 -71
  194. data/ext/libmongocrypt/libmongocrypt/src/mc-reader.c +111 -164
  195. data/ext/libmongocrypt/libmongocrypt/src/mc-tokens-private.h +87 -65
  196. data/ext/libmongocrypt/libmongocrypt/src/mc-tokens.c +153 -125
  197. data/ext/libmongocrypt/libmongocrypt/src/mc-writer-private.h +66 -0
  198. data/ext/libmongocrypt/libmongocrypt/src/mc-writer.c +141 -0
  199. data/ext/libmongocrypt/libmongocrypt/src/mlib/check.hpp +37 -55
  200. data/ext/libmongocrypt/libmongocrypt/src/mlib/endian.h +11 -11
  201. data/ext/libmongocrypt/libmongocrypt/src/mlib/error.h +27 -32
  202. data/ext/libmongocrypt/libmongocrypt/src/mlib/int128.h +461 -499
  203. data/ext/libmongocrypt/libmongocrypt/src/mlib/int128.test.cpp +256 -334
  204. data/ext/libmongocrypt/libmongocrypt/src/mlib/macros.h +4 -5
  205. data/ext/libmongocrypt/libmongocrypt/src/mlib/path.h +196 -231
  206. data/ext/libmongocrypt/libmongocrypt/src/mlib/path.test.c +56 -79
  207. data/ext/libmongocrypt/libmongocrypt/src/mlib/str.h +411 -530
  208. data/ext/libmongocrypt/libmongocrypt/src/mlib/str.test.c +116 -131
  209. data/ext/libmongocrypt/libmongocrypt/src/mlib/thread.h +17 -26
  210. data/ext/libmongocrypt/libmongocrypt/src/mlib/user-check.h +2 -2
  211. data/ext/libmongocrypt/libmongocrypt/src/mongocrypt-binary-private.h +1 -9
  212. data/ext/libmongocrypt/libmongocrypt/src/mongocrypt-binary.c +31 -48
  213. data/ext/libmongocrypt/libmongocrypt/src/mongocrypt-buffer-private.h +55 -131
  214. data/ext/libmongocrypt/libmongocrypt/src/mongocrypt-buffer.c +442 -565
  215. data/ext/libmongocrypt/libmongocrypt/src/mongocrypt-cache-collinfo-private.h +1 -2
  216. data/ext/libmongocrypt/libmongocrypt/src/mongocrypt-cache-collinfo.c +28 -45
  217. data/ext/libmongocrypt/libmongocrypt/src/mongocrypt-cache-key-private.h +11 -17
  218. data/ext/libmongocrypt/libmongocrypt/src/mongocrypt-cache-key.c +104 -132
  219. data/ext/libmongocrypt/libmongocrypt/src/mongocrypt-cache-oauth-private.h +16 -24
  220. data/ext/libmongocrypt/libmongocrypt/src/mongocrypt-cache-oauth.c +110 -93
  221. data/ext/libmongocrypt/libmongocrypt/src/mongocrypt-cache-private.h +26 -45
  222. data/ext/libmongocrypt/libmongocrypt/src/mongocrypt-cache.c +220 -273
  223. data/ext/libmongocrypt/libmongocrypt/src/mongocrypt-ciphertext-private.h +13 -25
  224. data/ext/libmongocrypt/libmongocrypt/src/mongocrypt-ciphertext.c +147 -166
  225. data/ext/libmongocrypt/libmongocrypt/src/mongocrypt-compat.h +2 -2
  226. data/ext/libmongocrypt/libmongocrypt/src/mongocrypt-crypto-private.h +110 -204
  227. data/ext/libmongocrypt/libmongocrypt/src/mongocrypt-crypto.c +1145 -1567
  228. data/ext/libmongocrypt/libmongocrypt/src/mongocrypt-ctx-datakey.c +510 -476
  229. data/ext/libmongocrypt/libmongocrypt/src/mongocrypt-ctx-decrypt.c +817 -694
  230. data/ext/libmongocrypt/libmongocrypt/src/mongocrypt-ctx-encrypt.c +2775 -2697
  231. data/ext/libmongocrypt/libmongocrypt/src/mongocrypt-ctx-private.h +189 -184
  232. data/ext/libmongocrypt/libmongocrypt/src/mongocrypt-ctx-rewrap-many-datakey.c +308 -351
  233. data/ext/libmongocrypt/libmongocrypt/src/mongocrypt-ctx.c +990 -1139
  234. data/ext/libmongocrypt/libmongocrypt/src/mongocrypt-dll-private.h +23 -24
  235. data/ext/libmongocrypt/libmongocrypt/src/mongocrypt-endian-private.h +44 -58
  236. data/ext/libmongocrypt/libmongocrypt/src/mongocrypt-endpoint-private.h +21 -25
  237. data/ext/libmongocrypt/libmongocrypt/src/mongocrypt-endpoint.c +167 -181
  238. data/ext/libmongocrypt/libmongocrypt/src/mongocrypt-kek-private.h +42 -44
  239. data/ext/libmongocrypt/libmongocrypt/src/mongocrypt-kek.c +292 -272
  240. data/ext/libmongocrypt/libmongocrypt/src/mongocrypt-key-broker-private.h +70 -110
  241. data/ext/libmongocrypt/libmongocrypt/src/mongocrypt-key-broker.c +1010 -1033
  242. data/ext/libmongocrypt/libmongocrypt/src/mongocrypt-key-private.h +27 -44
  243. data/ext/libmongocrypt/libmongocrypt/src/mongocrypt-key.c +349 -402
  244. data/ext/libmongocrypt/libmongocrypt/src/mongocrypt-kms-ctx-private.h +127 -120
  245. data/ext/libmongocrypt/libmongocrypt/src/mongocrypt-kms-ctx.c +1692 -1611
  246. data/ext/libmongocrypt/libmongocrypt/src/mongocrypt-log-private.h +35 -67
  247. data/ext/libmongocrypt/libmongocrypt/src/mongocrypt-log.c +49 -83
  248. data/ext/libmongocrypt/libmongocrypt/src/mongocrypt-marking-private.h +31 -36
  249. data/ext/libmongocrypt/libmongocrypt/src/mongocrypt-marking.c +1923 -1479
  250. data/ext/libmongocrypt/libmongocrypt/src/mongocrypt-mutex-private.h +7 -12
  251. data/ext/libmongocrypt/libmongocrypt/src/mongocrypt-opts-private.h +124 -107
  252. data/ext/libmongocrypt/libmongocrypt/src/mongocrypt-opts.c +925 -419
  253. data/ext/libmongocrypt/libmongocrypt/src/mongocrypt-private.h +99 -122
  254. data/ext/libmongocrypt/libmongocrypt/src/mongocrypt-status-private.h +3 -8
  255. data/ext/libmongocrypt/libmongocrypt/src/mongocrypt-status.c +92 -119
  256. data/ext/libmongocrypt/libmongocrypt/src/mongocrypt-traverse-util-private.h +19 -29
  257. data/ext/libmongocrypt/libmongocrypt/src/mongocrypt-traverse-util.c +136 -176
  258. data/ext/libmongocrypt/libmongocrypt/src/mongocrypt-util-private.h +11 -21
  259. data/ext/libmongocrypt/libmongocrypt/src/mongocrypt-util.c +98 -136
  260. data/ext/libmongocrypt/libmongocrypt/src/mongocrypt.c +924 -1339
  261. data/ext/libmongocrypt/libmongocrypt/src/mongocrypt.h +199 -313
  262. data/ext/libmongocrypt/libmongocrypt/src/os_posix/os_dll.c +83 -79
  263. data/ext/libmongocrypt/libmongocrypt/src/os_posix/os_mutex.c +20 -28
  264. data/ext/libmongocrypt/libmongocrypt/src/os_win/os_dll.c +64 -73
  265. data/ext/libmongocrypt/libmongocrypt/src/os_win/os_mutex.c +8 -16
  266. data/ext/libmongocrypt/libmongocrypt/test/crypt_shared-stub.cpp +57 -87
  267. data/ext/libmongocrypt/libmongocrypt/test/data/bulkWrite/bypassQueryAnalysis/payload.json +53 -0
  268. data/ext/libmongocrypt/libmongocrypt/test/data/bulkWrite/jsonSchema/cmd-to-mongocryptd.json +23 -0
  269. data/ext/libmongocrypt/libmongocrypt/test/data/bulkWrite/jsonSchema/cmd.json +20 -0
  270. data/ext/libmongocrypt/libmongocrypt/test/data/bulkWrite/simple/cmd-to-mongocryptd.json +50 -0
  271. data/ext/libmongocrypt/libmongocrypt/test/data/bulkWrite/simple/cmd.json +20 -0
  272. data/ext/libmongocrypt/libmongocrypt/test/data/bulkWrite/simple/collinfo.json +44 -0
  273. data/ext/libmongocrypt/libmongocrypt/test/data/bulkWrite/simple/encrypted-field-map.json +24 -0
  274. data/ext/libmongocrypt/libmongocrypt/test/data/bulkWrite/simple/encrypted-payload-pattern.json +53 -0
  275. data/ext/libmongocrypt/libmongocrypt/test/data/bulkWrite/simple/mongocryptd-reply.json +62 -0
  276. data/ext/libmongocrypt/libmongocrypt/test/data/bulkWrite/unencrypted/cmd-to-mongocryptd.json +30 -0
  277. data/ext/libmongocrypt/libmongocrypt/test/data/bulkWrite/unencrypted/cmd.json +17 -0
  278. data/ext/libmongocrypt/libmongocrypt/test/data/bulkWrite/unencrypted/mongocryptd-reply.json +39 -0
  279. data/ext/libmongocrypt/libmongocrypt/test/data/bulkWrite/unencrypted/payload.json +21 -0
  280. data/ext/libmongocrypt/libmongocrypt/test/data/cleanup/missing-key-id/collinfo.json +20 -0
  281. data/ext/libmongocrypt/libmongocrypt/test/data/cleanup/no-fields/collinfo.json +9 -0
  282. data/ext/libmongocrypt/libmongocrypt/test/data/cleanup/no-fields/encrypted-payload.json +4 -0
  283. data/ext/libmongocrypt/libmongocrypt/test/data/cleanup/success/cmd.json +1 -0
  284. data/ext/libmongocrypt/libmongocrypt/test/data/cleanup/success/collinfo.json +63 -0
  285. data/ext/libmongocrypt/libmongocrypt/test/data/cleanup/success/encrypted-field-config-map.json +61 -0
  286. data/ext/libmongocrypt/libmongocrypt/test/data/cleanup/success/encrypted-payload-range-v2.json +37 -0
  287. data/ext/libmongocrypt/libmongocrypt/test/data/cleanup/success/encrypted-payload.json +29 -0
  288. data/ext/libmongocrypt/libmongocrypt/test/data/compact/anchor-pad/cmd.json +1 -0
  289. data/ext/libmongocrypt/libmongocrypt/test/data/compact/anchor-pad/collinfo.json +64 -0
  290. data/ext/libmongocrypt/libmongocrypt/test/data/compact/anchor-pad/encrypted-payload-range-v2.json +105 -0
  291. data/ext/libmongocrypt/libmongocrypt/test/data/compact/anchor-pad/encrypted-payload.json +30 -0
  292. data/ext/libmongocrypt/libmongocrypt/test/data/compact/no-range/cmd.json +1 -0
  293. data/ext/libmongocrypt/libmongocrypt/test/data/compact/no-range/collinfo.json +49 -0
  294. data/ext/libmongocrypt/libmongocrypt/test/data/compact/no-range/encrypted-field-config-map.json +47 -0
  295. data/ext/libmongocrypt/libmongocrypt/test/data/compact/no-range/encrypted-payload.json +23 -0
  296. data/ext/libmongocrypt/libmongocrypt/test/data/compact/success/collinfo.json +15 -0
  297. data/ext/libmongocrypt/libmongocrypt/test/data/compact/success/encrypted-field-config-map.json +10 -0
  298. data/ext/libmongocrypt/libmongocrypt/test/data/compact/success/encrypted-payload-range-v2.json +104 -0
  299. data/ext/libmongocrypt/libmongocrypt/test/data/compact/success/encrypted-payload.json +6 -0
  300. data/ext/libmongocrypt/libmongocrypt/test/data/fle2-delete/empty/encrypted-payload-v2.json +60 -0
  301. data/ext/libmongocrypt/libmongocrypt/test/data/fle2-delete/success/encrypted-payload-v2.json +67 -0
  302. data/ext/libmongocrypt/libmongocrypt/test/data/fle2-explain/with-csfle/collinfo.json +4 -4
  303. data/ext/libmongocrypt/libmongocrypt/test/data/fle2-explain/with-csfle/encrypted-payload.json +5 -5
  304. data/ext/libmongocrypt/libmongocrypt/test/data/fle2-explicit/find-indexed-contentionFactor1-v2.json +8 -0
  305. data/ext/libmongocrypt/libmongocrypt/test/data/fle2-explicit/find-indexed-v2.json +8 -0
  306. data/ext/libmongocrypt/libmongocrypt/test/data/fle2-explicit/insert-indexed-contentionFactor1-v2.json +8 -0
  307. data/ext/libmongocrypt/libmongocrypt/test/data/fle2-explicit/insert-indexed-same-user-and-index-key-v2.json +8 -0
  308. data/ext/libmongocrypt/libmongocrypt/test/data/fle2-explicit/insert-indexed-v2.json +8 -0
  309. data/ext/libmongocrypt/libmongocrypt/test/data/fle2-find-equality-v2/cmd.json +6 -0
  310. data/ext/libmongocrypt/libmongocrypt/test/data/fle2-find-equality-v2/encrypted-field-map.json +22 -0
  311. data/ext/libmongocrypt/libmongocrypt/test/data/fle2-find-equality-v2/encrypted-payload.json +40 -0
  312. data/ext/libmongocrypt/libmongocrypt/test/data/fle2-find-equality-v2/mongocryptd-reply.json +19 -0
  313. data/ext/libmongocrypt/libmongocrypt/test/data/fle2-find-range/date-v2/cmd.json +10 -0
  314. data/ext/libmongocrypt/libmongocrypt/test/data/fle2-find-range/date-v2/encrypted-field-map.json +27 -0
  315. data/ext/libmongocrypt/libmongocrypt/test/data/fle2-find-range/date-v2/encrypted-payload.json +41 -0
  316. data/ext/libmongocrypt/libmongocrypt/test/data/fle2-find-range/date-v2/mongocryptd-reply.json +49 -0
  317. data/ext/libmongocrypt/libmongocrypt/test/data/fle2-find-range/decimal128-precision-v2/cmd.json +6 -0
  318. data/ext/libmongocrypt/libmongocrypt/test/data/fle2-find-range/decimal128-precision-v2/encrypted-field-map.json +30 -0
  319. data/ext/libmongocrypt/libmongocrypt/test/data/fle2-find-range/decimal128-precision-v2/encrypted-payload.json +50 -0
  320. data/ext/libmongocrypt/libmongocrypt/test/data/fle2-find-range/decimal128-precision-v2/mongocryptd-reply.json +58 -0
  321. data/ext/libmongocrypt/libmongocrypt/test/data/fle2-find-range/decimal128-v2/cmd.json +6 -0
  322. data/ext/libmongocrypt/libmongocrypt/test/data/fle2-find-range/decimal128-v2/encrypted-field-map.json +27 -0
  323. data/ext/libmongocrypt/libmongocrypt/test/data/fle2-find-range/decimal128-v2/encrypted-payload.json +41 -0
  324. data/ext/libmongocrypt/libmongocrypt/test/data/fle2-find-range/decimal128-v2/mongocryptd-reply.json +49 -0
  325. data/ext/libmongocrypt/libmongocrypt/test/data/fle2-find-range/double-precision-v2/cmd.json +8 -0
  326. data/ext/libmongocrypt/libmongocrypt/test/data/fle2-find-range/double-precision-v2/encrypted-field-map.json +30 -0
  327. data/ext/libmongocrypt/libmongocrypt/test/data/fle2-find-range/double-precision-v2/encrypted-payload.json +44 -0
  328. data/ext/libmongocrypt/libmongocrypt/test/data/fle2-find-range/double-precision-v2/mongocryptd-reply.json +52 -0
  329. data/ext/libmongocrypt/libmongocrypt/test/data/fle2-find-range/double-v2/cmd.json +8 -0
  330. data/ext/libmongocrypt/libmongocrypt/test/data/fle2-find-range/double-v2/encrypted-field-map.json +27 -0
  331. data/ext/libmongocrypt/libmongocrypt/test/data/fle2-find-range/double-v2/encrypted-payload.json +41 -0
  332. data/ext/libmongocrypt/libmongocrypt/test/data/fle2-find-range/double-v2/mongocryptd-reply.json +49 -0
  333. data/ext/libmongocrypt/libmongocrypt/test/data/fle2-find-range/int32-v2/cmd.json +8 -0
  334. data/ext/libmongocrypt/libmongocrypt/test/data/fle2-find-range/int32-v2/encrypted-field-map.json +27 -0
  335. data/ext/libmongocrypt/libmongocrypt/test/data/fle2-find-range/int32-v2/encrypted-payload.json +41 -0
  336. data/ext/libmongocrypt/libmongocrypt/test/data/fle2-find-range/int32-v2/mongocryptd-reply.json +49 -0
  337. data/ext/libmongocrypt/libmongocrypt/test/data/fle2-find-range/int64-v2/cmd.json +8 -0
  338. data/ext/libmongocrypt/libmongocrypt/test/data/fle2-find-range/int64-v2/encrypted-field-map.json +27 -0
  339. data/ext/libmongocrypt/libmongocrypt/test/data/fle2-find-range/int64-v2/encrypted-payload.json +41 -0
  340. data/ext/libmongocrypt/libmongocrypt/test/data/fle2-find-range/int64-v2/mongocryptd-reply.json +49 -0
  341. data/ext/libmongocrypt/libmongocrypt/test/data/fle2-find-range-explicit/double/encrypted-payload-v2.json +26 -0
  342. data/ext/libmongocrypt/libmongocrypt/test/data/fle2-find-range-explicit/double-precision/encrypted-payload-v2.json +26 -0
  343. data/ext/libmongocrypt/libmongocrypt/test/data/fle2-find-range-explicit/int32/encrypted-payload-v2.json +26 -0
  344. data/ext/libmongocrypt/libmongocrypt/test/data/fle2-find-range-explicit/int32-nominmax/encrypted-payload-v2.json +26 -0
  345. data/ext/libmongocrypt/libmongocrypt/test/data/fle2-find-range-explicit/int32-openinterval/encrypted-payload-v2.json +16 -0
  346. data/ext/libmongocrypt/libmongocrypt/test/data/fle2-insert/cmd.json +1 -1
  347. data/ext/libmongocrypt/libmongocrypt/test/data/fle2-insert-range/date/RNG_DATA.h +65 -65
  348. data/ext/libmongocrypt/libmongocrypt/test/data/fle2-insert-range/date-v2/cmd.json +13 -0
  349. data/ext/libmongocrypt/libmongocrypt/test/data/fle2-insert-range/date-v2/encrypted-field-map.json +27 -0
  350. data/ext/libmongocrypt/libmongocrypt/test/data/fle2-insert-range/date-v2/encrypted-payload.json +44 -0
  351. data/ext/libmongocrypt/libmongocrypt/test/data/fle2-insert-range/date-v2/mongocryptd-reply.json +52 -0
  352. data/ext/libmongocrypt/libmongocrypt/test/data/fle2-insert-range/decimal128/RNG_DATA.h +132 -132
  353. data/ext/libmongocrypt/libmongocrypt/test/data/fle2-insert-range/decimal128-precision/RNG_DATA.h +71 -71
  354. data/ext/libmongocrypt/libmongocrypt/test/data/fle2-insert-range/decimal128-precision-v2/cmd.json +9 -0
  355. data/ext/libmongocrypt/libmongocrypt/test/data/fle2-insert-range/decimal128-precision-v2/encrypted-field-map.json +30 -0
  356. data/ext/libmongocrypt/libmongocrypt/test/data/fle2-insert-range/decimal128-precision-v2/encrypted-payload.json +53 -0
  357. data/ext/libmongocrypt/libmongocrypt/test/data/fle2-insert-range/decimal128-precision-v2/mongocryptd-reply.json +61 -0
  358. data/ext/libmongocrypt/libmongocrypt/test/data/fle2-insert-range/decimal128-v2/cmd.json +9 -0
  359. data/ext/libmongocrypt/libmongocrypt/test/data/fle2-insert-range/decimal128-v2/encrypted-field-map.json +27 -0
  360. data/ext/libmongocrypt/libmongocrypt/test/data/fle2-insert-range/decimal128-v2/encrypted-payload.json +44 -0
  361. data/ext/libmongocrypt/libmongocrypt/test/data/fle2-insert-range/decimal128-v2/mongocryptd-reply.json +52 -0
  362. data/ext/libmongocrypt/libmongocrypt/test/data/fle2-insert-range/double/RNG_DATA.h +68 -68
  363. data/ext/libmongocrypt/libmongocrypt/test/data/fle2-insert-range/double-precision/RNG_DATA.h +19 -19
  364. data/ext/libmongocrypt/libmongocrypt/test/data/fle2-insert-range/double-precision-v2/cmd.json +11 -0
  365. data/ext/libmongocrypt/libmongocrypt/test/data/fle2-insert-range/double-precision-v2/encrypted-field-map.json +30 -0
  366. data/ext/libmongocrypt/libmongocrypt/test/data/fle2-insert-range/double-precision-v2/encrypted-payload.json +47 -0
  367. data/ext/libmongocrypt/libmongocrypt/test/data/fle2-insert-range/double-precision-v2/mongocryptd-reply.json +55 -0
  368. data/ext/libmongocrypt/libmongocrypt/test/data/fle2-insert-range/double-v2/cmd.json +11 -0
  369. data/ext/libmongocrypt/libmongocrypt/test/data/fle2-insert-range/double-v2/encrypted-field-map.json +27 -0
  370. data/ext/libmongocrypt/libmongocrypt/test/data/fle2-insert-range/double-v2/encrypted-payload.json +44 -0
  371. data/ext/libmongocrypt/libmongocrypt/test/data/fle2-insert-range/double-v2/mongocryptd-reply.json +52 -0
  372. data/ext/libmongocrypt/libmongocrypt/test/data/fle2-insert-range/int32/RNG_DATA.h +25 -25
  373. data/ext/libmongocrypt/libmongocrypt/test/data/fle2-insert-range/int32-v2/cmd.json +11 -0
  374. data/ext/libmongocrypt/libmongocrypt/test/data/fle2-insert-range/int32-v2/encrypted-field-map.json +27 -0
  375. data/ext/libmongocrypt/libmongocrypt/test/data/fle2-insert-range/int32-v2/encrypted-payload.json +44 -0
  376. data/ext/libmongocrypt/libmongocrypt/test/data/fle2-insert-range/int32-v2/mongocryptd-reply.json +52 -0
  377. data/ext/libmongocrypt/libmongocrypt/test/data/fle2-insert-range/int64/RNG_DATA.h +65 -65
  378. data/ext/libmongocrypt/libmongocrypt/test/data/fle2-insert-range/int64-v2/cmd.json +11 -0
  379. data/ext/libmongocrypt/libmongocrypt/test/data/fle2-insert-range/int64-v2/encrypted-field-map.json +27 -0
  380. data/ext/libmongocrypt/libmongocrypt/test/data/fle2-insert-range/int64-v2/encrypted-payload.json +44 -0
  381. data/ext/libmongocrypt/libmongocrypt/test/data/fle2-insert-range/int64-v2/mongocryptd-reply.json +52 -0
  382. data/ext/libmongocrypt/libmongocrypt/test/data/fle2-insert-range-explicit/double/RNG_DATA.h +68 -68
  383. data/ext/libmongocrypt/libmongocrypt/test/data/fle2-insert-range-explicit/double/encrypted-payload-v2.json +8 -0
  384. data/ext/libmongocrypt/libmongocrypt/test/data/fle2-insert-range-explicit/double-precision/RNG_DATA.h +19 -19
  385. data/ext/libmongocrypt/libmongocrypt/test/data/fle2-insert-range-explicit/double-precision/encrypted-payload-v2.json +8 -0
  386. data/ext/libmongocrypt/libmongocrypt/test/data/fle2-insert-range-explicit/int32/RNG_DATA.h +25 -25
  387. data/ext/libmongocrypt/libmongocrypt/test/data/fle2-insert-range-explicit/int32/encrypted-payload-v2.json +8 -0
  388. data/ext/libmongocrypt/libmongocrypt/test/data/fle2-insert-range-explicit/int32-nominmax/encrypted-payload-v2.json +8 -0
  389. data/ext/libmongocrypt/libmongocrypt/test/data/fle2-insert-range-explicit/sparsity-2/RNG_DATA.h +15 -15
  390. data/ext/libmongocrypt/libmongocrypt/test/data/fle2-insert-range-explicit/sparsity-2/encrypted-payload-v2.json +8 -0
  391. data/ext/libmongocrypt/libmongocrypt/test/data/fle2-insert-unindexed-v2/cmd.json +9 -0
  392. data/ext/libmongocrypt/libmongocrypt/test/data/fle2-insert-unindexed-v2/encrypted-field-map.json +18 -0
  393. data/ext/libmongocrypt/libmongocrypt/test/data/fle2-insert-unindexed-v2/encrypted-payload.json +14 -0
  394. data/ext/libmongocrypt/libmongocrypt/test/data/fle2-insert-unindexed-v2/mongocryptd-reply.json +41 -0
  395. data/ext/libmongocrypt/libmongocrypt/test/data/fle2-insert-v2/cmd.json +9 -0
  396. data/ext/libmongocrypt/libmongocrypt/test/data/fle2-insert-v2/encrypted-field-map.json +22 -0
  397. data/ext/libmongocrypt/libmongocrypt/test/data/fle2-insert-v2/encrypted-payload.json +39 -0
  398. data/ext/libmongocrypt/libmongocrypt/test/data/fle2-insert-v2/mongocryptd-reply.json +49 -0
  399. data/ext/libmongocrypt/libmongocrypt/test/data/iev-v2/FLECrudTest-insertOneRangeV2.json +10 -0
  400. data/ext/libmongocrypt/libmongocrypt/test/data/iev-v2/FLECrudTest-insertOneV2.json +10 -0
  401. data/ext/libmongocrypt/libmongocrypt/test/data/kms-azure/decrypt-response.txt +16 -0
  402. data/ext/libmongocrypt/libmongocrypt/test/data/kms-azure/encrypt-response.txt +16 -0
  403. data/ext/libmongocrypt/libmongocrypt/test/data/kms-azure/oauth-response.txt +19 -0
  404. data/ext/libmongocrypt/libmongocrypt/test/data/no-trimFactor/find/cmd.json +9 -0
  405. data/ext/libmongocrypt/libmongocrypt/test/data/no-trimFactor/find/encrypted-field-map.json +19 -0
  406. data/ext/libmongocrypt/libmongocrypt/test/data/no-trimFactor/find/encrypted-payload.json +62 -0
  407. data/ext/libmongocrypt/libmongocrypt/test/data/no-trimFactor/find/mongocryptd-reply.json +69 -0
  408. data/ext/libmongocrypt/libmongocrypt/test/data/no-trimFactor/insert/cmd.json +11 -0
  409. data/ext/libmongocrypt/libmongocrypt/test/data/no-trimFactor/insert/encrypted-field-map.json +19 -0
  410. data/ext/libmongocrypt/libmongocrypt/test/data/no-trimFactor/insert/encrypted-payload.json +40 -0
  411. data/ext/libmongocrypt/libmongocrypt/test/data/no-trimFactor/insert/mongocryptd-reply.json +47 -0
  412. data/ext/libmongocrypt/libmongocrypt/test/data/range-edge-generation/edges_decimal128.cstruct +1 -1
  413. data/ext/libmongocrypt/libmongocrypt/test/data/range-edge-generation/edges_double.cstruct +8637 -7958
  414. data/ext/libmongocrypt/libmongocrypt/test/data/range-edge-generation/edges_int32.cstruct +5522 -1382
  415. data/ext/libmongocrypt/libmongocrypt/test/data/range-edge-generation/edges_int64.cstruct +5042 -1262
  416. data/ext/libmongocrypt/libmongocrypt/test/data/range-min-cover/mincover_decimal128.cstruct +1 -1
  417. data/ext/libmongocrypt/libmongocrypt/test/data/range-min-cover/mincover_decimal128_precision.cstruct +1 -1
  418. data/ext/libmongocrypt/libmongocrypt/test/data/range-min-cover/mincover_double.cstruct +1 -1
  419. data/ext/libmongocrypt/libmongocrypt/test/data/range-min-cover/mincover_double_precision.cstruct +2 -2
  420. data/ext/libmongocrypt/libmongocrypt/test/data/range-min-cover/mincover_int32.cstruct +1 -1
  421. data/ext/libmongocrypt/libmongocrypt/test/data/range-min-cover/mincover_int64.cstruct +1 -1
  422. data/ext/libmongocrypt/libmongocrypt/test/data/range-sends-cryptoParams/auto-find-int32/cmd.json +8 -0
  423. data/ext/libmongocrypt/libmongocrypt/test/data/range-sends-cryptoParams/auto-find-int32/encrypted-field-map.json +19 -0
  424. data/ext/libmongocrypt/libmongocrypt/test/data/range-sends-cryptoParams/auto-find-int32/encrypted-payload.json +53 -0
  425. data/ext/libmongocrypt/libmongocrypt/test/data/range-sends-cryptoParams/auto-find-int32/mongocryptd-reply.json +58 -0
  426. data/ext/libmongocrypt/libmongocrypt/test/data/range-sends-cryptoParams/auto-insert-int32/cmd.json +11 -0
  427. data/ext/libmongocrypt/libmongocrypt/test/data/range-sends-cryptoParams/auto-insert-int32/encrypted-field-map.json +19 -0
  428. data/ext/libmongocrypt/libmongocrypt/test/data/range-sends-cryptoParams/auto-insert-int32/encrypted-payload.json +40 -0
  429. data/ext/libmongocrypt/libmongocrypt/test/data/range-sends-cryptoParams/auto-insert-int32/mongocryptd-reply.json +45 -0
  430. data/ext/libmongocrypt/libmongocrypt/test/data/range-sends-cryptoParams/explicit-find-int32/expected.json +26 -0
  431. data/ext/libmongocrypt/libmongocrypt/test/data/range-sends-cryptoParams/explicit-find-int32/to-encrypt.json +20 -0
  432. data/ext/libmongocrypt/libmongocrypt/test/data/range-sends-cryptoParams/explicit-find-int32-defaults/expected.json +26 -0
  433. data/ext/libmongocrypt/libmongocrypt/test/data/range-sends-cryptoParams/explicit-find-int32-defaults/to-encrypt.json +20 -0
  434. data/ext/libmongocrypt/libmongocrypt/test/data/range-sends-cryptoParams/explicit-insert-double/expected.json +8 -0
  435. data/ext/libmongocrypt/libmongocrypt/test/data/range-sends-cryptoParams/explicit-insert-int32/expected.json +8 -0
  436. data/ext/libmongocrypt/libmongocrypt/test/data/range-sends-cryptoParams/explicit-insert-int32-defaults/expected.json +8 -0
  437. data/ext/libmongocrypt/libmongocrypt/test/data/roundtrip/README.md +17 -0
  438. data/ext/libmongocrypt/libmongocrypt/test/data/roundtrip/aes-ctr.json +29 -0
  439. data/ext/libmongocrypt/libmongocrypt/test/data/roundtrip/fle2-fixed.json +10 -0
  440. data/ext/libmongocrypt/libmongocrypt/test/data/roundtrip/fle2-generated.json +38 -0
  441. data/ext/libmongocrypt/libmongocrypt/test/data/roundtrip/fle2aead-decrypt.json +35 -0
  442. data/ext/libmongocrypt/libmongocrypt/test/data/roundtrip/fle2aead-fixed.json +29 -0
  443. data/ext/libmongocrypt/libmongocrypt/test/data/roundtrip/fle2aead-generated.json +122 -0
  444. data/ext/libmongocrypt/libmongocrypt/test/data/roundtrip/fle2v2-aead-fixed.json +29 -0
  445. data/ext/libmongocrypt/libmongocrypt/test/data/roundtrip/fle2v2-aead-generated.json +122 -0
  446. data/ext/libmongocrypt/libmongocrypt/test/data/roundtrip/mcgrew.json +12 -0
  447. data/ext/libmongocrypt/libmongocrypt/test/data/roundtrip/nist.json +20 -0
  448. data/ext/libmongocrypt/libmongocrypt/test/data/tokens/README.md +30 -0
  449. data/ext/libmongocrypt/libmongocrypt/test/data/tokens/mc.json +25 -0
  450. data/ext/libmongocrypt/libmongocrypt/test/data/tokens/server.json +25 -0
  451. data/ext/libmongocrypt/libmongocrypt/test/example-no-bson.c +4 -4
  452. data/ext/libmongocrypt/libmongocrypt/test/example-state-machine.c +279 -323
  453. data/ext/libmongocrypt/libmongocrypt/test/fuzz_kms.c +8 -7
  454. data/ext/libmongocrypt/libmongocrypt/test/test-dll.cpp +6 -7
  455. data/ext/libmongocrypt/libmongocrypt/test/test-gcp-auth.c +221 -283
  456. data/ext/libmongocrypt/libmongocrypt/test/test-mc-efc.c +60 -73
  457. data/ext/libmongocrypt/libmongocrypt/test/test-mc-fle2-find-equality-payload-v2.c +78 -0
  458. data/ext/libmongocrypt/libmongocrypt/test/test-mc-fle2-find-range-payload-v2.c +129 -0
  459. data/ext/libmongocrypt/libmongocrypt/test/test-mc-fle2-payload-iev-v2.c +248 -0
  460. data/ext/libmongocrypt/libmongocrypt/test/test-mc-fle2-payload-iev.c +467 -414
  461. data/ext/libmongocrypt/libmongocrypt/test/test-mc-fle2-payload-iup-v2.c +248 -0
  462. data/ext/libmongocrypt/libmongocrypt/test/test-mc-fle2-payload-iup.c +141 -159
  463. data/ext/libmongocrypt/libmongocrypt/test/test-mc-fle2-payload-uev-v2.c +338 -0
  464. data/ext/libmongocrypt/libmongocrypt/test/test-mc-fle2-payload-uev.c +238 -176
  465. data/ext/libmongocrypt/libmongocrypt/test/test-mc-fle2-rfds.c +373 -474
  466. data/ext/libmongocrypt/libmongocrypt/test/test-mc-range-edge-generation.c +421 -388
  467. data/ext/libmongocrypt/libmongocrypt/test/test-mc-range-encoding.c +974 -825
  468. data/ext/libmongocrypt/libmongocrypt/test/test-mc-range-mincover.c +499 -481
  469. data/ext/libmongocrypt/libmongocrypt/test/test-mc-rangeopts.c +312 -148
  470. data/ext/libmongocrypt/libmongocrypt/test/test-mc-reader.c +124 -207
  471. data/ext/libmongocrypt/libmongocrypt/test/test-mc-tokens.c +249 -213
  472. data/ext/libmongocrypt/libmongocrypt/test/test-mc-writer.c +176 -0
  473. data/ext/libmongocrypt/libmongocrypt/test/test-mongocrypt-assert-match-bson.c +632 -808
  474. data/ext/libmongocrypt/libmongocrypt/test/test-mongocrypt-assert-match-bson.h +22 -2
  475. data/ext/libmongocrypt/libmongocrypt/test/test-mongocrypt-assert.h +168 -189
  476. data/ext/libmongocrypt/libmongocrypt/test/test-mongocrypt-buffer.c +187 -211
  477. data/ext/libmongocrypt/libmongocrypt/test/test-mongocrypt-cache-oauth.c +118 -37
  478. data/ext/libmongocrypt/libmongocrypt/test/test-mongocrypt-cache.c +210 -233
  479. data/ext/libmongocrypt/libmongocrypt/test/test-mongocrypt-ciphertext.c +185 -220
  480. data/ext/libmongocrypt/libmongocrypt/test/test-mongocrypt-cleanup.c +374 -0
  481. data/ext/libmongocrypt/libmongocrypt/test/test-mongocrypt-compact.c +410 -445
  482. data/ext/libmongocrypt/libmongocrypt/test/test-mongocrypt-crypto-hooks.c +798 -812
  483. data/ext/libmongocrypt/libmongocrypt/test/test-mongocrypt-crypto-std-hooks.c +142 -135
  484. data/ext/libmongocrypt/libmongocrypt/test/test-mongocrypt-crypto-std-hooks.h +70 -71
  485. data/ext/libmongocrypt/libmongocrypt/test/test-mongocrypt-crypto.c +394 -846
  486. data/ext/libmongocrypt/libmongocrypt/test/test-mongocrypt-csfle-lib.c +159 -183
  487. data/ext/libmongocrypt/libmongocrypt/test/test-mongocrypt-ctx-decrypt.c +870 -1045
  488. data/ext/libmongocrypt/libmongocrypt/test/test-mongocrypt-ctx-encrypt.c +5183 -4717
  489. data/ext/libmongocrypt/libmongocrypt/test/test-mongocrypt-ctx-rewrap-many-datakey.c +750 -964
  490. data/ext/libmongocrypt/libmongocrypt/test/test-mongocrypt-ctx-setopt.c +1093 -1178
  491. data/ext/libmongocrypt/libmongocrypt/test/test-mongocrypt-datakey.c +348 -420
  492. data/ext/libmongocrypt/libmongocrypt/test/test-mongocrypt-dll.c +23 -30
  493. data/ext/libmongocrypt/libmongocrypt/test/test-mongocrypt-endpoint.c +98 -111
  494. data/ext/libmongocrypt/libmongocrypt/test/test-mongocrypt-kek.c +49 -52
  495. data/ext/libmongocrypt/libmongocrypt/test/test-mongocrypt-key-broker.c +770 -920
  496. data/ext/libmongocrypt/libmongocrypt/test/test-mongocrypt-key-cache.c +354 -407
  497. data/ext/libmongocrypt/libmongocrypt/test/test-mongocrypt-key.c +197 -245
  498. data/ext/libmongocrypt/libmongocrypt/test/test-mongocrypt-kms-ctx.c +705 -368
  499. data/ext/libmongocrypt/libmongocrypt/test/test-mongocrypt-kms-responses.c +147 -166
  500. data/ext/libmongocrypt/libmongocrypt/test/test-mongocrypt-local-kms.c +50 -61
  501. data/ext/libmongocrypt/libmongocrypt/test/test-mongocrypt-log.c +85 -100
  502. data/ext/libmongocrypt/libmongocrypt/test/test-mongocrypt-marking.c +1073 -690
  503. data/ext/libmongocrypt/libmongocrypt/test/test-mongocrypt-opts.c +42 -0
  504. data/ext/libmongocrypt/libmongocrypt/test/test-mongocrypt-status.c +46 -58
  505. data/ext/libmongocrypt/libmongocrypt/test/test-mongocrypt-traverse-util.c +381 -451
  506. data/ext/libmongocrypt/libmongocrypt/test/test-mongocrypt-util.c +55 -67
  507. data/ext/libmongocrypt/libmongocrypt/test/test-mongocrypt-util.h +7 -10
  508. data/ext/libmongocrypt/libmongocrypt/test/test-mongocrypt.c +879 -918
  509. data/ext/libmongocrypt/libmongocrypt/test/test-mongocrypt.h +119 -169
  510. data/ext/libmongocrypt/libmongocrypt/test/test-named-kms-providers.c +2381 -0
  511. data/ext/libmongocrypt/libmongocrypt/test/util/HELP.autogen +3 -1
  512. data/ext/libmongocrypt/libmongocrypt/test/util/README.md +1 -0
  513. data/ext/libmongocrypt/libmongocrypt/test/util/csfle.c +512 -559
  514. data/ext/libmongocrypt/libmongocrypt/test/util/make_includes.py +1 -1
  515. data/ext/libmongocrypt/libmongocrypt/test/util/util.c +771 -882
  516. data/ext/libmongocrypt/libmongocrypt/test/util/util.h +33 -55
  517. data/lib/libmongocrypt_helper/version.rb +2 -2
  518. metadata +245 -111
  519. checksums.yaml.gz.sig +0 -0
  520. data/ext/libmongocrypt/libmongocrypt/VERSION_CURRENT +0 -1
  521. data/ext/libmongocrypt/libmongocrypt/bindings/java/mongocrypt/src/test/resources/fle2-find-range-explicit/int32/encrypted-payload.json +0 -26
  522. data/ext/libmongocrypt/libmongocrypt/bindings/java/mongocrypt/src/test/resources/fle2-find-range-explicit/int32/key-document.json +0 -0
  523. data/ext/libmongocrypt/libmongocrypt/bindings/node/CHANGELOG.md +0 -81
  524. data/ext/libmongocrypt/libmongocrypt/bindings/node/LICENSE +0 -201
  525. data/ext/libmongocrypt/libmongocrypt/bindings/node/binding.gyp +0 -79
  526. data/ext/libmongocrypt/libmongocrypt/bindings/node/etc/README.hbs +0 -44
  527. data/ext/libmongocrypt/libmongocrypt/bindings/node/etc/build-static.sh +0 -39
  528. data/ext/libmongocrypt/libmongocrypt/bindings/node/index.d.ts +0 -515
  529. data/ext/libmongocrypt/libmongocrypt/bindings/node/lib/autoEncrypter.js +0 -420
  530. data/ext/libmongocrypt/libmongocrypt/bindings/node/lib/buffer_pool.js +0 -123
  531. data/ext/libmongocrypt/libmongocrypt/bindings/node/lib/clientEncryption.js +0 -699
  532. data/ext/libmongocrypt/libmongocrypt/bindings/node/lib/common.js +0 -100
  533. data/ext/libmongocrypt/libmongocrypt/bindings/node/lib/credentialsProvider.js +0 -33
  534. data/ext/libmongocrypt/libmongocrypt/bindings/node/lib/cryptoCallbacks.js +0 -87
  535. data/ext/libmongocrypt/libmongocrypt/bindings/node/lib/index.js +0 -42
  536. data/ext/libmongocrypt/libmongocrypt/bindings/node/lib/mongocryptdManager.js +0 -66
  537. data/ext/libmongocrypt/libmongocrypt/bindings/node/lib/stateMachine.js +0 -487
  538. data/ext/libmongocrypt/libmongocrypt/bindings/node/package-lock.json +0 -16051
  539. data/ext/libmongocrypt/libmongocrypt/bindings/node/package.json +0 -81
  540. data/ext/libmongocrypt/libmongocrypt/bindings/node/src/mongocrypt.cc +0 -929
  541. data/ext/libmongocrypt/libmongocrypt/bindings/node/src/mongocrypt.h +0 -114
  542. data/ext/libmongocrypt/libmongocrypt/bindings/node/test/autoEncrypter.test.js +0 -953
  543. data/ext/libmongocrypt/libmongocrypt/bindings/node/test/buffer_pool.test.js +0 -91
  544. data/ext/libmongocrypt/libmongocrypt/bindings/node/test/clientEncryption.test.js +0 -701
  545. data/ext/libmongocrypt/libmongocrypt/bindings/node/test/credentialsProvider.test.js +0 -163
  546. data/ext/libmongocrypt/libmongocrypt/bindings/node/test/cryptoCallbacks.test.js +0 -284
  547. data/ext/libmongocrypt/libmongocrypt/bindings/node/test/data/README.md +0 -5
  548. data/ext/libmongocrypt/libmongocrypt/bindings/node/test/data/cmd.json +0 -6
  549. data/ext/libmongocrypt/libmongocrypt/bindings/node/test/data/collection-info.json +0 -37
  550. data/ext/libmongocrypt/libmongocrypt/bindings/node/test/data/encrypted-document-nested.json +0 -8
  551. data/ext/libmongocrypt/libmongocrypt/bindings/node/test/data/encrypted-document.json +0 -11
  552. data/ext/libmongocrypt/libmongocrypt/bindings/node/test/data/encryptedFields.json +0 -30
  553. data/ext/libmongocrypt/libmongocrypt/bindings/node/test/data/key-document.json +0 -32
  554. data/ext/libmongocrypt/libmongocrypt/bindings/node/test/data/key1-document.json +0 -30
  555. data/ext/libmongocrypt/libmongocrypt/bindings/node/test/data/mongocryptd-reply.json +0 -18
  556. data/ext/libmongocrypt/libmongocrypt/bindings/node/test/mongocryptdManager.test.js +0 -48
  557. data/ext/libmongocrypt/libmongocrypt/bindings/node/test/release.test.js +0 -59
  558. data/ext/libmongocrypt/libmongocrypt/bindings/node/test/requirements.helper.js +0 -29
  559. data/ext/libmongocrypt/libmongocrypt/bindings/node/test/stateMachine.test.js +0 -331
  560. data/ext/libmongocrypt/libmongocrypt/bindings/node/test/tools/mongodb_reporter.js +0 -325
  561. data/ext/libmongocrypt/libmongocrypt/bindings/python/setup.py +0 -84
  562. data/ext/libmongocrypt/libmongocrypt/bindings/python/test/data/fle2-find-range-explicit/int32/encrypted-payload.json +0 -26
  563. data/ext/libmongocrypt/libmongocrypt/bindings/python/test-requirements.txt +0 -12
  564. data/ext/libmongocrypt/libmongocrypt/debian/build_snapshot.sh +0 -79
  565. data/ext/libmongocrypt/libmongocrypt/debian/changelog +0 -105
  566. data/ext/libmongocrypt/libmongocrypt/debian/compat +0 -1
  567. data/ext/libmongocrypt/libmongocrypt/debian/control +0 -41
  568. data/ext/libmongocrypt/libmongocrypt/debian/copyright +0 -129
  569. data/ext/libmongocrypt/libmongocrypt/debian/gbp.conf +0 -23
  570. data/ext/libmongocrypt/libmongocrypt/debian/libmongocrypt-dev.dirs +0 -2
  571. data/ext/libmongocrypt/libmongocrypt/debian/libmongocrypt-dev.install +0 -5
  572. data/ext/libmongocrypt/libmongocrypt/debian/libmongocrypt0.dirs +0 -1
  573. data/ext/libmongocrypt/libmongocrypt/debian/libmongocrypt0.install +0 -1
  574. data/ext/libmongocrypt/libmongocrypt/debian/rules +0 -46
  575. data/ext/libmongocrypt/libmongocrypt/debian/source/format +0 -1
  576. data/ext/libmongocrypt/libmongocrypt/debian/source/lintian-overrides +0 -3
  577. data/ext/libmongocrypt/libmongocrypt/debian/source/options +0 -1
  578. data/ext/libmongocrypt/libmongocrypt/debian/watch +0 -3
  579. data/ext/libmongocrypt/libmongocrypt/test/data/aes-ctr.cstructs +0 -359
  580. data/ext/libmongocrypt/libmongocrypt/test/data/compact/success/mongocryptd-reply.json +0 -72
  581. data/ext/libmongocrypt/libmongocrypt/test/data/fle2-aead.cstructs +0 -109
  582. data/ext/libmongocrypt/libmongocrypt/test/data/fle2-find-range-explicit/int32-nominmax/encrypted-payload.json +0 -26
  583. data/ext/libmongocrypt/libmongocrypt/test/data/fle2-find-range-explicit/int32-nominmax/rangeopts.json +0 -5
  584. data/ext/libmongocrypt/libmongocrypt/test/data/fle2-insert-range-explicit/int32-nominmax/RNG_DATA.h +0 -70
  585. data/ext/libmongocrypt/libmongocrypt/test/data/fle2-insert-range-explicit/int32-nominmax/encrypted-payload.json +0 -8
  586. data/ext/libmongocrypt/libmongocrypt/test/data/fle2-insert-range-explicit/int32-nominmax/rangeopts.json +0 -5
  587. data/ext/libmongocrypt/libmongocrypt/test/data/fle2-insert-range-explicit/int32-nominmax/value-to-encrypt.json +0 -5
  588. data/ext/libmongocrypt/libmongocrypt/test/data/fle2.cstructs +0 -33
  589. data.tar.gz.sig +0 -0
  590. metadata.gz.sig +0 -0
  591. /data/ext/libmongocrypt/libmongocrypt/bindings/java/mongocrypt/src/test/resources/{fle2-find-range-explicit → fle2-find-range-explicit-v2}/int32/key-filter.json +0 -0
  592. /data/ext/libmongocrypt/libmongocrypt/bindings/java/mongocrypt/src/test/resources/{fle2-find-range-explicit → fle2-find-range-explicit-v2}/int32/value-to-encrypt.json +0 -0
  593. /data/ext/libmongocrypt/libmongocrypt/bindings/python/test/data/{fle2-find-range-explicit → fle2-find-range-explicit-v2}/int32/value-to-encrypt.json +0 -0
  594. /data/ext/libmongocrypt/libmongocrypt/bindings/{java/mongocrypt/src/test/resources/fle2-find-range-explicit → python/test/data/fle2-find-rangePreview-explicit}/int32/rangeopts.json +0 -0
  595. /data/ext/libmongocrypt/libmongocrypt/{test/data/fle2-find-range-explicit/int32-nominmax → bindings/python/test/data/fle2-find-rangePreview-explicit/int32}/value-to-encrypt.json +0 -0
  596. /data/ext/libmongocrypt/libmongocrypt/{bindings/node/test/data/kms-decrypt-reply.txt → test/data/kms-aws/decrypt-response.txt} +0 -0
  597. /data/ext/libmongocrypt/libmongocrypt/{bindings/node/test/data/kms-encrypt-reply.txt → test/data/kms-aws/encrypt-response.txt} +0 -0
  598. /data/ext/libmongocrypt/libmongocrypt/test/data/{gcp-auth → kms-gcp}/decrypt-response.txt +0 -0
  599. /data/ext/libmongocrypt/libmongocrypt/test/data/{gcp-auth → kms-gcp}/encrypt-response.txt +0 -0
  600. /data/ext/libmongocrypt/libmongocrypt/test/data/{gcp-auth → kms-gcp}/oauth-response.txt +0 -0
@@ -16,1609 +16,2053 @@
16
16
 
17
17
  #include "mc-fle-blob-subtype-private.h"
18
18
  #include "mc-fle2-encryption-placeholder-private.h"
19
+ #include "mc-fle2-find-equality-payload-private-v2.h"
19
20
  #include "mc-fle2-find-equality-payload-private.h"
21
+ #include "mc-fle2-find-range-payload-private-v2.h"
20
22
  #include "mc-fle2-find-range-payload-private.h"
23
+ #include "mc-fle2-insert-update-payload-private-v2.h"
21
24
  #include "mc-fle2-insert-update-payload-private.h"
22
25
  #include "mc-fle2-payload-uev-private.h"
23
- #include "mc-range-mincover-private.h"
24
- #include "mc-range-encoding-private.h"
26
+ #include "mc-fle2-payload-uev-v2-private.h"
27
+ #include "mc-optional-private.h"
25
28
  #include "mc-range-edge-generation-private.h"
29
+ #include "mc-range-encoding-private.h"
30
+ #include "mc-range-mincover-private.h"
26
31
  #include "mc-tokens-private.h"
27
- #include "mongocrypt.h"
28
32
  #include "mongocrypt-buffer-private.h"
29
33
  #include "mongocrypt-ciphertext-private.h"
30
34
  #include "mongocrypt-crypto-private.h"
31
35
  #include "mongocrypt-key-broker-private.h"
32
36
  #include "mongocrypt-marking-private.h"
37
+ #include "mongocrypt-private.h"
33
38
  #include "mongocrypt-util-private.h" // mc_bson_type_to_string
39
+ #include "mongocrypt.h"
34
40
 
35
41
  #include <math.h> // isinf
36
42
 
37
43
  static bool
38
- _mongocrypt_marking_parse_fle1_placeholder (const bson_t *in,
39
- _mongocrypt_marking_t *out,
40
- mongocrypt_status_t *status)
41
- {
42
- bson_iter_t iter;
43
- bool has_ki = false, has_ka = false, has_a = false, has_v = false;
44
-
45
- BSON_ASSERT_PARAM (in);
46
- BSON_ASSERT_PARAM (out);
47
-
48
- out->type = MONGOCRYPT_MARKING_FLE1_BY_ID;
49
-
50
- if (!bson_iter_init (&iter, in)) {
51
- CLIENT_ERR ("invalid BSON");
52
- return false;
53
- }
54
-
55
- while (bson_iter_next (&iter)) {
56
- const char *field;
57
-
58
- field = bson_iter_key (&iter);
59
- BSON_ASSERT (field);
60
- if (0 == strcmp ("ki", field)) {
61
- has_ki = true;
62
- if (!_mongocrypt_buffer_from_uuid_iter (&out->key_id, &iter)) {
63
- CLIENT_ERR ("key id must be a UUID");
64
- return false;
65
- }
66
- continue;
67
- }
68
-
69
- if (0 == strcmp ("ka", field)) {
70
- has_ka = true;
71
- /* Some bson_value types are not allowed to be key alt names */
72
- const bson_value_t *value;
73
-
74
- value = bson_iter_value (&iter);
75
-
76
- if (!BSON_ITER_HOLDS_UTF8 (&iter)) {
77
- CLIENT_ERR ("key alt name must be a UTF8");
78
- return false;
79
- }
80
- /* CDRIVER-3100 We must make a copy of this value; the result of
81
- * bson_iter_value is ephemeral. */
82
- bson_value_copy (value, &out->key_alt_name);
83
- out->type = MONGOCRYPT_MARKING_FLE1_BY_ALTNAME;
84
- continue;
85
- }
86
-
87
- if (0 == strcmp ("v", field)) {
88
- has_v = true;
89
- memcpy (&out->v_iter, &iter, sizeof (bson_iter_t));
90
- continue;
91
- }
92
-
93
-
94
- if (0 == strcmp ("a", field)) {
95
- int32_t algorithm;
96
-
97
- has_a = true;
98
- if (!BSON_ITER_HOLDS_INT32 (&iter)) {
99
- CLIENT_ERR ("invalid marking, 'a' must be an int32");
100
- return false;
101
- }
102
- algorithm = bson_iter_int32 (&iter);
103
- if (algorithm != MONGOCRYPT_ENCRYPTION_ALGORITHM_DETERMINISTIC &&
104
- algorithm != MONGOCRYPT_ENCRYPTION_ALGORITHM_RANDOM) {
105
- CLIENT_ERR ("invalid algorithm value: %d", algorithm);
106
- return false;
107
- }
108
- out->algorithm = (mongocrypt_encryption_algorithm_t) algorithm;
109
- continue;
110
- }
111
-
112
- CLIENT_ERR ("unrecognized field '%s'", field);
113
- return false;
114
- }
115
-
116
- if (!has_v) {
117
- CLIENT_ERR ("no 'v' specified");
118
- return false;
119
- }
120
-
121
- if (!has_ki && !has_ka) {
122
- CLIENT_ERR ("neither 'ki' nor 'ka' specified");
123
- return false;
124
- }
125
-
126
- if (has_ki && has_ka) {
127
- CLIENT_ERR ("both 'ki' and 'ka' specified");
128
- return false;
129
- }
130
-
131
- if (!has_a) {
132
- CLIENT_ERR ("no 'a' specified");
133
- return false;
134
- }
135
-
136
- return true;
137
- }
44
+ _mongocrypt_marking_parse_fle1_placeholder(const bson_t *in, _mongocrypt_marking_t *out, mongocrypt_status_t *status) {
45
+ bson_iter_t iter = {0};
46
+ bool has_ki = false, has_ka = false, has_a = false, has_v = false;
47
+
48
+ BSON_ASSERT_PARAM(in);
49
+ BSON_ASSERT_PARAM(out);
50
+
51
+ out->type = MONGOCRYPT_MARKING_FLE1_BY_ID;
52
+
53
+ if (!bson_iter_init(&iter, in)) {
54
+ CLIENT_ERR("invalid BSON");
55
+ return false;
56
+ }
57
+
58
+ while (bson_iter_next(&iter)) {
59
+ const char *field;
60
+
61
+ field = bson_iter_key(&iter);
62
+ BSON_ASSERT(field);
63
+ if (0 == strcmp("ki", field)) {
64
+ has_ki = true;
65
+ if (!_mongocrypt_buffer_from_uuid_iter(&out->key_id, &iter)) {
66
+ CLIENT_ERR("key id must be a UUID");
67
+ return false;
68
+ }
69
+ continue;
70
+ }
138
71
 
139
- static bool
140
- _mongocrypt_marking_parse_fle2_placeholder (const bson_t *in,
141
- _mongocrypt_marking_t *out,
142
- mongocrypt_status_t *status)
143
- {
144
- BSON_ASSERT_PARAM (in);
145
- BSON_ASSERT_PARAM (out);
146
-
147
- out->type = MONGOCRYPT_MARKING_FLE2_ENCRYPTION;
148
- return mc_FLE2EncryptionPlaceholder_parse (&out->fle2, in, status);
149
- }
72
+ if (0 == strcmp("ka", field)) {
73
+ has_ka = true;
74
+ /* Some bson_value types are not allowed to be key alt names */
75
+ const bson_value_t *value;
150
76
 
151
- bool
152
- _mongocrypt_marking_parse_unowned (const _mongocrypt_buffer_t *in,
153
- _mongocrypt_marking_t *out,
154
- mongocrypt_status_t *status)
155
- {
156
- bson_t bson;
157
-
158
- BSON_ASSERT_PARAM (in);
159
- BSON_ASSERT_PARAM (out);
160
-
161
- _mongocrypt_marking_init (out);
162
- /* 5 for minimal BSON object, plus one for blob subtype */
163
- if (in->len < 6) {
164
- CLIENT_ERR ("invalid marking, length < 6");
165
- return false;
166
- }
167
-
168
- if (!bson_init_static (&bson, in->data + 1, in->len - 1) ||
169
- !bson_validate (&bson, BSON_VALIDATE_NONE, NULL)) {
170
- CLIENT_ERR ("invalid BSON");
171
- return false;
172
- }
173
-
174
- if (in->data[0] == MC_SUBTYPE_FLE1EncryptionPlaceholder) {
175
- return _mongocrypt_marking_parse_fle1_placeholder (&bson, out, status);
176
- } else if (in->data[0] == MC_SUBTYPE_FLE2EncryptionPlaceholder) {
177
- return _mongocrypt_marking_parse_fle2_placeholder (&bson, out, status);
178
- } else {
179
- CLIENT_ERR ("invalid marking, first byte must be 0 or 3");
180
- return false;
181
- }
77
+ value = bson_iter_value(&iter);
78
+
79
+ if (!BSON_ITER_HOLDS_UTF8(&iter)) {
80
+ CLIENT_ERR("key alt name must be a UTF8");
81
+ return false;
82
+ }
83
+ /* CDRIVER-3100 We must make a copy of this value; the result of
84
+ * bson_iter_value is ephemeral. */
85
+ bson_value_copy(value, &out->key_alt_name);
86
+ out->type = MONGOCRYPT_MARKING_FLE1_BY_ALTNAME;
87
+ continue;
88
+ }
89
+
90
+ if (0 == strcmp("v", field)) {
91
+ has_v = true;
92
+ memcpy(&out->v_iter, &iter, sizeof(bson_iter_t));
93
+ continue;
94
+ }
95
+
96
+ if (0 == strcmp("a", field)) {
97
+ int32_t algorithm;
98
+
99
+ has_a = true;
100
+ if (!BSON_ITER_HOLDS_INT32(&iter)) {
101
+ CLIENT_ERR("invalid marking, 'a' must be an int32");
102
+ return false;
103
+ }
104
+ algorithm = bson_iter_int32(&iter);
105
+ if (algorithm != MONGOCRYPT_ENCRYPTION_ALGORITHM_DETERMINISTIC
106
+ && algorithm != MONGOCRYPT_ENCRYPTION_ALGORITHM_RANDOM) {
107
+ CLIENT_ERR("invalid algorithm value: %d", algorithm);
108
+ return false;
109
+ }
110
+ out->algorithm = (mongocrypt_encryption_algorithm_t)algorithm;
111
+ continue;
112
+ }
113
+
114
+ CLIENT_ERR("unrecognized field '%s'", field);
115
+ return false;
116
+ }
117
+
118
+ if (!has_v) {
119
+ CLIENT_ERR("no 'v' specified");
120
+ return false;
121
+ }
122
+
123
+ if (!has_ki && !has_ka) {
124
+ CLIENT_ERR("neither 'ki' nor 'ka' specified");
125
+ return false;
126
+ }
127
+
128
+ if (has_ki && has_ka) {
129
+ CLIENT_ERR("both 'ki' and 'ka' specified");
130
+ return false;
131
+ }
132
+
133
+ if (!has_a) {
134
+ CLIENT_ERR("no 'a' specified");
135
+ return false;
136
+ }
137
+
138
+ return true;
182
139
  }
183
140
 
141
+ static bool
142
+ _mongocrypt_marking_parse_fle2_placeholder(const bson_t *in, _mongocrypt_marking_t *out, mongocrypt_status_t *status) {
143
+ BSON_ASSERT_PARAM(in);
144
+ BSON_ASSERT_PARAM(out);
184
145
 
185
- void
186
- _mongocrypt_marking_init (_mongocrypt_marking_t *marking)
187
- {
188
- BSON_ASSERT_PARAM (marking);
146
+ out->type = MONGOCRYPT_MARKING_FLE2_ENCRYPTION;
147
+ return mc_FLE2EncryptionPlaceholder_parse(&out->fle2, in, status);
148
+ }
189
149
 
190
- memset (marking, 0, sizeof (*marking));
150
+ bool _mongocrypt_marking_parse_unowned(const _mongocrypt_buffer_t *in,
151
+ _mongocrypt_marking_t *out,
152
+ mongocrypt_status_t *status) {
153
+ bson_t bson;
154
+
155
+ BSON_ASSERT_PARAM(in);
156
+ BSON_ASSERT_PARAM(out);
157
+
158
+ _mongocrypt_marking_init(out);
159
+ /* 5 for minimal BSON object, plus one for blob subtype */
160
+ if (in->len < 6) {
161
+ CLIENT_ERR("invalid marking, length < 6");
162
+ return false;
163
+ }
164
+
165
+ if (!bson_init_static(&bson, in->data + 1, in->len - 1) || !bson_validate(&bson, BSON_VALIDATE_NONE, NULL)) {
166
+ CLIENT_ERR("invalid BSON");
167
+ return false;
168
+ }
169
+
170
+ if (in->data[0] == MC_SUBTYPE_FLE1EncryptionPlaceholder) {
171
+ return _mongocrypt_marking_parse_fle1_placeholder(&bson, out, status);
172
+ } else if (in->data[0] == MC_SUBTYPE_FLE2EncryptionPlaceholder) {
173
+ return _mongocrypt_marking_parse_fle2_placeholder(&bson, out, status);
174
+ } else {
175
+ CLIENT_ERR("invalid marking, first byte must be 0 or 3");
176
+ return false;
177
+ }
191
178
  }
192
179
 
180
+ void _mongocrypt_marking_init(_mongocrypt_marking_t *marking) {
181
+ BSON_ASSERT_PARAM(marking);
193
182
 
194
- void
195
- _mongocrypt_marking_cleanup (_mongocrypt_marking_t *marking)
196
- {
197
- if (!marking) {
198
- return;
199
- }
200
- if (marking->type == MONGOCRYPT_MARKING_FLE2_ENCRYPTION) {
201
- mc_FLE2EncryptionPlaceholder_cleanup (&marking->fle2);
202
- return;
203
- }
204
-
205
- // else FLE1
206
- _mongocrypt_buffer_cleanup (&marking->key_id);
207
- bson_value_destroy (&marking->key_alt_name);
183
+ memset(marking, 0, sizeof(*marking));
208
184
  }
209
185
 
186
+ void _mongocrypt_marking_cleanup(_mongocrypt_marking_t *marking) {
187
+ if (!marking) {
188
+ return;
189
+ }
190
+ if (marking->type == MONGOCRYPT_MARKING_FLE2_ENCRYPTION) {
191
+ mc_FLE2EncryptionPlaceholder_cleanup(&marking->fle2);
192
+ return;
193
+ }
194
+
195
+ // else FLE1
196
+ _mongocrypt_buffer_cleanup(&marking->key_id);
197
+ bson_value_destroy(&marking->key_alt_name);
198
+ }
210
199
 
211
200
  /**
212
201
  * Calculates:
213
202
  * E?CToken = HMAC(collectionLevel1Token, n)
214
203
  * E?CDerivedFromDataToken = HMAC(E?CToken, value)
215
- * E?CDerivedFromDataTokenAndCounter = HMAC(E?CDerivedFromDataToken, c)
204
+ * E?CDerivedFromDataTokenAndContentionFactor = HMAC(E?CDerivedFromDataToken, cf)
216
205
  *
217
206
  * E?C = EDC|ESC|ECC
218
207
  * n = 1 for EDC, 2 for ESC, 3 for ECC
219
- * c = maxContentionCounter
208
+ * cf = contentionFactor
220
209
  *
221
- * E?CDerivedFromDataTokenAndCounter is saved to out,
222
- * which is initialized even on failure.
210
+ * If {useContentionFactor} is False, E?CDerivedFromDataToken is saved to out, and {contentionFactor} is ignored.
211
+ * Otherwise, E?CDerivedFromDataTokenAndContentionFactor is saved to out using {contentionFactor}.
212
+ *
213
+ * Note that {out} is initialized even on failure.
223
214
  */
224
- #define DERIVE_TOKEN_IMPL(Name) \
225
- static bool _fle2_derive_##Name##_token ( \
226
- _mongocrypt_crypto_t *crypto, \
227
- _mongocrypt_buffer_t *out, \
228
- const mc_CollectionsLevel1Token_t *level1Token, \
229
- const _mongocrypt_buffer_t *value, \
230
- bool useCounter, \
231
- int64_t counter, \
232
- mongocrypt_status_t *status) \
233
- { \
234
- BSON_ASSERT_PARAM (crypto); \
235
- BSON_ASSERT_PARAM (out); \
236
- BSON_ASSERT_PARAM (level1Token); \
237
- BSON_ASSERT_PARAM (value); \
238
- \
239
- _mongocrypt_buffer_init (out); \
240
- \
241
- mc_##Name##Token_t *token = \
242
- mc_##Name##Token_new (crypto, level1Token, status); \
243
- if (!token) { \
244
- return false; \
245
- } \
246
- \
247
- mc_##Name##DerivedFromDataToken_t *fromDataToken = \
248
- mc_##Name##DerivedFromDataToken_new (crypto, token, value, status); \
249
- mc_##Name##Token_destroy (token); \
250
- if (!fromDataToken) { \
251
- return false; \
252
- } \
253
- \
254
- if (!useCounter) { \
255
- /* FindEqualityPayload uses *fromDataToken */ \
256
- _mongocrypt_buffer_copy_to ( \
257
- mc_##Name##DerivedFromDataToken_get (fromDataToken), out); \
258
- mc_##Name##DerivedFromDataToken_destroy (fromDataToken); \
259
- return true; \
260
- } \
261
- \
262
- BSON_ASSERT (counter >= 0); \
263
- /* InsertUpdatePayload continues through *fromDataTokenAndCounter */ \
264
- mc_##Name##DerivedFromDataTokenAndCounter_t *fromTokenAndCounter = \
265
- mc_##Name##DerivedFromDataTokenAndCounter_new ( \
266
- crypto, fromDataToken, (uint64_t) counter, status); \
267
- mc_##Name##DerivedFromDataToken_destroy (fromDataToken); \
268
- if (!fromTokenAndCounter) { \
269
- return false; \
270
- } \
271
- \
272
- _mongocrypt_buffer_copy_to ( \
273
- mc_##Name##DerivedFromDataTokenAndCounter_get (fromTokenAndCounter), \
274
- out); \
275
- mc_##Name##DerivedFromDataTokenAndCounter_destroy (fromTokenAndCounter); \
276
- \
277
- return true; \
278
- }
279
-
280
- DERIVE_TOKEN_IMPL (EDC)
281
- DERIVE_TOKEN_IMPL (ESC)
282
- DERIVE_TOKEN_IMPL (ECC)
215
+ #define DERIVE_TOKEN_IMPL(Name) \
216
+ static bool _fle2_derive_##Name##_token(_mongocrypt_crypto_t *crypto, \
217
+ _mongocrypt_buffer_t *out, \
218
+ const mc_CollectionsLevel1Token_t *level1Token, \
219
+ const _mongocrypt_buffer_t *value, \
220
+ bool useContentionFactor, \
221
+ int64_t contentionFactor, \
222
+ mongocrypt_status_t *status) { \
223
+ BSON_ASSERT_PARAM(crypto); \
224
+ BSON_ASSERT_PARAM(out); \
225
+ BSON_ASSERT_PARAM(level1Token); \
226
+ BSON_ASSERT_PARAM(value); \
227
+ \
228
+ _mongocrypt_buffer_init(out); \
229
+ \
230
+ mc_##Name##Token_t *token = mc_##Name##Token_new(crypto, level1Token, status); \
231
+ if (!token) { \
232
+ return false; \
233
+ } \
234
+ \
235
+ mc_##Name##DerivedFromDataToken_t *fromDataToken = \
236
+ mc_##Name##DerivedFromDataToken_new(crypto, token, value, status); \
237
+ mc_##Name##Token_destroy(token); \
238
+ if (!fromDataToken) { \
239
+ return false; \
240
+ } \
241
+ \
242
+ if (!useContentionFactor) { \
243
+ /* FindEqualityPayload uses *fromDataToken */ \
244
+ _mongocrypt_buffer_copy_to(mc_##Name##DerivedFromDataToken_get(fromDataToken), out); \
245
+ mc_##Name##DerivedFromDataToken_destroy(fromDataToken); \
246
+ return true; \
247
+ } \
248
+ \
249
+ BSON_ASSERT(contentionFactor >= 0); \
250
+ /* InsertUpdatePayload continues through *fromDataTokenAndContentionFactor */ \
251
+ mc_##Name##DerivedFromDataTokenAndContentionFactor_t *fromTokenAndContentionFactor = \
252
+ mc_##Name##DerivedFromDataTokenAndContentionFactor_new(crypto, \
253
+ fromDataToken, \
254
+ (uint64_t)contentionFactor, \
255
+ status); \
256
+ mc_##Name##DerivedFromDataToken_destroy(fromDataToken); \
257
+ if (!fromTokenAndContentionFactor) { \
258
+ return false; \
259
+ } \
260
+ \
261
+ _mongocrypt_buffer_copy_to( \
262
+ mc_##Name##DerivedFromDataTokenAndContentionFactor_get(fromTokenAndContentionFactor), \
263
+ out); \
264
+ mc_##Name##DerivedFromDataTokenAndContentionFactor_destroy(fromTokenAndContentionFactor); \
265
+ \
266
+ return true; \
267
+ }
268
+
269
+ DERIVE_TOKEN_IMPL(EDC)
270
+ DERIVE_TOKEN_IMPL(ESC)
271
+ DERIVE_TOKEN_IMPL(ECC)
283
272
 
284
273
  #undef DERIVE_TOKEN_IMPL
285
274
 
286
- static bool
287
- _fle2_placeholder_aes_ctr_encrypt (_mongocrypt_key_broker_t *kb,
288
- const _mongocrypt_buffer_t *key,
289
- const _mongocrypt_buffer_t *in,
290
- _mongocrypt_buffer_t *out,
291
- mongocrypt_status_t *status)
292
- {
293
- BSON_ASSERT_PARAM (kb);
294
- BSON_ASSERT_PARAM (key);
295
- BSON_ASSERT_PARAM (in);
296
- BSON_ASSERT_PARAM (out);
297
- BSON_ASSERT (kb->crypt);
298
-
299
- _mongocrypt_crypto_t *crypto = kb->crypt->crypto;
300
- _mongocrypt_buffer_t iv;
301
- const uint32_t cipherlen =
302
- _mongocrypt_fle2_calculate_ciphertext_len (in->len, status);
303
- if (cipherlen == 0) {
304
- return false;
305
- }
306
- uint32_t written = 0;
307
-
308
- _mongocrypt_buffer_init_size (out, cipherlen);
309
-
310
- BSON_ASSERT (
311
- _mongocrypt_buffer_from_subrange (&iv, out, 0, MONGOCRYPT_IV_LEN));
312
- if (!_mongocrypt_random (crypto, &iv, MONGOCRYPT_IV_LEN, status)) {
313
- return false;
314
- }
315
-
316
- if (!_mongocrypt_fle2_do_encryption (
317
- crypto, &iv, key, in, out, &written, status)) {
318
- _mongocrypt_buffer_cleanup (out);
319
- _mongocrypt_buffer_init (out);
320
- return false;
321
- }
322
-
323
- return true;
275
+ static bool _fle2_derive_serverDerivedFromDataToken(_mongocrypt_crypto_t *crypto,
276
+ _mongocrypt_buffer_t *out,
277
+ const mc_ServerTokenDerivationLevel1Token_t *level1Token,
278
+ const _mongocrypt_buffer_t *value,
279
+ mongocrypt_status_t *status) {
280
+ BSON_ASSERT_PARAM(crypto);
281
+ BSON_ASSERT_PARAM(out);
282
+ BSON_ASSERT_PARAM(level1Token);
283
+ BSON_ASSERT_PARAM(value);
284
+ BSON_ASSERT_PARAM(status);
285
+
286
+ _mongocrypt_buffer_init(out);
287
+
288
+ mc_ServerDerivedFromDataToken_t *token = mc_ServerDerivedFromDataToken_new(crypto, level1Token, value, status);
289
+ if (!token) {
290
+ return false;
291
+ }
292
+
293
+ _mongocrypt_buffer_copy_to(mc_ServerDerivedFromDataToken_get(token), out);
294
+ mc_ServerDerivedFromDataToken_destroy(token);
295
+ return true;
324
296
  }
325
297
 
298
+ static bool _fle2_placeholder_aes_ctr_encrypt(_mongocrypt_crypto_t *crypto,
299
+ const _mongocrypt_buffer_t *key,
300
+ const _mongocrypt_buffer_t *in,
301
+ _mongocrypt_buffer_t *out,
302
+ mongocrypt_status_t *status) {
303
+ const _mongocrypt_value_encryption_algorithm_t *fle2alg = _mcFLE2Algorithm();
304
+ BSON_ASSERT_PARAM(crypto);
305
+ BSON_ASSERT_PARAM(key);
306
+ BSON_ASSERT_PARAM(in);
307
+ BSON_ASSERT_PARAM(out);
308
+
309
+ _mongocrypt_buffer_t iv;
310
+ const uint32_t cipherlen = fle2alg->get_ciphertext_len(in->len, status);
311
+ if (cipherlen == 0) {
312
+ return false;
313
+ }
314
+ uint32_t written = 0;
315
+
316
+ _mongocrypt_buffer_init_size(out, cipherlen);
317
+
318
+ BSON_ASSERT(_mongocrypt_buffer_from_subrange(&iv, out, 0, MONGOCRYPT_IV_LEN));
319
+ if (!_mongocrypt_random(crypto, &iv, MONGOCRYPT_IV_LEN, status)) {
320
+ return false;
321
+ }
322
+
323
+ if (!fle2alg->do_encrypt(crypto, &iv, NULL /* aad */, key, in, out, &written, status)) {
324
+ _mongocrypt_buffer_cleanup(out);
325
+ _mongocrypt_buffer_init(out);
326
+ return false;
327
+ }
328
+
329
+ return true;
330
+ }
326
331
 
327
- static bool
328
- _fle2_placeholder_aead_encrypt (_mongocrypt_key_broker_t *kb,
329
- const _mongocrypt_buffer_t *keyId,
330
- const _mongocrypt_buffer_t *in,
331
- _mongocrypt_buffer_t *out,
332
- mongocrypt_status_t *status)
333
- {
334
- BSON_ASSERT_PARAM (kb);
335
- BSON_ASSERT_PARAM (keyId);
336
- BSON_ASSERT_PARAM (in);
337
- BSON_ASSERT_PARAM (out);
338
- BSON_ASSERT (kb->crypt);
339
-
340
- _mongocrypt_crypto_t *crypto = kb->crypt->crypto;
341
- _mongocrypt_buffer_t iv, key;
342
- const uint32_t cipherlen =
343
- _mongocrypt_fle2aead_calculate_ciphertext_len (in->len, status);
344
- if (cipherlen == 0) {
345
- return false;
346
- }
347
- uint32_t written = 0;
348
- bool res;
349
-
350
- if (!_mongocrypt_key_broker_decrypted_key_by_id (kb, keyId, &key)) {
351
- CLIENT_ERR ("unable to retrieve key");
352
- return false;
353
- }
354
-
355
- _mongocrypt_buffer_init_size (&iv, MONGOCRYPT_IV_LEN);
356
- if (!_mongocrypt_random (crypto, &iv, iv.len, status)) {
357
- _mongocrypt_buffer_cleanup (&key);
358
- return false;
359
- }
360
-
361
- _mongocrypt_buffer_init_size (out, cipherlen);
362
- res = _mongocrypt_fle2aead_do_encryption (
363
- crypto, &iv, keyId, &key, in, out, &written, status);
364
- _mongocrypt_buffer_cleanup (&key);
365
- _mongocrypt_buffer_cleanup (&iv);
366
-
367
- if (!res) {
368
- _mongocrypt_buffer_cleanup (out);
369
- _mongocrypt_buffer_init (out);
370
- return false;
371
- }
372
-
373
- return true;
332
+ static bool _fle2_placeholder_aes_aead_encrypt(_mongocrypt_key_broker_t *kb,
333
+ const _mongocrypt_value_encryption_algorithm_t *algorithm,
334
+ _mongocrypt_buffer_t *out,
335
+ const _mongocrypt_buffer_t *keyId,
336
+ const _mongocrypt_buffer_t *in,
337
+ mongocrypt_status_t *status) {
338
+ BSON_ASSERT_PARAM(kb);
339
+ BSON_ASSERT_PARAM(keyId);
340
+ BSON_ASSERT_PARAM(in);
341
+ BSON_ASSERT_PARAM(out);
342
+ BSON_ASSERT(kb->crypt);
343
+
344
+ _mongocrypt_crypto_t *crypto = kb->crypt->crypto;
345
+ _mongocrypt_buffer_t iv, key;
346
+ const uint32_t cipherlen = algorithm->get_ciphertext_len(in->len, status);
347
+ if (cipherlen == 0) {
348
+ return false;
349
+ }
350
+ uint32_t written = 0;
351
+ bool res;
352
+
353
+ if (!_mongocrypt_key_broker_decrypted_key_by_id(kb, keyId, &key)) {
354
+ CLIENT_ERR("unable to retrieve key");
355
+ return false;
356
+ }
357
+
358
+ _mongocrypt_buffer_init_size(&iv, MONGOCRYPT_IV_LEN);
359
+ if (!_mongocrypt_random(crypto, &iv, iv.len, status)) {
360
+ _mongocrypt_buffer_cleanup(&key);
361
+ return false;
362
+ }
363
+
364
+ _mongocrypt_buffer_init_size(out, cipherlen);
365
+ res = algorithm->do_encrypt(crypto, &iv, keyId, &key, in, out, &written, status);
366
+ _mongocrypt_buffer_cleanup(&key);
367
+ _mongocrypt_buffer_cleanup(&iv);
368
+
369
+ if (!res) {
370
+ _mongocrypt_buffer_cleanup(out);
371
+ _mongocrypt_buffer_init(out);
372
+ return false;
373
+ }
374
+
375
+ return true;
374
376
  }
375
377
 
378
+ // FLE V1: p := EncryptCTR(ECOCToken, ESCDerivedFromDataTokenAndContentionFactor ||
379
+ // ECCDerivedFromDataTokenAndContentionFactor)
380
+ // FLE V2: p := EncryptCTR(ECOCToken, ESCDerivedFromDataTokenAndContentionFactor)
381
+ // Range V2: p := EncryptCTR(ECOCToken, ESCDerivedFromDataTokenAndContentionFactor || isLeaf)
382
+ static bool _fle2_derive_encrypted_token(_mongocrypt_crypto_t *crypto,
383
+ _mongocrypt_buffer_t *out,
384
+ bool use_range_v2,
385
+ const mc_CollectionsLevel1Token_t *collectionsLevel1Token,
386
+ const _mongocrypt_buffer_t *escDerivedToken,
387
+ const _mongocrypt_buffer_t *eccDerivedToken,
388
+ mc_optional_bool_t is_leaf,
389
+ mongocrypt_status_t *status) {
390
+ mc_ECOCToken_t *ecocToken = mc_ECOCToken_new(crypto, collectionsLevel1Token, status);
391
+ if (!ecocToken) {
392
+ return false;
393
+ }
394
+ bool ok = false;
395
+
396
+ _mongocrypt_buffer_t tmp;
397
+ _mongocrypt_buffer_init(&tmp);
398
+ const _mongocrypt_buffer_t *p = &tmp;
399
+ if (!eccDerivedToken) {
400
+ // FLE2v2
401
+ if (use_range_v2 && is_leaf.set) {
402
+ // Range V2; concat isLeaf
403
+ _mongocrypt_buffer_t isLeafBuf;
404
+ if (!_mongocrypt_buffer_copy_from_data_and_size(&isLeafBuf, (uint8_t[]){is_leaf.value}, 1)) {
405
+ CLIENT_ERR("failed to create is_leaf buffer");
406
+ goto fail;
407
+ }
408
+ if (!_mongocrypt_buffer_concat(&tmp, (_mongocrypt_buffer_t[]){*escDerivedToken, isLeafBuf}, 2)) {
409
+ CLIENT_ERR("failed to allocate buffer");
410
+ _mongocrypt_buffer_cleanup(&isLeafBuf);
411
+ goto fail;
412
+ }
413
+ _mongocrypt_buffer_cleanup(&isLeafBuf);
414
+ } else {
415
+ p = escDerivedToken;
416
+ }
417
+
418
+ } else {
419
+ // FLE2v1
420
+ const _mongocrypt_buffer_t tokens[] = {*escDerivedToken, *eccDerivedToken};
421
+ if (!_mongocrypt_buffer_concat(&tmp, tokens, 2)) {
422
+ CLIENT_ERR("failed to allocate buffer");
423
+ goto fail;
424
+ }
425
+ }
426
+
427
+ if (!_fle2_placeholder_aes_ctr_encrypt(crypto, mc_ECOCToken_get(ecocToken), p, out, status)) {
428
+ goto fail;
429
+ }
430
+
431
+ ok = true;
432
+ fail:
433
+ _mongocrypt_buffer_cleanup(&tmp);
434
+ mc_ECOCToken_destroy(ecocToken);
435
+ return ok;
436
+ }
376
437
 
377
438
  // Field derivations shared by both INSERT and FIND payloads.
378
439
  typedef struct {
379
- _mongocrypt_buffer_t tokenKey;
380
- mc_CollectionsLevel1Token_t *collectionsLevel1Token;
381
- _mongocrypt_buffer_t edcDerivedToken;
382
- _mongocrypt_buffer_t escDerivedToken;
383
- _mongocrypt_buffer_t eccDerivedToken;
440
+ _mongocrypt_buffer_t tokenKey;
441
+ mc_CollectionsLevel1Token_t *collectionsLevel1Token;
442
+ mc_ServerDataEncryptionLevel1Token_t *serverDataEncryptionLevel1Token;
443
+ mc_ServerTokenDerivationLevel1Token_t *serverTokenDerivationLevel1Token; // v2
444
+ _mongocrypt_buffer_t edcDerivedToken;
445
+ _mongocrypt_buffer_t escDerivedToken;
446
+ _mongocrypt_buffer_t eccDerivedToken; // v1
447
+ _mongocrypt_buffer_t serverDerivedFromDataToken; // v2
384
448
  } _FLE2EncryptedPayloadCommon_t;
385
449
 
386
- static void
387
- _FLE2EncryptedPayloadCommon_cleanup (_FLE2EncryptedPayloadCommon_t *common)
388
- {
389
- if (!common) {
390
- return;
391
- }
392
-
393
- _mongocrypt_buffer_cleanup (&common->tokenKey);
394
- mc_CollectionsLevel1Token_destroy (common->collectionsLevel1Token);
395
- _mongocrypt_buffer_cleanup (&common->edcDerivedToken);
396
- _mongocrypt_buffer_cleanup (&common->escDerivedToken);
397
- _mongocrypt_buffer_cleanup (&common->eccDerivedToken);
398
- memset (common, 0, sizeof (*common));
450
+ static void _FLE2EncryptedPayloadCommon_cleanup(_FLE2EncryptedPayloadCommon_t *common) {
451
+ if (!common) {
452
+ return;
453
+ }
454
+
455
+ _mongocrypt_buffer_cleanup(&common->tokenKey);
456
+ mc_CollectionsLevel1Token_destroy(common->collectionsLevel1Token);
457
+ mc_ServerDataEncryptionLevel1Token_destroy(common->serverDataEncryptionLevel1Token);
458
+ mc_ServerTokenDerivationLevel1Token_destroy(common->serverTokenDerivationLevel1Token);
459
+ _mongocrypt_buffer_cleanup(&common->edcDerivedToken);
460
+ _mongocrypt_buffer_cleanup(&common->escDerivedToken);
461
+ _mongocrypt_buffer_cleanup(&common->eccDerivedToken);
462
+ _mongocrypt_buffer_cleanup(&common->serverDerivedFromDataToken);
463
+ memset(common, 0, sizeof(*common));
399
464
  }
400
465
 
401
466
  // _get_tokenKey returns the tokenKey identified by indexKeyId.
402
467
  // Returns false on error.
403
- static bool
404
- _get_tokenKey (_mongocrypt_key_broker_t *kb,
405
- const _mongocrypt_buffer_t *indexKeyId,
406
- _mongocrypt_buffer_t *tokenKey,
407
- mongocrypt_status_t *status)
408
- {
409
- BSON_ASSERT_PARAM (kb);
410
- BSON_ASSERT_PARAM (indexKeyId);
411
- BSON_ASSERT_PARAM (tokenKey);
412
-
413
- _mongocrypt_buffer_t indexKey = {0};
414
- _mongocrypt_buffer_init (tokenKey);
415
-
416
- if (!_mongocrypt_key_broker_decrypted_key_by_id (
417
- kb, indexKeyId, &indexKey)) {
418
- CLIENT_ERR ("unable to retrieve key");
419
- return false;
420
- }
421
-
422
- if (indexKey.len != MONGOCRYPT_KEY_LEN) {
423
- CLIENT_ERR ("invalid indexKey, expected len=%" PRIu32
424
- ", got len=%" PRIu32,
425
- MONGOCRYPT_KEY_LEN,
426
- indexKey.len);
427
- _mongocrypt_buffer_cleanup (&indexKey);
428
- return false;
429
- }
430
-
431
- // indexKey is 3 equal sized keys: [Ke][Km][TokenKey]
432
- BSON_ASSERT (MONGOCRYPT_KEY_LEN == (3 * MONGOCRYPT_TOKEN_KEY_LEN));
433
- if (!_mongocrypt_buffer_copy_from_data_and_size (
434
- tokenKey,
435
- indexKey.data + (2 * MONGOCRYPT_TOKEN_KEY_LEN),
436
- MONGOCRYPT_TOKEN_KEY_LEN)) {
437
- CLIENT_ERR ("failed allocating memory for token key");
438
- _mongocrypt_buffer_cleanup (&indexKey);
439
- return false;
440
- }
441
- _mongocrypt_buffer_cleanup (&indexKey);
442
- return true;
468
+ static bool _get_tokenKey(_mongocrypt_key_broker_t *kb,
469
+ const _mongocrypt_buffer_t *indexKeyId,
470
+ _mongocrypt_buffer_t *tokenKey,
471
+ mongocrypt_status_t *status) {
472
+ BSON_ASSERT_PARAM(kb);
473
+ BSON_ASSERT_PARAM(indexKeyId);
474
+ BSON_ASSERT_PARAM(tokenKey);
475
+
476
+ _mongocrypt_buffer_t indexKey = {0};
477
+ _mongocrypt_buffer_init(tokenKey);
478
+
479
+ if (!_mongocrypt_key_broker_decrypted_key_by_id(kb, indexKeyId, &indexKey)) {
480
+ CLIENT_ERR("unable to retrieve key");
481
+ return false;
482
+ }
483
+
484
+ if (indexKey.len != MONGOCRYPT_KEY_LEN) {
485
+ CLIENT_ERR("invalid indexKey, expected len=%" PRIu32 ", got len=%" PRIu32, MONGOCRYPT_KEY_LEN, indexKey.len);
486
+ _mongocrypt_buffer_cleanup(&indexKey);
487
+ return false;
488
+ }
489
+
490
+ // indexKey is 3 equal sized keys: [Ke][Km][TokenKey]
491
+ BSON_ASSERT(MONGOCRYPT_KEY_LEN == (3 * MONGOCRYPT_TOKEN_KEY_LEN));
492
+ if (!_mongocrypt_buffer_copy_from_data_and_size(tokenKey,
493
+ indexKey.data + (2 * MONGOCRYPT_TOKEN_KEY_LEN),
494
+ MONGOCRYPT_TOKEN_KEY_LEN)) {
495
+ CLIENT_ERR("failed allocating memory for token key");
496
+ _mongocrypt_buffer_cleanup(&indexKey);
497
+ return false;
498
+ }
499
+ _mongocrypt_buffer_cleanup(&indexKey);
500
+ return true;
443
501
  }
444
502
 
445
- static bool
446
- _mongocrypt_fle2_placeholder_common (_mongocrypt_key_broker_t *kb,
447
- _FLE2EncryptedPayloadCommon_t *ret,
448
- const _mongocrypt_buffer_t *indexKeyId,
449
- const _mongocrypt_buffer_t *value,
450
- bool useCounter,
451
- int64_t maxContentionCounter,
452
- mongocrypt_status_t *status)
453
- {
454
- BSON_ASSERT_PARAM (kb);
455
- BSON_ASSERT_PARAM (ret);
456
- BSON_ASSERT_PARAM (indexKeyId);
457
- BSON_ASSERT_PARAM (value);
458
-
459
- _mongocrypt_crypto_t *crypto = kb->crypt->crypto;
460
- _mongocrypt_buffer_t indexKey = {0};
461
- *ret = (_FLE2EncryptedPayloadCommon_t){{0}};
462
-
463
- if (!_get_tokenKey (kb, indexKeyId, &ret->tokenKey, status)) {
464
- goto fail;
465
- }
466
-
467
- ret->collectionsLevel1Token =
468
- mc_CollectionsLevel1Token_new (crypto, &ret->tokenKey, status);
469
- if (!ret->collectionsLevel1Token) {
470
- CLIENT_ERR ("unable to derive collectionLevel1Token");
471
- goto fail;
472
- }
473
-
474
- if (!_fle2_derive_EDC_token (crypto,
503
+ static bool _mongocrypt_fle2_placeholder_common(_mongocrypt_key_broker_t *kb,
504
+ _FLE2EncryptedPayloadCommon_t *ret,
505
+ const _mongocrypt_buffer_t *indexKeyId,
506
+ const _mongocrypt_buffer_t *value,
507
+ bool useContentionFactor,
508
+ int64_t contentionFactor,
509
+ mongocrypt_status_t *status) {
510
+ BSON_ASSERT_PARAM(kb);
511
+ BSON_ASSERT_PARAM(ret);
512
+ BSON_ASSERT_PARAM(indexKeyId);
513
+ BSON_ASSERT_PARAM(value);
514
+
515
+ _mongocrypt_crypto_t *crypto = kb->crypt->crypto;
516
+ _mongocrypt_buffer_t indexKey = {0};
517
+ *ret = (_FLE2EncryptedPayloadCommon_t){{0}};
518
+
519
+ if (!_get_tokenKey(kb, indexKeyId, &ret->tokenKey, status)) {
520
+ goto fail;
521
+ }
522
+
523
+ ret->collectionsLevel1Token = mc_CollectionsLevel1Token_new(crypto, &ret->tokenKey, status);
524
+ if (!ret->collectionsLevel1Token) {
525
+ CLIENT_ERR("unable to derive collectionLevel1Token");
526
+ goto fail;
527
+ }
528
+
529
+ ret->serverDataEncryptionLevel1Token = mc_ServerDataEncryptionLevel1Token_new(crypto, &ret->tokenKey, status);
530
+ if (!ret->serverDataEncryptionLevel1Token) {
531
+ CLIENT_ERR("unable to derive serverDataEncryptionLevel1Token");
532
+ goto fail;
533
+ }
534
+
535
+ if (!_fle2_derive_EDC_token(crypto,
475
536
  &ret->edcDerivedToken,
476
537
  ret->collectionsLevel1Token,
477
538
  value,
478
- useCounter,
479
- maxContentionCounter,
539
+ useContentionFactor,
540
+ contentionFactor,
480
541
  status)) {
481
- goto fail;
482
- }
542
+ goto fail;
543
+ }
483
544
 
484
- if (!_fle2_derive_ESC_token (crypto,
545
+ if (!_fle2_derive_ESC_token(crypto,
485
546
  &ret->escDerivedToken,
486
547
  ret->collectionsLevel1Token,
487
548
  value,
488
- useCounter,
489
- maxContentionCounter,
549
+ useContentionFactor,
550
+ contentionFactor,
490
551
  status)) {
491
- goto fail;
492
- }
552
+ goto fail;
553
+ }
554
+
555
+ if (kb->crypt->opts.use_fle2_v2) {
556
+ /* FLE2v2 */
557
+ ret->serverTokenDerivationLevel1Token = mc_ServerTokenDerivationLevel1Token_new(crypto, &ret->tokenKey, status);
558
+ if (!ret->serverTokenDerivationLevel1Token) {
559
+ CLIENT_ERR("unable to derive serverTokenDerivationLevel1Token");
560
+ goto fail;
561
+ }
493
562
 
494
- if (!_fle2_derive_ECC_token (crypto,
495
- &ret->eccDerivedToken,
496
- ret->collectionsLevel1Token,
497
- value,
498
- useCounter,
499
- maxContentionCounter,
500
- status)) {
501
- goto fail;
502
- }
563
+ if (!_fle2_derive_serverDerivedFromDataToken(crypto,
564
+ &ret->serverDerivedFromDataToken,
565
+ ret->serverTokenDerivationLevel1Token,
566
+ value,
567
+ status)) {
568
+ goto fail;
569
+ }
570
+ } else {
571
+ /* FLE2v1 */
572
+ if (!_fle2_derive_ECC_token(crypto,
573
+ &ret->eccDerivedToken,
574
+ ret->collectionsLevel1Token,
575
+ value,
576
+ useContentionFactor,
577
+ contentionFactor,
578
+ status)) {
579
+ goto fail;
580
+ }
581
+ }
582
+
583
+ _mongocrypt_buffer_cleanup(&indexKey);
584
+ return true;
585
+
586
+ fail:
587
+ _FLE2EncryptedPayloadCommon_cleanup(ret);
588
+ _mongocrypt_buffer_cleanup(&indexKey);
589
+ return false;
590
+ }
591
+
592
+ // Shared implementation for insert/update and insert/update ForRange (v1)
593
+ static bool _mongocrypt_fle2_placeholder_to_insert_update_common_v1(_mongocrypt_key_broker_t *kb,
594
+ mc_FLE2InsertUpdatePayload_t *out,
595
+ int64_t *contentionFactor,
596
+ _FLE2EncryptedPayloadCommon_t *common,
597
+ const mc_FLE2EncryptionPlaceholder_t *placeholder,
598
+ bson_iter_t *value_iter,
599
+ mongocrypt_status_t *status) {
600
+ BSON_ASSERT_PARAM(kb);
601
+ BSON_ASSERT_PARAM(out);
602
+ BSON_ASSERT_PARAM(common);
603
+ BSON_ASSERT_PARAM(placeholder);
604
+ BSON_ASSERT_PARAM(value_iter);
605
+ BSON_ASSERT(kb->crypt);
606
+ BSON_ASSERT(kb->crypt->opts.use_fle2_v2 == false);
607
+ BSON_ASSERT(kb->crypt->opts.use_range_v2 == false);
608
+ BSON_ASSERT(placeholder->type == MONGOCRYPT_FLE2_PLACEHOLDER_TYPE_INSERT);
609
+
610
+ _mongocrypt_crypto_t *crypto = kb->crypt->crypto;
611
+ _mongocrypt_buffer_t value = {0};
612
+ bool res = false;
613
+
614
+ *contentionFactor = 0;
615
+ if (placeholder->maxContentionFactor > 0) {
616
+ /* Choose a random contentionFactor in the inclusive range [0,
617
+ * placeholder->maxContentionFactor] */
618
+ if (!_mongocrypt_random_int64(crypto, placeholder->maxContentionFactor + 1, contentionFactor, status)) {
619
+ goto fail;
620
+ }
621
+ }
622
+
623
+ _mongocrypt_buffer_from_iter(&value, value_iter);
624
+ if (!_mongocrypt_fle2_placeholder_common(kb,
625
+ common,
626
+ &placeholder->index_key_id,
627
+ &value,
628
+ true, /* derive tokens using contentionFactor */
629
+ *contentionFactor,
630
+ status)) {
631
+ goto fail;
632
+ }
633
+
634
+ // d := EDCDerivedToken
635
+ _mongocrypt_buffer_steal(&out->edcDerivedToken, &common->edcDerivedToken);
636
+ // s := ESCDerivedToken
637
+ _mongocrypt_buffer_steal(&out->escDerivedToken, &common->escDerivedToken);
638
+ // c := ECCDerivedToken
639
+ _mongocrypt_buffer_steal(&out->eccDerivedToken, &common->eccDerivedToken);
640
+
641
+ // p := EncryptCTR(ECOCToken, ESCDerivedFromDataTokenAndContentionFactor ||
642
+ // ECCDerivedFromDataTokenAndContentionFactor)
643
+ if (!_fle2_derive_encrypted_token(crypto,
644
+ &out->encryptedTokens,
645
+ false, // Can't use range V2 with FLE V1
646
+ common->collectionsLevel1Token,
647
+ &out->escDerivedToken,
648
+ &out->eccDerivedToken,
649
+ (mc_optional_bool_t){0}, // Unset is_leaf as it's not used in V1
650
+ status)) {
651
+ goto fail;
652
+ }
653
+
654
+ _mongocrypt_buffer_copy_to(&placeholder->index_key_id,
655
+ &out->indexKeyId); // u
656
+ out->valueType = bson_iter_type(value_iter); // t
657
+
658
+ // v := UserKeyId + EncryptCTRAEAD(UserKey, value)
659
+ {
660
+ _mongocrypt_buffer_t ciphertext = {0};
661
+ if (!_fle2_placeholder_aes_aead_encrypt(kb,
662
+ _mcFLE2AEADAlgorithm(),
663
+ &ciphertext,
664
+ &placeholder->user_key_id,
665
+ &value,
666
+ status)) {
667
+ goto fail;
668
+ }
669
+ const _mongocrypt_buffer_t v[2] = {placeholder->user_key_id, ciphertext};
670
+ const bool ok = _mongocrypt_buffer_concat(&out->value, v, 2);
671
+ _mongocrypt_buffer_cleanup(&ciphertext);
672
+ if (!ok) {
673
+ goto fail;
674
+ }
675
+ }
503
676
 
504
- _mongocrypt_buffer_cleanup (&indexKey);
505
- return true;
677
+ // e := ServerDataEncryptionLevel1Token
678
+ _mongocrypt_buffer_copy_to(mc_ServerDataEncryptionLevel1Token_get(common->serverDataEncryptionLevel1Token),
679
+ &out->serverEncryptionToken);
506
680
 
681
+ res = true;
507
682
  fail:
508
- _FLE2EncryptedPayloadCommon_cleanup (ret);
509
- _mongocrypt_buffer_cleanup (&indexKey);
510
- return false;
683
+ _mongocrypt_buffer_cleanup(&value);
684
+ return res;
511
685
  }
512
686
 
687
+ /**
688
+ * Payload subtype 4: FLE2InsertUpdatePayload
689
+ *
690
+ * {d: EDC, s: ESC, c: ECC,
691
+ * p: encToken, u: indexKeyId, t: type,
692
+ * v: value, e: serverToken}
693
+ */
694
+ static bool _mongocrypt_fle2_placeholder_to_insert_update_ciphertext_v1(_mongocrypt_key_broker_t *kb,
695
+ _mongocrypt_marking_t *marking,
696
+ _mongocrypt_ciphertext_t *ciphertext,
697
+ mongocrypt_status_t *status) {
698
+ BSON_ASSERT_PARAM(kb);
699
+ BSON_ASSERT_PARAM(marking);
700
+ BSON_ASSERT_PARAM(ciphertext);
701
+ BSON_ASSERT_PARAM(status);
702
+ BSON_ASSERT(kb->crypt);
703
+ BSON_ASSERT(kb->crypt->opts.use_fle2_v2 == false);
704
+ BSON_ASSERT(marking->type == MONGOCRYPT_MARKING_FLE2_ENCRYPTION);
705
+ BSON_ASSERT(marking->fle2.algorithm == MONGOCRYPT_FLE2_ALGORITHM_EQUALITY);
706
+
707
+ mc_FLE2EncryptionPlaceholder_t *placeholder = &marking->fle2;
708
+ _FLE2EncryptedPayloadCommon_t common = {{0}};
709
+ mc_FLE2InsertUpdatePayload_t payload;
710
+ mc_FLE2InsertUpdatePayload_init(&payload);
711
+ bool res = false;
712
+
713
+ int64_t contentionFactor = 0; /* ignored */
714
+ if (!_mongocrypt_fle2_placeholder_to_insert_update_common_v1(kb,
715
+ &payload,
716
+ &contentionFactor,
717
+ &common,
718
+ placeholder,
719
+ &placeholder->v_iter,
720
+ status)) {
721
+ goto fail;
722
+ }
723
+
724
+ {
725
+ bson_t out;
726
+ bson_init(&out);
727
+ mc_FLE2InsertUpdatePayload_serialize(&payload, &out);
728
+ _mongocrypt_buffer_steal_from_bson(&ciphertext->data, &out);
729
+ }
730
+ // Do not set ciphertext->original_bson_type and ciphertext->key_id. They are
731
+ // not used for FLE2InsertUpdatePayload.
732
+ ciphertext->blob_subtype = MC_SUBTYPE_FLE2InsertUpdatePayload;
733
+
734
+ res = true;
735
+ fail:
736
+ mc_FLE2InsertUpdatePayload_cleanup(&payload);
737
+ _FLE2EncryptedPayloadCommon_cleanup(&common);
513
738
 
514
- static bool
515
- _mongocrypt_fle2_placeholder_to_insert_update_ciphertext (
516
- _mongocrypt_key_broker_t *kb,
517
- _mongocrypt_marking_t *marking,
518
- _mongocrypt_ciphertext_t *ciphertext,
519
- mongocrypt_status_t *status)
520
- {
521
- BSON_ASSERT_PARAM (kb);
522
- BSON_ASSERT_PARAM (marking);
523
- BSON_ASSERT_PARAM (ciphertext);
524
- BSON_ASSERT (kb->crypt);
525
-
526
- _mongocrypt_crypto_t *crypto = kb->crypt->crypto;
527
- _FLE2EncryptedPayloadCommon_t common = {{0}};
528
- _mongocrypt_buffer_t value = {0};
529
- mc_FLE2EncryptionPlaceholder_t *placeholder = &marking->fle2;
530
- mc_FLE2InsertUpdatePayload_t payload;
531
- bool res = false;
532
-
533
- BSON_ASSERT (marking->type == MONGOCRYPT_MARKING_FLE2_ENCRYPTION);
534
- BSON_ASSERT (placeholder->type == MONGOCRYPT_FLE2_PLACEHOLDER_TYPE_INSERT);
535
- _mongocrypt_ciphertext_init (ciphertext);
536
- _mongocrypt_buffer_init (&value);
537
- mc_FLE2InsertUpdatePayload_init (&payload);
538
-
539
- _mongocrypt_buffer_from_iter (&value, &placeholder->v_iter);
540
-
541
- int64_t contentionFactor = 0;
542
- if (placeholder->maxContentionCounter > 0) {
543
- /* Choose a random contentionFactor in the inclusive range [0,
544
- * placeholder->maxContentionCounter] */
545
- if (!_mongocrypt_random_int64 (crypto,
546
- placeholder->maxContentionCounter + 1,
547
- &contentionFactor,
548
- status)) {
549
- goto fail;
550
- }
551
- }
552
-
553
- if (!_mongocrypt_fle2_placeholder_common (
554
- kb,
555
- &common,
556
- &placeholder->index_key_id,
557
- &value,
558
- true, /* derive tokens using counter */
559
- contentionFactor,
560
- status)) {
561
- goto fail;
562
- }
563
-
564
- // d := EDCDerivedToken
565
- _mongocrypt_buffer_steal (&payload.edcDerivedToken, &common.edcDerivedToken);
566
- // s := ESCDerivedToken
567
- _mongocrypt_buffer_steal (&payload.escDerivedToken, &common.escDerivedToken);
568
- // c := ECCDerivedToken
569
- _mongocrypt_buffer_steal (&payload.eccDerivedToken, &common.eccDerivedToken);
570
-
571
- // p := EncryptCTR(ECOCToken, ESCDerivedFromDataTokenAndCounter ||
572
- // ECCDerivedFromDataTokenAndCounter)
573
- {
574
- _mongocrypt_buffer_t tokens[] = {payload.escDerivedToken,
575
- payload.eccDerivedToken};
576
- _mongocrypt_buffer_t p;
577
- _mongocrypt_buffer_concat (&p, tokens, 2);
578
- mc_ECOCToken_t *ecocToken =
579
- mc_ECOCToken_new (crypto, common.collectionsLevel1Token, status);
580
- if (!ecocToken) {
581
- _mongocrypt_buffer_cleanup (&p);
582
- goto fail;
583
- }
584
- bool ok = _fle2_placeholder_aes_ctr_encrypt (kb,
585
- mc_ECOCToken_get (ecocToken),
586
- &p,
587
- &payload.encryptedTokens,
588
- status);
589
- _mongocrypt_buffer_cleanup (&p);
590
- mc_ECOCToken_destroy (ecocToken);
591
- if (!ok) {
592
- goto fail;
593
- }
594
- }
595
-
596
- _mongocrypt_buffer_copy_to (&placeholder->index_key_id,
597
- &payload.indexKeyId); // u
598
- payload.valueType = bson_iter_type (&placeholder->v_iter); // t
599
-
600
- // v := UserKeyId + EncryptAEAD(UserKey, value)
601
- {
602
- _mongocrypt_buffer_t tmp[2] = {placeholder->user_key_id, {0}};
603
- if (!_fle2_placeholder_aead_encrypt (
604
- kb, &placeholder->user_key_id, &value, &tmp[1], status)) {
605
- goto fail;
606
- }
607
- bool ok = _mongocrypt_buffer_concat (&payload.value, tmp, 2);
608
- _mongocrypt_buffer_cleanup (&tmp[1]);
609
- if (!ok) {
610
- goto fail;
611
- }
612
- }
613
-
614
- // e := ServerDataEncryptionLevel1Token
615
- {
616
- mc_ServerDataEncryptionLevel1Token_t *serverToken =
617
- mc_ServerDataEncryptionLevel1Token_new (
618
- crypto, &common.tokenKey, status);
619
- if (!serverToken) {
620
- goto fail;
621
- }
622
- _mongocrypt_buffer_copy_to (
623
- mc_ServerDataEncryptionLevel1Token_get (serverToken),
624
- &payload.serverEncryptionToken);
625
- mc_ServerDataEncryptionLevel1Token_destroy (serverToken);
626
- }
627
-
628
- {
629
- bson_t out;
630
- bson_init (&out);
631
- mc_FLE2InsertUpdatePayload_serialize (&payload, &out);
632
- _mongocrypt_buffer_steal_from_bson (&ciphertext->data, &out);
633
- }
634
- // Do not set ciphertext->original_bson_type and ciphertext->key_id. They are
635
- // not used for FLE2InsertUpdatePayload.
636
- ciphertext->blob_subtype = MC_SUBTYPE_FLE2InsertUpdatePayload;
637
-
638
- res = true;
739
+ return res;
740
+ }
741
+
742
+ // Shared implementation for insert/update and insert/update ForRange (v2)
743
+ static bool _mongocrypt_fle2_placeholder_to_insert_update_common(_mongocrypt_key_broker_t *kb,
744
+ mc_FLE2InsertUpdatePayloadV2_t *out,
745
+ _FLE2EncryptedPayloadCommon_t *common,
746
+ const mc_FLE2EncryptionPlaceholder_t *placeholder,
747
+ bson_iter_t *value_iter,
748
+ mongocrypt_status_t *status) {
749
+ BSON_ASSERT_PARAM(kb);
750
+ BSON_ASSERT_PARAM(out);
751
+ BSON_ASSERT_PARAM(common);
752
+ BSON_ASSERT_PARAM(placeholder);
753
+ BSON_ASSERT_PARAM(value_iter);
754
+ BSON_ASSERT(kb->crypt);
755
+ BSON_ASSERT(kb->crypt->opts.use_fle2_v2 == true);
756
+ BSON_ASSERT(placeholder->type == MONGOCRYPT_FLE2_PLACEHOLDER_TYPE_INSERT);
757
+
758
+ _mongocrypt_crypto_t *crypto = kb->crypt->crypto;
759
+ _mongocrypt_buffer_t value = {0};
760
+ bool res = false;
761
+
762
+ out->contentionFactor = 0; // k
763
+ if (placeholder->maxContentionFactor > 0) {
764
+ /* Choose a random contentionFactor in the inclusive range [0,
765
+ * placeholder->maxContentionFactor] */
766
+ if (!_mongocrypt_random_int64(crypto, placeholder->maxContentionFactor + 1, &out->contentionFactor, status)) {
767
+ goto fail;
768
+ }
769
+ }
770
+
771
+ _mongocrypt_buffer_from_iter(&value, value_iter);
772
+ if (!_mongocrypt_fle2_placeholder_common(kb,
773
+ common,
774
+ &placeholder->index_key_id,
775
+ &value,
776
+ true, /* derive tokens using contentionFactor */
777
+ out->contentionFactor,
778
+ status)) {
779
+ goto fail;
780
+ }
781
+
782
+ // d := EDCDerivedToken
783
+ _mongocrypt_buffer_steal(&out->edcDerivedToken, &common->edcDerivedToken);
784
+ // s := ESCDerivedToken
785
+ _mongocrypt_buffer_steal(&out->escDerivedToken, &common->escDerivedToken);
786
+ BSON_ASSERT(common->eccDerivedToken.data == NULL);
787
+
788
+ // p := EncryptCTR(ECOCToken, ESCDerivedFromDataTokenAndContentionFactor)
789
+ // Or in Range V2, when using range: p := EncryptCTR(ECOCToken, ESCDerivedFromDataTokenAndContentionFactor || 0x00)
790
+ if (!_fle2_derive_encrypted_token(
791
+ crypto,
792
+ &out->encryptedTokens,
793
+ kb->crypt->opts.use_range_v2,
794
+ common->collectionsLevel1Token,
795
+ &out->escDerivedToken,
796
+ NULL, // unused in v2
797
+ // If this is a range insert, we append isLeaf to the encryptedTokens. Otherwise, we don't.
798
+ placeholder->algorithm == MONGOCRYPT_FLE2_ALGORITHM_RANGE ? OPT_BOOL(false) : (mc_optional_bool_t){0},
799
+ status)) {
800
+ goto fail;
801
+ }
802
+
803
+ _mongocrypt_buffer_copy_to(&placeholder->index_key_id,
804
+ &out->indexKeyId); // u
805
+ out->valueType = bson_iter_type(value_iter); // t
806
+
807
+ // v := UserKeyId + EncryptCBCAEAD(UserKey, value)
808
+ {
809
+ _mongocrypt_buffer_t ciphertext = {0};
810
+ if (!_fle2_placeholder_aes_aead_encrypt(kb,
811
+ _mcFLE2v2AEADAlgorithm(),
812
+ &ciphertext,
813
+ &placeholder->user_key_id,
814
+ &value,
815
+ status)) {
816
+ goto fail;
817
+ }
818
+ const _mongocrypt_buffer_t v[2] = {placeholder->user_key_id, ciphertext};
819
+ const bool ok = _mongocrypt_buffer_concat(&out->value, v, 2);
820
+ _mongocrypt_buffer_cleanup(&ciphertext);
821
+ if (!ok) {
822
+ goto fail;
823
+ }
824
+ }
825
+
826
+ // e := ServerDataEncryptionLevel1Token
827
+ _mongocrypt_buffer_copy_to(mc_ServerDataEncryptionLevel1Token_get(common->serverDataEncryptionLevel1Token),
828
+ &out->serverEncryptionToken);
829
+
830
+ // l := ServerDerivedFromDataToken
831
+ _mongocrypt_buffer_steal(&out->serverDerivedFromDataToken, &common->serverDerivedFromDataToken);
832
+
833
+ res = true;
639
834
  fail:
640
- mc_FLE2InsertUpdatePayload_cleanup (&payload);
641
- _mongocrypt_buffer_cleanup (&value);
642
- _FLE2EncryptedPayloadCommon_cleanup (&common);
835
+ _mongocrypt_buffer_cleanup(&value);
836
+ return res;
837
+ }
838
+
839
+ /**
840
+ * Payload subtype 11: FLE2InsertUpdatePayloadV2
841
+ * Delegates to ..._insert_update_ciphertext_v1 for subtype 4
842
+ * when crypt.opts.use_fle2_v2 == false
843
+ *
844
+ * {d: EDC, s: ESC, p: encToken,
845
+ * u: indexKeyId, t: valueType, v: value,
846
+ * e: serverToken, l: serverDerivedFromDataToken,
847
+ * k: contentionFactor}
848
+ */
849
+ static bool _mongocrypt_fle2_placeholder_to_insert_update_ciphertext(_mongocrypt_key_broker_t *kb,
850
+ _mongocrypt_marking_t *marking,
851
+ _mongocrypt_ciphertext_t *ciphertext,
852
+ mongocrypt_status_t *status) {
853
+ BSON_ASSERT_PARAM(kb);
854
+ BSON_ASSERT_PARAM(marking);
855
+ BSON_ASSERT_PARAM(ciphertext);
856
+ BSON_ASSERT(kb->crypt);
857
+ BSON_ASSERT(marking->type == MONGOCRYPT_MARKING_FLE2_ENCRYPTION);
858
+
859
+ if (!kb->crypt->opts.use_fle2_v2) {
860
+ return _mongocrypt_fle2_placeholder_to_insert_update_ciphertext_v1(kb, marking, ciphertext, status);
861
+ }
862
+
863
+ mc_FLE2EncryptionPlaceholder_t *placeholder = &marking->fle2;
864
+ _FLE2EncryptedPayloadCommon_t common = {{0}};
865
+ mc_FLE2InsertUpdatePayloadV2_t payload;
866
+ mc_FLE2InsertUpdatePayloadV2_init(&payload);
867
+ bool res = false;
868
+
869
+ if (!_mongocrypt_fle2_placeholder_to_insert_update_common(kb,
870
+ &payload,
871
+ &common,
872
+ placeholder,
873
+ &placeholder->v_iter,
874
+ status)) {
875
+ goto fail;
876
+ }
877
+
878
+ {
879
+ bson_t out;
880
+ bson_init(&out);
881
+ mc_FLE2InsertUpdatePayloadV2_serialize(&payload, &out);
882
+ _mongocrypt_buffer_steal_from_bson(&ciphertext->data, &out);
883
+ }
884
+
885
+ // Do not set ciphertext->original_bson_type and ciphertext->key_id. They are
886
+ // not used for FLE2InsertUpdatePayloadV2.
887
+ ciphertext->blob_subtype = MC_SUBTYPE_FLE2InsertUpdatePayloadV2;
888
+
889
+ res = true;
890
+ fail:
891
+ mc_FLE2InsertUpdatePayloadV2_cleanup(&payload);
892
+ _FLE2EncryptedPayloadCommon_cleanup(&common);
643
893
 
644
- return res;
894
+ return res;
645
895
  }
646
896
 
647
897
  // get_edges creates and returns edges from an FLE2RangeInsertSpec. Returns NULL
648
898
  // on error.
649
899
  static mc_edges_t *
650
- get_edges (mc_FLE2RangeInsertSpec_t *insertSpec,
651
- size_t sparsity,
652
- mongocrypt_status_t *status)
653
- {
654
- BSON_ASSERT_PARAM (insertSpec);
655
-
656
- bson_type_t value_type = bson_iter_type (&insertSpec->v);
657
-
658
-
659
- if (value_type == BSON_TYPE_INT32) {
660
- return mc_getEdgesInt32 (
661
- (mc_getEdgesInt32_args_t){
662
- .value = bson_iter_int32 (&insertSpec->v),
663
- .min = OPT_I32 (bson_iter_int32 (&insertSpec->min)),
664
- .max = OPT_I32 (bson_iter_int32 (&insertSpec->max)),
665
- .sparsity = sparsity},
666
- status);
667
- }
668
-
669
- else if (value_type == BSON_TYPE_INT64) {
670
- return mc_getEdgesInt64 (
671
- (mc_getEdgesInt64_args_t){
672
- .value = bson_iter_int64 (&insertSpec->v),
673
- .min = OPT_I64 (bson_iter_int64 (&insertSpec->min)),
674
- .max = OPT_I64 (bson_iter_int64 (&insertSpec->max)),
675
- .sparsity = sparsity},
676
- status);
677
- }
678
-
679
- else if (value_type == BSON_TYPE_DATE_TIME) {
680
- return mc_getEdgesInt64 (
681
- (mc_getEdgesInt64_args_t){
682
- .value = bson_iter_date_time (&insertSpec->v),
683
- .min = OPT_I64 (bson_iter_date_time (&insertSpec->min)),
684
- .max = OPT_I64 (bson_iter_date_time (&insertSpec->max)),
685
- .sparsity = sparsity},
686
- status);
687
- }
688
-
689
- else if (value_type == BSON_TYPE_DOUBLE) {
690
- mc_getEdgesDouble_args_t args = {
691
- .value = bson_iter_double (&insertSpec->v), .sparsity = sparsity};
692
- if (insertSpec->precision.set) {
693
- // If precision is set, pass min/max/precision to mc_getEdgesDouble.
694
- // Do not pass min/max if precision is not set. All three must be set
695
- // or all three must be unset in mc_getTypeInfoDouble.
696
- args.min = OPT_DOUBLE (bson_iter_double (&insertSpec->min));
697
- args.max = OPT_DOUBLE (bson_iter_double (&insertSpec->max));
698
- args.precision = insertSpec->precision;
699
- }
700
-
701
- return mc_getEdgesDouble (args, status);
702
- }
703
-
704
- else if (value_type == BSON_TYPE_DECIMAL128) {
900
+ get_edges(mc_FLE2RangeInsertSpec_t *insertSpec, size_t sparsity, mongocrypt_status_t *status, bool use_range_v2) {
901
+ BSON_ASSERT_PARAM(insertSpec);
902
+
903
+ bson_type_t value_type = bson_iter_type(&insertSpec->v);
904
+
905
+ if (value_type == BSON_TYPE_INT32) {
906
+ return mc_getEdgesInt32((mc_getEdgesInt32_args_t){.value = bson_iter_int32(&insertSpec->v),
907
+ .min = OPT_I32(bson_iter_int32(&insertSpec->min)),
908
+ .max = OPT_I32(bson_iter_int32(&insertSpec->max)),
909
+ .sparsity = sparsity,
910
+ .trimFactor = insertSpec->trimFactor},
911
+ status,
912
+ use_range_v2);
913
+ }
914
+
915
+ else if (value_type == BSON_TYPE_INT64) {
916
+ return mc_getEdgesInt64((mc_getEdgesInt64_args_t){.value = bson_iter_int64(&insertSpec->v),
917
+ .min = OPT_I64(bson_iter_int64(&insertSpec->min)),
918
+ .max = OPT_I64(bson_iter_int64(&insertSpec->max)),
919
+ .sparsity = sparsity,
920
+ .trimFactor = insertSpec->trimFactor},
921
+ status,
922
+ use_range_v2);
923
+ }
924
+
925
+ else if (value_type == BSON_TYPE_DATE_TIME) {
926
+ return mc_getEdgesInt64((mc_getEdgesInt64_args_t){.value = bson_iter_date_time(&insertSpec->v),
927
+ .min = OPT_I64(bson_iter_date_time(&insertSpec->min)),
928
+ .max = OPT_I64(bson_iter_date_time(&insertSpec->max)),
929
+ .sparsity = sparsity,
930
+ .trimFactor = insertSpec->trimFactor},
931
+ status,
932
+ use_range_v2);
933
+ }
934
+
935
+ else if (value_type == BSON_TYPE_DOUBLE) {
936
+ mc_getEdgesDouble_args_t args = {.value = bson_iter_double(&insertSpec->v),
937
+ .sparsity = sparsity,
938
+ .trimFactor = insertSpec->trimFactor};
939
+ if (insertSpec->precision.set) {
940
+ // If precision is set, pass min/max/precision to mc_getEdgesDouble.
941
+ // Do not pass min/max if precision is not set. All three must be set
942
+ // or all three must be unset in mc_getTypeInfoDouble.
943
+ args.min = OPT_DOUBLE(bson_iter_double(&insertSpec->min));
944
+ args.max = OPT_DOUBLE(bson_iter_double(&insertSpec->max));
945
+ args.precision = insertSpec->precision;
946
+ }
947
+
948
+ return mc_getEdgesDouble(args, status, use_range_v2);
949
+ }
950
+
951
+ else if (value_type == BSON_TYPE_DECIMAL128) {
705
952
  #if MONGOCRYPT_HAVE_DECIMAL128_SUPPORT
706
- const mc_dec128 value = mc_dec128_from_bson_iter (&insertSpec->v);
707
- mc_getEdgesDecimal128_args_t args = {
708
- .value = value,
709
- .sparsity = sparsity,
710
- };
711
- if (insertSpec->precision.set) {
712
- const mc_dec128 min = mc_dec128_from_bson_iter (&insertSpec->min);
713
- const mc_dec128 max = mc_dec128_from_bson_iter (&insertSpec->max);
714
- args.min = OPT_MC_DEC128 (min);
715
- args.max = OPT_MC_DEC128 (max);
716
- args.precision = insertSpec->precision;
717
- }
718
- return mc_getEdgesDecimal128 (args, status);
953
+ const mc_dec128 value = mc_dec128_from_bson_iter(&insertSpec->v);
954
+ mc_getEdgesDecimal128_args_t args = {
955
+ .value = value,
956
+ .sparsity = sparsity,
957
+ .trimFactor = insertSpec->trimFactor,
958
+ };
959
+ if (insertSpec->precision.set) {
960
+ const mc_dec128 min = mc_dec128_from_bson_iter(&insertSpec->min);
961
+ const mc_dec128 max = mc_dec128_from_bson_iter(&insertSpec->max);
962
+ args.min = OPT_MC_DEC128(min);
963
+ args.max = OPT_MC_DEC128(max);
964
+ args.precision = insertSpec->precision;
965
+ }
966
+ return mc_getEdgesDecimal128(args, status, use_range_v2);
719
967
  #else // ↑↑↑↑↑↑↑↑ With Decimal128 / Without ↓↓↓↓↓↓↓↓↓↓
720
- CLIENT_ERR ("unsupported BSON type (Decimal128) for range: libmongocrypt "
721
- "was built without extended Decimal128 support");
722
- return NULL;
968
+ CLIENT_ERR("unsupported BSON type (Decimal128) for range: libmongocrypt "
969
+ "was built without extended Decimal128 support");
970
+ return NULL;
723
971
  #endif
724
- }
725
-
972
+ }
726
973
 
727
- CLIENT_ERR ("unsupported BSON type: %s for range",
728
- mc_bson_type_to_string (value_type));
729
- return NULL;
974
+ CLIENT_ERR("unsupported BSON type: %s for range", mc_bson_type_to_string(value_type));
975
+ return NULL;
730
976
  }
731
977
 
732
- // _mongocrypt_fle2_placeholder_to_insert_update_ciphertextForRange transforms a
733
- // FLE2EncryptedPlaceholder to an FLE2InsertUpdatePayload for the range
734
- // algorithm.
735
- static bool
736
- _mongocrypt_fle2_placeholder_to_insert_update_ciphertextForRange (
737
- _mongocrypt_key_broker_t *kb,
738
- _mongocrypt_marking_t *marking,
739
- _mongocrypt_ciphertext_t *ciphertext,
740
- mongocrypt_status_t *status)
741
- {
742
- BSON_ASSERT_PARAM (kb);
743
- BSON_ASSERT_PARAM (marking);
744
- BSON_ASSERT_PARAM (ciphertext);
745
- BSON_ASSERT (kb->crypt);
746
-
747
- _mongocrypt_crypto_t *crypto = kb->crypt->crypto;
748
- _FLE2EncryptedPayloadCommon_t common = {{0}};
749
- _mongocrypt_buffer_t value = {0};
750
- mc_FLE2EncryptionPlaceholder_t *placeholder = &marking->fle2;
751
- mc_FLE2InsertUpdatePayload_t payload;
752
- bool res = false;
753
- mc_edges_t *edges = NULL;
754
-
755
- BSON_ASSERT (marking->type == MONGOCRYPT_MARKING_FLE2_ENCRYPTION);
756
- BSON_ASSERT (placeholder->type == MONGOCRYPT_FLE2_PLACEHOLDER_TYPE_INSERT);
757
- BSON_ASSERT (placeholder->algorithm == MONGOCRYPT_FLE2_ALGORITHM_RANGE);
758
- _mongocrypt_ciphertext_init (ciphertext);
759
- mc_FLE2InsertUpdatePayload_init (&payload);
760
-
761
- // Parse the value ("v"), min ("min"), and max ("max") from
762
- // FLE2EncryptionPlaceholder for range insert.
763
- mc_FLE2RangeInsertSpec_t insertSpec;
764
- if (!mc_FLE2RangeInsertSpec_parse (
765
- &insertSpec, &placeholder->v_iter, status)) {
766
- goto fail;
767
- }
768
-
769
- _mongocrypt_buffer_from_iter (&value, &insertSpec.v);
770
-
771
- int64_t contentionFactor = 0;
772
- if (placeholder->maxContentionCounter > 0) {
773
- /* Choose a random contentionFactor in the inclusive range [0,
774
- * placeholder->maxContentionCounter] */
775
- if (!_mongocrypt_random_int64 (crypto,
776
- placeholder->maxContentionCounter + 1,
777
- &contentionFactor,
778
- status)) {
779
- goto fail;
780
- }
781
- }
782
-
783
- if (!_mongocrypt_fle2_placeholder_common (
784
- kb,
785
- &common,
786
- &placeholder->index_key_id,
787
- &value,
788
- true, /* derive tokens using counter */
789
- contentionFactor,
790
- status)) {
791
- goto fail;
792
- }
793
-
794
- // d := EDCDerivedToken
795
- _mongocrypt_buffer_steal (&payload.edcDerivedToken, &common.edcDerivedToken);
796
- // s := ESCDerivedToken
797
- _mongocrypt_buffer_steal (&payload.escDerivedToken, &common.escDerivedToken);
798
- // c := ECCDerivedToken
799
- _mongocrypt_buffer_steal (&payload.eccDerivedToken, &common.eccDerivedToken);
800
-
801
- // p := EncryptCTR(ECOCToken, ESCDerivedFromDataTokenAndCounter ||
802
- // ECCDerivedFromDataTokenAndCounter)
803
- {
804
- _mongocrypt_buffer_t tokens[] = {payload.escDerivedToken,
805
- payload.eccDerivedToken};
806
- _mongocrypt_buffer_t p;
807
- _mongocrypt_buffer_concat (&p, tokens, 2);
808
- mc_ECOCToken_t *ecocToken =
809
- mc_ECOCToken_new (crypto, common.collectionsLevel1Token, status);
810
- if (!ecocToken) {
811
- _mongocrypt_buffer_cleanup (&p);
812
- goto fail;
813
- }
814
- bool ok = _fle2_placeholder_aes_ctr_encrypt (kb,
815
- mc_ECOCToken_get (ecocToken),
816
- &p,
817
- &payload.encryptedTokens,
818
- status);
819
- _mongocrypt_buffer_cleanup (&p);
820
- mc_ECOCToken_destroy (ecocToken);
821
- if (!ok) {
822
- goto fail;
823
- }
824
- }
825
-
826
- _mongocrypt_buffer_copy_to (&placeholder->index_key_id,
827
- &payload.indexKeyId); // u
828
- payload.valueType = bson_iter_type (&insertSpec.v); // t
829
-
830
- // v := UserKeyId + EncryptAEAD(UserKey, value)
831
- {
832
- _mongocrypt_buffer_t tmp[2] = {placeholder->user_key_id, {0}};
833
- if (!_fle2_placeholder_aead_encrypt (
834
- kb, &placeholder->user_key_id, &value, &tmp[1], status)) {
835
- goto fail;
836
- }
837
- bool ok = _mongocrypt_buffer_concat (&payload.value, tmp, 2);
838
- _mongocrypt_buffer_cleanup (&tmp[1]);
839
- if (!ok) {
840
- goto fail;
841
- }
842
- }
843
-
844
- // e := ServerDataEncryptionLevel1Token
845
- {
846
- mc_ServerDataEncryptionLevel1Token_t *serverToken =
847
- mc_ServerDataEncryptionLevel1Token_new (
848
- crypto, &common.tokenKey, status);
849
- if (!serverToken) {
850
- goto fail;
851
- }
852
- _mongocrypt_buffer_copy_to (
853
- mc_ServerDataEncryptionLevel1Token_get (serverToken),
854
- &payload.serverEncryptionToken);
855
- mc_ServerDataEncryptionLevel1Token_destroy (serverToken);
856
- }
857
-
858
- // g:= array<EdgeTokenSet>
859
- {
860
- BSON_ASSERT (placeholder->sparsity >= 0 &&
861
- (uint64_t) placeholder->sparsity <= (uint64_t) SIZE_MAX);
862
- edges = get_edges (&insertSpec, (size_t) placeholder->sparsity, status);
863
- if (!edges) {
864
- goto fail;
865
- }
866
-
867
- for (size_t i = 0; i < mc_edges_len (edges); i++) {
868
- // Create an EdgeTokenSet from each edge.
869
- bool loop_ok = false;
870
- const char *edge = mc_edges_get (edges, i);
871
- _mongocrypt_buffer_t edge_buf = {0};
872
- _FLE2EncryptedPayloadCommon_t edge_tokens = {{0}};
873
- _mongocrypt_buffer_t encryptedTokens = {0};
874
- mc_EdgeTokenSet_t etc = {{0}};
875
-
876
- if (!_mongocrypt_buffer_from_string (&edge_buf, edge)) {
877
- CLIENT_ERR ("failed to copy edge to buffer");
878
- goto fail_loop;
879
- }
880
-
881
- if (!_mongocrypt_fle2_placeholder_common (
882
- kb,
883
- &edge_tokens,
884
- &placeholder->index_key_id,
885
- &edge_buf,
886
- true, /* derive tokens using counter */
887
- contentionFactor,
888
- status)) {
889
- goto fail_loop;
890
- }
891
-
892
- // p := EncryptCTR(ECOCToken, ESCDerivedFromDataTokenAndCounter ||
893
- // ECCDerivedFromDataTokenAndCounter)
894
- {
895
- _mongocrypt_buffer_t tokens[] = {edge_tokens.escDerivedToken,
896
- edge_tokens.eccDerivedToken};
897
- _mongocrypt_buffer_t p;
898
- _mongocrypt_buffer_concat (&p, tokens, 2);
899
- mc_ECOCToken_t *ecocToken = mc_ECOCToken_new (
900
- crypto, edge_tokens.collectionsLevel1Token, status);
901
- if (!ecocToken) {
902
- _mongocrypt_buffer_cleanup (&p);
903
- goto fail_loop;
978
+ /**
979
+ * Payload subtype 4: FLE2InsertUpdatePayload for range updates
980
+ *
981
+ * {d: EDC, s: ESC, c: ECC,
982
+ * p: encToken, u: indexKeyId, t: type,
983
+ * v: value, e: serverToken,
984
+ * g: [{d: EDC, s: ESC, c: ECC, p: encToken},
985
+ * {d: EDC, s: ESC, c: ECC, p: encToken},
986
+ * ...]}
987
+ */
988
+ static bool _mongocrypt_fle2_placeholder_to_insert_update_ciphertextForRange_v1(_mongocrypt_key_broker_t *kb,
989
+ _mongocrypt_marking_t *marking,
990
+ _mongocrypt_ciphertext_t *ciphertext,
991
+ mongocrypt_status_t *status) {
992
+ BSON_ASSERT_PARAM(kb);
993
+ BSON_ASSERT_PARAM(marking);
994
+ BSON_ASSERT_PARAM(ciphertext);
995
+ BSON_ASSERT_PARAM(status);
996
+ BSON_ASSERT(kb->crypt);
997
+ BSON_ASSERT(kb->crypt->opts.use_fle2_v2 == false);
998
+ BSON_ASSERT(kb->crypt->opts.use_range_v2 == false);
999
+ BSON_ASSERT(marking->type == MONGOCRYPT_MARKING_FLE2_ENCRYPTION);
1000
+ BSON_ASSERT(marking->fle2.algorithm == MONGOCRYPT_FLE2_ALGORITHM_RANGE);
1001
+
1002
+ mc_FLE2EncryptionPlaceholder_t *placeholder = &marking->fle2;
1003
+ _FLE2EncryptedPayloadCommon_t common = {{0}};
1004
+ mc_FLE2InsertUpdatePayload_t payload;
1005
+ mc_FLE2InsertUpdatePayload_init(&payload);
1006
+ bool res = false;
1007
+ mc_edges_t *edges = NULL;
1008
+
1009
+ // Parse the value ("v"), min ("min"), and max ("max") from
1010
+ // FLE2EncryptionPlaceholder for range insert.
1011
+ mc_FLE2RangeInsertSpec_t insertSpec;
1012
+ if (!mc_FLE2RangeInsertSpec_parse(&insertSpec, &placeholder->v_iter, kb->crypt->opts.use_range_v2, status)) {
1013
+ goto fail;
1014
+ }
1015
+
1016
+ int64_t contentionFactor = 0;
1017
+ if (!_mongocrypt_fle2_placeholder_to_insert_update_common_v1(kb,
1018
+ &payload,
1019
+ &contentionFactor,
1020
+ &common,
1021
+ &marking->fle2,
1022
+ &insertSpec.v,
1023
+ status)) {
1024
+ goto fail;
1025
+ }
1026
+
1027
+ // g:= array<EdgeTokenSet>
1028
+ {
1029
+ BSON_ASSERT(placeholder->sparsity >= 0 && (uint64_t)placeholder->sparsity <= (uint64_t)SIZE_MAX);
1030
+ edges = get_edges(&insertSpec, (size_t)placeholder->sparsity, status, kb->crypt->opts.use_range_v2);
1031
+ if (!edges) {
1032
+ goto fail;
1033
+ }
1034
+
1035
+ for (size_t i = 0; i < mc_edges_len(edges); ++i) {
1036
+ // Create an EdgeTokenSet from each edge.
1037
+ bool loop_ok = false;
1038
+ const char *edge = mc_edges_get(edges, i);
1039
+ _mongocrypt_buffer_t edge_buf = {0};
1040
+ _FLE2EncryptedPayloadCommon_t edge_tokens = {{0}};
1041
+ _mongocrypt_buffer_t encryptedTokens = {0};
1042
+ mc_EdgeTokenSet_t etc = {{0}};
1043
+
1044
+ if (!_mongocrypt_buffer_from_string(&edge_buf, edge)) {
1045
+ CLIENT_ERR("failed to copy edge to buffer");
1046
+ goto fail_loop;
904
1047
  }
905
- bool ok = _fle2_placeholder_aes_ctr_encrypt (
906
- kb, mc_ECOCToken_get (ecocToken), &p, &encryptedTokens, status);
907
- _mongocrypt_buffer_cleanup (&p);
908
- mc_ECOCToken_destroy (ecocToken);
909
- if (!ok) {
910
- goto fail_loop;
1048
+
1049
+ if (!_mongocrypt_fle2_placeholder_common(kb,
1050
+ &edge_tokens,
1051
+ &placeholder->index_key_id,
1052
+ &edge_buf,
1053
+ true, /* derive tokens using contentionFactor */
1054
+ contentionFactor,
1055
+ status)) {
1056
+ goto fail_loop;
911
1057
  }
912
- }
913
-
914
- // d := EDCDerivedToken
915
- _mongocrypt_buffer_steal (&etc.edcDerivedToken,
916
- &edge_tokens.edcDerivedToken);
917
- // s := ESCDerivedToken
918
- _mongocrypt_buffer_steal (&etc.escDerivedToken,
919
- &edge_tokens.escDerivedToken);
920
- // c := ECCDerivedToken
921
- _mongocrypt_buffer_steal (&etc.eccDerivedToken,
922
- &edge_tokens.eccDerivedToken);
923
-
924
- _mongocrypt_buffer_steal (&etc.encryptedTokens, &encryptedTokens);
925
- _mc_array_append_val (&payload.edgeTokenSetArray, etc);
926
-
927
- loop_ok = true;
928
- fail_loop:
929
- _mongocrypt_buffer_cleanup (&encryptedTokens);
930
- _FLE2EncryptedPayloadCommon_cleanup (&edge_tokens);
931
- _mongocrypt_buffer_cleanup (&edge_buf);
932
- if (!loop_ok) {
1058
+
1059
+ // d := EDCDerivedToken
1060
+ _mongocrypt_buffer_steal(&etc.edcDerivedToken, &edge_tokens.edcDerivedToken);
1061
+ // s := ESCDerivedToken
1062
+ _mongocrypt_buffer_steal(&etc.escDerivedToken, &edge_tokens.escDerivedToken);
1063
+ // c := ECCDerivedToken
1064
+ _mongocrypt_buffer_steal(&etc.eccDerivedToken, &edge_tokens.eccDerivedToken);
1065
+
1066
+ // p := EncryptCTR(ECOCToken, ESCDerivedFromDataTokenAndContentionFactor ||
1067
+ // ECCDerivedFromDataTokenAndContentionFactor)
1068
+ if (!_fle2_derive_encrypted_token(kb->crypt->crypto,
1069
+ &etc.encryptedTokens,
1070
+ false, // Range V2 is incompatible with FLE V1
1071
+ edge_tokens.collectionsLevel1Token,
1072
+ &etc.escDerivedToken,
1073
+ &etc.eccDerivedToken,
1074
+ (mc_optional_bool_t){0}, // Dummy value for isLeaf, unused in FLE V1
1075
+ status)) {
1076
+ goto fail_loop;
1077
+ }
1078
+
1079
+ _mc_array_append_val(&payload.edgeTokenSetArray, etc);
1080
+
1081
+ loop_ok = true;
1082
+ fail_loop:
1083
+ _mongocrypt_buffer_cleanup(&encryptedTokens);
1084
+ _FLE2EncryptedPayloadCommon_cleanup(&edge_tokens);
1085
+ _mongocrypt_buffer_cleanup(&edge_buf);
1086
+ if (!loop_ok) {
1087
+ goto fail;
1088
+ }
1089
+ }
1090
+ }
1091
+
1092
+ {
1093
+ bson_t out;
1094
+ bson_init(&out);
1095
+ mc_FLE2InsertUpdatePayload_serializeForRange(&payload, &out);
1096
+ _mongocrypt_buffer_steal_from_bson(&ciphertext->data, &out);
1097
+ }
1098
+ // Do not set ciphertext->original_bson_type and ciphertext->key_id. They are
1099
+ // not used for FLE2InsertUpdatePayload.
1100
+ ciphertext->blob_subtype = MC_SUBTYPE_FLE2InsertUpdatePayload;
1101
+
1102
+ res = true;
1103
+ fail:
1104
+ mc_edges_destroy(edges);
1105
+ mc_FLE2InsertUpdatePayload_cleanup(&payload);
1106
+ _FLE2EncryptedPayloadCommon_cleanup(&common);
1107
+
1108
+ return res;
1109
+ }
1110
+
1111
+ /**
1112
+ * Payload subtype 11: FLE2InsertUpdatePayloadV2 for range updates
1113
+ * Delegates to ..._insert_update_ciphertextForRange_v1 for subtype 4
1114
+ * when crypt.opts.use_fle2_v2 == false
1115
+ *
1116
+ * {d: EDC, s: ESC, p: encToken,
1117
+ * u: indexKeyId, t: valueType, v: value,
1118
+ * e: serverToken, l: serverDerivedFromDataToken,
1119
+ * k: contentionFactor,
1120
+ * g: [{d: EDC, s: ESC, l: serverDerivedFromDataToken, p: encToken},
1121
+ * {d: EDC, s: ESC, l: serverDerivedFromDataToken, p: encToken},
1122
+ * ...]}
1123
+ */
1124
+ static bool _mongocrypt_fle2_placeholder_to_insert_update_ciphertextForRange(_mongocrypt_key_broker_t *kb,
1125
+ _mongocrypt_marking_t *marking,
1126
+ _mongocrypt_ciphertext_t *ciphertext,
1127
+ mongocrypt_status_t *status) {
1128
+ BSON_ASSERT_PARAM(kb);
1129
+ BSON_ASSERT_PARAM(marking);
1130
+ BSON_ASSERT_PARAM(ciphertext);
1131
+ BSON_ASSERT(kb->crypt);
1132
+ BSON_ASSERT(marking->type == MONGOCRYPT_MARKING_FLE2_ENCRYPTION);
1133
+ const bool use_range_v2 = kb->crypt->opts.use_range_v2;
1134
+
1135
+ if (!kb->crypt->opts.use_fle2_v2) {
1136
+ return _mongocrypt_fle2_placeholder_to_insert_update_ciphertextForRange_v1(kb, marking, ciphertext, status);
1137
+ }
1138
+
1139
+ mc_FLE2EncryptionPlaceholder_t *placeholder = &marking->fle2;
1140
+ _FLE2EncryptedPayloadCommon_t common = {{0}};
1141
+ mc_FLE2InsertUpdatePayloadV2_t payload;
1142
+ mc_FLE2InsertUpdatePayloadV2_init(&payload);
1143
+ bool res = false;
1144
+ mc_edges_t *edges = NULL;
1145
+
1146
+ // Parse the value ("v"), min ("min"), and max ("max") from
1147
+ // FLE2EncryptionPlaceholder for range insert.
1148
+ mc_FLE2RangeInsertSpec_t insertSpec;
1149
+ if (!mc_FLE2RangeInsertSpec_parse(&insertSpec, &placeholder->v_iter, use_range_v2, status)) {
1150
+ goto fail;
1151
+ }
1152
+
1153
+ if (!_mongocrypt_fle2_placeholder_to_insert_update_common(kb,
1154
+ &payload,
1155
+ &common,
1156
+ &marking->fle2,
1157
+ &insertSpec.v,
1158
+ status)) {
1159
+ goto fail;
1160
+ }
1161
+
1162
+ // g:= array<EdgeTokenSetV2>
1163
+ {
1164
+ BSON_ASSERT(placeholder->sparsity >= 0 && (uint64_t)placeholder->sparsity <= (uint64_t)SIZE_MAX);
1165
+ edges = get_edges(&insertSpec, (size_t)placeholder->sparsity, status, kb->crypt->opts.use_range_v2);
1166
+ if (!edges) {
933
1167
  goto fail;
934
- }
935
- }
936
- }
937
-
938
- // Serialize.
939
- {
940
- bson_t out;
941
- bson_init (&out);
942
- mc_FLE2InsertUpdatePayload_serializeForRange (&payload, &out);
943
- _mongocrypt_buffer_steal_from_bson (&ciphertext->data, &out);
944
- }
945
- // Do not set ciphertext->original_bson_type and ciphertext->key_id. They are
946
- // not used for FLE2InsertUpdatePayload.
947
- ciphertext->blob_subtype = MC_SUBTYPE_FLE2InsertUpdatePayload;
948
-
949
- res = true;
1168
+ }
1169
+
1170
+ for (size_t i = 0; i < mc_edges_len(edges); ++i) {
1171
+ // Create an EdgeTokenSet from each edge.
1172
+ bool loop_ok = false;
1173
+ const char *edge = mc_edges_get(edges, i);
1174
+ bool is_leaf = mc_edges_is_leaf(edges, edge);
1175
+ _mongocrypt_buffer_t edge_buf = {0};
1176
+ _FLE2EncryptedPayloadCommon_t edge_tokens = {{0}};
1177
+ _mongocrypt_buffer_t encryptedTokens = {0};
1178
+ mc_EdgeTokenSetV2_t etc = {{0}};
1179
+
1180
+ if (!_mongocrypt_buffer_from_string(&edge_buf, edge)) {
1181
+ CLIENT_ERR("failed to copy edge to buffer");
1182
+ goto fail_loop;
1183
+ }
1184
+
1185
+ if (!_mongocrypt_fle2_placeholder_common(kb,
1186
+ &edge_tokens,
1187
+ &placeholder->index_key_id,
1188
+ &edge_buf,
1189
+ true, /* derive tokens using contentionFactor */
1190
+ payload.contentionFactor,
1191
+ status)) {
1192
+ goto fail_loop;
1193
+ }
1194
+ BSON_ASSERT(edge_tokens.eccDerivedToken.data == NULL);
1195
+
1196
+ // d := EDCDerivedToken
1197
+ _mongocrypt_buffer_steal(&etc.edcDerivedToken, &edge_tokens.edcDerivedToken);
1198
+ // s := ESCDerivedToken
1199
+ _mongocrypt_buffer_steal(&etc.escDerivedToken, &edge_tokens.escDerivedToken);
1200
+
1201
+ // l := serverDerivedFromDataToken
1202
+ _mongocrypt_buffer_steal(&etc.serverDerivedFromDataToken, &edge_tokens.serverDerivedFromDataToken);
1203
+
1204
+ // p := EncryptCTR(ECOCToken, ESCDerivedFromDataTokenAndContentionFactor)
1205
+ // Or in Range V2: p := EncryptCTR(ECOCToken, ESCDerivedFromDataTokenAndContentionFactor || isLeaf)
1206
+ if (!_fle2_derive_encrypted_token(kb->crypt->crypto,
1207
+ &etc.encryptedTokens,
1208
+ kb->crypt->opts.use_range_v2,
1209
+ edge_tokens.collectionsLevel1Token,
1210
+ &etc.escDerivedToken,
1211
+ NULL, // ecc unsed in FLE2v2
1212
+ OPT_BOOL(is_leaf),
1213
+ status)) {
1214
+ goto fail_loop;
1215
+ }
1216
+
1217
+ _mc_array_append_val(&payload.edgeTokenSetArray, etc);
1218
+
1219
+ loop_ok = true;
1220
+ fail_loop:
1221
+ _mongocrypt_buffer_cleanup(&encryptedTokens);
1222
+ _FLE2EncryptedPayloadCommon_cleanup(&edge_tokens);
1223
+ _mongocrypt_buffer_cleanup(&edge_buf);
1224
+ if (!loop_ok) {
1225
+ goto fail;
1226
+ }
1227
+ }
1228
+ }
1229
+
1230
+ // Include "range" payload fields introduced in SERVER-91889.
1231
+ payload.sparsity = OPT_I64(placeholder->sparsity);
1232
+ payload.precision = insertSpec.precision;
1233
+ payload.trimFactor = OPT_I32(mc_edges_get_used_trimFactor(edges));
1234
+ bson_value_copy(bson_iter_value(&insertSpec.min), &payload.indexMin);
1235
+ bson_value_copy(bson_iter_value(&insertSpec.max), &payload.indexMax);
1236
+
1237
+ {
1238
+ bson_t out;
1239
+ bson_init(&out);
1240
+ mc_FLE2InsertUpdatePayloadV2_serializeForRange(&payload, &out, use_range_v2);
1241
+ _mongocrypt_buffer_steal_from_bson(&ciphertext->data, &out);
1242
+ }
1243
+ // Do not set ciphertext->original_bson_type and ciphertext->key_id. They are
1244
+ // not used for FLE2InsertUpdatePayloadV2.
1245
+ ciphertext->blob_subtype = MC_SUBTYPE_FLE2InsertUpdatePayloadV2;
1246
+
1247
+ res = true;
950
1248
  fail:
951
- mc_edges_destroy (edges);
952
- mc_FLE2InsertUpdatePayload_cleanup (&payload);
953
- _mongocrypt_buffer_cleanup (&value);
954
- _FLE2EncryptedPayloadCommon_cleanup (&common);
1249
+ mc_edges_destroy(edges);
1250
+ mc_FLE2InsertUpdatePayloadV2_cleanup(&payload);
1251
+ _FLE2EncryptedPayloadCommon_cleanup(&common);
955
1252
 
956
- return res;
1253
+ return res;
957
1254
  }
958
1255
 
1256
+ /**
1257
+ * Payload subtype 5: FLE2FindEqualityPayload
1258
+ *
1259
+ * {d: EDC, s: ESC, c: ECC, e: serverToken, cm: maxContentionFactor}
1260
+ */
1261
+ static bool _mongocrypt_fle2_placeholder_to_find_ciphertext_v1(_mongocrypt_key_broker_t *kb,
1262
+ _mongocrypt_marking_t *marking,
1263
+ _mongocrypt_ciphertext_t *ciphertext,
1264
+ mongocrypt_status_t *status) {
1265
+ BSON_ASSERT_PARAM(kb);
1266
+ BSON_ASSERT_PARAM(marking);
1267
+ BSON_ASSERT_PARAM(ciphertext);
1268
+
1269
+ _FLE2EncryptedPayloadCommon_t common = {{0}};
1270
+ _mongocrypt_buffer_t value = {0};
1271
+ mc_FLE2EncryptionPlaceholder_t *placeholder = &marking->fle2;
1272
+ mc_FLE2FindEqualityPayload_t payload;
1273
+ bool res = false;
1274
+
1275
+ BSON_ASSERT(kb->crypt->opts.use_fle2_v2 == false);
1276
+ BSON_ASSERT(marking->type == MONGOCRYPT_MARKING_FLE2_ENCRYPTION);
1277
+ BSON_ASSERT(placeholder->type == MONGOCRYPT_FLE2_PLACEHOLDER_TYPE_FIND);
1278
+ _mongocrypt_buffer_init(&value);
1279
+ mc_FLE2FindEqualityPayload_init(&payload);
1280
+
1281
+ _mongocrypt_buffer_from_iter(&value, &placeholder->v_iter);
1282
+
1283
+ if (!_mongocrypt_fle2_placeholder_common(kb,
1284
+ &common,
1285
+ &placeholder->index_key_id,
1286
+ &value,
1287
+ false, /* derive tokens without contentionFactor */
1288
+ placeholder->maxContentionFactor, /* ignored */
1289
+ status)) {
1290
+ goto fail;
1291
+ }
1292
+
1293
+ // d := EDCDerivedToken
1294
+ _mongocrypt_buffer_steal(&payload.edcDerivedToken, &common.edcDerivedToken);
1295
+ // s := ESCDerivedToken
1296
+ _mongocrypt_buffer_steal(&payload.escDerivedToken, &common.escDerivedToken);
1297
+ // c := ECCDerivedToken
1298
+ _mongocrypt_buffer_steal(&payload.eccDerivedToken, &common.eccDerivedToken);
1299
+
1300
+ // e := ServerDataEncryptionLevel1Token
1301
+ _mongocrypt_buffer_copy_to(mc_ServerDataEncryptionLevel1Token_get(common.serverDataEncryptionLevel1Token),
1302
+ &payload.serverEncryptionToken);
1303
+
1304
+ payload.maxContentionFactor = placeholder->maxContentionFactor;
1305
+
1306
+ {
1307
+ bson_t out;
1308
+ bson_init(&out);
1309
+ mc_FLE2FindEqualityPayload_serialize(&payload, &out);
1310
+ _mongocrypt_buffer_steal_from_bson(&ciphertext->data, &out);
1311
+ }
1312
+ // Do not set ciphertext->original_bson_type and ciphertext->key_id. They are
1313
+ // not used for FLE2FindEqualityPayload.
1314
+ ciphertext->blob_subtype = MC_SUBTYPE_FLE2FindEqualityPayload;
1315
+
1316
+ res = true;
1317
+ fail:
1318
+ mc_FLE2FindEqualityPayload_cleanup(&payload);
1319
+ _mongocrypt_buffer_cleanup(&value);
1320
+ _FLE2EncryptedPayloadCommon_cleanup(&common);
959
1321
 
960
- static bool
961
- _mongocrypt_fle2_placeholder_to_find_ciphertext (
962
- _mongocrypt_key_broker_t *kb,
963
- _mongocrypt_marking_t *marking,
964
- _mongocrypt_ciphertext_t *ciphertext,
965
- mongocrypt_status_t *status)
966
- {
967
- BSON_ASSERT_PARAM (kb);
968
- BSON_ASSERT_PARAM (marking);
969
- BSON_ASSERT_PARAM (ciphertext);
970
-
971
- _FLE2EncryptedPayloadCommon_t common = {{0}};
972
- _mongocrypt_buffer_t value = {0};
973
- mc_FLE2EncryptionPlaceholder_t *placeholder = &marking->fle2;
974
- mc_FLE2FindEqualityPayload_t payload;
975
- bool res = false;
976
-
977
- BSON_ASSERT (marking->type == MONGOCRYPT_MARKING_FLE2_ENCRYPTION);
978
- BSON_ASSERT (placeholder->type == MONGOCRYPT_FLE2_PLACEHOLDER_TYPE_FIND);
979
- _mongocrypt_ciphertext_init (ciphertext);
980
- _mongocrypt_buffer_init (&value);
981
- mc_FLE2FindEqualityPayload_init (&payload);
982
-
983
- _mongocrypt_buffer_from_iter (&value, &placeholder->v_iter);
984
-
985
- if (!_mongocrypt_fle2_placeholder_common (
986
- kb,
987
- &common,
988
- &placeholder->index_key_id,
989
- &value,
990
- false, /* derive tokens without counter */
991
- placeholder->maxContentionCounter,
992
- status)) {
993
- goto fail;
994
- }
995
-
996
- // d := EDCDerivedToken
997
- _mongocrypt_buffer_steal (&payload.edcDerivedToken, &common.edcDerivedToken);
998
- // s := ESCDerivedToken
999
- _mongocrypt_buffer_steal (&payload.escDerivedToken, &common.escDerivedToken);
1000
- // c := ECCDerivedToken
1001
- _mongocrypt_buffer_steal (&payload.eccDerivedToken, &common.eccDerivedToken);
1002
-
1003
- // e := ServerDataEncryptionLevel1Token
1004
- BSON_ASSERT (kb->crypt);
1005
- {
1006
- mc_ServerDataEncryptionLevel1Token_t *serverToken =
1007
- mc_ServerDataEncryptionLevel1Token_new (
1008
- kb->crypt->crypto, &common.tokenKey, status);
1009
- if (!serverToken) {
1010
- goto fail;
1011
- }
1012
- _mongocrypt_buffer_copy_to (
1013
- mc_ServerDataEncryptionLevel1Token_get (serverToken),
1014
- &payload.serverEncryptionToken);
1015
- mc_ServerDataEncryptionLevel1Token_destroy (serverToken);
1016
- }
1017
-
1018
- payload.maxContentionCounter = placeholder->maxContentionCounter;
1019
-
1020
- {
1021
- bson_t out;
1022
- bson_init (&out);
1023
- mc_FLE2FindEqualityPayload_serialize (&payload, &out);
1024
- _mongocrypt_buffer_steal_from_bson (&ciphertext->data, &out);
1025
- }
1026
- // Do not set ciphertext->original_bson_type and ciphertext->key_id. They are
1027
- // not used for FLE2FindEqualityPayload.
1028
- ciphertext->blob_subtype = MC_SUBTYPE_FLE2FindEqualityPayload;
1029
-
1030
- res = true;
1322
+ return res;
1323
+ }
1324
+
1325
+ /**
1326
+ * Payload subtype 12: FLE2FindEqualityPayloadV2
1327
+ * Delegates to ..._find_ciphertext_v1 when crypt->opts.use_fle2_v2 == false.
1328
+ *
1329
+ * {d: EDC, s: ESC, l: serverDerivedFromDataToken, cm: maxContentionFactor}
1330
+ */
1331
+ static bool _mongocrypt_fle2_placeholder_to_find_ciphertext(_mongocrypt_key_broker_t *kb,
1332
+ _mongocrypt_marking_t *marking,
1333
+ _mongocrypt_ciphertext_t *ciphertext,
1334
+ mongocrypt_status_t *status) {
1335
+ BSON_ASSERT_PARAM(kb);
1336
+ BSON_ASSERT_PARAM(marking);
1337
+ BSON_ASSERT_PARAM(ciphertext);
1338
+
1339
+ if (kb->crypt->opts.use_fle2_v2 == false) {
1340
+ return _mongocrypt_fle2_placeholder_to_find_ciphertext_v1(kb, marking, ciphertext, status);
1341
+ }
1342
+
1343
+ _FLE2EncryptedPayloadCommon_t common = {{0}};
1344
+ _mongocrypt_buffer_t value = {0};
1345
+ mc_FLE2EncryptionPlaceholder_t *placeholder = &marking->fle2;
1346
+ mc_FLE2FindEqualityPayloadV2_t payload;
1347
+ bool res = false;
1348
+
1349
+ BSON_ASSERT(marking->type == MONGOCRYPT_MARKING_FLE2_ENCRYPTION);
1350
+ BSON_ASSERT(placeholder->type == MONGOCRYPT_FLE2_PLACEHOLDER_TYPE_FIND);
1351
+
1352
+ _mongocrypt_buffer_init(&value);
1353
+ mc_FLE2FindEqualityPayloadV2_init(&payload);
1354
+
1355
+ _mongocrypt_buffer_from_iter(&value, &placeholder->v_iter);
1356
+
1357
+ if (!_mongocrypt_fle2_placeholder_common(kb,
1358
+ &common,
1359
+ &placeholder->index_key_id,
1360
+ &value,
1361
+ false, /* derive tokens without contentionFactor */
1362
+ placeholder->maxContentionFactor, /* ignored */
1363
+ status)) {
1364
+ goto fail;
1365
+ }
1366
+ BSON_ASSERT(common.eccDerivedToken.data == NULL);
1367
+
1368
+ // d := EDCDerivedToken
1369
+ _mongocrypt_buffer_steal(&payload.edcDerivedToken, &common.edcDerivedToken);
1370
+ // s := ESCDerivedToken
1371
+ _mongocrypt_buffer_steal(&payload.escDerivedToken, &common.escDerivedToken);
1372
+ // l := serverDerivedFromDataToken
1373
+ _mongocrypt_buffer_steal(&payload.serverDerivedFromDataToken, &common.serverDerivedFromDataToken);
1374
+
1375
+ // cm := maxContentionFactor
1376
+ payload.maxContentionFactor = placeholder->maxContentionFactor;
1377
+
1378
+ {
1379
+ bson_t out;
1380
+ bson_init(&out);
1381
+ mc_FLE2FindEqualityPayloadV2_serialize(&payload, &out);
1382
+ _mongocrypt_buffer_steal_from_bson(&ciphertext->data, &out);
1383
+ }
1384
+ // Do not set ciphertext->original_bson_type and ciphertext->key_id. They are
1385
+ // not used for FLE2FindEqualityPayloadV2.
1386
+ ciphertext->blob_subtype = MC_SUBTYPE_FLE2FindEqualityPayloadV2;
1387
+
1388
+ res = true;
1031
1389
  fail:
1032
- mc_FLE2FindEqualityPayload_cleanup (&payload);
1033
- _mongocrypt_buffer_cleanup (&value);
1034
- _FLE2EncryptedPayloadCommon_cleanup (&common);
1390
+ mc_FLE2FindEqualityPayloadV2_cleanup(&payload);
1391
+ _mongocrypt_buffer_cleanup(&value);
1392
+ _FLE2EncryptedPayloadCommon_cleanup(&common);
1035
1393
 
1036
- return res;
1394
+ return res;
1037
1395
  }
1038
1396
 
1039
- static bool
1040
- isInfinite (bson_iter_t *iter)
1041
- {
1042
- return mc_isinf (bson_iter_double (iter));
1397
+ static bool isInfinite(bson_iter_t *iter) {
1398
+ return mc_isinf(bson_iter_double(iter));
1043
1399
  }
1044
1400
 
1045
1401
  // mc_get_mincover_from_FLE2RangeFindSpec creates and returns a mincover from an
1046
1402
  // FLE2RangeFindSpec. Returns NULL on error.
1047
- mc_mincover_t *
1048
- mc_get_mincover_from_FLE2RangeFindSpec (mc_FLE2RangeFindSpec_t *findSpec,
1049
- size_t sparsity,
1050
- mongocrypt_status_t *status)
1051
- {
1052
- BSON_ASSERT_PARAM (findSpec);
1053
- BSON_ASSERT (findSpec->edgesInfo.set);
1054
-
1055
- bson_type_t bsonType = bson_iter_type (&findSpec->edgesInfo.value.indexMin);
1056
-
1057
- if (bson_iter_type (&findSpec->edgesInfo.value.indexMin) !=
1058
- bson_iter_type (&findSpec->edgesInfo.value.indexMax)) {
1059
- CLIENT_ERR (
1060
- "indexMin and indexMax must have the same type. Got: %s indexMin and "
1061
- "%s indexMax",
1062
- mc_bson_type_to_string (
1063
- bson_iter_type (&findSpec->edgesInfo.value.indexMin)),
1064
- mc_bson_type_to_string (
1065
- bson_iter_type (&findSpec->edgesInfo.value.indexMax)));
1066
- return NULL;
1067
- }
1068
-
1069
- bson_iter_t lowerBound = findSpec->edgesInfo.value.lowerBound;
1070
- bson_iter_t upperBound = findSpec->edgesInfo.value.upperBound;
1071
- bool includeLowerBound = findSpec->edgesInfo.value.lbIncluded;
1072
- bool includeUpperBound = findSpec->edgesInfo.value.ubIncluded;
1073
-
1074
- // Open-ended ranges are represented with infinity as the other endpoint.
1075
- // Resolve infinite bounds at this point to end at the min or max for this
1076
- // index.
1077
- if (isInfinite (&lowerBound)) {
1078
- lowerBound = findSpec->edgesInfo.value.indexMin;
1079
- includeLowerBound = true;
1080
- }
1081
- if (isInfinite (&upperBound)) {
1082
- upperBound = findSpec->edgesInfo.value.indexMax;
1083
- includeUpperBound = true;
1084
- }
1085
-
1086
- if (bson_iter_type (&lowerBound) != bsonType) {
1087
- CLIENT_ERR ("expected lowerBound to match index type %s, got %s",
1088
- mc_bson_type_to_string (bsonType),
1089
- mc_bson_type_to_string (bson_iter_type (&lowerBound)));
1090
- return NULL;
1091
- }
1092
-
1093
- if (bson_iter_type (&upperBound) != bsonType) {
1094
- CLIENT_ERR ("expected upperBound to match index type %s, got %s",
1095
- mc_bson_type_to_string (bsonType),
1096
- mc_bson_type_to_string (bson_iter_type (&upperBound)));
1097
- return NULL;
1098
- }
1099
-
1100
- switch (bsonType) {
1101
- case BSON_TYPE_INT32:
1102
- BSON_ASSERT (bson_iter_type (&lowerBound) == BSON_TYPE_INT32);
1103
- BSON_ASSERT (bson_iter_type (&upperBound) == BSON_TYPE_INT32);
1104
- BSON_ASSERT (bson_iter_type (&findSpec->edgesInfo.value.indexMin) ==
1105
- BSON_TYPE_INT32);
1106
- BSON_ASSERT (bson_iter_type (&findSpec->edgesInfo.value.indexMax) ==
1107
- BSON_TYPE_INT32);
1108
- return mc_getMincoverInt32 (
1109
- (mc_getMincoverInt32_args_t){
1110
- .lowerBound = bson_iter_int32 (&lowerBound),
1111
- .includeLowerBound = includeLowerBound,
1112
- .upperBound = bson_iter_int32 (&upperBound),
1113
- .includeUpperBound = includeUpperBound,
1114
- .min =
1115
- OPT_I32 (bson_iter_int32 (&findSpec->edgesInfo.value.indexMin)),
1116
- .max =
1117
- OPT_I32 (bson_iter_int32 (&findSpec->edgesInfo.value.indexMax)),
1118
- .sparsity = sparsity},
1119
- status);
1120
-
1121
- case BSON_TYPE_INT64:
1122
- BSON_ASSERT (bson_iter_type (&lowerBound) == BSON_TYPE_INT64);
1123
- BSON_ASSERT (bson_iter_type (&upperBound) == BSON_TYPE_INT64);
1124
- BSON_ASSERT (bson_iter_type (&findSpec->edgesInfo.value.indexMin) ==
1125
- BSON_TYPE_INT64);
1126
- BSON_ASSERT (bson_iter_type (&findSpec->edgesInfo.value.indexMax) ==
1127
- BSON_TYPE_INT64);
1128
- return mc_getMincoverInt64 (
1129
- (mc_getMincoverInt64_args_t){
1130
- .lowerBound = bson_iter_int64 (&lowerBound),
1131
- .includeLowerBound = includeLowerBound,
1132
- .upperBound = bson_iter_int64 (&upperBound),
1133
- .includeUpperBound = includeUpperBound,
1134
- .min =
1135
- OPT_I64 (bson_iter_int64 (&findSpec->edgesInfo.value.indexMin)),
1136
- .max =
1137
- OPT_I64 (bson_iter_int64 (&findSpec->edgesInfo.value.indexMax)),
1138
- .sparsity = sparsity},
1139
- status);
1140
- case BSON_TYPE_DATE_TIME:
1141
- BSON_ASSERT (bson_iter_type (&lowerBound) == BSON_TYPE_DATE_TIME);
1142
- BSON_ASSERT (bson_iter_type (&upperBound) == BSON_TYPE_DATE_TIME);
1143
- BSON_ASSERT (bson_iter_type (&findSpec->edgesInfo.value.indexMin) ==
1144
- BSON_TYPE_DATE_TIME);
1145
- BSON_ASSERT (bson_iter_type (&findSpec->edgesInfo.value.indexMax) ==
1146
- BSON_TYPE_DATE_TIME);
1147
- return mc_getMincoverInt64 (
1148
- (mc_getMincoverInt64_args_t){
1149
- .lowerBound = bson_iter_date_time (&lowerBound),
1150
- .includeLowerBound = includeLowerBound,
1151
- .upperBound = bson_iter_date_time (&upperBound),
1152
- .includeUpperBound = includeUpperBound,
1153
- .min = OPT_I64 (
1154
- bson_iter_date_time (&findSpec->edgesInfo.value.indexMin)),
1155
- .max = OPT_I64 (
1156
- bson_iter_date_time (&findSpec->edgesInfo.value.indexMax)),
1157
- .sparsity = sparsity},
1158
- status);
1159
- case BSON_TYPE_DOUBLE: {
1160
- BSON_ASSERT (bson_iter_type (&lowerBound) == BSON_TYPE_DOUBLE);
1161
- BSON_ASSERT (bson_iter_type (&upperBound) == BSON_TYPE_DOUBLE);
1162
- BSON_ASSERT (bson_iter_type (&findSpec->edgesInfo.value.indexMin) ==
1163
- BSON_TYPE_DOUBLE);
1164
- BSON_ASSERT (bson_iter_type (&findSpec->edgesInfo.value.indexMax) ==
1165
- BSON_TYPE_DOUBLE);
1166
-
1167
- mc_getMincoverDouble_args_t args = {
1168
- .lowerBound = bson_iter_double (&lowerBound),
1169
- .includeLowerBound = includeLowerBound,
1170
- .upperBound = bson_iter_double (&upperBound),
1171
- .includeUpperBound = includeUpperBound,
1172
- .sparsity = sparsity};
1173
- if (findSpec->edgesInfo.value.precision.set) {
1174
- // If precision is set, pass min/max/precision to mc_getMincoverDouble.
1175
- // Do not pass min/max if precision is not set. All three must be set
1176
- // or all three must be unset in mc_getTypeInfoDouble.
1177
- args.min =
1178
- OPT_DOUBLE (bson_iter_double (&findSpec->edgesInfo.value.indexMin));
1179
- args.max =
1180
- OPT_DOUBLE (bson_iter_double (&findSpec->edgesInfo.value.indexMax));
1181
- args.precision = findSpec->edgesInfo.value.precision;
1182
- }
1183
- return mc_getMincoverDouble (args, status);
1184
- }
1185
- case BSON_TYPE_DECIMAL128: {
1403
+ mc_mincover_t *mc_get_mincover_from_FLE2RangeFindSpec(mc_FLE2RangeFindSpec_t *findSpec,
1404
+ size_t sparsity,
1405
+ mongocrypt_status_t *status,
1406
+ bool use_range_v2) {
1407
+ BSON_ASSERT_PARAM(findSpec);
1408
+ BSON_ASSERT(findSpec->edgesInfo.set);
1409
+
1410
+ bson_type_t bsonType = bson_iter_type(&findSpec->edgesInfo.value.indexMin);
1411
+
1412
+ if (bson_iter_type(&findSpec->edgesInfo.value.indexMin) != bson_iter_type(&findSpec->edgesInfo.value.indexMax)) {
1413
+ CLIENT_ERR("indexMin and indexMax must have the same type. Got: %s indexMin and "
1414
+ "%s indexMax",
1415
+ mc_bson_type_to_string(bson_iter_type(&findSpec->edgesInfo.value.indexMin)),
1416
+ mc_bson_type_to_string(bson_iter_type(&findSpec->edgesInfo.value.indexMax)));
1417
+ return NULL;
1418
+ }
1419
+
1420
+ bson_iter_t lowerBound = findSpec->edgesInfo.value.lowerBound;
1421
+ bson_iter_t upperBound = findSpec->edgesInfo.value.upperBound;
1422
+ bool includeLowerBound = findSpec->edgesInfo.value.lbIncluded;
1423
+ bool includeUpperBound = findSpec->edgesInfo.value.ubIncluded;
1424
+
1425
+ // Open-ended ranges are represented with infinity as the other endpoint.
1426
+ // Resolve infinite bounds at this point to end at the min or max for this
1427
+ // index.
1428
+ if (isInfinite(&lowerBound)) {
1429
+ lowerBound = findSpec->edgesInfo.value.indexMin;
1430
+ includeLowerBound = true;
1431
+ }
1432
+ if (isInfinite(&upperBound)) {
1433
+ upperBound = findSpec->edgesInfo.value.indexMax;
1434
+ includeUpperBound = true;
1435
+ }
1436
+
1437
+ if (bson_iter_type(&lowerBound) != bsonType) {
1438
+ CLIENT_ERR("expected lowerBound to match index type %s, got %s",
1439
+ mc_bson_type_to_string(bsonType),
1440
+ mc_bson_type_to_string(bson_iter_type(&lowerBound)));
1441
+ return NULL;
1442
+ }
1443
+
1444
+ if (bson_iter_type(&upperBound) != bsonType) {
1445
+ CLIENT_ERR("expected upperBound to match index type %s, got %s",
1446
+ mc_bson_type_to_string(bsonType),
1447
+ mc_bson_type_to_string(bson_iter_type(&upperBound)));
1448
+ return NULL;
1449
+ }
1450
+
1451
+ switch (bsonType) {
1452
+ case BSON_TYPE_INT32:
1453
+ BSON_ASSERT(bson_iter_type(&lowerBound) == BSON_TYPE_INT32);
1454
+ BSON_ASSERT(bson_iter_type(&upperBound) == BSON_TYPE_INT32);
1455
+ BSON_ASSERT(bson_iter_type(&findSpec->edgesInfo.value.indexMin) == BSON_TYPE_INT32);
1456
+ BSON_ASSERT(bson_iter_type(&findSpec->edgesInfo.value.indexMax) == BSON_TYPE_INT32);
1457
+
1458
+ return mc_getMincoverInt32(
1459
+ (mc_getMincoverInt32_args_t){.lowerBound = bson_iter_int32(&lowerBound),
1460
+ .includeLowerBound = includeLowerBound,
1461
+ .upperBound = bson_iter_int32(&upperBound),
1462
+ .includeUpperBound = includeUpperBound,
1463
+ .min = OPT_I32(bson_iter_int32(&findSpec->edgesInfo.value.indexMin)),
1464
+ .max = OPT_I32(bson_iter_int32(&findSpec->edgesInfo.value.indexMax)),
1465
+ .sparsity = sparsity,
1466
+ .trimFactor = findSpec->edgesInfo.value.trimFactor},
1467
+ status,
1468
+ use_range_v2);
1469
+
1470
+ case BSON_TYPE_INT64:
1471
+ BSON_ASSERT(bson_iter_type(&lowerBound) == BSON_TYPE_INT64);
1472
+ BSON_ASSERT(bson_iter_type(&upperBound) == BSON_TYPE_INT64);
1473
+ BSON_ASSERT(bson_iter_type(&findSpec->edgesInfo.value.indexMin) == BSON_TYPE_INT64);
1474
+ BSON_ASSERT(bson_iter_type(&findSpec->edgesInfo.value.indexMax) == BSON_TYPE_INT64);
1475
+ return mc_getMincoverInt64(
1476
+ (mc_getMincoverInt64_args_t){.lowerBound = bson_iter_int64(&lowerBound),
1477
+ .includeLowerBound = includeLowerBound,
1478
+ .upperBound = bson_iter_int64(&upperBound),
1479
+ .includeUpperBound = includeUpperBound,
1480
+ .min = OPT_I64(bson_iter_int64(&findSpec->edgesInfo.value.indexMin)),
1481
+ .max = OPT_I64(bson_iter_int64(&findSpec->edgesInfo.value.indexMax)),
1482
+ .sparsity = sparsity,
1483
+ .trimFactor = findSpec->edgesInfo.value.trimFactor},
1484
+ status,
1485
+ use_range_v2);
1486
+ case BSON_TYPE_DATE_TIME:
1487
+ BSON_ASSERT(bson_iter_type(&lowerBound) == BSON_TYPE_DATE_TIME);
1488
+ BSON_ASSERT(bson_iter_type(&upperBound) == BSON_TYPE_DATE_TIME);
1489
+ BSON_ASSERT(bson_iter_type(&findSpec->edgesInfo.value.indexMin) == BSON_TYPE_DATE_TIME);
1490
+ BSON_ASSERT(bson_iter_type(&findSpec->edgesInfo.value.indexMax) == BSON_TYPE_DATE_TIME);
1491
+ return mc_getMincoverInt64(
1492
+ (mc_getMincoverInt64_args_t){.lowerBound = bson_iter_date_time(&lowerBound),
1493
+ .includeLowerBound = includeLowerBound,
1494
+ .upperBound = bson_iter_date_time(&upperBound),
1495
+ .includeUpperBound = includeUpperBound,
1496
+ .min = OPT_I64(bson_iter_date_time(&findSpec->edgesInfo.value.indexMin)),
1497
+ .max = OPT_I64(bson_iter_date_time(&findSpec->edgesInfo.value.indexMax)),
1498
+ .sparsity = sparsity,
1499
+ .trimFactor = findSpec->edgesInfo.value.trimFactor},
1500
+ status,
1501
+ use_range_v2);
1502
+ case BSON_TYPE_DOUBLE: {
1503
+ BSON_ASSERT(bson_iter_type(&lowerBound) == BSON_TYPE_DOUBLE);
1504
+ BSON_ASSERT(bson_iter_type(&upperBound) == BSON_TYPE_DOUBLE);
1505
+ BSON_ASSERT(bson_iter_type(&findSpec->edgesInfo.value.indexMin) == BSON_TYPE_DOUBLE);
1506
+ BSON_ASSERT(bson_iter_type(&findSpec->edgesInfo.value.indexMax) == BSON_TYPE_DOUBLE);
1507
+
1508
+ mc_getMincoverDouble_args_t args = {.lowerBound = bson_iter_double(&lowerBound),
1509
+ .includeLowerBound = includeLowerBound,
1510
+ .upperBound = bson_iter_double(&upperBound),
1511
+ .includeUpperBound = includeUpperBound,
1512
+ .sparsity = sparsity,
1513
+ .trimFactor = findSpec->edgesInfo.value.trimFactor};
1514
+ if (findSpec->edgesInfo.value.precision.set) {
1515
+ // If precision is set, pass min/max/precision to mc_getMincoverDouble.
1516
+ // Do not pass min/max if precision is not set. All three must be set
1517
+ // or all three must be unset in mc_getTypeInfoDouble.
1518
+ args.min = OPT_DOUBLE(bson_iter_double(&findSpec->edgesInfo.value.indexMin));
1519
+ args.max = OPT_DOUBLE(bson_iter_double(&findSpec->edgesInfo.value.indexMax));
1520
+ args.precision = findSpec->edgesInfo.value.precision;
1521
+ }
1522
+ return mc_getMincoverDouble(args, status, use_range_v2);
1523
+ }
1524
+ case BSON_TYPE_DECIMAL128: {
1186
1525
  #if MONGOCRYPT_HAVE_DECIMAL128_SUPPORT
1187
- BSON_ASSERT (bson_iter_type (&lowerBound) == BSON_TYPE_DECIMAL128);
1188
- BSON_ASSERT (bson_iter_type (&upperBound) == BSON_TYPE_DECIMAL128);
1189
- BSON_ASSERT (bson_iter_type (&findSpec->edgesInfo.value.indexMin) ==
1190
- BSON_TYPE_DECIMAL128);
1191
- BSON_ASSERT (bson_iter_type (&findSpec->edgesInfo.value.indexMax) ==
1192
- BSON_TYPE_DECIMAL128);
1193
-
1194
- mc_getMincoverDecimal128_args_t args = {
1195
- .lowerBound = mc_dec128_from_bson_iter (&lowerBound),
1196
- .includeLowerBound = includeLowerBound,
1197
- .upperBound = mc_dec128_from_bson_iter (&upperBound),
1198
- .includeUpperBound = includeUpperBound,
1199
- .sparsity = sparsity,
1200
- };
1201
- if (findSpec->edgesInfo.value.precision.set) {
1202
- args.min = OPT_MC_DEC128 (
1203
- mc_dec128_from_bson_iter (&findSpec->edgesInfo.value.indexMin));
1204
- args.max = OPT_MC_DEC128 (
1205
- mc_dec128_from_bson_iter (&findSpec->edgesInfo.value.indexMax));
1206
- args.precision = findSpec->edgesInfo.value.precision;
1207
- }
1208
- return mc_getMincoverDecimal128 (args, status);
1526
+ BSON_ASSERT(bson_iter_type(&lowerBound) == BSON_TYPE_DECIMAL128);
1527
+ BSON_ASSERT(bson_iter_type(&upperBound) == BSON_TYPE_DECIMAL128);
1528
+ BSON_ASSERT(bson_iter_type(&findSpec->edgesInfo.value.indexMin) == BSON_TYPE_DECIMAL128);
1529
+ BSON_ASSERT(bson_iter_type(&findSpec->edgesInfo.value.indexMax) == BSON_TYPE_DECIMAL128);
1530
+
1531
+ mc_getMincoverDecimal128_args_t args = {.lowerBound = mc_dec128_from_bson_iter(&lowerBound),
1532
+ .includeLowerBound = includeLowerBound,
1533
+ .upperBound = mc_dec128_from_bson_iter(&upperBound),
1534
+ .includeUpperBound = includeUpperBound,
1535
+ .sparsity = sparsity,
1536
+ .trimFactor = findSpec->edgesInfo.value.trimFactor};
1537
+ if (findSpec->edgesInfo.value.precision.set) {
1538
+ args.min = OPT_MC_DEC128(mc_dec128_from_bson_iter(&findSpec->edgesInfo.value.indexMin));
1539
+ args.max = OPT_MC_DEC128(mc_dec128_from_bson_iter(&findSpec->edgesInfo.value.indexMax));
1540
+ args.precision = findSpec->edgesInfo.value.precision;
1541
+ }
1542
+ return mc_getMincoverDecimal128(args, status, use_range_v2);
1209
1543
  #else // ↑↑↑↑↑↑↑↑ With Decimal128 / Without ↓↓↓↓↓↓↓↓↓↓
1210
- CLIENT_ERR ("FLE2 find is not supported for Decimal128: libmongocrypt "
1211
- "was built without Decimal128 support");
1212
- return NULL;
1544
+ CLIENT_ERR("FLE2 find is not supported for Decimal128: libmongocrypt "
1545
+ "was built without Decimal128 support");
1546
+ return NULL;
1213
1547
  #endif
1214
- }
1215
-
1216
- case BSON_TYPE_EOD:
1217
- case BSON_TYPE_UTF8:
1218
- case BSON_TYPE_DOCUMENT:
1219
- case BSON_TYPE_ARRAY:
1220
- case BSON_TYPE_BINARY:
1221
- case BSON_TYPE_UNDEFINED:
1222
- case BSON_TYPE_OID:
1223
- case BSON_TYPE_BOOL:
1224
- case BSON_TYPE_NULL:
1225
- case BSON_TYPE_REGEX:
1226
- case BSON_TYPE_DBPOINTER:
1227
- case BSON_TYPE_CODE:
1228
- case BSON_TYPE_SYMBOL:
1229
- case BSON_TYPE_CODEWSCOPE:
1230
- case BSON_TYPE_TIMESTAMP:
1231
- case BSON_TYPE_MAXKEY:
1232
- case BSON_TYPE_MINKEY:
1233
- default:
1234
- CLIENT_ERR ("FLE2 find is not supported for type: %s",
1235
- mc_bson_type_to_string (bsonType));
1236
- return NULL;
1237
- }
1548
+ }
1549
+
1550
+ case BSON_TYPE_EOD:
1551
+ case BSON_TYPE_UTF8:
1552
+ case BSON_TYPE_DOCUMENT:
1553
+ case BSON_TYPE_ARRAY:
1554
+ case BSON_TYPE_BINARY:
1555
+ case BSON_TYPE_UNDEFINED:
1556
+ case BSON_TYPE_OID:
1557
+ case BSON_TYPE_BOOL:
1558
+ case BSON_TYPE_NULL:
1559
+ case BSON_TYPE_REGEX:
1560
+ case BSON_TYPE_DBPOINTER:
1561
+ case BSON_TYPE_CODE:
1562
+ case BSON_TYPE_SYMBOL:
1563
+ case BSON_TYPE_CODEWSCOPE:
1564
+ case BSON_TYPE_TIMESTAMP:
1565
+ case BSON_TYPE_MAXKEY:
1566
+ case BSON_TYPE_MINKEY:
1567
+ default: CLIENT_ERR("FLE2 find is not supported for type: %s", mc_bson_type_to_string(bsonType)); return NULL;
1568
+ }
1238
1569
  }
1239
1570
 
1240
- static bool
1241
- _mongocrypt_fle2_placeholder_to_find_ciphertextForRange (
1242
- _mongocrypt_key_broker_t *kb,
1243
- _mongocrypt_marking_t *marking,
1244
- _mongocrypt_ciphertext_t *ciphertext,
1245
- mongocrypt_status_t *status)
1246
- {
1247
- BSON_ASSERT_PARAM (kb);
1248
- BSON_ASSERT_PARAM (marking);
1249
- BSON_ASSERT_PARAM (ciphertext);
1250
- BSON_ASSERT (kb->crypt);
1251
-
1252
- _mongocrypt_crypto_t *crypto = kb->crypt->crypto;
1253
- mc_FLE2EncryptionPlaceholder_t *placeholder = &marking->fle2;
1254
- mc_FLE2FindRangePayload_t payload;
1255
- bool res = false;
1256
- mc_mincover_t *mincover = NULL;
1257
- _mongocrypt_buffer_t tokenKey = {0};
1258
-
1259
- BSON_ASSERT (marking->type == MONGOCRYPT_MARKING_FLE2_ENCRYPTION);
1260
- BSON_ASSERT (placeholder);
1261
- BSON_ASSERT (placeholder->type == MONGOCRYPT_FLE2_PLACEHOLDER_TYPE_FIND);
1262
- BSON_ASSERT (placeholder->algorithm == MONGOCRYPT_FLE2_ALGORITHM_RANGE);
1263
- _mongocrypt_ciphertext_init (ciphertext);
1264
- mc_FLE2FindRangePayload_init (&payload);
1265
-
1266
- // Parse the query bounds and index bounds from FLE2EncryptionPlaceholder for
1267
- // range find.
1268
- mc_FLE2RangeFindSpec_t findSpec;
1269
- if (!mc_FLE2RangeFindSpec_parse (&findSpec, &placeholder->v_iter, status)) {
1270
- goto fail;
1271
- }
1272
-
1273
- if (findSpec.edgesInfo.set) {
1274
- // cm := Queryable Encryption max counter
1275
- payload.payload.value.maxContentionCounter =
1276
- placeholder->maxContentionCounter;
1277
-
1278
- // e := ServerDataEncryptionLevel1Token
1279
- {
1280
- if (!_get_tokenKey (
1281
- kb, &placeholder->index_key_id, &tokenKey, status)) {
1282
- goto fail;
1283
- }
1284
-
1285
- mc_ServerDataEncryptionLevel1Token_t *serverToken =
1286
- mc_ServerDataEncryptionLevel1Token_new (crypto, &tokenKey, status);
1287
- if (!serverToken) {
1288
- goto fail;
1289
- }
1290
- _mongocrypt_buffer_copy_to (
1291
- mc_ServerDataEncryptionLevel1Token_get (serverToken),
1292
- &payload.payload.value.serverEncryptionToken);
1293
- mc_ServerDataEncryptionLevel1Token_destroy (serverToken);
1294
- }
1295
-
1296
- // g:= array<EdgeFindTokenSet>
1297
- {
1298
- BSON_ASSERT (placeholder->sparsity >= 0 &&
1299
- (uint64_t) placeholder->sparsity <= (uint64_t) SIZE_MAX);
1300
- mincover = mc_get_mincover_from_FLE2RangeFindSpec (
1301
- &findSpec, (size_t) placeholder->sparsity, status);
1302
- if (!mincover) {
1303
- goto fail;
1304
- }
1305
-
1306
- for (size_t i = 0; i < mc_mincover_len (mincover); i++) {
1307
- // Create a EdgeFindTokenSet from each edge.
1308
- bool loop_ok = false;
1309
- const char *edge = mc_mincover_get (mincover, i);
1310
- _mongocrypt_buffer_t edge_buf = {0};
1311
- _FLE2EncryptedPayloadCommon_t edge_tokens = {{0}};
1312
- mc_EdgeFindTokenSet_t eftc = {{0}};
1571
+ /**
1572
+ * Payload subtype 10: FLE2FindRangePayload
1573
+ *
1574
+ * {e: serverToken, cm: maxContentionFactor,
1575
+ * g: [{d: EDC, s: ESC, c: ECC}, ...]}
1576
+ */
1577
+ static bool _mongocrypt_fle2_placeholder_to_find_ciphertextForRange_v1(_mongocrypt_key_broker_t *kb,
1578
+ _mongocrypt_marking_t *marking,
1579
+ _mongocrypt_ciphertext_t *ciphertext,
1580
+ mongocrypt_status_t *status) {
1581
+ BSON_ASSERT_PARAM(kb);
1582
+ BSON_ASSERT_PARAM(marking);
1583
+ BSON_ASSERT_PARAM(ciphertext);
1584
+ BSON_ASSERT(kb->crypt);
1585
+
1586
+ const bool use_range_v2 = kb->crypt->opts.use_range_v2;
1587
+ _mongocrypt_crypto_t *crypto = kb->crypt->crypto;
1588
+ mc_FLE2EncryptionPlaceholder_t *placeholder = &marking->fle2;
1589
+ mc_FLE2FindRangePayload_t payload;
1590
+ bool res = false;
1591
+ mc_mincover_t *mincover = NULL;
1592
+ _mongocrypt_buffer_t tokenKey = {0};
1593
+
1594
+ BSON_ASSERT(kb->crypt->opts.use_fle2_v2 == false);
1595
+ BSON_ASSERT(marking->type == MONGOCRYPT_MARKING_FLE2_ENCRYPTION);
1596
+ BSON_ASSERT(placeholder);
1597
+ BSON_ASSERT(placeholder->type == MONGOCRYPT_FLE2_PLACEHOLDER_TYPE_FIND);
1598
+ BSON_ASSERT(placeholder->algorithm == MONGOCRYPT_FLE2_ALGORITHM_RANGE);
1599
+ mc_FLE2FindRangePayload_init(&payload);
1600
+
1601
+ // Parse the query bounds and index bounds from FLE2EncryptionPlaceholder for
1602
+ // range find.
1603
+ mc_FLE2RangeFindSpec_t findSpec;
1604
+ if (!mc_FLE2RangeFindSpec_parse(&findSpec, &placeholder->v_iter, use_range_v2, status)) {
1605
+ goto fail;
1606
+ }
1607
+
1608
+ if (findSpec.edgesInfo.set) {
1609
+ // cm := Queryable Encryption max contentionFactor
1610
+ payload.payload.value.maxContentionFactor = placeholder->maxContentionFactor;
1611
+
1612
+ // e := ServerDataEncryptionLevel1Token
1613
+ {
1614
+ if (!_get_tokenKey(kb, &placeholder->index_key_id, &tokenKey, status)) {
1615
+ goto fail;
1616
+ }
1313
1617
 
1314
- if (!_mongocrypt_buffer_from_string (&edge_buf, edge)) {
1315
- CLIENT_ERR ("failed to copy edge to buffer");
1316
- goto fail_loop;
1618
+ mc_ServerDataEncryptionLevel1Token_t *serverToken =
1619
+ mc_ServerDataEncryptionLevel1Token_new(crypto, &tokenKey, status);
1620
+ if (!serverToken) {
1621
+ goto fail;
1622
+ }
1623
+ _mongocrypt_buffer_copy_to(mc_ServerDataEncryptionLevel1Token_get(serverToken),
1624
+ &payload.payload.value.serverEncryptionToken);
1625
+ mc_ServerDataEncryptionLevel1Token_destroy(serverToken);
1626
+ }
1627
+
1628
+ // g:= array<EdgeFindTokenSet>
1629
+ {
1630
+ BSON_ASSERT(placeholder->sparsity >= 0 && (uint64_t)placeholder->sparsity <= (uint64_t)SIZE_MAX);
1631
+ mincover =
1632
+ mc_get_mincover_from_FLE2RangeFindSpec(&findSpec, (size_t)placeholder->sparsity, status, use_range_v2);
1633
+ if (!mincover) {
1634
+ goto fail;
1317
1635
  }
1318
1636
 
1319
- if (!_mongocrypt_fle2_placeholder_common (
1320
- kb,
1321
- &edge_tokens,
1322
- &placeholder->index_key_id,
1323
- &edge_buf,
1324
- false, /* derive tokens using counter */
1325
- placeholder->maxContentionCounter,
1326
- status)) {
1327
- goto fail_loop;
1637
+ for (size_t i = 0; i < mc_mincover_len(mincover); i++) {
1638
+ // Create a EdgeFindTokenSet from each edge.
1639
+ bool loop_ok = false;
1640
+ const char *edge = mc_mincover_get(mincover, i);
1641
+ _mongocrypt_buffer_t edge_buf = {0};
1642
+ _FLE2EncryptedPayloadCommon_t edge_tokens = {{0}};
1643
+ mc_EdgeFindTokenSet_t eftc = {{0}};
1644
+
1645
+ if (!_mongocrypt_buffer_from_string(&edge_buf, edge)) {
1646
+ CLIENT_ERR("failed to copy edge to buffer");
1647
+ goto fail_loop;
1648
+ }
1649
+
1650
+ if (!_mongocrypt_fle2_placeholder_common(kb,
1651
+ &edge_tokens,
1652
+ &placeholder->index_key_id,
1653
+ &edge_buf,
1654
+ false, /* derive tokens using contentionFactor */
1655
+ placeholder->maxContentionFactor, /* ignored */
1656
+ status)) {
1657
+ goto fail_loop;
1658
+ }
1659
+
1660
+ // d := EDCDerivedToken
1661
+ _mongocrypt_buffer_steal(&eftc.edcDerivedToken, &edge_tokens.edcDerivedToken);
1662
+ // s := ESCDerivedToken
1663
+ _mongocrypt_buffer_steal(&eftc.escDerivedToken, &edge_tokens.escDerivedToken);
1664
+ // c := ECCDerivedToken
1665
+ _mongocrypt_buffer_steal(&eftc.eccDerivedToken, &edge_tokens.eccDerivedToken);
1666
+
1667
+ _mc_array_append_val(&payload.payload.value.edgeFindTokenSetArray, eftc);
1668
+
1669
+ loop_ok = true;
1670
+ fail_loop:
1671
+ _FLE2EncryptedPayloadCommon_cleanup(&edge_tokens);
1672
+ _mongocrypt_buffer_cleanup(&edge_buf);
1673
+ if (!loop_ok) {
1674
+ goto fail;
1675
+ }
1328
1676
  }
1677
+ }
1678
+ payload.payload.set = true;
1679
+ }
1680
+
1681
+ payload.payloadId = findSpec.payloadId;
1682
+ payload.firstOperator = findSpec.firstOperator;
1683
+ payload.secondOperator = findSpec.secondOperator;
1684
+
1685
+ // Serialize.
1686
+ {
1687
+ bson_t out = BSON_INITIALIZER;
1688
+ mc_FLE2FindRangePayload_serialize(&payload, &out);
1689
+ _mongocrypt_buffer_steal_from_bson(&ciphertext->data, &out);
1690
+ }
1691
+ _mongocrypt_buffer_steal(&ciphertext->key_id, &placeholder->index_key_id);
1692
+
1693
+ // Do not set ciphertext->original_bson_type and ciphertext->key_id. They are
1694
+ // not used for FLE2FindRangePayload.
1695
+ ciphertext->blob_subtype = MC_SUBTYPE_FLE2FindRangePayload;
1696
+
1697
+ res = true;
1698
+ fail:
1699
+ mc_mincover_destroy(mincover);
1700
+ mc_FLE2FindRangePayload_cleanup(&payload);
1701
+ _mongocrypt_buffer_cleanup(&tokenKey);
1329
1702
 
1330
- // d := EDCDerivedToken
1331
- _mongocrypt_buffer_steal (&eftc.edcDerivedToken,
1332
- &edge_tokens.edcDerivedToken);
1333
- // s := ESCDerivedToken
1334
- _mongocrypt_buffer_steal (&eftc.escDerivedToken,
1335
- &edge_tokens.escDerivedToken);
1336
- // c := ECCDerivedToken
1337
- _mongocrypt_buffer_steal (&eftc.eccDerivedToken,
1338
- &edge_tokens.eccDerivedToken);
1703
+ return res;
1704
+ }
1339
1705
 
1340
- _mc_array_append_val (&payload.payload.value.edgeFindTokenSetArray,
1341
- eftc);
1706
+ /**
1707
+ * Payload subtype 13: FLE2FindRangePayloadV2
1708
+ * Delegates to ..._find_ciphertextForRange_v1
1709
+ * when crypt->opts.use_fle2_v2 is false
1710
+ *
1711
+ * {cm: maxContentionFactor,
1712
+ * g: [{d: EDC, s: ESC, l: serverDerivedFromDataToken}, ...]}
1713
+ */
1714
+ static bool _mongocrypt_fle2_placeholder_to_find_ciphertextForRange(_mongocrypt_key_broker_t *kb,
1715
+ _mongocrypt_marking_t *marking,
1716
+ _mongocrypt_ciphertext_t *ciphertext,
1717
+ mongocrypt_status_t *status) {
1718
+ BSON_ASSERT_PARAM(kb);
1719
+ BSON_ASSERT_PARAM(marking);
1720
+ BSON_ASSERT_PARAM(ciphertext);
1721
+
1722
+ if (kb->crypt->opts.use_fle2_v2 == false) {
1723
+ return _mongocrypt_fle2_placeholder_to_find_ciphertextForRange_v1(kb, marking, ciphertext, status);
1724
+ }
1725
+
1726
+ const bool use_range_v2 = kb->crypt->opts.use_range_v2;
1727
+ mc_FLE2EncryptionPlaceholder_t *placeholder = &marking->fle2;
1728
+ mc_FLE2FindRangePayloadV2_t payload;
1729
+ bool res = false;
1730
+ mc_mincover_t *mincover = NULL;
1731
+ _mongocrypt_buffer_t tokenKey = {0};
1732
+
1733
+ BSON_ASSERT(marking->type == MONGOCRYPT_MARKING_FLE2_ENCRYPTION);
1734
+ BSON_ASSERT(placeholder);
1735
+ BSON_ASSERT(placeholder->type == MONGOCRYPT_FLE2_PLACEHOLDER_TYPE_FIND);
1736
+ BSON_ASSERT(placeholder->algorithm == MONGOCRYPT_FLE2_ALGORITHM_RANGE);
1737
+ mc_FLE2FindRangePayloadV2_init(&payload);
1738
+
1739
+ // Parse the query bounds and index bounds from FLE2EncryptionPlaceholder for
1740
+ // range find.
1741
+ mc_FLE2RangeFindSpec_t findSpec;
1742
+ if (!mc_FLE2RangeFindSpec_parse(&findSpec, &placeholder->v_iter, use_range_v2, status)) {
1743
+ goto fail;
1744
+ }
1745
+
1746
+ if (findSpec.edgesInfo.set) {
1747
+ // cm := Queryable Encryption max contentionFactor
1748
+ payload.payload.value.maxContentionFactor = placeholder->maxContentionFactor;
1749
+
1750
+ // g:= array<EdgeFindTokenSet>
1751
+ {
1752
+ BSON_ASSERT(placeholder->sparsity >= 0 && (uint64_t)placeholder->sparsity <= (uint64_t)SIZE_MAX);
1753
+ mincover =
1754
+ mc_get_mincover_from_FLE2RangeFindSpec(&findSpec, (size_t)placeholder->sparsity, status, use_range_v2);
1755
+ if (!mincover) {
1756
+ goto fail;
1757
+ }
1342
1758
 
1343
- loop_ok = true;
1344
- fail_loop:
1345
- _FLE2EncryptedPayloadCommon_cleanup (&edge_tokens);
1346
- _mongocrypt_buffer_cleanup (&edge_buf);
1347
- if (!loop_ok) {
1348
- goto fail;
1759
+ for (size_t i = 0; i < mc_mincover_len(mincover); i++) {
1760
+ // Create a EdgeFindTokenSet from each edge.
1761
+ bool loop_ok = false;
1762
+ const char *edge = mc_mincover_get(mincover, i);
1763
+ _mongocrypt_buffer_t edge_buf = {0};
1764
+ _FLE2EncryptedPayloadCommon_t edge_tokens = {{0}};
1765
+ mc_EdgeFindTokenSetV2_t eftc = {{0}};
1766
+
1767
+ if (!_mongocrypt_buffer_from_string(&edge_buf, edge)) {
1768
+ CLIENT_ERR("failed to copy edge to buffer");
1769
+ goto fail_loop;
1770
+ }
1771
+
1772
+ if (!_mongocrypt_fle2_placeholder_common(kb,
1773
+ &edge_tokens,
1774
+ &placeholder->index_key_id,
1775
+ &edge_buf,
1776
+ false, /* derive tokens without using contentionFactor */
1777
+ placeholder->maxContentionFactor, /* ignored */
1778
+ status)) {
1779
+ goto fail_loop;
1780
+ }
1781
+
1782
+ // d := EDCDerivedToken
1783
+ _mongocrypt_buffer_steal(&eftc.edcDerivedToken, &edge_tokens.edcDerivedToken);
1784
+ // s := ESCDerivedToken
1785
+ _mongocrypt_buffer_steal(&eftc.escDerivedToken, &edge_tokens.escDerivedToken);
1786
+
1787
+ // l := serverDerivedFromDataToken
1788
+ _mongocrypt_buffer_steal(&eftc.serverDerivedFromDataToken, &edge_tokens.serverDerivedFromDataToken);
1789
+
1790
+ _mc_array_append_val(&payload.payload.value.edgeFindTokenSetArray, eftc);
1791
+
1792
+ loop_ok = true;
1793
+ fail_loop:
1794
+ _FLE2EncryptedPayloadCommon_cleanup(&edge_tokens);
1795
+ _mongocrypt_buffer_cleanup(&edge_buf);
1796
+ if (!loop_ok) {
1797
+ goto fail;
1798
+ }
1349
1799
  }
1350
- }
1351
- }
1352
- payload.payload.set = true;
1353
- }
1354
-
1355
- payload.payloadId = findSpec.payloadId;
1356
- payload.firstOperator = findSpec.firstOperator;
1357
- payload.secondOperator = findSpec.secondOperator;
1358
-
1359
- // Serialize.
1360
- {
1361
- bson_t out = BSON_INITIALIZER;
1362
- mc_FLE2FindRangePayload_serialize (&payload, &out);
1363
- _mongocrypt_buffer_steal_from_bson (&ciphertext->data, &out);
1364
- }
1365
- _mongocrypt_buffer_steal (&ciphertext->key_id, &placeholder->index_key_id);
1366
-
1367
- // Do not set ciphertext->original_bson_type and ciphertext->key_id. They are
1368
- // not used for FLE2FindRangePayload.
1369
- ciphertext->blob_subtype = MC_SUBTYPE_FLE2FindRangePayload;
1370
-
1371
- res = true;
1800
+ }
1801
+ payload.payload.set = true;
1802
+
1803
+ if (use_range_v2) {
1804
+ // Include "range" payload fields introduced in SERVER-91889.
1805
+ payload.sparsity = OPT_I64(placeholder->sparsity);
1806
+ payload.precision = findSpec.edgesInfo.value.precision;
1807
+ payload.trimFactor = OPT_I32(mc_mincover_get_used_trimFactor(mincover));
1808
+ bson_value_copy(bson_iter_value(&findSpec.edgesInfo.value.indexMin), &payload.indexMin);
1809
+ bson_value_copy(bson_iter_value(&findSpec.edgesInfo.value.indexMax), &payload.indexMax);
1810
+ }
1811
+ }
1812
+
1813
+ payload.payloadId = findSpec.payloadId;
1814
+ payload.firstOperator = findSpec.firstOperator;
1815
+ payload.secondOperator = findSpec.secondOperator;
1816
+
1817
+ // Serialize.
1818
+ {
1819
+ bson_t out = BSON_INITIALIZER;
1820
+ mc_FLE2FindRangePayloadV2_serialize(&payload, &out, use_range_v2);
1821
+ _mongocrypt_buffer_steal_from_bson(&ciphertext->data, &out);
1822
+ }
1823
+ _mongocrypt_buffer_steal(&ciphertext->key_id, &placeholder->index_key_id);
1824
+
1825
+ // Do not set ciphertext->original_bson_type and ciphertext->key_id. They are
1826
+ // not used for FLE2FindRangePayloadV2.
1827
+ ciphertext->blob_subtype = MC_SUBTYPE_FLE2FindRangePayloadV2;
1828
+
1829
+ res = true;
1372
1830
  fail:
1373
- mc_mincover_destroy (mincover);
1374
- mc_FLE2FindRangePayload_cleanup (&payload);
1375
- _mongocrypt_buffer_cleanup (&tokenKey);
1831
+ mc_mincover_destroy(mincover);
1832
+ mc_FLE2FindRangePayloadV2_cleanup(&payload);
1833
+ _mongocrypt_buffer_cleanup(&tokenKey);
1376
1834
 
1377
- return res;
1835
+ return res;
1378
1836
  }
1379
1837
 
1380
- static bool
1381
- _mongocrypt_fle2_placeholder_to_FLE2UnindexedEncryptedValue (
1382
- _mongocrypt_key_broker_t *kb,
1383
- _mongocrypt_marking_t *marking,
1384
- _mongocrypt_ciphertext_t *ciphertext,
1385
- mongocrypt_status_t *status)
1386
- {
1387
- BSON_ASSERT_PARAM (kb);
1388
- BSON_ASSERT_PARAM (marking);
1389
- BSON_ASSERT_PARAM (ciphertext);
1390
-
1391
- _mongocrypt_buffer_t plaintext = {0};
1392
- mc_FLE2EncryptionPlaceholder_t *placeholder = &marking->fle2;
1393
- _mongocrypt_buffer_t user_key = {0};
1394
- bool res = false;
1395
-
1396
- BSON_ASSERT (marking->type == MONGOCRYPT_MARKING_FLE2_ENCRYPTION);
1397
- BSON_ASSERT (placeholder);
1398
- BSON_ASSERT (placeholder->algorithm == MONGOCRYPT_FLE2_ALGORITHM_UNINDEXED);
1399
- _mongocrypt_ciphertext_init (ciphertext);
1400
- _mongocrypt_buffer_from_iter (&plaintext, &placeholder->v_iter);
1401
-
1402
- if (!_mongocrypt_key_broker_decrypted_key_by_id (
1403
- kb, &placeholder->user_key_id, &user_key)) {
1404
- CLIENT_ERR ("unable to retrieve key");
1405
- goto fail;
1406
- }
1407
-
1408
- BSON_ASSERT (kb->crypt);
1409
- if (!mc_FLE2UnindexedEncryptedValue_encrypt (
1410
- kb->crypt->crypto,
1411
- &placeholder->user_key_id,
1412
- bson_iter_type (&placeholder->v_iter),
1413
- &plaintext,
1414
- &user_key,
1415
- &ciphertext->data,
1416
- status)) {
1417
- goto fail;
1418
- }
1419
-
1420
- _mongocrypt_buffer_steal (&ciphertext->key_id, &placeholder->user_key_id);
1421
- ciphertext->original_bson_type =
1422
- (uint8_t) bson_iter_type (&placeholder->v_iter);
1423
- ciphertext->blob_subtype = MC_SUBTYPE_FLE2UnindexedEncryptedValue;
1424
- res = true;
1838
+ static bool _mongocrypt_fle2_placeholder_to_FLE2UnindexedEncryptedValue(_mongocrypt_key_broker_t *kb,
1839
+ _mongocrypt_marking_t *marking,
1840
+ _mongocrypt_ciphertext_t *ciphertext,
1841
+ mongocrypt_status_t *status) {
1842
+ BSON_ASSERT_PARAM(kb);
1843
+ BSON_ASSERT_PARAM(marking);
1844
+ BSON_ASSERT_PARAM(ciphertext);
1845
+
1846
+ _mongocrypt_buffer_t plaintext = {0};
1847
+ mc_FLE2EncryptionPlaceholder_t *placeholder = &marking->fle2;
1848
+ _mongocrypt_buffer_t user_key = {0};
1849
+ bool res = false;
1850
+
1851
+ BSON_ASSERT(marking->type == MONGOCRYPT_MARKING_FLE2_ENCRYPTION);
1852
+ BSON_ASSERT(placeholder);
1853
+ BSON_ASSERT(placeholder->algorithm == MONGOCRYPT_FLE2_ALGORITHM_UNINDEXED);
1854
+ _mongocrypt_buffer_from_iter(&plaintext, &placeholder->v_iter);
1855
+
1856
+ if (!_mongocrypt_key_broker_decrypted_key_by_id(kb, &placeholder->user_key_id, &user_key)) {
1857
+ CLIENT_ERR("unable to retrieve key");
1858
+ goto fail;
1859
+ }
1860
+
1861
+ BSON_ASSERT(kb->crypt);
1862
+ if (kb->crypt->opts.use_fle2_v2) {
1863
+ res = mc_FLE2UnindexedEncryptedValueV2_encrypt(kb->crypt->crypto,
1864
+ &placeholder->user_key_id,
1865
+ bson_iter_type(&placeholder->v_iter),
1866
+ &plaintext,
1867
+ &user_key,
1868
+ &ciphertext->data,
1869
+ status);
1870
+ ciphertext->blob_subtype = MC_SUBTYPE_FLE2UnindexedEncryptedValueV2;
1871
+ } else {
1872
+ res = mc_FLE2UnindexedEncryptedValue_encrypt(kb->crypt->crypto,
1873
+ &placeholder->user_key_id,
1874
+ bson_iter_type(&placeholder->v_iter),
1875
+ &plaintext,
1876
+ &user_key,
1877
+ &ciphertext->data,
1878
+ status);
1879
+ ciphertext->blob_subtype = MC_SUBTYPE_FLE2UnindexedEncryptedValue;
1880
+ }
1881
+
1882
+ if (!res) {
1883
+ goto fail;
1884
+ }
1885
+
1886
+ _mongocrypt_buffer_steal(&ciphertext->key_id, &placeholder->user_key_id);
1887
+ ciphertext->original_bson_type = (uint8_t)bson_iter_type(&placeholder->v_iter);
1888
+
1889
+ res = true;
1425
1890
  fail:
1426
- _mongocrypt_buffer_cleanup (&plaintext);
1427
- _mongocrypt_buffer_cleanup (&user_key);
1891
+ _mongocrypt_buffer_cleanup(&plaintext);
1892
+ _mongocrypt_buffer_cleanup(&user_key);
1428
1893
 
1429
- return res;
1894
+ return res;
1430
1895
  }
1431
1896
 
1432
- static bool
1433
- _mongocrypt_fle1_marking_to_ciphertext (_mongocrypt_key_broker_t *kb,
1434
- _mongocrypt_marking_t *marking,
1435
- _mongocrypt_ciphertext_t *ciphertext,
1436
- mongocrypt_status_t *status)
1437
- {
1438
- _mongocrypt_buffer_t plaintext;
1439
- _mongocrypt_buffer_t iv;
1440
- _mongocrypt_buffer_t associated_data;
1441
- _mongocrypt_buffer_t key_material;
1442
- _mongocrypt_buffer_t key_id;
1443
- bool ret = false;
1444
- bool key_found;
1445
- uint32_t bytes_written;
1446
-
1447
- BSON_ASSERT_PARAM (kb);
1448
- BSON_ASSERT_PARAM (marking);
1449
- BSON_ASSERT_PARAM (ciphertext);
1450
-
1451
- BSON_ASSERT ((marking->type == MONGOCRYPT_MARKING_FLE1_BY_ID) ||
1452
- (marking->type == MONGOCRYPT_MARKING_FLE1_BY_ALTNAME));
1453
-
1454
- _mongocrypt_buffer_init (&plaintext);
1455
- _mongocrypt_buffer_init (&associated_data);
1456
- _mongocrypt_buffer_init (&iv);
1457
- _mongocrypt_buffer_init (&key_id);
1458
- _mongocrypt_buffer_init (&key_material);
1459
-
1460
- /* Get the decrypted key for this marking. */
1461
- if (marking->type == MONGOCRYPT_MARKING_FLE1_BY_ALTNAME) {
1462
- key_found = _mongocrypt_key_broker_decrypted_key_by_name (
1463
- kb, &marking->key_alt_name, &key_material, &key_id);
1464
- } else if (!_mongocrypt_buffer_empty (&marking->key_id)) {
1465
- key_found = _mongocrypt_key_broker_decrypted_key_by_id (
1466
- kb, &marking->key_id, &key_material);
1467
- _mongocrypt_buffer_copy_to (&marking->key_id, &key_id);
1468
- } else {
1469
- CLIENT_ERR ("marking must have either key_id or key_alt_name");
1470
- goto fail;
1471
- }
1472
-
1473
- if (!key_found) {
1474
- _mongocrypt_status_copy_to (kb->status, status);
1475
- goto fail;
1476
- }
1477
-
1478
- _mongocrypt_ciphertext_init (ciphertext);
1479
- ciphertext->original_bson_type = (uint8_t) bson_iter_type (&marking->v_iter);
1480
- if (marking->algorithm == MONGOCRYPT_ENCRYPTION_ALGORITHM_DETERMINISTIC) {
1481
- ciphertext->blob_subtype = MC_SUBTYPE_FLE1DeterministicEncryptedValue;
1482
- } else {
1483
- BSON_ASSERT (marking->algorithm ==
1484
- MONGOCRYPT_ENCRYPTION_ALGORITHM_RANDOM);
1485
- ciphertext->blob_subtype = MC_SUBTYPE_FLE1RandomEncryptedValue;
1486
- }
1487
- _mongocrypt_buffer_copy_to (&key_id, &ciphertext->key_id);
1488
- if (!_mongocrypt_ciphertext_serialize_associated_data (ciphertext,
1489
- &associated_data)) {
1490
- CLIENT_ERR ("could not serialize associated data");
1491
- goto fail;
1492
- }
1493
-
1494
- _mongocrypt_buffer_from_iter (&plaintext, &marking->v_iter);
1495
- ciphertext->data.len =
1496
- _mongocrypt_calculate_ciphertext_len (plaintext.len, status);
1497
- if (ciphertext->data.len == 0) {
1498
- goto fail;
1499
- }
1500
- ciphertext->data.data = bson_malloc (ciphertext->data.len);
1501
- BSON_ASSERT (ciphertext->data.data);
1502
-
1503
- ciphertext->data.owned = true;
1504
-
1505
- BSON_ASSERT (kb->crypt);
1506
- switch (marking->algorithm) {
1507
- case MONGOCRYPT_ENCRYPTION_ALGORITHM_DETERMINISTIC:
1508
- /* Use deterministic encryption. */
1509
- _mongocrypt_buffer_resize (&iv, MONGOCRYPT_IV_LEN);
1510
- ret = _mongocrypt_calculate_deterministic_iv (kb->crypt->crypto,
1511
- &key_material,
1512
- &plaintext,
1513
- &associated_data,
1514
- &iv,
1515
- status);
1516
- if (!ret) {
1517
- goto fail;
1518
- }
1519
-
1520
- ret = _mongocrypt_do_encryption (kb->crypt->crypto,
1521
- &iv,
1522
- &associated_data,
1523
- &key_material,
1524
- &plaintext,
1525
- &ciphertext->data,
1526
- &bytes_written,
1527
- status);
1528
- break;
1529
- case MONGOCRYPT_ENCRYPTION_ALGORITHM_RANDOM:
1530
- /* Use randomized encryption.
1531
- * In this case, we must generate a new, random iv. */
1532
- _mongocrypt_buffer_resize (&iv, MONGOCRYPT_IV_LEN);
1533
- if (!_mongocrypt_random (
1534
- kb->crypt->crypto, &iv, MONGOCRYPT_IV_LEN, status)) {
1535
- goto fail;
1536
- }
1537
- ret = _mongocrypt_do_encryption (kb->crypt->crypto,
1538
- &iv,
1539
- &associated_data,
1540
- &key_material,
1541
- &plaintext,
1542
- &ciphertext->data,
1543
- &bytes_written,
1544
- status);
1545
- break;
1546
- case MONGOCRYPT_ENCRYPTION_ALGORITHM_NONE:
1547
- default:
1548
- /* Error. */
1549
- CLIENT_ERR ("Unsupported value for encryption algorithm");
1550
- goto fail;
1551
- }
1552
-
1553
- if (!ret) {
1554
- goto fail;
1555
- }
1556
-
1557
- BSON_ASSERT (bytes_written == ciphertext->data.len);
1558
-
1559
- ret = true;
1897
+ static bool _mongocrypt_fle1_marking_to_ciphertext(_mongocrypt_key_broker_t *kb,
1898
+ _mongocrypt_marking_t *marking,
1899
+ _mongocrypt_ciphertext_t *ciphertext,
1900
+ mongocrypt_status_t *status) {
1901
+ const _mongocrypt_value_encryption_algorithm_t *fle1 = _mcFLE1Algorithm();
1902
+ _mongocrypt_buffer_t plaintext;
1903
+ _mongocrypt_buffer_t iv;
1904
+ _mongocrypt_buffer_t associated_data;
1905
+ _mongocrypt_buffer_t key_material;
1906
+ _mongocrypt_buffer_t key_id;
1907
+ bool ret = false;
1908
+ bool key_found;
1909
+ uint32_t bytes_written;
1910
+
1911
+ BSON_ASSERT_PARAM(kb);
1912
+ BSON_ASSERT_PARAM(marking);
1913
+ BSON_ASSERT_PARAM(ciphertext);
1914
+
1915
+ BSON_ASSERT((marking->type == MONGOCRYPT_MARKING_FLE1_BY_ID)
1916
+ || (marking->type == MONGOCRYPT_MARKING_FLE1_BY_ALTNAME));
1917
+
1918
+ _mongocrypt_buffer_init(&plaintext);
1919
+ _mongocrypt_buffer_init(&associated_data);
1920
+ _mongocrypt_buffer_init(&iv);
1921
+ _mongocrypt_buffer_init(&key_id);
1922
+ _mongocrypt_buffer_init(&key_material);
1923
+
1924
+ /* Get the decrypted key for this marking. */
1925
+ if (marking->type == MONGOCRYPT_MARKING_FLE1_BY_ALTNAME) {
1926
+ key_found = _mongocrypt_key_broker_decrypted_key_by_name(kb, &marking->key_alt_name, &key_material, &key_id);
1927
+ } else if (!_mongocrypt_buffer_empty(&marking->key_id)) {
1928
+ key_found = _mongocrypt_key_broker_decrypted_key_by_id(kb, &marking->key_id, &key_material);
1929
+ _mongocrypt_buffer_copy_to(&marking->key_id, &key_id);
1930
+ } else {
1931
+ CLIENT_ERR("marking must have either key_id or key_alt_name");
1932
+ goto fail;
1933
+ }
1934
+
1935
+ if (!key_found) {
1936
+ _mongocrypt_status_copy_to(kb->status, status);
1937
+ goto fail;
1938
+ }
1939
+
1940
+ ciphertext->original_bson_type = (uint8_t)bson_iter_type(&marking->v_iter);
1941
+ if (marking->algorithm == MONGOCRYPT_ENCRYPTION_ALGORITHM_DETERMINISTIC) {
1942
+ ciphertext->blob_subtype = MC_SUBTYPE_FLE1DeterministicEncryptedValue;
1943
+ } else {
1944
+ BSON_ASSERT(marking->algorithm == MONGOCRYPT_ENCRYPTION_ALGORITHM_RANDOM);
1945
+ ciphertext->blob_subtype = MC_SUBTYPE_FLE1RandomEncryptedValue;
1946
+ }
1947
+ _mongocrypt_buffer_copy_to(&key_id, &ciphertext->key_id);
1948
+ if (!_mongocrypt_ciphertext_serialize_associated_data(ciphertext, &associated_data)) {
1949
+ CLIENT_ERR("could not serialize associated data");
1950
+ goto fail;
1951
+ }
1952
+
1953
+ _mongocrypt_buffer_from_iter(&plaintext, &marking->v_iter);
1954
+ ciphertext->data.len = fle1->get_ciphertext_len(plaintext.len, status);
1955
+ if (ciphertext->data.len == 0) {
1956
+ goto fail;
1957
+ }
1958
+ ciphertext->data.data = bson_malloc(ciphertext->data.len);
1959
+ BSON_ASSERT(ciphertext->data.data);
1960
+
1961
+ ciphertext->data.owned = true;
1962
+
1963
+ BSON_ASSERT(kb->crypt);
1964
+ switch (marking->algorithm) {
1965
+ case MONGOCRYPT_ENCRYPTION_ALGORITHM_DETERMINISTIC:
1966
+ /* Use deterministic encryption. */
1967
+ _mongocrypt_buffer_resize(&iv, MONGOCRYPT_IV_LEN);
1968
+ ret = _mongocrypt_calculate_deterministic_iv(kb->crypt->crypto,
1969
+ &key_material,
1970
+ &plaintext,
1971
+ &associated_data,
1972
+ &iv,
1973
+ status);
1974
+ if (!ret) {
1975
+ goto fail;
1976
+ }
1977
+
1978
+ ret = fle1->do_encrypt(kb->crypt->crypto,
1979
+ &iv,
1980
+ &associated_data,
1981
+ &key_material,
1982
+ &plaintext,
1983
+ &ciphertext->data,
1984
+ &bytes_written,
1985
+ status);
1986
+ break;
1987
+ case MONGOCRYPT_ENCRYPTION_ALGORITHM_RANDOM:
1988
+ /* Use randomized encryption.
1989
+ * In this case, we must generate a new, random iv. */
1990
+ _mongocrypt_buffer_resize(&iv, MONGOCRYPT_IV_LEN);
1991
+ if (!_mongocrypt_random(kb->crypt->crypto, &iv, MONGOCRYPT_IV_LEN, status)) {
1992
+ goto fail;
1993
+ }
1994
+ ret = fle1->do_encrypt(kb->crypt->crypto,
1995
+ &iv,
1996
+ &associated_data,
1997
+ &key_material,
1998
+ &plaintext,
1999
+ &ciphertext->data,
2000
+ &bytes_written,
2001
+ status);
2002
+ break;
2003
+ case MONGOCRYPT_ENCRYPTION_ALGORITHM_NONE:
2004
+ default:
2005
+ /* Error. */
2006
+ CLIENT_ERR("Unsupported value for encryption algorithm");
2007
+ goto fail;
2008
+ }
2009
+
2010
+ if (!ret) {
2011
+ goto fail;
2012
+ }
2013
+
2014
+ BSON_ASSERT(bytes_written == ciphertext->data.len);
2015
+
2016
+ ret = true;
1560
2017
 
1561
2018
  fail:
1562
- _mongocrypt_buffer_cleanup (&iv);
1563
- _mongocrypt_buffer_cleanup (&key_id);
1564
- _mongocrypt_buffer_cleanup (&plaintext);
1565
- _mongocrypt_buffer_cleanup (&associated_data);
1566
- _mongocrypt_buffer_cleanup (&key_material);
1567
- return ret;
2019
+ _mongocrypt_buffer_cleanup(&iv);
2020
+ _mongocrypt_buffer_cleanup(&key_id);
2021
+ _mongocrypt_buffer_cleanup(&plaintext);
2022
+ _mongocrypt_buffer_cleanup(&associated_data);
2023
+ _mongocrypt_buffer_cleanup(&key_material);
2024
+ return ret;
1568
2025
  }
1569
2026
 
1570
- bool
1571
- _mongocrypt_marking_to_ciphertext (void *ctx,
1572
- _mongocrypt_marking_t *marking,
1573
- _mongocrypt_ciphertext_t *ciphertext,
1574
- mongocrypt_status_t *status)
1575
- {
1576
- BSON_ASSERT_PARAM (marking);
1577
- BSON_ASSERT_PARAM (ciphertext);
1578
- BSON_ASSERT_PARAM (ctx);
1579
-
1580
- _mongocrypt_key_broker_t *kb = (_mongocrypt_key_broker_t *) ctx;
1581
-
1582
- switch (marking->type) {
1583
- case MONGOCRYPT_MARKING_FLE2_ENCRYPTION:
1584
- switch (marking->fle2.algorithm) {
1585
- case MONGOCRYPT_FLE2_ALGORITHM_UNINDEXED:
1586
- return _mongocrypt_fle2_placeholder_to_FLE2UnindexedEncryptedValue (
1587
- kb, marking, ciphertext, status);
1588
- case MONGOCRYPT_FLE2_ALGORITHM_RANGE:
1589
- switch (marking->fle2.type) {
1590
- case MONGOCRYPT_FLE2_PLACEHOLDER_TYPE_INSERT:
1591
- return _mongocrypt_fle2_placeholder_to_insert_update_ciphertextForRange (
1592
- kb, marking, ciphertext, status);
1593
- case MONGOCRYPT_FLE2_PLACEHOLDER_TYPE_FIND:
1594
- return _mongocrypt_fle2_placeholder_to_find_ciphertextForRange (
1595
- kb, marking, ciphertext, status);
1596
- default:
1597
- CLIENT_ERR ("unexpected fle2 type: %d", (int) marking->fle2.type);
1598
- return false;
1599
- }
1600
- case MONGOCRYPT_FLE2_ALGORITHM_EQUALITY:
1601
- switch (marking->fle2.type) {
1602
- case MONGOCRYPT_FLE2_PLACEHOLDER_TYPE_INSERT:
1603
- return _mongocrypt_fle2_placeholder_to_insert_update_ciphertext (
1604
- kb, marking, ciphertext, status);
1605
- case MONGOCRYPT_FLE2_PLACEHOLDER_TYPE_FIND:
1606
- return _mongocrypt_fle2_placeholder_to_find_ciphertext (
1607
- kb, marking, ciphertext, status);
1608
- default:
1609
- CLIENT_ERR ("unexpected fle2 type: %d", (int) marking->fle2.type);
1610
- return false;
1611
- }
1612
- default:
1613
- CLIENT_ERR ("unexpected algorithm: %d", (int) marking->algorithm);
1614
- return false;
1615
- }
1616
- case MONGOCRYPT_MARKING_FLE1_BY_ID:
1617
- case MONGOCRYPT_MARKING_FLE1_BY_ALTNAME:
1618
- return _mongocrypt_fle1_marking_to_ciphertext (
1619
- kb, marking, ciphertext, status);
1620
- default:
1621
- CLIENT_ERR ("unexpected marking type: %d", (int) marking->type);
1622
- return false;
1623
- }
2027
+ bool _mongocrypt_marking_to_ciphertext(void *ctx,
2028
+ _mongocrypt_marking_t *marking,
2029
+ _mongocrypt_ciphertext_t *ciphertext,
2030
+ mongocrypt_status_t *status) {
2031
+ BSON_ASSERT_PARAM(marking);
2032
+ BSON_ASSERT_PARAM(ciphertext);
2033
+ BSON_ASSERT_PARAM(ctx);
2034
+
2035
+ _mongocrypt_key_broker_t *kb = (_mongocrypt_key_broker_t *)ctx;
2036
+
2037
+ switch (marking->type) {
2038
+ case MONGOCRYPT_MARKING_FLE2_ENCRYPTION:
2039
+ switch (marking->fle2.algorithm) {
2040
+ case MONGOCRYPT_FLE2_ALGORITHM_UNINDEXED:
2041
+ return _mongocrypt_fle2_placeholder_to_FLE2UnindexedEncryptedValue(kb, marking, ciphertext, status);
2042
+ case MONGOCRYPT_FLE2_ALGORITHM_RANGE:
2043
+ switch (marking->fle2.type) {
2044
+ case MONGOCRYPT_FLE2_PLACEHOLDER_TYPE_INSERT:
2045
+ return _mongocrypt_fle2_placeholder_to_insert_update_ciphertextForRange(kb,
2046
+ marking,
2047
+ ciphertext,
2048
+ status);
2049
+ case MONGOCRYPT_FLE2_PLACEHOLDER_TYPE_FIND:
2050
+ return _mongocrypt_fle2_placeholder_to_find_ciphertextForRange(kb, marking, ciphertext, status);
2051
+ default: CLIENT_ERR("unexpected fle2 type: %d", (int)marking->fle2.type); return false;
2052
+ }
2053
+ case MONGOCRYPT_FLE2_ALGORITHM_EQUALITY:
2054
+ switch (marking->fle2.type) {
2055
+ case MONGOCRYPT_FLE2_PLACEHOLDER_TYPE_INSERT:
2056
+ return _mongocrypt_fle2_placeholder_to_insert_update_ciphertext(kb, marking, ciphertext, status);
2057
+ case MONGOCRYPT_FLE2_PLACEHOLDER_TYPE_FIND:
2058
+ return _mongocrypt_fle2_placeholder_to_find_ciphertext(kb, marking, ciphertext, status);
2059
+ default: CLIENT_ERR("unexpected fle2 type: %d", (int)marking->fle2.type); return false;
2060
+ }
2061
+ default: CLIENT_ERR("unexpected algorithm: %d", (int)marking->algorithm); return false;
2062
+ }
2063
+ case MONGOCRYPT_MARKING_FLE1_BY_ID:
2064
+ case MONGOCRYPT_MARKING_FLE1_BY_ALTNAME:
2065
+ return _mongocrypt_fle1_marking_to_ciphertext(kb, marking, ciphertext, status);
2066
+ default: CLIENT_ERR("unexpected marking type: %d", (int)marking->type); return false;
2067
+ }
1624
2068
  }