react-native-quick-crypto 1.0.0 → 1.0.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (92) hide show
  1. package/QuickCrypto.podspec +19 -52
  2. package/android/CMakeLists.txt +4 -2
  3. package/android/build.gradle +1 -1
  4. package/cpp/cipher/HybridCipher.cpp +20 -3
  5. package/cpp/cipher/HybridRsaCipher.cpp +20 -1
  6. package/cpp/ed25519/HybridEdKeyPair.cpp +8 -2
  7. package/cpp/keys/HybridKeyObjectHandle.cpp +8 -0
  8. package/cpp/keys/KeyObjectData.hpp +1 -1
  9. package/cpp/mldsa/HybridMlDsaKeyPair.cpp +264 -0
  10. package/cpp/mldsa/HybridMlDsaKeyPair.hpp +47 -0
  11. package/cpp/sign/HybridSignHandle.cpp +97 -22
  12. package/cpp/sign/HybridVerifyHandle.cpp +90 -21
  13. package/deps/ncrypto/.bazelignore +4 -0
  14. package/deps/ncrypto/.bazelrc +2 -0
  15. package/deps/ncrypto/.bazelversion +1 -0
  16. package/deps/ncrypto/.clang-format +111 -0
  17. package/deps/ncrypto/.github/workflows/bazel.yml +58 -0
  18. package/deps/ncrypto/.github/workflows/linter.yml +38 -0
  19. package/deps/ncrypto/.github/workflows/macos.yml +43 -0
  20. package/deps/ncrypto/.github/workflows/ubuntu.yml +46 -0
  21. package/deps/ncrypto/.github/workflows/visual-studio.yml +49 -0
  22. package/deps/ncrypto/.python-version +1 -0
  23. package/deps/ncrypto/BUILD.bazel +36 -0
  24. package/deps/ncrypto/CMakeLists.txt +55 -0
  25. package/deps/ncrypto/LICENSE +21 -0
  26. package/deps/ncrypto/MODULE.bazel +1 -0
  27. package/deps/ncrypto/MODULE.bazel.lock +280 -0
  28. package/deps/ncrypto/README.md +18 -0
  29. package/deps/ncrypto/WORKSPACE +15 -0
  30. package/deps/ncrypto/cmake/CPM.cmake +1225 -0
  31. package/deps/ncrypto/cmake/ncrypto-flags.cmake +16 -0
  32. package/deps/ncrypto/include/dh-primes.h +67 -0
  33. package/deps/ncrypto/{ncrypto.h → include/ncrypto.h} +361 -89
  34. package/deps/ncrypto/patches/0001-Expose-libdecrepit-so-NodeJS-can-use-it-for-ncrypto.patch +28 -0
  35. package/deps/ncrypto/pyproject.toml +38 -0
  36. package/deps/ncrypto/src/CMakeLists.txt +15 -0
  37. package/deps/ncrypto/src/engine.cpp +93 -0
  38. package/deps/ncrypto/{ncrypto.cc → src/ncrypto.cpp} +1168 -234
  39. package/deps/ncrypto/tests/BUILD.bazel +9 -0
  40. package/deps/ncrypto/tests/CMakeLists.txt +7 -0
  41. package/deps/ncrypto/tests/basic.cpp +86 -0
  42. package/deps/ncrypto/tools/run-clang-format.sh +42 -0
  43. package/lib/commonjs/ed.js +68 -0
  44. package/lib/commonjs/ed.js.map +1 -1
  45. package/lib/commonjs/keys/classes.js +6 -0
  46. package/lib/commonjs/keys/classes.js.map +1 -1
  47. package/lib/commonjs/mldsa.js +69 -0
  48. package/lib/commonjs/mldsa.js.map +1 -0
  49. package/lib/commonjs/specs/mlDsaKeyPair.nitro.js +6 -0
  50. package/lib/commonjs/specs/mlDsaKeyPair.nitro.js.map +1 -0
  51. package/lib/commonjs/subtle.js +483 -13
  52. package/lib/commonjs/subtle.js.map +1 -1
  53. package/lib/commonjs/utils/types.js.map +1 -1
  54. package/lib/module/ed.js +66 -0
  55. package/lib/module/ed.js.map +1 -1
  56. package/lib/module/keys/classes.js +6 -0
  57. package/lib/module/keys/classes.js.map +1 -1
  58. package/lib/module/mldsa.js +63 -0
  59. package/lib/module/mldsa.js.map +1 -0
  60. package/lib/module/specs/mlDsaKeyPair.nitro.js +4 -0
  61. package/lib/module/specs/mlDsaKeyPair.nitro.js.map +1 -0
  62. package/lib/module/subtle.js +484 -14
  63. package/lib/module/subtle.js.map +1 -1
  64. package/lib/module/utils/types.js.map +1 -1
  65. package/lib/tsconfig.tsbuildinfo +1 -1
  66. package/lib/typescript/ed.d.ts +4 -1
  67. package/lib/typescript/ed.d.ts.map +1 -1
  68. package/lib/typescript/index.d.ts +2 -0
  69. package/lib/typescript/index.d.ts.map +1 -1
  70. package/lib/typescript/keys/classes.d.ts +2 -0
  71. package/lib/typescript/keys/classes.d.ts.map +1 -1
  72. package/lib/typescript/mldsa.d.ts +18 -0
  73. package/lib/typescript/mldsa.d.ts.map +1 -0
  74. package/lib/typescript/specs/mlDsaKeyPair.nitro.d.ts +16 -0
  75. package/lib/typescript/specs/mlDsaKeyPair.nitro.d.ts.map +1 -0
  76. package/lib/typescript/subtle.d.ts +4 -1
  77. package/lib/typescript/subtle.d.ts.map +1 -1
  78. package/lib/typescript/utils/types.d.ts +14 -6
  79. package/lib/typescript/utils/types.d.ts.map +1 -1
  80. package/nitrogen/generated/android/QuickCrypto+autolinking.cmake +1 -0
  81. package/nitrogen/generated/android/QuickCryptoOnLoad.cpp +10 -0
  82. package/nitrogen/generated/ios/QuickCryptoAutolinking.mm +10 -0
  83. package/nitrogen/generated/shared/c++/AsymmetricKeyType.hpp +12 -0
  84. package/nitrogen/generated/shared/c++/HybridMlDsaKeyPairSpec.cpp +29 -0
  85. package/nitrogen/generated/shared/c++/HybridMlDsaKeyPairSpec.hpp +73 -0
  86. package/package.json +7 -3
  87. package/src/ed.ts +102 -0
  88. package/src/keys/classes.ts +9 -0
  89. package/src/mldsa.ts +125 -0
  90. package/src/specs/mlDsaKeyPair.nitro.ts +29 -0
  91. package/src/subtle.ts +667 -17
  92. package/src/utils/types.ts +27 -6
@@ -1,4 +1,5 @@
1
1
  #include "ncrypto.h"
2
+
2
3
  #include <openssl/asn1.h>
3
4
  #include <openssl/bn.h>
4
5
  #include <openssl/dh.h>
@@ -7,8 +8,21 @@
7
8
  #include <openssl/pkcs12.h>
8
9
  #include <openssl/rand.h>
9
10
  #include <openssl/x509v3.h>
11
+
12
+ #ifndef NCRYPTO_NO_KDF_H
13
+ #include <openssl/kdf.h>
14
+ #else
15
+ #include <openssl/hkdf.h>
16
+ #endif
17
+
10
18
  #include <algorithm>
19
+ #include <array>
20
+ #include <cctype>
21
+ #include <climits>
11
22
  #include <cstring>
23
+ #include <string_view>
24
+ #include <vector>
25
+
12
26
  #if OPENSSL_VERSION_MAJOR >= 3
13
27
  #include <openssl/core_names.h>
14
28
  #include <openssl/params.h>
@@ -57,6 +71,8 @@ constexpr static PQCMapping pqc_mappings[] = {
57
71
  nullptr)
58
72
  #endif
59
73
 
