From fb9e6dd6f8b1de99c880ff3b458d6bc0dec907bb Mon Sep 17 00:00:00 2001 From: Pauli Date: Wed, 21 Aug 2019 18:54:35 +1000 Subject: [PATCH] KDF/PRF updates to libcrypto Reviewed-by: Richard Levitte (Merged from https://github.com/openssl/openssl/pull/9662) --- crypto/evp/build.info | 6 +- crypto/evp/evp_locl.h | 4 +- crypto/evp/kdf_lib.c | 156 ++++++++++++++---------- crypto/evp/kdf_meth.c | 192 ++++++++++++++++++++++++++++++ crypto/evp/names.c | 29 ----- crypto/include/internal/evp_int.h | 37 +++--- crypto/kdf/build.info | 3 +- crypto/kdf/kdf_local.h | 22 ---- crypto/kdf/kdf_util.c | 73 ------------ include/openssl/kdf.h | 65 +++++----- 10 files changed, 342 insertions(+), 245 deletions(-) create mode 100644 crypto/evp/kdf_meth.c delete mode 100644 crypto/kdf/kdf_local.h delete mode 100644 crypto/kdf/kdf_util.c diff --git a/crypto/evp/build.info b/crypto/evp/build.info index 688e6fc94e..d9df71959c 100644 --- a/crypto/evp/build.info +++ b/crypto/evp/build.info @@ -1,6 +1,6 @@ LIBS=../../libcrypto $COMMON=digest.c evp_enc.c evp_lib.c evp_fetch.c cmeth_lib.c evp_utils.c \ - mac_lib.c mac_meth.c keymgmt_meth.c keymgmt_lib.c + mac_lib.c mac_meth.c keymgmt_meth.c keymgmt_lib.c kdf_lib.c kdf_meth.c SOURCE[../../libcrypto]=$COMMON\ encode.c evp_key.c evp_cnf.c \ e_des.c e_bf.c e_idea.c e_des3.c e_camellia.c\ @@ -11,8 +11,8 @@ SOURCE[../../libcrypto]=$COMMON\ p_open.c p_seal.c p_sign.c p_verify.c p_lib.c p_enc.c p_dec.c \ bio_md.c bio_b64.c bio_enc.c evp_err.c e_null.c \ c_allc.c c_alld.c bio_ok.c \ - evp_pkey.c kdf_lib.c evp_pbe.c p5_crpt.c p5_crpt2.c pbe_scrypt.c \ - pkey_kdf.c c_allkdf.c \ + evp_pkey.c evp_pbe.c p5_crpt.c p5_crpt2.c pbe_scrypt.c \ + pkey_kdf.c \ e_old.c pmeth_lib.c pmeth_fn.c pmeth_gn.c m_sigver.c \ e_aes_cbc_hmac_sha1.c e_aes_cbc_hmac_sha256.c e_rc4_hmac_md5.c \ e_chacha20_poly1305.c \ diff --git a/crypto/evp/evp_locl.h b/crypto/evp/evp_locl.h index 87f54bdc5f..750e593b66 100644 --- a/crypto/evp/evp_locl.h +++ b/crypto/evp/evp_locl.h @@ -61,8 +61,8 @@ struct evp_mac_ctx_st { } /* EVP_MAC_CTX */; struct evp_kdf_ctx_st { - const EVP_KDF *meth; /* Method structure */ - EVP_KDF_IMPL *impl; /* Algorithm-specific data */ + EVP_KDF *meth; /* Method structure */ + void *data; /* Algorithm-specific data */ } /* EVP_KDF_CTX */ ; struct evp_keymgmt_st { diff --git a/crypto/evp/kdf_lib.c b/crypto/evp/kdf_lib.c index 6131d8ef77..aa0c5e341f 100644 --- a/crypto/evp/kdf_lib.c +++ b/crypto/evp/kdf_lib.c @@ -15,12 +15,15 @@ #include #include #include +#include +#include #include "internal/asn1_int.h" #include "internal/evp_int.h" #include "internal/numbers.h" +#include "internal/provider.h" #include "evp_locl.h" -EVP_KDF_CTX *EVP_KDF_CTX_new(const EVP_KDF *kdf) +EVP_KDF_CTX *EVP_KDF_CTX_new(EVP_KDF *kdf) { EVP_KDF_CTX *ctx = NULL; @@ -28,8 +31,12 @@ EVP_KDF_CTX *EVP_KDF_CTX_new(const EVP_KDF *kdf) return NULL; ctx = OPENSSL_zalloc(sizeof(EVP_KDF_CTX)); - if (ctx == NULL || (ctx->impl = kdf->new()) == NULL) { + if (ctx == NULL + || (ctx->data = kdf->newctx(ossl_provider_ctx(kdf->prov))) == NULL + || !EVP_KDF_up_ref(kdf)) { EVPerr(EVP_F_EVP_KDF_CTX_NEW, ERR_R_MALLOC_FAILURE); + if (ctx != NULL) + kdf->freectx(ctx->data); OPENSSL_free(ctx); ctx = NULL; } else { @@ -38,16 +45,52 @@ EVP_KDF_CTX *EVP_KDF_CTX_new(const EVP_KDF *kdf) return ctx; } -EVP_KDF_CTX *EVP_KDF_CTX_new_id(int id) +void EVP_KDF_CTX_free(EVP_KDF_CTX *ctx) { - const EVP_KDF *kdf = EVP_get_kdfbynid(id); - - return EVP_KDF_CTX_new(kdf); + if (ctx != NULL) { + ctx->meth->freectx(ctx->data); + ctx->data = NULL; + EVP_KDF_free(ctx->meth); + OPENSSL_free(ctx); + } } -int EVP_KDF_nid(const EVP_KDF *kdf) +EVP_KDF_CTX *EVP_KDF_CTX_dup(const EVP_KDF_CTX *src) { - return kdf->type; + EVP_KDF_CTX *dst; + + if (src->data == NULL || src == NULL || src->meth->dupctx == NULL) + return NULL; + + dst = OPENSSL_malloc(sizeof(*dst)); + if (dst == NULL) { + EVPerr(EVP_F_EVP_KDF_CTX_DUP, ERR_R_MALLOC_FAILURE); + return NULL; + } + + memcpy(dst, src, sizeof(*dst)); + if (!EVP_KDF_up_ref(dst->meth)) { + EVPerr(EVP_F_EVP_KDF_CTX_DUP, ERR_R_MALLOC_FAILURE); + OPENSSL_free(dst); + return NULL; + } + + dst->data = src->meth->dupctx(src->data); + if (dst->data == NULL) { + EVP_KDF_CTX_free(dst); + return NULL; + } + return dst; +} + +const char *EVP_KDF_name(const EVP_KDF *kdf) +{ + return kdf->name; +} + +const OSSL_PROVIDER *EVP_KDF_provider(const EVP_KDF *kdf) +{ + return kdf->prov; } const EVP_KDF *EVP_KDF_CTX_kdf(EVP_KDF_CTX *ctx) @@ -55,75 +98,31 @@ const EVP_KDF *EVP_KDF_CTX_kdf(EVP_KDF_CTX *ctx) return ctx->meth; } -void EVP_KDF_CTX_free(EVP_KDF_CTX *ctx) -{ - if (ctx == NULL) - return; - - ctx->meth->free(ctx->impl); - OPENSSL_free(ctx); -} - void EVP_KDF_reset(EVP_KDF_CTX *ctx) { if (ctx == NULL) return; if (ctx->meth->reset != NULL) - ctx->meth->reset(ctx->impl); -} - -int EVP_KDF_ctrl(EVP_KDF_CTX *ctx, int cmd, ...) -{ - int ret; - va_list args; - - va_start(args, cmd); - ret = EVP_KDF_vctrl(ctx, cmd, args); - va_end(args); - - if (ret == -2) - EVPerr(EVP_F_EVP_KDF_CTRL, EVP_R_COMMAND_NOT_SUPPORTED); - - return ret; -} - -int EVP_KDF_vctrl(EVP_KDF_CTX *ctx, int cmd, va_list args) -{ - if (ctx == NULL) - return 0; - - return ctx->meth->ctrl(ctx->impl, cmd, args); -} - -int EVP_KDF_ctrl_str(EVP_KDF_CTX *ctx, const char *type, const char *value) -{ - int ret; - - if (ctx == NULL) - return 0; - - if (ctx->meth->ctrl_str == NULL) { - EVPerr(EVP_F_EVP_KDF_CTRL_STR, EVP_R_COMMAND_NOT_SUPPORTED); - return -2; - } - - ret = ctx->meth->ctrl_str(ctx->impl, type, value); - if (ret == -2) - EVPerr(EVP_F_EVP_KDF_CTRL_STR, EVP_R_COMMAND_NOT_SUPPORTED); - - return ret; + ctx->meth->reset(ctx->data); } size_t EVP_KDF_size(EVP_KDF_CTX *ctx) { + OSSL_PARAM params[2] = { OSSL_PARAM_END, OSSL_PARAM_END }; + size_t s; + if (ctx == NULL) return 0; - if (ctx->meth->size == NULL) - return SIZE_MAX; - - return ctx->meth->size(ctx->impl); + *params = OSSL_PARAM_construct_size_t(OSSL_KDF_PARAM_SIZE, &s); + if (ctx->meth->get_ctx_params != NULL + && ctx->meth->get_ctx_params(ctx, params)) + return s; + if (ctx->meth->get_params != NULL + && ctx->meth->get_params(params)) + return s; + return 0; } int EVP_KDF_derive(EVP_KDF_CTX *ctx, unsigned char *key, size_t keylen) @@ -131,5 +130,32 @@ int EVP_KDF_derive(EVP_KDF_CTX *ctx, unsigned char *key, size_t keylen) if (ctx == NULL) return 0; - return ctx->meth->derive(ctx->impl, key, keylen); + return ctx->meth->derive(ctx->data, key, keylen); +} + +/* + * The {get,set}_params functions return 1 if there is no corresponding + * function in the implementation. This is the same as if there was one, + * but it didn't recognise any of the given params, i.e. nothing in the + * bag of parameters was useful. + */ +int EVP_KDF_get_params(EVP_KDF *kdf, OSSL_PARAM params[]) +{ + if (kdf->get_params != NULL) + return kdf->get_params(params); + return 1; +} + +int EVP_KDF_CTX_get_params(EVP_KDF_CTX *ctx, OSSL_PARAM params[]) +{ + if (ctx->meth->get_ctx_params != NULL) + return ctx->meth->get_ctx_params(ctx->data, params); + return 1; +} + +int EVP_KDF_CTX_set_params(EVP_KDF_CTX *ctx, const OSSL_PARAM params[]) +{ + if (ctx->meth->set_ctx_params != NULL) + return ctx->meth->set_ctx_params(ctx->data, params); + return 1; } diff --git a/crypto/evp/kdf_meth.c b/crypto/evp/kdf_meth.c new file mode 100644 index 0000000000..f45fa3f74f --- /dev/null +++ b/crypto/evp/kdf_meth.c @@ -0,0 +1,192 @@ +/* + * Copyright 2019 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 +#include +#include +#include +#include +#include "internal/evp_int.h" +#include "internal/provider.h" +#include "evp_locl.h" + +static int evp_kdf_up_ref(void *vkdf) +{ + EVP_KDF *kdf = (EVP_KDF *)vkdf; + int ref = 0; + + CRYPTO_UP_REF(&kdf->refcnt, &ref, kdf->lock); + return 1; +} + +static void evp_kdf_free(void *vkdf){ + EVP_KDF *kdf = (EVP_KDF *)vkdf; + int ref = 0; + + if (kdf != NULL) { + CRYPTO_DOWN_REF(&kdf->refcnt, &ref, kdf->lock); + if (ref <= 0) { + ossl_provider_free(kdf->prov); + OPENSSL_free(kdf->name); + CRYPTO_THREAD_lock_free(kdf->lock); + OPENSSL_free(kdf); + } + } +} + +static void *evp_kdf_new(void) +{ + EVP_KDF *kdf = NULL; + + if ((kdf = OPENSSL_zalloc(sizeof(*kdf))) == NULL + || (kdf->lock = CRYPTO_THREAD_lock_new()) == NULL) { + OPENSSL_free(kdf); + return NULL; + } + kdf->refcnt = 1; + return kdf; +} + +static void *evp_kdf_from_dispatch(const char *name, const OSSL_DISPATCH *fns, + OSSL_PROVIDER *prov, void *method_data) +{ + EVP_KDF *kdf = NULL; + int fnkdfcnt = 0, fnctxcnt = 0; + + if ((kdf = evp_kdf_new()) == NULL + || (kdf->name = OPENSSL_strdup(name)) == NULL) { + evp_kdf_free(kdf); + EVPerr(0, ERR_R_MALLOC_FAILURE); + return NULL; + } + + for (; fns->function_id != 0; fns++) { + switch (fns->function_id) { + case OSSL_FUNC_KDF_NEWCTX: + if (kdf->newctx != NULL) + break; + kdf->newctx = OSSL_get_OP_kdf_newctx(fns); + fnctxcnt++; + break; + case OSSL_FUNC_KDF_DUPCTX: + if (kdf->dupctx != NULL) + break; + kdf->dupctx = OSSL_get_OP_kdf_dupctx(fns); + break; + case OSSL_FUNC_KDF_FREECTX: + if (kdf->freectx != NULL) + break; + kdf->freectx = OSSL_get_OP_kdf_freectx(fns); + fnctxcnt++; + break; + case OSSL_FUNC_KDF_DERIVE: + if (kdf->derive != NULL) + break; + kdf->derive = OSSL_get_OP_kdf_derive(fns); + fnkdfcnt++; + break; + case OSSL_FUNC_KDF_GETTABLE_PARAMS: + if (kdf->gettable_params != NULL) + break; + kdf->gettable_params = + OSSL_get_OP_kdf_gettable_params(fns); + break; + case OSSL_FUNC_KDF_GETTABLE_CTX_PARAMS: + if (kdf->gettable_ctx_params != NULL) + break; + kdf->gettable_ctx_params = + OSSL_get_OP_kdf_gettable_ctx_params(fns); + break; + case OSSL_FUNC_KDF_SETTABLE_CTX_PARAMS: + if (kdf->settable_ctx_params != NULL) + break; + kdf->settable_ctx_params = + OSSL_get_OP_kdf_settable_ctx_params(fns); + break; + case OSSL_FUNC_KDF_GET_PARAMS: + if (kdf->get_params != NULL) + break; + kdf->get_params = OSSL_get_OP_kdf_get_params(fns); + break; + case OSSL_FUNC_KDF_GET_CTX_PARAMS: + if (kdf->get_ctx_params != NULL) + break; + kdf->get_ctx_params = OSSL_get_OP_kdf_get_ctx_params(fns); + break; + case OSSL_FUNC_KDF_SET_CTX_PARAMS: + if (kdf->set_ctx_params != NULL) + break; + kdf->set_ctx_params = OSSL_get_OP_kdf_set_ctx_params(fns); + break; + } + } + if (fnkdfcnt != 1 || fnctxcnt != 2) { + /* + * In order to be a consistent set of functions we must have at least + * a derive function, and a complete set of context management + * functions. + */ + evp_kdf_free(kdf); + ERR_raise(ERR_LIB_EVP, EVP_R_INVALID_PROVIDER_FUNCTIONS); + return NULL; + } + kdf->prov = prov; + if (prov != NULL) + ossl_provider_up_ref(prov); + + return kdf; +} + +EVP_KDF *EVP_KDF_fetch(OPENSSL_CTX *libctx, const char *algorithm, + const char *properties) +{ + return evp_generic_fetch(libctx, OSSL_OP_KDF, algorithm, properties, + evp_kdf_from_dispatch, NULL, evp_kdf_up_ref, + evp_kdf_free); +} + +int EVP_KDF_up_ref(EVP_KDF *kdf) +{ + return evp_kdf_up_ref(kdf); +} + +void EVP_KDF_free(EVP_KDF *kdf) +{ + evp_kdf_free(kdf); +} + +const OSSL_PARAM *EVP_KDF_gettable_params(const EVP_KDF *kdf) +{ + if (kdf->gettable_params == NULL) + return NULL; + return kdf->gettable_params(); +} + +const OSSL_PARAM *EVP_KDF_CTX_gettable_params(const EVP_KDF *kdf) +{ + if (kdf->gettable_ctx_params == NULL) + return NULL; + return kdf->gettable_ctx_params(); +} + +const OSSL_PARAM *EVP_KDF_CTX_settable_params(const EVP_KDF *kdf) +{ + if (kdf->settable_ctx_params == NULL) + return NULL; + return kdf->settable_ctx_params(); +} + +void EVP_KDF_do_all_ex(OPENSSL_CTX *libctx, + void (*fn)(EVP_KDF *kdf, void *arg), + void *arg) +{ + evp_generic_do_all(libctx, OSSL_OP_KDF, + (void (*)(void *, void *))fn, arg, + evp_kdf_from_dispatch, NULL, evp_kdf_free); +} diff --git a/crypto/evp/names.c b/crypto/evp/names.c index 82db98a1f2..7c2f4f061c 100644 --- a/crypto/evp/names.c +++ b/crypto/evp/names.c @@ -56,23 +56,6 @@ int EVP_add_digest(const EVP_MD *md) return r; } -/* TODO(3.0) Is this needed after changing to providers? */ -int EVP_add_kdf(const EVP_KDF *k) -{ - int r; - - if (k == NULL) - return 0; - - r = OBJ_NAME_add(OBJ_nid2sn(k->type), OBJ_NAME_TYPE_KDF_METH, - (const char *)k); - if (r == 0) - return 0; - r = OBJ_NAME_add(OBJ_nid2ln(k->type), OBJ_NAME_TYPE_KDF_METH, - (const char *)k); - return r; -} - const EVP_CIPHER *EVP_get_cipherbyname(const char *name) { const EVP_CIPHER *cp; @@ -95,18 +78,6 @@ const EVP_MD *EVP_get_digestbyname(const char *name) return cp; } -/* TODO(3.0) Is this API needed after implementing providers? */ -const EVP_KDF *EVP_get_kdfbyname(const char *name) -{ - const EVP_KDF *kdf; - - if (!OPENSSL_init_crypto(OPENSSL_INIT_ADD_ALL_KDFS, NULL)) - return NULL; - - kdf = (const EVP_KDF *)OBJ_NAME_get(name, OBJ_NAME_TYPE_KDF_METH); - return kdf; -} - void evp_cleanup_int(void) { OBJ_NAME_cleanup(OBJ_NAME_TYPE_KDF_METH); diff --git a/crypto/include/internal/evp_int.h b/crypto/include/internal/evp_int.h index b86b1d1af0..d54edc78d3 100644 --- a/crypto/include/internal/evp_int.h +++ b/crypto/include/internal/evp_int.h @@ -140,26 +140,23 @@ struct evp_mac_st { OSSL_OP_mac_set_ctx_params_fn *set_ctx_params; }; -/* - * This function is internal for now, but can be made external when needed. - * The documentation would read: - * - * EVP_add_mac() adds the MAC implementation C to the internal - * object database. - */ -int EVP_add_kdf(const EVP_KDF *kdf); - -/* struct evp_kdf_impl_st is defined by the implementation */ -typedef struct evp_kdf_impl_st EVP_KDF_IMPL; struct evp_kdf_st { - int type; - EVP_KDF_IMPL *(*new) (void); - void (*free) (EVP_KDF_IMPL *impl); - void (*reset) (EVP_KDF_IMPL *impl); - int (*ctrl) (EVP_KDF_IMPL *impl, int cmd, va_list args); - int (*ctrl_str) (EVP_KDF_IMPL *impl, const char *type, const char *value); - size_t (*size) (EVP_KDF_IMPL *impl); - int (*derive) (EVP_KDF_IMPL *impl, unsigned char *key, size_t keylen); + OSSL_PROVIDER *prov; + char *name; + CRYPTO_REF_COUNT refcnt; + CRYPTO_RWLOCK *lock; + + OSSL_OP_kdf_newctx_fn *newctx; + OSSL_OP_kdf_dupctx_fn *dupctx; + OSSL_OP_kdf_freectx_fn *freectx; + OSSL_OP_kdf_reset_fn *reset; + OSSL_OP_kdf_derive_fn *derive; + OSSL_OP_kdf_gettable_params_fn *gettable_params; + OSSL_OP_kdf_gettable_ctx_params_fn *gettable_ctx_params; + OSSL_OP_kdf_settable_ctx_params_fn *settable_ctx_params; + OSSL_OP_kdf_get_params_fn *get_params; + OSSL_OP_kdf_get_ctx_params_fn *get_ctx_params; + OSSL_OP_kdf_set_ctx_params_fn *set_ctx_params; }; extern const EVP_KDF pbkdf2_kdf_meth; @@ -553,8 +550,6 @@ struct evp_pkey_st { void openssl_add_all_ciphers_int(void); void openssl_add_all_digests_int(void); -void openssl_add_all_macs_int(void); -void openssl_add_all_kdfs_int(void); void evp_cleanup_int(void); void evp_app_cleanup_int(void); diff --git a/crypto/kdf/build.info b/crypto/kdf/build.info index 4fdaccddec..bc4b31ce91 100644 --- a/crypto/kdf/build.info +++ b/crypto/kdf/build.info @@ -1,4 +1,3 @@ LIBS=../../libcrypto SOURCE[../../libcrypto]=\ - tls1_prf.c kdf_err.c kdf_util.c hkdf.c scrypt.c pbkdf2.c sshkdf.c \ - sskdf.c x942kdf.c + kdf_err.c kdf_util.c diff --git a/crypto/kdf/kdf_local.h b/crypto/kdf/kdf_local.h deleted file mode 100644 index 4956dad920..0000000000 --- a/crypto/kdf/kdf_local.h +++ /dev/null @@ -1,22 +0,0 @@ -/* - * Copyright 2018 The OpenSSL Project Authors. All Rights Reserved. - * Copyright (c) 2018, Oracle and/or its affiliates. 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 - */ - -int call_ctrl(int (*ctrl)(EVP_KDF_IMPL *impl, int cmd, va_list args), - EVP_KDF_IMPL *impl, int cmd, ...); -int kdf_str2ctrl(EVP_KDF_IMPL *impl, - int (*ctrl)(EVP_KDF_IMPL *impl, int cmd, va_list args), - int cmd, const char *str); -int kdf_hex2ctrl(EVP_KDF_IMPL *impl, - int (*ctrl)(EVP_KDF_IMPL *impl, int cmd, va_list args), - int cmd, const char *hex); -int kdf_md2ctrl(EVP_KDF_IMPL *impl, - int (*ctrl)(EVP_KDF_IMPL *impl, int cmd, va_list args), - int cmd, const char *md_name); - diff --git a/crypto/kdf/kdf_util.c b/crypto/kdf/kdf_util.c deleted file mode 100644 index 8eb6d26b34..0000000000 --- a/crypto/kdf/kdf_util.c +++ /dev/null @@ -1,73 +0,0 @@ -/* - * Copyright 2018 The OpenSSL Project Authors. All Rights Reserved. - * Copyright (c) 2018, Oracle and/or its affiliates. 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 -#include -#include -#include -#include "internal/cryptlib.h" -#include "internal/evp_int.h" -#include "internal/numbers.h" -#include "kdf_local.h" - -int call_ctrl(int (*ctrl)(EVP_KDF_IMPL *impl, int cmd, va_list args), - EVP_KDF_IMPL *impl, int cmd, ...) -{ - int ret; - va_list args; - - va_start(args, cmd); - ret = ctrl(impl, cmd, args); - va_end(args); - - return ret; -} - -/* Utility functions to send a string or hex string to a ctrl */ - -int kdf_str2ctrl(EVP_KDF_IMPL *impl, - int (*ctrl)(EVP_KDF_IMPL *impl, int cmd, va_list args), - int cmd, const char *str) -{ - return call_ctrl(ctrl, impl, cmd, (const unsigned char *)str, strlen(str)); -} - -int kdf_hex2ctrl(EVP_KDF_IMPL *impl, - int (*ctrl)(EVP_KDF_IMPL *impl, int cmd, va_list args), - int cmd, const char *hex) -{ - unsigned char *bin; - long binlen; - int ret = -1; - - bin = OPENSSL_hexstr2buf(hex, &binlen); - if (bin == NULL) - return 0; - - if (binlen <= INT_MAX) - ret = call_ctrl(ctrl, impl, cmd, bin, (size_t)binlen); - OPENSSL_free(bin); - return ret; -} - -/* Pass a message digest to a ctrl */ -int kdf_md2ctrl(EVP_KDF_IMPL *impl, - int (*ctrl)(EVP_KDF_IMPL *impl, int cmd, va_list args), - int cmd, const char *md_name) -{ - const EVP_MD *md; - - if (md_name == NULL || (md = EVP_get_digestbyname(md_name)) == NULL) { - KDFerr(KDF_F_KDF_MD2CTRL, KDF_R_INVALID_DIGEST); - return 0; - } - return call_ctrl(ctrl, impl, cmd, md); -} - diff --git a/include/openssl/kdf.h b/include/openssl/kdf.h index 300cf760dc..d76b39e65e 100644 --- a/include/openssl/kdf.h +++ b/include/openssl/kdf.h @@ -13,7 +13,8 @@ # include # include # include -# include +# include + # ifdef __cplusplus extern "C" { # endif @@ -27,23 +28,32 @@ extern "C" { # define EVP_KDF_X963 NID_x963kdf # define EVP_KDF_X942 NID_x942kdf -EVP_KDF_CTX *EVP_KDF_CTX_new_id(int id); -EVP_KDF_CTX *EVP_KDF_CTX_new(const EVP_KDF *kdf); +int EVP_KDF_up_ref(EVP_KDF *kdf); +void EVP_KDF_free(EVP_KDF *kdf); +EVP_KDF *EVP_KDF_fetch(OPENSSL_CTX *libctx, const char *algorithm, + const char *properties); +#define EVP_get_kdfbyname(name) EVP_KDF_fetch(NULL, (name), NULL) + +EVP_KDF_CTX *EVP_KDF_CTX_new(EVP_KDF *kdf); void EVP_KDF_CTX_free(EVP_KDF_CTX *ctx); +EVP_KDF_CTX *EVP_KDF_CTX_dup(const EVP_KDF_CTX *src); +const char *EVP_KDF_name(const EVP_KDF *kdf); +const OSSL_PROVIDER *EVP_KDF_provider(const EVP_KDF *kdf); const EVP_KDF *EVP_KDF_CTX_kdf(EVP_KDF_CTX *ctx); void EVP_KDF_reset(EVP_KDF_CTX *ctx); -int EVP_KDF_ctrl(EVP_KDF_CTX *ctx, int cmd, ...); -int EVP_KDF_vctrl(EVP_KDF_CTX *ctx, int cmd, va_list args); -int EVP_KDF_ctrl_str(EVP_KDF_CTX *ctx, const char *type, const char *value); size_t EVP_KDF_size(EVP_KDF_CTX *ctx); int EVP_KDF_derive(EVP_KDF_CTX *ctx, unsigned char *key, size_t keylen); +int EVP_KDF_get_params(EVP_KDF *kdf, OSSL_PARAM params[]); +int EVP_KDF_CTX_get_params(EVP_KDF_CTX *ctx, OSSL_PARAM params[]); +int EVP_KDF_CTX_set_params(EVP_KDF_CTX *ctx, const OSSL_PARAM params[]); +const OSSL_PARAM *EVP_KDF_gettable_params(const EVP_KDF *kdf); +const OSSL_PARAM *EVP_KDF_CTX_gettable_params(const EVP_KDF *kdf); +const OSSL_PARAM *EVP_KDF_CTX_settable_params(const EVP_KDF *kdf); -int EVP_KDF_nid(const EVP_KDF *kdf); -# define EVP_get_kdfbynid(a) EVP_get_kdfbyname(OBJ_nid2sn(a)) -# define EVP_get_kdfbyobj(a) EVP_get_kdfbynid(OBJ_obj2nid(a)) -# define EVP_KDF_name(o) OBJ_nid2sn(EVP_KDF_nid(o)) -const EVP_KDF *EVP_get_kdfbyname(const char *name); +void EVP_KDF_do_all_ex(OPENSSL_CTX *libctx, + void (*fn)(EVP_KDF *kdf, void *arg), + void *arg); # define EVP_KDF_CTRL_SET_PASS 0x01 /* unsigned char *, size_t */ # define EVP_KDF_CTRL_SET_SALT 0x02 /* unsigned char *, size_t */ @@ -52,23 +62,22 @@ const EVP_KDF *EVP_get_kdfbyname(const char *name); # define EVP_KDF_CTRL_SET_KEY 0x05 /* unsigned char *, size_t */ # define EVP_KDF_CTRL_SET_MAXMEM_BYTES 0x06 /* uint64_t */ # define EVP_KDF_CTRL_SET_TLS_SECRET 0x07 /* unsigned char *, size_t */ -# define EVP_KDF_CTRL_RESET_TLS_SEED 0x08 -# define EVP_KDF_CTRL_ADD_TLS_SEED 0x09 /* unsigned char *, size_t */ -# define EVP_KDF_CTRL_RESET_HKDF_INFO 0x0a -# define EVP_KDF_CTRL_ADD_HKDF_INFO 0x0b /* unsigned char *, size_t */ -# define EVP_KDF_CTRL_SET_HKDF_MODE 0x0c /* int */ -# define EVP_KDF_CTRL_SET_SCRYPT_N 0x0d /* uint64_t */ -# define EVP_KDF_CTRL_SET_SCRYPT_R 0x0e /* uint32_t */ -# define EVP_KDF_CTRL_SET_SCRYPT_P 0x0f /* uint32_t */ -# define EVP_KDF_CTRL_SET_SSHKDF_XCGHASH 0x10 /* unsigned char *, size_t */ -# define EVP_KDF_CTRL_SET_SSHKDF_SESSION_ID 0x11 /* unsigned char *, size_t */ -# define EVP_KDF_CTRL_SET_SSHKDF_TYPE 0x12 /* int */ -# define EVP_KDF_CTRL_SET_MAC 0x13 /* EVP_MAC * */ -# define EVP_KDF_CTRL_SET_MAC_SIZE 0x14 /* size_t */ -# define EVP_KDF_CTRL_SET_SSKDF_INFO 0x15 /* unsigned char *, size_t */ -# define EVP_KDF_CTRL_SET_PBKDF2_PKCS5_MODE 0x16 /* int */ -# define EVP_KDF_CTRL_SET_UKM 0x17 /* unsigned char *, size_t */ -# define EVP_KDF_CTRL_SET_CEK_ALG 0x18 /* char * */ +# define EVP_KDF_CTRL_ADD_TLS_SEED 0x08 /* unsigned char *, size_t */ +# define EVP_KDF_CTRL_RESET_HKDF_INFO 0x09 +# define EVP_KDF_CTRL_ADD_HKDF_INFO 0x0a /* unsigned char *, size_t */ +# define EVP_KDF_CTRL_SET_HKDF_MODE 0x0b /* int */ +# define EVP_KDF_CTRL_SET_SCRYPT_N 0x0c /* uint64_t */ +# define EVP_KDF_CTRL_SET_SCRYPT_R 0x0d /* uint32_t */ +# define EVP_KDF_CTRL_SET_SCRYPT_P 0x0e /* uint32_t */ +# define EVP_KDF_CTRL_SET_SSHKDF_XCGHASH 0x0f /* unsigned char *, size_t */ +# define EVP_KDF_CTRL_SET_SSHKDF_SESSION_ID 0x10 /* unsigned char *, size_t */ +# define EVP_KDF_CTRL_SET_SSHKDF_TYPE 0x11 /* int */ +# define EVP_KDF_CTRL_SET_MAC 0x12 /* EVP_MAC * */ +# define EVP_KDF_CTRL_SET_MAC_SIZE 0x13 /* size_t */ +# define EVP_KDF_CTRL_SET_SSKDF_INFO 0x14 /* unsigned char *, size_t */ +# define EVP_KDF_CTRL_SET_PBKDF2_PKCS5_MODE 0x15 /* int */ +# define EVP_KDF_CTRL_SET_UKM 0x16 /* unsigned char *, size_t */ +# define EVP_KDF_CTRL_SET_CEK_ALG 0x17 /* char * */ # define EVP_KDF_CTRL_SET_SHARED_INFO EVP_KDF_CTRL_SET_SSKDF_INFO # define EVP_KDF_HKDF_MODE_EXTRACT_AND_EXPAND 0