diff --git a/crypto/evp/kdf_lib.c b/crypto/evp/kdf_lib.c index 1093aac29e91d8..fd8b518f05fd45 100644 --- a/crypto/evp/kdf_lib.c +++ b/crypto/evp/kdf_lib.c @@ -144,6 +144,30 @@ int EVP_KDF_derive(EVP_KDF_CTX *ctx, unsigned char *key, size_t keylen, return ctx->meth->derive(ctx->algctx, key, keylen, params); } +int EVP_KDF_derive_SKEY(EVP_KDF_CTX *ctx, EVP_SKEY *skey, + const OSSL_PARAM params[]) +{ + if (ctx == NULL || skey == NULL) + return 0; + + if (ctx->meth->derive_opaque == NULL) { + ERR_raise(ERR_R_EVP_LIB, ERR_R_UNSUPPORTED); + return 0; + } + + if (skey->keymgmt->prov != ctx->meth->prov) { + ERR_raise(ERR_R_EVP_LIB, ERR_R_UNSUPPORTED); + return 0; + } + + if (skey->keydata != NULL) { + ERR_raise(ERR_R_EVP_LIB, ERR_R_UNSUPPORTED); + return 0; + } + + return ctx->meth->derive_opaque(ctx->algctx, &(skey->keydata), params); +} + /* * 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, diff --git a/crypto/evp/kdf_meth.c b/crypto/evp/kdf_meth.c index 5ee36b2b4213ee..b8f1ac146ae955 100644 --- a/crypto/evp/kdf_meth.c +++ b/crypto/evp/kdf_meth.c @@ -137,9 +137,15 @@ static void *evp_kdf_from_algorithm(int name_id, break; kdf->set_ctx_params = OSSL_FUNC_kdf_set_ctx_params(fns); break; + case OSSL_FUNC_KDF_DERIVE_OPAQUE: + if (kdf->derive_opaque != NULL) + break; + kdf->derive_opaque = OSSL_FUNC_kdf_derive_opaque(fns); + fnkdfcnt++; + break; } } - if (fnkdfcnt != 1 || fnctxcnt != 2) { + if (fnkdfcnt == 0 || 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 diff --git a/doc/man3/EVP_KDF.pod b/doc/man3/EVP_KDF.pod index 9447651a340e44..d3af0246633dfc 100644 --- a/doc/man3/EVP_KDF.pod +++ b/doc/man3/EVP_KDF.pod @@ -4,7 +4,7 @@ EVP_KDF, EVP_KDF_fetch, EVP_KDF_free, EVP_KDF_up_ref, EVP_KDF_CTX, EVP_KDF_CTX_new, EVP_KDF_CTX_free, EVP_KDF_CTX_dup, -EVP_KDF_CTX_reset, EVP_KDF_derive, +EVP_KDF_CTX_reset, EVP_KDF_derive, EVP_KDF_derive_SKEY, EVP_KDF_CTX_get_kdf_size, EVP_KDF_get0_provider, EVP_KDF_CTX_kdf, EVP_KDF_is_a, EVP_KDF_get0_name, EVP_KDF_names_do_all, EVP_KDF_get0_description, @@ -28,6 +28,8 @@ EVP_KDF_CTX_gettable_params, EVP_KDF_CTX_settable_params - EVP KDF routines size_t EVP_KDF_CTX_get_kdf_size(EVP_KDF_CTX *ctx); int EVP_KDF_derive(EVP_KDF_CTX *ctx, unsigned char *key, size_t keylen, const OSSL_PARAM params[]); + int EVP_KDF_derive_SKEY(EVP_KDF_CTX *ctx, EVP_SKEY *skey, + const OSSL_PARAM params[]); int EVP_KDF_up_ref(EVP_KDF *kdf); void EVP_KDF_free(EVP_KDF *kdf); EVP_KDF *EVP_KDF_fetch(OSSL_LIB_CTX *libctx, const char *algorithm, @@ -58,10 +60,10 @@ The EVP KDF routines are a high-level interface to Key Derivation Function algorithms and should be used instead of algorithm-specific functions. After creating a B for the required algorithm using -EVP_KDF_CTX_new(), inputs to the algorithm are supplied either by -passing them as part of the EVP_KDF_derive() call or using calls -to EVP_KDF_CTX_set_params() before calling EVP_KDF_derive() to derive -the key. +EVP_KDF_CTX_new(), inputs to the algorithm are supplied either by passing them +as part of the EVP_KDF_derive() or EVP_KDF_derive_SKEY() call or using calls to +EVP_KDF_CTX_set_params() before calling EVP_KDF_derive() or +EVP_KDF_derive_SKEY() to derive the key. =head2 Types @@ -108,6 +110,10 @@ If the algorithm produces a fixed amount of output then an error will occur unless the I parameter is equal to that output size, as returned by EVP_KDF_CTX_get_kdf_size(). +EVP_KDF_derive_SKEY() behaves similar except it accepts an B object +as an output argument. The B object must be the fresh one and have a +keymgmt from the same provider as the ctx has. + EVP_KDF_get_params() retrieves details about the implementation I. The set of parameters given with I determine exactly what @@ -302,6 +308,8 @@ L. This functionality was added in OpenSSL 3.0. +EVP_KDF_derive_SKEY() function was introduced in OpenSSL 3.5. + =head1 COPYRIGHT Copyright 2019-2024 The OpenSSL Project Authors. All Rights Reserved. diff --git a/include/crypto/evp.h b/include/crypto/evp.h index 36dba1e1fa5e68..16d43e434f9d7e 100644 --- a/include/crypto/evp.h +++ b/include/crypto/evp.h @@ -246,6 +246,7 @@ struct evp_kdf_st { OSSL_FUNC_kdf_get_params_fn *get_params; OSSL_FUNC_kdf_get_ctx_params_fn *get_ctx_params; OSSL_FUNC_kdf_set_ctx_params_fn *set_ctx_params; + OSSL_FUNC_kdf_derive_opaque_fn *derive_opaque; }; #define EVP_ORIG_DYNAMIC 0 diff --git a/include/openssl/core_dispatch.h b/include/openssl/core_dispatch.h index f677eb692cc075..7a1a864d355804 100644 --- a/include/openssl/core_dispatch.h +++ b/include/openssl/core_dispatch.h @@ -452,6 +452,7 @@ OSSL_CORE_MAKE_FUNC(int, mac_set_ctx_params, # define OSSL_FUNC_KDF_GET_PARAMS 9 # define OSSL_FUNC_KDF_GET_CTX_PARAMS 10 # define OSSL_FUNC_KDF_SET_CTX_PARAMS 11 +# define OSSL_FUNC_KDF_DERIVE_OPAQUE 12 OSSL_CORE_MAKE_FUNC(void *, kdf_newctx, (void *provctx)) OSSL_CORE_MAKE_FUNC(void *, kdf_dupctx, (void *src)) @@ -469,6 +470,8 @@ OSSL_CORE_MAKE_FUNC(int, kdf_get_ctx_params, (void *kctx, OSSL_PARAM params[])) OSSL_CORE_MAKE_FUNC(int, kdf_set_ctx_params, (void *kctx, const OSSL_PARAM params[])) +OSSL_CORE_MAKE_FUNC(int, kdf_derive_opaque, (void *kctx, void *key, + const OSSL_PARAM params[])) /* RAND */ diff --git a/include/openssl/kdf.h b/include/openssl/kdf.h index 0983230a488afe..0cd2ce06c6e007 100644 --- a/include/openssl/kdf.h +++ b/include/openssl/kdf.h @@ -43,6 +43,8 @@ void EVP_KDF_CTX_reset(EVP_KDF_CTX *ctx); size_t EVP_KDF_CTX_get_kdf_size(EVP_KDF_CTX *ctx); int EVP_KDF_derive(EVP_KDF_CTX *ctx, unsigned char *key, size_t keylen, const OSSL_PARAM params[]); +int EVP_KDF_derive_SKEY(EVP_KDF_CTX *ctx, EVP_SKEY *skey, + const OSSL_PARAM params[]); 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[]); diff --git a/util/libcrypto.num b/util/libcrypto.num index bc38dd0e02bef7..c4c51bc59ecc68 100644 --- a/util/libcrypto.num +++ b/util/libcrypto.num @@ -5757,3 +5757,4 @@ EVP_SKEY_export ? 3_5_0 EXIST::FUNCTION: EVP_SKEY_up_ref ? 3_5_0 EXIST::FUNCTION: EVP_SKEY_free ? 3_5_0 EXIST::FUNCTION: EVP_SKEY_dup ? 3_5_0 EXIST::FUNCTION: +EVP_KDF_derive_SKEY ? 3_5_0 EXIST::FUNCTION: