mirror of
https://github.com/QuasarApp/openssl.git
synced 2025-04-29 11:14:36 +00:00
Implement a EVP_PKEY KDF to KDF provider bridge
Some KDF implementations were available before the current EVP_KDF API. They were used via EVP_PKEY_derive. There exists a bridge between the old API and the EVP_KDF API however this bridge itself uses a legacy EVP_PKEY_METHOD. This commit implements a provider side bridge without having to use any legacy code. Reviewed-by: Paul Dale <paul.dale@oracle.com> (Merged from https://github.com/openssl/openssl/pull/12573)
This commit is contained in:
parent
23f04372f4
commit
ac2d58c72b
@ -2558,6 +2558,8 @@ 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_SEED_LENGTH:220:invalid seed length
|
||||
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
|
||||
|
@ -97,6 +97,10 @@ static const ERR_STRING_DATA EVP_str_reasons[] = {
|
||||
"invalid provider functions"},
|
||||
{ERR_PACK(ERR_LIB_EVP, 0, EVP_R_INVALID_SALT_LENGTH),
|
||||
"invalid salt length"},
|
||||
{ERR_PACK(ERR_LIB_EVP, 0, EVP_R_INVALID_SECRET_LENGTH),
|
||||
"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_KEYGEN_FAILURE), "keygen failure"},
|
||||
{ERR_PACK(ERR_LIB_EVP, 0, EVP_R_KEYMGMT_EXPORT_FAILURE),
|
||||
"keymgmt export failure"},
|
||||
|
@ -202,11 +202,31 @@ int EVP_PKEY_derive_init(EVP_PKEY_CTX *ctx)
|
||||
|
||||
/*
|
||||
* Ensure that the key is provided, either natively, or as a cached export.
|
||||
* If not, go legacy
|
||||
* If not, goto legacy
|
||||
*/
|
||||
tmp_keymgmt = ctx->keymgmt;
|
||||
provkey = evp_pkey_export_to_provider(ctx->pkey, ctx->libctx,
|
||||
&tmp_keymgmt, ctx->propquery);
|
||||
if (ctx->pkey == NULL) {
|
||||
/*
|
||||
* Some algorithms (e.g. legacy KDFs) don't have a pkey - so we create
|
||||
* a blank one.
|
||||
*/
|
||||
EVP_PKEY *pkey = EVP_PKEY_new();
|
||||
|
||||
if (pkey == NULL || !EVP_PKEY_set_type_by_keymgmt(pkey, tmp_keymgmt)) {
|
||||
ERR_clear_last_mark();
|
||||
EVP_PKEY_free(pkey);
|
||||
ERR_raise(ERR_LIB_EVP, EVP_R_INITIALIZATION_ERROR);
|
||||
goto err;
|
||||
}
|
||||
provkey = pkey->keydata = evp_keymgmt_newdata(tmp_keymgmt);
|
||||
if (provkey == NULL)
|
||||
EVP_PKEY_free(pkey);
|
||||
else
|
||||
ctx->pkey = pkey;
|
||||
} else {
|
||||
provkey = evp_pkey_export_to_provider(ctx->pkey, ctx->libctx,
|
||||
&tmp_keymgmt, ctx->propquery);
|
||||
}
|
||||
if (provkey == NULL)
|
||||
goto legacy;
|
||||
if (!EVP_KEYMGMT_up_ref(tmp_keymgmt)) {
|
||||
|
@ -21,6 +21,7 @@
|
||||
#include <openssl/core_names.h>
|
||||
#include <openssl/dh.h>
|
||||
#include <openssl/rsa.h>
|
||||
#include <openssl/kdf.h>
|
||||
#include "internal/cryptlib.h"
|
||||
#include "crypto/asn1.h"
|
||||
#include "crypto/evp.h"
|
||||
@ -156,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_TLS1_PRF:
|
||||
case EVP_PKEY_HKDF:
|
||||
case EVP_PKEY_CMAC:
|
||||
case EVP_PKEY_HMAC:
|
||||
@ -241,7 +241,7 @@ static EVP_PKEY_CTX *int_ctx_new(OPENSSL_CTX *libctx,
|
||||
* If an ENGINE handled this method look it up. Otherwise use internal
|
||||
* tables.
|
||||
*/
|
||||
if (e)
|
||||
if (e != NULL) {
|
||||
pmeth = ENGINE_get_pkey_meth(e, id);
|
||||
else
|
||||
# endif
|
||||
@ -759,7 +759,7 @@ int EVP_PKEY_CTX_set_dh_pad(EVP_PKEY_CTX *ctx, int pad)
|
||||
|
||||
int EVP_PKEY_CTX_get_signature_md(EVP_PKEY_CTX *ctx, const EVP_MD **md)
|
||||
{
|
||||
OSSL_PARAM sig_md_params[3], *p = sig_md_params;
|
||||
OSSL_PARAM sig_md_params[2], *p = sig_md_params;
|
||||
/* 80 should be big enough */
|
||||
char name[80] = "";
|
||||
const EVP_MD *tmp;
|
||||
@ -778,7 +778,7 @@ int EVP_PKEY_CTX_get_signature_md(EVP_PKEY_CTX *ctx, const EVP_MD **md)
|
||||
*p++ = OSSL_PARAM_construct_utf8_string(OSSL_SIGNATURE_PARAM_DIGEST,
|
||||
name,
|
||||
sizeof(name));
|
||||
*p++ = OSSL_PARAM_construct_end();
|
||||
*p = OSSL_PARAM_construct_end();
|
||||
|
||||
if (!EVP_PKEY_CTX_get_params(ctx, sig_md_params))
|
||||
return 0;
|
||||
@ -820,11 +820,113 @@ int EVP_PKEY_CTX_set_signature_md(EVP_PKEY_CTX *ctx, const EVP_MD *md)
|
||||
* only so should be safe
|
||||
*/
|
||||
(char *)name, 0);
|
||||
*p++ = OSSL_PARAM_construct_end();
|
||||
*p = OSSL_PARAM_construct_end();
|
||||
|
||||
return EVP_PKEY_CTX_set_params(ctx, sig_md_params);
|
||||
}
|
||||
|
||||
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;
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
/* 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 (md == NULL) {
|
||||
name = "";
|
||||
} else {
|
||||
name = EVP_MD_name(md);
|
||||
}
|
||||
|
||||
*p++ = OSSL_PARAM_construct_utf8_string(OSSL_KDF_PARAM_DIGEST,
|
||||
/*
|
||||
* Cast away the const. This is read
|
||||
* only so should be safe
|
||||
*/
|
||||
(char *)name, 0);
|
||||
*p++ = OSSL_PARAM_construct_end();
|
||||
|
||||
return EVP_PKEY_CTX_set_params(ctx, tls1_prf_md_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;
|
||||
}
|
||||
|
||||
/* 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));
|
||||
|
||||
|
||||
if (seclen < 0) {
|
||||
ERR_raise(ERR_LIB_EVP, EVP_R_INVALID_SECRET_LENGTH);
|
||||
return 0;
|
||||
}
|
||||
|
||||
*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();
|
||||
|
||||
return EVP_PKEY_CTX_set_params(ctx, tls1_prf_secret_params);
|
||||
}
|
||||
|
||||
int EVP_PKEY_CTX_add1_tls1_prf_seed(EVP_PKEY_CTX *ctx,
|
||||
const unsigned char *seed, int seedlen)
|
||||
{
|
||||
OSSL_PARAM tls1_prf_seed_params[2], *p = tls1_prf_seed_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;
|
||||
}
|
||||
|
||||
/* 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));
|
||||
|
||||
if (seedlen < 0) {
|
||||
ERR_raise(ERR_LIB_EVP, EVP_R_INVALID_SEED_LENGTH);
|
||||
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_end();
|
||||
|
||||
return EVP_PKEY_CTX_set_params(ctx, tls1_prf_seed_params);
|
||||
}
|
||||
|
||||
static int legacy_ctrl_to_param(EVP_PKEY_CTX *ctx, int keytype, int optype,
|
||||
int cmd, int p1, void *p2)
|
||||
{
|
||||
@ -926,6 +1028,16 @@ static int legacy_ctrl_to_param(EVP_PKEY_CTX *ctx, int keytype, int optype,
|
||||
* or for generic controls that are the same across multiple key types.
|
||||
*/
|
||||
if (keytype == -1) {
|
||||
if (optype == EVP_PKEY_OP_DERIVE) {
|
||||
switch (cmd) {
|
||||
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);
|
||||
}
|
||||
}
|
||||
switch (cmd) {
|
||||
case EVP_PKEY_CTRL_MD:
|
||||
return EVP_PKEY_CTX_set_signature_md(ctx, p2);
|
||||
@ -1034,7 +1146,9 @@ static int legacy_ctrl_str_to_param(EVP_PKEY_CTX *ctx, const char *name,
|
||||
}
|
||||
# endif
|
||||
|
||||
if (strcmp(name, "rsa_padding_mode") == 0)
|
||||
if (strcmp(name, "md") == 0)
|
||||
name = OSSL_ALG_PARAM_DIGEST;
|
||||
else if (strcmp(name, "rsa_padding_mode") == 0)
|
||||
name = OSSL_ASYM_CIPHER_PARAM_PAD_MODE;
|
||||
else if (strcmp(name, "rsa_mgf1_md") == 0)
|
||||
name = OSSL_ASYM_CIPHER_PARAM_MGF1_DIGEST;
|
||||
|
@ -210,6 +210,8 @@ int ERR_load_EVP_strings(void);
|
||||
# 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_SEED_LENGTH 220
|
||||
# define EVP_R_KEYGEN_FAILURE 120
|
||||
# define EVP_R_KEYMGMT_EXPORT_FAILURE 205
|
||||
# define EVP_R_KEY_SETUP_FAILED 180
|
||||
|
@ -115,17 +115,13 @@ void EVP_KDF_names_do_all(const EVP_KDF *kdf,
|
||||
# define EVP_PKEY_HKDEF_MODE_EXPAND_ONLY \
|
||||
EVP_KDF_HKDF_MODE_EXPAND_ONLY
|
||||
|
||||
# define EVP_PKEY_CTX_set_tls1_prf_md(pctx, md) \
|
||||
EVP_PKEY_CTX_ctrl(pctx, -1, EVP_PKEY_OP_DERIVE, \
|
||||
EVP_PKEY_CTRL_TLS_MD, 0, (void *)(md))
|
||||
int EVP_PKEY_CTX_set_tls1_prf_md(EVP_PKEY_CTX *ctx, const EVP_MD *md);
|
||||
|
||||
# define EVP_PKEY_CTX_set1_tls1_prf_secret(pctx, sec, seclen) \
|
||||
EVP_PKEY_CTX_ctrl(pctx, -1, EVP_PKEY_OP_DERIVE, \
|
||||
EVP_PKEY_CTRL_TLS_SECRET, seclen, (void *)(sec))
|
||||
int EVP_PKEY_CTX_set1_tls1_prf_secret(EVP_PKEY_CTX *pctx,
|
||||
const unsigned char *sec, int seclen);
|
||||
|
||||
# define EVP_PKEY_CTX_add1_tls1_prf_seed(pctx, seed, seedlen) \
|
||||
EVP_PKEY_CTX_ctrl(pctx, -1, EVP_PKEY_OP_DERIVE, \
|
||||
EVP_PKEY_CTRL_TLS_SEED, seedlen, (void *)(seed))
|
||||
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, \
|
||||
|
@ -339,6 +339,7 @@ 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 },
|
||||
{ NULL, NULL, NULL }
|
||||
};
|
||||
|
||||
@ -384,6 +385,7 @@ static const OSSL_ALGORITHM deflt_keymgmt[] = {
|
||||
{ "ED25519", "provider=default", ed25519_keymgmt_functions },
|
||||
{ "ED448", "provider=default", ed448_keymgmt_functions },
|
||||
#endif
|
||||
{ "TLS1-PRF", "provider=default", kdf_keymgmt_functions },
|
||||
{ NULL, NULL, NULL }
|
||||
};
|
||||
|
||||
|
@ -4,6 +4,7 @@
|
||||
$DH_GOAL=../../libimplementations.a
|
||||
$ECX_GOAL=../../libimplementations.a
|
||||
$ECDH_GOAL=../../libimplementations.a
|
||||
$KDF_GOAL=../../libimplementations.a
|
||||
|
||||
IF[{- !$disabled{dh} -}]
|
||||
SOURCE[$DH_GOAL]=dh_exch.c
|
||||
@ -25,3 +26,5 @@ IF[{- !$disabled{ec} -}]
|
||||
SOURCE[../../libfips.a]=ecdh_exch.c
|
||||
SOURCE[../../libnonfips.a]=ecdh_exch.c
|
||||
ENDIF
|
||||
|
||||
SOURCE[$KDF_GOAL]=kdf_exch.c
|
||||
|
148
providers/implementations/exchange/kdf_exch.c
Normal file
148
providers/implementations/exchange/kdf_exch.c
Normal file
@ -0,0 +1,148 @@
|
||||
/*
|
||||
* Copyright 2020 The OpenSSL Project Authors. All Rights Reserved.
|
||||
*
|
||||
* Licensed under the Apache License 2.0 (the "License"). You may not use
|
||||
* this file except in compliance with the License. You can obtain a copy
|
||||
* in the file LICENSE in the source distribution or at
|
||||
* https://www.openssl.org/source/license.html
|
||||
*/
|
||||
|
||||
#include <openssl/crypto.h>
|
||||
#include <openssl/kdf.h>
|
||||
#include <openssl/core_dispatch.h>
|
||||
#include <openssl/core_names.h>
|
||||
#include <openssl/params.h>
|
||||
#include "prov/implementations.h"
|
||||
#include "prov/provider_ctx.h"
|
||||
#include "prov/kdfexchange.h"
|
||||
|
||||
static OSSL_FUNC_keyexch_newctx_fn kdf_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;
|
||||
|
||||
typedef struct {
|
||||
void *provctx;
|
||||
EVP_KDF_CTX *kdfctx;
|
||||
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);
|
||||
|
||||
if (kdfctx->kdfctx == NULL)
|
||||
goto err;
|
||||
|
||||
return kdfctx;
|
||||
err:
|
||||
OPENSSL_free(kdfctx);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static int kdf_init(void *vpkdfctx, void *vkdf)
|
||||
{
|
||||
PROV_KDF_CTX *pkdfctx = (PROV_KDF_CTX *)vpkdfctx;
|
||||
|
||||
if (pkdfctx == NULL || vkdf == NULL || !kdf_data_up_ref(vkdf))
|
||||
return 0;
|
||||
pkdfctx->kdfdata = vkdf;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int kdf_derive(void *vpkdfctx, unsigned char *secret, size_t *secretlen,
|
||||
size_t outlen)
|
||||
{
|
||||
PROV_KDF_CTX *pkdfctx = (PROV_KDF_CTX *)vpkdfctx;
|
||||
|
||||
return EVP_KDF_derive(pkdfctx->kdfctx, secret, *secretlen);
|
||||
}
|
||||
|
||||
static void kdf_freectx(void *vpkdfctx)
|
||||
{
|
||||
PROV_KDF_CTX *pkdfctx = (PROV_KDF_CTX *)vpkdfctx;
|
||||
|
||||
EVP_KDF_CTX_free(pkdfctx->kdfctx);
|
||||
kdf_data_free(pkdfctx->kdfdata);
|
||||
|
||||
OPENSSL_free(pkdfctx);
|
||||
}
|
||||
|
||||
static void *kdf_dupctx(void *vpkdfctx)
|
||||
{
|
||||
PROV_KDF_CTX *srcctx = (PROV_KDF_CTX *)vpkdfctx;
|
||||
PROV_KDF_CTX *dstctx;
|
||||
|
||||
dstctx = OPENSSL_zalloc(sizeof(*srcctx));
|
||||
if (dstctx == NULL)
|
||||
return NULL;
|
||||
|
||||
*dstctx = *srcctx;
|
||||
|
||||
dstctx->kdfctx = EVP_KDF_dup_ctx(srcctx->kdfctx);
|
||||
if (dstctx->kdfctx == NULL) {
|
||||
OPENSSL_free(dstctx);
|
||||
return NULL;
|
||||
}
|
||||
if (!kdf_data_up_ref(dstctx->kdfdata)) {
|
||||
EVP_KDF_CTX_free(dstctx->kdfctx);
|
||||
OPENSSL_free(dstctx);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return dstctx;
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
|
||||
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 }
|
||||
};
|
@ -275,12 +275,14 @@ extern const OSSL_DISPATCH x448_keymgmt_functions[];
|
||||
extern const OSSL_DISPATCH ed25519_keymgmt_functions[];
|
||||
extern const OSSL_DISPATCH ed448_keymgmt_functions[];
|
||||
extern const OSSL_DISPATCH ec_keymgmt_functions[];
|
||||
extern const OSSL_DISPATCH kdf_keymgmt_functions[];
|
||||
|
||||
/* Key Exchange */
|
||||
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[];
|
||||
|
||||
/* Signature */
|
||||
extern const OSSL_DISPATCH dsa_signature_functions[];
|
||||
|
24
providers/implementations/include/prov/kdfexchange.h
Normal file
24
providers/implementations/include/prov/kdfexchange.h
Normal file
@ -0,0 +1,24 @@
|
||||
/*
|
||||
* Copyright 2020 The OpenSSL Project Authors. All Rights Reserved.
|
||||
*
|
||||
* Licensed under the Apache License 2.0 (the "License"). You may not use
|
||||
* this file except in compliance with the License. You can obtain a copy
|
||||
* in the file LICENSE in the source distribution or at
|
||||
* https://www.openssl.org/source/license.html
|
||||
*/
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <openssl/crypto.h>
|
||||
#include "internal/refcount.h"
|
||||
|
||||
struct kdf_data_st {
|
||||
OPENSSL_CTX *libctx;
|
||||
CRYPTO_REF_COUNT refcnt;
|
||||
CRYPTO_RWLOCK *lock;
|
||||
};
|
||||
|
||||
typedef struct kdf_data_st KDF_DATA;
|
||||
|
||||
KDF_DATA *kdf_data_new(void *provctx);
|
||||
void kdf_data_free(KDF_DATA *kdfdata);
|
||||
int kdf_data_up_ref(KDF_DATA *kdfdata);
|
@ -183,9 +183,6 @@ static int kdf_tls1_prf_set_ctx_params(void *vctx, const OSSL_PARAM params[])
|
||||
}
|
||||
/* The seed fields concatenate, so process them all */
|
||||
if ((p = OSSL_PARAM_locate_const(params, OSSL_KDF_PARAM_SEED)) != NULL) {
|
||||
OPENSSL_cleanse(ctx->seed, ctx->seedlen);
|
||||
ctx->seedlen = 0;
|
||||
|
||||
for (; p != NULL; p = OSSL_PARAM_locate_const(p + 1,
|
||||
OSSL_KDF_PARAM_SEED)) {
|
||||
const void *q = ctx->seed + ctx->seedlen;
|
||||
|
@ -5,6 +5,7 @@ $DH_GOAL=../../libimplementations.a
|
||||
$DSA_GOAL=../../libimplementations.a
|
||||
$EC_GOAL=../../libimplementations.a
|
||||
$ECX_GOAL=../../libimplementations.a
|
||||
$KDF_GOAL=../../libimplementations.a
|
||||
|
||||
IF[{- !$disabled{dh} -}]
|
||||
SOURCE[$DH_GOAL]=dh_kmgmt.c
|
||||
@ -33,3 +34,5 @@ ENDIF
|
||||
|
||||
SOURCE[../../libfips.a]=rsa_kmgmt.c
|
||||
SOURCE[../../libnonfips.a]=rsa_kmgmt.c
|
||||
|
||||
SOURCE[$KDF_GOAL]=kdf_legacy_kmgmt.c
|
||||
|
90
providers/implementations/keymgmt/kdf_legacy_kmgmt.c
Normal file
90
providers/implementations/keymgmt/kdf_legacy_kmgmt.c
Normal file
@ -0,0 +1,90 @@
|
||||
/*
|
||||
* Copyright 2019-2020 The OpenSSL Project Authors. All Rights Reserved.
|
||||
*
|
||||
* Licensed under the Apache License 2.0 (the "License"). You may not use
|
||||
* this file except in compliance with the License. You can obtain a copy
|
||||
* in the file LICENSE in the source distribution or at
|
||||
* https://www.openssl.org/source/license.html
|
||||
*/
|
||||
|
||||
/*
|
||||
* This implemments a dummy key manager for legacy KDFs that still support the
|
||||
* old way of performing a KDF via EVP_PKEY_derive(). New KDFs should not be
|
||||
* implemented this way. In reality there is no key data for such KDFs, so this
|
||||
* key manager does very little.
|
||||
*/
|
||||
|
||||
#include <openssl/core_dispatch.h>
|
||||
#include <openssl/core_names.h>
|
||||
#include <openssl/err.h>
|
||||
#include "prov/implementations.h"
|
||||
#include "prov/providercommon.h"
|
||||
#include "prov/provider_ctx.h"
|
||||
#include "prov/kdfexchange.h"
|
||||
|
||||
static OSSL_FUNC_keymgmt_new_fn kdf_newdata;
|
||||
static OSSL_FUNC_keymgmt_free_fn kdf_freedata;
|
||||
static OSSL_FUNC_keymgmt_has_fn kdf_has;
|
||||
|
||||
KDF_DATA *kdf_data_new(void *provctx)
|
||||
{
|
||||
KDF_DATA *kdfdata = OPENSSL_zalloc(sizeof(*kdfdata));
|
||||
|
||||
if (kdfdata == NULL)
|
||||
return NULL;
|
||||
|
||||
kdfdata->lock = CRYPTO_THREAD_lock_new();
|
||||
if (kdfdata->lock == NULL) {
|
||||
OPENSSL_free(kdfdata);
|
||||
return NULL;
|
||||
}
|
||||
kdfdata->libctx = PROV_LIBRARY_CONTEXT_OF(provctx);
|
||||
kdfdata->refcnt = 1;
|
||||
|
||||
return kdfdata;
|
||||
}
|
||||
|
||||
void kdf_data_free(KDF_DATA *kdfdata)
|
||||
{
|
||||
int ref = 0;
|
||||
|
||||
if (kdfdata == NULL)
|
||||
return;
|
||||
|
||||
CRYPTO_DOWN_REF(&kdfdata->refcnt, &ref, kdfdata->lock);
|
||||
if (ref > 0)
|
||||
return;
|
||||
|
||||
CRYPTO_THREAD_lock_free(kdfdata->lock);
|
||||
OPENSSL_free(kdfdata);
|
||||
}
|
||||
|
||||
int kdf_data_up_ref(KDF_DATA *kdfdata)
|
||||
{
|
||||
int ref = 0;
|
||||
|
||||
CRYPTO_UP_REF(&kdfdata->refcnt, &ref, kdfdata->lock);
|
||||
return 1;
|
||||
}
|
||||
|
||||
static void *kdf_newdata(void *provctx)
|
||||
{
|
||||
return kdf_data_new(provctx);
|
||||
}
|
||||
|
||||
static void kdf_freedata(void *kdfdata)
|
||||
{
|
||||
kdf_data_free(kdfdata);
|
||||
}
|
||||
|
||||
static int kdf_has(void *keydata, int selection)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
const OSSL_DISPATCH kdf_keymgmt_functions[] = {
|
||||
{ OSSL_FUNC_KEYMGMT_NEW, (void (*)(void))kdf_newdata },
|
||||
{ OSSL_FUNC_KEYMGMT_FREE, (void (*)(void))kdf_freedata },
|
||||
{ OSSL_FUNC_KEYMGMT_HAS, (void (*)(void))kdf_has },
|
||||
{ 0, NULL }
|
||||
};
|
@ -35,11 +35,13 @@ static int test_kdf_tls1_prf(void)
|
||||
TEST_error("EVP_PKEY_CTX_set_tls1_prf_md");
|
||||
goto err;
|
||||
}
|
||||
if (EVP_PKEY_CTX_set1_tls1_prf_secret(pctx, "secret", 6) <= 0) {
|
||||
if (EVP_PKEY_CTX_set1_tls1_prf_secret(pctx,
|
||||
(unsigned char *)"secret", 6) <= 0) {
|
||||
TEST_error("EVP_PKEY_CTX_set1_tls1_prf_secret");
|
||||
goto err;
|
||||
}
|
||||
if (EVP_PKEY_CTX_add1_tls1_prf_seed(pctx, "seed", 4) <= 0) {
|
||||
if (EVP_PKEY_CTX_add1_tls1_prf_seed(pctx,
|
||||
(unsigned char *)"seed", 4) <= 0) {
|
||||
TEST_error("EVP_PKEY_CTX_add1_tls1_prf_seed");
|
||||
goto err;
|
||||
}
|
||||
|
@ -5226,3 +5226,6 @@ PKCS7_sign_with_libctx ? 3_0_0 EXIST::FUNCTION:
|
||||
PKCS7_encrypt_with_libctx ? 3_0_0 EXIST::FUNCTION:
|
||||
SMIME_read_PKCS7_ex ? 3_0_0 EXIST::FUNCTION:
|
||||
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:
|
||||
|
Loading…
x
Reference in New Issue
Block a user