libmongocrypt-helper 1.7.4.0.1002 → 1.8.0.0.1001

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