Skip to content

Commit c3dbe18

Browse files
tniessenRafaelGSS
authored andcommitted
crypto: simplify control flow in HKDF
Unify the implementation and perform the same OpenSSL calls regardless of whether the key and/or salt are empty. This simplifies the code and improves coverage. Refs: #44201 PR-URL: #44272 Reviewed-By: Filip Skokan <panva.ip@gmail.com>
1 parent e001aaf commit c3dbe18

File tree

1 file changed

+26
-40
lines changed

1 file changed

+26
-40
lines changed

src/crypto/crypto_hkdf.cc

Lines changed: 26 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -112,47 +112,33 @@ bool HKDFTraits::DeriveBits(
112112
// TODO(panva): Once support for OpenSSL 1.1.1 is dropped the whole
113113
// of HKDFTraits::DeriveBits can be refactored to use
114114
// 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()};
126119
} 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;
156142
}
157143

158144
size_t length = params.length;

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy