libmongocrypt-helper 1.7.4.0.1002 → 1.11.0.0.1001

Sign up to get free protection for your applications and to get access to all the features.
Files changed (600) hide show
  1. checksums.yaml +4 -4
  2. data/ext/libmongocrypt/libmongocrypt/CHANGELOG.md +40 -5
  3. data/ext/libmongocrypt/libmongocrypt/CMakeLists.txt +29 -24
  4. data/ext/libmongocrypt/libmongocrypt/CODEOWNERS +1 -4
  5. data/ext/libmongocrypt/libmongocrypt/Earthfile +522 -0
  6. data/ext/libmongocrypt/libmongocrypt/README.md +36 -40
  7. data/ext/libmongocrypt/libmongocrypt/bindings/cs/CMakeLists.txt +1 -0
  8. data/ext/libmongocrypt/libmongocrypt/bindings/cs/MongoDB.Driver.snk +0 -0
  9. data/ext/libmongocrypt/libmongocrypt/bindings/cs/MongoDB.Libmongocrypt/AssemblyInfo.cs +2 -2
  10. data/ext/libmongocrypt/libmongocrypt/bindings/cs/MongoDB.Libmongocrypt/Binary.cs +16 -2
  11. data/ext/libmongocrypt/libmongocrypt/bindings/cs/MongoDB.Libmongocrypt/CryptClient.cs +25 -6
  12. data/ext/libmongocrypt/libmongocrypt/bindings/cs/MongoDB.Libmongocrypt/CryptClientFactory.cs +8 -4
  13. data/ext/libmongocrypt/libmongocrypt/bindings/cs/MongoDB.Libmongocrypt/Library.cs +35 -3
  14. data/ext/libmongocrypt/libmongocrypt/bindings/cs/MongoDB.Libmongocrypt/LibraryLoader.cs +81 -44
  15. data/ext/libmongocrypt/libmongocrypt/bindings/cs/MongoDB.Libmongocrypt/MongoDB.Libmongocrypt.csproj +2 -1
  16. data/ext/libmongocrypt/libmongocrypt/bindings/cs/MongoDB.Libmongocrypt.Example/MongoDB.Libmongocrypt.Example.csproj +1 -1
  17. data/ext/libmongocrypt/libmongocrypt/bindings/cs/MongoDB.Libmongocrypt.Test/BasicTests.cs +1 -1
  18. data/ext/libmongocrypt/libmongocrypt/bindings/cs/MongoDB.Libmongocrypt.Test/MongoDB.Libmongocrypt.Test.csproj +2 -0
  19. data/ext/libmongocrypt/libmongocrypt/bindings/cs/MongoDB.Libmongocrypt.Test32/MongoDB.Libmongocrypt.Test32.csproj +2 -0
  20. data/ext/libmongocrypt/libmongocrypt/bindings/cs/README.md +3 -0
  21. data/ext/libmongocrypt/libmongocrypt/bindings/cs/Scripts/build.cake +22 -26
  22. data/ext/libmongocrypt/libmongocrypt/bindings/cs/Scripts/build.config +3 -0
  23. data/ext/libmongocrypt/libmongocrypt/bindings/cs/Scripts/build.sh +0 -0
  24. data/ext/libmongocrypt/libmongocrypt/bindings/java/mongocrypt/benchmarks/build.gradle.kts +28 -0
  25. data/ext/libmongocrypt/libmongocrypt/bindings/java/mongocrypt/benchmarks/src/main/java/com/mongodb/crypt/benchmark/BenchmarkRunner.java +217 -0
  26. data/ext/libmongocrypt/libmongocrypt/bindings/java/mongocrypt/benchmarks/src/main/resources/keyDocument.json +24 -0
  27. data/ext/libmongocrypt/libmongocrypt/bindings/java/mongocrypt/build.gradle.kts +22 -7
  28. data/ext/libmongocrypt/libmongocrypt/bindings/java/mongocrypt/gradle/wrapper/gradle-wrapper.jar +0 -0
  29. data/ext/libmongocrypt/libmongocrypt/bindings/java/mongocrypt/gradle/wrapper/gradle-wrapper.properties +1 -1
  30. data/ext/libmongocrypt/libmongocrypt/bindings/java/mongocrypt/gradlew +154 -108
  31. data/ext/libmongocrypt/libmongocrypt/bindings/java/mongocrypt/gradlew.bat +7 -18
  32. data/ext/libmongocrypt/libmongocrypt/bindings/java/mongocrypt/settings.gradle.kts +1 -0
  33. data/ext/libmongocrypt/libmongocrypt/bindings/java/mongocrypt/src/main/java/com/mongodb/crypt/capi/CAPI.java +41 -6
  34. data/ext/libmongocrypt/libmongocrypt/bindings/java/mongocrypt/src/main/java/com/mongodb/crypt/capi/CAPIHelper.java +5 -5
  35. data/ext/libmongocrypt/libmongocrypt/bindings/java/mongocrypt/src/main/java/com/mongodb/crypt/capi/CipherCallback.java +27 -1
  36. data/ext/libmongocrypt/libmongocrypt/bindings/java/mongocrypt/src/main/java/com/mongodb/crypt/capi/MongoCryptImpl.java +34 -19
  37. data/ext/libmongocrypt/libmongocrypt/bindings/java/mongocrypt/src/main/java/com/mongodb/crypt/capi/MongoExplicitEncryptOptions.java +6 -4
  38. data/ext/libmongocrypt/libmongocrypt/bindings/java/mongocrypt/src/main/resources/META-INF/native-image/jni-config.json +180 -0
  39. data/ext/libmongocrypt/libmongocrypt/bindings/java/mongocrypt/src/main/resources/META-INF/native-image/reflect-config.json +134 -0
  40. data/ext/libmongocrypt/libmongocrypt/bindings/java/mongocrypt/src/test/java/com/mongodb/crypt/capi/MongoCryptTest.java +50 -6
  41. data/ext/libmongocrypt/libmongocrypt/bindings/java/mongocrypt/src/test/resources/fle2-find-range-explicit-v2/int32/encrypted-payload.json +26 -0
  42. data/ext/libmongocrypt/libmongocrypt/bindings/{python/test/data/fle2-find-range-explicit → java/mongocrypt/src/test/resources/fle2-find-range-explicit-v2}/int32/rangeopts.json +3 -0
  43. data/ext/libmongocrypt/libmongocrypt/bindings/node/README.md +4 -771
  44. data/ext/libmongocrypt/libmongocrypt/bindings/python/CHANGELOG.rst +86 -0
  45. data/ext/libmongocrypt/libmongocrypt/bindings/python/README.rst +41 -20
  46. data/ext/libmongocrypt/libmongocrypt/bindings/python/RELEASE.rst +6 -24
  47. data/ext/libmongocrypt/libmongocrypt/bindings/python/build-manylinux-wheel.sh +4 -13
  48. data/ext/libmongocrypt/libmongocrypt/bindings/python/hatch_build.py +36 -0
  49. data/ext/libmongocrypt/libmongocrypt/bindings/python/libmongocrypt-version.txt +1 -0
  50. data/ext/libmongocrypt/libmongocrypt/bindings/python/pymongocrypt/__init__.py +2 -2
  51. data/ext/libmongocrypt/libmongocrypt/bindings/python/pymongocrypt/asynchronous/auto_encrypter.py +61 -0
  52. data/ext/libmongocrypt/libmongocrypt/bindings/python/pymongocrypt/asynchronous/credentials.py +156 -0
  53. data/ext/libmongocrypt/libmongocrypt/bindings/python/pymongocrypt/asynchronous/explicit_encrypter.py +156 -0
  54. data/ext/libmongocrypt/libmongocrypt/bindings/python/pymongocrypt/asynchronous/state_machine.py +149 -0
  55. data/ext/libmongocrypt/libmongocrypt/bindings/python/pymongocrypt/auto_encrypter.py +2 -46
  56. data/ext/libmongocrypt/libmongocrypt/bindings/python/pymongocrypt/binary.py +14 -17
  57. data/ext/libmongocrypt/libmongocrypt/bindings/python/pymongocrypt/binding.py +232 -296
  58. data/ext/libmongocrypt/libmongocrypt/bindings/python/pymongocrypt/compat.py +6 -31
  59. data/ext/libmongocrypt/libmongocrypt/bindings/python/pymongocrypt/credentials.py +2 -121
  60. data/ext/libmongocrypt/libmongocrypt/bindings/python/pymongocrypt/crypto.py +31 -20
  61. data/ext/libmongocrypt/libmongocrypt/bindings/python/pymongocrypt/errors.py +2 -2
  62. data/ext/libmongocrypt/libmongocrypt/bindings/python/pymongocrypt/explicit_encrypter.py +2 -233
  63. data/ext/libmongocrypt/libmongocrypt/bindings/python/pymongocrypt/mongocrypt.py +168 -254
  64. data/ext/libmongocrypt/libmongocrypt/bindings/python/pymongocrypt/options.py +265 -0
  65. data/ext/libmongocrypt/libmongocrypt/bindings/python/pymongocrypt/state_machine.py +2 -141
  66. data/ext/libmongocrypt/libmongocrypt/bindings/python/pymongocrypt/synchronous/auto_encrypter.py +61 -0
  67. data/ext/libmongocrypt/libmongocrypt/bindings/python/pymongocrypt/synchronous/credentials.py +156 -0
  68. data/ext/libmongocrypt/libmongocrypt/bindings/python/pymongocrypt/synchronous/explicit_encrypter.py +156 -0
  69. data/ext/libmongocrypt/libmongocrypt/bindings/python/pymongocrypt/synchronous/state_machine.py +149 -0
  70. data/ext/libmongocrypt/libmongocrypt/bindings/python/pymongocrypt/version.py +2 -2
  71. data/ext/libmongocrypt/libmongocrypt/bindings/python/pyproject.toml +118 -0
  72. data/ext/libmongocrypt/libmongocrypt/bindings/python/release.sh +97 -61
  73. data/ext/libmongocrypt/libmongocrypt/bindings/python/requirements-test.txt +7 -0
  74. data/ext/libmongocrypt/libmongocrypt/bindings/python/requirements.txt +4 -0
  75. data/ext/libmongocrypt/libmongocrypt/bindings/python/sbom.json +76 -0
  76. data/ext/libmongocrypt/libmongocrypt/bindings/python/strip_header.py +6 -7
  77. data/ext/libmongocrypt/libmongocrypt/bindings/python/synchro.py +64 -0
  78. data/ext/libmongocrypt/libmongocrypt/bindings/python/test/__init__.py +2 -10
  79. data/ext/libmongocrypt/libmongocrypt/bindings/python/test/data/collection-info.json +1 -1
  80. data/ext/libmongocrypt/libmongocrypt/bindings/python/test/data/command.json +1 -1
  81. data/ext/libmongocrypt/libmongocrypt/bindings/python/test/data/compact/success/encrypted-payload.json +21 -21
  82. data/ext/libmongocrypt/libmongocrypt/bindings/python/test/data/encrypted-command-reply.json +1 -1
  83. data/ext/libmongocrypt/libmongocrypt/bindings/python/test/data/encrypted-field-config-map.json +1 -1
  84. data/ext/libmongocrypt/libmongocrypt/bindings/python/test/data/fle2-find-range-explicit-v2/int32/encrypted-payload.json +26 -0
  85. data/ext/libmongocrypt/libmongocrypt/bindings/python/test/data/fle2-find-range-explicit-v2/int32/rangeopts.json +14 -0
  86. data/ext/libmongocrypt/libmongocrypt/bindings/python/test/data/key-document-azure.json +1 -1
  87. data/ext/libmongocrypt/libmongocrypt/bindings/python/test/data/key-document-gcp.json +1 -1
  88. data/ext/libmongocrypt/libmongocrypt/bindings/python/test/data/key-document.json +1 -1
  89. data/ext/libmongocrypt/libmongocrypt/bindings/python/test/data/key-filter.json +1 -1
  90. data/ext/libmongocrypt/libmongocrypt/bindings/python/test/data/list-collections-filter.json +1 -1
  91. data/ext/libmongocrypt/libmongocrypt/bindings/python/test/data/mongocryptd-command.json +1 -1
  92. data/ext/libmongocrypt/libmongocrypt/bindings/python/test/data/mongocryptd-reply.json +1 -1
  93. data/ext/libmongocrypt/libmongocrypt/bindings/python/test/data/schema-map.json +1 -1
  94. data/ext/libmongocrypt/libmongocrypt/bindings/python/test/performance/keyDocument.json +24 -0
  95. data/ext/libmongocrypt/libmongocrypt/bindings/python/test/performance/perf_test.py +165 -0
  96. data/ext/libmongocrypt/libmongocrypt/bindings/python/test/test_binding.py +8 -12
  97. data/ext/libmongocrypt/libmongocrypt/bindings/python/test/test_crypto.py +9 -11
  98. data/ext/libmongocrypt/libmongocrypt/bindings/python/test/test_mongocrypt.py +991 -343
  99. data/ext/libmongocrypt/libmongocrypt/bindings/python/update-sbom.sh +14 -0
  100. data/ext/libmongocrypt/libmongocrypt/cmake/FetchMongoC.cmake +19 -1
  101. data/ext/libmongocrypt/libmongocrypt/cmake/ImportBSON.cmake +31 -6
  102. data/ext/libmongocrypt/libmongocrypt/cmake/IntelDFP.cmake +20 -227
  103. data/ext/libmongocrypt/libmongocrypt/cmake/Patch.cmake +54 -0
  104. data/ext/libmongocrypt/libmongocrypt/cmake/Platform.cmake +50 -0
  105. data/ext/libmongocrypt/libmongocrypt/cmake/mongocrypt-config.cmake +21 -0
  106. data/ext/libmongocrypt/libmongocrypt/doc/img/cli-icon.png +0 -0
  107. data/ext/libmongocrypt/libmongocrypt/doc/img/reference-targets.png +0 -0
  108. data/ext/libmongocrypt/libmongocrypt/doc/releasing.md +153 -0
  109. data/ext/libmongocrypt/libmongocrypt/etc/c6-vault.repo +39 -0
  110. data/ext/libmongocrypt/libmongocrypt/etc/calc_release_version.py +61 -28
  111. data/ext/libmongocrypt/libmongocrypt/etc/calc_release_version_selftest.sh +73 -0
  112. data/ext/libmongocrypt/libmongocrypt/etc/cyclonedx.sbom.json +108 -0
  113. data/ext/libmongocrypt/libmongocrypt/etc/fle2_aead_generate_tests.py +15 -24
  114. data/ext/libmongocrypt/libmongocrypt/etc/fle2_crypto.py +66 -54
  115. data/ext/libmongocrypt/libmongocrypt/etc/fle2_generate_tests.py +14 -23
  116. data/ext/libmongocrypt/libmongocrypt/etc/fle2v2_aead_generate_tests.py +32 -0
  117. data/ext/libmongocrypt/libmongocrypt/etc/format-all.sh +12 -0
  118. data/ext/libmongocrypt/libmongocrypt/etc/format.sh +16 -0
  119. data/ext/libmongocrypt/libmongocrypt/etc/install-package.sh +48 -0
  120. data/ext/libmongocrypt/libmongocrypt/etc/libbson-remove-GCC-diagnostic-pragma.patch +27 -0
  121. data/ext/libmongocrypt/libmongocrypt/etc/mongo-inteldfp-alpine-arm-fix.patch +17 -0
  122. data/ext/libmongocrypt/libmongocrypt/etc/mongo-inteldfp-libmongocrypt-pr-625.patch +13 -0
  123. data/ext/libmongocrypt/libmongocrypt/etc/packager.py +120 -91
  124. data/ext/libmongocrypt/libmongocrypt/etc/purls.txt +14 -0
  125. data/ext/libmongocrypt/libmongocrypt/etc/repo_config.yaml +56 -0
  126. data/ext/libmongocrypt/libmongocrypt/etc/silk-create-asset-group.sh +70 -0
  127. data/ext/libmongocrypt/libmongocrypt/etc/ssdlc_compliance_report.md +37 -0
  128. data/ext/libmongocrypt/libmongocrypt/etc/third_party_vulnerabilities.md +42 -0
  129. data/ext/libmongocrypt/libmongocrypt/integrating.md +18 -1
  130. data/ext/libmongocrypt/libmongocrypt/kms-message/CMakeLists.txt +11 -3
  131. data/ext/libmongocrypt/libmongocrypt/kms-message/src/kms_gcp_request.c +1 -1
  132. data/ext/libmongocrypt/libmongocrypt/kms-message/src/kms_kmip_reader_writer.c +17 -0
  133. data/ext/libmongocrypt/libmongocrypt/kms-message/src/kms_kmip_reader_writer_private.h +6 -0
  134. data/ext/libmongocrypt/libmongocrypt/kms-message/src/kms_kmip_request.c +211 -1
  135. data/ext/libmongocrypt/libmongocrypt/kms-message/src/kms_kmip_response.c +163 -0
  136. data/ext/libmongocrypt/libmongocrypt/kms-message/src/kms_kmip_tag_type_private.h +2 -1
  137. data/ext/libmongocrypt/libmongocrypt/kms-message/src/kms_message/kms_kmip_request.h +17 -0
  138. data/ext/libmongocrypt/libmongocrypt/kms-message/src/kms_message/kms_kmip_response.h +6 -0
  139. data/ext/libmongocrypt/libmongocrypt/kms-message/src/kms_port.c +3 -2
  140. data/ext/libmongocrypt/libmongocrypt/kms-message/src/kms_request.c +4 -2
  141. data/ext/libmongocrypt/libmongocrypt/kms-message/src/kms_request_str.c +2 -2
  142. data/ext/libmongocrypt/libmongocrypt/kms-message/test/test_kmip_reader_writer.c +23 -2
  143. data/ext/libmongocrypt/libmongocrypt/src/crypto/cng.c +381 -436
  144. data/ext/libmongocrypt/libmongocrypt/src/crypto/commoncrypto.c +162 -227
  145. data/ext/libmongocrypt/libmongocrypt/src/crypto/libcrypto.c +183 -248
  146. data/ext/libmongocrypt/libmongocrypt/src/crypto/none.c +33 -55
  147. data/ext/libmongocrypt/libmongocrypt/src/csfle-markup.cpp +175 -205
  148. data/ext/libmongocrypt/libmongocrypt/src/mc-array-private.h +10 -21
  149. data/ext/libmongocrypt/libmongocrypt/src/mc-array.c +44 -56
  150. data/ext/libmongocrypt/libmongocrypt/src/mc-check-conversions-private.h +4 -8
  151. data/ext/libmongocrypt/libmongocrypt/src/mc-dec128.h +351 -463
  152. data/ext/libmongocrypt/libmongocrypt/src/mc-dec128.test.cpp +59 -66
  153. data/ext/libmongocrypt/libmongocrypt/src/mc-efc-private.h +21 -11
  154. data/ext/libmongocrypt/libmongocrypt/src/mc-efc.c +175 -99
  155. data/ext/libmongocrypt/libmongocrypt/src/mc-fle-blob-subtype-private.h +18 -10
  156. data/ext/libmongocrypt/libmongocrypt/src/mc-fle2-encryption-placeholder-private.h +69 -70
  157. data/ext/libmongocrypt/libmongocrypt/src/mc-fle2-encryption-placeholder.c +445 -439
  158. data/ext/libmongocrypt/libmongocrypt/src/mc-fle2-find-equality-payload-private-v2.h +41 -0
  159. data/ext/libmongocrypt/libmongocrypt/src/mc-fle2-find-equality-payload-private.h +11 -18
  160. data/ext/libmongocrypt/libmongocrypt/src/mc-fle2-find-equality-payload-v2.c +135 -0
  161. data/ext/libmongocrypt/libmongocrypt/src/mc-fle2-find-equality-payload.c +109 -126
  162. data/ext/libmongocrypt/libmongocrypt/src/mc-fle2-find-range-payload-private-v2.h +103 -0
  163. data/ext/libmongocrypt/libmongocrypt/src/mc-fle2-find-range-payload-private.h +28 -31
  164. data/ext/libmongocrypt/libmongocrypt/src/mc-fle2-find-range-payload-v2.c +173 -0
  165. data/ext/libmongocrypt/libmongocrypt/src/mc-fle2-find-range-payload.c +106 -125
  166. data/ext/libmongocrypt/libmongocrypt/src/mc-fle2-insert-update-payload-private-v2.h +130 -0
  167. data/ext/libmongocrypt/libmongocrypt/src/mc-fle2-insert-update-payload-private.h +36 -44
  168. data/ext/libmongocrypt/libmongocrypt/src/mc-fle2-insert-update-payload-v2.c +382 -0
  169. data/ext/libmongocrypt/libmongocrypt/src/mc-fle2-insert-update-payload.c +237 -278
  170. data/ext/libmongocrypt/libmongocrypt/src/mc-fle2-payload-iev-private-v2.h +133 -0
  171. data/ext/libmongocrypt/libmongocrypt/src/mc-fle2-payload-iev-private.h +67 -56
  172. data/ext/libmongocrypt/libmongocrypt/src/mc-fle2-payload-iev-v2.c +437 -0
  173. data/ext/libmongocrypt/libmongocrypt/src/mc-fle2-payload-iev.c +454 -325
  174. data/ext/libmongocrypt/libmongocrypt/src/mc-fle2-payload-uev-common-private.h +69 -0
  175. data/ext/libmongocrypt/libmongocrypt/src/mc-fle2-payload-uev-common.c +182 -0
  176. data/ext/libmongocrypt/libmongocrypt/src/mc-fle2-payload-uev-private.h +23 -31
  177. data/ext/libmongocrypt/libmongocrypt/src/mc-fle2-payload-uev-v2-private.h +85 -0
  178. data/ext/libmongocrypt/libmongocrypt/src/mc-fle2-payload-uev-v2.c +142 -0
  179. data/ext/libmongocrypt/libmongocrypt/src/mc-fle2-payload-uev.c +104 -231
  180. data/ext/libmongocrypt/libmongocrypt/src/mc-fle2-range-operator-private.h +8 -7
  181. data/ext/libmongocrypt/libmongocrypt/src/mc-fle2-rfds-private.h +56 -56
  182. data/ext/libmongocrypt/libmongocrypt/src/mc-fle2-rfds.c +520 -580
  183. data/ext/libmongocrypt/libmongocrypt/src/mc-optional-private.h +47 -66
  184. data/ext/libmongocrypt/libmongocrypt/src/mc-range-edge-generation-private.h +67 -76
  185. data/ext/libmongocrypt/libmongocrypt/src/mc-range-edge-generation.c +201 -190
  186. data/ext/libmongocrypt/libmongocrypt/src/mc-range-encoding-private.h +55 -42
  187. data/ext/libmongocrypt/libmongocrypt/src/mc-range-encoding.c +809 -558
  188. data/ext/libmongocrypt/libmongocrypt/src/mc-range-mincover-generator.template.h +177 -201
  189. data/ext/libmongocrypt/libmongocrypt/src/mc-range-mincover-private.h +54 -53
  190. data/ext/libmongocrypt/libmongocrypt/src/mc-range-mincover.c +188 -240
  191. data/ext/libmongocrypt/libmongocrypt/src/mc-rangeopts-private.h +43 -35
  192. data/ext/libmongocrypt/libmongocrypt/src/mc-rangeopts.c +484 -337
  193. data/ext/libmongocrypt/libmongocrypt/src/mc-reader-private.h +36 -71
  194. data/ext/libmongocrypt/libmongocrypt/src/mc-reader.c +111 -164
  195. data/ext/libmongocrypt/libmongocrypt/src/mc-tokens-private.h +87 -65
  196. data/ext/libmongocrypt/libmongocrypt/src/mc-tokens.c +153 -125
  197. data/ext/libmongocrypt/libmongocrypt/src/mc-writer-private.h +66 -0
  198. data/ext/libmongocrypt/libmongocrypt/src/mc-writer.c +141 -0
  199. data/ext/libmongocrypt/libmongocrypt/src/mlib/check.hpp +37 -55
  200. data/ext/libmongocrypt/libmongocrypt/src/mlib/endian.h +11 -11
  201. data/ext/libmongocrypt/libmongocrypt/src/mlib/error.h +27 -32
  202. data/ext/libmongocrypt/libmongocrypt/src/mlib/int128.h +461 -499
  203. data/ext/libmongocrypt/libmongocrypt/src/mlib/int128.test.cpp +256 -334
  204. data/ext/libmongocrypt/libmongocrypt/src/mlib/macros.h +4 -5
  205. data/ext/libmongocrypt/libmongocrypt/src/mlib/path.h +196 -231
  206. data/ext/libmongocrypt/libmongocrypt/src/mlib/path.test.c +56 -79
  207. data/ext/libmongocrypt/libmongocrypt/src/mlib/str.h +411 -530
  208. data/ext/libmongocrypt/libmongocrypt/src/mlib/str.test.c +116 -131
  209. data/ext/libmongocrypt/libmongocrypt/src/mlib/thread.h +17 -26
  210. data/ext/libmongocrypt/libmongocrypt/src/mlib/user-check.h +2 -2
  211. data/ext/libmongocrypt/libmongocrypt/src/mongocrypt-binary-private.h +1 -9
  212. data/ext/libmongocrypt/libmongocrypt/src/mongocrypt-binary.c +31 -48
  213. data/ext/libmongocrypt/libmongocrypt/src/mongocrypt-buffer-private.h +55 -131
  214. data/ext/libmongocrypt/libmongocrypt/src/mongocrypt-buffer.c +442 -565
  215. data/ext/libmongocrypt/libmongocrypt/src/mongocrypt-cache-collinfo-private.h +1 -2
  216. data/ext/libmongocrypt/libmongocrypt/src/mongocrypt-cache-collinfo.c +28 -45
  217. data/ext/libmongocrypt/libmongocrypt/src/mongocrypt-cache-key-private.h +11 -17
  218. data/ext/libmongocrypt/libmongocrypt/src/mongocrypt-cache-key.c +104 -132
  219. data/ext/libmongocrypt/libmongocrypt/src/mongocrypt-cache-oauth-private.h +16 -24
  220. data/ext/libmongocrypt/libmongocrypt/src/mongocrypt-cache-oauth.c +110 -93
  221. data/ext/libmongocrypt/libmongocrypt/src/mongocrypt-cache-private.h +26 -45
  222. data/ext/libmongocrypt/libmongocrypt/src/mongocrypt-cache.c +220 -273
  223. data/ext/libmongocrypt/libmongocrypt/src/mongocrypt-ciphertext-private.h +13 -25
  224. data/ext/libmongocrypt/libmongocrypt/src/mongocrypt-ciphertext.c +147 -166
  225. data/ext/libmongocrypt/libmongocrypt/src/mongocrypt-compat.h +2 -2
  226. data/ext/libmongocrypt/libmongocrypt/src/mongocrypt-crypto-private.h +110 -204
  227. data/ext/libmongocrypt/libmongocrypt/src/mongocrypt-crypto.c +1145 -1567
  228. data/ext/libmongocrypt/libmongocrypt/src/mongocrypt-ctx-datakey.c +510 -476
  229. data/ext/libmongocrypt/libmongocrypt/src/mongocrypt-ctx-decrypt.c +817 -694
  230. data/ext/libmongocrypt/libmongocrypt/src/mongocrypt-ctx-encrypt.c +2775 -2697
  231. data/ext/libmongocrypt/libmongocrypt/src/mongocrypt-ctx-private.h +189 -184
  232. data/ext/libmongocrypt/libmongocrypt/src/mongocrypt-ctx-rewrap-many-datakey.c +308 -351
  233. data/ext/libmongocrypt/libmongocrypt/src/mongocrypt-ctx.c +990 -1139
  234. data/ext/libmongocrypt/libmongocrypt/src/mongocrypt-dll-private.h +23 -24
  235. data/ext/libmongocrypt/libmongocrypt/src/mongocrypt-endian-private.h +44 -58
  236. data/ext/libmongocrypt/libmongocrypt/src/mongocrypt-endpoint-private.h +21 -25
  237. data/ext/libmongocrypt/libmongocrypt/src/mongocrypt-endpoint.c +167 -181
  238. data/ext/libmongocrypt/libmongocrypt/src/mongocrypt-kek-private.h +42 -44
  239. data/ext/libmongocrypt/libmongocrypt/src/mongocrypt-kek.c +292 -272
  240. data/ext/libmongocrypt/libmongocrypt/src/mongocrypt-key-broker-private.h +70 -110
  241. data/ext/libmongocrypt/libmongocrypt/src/mongocrypt-key-broker.c +1010 -1033
  242. data/ext/libmongocrypt/libmongocrypt/src/mongocrypt-key-private.h +27 -44
  243. data/ext/libmongocrypt/libmongocrypt/src/mongocrypt-key.c +349 -402
  244. data/ext/libmongocrypt/libmongocrypt/src/mongocrypt-kms-ctx-private.h +127 -120
  245. data/ext/libmongocrypt/libmongocrypt/src/mongocrypt-kms-ctx.c +1692 -1611
  246. data/ext/libmongocrypt/libmongocrypt/src/mongocrypt-log-private.h +35 -67
  247. data/ext/libmongocrypt/libmongocrypt/src/mongocrypt-log.c +49 -83
  248. data/ext/libmongocrypt/libmongocrypt/src/mongocrypt-marking-private.h +31 -36
  249. data/ext/libmongocrypt/libmongocrypt/src/mongocrypt-marking.c +1923 -1479
  250. data/ext/libmongocrypt/libmongocrypt/src/mongocrypt-mutex-private.h +7 -12
  251. data/ext/libmongocrypt/libmongocrypt/src/mongocrypt-opts-private.h +124 -107
  252. data/ext/libmongocrypt/libmongocrypt/src/mongocrypt-opts.c +925 -419
  253. data/ext/libmongocrypt/libmongocrypt/src/mongocrypt-private.h +99 -122
  254. data/ext/libmongocrypt/libmongocrypt/src/mongocrypt-status-private.h +3 -8
  255. data/ext/libmongocrypt/libmongocrypt/src/mongocrypt-status.c +92 -119
  256. data/ext/libmongocrypt/libmongocrypt/src/mongocrypt-traverse-util-private.h +19 -29
  257. data/ext/libmongocrypt/libmongocrypt/src/mongocrypt-traverse-util.c +136 -176
  258. data/ext/libmongocrypt/libmongocrypt/src/mongocrypt-util-private.h +11 -21
  259. data/ext/libmongocrypt/libmongocrypt/src/mongocrypt-util.c +98 -136
  260. data/ext/libmongocrypt/libmongocrypt/src/mongocrypt.c +924 -1339
  261. data/ext/libmongocrypt/libmongocrypt/src/mongocrypt.h +199 -313
  262. data/ext/libmongocrypt/libmongocrypt/src/os_posix/os_dll.c +83 -79
  263. data/ext/libmongocrypt/libmongocrypt/src/os_posix/os_mutex.c +20 -28
  264. data/ext/libmongocrypt/libmongocrypt/src/os_win/os_dll.c +64 -73
  265. data/ext/libmongocrypt/libmongocrypt/src/os_win/os_mutex.c +8 -16
  266. data/ext/libmongocrypt/libmongocrypt/test/crypt_shared-stub.cpp +57 -87
  267. data/ext/libmongocrypt/libmongocrypt/test/data/bulkWrite/bypassQueryAnalysis/payload.json +53 -0
  268. data/ext/libmongocrypt/libmongocrypt/test/data/bulkWrite/jsonSchema/cmd-to-mongocryptd.json +23 -0
  269. data/ext/libmongocrypt/libmongocrypt/test/data/bulkWrite/jsonSchema/cmd.json +20 -0
  270. data/ext/libmongocrypt/libmongocrypt/test/data/bulkWrite/simple/cmd-to-mongocryptd.json +50 -0
  271. data/ext/libmongocrypt/libmongocrypt/test/data/bulkWrite/simple/cmd.json +20 -0
  272. data/ext/libmongocrypt/libmongocrypt/test/data/bulkWrite/simple/collinfo.json +44 -0
  273. data/ext/libmongocrypt/libmongocrypt/test/data/bulkWrite/simple/encrypted-field-map.json +24 -0
  274. data/ext/libmongocrypt/libmongocrypt/test/data/bulkWrite/simple/encrypted-payload-pattern.json +53 -0
  275. data/ext/libmongocrypt/libmongocrypt/test/data/bulkWrite/simple/mongocryptd-reply.json +62 -0
  276. data/ext/libmongocrypt/libmongocrypt/test/data/bulkWrite/unencrypted/cmd-to-mongocryptd.json +30 -0
  277. data/ext/libmongocrypt/libmongocrypt/test/data/bulkWrite/unencrypted/cmd.json +17 -0
  278. data/ext/libmongocrypt/libmongocrypt/test/data/bulkWrite/unencrypted/mongocryptd-reply.json +39 -0
  279. data/ext/libmongocrypt/libmongocrypt/test/data/bulkWrite/unencrypted/payload.json +21 -0
  280. data/ext/libmongocrypt/libmongocrypt/test/data/cleanup/missing-key-id/collinfo.json +20 -0
  281. data/ext/libmongocrypt/libmongocrypt/test/data/cleanup/no-fields/collinfo.json +9 -0
  282. data/ext/libmongocrypt/libmongocrypt/test/data/cleanup/no-fields/encrypted-payload.json +4 -0
  283. data/ext/libmongocrypt/libmongocrypt/test/data/cleanup/success/cmd.json +1 -0
  284. data/ext/libmongocrypt/libmongocrypt/test/data/cleanup/success/collinfo.json +63 -0
  285. data/ext/libmongocrypt/libmongocrypt/test/data/cleanup/success/encrypted-field-config-map.json +61 -0
  286. data/ext/libmongocrypt/libmongocrypt/test/data/cleanup/success/encrypted-payload-range-v2.json +37 -0
  287. data/ext/libmongocrypt/libmongocrypt/test/data/cleanup/success/encrypted-payload.json +29 -0
  288. data/ext/libmongocrypt/libmongocrypt/test/data/compact/anchor-pad/cmd.json +1 -0
  289. data/ext/libmongocrypt/libmongocrypt/test/data/compact/anchor-pad/collinfo.json +64 -0
  290. data/ext/libmongocrypt/libmongocrypt/test/data/compact/anchor-pad/encrypted-payload-range-v2.json +105 -0
  291. data/ext/libmongocrypt/libmongocrypt/test/data/compact/anchor-pad/encrypted-payload.json +30 -0
  292. data/ext/libmongocrypt/libmongocrypt/test/data/compact/no-range/cmd.json +1 -0
  293. data/ext/libmongocrypt/libmongocrypt/test/data/compact/no-range/collinfo.json +49 -0
  294. data/ext/libmongocrypt/libmongocrypt/test/data/compact/no-range/encrypted-field-config-map.json +47 -0
  295. data/ext/libmongocrypt/libmongocrypt/test/data/compact/no-range/encrypted-payload.json +23 -0
  296. data/ext/libmongocrypt/libmongocrypt/test/data/compact/success/collinfo.json +15 -0
  297. data/ext/libmongocrypt/libmongocrypt/test/data/compact/success/encrypted-field-config-map.json +10 -0
  298. data/ext/libmongocrypt/libmongocrypt/test/data/compact/success/encrypted-payload-range-v2.json +104 -0
  299. data/ext/libmongocrypt/libmongocrypt/test/data/compact/success/encrypted-payload.json +6 -0
  300. data/ext/libmongocrypt/libmongocrypt/test/data/fle2-delete/empty/encrypted-payload-v2.json +60 -0
  301. data/ext/libmongocrypt/libmongocrypt/test/data/fle2-delete/success/encrypted-payload-v2.json +67 -0
  302. data/ext/libmongocrypt/libmongocrypt/test/data/fle2-explain/with-csfle/collinfo.json +4 -4
  303. data/ext/libmongocrypt/libmongocrypt/test/data/fle2-explain/with-csfle/encrypted-payload.json +5 -5
  304. data/ext/libmongocrypt/libmongocrypt/test/data/fle2-explicit/find-indexed-contentionFactor1-v2.json +8 -0
  305. data/ext/libmongocrypt/libmongocrypt/test/data/fle2-explicit/find-indexed-v2.json +8 -0
  306. data/ext/libmongocrypt/libmongocrypt/test/data/fle2-explicit/insert-indexed-contentionFactor1-v2.json +8 -0
  307. data/ext/libmongocrypt/libmongocrypt/test/data/fle2-explicit/insert-indexed-same-user-and-index-key-v2.json +8 -0
  308. data/ext/libmongocrypt/libmongocrypt/test/data/fle2-explicit/insert-indexed-v2.json +8 -0
  309. data/ext/libmongocrypt/libmongocrypt/test/data/fle2-find-equality-v2/cmd.json +6 -0
  310. data/ext/libmongocrypt/libmongocrypt/test/data/fle2-find-equality-v2/encrypted-field-map.json +22 -0
  311. data/ext/libmongocrypt/libmongocrypt/test/data/fle2-find-equality-v2/encrypted-payload.json +40 -0
  312. data/ext/libmongocrypt/libmongocrypt/test/data/fle2-find-equality-v2/mongocryptd-reply.json +19 -0
  313. data/ext/libmongocrypt/libmongocrypt/test/data/fle2-find-range/date-v2/cmd.json +10 -0
  314. data/ext/libmongocrypt/libmongocrypt/test/data/fle2-find-range/date-v2/encrypted-field-map.json +27 -0
  315. data/ext/libmongocrypt/libmongocrypt/test/data/fle2-find-range/date-v2/encrypted-payload.json +41 -0
  316. data/ext/libmongocrypt/libmongocrypt/test/data/fle2-find-range/date-v2/mongocryptd-reply.json +49 -0
  317. data/ext/libmongocrypt/libmongocrypt/test/data/fle2-find-range/decimal128-precision-v2/cmd.json +6 -0
  318. data/ext/libmongocrypt/libmongocrypt/test/data/fle2-find-range/decimal128-precision-v2/encrypted-field-map.json +30 -0
  319. data/ext/libmongocrypt/libmongocrypt/test/data/fle2-find-range/decimal128-precision-v2/encrypted-payload.json +50 -0
  320. data/ext/libmongocrypt/libmongocrypt/test/data/fle2-find-range/decimal128-precision-v2/mongocryptd-reply.json +58 -0
  321. data/ext/libmongocrypt/libmongocrypt/test/data/fle2-find-range/decimal128-v2/cmd.json +6 -0
  322. data/ext/libmongocrypt/libmongocrypt/test/data/fle2-find-range/decimal128-v2/encrypted-field-map.json +27 -0
  323. data/ext/libmongocrypt/libmongocrypt/test/data/fle2-find-range/decimal128-v2/encrypted-payload.json +41 -0
  324. data/ext/libmongocrypt/libmongocrypt/test/data/fle2-find-range/decimal128-v2/mongocryptd-reply.json +49 -0
  325. data/ext/libmongocrypt/libmongocrypt/test/data/fle2-find-range/double-precision-v2/cmd.json +8 -0
  326. data/ext/libmongocrypt/libmongocrypt/test/data/fle2-find-range/double-precision-v2/encrypted-field-map.json +30 -0
  327. data/ext/libmongocrypt/libmongocrypt/test/data/fle2-find-range/double-precision-v2/encrypted-payload.json +44 -0
  328. data/ext/libmongocrypt/libmongocrypt/test/data/fle2-find-range/double-precision-v2/mongocryptd-reply.json +52 -0
  329. data/ext/libmongocrypt/libmongocrypt/test/data/fle2-find-range/double-v2/cmd.json +8 -0
  330. data/ext/libmongocrypt/libmongocrypt/test/data/fle2-find-range/double-v2/encrypted-field-map.json +27 -0
  331. data/ext/libmongocrypt/libmongocrypt/test/data/fle2-find-range/double-v2/encrypted-payload.json +41 -0
  332. data/ext/libmongocrypt/libmongocrypt/test/data/fle2-find-range/double-v2/mongocryptd-reply.json +49 -0
  333. data/ext/libmongocrypt/libmongocrypt/test/data/fle2-find-range/int32-v2/cmd.json +8 -0
  334. data/ext/libmongocrypt/libmongocrypt/test/data/fle2-find-range/int32-v2/encrypted-field-map.json +27 -0
  335. data/ext/libmongocrypt/libmongocrypt/test/data/fle2-find-range/int32-v2/encrypted-payload.json +41 -0
  336. data/ext/libmongocrypt/libmongocrypt/test/data/fle2-find-range/int32-v2/mongocryptd-reply.json +49 -0
  337. data/ext/libmongocrypt/libmongocrypt/test/data/fle2-find-range/int64-v2/cmd.json +8 -0
  338. data/ext/libmongocrypt/libmongocrypt/test/data/fle2-find-range/int64-v2/encrypted-field-map.json +27 -0
  339. data/ext/libmongocrypt/libmongocrypt/test/data/fle2-find-range/int64-v2/encrypted-payload.json +41 -0
  340. data/ext/libmongocrypt/libmongocrypt/test/data/fle2-find-range/int64-v2/mongocryptd-reply.json +49 -0
  341. data/ext/libmongocrypt/libmongocrypt/test/data/fle2-find-range-explicit/double/encrypted-payload-v2.json +26 -0
  342. data/ext/libmongocrypt/libmongocrypt/test/data/fle2-find-range-explicit/double-precision/encrypted-payload-v2.json +26 -0
  343. data/ext/libmongocrypt/libmongocrypt/test/data/fle2-find-range-explicit/int32/encrypted-payload-v2.json +26 -0
  344. data/ext/libmongocrypt/libmongocrypt/test/data/fle2-find-range-explicit/int32-nominmax/encrypted-payload-v2.json +26 -0
  345. data/ext/libmongocrypt/libmongocrypt/test/data/fle2-find-range-explicit/int32-openinterval/encrypted-payload-v2.json +16 -0
  346. data/ext/libmongocrypt/libmongocrypt/test/data/fle2-insert/cmd.json +1 -1
  347. data/ext/libmongocrypt/libmongocrypt/test/data/fle2-insert-range/date/RNG_DATA.h +65 -65
  348. data/ext/libmongocrypt/libmongocrypt/test/data/fle2-insert-range/date-v2/cmd.json +13 -0
  349. data/ext/libmongocrypt/libmongocrypt/test/data/fle2-insert-range/date-v2/encrypted-field-map.json +27 -0
  350. data/ext/libmongocrypt/libmongocrypt/test/data/fle2-insert-range/date-v2/encrypted-payload.json +44 -0
  351. data/ext/libmongocrypt/libmongocrypt/test/data/fle2-insert-range/date-v2/mongocryptd-reply.json +52 -0
  352. data/ext/libmongocrypt/libmongocrypt/test/data/fle2-insert-range/decimal128/RNG_DATA.h +132 -132
  353. data/ext/libmongocrypt/libmongocrypt/test/data/fle2-insert-range/decimal128-precision/RNG_DATA.h +71 -71
  354. data/ext/libmongocrypt/libmongocrypt/test/data/fle2-insert-range/decimal128-precision-v2/cmd.json +9 -0
  355. data/ext/libmongocrypt/libmongocrypt/test/data/fle2-insert-range/decimal128-precision-v2/encrypted-field-map.json +30 -0
  356. data/ext/libmongocrypt/libmongocrypt/test/data/fle2-insert-range/decimal128-precision-v2/encrypted-payload.json +53 -0
  357. data/ext/libmongocrypt/libmongocrypt/test/data/fle2-insert-range/decimal128-precision-v2/mongocryptd-reply.json +61 -0
  358. data/ext/libmongocrypt/libmongocrypt/test/data/fle2-insert-range/decimal128-v2/cmd.json +9 -0
  359. data/ext/libmongocrypt/libmongocrypt/test/data/fle2-insert-range/decimal128-v2/encrypted-field-map.json +27 -0
  360. data/ext/libmongocrypt/libmongocrypt/test/data/fle2-insert-range/decimal128-v2/encrypted-payload.json +44 -0
  361. data/ext/libmongocrypt/libmongocrypt/test/data/fle2-insert-range/decimal128-v2/mongocryptd-reply.json +52 -0
  362. data/ext/libmongocrypt/libmongocrypt/test/data/fle2-insert-range/double/RNG_DATA.h +68 -68
  363. data/ext/libmongocrypt/libmongocrypt/test/data/fle2-insert-range/double-precision/RNG_DATA.h +19 -19
  364. data/ext/libmongocrypt/libmongocrypt/test/data/fle2-insert-range/double-precision-v2/cmd.json +11 -0
  365. data/ext/libmongocrypt/libmongocrypt/test/data/fle2-insert-range/double-precision-v2/encrypted-field-map.json +30 -0
  366. data/ext/libmongocrypt/libmongocrypt/test/data/fle2-insert-range/double-precision-v2/encrypted-payload.json +47 -0
  367. data/ext/libmongocrypt/libmongocrypt/test/data/fle2-insert-range/double-precision-v2/mongocryptd-reply.json +55 -0
  368. data/ext/libmongocrypt/libmongocrypt/test/data/fle2-insert-range/double-v2/cmd.json +11 -0
  369. data/ext/libmongocrypt/libmongocrypt/test/data/fle2-insert-range/double-v2/encrypted-field-map.json +27 -0
  370. data/ext/libmongocrypt/libmongocrypt/test/data/fle2-insert-range/double-v2/encrypted-payload.json +44 -0
  371. data/ext/libmongocrypt/libmongocrypt/test/data/fle2-insert-range/double-v2/mongocryptd-reply.json +52 -0
  372. data/ext/libmongocrypt/libmongocrypt/test/data/fle2-insert-range/int32/RNG_DATA.h +25 -25
  373. data/ext/libmongocrypt/libmongocrypt/test/data/fle2-insert-range/int32-v2/cmd.json +11 -0
  374. data/ext/libmongocrypt/libmongocrypt/test/data/fle2-insert-range/int32-v2/encrypted-field-map.json +27 -0
  375. data/ext/libmongocrypt/libmongocrypt/test/data/fle2-insert-range/int32-v2/encrypted-payload.json +44 -0
  376. data/ext/libmongocrypt/libmongocrypt/test/data/fle2-insert-range/int32-v2/mongocryptd-reply.json +52 -0
  377. data/ext/libmongocrypt/libmongocrypt/test/data/fle2-insert-range/int64/RNG_DATA.h +65 -65
  378. data/ext/libmongocrypt/libmongocrypt/test/data/fle2-insert-range/int64-v2/cmd.json +11 -0
  379. data/ext/libmongocrypt/libmongocrypt/test/data/fle2-insert-range/int64-v2/encrypted-field-map.json +27 -0
  380. data/ext/libmongocrypt/libmongocrypt/test/data/fle2-insert-range/int64-v2/encrypted-payload.json +44 -0
  381. data/ext/libmongocrypt/libmongocrypt/test/data/fle2-insert-range/int64-v2/mongocryptd-reply.json +52 -0
  382. data/ext/libmongocrypt/libmongocrypt/test/data/fle2-insert-range-explicit/double/RNG_DATA.h +68 -68
  383. data/ext/libmongocrypt/libmongocrypt/test/data/fle2-insert-range-explicit/double/encrypted-payload-v2.json +8 -0
  384. data/ext/libmongocrypt/libmongocrypt/test/data/fle2-insert-range-explicit/double-precision/RNG_DATA.h +19 -19
  385. data/ext/libmongocrypt/libmongocrypt/test/data/fle2-insert-range-explicit/double-precision/encrypted-payload-v2.json +8 -0
  386. data/ext/libmongocrypt/libmongocrypt/test/data/fle2-insert-range-explicit/int32/RNG_DATA.h +25 -25
  387. data/ext/libmongocrypt/libmongocrypt/test/data/fle2-insert-range-explicit/int32/encrypted-payload-v2.json +8 -0
  388. data/ext/libmongocrypt/libmongocrypt/test/data/fle2-insert-range-explicit/int32-nominmax/encrypted-payload-v2.json +8 -0
  389. data/ext/libmongocrypt/libmongocrypt/test/data/fle2-insert-range-explicit/sparsity-2/RNG_DATA.h +15 -15
  390. data/ext/libmongocrypt/libmongocrypt/test/data/fle2-insert-range-explicit/sparsity-2/encrypted-payload-v2.json +8 -0
  391. data/ext/libmongocrypt/libmongocrypt/test/data/fle2-insert-unindexed-v2/cmd.json +9 -0
  392. data/ext/libmongocrypt/libmongocrypt/test/data/fle2-insert-unindexed-v2/encrypted-field-map.json +18 -0
  393. data/ext/libmongocrypt/libmongocrypt/test/data/fle2-insert-unindexed-v2/encrypted-payload.json +14 -0
  394. data/ext/libmongocrypt/libmongocrypt/test/data/fle2-insert-unindexed-v2/mongocryptd-reply.json +41 -0
  395. data/ext/libmongocrypt/libmongocrypt/test/data/fle2-insert-v2/cmd.json +9 -0
  396. data/ext/libmongocrypt/libmongocrypt/test/data/fle2-insert-v2/encrypted-field-map.json +22 -0
  397. data/ext/libmongocrypt/libmongocrypt/test/data/fle2-insert-v2/encrypted-payload.json +39 -0
  398. data/ext/libmongocrypt/libmongocrypt/test/data/fle2-insert-v2/mongocryptd-reply.json +49 -0
  399. data/ext/libmongocrypt/libmongocrypt/test/data/iev-v2/FLECrudTest-insertOneRangeV2.json +10 -0
  400. data/ext/libmongocrypt/libmongocrypt/test/data/iev-v2/FLECrudTest-insertOneV2.json +10 -0
  401. data/ext/libmongocrypt/libmongocrypt/test/data/kms-azure/decrypt-response.txt +16 -0
  402. data/ext/libmongocrypt/libmongocrypt/test/data/kms-azure/encrypt-response.txt +16 -0
  403. data/ext/libmongocrypt/libmongocrypt/test/data/kms-azure/oauth-response.txt +19 -0
  404. data/ext/libmongocrypt/libmongocrypt/test/data/no-trimFactor/find/cmd.json +9 -0
  405. data/ext/libmongocrypt/libmongocrypt/test/data/no-trimFactor/find/encrypted-field-map.json +19 -0
  406. data/ext/libmongocrypt/libmongocrypt/test/data/no-trimFactor/find/encrypted-payload.json +62 -0
  407. data/ext/libmongocrypt/libmongocrypt/test/data/no-trimFactor/find/mongocryptd-reply.json +69 -0
  408. data/ext/libmongocrypt/libmongocrypt/test/data/no-trimFactor/insert/cmd.json +11 -0
  409. data/ext/libmongocrypt/libmongocrypt/test/data/no-trimFactor/insert/encrypted-field-map.json +19 -0
  410. data/ext/libmongocrypt/libmongocrypt/test/data/no-trimFactor/insert/encrypted-payload.json +40 -0
  411. data/ext/libmongocrypt/libmongocrypt/test/data/no-trimFactor/insert/mongocryptd-reply.json +47 -0
  412. data/ext/libmongocrypt/libmongocrypt/test/data/range-edge-generation/edges_decimal128.cstruct +1 -1
  413. data/ext/libmongocrypt/libmongocrypt/test/data/range-edge-generation/edges_double.cstruct +8637 -7958
  414. data/ext/libmongocrypt/libmongocrypt/test/data/range-edge-generation/edges_int32.cstruct +5522 -1382
  415. data/ext/libmongocrypt/libmongocrypt/test/data/range-edge-generation/edges_int64.cstruct +5042 -1262
  416. data/ext/libmongocrypt/libmongocrypt/test/data/range-min-cover/mincover_decimal128.cstruct +1 -1
  417. data/ext/libmongocrypt/libmongocrypt/test/data/range-min-cover/mincover_decimal128_precision.cstruct +1 -1
  418. data/ext/libmongocrypt/libmongocrypt/test/data/range-min-cover/mincover_double.cstruct +1 -1
  419. data/ext/libmongocrypt/libmongocrypt/test/data/range-min-cover/mincover_double_precision.cstruct +2 -2
  420. data/ext/libmongocrypt/libmongocrypt/test/data/range-min-cover/mincover_int32.cstruct +1 -1
  421. data/ext/libmongocrypt/libmongocrypt/test/data/range-min-cover/mincover_int64.cstruct +1 -1
  422. data/ext/libmongocrypt/libmongocrypt/test/data/range-sends-cryptoParams/auto-find-int32/cmd.json +8 -0
  423. data/ext/libmongocrypt/libmongocrypt/test/data/range-sends-cryptoParams/auto-find-int32/encrypted-field-map.json +19 -0
  424. data/ext/libmongocrypt/libmongocrypt/test/data/range-sends-cryptoParams/auto-find-int32/encrypted-payload.json +53 -0
  425. data/ext/libmongocrypt/libmongocrypt/test/data/range-sends-cryptoParams/auto-find-int32/mongocryptd-reply.json +58 -0
  426. data/ext/libmongocrypt/libmongocrypt/test/data/range-sends-cryptoParams/auto-insert-int32/cmd.json +11 -0
  427. data/ext/libmongocrypt/libmongocrypt/test/data/range-sends-cryptoParams/auto-insert-int32/encrypted-field-map.json +19 -0
  428. data/ext/libmongocrypt/libmongocrypt/test/data/range-sends-cryptoParams/auto-insert-int32/encrypted-payload.json +40 -0
  429. data/ext/libmongocrypt/libmongocrypt/test/data/range-sends-cryptoParams/auto-insert-int32/mongocryptd-reply.json +45 -0
  430. data/ext/libmongocrypt/libmongocrypt/test/data/range-sends-cryptoParams/explicit-find-int32/expected.json +26 -0
  431. data/ext/libmongocrypt/libmongocrypt/test/data/range-sends-cryptoParams/explicit-find-int32/to-encrypt.json +20 -0
  432. data/ext/libmongocrypt/libmongocrypt/test/data/range-sends-cryptoParams/explicit-find-int32-defaults/expected.json +26 -0
  433. data/ext/libmongocrypt/libmongocrypt/test/data/range-sends-cryptoParams/explicit-find-int32-defaults/to-encrypt.json +20 -0
  434. data/ext/libmongocrypt/libmongocrypt/test/data/range-sends-cryptoParams/explicit-insert-double/expected.json +8 -0
  435. data/ext/libmongocrypt/libmongocrypt/test/data/range-sends-cryptoParams/explicit-insert-int32/expected.json +8 -0
  436. data/ext/libmongocrypt/libmongocrypt/test/data/range-sends-cryptoParams/explicit-insert-int32-defaults/expected.json +8 -0
  437. data/ext/libmongocrypt/libmongocrypt/test/data/roundtrip/README.md +17 -0
  438. data/ext/libmongocrypt/libmongocrypt/test/data/roundtrip/aes-ctr.json +29 -0
  439. data/ext/libmongocrypt/libmongocrypt/test/data/roundtrip/fle2-fixed.json +10 -0
  440. data/ext/libmongocrypt/libmongocrypt/test/data/roundtrip/fle2-generated.json +38 -0
  441. data/ext/libmongocrypt/libmongocrypt/test/data/roundtrip/fle2aead-decrypt.json +35 -0
  442. data/ext/libmongocrypt/libmongocrypt/test/data/roundtrip/fle2aead-fixed.json +29 -0
  443. data/ext/libmongocrypt/libmongocrypt/test/data/roundtrip/fle2aead-generated.json +122 -0
  444. data/ext/libmongocrypt/libmongocrypt/test/data/roundtrip/fle2v2-aead-fixed.json +29 -0
  445. data/ext/libmongocrypt/libmongocrypt/test/data/roundtrip/fle2v2-aead-generated.json +122 -0
  446. data/ext/libmongocrypt/libmongocrypt/test/data/roundtrip/mcgrew.json +12 -0
  447. data/ext/libmongocrypt/libmongocrypt/test/data/roundtrip/nist.json +20 -0
  448. data/ext/libmongocrypt/libmongocrypt/test/data/tokens/README.md +30 -0
  449. data/ext/libmongocrypt/libmongocrypt/test/data/tokens/mc.json +25 -0
  450. data/ext/libmongocrypt/libmongocrypt/test/data/tokens/server.json +25 -0
  451. data/ext/libmongocrypt/libmongocrypt/test/example-no-bson.c +4 -4
  452. data/ext/libmongocrypt/libmongocrypt/test/example-state-machine.c +279 -323
  453. data/ext/libmongocrypt/libmongocrypt/test/fuzz_kms.c +8 -7
  454. data/ext/libmongocrypt/libmongocrypt/test/test-dll.cpp +6 -7
  455. data/ext/libmongocrypt/libmongocrypt/test/test-gcp-auth.c +221 -283
  456. data/ext/libmongocrypt/libmongocrypt/test/test-mc-efc.c +60 -73
  457. data/ext/libmongocrypt/libmongocrypt/test/test-mc-fle2-find-equality-payload-v2.c +78 -0
  458. data/ext/libmongocrypt/libmongocrypt/test/test-mc-fle2-find-range-payload-v2.c +129 -0
  459. data/ext/libmongocrypt/libmongocrypt/test/test-mc-fle2-payload-iev-v2.c +248 -0
  460. data/ext/libmongocrypt/libmongocrypt/test/test-mc-fle2-payload-iev.c +467 -414
  461. data/ext/libmongocrypt/libmongocrypt/test/test-mc-fle2-payload-iup-v2.c +248 -0
  462. data/ext/libmongocrypt/libmongocrypt/test/test-mc-fle2-payload-iup.c +141 -159
  463. data/ext/libmongocrypt/libmongocrypt/test/test-mc-fle2-payload-uev-v2.c +338 -0
  464. data/ext/libmongocrypt/libmongocrypt/test/test-mc-fle2-payload-uev.c +238 -176
  465. data/ext/libmongocrypt/libmongocrypt/test/test-mc-fle2-rfds.c +373 -474
  466. data/ext/libmongocrypt/libmongocrypt/test/test-mc-range-edge-generation.c +421 -388
  467. data/ext/libmongocrypt/libmongocrypt/test/test-mc-range-encoding.c +974 -825
  468. data/ext/libmongocrypt/libmongocrypt/test/test-mc-range-mincover.c +499 -481
  469. data/ext/libmongocrypt/libmongocrypt/test/test-mc-rangeopts.c +312 -148
  470. data/ext/libmongocrypt/libmongocrypt/test/test-mc-reader.c +124 -207
  471. data/ext/libmongocrypt/libmongocrypt/test/test-mc-tokens.c +249 -213
  472. data/ext/libmongocrypt/libmongocrypt/test/test-mc-writer.c +176 -0
  473. data/ext/libmongocrypt/libmongocrypt/test/test-mongocrypt-assert-match-bson.c +632 -808
  474. data/ext/libmongocrypt/libmongocrypt/test/test-mongocrypt-assert-match-bson.h +22 -2
  475. data/ext/libmongocrypt/libmongocrypt/test/test-mongocrypt-assert.h +168 -189
  476. data/ext/libmongocrypt/libmongocrypt/test/test-mongocrypt-buffer.c +187 -211
  477. data/ext/libmongocrypt/libmongocrypt/test/test-mongocrypt-cache-oauth.c +118 -37
  478. data/ext/libmongocrypt/libmongocrypt/test/test-mongocrypt-cache.c +210 -233
  479. data/ext/libmongocrypt/libmongocrypt/test/test-mongocrypt-ciphertext.c +185 -220
  480. data/ext/libmongocrypt/libmongocrypt/test/test-mongocrypt-cleanup.c +374 -0
  481. data/ext/libmongocrypt/libmongocrypt/test/test-mongocrypt-compact.c +410 -445
  482. data/ext/libmongocrypt/libmongocrypt/test/test-mongocrypt-crypto-hooks.c +798 -812
  483. data/ext/libmongocrypt/libmongocrypt/test/test-mongocrypt-crypto-std-hooks.c +142 -135
  484. data/ext/libmongocrypt/libmongocrypt/test/test-mongocrypt-crypto-std-hooks.h +70 -71
  485. data/ext/libmongocrypt/libmongocrypt/test/test-mongocrypt-crypto.c +394 -846
  486. data/ext/libmongocrypt/libmongocrypt/test/test-mongocrypt-csfle-lib.c +159 -183
  487. data/ext/libmongocrypt/libmongocrypt/test/test-mongocrypt-ctx-decrypt.c +870 -1045
  488. data/ext/libmongocrypt/libmongocrypt/test/test-mongocrypt-ctx-encrypt.c +5183 -4717
  489. data/ext/libmongocrypt/libmongocrypt/test/test-mongocrypt-ctx-rewrap-many-datakey.c +750 -964
  490. data/ext/libmongocrypt/libmongocrypt/test/test-mongocrypt-ctx-setopt.c +1093 -1178
  491. data/ext/libmongocrypt/libmongocrypt/test/test-mongocrypt-datakey.c +348 -420
  492. data/ext/libmongocrypt/libmongocrypt/test/test-mongocrypt-dll.c +23 -30
  493. data/ext/libmongocrypt/libmongocrypt/test/test-mongocrypt-endpoint.c +98 -111
  494. data/ext/libmongocrypt/libmongocrypt/test/test-mongocrypt-kek.c +49 -52
  495. data/ext/libmongocrypt/libmongocrypt/test/test-mongocrypt-key-broker.c +770 -920
  496. data/ext/libmongocrypt/libmongocrypt/test/test-mongocrypt-key-cache.c +354 -407
  497. data/ext/libmongocrypt/libmongocrypt/test/test-mongocrypt-key.c +197 -245
  498. data/ext/libmongocrypt/libmongocrypt/test/test-mongocrypt-kms-ctx.c +705 -368
  499. data/ext/libmongocrypt/libmongocrypt/test/test-mongocrypt-kms-responses.c +147 -166
  500. data/ext/libmongocrypt/libmongocrypt/test/test-mongocrypt-local-kms.c +50 -61
  501. data/ext/libmongocrypt/libmongocrypt/test/test-mongocrypt-log.c +85 -100
  502. data/ext/libmongocrypt/libmongocrypt/test/test-mongocrypt-marking.c +1073 -690
  503. data/ext/libmongocrypt/libmongocrypt/test/test-mongocrypt-opts.c +42 -0
  504. data/ext/libmongocrypt/libmongocrypt/test/test-mongocrypt-status.c +46 -58
  505. data/ext/libmongocrypt/libmongocrypt/test/test-mongocrypt-traverse-util.c +381 -451
  506. data/ext/libmongocrypt/libmongocrypt/test/test-mongocrypt-util.c +55 -67
  507. data/ext/libmongocrypt/libmongocrypt/test/test-mongocrypt-util.h +7 -10
  508. data/ext/libmongocrypt/libmongocrypt/test/test-mongocrypt.c +879 -918
  509. data/ext/libmongocrypt/libmongocrypt/test/test-mongocrypt.h +119 -169
  510. data/ext/libmongocrypt/libmongocrypt/test/test-named-kms-providers.c +2381 -0
  511. data/ext/libmongocrypt/libmongocrypt/test/util/HELP.autogen +3 -1
  512. data/ext/libmongocrypt/libmongocrypt/test/util/README.md +1 -0
  513. data/ext/libmongocrypt/libmongocrypt/test/util/csfle.c +512 -559
  514. data/ext/libmongocrypt/libmongocrypt/test/util/make_includes.py +1 -1
  515. data/ext/libmongocrypt/libmongocrypt/test/util/util.c +771 -882
  516. data/ext/libmongocrypt/libmongocrypt/test/util/util.h +33 -55
  517. data/lib/libmongocrypt_helper/version.rb +2 -2
  518. metadata +245 -111
  519. checksums.yaml.gz.sig +0 -0
  520. data/ext/libmongocrypt/libmongocrypt/VERSION_CURRENT +0 -1
  521. data/ext/libmongocrypt/libmongocrypt/bindings/java/mongocrypt/src/test/resources/fle2-find-range-explicit/int32/encrypted-payload.json +0 -26
  522. data/ext/libmongocrypt/libmongocrypt/bindings/java/mongocrypt/src/test/resources/fle2-find-range-explicit/int32/key-document.json +0 -0
  523. data/ext/libmongocrypt/libmongocrypt/bindings/node/CHANGELOG.md +0 -81
  524. data/ext/libmongocrypt/libmongocrypt/bindings/node/LICENSE +0 -201
  525. data/ext/libmongocrypt/libmongocrypt/bindings/node/binding.gyp +0 -79
  526. data/ext/libmongocrypt/libmongocrypt/bindings/node/etc/README.hbs +0 -44
  527. data/ext/libmongocrypt/libmongocrypt/bindings/node/etc/build-static.sh +0 -39
  528. data/ext/libmongocrypt/libmongocrypt/bindings/node/index.d.ts +0 -515
  529. data/ext/libmongocrypt/libmongocrypt/bindings/node/lib/autoEncrypter.js +0 -420
  530. data/ext/libmongocrypt/libmongocrypt/bindings/node/lib/buffer_pool.js +0 -123
  531. data/ext/libmongocrypt/libmongocrypt/bindings/node/lib/clientEncryption.js +0 -699
  532. data/ext/libmongocrypt/libmongocrypt/bindings/node/lib/common.js +0 -100
  533. data/ext/libmongocrypt/libmongocrypt/bindings/node/lib/credentialsProvider.js +0 -33
  534. data/ext/libmongocrypt/libmongocrypt/bindings/node/lib/cryptoCallbacks.js +0 -87
  535. data/ext/libmongocrypt/libmongocrypt/bindings/node/lib/index.js +0 -42
  536. data/ext/libmongocrypt/libmongocrypt/bindings/node/lib/mongocryptdManager.js +0 -66
  537. data/ext/libmongocrypt/libmongocrypt/bindings/node/lib/stateMachine.js +0 -487
  538. data/ext/libmongocrypt/libmongocrypt/bindings/node/package-lock.json +0 -16051
  539. data/ext/libmongocrypt/libmongocrypt/bindings/node/package.json +0 -81
  540. data/ext/libmongocrypt/libmongocrypt/bindings/node/src/mongocrypt.cc +0 -929
  541. data/ext/libmongocrypt/libmongocrypt/bindings/node/src/mongocrypt.h +0 -114
  542. data/ext/libmongocrypt/libmongocrypt/bindings/node/test/autoEncrypter.test.js +0 -953
  543. data/ext/libmongocrypt/libmongocrypt/bindings/node/test/buffer_pool.test.js +0 -91
  544. data/ext/libmongocrypt/libmongocrypt/bindings/node/test/clientEncryption.test.js +0 -701
  545. data/ext/libmongocrypt/libmongocrypt/bindings/node/test/credentialsProvider.test.js +0 -163
  546. data/ext/libmongocrypt/libmongocrypt/bindings/node/test/cryptoCallbacks.test.js +0 -284
  547. data/ext/libmongocrypt/libmongocrypt/bindings/node/test/data/README.md +0 -5
  548. data/ext/libmongocrypt/libmongocrypt/bindings/node/test/data/cmd.json +0 -6
  549. data/ext/libmongocrypt/libmongocrypt/bindings/node/test/data/collection-info.json +0 -37
  550. data/ext/libmongocrypt/libmongocrypt/bindings/node/test/data/encrypted-document-nested.json +0 -8
  551. data/ext/libmongocrypt/libmongocrypt/bindings/node/test/data/encrypted-document.json +0 -11
  552. data/ext/libmongocrypt/libmongocrypt/bindings/node/test/data/encryptedFields.json +0 -30
  553. data/ext/libmongocrypt/libmongocrypt/bindings/node/test/data/key-document.json +0 -32
  554. data/ext/libmongocrypt/libmongocrypt/bindings/node/test/data/key1-document.json +0 -30
  555. data/ext/libmongocrypt/libmongocrypt/bindings/node/test/data/mongocryptd-reply.json +0 -18
  556. data/ext/libmongocrypt/libmongocrypt/bindings/node/test/mongocryptdManager.test.js +0 -48
  557. data/ext/libmongocrypt/libmongocrypt/bindings/node/test/release.test.js +0 -59
  558. data/ext/libmongocrypt/libmongocrypt/bindings/node/test/requirements.helper.js +0 -29
  559. data/ext/libmongocrypt/libmongocrypt/bindings/node/test/stateMachine.test.js +0 -331
  560. data/ext/libmongocrypt/libmongocrypt/bindings/node/test/tools/mongodb_reporter.js +0 -325
  561. data/ext/libmongocrypt/libmongocrypt/bindings/python/setup.py +0 -84
  562. data/ext/libmongocrypt/libmongocrypt/bindings/python/test/data/fle2-find-range-explicit/int32/encrypted-payload.json +0 -26
  563. data/ext/libmongocrypt/libmongocrypt/bindings/python/test-requirements.txt +0 -12
  564. data/ext/libmongocrypt/libmongocrypt/debian/build_snapshot.sh +0 -79
  565. data/ext/libmongocrypt/libmongocrypt/debian/changelog +0 -105
  566. data/ext/libmongocrypt/libmongocrypt/debian/compat +0 -1
  567. data/ext/libmongocrypt/libmongocrypt/debian/control +0 -41
  568. data/ext/libmongocrypt/libmongocrypt/debian/copyright +0 -129
  569. data/ext/libmongocrypt/libmongocrypt/debian/gbp.conf +0 -23
  570. data/ext/libmongocrypt/libmongocrypt/debian/libmongocrypt-dev.dirs +0 -2
  571. data/ext/libmongocrypt/libmongocrypt/debian/libmongocrypt-dev.install +0 -5
  572. data/ext/libmongocrypt/libmongocrypt/debian/libmongocrypt0.dirs +0 -1
  573. data/ext/libmongocrypt/libmongocrypt/debian/libmongocrypt0.install +0 -1
  574. data/ext/libmongocrypt/libmongocrypt/debian/rules +0 -46
  575. data/ext/libmongocrypt/libmongocrypt/debian/source/format +0 -1
  576. data/ext/libmongocrypt/libmongocrypt/debian/source/lintian-overrides +0 -3
  577. data/ext/libmongocrypt/libmongocrypt/debian/source/options +0 -1
  578. data/ext/libmongocrypt/libmongocrypt/debian/watch +0 -3
  579. data/ext/libmongocrypt/libmongocrypt/test/data/aes-ctr.cstructs +0 -359
  580. data/ext/libmongocrypt/libmongocrypt/test/data/compact/success/mongocryptd-reply.json +0 -72
  581. data/ext/libmongocrypt/libmongocrypt/test/data/fle2-aead.cstructs +0 -109
  582. data/ext/libmongocrypt/libmongocrypt/test/data/fle2-find-range-explicit/int32-nominmax/encrypted-payload.json +0 -26
  583. data/ext/libmongocrypt/libmongocrypt/test/data/fle2-find-range-explicit/int32-nominmax/rangeopts.json +0 -5
  584. data/ext/libmongocrypt/libmongocrypt/test/data/fle2-insert-range-explicit/int32-nominmax/RNG_DATA.h +0 -70
  585. data/ext/libmongocrypt/libmongocrypt/test/data/fle2-insert-range-explicit/int32-nominmax/encrypted-payload.json +0 -8
  586. data/ext/libmongocrypt/libmongocrypt/test/data/fle2-insert-range-explicit/int32-nominmax/rangeopts.json +0 -5
  587. data/ext/libmongocrypt/libmongocrypt/test/data/fle2-insert-range-explicit/int32-nominmax/value-to-encrypt.json +0 -5
  588. data/ext/libmongocrypt/libmongocrypt/test/data/fle2.cstructs +0 -33
  589. data.tar.gz.sig +0 -0
  590. metadata.gz.sig +0 -0
  591. /data/ext/libmongocrypt/libmongocrypt/bindings/java/mongocrypt/src/test/resources/{fle2-find-range-explicit → fle2-find-range-explicit-v2}/int32/key-filter.json +0 -0
  592. /data/ext/libmongocrypt/libmongocrypt/bindings/java/mongocrypt/src/test/resources/{fle2-find-range-explicit → fle2-find-range-explicit-v2}/int32/value-to-encrypt.json +0 -0
  593. /data/ext/libmongocrypt/libmongocrypt/bindings/python/test/data/{fle2-find-range-explicit → fle2-find-range-explicit-v2}/int32/value-to-encrypt.json +0 -0
  594. /data/ext/libmongocrypt/libmongocrypt/bindings/{java/mongocrypt/src/test/resources/fle2-find-range-explicit → python/test/data/fle2-find-rangePreview-explicit}/int32/rangeopts.json +0 -0
  595. /data/ext/libmongocrypt/libmongocrypt/{test/data/fle2-find-range-explicit/int32-nominmax → bindings/python/test/data/fle2-find-rangePreview-explicit/int32}/value-to-encrypt.json +0 -0
  596. /data/ext/libmongocrypt/libmongocrypt/{bindings/node/test/data/kms-decrypt-reply.txt → test/data/kms-aws/decrypt-response.txt} +0 -0
  597. /data/ext/libmongocrypt/libmongocrypt/{bindings/node/test/data/kms-encrypt-reply.txt → test/data/kms-aws/encrypt-response.txt} +0 -0
  598. /data/ext/libmongocrypt/libmongocrypt/test/data/{gcp-auth → kms-gcp}/decrypt-response.txt +0 -0
  599. /data/ext/libmongocrypt/libmongocrypt/test/data/{gcp-auth → kms-gcp}/encrypt-response.txt +0 -0
  600. /data/ext/libmongocrypt/libmongocrypt/test/data/{gcp-auth → kms-gcp}/oauth-response.txt +0 -0
