Skip to content

Commit d464647

Browse files
committed
EVP_PKEY_CTX_ctrl_str w/ HKDF
1 parent b298c65 commit d464647

File tree

2 files changed

+190
-1
lines changed

2 files changed

+190
-1
lines changed

crypto/fipsmodule/evp/evp_ctx_test.cc

Lines changed: 110 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
#include <openssl/ec_key.h>
88
#include <openssl/err.h>
99
#include <openssl/evp.h>
10+
#include <openssl/kdf.h>
1011
#include <openssl/rsa.h>
1112

1213
#include "../../internal.h"
@@ -236,3 +237,112 @@ TEST_F(EvpPkeyCtxCtrlStrTest, DhPad) {
236237

237238
// There is no function to retrieve the DH pad value.
238239
}
240+
241+
static const char *hkdf_hexsalt = "000102030405060708090a0b0c";
242+
static const char *hkdf_hexinfo = "f0f1f2f3f4f5f6f7f8f9";
243+
static const char *hkdf_hexkey = "0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b";
244+
static const char *hkdf_hex_expected_okm =
245+
"3cb25f25faacd57a90434f64d0362f2a2d2d0a90cf1a5a4c5db02d56ecc4c5bf34007208d5"
246+
"b887185865";
247+
static const char *hkdf_hex_expected_prk =
248+
"077709362c2e32df0ddc3f0dc47bba6390b6c73bb50f9c3122ec844ad7c2b3e5";
249+
250+
TEST_F(EvpPkeyCtxCtrlStrTest, HkdfHex) {
251+
// Test Cases from RFC 5869.
252+
253+
bssl::UniquePtr<EVP_PKEY_CTX> ctx(
254+
EVP_PKEY_CTX_new_id(EVP_PKEY_HKDF, nullptr));
255+
ASSERT_TRUE(ctx);
256+
ASSERT_TRUE(EVP_PKEY_derive_init(ctx.get()));
257+
ASSERT_EQ(EVP_PKEY_CTX_ctrl_str(ctx.get(), "mode", "EXTRACT_AND_EXPAND"), 1);
258+
ASSERT_EQ(EVP_PKEY_CTX_ctrl_str(ctx.get(), "md", "SHA256"), 1);
259+
ASSERT_EQ(EVP_PKEY_CTX_ctrl_str(ctx.get(), "hexsalt", hkdf_hexsalt), 1);
260+
ASSERT_EQ(EVP_PKEY_CTX_ctrl_str(ctx.get(), "hexinfo", hkdf_hexinfo), 1);
261+
ASSERT_EQ(EVP_PKEY_CTX_ctrl_str(ctx.get(), "hexkey", hkdf_hexkey), 1);
262+
263+
size_t okm_len;
264+
bssl::UniquePtr<uint8_t> expected_okm(
265+
OPENSSL_hexstr2buf(hkdf_hex_expected_okm, &okm_len));
266+
ASSERT_TRUE(expected_okm);
267+
268+
bssl::UniquePtr<uint8_t> actual_okm(
269+
static_cast<uint8_t *>(OPENSSL_zalloc(okm_len)));
270+
ASSERT_TRUE(actual_okm);
271+
272+
ASSERT_TRUE(EVP_PKEY_derive(ctx.get(), actual_okm.get(), &okm_len));
273+
274+
ASSERT_EQ(OPENSSL_memcmp(actual_okm.get(), expected_okm.get(), okm_len), 0);
275+
}
276+
277+
TEST_F(EvpPkeyCtxCtrlStrTest, HkdfRaw) {
278+
// Test Cases from RFC 5869.
279+
280+
bssl::UniquePtr<EVP_PKEY_CTX> ctx(
281+
EVP_PKEY_CTX_new_id(EVP_PKEY_HKDF, nullptr));
282+
ASSERT_TRUE(ctx);
283+
ASSERT_TRUE(EVP_PKEY_derive_init(ctx.get()));
284+
ASSERT_EQ(EVP_PKEY_CTX_ctrl_str(ctx.get(), "mode", "EXTRACT_AND_EXPAND"), 1);
285+
ASSERT_EQ(EVP_PKEY_CTX_ctrl_str(ctx.get(), "md", "SHA256"), 1);
286+
287+
// The salt in the KAT contains a 0-byte so "salt" cannot be used.
288+
ASSERT_EQ(
289+
EVP_PKEY_CTX_ctrl_str(ctx.get(), "hexsalt", "000102030405060708090a0b0c"),
290+
1);
291+
292+
293+
size_t len;
294+
bssl::UniquePtr<uint8_t> info_parsed(OPENSSL_hexstr2buf(hkdf_hexinfo, &len));
295+
bssl::UniquePtr<uint8_t> info((uint8_t*)OPENSSL_zalloc(len+1));
296+
OPENSSL_memcpy(info.get(), info_parsed.get(), len);
297+
298+
ASSERT_EQ(EVP_PKEY_CTX_ctrl_str(ctx.get(), "info",
299+
reinterpret_cast<const char *>(info.get())),
300+
1);
301+
bssl::UniquePtr<uint8_t> key_parsed(OPENSSL_hexstr2buf(hkdf_hexkey, &len));
302+
bssl::UniquePtr<uint8_t> key((uint8_t*)OPENSSL_zalloc(len+1));
303+
OPENSSL_memcpy(key.get(), key_parsed.get(), len);
304+
305+
ASSERT_EQ(EVP_PKEY_CTX_ctrl_str(ctx.get(), "key",
306+
reinterpret_cast<const char *>(key.get())),
307+
1);
308+
309+
size_t okm_len;
310+
bssl::UniquePtr<uint8_t> expected_okm(
311+
OPENSSL_hexstr2buf(hkdf_hex_expected_okm, &okm_len));
312+
ASSERT_TRUE(expected_okm);
313+
314+
bssl::UniquePtr<uint8_t> actual_okm(
315+
static_cast<uint8_t *>(OPENSSL_zalloc(okm_len)));
316+
ASSERT_TRUE(actual_okm);
317+
318+
ASSERT_TRUE(EVP_PKEY_derive(ctx.get(), actual_okm.get(), &okm_len));
319+
320+
ASSERT_EQ(OPENSSL_memcmp(actual_okm.get(), expected_okm.get(), okm_len), 0);
321+
}
322+
323+
TEST_F(EvpPkeyCtxCtrlStrTest, HkdfExtract) {
324+
// Test Cases from RFC 5869.
325+
326+
bssl::UniquePtr<EVP_PKEY_CTX> ctx(
327+
EVP_PKEY_CTX_new_id(EVP_PKEY_HKDF, nullptr));
328+
ASSERT_TRUE(ctx);
329+
ASSERT_TRUE(EVP_PKEY_derive_init(ctx.get()));
330+
ASSERT_EQ(EVP_PKEY_CTX_ctrl_str(ctx.get(), "mode", "EXTRACT_ONLY"), 1);
331+
ASSERT_EQ(EVP_PKEY_CTX_ctrl_str(ctx.get(), "md", "SHA256"), 1);
332+
ASSERT_EQ(EVP_PKEY_CTX_ctrl_str(ctx.get(), "hexsalt", hkdf_hexsalt), 1);
333+
ASSERT_EQ(EVP_PKEY_CTX_ctrl_str(ctx.get(), "hexinfo", hkdf_hexinfo), 1);
334+
ASSERT_EQ(EVP_PKEY_CTX_ctrl_str(ctx.get(), "hexkey", hkdf_hexkey), 1);
335+
336+
size_t prk_len;
337+
bssl::UniquePtr<uint8_t> expected_prk(
338+
OPENSSL_hexstr2buf(hkdf_hex_expected_prk, &prk_len));
339+
ASSERT_TRUE(expected_prk);
340+
341+
bssl::UniquePtr<uint8_t> actual_prk(
342+
static_cast<uint8_t *>(OPENSSL_zalloc(prk_len)));
343+
ASSERT_TRUE(actual_prk);
344+
345+
ASSERT_TRUE(EVP_PKEY_derive(ctx.get(), actual_prk.get(), &prk_len));
346+
347+
ASSERT_EQ(OPENSSL_memcmp(actual_prk.get(), expected_prk.get(), prk_len), 0);
348+
}

