提交 d2139cf8 编写于 作者: M Matt Caswell

Update HKDF to support separte Extract and Expand steps

At the moment you can only do an HKDF Extract and Expand in one go. For
TLS1.3 we need to be able to do an Extract first, and the subsequently do
a number of Expand steps on the same PRK.
Reviewed-by: NRich Salz <rsalz@openssl.org>
上级 234b8af4
......@@ -34,6 +34,7 @@ static unsigned char *HKDF_Expand(const EVP_MD *evp_md,
unsigned char *okm, size_t okm_len);
typedef struct {
int mode;
const EVP_MD *md;
unsigned char *salt;
size_t salt_len;
......@@ -77,6 +78,10 @@ static int pkey_hkdf_ctrl(EVP_PKEY_CTX *ctx, int type, int p1, void *p2)
kctx->md = p2;
return 1;
case EVP_PKEY_CTRL_HKDF_MODE:
kctx->mode = p1;
return 1;
case EVP_PKEY_CTRL_HKDF_SALT:
if (p1 == 0 || p2 == NULL)
return 1;
......@@ -160,13 +165,27 @@ static int pkey_hkdf_derive(EVP_PKEY_CTX *ctx, unsigned char *key,
if (kctx->md == NULL || kctx->key == NULL)
return 0;
if (HKDF(kctx->md, kctx->salt, kctx->salt_len, kctx->key, kctx->key_len,
kctx->info, kctx->info_len, key, *keylen) == NULL)
{
switch (kctx->mode) {
case EVP_PKEY_HKDEF_MODE_EXTRACT_AND_EXPAND:
return HKDF(kctx->md, kctx->salt, kctx->salt_len, kctx->key,
kctx->key_len, kctx->info, kctx->info_len, key,
*keylen) != NULL;
case EVP_PKEY_HKDEF_MODE_EXTRACT_ONLY:
if (key == NULL) {
*keylen = EVP_MD_size(kctx->md);
return 1;
}
return HKDF_Extract(kctx->md, kctx->salt, kctx->salt_len, kctx->key,
kctx->key_len, key, keylen) != NULL;
case EVP_PKEY_HKDEF_MODE_EXPAND_ONLY:
return HKDF_Expand(kctx->md, kctx->key, kctx->key_len, kctx->info,
kctx->info_len, key, *keylen) != NULL;
default:
return 0;
}
return 1;
}
const EVP_PKEY_METHOD hkdf_pkey_meth = {
......@@ -206,12 +225,16 @@ static unsigned char *HKDF(const EVP_MD *evp_md,
unsigned char *okm, size_t okm_len)
{
unsigned char prk[EVP_MAX_MD_SIZE];
unsigned char *ret;
size_t prk_len;
if (!HKDF_Extract(evp_md, salt, salt_len, key, key_len, prk, &prk_len))
return NULL;
return HKDF_Expand(evp_md, prk, prk_len, info, info_len, okm, okm_len);
ret = HKDF_Expand(evp_md, prk, prk_len, info, info_len, okm, okm_len);
OPENSSL_cleanse(prk, sizeof(prk));
return ret;
}
static unsigned char *HKDF_Extract(const EVP_MD *evp_md,
......@@ -245,7 +268,7 @@ static unsigned char *HKDF_Expand(const EVP_MD *evp_md,
if (okm_len % dig_len)
n++;
if (n > 255)
if (n > 255 || okm == NULL)
return NULL;
if ((hmac = HMAC_CTX_new()) == NULL)
......
......@@ -97,9 +97,9 @@ salt value "salt" and info value "label":
/* Error */
if (EVP_PKEY_CTX_set_hkdf_md(pctx, EVP_sha256()) <= 0)
/* Error */
if (EVP_PKEY_CTX_set1_salt(pctx, "salt", 4) <= 0)
if (EVP_PKEY_CTX_set1_hkdf_salt(pctx, "salt", 4) <= 0)
/* Error */
if (EVP_PKEY_CTX_set1_key(pctx, "secret", 6) <= 0)
if (EVP_PKEY_CTX_set1_hkdf_key(pctx, "secret", 6) <= 0)
/* Error */
if (EVP_PKEY_CTX_add1_hkdf_info(pctx, "label", 6) <= 0)
/* Error */
......
......@@ -14,13 +14,18 @@
extern "C" {
#endif
# define EVP_PKEY_CTRL_TLS_MD (EVP_PKEY_ALG_CTRL)
# define EVP_PKEY_CTRL_TLS_SECRET (EVP_PKEY_ALG_CTRL + 1)
# define EVP_PKEY_CTRL_TLS_SEED (EVP_PKEY_ALG_CTRL + 2)
# define EVP_PKEY_CTRL_HKDF_MD (EVP_PKEY_ALG_CTRL + 3)
# define EVP_PKEY_CTRL_HKDF_SALT (EVP_PKEY_ALG_CTRL + 4)
# define EVP_PKEY_CTRL_HKDF_KEY (EVP_PKEY_ALG_CTRL + 5)
# define EVP_PKEY_CTRL_HKDF_INFO (EVP_PKEY_ALG_CTRL + 6)
# define EVP_PKEY_CTRL_TLS_MD (EVP_PKEY_ALG_CTRL)
# define EVP_PKEY_CTRL_TLS_SECRET (EVP_PKEY_ALG_CTRL + 1)
# define EVP_PKEY_CTRL_TLS_SEED (EVP_PKEY_ALG_CTRL + 2)
# define EVP_PKEY_CTRL_HKDF_MD (EVP_PKEY_ALG_CTRL + 3)
# define EVP_PKEY_CTRL_HKDF_SALT (EVP_PKEY_ALG_CTRL + 4)
# define EVP_PKEY_CTRL_HKDF_KEY (EVP_PKEY_ALG_CTRL + 5)
# define EVP_PKEY_CTRL_HKDF_INFO (EVP_PKEY_ALG_CTRL + 6)
# define EVP_PKEY_CTRL_HKDF_MODE (EVP_PKEY_ALG_CTRL + 7)
# define EVP_PKEY_HKDEF_MODE_EXTRACT_AND_EXPAND 0
# define EVP_PKEY_HKDEF_MODE_EXTRACT_ONLY 1
# define EVP_PKEY_HKDEF_MODE_EXPAND_ONLY 2
# define EVP_PKEY_CTX_set_tls1_prf_md(pctx, md) \
EVP_PKEY_CTX_ctrl(pctx, -1, EVP_PKEY_OP_DERIVE, \
......@@ -50,6 +55,10 @@ extern "C" {
EVP_PKEY_CTX_ctrl(pctx, -1, EVP_PKEY_OP_DERIVE, \
EVP_PKEY_CTRL_HKDF_INFO, infolen, (void *)info)
# define EVP_PKEY_CTX_hkdf_mode(pctx, mode) \
EVP_PKEY_CTX_ctrl(pctx, -1, EVP_PKEY_OP_DERIVE, \
EVP_PKEY_CTRL_HKDF_MODE, mode, NULL)
/* BEGIN ERROR CODES */
/*
* The following lines are auto generated by the script mkerr.pl. Any changes
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册