@@ -36,430 +36,422 @@
36
36
  * encryption function
37
37
  */
38
38
 
39
- static bool
40
- _crypto_aes_256_ctr_encrypt_decrypt_via_ecb (
41
- void *ctx,
42
- mongocrypt_crypto_fn aes_256_ecb_encrypt,
43
- aes_256_args_t args,
44
- mongocrypt_status_t *status)
45
- {
46
- BSON_ASSERT (args.iv && args.iv->len);
47
- BSON_ASSERT (args.in);
48
- BSON_ASSERT (args.out);
49
-
50
- if (args.out->len < args.in->len) {
51
- CLIENT_ERR ("output buffer too small");
52
- return false;
53
- }
54
-
55
- _mongocrypt_buffer_t ctr, tmp;
56
- mongocrypt_binary_t key_bin, out_bin, in_bin, ctr_bin, tmp_bin;
57
- bool ret;
58
-
59
- _mongocrypt_buffer_to_binary (args.key, &key_bin);
60
- _mongocrypt_buffer_init (&ctr);
61
- _mongocrypt_buffer_copy_to (args.iv, &ctr);
62
- _mongocrypt_buffer_to_binary (&ctr, &ctr_bin);
63
- _mongocrypt_buffer_to_binary (args.out, &out_bin);
64
- _mongocrypt_buffer_to_binary (args.in, &in_bin);
65
- _mongocrypt_buffer_init_size (&tmp, args.iv->len);
66
- _mongocrypt_buffer_to_binary (&tmp, &tmp_bin);
67
-
68
- for (uint32_t ptr = 0; ptr < args.in->len;) {
69
- /* Encrypt value in CTR buffer */
70
- uint32_t bytes_written = 0;
71
- if (!aes_256_ecb_encrypt (
72
- ctx, &key_bin, NULL, &ctr_bin, &tmp_bin, &bytes_written, status)) {
73
- ret = false;
74
- goto cleanup;
75
- }
76
-
77
- if (bytes_written != tmp_bin.len) {
78
- CLIENT_ERR ("encryption hook returned unexpected length");
79
- ret = false;
80
- goto cleanup;
81
- }
82
-
83
- /* XOR resulting stream with original data */
84
- for (uint32_t i = 0; i < bytes_written && ptr < args.in->len;
85
- i++, ptr++) {
86
- out_bin.data[ptr] = in_bin.data[ptr] ^ tmp_bin.data[i];
87
- }
88
-
89
- /* Increment value in CTR buffer */
90
- uint32_t carry = 1;
91
- /* assert rather than return since this should never happen */
92
- BSON_ASSERT (ctr_bin.len == 0u || ctr_bin.len - 1u <= INT_MAX);
93
- for (int i = (int) ctr_bin.len - 1; i >= 0 && carry != 0; --i) {
94
- uint32_t bpp = carry + ctr_bin.data[i];
95
- carry = bpp >> 8;
96
- ctr_bin.data[i] = bpp & 0xFF;
97
- }
98
- }
99
-
100
- if (args.bytes_written) {
101
- *args.bytes_written = args.in->len;
102
- }
103
-
104
- ret = true;
39
+ static bool _crypto_aes_256_ctr_encrypt_decrypt_via_ecb(void *ctx,
40
+ mongocrypt_crypto_fn aes_256_ecb_encrypt,
41
+ aes_256_args_t args,
42
+ mongocrypt_status_t *status) {
43
+ BSON_ASSERT(args.iv && args.iv->len);
44
+ BSON_ASSERT(args.in);
45
+ BSON_ASSERT(args.out);
46
+
47
+ if (args.out->len < args.in->len) {
48
+ CLIENT_ERR("output buffer too small");
49
+ return false;
50
+ }
51
+
52
+ _mongocrypt_buffer_t ctr, tmp;
53
+ mongocrypt_binary_t key_bin, out_bin, in_bin, ctr_bin, tmp_bin;
54
+ bool ret;
55
+
56
+ _mongocrypt_buffer_to_binary(args.key, &key_bin);
57
+ _mongocrypt_buffer_init(&ctr);
58
+ _mongocrypt_buffer_copy_to(args.iv, &ctr);
59
+ _mongocrypt_buffer_to_binary(&ctr, &ctr_bin);
60
+ _mongocrypt_buffer_to_binary(args.out, &out_bin);
61
+ _mongocrypt_buffer_to_binary(args.in, &in_bin);
62
+ _mongocrypt_buffer_init_size(&tmp, args.iv->len);
63
+ _mongocrypt_buffer_to_binary(&tmp, &tmp_bin);
64
+
65
+ for (uint32_t ptr = 0; ptr < args.in->len;) {
66
+ /* Encrypt value in CTR buffer */
67
+ uint32_t bytes_written = 0;
68
+ if (!aes_256_ecb_encrypt(ctx, &key_bin, NULL, &ctr_bin, &tmp_bin, &bytes_written, status)) {
69
+ ret = false;
70
+ goto cleanup;
71
+ }
72
+
73
+ if (bytes_written != tmp_bin.len) {
74
+ CLIENT_ERR("encryption hook returned unexpected length");
75
+ ret = false;
76
+ goto cleanup;
77
+ }
78
+
79
+ /* XOR resulting stream with original data */
80
+ for (uint32_t i = 0; i < bytes_written && ptr < args.in->len; i++, ptr++) {
81
+ uint8_t *in_bin_u8 = in_bin.data;
82
+ uint8_t *out_bin_u8 = out_bin.data;
83
+ uint8_t *tmp_bin_u8 = tmp_bin.data;
84
+ out_bin_u8[ptr] = in_bin_u8[ptr] ^ tmp_bin_u8[i];
85
+ }
86
+
87
+ /* Increment value in CTR buffer */
88
+ uint32_t carry = 1;
89
+ /* assert rather than return since this should never happen */
90
+ BSON_ASSERT(ctr_bin.len == 0u || ctr_bin.len - 1u <= INT_MAX);
91
+ for (int i = (int)ctr_bin.len - 1; i >= 0 && carry != 0; --i) {
92
+ uint8_t *ctr_bin_u8 = ctr_bin.data;
93
+ uint32_t bpp = carry + ctr_bin_u8[i];
94
+ carry = bpp >> 8;
95
+ ctr_bin_u8[i] = bpp & 0xFF;
96
+ }
97
+ }
98
+
99
+ if (args.bytes_written) {
100
+ *args.bytes_written = args.in->len;
101
+ }
102
+
103
+ ret = true;
105
104
 
106
105
  cleanup:
107
- _mongocrypt_buffer_cleanup (&ctr);
108
- _mongocrypt_buffer_cleanup (&tmp);
109
- return ret;
106
+ _mongocrypt_buffer_cleanup(&ctr);
107
+ _mongocrypt_buffer_cleanup(&tmp);
108
+ return ret;
110
109
  }
111
110
 
112
111
  /* Crypto primitives. These either call the native built in crypto primitives or
113
112
  * user supplied hooks. */
114
- static bool
115
- _crypto_aes_256_cbc_encrypt (_mongocrypt_crypto_t *crypto, aes_256_args_t args)
116
- {
117
- mongocrypt_status_t *status = args.status;
118
-
119
- BSON_ASSERT_PARAM (crypto);
120
-
121
- BSON_ASSERT (args.key);
122
- if (args.key->len != MONGOCRYPT_ENC_KEY_LEN) {
123
- CLIENT_ERR ("invalid encryption key length");
124
- return false;
125
- }
126
-
127
- BSON_ASSERT (args.iv);
128
- if (args.iv->len != MONGOCRYPT_IV_LEN) {
129
- CLIENT_ERR ("invalid iv length");
130
- return false;
131
- }
132
-
133
- if (crypto->hooks_enabled) {
134
- mongocrypt_binary_t enc_key_bin, iv_bin, out_bin, in_bin;
135
- bool ret;
136
-
137
- _mongocrypt_buffer_to_binary (args.key, &enc_key_bin);
138
- _mongocrypt_buffer_to_binary (args.iv, &iv_bin);
139
- _mongocrypt_buffer_to_binary (args.out, &out_bin);
140
- _mongocrypt_buffer_to_binary (args.in, &in_bin);
141
-
142
- ret = crypto->aes_256_cbc_encrypt (crypto->ctx,
143
- &enc_key_bin,
144
- &iv_bin,
145
- &in_bin,
146
- &out_bin,
147
- args.bytes_written,
148
- status);
149
- return ret;
150
- }
151
- return _native_crypto_aes_256_cbc_encrypt (args);
113
+ static bool _crypto_aes_256_cbc_encrypt(_mongocrypt_crypto_t *crypto, aes_256_args_t args) {
114
+ mongocrypt_status_t *status = args.status;
115
+
116
+ BSON_ASSERT_PARAM(crypto);
117
+
118
+ BSON_ASSERT(args.key);
119
+ if (args.key->len != MONGOCRYPT_ENC_KEY_LEN) {
120
+ CLIENT_ERR("invalid encryption key length");
121
+ return false;
122
+ }
123
+
124
+ BSON_ASSERT(args.iv);
125
+ if (args.iv->len != MONGOCRYPT_IV_LEN) {
126
+ CLIENT_ERR("invalid iv length");
127
+ return false;
128
+ }
129
+
130
+ if (crypto->hooks_enabled) {
131
+ mongocrypt_binary_t enc_key_bin, iv_bin, out_bin, in_bin;
132
+ bool ret;
133
+
134
+ _mongocrypt_buffer_to_binary(args.key, &enc_key_bin);
135
+ _mongocrypt_buffer_to_binary(args.iv, &iv_bin);
136
+ _mongocrypt_buffer_to_binary(args.out, &out_bin);
137
+ _mongocrypt_buffer_to_binary(args.in, &in_bin);
138
+
139
+ ret = crypto->aes_256_cbc_encrypt(crypto->ctx,
140
+ &enc_key_bin,
141
+ &iv_bin,
142
+ &in_bin,
143
+ &out_bin,
144
+ args.bytes_written,
145
+ status);
146
+ return ret;
147
+ }
148
+ return _native_crypto_aes_256_cbc_encrypt(args);
152
149
  }
153
150
 
154
- static bool
155
- _crypto_aes_256_ctr_encrypt (_mongocrypt_crypto_t *crypto, aes_256_args_t args)
156
- {
157
- mongocrypt_status_t *status = args.status;
158
-
159
- BSON_ASSERT_PARAM (crypto);
160
-
161
- BSON_ASSERT (args.key);
162
- if (args.key->len != MONGOCRYPT_ENC_KEY_LEN) {
163
- CLIENT_ERR ("invalid encryption key length");
164
- return false;
165
- }
166
-
167
- BSON_ASSERT (args.iv);
168
- if (args.iv->len != MONGOCRYPT_IV_LEN) {
169
- CLIENT_ERR ("invalid iv length");
170
- return false;
171
- }
172
-
173
- if (crypto->aes_256_ctr_encrypt) {
174
- mongocrypt_binary_t enc_key_bin, iv_bin, out_bin, in_bin;
175
- bool ret;
176
-
177
- _mongocrypt_buffer_to_binary (args.key, &enc_key_bin);
178
- _mongocrypt_buffer_to_binary (args.iv, &iv_bin);
179
- _mongocrypt_buffer_to_binary (args.out, &out_bin);
180
- _mongocrypt_buffer_to_binary (args.in, &in_bin);
181
-
182
- ret = crypto->aes_256_ctr_encrypt (crypto->ctx,
183
- &enc_key_bin,
184
- &iv_bin,
185
- &in_bin,
186
- &out_bin,
187
- args.bytes_written,
188
- status);
189
- return ret;
190
- }
191
-
192
- if (crypto->aes_256_ecb_encrypt) {
193
- return _crypto_aes_256_ctr_encrypt_decrypt_via_ecb (
194
- crypto->ctx, crypto->aes_256_ecb_encrypt, args, status);
195
- }
196
-
197
- return _native_crypto_aes_256_ctr_encrypt (args);
151
+ static bool _crypto_aes_256_ctr_encrypt(_mongocrypt_crypto_t *crypto, aes_256_args_t args) {
152
+ mongocrypt_status_t *status = args.status;
153
+
154
+ BSON_ASSERT_PARAM(crypto);
155
+
156
+ BSON_ASSERT(args.key);
157
+ if (args.key->len != MONGOCRYPT_ENC_KEY_LEN) {
158
+ CLIENT_ERR("invalid encryption key length");
159
+ return false;
160
+ }
161
+
162
+ BSON_ASSERT(args.iv);
163
+ if (args.iv->len != MONGOCRYPT_IV_LEN) {
164
+ CLIENT_ERR("invalid iv length");
165
+ return false;
166
+ }
167
+
168
+ if (crypto->aes_256_ctr_encrypt) {
169
+ mongocrypt_binary_t enc_key_bin, iv_bin, out_bin, in_bin;
170
+ bool ret;
171
+
172
+ _mongocrypt_buffer_to_binary(args.key, &enc_key_bin);
173
+ _mongocrypt_buffer_to_binary(args.iv, &iv_bin);
174
+ _mongocrypt_buffer_to_binary(args.out, &out_bin);
175
+ _mongocrypt_buffer_to_binary(args.in, &in_bin);
176
+
177
+ ret = crypto->aes_256_ctr_encrypt(crypto->ctx,
178
+ &enc_key_bin,
179
+ &iv_bin,
180
+ &in_bin,
181
+ &out_bin,
182
+ args.bytes_written,
183
+ status);
184
+ return ret;
185
+ }
186
+
187
+ if (crypto->aes_256_ecb_encrypt) {
188
+ return _crypto_aes_256_ctr_encrypt_decrypt_via_ecb(crypto->ctx, crypto->aes_256_ecb_encrypt, args, status);
189
+ }
190
+
191
+ return _native_crypto_aes_256_ctr_encrypt(args);
198
192
  }
199
193
 
200
- static bool
201
- _crypto_aes_256_cbc_decrypt (_mongocrypt_crypto_t *crypto, aes_256_args_t args)
202
- {
203
- mongocrypt_status_t *status = args.status;
204
-
205
- BSON_ASSERT_PARAM (crypto);
206
-
207
- BSON_ASSERT (args.key);
208
- if (args.key->len != MONGOCRYPT_ENC_KEY_LEN) {
209
- CLIENT_ERR ("invalid encryption key length");
210
- return false;
211
- }
212
-
213
- if (crypto->hooks_enabled) {
214
- mongocrypt_binary_t enc_key_bin, iv_bin, out_bin, in_bin;
215
- bool ret;
216
-
217
- _mongocrypt_buffer_to_binary (args.key, &enc_key_bin);
218
- _mongocrypt_buffer_to_binary (args.iv, &iv_bin);
219
- _mongocrypt_buffer_to_binary (args.out, &out_bin);
220
- _mongocrypt_buffer_to_binary (args.in, &in_bin);
221
-
222
- ret = crypto->aes_256_cbc_decrypt (crypto->ctx,
223
- &enc_key_bin,
224
- &iv_bin,
225
- &in_bin,
226
- &out_bin,
227
- args.bytes_written,
228
- status);
229
- return ret;
230
- }
231
- return _native_crypto_aes_256_cbc_decrypt (args);
194
+ static bool _crypto_aes_256_cbc_decrypt(_mongocrypt_crypto_t *crypto, aes_256_args_t args) {
195
+ mongocrypt_status_t *status = args.status;
196
+
197
+ BSON_ASSERT_PARAM(crypto);
198
+
199
+ BSON_ASSERT(args.key);
200
+ if (args.key->len != MONGOCRYPT_ENC_KEY_LEN) {
201
+ CLIENT_ERR("invalid encryption key length");
202
+ return false;
203
+ }
204
+
205
+ if (crypto->hooks_enabled) {
206
+ mongocrypt_binary_t enc_key_bin, iv_bin, out_bin, in_bin;
207
+ bool ret;
208
+
209
+ _mongocrypt_buffer_to_binary(args.key, &enc_key_bin);
210
+ _mongocrypt_buffer_to_binary(args.iv, &iv_bin);
211
+ _mongocrypt_buffer_to_binary(args.out, &out_bin);
212
+ _mongocrypt_buffer_to_binary(args.in, &in_bin);
213
+
214
+ ret = crypto->aes_256_cbc_decrypt(crypto->ctx,
215
+ &enc_key_bin,
216
+ &iv_bin,
217
+ &in_bin,
218
+ &out_bin,
219
+ args.bytes_written,
220
+ status);
221
+ return ret;
222
+ }
223
+ return _native_crypto_aes_256_cbc_decrypt(args);
232
224
  }
233
225
 
234
- static bool
235
- _crypto_aes_256_ctr_decrypt (_mongocrypt_crypto_t *crypto, aes_256_args_t args)
236
- {
237
- mongocrypt_status_t *status = args.status;
238
-
239
- BSON_ASSERT_PARAM (crypto);
240
-
241
- BSON_ASSERT (args.key);
242
- if (args.key->len != MONGOCRYPT_ENC_KEY_LEN) {
243
- CLIENT_ERR ("invalid encryption key length");
244
- return false;
245
- }
246
-
247
- if (crypto->aes_256_ctr_decrypt) {
248
- mongocrypt_binary_t enc_key_bin, iv_bin, out_bin, in_bin;
249
- bool ret;
250
-
251
- _mongocrypt_buffer_to_binary (args.key, &enc_key_bin);
252
- _mongocrypt_buffer_to_binary (args.iv, &iv_bin);
253
- _mongocrypt_buffer_to_binary (args.out, &out_bin);
254
- _mongocrypt_buffer_to_binary (args.in, &in_bin);
255
-
256
- ret = crypto->aes_256_ctr_decrypt (crypto->ctx,
257
- &enc_key_bin,
258
- &iv_bin,
259
- &in_bin,
260
- &out_bin,
261
- args.bytes_written,
262
- status);
263
- return ret;
264
- }
265
-
266
- if (crypto->aes_256_ecb_encrypt) {
267
- return _crypto_aes_256_ctr_encrypt_decrypt_via_ecb (
268
- crypto->ctx, crypto->aes_256_ecb_encrypt, args, status);
269
- }
270
-
271
- return _native_crypto_aes_256_ctr_decrypt (args);
226
+ static bool _crypto_aes_256_ctr_decrypt(_mongocrypt_crypto_t *crypto, aes_256_args_t args) {
227
+ mongocrypt_status_t *status = args.status;
228
+
229
+ BSON_ASSERT_PARAM(crypto);
230
+
231
+ BSON_ASSERT(args.key);
232
+ if (args.key->len != MONGOCRYPT_ENC_KEY_LEN) {
233
+ CLIENT_ERR("invalid encryption key length");
234
+ return false;
235
+ }
236
+
237
+ if (crypto->aes_256_ctr_decrypt) {
238
+ mongocrypt_binary_t enc_key_bin, iv_bin, out_bin, in_bin;
239
+ bool ret;
240
+
241
+ _mongocrypt_buffer_to_binary(args.key, &enc_key_bin);
242
+ _mongocrypt_buffer_to_binary(args.iv, &iv_bin);
243
+ _mongocrypt_buffer_to_binary(args.out, &out_bin);
244
+ _mongocrypt_buffer_to_binary(args.in, &in_bin);
245
+
246
+ ret = crypto->aes_256_ctr_decrypt(crypto->ctx,
247
+ &enc_key_bin,
248
+ &iv_bin,
249
+ &in_bin,
250
+ &out_bin,
251
+ args.bytes_written,
252
+ status);
253
+ return ret;
254
+ }
255
+
256
+ if (crypto->aes_256_ecb_encrypt) {
257
+ return _crypto_aes_256_ctr_encrypt_decrypt_via_ecb(crypto->ctx, crypto->aes_256_ecb_encrypt, args, status);
258
+ }
259
+
260
+ return _native_crypto_aes_256_ctr_decrypt(args);
272
261
  }
273
262
 
274
- static bool
275
- _crypto_hmac_sha_512 (_mongocrypt_crypto_t *crypto,
276
- const _mongocrypt_buffer_t *hmac_key,
277
- const _mongocrypt_buffer_t *in,
278
- _mongocrypt_buffer_t *out,
279
- mongocrypt_status_t *status)
280
- {
281
- BSON_ASSERT_PARAM (crypto);
282
- BSON_ASSERT_PARAM (hmac_key);
283
- BSON_ASSERT_PARAM (in);
284
- BSON_ASSERT_PARAM (out);
285
-
286
- if (hmac_key->len != MONGOCRYPT_MAC_KEY_LEN) {
287
- CLIENT_ERR ("invalid hmac key length");
288
- return false;
289
- }
290
-
291
- if (out->len != MONGOCRYPT_HMAC_SHA512_LEN) {
292
- CLIENT_ERR ("out does not contain %d bytes", MONGOCRYPT_HMAC_SHA512_LEN);
293
- return false;
294
- }
295
-
296
- if (crypto->hooks_enabled) {
297
- mongocrypt_binary_t hmac_key_bin, out_bin, in_bin;
298
- bool ret;
299
-
300
- _mongocrypt_buffer_to_binary (hmac_key, &hmac_key_bin);
301
- _mongocrypt_buffer_to_binary (out, &out_bin);
302
- _mongocrypt_buffer_to_binary (in, &in_bin);
303
-
304
- ret = crypto->hmac_sha_512 (
305
- crypto->ctx, &hmac_key_bin, &in_bin, &out_bin, status);
306
- return ret;
307
- }
308
- return _native_crypto_hmac_sha_512 (hmac_key, in, out, status);
263
+ static bool _crypto_hmac_sha_512(_mongocrypt_crypto_t *crypto,
264
+ const _mongocrypt_buffer_t *hmac_key,
265
+ const _mongocrypt_buffer_t *in,
266
+ _mongocrypt_buffer_t *out,
267
+ mongocrypt_status_t *status) {
268
+ BSON_ASSERT_PARAM(crypto);
269
+ BSON_ASSERT_PARAM(hmac_key);
270
+ BSON_ASSERT_PARAM(in);
271
+ BSON_ASSERT_PARAM(out);
272
+
273
+ if (hmac_key->len != MONGOCRYPT_MAC_KEY_LEN) {
274
+ CLIENT_ERR("invalid hmac key length");
275
+ return false;
276
+ }
277
+
278
+ if (out->len != MONGOCRYPT_HMAC_SHA512_LEN) {
279
+ CLIENT_ERR("out does not contain %d bytes", MONGOCRYPT_HMAC_SHA512_LEN);
280
+ return false;
281
+ }
282
+
283
+ if (crypto->hooks_enabled) {
284
+ mongocrypt_binary_t hmac_key_bin, out_bin, in_bin;
285
+ bool ret;
286
+
287
+ _mongocrypt_buffer_to_binary(hmac_key, &hmac_key_bin);
288
+ _mongocrypt_buffer_to_binary(out, &out_bin);
289
+ _mongocrypt_buffer_to_binary(in, &in_bin);
290
+
291
+ ret = crypto->hmac_sha_512(crypto->ctx, &hmac_key_bin, &in_bin, &out_bin, status);
292
+ return ret;
293
+ }
294
+ return _native_crypto_hmac_sha_512(hmac_key, in, out, status);
309
295
  }
310
296
 
297
+ bool _mongocrypt_hmac_sha_256(_mongocrypt_crypto_t *crypto,
298
+ const _mongocrypt_buffer_t *key,
299
+ const _mongocrypt_buffer_t *in,
300
+ _mongocrypt_buffer_t *out,
301
+ mongocrypt_status_t *status) {
302
+ BSON_ASSERT_PARAM(crypto);
303
+ BSON_ASSERT_PARAM(key);
304
+ BSON_ASSERT_PARAM(in);
305
+ BSON_ASSERT_PARAM(out);
306
+
307
+ if (key->len != MONGOCRYPT_MAC_KEY_LEN) {
308
+ CLIENT_ERR("invalid hmac_sha_256 key length. Got %" PRIu32 ", expected: %" PRIu32,
309
+ key->len,
310
+ MONGOCRYPT_MAC_KEY_LEN);
311
+ return false;
312
+ }
313
+
314
+ if (crypto->hooks_enabled) {
315
+ mongocrypt_binary_t key_bin, out_bin, in_bin;
316
+ _mongocrypt_buffer_to_binary(key, &key_bin);
317
+ _mongocrypt_buffer_to_binary(out, &out_bin);
318
+ _mongocrypt_buffer_to_binary(in, &in_bin);
319
+
320
+ return crypto->hmac_sha_256(crypto->ctx, &key_bin, &in_bin, &out_bin, status);
321
+ }
322
+ return _native_crypto_hmac_sha_256(key, in, out, status);
323
+ }
311
324
 
312
325
  static bool
313
- _crypto_random (_mongocrypt_crypto_t *crypto,
314
- _mongocrypt_buffer_t *out,
315
- uint32_t count,
316
- mongocrypt_status_t *status)
317
- {
318
- BSON_ASSERT_PARAM (crypto);
319
- BSON_ASSERT_PARAM (out);
320
-
321
- if (out->len != count) {
322
- CLIENT_ERR ("out does not contain %u bytes", count);
323
- return false;
324
- }
325
-
326
- if (crypto->hooks_enabled) {
327
- mongocrypt_binary_t out_bin;
328
-
329
- _mongocrypt_buffer_to_binary (out, &out_bin);
330
- return crypto->random (crypto->ctx, &out_bin, count, status);
331
- }
332
- return _native_crypto_random (out, count, status);
326
+ _crypto_random(_mongocrypt_crypto_t *crypto, _mongocrypt_buffer_t *out, uint32_t count, mongocrypt_status_t *status) {
327
+ BSON_ASSERT_PARAM(crypto);
328
+ BSON_ASSERT_PARAM(out);
329
+
330
+ if (out->len != count) {
331
+ CLIENT_ERR("out does not contain %u bytes", count);
332
+ return false;
333
+ }
334
+
335
+ if (crypto->hooks_enabled) {
336
+ mongocrypt_binary_t out_bin;
337
+
338
+ _mongocrypt_buffer_to_binary(out, &out_bin);
339
+ return crypto->random(crypto->ctx, &out_bin, count, status);
340
+ }
341
+ return _native_crypto_random(out, count, status);
333
342
  }
334
343
 
335
-
336
344
  /*
337
345
  * Secure memcmp copied from the C driver.
338
346
  */
339
- int
340
- _mongocrypt_memequal (const void *const b1, const void *const b2, size_t len)
341
- {
342
- const unsigned char *p1 = b1, *p2 = b2;
343
- int ret = 0;
347
+ int _mongocrypt_memequal(const void *const b1, const void *const b2, size_t len) {
348
+ const unsigned char *p1 = b1, *p2 = b2;
349
+ int ret = 0;
344
350
 
345
- BSON_ASSERT_PARAM (b1);
346
- BSON_ASSERT_PARAM (b2);
351
+ BSON_ASSERT_PARAM(b1);
352
+ BSON_ASSERT_PARAM(b2);
347
353
 
348
- for (; len > 0; len--) {
349
- ret |= *p1++ ^ *p2++;
350
- }
354
+ for (; len > 0; len--) {
355
+ ret |= *p1++ ^ *p2++;
356
+ }
351
357
 
352
- return ret;
358
+ return ret;
353
359
  }
354
360
 
361
+ typedef enum {
362
+ MODE_CBC,
363
+ MODE_CTR,
364
+ } _mongocrypt_encryption_mode_t;
365
+
366
+ typedef enum {
367
+ HMAC_NONE,
368
+ HMAC_SHA_512_256, // sha512 truncated to 256 bits
369
+ HMAC_SHA_256,
370
+ } _mongocrypt_hmac_type_t;
371
+
372
+ typedef enum {
373
+ KEY_FORMAT_FLE1, // 32 octets MAC key, 32 DATA key, 32 IV key (ignored)
374
+ KEY_FORMAT_FLE2, // 32 octets DATA key
375
+ KEY_FORMAT_FLE2AEAD, // 32 octets DATA key, 32 MAC key, 32 IV key (ignored)
376
+ KEY_FORMAT_FLE2v2AEAD, // 32 octets DATA key, 32 MAC key, 32 IV key (ignored)
377
+ } _mongocrypt_key_format_t;
378
+
379
+ typedef enum {
380
+ MAC_FORMAT_FLE1, // HMAC(AAD || IV || S || LEN(AAD) as uint64be)
381
+ MAC_FORMAT_FLE2, // NONE
382
+ MAC_FORMAT_FLE2AEAD, // HMAC(AAD || IV || S)
383
+ MAC_FORMAT_FLE2v2AEAD, // HMAC(AAD || IV || S)
384
+ } _mongocrypt_mac_format_t;
385
+
355
386
  /* ----------------------------------------------------------------------------
356
387
  *
357
- * _mongocrypt_calculate_ciphertext_len --
388
+ * _mongocrypt_calculate_ciphertext_len
358
389
  *
359
- * For a given plaintext length, return the length of the ciphertext.
360
- * This includes IV and HMAC.
390
+ * Calculate the space needed for a ciphertext payload of a given size
391
+ * and using fixed iv/hmac lengths.
361
392
  *
362
- * To compute that I'm following section 2.3 in [MCGREW]:
363
- * L = 16 * ( floor(M / 16) + 2)
364
- * This formula includes space for the IV, but not the sha512 HMAC.
365
- * Add 32 for the sha512 HMAC.
393
+ * MODE_CBC: Assumes the ciphertext will be padded according to PKCS#7
394
+ * which rounds up to the next block size, adding up to a complete block
395
+ * for block aligned input payloads.
366
396
  *
367
- * Parameters:
368
- * @plaintext_len then length of the plaintext.
369
- * @status set on error.
397
+ * MODE_CTR: Assumes no additional padding since CTR is a streaming cipher.
370
398
  *
371
- * Returns:
372
- * The calculated length of the ciphertext.
399
+ * Assumes all algorithms use identical IV length and blocksizes.
373
400
  *
374
401
  * ----------------------------------------------------------------------------
375
402
  */
376
- uint32_t
377
- _mongocrypt_calculate_ciphertext_len (uint32_t plaintext_len,
378
- mongocrypt_status_t *status)
379
- {
380
- if ((plaintext_len / 16u) >
381
- ((UINT32_MAX - (uint32_t) MONGOCRYPT_HMAC_LEN) / 16u) - 2u) {
382
- CLIENT_ERR ("plaintext too long");
383
- return 0;
384
- }
385
- return 16 * ((plaintext_len / 16) + 2) + MONGOCRYPT_HMAC_LEN;
386
- }
387
-
388
- uint32_t
389
- _mongocrypt_fle2aead_calculate_ciphertext_len (uint32_t plaintext_len,
390
- mongocrypt_status_t *status)
391
- {
392
- if (plaintext_len > UINT32_MAX - MONGOCRYPT_IV_LEN - MONGOCRYPT_HMAC_LEN) {
393
- CLIENT_ERR ("plaintext too long");
394
- return 0;
395
- }
396
- /* FLE2 AEAD uses CTR mode. CTR mode does not pad. */
397
- return MONGOCRYPT_IV_LEN + plaintext_len + MONGOCRYPT_HMAC_LEN;
398
- }
399
-
400
- uint32_t
401
- _mongocrypt_fle2_calculate_ciphertext_len (uint32_t plaintext_len,
402
- mongocrypt_status_t *status)
403
- {
404
- if (plaintext_len > UINT32_MAX - MONGOCRYPT_IV_LEN) {
405
- CLIENT_ERR ("plaintext too long");
406
- return 0;
407
- }
408
- /* FLE2 AEAD uses CTR mode. CTR mode does not pad. */
409
- return MONGOCRYPT_IV_LEN + plaintext_len;
403
+ static uint32_t _mongocrypt_calculate_ciphertext_len(uint32_t inlen,
404
+ _mongocrypt_encryption_mode_t mode,
405
+ _mongocrypt_hmac_type_t hmac,
406
+ mongocrypt_status_t *status) {
407
+ const uint32_t hmaclen = (hmac == HMAC_NONE) ? 0 : MONGOCRYPT_HMAC_LEN;
408
+ const uint32_t maxinlen = UINT32_MAX - (MONGOCRYPT_IV_LEN + MONGOCRYPT_BLOCK_SIZE + hmaclen);
409
+ uint32_t fill;
410
+ if (inlen > maxinlen) {
411
+ CLIENT_ERR("plaintext too long");
412
+ return 0;
413
+ }
414
+
415
+ if (mode == MODE_CBC) {
416
+ fill = MONGOCRYPT_BLOCK_SIZE - (inlen % MONGOCRYPT_BLOCK_SIZE);
417
+ } else {
418
+ BSON_ASSERT(mode == MODE_CTR);
419
+ fill = 0;
420
+ }
421
+
422
+ return MONGOCRYPT_IV_LEN + inlen + fill + hmaclen;
410
423
  }
411
424
 
412
-
413
425
  /* ----------------------------------------------------------------------------
414
426
  *
415
- * _mongocrypt_calculate_plaintext_len --
427
+ * _mongocrypt_calculate_plaintext_len
416
428
  *
417
- * For a given ciphertext length, return the length of the plaintext.
418
- * This excludes the IV and HMAC, but includes the padding.
429
+ * Calculate the space needed for a plaintext payload of a given size
430
+ * and using fixed iv/hmac lengths.
419
431
  *
420
- * Parameters:
421
- * @ciphertext_len then length of the ciphertext.
422
- * @status set on error.
432
+ * MODE_CBC: In practice, plaintext will be between 1 and {blocksize} bytes
433
+ * shorter
434
+ * than the input ciphertext, but it's easier and safer to assume the
435
+ * full ciphertext length and waste a few bytes.
423
436
  *
424
- * Returns:
425
- * The calculated length of the plaintext.
437
+ * MODE_CTR: Assumes no additional padding since CTR is a streaming cipher.
438
+ *
439
+ * Assumes all algorithms use identical IV length and blocksizes.
426
440
  *
427
441
  * ----------------------------------------------------------------------------
428
442
  */
429
- uint32_t
430
- _mongocrypt_calculate_plaintext_len (uint32_t ciphertext_len,
431
- mongocrypt_status_t *status)
432
- {
433
- if (ciphertext_len <
434
- MONGOCRYPT_HMAC_LEN + MONGOCRYPT_IV_LEN + MONGOCRYPT_BLOCK_SIZE) {
435
- CLIENT_ERR ("ciphertext too short");
436
- return 0;
437
- }
438
- return ciphertext_len - (MONGOCRYPT_IV_LEN + MONGOCRYPT_HMAC_LEN);
439
- }
440
-
441
- uint32_t
442
- _mongocrypt_fle2aead_calculate_plaintext_len (uint32_t ciphertext_len,
443
- mongocrypt_status_t *status)
444
- {
445
- /* FLE2 AEAD uses CTR mode. CTR mode does not pad. */
446
- if (ciphertext_len < MONGOCRYPT_IV_LEN + MONGOCRYPT_HMAC_LEN) {
447
- CLIENT_ERR ("ciphertext too short");
448
- return 0;
449
- }
450
- return ciphertext_len - MONGOCRYPT_IV_LEN - MONGOCRYPT_HMAC_LEN;
451
- }
452
-
453
- uint32_t
454
- _mongocrypt_fle2_calculate_plaintext_len (uint32_t ciphertext_len,
455
- mongocrypt_status_t *status)
456
- {
457
- /* FLE2 AEAD uses CTR mode. CTR mode does not pad. */
458
- if (ciphertext_len < MONGOCRYPT_IV_LEN) {
459
- CLIENT_ERR ("ciphertext too short");
460
- return 0;
461
- }
462
- return ciphertext_len - MONGOCRYPT_IV_LEN;
443
+ static uint32_t _mongocrypt_calculate_plaintext_len(uint32_t inlen,
444
+ _mongocrypt_encryption_mode_t mode,
445
+ _mongocrypt_hmac_type_t hmac,
446
+ mongocrypt_status_t *status) {
447
+ const uint32_t hmaclen = (hmac == HMAC_NONE) ? 0 : MONGOCRYPT_HMAC_LEN;
448
+ const uint32_t mincipher = (mode == MODE_CTR) ? 0 : MONGOCRYPT_BLOCK_SIZE;
449
+ if (inlen < (MONGOCRYPT_IV_LEN + mincipher + hmaclen)) {
450
+ CLIENT_ERR("input ciphertext too small. Must be at least %" PRIu32 " bytes",
451
+ MONGOCRYPT_IV_LEN + mincipher + hmaclen);
452
+ return 0;
453
+ }
454
+ return inlen - (MONGOCRYPT_IV_LEN + hmaclen);
463
455
  }
464
456
 
465
457
  /* ----------------------------------------------------------------------------
@@ -487,129 +479,120 @@ _mongocrypt_fle2_calculate_plaintext_len (uint32_t ciphertext_len,
487
479
  * Postconditions:
488
480
  * 1. bytes_written is set to the length of the written ciphertext. This
489
481
  * is the same as
490
- * _mongocrypt_calculate_ciphertext_len (plaintext->len, status).
482
+ * _mongocrypt_calculate_ciphertext_len (plaintext->len, mode, hmac, status).
491
483
  *
492
484
  * ----------------------------------------------------------------------------
493
485
  */
494
- static bool
495
- _encrypt_step (_mongocrypt_crypto_t *crypto,
496
- const _mongocrypt_buffer_t *iv,
497
- const _mongocrypt_buffer_t *enc_key,
498
- const _mongocrypt_buffer_t *plaintext,
499
- _mongocrypt_buffer_t *ciphertext,
500
- uint32_t *bytes_written,
501
- mongocrypt_status_t *status)
502
- {
503
- uint32_t unaligned;
504
- uint32_t padding_byte;
505
- _mongocrypt_buffer_t intermediates[2];
506
- _mongocrypt_buffer_t to_encrypt;
507
- uint8_t final_block_storage[MONGOCRYPT_BLOCK_SIZE];
508
- bool ret = false;
509
-
510
- BSON_ASSERT_PARAM (crypto);
511
- BSON_ASSERT_PARAM (iv);
512
- BSON_ASSERT_PARAM (enc_key);
513
- BSON_ASSERT_PARAM (plaintext);
514
- BSON_ASSERT_PARAM (ciphertext);
515
-
516
- _mongocrypt_buffer_init (&to_encrypt);
517
-
518
- BSON_ASSERT_PARAM (bytes_written);
519
- *bytes_written = 0;
520
-
521
- if (MONGOCRYPT_IV_LEN != iv->len) {
522
- CLIENT_ERR ("IV should have length %d, but has length %d",
523
- MONGOCRYPT_IV_LEN,
524
- iv->len);
525
- goto done;
526
- }
527
-
528
- if (MONGOCRYPT_ENC_KEY_LEN != enc_key->len) {
529
- CLIENT_ERR ("Encryption key should have length %d, but has length %d",
530
- MONGOCRYPT_ENC_KEY_LEN,
531
- enc_key->len);
532
- goto done;
533
- }
534
-
535
- /* calculate how many extra bytes there are after a block boundary */
536
- unaligned = plaintext->len % MONGOCRYPT_BLOCK_SIZE;
537
-
538
- /* Some crypto providers disallow variable length inputs, and require
539
- * the input to be a multiple of the block size. So add everything up
540
- * to but excluding the last block if not block aligned, then add
541
- * the last block with padding. */
542
- _mongocrypt_buffer_init (&intermediates[0]);
543
- _mongocrypt_buffer_init (&intermediates[1]);
544
- intermediates[0].data = (uint8_t *) plaintext->data;
545
- /* don't check plaintext->len, as the above modulo operation guarantees
546
- * that unaligned will be smaller */
547
- intermediates[0].len = plaintext->len - unaligned;
548
- intermediates[1].data = final_block_storage;
549
- intermediates[1].len = sizeof (final_block_storage);
550
-
551
- /* [MCGREW]: "Prior to CBC encryption, the plaintext P is padded by appending
552
- * a padding string PS to that data, to ensure that len(P || PS) is a
553
- * multiple of 128". This is also known as PKCS #7 padding. */
554
- if (unaligned) {
555
- /* Copy the unaligned bytes. */
556
- memcpy (intermediates[1].data,
557
- plaintext->data + (plaintext->len - unaligned),
558
- unaligned);
559
- /* Fill the rest with the padding byte. */
560
- BSON_ASSERT (MONGOCRYPT_BLOCK_SIZE >= unaligned);
561
- padding_byte = MONGOCRYPT_BLOCK_SIZE - unaligned;
562
- /* it is certain that padding_byte is in range for a cast to int */
563
- memset (
564
- intermediates[1].data + unaligned, (int) padding_byte, padding_byte);
565
- } else {
566
- /* Fill the rest with the padding byte. */
567
- padding_byte = MONGOCRYPT_BLOCK_SIZE;
568
- memset (intermediates[1].data, (int) padding_byte, padding_byte);
569
- }
570
-
571
- if (!_mongocrypt_buffer_concat (&to_encrypt, intermediates, 2)) {
572
- CLIENT_ERR ("failed to allocate buffer");
573
- goto done;
574
- }
575
-
576
- if (!_crypto_aes_256_cbc_encrypt (
577
- crypto,
578
- (aes_256_args_t){.key = enc_key,
579
- .iv = iv,
580
- .in = &to_encrypt,
581
- .out = ciphertext,
582
- .bytes_written = bytes_written,
583
- .status = status})) {
584
- goto done;
585
- }
586
-
587
-
588
- if (*bytes_written % MONGOCRYPT_BLOCK_SIZE != 0) {
589
- CLIENT_ERR ("encryption failure, wrote %d bytes, not a multiple of %d",
590
- *bytes_written,
591
- MONGOCRYPT_BLOCK_SIZE);
592
- goto done;
593
- }
594
-
595
- ret = true;
596
- done:
597
- _mongocrypt_buffer_cleanup (&to_encrypt);
598
- return ret;
486
+ static bool _encrypt_step(_mongocrypt_crypto_t *crypto,
487
+ _mongocrypt_encryption_mode_t mode,
488
+ const _mongocrypt_buffer_t *iv,
489
+ const _mongocrypt_buffer_t *enc_key,
490
+ const _mongocrypt_buffer_t *plaintext,
491
+ _mongocrypt_buffer_t *ciphertext,
492
+ uint32_t *bytes_written,
493
+ mongocrypt_status_t *status) {
494
+ BSON_ASSERT_PARAM(crypto);
495
+ BSON_ASSERT_PARAM(iv);
496
+ BSON_ASSERT_PARAM(enc_key);
497
+ BSON_ASSERT_PARAM(plaintext);
498
+ BSON_ASSERT_PARAM(ciphertext);
499
+
500
+ BSON_ASSERT_PARAM(bytes_written);
501
+ *bytes_written = 0;
502
+
503
+ if (MONGOCRYPT_IV_LEN != iv->len) {
504
+ CLIENT_ERR("IV should have length %d, but has length %d", MONGOCRYPT_IV_LEN, iv->len);
505
+ return false;
506
+ }
507
+
508
+ if (MONGOCRYPT_ENC_KEY_LEN != enc_key->len) {
509
+ CLIENT_ERR("Encryption key should have length %d, but has length %d", MONGOCRYPT_ENC_KEY_LEN, enc_key->len);
510
+ return false;
511
+ }
512
+
513
+ if (mode == MODE_CTR) {
514
+ // Streaming cipher, no padding required.
515
+ return _crypto_aes_256_ctr_encrypt(crypto,
516
+ (aes_256_args_t){.key = enc_key,
517
+ .iv = iv,
518
+ .in = plaintext,
519
+ .out = ciphertext,
520
+ .bytes_written = bytes_written,
521
+ .status = status});
522
+ }
523
+
524
+ BSON_ASSERT(mode == MODE_CBC);
525
+
526
+ /* calculate how many extra bytes there are after a block boundary */
527
+ const uint32_t unaligned = plaintext->len % MONGOCRYPT_BLOCK_SIZE;
528
+ uint32_t padding_byte = MONGOCRYPT_BLOCK_SIZE - unaligned;
529
+ _mongocrypt_buffer_t intermediates[2], to_encrypt;
530
+ uint8_t final_block_storage[MONGOCRYPT_BLOCK_SIZE];
531
+ bool ret;
532
+
533
+ BSON_ASSERT(MONGOCRYPT_BLOCK_SIZE >= unaligned);
534
+
535
+ /* Some crypto providers disallow variable length inputs, and require
536
+ * the input to be a multiple of the block size. So add everything up
537
+ * to but excluding the last block if not block aligned, then add
538
+ * the last block with padding. */
539
+ _mongocrypt_buffer_init(&intermediates[0]);
540
+ _mongocrypt_buffer_init(&intermediates[1]);
541
+ intermediates[0].data = (uint8_t *)plaintext->data;
542
+ /* don't check plaintext->len, as the above modulo operation guarantees
543
+ * that unaligned will be smaller */
544
+ intermediates[0].len = plaintext->len - unaligned;
545
+ intermediates[1].data = final_block_storage;
546
+ intermediates[1].len = sizeof(final_block_storage);
547
+
548
+ /* [MCGREW]: "Prior to CBC encryption, the plaintext P is padded by appending
549
+ * a padding string PS to that data, to ensure that len(P || PS) is a
550
+ * multiple of 128". This is also known as PKCS #7 padding. */
551
+ if (unaligned) {
552
+ /* Copy the unaligned bytes. */
553
+ memcpy(intermediates[1].data, plaintext->data + (plaintext->len - unaligned), unaligned);
554
+ }
555
+ /* Fill out block remained or whole block with padding_byte */
556
+ memset(intermediates[1].data + unaligned, (int)padding_byte, padding_byte);
557
+
558
+ _mongocrypt_buffer_init(&to_encrypt);
559
+ if (!_mongocrypt_buffer_concat(&to_encrypt, intermediates, 2)) {
560
+ CLIENT_ERR("failed to allocate buffer");
561
+ _mongocrypt_buffer_cleanup(&to_encrypt);
562
+ return false;
563
+ }
564
+
565
+ ret = _crypto_aes_256_cbc_encrypt(crypto,
566
+ (aes_256_args_t){.key = enc_key,
567
+ .iv = iv,
568
+ .in = &to_encrypt,
569
+ .out = ciphertext,
570
+ .bytes_written = bytes_written,
571
+ .status = status});
572
+ _mongocrypt_buffer_cleanup(&to_encrypt);
573
+ if (!ret) {
574
+ return false;
575
+ }
576
+
577
+ if (*bytes_written % MONGOCRYPT_BLOCK_SIZE != 0) {
578
+ CLIENT_ERR("encryption failure, wrote %d bytes, not a multiple of %d", *bytes_written, MONGOCRYPT_BLOCK_SIZE);
579
+ return false;
580
+ }
581
+
582
+ return true;
599
583
  }
600
584
 
601
-
602
585
  /* ----------------------------------------------------------------------------
603
586
  *
604
- * _hmac_sha512 --
587
+ * _hmac_step --
605
588
  *
606
- * Compute the SHA512 HMAC with a secret key.
589
+ * Compute the selected HMAC with a secret key.
607
590
  *
608
591
  * Parameters:
609
- * @mac_key a 32 byte key.
610
- * @associated_data associated data to add into the HMAC. This may be
592
+ * @Km a 32 byte key.
593
+ * @AAD associated data to add into the HMAC. This may be
611
594
  * an empty buffer.
612
- * @ciphertext the ciphertext to add into the HMAC.
595
+ * @iv_and_ciphertext the IV and S components to add into the HMAC.
613
596
  * @out a location for the resulting HMAC tag.
614
597
  * @status set on error.
615
598
  *
@@ -624,84 +607,99 @@ done:
624
607
  *
625
608
  * ----------------------------------------------------------------------------
626
609
  */
627
- static bool
628
- _hmac_step (_mongocrypt_crypto_t *crypto,
629
- const _mongocrypt_buffer_t *mac_key,
630
- const _mongocrypt_buffer_t *associated_data,
631
- const _mongocrypt_buffer_t *ciphertext,
632
- _mongocrypt_buffer_t *out,
633
- mongocrypt_status_t *status)
634
- {
635
- _mongocrypt_buffer_t intermediates[3];
636
- _mongocrypt_buffer_t to_hmac;
637
- uint64_t associated_data_len_be;
638
- uint8_t tag_storage[64];
639
- _mongocrypt_buffer_t tag;
640
- bool ret = false;
641
-
642
- BSON_ASSERT_PARAM (crypto);
643
- BSON_ASSERT_PARAM (mac_key);
644
- BSON_ASSERT_PARAM (associated_data);
645
- BSON_ASSERT_PARAM (ciphertext);
646
- BSON_ASSERT_PARAM (out);
647
-
648
- _mongocrypt_buffer_init (&to_hmac);
649
-
650
- if (MONGOCRYPT_MAC_KEY_LEN != mac_key->len) {
651
- CLIENT_ERR ("HMAC key wrong length: %d", mac_key->len);
652
- goto done;
653
- }
654
-
655
- if (out->len != MONGOCRYPT_HMAC_LEN) {
656
- CLIENT_ERR ("out wrong length: %d", out->len);
657
- goto done;
658
- }
659
-
660
- /* [MCGREW]:
661
- * """
662
- * 4. The octet string AL is equal to the number of bits in A expressed as a
663
- * 64-bit unsigned integer in network byte order.
664
- * 5. A message authentication tag T is computed by applying HMAC [RFC2104]
665
- * to the following data, in order:
666
- * the associated data A,
667
- * the ciphertext S computed in the previous step, and
668
- * the octet string AL defined above.
669
- * """
670
- */
671
-
672
- /* Add associated data. */
673
- _mongocrypt_buffer_init (&intermediates[0]);
674
- _mongocrypt_buffer_init (&intermediates[1]);
675
- _mongocrypt_buffer_init (&intermediates[2]);
676
- intermediates[0].data = associated_data->data;
677
- intermediates[0].len = associated_data->len;
678
- /* Add ciphertext. */
679
- intermediates[1].data = ciphertext->data;
680
- intermediates[1].len = ciphertext->len;
681
- /* Add associated data length in bits. */
682
- /* multiplying a uint32_t by 8 won't bring it anywhere close to UINT64_MAX */
683
- associated_data_len_be = 8 * (uint64_t) associated_data->len;
684
- associated_data_len_be = BSON_UINT64_TO_BE (associated_data_len_be);
685
- intermediates[2].data = (uint8_t *) &associated_data_len_be;
686
- intermediates[2].len = sizeof (uint64_t);
687
- tag.data = tag_storage;
688
- tag.len = sizeof (tag_storage);
689
-
690
-
691
- if (!_mongocrypt_buffer_concat (&to_hmac, intermediates, 3)) {
692
- CLIENT_ERR ("failed to allocate buffer");
693
- goto done;
694
- }
695
- if (!_crypto_hmac_sha_512 (crypto, mac_key, &to_hmac, &tag, status)) {
696
- goto done;
697
- }
698
-
699
- /* [MCGREW 2.7] "The HMAC-SHA-512 value is truncated to T_LEN=32 octets" */
700
- memcpy (out->data, tag.data, MONGOCRYPT_HMAC_LEN);
701
- ret = true;
610
+ static bool _hmac_step(_mongocrypt_crypto_t *crypto,
611
+ _mongocrypt_mac_format_t mac_format,
612
+ _mongocrypt_hmac_type_t hmac,
613
+ const _mongocrypt_buffer_t *Km,
614
+ const _mongocrypt_buffer_t *AAD,
615
+ const _mongocrypt_buffer_t *iv_and_ciphertext,
616
+ _mongocrypt_buffer_t *out,
617
+ mongocrypt_status_t *status) {
618
+ _mongocrypt_buffer_t to_hmac = {0};
619
+ bool ret = false;
620
+
621
+ BSON_ASSERT(hmac != HMAC_NONE);
622
+ BSON_ASSERT_PARAM(crypto);
623
+ BSON_ASSERT_PARAM(Km);
624
+ // AAD may be NULL
625
+ BSON_ASSERT_PARAM(iv_and_ciphertext);
626
+ BSON_ASSERT_PARAM(out);
627
+
628
+ _mongocrypt_buffer_init(&to_hmac);
629
+
630
+ if (MONGOCRYPT_MAC_KEY_LEN != Km->len) {
631
+ CLIENT_ERR("HMAC key wrong length: %d", Km->len);
632
+ goto done;
633
+ }
634
+
635
+ if (out->len != MONGOCRYPT_HMAC_LEN) {
636
+ CLIENT_ERR("out wrong length: %d", out->len);
637
+ goto done;
638
+ }
639
+
640
+ /* Construct the input to the HMAC */
641
+ uint32_t num_intermediates = 0;
642
+ _mongocrypt_buffer_t intermediates[3];
643
+ if (AAD && !_mongocrypt_buffer_from_subrange(&intermediates[num_intermediates++], AAD, 0, AAD->len)) {
644
+ CLIENT_ERR("Failed creating MAC subrange on AD");
645
+ goto done;
646
+ }
647
+ if (!_mongocrypt_buffer_from_subrange(&intermediates[num_intermediates++],
648
+ iv_and_ciphertext,
649
+ 0,
650
+ iv_and_ciphertext->len)) {
651
+ CLIENT_ERR("Failed creating MAC subrange on IV and S");
652
+ goto done;
653
+ }
654
+
655
+ // {AL} must be stored in the function's lexical scope so that
656
+ // {intermediates}'s reference to it survives until the
657
+ // _mongocrypt_buffer_concat operation later.
658
+ uint64_t AL;
659
+ if (mac_format == MAC_FORMAT_FLE1) {
660
+ /* T := HMAC(AAD || IV || S || AL)
661
+ * AL is equal to the number of bits in AAD expressed
662
+ * as a 64bit unsigned big-endian integer.
663
+ * Multiplying a uint32_t by 8 won't bring it anywhere close to
664
+ * UINT64_MAX.
665
+ */
666
+ AL = AAD ? BSON_UINT64_TO_BE(8 * (uint64_t)AAD->len) : 0;
667
+ _mongocrypt_buffer_init(&intermediates[num_intermediates]);
668
+ intermediates[num_intermediates].data = (uint8_t *)&AL;
669
+ intermediates[num_intermediates++].len = sizeof(uint64_t);
670
+
671
+ } else {
672
+ /* T := HMAC(AAD || IV || S) */
673
+ BSON_ASSERT((mac_format == MAC_FORMAT_FLE2AEAD) || (mac_format == MAC_FORMAT_FLE2v2AEAD));
674
+ }
675
+
676
+ if (!_mongocrypt_buffer_concat(&to_hmac, intermediates, num_intermediates)) {
677
+ CLIENT_ERR("failed to allocate buffer");
678
+ goto done;
679
+ }
680
+
681
+ if (hmac == HMAC_SHA_512_256) {
682
+ uint8_t storage[64];
683
+ _mongocrypt_buffer_t tag = {.data = storage, .len = sizeof(storage)};
684
+
685
+ if (!_crypto_hmac_sha_512(crypto, Km, &to_hmac, &tag, status)) {
686
+ goto done;
687
+ }
688
+
689
+ // Truncate sha512 to first 256 bits.
690
+ memcpy(out->data, tag.data, MONGOCRYPT_HMAC_LEN);
691
+
692
+ } else {
693
+ BSON_ASSERT(hmac == HMAC_SHA_256);
694
+ if (!_mongocrypt_hmac_sha_256(crypto, Km, &to_hmac, out, status)) {
695
+ goto done;
696
+ }
697
+ }
698
+
699
+ ret = true;
702
700
  done:
703
- _mongocrypt_buffer_cleanup (&to_hmac);
704
- return ret;
701
+ _mongocrypt_buffer_cleanup(&to_hmac);
702
+ return ret;
705
703
  }
706
704
 
707
705
  /* ----------------------------------------------------------------------------
@@ -713,7 +711,7 @@ done:
713
711
  * Parameters:
714
712
  * @iv a 16 byte IV.
715
713
  * @associated_data associated data for the HMAC. May be NULL.
716
- * @key a 96 byte key.
714
+ * @key is the encryption key. The size depends on @key_format.
717
715
  * @plaintext the plaintext to encrypt.
718
716
  * @ciphertext a location for the resulting ciphertext and HMAC tag.
719
717
  * @bytes_written a location for the resulting bytes written.
@@ -729,117 +727,124 @@ done:
729
727
  * Postconditions:
730
728
  * 1. bytes_written is set to the length of the written ciphertext. This
731
729
  * is the same as
732
- * _mongocrypt_calculate_ciphertext_len (plaintext->len, status).
730
+ * _mongocrypt_calculate_ciphertext_len (plaintext->len, mode, hmac, status).
733
731
  *
734
732
  * ----------------------------------------------------------------------------
735
733
  */
736
- bool
737
- _mongocrypt_do_encryption (_mongocrypt_crypto_t *crypto,
738
- const _mongocrypt_buffer_t *iv,
739
- const _mongocrypt_buffer_t *associated_data,
740
- const _mongocrypt_buffer_t *key,
741
- const _mongocrypt_buffer_t *plaintext,
742
- _mongocrypt_buffer_t *ciphertext,
743
- uint32_t *bytes_written,
744
- mongocrypt_status_t *status)
745
- {
746
- _mongocrypt_buffer_t mac_key = {0}, enc_key = {0}, intermediate = {0},
747
- intermediate_hmac = {0}, empty_buffer = {0};
748
- uint32_t intermediate_bytes_written = 0;
749
-
750
- BSON_ASSERT_PARAM (crypto);
751
- BSON_ASSERT_PARAM (iv);
752
- /* associated_data is checked at the point it is used, so it can be NULL */
753
- BSON_ASSERT_PARAM (key);
754
- BSON_ASSERT_PARAM (plaintext);
755
- BSON_ASSERT_PARAM (ciphertext);
756
-
757
- memset (ciphertext->data, 0, ciphertext->len);
758
-
759
- if (ciphertext->len !=
760
- _mongocrypt_calculate_ciphertext_len (plaintext->len, status)) {
761
- CLIENT_ERR (
762
- "output ciphertext should have been allocated with %d bytes",
763
- _mongocrypt_calculate_ciphertext_len (plaintext->len, status));
764
- return false;
765
- }
766
-
767
- BSON_ASSERT_PARAM (bytes_written);
768
- *bytes_written = 0;
769
-
770
- if (MONGOCRYPT_IV_LEN != iv->len) {
771
- CLIENT_ERR ("IV should have length %d, but has length %d",
772
- MONGOCRYPT_IV_LEN,
773
- iv->len);
774
- return false;
775
- }
776
- if (MONGOCRYPT_KEY_LEN != key->len) {
777
- CLIENT_ERR ("key should have length %d, but has length %d",
778
- MONGOCRYPT_KEY_LEN,
779
- key->len);
780
- return false;
781
- }
782
-
783
- intermediate.len = ciphertext->len;
784
- intermediate.data = ciphertext->data;
785
-
786
- /* [MCGREW]: Step 1. "MAC_KEY consists of the initial MAC_KEY_LEN octets of
787
- * K, in order. ENC_KEY consists of the final ENC_KEY_LEN octets of K, in
788
- * order." */
789
- mac_key.data = (uint8_t *) key->data;
790
- mac_key.len = MONGOCRYPT_MAC_KEY_LEN;
791
- enc_key.data = (uint8_t *) key->data + MONGOCRYPT_MAC_KEY_LEN;
792
- enc_key.len = MONGOCRYPT_ENC_KEY_LEN;
793
-
794
- /* Prepend the IV. */
795
- memcpy (intermediate.data, iv->data, iv->len);
796
- intermediate.data += iv->len;
797
- BSON_ASSERT (intermediate.len >= iv->len);
798
- intermediate.len -= iv->len;
799
- BSON_ASSERT (*bytes_written <= UINT32_MAX - iv->len);
800
- *bytes_written += iv->len;
801
-
802
- /* [MCGREW]: Steps 2 & 3. */
803
- if (!_encrypt_step (crypto,
804
- iv,
805
- &enc_key,
806
- plaintext,
807
- &intermediate,
808
- &intermediate_bytes_written,
809
- status)) {
810
- return false;
811
- }
812
-
813
- BSON_ASSERT (*bytes_written <= UINT32_MAX - intermediate_bytes_written);
814
- *bytes_written += intermediate_bytes_written;
815
-
816
- /* Append the HMAC tag. */
817
- intermediate_hmac.data = ciphertext->data + *bytes_written;
818
- intermediate_hmac.len = MONGOCRYPT_HMAC_LEN;
819
-
820
- intermediate.data = ciphertext->data;
821
- intermediate.len = *bytes_written;
822
-
823
- /* [MCGREW]: Steps 4 & 5, compute the HMAC. */
824
- if (!_hmac_step (crypto,
825
- &mac_key,
826
- associated_data ? associated_data : &empty_buffer,
827
- &intermediate,
828
- &intermediate_hmac,
829
- status)) {
830
- return false;
831
- }
832
-
833
- *bytes_written += MONGOCRYPT_HMAC_LEN;
834
- return true;
734
+ static bool _mongocrypt_do_encryption(_mongocrypt_crypto_t *crypto,
735
+ _mongocrypt_key_format_t key_format,
736
+ _mongocrypt_mac_format_t mac_format,
737
+ _mongocrypt_encryption_mode_t mode,
738
+ _mongocrypt_hmac_type_t hmac,
739
+ const _mongocrypt_buffer_t *iv,
740
+ const _mongocrypt_buffer_t *associated_data,
741
+ const _mongocrypt_buffer_t *key,
742
+ const _mongocrypt_buffer_t *plaintext,
743
+ _mongocrypt_buffer_t *ciphertext,
744
+ uint32_t *bytes_written,
745
+ mongocrypt_status_t *status) {
746
+ _mongocrypt_buffer_t Ke = {0}; // Ke == Key for Encryption
747
+ BSON_ASSERT_PARAM(crypto);
748
+ BSON_ASSERT_PARAM(iv);
749
+ /* associated_data is checked at the point it is used, so it can be NULL */
750
+ BSON_ASSERT_PARAM(key);
751
+ BSON_ASSERT_PARAM(plaintext);
752
+ BSON_ASSERT_PARAM(ciphertext);
753
+
754
+ if (plaintext->len <= 0) {
755
+ CLIENT_ERR("input plaintext too small. Must be more than zero bytes.");
756
+ return false;
757
+ }
758
+
759
+ const uint32_t expect_ciphertext_len = _mongocrypt_calculate_ciphertext_len(plaintext->len, mode, hmac, status);
760
+ if (mongocrypt_status_type(status) != MONGOCRYPT_STATUS_OK) {
761
+ return false;
762
+ }
763
+ if (expect_ciphertext_len != ciphertext->len) {
764
+ CLIENT_ERR("output ciphertext should have been allocated with %d bytes", expect_ciphertext_len);
765
+ return false;
766
+ }
767
+
768
+ if (MONGOCRYPT_IV_LEN != iv->len) {
769
+ CLIENT_ERR("IV should have length %d, but has length %d", MONGOCRYPT_IV_LEN, iv->len);
770
+ return false;
771
+ }
772
+
773
+ const uint32_t expected_key_len = (key_format == KEY_FORMAT_FLE2) ? MONGOCRYPT_ENC_KEY_LEN : MONGOCRYPT_KEY_LEN;
774
+ if (key->len != expected_key_len) {
775
+ CLIENT_ERR("key should have length %d, but has length %d", expected_key_len, key->len);
776
+ return false;
777
+ }
778
+
779
+ // Copy IV into the output, and clear remainder.
780
+ memmove(ciphertext->data, iv->data, MONGOCRYPT_IV_LEN);
781
+ memset(ciphertext->data + MONGOCRYPT_IV_LEN, 0, ciphertext->len - MONGOCRYPT_IV_LEN);
782
+
783
+ // S is the encryption payload without IV or HMAC
784
+ _mongocrypt_buffer_t S;
785
+ if (!_mongocrypt_buffer_from_subrange(&S, ciphertext, MONGOCRYPT_IV_LEN, ciphertext->len - MONGOCRYPT_IV_LEN)) {
786
+ CLIENT_ERR("unable to create S subrange from C");
787
+ return false;
788
+ }
789
+ if (hmac != HMAC_NONE) {
790
+ S.len -= MONGOCRYPT_HMAC_LEN;
791
+ }
792
+
793
+ // Ke is the key used for payload encryption
794
+ const uint32_t Ke_offset = (key_format == KEY_FORMAT_FLE1) ? MONGOCRYPT_MAC_KEY_LEN : 0;
795
+ if (!_mongocrypt_buffer_from_subrange(&Ke, key, Ke_offset, MONGOCRYPT_ENC_KEY_LEN)) {
796
+ CLIENT_ERR("unable to create Ke subrange from key");
797
+ return false;
798
+ }
799
+
800
+ uint32_t S_bytes_written = 0;
801
+ if (!_encrypt_step(crypto, mode, iv, &Ke, plaintext, &S, &S_bytes_written, status)) {
802
+ return false;
803
+ }
804
+ BSON_ASSERT_PARAM(bytes_written);
805
+ BSON_ASSERT((UINT32_MAX - S_bytes_written) > MONGOCRYPT_IV_LEN);
806
+ *bytes_written = MONGOCRYPT_IV_LEN + S_bytes_written;
807
+
808
+ if (hmac != HMAC_NONE) {
809
+ // Km == Key for MAC
810
+ const uint32_t Km_offset = (key_format == KEY_FORMAT_FLE1) ? 0 : MONGOCRYPT_ENC_KEY_LEN;
811
+
812
+ // Km is the HMAC Key.
813
+ _mongocrypt_buffer_t Km;
814
+ if (!_mongocrypt_buffer_from_subrange(&Km, key, Km_offset, MONGOCRYPT_MAC_KEY_LEN)) {
815
+ CLIENT_ERR("unable to create Km subrange from key");
816
+ return false;
817
+ }
818
+
819
+ /* Primary payload to MAC. */
820
+ _mongocrypt_buffer_t iv_and_ciphertext;
821
+ if (!_mongocrypt_buffer_from_subrange(&iv_and_ciphertext, ciphertext, 0, *bytes_written)) {
822
+ CLIENT_ERR("unable to create IV || S subrange from C");
823
+ return false;
824
+ }
825
+
826
+ // T == HMAC Tag
827
+ _mongocrypt_buffer_t T;
828
+ if (!_mongocrypt_buffer_from_subrange(&T, ciphertext, *bytes_written, MONGOCRYPT_HMAC_LEN)) {
829
+ CLIENT_ERR("unable to create T subrange from C");
830
+ return false;
831
+ }
832
+
833
+ if (!_hmac_step(crypto, mac_format, hmac, &Km, associated_data, &iv_and_ciphertext, &T, status)) {
834
+ return false;
835
+ }
836
+
837
+ *bytes_written += MONGOCRYPT_HMAC_LEN;
838
+ }
839
+
840
+ return true;
835
841
  }
836
842
 
837
-
838
843
  /* ----------------------------------------------------------------------------
839
844
  *
840
- * _aes256_cbc_decrypt --
845
+ * _decrypt_step --
841
846
  *
842
- * Decrypts using AES256 CBC using a secret key and a known IV.
847
+ * Decrypts using AES256 using a secret key and a known IV.
843
848
  *
844
849
  * Parameters:
845
850
  * @enc_key a 32 byte key.
@@ -859,71 +864,77 @@ _mongocrypt_do_encryption (_mongocrypt_crypto_t *crypto,
859
864
  * Postconditions:
860
865
  * 1. bytes_written is set to the length of the written plaintext, excluding
861
866
  * padding. This may be less than
862
- * _mongocrypt_calculate_plaintext_len (ciphertext->len, status).
867
+ * _mongocrypt_calculate_plaintext_len (ciphertext->len, home, hmac, status).
863
868
  *
864
869
  * ----------------------------------------------------------------------------
865
870
  */
866
- static bool
867
- _decrypt_step (_mongocrypt_crypto_t *crypto,
868
- const _mongocrypt_buffer_t *iv,
869
- const _mongocrypt_buffer_t *enc_key,
870
- const _mongocrypt_buffer_t *ciphertext,
871
- _mongocrypt_buffer_t *plaintext,
872
- uint32_t *bytes_written,
873
- mongocrypt_status_t *status)
874
- {
875
- uint8_t padding_byte;
876
-
877
- BSON_ASSERT_PARAM (crypto);
878
- BSON_ASSERT_PARAM (iv);
879
- BSON_ASSERT_PARAM (enc_key);
880
- BSON_ASSERT_PARAM (ciphertext);
881
- BSON_ASSERT_PARAM (plaintext);
882
-
883
- BSON_ASSERT_PARAM (bytes_written);
884
- *bytes_written = 0;
885
-
886
- if (MONGOCRYPT_IV_LEN != iv->len) {
887
- CLIENT_ERR ("IV should have length %d, but has length %d",
888
- MONGOCRYPT_IV_LEN,
889
- iv->len);
890
- return false;
891
- }
892
- if (MONGOCRYPT_ENC_KEY_LEN != enc_key->len) {
893
- CLIENT_ERR ("encryption key should have length %d, but has length %d",
894
- MONGOCRYPT_ENC_KEY_LEN,
895
- enc_key->len);
896
- return false;
897
- }
898
-
899
-
900
- if (ciphertext->len % MONGOCRYPT_BLOCK_SIZE > 0) {
901
- CLIENT_ERR ("error, ciphertext length is not a multiple of block size");
902
- return false;
903
- }
904
-
905
- if (!_crypto_aes_256_cbc_decrypt (
906
- crypto,
907
- (aes_256_args_t){.iv = iv,
908
- .key = enc_key,
909
- .in = ciphertext,
910
- .out = plaintext,
911
- .bytes_written = bytes_written,
912
- .status = status})) {
913
- return false;
914
- }
915
-
916
- BSON_ASSERT (*bytes_written > 0);
917
- padding_byte = plaintext->data[*bytes_written - 1];
918
- if (padding_byte > 16) {
919
- CLIENT_ERR ("error, ciphertext malformed padding");
920
- return false;
921
- }
922
- *bytes_written -= padding_byte;
923
- return true;
871
+ static bool _decrypt_step(_mongocrypt_crypto_t *crypto,
872
+ _mongocrypt_encryption_mode_t mode,
873
+ const _mongocrypt_buffer_t *iv,
874
+ const _mongocrypt_buffer_t *enc_key,
875
+ const _mongocrypt_buffer_t *ciphertext,
876
+ _mongocrypt_buffer_t *plaintext,
877
+ uint32_t *bytes_written,
878
+ mongocrypt_status_t *status) {
879
+ BSON_ASSERT_PARAM(crypto);
880
+ BSON_ASSERT_PARAM(iv);
881
+ BSON_ASSERT_PARAM(enc_key);
882
+ BSON_ASSERT_PARAM(ciphertext);
883
+ BSON_ASSERT_PARAM(plaintext);
884
+
885
+ BSON_ASSERT_PARAM(bytes_written);
886
+ *bytes_written = 0;
887
+
888
+ if (MONGOCRYPT_IV_LEN != iv->len) {
889
+ CLIENT_ERR("IV should have length %d, but has length %d", MONGOCRYPT_IV_LEN, iv->len);
890
+ return false;
891
+ }
892
+ if (MONGOCRYPT_ENC_KEY_LEN != enc_key->len) {
893
+ CLIENT_ERR("encryption key should have length %d, but has length %d", MONGOCRYPT_ENC_KEY_LEN, enc_key->len);
894
+ return false;
895
+ }
896
+
897
+ if (mode == MODE_CBC) {
898
+ if (ciphertext->len % MONGOCRYPT_BLOCK_SIZE > 0) {
899
+ CLIENT_ERR("error, ciphertext length is not a multiple of block size");
900
+ return false;
901
+ }
902
+
903
+ if (!_crypto_aes_256_cbc_decrypt(crypto,
904
+ (aes_256_args_t){.iv = iv,
905
+ .key = enc_key,
906
+ .in = ciphertext,
907
+ .out = plaintext,
908
+ .bytes_written = bytes_written,
909
+ .status = status})) {
910
+ return false;
911
+ }
912
+
913
+ BSON_ASSERT(*bytes_written > 0);
914
+ uint8_t padding_byte = plaintext->data[*bytes_written - 1];
915
+ if (padding_byte > 16) {
916
+ CLIENT_ERR("error, ciphertext malformed padding");
917
+ return false;
918
+ }
919
+ *bytes_written -= padding_byte;
920
+
921
+ } else {
922
+ BSON_ASSERT(mode == MODE_CTR);
923
+ if (!_crypto_aes_256_ctr_decrypt(crypto,
924
+ (aes_256_args_t){.iv = iv,
925
+ .key = enc_key,
926
+ .in = ciphertext,
927
+ .out = plaintext,
928
+ .bytes_written = bytes_written,
929
+ .status = status})) {
930
+ return false;
931
+ }
932
+ BSON_ASSERT(*bytes_written == plaintext->len);
933
+ }
934
+
935
+ return true;
924
936
  }
925
937
 
926
-
927
938
  /* ----------------------------------------------------------------------------
928
939
  *
929
940
  * _mongocrypt_do_decryption --
@@ -948,108 +959,200 @@ _decrypt_step (_mongocrypt_crypto_t *crypto,
948
959
  * Postconditions:
949
960
  * 1. bytes_written is set to the length of the written plaintext, excluding
950
961
  * padding. This may be less than
951
- * _mongocrypt_calculate_plaintext_len (ciphertext->len, status).
962
+ * _mongocrypt_calculate_plaintext_len (ciphertext->len, mode, hmac, status).
952
963
  *
953
964
  * ----------------------------------------------------------------------------
954
965
  */
955
- bool
956
- _mongocrypt_do_decryption (_mongocrypt_crypto_t *crypto,
957
- const _mongocrypt_buffer_t *associated_data,
958
- const _mongocrypt_buffer_t *key,
959
- const _mongocrypt_buffer_t *ciphertext,
960
- _mongocrypt_buffer_t *plaintext,
961
- uint32_t *bytes_written,
962
- mongocrypt_status_t *status)
963
- {
964
- bool ret = false;
965
- _mongocrypt_buffer_t mac_key = {0}, enc_key = {0}, intermediate = {0},
966
- hmac_tag = {0}, iv = {0}, empty_buffer = {0};
967
- uint8_t hmac_tag_storage[MONGOCRYPT_HMAC_LEN];
968
-
969
- BSON_ASSERT_PARAM (crypto);
970
- /* associated_data is checked at the point it is used, so it can be NULL */
971
- BSON_ASSERT_PARAM (key);
972
- BSON_ASSERT_PARAM (ciphertext);
973
- BSON_ASSERT_PARAM (plaintext);
974
- BSON_ASSERT_PARAM (bytes_written);
975
-
976
- if (plaintext->len !=
977
- _mongocrypt_calculate_plaintext_len (ciphertext->len, status)) {
978
- CLIENT_ERR ("output plaintext should have been allocated with %d bytes, "
979
- "but has: %d",
980
- _mongocrypt_calculate_plaintext_len (ciphertext->len, status),
981
- plaintext->len);
982
- return false;
983
- }
984
-
985
- if (MONGOCRYPT_KEY_LEN != key->len) {
986
- CLIENT_ERR ("key should have length %d, but has length %d",
987
- MONGOCRYPT_KEY_LEN,
988
- key->len);
989
- return false;
990
- }
991
-
992
- if (ciphertext->len <
993
- MONGOCRYPT_HMAC_LEN + MONGOCRYPT_IV_LEN + MONGOCRYPT_BLOCK_SIZE) {
994
- CLIENT_ERR ("corrupt ciphertext - must be > %d bytes",
995
- MONGOCRYPT_HMAC_LEN + MONGOCRYPT_IV_LEN +
996
- MONGOCRYPT_BLOCK_SIZE);
997
- goto done;
998
- }
999
-
1000
- mac_key.data = (uint8_t *) key->data;
1001
- mac_key.len = MONGOCRYPT_MAC_KEY_LEN;
1002
- enc_key.data = (uint8_t *) key->data + MONGOCRYPT_MAC_KEY_LEN;
1003
- enc_key.len = MONGOCRYPT_ENC_KEY_LEN;
1004
-
1005
- iv.data = ciphertext->data;
1006
- iv.len = MONGOCRYPT_IV_LEN;
1007
-
1008
- intermediate.data = (uint8_t *) ciphertext->data;
1009
- intermediate.len = ciphertext->len - MONGOCRYPT_HMAC_LEN;
1010
-
1011
- hmac_tag.data = hmac_tag_storage;
1012
- hmac_tag.len = MONGOCRYPT_HMAC_LEN;
1013
-
1014
- /* [MCGREW 2.2]: Step 3: HMAC check. */
1015
- if (!_hmac_step (crypto,
1016
- &mac_key,
1017
- associated_data ? associated_data : &empty_buffer,
1018
- &intermediate,
1019
- &hmac_tag,
1020
- status)) {
1021
- goto done;
1022
- }
1023
-
1024
- /* [MCGREW] "using a comparison routine that takes constant time". */
1025
- if (0 != _mongocrypt_memequal (hmac_tag.data,
1026
- ciphertext->data +
1027
- (ciphertext->len - MONGOCRYPT_HMAC_LEN),
1028
- MONGOCRYPT_HMAC_LEN)) {
1029
- CLIENT_ERR ("HMAC validation failure");
1030
- goto done;
1031
- }
1032
-
1033
- /* Decrypt data excluding IV + HMAC. */
1034
- intermediate.data = (uint8_t *) ciphertext->data + MONGOCRYPT_IV_LEN;
1035
- intermediate.len =
1036
- ciphertext->len - (MONGOCRYPT_IV_LEN + MONGOCRYPT_HMAC_LEN);
1037
-
1038
- if (!_decrypt_step (crypto,
1039
- &iv,
1040
- &enc_key,
1041
- &intermediate,
1042
- plaintext,
1043
- bytes_written,
1044
- status)) {
1045
- goto done;
1046
- }
1047
-
1048
- ret = true;
1049
- done:
1050
- return ret;
966
+ static bool _mongocrypt_do_decryption(_mongocrypt_crypto_t *crypto,
967
+ _mongocrypt_key_format_t key_format,
968
+ _mongocrypt_mac_format_t mac_format,
969
+ _mongocrypt_encryption_mode_t mode,
970
+ _mongocrypt_hmac_type_t hmac,
971
+ const _mongocrypt_buffer_t *associated_data,
972
+ const _mongocrypt_buffer_t *key,
973
+ const _mongocrypt_buffer_t *ciphertext,
974
+ _mongocrypt_buffer_t *plaintext,
975
+ uint32_t *bytes_written,
976
+ mongocrypt_status_t *status) {
977
+ BSON_ASSERT_PARAM(crypto);
978
+ /* associated_data is checked at the point it is used, so it can be NULL */
979
+ BSON_ASSERT_PARAM(key);
980
+ BSON_ASSERT_PARAM(ciphertext);
981
+ BSON_ASSERT_PARAM(plaintext);
982
+ BSON_ASSERT_PARAM(bytes_written);
983
+
984
+ const uint32_t expect_plaintext_len = _mongocrypt_calculate_plaintext_len(ciphertext->len, mode, hmac, status);
985
+ if (mongocrypt_status_type(status) != MONGOCRYPT_STATUS_OK) {
986
+ return false;
987
+ }
988
+ if (plaintext->len != expect_plaintext_len) {
989
+ CLIENT_ERR("output plaintext should have been allocated with %d bytes, "
990
+ "but has: %d",
991
+ expect_plaintext_len,
992
+ plaintext->len);
993
+ return false;
994
+ }
995
+ if (expect_plaintext_len == 0) {
996
+ // While a ciphertext string describing a zero length plaintext is
997
+ // technically valid,
998
+ // it's not actually particularly useful in the context of FLE where such
999
+ // values aren't encoded.
1000
+ CLIENT_ERR("input ciphertext too small. Must be more than %" PRIu32 " bytes",
1001
+ _mongocrypt_calculate_ciphertext_len(0, mode, hmac, NULL));
1002
+ return false;
1003
+ }
1004
+
1005
+ const uint32_t expected_key_len = (key_format == KEY_FORMAT_FLE2) ? MONGOCRYPT_ENC_KEY_LEN : MONGOCRYPT_KEY_LEN;
1006
+ if (expected_key_len != key->len) {
1007
+ CLIENT_ERR("key should have length %d, but has length %d", expected_key_len, key->len);
1008
+ return false;
1009
+ }
1010
+
1011
+ const uint32_t min_cipherlen = _mongocrypt_calculate_ciphertext_len(0, mode, hmac, NULL);
1012
+ if (ciphertext->len < min_cipherlen) {
1013
+ CLIENT_ERR("corrupt ciphertext - must be >= %d bytes", min_cipherlen);
1014
+ return false;
1015
+ }
1016
+
1017
+ _mongocrypt_buffer_t Ke;
1018
+ const uint32_t Ke_offset = (key_format == KEY_FORMAT_FLE1) ? MONGOCRYPT_MAC_KEY_LEN : 0;
1019
+ if (!_mongocrypt_buffer_from_subrange(&Ke, key, Ke_offset, MONGOCRYPT_ENC_KEY_LEN)) {
1020
+ CLIENT_ERR("unable to create Ke subrange from key");
1021
+ return false;
1022
+ }
1023
+
1024
+ _mongocrypt_buffer_t IV;
1025
+ if (!_mongocrypt_buffer_from_subrange(&IV, ciphertext, 0, MONGOCRYPT_IV_LEN)) {
1026
+ CLIENT_ERR("unable to create IV subrange from ciphertext");
1027
+ return false;
1028
+ }
1029
+
1030
+ if (hmac == HMAC_NONE) {
1031
+ BSON_ASSERT(key_format == KEY_FORMAT_FLE2);
1032
+
1033
+ } else {
1034
+ BSON_ASSERT(key_format != KEY_FORMAT_FLE2);
1035
+
1036
+ uint8_t hmac_tag_storage[MONGOCRYPT_HMAC_LEN];
1037
+ const uint32_t mac_key_offset = (key_format == KEY_FORMAT_FLE1) ? 0 : MONGOCRYPT_ENC_KEY_LEN;
1038
+ _mongocrypt_buffer_t Km;
1039
+ if (!_mongocrypt_buffer_from_subrange(&Km, key, mac_key_offset, MONGOCRYPT_MAC_KEY_LEN)) {
1040
+ CLIENT_ERR("unable to create Km subrange from key");
1041
+ return false;
1042
+ }
1043
+
1044
+ _mongocrypt_buffer_t iv_and_ciphertext;
1045
+ if (!_mongocrypt_buffer_from_subrange(&iv_and_ciphertext,
1046
+ ciphertext,
1047
+ 0,
1048
+ ciphertext->len - MONGOCRYPT_HMAC_LEN)) {
1049
+ CLIENT_ERR("unable to create IV || S subrange from C");
1050
+ return false;
1051
+ }
1052
+
1053
+ _mongocrypt_buffer_t hmac_tag = {.data = hmac_tag_storage, .len = MONGOCRYPT_HMAC_LEN};
1054
+
1055
+ if (!_hmac_step(crypto, mac_format, hmac, &Km, associated_data, &iv_and_ciphertext, &hmac_tag, status)) {
1056
+ return false;
1057
+ }
1058
+
1059
+ /* Constant time compare. */
1060
+ _mongocrypt_buffer_t T;
1061
+ if (!_mongocrypt_buffer_from_subrange(&T,
1062
+ ciphertext,
1063
+ ciphertext->len - MONGOCRYPT_HMAC_LEN,
1064
+ MONGOCRYPT_HMAC_LEN)) {
1065
+ CLIENT_ERR("unable to create T subrange from C");
1066
+ return false;
1067
+ }
1068
+ if (0 != _mongocrypt_memequal(hmac_tag.data, T.data, MONGOCRYPT_HMAC_LEN)) {
1069
+ CLIENT_ERR("HMAC validation failure");
1070
+ return false;
1071
+ }
1072
+ }
1073
+
1074
+ /* Decrypt data excluding IV + HMAC. */
1075
+ const uint32_t hmac_len = (hmac == HMAC_NONE) ? 0 : MONGOCRYPT_HMAC_LEN;
1076
+ _mongocrypt_buffer_t S;
1077
+ if (!_mongocrypt_buffer_from_subrange(&S,
1078
+ ciphertext,
1079
+ MONGOCRYPT_IV_LEN,
1080
+ ciphertext->len - MONGOCRYPT_IV_LEN - hmac_len)) {
1081
+ CLIENT_ERR("unable to create S subrange from C");
1082
+ return false;
1083
+ }
1084
+
1085
+ return _decrypt_step(crypto, mode, &IV, &Ke, &S, plaintext, bytes_written, status);
1051
1086
  }
1052
1087
 
1088
+ #define DECLARE_ALGORITHM(name, mode, hmac) \
1089
+ static uint32_t _mc_##name##_ciphertext_len(uint32_t plaintext_len, mongocrypt_status_t *status) { \
1090
+ return _mongocrypt_calculate_ciphertext_len(plaintext_len, MODE_##mode, HMAC_##hmac, status); \
1091
+ } \
1092
+ static uint32_t _mc_##name##_plaintext_len(uint32_t ciphertext_len, mongocrypt_status_t *status) { \
1093
+ return _mongocrypt_calculate_plaintext_len(ciphertext_len, MODE_##mode, HMAC_##hmac, status); \
1094
+ } \
1095
+ static bool _mc_##name##_do_encryption(_mongocrypt_crypto_t *crypto, \
1096
+ const _mongocrypt_buffer_t *iv, \
1097
+ const _mongocrypt_buffer_t *aad, \
1098
+ const _mongocrypt_buffer_t *key, \
1099
+ const _mongocrypt_buffer_t *plaintext, \
1100
+ _mongocrypt_buffer_t *ciphertext, \
1101
+ uint32_t *written, \
1102
+ mongocrypt_status_t *status) { \
1103
+ return _mongocrypt_do_encryption(crypto, \
1104
+ KEY_FORMAT_##name, \
1105
+ MAC_FORMAT_##name, \
1106
+ MODE_##mode, \
1107
+ HMAC_##hmac, \
1108
+ iv, \
1109
+ aad, \
1110
+ key, \
1111
+ plaintext, \
1112
+ ciphertext, \
1113
+ written, \
1114
+ status); \
1115
+ } \
1116
+ static bool _mc_##name##_do_decryption(_mongocrypt_crypto_t *crypto, \
1117
+ const _mongocrypt_buffer_t *aad, \
1118
+ const _mongocrypt_buffer_t *key, \
1119
+ const _mongocrypt_buffer_t *ciphertext, \
1120
+ _mongocrypt_buffer_t *plaintext, \
1121
+ uint32_t *written, \
1122
+ mongocrypt_status_t *status) { \
1123
+ return _mongocrypt_do_decryption(crypto, \
1124
+ KEY_FORMAT_##name, \
1125
+ MAC_FORMAT_##name, \
1126
+ MODE_##mode, \
1127
+ HMAC_##hmac, \
1128
+ aad, \
1129
+ key, \
1130
+ ciphertext, \
1131
+ plaintext, \
1132
+ written, \
1133
+ status); \
1134
+ } \
1135
+ static const _mongocrypt_value_encryption_algorithm_t _mc##name##Algorithm_definition = { \
1136
+ _mc_##name##_ciphertext_len, \
1137
+ _mc_##name##_plaintext_len, \
1138
+ _mc_##name##_do_encryption, \
1139
+ _mc_##name##_do_decryption, \
1140
+ }; \
1141
+ const _mongocrypt_value_encryption_algorithm_t *_mc##name##Algorithm() { return &_mc##name##Algorithm_definition; }
1142
+
1143
+ // FLE1 algorithm: AES-256-CBC HMAC/SHA-512-256 (SHA-512 truncated to 256 bits)
1144
+ DECLARE_ALGORITHM(FLE1, CBC, SHA_512_256)
1145
+
1146
+ // FLE2 AEAD used value algorithm: AES-256-CTR HMAC/SHA-256
1147
+ DECLARE_ALGORITHM(FLE2AEAD, CTR, SHA_256)
1148
+
1149
+ // FLE2 used with ESC/ECOC tokens: AES-256-CTR no HMAC
1150
+ DECLARE_ALGORITHM(FLE2, CTR, NONE)
1151
+
1152
+ // FLE2v2 AEAD general algorithm: AES-256-CBC HMAC/SHA-256
1153
+ DECLARE_ALGORITHM(FLE2v2AEAD, CBC, SHA_256)
1154
+
1155
+ #undef DECLARE_ALGORITHM
1053
1156
 
1054
1157
  /* ----------------------------------------------------------------------------
1055
1158
  *
@@ -1070,25 +1173,21 @@ done:
1070
1173
  *
1071
1174
  * ----------------------------------------------------------------------------
1072
1175
  */
1073
- bool
1074
- _mongocrypt_random (_mongocrypt_crypto_t *crypto,
1075
- _mongocrypt_buffer_t *out,
1076
- uint32_t count,
1077
- mongocrypt_status_t *status)
1078
- {
1079
- BSON_ASSERT_PARAM (crypto);
1080
- BSON_ASSERT_PARAM (out);
1081
-
1082
- if (count != out->len) {
1083
- CLIENT_ERR (
1084
- "out should have length %d, but has length %d", count, out->len);
1085
- return false;
1086
- }
1087
-
1088
- return _crypto_random (crypto, out, count, status);
1176
+ bool _mongocrypt_random(_mongocrypt_crypto_t *crypto,
1177
+ _mongocrypt_buffer_t *out,
1178
+ uint32_t count,
1179
+ mongocrypt_status_t *status) {
1180
+ BSON_ASSERT_PARAM(crypto);
1181
+ BSON_ASSERT_PARAM(out);
1182
+
1183
+ if (count != out->len) {
1184
+ CLIENT_ERR("out should have length %d, but has length %d", count, out->len);
1185
+ return false;
1186
+ }
1187
+
1188
+ return _crypto_random(crypto, out, count, status);
1089
1189
  }
1090
1190
 
1091
-
1092
1191
  /* ----------------------------------------------------------------------------
1093
1192
  *
1094
1193
  * _mongocrypt_calculate_deterministic_iv --
@@ -1111,740 +1210,219 @@ _mongocrypt_random (_mongocrypt_crypto_t *crypto,
1111
1210
  *
1112
1211
  * ----------------------------------------------------------------------------
1113
1212
  */
1114
- bool
1115
- _mongocrypt_calculate_deterministic_iv (
1116
- _mongocrypt_crypto_t *crypto,
1117
- const _mongocrypt_buffer_t *key,
1118
- const _mongocrypt_buffer_t *plaintext,
1119
- const _mongocrypt_buffer_t *associated_data,
1120
- _mongocrypt_buffer_t *out,
1121
- mongocrypt_status_t *status)
1122
- {
1123
- _mongocrypt_buffer_t intermediates[3];
1124
- _mongocrypt_buffer_t to_hmac;
1125
- _mongocrypt_buffer_t iv_key;
1126
- uint64_t associated_data_len_be;
1127
- uint8_t tag_storage[64];
1128
- _mongocrypt_buffer_t tag;
1129
- bool ret = false;
1130
-
1131
- _mongocrypt_buffer_init (&to_hmac);
1132
-
1133
- BSON_ASSERT_PARAM (crypto);
1134
- BSON_ASSERT_PARAM (key);
1135
- BSON_ASSERT_PARAM (plaintext);
1136
- BSON_ASSERT_PARAM (associated_data);
1137
- BSON_ASSERT_PARAM (out);
1138
-
1139
- if (MONGOCRYPT_KEY_LEN != key->len) {
1140
- CLIENT_ERR ("key should have length %d, but has length %d\n",
1141
- MONGOCRYPT_KEY_LEN,
1142
- key->len);
1143
- goto done;
1144
- }
1145
- if (MONGOCRYPT_IV_LEN != out->len) {
1146
- CLIENT_ERR ("out should have length %d, but has length %d\n",
1147
- MONGOCRYPT_IV_LEN,
1148
- out->len);
1149
- goto done;
1150
- }
1151
-
1152
- _mongocrypt_buffer_init (&iv_key);
1153
- iv_key.data = key->data + MONGOCRYPT_ENC_KEY_LEN + MONGOCRYPT_MAC_KEY_LEN;
1154
- iv_key.len = MONGOCRYPT_IV_KEY_LEN;
1155
-
1156
- _mongocrypt_buffer_init (&intermediates[0]);
1157
- _mongocrypt_buffer_init (&intermediates[1]);
1158
- _mongocrypt_buffer_init (&intermediates[2]);
1159
- /* Add associated data. */
1160
- intermediates[0].data = associated_data->data;
1161
- intermediates[0].len = associated_data->len;
1162
- /* Add associated data length in bits. */
1163
- /* multiplying a uint32_t by 8 won't bring it anywhere close to UINT64_MAX */
1164
- associated_data_len_be = 8 * (uint64_t) associated_data->len;
1165
- associated_data_len_be = BSON_UINT64_TO_BE (associated_data_len_be);
1166
- intermediates[1].data = (uint8_t *) &associated_data_len_be;
1167
- intermediates[1].len = sizeof (uint64_t);
1168
- /* Add plaintext. */
1169
- intermediates[2].data = (uint8_t *) plaintext->data;
1170
- intermediates[2].len = plaintext->len;
1171
-
1172
- tag.data = tag_storage;
1173
- tag.len = sizeof (tag_storage);
1174
-
1175
- if (!_mongocrypt_buffer_concat (&to_hmac, intermediates, 3)) {
1176
- CLIENT_ERR ("failed to allocate buffer");
1177
- goto done;
1178
- }
1179
-
1180
- if (!_crypto_hmac_sha_512 (crypto, &iv_key, &to_hmac, &tag, status)) {
1181
- goto done;
1182
- }
1183
-
1184
- /* Truncate to IV length */
1185
- memcpy (out->data, tag.data, MONGOCRYPT_IV_LEN);
1186
-
1187
- ret = true;
1213
+ bool _mongocrypt_calculate_deterministic_iv(_mongocrypt_crypto_t *crypto,
1214
+ const _mongocrypt_buffer_t *key,
1215
+ const _mongocrypt_buffer_t *plaintext,
1216
+ const _mongocrypt_buffer_t *associated_data,
1217
+ _mongocrypt_buffer_t *out,
1218
+ mongocrypt_status_t *status) {
1219
+ _mongocrypt_buffer_t intermediates[3];
1220
+ _mongocrypt_buffer_t to_hmac;
1221
+ _mongocrypt_buffer_t iv_key;
1222
+ uint64_t associated_data_len_be;
1223
+ uint8_t tag_storage[64];
1224
+ _mongocrypt_buffer_t tag;
1225
+ bool ret = false;
1226
+
1227
+ _mongocrypt_buffer_init(&to_hmac);
1228
+
1229
+ BSON_ASSERT_PARAM(crypto);
1230
+ BSON_ASSERT_PARAM(key);
1231
+ BSON_ASSERT_PARAM(plaintext);
1232
+ BSON_ASSERT_PARAM(associated_data);
1233
+ BSON_ASSERT_PARAM(out);
1234
+
1235
+ if (MONGOCRYPT_KEY_LEN != key->len) {
1236
+ CLIENT_ERR("key should have length %d, but has length %d\n", MONGOCRYPT_KEY_LEN, key->len);
1237
+ goto done;
1238
+ }
1239
+ if (MONGOCRYPT_IV_LEN != out->len) {
1240
+ CLIENT_ERR("out should have length %d, but has length %d\n", MONGOCRYPT_IV_LEN, out->len);
1241
+ goto done;
1242
+ }
1243
+
1244
+ _mongocrypt_buffer_init(&iv_key);
1245
+ iv_key.data = key->data + MONGOCRYPT_ENC_KEY_LEN + MONGOCRYPT_MAC_KEY_LEN;
1246
+ iv_key.len = MONGOCRYPT_IV_KEY_LEN;
1247
+
1248
+ _mongocrypt_buffer_init(&intermediates[0]);
1249
+ _mongocrypt_buffer_init(&intermediates[1]);
1250
+ _mongocrypt_buffer_init(&intermediates[2]);
1251
+ /* Add associated data. */
1252
+ intermediates[0].data = associated_data->data;
1253
+ intermediates[0].len = associated_data->len;
1254
+ /* Add associated data length in bits. */
1255
+ /* multiplying a uint32_t by 8 won't bring it anywhere close to UINT64_MAX */
1256
+ associated_data_len_be = 8 * (uint64_t)associated_data->len;
1257
+ associated_data_len_be = BSON_UINT64_TO_BE(associated_data_len_be);
1258
+ intermediates[1].data = (uint8_t *)&associated_data_len_be;
1259
+ intermediates[1].len = sizeof(uint64_t);
1260
+ /* Add plaintext. */
1261
+ intermediates[2].data = (uint8_t *)plaintext->data;
1262
+ intermediates[2].len = plaintext->len;
1263
+
1264
+ tag.data = tag_storage;
1265
+ tag.len = sizeof(tag_storage);
1266
+
1267
+ if (!_mongocrypt_buffer_concat(&to_hmac, intermediates, 3)) {
1268
+ CLIENT_ERR("failed to allocate buffer");
1269
+ goto done;
1270
+ }
1271
+
1272
+ if (!_crypto_hmac_sha_512(crypto, &iv_key, &to_hmac, &tag, status)) {
1273
+ goto done;
1274
+ }
1275
+
1276
+ /* Truncate to IV length */
1277
+ memcpy(out->data, tag.data, MONGOCRYPT_IV_LEN);
1278
+
1279
+ ret = true;
1188
1280
  done:
1189
- _mongocrypt_buffer_cleanup (&to_hmac);
1190
- return ret;
1281
+ _mongocrypt_buffer_cleanup(&to_hmac);
1282
+ return ret;
1191
1283
  }
1192
1284
 
1193
- bool
1194
- _mongocrypt_wrap_key (_mongocrypt_crypto_t *crypto,
1195
- _mongocrypt_buffer_t *kek,
1196
- _mongocrypt_buffer_t *dek,
1197
- _mongocrypt_buffer_t *encrypted_dek,
1198
- mongocrypt_status_t *status)
1199
- {
1200
- uint32_t bytes_written;
1201
- _mongocrypt_buffer_t iv = {0};
1202
- bool ret = false;
1203
-
1204
- BSON_ASSERT_PARAM (crypto);
1205
- BSON_ASSERT_PARAM (kek);
1206
- BSON_ASSERT_PARAM (dek);
1207
- BSON_ASSERT_PARAM (encrypted_dek);
1208
-
1209
- _mongocrypt_buffer_init (encrypted_dek);
1210
-
1211
- if (dek->len != MONGOCRYPT_KEY_LEN) {
1212
- CLIENT_ERR ("data encryption key is incorrect length, expected: %" PRIu32
1213
- ", got: %" PRIu32,
1214
- MONGOCRYPT_KEY_LEN,
1215
- dek->len);
1216
- goto done;
1217
- }
1218
-
1219
- _mongocrypt_buffer_resize (
1220
- encrypted_dek, _mongocrypt_calculate_ciphertext_len (dek->len, status));
1221
- _mongocrypt_buffer_resize (&iv, MONGOCRYPT_IV_LEN);
1222
-
1223
- if (!_mongocrypt_random (crypto, &iv, MONGOCRYPT_IV_LEN, status)) {
1224
- goto done;
1225
- }
1226
-
1227
- if (!_mongocrypt_do_encryption (crypto,
1228
- &iv,
1229
- NULL /* associated data. */,
1230
- kek,
1231
- dek,
1232
- encrypted_dek,
1233
- &bytes_written,
1234
- status)) {
1235
- goto done;
1236
- }
1237
-
1238
- ret = true;
1285
+ bool _mongocrypt_wrap_key(_mongocrypt_crypto_t *crypto,
1286
+ _mongocrypt_buffer_t *kek,
1287
+ _mongocrypt_buffer_t *dek,
1288
+ _mongocrypt_buffer_t *encrypted_dek,
1289
+ mongocrypt_status_t *status) {
1290
+ const _mongocrypt_value_encryption_algorithm_t *fle1alg = _mcFLE1Algorithm();
1291
+ uint32_t bytes_written;
1292
+ _mongocrypt_buffer_t iv = {0};
1293
+ bool ret = false;
1294
+
1295
+ BSON_ASSERT_PARAM(crypto);
1296
+ BSON_ASSERT_PARAM(kek);
1297
+ BSON_ASSERT_PARAM(dek);
1298
+ BSON_ASSERT_PARAM(encrypted_dek);
1299
+
1300
+ _mongocrypt_buffer_init(encrypted_dek);
1301
+
1302
+ if (dek->len != MONGOCRYPT_KEY_LEN) {
1303
+ CLIENT_ERR("data encryption key is incorrect length, expected: %" PRIu32 ", got: %" PRIu32,
1304
+ MONGOCRYPT_KEY_LEN,
1305
+ dek->len);
1306
+ goto done;
1307
+ }
1308
+
1309
+ // _mongocrypt_wrap_key() uses FLE1 algorithm parameters.
1310
+ _mongocrypt_buffer_resize(encrypted_dek, fle1alg->get_ciphertext_len(dek->len, status));
1311
+ _mongocrypt_buffer_resize(&iv, MONGOCRYPT_IV_LEN);
1312
+
1313
+ if (!_mongocrypt_random(crypto, &iv, MONGOCRYPT_IV_LEN, status)) {
1314
+ goto done;
1315
+ }
1316
+
1317
+ if (!fle1alg
1318
+ ->do_encrypt(crypto, &iv, NULL /* associated data. */, kek, dek, encrypted_dek, &bytes_written, status)) {
1319
+ goto done;
1320
+ }
1321
+
1322
+ ret = true;
1239
1323
  done:
1240
- _mongocrypt_buffer_cleanup (&iv);
1241
- return ret;
1242
- }
1243
-
1244
- bool
1245
- _mongocrypt_unwrap_key (_mongocrypt_crypto_t *crypto,
1246
- _mongocrypt_buffer_t *kek,
1247
- _mongocrypt_buffer_t *encrypted_dek,
1248
- _mongocrypt_buffer_t *dek,
1249
- mongocrypt_status_t *status)
1250
- {
1251
- uint32_t bytes_written;
1252
-
1253
- BSON_ASSERT_PARAM (crypto);
1254
- BSON_ASSERT_PARAM (kek);
1255
- BSON_ASSERT_PARAM (dek);
1256
- BSON_ASSERT_PARAM (encrypted_dek);
1257
-
1258
- _mongocrypt_buffer_init (dek);
1259
- _mongocrypt_buffer_resize (
1260
- dek, _mongocrypt_calculate_plaintext_len (encrypted_dek->len, status));
1261
-
1262
- if (!_mongocrypt_do_decryption (crypto,
1263
- NULL /* associated data. */,
1264
- kek,
1265
- encrypted_dek,
1266
- dek,
1267
- &bytes_written,
1268
- status)) {
1269
- return false;
1270
- }
1271
- dek->len = bytes_written;
1272
-
1273
- if (dek->len != MONGOCRYPT_KEY_LEN) {
1274
- CLIENT_ERR ("decrypted key is incorrect length, expected: %" PRIu32
1275
- ", got: %" PRIu32,
1276
- MONGOCRYPT_KEY_LEN,
1277
- dek->len);
1278
- return false;
1279
- }
1280
- return true;
1281
- }
1282
-
1283
- bool
1284
- _mongocrypt_hmac_sha_256 (_mongocrypt_crypto_t *crypto,
1285
- const _mongocrypt_buffer_t *key,
1286
- const _mongocrypt_buffer_t *in,
1287
- _mongocrypt_buffer_t *out,
1288
- mongocrypt_status_t *status)
1289
- {
1290
- BSON_ASSERT_PARAM (crypto);
1291
- BSON_ASSERT_PARAM (key);
1292
- BSON_ASSERT_PARAM (in);
1293
- BSON_ASSERT_PARAM (out);
1294
-
1295
- if (key->len != MONGOCRYPT_MAC_KEY_LEN) {
1296
- CLIENT_ERR ("invalid hmac_sha_256 key length. Got %" PRIu32
1297
- ", expected: %" PRIu32,
1298
- key->len,
1299
- MONGOCRYPT_MAC_KEY_LEN);
1300
- return false;
1301
- }
1302
-
1303
- if (crypto->hooks_enabled) {
1304
- mongocrypt_binary_t key_bin, out_bin, in_bin;
1305
- _mongocrypt_buffer_to_binary (key, &key_bin);
1306
- _mongocrypt_buffer_to_binary (out, &out_bin);
1307
- _mongocrypt_buffer_to_binary (in, &in_bin);
1308
-
1309
- return crypto->hmac_sha_256 (
1310
- crypto->ctx, &key_bin, &in_bin, &out_bin, status);
1311
- }
1312
- return _native_crypto_hmac_sha_256 (key, in, out, status);
1313
- }
1314
-
1315
- bool
1316
- _mongocrypt_fle2aead_do_encryption (_mongocrypt_crypto_t *crypto,
1317
- const _mongocrypt_buffer_t *iv,
1318
- const _mongocrypt_buffer_t *associated_data,
1319
- const _mongocrypt_buffer_t *key,
1320
- const _mongocrypt_buffer_t *plaintext,
1321
- _mongocrypt_buffer_t *ciphertext,
1322
- uint32_t *bytes_written,
1323
- mongocrypt_status_t *status)
1324
- {
1325
- BSON_ASSERT_PARAM (crypto);
1326
- BSON_ASSERT_PARAM (iv);
1327
- BSON_ASSERT_PARAM (associated_data);
1328
- BSON_ASSERT_PARAM (key);
1329
- BSON_ASSERT_PARAM (plaintext);
1330
- BSON_ASSERT_PARAM (ciphertext);
1331
- BSON_ASSERT_PARAM (bytes_written);
1332
-
1333
- if (ciphertext->len !=
1334
- _mongocrypt_fle2aead_calculate_ciphertext_len (plaintext->len, status)) {
1335
- CLIENT_ERR ("output ciphertext must be allocated with %" PRIu32 " bytes",
1336
- _mongocrypt_fle2aead_calculate_ciphertext_len (plaintext->len,
1337
- status));
1338
- return false;
1339
- }
1340
-
1341
- if (plaintext->len <= 0) {
1342
- CLIENT_ERR ("input plaintext too small. Must be more than zero bytes.");
1343
- return false;
1344
- }
1345
-
1346
- if (MONGOCRYPT_IV_LEN != iv->len) {
1347
- CLIENT_ERR ("IV must be length %d, but is length %" PRIu32,
1348
- MONGOCRYPT_IV_LEN,
1349
- iv->len);
1350
- return false;
1351
- }
1352
- if (MONGOCRYPT_KEY_LEN != key->len) {
1353
- CLIENT_ERR ("key must be length %d, but is length %" PRIu32,
1354
- MONGOCRYPT_KEY_LEN,
1355
- key->len);
1356
- return false;
1357
- }
1358
-
1359
- memset (ciphertext->data, 0, ciphertext->len);
1360
- *bytes_written = 0;
1361
-
1362
- /* Declare variable names matching [AEAD with
1363
- * CTR](https://docs.google.com/document/d/1eCU7R8Kjr-mdyz6eKvhNIDVmhyYQcAaLtTfHeK7a_vE/).
1364
- */
1365
- /* M is the input plaintext. */
1366
- _mongocrypt_buffer_t M;
1367
- if (!_mongocrypt_buffer_from_subrange (&M, plaintext, 0, plaintext->len)) {
1368
- CLIENT_ERR ("unable to create M view from plaintext");
1369
- return false;
1370
- }
1371
- /* Ke is 32 byte Key for encryption. */
1372
- _mongocrypt_buffer_t Ke;
1373
- if (!_mongocrypt_buffer_from_subrange (
1374
- &Ke, key, 0, MONGOCRYPT_ENC_KEY_LEN)) {
1375
- CLIENT_ERR ("unable to create Ke view from key");
1376
- return false;
1377
- }
1378
- /* IV is 16 byte IV. */
1379
- _mongocrypt_buffer_t IV;
1380
- if (!_mongocrypt_buffer_from_subrange (&IV, iv, 0, iv->len)) {
1381
- CLIENT_ERR ("unable to create IV view from iv");
1382
- return false;
1383
- }
1384
- /* Km is 32 byte Key for HMAC. */
1385
- _mongocrypt_buffer_t Km;
1386
- if (!_mongocrypt_buffer_from_subrange (
1387
- &Km, key, MONGOCRYPT_ENC_KEY_LEN, MONGOCRYPT_MAC_KEY_LEN)) {
1388
- CLIENT_ERR ("unable to create Km view from key");
1389
- return false;
1390
- }
1391
- /* AD is Associated Data. */
1392
- _mongocrypt_buffer_t AD;
1393
- if (!_mongocrypt_buffer_from_subrange (
1394
- &AD, associated_data, 0, associated_data->len)) {
1395
- CLIENT_ERR ("unable to create AD view from associated_data");
1396
- return false;
1397
- }
1398
- /* C is the output ciphertext. */
1399
- _mongocrypt_buffer_t C;
1400
- if (!_mongocrypt_buffer_from_subrange (&C, ciphertext, 0, ciphertext->len)) {
1401
- CLIENT_ERR ("unable to create C view from ciphertext");
1402
- return false;
1403
- }
1404
- /* S is the output of the symmetric cipher. It is appended after IV in C. */
1405
- _mongocrypt_buffer_t S;
1406
- BSON_ASSERT (C.len >= MONGOCRYPT_IV_LEN + MONGOCRYPT_HMAC_LEN);
1407
- if (!_mongocrypt_buffer_from_subrange (&S,
1408
- &C,
1409
- MONGOCRYPT_IV_LEN,
1410
- C.len - MONGOCRYPT_IV_LEN -
1411
- MONGOCRYPT_HMAC_LEN)) {
1412
- CLIENT_ERR ("unable to create S view from C");
1413
- return false;
1414
- }
1415
- uint32_t S_bytes_written = 0;
1416
- /* T is the output of the HMAC tag. It is appended after S in C. */
1417
- _mongocrypt_buffer_t T;
1418
- if (!_mongocrypt_buffer_from_subrange (
1419
- &T, &C, C.len - MONGOCRYPT_HMAC_LEN, MONGOCRYPT_HMAC_LEN)) {
1420
- CLIENT_ERR ("unable to create T view from C");
1421
- return false;
1422
- }
1423
-
1424
- /* Compute S = AES-CTR.Enc(Ke, IV, M). */
1425
- if (!_crypto_aes_256_ctr_encrypt (
1426
- crypto,
1427
- (aes_256_args_t){.key = &Ke,
1428
- .iv = &IV,
1429
- .in = &M,
1430
- .out = &S,
1431
- .bytes_written = &S_bytes_written,
1432
- .status = status})) {
1433
- return false;
1434
- }
1435
-
1436
- /* Compute T = HMAC-SHA256(Km, AD || IV || S). */
1437
- {
1438
- _mongocrypt_buffer_t hmac_inputs[] = {AD, IV, S};
1439
- _mongocrypt_buffer_t hmac_input = {0};
1440
- _mongocrypt_buffer_concat (&hmac_input, hmac_inputs, 3);
1441
- if (!_mongocrypt_hmac_sha_256 (crypto, &Km, &hmac_input, &T, status)) {
1442
- _mongocrypt_buffer_cleanup (&hmac_input);
1443
- return false;
1444
- }
1445
- _mongocrypt_buffer_cleanup (&hmac_input);
1446
- }
1447
-
1448
- /* Output C = IV || S || T. */
1449
- /* S and T are already in C. Prepend IV. */
1450
- memmove (C.data, IV.data, MONGOCRYPT_IV_LEN);
1451
-
1452
- *bytes_written = MONGOCRYPT_IV_LEN + S_bytes_written + MONGOCRYPT_HMAC_LEN;
1453
- return true;
1454
- }
1455
-
1456
- bool
1457
- _mongocrypt_fle2aead_do_decryption (_mongocrypt_crypto_t *crypto,
1458
- const _mongocrypt_buffer_t *associated_data,
1459
- const _mongocrypt_buffer_t *key,
1460
- const _mongocrypt_buffer_t *ciphertext,
1461
- _mongocrypt_buffer_t *plaintext,
1462
- uint32_t *bytes_written,
1463
- mongocrypt_status_t *status)
1464
- {
1465
- BSON_ASSERT_PARAM (crypto);
1466
- BSON_ASSERT_PARAM (associated_data);
1467
- BSON_ASSERT_PARAM (key);
1468
- BSON_ASSERT_PARAM (ciphertext);
1469
- BSON_ASSERT_PARAM (plaintext);
1470
- BSON_ASSERT_PARAM (bytes_written);
1471
-
1472
- if (ciphertext->len <= MONGOCRYPT_IV_LEN + MONGOCRYPT_HMAC_LEN) {
1473
- CLIENT_ERR ("input ciphertext too small. Must be more than %" PRIu32
1474
- " bytes",
1475
- MONGOCRYPT_IV_LEN + MONGOCRYPT_HMAC_LEN);
1476
- return false;
1477
- }
1478
-
1479
- if (plaintext->len !=
1480
- _mongocrypt_fle2aead_calculate_plaintext_len (ciphertext->len, status)) {
1481
- CLIENT_ERR ("output plaintext must be allocated with %" PRIu32 " bytes",
1482
- _mongocrypt_fle2aead_calculate_plaintext_len (ciphertext->len,
1483
- status));
1484
- return false;
1485
- }
1486
-
1487
- if (MONGOCRYPT_KEY_LEN != key->len) {
1488
- CLIENT_ERR ("key must be length %d, but is length %" PRIu32,
1489
- MONGOCRYPT_KEY_LEN,
1490
- key->len);
1491
- return false;
1492
- }
1493
-
1494
- memset (plaintext->data, 0, plaintext->len);
1495
- *bytes_written = 0;
1496
-
1497
- /* Declare variable names matching [AEAD with
1498
- * CTR](https://docs.google.com/document/d/1eCU7R8Kjr-mdyz6eKvhNIDVmhyYQcAaLtTfHeK7a_vE/).
1499
- */
1500
- /* C is the input ciphertext. */
1501
- _mongocrypt_buffer_t C;
1502
- if (!_mongocrypt_buffer_from_subrange (&C, ciphertext, 0, ciphertext->len)) {
1503
- CLIENT_ERR ("unable to create C view from ciphertext");
1504
- return false;
1505
- }
1506
- /* IV is 16 byte IV. It is the first part of C. */
1507
- _mongocrypt_buffer_t IV;
1508
- if (!_mongocrypt_buffer_from_subrange (
1509
- &IV, ciphertext, 0, MONGOCRYPT_IV_LEN)) {
1510
- CLIENT_ERR ("unable to create IV view from ciphertext");
1511
- return false;
1512
- }
1513
- /* S is the symmetric cipher output from C. It is after the IV in C. */
1514
- _mongocrypt_buffer_t S;
1515
- if (!_mongocrypt_buffer_from_subrange (&S,
1516
- ciphertext,
1517
- MONGOCRYPT_IV_LEN,
1518
- C.len - MONGOCRYPT_IV_LEN -
1519
- MONGOCRYPT_HMAC_LEN)) {
1520
- CLIENT_ERR ("unable to create S view from C");
1521
- return false;
1522
- }
1523
- /* T is the HMAC tag from C. It is after S in C. */
1524
- _mongocrypt_buffer_t T;
1525
- if (!_mongocrypt_buffer_from_subrange (
1526
- &T, &C, C.len - MONGOCRYPT_HMAC_LEN, MONGOCRYPT_HMAC_LEN)) {
1527
- CLIENT_ERR ("unable to create T view from C");
1528
- return false;
1529
- }
1530
- /* Tp is the computed HMAC of the input. */
1531
- _mongocrypt_buffer_t Tp = {0};
1532
- /* M is the output plaintext. */
1533
- _mongocrypt_buffer_t M;
1534
- if (!_mongocrypt_buffer_from_subrange (&M, plaintext, 0, plaintext->len)) {
1535
- CLIENT_ERR ("unable to create M view from plaintext");
1536
- return false;
1537
- }
1538
- /* Ke is 32 byte Key for encryption. */
1539
- _mongocrypt_buffer_t Ke;
1540
- if (!_mongocrypt_buffer_from_subrange (
1541
- &Ke, key, 0, MONGOCRYPT_ENC_KEY_LEN)) {
1542
- CLIENT_ERR ("unable to create Ke view from key");
1543
- return false;
1544
- }
1545
- /* Km is 32 byte Key for HMAC. */
1546
- _mongocrypt_buffer_t Km;
1547
- if (!_mongocrypt_buffer_from_subrange (
1548
- &Km, key, MONGOCRYPT_ENC_KEY_LEN, MONGOCRYPT_MAC_KEY_LEN)) {
1549
- CLIENT_ERR ("unable to create Km view from key");
1550
- return false;
1551
- }
1552
- /* AD is Associated Data. */
1553
- _mongocrypt_buffer_t AD;
1554
- if (!_mongocrypt_buffer_from_subrange (
1555
- &AD, associated_data, 0, associated_data->len)) {
1556
- CLIENT_ERR ("unable to create AD view from associated_data");
1557
- return false;
1558
- }
1559
-
1560
- /* Compute Tp = HMAC-SHA256(Km, AD || IV || S). Check that it matches input
1561
- * ciphertext T. */
1562
- {
1563
- _mongocrypt_buffer_t hmac_inputs[] = {AD, IV, S};
1564
- _mongocrypt_buffer_t hmac_input = {0};
1565
- _mongocrypt_buffer_concat (&hmac_input, hmac_inputs, 3);
1566
- _mongocrypt_buffer_resize (&Tp, MONGOCRYPT_HMAC_LEN);
1567
- if (!_mongocrypt_hmac_sha_256 (crypto, &Km, &hmac_input, &Tp, status)) {
1568
- _mongocrypt_buffer_cleanup (&hmac_input);
1569
- _mongocrypt_buffer_cleanup (&Tp);
1570
- return false;
1571
- }
1572
- if (0 != _mongocrypt_buffer_cmp (&T, &Tp)) {
1573
- CLIENT_ERR ("decryption error");
1574
- _mongocrypt_buffer_cleanup (&hmac_input);
1575
- _mongocrypt_buffer_cleanup (&Tp);
1576
- return false;
1577
- }
1578
- _mongocrypt_buffer_cleanup (&hmac_input);
1579
- _mongocrypt_buffer_cleanup (&Tp);
1580
- }
1581
-
1582
- /* Compute and output M = AES-CTR.Dec(Ke, S) */
1583
- if (!_crypto_aes_256_ctr_decrypt (
1584
- crypto,
1585
- (aes_256_args_t){.key = &Ke,
1586
- .iv = &IV,
1587
- .in = &S,
1588
- .out = &M,
1589
- .bytes_written = bytes_written,
1590
- .status = status})) {
1591
- return false;
1592
- }
1593
-
1594
- return true;
1595
- }
1596
-
1597
- bool
1598
- _mongocrypt_fle2_do_encryption (_mongocrypt_crypto_t *crypto,
1599
- const _mongocrypt_buffer_t *iv,
1600
- const _mongocrypt_buffer_t *key,
1601
- const _mongocrypt_buffer_t *plaintext,
1602
- _mongocrypt_buffer_t *ciphertext,
1603
- uint32_t *bytes_written,
1604
- mongocrypt_status_t *status)
1605
- {
1606
- BSON_ASSERT_PARAM (crypto);
1607
- BSON_ASSERT_PARAM (iv);
1608
- BSON_ASSERT_PARAM (key);
1609
- BSON_ASSERT_PARAM (plaintext);
1610
- BSON_ASSERT_PARAM (ciphertext);
1611
- BSON_ASSERT_PARAM (bytes_written);
1612
-
1613
- if (ciphertext->len !=
1614
- _mongocrypt_fle2_calculate_ciphertext_len (plaintext->len, status)) {
1615
- CLIENT_ERR (
1616
- "output ciphertext must be allocated with %" PRIu32 " bytes",
1617
- _mongocrypt_fle2_calculate_ciphertext_len (plaintext->len, status));
1618
- return false;
1619
- }
1620
-
1621
- if (plaintext->len <= 0) {
1622
- CLIENT_ERR ("input plaintext too small. Must be more than zero bytes.");
1623
- return false;
1624
- }
1625
-
1626
- if (MONGOCRYPT_IV_LEN != iv->len) {
1627
- CLIENT_ERR ("IV must be length %d, but is length %" PRIu32,
1628
- MONGOCRYPT_IV_LEN,
1629
- iv->len);
1630
- return false;
1631
- }
1632
- if (MONGOCRYPT_ENC_KEY_LEN != key->len) {
1633
- CLIENT_ERR ("key must be length %d, but is length %" PRIu32,
1634
- MONGOCRYPT_ENC_KEY_LEN,
1635
- key->len);
1636
- return false;
1637
- }
1638
-
1639
- BSON_ASSERT (ciphertext->len >= MONGOCRYPT_IV_LEN);
1640
- memset (ciphertext->data + MONGOCRYPT_IV_LEN,
1641
- 0,
1642
- ciphertext->len - MONGOCRYPT_IV_LEN);
1643
- *bytes_written = 0;
1644
-
1645
- /* Declare variable names matching [AEAD with
1646
- * CTR](https://docs.google.com/document/d/1eCU7R8Kjr-mdyz6eKvhNIDVmhyYQcAaLtTfHeK7a_vE/).
1647
- */
1648
- /* M is the input plaintext. */
1649
- _mongocrypt_buffer_t M = *plaintext;
1650
- /* Ke is 32 byte Key for encryption. */
1651
- _mongocrypt_buffer_t Ke = *key;
1652
- /* IV is 16 byte IV. */
1653
- _mongocrypt_buffer_t IV = *iv;
1654
- /* C is the output ciphertext. */
1655
- _mongocrypt_buffer_t C = *ciphertext;
1656
- /* S is the output of the symmetric cipher. It is appended after IV in C. */
1657
- _mongocrypt_buffer_t S;
1658
- if (!_mongocrypt_buffer_from_subrange (
1659
- &S, &C, MONGOCRYPT_IV_LEN, C.len - MONGOCRYPT_IV_LEN)) {
1660
- CLIENT_ERR ("unable to create S view from C");
1661
- return false;
1662
- }
1663
- uint32_t S_bytes_written = 0;
1664
-
1665
- /* Compute S = AES-CTR.Enc(Ke, IV, M). */
1666
- if (!_crypto_aes_256_ctr_encrypt (
1667
- crypto,
1668
- (aes_256_args_t){.key = &Ke,
1669
- .iv = &IV,
1670
- .in = &M,
1671
- .out = &S,
1672
- .bytes_written = &S_bytes_written,
1673
- .status = status})) {
1674
- return false;
1675
- }
1676
-
1677
- if (S_bytes_written != M.len) {
1678
- CLIENT_ERR ("expected S_bytes_written=%" PRIu32 " got %" PRIu32,
1679
- M.len,
1680
- S_bytes_written);
1681
- return false;
1682
- }
1683
-
1684
- /* Output C = IV || S. */
1685
- /* S is already in C. Prepend IV. */
1686
- memmove (C.data, IV.data, MONGOCRYPT_IV_LEN);
1687
-
1688
- *bytes_written = MONGOCRYPT_IV_LEN + S_bytes_written;
1689
- return true;
1324
+ _mongocrypt_buffer_cleanup(&iv);
1325
+ return ret;
1690
1326
  }
1691
1327
 
1692
- bool
1693
- _mongocrypt_fle2_do_decryption (_mongocrypt_crypto_t *crypto,
1694
- const _mongocrypt_buffer_t *key,
1695
- const _mongocrypt_buffer_t *ciphertext,
1696
- _mongocrypt_buffer_t *plaintext,
1697
- uint32_t *bytes_written,
1698
- mongocrypt_status_t *status)
1699
- {
1700
- BSON_ASSERT_PARAM (crypto);
1701
- BSON_ASSERT_PARAM (key);
1702
- BSON_ASSERT_PARAM (ciphertext);
1703
- BSON_ASSERT_PARAM (plaintext);
1704
- BSON_ASSERT_PARAM (bytes_written);
1705
-
1706
- if (ciphertext->len <= MONGOCRYPT_IV_LEN) {
1707
- CLIENT_ERR ("input ciphertext too small. Must be more than %" PRIu32
1708
- " bytes",
1709
- MONGOCRYPT_IV_LEN);
1710
- return false;
1711
- }
1712
-
1713
- if (plaintext->len !=
1714
- _mongocrypt_fle2_calculate_plaintext_len (ciphertext->len, status)) {
1715
- CLIENT_ERR (
1716
- "output plaintext must be allocated with %" PRIu32 " bytes",
1717
- _mongocrypt_fle2_calculate_plaintext_len (ciphertext->len, status));
1718
- return false;
1719
- }
1720
-
1721
- if (MONGOCRYPT_ENC_KEY_LEN != key->len) {
1722
- CLIENT_ERR ("key must be length %d, but is length %" PRIu32,
1723
- MONGOCRYPT_ENC_KEY_LEN,
1724
- key->len);
1725
- return false;
1726
- }
1727
-
1728
- memset (plaintext->data, 0, plaintext->len);
1729
- *bytes_written = 0;
1730
-
1731
- /* Declare variable names matching [AEAD with
1732
- * CTR](https://docs.google.com/document/d/1eCU7R8Kjr-mdyz6eKvhNIDVmhyYQcAaLtTfHeK7a_vE/).
1733
- */
1734
- /* C is the input ciphertext. */
1735
- _mongocrypt_buffer_t C = *ciphertext;
1736
- /* IV is 16 byte IV. It is the first part of C. */
1737
- _mongocrypt_buffer_t IV;
1738
- if (!_mongocrypt_buffer_from_subrange (
1739
- &IV, ciphertext, 0, MONGOCRYPT_IV_LEN)) {
1740
- CLIENT_ERR ("unable to create IV view from ciphertext");
1741
- return false;
1742
- }
1743
- /* S is the symmetric cipher output from C. It is after the IV in C. */
1744
- _mongocrypt_buffer_t S;
1745
- if (!_mongocrypt_buffer_from_subrange (
1746
- &S, ciphertext, MONGOCRYPT_IV_LEN, C.len - MONGOCRYPT_IV_LEN)) {
1747
- CLIENT_ERR ("unable to create S view from C");
1748
- return false;
1749
- }
1750
- /* M is the output plaintext. */
1751
- _mongocrypt_buffer_t M = *plaintext;
1752
- /* Ke is 32 byte Key for encryption. */
1753
- _mongocrypt_buffer_t Ke = *key;
1754
-
1755
- /* Compute and output M = AES-CTR.Dec(Ke, S) */
1756
- if (!_crypto_aes_256_ctr_decrypt (
1757
- crypto,
1758
- (aes_256_args_t){.key = &Ke,
1759
- .iv = &IV,
1760
- .in = &S,
1761
- .out = &M,
1762
- .bytes_written = bytes_written,
1763
- .status = status})) {
1764
- return false;
1765
- }
1766
-
1767
- if (*bytes_written != S.len) {
1768
- CLIENT_ERR ("expected bytes_written=%" PRIu32 " got %" PRIu32,
1769
- S.len,
1770
- *bytes_written);
1771
- return false;
1772
- }
1773
-
1774
- return true;
1328
+ bool _mongocrypt_unwrap_key(_mongocrypt_crypto_t *crypto,
1329
+ _mongocrypt_buffer_t *kek,
1330
+ _mongocrypt_buffer_t *encrypted_dek,
1331
+ _mongocrypt_buffer_t *dek,
1332
+ mongocrypt_status_t *status) {
1333
+ const _mongocrypt_value_encryption_algorithm_t *fle1alg = _mcFLE1Algorithm();
1334
+ uint32_t bytes_written;
1335
+
1336
+ BSON_ASSERT_PARAM(crypto);
1337
+ BSON_ASSERT_PARAM(kek);
1338
+ BSON_ASSERT_PARAM(dek);
1339
+ BSON_ASSERT_PARAM(encrypted_dek);
1340
+
1341
+ // _mongocrypt_wrap_key() uses FLE1 algorithm parameters.
1342
+ _mongocrypt_buffer_init(dek);
1343
+ _mongocrypt_buffer_resize(dek, fle1alg->get_plaintext_len(encrypted_dek->len, status));
1344
+
1345
+ if (!fle1alg->do_decrypt(crypto, NULL /* associated data. */, kek, encrypted_dek, dek, &bytes_written, status)) {
1346
+ return false;
1347
+ }
1348
+ dek->len = bytes_written;
1349
+
1350
+ if (dek->len != MONGOCRYPT_KEY_LEN) {
1351
+ CLIENT_ERR("decrypted key is incorrect length, expected: %" PRIu32 ", got: %" PRIu32,
1352
+ MONGOCRYPT_KEY_LEN,
1353
+ dek->len);
1354
+ return false;
1355
+ }
1356
+ return true;
1775
1357
  }
1776
1358
 
1777
1359
  /* This implementation avoids modulo bias. It is based on arc4random_uniform:
1778
1360
  https://github.com/openbsd/src/blob/2207c4325726fdc5c4bcd0011af0fdf7d3dab137/lib/libc/crypt/arc4random_uniform.c#L33
1779
1361
  */
1780
- bool
1781
- _mongocrypt_random_uint64 (_mongocrypt_crypto_t *crypto,
1782
- uint64_t exclusive_upper_bound,
1783
- uint64_t *out,
1784
- mongocrypt_status_t *status)
1785
- {
1786
- BSON_ASSERT_PARAM (crypto);
1787
- BSON_ASSERT_PARAM (out);
1788
-
1789
- *out = 0;
1790
-
1791
- if (exclusive_upper_bound < 2) {
1792
- *out = 0;
1793
- return true;
1794
- }
1795
-
1796
- /* 2**64 % x == (2**64 - x) % x */
1797
- uint64_t min = (0 - exclusive_upper_bound) % exclusive_upper_bound;
1798
-
1799
- _mongocrypt_buffer_t rand_u64_buf;
1800
- _mongocrypt_buffer_init (&rand_u64_buf);
1801
- _mongocrypt_buffer_resize (&rand_u64_buf, (uint32_t) sizeof (uint64_t));
1802
-
1803
- uint64_t rand_u64;
1804
- for (;;) {
1805
- if (!_mongocrypt_random (
1806
- crypto, &rand_u64_buf, rand_u64_buf.len, status)) {
1807
- _mongocrypt_buffer_cleanup (&rand_u64_buf);
1808
- return false;
1809
- }
1810
-
1811
- memcpy (&rand_u64, rand_u64_buf.data, rand_u64_buf.len);
1812
-
1813
- if (rand_u64 >= min) {
1814
- break;
1815
- }
1816
- }
1817
-
1818
- *out = rand_u64 % exclusive_upper_bound;
1819
-
1820
- _mongocrypt_buffer_cleanup (&rand_u64_buf);
1821
- return true;
1362
+ bool _mongocrypt_random_uint64(_mongocrypt_crypto_t *crypto,
1363
+ uint64_t exclusive_upper_bound,
1364
+ uint64_t *out,
1365
+ mongocrypt_status_t *status) {
1366
+ BSON_ASSERT_PARAM(crypto);
1367
+ BSON_ASSERT_PARAM(out);
1368
+
1369
+ *out = 0;
1370
+
1371
+ if (exclusive_upper_bound < 2) {
1372
+ *out = 0;
1373
+ return true;
1374
+ }
1375
+
1376
+ /* 2**64 % x == (2**64 - x) % x */
1377
+ uint64_t min = (0 - exclusive_upper_bound) % exclusive_upper_bound;
1378
+
1379
+ _mongocrypt_buffer_t rand_u64_buf;
1380
+ _mongocrypt_buffer_init(&rand_u64_buf);
1381
+ _mongocrypt_buffer_resize(&rand_u64_buf, (uint32_t)sizeof(uint64_t));
1382
+
1383
+ uint64_t rand_u64;
1384
+ for (;;) {
1385
+ if (!_mongocrypt_random(crypto, &rand_u64_buf, rand_u64_buf.len, status)) {
1386
+ _mongocrypt_buffer_cleanup(&rand_u64_buf);
1387
+ return false;
1388
+ }
1389
+
1390
+ memcpy(&rand_u64, rand_u64_buf.data, rand_u64_buf.len);
1391
+ // Use little-endian to enable deterministic tests on big-endian machines.
1392
+ rand_u64 = BSON_UINT64_FROM_LE(rand_u64);
1393
+
1394
+ if (rand_u64 >= min) {
1395
+ break;
1396
+ }
1397
+ }
1398
+
1399
+ *out = rand_u64 % exclusive_upper_bound;
1400
+
1401
+ _mongocrypt_buffer_cleanup(&rand_u64_buf);
1402
+ return true;
1822
1403
  }
1823
1404
 
1824
- bool
1825
- _mongocrypt_random_int64 (_mongocrypt_crypto_t *crypto,
1826
- int64_t exclusive_upper_bound,
1827
- int64_t *out,
1828
- mongocrypt_status_t *status)
1829
- {
1830
- BSON_ASSERT_PARAM (crypto);
1831
- BSON_ASSERT_PARAM (out);
1832
-
1833
- if (exclusive_upper_bound <= 0) {
1834
- CLIENT_ERR ("Expected exclusive_upper_bound > 0");
1835
- return false;
1836
- }
1837
-
1838
- uint64_t u64_exclusive_upper_bound = (uint64_t) exclusive_upper_bound;
1839
- uint64_t u64_out;
1840
-
1841
- if (!_mongocrypt_random_uint64 (
1842
- crypto, u64_exclusive_upper_bound, &u64_out, status)) {
1843
- return false;
1844
- }
1845
-
1846
- /* Zero the leading bit to ensure rand_i64 is non-negative. */
1847
- u64_out &= (~(1ull << 63));
1848
- *out = (int64_t) u64_out;
1849
- return true;
1405
+ bool _mongocrypt_random_int64(_mongocrypt_crypto_t *crypto,
1406
+ int64_t exclusive_upper_bound,
1407
+ int64_t *out,
1408
+ mongocrypt_status_t *status) {
1409
+ BSON_ASSERT_PARAM(crypto);
1410
+ BSON_ASSERT_PARAM(out);
1411
+
1412
+ if (exclusive_upper_bound <= 0) {
1413
+ CLIENT_ERR("Expected exclusive_upper_bound > 0");
1414
+ return false;
1415
+ }
1416
+
1417
+ uint64_t u64_exclusive_upper_bound = (uint64_t)exclusive_upper_bound;
1418
+ uint64_t u64_out;
1419
+
1420
+ if (!_mongocrypt_random_uint64(crypto, u64_exclusive_upper_bound, &u64_out, status)) {
1421
+ return false;
1422
+ }
1423
+
1424
+ /* Zero the leading bit to ensure rand_i64 is non-negative. */
1425
+ u64_out &= (~(1ull << 63));
1426
+ *out = (int64_t)u64_out;
1427
+ return true;
1850
1428
  }