74
+ // ============================================================================
75
+
60
76
  namespace ncrypto {
61
77
  namespace {
62
78
  using BignumCtxPointer = DeleteFnPtr<BN_CTX, BN_CTX_free>;
@@ -245,7 +261,7 @@ Buffer<void> DataPointer::release() {
245
261
  DataPointer DataPointer::resize(size_t len) {
246
262
  size_t actual_len = std::min(len_, len);
247
263
  auto buf = release();
248
- if (actual_len == len_) return DataPointer(buf.data, actual_len);
264
+ if (actual_len == len_) return DataPointer(buf);
249
265
  buf.data = OPENSSL_realloc(buf.data, actual_len);
250
266
  buf.len = actual_len;
251
267
  return DataPointer(buf);
@@ -286,7 +302,7 @@ bool testFipsEnabled() {
286
302
  #else
287
303
  #ifdef OPENSSL_FIPS
288
304
  return FIPS_selftest();
289
- #else // OPENSSL_FIPS
305
+ #else // OPENSSL_FIPS
290
306
  return false;
291
307
  #endif // OPENSSL_FIPS
292
308
  #endif
@@ -338,10 +354,15 @@ BIGNUM* BignumPointer::release() {
338
354
  }
339
355
 
340
356
  size_t BignumPointer::byteLength() const {
341
- if (bn_ == nullptr) return 0;
357
+ if (!bn_) return 0;
342
358
  return BN_num_bytes(bn_.get());
343
359
  }
344
360
 
361
+ size_t BignumPointer::bitLength() const {
362
+ if (!bn_) return 0;
363
+ return BN_num_bits(bn_.get());
364
+ }
365
+
345
366
  DataPointer BignumPointer::encode() const {
346
367
  return EncodePadded(bn_.get(), byteLength());
347
368
  }
@@ -451,6 +472,7 @@ int BignumPointer::isPrime(int nchecks,
451
472
  // TODO(@jasnell): This could be refactored to allow inlining.
452
473
  // Not too important right now tho.
453
474
  [](int a, int b, BN_GENCB* ctx) mutable -> int {
475
+ // BN_GENCB is opaque in OpenSSL 3.x, must use accessor
454
476
  PrimeCheckCallback& ptr =
455
477
  *static_cast<PrimeCheckCallback*>(BN_GENCB_get_arg(ctx));
456
478
  return ptr(a, b) ? 1 : 0;
@@ -482,6 +504,7 @@ bool BignumPointer::generate(const PrimeConfig& params,
482
504
  BN_GENCB_set(
483
505
  cb.get(),
484
506
  [](int a, int b, BN_GENCB* ctx) mutable -> int {
507
+ // BN_GENCB is opaque in OpenSSL 3.x, must use accessor
485
508
  PrimeCheckCallback& ptr =
486
509
  *static_cast<PrimeCheckCallback*>(BN_GENCB_get_arg(ctx));
487
510
  return ptr(a, b) ? 1 : 0;
@@ -612,7 +635,9 @@ int64_t PortableTimeGM(struct tm* t) {
612
635
  // ============================================================================
613
636
  // SPKAC
614
637
 
615
- bool VerifySpkac(const char* input, size_t length) {
638
+ namespace {
639
+ bool VerifySpkacImpl(const char* input, size_t length) {
640
+ ClearErrorOnReturn clearErrorOnReturn;
616
641
  #ifdef OPENSSL_IS_BORINGSSL
617
642
  // OpenSSL uses EVP_DecodeBlock, which explicitly removes trailing characters,
618
643
  // while BoringSSL uses EVP_DecodedLength and EVP_DecodeBase64, which do not.
@@ -630,9 +655,11 @@ bool VerifySpkac(const char* input, size_t length) {
630
655
  return pkey ? NETSCAPE_SPKI_verify(spki.get(), pkey.get()) > 0 : false;
631
656
  }
632
657
 
633
- BIOPointer ExportPublicKey(const char* input, size_t length) {
634
- BIOPointer bio(BIO_new(BIO_s_mem()));
635
- if (!bio) return {};
658
+ BIOPointer ExportPublicKeyImpl(const char* input, size_t length) {
659
+ ClearErrorOnReturn clearErrorOnReturn;
660
+ auto bio = BIOPointer::NewMem();
661
+ if (!bio) [[unlikely]]
662
+ return {};
636
663
 
637
664
  #ifdef OPENSSL_IS_BORINGSSL
638
665
  // OpenSSL uses EVP_DecodeBlock, which explicitly removes trailing characters,
@@ -641,17 +668,21 @@ BIOPointer ExportPublicKey(const char* input, size_t length) {
641
668
  length = std::string_view(input, length).find_last_not_of(" \n\r\t") + 1;
642
669
  #endif
643
670
  NetscapeSPKIPointer spki(NETSCAPE_SPKI_b64_decode(input, length));
644
- if (!spki) return {};
671
+ if (!spki) [[unlikely]] {
672
+ return {};
673
+ }
645
674
 
646
675
  EVPKeyPointer pkey(NETSCAPE_SPKI_get_pubkey(spki.get()));
647
- if (!pkey) return {};
648
676
 
649
- if (PEM_write_bio_PUBKEY(bio.get(), pkey.get()) <= 0) return {};
677
+ if (!pkey || PEM_write_bio_PUBKEY(bio.get(), pkey.get()) <= 0) [[unlikely]] {
678
+ return {};
679
+ }
650
680
 
651
681
  return bio;
652
682
  }
653
683
 
654
- Buffer<char> ExportChallenge(const char* input, size_t length) {
684
+ DataPointer ExportChallengeImpl(const char* input, size_t length) {
685
+ ClearErrorOnReturn clearErrorOnReturn;
655
686
  #ifdef OPENSSL_IS_BORINGSSL
656
687
  // OpenSSL uses EVP_DecodeBlock, which explicitly removes trailing characters,
657
688
  // while BoringSSL uses EVP_DecodedLength and EVP_DecodeBase64, which do not.
@@ -664,14 +695,46 @@ Buffer<char> ExportChallenge(const char* input, size_t length) {
664
695
  unsigned char* buf = nullptr;
665
696
  int buf_size = ASN1_STRING_to_UTF8(&buf, sp->spkac->challenge);
666
697
  if (buf_size >= 0) {
667
- return {
698
+ return DataPointer({
668
699
  .data = reinterpret_cast<char*>(buf),
669
700
  .len = static_cast<size_t>(buf_size),
670
- };
701
+ });
671
702
  }
672
703
 
673
704
  return {};
674
705
  }
706
+ } // namespace
707
+
708
+ bool VerifySpkac(const Buffer<const char>& input) {
709
+ return VerifySpkacImpl(input.data, input.len);
710
+ }
711
+
712
+ BIOPointer ExportPublicKey(const Buffer<const char>& input) {
713
+ return ExportPublicKeyImpl(input.data, input.len);
714
+ }
715
+
716
+ DataPointer ExportChallenge(const Buffer<const char>& input) {
717
+ return ExportChallengeImpl(input.data, input.len);
718
+ }
719
+
720
+ bool VerifySpkac(const char* input, size_t length) {
721
+ return VerifySpkacImpl(input, length);
722
+ }
723
+
724
+ BIOPointer ExportPublicKey(const char* input, size_t length) {
725
+ return ExportPublicKeyImpl(input, length);
726
+ }
727
+
728
+ Buffer<char> ExportChallenge(const char* input, size_t length) {
729
+ if (auto dp = ExportChallengeImpl(input, length)) {
730
+ auto released = dp.release();
731
+ return Buffer<char>{
732
+ .data = static_cast<char*>(released.data),
733
+ .len = released.len,
734
+ };
735
+ }
736
+ return {};
737
+ }
675
738
 
676
739
  // ============================================================================
677
740
  namespace {
@@ -1094,8 +1157,32 @@ BIOPointer X509View::getValidTo() const {
1094
1157
  return bio;
1095
1158
  }
1096
1159
 
1160
+ std::optional<std::string_view> X509View::getSignatureAlgorithm() const {
1161
+ if (cert_ == nullptr) return std::nullopt;
1162
+ int nid = X509_get_signature_nid(cert_);
1163
+ if (nid == NID_undef) return std::nullopt;
1164
+ const char* ln = OBJ_nid2ln(nid);
1165
+ if (ln == nullptr) return std::nullopt;
1166
+ return std::string_view(ln);
1167
+ }
1168
+
1169
+ std::optional<std::string> X509View::getSignatureAlgorithmOID() const {
1170
+ if (cert_ == nullptr) return std::nullopt;
1171
+ const X509_ALGOR* alg = nullptr;
1172
+ X509_get0_signature(nullptr, &alg, cert_);
1173
+ if (alg == nullptr) return std::nullopt;
1174
+ const ASN1_OBJECT* obj = nullptr;
1175
+ X509_ALGOR_get0(&obj, nullptr, nullptr, alg);
1176
+ if (obj == nullptr) return std::nullopt;
1177
+ std::array<char, 128> buf{};
1178
+ int len = OBJ_obj2txt(buf.data(), buf.size(), obj, 1);
1179
+ if (len < 0 || static_cast<size_t>(len) >= buf.size()) return std::nullopt;
1180
+ return std::string(buf.data(), static_cast<size_t>(len));
1181
+ }
1182
+
1097
1183
  int64_t X509View::getValidToTime() const {
1098
1184
  #ifdef OPENSSL_IS_BORINGSSL
1185
+ #ifndef NCRYPTO_NO_ASN1_TIME
1099
1186
  // Boringssl does not implement ASN1_TIME_to_tm in a public way,
1100
1187
  // and only recently added ASN1_TIME_to_posix. Some boringssl
1101
1188
  // users on older version may still need to patch around this
@@ -1104,6 +1191,11 @@ int64_t X509View::getValidToTime() const {
1104
1191
  ASN1_TIME_to_posix(X509_get0_notAfter(cert_), &tp);
1105
1192
  return tp;
1106
1193
  #else
1194
+ // Older versions of Boringssl do not implement the ASN1_TIME_to_*
1195
+ // version functions. For now, neither shall we.
1196
+ return 0LL;
1197
+ #endif // NCRYPTO_NO_ASN1_TIME
1198
+ #else // OPENSSL_IS_BORINGSSL
1107
1199
  struct tm tp;
1108
1200
  ASN1_TIME_to_tm(X509_get0_notAfter(cert_), &tp);
1109
1201
  return PortableTimeGM(&tp);
@@ -1112,9 +1204,15 @@ int64_t X509View::getValidToTime() const {
1112
1204
 
1113
1205
  int64_t X509View::getValidFromTime() const {
1114
1206
  #ifdef OPENSSL_IS_BORINGSSL
1207
+ #ifndef NCRYPTO_NO_ASN1_TIME
1115
1208
  int64_t tp;
1116
1209
  ASN1_TIME_to_posix(X509_get0_notBefore(cert_), &tp);
1117
1210
  return tp;
1211
+ #else
1212
+ // Older versions of Boringssl do not implement the ASN1_TIME_to_*
1213
+ // version functions. For now, neither shall we.
1214
+ return 0LL;
1215
+ #endif // NCRYPTO_NO_ASN1_TIME
1118
1216
  #else
1119
1217
  struct tm tp;
1120
1218
  ASN1_TIME_to_tm(X509_get0_notBefore(cert_), &tp);
@@ -1308,10 +1406,16 @@ bool X509View::enumUsages(UsageCallback callback) const {
1308
1406
 
1309
1407
  bool X509View::ifRsa(KeyCallback<Rsa> callback) const {
1310
1408
  if (cert_ == nullptr) return true;
1311
- OSSL3_CONST EVP_PKEY* pkey = X509_get0_pubkey(cert_);
1312
- auto id = EVP_PKEY_id(pkey);
1409
+ // The const_cast is a bit unfortunate. The X509_get_pubkey API accepts
1410
+ // a const X509* in newer versions of openssl and boringssl but a non-const
1411
+ // X509* in older versions. By removing the const if it exists we can
1412
+ // support both.
1413
+ EVPKeyPointer pkey(X509_get_pubkey(const_cast<X509*>(cert_)));
1414
+ if (!pkey) [[unlikely]]
1415
+ return true;
1416
+ auto id = pkey.id();
1313
1417
  if (id == EVP_PKEY_RSA || id == EVP_PKEY_RSA2 || id == EVP_PKEY_RSA_PSS) {
1314
- Rsa rsa(EVP_PKEY_get0_RSA(pkey));
1418
+ Rsa rsa = pkey;
1315
1419
  if (!rsa) [[unlikely]]
1316
1420
  return true;
1317
1421
  return callback(rsa);
@@ -1321,10 +1425,16 @@ bool X509View::ifRsa(KeyCallback<Rsa> callback) const {
1321
1425
 
1322
1426
  bool X509View::ifEc(KeyCallback<Ec> callback) const {
1323
1427
  if (cert_ == nullptr) return true;
1324
- OSSL3_CONST EVP_PKEY* pkey = X509_get0_pubkey(cert_);
1325
- auto id = EVP_PKEY_id(pkey);
1428
+ // The const_cast is a bit unfortunate. The X509_get_pubkey API accepts
1429
+ // a const X509* in newer versions of openssl and boringssl but a non-const
1430
+ // X509* in older versions. By removing the const if it exists we can
1431
+ // support both.
1432
+ EVPKeyPointer pkey(X509_get_pubkey(const_cast<X509*>(cert_)));
1433
+ if (!pkey) [[unlikely]]
1434
+ return true;
1435
+ auto id = pkey.id();
1326
1436
  if (id == EVP_PKEY_EC) {
1327
- Ec ec(EVP_PKEY_get0_EC_KEY(pkey));
1437
+ Ec ec = pkey;
1328
1438
  if (!ec) [[unlikely]]
1329
1439
  return true;
1330
1440
  return callback(ec);
@@ -1758,18 +1868,28 @@ bool checkHkdfLength(const Digest& md, size_t length) {
1758
1868
  return true;
1759
1869
  }
1760
1870
 
1761
- DataPointer hkdf(const Digest& md,
1762
- const Buffer<const unsigned char>& key,
1763
- const Buffer<const unsigned char>& info,
1764
- const Buffer<const unsigned char>& salt,
1765
- size_t length) {
1871
+ bool hkdfInfo(const Digest& md,
1872
+ const Buffer<const unsigned char>& key,
1873
+ const Buffer<const unsigned char>& info,
1874
+ const Buffer<const unsigned char>& salt,
1875
+ size_t length,
1876
+ Buffer<unsigned char>* out) {
1766
1877
  ClearErrorOnReturn clearErrorOnReturn;
1767
1878
 
1768
1879
  if (!checkHkdfLength(md, length) || info.len > INT_MAX ||
1769
1880
  salt.len > INT_MAX) {
1770
- return {};
1881
+ return false;
1882
+ }
1883
+
1884
+ std::string_view actual_salt;
1885
+ static const char default_salt[EVP_MAX_MD_SIZE] = {0};
1886
+ if (salt.len > 0) {
1887
+ actual_salt = {reinterpret_cast<const char*>(salt.data), salt.len};
1888
+ } else {
1889
+ actual_salt = {default_salt, static_cast<unsigned>(md.size())};
1771
1890
  }
1772
1891
 
1892
+ #ifndef NCRYPTO_NO_KDF_H
1773
1893
  auto ctx = EVPKeyCtxPointer::NewFromID(EVP_PKEY_HKDF);
1774
1894
  // OpenSSL < 3.0.0 accepted only a void* as the argument of
1775
1895
  // EVP_PKEY_CTX_set_hkdf_md.
@@ -1777,22 +1897,14 @@ DataPointer hkdf(const Digest& md,
1777
1897
  if (!ctx || !EVP_PKEY_derive_init(ctx.get()) ||
1778
1898
  !EVP_PKEY_CTX_set_hkdf_md(ctx.get(), md_ptr) ||
1779
1899
  !EVP_PKEY_CTX_add1_hkdf_info(ctx.get(), info.data, info.len)) {
1780
- return {};
1781
- }
1782
-
1783
- std::string_view actual_salt;
1784
- static const char default_salt[EVP_MAX_MD_SIZE] = {0};
1785
- if (salt.len > 0) {
1786
- actual_salt = {reinterpret_cast<const char*>(salt.data), salt.len};
1787
- } else {
1788
- actual_salt = {default_salt, static_cast<unsigned>(md.size())};
1900
+ return false;
1789
1901
  }
1790
1902
 
1791
1903
  // We do not use EVP_PKEY_HKDF_MODE_EXTRACT_AND_EXPAND because and instead
1792
1904
  // implement the extraction step ourselves because EVP_PKEY_derive does not
1793
1905
  // handle zero-length keys, which are required for Web Crypto.
1794
1906
  // TODO(jasnell): Once OpenSSL 1.1.1 support is dropped completely, and once
1795
- // BoringSSL is confirmed to support it, wen can hopefully drop this and use
1907
+ // BoringSSL is confirmed to support it, we can hopefully drop this and use
1796
1908
  // EVP_KDF directly which does support zero length keys.
1797
1909
  unsigned char pseudorandom_key[EVP_MAX_MD_SIZE];
1798
1910
  unsigned pseudorandom_key_len = sizeof(pseudorandom_key);
@@ -1804,23 +1916,41 @@ DataPointer hkdf(const Digest& md,
1804
1916
  key.len,
1805
1917
  pseudorandom_key,
1806
1918
  &pseudorandom_key_len) == nullptr) {
1807
- return {};
1919
+ return false;
1808
1920
  }
1809
1921
  if (!EVP_PKEY_CTX_hkdf_mode(ctx.get(), EVP_PKEY_HKDEF_MODE_EXPAND_ONLY) ||
1810
1922
  !EVP_PKEY_CTX_set1_hkdf_key(
1811
1923
  ctx.get(), pseudorandom_key, pseudorandom_key_len)) {
1812
- return {};
1924
+ return false;
1813
1925
  }
1814
1926
 
1927
+ if (out == nullptr || out->len != length) return false;
1928
+
1929
+ return EVP_PKEY_derive(ctx.get(), out->data, &length) > 0;
1930
+ #else
1931
+ return HKDF(out->data,
1932
+ length,
1933
+ md,
1934
+ key.data,
1935
+ key.len,
1936
+ salt.data,
1937
+ salt.len,
1938
+ info.data,
1939
+ info.len);
1940
+ #endif
1941
+ }
1942
+
1943
+ DataPointer hkdf(const Digest& md,
1944
+ const Buffer<const unsigned char>& key,
1945
+ const Buffer<const unsigned char>& info,
1946
+ const Buffer<const unsigned char>& salt,
1947
+ size_t length) {
1815
1948
  auto buf = DataPointer::Alloc(length);
1816
1949
  if (!buf) return {};
1950
+ Buffer<unsigned char> out = buf;
1817
1951
 
1818
- if (EVP_PKEY_derive(
1819
- ctx.get(), static_cast<unsigned char*>(buf.get()), &length) <= 0) {
1820
- return {};
1821
- }
1822
-
1823
- return buf;
1952
+ return hkdfInfo(md, key, info, salt, length, &out) ? std::move(buf)
1953
+ : DataPointer();
1824
1954
  }
1825
1955
 
1826
1956
  bool checkScryptParams(uint64_t N, uint64_t r, uint64_t p, uint64_t maxmem) {
@@ -1828,6 +1958,36 @@ bool checkScryptParams(uint64_t N, uint64_t r, uint64_t p, uint64_t maxmem) {
1828
1958
  1;
1829
1959
  }
1830
1960
 
1961
+ bool scryptInto(const Buffer<const char>& pass,
1962
+ const Buffer<const unsigned char>& salt,
1963
+ uint64_t N,
1964
+ uint64_t r,
1965
+ uint64_t p,
1966
+ uint64_t maxmem,
1967
+ size_t length,
1968
+ Buffer<unsigned char>* out) {
1969
+ ClearErrorOnReturn clearErrorOnReturn;
1970
+
1971
+ if (pass.len > INT_MAX || salt.len > INT_MAX || out == nullptr) {
1972
+ return false;
1973
+ }
1974
+
1975
+ if (auto dp = DataPointer::Alloc(length)) {
1976
+ return EVP_PBE_scrypt(pass.data,
1977
+ pass.len,
1978
+ salt.data,
1979
+ salt.len,
1980
+ N,
1981
+ r,
1982
+ p,
1983
+ maxmem,
1984
+ out->data,
1985
+ length);
1986
+ }
1987
+
1988
+ return false;
1989
+ }
1990
+
1831
1991
  DataPointer scrypt(const Buffer<const char>& pass,
1832
1992
  const Buffer<const unsigned char>& salt,
1833
1993
  uint64_t N,
@@ -1835,27 +1995,42 @@ DataPointer scrypt(const Buffer<const char>& pass,
1835
1995
  uint64_t p,
1836
1996
  uint64_t maxmem,
1837
1997
  size_t length) {
1998
+ if (auto dp = DataPointer::Alloc(length)) {
1999
+ Buffer<unsigned char> buf = dp;
2000
+ if (scryptInto(pass, salt, N, r, p, maxmem, length, &buf)) {
2001
+ return dp;
2002
+ }
2003
+ }
2004
+
2005
+ return {};
2006
+ }
2007
+
2008
+ bool pbkdf2Into(const Digest& md,
2009
+ const Buffer<const char>& pass,
2010
+ const Buffer<const unsigned char>& salt,
2011
+ uint32_t iterations,
2012
+ size_t length,
2013
+ Buffer<unsigned char>* out) {
1838
2014
  ClearErrorOnReturn clearErrorOnReturn;
1839
2015
 
1840
- if (pass.len > INT_MAX || salt.len > INT_MAX) {
1841
- return {};
2016
+ if (pass.len > INT_MAX || salt.len > INT_MAX || length > INT_MAX ||
2017
+ out == nullptr) {
2018
+ return false;
1842
2019
  }
1843
2020
 
1844
- auto dp = DataPointer::Alloc(length);
1845
- if (dp && EVP_PBE_scrypt(pass.data,
1846
- pass.len,
1847
- salt.data,
1848
- salt.len,
1849
- N,
1850
- r,
1851
- p,
1852
- maxmem,
1853
- reinterpret_cast<unsigned char*>(dp.get()),
1854
- length)) {
1855
- return dp;
2021
+ const EVP_MD* md_ptr = md;
2022
+ if (PKCS5_PBKDF2_HMAC(pass.data,
2023
+ pass.len,
2024
+ salt.data,
2025
+ salt.len,
2026
+ iterations,
2027
+ md_ptr,
2028
+ length,
2029
+ out->data)) {
2030
+ return true;
1856
2031
  }
1857
2032
 
1858
- return {};
2033
+ return false;
1859
2034
  }
1860
2035
 
1861
2036
  DataPointer pbkdf2(const Digest& md,
@@ -1863,23 +2038,11 @@ DataPointer pbkdf2(const Digest& md,
1863
2038
  const Buffer<const unsigned char>& salt,
1864
2039
  uint32_t iterations,
1865
2040
  size_t length) {
1866
- ClearErrorOnReturn clearErrorOnReturn;
1867
-
1868
- if (pass.len > INT_MAX || salt.len > INT_MAX || length > INT_MAX) {
1869
- return {};
1870
- }
1871
-
1872
- auto dp = DataPointer::Alloc(length);
1873
- const EVP_MD* md_ptr = md;
1874
- if (dp && PKCS5_PBKDF2_HMAC(pass.data,
1875
- pass.len,
1876
- salt.data,
1877
- salt.len,
1878
- iterations,
1879
- md_ptr,
1880
- length,
1881
- reinterpret_cast<unsigned char*>(dp.get()))) {
1882
- return dp;
2041
+ if (auto dp = DataPointer::Alloc(length)) {
2042
+ Buffer<unsigned char> buf = dp;
2043
+ if (pbkdf2Into(md, pass, salt, iterations, length, &buf)) {
2044
+ return dp;
2045
+ }
1883
2046
  }
1884
2047
 
1885
2048
  return {};
@@ -2052,6 +2215,7 @@ EVPKeyPointer EVPKeyPointer::NewRawSeed(
2052
2215
  #endif
2053
2216
 
2054
2217
  EVPKeyPointer EVPKeyPointer::NewDH(DHPointer&& dh) {
2218
+ #ifndef NCRYPTO_NO_EVP_DH
2055
2219
  if (!dh) return {};
2056
2220
  auto key = New();
2057
2221
  if (!key) return {};
@@ -2059,6 +2223,11 @@ EVPKeyPointer EVPKeyPointer::NewDH(DHPointer&& dh) {
2059
2223
  dh.release();
2060
2224
  }
2061
2225
  return key;
2226
+ #else
2227
+ // Older versions of openssl/boringssl do not implement the EVP_PKEY_*_DH
2228
+ // APIs
2229
+ return {};
2230
+ #endif
2062
2231
  }
2063
2232
 
2064
2233
  EVPKeyPointer EVPKeyPointer::NewRSA(RSAPointer&& rsa) {
@@ -2076,6 +2245,12 @@ EVPKeyPointer::EVPKeyPointer(EVP_PKEY* pkey) : pkey_(pkey) {}
2076
2245
  EVPKeyPointer::EVPKeyPointer(EVPKeyPointer&& other) noexcept
2077
2246
  : pkey_(other.release()) {}
2078
2247
 
2248
+ EVPKeyPointer EVPKeyPointer::clone() const {
2249
+ if (!pkey_) return {};
2250
+ if (!EVP_PKEY_up_ref(pkey_.get())) return {};
2251
+ return EVPKeyPointer(pkey_.get());
2252
+ }
2253
+
2079
2254
  EVPKeyPointer& EVPKeyPointer::operator=(EVPKeyPointer&& other) noexcept {
2080
2255
  if (this == &other) return *this;
2081
2256
  this->~EVPKeyPointer();
@@ -2424,6 +2599,7 @@ EVPKeyPointer::ParseKeyResult EVPKeyPointer::TryParsePrivateKey(
2424
2599
  ERR_GET_REASON(err) == PEM_R_BAD_PASSWORD_READ && !had_passphrase) {
2425
2600
  return ParseKeyResult(PKParseError::NEED_PASSPHRASE);
2426
2601
  }
2602
+
2427
2603
  return ParseKeyResult(PKParseError::FAILED, err);
2428
2604
  }
2429
2605
  if (!pkey) return ParseKeyResult(PKParseError::FAILED);
@@ -2499,11 +2675,8 @@ Result<BIOPointer, bool> EVPKeyPointer::writePrivateKey(
2499
2675
  // PKCS1 is only permitted for RSA keys.
2500
2676
  if (id() != EVP_PKEY_RSA) return Result<BIOPointer, bool>(false);
2501
2677
 
2502
- #if OPENSSL_VERSION_MAJOR >= 3
2503
- const RSA* rsa = EVP_PKEY_get0_RSA(get());
2504
- #else
2505
- RSA* rsa = EVP_PKEY_get0_RSA(get());
2506
- #endif
2678
+ OSSL3_CONST RSA* rsa = EVP_PKEY_get0_RSA(get());
2679
+
2507
2680
  switch (config.format) {
2508
2681
  case PKFormatType::PEM: {
2509
2682
  err = PEM_write_bio_RSAPrivateKey(
@@ -2562,11 +2735,8 @@ Result<BIOPointer, bool> EVPKeyPointer::writePrivateKey(
2562
2735
  // SEC1 is only permitted for EC keys
2563
2736
  if (id() != EVP_PKEY_EC) return Result<BIOPointer, bool>(false);
2564
2737
 
2565
- #if OPENSSL_VERSION_MAJOR >= 3
2566
- const EC_KEY* ec = EVP_PKEY_get0_EC_KEY(get());
2567
- #else
2568
- EC_KEY* ec = EVP_PKEY_get0_EC_KEY(get());
2569
- #endif
2738
+ OSSL3_CONST EC_KEY* ec = EVP_PKEY_get0_EC_KEY(get());
2739
+
2570
2740
  switch (config.format) {
2571
2741
  case PKFormatType::PEM: {
2572
2742
  err = PEM_write_bio_ECPrivateKey(
@@ -2742,6 +2912,15 @@ EVPKeyPointer::operator Dsa() const {
2742
2912
  return Dsa(dsa);
2743
2913
  }
2744
2914
 
2915
+ EVPKeyPointer::operator Ec() const {
2916
+ int type = id();
2917
+ if (type != EVP_PKEY_EC) return {};
2918
+
2919
+ OSSL3_CONST EC_KEY* ec = EVP_PKEY_get0_EC_KEY(get());
2920
+ if (ec == nullptr) return {};
2921
+ return Ec(ec);
2922
+ }
2923
+
2745
2924
  bool EVPKeyPointer::validateDsaParameters() const {
2746
2925
  if (!pkey_) return false;
2747
2926
  /* Validate DSA2 parameters from FIPS 186-4 */
@@ -3024,7 +3203,13 @@ SSLCtxPointer SSLCtxPointer::New(const SSL_METHOD* method) {
3024
3203
  }
3025
3204
 
3026
3205
  bool SSLCtxPointer::setGroups(const char* groups) {
3206
+ #ifndef NCRYPTO_NO_SSL_GROUP_LIST
3027
3207
  return SSL_CTX_set1_groups_list(get(), groups) == 1;
3208
+ #else
3209
+ // Older versions of openssl/boringssl do not implement the
3210
+ // SSL_CTX_set1_groups_list API
3211
+ return false;
3212
+ #endif
3028
3213
  }
3029
3214
 
3030
3215
  bool SSLCtxPointer::setCipherSuites(const char* ciphers) {
@@ -3037,6 +3222,36 @@ bool SSLCtxPointer::setCipherSuites(const char* ciphers) {
3037
3222
  return true;
3038
3223
  #endif
3039
3224
  }
3225
+ // ============================================================================
3226
+
3227
+ template <typename T>
3228
+ std::string_view ModeMixin<T>::getModeLabel() const {
3229
+ switch (self().getMode()) {
3230
+ case EVP_CIPH_CCM_MODE:
3231
+ return "ccm";
3232
+ case EVP_CIPH_CFB_MODE:
3233
+ return "cfb";
3234
+ case EVP_CIPH_CBC_MODE:
3235
+ return "cbc";
3236
+ case EVP_CIPH_CTR_MODE:
3237
+ return "ctr";
3238
+ case EVP_CIPH_ECB_MODE:
3239
+ return "ecb";
3240
+ case EVP_CIPH_GCM_MODE:
3241
+ return "gcm";
3242
+ case EVP_CIPH_OCB_MODE:
3243
+ return "ocb";
3244
+ case EVP_CIPH_OFB_MODE:
3245
+ return "ofb";
3246
+ case EVP_CIPH_WRAP_MODE:
3247
+ return "wrap";
3248
+ case EVP_CIPH_XTS_MODE:
3249
+ return "xts";
3250
+ case EVP_CIPH_STREAM_CIPHER:
3251
+ return "stream";
3252
+ }
3253
+ return "{unknown}";
3254
+ }
3040
3255
 
3041
3256
  // ============================================================================
3042
3257
 
@@ -3065,40 +3280,14 @@ const Cipher Cipher::AES_256_GCM = Cipher::FromNid(NID_aes_256_gcm);
3065
3280
  const Cipher Cipher::AES_128_KW = Cipher::FromNid(NID_id_aes128_wrap);
3066
3281
  const Cipher Cipher::AES_192_KW = Cipher::FromNid(NID_id_aes192_wrap);
3067
3282
  const Cipher Cipher::AES_256_KW = Cipher::FromNid(NID_id_aes256_wrap);
3283
+
3284
+ #ifndef OPENSSL_IS_BORINGSSL
3068
3285
  const Cipher Cipher::AES_128_OCB = Cipher::FromNid(NID_aes_128_ocb);
3069
3286
  const Cipher Cipher::AES_192_OCB = Cipher::FromNid(NID_aes_192_ocb);
3070
3287
  const Cipher Cipher::AES_256_OCB = Cipher::FromNid(NID_aes_256_ocb);
3071
- const Cipher Cipher::CHACHA20_POLY1305 = Cipher::FromNid(NID_chacha20_poly1305);
3072
-
3073
- bool Cipher::isGcmMode() const {
3074
- if (!cipher_) return false;
3075
- return getMode() == EVP_CIPH_GCM_MODE;
3076
- }
3077
-
3078
- bool Cipher::isWrapMode() const {
3079
- if (!cipher_) return false;
3080
- return getMode() == EVP_CIPH_WRAP_MODE;
3081
- }
3082
-
3083
- bool Cipher::isCtrMode() const {
3084
- if (!cipher_) return false;
3085
- return getMode() == EVP_CIPH_CTR_MODE;
3086
- }
3087
-
3088
- bool Cipher::isCcmMode() const {
3089
- if (!cipher_) return false;
3090
- return getMode() == EVP_CIPH_CCM_MODE;
3091
- }
3092
-
3093
- bool Cipher::isOcbMode() const {
3094
- if (!cipher_) return false;
3095
- return getMode() == EVP_CIPH_OCB_MODE;
3096
- }
3288
+ #endif
3097
3289
 
3098
- bool Cipher::isStreamMode() const {
3099
- if (!cipher_) return false;
3100
- return getMode() == EVP_CIPH_STREAM_CIPHER;
3101
- }
3290
+ const Cipher Cipher::CHACHA20_POLY1305 = Cipher::FromNid(NID_chacha20_poly1305);
3102
3291
 
3103
3292
  bool Cipher::isChaCha20Poly1305() const {
3104
3293
  if (!cipher_) return false;
@@ -3106,7 +3295,7 @@ bool Cipher::isChaCha20Poly1305() const {
3106
3295
  }
3107
3296
 
3108
3297
  int Cipher::getMode() const {
3109
- if (!cipher_) return 0;
3298
+ if (!cipher_) return -1;
3110
3299
  return EVP_CIPHER_mode(cipher_);
3111
3300
  }
3112
3301
 
@@ -3130,35 +3319,6 @@ int Cipher::getNid() const {
3130
3319
  return EVP_CIPHER_nid(cipher_);
3131
3320
  }
3132
3321
 
3133
- std::string_view Cipher::getModeLabel() const {
3134
- if (!cipher_) return {};
3135
- switch (getMode()) {
3136
- case EVP_CIPH_CCM_MODE:
3137
- return "ccm";
3138
- case EVP_CIPH_CFB_MODE:
3139
- return "cfb";
3140
- case EVP_CIPH_CBC_MODE:
3141
- return "cbc";
3142
- case EVP_CIPH_CTR_MODE:
3143
- return "ctr";
3144
- case EVP_CIPH_ECB_MODE:
3145
- return "ecb";
3146
- case EVP_CIPH_GCM_MODE:
3147
- return "gcm";
3148
- case EVP_CIPH_OCB_MODE:
3149
- return "ocb";
3150
- case EVP_CIPH_OFB_MODE:
3151
- return "ofb";
3152
- case EVP_CIPH_WRAP_MODE:
3153
- return "wrap";
3154
- case EVP_CIPH_XTS_MODE:
3155
- return "xts";
3156
- case EVP_CIPH_STREAM_CIPHER:
3157
- return "stream";
3158
- }
3159
- return "{unknown}";
3160
- }
3161
-
3162
3322
  const char* Cipher::getName() const {
3163
3323
  if (!cipher_) return {};
3164
3324
  // OBJ_nid2sn(EVP_CIPHER_nid(cipher)) is used here instead of
@@ -3189,22 +3349,92 @@ int Cipher::bytesToKey(const Digest& digest,
3189
3349
  *this, Digest::MD5, nullptr, input.data, input.len, 1, key, iv);
3190
3350
  }
3191
3351
 
3192
- // ============================================================================
3193
-
3194
- CipherCtxPointer CipherCtxPointer::New() {
3195
- auto ret = CipherCtxPointer(EVP_CIPHER_CTX_new());
3196
- if (!ret) return {};
3197
- EVP_CIPHER_CTX_init(ret.get());
3198
- return ret;
3199
- }
3200
-
3201
- CipherCtxPointer::CipherCtxPointer(EVP_CIPHER_CTX* ctx) : ctx_(ctx) {}
3352
+ template class ModeMixin<Cipher>;
3202
3353
 
3203
- CipherCtxPointer::CipherCtxPointer(CipherCtxPointer&& other) noexcept
3204
- : ctx_(other.release()) {}
3354
+ namespace {
3355
+ struct CipherCallbackContext {
3356
+ Cipher::CipherNameCallback cb;
3357
+ void operator()(const char* name) { cb(name); }
3358
+ };
3205
3359
 
3206
- CipherCtxPointer& CipherCtxPointer::operator=(
3207
- CipherCtxPointer&& other) noexcept {
3360
+ #if OPENSSL_VERSION_MAJOR >= 3
3361
+ template <class TypeName,
3362
+ TypeName* fetch_type(OSSL_LIB_CTX*, const char*, const char*),
3363
+ void free_type(TypeName*),
3364
+ const TypeName* getbyname(const char*),
3365
+ const char* getname(const TypeName*)>
3366
+ void array_push_back(const TypeName* evp_ref,
3367
+ const char* from,
3368
+ const char* to,
3369
+ void* arg) {
3370
+ if (from == nullptr) return;
3371
+
3372
+ const TypeName* real_instance = getbyname(from);
3373
+ if (!real_instance) return;
3374
+
3375
+ const char* real_name = getname(real_instance);
3376
+ if (!real_name) return;
3377
+
3378
+ // EVP_*_fetch() does not support alias names, so we need to pass it the
3379
+ // real/original algorithm name.
3380
+ // We use EVP_*_fetch() as a filter here because it will only return an
3381
+ // instance if the algorithm is supported by the public OpenSSL APIs (some
3382
+ // algorithms are used internally by OpenSSL and are also passed to this
3383
+ // callback).
3384
+ TypeName* fetched = fetch_type(nullptr, real_name, nullptr);
3385
+ if (fetched == nullptr) return;
3386
+
3387
+ free_type(fetched);
3388
+ auto& cb = *(static_cast<CipherCallbackContext*>(arg));
3389
+ cb(from);
3390
+ }
3391
+ #else
3392
+ template <class TypeName>
3393
+ void array_push_back(const TypeName* evp_ref,
3394
+ const char* from,
3395
+ const char* to,
3396
+ void* arg) {
3397
+ if (!from) return;
3398
+ auto& cb = *(static_cast<CipherCallbackContext*>(arg));
3399
+ cb(from);
3400
+ }
3401
+ #endif
3402
+ } // namespace
3403
+
3404
+ void Cipher::ForEach(Cipher::CipherNameCallback callback) {
3405
+ ClearErrorOnReturn clearErrorOnReturn;
3406
+ CipherCallbackContext context;
3407
+ context.cb = std::move(callback);
3408
+
3409
+ EVP_CIPHER_do_all_sorted(
3410
+ #if OPENSSL_VERSION_MAJOR >= 3
3411
+ array_push_back<EVP_CIPHER,
3412
+ EVP_CIPHER_fetch,
3413
+ EVP_CIPHER_free,
3414
+ EVP_get_cipherbyname,
3415
+ EVP_CIPHER_get0_name>,
3416
+ #else
3417
+ array_push_back<EVP_CIPHER>,
3418
+ #endif
3419
+ &context);
3420
+ }
3421
+
3422
+ // ============================================================================
3423
+
3424
+ CipherCtxPointer CipherCtxPointer::New() {
3425
+ auto ret = CipherCtxPointer(EVP_CIPHER_CTX_new());
3426
+ if (!ret) return {};
3427
+ EVP_CIPHER_CTX_init(ret.get());
3428
+ return ret;
3429
+ }
3430
+
3431
+ CipherCtxPointer::CipherCtxPointer(EVP_CIPHER_CTX* ctx) : ctx_(ctx) {}
3432
+
3433
+ CipherCtxPointer::CipherCtxPointer(CipherCtxPointer&& other) noexcept
3434
+ : ctx_(other.release()) {}
3435
+
3436
+ CipherCtxPointer& CipherCtxPointer::operator=(
3437
+ CipherCtxPointer&& other) noexcept {
3208
3438
  if (this == &other) return *this;
3209
3439
  this->~CipherCtxPointer();
3210
3440
  return *new (this) CipherCtxPointer(std::move(other));
@@ -3265,6 +3495,11 @@ int CipherCtxPointer::getMode() const {
3265
3495
  return EVP_CIPHER_CTX_mode(ctx_.get());
3266
3496
  }
3267
3497
 
3498
+ int CipherCtxPointer::getNid() const {
3499
+ if (!ctx_) return 0;
3500
+ return EVP_CIPHER_CTX_nid(ctx_.get());
3501
+ }
3502
+
3268
3503
  bool CipherCtxPointer::isGcmMode() const {
3269
3504
  if (!ctx_) return false;
3270
3505
  return getMode() == EVP_CIPH_GCM_MODE;
@@ -3290,11 +3525,6 @@ bool CipherCtxPointer::isChaCha20Poly1305() const {
3290
3525
  return getNid() == NID_chacha20_poly1305;
3291
3526
  }
3292
3527
 
3293
- int CipherCtxPointer::getNid() const {
3294
- if (!ctx_) return 0;
3295
- return EVP_CIPHER_CTX_nid(ctx_.get());
3296
- }
3297
-
3298
3528
  bool CipherCtxPointer::init(const Cipher& cipher,
3299
3529
  bool encrypt,
3300
3530
  const unsigned char* key,
@@ -3641,6 +3871,7 @@ bool EVPKeyCtxPointer::setDhParameters(int prime_size, uint32_t generator) {
3641
3871
 
3642
3872
  bool EVPKeyCtxPointer::setDsaParameters(uint32_t bits,
3643
3873
  std::optional<int> q_bits) {
3874
+ #ifndef NCRYPTO_NO_DSA_KEYGEN
3644
3875
  if (!ctx_) return false;
3645
3876
  if (EVP_PKEY_CTX_set_dsa_paramgen_bits(ctx_.get(), bits) != 1) {
3646
3877
  return false;
@@ -3650,6 +3881,10 @@ bool EVPKeyCtxPointer::setDsaParameters(uint32_t bits,
3650
3881
  return false;
3651
3882
  }
3652
3883
  return true;
3884
+ #else
3885
+ // Older versions of openssl/boringssl do not implement the DSA keygen.
3886
+ return false;
3887
+ #endif
3653
3888
  }
3654
3889
 
3655
3890
  bool EVPKeyCtxPointer::setEcParameters(int curve, int encoding) {
@@ -3990,9 +4225,14 @@ const std::optional<Rsa::PssParams> Rsa::getPssParams() const {
3990
4225
  }
3991
4226
 
3992
4227
  if (params->saltLength != nullptr) {
3993
- if (ASN1_INTEGER_get_int64(&ret.salt_length, params->saltLength) != 1) {
4228
+ // Older versions of openssl/boringssl do not implement
4229
+ // ASN1_INTEGER_get_int64, which the salt length here technically
4230
+ // is. Let's walk it through uint64_t with a conversion.
4231
+ uint64_t temp;
4232
+ if (ASN1_INTEGER_get_uint64(&temp, params->saltLength) != 1) {
3994
4233
  return std::nullopt;
3995
4234
  }
4235
+ ret.salt_length = static_cast<int64_t>(temp);
3996
4236
  }
3997
4237
  return ret;
3998
4238
  }
@@ -4077,79 +4317,18 @@ DataPointer Cipher::recover(const EVPKeyPointer& key,
4077
4317
  key, params, in);
4078
4318
  }
4079
4319
 
4080
- namespace {
4081
- struct CipherCallbackContext {
4082
- Cipher::CipherNameCallback cb;
4083
- void operator()(const char* name) { cb(name); }
4084
- };
4085
-
4086
- #if OPENSSL_VERSION_MAJOR >= 3
4087
- template <class TypeName,
4088
- TypeName* fetch_type(OSSL_LIB_CTX*, const char*, const char*),
4089
- void free_type(TypeName*),
4090
- const TypeName* getbyname(const char*),
4091
- const char* getname(const TypeName*)>
4092
- void array_push_back(const TypeName* evp_ref,
4093
- const char* from,
4094
- const char* to,
4095
- void* arg) {
4096
- if (from == nullptr) return;
4097
-
4098
- const TypeName* real_instance = getbyname(from);
4099
- if (!real_instance) return;
4100
-
4101
- const char* real_name = getname(real_instance);
4102
- if (!real_name) return;
4103
-
4104
- // EVP_*_fetch() does not support alias names, so we need to pass it the
4105
- // real/original algorithm name.
4106
- // We use EVP_*_fetch() as a filter here because it will only return an
4107
- // instance if the algorithm is supported by the public OpenSSL APIs (some
4108
- // algorithms are used internally by OpenSSL and are also passed to this
4109
- // callback).
4110
- TypeName* fetched = fetch_type(nullptr, real_name, nullptr);
4111
- if (fetched == nullptr) return;
4112
-
4113
- free_type(fetched);
4114
- auto& cb = *(static_cast<CipherCallbackContext*>(arg));
4115
- cb(from);
4116
- }
4117
- #else
4118
- template <class TypeName>
4119
- void array_push_back(const TypeName* evp_ref,
4120
- const char* from,
4121
- const char* to,
4122
- void* arg) {
4123
- if (!from) return;
4124
- auto& cb = *(static_cast<CipherCallbackContext*>(arg));
4125
- cb(from);
4126
- }
4127
- #endif
4128
- } // namespace
4129
-
4130
- void Cipher::ForEach(Cipher::CipherNameCallback callback) {
4131
- ClearErrorOnReturn clearErrorOnReturn;
4132
- CipherCallbackContext context;
4133
- context.cb = std::move(callback);
4134
-
4135
- EVP_CIPHER_do_all_sorted(
4136
- #if OPENSSL_VERSION_MAJOR >= 3
4137
- array_push_back<EVP_CIPHER,
4138
- EVP_CIPHER_fetch,
4139
- EVP_CIPHER_free,
4140
- EVP_get_cipherbyname,
4141
- EVP_CIPHER_get0_name>,
4142
- #else
4143
- array_push_back<EVP_CIPHER>,
4144
- #endif
4145
- &context);
4146
- }
4147
-
4148
4320
  // ============================================================================
4149
4321
 
4150
4322
  Ec::Ec() : ec_(nullptr) {}
4151
4323
 
4152
- Ec::Ec(OSSL3_CONST EC_KEY* key) : ec_(key) {}
4324
+ Ec::Ec(OSSL3_CONST EC_KEY* key)
4325
+ : ec_(key), x_(BignumPointer::New()), y_(BignumPointer::New()) {
4326
+ if (ec_ != nullptr) {
4327
+ MarkPopErrorOnReturn mark_pop_error_on_return;
4328
+ EC_POINT_get_affine_coordinates(
4329
+ getGroup(), getPublicKey(), x_.get(), y_.get(), nullptr);
4330
+ }
4331
+ }
4153
4332
 
4154
4333
  const EC_GROUP* Ec::getGroup() const {
4155
4334
  return ECKeyPointer::GetGroup(ec_);
@@ -4179,6 +4358,22 @@ bool Ec::GetCurves(Ec::GetCurveCallback callback) {
4179
4358
  return true;
4180
4359
  }
4181
4360
 
4361
+ uint32_t Ec::getDegree() const {
4362
+ return EC_GROUP_get_degree(getGroup());
4363
+ }
4364
+
4365
+ std::string Ec::getCurveName() const {
4366
+ return std::string(OBJ_nid2sn(getCurve()));
4367
+ }
4368
+
4369
+ const EC_POINT* Ec::getPublicKey() const {
4370
+ return EC_KEY_get0_public_key(ec_);
4371
+ }
4372
+
4373
+ const BIGNUM* Ec::getPrivateKey() const {
4374
+ return EC_KEY_get0_private_key(ec_);
4375
+ }
4376
+
4182
4377
  // ============================================================================
4183
4378
 
4184
4379
  EVPMDCtxPointer::EVPMDCtxPointer() : ctx_(nullptr) {}
@@ -4288,6 +4483,54 @@ std::optional<EVP_PKEY_CTX*> EVPMDCtxPointer::verifyInit(
4288
4483
  return ctx;
4289
4484
  }
4290
4485
 
4486
+ std::optional<EVP_PKEY_CTX*> EVPMDCtxPointer::signInitWithContext(
4487
+ const EVPKeyPointer& key,
4488
+ const Digest& digest,
4489
+ const Buffer<const unsigned char>& context_string) {
4490
+ #ifdef OSSL_SIGNATURE_PARAM_CONTEXT_STRING
4491
+ EVP_PKEY_CTX* ctx = nullptr;
4492
+
4493
+ const OSSL_PARAM params[] = {
4494
+ OSSL_PARAM_construct_octet_string(
4495
+ OSSL_SIGNATURE_PARAM_CONTEXT_STRING,
4496
+ const_cast<unsigned char*>(context_string.data),
4497
+ context_string.len),
4498
+ OSSL_PARAM_END};
4499
+
4500
+ if (!EVP_DigestSignInit_ex(
4501
+ ctx_.get(), &ctx, nullptr, nullptr, nullptr, key.get(), params)) {
4502
+ return std::nullopt;
4503
+ }
4504
+ return ctx;
4505
+ #else
4506
+ return std::nullopt;
4507
+ #endif
4508
+ }
4509
+
4510
+ std::optional<EVP_PKEY_CTX*> EVPMDCtxPointer::verifyInitWithContext(
4511
+ const EVPKeyPointer& key,
4512
+ const Digest& digest,
4513
+ const Buffer<const unsigned char>& context_string) {
4514
+ #ifdef OSSL_SIGNATURE_PARAM_CONTEXT_STRING
4515
+ EVP_PKEY_CTX* ctx = nullptr;
4516
+
4517
+ const OSSL_PARAM params[] = {
4518
+ OSSL_PARAM_construct_octet_string(
4519
+ OSSL_SIGNATURE_PARAM_CONTEXT_STRING,
4520
+ const_cast<unsigned char*>(context_string.data),
4521
+ context_string.len),
4522
+ OSSL_PARAM_END};
4523
+
4524
+ if (!EVP_DigestVerifyInit_ex(
4525
+ ctx_.get(), &ctx, nullptr, nullptr, nullptr, key.get(), params)) {
4526
+ return std::nullopt;
4527
+ }
4528
+ return ctx;
4529
+ #else
4530
+ return std::nullopt;
4531
+ #endif
4532
+ }
4533
+
4291
4534
  DataPointer EVPMDCtxPointer::signOneShot(
4292
4535
  const Buffer<const unsigned char>& buf) const {
4293
4536
  if (!ctx_) return {};
@@ -4413,6 +4656,96 @@ HMACCtxPointer HMACCtxPointer::New() {
4413
4656
  return HMACCtxPointer(HMAC_CTX_new());
4414
4657
  }
4415
4658
 
4659
+ #if OPENSSL_VERSION_MAJOR >= 3
4660
+ EVPMacPointer::EVPMacPointer(EVP_MAC* mac) : mac_(mac) {}
4661
+
4662
+ EVPMacPointer::EVPMacPointer(EVPMacPointer&& other) noexcept
4663
+ : mac_(std::move(other.mac_)) {}
4664
+
4665
+ EVPMacPointer& EVPMacPointer::operator=(EVPMacPointer&& other) noexcept {
4666
+ if (this == &other) return *this;
4667
+ mac_ = std::move(other.mac_);
4668
+ return *this;
4669
+ }
4670
+
4671
+ EVPMacPointer::~EVPMacPointer() {
4672
+ mac_.reset();
4673
+ }
4674
+
4675
+ void EVPMacPointer::reset(EVP_MAC* mac) {
4676
+ mac_.reset(mac);
4677
+ }
4678
+
4679
+ EVP_MAC* EVPMacPointer::release() {
4680
+ return mac_.release();
4681
+ }
4682
+
4683
+ EVPMacPointer EVPMacPointer::Fetch(const char* algorithm) {
4684
+ return EVPMacPointer(EVP_MAC_fetch(nullptr, algorithm, nullptr));
4685
+ }
4686
+
4687
+ EVPMacCtxPointer::EVPMacCtxPointer(EVP_MAC_CTX* ctx) : ctx_(ctx) {}
4688
+
4689
+ EVPMacCtxPointer::EVPMacCtxPointer(EVPMacCtxPointer&& other) noexcept
4690
+ : ctx_(std::move(other.ctx_)) {}
4691
+
4692
+ EVPMacCtxPointer& EVPMacCtxPointer::operator=(
4693
+ EVPMacCtxPointer&& other) noexcept {
4694
+ if (this == &other) return *this;
4695
+ ctx_ = std::move(other.ctx_);
4696
+ return *this;
4697
+ }
4698
+
4699
+ EVPMacCtxPointer::~EVPMacCtxPointer() {
4700
+ ctx_.reset();
4701
+ }
4702
+
4703
+ void EVPMacCtxPointer::reset(EVP_MAC_CTX* ctx) {
4704
+ ctx_.reset(ctx);
4705
+ }
4706
+
4707
+ EVP_MAC_CTX* EVPMacCtxPointer::release() {
4708
+ return ctx_.release();
4709
+ }
4710
+
4711
+ bool EVPMacCtxPointer::init(const Buffer<const void>& key,
4712
+ const OSSL_PARAM* params) {
4713
+ if (!ctx_) return false;
4714
+ return EVP_MAC_init(ctx_.get(),
4715
+ static_cast<const unsigned char*>(key.data),
4716
+ key.len,
4717
+ params) == 1;
4718
+ }
4719
+
4720
+ bool EVPMacCtxPointer::update(const Buffer<const void>& data) {
4721
+ if (!ctx_) return false;
4722
+ return EVP_MAC_update(ctx_.get(),
4723
+ static_cast<const unsigned char*>(data.data),
4724
+ data.len) == 1;
4725
+ }
4726
+
4727
+ DataPointer EVPMacCtxPointer::final(size_t length) {
4728
+ if (!ctx_) return {};
4729
+ auto buf = DataPointer::Alloc(length);
4730
+ if (!buf) return {};
4731
+
4732
+ size_t result_len = length;
4733
+ if (EVP_MAC_final(ctx_.get(),
4734
+ static_cast<unsigned char*>(buf.get()),
4735
+ &result_len,
4736
+ length) != 1) {
4737
+ return {};
4738
+ }
4739
+
4740
+ return buf;
4741
+ }
4742
+
4743
+ EVPMacCtxPointer EVPMacCtxPointer::New(EVP_MAC* mac) {
4744
+ if (!mac) return EVPMacCtxPointer();
4745
+ return EVPMacCtxPointer(EVP_MAC_CTX_new(mac));
4746
+ }
4747
+ #endif // OPENSSL_VERSION_MAJOR >= 3
4748
+
4416
4749
  DataPointer hashDigest(const Buffer<const unsigned char>& buf,
4417
4750
  const EVP_MD* md) {
4418
4751
  if (md == nullptr) return {};
@@ -4676,4 +5009,605 @@ DataPointer KEM::Decapsulate(const EVPKeyPointer& private_key,
4676
5009
 
4677
5010
  #endif // OPENSSL_VERSION_MAJOR >= 3
4678
5011
 
5012
+ // ============================================================================
5013
+ // AEAD (Authenticated Encryption with Associated Data)
5014
+ #ifdef OPENSSL_IS_BORINGSSL
5015
+
5016
+ const Aead Aead::FromName(std::string_view name) {
5017
+ for (const auto& [construct, info] : aeadIndex) {
5018
+ if (EqualNoCase(info.name, name)) {
5019
+ return Aead(&info, construct());
5020
+ }
5021
+ }
5022
+
5023
+ return Aead();
5024
+ }
5025
+
5026
+ const Aead Aead::FromCtx(std::string_view name, const AeadCtxPointer& ctx) {
5027
+ for (const auto& [_, info] : aeadIndex) {
5028
+ if (info.name == name) {
5029
+ return Aead(&info, EVP_AEAD_CTX_aead(ctx.get()));
5030
+ }
5031
+ }
5032
+
5033
+ return Aead();
5034
+ }
5035
+
5036
+ int Aead::getMode() const {
5037
+ if (!aead_) return -1;
5038
+
5039
+ return info_->mode;
5040
+ }
5041
+
5042
+ int Aead::getNonceLength() const {
5043
+ if (!aead_) return 0;
5044
+ return EVP_AEAD_nonce_length(aead_);
5045
+ }
5046
+
5047
+ int Aead::getKeyLength() const {
5048
+ if (!aead_) return 0;
5049
+ return EVP_AEAD_key_length(aead_);
5050
+ }
5051
+
5052
+ int Aead::getMaxOverhead() const {
5053
+ if (!aead_) return 0;
5054
+ return EVP_AEAD_max_overhead(aead_);
5055
+ }
5056
+
5057
+ int Aead::getMaxTagLength() const {
5058
+ if (!aead_) return 0;
5059
+ return EVP_AEAD_max_tag_len(aead_);
5060
+ }
5061
+
5062
+ int Aead::getBlockSize() const {
5063
+ if (!aead_) return 0;
5064
+
5065
+ // EVP_CIPHER_CTX_block_size returns the block size, in bytes, of the cipher
5066
+ // underlying |ctx|, or one if the cipher is a stream cipher.
5067
+ return 1;
5068
+ }
5069
+
5070
+ std::string_view Aead::getName() const {
5071
+ if (!aead_) return "";
5072
+
5073
+ return info_->name;
5074
+ }
5075
+
5076
+ int Aead::getNid() const {
5077
+ if (!aead_) return 0;
5078
+
5079
+ return info_->nid;
5080
+ }
5081
+
5082
+ const Aead Aead::FromConstructor(Aead::AeadConstructor construct) {
5083
+ return Aead(&aeadIndex.at(construct), construct());
5084
+ }
5085
+
5086
+ const std::unordered_map<Aead::AeadConstructor, Aead::AeadInfo>
5087
+ Aead::aeadIndex = {
5088
+ {EVP_aead_aes_128_gcm,
5089
+ {.name = LN_aes_128_gcm,
5090
+ .mode = EVP_CIPH_GCM_MODE,
5091
+ .nid = NID_aes_128_gcm}},
5092
+ {EVP_aead_aes_192_gcm,
5093
+ {.name = LN_aes_192_gcm,
5094
+ .mode = EVP_CIPH_GCM_MODE,
5095
+ .nid = NID_aes_192_gcm}},
5096
+ {EVP_aead_aes_256_gcm,
5097
+ {.name = LN_aes_256_gcm,
5098
+ .mode = EVP_CIPH_GCM_MODE,
5099
+ .nid = NID_aes_256_gcm}},
5100
+ {EVP_aead_chacha20_poly1305,
5101
+ {.name = LN_chacha20_poly1305,
5102
+ .mode = EVP_CIPH_STREAM_CIPHER,
5103
+ .nid = NID_chacha20_poly1305}},
5104
+ {EVP_aead_xchacha20_poly1305,
5105
+ {
5106
+ .name = "xchacha20-poly1305",
5107
+ .mode = EVP_CIPH_STREAM_CIPHER,
5108
+ }},
5109
+ {EVP_aead_aes_128_ctr_hmac_sha256,
5110
+ {
5111
+ .name = "aes-128-ctr-hmac-sha256",
5112
+ .mode = EVP_CIPH_CTR_MODE,
5113
+ }},
5114
+ {EVP_aead_aes_256_ctr_hmac_sha256,
5115
+ {
5116
+ .name = "aes-256-ctr-hmac-sha256",
5117
+ .mode = EVP_CIPH_CTR_MODE,
5118
+ }},
5119
+ {EVP_aead_aes_128_gcm_siv,
5120
+ {
5121
+ .name = "aes-128-gcm-siv",
5122
+ .mode = EVP_CIPH_GCM_MODE,
5123
+ }},
5124
+ {EVP_aead_aes_256_gcm_siv,
5125
+ {
5126
+ .name = "aes-256-gcm-siv",
5127
+ .mode = EVP_CIPH_GCM_MODE,
5128
+ }},
5129
+ {EVP_aead_aes_128_gcm_randnonce,
5130
+ {
5131
+ .name = "aes-128-gcm-randnonce",
5132
+ .mode = EVP_CIPH_GCM_MODE,
5133
+ }},
5134
+ {EVP_aead_aes_256_gcm_randnonce,
5135
+ {
5136
+ .name = "aes-256-gcm-randnonce",
5137
+ .mode = EVP_CIPH_GCM_MODE,
5138
+ }},
5139
+ {EVP_aead_aes_128_ccm_bluetooth,
5140
+ {
5141
+ .name = "aes-128-ccm-bluetooth",
5142
+ .mode = EVP_CIPH_CCM_MODE,
5143
+ }},
5144
+ {EVP_aead_aes_128_ccm_bluetooth_8,
5145
+ {
5146
+ .name = "aes-128-ccm-bluetooth-8",
5147
+ .mode = EVP_CIPH_CCM_MODE,
5148
+ }},
5149
+ {EVP_aead_aes_128_ccm_matter,
5150
+ {
5151
+ .name = "aes-128-ccm-matter",
5152
+ .mode = EVP_CIPH_CCM_MODE,
5153
+ }},
5154
+ {EVP_aead_aes_128_eax,
5155
+ {.name = "aes-128-eax",
5156
+ // BoringSSL does not define a mode constant for EAX. Using STREAM
5157
+ // arbitrarily
5158
+ .mode = EVP_CIPH_STREAM_CIPHER}},
5159
+ {EVP_aead_aes_256_eax,
5160
+ {.name = "aes-256-eax",
5161
+ // BoringSSL does not define a mode constant for EAX. Using STREAM
5162
+ // arbitrarily
5163
+ .mode = EVP_CIPH_STREAM_CIPHER}},
5164
+ };
5165
+
5166
+ void Aead::ForEach(AeadNameCallback callback) {
5167
+ for (const auto& [_, info] : aeadIndex) {
5168
+ callback(info.name);
5169
+ }
5170
+ }
5171
+
5172
+ const Aead Aead::EMPTY = Aead();
5173
+ const Aead Aead::AES_128_GCM = Aead::FromConstructor(EVP_aead_aes_128_gcm);
5174
+ const Aead Aead::AES_192_GCM = Aead::FromConstructor(EVP_aead_aes_192_gcm);
5175
+ const Aead Aead::AES_256_GCM = Aead::FromConstructor(EVP_aead_aes_256_gcm);
5176
+ const Aead Aead::CHACHA20_POLY1305 =
5177
+ Aead::FromConstructor(EVP_aead_chacha20_poly1305);
5178
+ const Aead Aead::XCHACHA20_POLY1305 =
5179
+ Aead::FromConstructor(EVP_aead_xchacha20_poly1305);
5180
+ const Aead Aead::AES_128_CTR_HMAC_SHA256 =
5181
+ Aead::FromConstructor(EVP_aead_aes_128_ctr_hmac_sha256);
5182
+ const Aead Aead::AES_256_CTR_HMAC_SHA256 =
5183
+ Aead::FromConstructor(EVP_aead_aes_256_ctr_hmac_sha256);
5184
+ const Aead Aead::AES_128_GCM_SIV =
5185
+ Aead::FromConstructor(EVP_aead_aes_128_gcm_siv);
5186
+ const Aead Aead::AES_256_GCM_SIV =
5187
+ Aead::FromConstructor(EVP_aead_aes_256_gcm_siv);
5188
+ const Aead Aead::AES_128_GCM_RANDNONCE =
5189
+ Aead::FromConstructor(EVP_aead_aes_128_gcm_randnonce);
5190
+ const Aead Aead::AES_256_GCM_RANDNONCE =
5191
+ Aead::FromConstructor(EVP_aead_aes_256_gcm_randnonce);
5192
+ const Aead Aead::AES_128_CCM_BLUETOOTH =
5193
+ Aead::FromConstructor(EVP_aead_aes_128_ccm_bluetooth);
5194
+ const Aead Aead::AES_128_CCM_BLUETOOTH_8 =
5195
+ Aead::FromConstructor(EVP_aead_aes_128_ccm_bluetooth_8);
5196
+ const Aead Aead::AES_128_CCM_MATTER =
5197
+ Aead::FromConstructor(EVP_aead_aes_128_ccm_matter);
5198
+ const Aead Aead::AES_128_EAX = Aead::FromConstructor(EVP_aead_aes_128_eax);
5199
+ const Aead Aead::AES_256_EAX = Aead::FromConstructor(EVP_aead_aes_256_eax);
5200
+
5201
+ template class ModeMixin<Aead>;
5202
+
5203
+ AeadCtxPointer AeadCtxPointer::New(const Aead& aead,
5204
+ bool encrypt,
5205
+ const unsigned char* key,
5206
+ size_t keyLen,
5207
+ size_t tagLen) {
5208
+ // Note: In the EVP_AEAD API new always calls init
5209
+ auto ret = AeadCtxPointer(EVP_AEAD_CTX_new(aead.get(), key, keyLen, tagLen));
5210
+
5211
+ if (!ret) {
5212
+ return {};
5213
+ }
5214
+
5215
+ return ret;
5216
+ }
5217
+
5218
+ AeadCtxPointer::AeadCtxPointer(EVP_AEAD_CTX* ctx) : ctx_(ctx) {}
5219
+
5220
+ AeadCtxPointer::AeadCtxPointer(AeadCtxPointer&& other) noexcept
5221
+ : ctx_(other.release()) {}
5222
+
5223
+ AeadCtxPointer& AeadCtxPointer::operator=(AeadCtxPointer&& other) noexcept {
5224
+ if (this == &other) return *this;
5225
+ this->~AeadCtxPointer();
5226
+ return *new (this) AeadCtxPointer(std::move(other));
5227
+ }
5228
+
5229
+ AeadCtxPointer::~AeadCtxPointer() {
5230
+ reset();
5231
+ }
5232
+
5233
+ void AeadCtxPointer::reset(EVP_AEAD_CTX* ctx) {
5234
+ ctx_.reset(ctx);
5235
+ }
5236
+
5237
+ EVP_AEAD_CTX* AeadCtxPointer::release() {
5238
+ return ctx_.release();
5239
+ }
5240
+
5241
+ bool AeadCtxPointer::init(const Aead& aead,
5242
+ bool encrypt,
5243
+ const unsigned char* key,
5244
+ size_t keyLen,
5245
+ size_t tagLen) {
5246
+ return EVP_AEAD_CTX_init_with_direction(
5247
+ ctx_.get(),
5248
+ aead,
5249
+ key,
5250
+ keyLen,
5251
+ tagLen,
5252
+ encrypt ? evp_aead_seal : evp_aead_open);
5253
+ }
5254
+
5255
+ bool AeadCtxPointer::encrypt(const Buffer<const unsigned char>& in,
5256
+ Buffer<unsigned char>& out,
5257
+ Buffer<unsigned char>& tag,
5258
+ const Buffer<const unsigned char>& nonce,
5259
+ const Buffer<const unsigned char>& aad) {
5260
+ if (!ctx_) return false;
5261
+ return EVP_AEAD_CTX_seal_scatter(ctx_.get(),
5262
+ out.data,
5263
+ tag.data,
5264
+ &tag.len,
5265
+ tag.len,
5266
+ nonce.data,
5267
+ nonce.len,
5268
+ in.data,
5269
+ in.len,
5270
+ nullptr /* extra_in */,
5271
+ 0 /* extra_in_len */,
5272
+ aad.data,
5273
+ aad.len) == 1;
5274
+ }
5275
+
5276
+ bool AeadCtxPointer::decrypt(const Buffer<const unsigned char>& in,
5277
+ Buffer<unsigned char>& out,
5278
+ const Buffer<const unsigned char>& tag,
5279
+ const Buffer<const unsigned char>& nonce,
5280
+ const Buffer<const unsigned char>& aad) {
5281
+ if (!ctx_) return false;
5282
+
5283
+ return EVP_AEAD_CTX_open_gather(ctx_.get(),
5284
+ out.data,
5285
+ nonce.data,
5286
+ nonce.len,
5287
+ in.data,
5288
+ in.len,
5289
+ tag.data,
5290
+ tag.len,
5291
+ aad.data,
5292
+ aad.len) == 1;
5293
+ }
5294
+ #endif
4679
5295
  } // namespace ncrypto
5296
+
5297
+ // ===========================================================================
5298
+ #ifdef NCRYPTO_BSSL_NEEDS_DH_PRIMES
5299
+ // While newer versions of BoringSSL have these primes, older versions do not,
5300
+ // in particular older versions that conform to fips. We conditionally add
5301
+ // them here only if the NCRYPTO_BSSL_NEEDS_DH_PRIMES define is set. Their
5302
+ // implementations are defined here to prevent duplicating the symbols.
5303
+ extern "C" int bn_set_words(BIGNUM* bn, const BN_ULONG* words, size_t num);
5304
+
5305
+ // Backporting primes that may not be supported in earlier boringssl versions.
5306
+ // Intentionally keeping the existing C-style formatting.
5307
+
5308
+ #define OPENSSL_ARRAY_SIZE(array) (sizeof(array) / sizeof((array)[0]))
5309
+
5310
+ #if defined(OPENSSL_64_BIT)
5311
+ #define TOBN(hi, lo) ((BN_ULONG)(hi) << 32 | (lo))
5312
+ #elif defined(OPENSSL_32_BIT)
5313
+ #define TOBN(hi, lo) (lo), (hi)
5314
+ #else
5315
+ #error "Must define either OPENSSL_32_BIT or OPENSSL_64_BIT"
5316
+ #endif
5317
+
5318
+ static BIGNUM* get_params(BIGNUM* ret,
5319
+ const BN_ULONG* words,
5320
+ size_t num_words) {
5321
+ BIGNUM* alloc = nullptr;
5322
+ if (ret == nullptr) {
5323
+ alloc = BN_new();
5324
+ if (alloc == nullptr) {
5325
+ return nullptr;
5326
+ }
5327
+ ret = alloc;
5328
+ }
5329
+
5330
+ if (!bn_set_words(ret, words, num_words)) {
5331
+ BN_free(alloc);
5332
+ return nullptr;
5333
+ }
5334
+
5335
+ return ret;
5336
+ }
5337
+
5338
+ BIGNUM* BN_get_rfc3526_prime_2048(BIGNUM* ret) {
5339
+ static const BN_ULONG kWords[] = {
5340
+ TOBN(0xffffffff, 0xffffffff), TOBN(0x15728e5a, 0x8aacaa68),
5341
+ TOBN(0x15d22618, 0x98fa0510), TOBN(0x3995497c, 0xea956ae5),
5342
+ TOBN(0xde2bcbf6, 0x95581718), TOBN(0xb5c55df0, 0x6f4c52c9),
5343
+ TOBN(0x9b2783a2, 0xec07a28f), TOBN(0xe39e772c, 0x180e8603),
5344
+ TOBN(0x32905e46, 0x2e36ce3b), TOBN(0xf1746c08, 0xca18217c),
5345
+ TOBN(0x670c354e, 0x4abc9804), TOBN(0x9ed52907, 0x7096966d),
5346
+ TOBN(0x1c62f356, 0x208552bb), TOBN(0x83655d23, 0xdca3ad96),
5347
+ TOBN(0x69163fa8, 0xfd24cf5f), TOBN(0x98da4836, 0x1c55d39a),
5348
+ TOBN(0xc2007cb8, 0xa163bf05), TOBN(0x49286651, 0xece45b3d),
5349
+ TOBN(0xae9f2411, 0x7c4b1fe6), TOBN(0xee386bfb, 0x5a899fa5),
5350
+ TOBN(0x0bff5cb6, 0xf406b7ed), TOBN(0xf44c42e9, 0xa637ed6b),
5351
+ TOBN(0xe485b576, 0x625e7ec6), TOBN(0x4fe1356d, 0x6d51c245),
5352
+ TOBN(0x302b0a6d, 0xf25f1437), TOBN(0xef9519b3, 0xcd3a431b),
5353
+ TOBN(0x514a0879, 0x8e3404dd), TOBN(0x020bbea6, 0x3b139b22),
5354
+ TOBN(0x29024e08, 0x8a67cc74), TOBN(0xc4c6628b, 0x80dc1cd1),
5355
+ TOBN(0xc90fdaa2, 0x2168c234), TOBN(0xffffffff, 0xffffffff),
5356
+ };
5357
+ return get_params(ret, kWords, OPENSSL_ARRAY_SIZE(kWords));
5358
+ }
5359
+
5360
+ BIGNUM* BN_get_rfc3526_prime_3072(BIGNUM* ret) {
5361
+ static const BN_ULONG kWords[] = {
5362
+ TOBN(0xffffffff, 0xffffffff), TOBN(0x4b82d120, 0xa93ad2ca),
5363
+ TOBN(0x43db5bfc, 0xe0fd108e), TOBN(0x08e24fa0, 0x74e5ab31),
5364
+ TOBN(0x770988c0, 0xbad946e2), TOBN(0xbbe11757, 0x7a615d6c),
5365
+ TOBN(0x521f2b18, 0x177b200c), TOBN(0xd8760273, 0x3ec86a64),
5366
+ TOBN(0xf12ffa06, 0xd98a0864), TOBN(0xcee3d226, 0x1ad2ee6b),
5367
+ TOBN(0x1e8c94e0, 0x4a25619d), TOBN(0xabf5ae8c, 0xdb0933d7),
5368
+ TOBN(0xb3970f85, 0xa6e1e4c7), TOBN(0x8aea7157, 0x5d060c7d),
5369
+ TOBN(0xecfb8504, 0x58dbef0a), TOBN(0xa85521ab, 0xdf1cba64),
5370
+ TOBN(0xad33170d, 0x04507a33), TOBN(0x15728e5a, 0x8aaac42d),
5371
+ TOBN(0x15d22618, 0x98fa0510), TOBN(0x3995497c, 0xea956ae5),
5372
+ TOBN(0xde2bcbf6, 0x95581718), TOBN(0xb5c55df0, 0x6f4c52c9),
5373
+ TOBN(0x9b2783a2, 0xec07a28f), TOBN(0xe39e772c, 0x180e8603),
5374
+ TOBN(0x32905e46, 0x2e36ce3b), TOBN(0xf1746c08, 0xca18217c),
5375
+ TOBN(0x670c354e, 0x4abc9804), TOBN(0x9ed52907, 0x7096966d),
5376
+ TOBN(0x1c62f356, 0x208552bb), TOBN(0x83655d23, 0xdca3ad96),
5377
+ TOBN(0x69163fa8, 0xfd24cf5f), TOBN(0x98da4836, 0x1c55d39a),
5378
+ TOBN(0xc2007cb8, 0xa163bf05), TOBN(0x49286651, 0xece45b3d),
5379
+ TOBN(0xae9f2411, 0x7c4b1fe6), TOBN(0xee386bfb, 0x5a899fa5),
5380
+ TOBN(0x0bff5cb6, 0xf406b7ed), TOBN(0xf44c42e9, 0xa637ed6b),
5381
+ TOBN(0xe485b576, 0x625e7ec6), TOBN(0x4fe1356d, 0x6d51c245),
5382
+ TOBN(0x302b0a6d, 0xf25f1437), TOBN(0xef9519b3, 0xcd3a431b),
5383
+ TOBN(0x514a0879, 0x8e3404dd), TOBN(0x020bbea6, 0x3b139b22),
5384
+ TOBN(0x29024e08, 0x8a67cc74), TOBN(0xc4c6628b, 0x80dc1cd1),
5385
+ TOBN(0xc90fdaa2, 0x2168c234), TOBN(0xffffffff, 0xffffffff),
5386
+ };
5387
+ return get_params(ret, kWords, OPENSSL_ARRAY_SIZE(kWords));
5388
+ }
5389
+
5390
+ BIGNUM* BN_get_rfc3526_prime_4096(BIGNUM* ret) {
5391
+ static const BN_ULONG kWords[] = {
5392
+ TOBN(0xffffffff, 0xffffffff), TOBN(0x4df435c9, 0x34063199),
5393
+ TOBN(0x86ffb7dc, 0x90a6c08f), TOBN(0x93b4ea98, 0x8d8fddc1),
5394
+ TOBN(0xd0069127, 0xd5b05aa9), TOBN(0xb81bdd76, 0x2170481c),
5395
+ TOBN(0x1f612970, 0xcee2d7af), TOBN(0x233ba186, 0x515be7ed),
5396
+ TOBN(0x99b2964f, 0xa090c3a2), TOBN(0x287c5947, 0x4e6bc05d),
5397
+ TOBN(0x2e8efc14, 0x1fbecaa6), TOBN(0xdbbbc2db, 0x04de8ef9),
5398
+ TOBN(0x2583e9ca, 0x2ad44ce8), TOBN(0x1a946834, 0xb6150bda),
5399
+ TOBN(0x99c32718, 0x6af4e23c), TOBN(0x88719a10, 0xbdba5b26),
5400
+ TOBN(0x1a723c12, 0xa787e6d7), TOBN(0x4b82d120, 0xa9210801),
5401
+ TOBN(0x43db5bfc, 0xe0fd108e), TOBN(0x08e24fa0, 0x74e5ab31),
5402
+ TOBN(0x770988c0, 0xbad946e2), TOBN(0xbbe11757, 0x7a615d6c),
5403
+ TOBN(0x521f2b18, 0x177b200c), TOBN(0xd8760273, 0x3ec86a64),
5404
+ TOBN(0xf12ffa06, 0xd98a0864), TOBN(0xcee3d226, 0x1ad2ee6b),
5405
+ TOBN(0x1e8c94e0, 0x4a25619d), TOBN(0xabf5ae8c, 0xdb0933d7),
5406
+ TOBN(0xb3970f85, 0xa6e1e4c7), TOBN(0x8aea7157, 0x5d060c7d),
5407
+ TOBN(0xecfb8504, 0x58dbef0a), TOBN(0xa85521ab, 0xdf1cba64),
5408
+ TOBN(0xad33170d, 0x04507a33), TOBN(0x15728e5a, 0x8aaac42d),
5409
+ TOBN(0x15d22618, 0x98fa0510), TOBN(0x3995497c, 0xea956ae5),
5410
+ TOBN(0xde2bcbf6, 0x95581718), TOBN(0xb5c55df0, 0x6f4c52c9),
5411
+ TOBN(0x9b2783a2, 0xec07a28f), TOBN(0xe39e772c, 0x180e8603),
5412
+ TOBN(0x32905e46, 0x2e36ce3b), TOBN(0xf1746c08, 0xca18217c),
5413
+ TOBN(0x670c354e, 0x4abc9804), TOBN(0x9ed52907, 0x7096966d),
5414
+ TOBN(0x1c62f356, 0x208552bb), TOBN(0x83655d23, 0xdca3ad96),
5415
+ TOBN(0x69163fa8, 0xfd24cf5f), TOBN(0x98da4836, 0x1c55d39a),
5416
+ TOBN(0xc2007cb8, 0xa163bf05), TOBN(0x49286651, 0xece45b3d),
5417
+ TOBN(0xae9f2411, 0x7c4b1fe6), TOBN(0xee386bfb, 0x5a899fa5),
5418
+ TOBN(0x0bff5cb6, 0xf406b7ed), TOBN(0xf44c42e9, 0xa637ed6b),
5419
+ TOBN(0xe485b576, 0x625e7ec6), TOBN(0x4fe1356d, 0x6d51c245),
5420
+ TOBN(0x302b0a6d, 0xf25f1437), TOBN(0xef9519b3, 0xcd3a431b),
5421
+ TOBN(0x514a0879, 0x8e3404dd), TOBN(0x020bbea6, 0x3b139b22),
5422
+ TOBN(0x29024e08, 0x8a67cc74), TOBN(0xc4c6628b, 0x80dc1cd1),
5423
+ TOBN(0xc90fdaa2, 0x2168c234), TOBN(0xffffffff, 0xffffffff),
5424
+ };
5425
+ return get_params(ret, kWords, OPENSSL_ARRAY_SIZE(kWords));
5426
+ }
5427
+
5428
+ BIGNUM* BN_get_rfc3526_prime_6144(BIGNUM* ret) {
5429
+ static const BN_ULONG kWords[] = {
5430
+ TOBN(0xffffffff, 0xffffffff), TOBN(0xe694f91e, 0x6dcc4024),
5431
+ TOBN(0x12bf2d5b, 0x0b7474d6), TOBN(0x043e8f66, 0x3f4860ee),
5432
+ TOBN(0x387fe8d7, 0x6e3c0468), TOBN(0xda56c9ec, 0x2ef29632),
5433
+ TOBN(0xeb19ccb1, 0xa313d55c), TOBN(0xf550aa3d, 0x8a1fbff0),
5434
+ TOBN(0x06a1d58b, 0xb7c5da76), TOBN(0xa79715ee, 0xf29be328),
5435
+ TOBN(0x14cc5ed2, 0x0f8037e0), TOBN(0xcc8f6d7e, 0xbf48e1d8),
5436
+ TOBN(0x4bd407b2, 0x2b4154aa), TOBN(0x0f1d45b7, 0xff585ac5),
5437
+ TOBN(0x23a97a7e, 0x36cc88be), TOBN(0x59e7c97f, 0xbec7e8f3),
5438
+ TOBN(0xb5a84031, 0x900b1c9e), TOBN(0xd55e702f, 0x46980c82),
5439
+ TOBN(0xf482d7ce, 0x6e74fef6), TOBN(0xf032ea15, 0xd1721d03),
5440
+ TOBN(0x5983ca01, 0xc64b92ec), TOBN(0x6fb8f401, 0x378cd2bf),
5441
+ TOBN(0x33205151, 0x2bd7af42), TOBN(0xdb7f1447, 0xe6cc254b),
5442
+ TOBN(0x44ce6cba, 0xced4bb1b), TOBN(0xda3edbeb, 0xcf9b14ed),
5443
+ TOBN(0x179727b0, 0x865a8918), TOBN(0xb06a53ed, 0x9027d831),
5444
+ TOBN(0xe5db382f, 0x413001ae), TOBN(0xf8ff9406, 0xad9e530e),
5445
+ TOBN(0xc9751e76, 0x3dba37bd), TOBN(0xc1d4dcb2, 0x602646de),
5446
+ TOBN(0x36c3fab4, 0xd27c7026), TOBN(0x4df435c9, 0x34028492),
5447
+ TOBN(0x86ffb7dc, 0x90a6c08f), TOBN(0x93b4ea98, 0x8d8fddc1),
5448
+ TOBN(0xd0069127, 0xd5b05aa9), TOBN(0xb81bdd76, 0x2170481c),
5449
+ TOBN(0x1f612970, 0xcee2d7af), TOBN(0x233ba186, 0x515be7ed),
5450
+ TOBN(0x99b2964f, 0xa090c3a2), TOBN(0x287c5947, 0x4e6bc05d),
5451
+ TOBN(0x2e8efc14, 0x1fbecaa6), TOBN(0xdbbbc2db, 0x04de8ef9),
5452
+ TOBN(0x2583e9ca, 0x2ad44ce8), TOBN(0x1a946834, 0xb6150bda),
5453
+ TOBN(0x99c32718, 0x6af4e23c), TOBN(0x88719a10, 0xbdba5b26),
5454
+ TOBN(0x1a723c12, 0xa787e6d7), TOBN(0x4b82d120, 0xa9210801),
5455
+ TOBN(0x43db5bfc, 0xe0fd108e), TOBN(0x08e24fa0, 0x74e5ab31),
5456
+ TOBN(0x770988c0, 0xbad946e2), TOBN(0xbbe11757, 0x7a615d6c),
5457
+ TOBN(0x521f2b18, 0x177b200c), TOBN(0xd8760273, 0x3ec86a64),
5458
+ TOBN(0xf12ffa06, 0xd98a0864), TOBN(0xcee3d226, 0x1ad2ee6b),
5459
+ TOBN(0x1e8c94e0, 0x4a25619d), TOBN(0xabf5ae8c, 0xdb0933d7),
5460
+ TOBN(0xb3970f85, 0xa6e1e4c7), TOBN(0x8aea7157, 0x5d060c7d),
5461
+ TOBN(0xecfb8504, 0x58dbef0a), TOBN(0xa85521ab, 0xdf1cba64),
5462
+ TOBN(0xad33170d, 0x04507a33), TOBN(0x15728e5a, 0x8aaac42d),
5463
+ TOBN(0x15d22618, 0x98fa0510), TOBN(0x3995497c, 0xea956ae5),
5464
+ TOBN(0xde2bcbf6, 0x95581718), TOBN(0xb5c55df0, 0x6f4c52c9),
5465
+ TOBN(0x9b2783a2, 0xec07a28f), TOBN(0xe39e772c, 0x180e8603),
5466
+ TOBN(0x32905e46, 0x2e36ce3b), TOBN(0xf1746c08, 0xca18217c),
5467
+ TOBN(0x670c354e, 0x4abc9804), TOBN(0x9ed52907, 0x7096966d),
5468
+ TOBN(0x1c62f356, 0x208552bb), TOBN(0x83655d23, 0xdca3ad96),
5469
+ TOBN(0x69163fa8, 0xfd24cf5f), TOBN(0x98da4836, 0x1c55d39a),
5470
+ TOBN(0xc2007cb8, 0xa163bf05), TOBN(0x49286651, 0xece45b3d),
5471
+ TOBN(0xae9f2411, 0x7c4b1fe6), TOBN(0xee386bfb, 0x5a899fa5),
5472
+ TOBN(0x0bff5cb6, 0xf406b7ed), TOBN(0xf44c42e9, 0xa637ed6b),
5473
+ TOBN(0xe485b576, 0x625e7ec6), TOBN(0x4fe1356d, 0x6d51c245),
5474
+ TOBN(0x302b0a6d, 0xf25f1437), TOBN(0xef9519b3, 0xcd3a431b),
5475
+ TOBN(0x514a0879, 0x8e3404dd), TOBN(0x020bbea6, 0x3b139b22),
5476
+ TOBN(0x29024e08, 0x8a67cc74), TOBN(0xc4c6628b, 0x80dc1cd1),
5477
+ TOBN(0xc90fdaa2, 0x2168c234), TOBN(0xffffffff, 0xffffffff),
5478
+ };
5479
+ return get_params(ret, kWords, OPENSSL_ARRAY_SIZE(kWords));
5480
+ }
5481
+
5482
+ BIGNUM* BN_get_rfc3526_prime_8192(BIGNUM* ret) {
5483
+ static const BN_ULONG kWords[] = {
5484
+ TOBN(0xffffffff, 0xffffffff), TOBN(0x60c980dd, 0x98edd3df),
5485
+ TOBN(0xc81f56e8, 0x80b96e71), TOBN(0x9e3050e2, 0x765694df),
5486
+ TOBN(0x9558e447, 0x5677e9aa), TOBN(0xc9190da6, 0xfc026e47),
5487
+ TOBN(0x889a002e, 0xd5ee382b), TOBN(0x4009438b, 0x481c6cd7),
5488
+ TOBN(0x359046f4, 0xeb879f92), TOBN(0xfaf36bc3, 0x1ecfa268),
5489
+ TOBN(0xb1d510bd, 0x7ee74d73), TOBN(0xf9ab4819, 0x5ded7ea1),
5490
+ TOBN(0x64f31cc5, 0x0846851d), TOBN(0x4597e899, 0xa0255dc1),
5491
+ TOBN(0xdf310ee0, 0x74ab6a36), TOBN(0x6d2a13f8, 0x3f44f82d),
5492
+ TOBN(0x062b3cf5, 0xb3a278a6), TOBN(0x79683303, 0xed5bdd3a),
5493
+ TOBN(0xfa9d4b7f, 0xa2c087e8), TOBN(0x4bcbc886, 0x2f8385dd),
5494
+ TOBN(0x3473fc64, 0x6cea306b), TOBN(0x13eb57a8, 0x1a23f0c7),
5495
+ TOBN(0x22222e04, 0xa4037c07), TOBN(0xe3fdb8be, 0xfc848ad9),
5496
+ TOBN(0x238f16cb, 0xe39d652d), TOBN(0x3423b474, 0x2bf1c978),
5497
+ TOBN(0x3aab639c, 0x5ae4f568), TOBN(0x2576f693, 0x6ba42466),
5498
+ TOBN(0x741fa7bf, 0x8afc47ed), TOBN(0x3bc832b6, 0x8d9dd300),
5499
+ TOBN(0xd8bec4d0, 0x73b931ba), TOBN(0x38777cb6, 0xa932df8c),
5500
+ TOBN(0x74a3926f, 0x12fee5e4), TOBN(0xe694f91e, 0x6dbe1159),
5501
+ TOBN(0x12bf2d5b, 0x0b7474d6), TOBN(0x043e8f66, 0x3f4860ee),
5502
+ TOBN(0x387fe8d7, 0x6e3c0468), TOBN(0xda56c9ec, 0x2ef29632),
5503
+ TOBN(0xeb19ccb1, 0xa313d55c), TOBN(0xf550aa3d, 0x8a1fbff0),
5504
+ TOBN(0x06a1d58b, 0xb7c5da76), TOBN(0xa79715ee, 0xf29be328),
5505
+ TOBN(0x14cc5ed2, 0x0f8037e0), TOBN(0xcc8f6d7e, 0xbf48e1d8),
5506
+ TOBN(0x4bd407b2, 0x2b4154aa), TOBN(0x0f1d45b7, 0xff585ac5),
5507
+ TOBN(0x23a97a7e, 0x36cc88be), TOBN(0x59e7c97f, 0xbec7e8f3),
5508
+ TOBN(0xb5a84031, 0x900b1c9e), TOBN(0xd55e702f, 0x46980c82),
5509
+ TOBN(0xf482d7ce, 0x6e74fef6), TOBN(0xf032ea15, 0xd1721d03),
5510
+ TOBN(0x5983ca01, 0xc64b92ec), TOBN(0x6fb8f401, 0x378cd2bf),
5511
+ TOBN(0x33205151, 0x2bd7af42), TOBN(0xdb7f1447, 0xe6cc254b),
5512
+ TOBN(0x44ce6cba, 0xced4bb1b), TOBN(0xda3edbeb, 0xcf9b14ed),
5513
+ TOBN(0x179727b0, 0x865a8918), TOBN(0xb06a53ed, 0x9027d831),
5514
+ TOBN(0xe5db382f, 0x413001ae), TOBN(0xf8ff9406, 0xad9e530e),
5515
+ TOBN(0xc9751e76, 0x3dba37bd), TOBN(0xc1d4dcb2, 0x602646de),
5516
+ TOBN(0x36c3fab4, 0xd27c7026), TOBN(0x4df435c9, 0x34028492),
5517
+ TOBN(0x86ffb7dc, 0x90a6c08f), TOBN(0x93b4ea98, 0x8d8fddc1),
5518
+ TOBN(0xd0069127, 0xd5b05aa9), TOBN(0xb81bdd76, 0x2170481c),
5519
+ TOBN(0x1f612970, 0xcee2d7af), TOBN(0x233ba186, 0x515be7ed),
5520
+ TOBN(0x99b2964f, 0xa090c3a2), TOBN(0x287c5947, 0x4e6bc05d),
5521
+ TOBN(0x2e8efc14, 0x1fbecaa6), TOBN(0xdbbbc2db, 0x04de8ef9),
5522
+ TOBN(0x2583e9ca, 0x2ad44ce8), TOBN(0x1a946834, 0xb6150bda),
5523
+ TOBN(0x99c32718, 0x6af4e23c), TOBN(0x88719a10, 0xbdba5b26),
5524
+ TOBN(0x1a723c12, 0xa787e6d7), TOBN(0x4b82d120, 0xa9210801),
5525
+ TOBN(0x43db5bfc, 0xe0fd108e), TOBN(0x08e24fa0, 0x74e5ab31),
5526
+ TOBN(0x770988c0, 0xbad946e2), TOBN(0xbbe11757, 0x7a615d6c),
5527
+ TOBN(0x521f2b18, 0x177b200c), TOBN(0xd8760273, 0x3ec86a64),
5528
+ TOBN(0xf12ffa06, 0xd98a0864), TOBN(0xcee3d226, 0x1ad2ee6b),
5529
+ TOBN(0x1e8c94e0, 0x4a25619d), TOBN(0xabf5ae8c, 0xdb0933d7),
5530
+ TOBN(0xb3970f85, 0xa6e1e4c7), TOBN(0x8aea7157, 0x5d060c7d),
5531
+ TOBN(0xecfb8504, 0x58dbef0a), TOBN(0xa85521ab, 0xdf1cba64),
5532
+ TOBN(0xad33170d, 0x04507a33), TOBN(0x15728e5a, 0x8aaac42d),
5533
+ TOBN(0x15d22618, 0x98fa0510), TOBN(0x3995497c, 0xea956ae5),
5534
+ TOBN(0xde2bcbf6, 0x95581718), TOBN(0xb5c55df0, 0x6f4c52c9),
5535
+ TOBN(0x9b2783a2, 0xec07a28f), TOBN(0xe39e772c, 0x180e8603),
5536
+ TOBN(0x32905e46, 0x2e36ce3b), TOBN(0xf1746c08, 0xca18217c),
5537
+ TOBN(0x670c354e, 0x4abc9804), TOBN(0x9ed52907, 0x7096966d),
5538
+ TOBN(0x1c62f356, 0x208552bb), TOBN(0x83655d23, 0xdca3ad96),
5539
+ TOBN(0x69163fa8, 0xfd24cf5f), TOBN(0x98da4836, 0x1c55d39a),
5540
+ TOBN(0xc2007cb8, 0xa163bf05), TOBN(0x49286651, 0xece45b3d),
5541
+ TOBN(0xae9f2411, 0x7c4b1fe6), TOBN(0xee386bfb, 0x5a899fa5),
5542
+ TOBN(0x0bff5cb6, 0xf406b7ed), TOBN(0xf44c42e9, 0xa637ed6b),
5543
+ TOBN(0xe485b576, 0x625e7ec6), TOBN(0x4fe1356d, 0x6d51c245),
5544
+ TOBN(0x302b0a6d, 0xf25f1437), TOBN(0xef9519b3, 0xcd3a431b),
5545
+ TOBN(0x514a0879, 0x8e3404dd), TOBN(0x020bbea6, 0x3b139b22),
5546
+ TOBN(0x29024e08, 0x8a67cc74), TOBN(0xc4c6628b, 0x80dc1cd1),
5547
+ TOBN(0xc90fdaa2, 0x2168c234), TOBN(0xffffffff, 0xffffffff),
5548
+ };
5549
+ return get_params(ret, kWords, OPENSSL_ARRAY_SIZE(kWords));
5550
+ }
5551
+ #endif
5552
+
5553
+ // ===========================================================================
5554
+ #if NCRYPTO_BSSL_LIBDECREPIT_MISSING
5555
+ // While BoringSSL implements EVP_CIPHER_do_all_sorted, it includes this
5556
+ // inplementation in a library called "libdecrepit", which might not be included
5557
+ // depending on how boringssl was built. In such cases, a copy of the function
5558
+ // is provided here:
5559
+
5560
+ extern "C" void EVP_CIPHER_do_all_sorted(
5561
+ void (*callback)(const EVP_CIPHER* cipher,
5562
+ const char* name,
5563
+ const char* unused,
5564
+ void* arg),
5565
+ void* arg) {
5566
+ callback(EVP_aes_128_cbc(), "AES-128-CBC", NULL, arg);
5567
+ callback(EVP_aes_192_cbc(), "AES-192-CBC", NULL, arg);
5568
+ callback(EVP_aes_256_cbc(), "AES-256-CBC", NULL, arg);
5569
+ callback(EVP_aes_128_ctr(), "AES-128-CTR", NULL, arg);
5570
+ callback(EVP_aes_192_ctr(), "AES-192-CTR", NULL, arg);
5571
+ callback(EVP_aes_256_ctr(), "AES-256-CTR", NULL, arg);
5572
+ callback(EVP_aes_128_ecb(), "AES-128-ECB", NULL, arg);
5573
+ callback(EVP_aes_192_ecb(), "AES-192-ECB", NULL, arg);
5574
+ callback(EVP_aes_256_ecb(), "AES-256-ECB", NULL, arg);
5575
+ callback(EVP_aes_128_ofb(), "AES-128-OFB", NULL, arg);
5576
+ callback(EVP_aes_192_ofb(), "AES-192-OFB", NULL, arg);
5577
+ callback(EVP_aes_256_ofb(), "AES-256-OFB", NULL, arg);
5578
+ callback(EVP_aes_128_gcm(), "AES-128-GCM", NULL, arg);
5579
+ callback(EVP_aes_192_gcm(), "AES-192-GCM", NULL, arg);
5580
+ callback(EVP_aes_256_gcm(), "AES-256-GCM", NULL, arg);
5581
+ callback(EVP_des_cbc(), "DES-CBC", NULL, arg);
5582
+ callback(EVP_des_ecb(), "DES-ECB", NULL, arg);
5583
+ callback(EVP_des_ede(), "DES-EDE", NULL, arg);
5584
+ callback(EVP_des_ede_cbc(), "DES-EDE-CBC", NULL, arg);
5585
+ callback(EVP_des_ede3_cbc(), "DES-EDE3-CBC", NULL, arg);
5586
+ callback(EVP_rc2_cbc(), "RC2-CBC", NULL, arg);
5587
+ callback(EVP_rc4(), "RC4", NULL, arg);
5588
+
5589
+ // OpenSSL returns everything twice, the second time in lower case.
5590
+ callback(EVP_aes_128_cbc(), "aes-128-cbc", NULL, arg);
5591
+ callback(EVP_aes_192_cbc(), "aes-192-cbc", NULL, arg);
5592
+ callback(EVP_aes_256_cbc(), "aes-256-cbc", NULL, arg);
5593
+ callback(EVP_aes_128_ctr(), "aes-128-ctr", NULL, arg);
5594
+ callback(EVP_aes_192_ctr(), "aes-192-ctr", NULL, arg);
5595
+ callback(EVP_aes_256_ctr(), "aes-256-ctr", NULL, arg);
5596
+ callback(EVP_aes_128_ecb(), "aes-128-ecb", NULL, arg);
5597
+ callback(EVP_aes_192_ecb(), "aes-192-ecb", NULL, arg);
5598
+ callback(EVP_aes_256_ecb(), "aes-256-ecb", NULL, arg);
5599
+ callback(EVP_aes_128_ofb(), "aes-128-ofb", NULL, arg);
5600
+ callback(EVP_aes_192_ofb(), "aes-192-ofb", NULL, arg);
5601
+ callback(EVP_aes_256_ofb(), "aes-256-ofb", NULL, arg);
5602
+ callback(EVP_aes_128_gcm(), "aes-128-gcm", NULL, arg);
5603
+ callback(EVP_aes_192_gcm(), "aes-192-gcm", NULL, arg);
5604
+ callback(EVP_aes_256_gcm(), "aes-256-gcm", NULL, arg);
5605
+ callback(EVP_des_cbc(), "des-cbc", NULL, arg);
5606
+ callback(EVP_des_ecb(), "des-ecb", NULL, arg);
5607
+ callback(EVP_des_ede(), "des-ede", NULL, arg);
5608
+ callback(EVP_des_ede_cbc(), "des-ede-cbc", NULL, arg);
5609
+ callback(EVP_des_ede3_cbc(), "des-ede3-cbc", NULL, arg);
5610
+ callback(EVP_rc2_cbc(), "rc2-cbc", NULL, arg);
5611
+ callback(EVP_rc4(), "rc4", NULL, arg);
5612
+ }
5613
+ #endif