xref: /third_party/node/src/crypto/crypto_rsa.cc (revision 1cb0ef41)
11cb0ef41Sopenharmony_ci#include "crypto/crypto_rsa.h"
21cb0ef41Sopenharmony_ci#include "async_wrap-inl.h"
31cb0ef41Sopenharmony_ci#include "base_object-inl.h"
41cb0ef41Sopenharmony_ci#include "crypto/crypto_bio.h"
51cb0ef41Sopenharmony_ci#include "crypto/crypto_keys.h"
61cb0ef41Sopenharmony_ci#include "crypto/crypto_util.h"
71cb0ef41Sopenharmony_ci#include "env-inl.h"
81cb0ef41Sopenharmony_ci#include "memory_tracker-inl.h"
91cb0ef41Sopenharmony_ci#include "threadpoolwork-inl.h"
101cb0ef41Sopenharmony_ci#include "v8.h"
111cb0ef41Sopenharmony_ci
121cb0ef41Sopenharmony_ci#include <openssl/bn.h>
131cb0ef41Sopenharmony_ci#include <openssl/rsa.h>
141cb0ef41Sopenharmony_ci
151cb0ef41Sopenharmony_cinamespace node {
161cb0ef41Sopenharmony_ci
171cb0ef41Sopenharmony_ciusing v8::ArrayBuffer;
181cb0ef41Sopenharmony_ciusing v8::BackingStore;
191cb0ef41Sopenharmony_ciusing v8::FunctionCallbackInfo;
201cb0ef41Sopenharmony_ciusing v8::Int32;
211cb0ef41Sopenharmony_ciusing v8::Just;
221cb0ef41Sopenharmony_ciusing v8::Local;
231cb0ef41Sopenharmony_ciusing v8::Maybe;
241cb0ef41Sopenharmony_ciusing v8::Nothing;
251cb0ef41Sopenharmony_ciusing v8::Number;
261cb0ef41Sopenharmony_ciusing v8::Object;
271cb0ef41Sopenharmony_ciusing v8::String;
281cb0ef41Sopenharmony_ciusing v8::Uint32;
291cb0ef41Sopenharmony_ciusing v8::Value;
301cb0ef41Sopenharmony_ci
311cb0ef41Sopenharmony_cinamespace crypto {
321cb0ef41Sopenharmony_ciEVPKeyCtxPointer RsaKeyGenTraits::Setup(RsaKeyPairGenConfig* params) {
331cb0ef41Sopenharmony_ci  EVPKeyCtxPointer ctx(
341cb0ef41Sopenharmony_ci      EVP_PKEY_CTX_new_id(
351cb0ef41Sopenharmony_ci          params->params.variant == kKeyVariantRSA_PSS
361cb0ef41Sopenharmony_ci              ? EVP_PKEY_RSA_PSS
371cb0ef41Sopenharmony_ci              : EVP_PKEY_RSA,
381cb0ef41Sopenharmony_ci          nullptr));
391cb0ef41Sopenharmony_ci
401cb0ef41Sopenharmony_ci  if (EVP_PKEY_keygen_init(ctx.get()) <= 0)
411cb0ef41Sopenharmony_ci    return EVPKeyCtxPointer();
421cb0ef41Sopenharmony_ci
431cb0ef41Sopenharmony_ci  if (EVP_PKEY_CTX_set_rsa_keygen_bits(
441cb0ef41Sopenharmony_ci          ctx.get(),
451cb0ef41Sopenharmony_ci          params->params.modulus_bits) <= 0) {
461cb0ef41Sopenharmony_ci    return EVPKeyCtxPointer();
471cb0ef41Sopenharmony_ci  }
481cb0ef41Sopenharmony_ci
491cb0ef41Sopenharmony_ci  // 0x10001 is the default RSA exponent.
501cb0ef41Sopenharmony_ci  if (params->params.exponent != 0x10001) {
511cb0ef41Sopenharmony_ci    BignumPointer bn(BN_new());
521cb0ef41Sopenharmony_ci    CHECK_NOT_NULL(bn.get());
531cb0ef41Sopenharmony_ci    CHECK(BN_set_word(bn.get(), params->params.exponent));
541cb0ef41Sopenharmony_ci    // EVP_CTX accepts ownership of bn on success.
551cb0ef41Sopenharmony_ci    if (EVP_PKEY_CTX_set_rsa_keygen_pubexp(ctx.get(), bn.get()) <= 0)
561cb0ef41Sopenharmony_ci      return EVPKeyCtxPointer();
571cb0ef41Sopenharmony_ci
581cb0ef41Sopenharmony_ci    bn.release();
591cb0ef41Sopenharmony_ci  }
601cb0ef41Sopenharmony_ci
611cb0ef41Sopenharmony_ci  if (params->params.variant == kKeyVariantRSA_PSS) {
621cb0ef41Sopenharmony_ci    if (params->params.md != nullptr &&
631cb0ef41Sopenharmony_ci        EVP_PKEY_CTX_set_rsa_pss_keygen_md(ctx.get(), params->params.md) <= 0) {
641cb0ef41Sopenharmony_ci      return EVPKeyCtxPointer();
651cb0ef41Sopenharmony_ci    }
661cb0ef41Sopenharmony_ci
671cb0ef41Sopenharmony_ci    // TODO(tniessen): This appears to only be necessary in OpenSSL 3, while
681cb0ef41Sopenharmony_ci    // OpenSSL 1.1.1 behaves as recommended by RFC 8017 and defaults the MGF1
691cb0ef41Sopenharmony_ci    // hash algorithm to the RSA-PSS hashAlgorithm. Remove this code if the
701cb0ef41Sopenharmony_ci    // behavior of OpenSSL 3 changes.
711cb0ef41Sopenharmony_ci    const EVP_MD* mgf1_md = params->params.mgf1_md;
721cb0ef41Sopenharmony_ci    if (mgf1_md == nullptr && params->params.md != nullptr) {
731cb0ef41Sopenharmony_ci      mgf1_md = params->params.md;
741cb0ef41Sopenharmony_ci    }
751cb0ef41Sopenharmony_ci
761cb0ef41Sopenharmony_ci    if (mgf1_md != nullptr &&
771cb0ef41Sopenharmony_ci        EVP_PKEY_CTX_set_rsa_pss_keygen_mgf1_md(
781cb0ef41Sopenharmony_ci            ctx.get(),
791cb0ef41Sopenharmony_ci            mgf1_md) <= 0) {
801cb0ef41Sopenharmony_ci      return EVPKeyCtxPointer();
811cb0ef41Sopenharmony_ci    }
821cb0ef41Sopenharmony_ci
831cb0ef41Sopenharmony_ci    int saltlen = params->params.saltlen;
841cb0ef41Sopenharmony_ci    if (saltlen < 0 && params->params.md != nullptr) {
851cb0ef41Sopenharmony_ci      saltlen = EVP_MD_size(params->params.md);
861cb0ef41Sopenharmony_ci    }
871cb0ef41Sopenharmony_ci
881cb0ef41Sopenharmony_ci    if (saltlen >= 0 &&
891cb0ef41Sopenharmony_ci        EVP_PKEY_CTX_set_rsa_pss_keygen_saltlen(
901cb0ef41Sopenharmony_ci            ctx.get(),
911cb0ef41Sopenharmony_ci            saltlen) <= 0) {
921cb0ef41Sopenharmony_ci      return EVPKeyCtxPointer();
931cb0ef41Sopenharmony_ci    }
941cb0ef41Sopenharmony_ci  }
951cb0ef41Sopenharmony_ci
961cb0ef41Sopenharmony_ci  return ctx;
971cb0ef41Sopenharmony_ci}
981cb0ef41Sopenharmony_ci
991cb0ef41Sopenharmony_ci// Input parameters to the RsaKeyGenJob:
1001cb0ef41Sopenharmony_ci// For key variants RSA-OAEP and RSA-SSA-PKCS1-v1_5
1011cb0ef41Sopenharmony_ci//   1. CryptoJobMode
1021cb0ef41Sopenharmony_ci//   2. Key Variant
1031cb0ef41Sopenharmony_ci//   3. Modulus Bits
1041cb0ef41Sopenharmony_ci//   4. Public Exponent
1051cb0ef41Sopenharmony_ci//   5. Public Format
1061cb0ef41Sopenharmony_ci//   6. Public Type
1071cb0ef41Sopenharmony_ci//   7. Private Format
1081cb0ef41Sopenharmony_ci//   8. Private Type
1091cb0ef41Sopenharmony_ci//   9. Cipher
1101cb0ef41Sopenharmony_ci//   10. Passphrase
1111cb0ef41Sopenharmony_ci//
1121cb0ef41Sopenharmony_ci// For RSA-PSS variant
1131cb0ef41Sopenharmony_ci//   1. CryptoJobMode
1141cb0ef41Sopenharmony_ci//   2. Key Variant
1151cb0ef41Sopenharmony_ci//   3. Modulus Bits
1161cb0ef41Sopenharmony_ci//   4. Public Exponent
1171cb0ef41Sopenharmony_ci//   5. Digest
1181cb0ef41Sopenharmony_ci//   6. mgf1 Digest
1191cb0ef41Sopenharmony_ci//   7. Salt length
1201cb0ef41Sopenharmony_ci//   8. Public Format
1211cb0ef41Sopenharmony_ci//   9. Public Type
1221cb0ef41Sopenharmony_ci//   10. Private Format
1231cb0ef41Sopenharmony_ci//   11. Private Type
1241cb0ef41Sopenharmony_ci//   12. Cipher
1251cb0ef41Sopenharmony_ci//   13. Passphrase
1261cb0ef41Sopenharmony_ciMaybe<bool> RsaKeyGenTraits::AdditionalConfig(
1271cb0ef41Sopenharmony_ci    CryptoJobMode mode,
1281cb0ef41Sopenharmony_ci    const FunctionCallbackInfo<Value>& args,
1291cb0ef41Sopenharmony_ci    unsigned int* offset,
1301cb0ef41Sopenharmony_ci    RsaKeyPairGenConfig* params) {
1311cb0ef41Sopenharmony_ci  Environment* env = Environment::GetCurrent(args);
1321cb0ef41Sopenharmony_ci
1331cb0ef41Sopenharmony_ci  CHECK(args[*offset]->IsUint32());  // Variant
1341cb0ef41Sopenharmony_ci  CHECK(args[*offset + 1]->IsUint32());  // Modulus bits
1351cb0ef41Sopenharmony_ci  CHECK(args[*offset + 2]->IsUint32());  // Exponent
1361cb0ef41Sopenharmony_ci
1371cb0ef41Sopenharmony_ci  params->params.variant =
1381cb0ef41Sopenharmony_ci      static_cast<RSAKeyVariant>(args[*offset].As<Uint32>()->Value());
1391cb0ef41Sopenharmony_ci
1401cb0ef41Sopenharmony_ci  CHECK_IMPLIES(params->params.variant != kKeyVariantRSA_PSS,
1411cb0ef41Sopenharmony_ci                args.Length() == 10);
1421cb0ef41Sopenharmony_ci  CHECK_IMPLIES(params->params.variant == kKeyVariantRSA_PSS,
1431cb0ef41Sopenharmony_ci                args.Length() == 13);
1441cb0ef41Sopenharmony_ci
1451cb0ef41Sopenharmony_ci  params->params.modulus_bits = args[*offset + 1].As<Uint32>()->Value();
1461cb0ef41Sopenharmony_ci  params->params.exponent = args[*offset + 2].As<Uint32>()->Value();
1471cb0ef41Sopenharmony_ci
1481cb0ef41Sopenharmony_ci  *offset += 3;
1491cb0ef41Sopenharmony_ci
1501cb0ef41Sopenharmony_ci  if (params->params.variant == kKeyVariantRSA_PSS) {
1511cb0ef41Sopenharmony_ci    if (!args[*offset]->IsUndefined()) {
1521cb0ef41Sopenharmony_ci      CHECK(args[*offset]->IsString());
1531cb0ef41Sopenharmony_ci      Utf8Value digest(env->isolate(), args[*offset]);
1541cb0ef41Sopenharmony_ci      params->params.md = EVP_get_digestbyname(*digest);
1551cb0ef41Sopenharmony_ci      if (params->params.md == nullptr) {
1561cb0ef41Sopenharmony_ci        THROW_ERR_CRYPTO_INVALID_DIGEST(env, "Invalid digest: %s", *digest);
1571cb0ef41Sopenharmony_ci        return Nothing<bool>();
1581cb0ef41Sopenharmony_ci      }
1591cb0ef41Sopenharmony_ci    }
1601cb0ef41Sopenharmony_ci
1611cb0ef41Sopenharmony_ci    if (!args[*offset + 1]->IsUndefined()) {
1621cb0ef41Sopenharmony_ci      CHECK(args[*offset + 1]->IsString());
1631cb0ef41Sopenharmony_ci      Utf8Value digest(env->isolate(), args[*offset + 1]);
1641cb0ef41Sopenharmony_ci      params->params.mgf1_md = EVP_get_digestbyname(*digest);
1651cb0ef41Sopenharmony_ci      if (params->params.mgf1_md == nullptr) {
1661cb0ef41Sopenharmony_ci        THROW_ERR_CRYPTO_INVALID_DIGEST(
1671cb0ef41Sopenharmony_ci            env, "Invalid MGF1 digest: %s", *digest);
1681cb0ef41Sopenharmony_ci        return Nothing<bool>();
1691cb0ef41Sopenharmony_ci      }
1701cb0ef41Sopenharmony_ci    }
1711cb0ef41Sopenharmony_ci
1721cb0ef41Sopenharmony_ci    if (!args[*offset + 2]->IsUndefined()) {
1731cb0ef41Sopenharmony_ci      CHECK(args[*offset + 2]->IsInt32());
1741cb0ef41Sopenharmony_ci      params->params.saltlen = args[*offset + 2].As<Int32>()->Value();
1751cb0ef41Sopenharmony_ci      if (params->params.saltlen < 0) {
1761cb0ef41Sopenharmony_ci        THROW_ERR_OUT_OF_RANGE(
1771cb0ef41Sopenharmony_ci          env,
1781cb0ef41Sopenharmony_ci          "salt length is out of range");
1791cb0ef41Sopenharmony_ci        return Nothing<bool>();
1801cb0ef41Sopenharmony_ci      }
1811cb0ef41Sopenharmony_ci    }
1821cb0ef41Sopenharmony_ci
1831cb0ef41Sopenharmony_ci    *offset += 3;
1841cb0ef41Sopenharmony_ci  }
1851cb0ef41Sopenharmony_ci
1861cb0ef41Sopenharmony_ci  return Just(true);
1871cb0ef41Sopenharmony_ci}
1881cb0ef41Sopenharmony_ci
1891cb0ef41Sopenharmony_cinamespace {
1901cb0ef41Sopenharmony_ciWebCryptoKeyExportStatus RSA_JWK_Export(
1911cb0ef41Sopenharmony_ci    KeyObjectData* key_data,
1921cb0ef41Sopenharmony_ci    const RSAKeyExportConfig& params,
1931cb0ef41Sopenharmony_ci    ByteSource* out) {
1941cb0ef41Sopenharmony_ci  return WebCryptoKeyExportStatus::FAILED;
1951cb0ef41Sopenharmony_ci}
1961cb0ef41Sopenharmony_ci
1971cb0ef41Sopenharmony_citemplate <PublicKeyCipher::EVP_PKEY_cipher_init_t init,
1981cb0ef41Sopenharmony_ci          PublicKeyCipher::EVP_PKEY_cipher_t cipher>
1991cb0ef41Sopenharmony_ciWebCryptoCipherStatus RSA_Cipher(
2001cb0ef41Sopenharmony_ci    Environment* env,
2011cb0ef41Sopenharmony_ci    KeyObjectData* key_data,
2021cb0ef41Sopenharmony_ci    const RSACipherConfig& params,
2031cb0ef41Sopenharmony_ci    const ByteSource& in,
2041cb0ef41Sopenharmony_ci    ByteSource* out) {
2051cb0ef41Sopenharmony_ci  CHECK_NE(key_data->GetKeyType(), kKeyTypeSecret);
2061cb0ef41Sopenharmony_ci  ManagedEVPPKey m_pkey = key_data->GetAsymmetricKey();
2071cb0ef41Sopenharmony_ci  Mutex::ScopedLock lock(*m_pkey.mutex());
2081cb0ef41Sopenharmony_ci
2091cb0ef41Sopenharmony_ci  EVPKeyCtxPointer ctx(EVP_PKEY_CTX_new(m_pkey.get(), nullptr));
2101cb0ef41Sopenharmony_ci
2111cb0ef41Sopenharmony_ci  if (!ctx || init(ctx.get()) <= 0)
2121cb0ef41Sopenharmony_ci    return WebCryptoCipherStatus::FAILED;
2131cb0ef41Sopenharmony_ci
2141cb0ef41Sopenharmony_ci  if (EVP_PKEY_CTX_set_rsa_padding(ctx.get(), params.padding) <= 0) {
2151cb0ef41Sopenharmony_ci    return WebCryptoCipherStatus::FAILED;
2161cb0ef41Sopenharmony_ci  }
2171cb0ef41Sopenharmony_ci
2181cb0ef41Sopenharmony_ci  if (params.digest != nullptr &&
2191cb0ef41Sopenharmony_ci      (EVP_PKEY_CTX_set_rsa_oaep_md(ctx.get(), params.digest) <= 0 ||
2201cb0ef41Sopenharmony_ci       EVP_PKEY_CTX_set_rsa_mgf1_md(ctx.get(), params.digest) <= 0)) {
2211cb0ef41Sopenharmony_ci    return WebCryptoCipherStatus::FAILED;
2221cb0ef41Sopenharmony_ci  }
2231cb0ef41Sopenharmony_ci
2241cb0ef41Sopenharmony_ci  if (!SetRsaOaepLabel(ctx, params.label)) return WebCryptoCipherStatus::FAILED;
2251cb0ef41Sopenharmony_ci
2261cb0ef41Sopenharmony_ci  size_t out_len = 0;
2271cb0ef41Sopenharmony_ci  if (cipher(
2281cb0ef41Sopenharmony_ci          ctx.get(),
2291cb0ef41Sopenharmony_ci          nullptr,
2301cb0ef41Sopenharmony_ci          &out_len,
2311cb0ef41Sopenharmony_ci          in.data<unsigned char>(),
2321cb0ef41Sopenharmony_ci          in.size()) <= 0) {
2331cb0ef41Sopenharmony_ci    return WebCryptoCipherStatus::FAILED;
2341cb0ef41Sopenharmony_ci  }
2351cb0ef41Sopenharmony_ci
2361cb0ef41Sopenharmony_ci  ByteSource::Builder buf(out_len);
2371cb0ef41Sopenharmony_ci
2381cb0ef41Sopenharmony_ci  if (cipher(ctx.get(),
2391cb0ef41Sopenharmony_ci             buf.data<unsigned char>(),
2401cb0ef41Sopenharmony_ci             &out_len,
2411cb0ef41Sopenharmony_ci             in.data<unsigned char>(),
2421cb0ef41Sopenharmony_ci             in.size()) <= 0) {
2431cb0ef41Sopenharmony_ci    return WebCryptoCipherStatus::FAILED;
2441cb0ef41Sopenharmony_ci  }
2451cb0ef41Sopenharmony_ci
2461cb0ef41Sopenharmony_ci  *out = std::move(buf).release(out_len);
2471cb0ef41Sopenharmony_ci  return WebCryptoCipherStatus::OK;
2481cb0ef41Sopenharmony_ci}
2491cb0ef41Sopenharmony_ci}  // namespace
2501cb0ef41Sopenharmony_ci
2511cb0ef41Sopenharmony_ciMaybe<bool> RSAKeyExportTraits::AdditionalConfig(
2521cb0ef41Sopenharmony_ci    const FunctionCallbackInfo<Value>& args,
2531cb0ef41Sopenharmony_ci    unsigned int offset,
2541cb0ef41Sopenharmony_ci    RSAKeyExportConfig* params) {
2551cb0ef41Sopenharmony_ci  CHECK(args[offset]->IsUint32());  // RSAKeyVariant
2561cb0ef41Sopenharmony_ci  params->variant =
2571cb0ef41Sopenharmony_ci      static_cast<RSAKeyVariant>(args[offset].As<Uint32>()->Value());
2581cb0ef41Sopenharmony_ci  return Just(true);
2591cb0ef41Sopenharmony_ci}
2601cb0ef41Sopenharmony_ci
2611cb0ef41Sopenharmony_ciWebCryptoKeyExportStatus RSAKeyExportTraits::DoExport(
2621cb0ef41Sopenharmony_ci    std::shared_ptr<KeyObjectData> key_data,
2631cb0ef41Sopenharmony_ci    WebCryptoKeyFormat format,
2641cb0ef41Sopenharmony_ci    const RSAKeyExportConfig& params,
2651cb0ef41Sopenharmony_ci    ByteSource* out) {
2661cb0ef41Sopenharmony_ci  CHECK_NE(key_data->GetKeyType(), kKeyTypeSecret);
2671cb0ef41Sopenharmony_ci
2681cb0ef41Sopenharmony_ci  switch (format) {
2691cb0ef41Sopenharmony_ci    case kWebCryptoKeyFormatRaw:
2701cb0ef41Sopenharmony_ci      // Not supported for RSA keys of either type
2711cb0ef41Sopenharmony_ci      return WebCryptoKeyExportStatus::FAILED;
2721cb0ef41Sopenharmony_ci    case kWebCryptoKeyFormatJWK:
2731cb0ef41Sopenharmony_ci      return RSA_JWK_Export(key_data.get(), params, out);
2741cb0ef41Sopenharmony_ci    case kWebCryptoKeyFormatPKCS8:
2751cb0ef41Sopenharmony_ci      if (key_data->GetKeyType() != kKeyTypePrivate)
2761cb0ef41Sopenharmony_ci        return WebCryptoKeyExportStatus::INVALID_KEY_TYPE;
2771cb0ef41Sopenharmony_ci      return PKEY_PKCS8_Export(key_data.get(), out);
2781cb0ef41Sopenharmony_ci    case kWebCryptoKeyFormatSPKI:
2791cb0ef41Sopenharmony_ci      if (key_data->GetKeyType() != kKeyTypePublic)
2801cb0ef41Sopenharmony_ci        return WebCryptoKeyExportStatus::INVALID_KEY_TYPE;
2811cb0ef41Sopenharmony_ci      return PKEY_SPKI_Export(key_data.get(), out);
2821cb0ef41Sopenharmony_ci    default:
2831cb0ef41Sopenharmony_ci      UNREACHABLE();
2841cb0ef41Sopenharmony_ci  }
2851cb0ef41Sopenharmony_ci}
2861cb0ef41Sopenharmony_ci
2871cb0ef41Sopenharmony_ciRSACipherConfig::RSACipherConfig(RSACipherConfig&& other) noexcept
2881cb0ef41Sopenharmony_ci    : mode(other.mode),
2891cb0ef41Sopenharmony_ci      label(std::move(other.label)),
2901cb0ef41Sopenharmony_ci      padding(other.padding),
2911cb0ef41Sopenharmony_ci      digest(other.digest) {}
2921cb0ef41Sopenharmony_ci
2931cb0ef41Sopenharmony_civoid RSACipherConfig::MemoryInfo(MemoryTracker* tracker) const {
2941cb0ef41Sopenharmony_ci  if (mode == kCryptoJobAsync)
2951cb0ef41Sopenharmony_ci    tracker->TrackFieldWithSize("label", label.size());
2961cb0ef41Sopenharmony_ci}
2971cb0ef41Sopenharmony_ci
2981cb0ef41Sopenharmony_ciMaybe<bool> RSACipherTraits::AdditionalConfig(
2991cb0ef41Sopenharmony_ci    CryptoJobMode mode,
3001cb0ef41Sopenharmony_ci    const FunctionCallbackInfo<Value>& args,
3011cb0ef41Sopenharmony_ci    unsigned int offset,
3021cb0ef41Sopenharmony_ci    WebCryptoCipherMode cipher_mode,
3031cb0ef41Sopenharmony_ci    RSACipherConfig* params) {
3041cb0ef41Sopenharmony_ci  Environment* env = Environment::GetCurrent(args);
3051cb0ef41Sopenharmony_ci
3061cb0ef41Sopenharmony_ci  params->mode = mode;
3071cb0ef41Sopenharmony_ci  params->padding = RSA_PKCS1_OAEP_PADDING;
3081cb0ef41Sopenharmony_ci
3091cb0ef41Sopenharmony_ci  CHECK(args[offset]->IsUint32());
3101cb0ef41Sopenharmony_ci  RSAKeyVariant variant =
3111cb0ef41Sopenharmony_ci      static_cast<RSAKeyVariant>(args[offset].As<Uint32>()->Value());
3121cb0ef41Sopenharmony_ci
3131cb0ef41Sopenharmony_ci  switch (variant) {
3141cb0ef41Sopenharmony_ci    case kKeyVariantRSA_OAEP: {
3151cb0ef41Sopenharmony_ci      CHECK(args[offset + 1]->IsString());  // digest
3161cb0ef41Sopenharmony_ci      Utf8Value digest(env->isolate(), args[offset + 1]);
3171cb0ef41Sopenharmony_ci
3181cb0ef41Sopenharmony_ci      params->digest = EVP_get_digestbyname(*digest);
3191cb0ef41Sopenharmony_ci      if (params->digest == nullptr) {
3201cb0ef41Sopenharmony_ci        THROW_ERR_CRYPTO_INVALID_DIGEST(env, "Invalid digest: %s", *digest);
3211cb0ef41Sopenharmony_ci        return Nothing<bool>();
3221cb0ef41Sopenharmony_ci      }
3231cb0ef41Sopenharmony_ci
3241cb0ef41Sopenharmony_ci      if (IsAnyByteSource(args[offset + 2])) {
3251cb0ef41Sopenharmony_ci        ArrayBufferOrViewContents<char> label(args[offset + 2]);
3261cb0ef41Sopenharmony_ci        if (UNLIKELY(!label.CheckSizeInt32())) {
3271cb0ef41Sopenharmony_ci          THROW_ERR_OUT_OF_RANGE(env, "label is too big");
3281cb0ef41Sopenharmony_ci          return Nothing<bool>();
3291cb0ef41Sopenharmony_ci        }
3301cb0ef41Sopenharmony_ci        params->label = label.ToCopy();
3311cb0ef41Sopenharmony_ci      }
3321cb0ef41Sopenharmony_ci      break;
3331cb0ef41Sopenharmony_ci    }
3341cb0ef41Sopenharmony_ci    default:
3351cb0ef41Sopenharmony_ci      THROW_ERR_CRYPTO_INVALID_KEYTYPE(env);
3361cb0ef41Sopenharmony_ci      return Nothing<bool>();
3371cb0ef41Sopenharmony_ci  }
3381cb0ef41Sopenharmony_ci
3391cb0ef41Sopenharmony_ci  return Just(true);
3401cb0ef41Sopenharmony_ci}
3411cb0ef41Sopenharmony_ci
3421cb0ef41Sopenharmony_ciWebCryptoCipherStatus RSACipherTraits::DoCipher(
3431cb0ef41Sopenharmony_ci    Environment* env,
3441cb0ef41Sopenharmony_ci    std::shared_ptr<KeyObjectData> key_data,
3451cb0ef41Sopenharmony_ci    WebCryptoCipherMode cipher_mode,
3461cb0ef41Sopenharmony_ci    const RSACipherConfig& params,
3471cb0ef41Sopenharmony_ci    const ByteSource& in,
3481cb0ef41Sopenharmony_ci    ByteSource* out) {
3491cb0ef41Sopenharmony_ci  switch (cipher_mode) {
3501cb0ef41Sopenharmony_ci    case kWebCryptoCipherEncrypt:
3511cb0ef41Sopenharmony_ci      CHECK_EQ(key_data->GetKeyType(), kKeyTypePublic);
3521cb0ef41Sopenharmony_ci      return RSA_Cipher<EVP_PKEY_encrypt_init, EVP_PKEY_encrypt>(
3531cb0ef41Sopenharmony_ci          env, key_data.get(), params, in, out);
3541cb0ef41Sopenharmony_ci    case kWebCryptoCipherDecrypt:
3551cb0ef41Sopenharmony_ci      CHECK_EQ(key_data->GetKeyType(), kKeyTypePrivate);
3561cb0ef41Sopenharmony_ci      return RSA_Cipher<EVP_PKEY_decrypt_init, EVP_PKEY_decrypt>(
3571cb0ef41Sopenharmony_ci          env, key_data.get(), params, in, out);
3581cb0ef41Sopenharmony_ci  }
3591cb0ef41Sopenharmony_ci  return WebCryptoCipherStatus::FAILED;
3601cb0ef41Sopenharmony_ci}
3611cb0ef41Sopenharmony_ci
3621cb0ef41Sopenharmony_ciMaybe<bool> ExportJWKRsaKey(
3631cb0ef41Sopenharmony_ci    Environment* env,
3641cb0ef41Sopenharmony_ci    std::shared_ptr<KeyObjectData> key,
3651cb0ef41Sopenharmony_ci    Local<Object> target) {
3661cb0ef41Sopenharmony_ci  ManagedEVPPKey m_pkey = key->GetAsymmetricKey();
3671cb0ef41Sopenharmony_ci  Mutex::ScopedLock lock(*m_pkey.mutex());
3681cb0ef41Sopenharmony_ci  int type = EVP_PKEY_id(m_pkey.get());
3691cb0ef41Sopenharmony_ci  CHECK(type == EVP_PKEY_RSA || type == EVP_PKEY_RSA_PSS);
3701cb0ef41Sopenharmony_ci
3711cb0ef41Sopenharmony_ci  // TODO(tniessen): Remove the "else" branch once we drop support for OpenSSL
3721cb0ef41Sopenharmony_ci  // versions older than 1.1.1e via FIPS / dynamic linking.
3731cb0ef41Sopenharmony_ci  const RSA* rsa;
3741cb0ef41Sopenharmony_ci  if (OpenSSL_version_num() >= 0x1010105fL) {
3751cb0ef41Sopenharmony_ci    rsa = EVP_PKEY_get0_RSA(m_pkey.get());
3761cb0ef41Sopenharmony_ci  } else {
3771cb0ef41Sopenharmony_ci    rsa = static_cast<const RSA*>(EVP_PKEY_get0(m_pkey.get()));
3781cb0ef41Sopenharmony_ci  }
3791cb0ef41Sopenharmony_ci  CHECK_NOT_NULL(rsa);
3801cb0ef41Sopenharmony_ci
3811cb0ef41Sopenharmony_ci  const BIGNUM* n;
3821cb0ef41Sopenharmony_ci  const BIGNUM* e;
3831cb0ef41Sopenharmony_ci  const BIGNUM* d;
3841cb0ef41Sopenharmony_ci  const BIGNUM* p;
3851cb0ef41Sopenharmony_ci  const BIGNUM* q;
3861cb0ef41Sopenharmony_ci  const BIGNUM* dp;
3871cb0ef41Sopenharmony_ci  const BIGNUM* dq;
3881cb0ef41Sopenharmony_ci  const BIGNUM* qi;
3891cb0ef41Sopenharmony_ci  RSA_get0_key(rsa, &n, &e, &d);
3901cb0ef41Sopenharmony_ci
3911cb0ef41Sopenharmony_ci  if (target->Set(
3921cb0ef41Sopenharmony_ci          env->context(),
3931cb0ef41Sopenharmony_ci          env->jwk_kty_string(),
3941cb0ef41Sopenharmony_ci          env->jwk_rsa_string()).IsNothing()) {
3951cb0ef41Sopenharmony_ci    return Nothing<bool>();
3961cb0ef41Sopenharmony_ci  }
3971cb0ef41Sopenharmony_ci
3981cb0ef41Sopenharmony_ci  if (SetEncodedValue(env, target, env->jwk_n_string(), n).IsNothing() ||
3991cb0ef41Sopenharmony_ci      SetEncodedValue(env, target, env->jwk_e_string(), e).IsNothing()) {
4001cb0ef41Sopenharmony_ci    return Nothing<bool>();
4011cb0ef41Sopenharmony_ci  }
4021cb0ef41Sopenharmony_ci
4031cb0ef41Sopenharmony_ci  if (key->GetKeyType() == kKeyTypePrivate) {
4041cb0ef41Sopenharmony_ci    RSA_get0_factors(rsa, &p, &q);
4051cb0ef41Sopenharmony_ci    RSA_get0_crt_params(rsa, &dp, &dq, &qi);
4061cb0ef41Sopenharmony_ci    if (SetEncodedValue(env, target, env->jwk_d_string(), d).IsNothing() ||
4071cb0ef41Sopenharmony_ci        SetEncodedValue(env, target, env->jwk_p_string(), p).IsNothing() ||
4081cb0ef41Sopenharmony_ci        SetEncodedValue(env, target, env->jwk_q_string(), q).IsNothing() ||
4091cb0ef41Sopenharmony_ci        SetEncodedValue(env, target, env->jwk_dp_string(), dp).IsNothing() ||
4101cb0ef41Sopenharmony_ci        SetEncodedValue(env, target, env->jwk_dq_string(), dq).IsNothing() ||
4111cb0ef41Sopenharmony_ci        SetEncodedValue(env, target, env->jwk_qi_string(), qi).IsNothing()) {
4121cb0ef41Sopenharmony_ci      return Nothing<bool>();
4131cb0ef41Sopenharmony_ci    }
4141cb0ef41Sopenharmony_ci  }
4151cb0ef41Sopenharmony_ci
4161cb0ef41Sopenharmony_ci  return Just(true);
4171cb0ef41Sopenharmony_ci}
4181cb0ef41Sopenharmony_ci
4191cb0ef41Sopenharmony_cistd::shared_ptr<KeyObjectData> ImportJWKRsaKey(
4201cb0ef41Sopenharmony_ci    Environment* env,
4211cb0ef41Sopenharmony_ci    Local<Object> jwk,
4221cb0ef41Sopenharmony_ci    const FunctionCallbackInfo<Value>& args,
4231cb0ef41Sopenharmony_ci    unsigned int offset) {
4241cb0ef41Sopenharmony_ci  Local<Value> n_value;
4251cb0ef41Sopenharmony_ci  Local<Value> e_value;
4261cb0ef41Sopenharmony_ci  Local<Value> d_value;
4271cb0ef41Sopenharmony_ci
4281cb0ef41Sopenharmony_ci  if (!jwk->Get(env->context(), env->jwk_n_string()).ToLocal(&n_value) ||
4291cb0ef41Sopenharmony_ci      !jwk->Get(env->context(), env->jwk_e_string()).ToLocal(&e_value) ||
4301cb0ef41Sopenharmony_ci      !jwk->Get(env->context(), env->jwk_d_string()).ToLocal(&d_value) ||
4311cb0ef41Sopenharmony_ci      !n_value->IsString() ||
4321cb0ef41Sopenharmony_ci      !e_value->IsString()) {
4331cb0ef41Sopenharmony_ci    THROW_ERR_CRYPTO_INVALID_JWK(env, "Invalid JWK RSA key");
4341cb0ef41Sopenharmony_ci    return std::shared_ptr<KeyObjectData>();
4351cb0ef41Sopenharmony_ci  }
4361cb0ef41Sopenharmony_ci
4371cb0ef41Sopenharmony_ci  if (!d_value->IsUndefined() && !d_value->IsString()) {
4381cb0ef41Sopenharmony_ci    THROW_ERR_CRYPTO_INVALID_JWK(env, "Invalid JWK RSA key");
4391cb0ef41Sopenharmony_ci    return std::shared_ptr<KeyObjectData>();
4401cb0ef41Sopenharmony_ci  }
4411cb0ef41Sopenharmony_ci
4421cb0ef41Sopenharmony_ci  KeyType type = d_value->IsString() ? kKeyTypePrivate : kKeyTypePublic;
4431cb0ef41Sopenharmony_ci
4441cb0ef41Sopenharmony_ci  RsaPointer rsa(RSA_new());
4451cb0ef41Sopenharmony_ci
4461cb0ef41Sopenharmony_ci  ByteSource n = ByteSource::FromEncodedString(env, n_value.As<String>());
4471cb0ef41Sopenharmony_ci  ByteSource e = ByteSource::FromEncodedString(env, e_value.As<String>());
4481cb0ef41Sopenharmony_ci
4491cb0ef41Sopenharmony_ci  if (!RSA_set0_key(
4501cb0ef41Sopenharmony_ci          rsa.get(),
4511cb0ef41Sopenharmony_ci          n.ToBN().release(),
4521cb0ef41Sopenharmony_ci          e.ToBN().release(),
4531cb0ef41Sopenharmony_ci          nullptr)) {
4541cb0ef41Sopenharmony_ci    THROW_ERR_CRYPTO_INVALID_JWK(env, "Invalid JWK RSA key");
4551cb0ef41Sopenharmony_ci    return std::shared_ptr<KeyObjectData>();
4561cb0ef41Sopenharmony_ci  }
4571cb0ef41Sopenharmony_ci
4581cb0ef41Sopenharmony_ci  if (type == kKeyTypePrivate) {
4591cb0ef41Sopenharmony_ci    Local<Value> p_value;
4601cb0ef41Sopenharmony_ci    Local<Value> q_value;
4611cb0ef41Sopenharmony_ci    Local<Value> dp_value;
4621cb0ef41Sopenharmony_ci    Local<Value> dq_value;
4631cb0ef41Sopenharmony_ci    Local<Value> qi_value;
4641cb0ef41Sopenharmony_ci
4651cb0ef41Sopenharmony_ci    if (!jwk->Get(env->context(), env->jwk_p_string()).ToLocal(&p_value) ||
4661cb0ef41Sopenharmony_ci        !jwk->Get(env->context(), env->jwk_q_string()).ToLocal(&q_value) ||
4671cb0ef41Sopenharmony_ci        !jwk->Get(env->context(), env->jwk_dp_string()).ToLocal(&dp_value) ||
4681cb0ef41Sopenharmony_ci        !jwk->Get(env->context(), env->jwk_dq_string()).ToLocal(&dq_value) ||
4691cb0ef41Sopenharmony_ci        !jwk->Get(env->context(), env->jwk_qi_string()).ToLocal(&qi_value)) {
4701cb0ef41Sopenharmony_ci      THROW_ERR_CRYPTO_INVALID_JWK(env, "Invalid JWK RSA key");
4711cb0ef41Sopenharmony_ci      return std::shared_ptr<KeyObjectData>();
4721cb0ef41Sopenharmony_ci    }
4731cb0ef41Sopenharmony_ci
4741cb0ef41Sopenharmony_ci    if (!p_value->IsString() ||
4751cb0ef41Sopenharmony_ci        !q_value->IsString() ||
4761cb0ef41Sopenharmony_ci        !dp_value->IsString() ||
4771cb0ef41Sopenharmony_ci        !dq_value->IsString() ||
4781cb0ef41Sopenharmony_ci        !qi_value->IsString()) {
4791cb0ef41Sopenharmony_ci      THROW_ERR_CRYPTO_INVALID_JWK(env, "Invalid JWK RSA key");
4801cb0ef41Sopenharmony_ci      return std::shared_ptr<KeyObjectData>();
4811cb0ef41Sopenharmony_ci    }
4821cb0ef41Sopenharmony_ci
4831cb0ef41Sopenharmony_ci    ByteSource d = ByteSource::FromEncodedString(env, d_value.As<String>());
4841cb0ef41Sopenharmony_ci    ByteSource q = ByteSource::FromEncodedString(env, q_value.As<String>());
4851cb0ef41Sopenharmony_ci    ByteSource p = ByteSource::FromEncodedString(env, p_value.As<String>());
4861cb0ef41Sopenharmony_ci    ByteSource dp = ByteSource::FromEncodedString(env, dp_value.As<String>());
4871cb0ef41Sopenharmony_ci    ByteSource dq = ByteSource::FromEncodedString(env, dq_value.As<String>());
4881cb0ef41Sopenharmony_ci    ByteSource qi = ByteSource::FromEncodedString(env, qi_value.As<String>());
4891cb0ef41Sopenharmony_ci
4901cb0ef41Sopenharmony_ci    if (!RSA_set0_key(rsa.get(), nullptr, nullptr, d.ToBN().release()) ||
4911cb0ef41Sopenharmony_ci        !RSA_set0_factors(rsa.get(), p.ToBN().release(), q.ToBN().release()) ||
4921cb0ef41Sopenharmony_ci        !RSA_set0_crt_params(
4931cb0ef41Sopenharmony_ci            rsa.get(),
4941cb0ef41Sopenharmony_ci            dp.ToBN().release(),
4951cb0ef41Sopenharmony_ci            dq.ToBN().release(),
4961cb0ef41Sopenharmony_ci            qi.ToBN().release())) {
4971cb0ef41Sopenharmony_ci      THROW_ERR_CRYPTO_INVALID_JWK(env, "Invalid JWK RSA key");
4981cb0ef41Sopenharmony_ci      return std::shared_ptr<KeyObjectData>();
4991cb0ef41Sopenharmony_ci    }
5001cb0ef41Sopenharmony_ci  }
5011cb0ef41Sopenharmony_ci
5021cb0ef41Sopenharmony_ci  EVPKeyPointer pkey(EVP_PKEY_new());
5031cb0ef41Sopenharmony_ci  CHECK_EQ(EVP_PKEY_set1_RSA(pkey.get(), rsa.get()), 1);
5041cb0ef41Sopenharmony_ci
5051cb0ef41Sopenharmony_ci  return KeyObjectData::CreateAsymmetric(type, ManagedEVPPKey(std::move(pkey)));
5061cb0ef41Sopenharmony_ci}
5071cb0ef41Sopenharmony_ci
5081cb0ef41Sopenharmony_ciMaybe<bool> GetRsaKeyDetail(
5091cb0ef41Sopenharmony_ci    Environment* env,
5101cb0ef41Sopenharmony_ci    std::shared_ptr<KeyObjectData> key,
5111cb0ef41Sopenharmony_ci    Local<Object> target) {
5121cb0ef41Sopenharmony_ci  const BIGNUM* e;  // Public Exponent
5131cb0ef41Sopenharmony_ci  const BIGNUM* n;  // Modulus
5141cb0ef41Sopenharmony_ci
5151cb0ef41Sopenharmony_ci  ManagedEVPPKey m_pkey = key->GetAsymmetricKey();
5161cb0ef41Sopenharmony_ci  Mutex::ScopedLock lock(*m_pkey.mutex());
5171cb0ef41Sopenharmony_ci  int type = EVP_PKEY_id(m_pkey.get());
5181cb0ef41Sopenharmony_ci  CHECK(type == EVP_PKEY_RSA || type == EVP_PKEY_RSA_PSS);
5191cb0ef41Sopenharmony_ci
5201cb0ef41Sopenharmony_ci  // TODO(tniessen): Remove the "else" branch once we drop support for OpenSSL
5211cb0ef41Sopenharmony_ci  // versions older than 1.1.1e via FIPS / dynamic linking.
5221cb0ef41Sopenharmony_ci  const RSA* rsa;
5231cb0ef41Sopenharmony_ci  if (OpenSSL_version_num() >= 0x1010105fL) {
5241cb0ef41Sopenharmony_ci    rsa = EVP_PKEY_get0_RSA(m_pkey.get());
5251cb0ef41Sopenharmony_ci  } else {
5261cb0ef41Sopenharmony_ci    rsa = static_cast<const RSA*>(EVP_PKEY_get0(m_pkey.get()));
5271cb0ef41Sopenharmony_ci  }
5281cb0ef41Sopenharmony_ci  CHECK_NOT_NULL(rsa);
5291cb0ef41Sopenharmony_ci
5301cb0ef41Sopenharmony_ci  RSA_get0_key(rsa, &n, &e, nullptr);
5311cb0ef41Sopenharmony_ci
5321cb0ef41Sopenharmony_ci  size_t modulus_length = BN_num_bits(n);
5331cb0ef41Sopenharmony_ci
5341cb0ef41Sopenharmony_ci  if (target
5351cb0ef41Sopenharmony_ci          ->Set(
5361cb0ef41Sopenharmony_ci              env->context(),
5371cb0ef41Sopenharmony_ci              env->modulus_length_string(),
5381cb0ef41Sopenharmony_ci              Number::New(env->isolate(), static_cast<double>(modulus_length)))
5391cb0ef41Sopenharmony_ci          .IsNothing()) {
5401cb0ef41Sopenharmony_ci    return Nothing<bool>();
5411cb0ef41Sopenharmony_ci  }
5421cb0ef41Sopenharmony_ci
5431cb0ef41Sopenharmony_ci  std::unique_ptr<BackingStore> public_exponent;
5441cb0ef41Sopenharmony_ci  {
5451cb0ef41Sopenharmony_ci    NoArrayBufferZeroFillScope no_zero_fill_scope(env->isolate_data());
5461cb0ef41Sopenharmony_ci    public_exponent =
5471cb0ef41Sopenharmony_ci        ArrayBuffer::NewBackingStore(env->isolate(), BN_num_bytes(e));
5481cb0ef41Sopenharmony_ci  }
5491cb0ef41Sopenharmony_ci  CHECK_EQ(BN_bn2binpad(e,
5501cb0ef41Sopenharmony_ci                        static_cast<unsigned char*>(public_exponent->Data()),
5511cb0ef41Sopenharmony_ci                        public_exponent->ByteLength()),
5521cb0ef41Sopenharmony_ci           static_cast<int>(public_exponent->ByteLength()));
5531cb0ef41Sopenharmony_ci
5541cb0ef41Sopenharmony_ci  if (target
5551cb0ef41Sopenharmony_ci          ->Set(env->context(),
5561cb0ef41Sopenharmony_ci                env->public_exponent_string(),
5571cb0ef41Sopenharmony_ci                ArrayBuffer::New(env->isolate(), std::move(public_exponent)))
5581cb0ef41Sopenharmony_ci          .IsNothing()) {
5591cb0ef41Sopenharmony_ci    return Nothing<bool>();
5601cb0ef41Sopenharmony_ci  }
5611cb0ef41Sopenharmony_ci
5621cb0ef41Sopenharmony_ci  if (type == EVP_PKEY_RSA_PSS) {
5631cb0ef41Sopenharmony_ci    // Due to the way ASN.1 encoding works, default values are omitted when
5641cb0ef41Sopenharmony_ci    // encoding the data structure. However, there are also RSA-PSS keys for
5651cb0ef41Sopenharmony_ci    // which no parameters are set. In that case, the ASN.1 RSASSA-PSS-params
5661cb0ef41Sopenharmony_ci    // sequence will be missing entirely and RSA_get0_pss_params will return
5671cb0ef41Sopenharmony_ci    // nullptr. If parameters are present but all parameters are set to their
5681cb0ef41Sopenharmony_ci    // default values, an empty sequence will be stored in the ASN.1 structure.
5691cb0ef41Sopenharmony_ci    // In that case, RSA_get0_pss_params does not return nullptr but all fields
5701cb0ef41Sopenharmony_ci    // of the returned RSA_PSS_PARAMS will be set to nullptr.
5711cb0ef41Sopenharmony_ci
5721cb0ef41Sopenharmony_ci    const RSA_PSS_PARAMS* params = RSA_get0_pss_params(rsa);
5731cb0ef41Sopenharmony_ci    if (params != nullptr) {
5741cb0ef41Sopenharmony_ci      int hash_nid = NID_sha1;
5751cb0ef41Sopenharmony_ci      int mgf_nid = NID_mgf1;
5761cb0ef41Sopenharmony_ci      int mgf1_hash_nid = NID_sha1;
5771cb0ef41Sopenharmony_ci      int64_t salt_length = 20;
5781cb0ef41Sopenharmony_ci
5791cb0ef41Sopenharmony_ci      if (params->hashAlgorithm != nullptr) {
5801cb0ef41Sopenharmony_ci        hash_nid = OBJ_obj2nid(params->hashAlgorithm->algorithm);
5811cb0ef41Sopenharmony_ci      }
5821cb0ef41Sopenharmony_ci
5831cb0ef41Sopenharmony_ci      if (target
5841cb0ef41Sopenharmony_ci              ->Set(
5851cb0ef41Sopenharmony_ci                  env->context(),
5861cb0ef41Sopenharmony_ci                  env->hash_algorithm_string(),
5871cb0ef41Sopenharmony_ci                  OneByteString(env->isolate(), OBJ_nid2ln(hash_nid)))
5881cb0ef41Sopenharmony_ci              .IsNothing()) {
5891cb0ef41Sopenharmony_ci        return Nothing<bool>();
5901cb0ef41Sopenharmony_ci      }
5911cb0ef41Sopenharmony_ci
5921cb0ef41Sopenharmony_ci      if (params->maskGenAlgorithm != nullptr) {
5931cb0ef41Sopenharmony_ci        mgf_nid = OBJ_obj2nid(params->maskGenAlgorithm->algorithm);
5941cb0ef41Sopenharmony_ci        if (mgf_nid == NID_mgf1) {
5951cb0ef41Sopenharmony_ci          mgf1_hash_nid = OBJ_obj2nid(params->maskHash->algorithm);
5961cb0ef41Sopenharmony_ci        }
5971cb0ef41Sopenharmony_ci      }
5981cb0ef41Sopenharmony_ci
5991cb0ef41Sopenharmony_ci      // If, for some reason, the MGF is not MGF1, then the MGF1 hash function
6001cb0ef41Sopenharmony_ci      // is intentionally not added to the object.
6011cb0ef41Sopenharmony_ci      if (mgf_nid == NID_mgf1) {
6021cb0ef41Sopenharmony_ci        if (target
6031cb0ef41Sopenharmony_ci                ->Set(
6041cb0ef41Sopenharmony_ci                    env->context(),
6051cb0ef41Sopenharmony_ci                    env->mgf1_hash_algorithm_string(),
6061cb0ef41Sopenharmony_ci                    OneByteString(env->isolate(), OBJ_nid2ln(mgf1_hash_nid)))
6071cb0ef41Sopenharmony_ci                .IsNothing()) {
6081cb0ef41Sopenharmony_ci          return Nothing<bool>();
6091cb0ef41Sopenharmony_ci        }
6101cb0ef41Sopenharmony_ci      }
6111cb0ef41Sopenharmony_ci
6121cb0ef41Sopenharmony_ci      if (params->saltLength != nullptr) {
6131cb0ef41Sopenharmony_ci        if (ASN1_INTEGER_get_int64(&salt_length, params->saltLength) != 1) {
6141cb0ef41Sopenharmony_ci          ThrowCryptoError(env, ERR_get_error(), "ASN1_INTEGER_get_in64 error");
6151cb0ef41Sopenharmony_ci          return Nothing<bool>();
6161cb0ef41Sopenharmony_ci        }
6171cb0ef41Sopenharmony_ci      }
6181cb0ef41Sopenharmony_ci
6191cb0ef41Sopenharmony_ci      if (target
6201cb0ef41Sopenharmony_ci              ->Set(
6211cb0ef41Sopenharmony_ci                  env->context(),
6221cb0ef41Sopenharmony_ci                  env->salt_length_string(),
6231cb0ef41Sopenharmony_ci                  Number::New(env->isolate(), static_cast<double>(salt_length)))
6241cb0ef41Sopenharmony_ci              .IsNothing()) {
6251cb0ef41Sopenharmony_ci        return Nothing<bool>();
6261cb0ef41Sopenharmony_ci      }
6271cb0ef41Sopenharmony_ci    }
6281cb0ef41Sopenharmony_ci  }
6291cb0ef41Sopenharmony_ci
6301cb0ef41Sopenharmony_ci  return Just<bool>(true);
6311cb0ef41Sopenharmony_ci}
6321cb0ef41Sopenharmony_ci
6331cb0ef41Sopenharmony_cinamespace RSAAlg {
6341cb0ef41Sopenharmony_civoid Initialize(Environment* env, Local<Object> target) {
6351cb0ef41Sopenharmony_ci  RSAKeyPairGenJob::Initialize(env, target);
6361cb0ef41Sopenharmony_ci  RSAKeyExportJob::Initialize(env, target);
6371cb0ef41Sopenharmony_ci  RSACipherJob::Initialize(env, target);
6381cb0ef41Sopenharmony_ci
6391cb0ef41Sopenharmony_ci  NODE_DEFINE_CONSTANT(target, kKeyVariantRSA_SSA_PKCS1_v1_5);
6401cb0ef41Sopenharmony_ci  NODE_DEFINE_CONSTANT(target, kKeyVariantRSA_PSS);
6411cb0ef41Sopenharmony_ci  NODE_DEFINE_CONSTANT(target, kKeyVariantRSA_OAEP);
6421cb0ef41Sopenharmony_ci}
6431cb0ef41Sopenharmony_ci
6441cb0ef41Sopenharmony_civoid RegisterExternalReferences(ExternalReferenceRegistry* registry) {
6451cb0ef41Sopenharmony_ci  RSAKeyPairGenJob::RegisterExternalReferences(registry);
6461cb0ef41Sopenharmony_ci  RSAKeyExportJob::RegisterExternalReferences(registry);
6471cb0ef41Sopenharmony_ci  RSACipherJob::RegisterExternalReferences(registry);
6481cb0ef41Sopenharmony_ci}
6491cb0ef41Sopenharmony_ci}  // namespace RSAAlg
6501cb0ef41Sopenharmony_ci}  // namespace crypto
6511cb0ef41Sopenharmony_ci}  // namespace node
652