crypto/fipsmodule/evp/p_hkdf.c

Lines changed: 80 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -179,6 +179,85 @@ static int pkey_hkdf_ctrl(EVP_PKEY_CTX *ctx, int type, int p1, void *p2) {
179179
}
180180
}
181181

182+
static int pkey_hkdf_ctrl_str(EVP_PKEY_CTX *ctx, const char *type,
183+
const char *value) {
184+
if (strcmp(type, "mode") == 0) {
185+
int mode;
186+
187+
if (strcmp(value, "EXTRACT_AND_EXPAND") == 0) {
188+
mode = EVP_PKEY_HKDEF_MODE_EXTRACT_AND_EXPAND;
189+
} else if (strcmp(value, "EXTRACT_ONLY") == 0) {
190+
mode = EVP_PKEY_HKDEF_MODE_EXTRACT_ONLY;
191+
} else if (strcmp(value, "EXPAND_ONLY") == 0) {
192+
mode = EVP_PKEY_HKDEF_MODE_EXPAND_ONLY;
193+
} else {
194+
return 0;
195+
}
196+
197+
return EVP_PKEY_CTX_hkdf_mode(ctx, mode);
198+
}
199+
200+
if (strcmp(type, "md") == 0) {
201+
OPENSSL_BEGIN_ALLOW_DEPRECATED
202+
return EVP_PKEY_CTX_md(ctx, EVP_PKEY_OP_DERIVE, EVP_PKEY_CTRL_HKDF_MD,
203+
value);
204+
OPENSSL_END_ALLOW_DEPRECATED
205+
}
206+
207+
if (strcmp(type, "salt") == 0) {
208+
// What if the salt contains a 0-byte?
209+
const size_t saltlen = OPENSSL_strnlen(value, INT16_MAX);
210+
return EVP_PKEY_CTX_set1_hkdf_salt(ctx, (const uint8_t *)value, saltlen);
211+
}
212+
213+
if (strcmp(type, "hexsalt") == 0) {
214+
size_t hex_saltlen = 0;
215+
uint8_t *salt = OPENSSL_hexstr2buf(value, &hex_saltlen);
216+
if (salt == NULL) {
217+
return -2;
218+
}
219+
int result = EVP_PKEY_CTX_set1_hkdf_salt(ctx, salt, hex_saltlen);
220+
OPENSSL_free(salt);
221+
return result;
222+
}
223+
224+
if (strcmp(type, "key") == 0) {
225+
// What if the key contains a 0-byte?
226+
const size_t keylen = OPENSSL_strnlen(value, INT16_MAX);
227+
return EVP_PKEY_CTX_set1_hkdf_key(ctx, (const uint8_t *)value, keylen);
228+
}
229+
230+
if (strcmp(type, "hexkey") == 0) {
231+
size_t hex_keylen = 0;
232+
uint8_t *key = OPENSSL_hexstr2buf(value, &hex_keylen);
233+
if (key == NULL) {
234+
return -2;
235+
}
236+
int result = EVP_PKEY_CTX_set1_hkdf_key(ctx, key, hex_keylen);
237+
OPENSSL_free(key);
238+
return result;
239+
}
240+
241+
if (strcmp(type, "info") == 0) {
242+
// What if info contains a 0-byte?
243+
const size_t infolen = OPENSSL_strnlen(value, INT16_MAX);
244+
return EVP_PKEY_CTX_add1_hkdf_info(ctx, (const uint8_t *)value, infolen);
245+
}
246+
247+
if (strcmp(type, "hexinfo") == 0) {
248+
size_t hex_infolen = 0;
249+
uint8_t *info = OPENSSL_hexstr2buf(value, &hex_infolen);
250+
if (info == NULL) {
251+
return -2;
252+
}
253+
int result = EVP_PKEY_CTX_add1_hkdf_info(ctx, info, hex_infolen);
254+
OPENSSL_free(info);
255+
return result;
256+
}
257+
258+
return -2;
259+
}
260+
182261
DEFINE_METHOD_FUNCTION(EVP_PKEY_METHOD, EVP_PKEY_hkdf_pkey_meth) {
183262
out->pkey_id = EVP_PKEY_HKDF;
184263
out->init = pkey_hkdf_init;
@@ -197,7 +276,7 @@ DEFINE_METHOD_FUNCTION(EVP_PKEY_METHOD, EVP_PKEY_hkdf_pkey_meth) {
197276
out->derive = pkey_hkdf_derive;
198277
out->paramgen = NULL; /* paramgen */
199278
out->ctrl = pkey_hkdf_ctrl;
200-
out->ctrl_str = NULL;
279+
out->ctrl_str = pkey_hkdf_ctrl_str;
201280
}
202281

203282
int EVP_PKEY_CTX_hkdf_mode(EVP_PKEY_CTX *ctx, int mode) {

0 commit comments

Comments
 (0)