diff --git a/deps/ncrypto/ncrypto.cc b/deps/ncrypto/ncrypto.cc index 69f7920c1cbca3e..220e0f253715fef 100644 --- a/deps/ncrypto/ncrypto.cc +++ b/deps/ncrypto/ncrypto.cc @@ -1669,17 +1669,17 @@ const EVP_CIPHER* getCipherByName(const std::string_view name) { return EVP_get_cipherbyname(name.data()); } -bool checkHkdfLength(const EVP_MD* md, size_t length) { +bool checkHkdfLength(const Digest& md, size_t length) { // HKDF-Expand computes up to 255 HMAC blocks, each having as many bits as // the output of the hash function. 255 is a hard limit because HKDF appends // an 8-bit counter to each HMAC'd message, starting at 1. static constexpr size_t kMaxDigestMultiplier = 255; - size_t max_length = EVP_MD_size(md) * kMaxDigestMultiplier; + size_t max_length = md.size() * kMaxDigestMultiplier; if (length > max_length) return false; return true; } -DataPointer hkdf(const EVP_MD* md, +DataPointer hkdf(const Digest& md, const Buffer& key, const Buffer& info, const Buffer& salt, @@ -1703,7 +1703,7 @@ DataPointer hkdf(const EVP_MD* md, if (salt.len > 0) { actual_salt = {reinterpret_cast(salt.data), salt.len}; } else { - actual_salt = {default_salt, static_cast(EVP_MD_size(md))}; + actual_salt = {default_salt, static_cast(md.size())}; } // We do not use EVP_PKEY_HKDF_MODE_EXTRACT_AND_EXPAND because and instead @@ -2786,6 +2786,11 @@ bool Cipher::isStreamMode() const { return getMode() == EVP_CIPH_STREAM_CIPHER; } +bool Cipher::isChaCha20Poly1305() const { + if (!cipher_) return false; + return getNid() == NID_chacha20_poly1305; +} + int Cipher::getMode() const { if (!cipher_) return 0; return EVP_CIPHER_mode(cipher_); @@ -2862,6 +2867,14 @@ bool Cipher::isSupportedAuthenticatedMode() const { } } +int Cipher::bytesToKey(const Digest& digest, + const Buffer& input, + unsigned char* key, + unsigned char* iv) const { + return EVP_BytesToKey( + *this, Digest::MD5, nullptr, input.data, input.len, 1, key, iv); +} + // ============================================================================ CipherCtxPointer CipherCtxPointer::New() { @@ -2938,6 +2951,26 @@ int CipherCtxPointer::getMode() const { return EVP_CIPHER_CTX_mode(ctx_.get()); } +bool CipherCtxPointer::isGcmMode() const { + if (!ctx_) return false; + return getMode() == EVP_CIPH_GCM_MODE; +} + +bool CipherCtxPointer::isCcmMode() const { + if (!ctx_) return false; + return getMode() == EVP_CIPH_CCM_MODE; +} + +bool CipherCtxPointer::isWrapMode() const { + if (!ctx_) return false; + return getMode() == EVP_CIPH_WRAP_MODE; +} + +bool CipherCtxPointer::isChaCha20Poly1305() const { + if (!ctx_) return false; + return getNid() == NID_chacha20_poly1305; +} + int CipherCtxPointer::getNid() const { if (!ctx_) return 0; return EVP_CIPHER_CTX_nid(ctx_.get()); @@ -3720,9 +3753,7 @@ DataPointer Cipher::recover(const EVPKeyPointer& key, namespace { struct CipherCallbackContext { Cipher::CipherNameCallback cb; - void operator()(std::string_view name) { - cb(name); - } + void operator()(std::string_view name) { cb(name); } }; #if OPENSSL_VERSION_MAJOR >= 3 @@ -3759,9 +3790,9 @@ void array_push_back(const TypeName* evp_ref, #else template void array_push_back(const TypeName* evp_ref, - const char* from, - const char* to, - void* arg) { + const char* from, + const char* to, + void* arg) { if (!from) return; auto& cb = *(static_cast(arg)); cb(from); @@ -3776,15 +3807,15 @@ void Cipher::ForEach(Cipher::CipherNameCallback callback) { EVP_CIPHER_do_all_sorted( #if OPENSSL_VERSION_MAJOR >= 3 - array_push_back, + array_push_back, #else - array_push_back, + array_push_back, #endif - &context); + &context); } // ============================================================================ @@ -4143,4 +4174,21 @@ size_t Dsa::getDivisorLength() const { return BignumPointer::GetBitCount(getQ()); } +// ============================================================================ + +size_t Digest::size() const { + if (md_ == nullptr) return 0; + return EVP_MD_size(md_); +} + +const Digest Digest::MD5 = Digest(EVP_md5()); +const Digest Digest::SHA1 = Digest(EVP_sha1()); +const Digest Digest::SHA256 = Digest(EVP_sha256()); +const Digest Digest::SHA384 = Digest(EVP_sha384()); +const Digest Digest::SHA512 = Digest(EVP_sha512()); + +const Digest Digest::FromName(std::string_view name) { + return ncrypto::getDigestByName(name); +} + } // namespace ncrypto diff --git a/deps/ncrypto/ncrypto.h b/deps/ncrypto/ncrypto.h index 12fbe964fbf5173..ad86ea58e028dfd 100644 --- a/deps/ncrypto/ncrypto.h +++ b/deps/ncrypto/ncrypto.h @@ -247,11 +247,44 @@ struct Buffer { size_t len = 0; }; +class Digest final { + public: + Digest() = default; + Digest(const EVP_MD* md) : md_(md) {} + Digest(const Digest&) = default; + Digest& operator=(const Digest&) = default; + inline Digest& operator=(const EVP_MD* md) { + md_ = md; + return *this; + } + NCRYPTO_DISALLOW_MOVE(Digest) + + size_t size() const; + + inline const EVP_MD* get() const { return md_; } + inline operator const EVP_MD*() const { return md_; } + inline operator bool() const { return md_ != nullptr; } + + static const Digest MD5; + static const Digest SHA1; + static const Digest SHA256; + static const Digest SHA384; + static const Digest SHA512; + + static const Digest FromName(std::string_view name); + + private: + const EVP_MD* md_ = nullptr; +}; + DataPointer hashDigest(const Buffer& data, const EVP_MD* md); class Cipher final { public: + static constexpr size_t MAX_KEY_LENGTH = EVP_MAX_KEY_LENGTH; + static constexpr size_t MAX_IV_LENGTH = EVP_MAX_IV_LENGTH; + Cipher() = default; Cipher(const EVP_CIPHER* cipher) : cipher_(cipher) {} Cipher(const Cipher&) = default; @@ -280,9 +313,15 @@ class Cipher final { bool isCcmMode() const; bool isOcbMode() const; bool isStreamMode() const; + bool isChaCha20Poly1305() const; bool isSupportedAuthenticatedMode() const; + int bytesToKey(const Digest& digest, + const Buffer& input, + unsigned char* key, + unsigned char* iv) const; + static const Cipher FromName(std::string_view name); static const Cipher FromNid(int nid); static const Cipher FromCtx(const CipherCtxPointer& ctx); @@ -644,6 +683,11 @@ class CipherCtxPointer final { int getMode() const; int getNid() const; + bool isGcmMode() const; + bool isCcmMode() const; + bool isWrapMode() const; + bool isChaCha20Poly1305() const; + bool update(const Buffer& in, unsigned char* out, int* out_len, @@ -1420,13 +1464,13 @@ const EVP_CIPHER* getCipherByName(const std::string_view name); // Verify that the specified HKDF output length is valid for the given digest. // The maximum length for HKDF output for a given digest is 255 times the // hash size for the given digest algorithm. -bool checkHkdfLength(const EVP_MD* md, size_t length); +bool checkHkdfLength(const Digest& digest, size_t length); bool extractP1363(const Buffer& buf, unsigned char* dest, size_t n); -DataPointer hkdf(const EVP_MD* md, +DataPointer hkdf(const Digest& md, const Buffer& key, const Buffer& info, const Buffer& salt, diff --git a/src/crypto/crypto_aes.cc b/src/crypto/crypto_aes.cc index d723ea54e3afb8a..48c2fbde65dc318 100644 --- a/src/crypto/crypto_aes.cc +++ b/src/crypto/crypto_aes.cc @@ -484,7 +484,7 @@ Maybe AESCipherTraits::AdditionalConfig( return Nothing(); } - if (params->cipher.isWrapMode()) { + if (!params->cipher.isWrapMode()) { if (!ValidateIV(env, mode, args[offset + 1], params)) { return Nothing(); } diff --git a/src/crypto/crypto_cipher.cc b/src/crypto/crypto_cipher.cc index 0e71890564bc4a3..7d7f78d329c074b 100644 --- a/src/crypto/crypto_cipher.cc +++ b/src/crypto/crypto_cipher.cc @@ -12,6 +12,8 @@ namespace node { using ncrypto::Cipher; using ncrypto::CipherCtxPointer; +using ncrypto::ClearErrorOnReturn; +using ncrypto::Digest; using ncrypto::EVPKeyCtxPointer; using ncrypto::EVPKeyPointer; using ncrypto::MarkPopErrorOnReturn; @@ -157,19 +159,18 @@ void GetCipherInfo(const FunctionCallbackInfo& args) { } // namespace void CipherBase::GetSSLCiphers(const FunctionCallbackInfo& args) { - MarkPopErrorOnReturn mark_pop_error_on_return; + ClearErrorOnReturn clear_error_on_return; Environment* env = Environment::GetCurrent(args); auto ctx = SSLCtxPointer::New(); if (!ctx) { return ThrowCryptoError( - env, mark_pop_error_on_return.peekError(), "SSL_CTX_new"); + env, clear_error_on_return.peekError(), "SSL_CTX_new"); } auto ssl = SSLPointer::New(ctx); if (!ssl) { - return ThrowCryptoError( - env, mark_pop_error_on_return.peekError(), "SSL_new"); + return ThrowCryptoError(env, clear_error_on_return.peekError(), "SSL_new"); } LocalVector arr(env->isolate()); @@ -304,7 +305,7 @@ void CipherBase::New(const FunctionCallbackInfo& args) { new CipherBase(env, args.This(), args[0]->IsTrue() ? kCipher : kDecipher); } -void CipherBase::CommonInit(const char* cipher_type, +void CipherBase::CommonInit(std::string_view cipher_type, const ncrypto::Cipher& cipher, const unsigned char* key, int key_len, @@ -346,32 +347,28 @@ void CipherBase::CommonInit(const char* cipher_type, } } -void CipherBase::Init(const char* cipher_type, +void CipherBase::Init(std::string_view cipher_type, const ArrayBufferOrViewContents& key_buf, unsigned int auth_tag_len) { HandleScope scope(env()->isolate()); MarkPopErrorOnReturn mark_pop_error_on_return; - auto cipher = Cipher::FromName(cipher_type); + const auto cipher = Cipher::FromName(cipher_type); if (!cipher) { return THROW_ERR_CRYPTO_UNKNOWN_CIPHER(env()); } - unsigned char key[EVP_MAX_KEY_LENGTH]; - unsigned char iv[EVP_MAX_IV_LENGTH]; - - int key_len = EVP_BytesToKey(cipher, - EVP_md5(), - nullptr, - key_buf.data(), - key_buf.size(), - 1, - key, - iv); + unsigned char key[Cipher::MAX_KEY_LENGTH]; + unsigned char iv[Cipher::MAX_IV_LENGTH]; + + ncrypto::Buffer keyBuf{ + .data = key_buf.data(), + .len = key_buf.size(), + }; + int key_len = cipher.bytesToKey(Digest::MD5, keyBuf, key, iv); CHECK_NE(key_len, 0); - if (kind_ == kCipher && (cipher.isCtrMode() || - cipher.isGcmMode() || - cipher.isCcmMode())) { + if (kind_ == kCipher && + (cipher.isCtrMode() || cipher.isGcmMode() || cipher.isCcmMode())) { // Ignore the return value (i.e. possible exception) because we are // not calling back into JS anyway. ProcessEmitWarning(env(), @@ -410,10 +407,10 @@ void CipherBase::Init(const FunctionCallbackInfo& args) { auth_tag_len = kNoAuthTagLength; } - cipher->Init(*cipher_type, key_buf, auth_tag_len); + cipher->Init(cipher_type.ToStringView(), key_buf, auth_tag_len); } -void CipherBase::InitIv(const char* cipher_type, +void CipherBase::InitIv(std::string_view cipher_type, const ByteSource& key_buf, const ArrayBufferOrViewContents& iv_buf, unsigned int auth_tag_len) { @@ -439,7 +436,7 @@ void CipherBase::InitIv(const char* cipher_type, return THROW_ERR_CRYPTO_INVALID_IV(env()); } - if (cipher.getNid() == NID_chacha20_poly1305) { + if (cipher.isChaCha20Poly1305()) { CHECK(has_iv); // Check for invalid IV lengths, since OpenSSL does not under some // conditions: @@ -493,13 +490,12 @@ void CipherBase::InitIv(const FunctionCallbackInfo& args) { auth_tag_len = kNoAuthTagLength; } - cipher->InitIv(*cipher_type, key_buf, iv_buf, auth_tag_len); + cipher->InitIv(cipher_type.ToStringView(), key_buf, iv_buf, auth_tag_len); } -bool CipherBase::InitAuthenticated( - const char* cipher_type, - int iv_len, - unsigned int auth_tag_len) { +bool CipherBase::InitAuthenticated(std::string_view cipher_type, + int iv_len, + unsigned int auth_tag_len) { CHECK(IsAuthenticatedMode()); MarkPopErrorOnReturn mark_pop_error_on_return; @@ -508,8 +504,7 @@ bool CipherBase::InitAuthenticated( return false; } - const int mode = ctx_.getMode(); - if (mode == EVP_CIPH_GCM_MODE) { + if (ctx_.isGcmMode()) { if (auth_tag_len != kNoAuthTagLength) { if (!Cipher::IsValidGCMTagLength(auth_tag_len)) { THROW_ERR_CRYPTO_INVALID_AUTH_TAG( @@ -528,7 +523,7 @@ bool CipherBase::InitAuthenticated( // length defaults to 16 bytes when encrypting. Unlike GCM, the // authentication tag length also defaults to 16 bytes when decrypting, // whereas GCM would accept any valid authentication tag length. - if (ctx_.getNid() == NID_chacha20_poly1305) { + if (ctx_.isChaCha20Poly1305()) { auth_tag_len = 16; } else { THROW_ERR_CRYPTO_INVALID_AUTH_TAG( @@ -539,12 +534,7 @@ bool CipherBase::InitAuthenticated( // TODO(tniessen) Support CCM decryption in FIPS mode -#if OPENSSL_VERSION_MAJOR >= 3 - if (mode == EVP_CIPH_CCM_MODE && kind_ == kDecipher && - EVP_default_properties_is_fips_enabled(nullptr)) { -#else - if (mode == EVP_CIPH_CCM_MODE && kind_ == kDecipher && FIPS_mode()) { -#endif + if (ctx_.isCcmMode() && kind_ == kDecipher && ncrypto::isFipsEnabled()) { THROW_ERR_CRYPTO_UNSUPPORTED_OPERATION(env(), "CCM encryption not supported in FIPS mode"); return false; @@ -560,7 +550,7 @@ bool CipherBase::InitAuthenticated( // Remember the given authentication tag length for later. auth_tag_len_ = auth_tag_len; - if (mode == EVP_CIPH_CCM_MODE) { + if (ctx_.isCcmMode()) { // Restrict the message length to min(INT_MAX, 2^(8*(15-iv_len))-1) bytes. CHECK(iv_len >= 7 && iv_len <= 13); max_message_size_ = INT_MAX; @@ -574,7 +564,7 @@ bool CipherBase::InitAuthenticated( bool CipherBase::CheckCCMMessageLength(int message_len) { CHECK(ctx_); - CHECK(ctx_.getMode() == EVP_CIPH_CCM_MODE); + CHECK(ctx_.isCcmMode()); if (message_len > max_message_size_) { THROW_ERR_CRYPTO_INVALID_MESSAGELEN(env()); @@ -627,9 +617,8 @@ void CipherBase::SetAuthTag(const FunctionCallbackInfo& args) { } unsigned int tag_len = auth_tag.size(); - const int mode = cipher->ctx_.getMode(); bool is_valid; - if (mode == EVP_CIPH_GCM_MODE) { + if (cipher->ctx_.isGcmMode()) { // Restrict GCM tag lengths according to NIST 800-38d, page 9. is_valid = (cipher->auth_tag_len_ == kNoAuthTagLength || cipher->auth_tag_len_ == tag_len) && @@ -647,7 +636,7 @@ void CipherBase::SetAuthTag(const FunctionCallbackInfo& args) { env, "Invalid authentication tag length: %u", tag_len); } - if (mode == EVP_CIPH_GCM_MODE && cipher->auth_tag_len_ == kNoAuthTagLength && + if (cipher->ctx_.isGcmMode() && cipher->auth_tag_len_ == kNoAuthTagLength && tag_len != 16 && env->EmitProcessEnvWarning()) { if (ProcessEmitDeprecationWarning( env, @@ -691,11 +680,10 @@ bool CipherBase::SetAAD( MarkPopErrorOnReturn mark_pop_error_on_return; int outlen; - const int mode = ctx_.getMode(); // When in CCM mode, we need to set the authentication tag and the plaintext // length in advance. - if (mode == EVP_CIPH_CCM_MODE) { + if (ctx_.isCcmMode()) { if (plaintext_len < 0) { THROW_ERR_MISSING_ARGS(env(), "options.plaintextLength required for CCM mode with AAD"); @@ -750,9 +738,7 @@ CipherBase::UpdateResult CipherBase::Update( if (!ctx_ || len > INT_MAX) return kErrorState; MarkPopErrorOnReturn mark_pop_error_on_return; - const int mode = ctx_.getMode(); - - if (mode == EVP_CIPH_CCM_MODE && !CheckCCMMessageLength(len)) { + if (ctx_.isCcmMode() && !CheckCCMMessageLength(len)) { return kErrorMessageSize; } @@ -771,7 +757,7 @@ CipherBase::UpdateResult CipherBase::Update( .data = reinterpret_cast(data), .len = len, }; - if (kind_ == kCipher && mode == EVP_CIPH_WRAP_MODE && + if (kind_ == kCipher && ctx_.isWrapMode() && !ctx_.update(buffer, nullptr, &buf_len)) { return kErrorState; } @@ -802,7 +788,7 @@ CipherBase::UpdateResult CipherBase::Update( // When in CCM mode, EVP_CipherUpdate will fail if the authentication tag is // invalid. In that case, remember the error and throw in final(). - if (!r && kind_ == kDecipher && mode == EVP_CIPH_CCM_MODE) { + if (!r && kind_ == kDecipher && ctx_.isCcmMode()) { pending_auth_failed_ = true; return kSuccess; } @@ -857,8 +843,6 @@ void CipherBase::SetAutoPadding(const FunctionCallbackInfo& args) { bool CipherBase::Final(std::unique_ptr* out) { if (!ctx_) return false; - const int mode = ctx_.getMode(); - *out = ArrayBuffer::NewBackingStore( env()->isolate(), static_cast(ctx_.getBlockSize()), @@ -869,18 +853,19 @@ bool CipherBase::Final(std::unique_ptr* out) { MaybePassAuthTagToOpenSSL(); } +#if (OPENSSL_VERSION_NUMBER < 0x30000000L) // OpenSSL v1.x doesn't verify the presence of the auth tag so do // it ourselves, see https://github.com/nodejs/node/issues/45874. - if (OPENSSL_VERSION_NUMBER < 0x30000000L && kind_ == kDecipher && - NID_chacha20_poly1305 == ctx_.getNid() && + if (kind_ == kDecipher && ctx_.isChaCha20Poly1305() && auth_tag_state_ != kAuthTagPassedToOpenSSL) { return false; } +#endif // In CCM mode, final() only checks whether authentication failed in update(). // EVP_CipherFinal_ex must not be called and will fail. bool ok; - if (kind_ == kDecipher && mode == EVP_CIPH_CCM_MODE) { + if (kind_ == kDecipher && ctx_.isCcmMode()) { ok = !pending_auth_failed_; *out = ArrayBuffer::NewBackingStore(env()->isolate(), 0); } else { @@ -904,7 +889,7 @@ bool CipherBase::Final(std::unique_ptr* out) { // but defaults to 16 bytes when encrypting. In CCM and OCB mode, it must // always be given by the user. if (auth_tag_len_ == kNoAuthTagLength) { - CHECK(mode == EVP_CIPH_GCM_MODE); + CHECK(ctx_.isGcmMode()); auth_tag_len_ = sizeof(auth_tag_); } ok = ctx_.getAeadTag(auth_tag_len_, @@ -951,7 +936,7 @@ bool PublicKeyCipher::Cipher( Environment* env, const EVPKeyPointer& pkey, int padding, - const EVP_MD* digest, + const Digest& digest, const ArrayBufferOrViewContents& oaep_label, const ArrayBufferOrViewContents& data, std::unique_ptr* out) { @@ -965,6 +950,7 @@ bool PublicKeyCipher::Cipher( }; auto buf = cipher(pkey, params, in); + if (!buf) return false; if (buf.size() == 0) { @@ -1007,23 +993,19 @@ void PublicKeyCipher::Cipher(const FunctionCallbackInfo& args) { return ThrowCryptoError(env, ERR_get_error()); } -#ifndef OPENSSL_IS_BORINGSSL // RSA implicit rejection here is not supported by BoringSSL. - // Skip this check when boring is used. - if (!ctx.setRsaImplicitRejection()) { + if (!ctx.setRsaImplicitRejection()) [[unlikely]] { return THROW_ERR_INVALID_ARG_VALUE( env, "RSA_PKCS1_PADDING is no longer supported for private decryption"); } -#endif } - const EVP_MD* digest = nullptr; + Digest digest; if (args[offset + 2]->IsString()) { - const Utf8Value oaep_str(env->isolate(), args[offset + 2]); - digest = ncrypto::getDigestByName(oaep_str.ToStringView()); - if (digest == nullptr) - return THROW_ERR_OSSL_EVP_INVALID_DIGEST(env); + Utf8Value oaep_str(env->isolate(), args[offset + 2]); + digest = Digest::FromName(oaep_str.ToStringView()); + if (!digest) return THROW_ERR_OSSL_EVP_INVALID_DIGEST(env); } ArrayBufferOrViewContents oaep_label( diff --git a/src/crypto/crypto_cipher.h b/src/crypto/crypto_cipher.h index 950acfa2521ede4..fa26f5aa864760b 100644 --- a/src/crypto/crypto_cipher.h +++ b/src/crypto/crypto_cipher.h @@ -43,21 +43,22 @@ class CipherBase : public BaseObject { }; static const unsigned kNoAuthTagLength = static_cast(-1); - void CommonInit(const char* cipher_type, + void CommonInit(std::string_view cipher_type, const ncrypto::Cipher& cipher, const unsigned char* key, int key_len, const unsigned char* iv, int iv_len, unsigned int auth_tag_len); - void Init(const char* cipher_type, + void Init(std::string_view cipher_type, const ArrayBufferOrViewContents& key_buf, unsigned int auth_tag_len); - void InitIv(const char* cipher_type, + void InitIv(std::string_view cipher_type, const ByteSource& key_buf, const ArrayBufferOrViewContents& iv_buf, unsigned int auth_tag_len); - bool InitAuthenticated(const char* cipher_type, int iv_len, + bool InitAuthenticated(std::string_view cipher_type, + int iv_len, unsigned int auth_tag_len); bool CheckCCMMessageLength(int message_len); UpdateResult Update(const char* data, size_t len, @@ -110,7 +111,7 @@ class PublicKeyCipher { static bool Cipher(Environment* env, const ncrypto::EVPKeyPointer& pkey, int padding, - const EVP_MD* digest, + const ncrypto::Digest& digest, const ArrayBufferOrViewContents& oaep_label, const ArrayBufferOrViewContents& data, std::unique_ptr* out); @@ -148,10 +149,8 @@ class CipherJob final : public CryptoJob { CryptoJobMode mode = GetCryptoJobMode(args[0]); CHECK(args[1]->IsUint32()); // Cipher Mode - - uint32_t cmode = args[1].As()->Value(); - CHECK_LE(cmode, WebCryptoCipherMode::kWebCryptoCipherDecrypt); - WebCryptoCipherMode cipher_mode = static_cast(cmode); + auto cipher_mode = + static_cast(args[1].As()->Value()); CHECK(args[2]->IsObject()); // KeyObject KeyObjectHandle* key; diff --git a/src/crypto/crypto_hkdf.cc b/src/crypto/crypto_hkdf.cc index 10bb8e4258bf630..418aa0bb23aa425 100644 --- a/src/crypto/crypto_hkdf.cc +++ b/src/crypto/crypto_hkdf.cc @@ -9,6 +9,7 @@ namespace node { +using ncrypto::Digest; using v8::FunctionCallbackInfo; using v8::JustVoid; using v8::Maybe; @@ -54,8 +55,8 @@ Maybe HKDFTraits::AdditionalConfig( CHECK(args[offset + 4]->IsUint32()); // Length Utf8Value hash(env->isolate(), args[offset]); - params->digest = ncrypto::getDigestByName(hash.ToStringView()); - if (params->digest == nullptr) [[unlikely]] { + params->digest = Digest::FromName(hash.ToStringView()); + if (!params->digest) [[unlikely]] { THROW_ERR_CRYPTO_INVALID_DIGEST(env, "Invalid digest: %s", *hash); return Nothing(); } diff --git a/src/crypto/crypto_hkdf.h b/src/crypto/crypto_hkdf.h index be6e823269d8ab0..67484e4711a96ec 100644 --- a/src/crypto/crypto_hkdf.h +++ b/src/crypto/crypto_hkdf.h @@ -14,7 +14,7 @@ namespace crypto { struct HKDFConfig final : public MemoryRetainer { CryptoJobMode mode; size_t length; - const EVP_MD* digest; + ncrypto::Digest digest; KeyObjectData key; ByteSource salt; ByteSource info;