@@ -112,47 +112,33 @@ bool HKDFTraits::DeriveBits(
112
112
// TODO(panva): Once support for OpenSSL 1.1.1 is dropped the whole
113
113
// of HKDFTraits::DeriveBits can be refactored to use
114
114
// EVP_KDF which does handle zero length key.
115
- if (params.key ->GetSymmetricKeySize () != 0 ) {
116
- if (!EVP_PKEY_CTX_hkdf_mode (ctx.get (),
117
- EVP_PKEY_HKDEF_MODE_EXTRACT_AND_EXPAND) ||
118
- !EVP_PKEY_CTX_set1_hkdf_salt (
119
- ctx.get (), params.salt .data <unsigned char >(), params.salt .size ()) ||
120
- !EVP_PKEY_CTX_set1_hkdf_key (ctx.get (),
121
- reinterpret_cast <const unsigned char *>(
122
- params.key ->GetSymmetricKey ()),
123
- params.key ->GetSymmetricKeySize ())) {
124
- return false ;
125
- }
115
+
116
+ std::string_view salt;
117
+ if (params.salt .size () != 0 ) {
118
+ salt = {params.salt .data <char >(), params.salt .size ()};
126
119
} else {
127
- // Workaround for EVP_PKEY_derive HKDF not handling zero length keys.
128
- unsigned char temp_key[EVP_MAX_MD_SIZE];
129
- unsigned int len = sizeof (temp_key);
130
- if (params.salt .size () != 0 ) {
131
- if (HMAC (params.digest ,
132
- params.salt .data (),
133
- params.salt .size (),
134
- nullptr ,
135
- 0 ,
136
- temp_key,
137
- &len) == nullptr ) {
138
- return false ;
139
- }
140
- } else {
141
- char salt[EVP_MAX_MD_SIZE] = {0 };
142
- if (HMAC (params.digest ,
143
- salt,
144
- EVP_MD_size (params.digest ),
145
- nullptr ,
146
- 0 ,
147
- temp_key,
148
- &len) == nullptr ) {
149
- return false ;
150
- }
151
- }
152
- if (!EVP_PKEY_CTX_hkdf_mode (ctx.get (), EVP_PKEY_HKDEF_MODE_EXPAND_ONLY) ||
153
- !EVP_PKEY_CTX_set1_hkdf_key (ctx.get (), temp_key, len)) {
154
- return false ;
155
- }
120
+ static const char default_salt[EVP_MAX_MD_SIZE] = {0 };
121
+ salt = {default_salt, static_cast <unsigned >(EVP_MD_size (params.digest ))};
122
+ }
123
+
124
+ // We do not use EVP_PKEY_HKDEF_MODE_EXTRACT_AND_EXPAND and instead implement
125
+ // the extraction step ourselves because EVP_PKEY_derive does not handle
126
+ // zero-length keys, which are required for Web Crypto.
127
+ unsigned char pseudorandom_key[EVP_MAX_MD_SIZE];
128
+ unsigned int prk_len = sizeof (pseudorandom_key);
129
+ if (HMAC (
130
+ params.digest ,
131
+ salt.data (),
132
+ salt.size (),
133
+ reinterpret_cast <const unsigned char *>(params.key ->GetSymmetricKey ()),
134
+ params.key ->GetSymmetricKeySize (),
135
+ pseudorandom_key,
136
+ &prk_len) == nullptr ) {
137
+ return false ;
138
+ }
139
+ if (!EVP_PKEY_CTX_hkdf_mode (ctx.get (), EVP_PKEY_HKDEF_MODE_EXPAND_ONLY) ||
140
+ !EVP_PKEY_CTX_set1_hkdf_key (ctx.get (), pseudorandom_key, prk_len)) {
141
+ return false ;
156
142
}
157
143
158
144
size_t length = params.length ;
0 commit comments