From: Matt Caswell Date: Mon, 9 Feb 2026 13:25:58 +0000 (+0000) Subject: Add a newdata_ex function which takes params and use it X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=c13e46f2044173a533fd529f09a2f4960c48337c;p=thirdparty%2Fopenssl.git Add a newdata_ex function which takes params and use it The keymgmt->newdata function does not accept params. We introduce a newdata_ex function that does, and we use that instead as a thread local to pass legacy objects to the default provider Reviewed-by: Shane Lontis Reviewed-by: Tomas Mraz MergeDate: Fri Feb 13 07:58:28 2026 (Merged from https://github.com/openssl/openssl/pull/29960) --- diff --git a/crypto/evp/evp_local.h b/crypto/evp/evp_local.h index f8550bdeffe..c8ccd6b6061 100644 --- a/crypto/evp/evp_local.h +++ b/crypto/evp/evp_local.h @@ -104,6 +104,7 @@ struct evp_keymgmt_st { /* Constructor(s), destructor, information */ OSSL_FUNC_keymgmt_new_fn *new; + OSSL_FUNC_keymgmt_new_ex_fn *new_ex; OSSL_FUNC_keymgmt_free_fn *free; OSSL_FUNC_keymgmt_get_params_fn *get_params; OSSL_FUNC_keymgmt_gettable_params_fn *gettable_params; diff --git a/crypto/evp/exchange.c b/crypto/evp/exchange.c index bd1b8f6d3e8..567ce21e9a1 100644 --- a/crypto/evp/exchange.c +++ b/crypto/evp/exchange.c @@ -243,7 +243,7 @@ int EVP_PKEY_derive_init_ex(EVP_PKEY_CTX *ctx, const OSSL_PARAM params[]) if (pkey == NULL || !EVP_PKEY_set_type_by_keymgmt(pkey, ctx->keymgmt) - || (pkey->keydata = evp_keymgmt_newdata(ctx->keymgmt)) == NULL) { + || (pkey->keydata = evp_keymgmt_newdata(ctx->keymgmt, NULL)) == NULL) { ERR_clear_last_mark(); EVP_PKEY_free(pkey); ERR_raise(ERR_LIB_EVP, EVP_R_INITIALIZATION_ERROR); diff --git a/crypto/evp/keymgmt_lib.c b/crypto/evp/keymgmt_lib.c index c4b08c0ed68..87ccae0c434 100644 --- a/crypto/evp/keymgmt_lib.c +++ b/crypto/evp/keymgmt_lib.c @@ -33,7 +33,7 @@ int evp_keymgmt_util_try_import(const OSSL_PARAM params[], void *arg) /* Just in time creation of keydata */ if (data->keydata == NULL) { - if ((data->keydata = evp_keymgmt_newdata(data->keymgmt)) == NULL) { + if ((data->keydata = evp_keymgmt_newdata(data->keymgmt, NULL)) == NULL) { ERR_raise(ERR_LIB_EVP, ERR_R_EVP_LIB); return 0; } @@ -320,7 +320,7 @@ void *evp_keymgmt_util_fromdata(EVP_PKEY *target, EVP_KEYMGMT *keymgmt, { void *keydata = NULL; - if ((keydata = evp_keymgmt_newdata(keymgmt)) == NULL + if ((keydata = evp_keymgmt_newdata(keymgmt, NULL)) == NULL || !evp_keymgmt_import(keymgmt, keydata, selection, params) || !evp_keymgmt_util_assign_pkey(target, keymgmt, keydata)) { evp_keymgmt_freedata(keymgmt, keydata); diff --git a/crypto/evp/keymgmt_meth.c b/crypto/evp/keymgmt_meth.c index b57e817e510..132334f151f 100644 --- a/crypto/evp/keymgmt_meth.c +++ b/crypto/evp/keymgmt_meth.c @@ -88,6 +88,10 @@ static void *keymgmt_from_algorithm(int name_id, if (keymgmt->new == NULL) keymgmt->new = OSSL_FUNC_keymgmt_new(fns); break; + case OSSL_FUNC_KEYMGMT_NEW_EX: + if (keymgmt->new_ex == NULL) + keymgmt->new_ex = OSSL_FUNC_keymgmt_new_ex(fns); + break; case OSSL_FUNC_KEYMGMT_GEN_INIT: if (keymgmt->gen_init == NULL) keymgmt->gen_init = OSSL_FUNC_keymgmt_gen_init(fns); @@ -236,6 +240,7 @@ static void *keymgmt_from_algorithm(int name_id, */ if (keymgmt->free == NULL || (keymgmt->new == NULL + && keymgmt->new_ex == NULL && keymgmt->gen == NULL && keymgmt->load == NULL) || keymgmt->has == NULL @@ -365,18 +370,20 @@ int EVP_KEYMGMT_names_do_all(const EVP_KEYMGMT *keymgmt, /* * Internal API that interfaces with the method function pointers */ -void *evp_keymgmt_newdata(const EVP_KEYMGMT *keymgmt) +void *evp_keymgmt_newdata(const EVP_KEYMGMT *keymgmt, const OSSL_PARAM params[]) { void *provctx = ossl_provider_ctx(EVP_KEYMGMT_get0_provider(keymgmt)); /* - * 'new' is currently mandatory on its own, but when new - * constructors appear, it won't be quite as mandatory, - * so we have a check for future cases. + * Some providers may have a new_ex which accepts parameters. Otherwise we + * fall back to the old "new" which doesn't accept params. */ - if (keymgmt->new == NULL) - return NULL; - return keymgmt->new(provctx); + if (keymgmt->new_ex == NULL) { + if (keymgmt->new == NULL) + return NULL; + return keymgmt->new(provctx); + } + return keymgmt->new_ex(provctx, params); } void evp_keymgmt_freedata(const EVP_KEYMGMT *keymgmt, void *keydata) diff --git a/crypto/evp/p_lib.c b/crypto/evp/p_lib.c index b91094504b8..b294cbc0e64 100644 --- a/crypto/evp/p_lib.c +++ b/crypto/evp/p_lib.c @@ -31,6 +31,7 @@ #include #include #include +#include #include "internal/numbers.h" /* includes SIZE_MAX */ #include "internal/ffc.h" @@ -46,7 +47,6 @@ #endif #include "internal/provider.h" #include "internal/common.h" -#include "internal/threads_common.h" #include "evp_local.h" static int pkey_set_type(EVP_PKEY *pkey, int type, const char *str, @@ -1860,6 +1860,8 @@ void *evp_pkey_export_to_provider(EVP_PKEY *pk, OSSL_LIB_CTX *libctx, #ifndef FIPS_MODULE if (pk->pkey.ptr != NULL) { OP_CACHE_ELEM *op; + OSSL_PARAM params[2] = { OSSL_PARAM_END, OSSL_PARAM_END }; + OSSL_PARAM *p = NULL; /* * If the legacy "origin" hasn't changed since last time, we try @@ -1898,15 +1900,20 @@ void *evp_pkey_export_to_provider(EVP_PKEY *pk, OSSL_LIB_CTX *libctx, if (!EVP_KEYMGMT_is_a(tmp_keymgmt, OBJ_nid2sn(pk->type))) goto end; - /* We attempt to pass the low-level object to the keymgmt via a thread - * local. This will actually only succeed in the case that we are using - * the default provider. Otherwise it will export in the normal way. - */ - if (!CRYPTO_THREAD_set_local_ex(CRYPTO_THREAD_LOCAL_LOW_LEVEL_OBJECT, libctx, pk->pkey.ptr)) - goto end; - keydata = evp_keymgmt_newdata(tmp_keymgmt); - if (!CRYPTO_THREAD_set_local_ex(CRYPTO_THREAD_LOCAL_LOW_LEVEL_OBJECT, libctx, NULL)) - goto end; + if (strcmp(OSSL_PROVIDER_get0_name(EVP_KEYMGMT_get0_provider(tmp_keymgmt)), "default") == 0) { + /* + * We attempt to pass the low-level object to the keymgmt. We only + * support this via an internal use only parameter. We break the + * normal rules that prevent passing complex objects via OSSL_PARAM, + * but this is only for the default provider where we can get away + * with this. This is necessary here for backwards compatibility + * reasons. + */ + params[0] = OSSL_PARAM_construct_octet_ptr("legacy-object", + &pk->pkey.ptr, sizeof(pk->pkey.ptr)); + p = params; + } + keydata = evp_keymgmt_newdata(tmp_keymgmt, p); if (keydata == NULL) goto end; @@ -1914,7 +1921,8 @@ void *evp_pkey_export_to_provider(EVP_PKEY *pk, OSSL_LIB_CTX *libctx, * We skip the export if the key data we got back is actually the same * as the low level object we passed in */ - if (keydata != pk->pkey.ptr && !pk->ameth->export_to(pk, keydata, tmp_keymgmt->import, libctx, propquery)) { + if (keydata != pk->pkey.ptr + && !pk->ameth->export_to(pk, keydata, tmp_keymgmt->import, libctx, propquery)) { evp_keymgmt_freedata(tmp_keymgmt, keydata); keydata = NULL; goto end; diff --git a/doc/internal/man3/evp_keymgmt_newdata.pod b/doc/internal/man3/evp_keymgmt_newdata.pod index 9b3f2c55f16..b5815cc5cb5 100644 --- a/doc/internal/man3/evp_keymgmt_newdata.pod +++ b/doc/internal/man3/evp_keymgmt_newdata.pod @@ -13,7 +13,7 @@ evp_keymgmt_export, evp_keymgmt_export_types #include "crypto/evp.h" - void *evp_keymgmt_newdata(const EVP_KEYMGMT *keymgmt); + void *evp_keymgmt_newdata(const EVP_KEYMGMT *keymgmt, const OSSL_PARAM params[]); void evp_keymgmt_freedata(const EVP_KEYMGMT *keymgmt, void *keyddata); int evp_keymgmt_get_params(const EVP_KEYMGMT *keymgmt, void *keydata, OSSL_PARAM params[]); @@ -39,7 +39,8 @@ first argument, which they also retrieve a provider context from when needed. The rest of the arguments are simply passed on to the function they wrap around. -evp_keymgmt_newdata() calls the method's new() function. +evp_keymgmt_newdata() calls the method's new() function or new_ex() if there is +one. evp_keymgmt_freedata() calls the method's free() function. diff --git a/doc/man7/provider-keymgmt.pod b/doc/man7/provider-keymgmt.pod index 237ea87a7fe..d3ae611222c 100644 --- a/doc/man7/provider-keymgmt.pod +++ b/doc/man7/provider-keymgmt.pod @@ -16,6 +16,7 @@ provider-keymgmt - The KEYMGMT library E-E provider functions /* Key object (keydata) creation and destruction */ void *OSSL_FUNC_keymgmt_new(void *provctx); + void *OSSL_FUNC_keymgmt_new_ex(void *provctx, const OSSL_PARAM params[]); void OSSL_FUNC_keymgmt_free(void *keydata); /* Generation, a more complex constructor */ @@ -219,7 +220,9 @@ since a match of one half implies a match of the other half. OSSL_FUNC_keymgmt_new() should create a provider side key object. The provider context I is passed and may be incorporated in the -key object, but that is not mandatory. +key object, but that is not mandatory. OSSL_FUNC_keymgmt_new_ex() may optionally +be defined and does the same as OSSL_FUNC_keymgmt_new(), but also accepts an +array of parameters. Currently no parameters are defined for this function. OSSL_FUNC_keymgmt_free() should free the passed I. diff --git a/include/crypto/evp.h b/include/crypto/evp.h index 021fac3df11..92eb37e5525 100644 --- a/include/crypto/evp.h +++ b/include/crypto/evp.h @@ -555,7 +555,7 @@ const char *evp_keymgmt_util_query_operation_name(EVP_KEYMGMT *keymgmt, /* * KEYMGMT provider interface functions */ -void *evp_keymgmt_newdata(const EVP_KEYMGMT *keymgmt); +void *evp_keymgmt_newdata(const EVP_KEYMGMT *keymgmt, const OSSL_PARAM params[]); void evp_keymgmt_freedata(const EVP_KEYMGMT *keymgmt, void *keyddata); int evp_keymgmt_get_params(const EVP_KEYMGMT *keymgmt, void *keydata, OSSL_PARAM params[]); diff --git a/include/internal/threads_common.h b/include/internal/threads_common.h index 6c9a5c271d2..660fb1e5c65 100644 --- a/include/internal/threads_common.h +++ b/include/internal/threads_common.h @@ -20,7 +20,6 @@ typedef enum { CRYPTO_THREAD_LOCAL_TEVENT_KEY, CRYPTO_THREAD_LOCAL_TANDEM_ID_KEY, CRYPTO_THREAD_LOCAL_FIPS_DEFERRED_KEY, - CRYPTO_THREAD_LOCAL_LOW_LEVEL_OBJECT, CRYPTO_THREAD_LOCAL_KEY_MAX } CRYPTO_THREAD_LOCAL_KEY_ID; diff --git a/include/openssl/core_dispatch.h b/include/openssl/core_dispatch.h index 63383d91957..b1372c86ce5 100644 --- a/include/openssl/core_dispatch.h +++ b/include/openssl/core_dispatch.h @@ -663,6 +663,8 @@ OSSL_CORE_MAKE_FUNC(void, rand_clear_seed, /* Basic key object creation */ #define OSSL_FUNC_KEYMGMT_NEW 1 OSSL_CORE_MAKE_FUNC(void *, keymgmt_new, (void *provctx)) +#define OSSL_FUNC_KEYMGMT_NEW_EX 17 +OSSL_CORE_MAKE_FUNC(void *, keymgmt_new_ex, (void *provctx, const OSSL_PARAM params[])) /* Generation, a more complex constructor */ #define OSSL_FUNC_KEYMGMT_GEN_INIT 2 diff --git a/providers/implementations/keymgmt/dh_kmgmt.c b/providers/implementations/keymgmt/dh_kmgmt.c index df42a7d1408..01accaea381 100644 --- a/providers/implementations/keymgmt/dh_kmgmt.c +++ b/providers/implementations/keymgmt/dh_kmgmt.c @@ -27,10 +27,12 @@ #include "crypto/dh.h" #include "internal/fips.h" #include "internal/sizes.h" -#include "internal/threads_common.h" #include "internal/cryptlib.h" static OSSL_FUNC_keymgmt_new_fn dh_newdata; +static OSSL_FUNC_keymgmt_new_ex_fn dh_newdata_ex; +static OSSL_FUNC_keymgmt_new_fn dhx_newdata; +static OSSL_FUNC_keymgmt_new_ex_fn dhx_newdata_ex; static OSSL_FUNC_keymgmt_free_fn dh_freedata; static OSSL_FUNC_keymgmt_gen_init_fn dh_gen_init; static OSSL_FUNC_keymgmt_gen_init_fn dhx_gen_init; @@ -106,16 +108,22 @@ static int dh_gen_type_name2id_w_default(const char *name, int type) * the EVP_PKEY, then we get hold of that object here. We return 0 if we hit * a fatal error or 1 otherwise. We may return 1 but with *dh set to NULL. */ -static int get_legacy_dh_object(OSSL_LIB_CTX *libctx, DH **dh) +static int get_legacy_dh_object(OSSL_LIB_CTX *libctx, DH **dh, const OSSL_PARAM params[]) { #ifndef FIPS_MODULE + const OSSL_PARAM *p; + + if (params == NULL) + return 1; + p = OSSL_PARAM_locate_const(params, "legacy-object"); + if (p == NULL) + return 1; /* * This only works because we are in the default provider. We are not * normally allowed to pass complex objects across the provider boundary * like this. */ - *dh = CRYPTO_THREAD_get_local_ex(CRYPTO_THREAD_LOCAL_LOW_LEVEL_OBJECT, libctx); - if (*dh != NULL) { + if (OSSL_PARAM_get_octet_ptr(p, (const void **)dh, NULL) && *dh != NULL) { if (ossl_lib_ctx_get_concrete(ossl_dh_get0_libctx(*dh)) != ossl_lib_ctx_get_concrete(libctx)) { *dh = NULL; return 1; @@ -128,14 +136,14 @@ static int get_legacy_dh_object(OSSL_LIB_CTX *libctx, DH **dh) return 1; } -static void *dh_newdata(void *provctx) +static void *dh_newdata_ex(void *provctx, const OSSL_PARAM params[]) { DH *dh = NULL; if (!ossl_prov_is_running()) return NULL; - if (!get_legacy_dh_object(PROV_LIBCTX_OF(provctx), &dh)) + if (!get_legacy_dh_object(PROV_LIBCTX_OF(provctx), &dh, params)) return NULL; if (dh == NULL) { @@ -149,14 +157,19 @@ static void *dh_newdata(void *provctx) return dh; } -static void *dhx_newdata(void *provctx) +static void *dh_newdata(void *provctx) +{ + return dh_newdata_ex(provctx, NULL); +} + +static void *dhx_newdata_ex(void *provctx, const OSSL_PARAM params[]) { DH *dh = NULL; if (!ossl_prov_is_running()) return NULL; - if (!get_legacy_dh_object(PROV_LIBCTX_OF(provctx), &dh)) + if (!get_legacy_dh_object(PROV_LIBCTX_OF(provctx), &dh, params)) return NULL; if (dh == NULL) { @@ -170,6 +183,11 @@ static void *dhx_newdata(void *provctx) return dh; } +static void *dhx_newdata(void *provctx) +{ + return dhx_newdata_ex(provctx, NULL); +} + static void dh_freedata(void *keydata) { DH_free(keydata); @@ -881,6 +899,7 @@ static void *dh_dup(const void *keydata_from, int selection) const OSSL_DISPATCH ossl_dh_keymgmt_functions[] = { { OSSL_FUNC_KEYMGMT_NEW, (void (*)(void))dh_newdata }, + { OSSL_FUNC_KEYMGMT_NEW_EX, (void (*)(void))dh_newdata_ex }, { OSSL_FUNC_KEYMGMT_GEN_INIT, (void (*)(void))dh_gen_init }, { OSSL_FUNC_KEYMGMT_GEN_SET_TEMPLATE, (void (*)(void))dh_gen_set_template }, { OSSL_FUNC_KEYMGMT_GEN_SET_PARAMS, (void (*)(void))dh_gen_set_params }, @@ -913,6 +932,7 @@ static const char *dhx_query_operation_name(int operation_id) const OSSL_DISPATCH ossl_dhx_keymgmt_functions[] = { { OSSL_FUNC_KEYMGMT_NEW, (void (*)(void))dhx_newdata }, + { OSSL_FUNC_KEYMGMT_NEW_EX, (void (*)(void))dhx_newdata_ex }, { OSSL_FUNC_KEYMGMT_GEN_INIT, (void (*)(void))dhx_gen_init }, { OSSL_FUNC_KEYMGMT_GEN_SET_TEMPLATE, (void (*)(void))dh_gen_set_template }, { OSSL_FUNC_KEYMGMT_GEN_SET_PARAMS, (void (*)(void))dhx_gen_set_params }, diff --git a/providers/implementations/keymgmt/dsa_kmgmt.c b/providers/implementations/keymgmt/dsa_kmgmt.c index d2d4abf105a..2b00ecc2e42 100644 --- a/providers/implementations/keymgmt/dsa_kmgmt.c +++ b/providers/implementations/keymgmt/dsa_kmgmt.c @@ -26,9 +26,9 @@ #include "internal/sizes.h" #include "internal/nelem.h" #include "internal/param_build_set.h" -#include "internal/threads_common.h" static OSSL_FUNC_keymgmt_new_fn dsa_newdata; +static OSSL_FUNC_keymgmt_new_ex_fn dsa_newdata_ex; static OSSL_FUNC_keymgmt_free_fn dsa_freedata; static OSSL_FUNC_keymgmt_gen_init_fn dsa_gen_init; static OSSL_FUNC_keymgmt_gen_set_template_fn dsa_gen_set_template; @@ -120,7 +120,7 @@ static int dsa_key_todata(DSA *dsa, OSSL_PARAM_BLD *bld, OSSL_PARAM *pubkey, return 1; } -static void *dsa_newdata(void *provctx) +static void *dsa_newdata_ex(void *provctx, const OSSL_PARAM params[]) { DSA *dsa = NULL; OSSL_LIB_CTX *libctx = PROV_LIBCTX_OF(provctx); @@ -129,20 +129,22 @@ static void *dsa_newdata(void *provctx) return NULL; #ifndef FIPS_MODULE + const OSSL_PARAM *p = NULL; + + if (params != NULL) + p = OSSL_PARAM_locate_const(params, "legacy-object"); + /* * This only works because we are in the default provider. We are not * normally allowed to pass complex objects across the provider boundary * like this. */ - dsa = CRYPTO_THREAD_get_local_ex(CRYPTO_THREAD_LOCAL_LOW_LEVEL_OBJECT, libctx); - if (dsa != NULL) { + if (p != NULL && OSSL_PARAM_get_octet_ptr(p, (const void **)&dsa, NULL) && dsa != NULL) { if (ossl_lib_ctx_get_concrete(ossl_dsa_get0_libctx(dsa)) != ossl_lib_ctx_get_concrete(libctx)) dsa = NULL; else if (!DSA_up_ref(dsa)) return NULL; } - if (dsa != NULL && !DSA_up_ref(dsa)) - return NULL; #endif if (dsa == NULL) @@ -151,6 +153,11 @@ static void *dsa_newdata(void *provctx) return dsa; } +static void *dsa_newdata(void *provctx) +{ + return dsa_newdata_ex(provctx, NULL); +} + static void dsa_freedata(void *keydata) { DSA_free(keydata); @@ -732,6 +739,7 @@ static void *dsa_dup(const void *keydata_from, int selection) const OSSL_DISPATCH ossl_dsa_keymgmt_functions[] = { { OSSL_FUNC_KEYMGMT_NEW, (void (*)(void))dsa_newdata }, + { OSSL_FUNC_KEYMGMT_NEW_EX, (void (*)(void))dsa_newdata_ex }, { OSSL_FUNC_KEYMGMT_GEN_INIT, (void (*)(void))dsa_gen_init }, { OSSL_FUNC_KEYMGMT_GEN_SET_TEMPLATE, (void (*)(void))dsa_gen_set_template }, { OSSL_FUNC_KEYMGMT_GEN_SET_PARAMS, (void (*)(void))dsa_gen_set_params }, diff --git a/providers/implementations/keymgmt/ec_kmgmt.c b/providers/implementations/keymgmt/ec_kmgmt.c index 8fda3899976..2768bc8e00c 100644 --- a/providers/implementations/keymgmt/ec_kmgmt.c +++ b/providers/implementations/keymgmt/ec_kmgmt.c @@ -29,7 +29,6 @@ #include "prov/securitycheck.h" #include "internal/fips.h" #include "internal/param_build_set.h" -#include "internal/threads_common.h" #ifndef FIPS_MODULE #ifndef OPENSSL_NO_SM2 @@ -38,6 +37,7 @@ #endif static OSSL_FUNC_keymgmt_new_fn ec_newdata; +static OSSL_FUNC_keymgmt_new_ex_fn ec_newdata_ex; static OSSL_FUNC_keymgmt_gen_init_fn ec_gen_init; static OSSL_FUNC_keymgmt_gen_set_template_fn ec_gen_set_template; static OSSL_FUNC_keymgmt_gen_set_params_fn ec_gen_set_params; @@ -275,7 +275,7 @@ static ossl_inline int otherparams_to_params(const EC_KEY *ec, OSSL_PARAM_BLD *t ecdh_cofactor_mode); } -static void *ec_newdata(void *provctx) +static void *ec_newdata_ex(void *provctx, const OSSL_PARAM params[]) { EC_KEY *eckey = NULL; OSSL_LIB_CTX *libctx = PROV_LIBCTX_OF(provctx); @@ -284,13 +284,17 @@ static void *ec_newdata(void *provctx) return NULL; #ifndef FIPS_MODULE + const OSSL_PARAM *p = NULL; + + if (params != NULL) + p = OSSL_PARAM_locate_const(params, "legacy-object"); + /* * This only works because we are in the default provider. We are not * normally allowed to pass complex objects across the provider boundary * like this. */ - eckey = CRYPTO_THREAD_get_local_ex(CRYPTO_THREAD_LOCAL_LOW_LEVEL_OBJECT, libctx); - if (eckey != NULL) { + if (p != NULL && OSSL_PARAM_get_octet_ptr(p, (const void **)&eckey, NULL) && eckey != NULL) { #ifdef OPENSSL_NO_EC_EXPLICIT_CURVES if (EC_GROUP_check_named_curve(EC_KEY_get0_group(eckey), 0, NULL) == NID_undef) return NULL; @@ -308,6 +312,11 @@ static void *ec_newdata(void *provctx) return eckey; } +static void *ec_newdata(void *provctx) +{ + return ec_newdata_ex(provctx, NULL); +} + #ifndef FIPS_MODULE #ifndef OPENSSL_NO_SM2 static void *sm2_newdata(void *provctx) @@ -1440,6 +1449,7 @@ static void *ec_dup(const void *keydata_from, int selection) const OSSL_DISPATCH ossl_ec_keymgmt_functions[] = { { OSSL_FUNC_KEYMGMT_NEW, (void (*)(void))ec_newdata }, + { OSSL_FUNC_KEYMGMT_NEW_EX, (void (*)(void))ec_newdata_ex }, { OSSL_FUNC_KEYMGMT_GEN_INIT, (void (*)(void))ec_gen_init }, { OSSL_FUNC_KEYMGMT_GEN_SET_TEMPLATE, (void (*)(void))ec_gen_set_template }, diff --git a/providers/implementations/keymgmt/rsa_kmgmt.c b/providers/implementations/keymgmt/rsa_kmgmt.c index 2d768823b84..28c33d42570 100644 --- a/providers/implementations/keymgmt/rsa_kmgmt.c +++ b/providers/implementations/keymgmt/rsa_kmgmt.c @@ -27,10 +27,11 @@ #include "crypto/cryptlib.h" #include "internal/fips.h" #include "internal/param_build_set.h" -#include "internal/threads_common.h" static OSSL_FUNC_keymgmt_new_fn rsa_newdata; +static OSSL_FUNC_keymgmt_new_ex_fn rsa_newdata_ex; static OSSL_FUNC_keymgmt_new_fn rsapss_newdata; +static OSSL_FUNC_keymgmt_new_ex_fn rsapss_newdata_ex; static OSSL_FUNC_keymgmt_gen_init_fn rsa_gen_init; static OSSL_FUNC_keymgmt_gen_init_fn rsapss_gen_init; static OSSL_FUNC_keymgmt_gen_set_params_fn rsa_gen_set_params; @@ -81,16 +82,22 @@ static int pss_params_fromdata(RSA_PSS_PARAMS_30 *pss_params, int *defaults_set, * the EVP_PKEY, then we get hold of that object here. We return 0 if we hit * a fatal error or 1 otherwise. We may return 1 but with *rsa set to NULL. */ -static int get_legacy_rsa_object(OSSL_LIB_CTX *libctx, RSA **rsa) +static int get_legacy_rsa_object(OSSL_LIB_CTX *libctx, RSA **rsa, const OSSL_PARAM params[]) { #ifndef FIPS_MODULE + const OSSL_PARAM *p; + + if (params == NULL) + return 1; + p = OSSL_PARAM_locate_const(params, "legacy-object"); + if (p == NULL) + return 1; /* * This only works because we are in the default provider. We are not * normally allowed to pass complex objects across the provider boundary * like this. */ - *rsa = CRYPTO_THREAD_get_local_ex(CRYPTO_THREAD_LOCAL_LOW_LEVEL_OBJECT, libctx); - if (*rsa != NULL) { + if (OSSL_PARAM_get_octet_ptr(p, (const void **)rsa, NULL) && *rsa != NULL) { if (ossl_lib_ctx_get_concrete(ossl_rsa_get0_libctx(*rsa)) != ossl_lib_ctx_get_concrete(libctx)) { *rsa = NULL; return 1; @@ -103,7 +110,7 @@ static int get_legacy_rsa_object(OSSL_LIB_CTX *libctx, RSA **rsa) return 1; } -static void *rsa_newdata(void *provctx) +static void *rsa_newdata_ex(void *provctx, const OSSL_PARAM params[]) { OSSL_LIB_CTX *libctx = PROV_LIBCTX_OF(provctx); RSA *rsa = NULL; @@ -111,7 +118,7 @@ static void *rsa_newdata(void *provctx) if (!ossl_prov_is_running()) return NULL; - if (!get_legacy_rsa_object(libctx, &rsa)) + if (!get_legacy_rsa_object(libctx, &rsa, params)) return NULL; if (rsa == NULL) { @@ -125,7 +132,12 @@ static void *rsa_newdata(void *provctx) return rsa; } -static void *rsapss_newdata(void *provctx) +static void *rsa_newdata(void *provctx) +{ + return rsa_newdata_ex(provctx, NULL); +} + +static void *rsapss_newdata_ex(void *provctx, const OSSL_PARAM params[]) { OSSL_LIB_CTX *libctx = PROV_LIBCTX_OF(provctx); RSA *rsa = NULL; @@ -133,7 +145,7 @@ static void *rsapss_newdata(void *provctx) if (!ossl_prov_is_running()) return NULL; - if (!get_legacy_rsa_object(libctx, &rsa)) + if (!get_legacy_rsa_object(libctx, &rsa, params)) return NULL; if (rsa == NULL) { @@ -147,6 +159,11 @@ static void *rsapss_newdata(void *provctx) return rsa; } +static void *rsapss_newdata(void *provctx) +{ + return rsapss_newdata_ex(provctx, NULL); +} + static void rsa_freedata(void *keydata) { RSA_free(keydata); @@ -756,6 +773,7 @@ static const char *rsa_query_operation_name(int operation_id) const OSSL_DISPATCH ossl_rsa_keymgmt_functions[] = { { OSSL_FUNC_KEYMGMT_NEW, (void (*)(void))rsa_newdata }, + { OSSL_FUNC_KEYMGMT_NEW_EX, (void (*)(void))rsa_newdata_ex }, { OSSL_FUNC_KEYMGMT_GEN_INIT, (void (*)(void))rsa_gen_init }, { OSSL_FUNC_KEYMGMT_GEN_SET_PARAMS, (void (*)(void))rsa_gen_set_params }, @@ -780,6 +798,7 @@ const OSSL_DISPATCH ossl_rsa_keymgmt_functions[] = { const OSSL_DISPATCH ossl_rsapss_keymgmt_functions[] = { { OSSL_FUNC_KEYMGMT_NEW, (void (*)(void))rsapss_newdata }, + { OSSL_FUNC_KEYMGMT_NEW_EX, (void (*)(void))rsapss_newdata_ex }, { OSSL_FUNC_KEYMGMT_GEN_INIT, (void (*)(void))rsapss_gen_init }, { OSSL_FUNC_KEYMGMT_GEN_SET_PARAMS, (void (*)(void))rsa_gen_set_params }, { OSSL_FUNC_KEYMGMT_GEN_SETTABLE_PARAMS,