From 05d2f72e79cdb1736681726dcd9a325491acf002 Mon Sep 17 00:00:00 2001 From: Matt Caswell Date: Mon, 20 Jul 2020 18:06:55 +0100 Subject: [PATCH] Extend the EVP_PKEY KDF to KDF provider bridge to also support HKDF Reviewed-by: Paul Dale (Merged from https://github.com/openssl/openssl/pull/12573) --- crypto/err/openssl.txt | 4 +- crypto/evp/evp_err.c | 2 + crypto/evp/pmeth_lib.c | 165 +++++++++++------- include/openssl/evperr.h | 4 +- include/openssl/kdf.h | 23 +-- providers/defltprov.c | 4 +- providers/implementations/exchange/kdf_exch.c | 125 +++++++------ .../include/prov/implementations.h | 3 +- test/pkey_meth_kdf_test.c | 9 +- util/libcrypto.num | 5 + 10 files changed, 206 insertions(+), 138 deletions(-) diff --git a/crypto/err/openssl.txt b/crypto/err/openssl.txt index d9512bc569..cca13cc78f 100644 --- a/crypto/err/openssl.txt +++ b/crypto/err/openssl.txt @@ -2554,12 +2554,14 @@ EVP_R_INVALID_FIPS_MODE:168:invalid fips mode EVP_R_INVALID_IV_LENGTH:194:invalid iv length EVP_R_INVALID_KEY:163:invalid key EVP_R_INVALID_KEY_LENGTH:130:invalid key length +EVP_R_INVALID_LENGTH:221:invalid length EVP_R_INVALID_NULL_ALGORITHM:218:invalid null algorithm EVP_R_INVALID_OPERATION:148:invalid operation EVP_R_INVALID_PROVIDER_FUNCTIONS:193:invalid provider functions EVP_R_INVALID_SALT_LENGTH:186:invalid salt length -EVP_R_INVALID_SECRET_LENGTH:221:invalid secret length +EVP_R_INVALID_SECRET_LENGTH:223:invalid secret length EVP_R_INVALID_SEED_LENGTH:220:invalid seed length +EVP_R_INVALID_VALUE:222:invalid value EVP_R_KEYGEN_FAILURE:120:keygen failure EVP_R_KEYMGMT_EXPORT_FAILURE:205:keymgmt export failure EVP_R_KEY_SETUP_FAILED:180:key setup failed diff --git a/crypto/evp/evp_err.c b/crypto/evp/evp_err.c index 4e9970d573..09351f2434 100644 --- a/crypto/evp/evp_err.c +++ b/crypto/evp/evp_err.c @@ -90,6 +90,7 @@ static const ERR_STRING_DATA EVP_str_reasons[] = { {ERR_PACK(ERR_LIB_EVP, 0, EVP_R_INVALID_IV_LENGTH), "invalid iv length"}, {ERR_PACK(ERR_LIB_EVP, 0, EVP_R_INVALID_KEY), "invalid key"}, {ERR_PACK(ERR_LIB_EVP, 0, EVP_R_INVALID_KEY_LENGTH), "invalid key length"}, + {ERR_PACK(ERR_LIB_EVP, 0, EVP_R_INVALID_LENGTH), "invalid length"}, {ERR_PACK(ERR_LIB_EVP, 0, EVP_R_INVALID_NULL_ALGORITHM), "invalid null algorithm"}, {ERR_PACK(ERR_LIB_EVP, 0, EVP_R_INVALID_OPERATION), "invalid operation"}, @@ -101,6 +102,7 @@ static const ERR_STRING_DATA EVP_str_reasons[] = { "invalid secret length"}, {ERR_PACK(ERR_LIB_EVP, 0, EVP_R_INVALID_SEED_LENGTH), "invalid seed length"}, + {ERR_PACK(ERR_LIB_EVP, 0, EVP_R_INVALID_VALUE), "invalid value"}, {ERR_PACK(ERR_LIB_EVP, 0, EVP_R_KEYGEN_FAILURE), "keygen failure"}, {ERR_PACK(ERR_LIB_EVP, 0, EVP_R_KEYMGMT_EXPORT_FAILURE), "keymgmt export failure"}, diff --git a/crypto/evp/pmeth_lib.c b/crypto/evp/pmeth_lib.c index 0fabaf4788..07a4658c21 100644 --- a/crypto/evp/pmeth_lib.c +++ b/crypto/evp/pmeth_lib.c @@ -157,7 +157,6 @@ static int is_legacy_alg(int id, const char *keytype) case EVP_PKEY_SM2: case EVP_PKEY_DHX: case EVP_PKEY_SCRYPT: - case EVP_PKEY_HKDF: case EVP_PKEY_CMAC: case EVP_PKEY_HMAC: case EVP_PKEY_SIPHASH: @@ -792,21 +791,22 @@ int EVP_PKEY_CTX_get_signature_md(EVP_PKEY_CTX *ctx, const EVP_MD **md) return 1; } -int EVP_PKEY_CTX_set_signature_md(EVP_PKEY_CTX *ctx, const EVP_MD *md) +static int evp_pkey_ctx_set_md(EVP_PKEY_CTX *ctx, const EVP_MD *md, + int fallback, const char *param, int op, + int ctrl) { - OSSL_PARAM sig_md_params[2], *p = sig_md_params; + OSSL_PARAM md_params[2], *p = md_params; const char *name; - if (ctx == NULL || !EVP_PKEY_CTX_IS_SIGNATURE_OP(ctx)) { + if (ctx == NULL || (ctx->operation & op) == 0) { ERR_raise(ERR_LIB_EVP, EVP_R_COMMAND_NOT_SUPPORTED); /* Uses the same return values as EVP_PKEY_CTX_ctrl */ return -2; } /* TODO(3.0): Remove this eventually when no more legacy */ - if (ctx->op.sig.sigprovctx == NULL) - return EVP_PKEY_CTX_ctrl(ctx, -1, EVP_PKEY_OP_TYPE_SIG, - EVP_PKEY_CTRL_MD, 0, (void *)(md)); + if (fallback) + return EVP_PKEY_CTX_ctrl(ctx, -1, op, ctrl, 0, (void *)(md)); if (md == NULL) { name = ""; @@ -814,7 +814,7 @@ int EVP_PKEY_CTX_set_signature_md(EVP_PKEY_CTX *ctx, const EVP_MD *md) name = EVP_MD_name(md); } - *p++ = OSSL_PARAM_construct_utf8_string(OSSL_SIGNATURE_PARAM_DIGEST, + *p++ = OSSL_PARAM_construct_utf8_string(param, /* * Cast away the const. This is read * only so should be safe @@ -822,13 +822,29 @@ int EVP_PKEY_CTX_set_signature_md(EVP_PKEY_CTX *ctx, const EVP_MD *md) (char *)name, 0); *p = OSSL_PARAM_construct_end(); - return EVP_PKEY_CTX_set_params(ctx, sig_md_params); + return EVP_PKEY_CTX_set_params(ctx, md_params); +} + +int EVP_PKEY_CTX_set_signature_md(EVP_PKEY_CTX *ctx, const EVP_MD *md) +{ + return evp_pkey_ctx_set_md(ctx, md, ctx->op.sig.sigprovctx == NULL, + OSSL_SIGNATURE_PARAM_DIGEST, + EVP_PKEY_OP_TYPE_SIG, EVP_PKEY_CTRL_MD); } int EVP_PKEY_CTX_set_tls1_prf_md(EVP_PKEY_CTX *ctx, const EVP_MD *md) { - OSSL_PARAM tls1_prf_md_params[2], *p = tls1_prf_md_params; - const char *name; + return evp_pkey_ctx_set_md(ctx, md, ctx->op.kex.exchprovctx == NULL, + OSSL_KDF_PARAM_DIGEST, + EVP_PKEY_OP_DERIVE, EVP_PKEY_CTRL_TLS_MD); +} + +static int evp_pkey_ctx_set1_octet_string(EVP_PKEY_CTX *ctx, int fallback, + const char *param, int op, int ctrl, + const unsigned char *data, + int datalen) +{ + OSSL_PARAM octet_string_params[2], *p = octet_string_params; if (ctx == NULL || !EVP_PKEY_CTX_IS_DERIVE_OP(ctx)) { ERR_raise(ERR_LIB_EVP, EVP_R_COMMAND_NOT_SUPPORTED); @@ -837,66 +853,86 @@ int EVP_PKEY_CTX_set_tls1_prf_md(EVP_PKEY_CTX *ctx, const EVP_MD *md) } /* TODO(3.0): Remove this eventually when no more legacy */ - if (ctx->op.kex.exchprovctx == NULL) - return EVP_PKEY_CTX_ctrl(ctx, -1, EVP_PKEY_OP_DERIVE, - EVP_PKEY_CTRL_TLS_MD, 0, (void *)(md)); + if (fallback) + return EVP_PKEY_CTX_ctrl(ctx, -1, op, ctrl, datalen, (void *)(data)); - if (md == NULL) { - name = ""; - } else { - name = EVP_MD_name(md); + if (datalen < 0) { + ERR_raise(ERR_LIB_EVP, EVP_R_INVALID_LENGTH); + return 0; } - *p++ = OSSL_PARAM_construct_utf8_string(OSSL_KDF_PARAM_DIGEST, + *p++ = OSSL_PARAM_construct_octet_string(param, /* * Cast away the const. This is read * only so should be safe */ - (char *)name, 0); + (unsigned char *)data, + (size_t)datalen); *p++ = OSSL_PARAM_construct_end(); - return EVP_PKEY_CTX_set_params(ctx, tls1_prf_md_params); + return EVP_PKEY_CTX_set_params(ctx, octet_string_params); } int EVP_PKEY_CTX_set1_tls1_prf_secret(EVP_PKEY_CTX *ctx, const unsigned char *sec, int seclen) { - OSSL_PARAM tls1_prf_secret_params[2], *p = tls1_prf_secret_params; - - if (ctx == NULL || !EVP_PKEY_CTX_IS_DERIVE_OP(ctx)) { - ERR_raise(ERR_LIB_EVP, EVP_R_COMMAND_NOT_SUPPORTED); - /* Uses the same return values as EVP_PKEY_CTX_ctrl */ - return -2; - } + return evp_pkey_ctx_set1_octet_string(ctx, ctx->op.kex.exchprovctx == NULL, + OSSL_KDF_PARAM_SECRET, + EVP_PKEY_OP_DERIVE, + EVP_PKEY_CTRL_TLS_SECRET, + sec, seclen); +} - /* TODO(3.0): Remove this eventually when no more legacy */ - if (ctx->op.kex.exchprovctx == NULL) - return EVP_PKEY_CTX_ctrl(ctx, -1, EVP_PKEY_OP_DERIVE, - EVP_PKEY_CTRL_TLS_SECRET, seclen, - (void *)(sec)); +int EVP_PKEY_CTX_add1_tls1_prf_seed(EVP_PKEY_CTX *ctx, + const unsigned char *seed, int seedlen) +{ + return evp_pkey_ctx_set1_octet_string(ctx, ctx->op.kex.exchprovctx == NULL, + OSSL_KDF_PARAM_SEED, + EVP_PKEY_OP_DERIVE, + EVP_PKEY_CTRL_TLS_SEED, + seed, seedlen); +} +int EVP_PKEY_CTX_set_hkdf_md(EVP_PKEY_CTX *ctx, const EVP_MD *md) +{ + return evp_pkey_ctx_set_md(ctx, md, ctx->op.kex.exchprovctx == NULL, + OSSL_KDF_PARAM_DIGEST, + EVP_PKEY_OP_DERIVE, EVP_PKEY_CTRL_HKDF_MD); +} - if (seclen < 0) { - ERR_raise(ERR_LIB_EVP, EVP_R_INVALID_SECRET_LENGTH); - return 0; - } +int EVP_PKEY_CTX_set1_hkdf_salt(EVP_PKEY_CTX *ctx, + const unsigned char *salt, int saltlen) +{ + return evp_pkey_ctx_set1_octet_string(ctx, ctx->op.kex.exchprovctx == NULL, + OSSL_KDF_PARAM_SALT, + EVP_PKEY_OP_DERIVE, + EVP_PKEY_CTRL_HKDF_SALT, + salt, saltlen); +} - *p++ = OSSL_PARAM_construct_octet_string(OSSL_KDF_PARAM_SECRET, - /* - * Cast away the const. This is read - * only so should be safe - */ - (unsigned char *)sec, - (size_t)seclen); - *p++ = OSSL_PARAM_construct_end(); +int EVP_PKEY_CTX_set1_hkdf_key(EVP_PKEY_CTX *ctx, + const unsigned char *key, int keylen) +{ + return evp_pkey_ctx_set1_octet_string(ctx, ctx->op.kex.exchprovctx == NULL, + OSSL_KDF_PARAM_KEY, + EVP_PKEY_OP_DERIVE, + EVP_PKEY_CTRL_HKDF_KEY, + key, keylen); +} - return EVP_PKEY_CTX_set_params(ctx, tls1_prf_secret_params); +int EVP_PKEY_CTX_add1_hkdf_info(EVP_PKEY_CTX *ctx, + const unsigned char *info, int infolen) +{ + return evp_pkey_ctx_set1_octet_string(ctx, ctx->op.kex.exchprovctx == NULL, + OSSL_KDF_PARAM_INFO, + EVP_PKEY_OP_DERIVE, + EVP_PKEY_CTRL_HKDF_INFO, + info, infolen); } -int EVP_PKEY_CTX_add1_tls1_prf_seed(EVP_PKEY_CTX *ctx, - const unsigned char *seed, int seedlen) +int EVP_PKEY_CTX_hkdf_mode(EVP_PKEY_CTX *ctx, int mode) { - OSSL_PARAM tls1_prf_seed_params[2], *p = tls1_prf_seed_params; + OSSL_PARAM int_params[2], *p = int_params; if (ctx == NULL || !EVP_PKEY_CTX_IS_DERIVE_OP(ctx)) { ERR_raise(ERR_LIB_EVP, EVP_R_COMMAND_NOT_SUPPORTED); @@ -907,24 +943,18 @@ int EVP_PKEY_CTX_add1_tls1_prf_seed(EVP_PKEY_CTX *ctx, /* TODO(3.0): Remove this eventually when no more legacy */ if (ctx->op.kex.exchprovctx == NULL) return EVP_PKEY_CTX_ctrl(ctx, -1, EVP_PKEY_OP_DERIVE, - EVP_PKEY_CTRL_TLS_SEED, seedlen, - (void *)(seed)); + EVP_PKEY_CTRL_HKDF_MODE, mode, NULL); + - if (seedlen < 0) { - ERR_raise(ERR_LIB_EVP, EVP_R_INVALID_SEED_LENGTH); + if (mode < 0) { + ERR_raise(ERR_LIB_EVP, EVP_R_INVALID_VALUE); return 0; } - *p++ = OSSL_PARAM_construct_octet_string(OSSL_KDF_PARAM_SEED, - /* - * Cast away the const. This is read - * only so should be safe - */ - (unsigned char *)seed, - (size_t)seedlen); + *p++ = OSSL_PARAM_construct_int(OSSL_KDF_PARAM_MODE, &mode); *p++ = OSSL_PARAM_construct_end(); - return EVP_PKEY_CTX_set_params(ctx, tls1_prf_seed_params); + return EVP_PKEY_CTX_set_params(ctx, int_params); } static int legacy_ctrl_to_param(EVP_PKEY_CTX *ctx, int keytype, int optype, @@ -1030,12 +1060,25 @@ static int legacy_ctrl_to_param(EVP_PKEY_CTX *ctx, int keytype, int optype, if (keytype == -1) { if (optype == EVP_PKEY_OP_DERIVE) { switch (cmd) { + /* TLS1-PRF */ case EVP_PKEY_CTRL_TLS_MD: return EVP_PKEY_CTX_set_tls1_prf_md(ctx, p2); case EVP_PKEY_CTRL_TLS_SECRET: return EVP_PKEY_CTX_set1_tls1_prf_secret(ctx, p2, p1); case EVP_PKEY_CTRL_TLS_SEED: return EVP_PKEY_CTX_add1_tls1_prf_seed(ctx, p2, p1); + + /* HKDF */ + case EVP_PKEY_CTRL_HKDF_MD: + return EVP_PKEY_CTX_set_hkdf_md(ctx, p2); + case EVP_PKEY_CTRL_HKDF_SALT : + return EVP_PKEY_CTX_set1_hkdf_salt(ctx, p2, p1); + case EVP_PKEY_CTRL_HKDF_KEY: + return EVP_PKEY_CTX_set1_hkdf_key(ctx, p2, p1); + case EVP_PKEY_CTRL_HKDF_INFO: + return EVP_PKEY_CTX_add1_hkdf_info(ctx, p2, p1); + case EVP_PKEY_CTRL_HKDF_MODE: + return EVP_PKEY_CTX_hkdf_mode(ctx, p1); } } switch (cmd) { diff --git a/include/openssl/evperr.h b/include/openssl/evperr.h index a4dd4c757d..ef74c10243 100644 --- a/include/openssl/evperr.h +++ b/include/openssl/evperr.h @@ -206,12 +206,14 @@ int ERR_load_EVP_strings(void); # define EVP_R_INVALID_IV_LENGTH 194 # define EVP_R_INVALID_KEY 163 # define EVP_R_INVALID_KEY_LENGTH 130 +# define EVP_R_INVALID_LENGTH 221 # define EVP_R_INVALID_NULL_ALGORITHM 218 # define EVP_R_INVALID_OPERATION 148 # define EVP_R_INVALID_PROVIDER_FUNCTIONS 193 # define EVP_R_INVALID_SALT_LENGTH 186 -# define EVP_R_INVALID_SECRET_LENGTH 221 +# define EVP_R_INVALID_SECRET_LENGTH 223 # define EVP_R_INVALID_SEED_LENGTH 220 +# define EVP_R_INVALID_VALUE 222 # define EVP_R_KEYGEN_FAILURE 120 # define EVP_R_KEYMGMT_EXPORT_FAILURE 205 # define EVP_R_KEY_SETUP_FAILED 180 diff --git a/include/openssl/kdf.h b/include/openssl/kdf.h index 1be54afc60..47f6422a96 100644 --- a/include/openssl/kdf.h +++ b/include/openssl/kdf.h @@ -123,25 +123,18 @@ int EVP_PKEY_CTX_set1_tls1_prf_secret(EVP_PKEY_CTX *pctx, int EVP_PKEY_CTX_add1_tls1_prf_seed(EVP_PKEY_CTX *pctx, const unsigned char *seed, int seedlen); -# define EVP_PKEY_CTX_set_hkdf_md(pctx, md) \ - EVP_PKEY_CTX_ctrl(pctx, -1, EVP_PKEY_OP_DERIVE, \ - EVP_PKEY_CTRL_HKDF_MD, 0, (void *)(md)) +int EVP_PKEY_CTX_set_hkdf_md(EVP_PKEY_CTX *ctx, const EVP_MD *md); -# define EVP_PKEY_CTX_set1_hkdf_salt(pctx, salt, saltlen) \ - EVP_PKEY_CTX_ctrl(pctx, -1, EVP_PKEY_OP_DERIVE, \ - EVP_PKEY_CTRL_HKDF_SALT, saltlen, (void *)(salt)) +int EVP_PKEY_CTX_set1_hkdf_salt(EVP_PKEY_CTX *ctx, + const unsigned char *salt, int saltlen); -# define EVP_PKEY_CTX_set1_hkdf_key(pctx, key, keylen) \ - EVP_PKEY_CTX_ctrl(pctx, -1, EVP_PKEY_OP_DERIVE, \ - EVP_PKEY_CTRL_HKDF_KEY, keylen, (void *)(key)) +int EVP_PKEY_CTX_set1_hkdf_key(EVP_PKEY_CTX *ctx, + const unsigned char *key, int keylen); -# define EVP_PKEY_CTX_add1_hkdf_info(pctx, info, infolen) \ - EVP_PKEY_CTX_ctrl(pctx, -1, EVP_PKEY_OP_DERIVE, \ - EVP_PKEY_CTRL_HKDF_INFO, infolen, (void *)(info)) +int EVP_PKEY_CTX_add1_hkdf_info(EVP_PKEY_CTX *ctx, + const unsigned char *info, int infolen); -# 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) +int EVP_PKEY_CTX_hkdf_mode(EVP_PKEY_CTX *ctx, int mode); # define EVP_PKEY_CTX_set1_pbe_pass(pctx, pass, passlen) \ EVP_PKEY_CTX_ctrl(pctx, -1, EVP_PKEY_OP_DERIVE, \ diff --git a/providers/defltprov.c b/providers/defltprov.c index 5b6d6a677e..f2fe98fc7f 100644 --- a/providers/defltprov.c +++ b/providers/defltprov.c @@ -339,7 +339,8 @@ static const OSSL_ALGORITHM deflt_keyexch[] = { { "X25519", "provider=default", x25519_keyexch_functions }, { "X448", "provider=default", x448_keyexch_functions }, #endif - { "TLS1-PRF", "provider=default", kdf_keyexch_functions }, + { "TLS1-PRF", "provider=default", kdf_tls1_prf_keyexch_functions }, + { "HKDF", "provider=default", kdf_hkdf_keyexch_functions }, { NULL, NULL, NULL } }; @@ -386,6 +387,7 @@ static const OSSL_ALGORITHM deflt_keymgmt[] = { { "ED448", "provider=default", ed448_keymgmt_functions }, #endif { "TLS1-PRF", "provider=default", kdf_keymgmt_functions }, + { "HKDF", "provider=default", kdf_keymgmt_functions }, { NULL, NULL, NULL } }; diff --git a/providers/implementations/exchange/kdf_exch.c b/providers/implementations/exchange/kdf_exch.c index 41278e6389..e238b0307b 100644 --- a/providers/implementations/exchange/kdf_exch.c +++ b/providers/implementations/exchange/kdf_exch.c @@ -16,13 +16,15 @@ #include "prov/provider_ctx.h" #include "prov/kdfexchange.h" -static OSSL_FUNC_keyexch_newctx_fn kdf_newctx; +static OSSL_FUNC_keyexch_newctx_fn kdf_tls1_prf_newctx; +static OSSL_FUNC_keyexch_newctx_fn kdf_hkdf_newctx; static OSSL_FUNC_keyexch_init_fn kdf_init; static OSSL_FUNC_keyexch_derive_fn kdf_derive; static OSSL_FUNC_keyexch_freectx_fn kdf_freectx; static OSSL_FUNC_keyexch_dupctx_fn kdf_dupctx; static OSSL_FUNC_keyexch_set_ctx_params_fn kdf_set_ctx_params; -static OSSL_FUNC_keyexch_settable_ctx_params_fn kdf_settable_ctx_params; +static OSSL_FUNC_keyexch_settable_ctx_params_fn kdf_tls1_prf_settable_ctx_params; +static OSSL_FUNC_keyexch_settable_ctx_params_fn kdf_hkdf_settable_ctx_params; typedef struct { void *provctx; @@ -30,30 +32,35 @@ typedef struct { KDF_DATA *kdfdata; } PROV_KDF_CTX; -static void *kdf_newctx(void *provctx) -{ - PROV_KDF_CTX *kdfctx = OPENSSL_zalloc(sizeof(PROV_KDF_CTX)); - EVP_KDF *kdf = NULL; - - if (kdfctx == NULL) - return NULL; - - kdfctx->provctx = provctx; - - kdf = EVP_KDF_fetch(PROV_LIBRARY_CONTEXT_OF(provctx), "TLS1-PRF", NULL); - if (kdf == NULL) - goto err; - kdfctx->kdfctx = EVP_KDF_new_ctx(kdf); - EVP_KDF_free(kdf); +#define KDF_NEWCTX(funcname, kdfname) \ + static void *kdf_##funcname##_newctx(void *provctx) \ + { \ + PROV_KDF_CTX *kdfctx = OPENSSL_zalloc(sizeof(PROV_KDF_CTX)); \ + EVP_KDF *kdf = NULL; \ + \ + if (kdfctx == NULL) \ + return NULL; \ + \ + kdfctx->provctx = provctx; \ + \ + kdf = EVP_KDF_fetch(PROV_LIBRARY_CONTEXT_OF(provctx), kdfname, NULL); \ + if (kdf == NULL) \ + goto err; \ + kdfctx->kdfctx = EVP_KDF_CTX_new(kdf); \ + EVP_KDF_free(kdf); \ + \ + if (kdfctx->kdfctx == NULL) \ + goto err; \ + \ + return kdfctx; \ + err: \ + OPENSSL_free(kdfctx); \ + return NULL; \ + } - if (kdfctx->kdfctx == NULL) - goto err; +KDF_NEWCTX(tls1_prf, "TLS1-PRF") +KDF_NEWCTX(hkdf, "HKDF") - return kdfctx; - err: - OPENSSL_free(kdfctx); - return NULL; -} static int kdf_init(void *vpkdfctx, void *vkdf) { @@ -95,7 +102,7 @@ static void *kdf_dupctx(void *vpkdfctx) *dstctx = *srcctx; - dstctx->kdfctx = EVP_KDF_dup_ctx(srcctx->kdfctx); + dstctx->kdfctx = EVP_KDF_CTX_dup(srcctx->kdfctx); if (dstctx->kdfctx == NULL) { OPENSSL_free(dstctx); return NULL; @@ -113,36 +120,44 @@ static int kdf_set_ctx_params(void *vpkdfctx, const OSSL_PARAM params[]) { PROV_KDF_CTX *pkdfctx = (PROV_KDF_CTX *)vpkdfctx; - return EVP_KDF_set_ctx_params(pkdfctx->kdfctx, params); + return EVP_KDF_CTX_set_params(pkdfctx->kdfctx, params); } +#define KDF_SETTABLE_CTX_PARAMS(funcname, kdfname) \ + static const OSSL_PARAM *kdf_##funcname##_settable_ctx_params(void) \ + { \ + /* \ + * TODO(3.0): FIXME FIXME!! These settable_ctx_params functions should \ + * should have a provctx argument so we can get hold of the libctx. \ + */ \ + EVP_KDF *kdf = EVP_KDF_fetch(NULL, kdfname, NULL); \ + const OSSL_PARAM *params; \ + \ + if (kdf == NULL) \ + return NULL; \ + \ + params = EVP_KDF_settable_ctx_params(kdf); \ + EVP_KDF_free(kdf); \ + \ + return params; \ + } -static const OSSL_PARAM *kdf_settable_ctx_params(void) -{ - /* - * TODO(3.0): FIXME FIXME!! These settable_ctx_params functions should - * should have a provctx argument so we can get hold of the libctx. - */ - EVP_KDF *kdf = EVP_KDF_fetch(NULL, "TLS1-PRF", NULL); - const OSSL_PARAM *params; - - if (kdf == NULL) - return NULL; - - params = EVP_KDF_settable_ctx_params(kdf); - EVP_KDF_free(kdf); - - return params; -} - -const OSSL_DISPATCH kdf_keyexch_functions[] = { - { OSSL_FUNC_KEYEXCH_NEWCTX, (void (*)(void))kdf_newctx }, - { OSSL_FUNC_KEYEXCH_INIT, (void (*)(void))kdf_init }, - { OSSL_FUNC_KEYEXCH_DERIVE, (void (*)(void))kdf_derive }, - { OSSL_FUNC_KEYEXCH_FREECTX, (void (*)(void))kdf_freectx }, - { OSSL_FUNC_KEYEXCH_DUPCTX, (void (*)(void))kdf_dupctx }, - { OSSL_FUNC_KEYEXCH_SET_CTX_PARAMS, (void (*)(void))kdf_set_ctx_params }, - { OSSL_FUNC_KEYEXCH_SETTABLE_CTX_PARAMS, - (void (*)(void))kdf_settable_ctx_params }, - { 0, NULL } -}; +KDF_SETTABLE_CTX_PARAMS(tls1_prf, "TLS1-PRF") +KDF_SETTABLE_CTX_PARAMS(hkdf, "HKDF") + + +#define KDF_KEYEXCH_FUNCTIONS(funcname) \ + const OSSL_DISPATCH kdf_##funcname##_keyexch_functions[] = { \ + { OSSL_FUNC_KEYEXCH_NEWCTX, (void (*)(void))kdf_##funcname##_newctx }, \ + { OSSL_FUNC_KEYEXCH_INIT, (void (*)(void))kdf_init }, \ + { OSSL_FUNC_KEYEXCH_DERIVE, (void (*)(void))kdf_derive }, \ + { OSSL_FUNC_KEYEXCH_FREECTX, (void (*)(void))kdf_freectx }, \ + { OSSL_FUNC_KEYEXCH_DUPCTX, (void (*)(void))kdf_dupctx }, \ + { OSSL_FUNC_KEYEXCH_SET_CTX_PARAMS, (void (*)(void))kdf_set_ctx_params }, \ + { OSSL_FUNC_KEYEXCH_SETTABLE_CTX_PARAMS, \ + (void (*)(void))kdf_##funcname##_settable_ctx_params }, \ + { 0, NULL } \ + }; + +KDF_KEYEXCH_FUNCTIONS(tls1_prf) +KDF_KEYEXCH_FUNCTIONS(hkdf) diff --git a/providers/implementations/include/prov/implementations.h b/providers/implementations/include/prov/implementations.h index e862e3f8e8..d30a105d2d 100644 --- a/providers/implementations/include/prov/implementations.h +++ b/providers/implementations/include/prov/implementations.h @@ -282,7 +282,8 @@ extern const OSSL_DISPATCH dh_keyexch_functions[]; extern const OSSL_DISPATCH x25519_keyexch_functions[]; extern const OSSL_DISPATCH x448_keyexch_functions[]; extern const OSSL_DISPATCH ecdh_keyexch_functions[]; -extern const OSSL_DISPATCH kdf_keyexch_functions[]; +extern const OSSL_DISPATCH kdf_tls1_prf_keyexch_functions[]; +extern const OSSL_DISPATCH kdf_hkdf_keyexch_functions[]; /* Signature */ extern const OSSL_DISPATCH dsa_signature_functions[]; diff --git a/test/pkey_meth_kdf_test.c b/test/pkey_meth_kdf_test.c index 55b10f546e..9fdec0a470 100644 --- a/test/pkey_meth_kdf_test.c +++ b/test/pkey_meth_kdf_test.c @@ -84,15 +84,18 @@ static int test_kdf_hkdf(void) TEST_error("EVP_PKEY_CTX_set_hkdf_md"); goto err; } - if (EVP_PKEY_CTX_set1_hkdf_salt(pctx, "salt", 4) <= 0) { + if (EVP_PKEY_CTX_set1_hkdf_salt(pctx, (const unsigned char *)"salt", 4) + <= 0) { TEST_error("EVP_PKEY_CTX_set1_hkdf_salt"); goto err; } - if (EVP_PKEY_CTX_set1_hkdf_key(pctx, "secret", 6) <= 0) { + if (EVP_PKEY_CTX_set1_hkdf_key(pctx, (const unsigned char *)"secret", 6) + <= 0) { TEST_error("EVP_PKEY_CTX_set1_hkdf_key"); goto err; } - if (EVP_PKEY_CTX_add1_hkdf_info(pctx, "label", 5) <= 0) { + if (EVP_PKEY_CTX_add1_hkdf_info(pctx, (const unsigned char *)"label", 5) + <= 0) { TEST_error("EVP_PKEY_CTX_set1_hkdf_info"); goto err; } diff --git a/util/libcrypto.num b/util/libcrypto.num index 7a31db8bb5..6b32883bfb 100644 --- a/util/libcrypto.num +++ b/util/libcrypto.num @@ -5229,3 +5229,8 @@ OSSL_PROVIDER_self_test ? 3_0_0 EXIST::FUNCTION: EVP_PKEY_CTX_set_tls1_prf_md ? 3_0_0 EXIST::FUNCTION: EVP_PKEY_CTX_set1_tls1_prf_secret ? 3_0_0 EXIST::FUNCTION: EVP_PKEY_CTX_add1_tls1_prf_seed ? 3_0_0 EXIST::FUNCTION: +EVP_PKEY_CTX_set_hkdf_md ? 3_0_0 EXIST::FUNCTION: +EVP_PKEY_CTX_set1_hkdf_salt ? 3_0_0 EXIST::FUNCTION: +EVP_PKEY_CTX_set1_hkdf_key ? 3_0_0 EXIST::FUNCTION: +EVP_PKEY_CTX_add1_hkdf_info ? 3_0_0 EXIST::FUNCTION: +EVP_PKEY_CTX_hkdf_mode ? 3_0_0 EXIST::FUNCTION: -- GitLab