@@ -56,7 +56,7 @@ Maybe<bool> HKDFTraits::AdditionalConfig(
56
56
CHECK (args[offset + 4 ]->IsUint32 ()); // Length
57
57
58
58
Utf8Value hash (env->isolate (), args[offset]);
59
- params->digest = EVP_get_digestbyname (* hash);
59
+ params->digest = ncrypto::getDigestByName ( hash. ToStringView () );
60
60
if (params->digest == nullptr ) {
61
61
THROW_ERR_CRYPTO_INVALID_DIGEST (env, " Invalid digest: %s" , *hash);
62
62
return Nothing<bool >();
@@ -90,9 +90,7 @@ Maybe<bool> HKDFTraits::AdditionalConfig(
90
90
// HKDF-Expand computes up to 255 HMAC blocks, each having as many bits as the
91
91
// output of the hash function. 255 is a hard limit because HKDF appends an
92
92
// 8-bit counter to each HMAC'd message, starting at 1.
93
- constexpr size_t kMaxDigestMultiplier = 255 ;
94
- size_t max_length = EVP_MD_size (params->digest ) * kMaxDigestMultiplier ;
95
- if (params->length > max_length) {
93
+ if (!ncrypto::checkHkdfLength (params->digest , params->length )) {
96
94
THROW_ERR_CRYPTO_INVALID_KEYLEN (env);
97
95
return Nothing<bool >();
98
96
}
@@ -104,53 +102,24 @@ bool HKDFTraits::DeriveBits(
104
102
Environment* env,
105
103
const HKDFConfig& params,
106
104
ByteSource* out) {
107
- EVPKeyCtxPointer ctx =
108
- EVPKeyCtxPointer (EVP_PKEY_CTX_new_id (EVP_PKEY_HKDF, nullptr ));
109
- if (!ctx || !EVP_PKEY_derive_init (ctx.get ()) ||
110
- !EVP_PKEY_CTX_set_hkdf_md (ctx.get (), params.digest ) ||
111
- !EVP_PKEY_CTX_add1_hkdf_info (
112
- ctx.get (), params.info .data <unsigned char >(), params.info .size ())) {
113
- return false ;
114
- }
115
-
116
- // TODO(panva): Once support for OpenSSL 1.1.1 is dropped the whole
117
- // of HKDFTraits::DeriveBits can be refactored to use
118
- // EVP_KDF which does handle zero length key.
119
-
120
- std::string_view salt;
121
- if (params.salt .size () != 0 ) {
122
- salt = {params.salt .data <char >(), params.salt .size ()};
123
- } else {
124
- static const char default_salt[EVP_MAX_MD_SIZE] = {0 };
125
- salt = {default_salt, static_cast <unsigned >(EVP_MD_size (params.digest ))};
126
- }
127
-
128
- // We do not use EVP_PKEY_HKDEF_MODE_EXTRACT_AND_EXPAND and instead implement
129
- // the extraction step ourselves because EVP_PKEY_derive does not handle
130
- // zero-length keys, which are required for Web Crypto.
131
- unsigned char pseudorandom_key[EVP_MAX_MD_SIZE];
132
- unsigned int prk_len = sizeof (pseudorandom_key);
133
- if (HMAC (
134
- params.digest ,
135
- salt.data (),
136
- salt.size (),
137
- reinterpret_cast <const unsigned char *>(params.key ->GetSymmetricKey ()),
138
- params.key ->GetSymmetricKeySize (),
139
- pseudorandom_key,
140
- &prk_len) == nullptr ) {
141
- return false ;
142
- }
143
- if (!EVP_PKEY_CTX_hkdf_mode (ctx.get (), EVP_PKEY_HKDEF_MODE_EXPAND_ONLY) ||
144
- !EVP_PKEY_CTX_set1_hkdf_key (ctx.get (), pseudorandom_key, prk_len)) {
145
- return false ;
146
- }
147
-
148
- size_t length = params.length ;
149
- ByteSource::Builder buf (length);
150
- if (EVP_PKEY_derive (ctx.get (), buf.data <unsigned char >(), &length) <= 0 )
151
- return false ;
152
-
153
- *out = std::move (buf).release ();
105
+ auto dp = ncrypto::hkdf (
106
+ params.digest ,
107
+ ncrypto::Buffer<const unsigned char > {
108
+ .data = reinterpret_cast <const unsigned char *>(params.key ->GetSymmetricKey ()),
109
+ .len = params.key ->GetSymmetricKeySize (),
110
+ },
111
+ ncrypto::Buffer<const unsigned char > {
112
+ .data = params.info .data <const unsigned char >(),
113
+ .len = params.info .size (),
114
+ },
115
+ ncrypto::Buffer<const unsigned char > {
116
+ .data = params.salt .data <const unsigned char >(),
117
+ .len = params.salt .size (),
118
+ },
119
+ params.length );
120
+ if (!dp) return false ;
121
+
122
+ *out = ByteSource::Allocated (dp.release ());
154
123
return true ;
155
124
}
156
125
0 commit comments