]> git.ipfire.org Git - thirdparty/openssl.git/commitdiff
Add a newdata_ex function which takes params and use it
authorMatt Caswell <matt@openssl.org>
Mon, 9 Feb 2026 13:25:58 +0000 (13:25 +0000)
committerTomas Mraz <tomas@openssl.org>
Fri, 13 Feb 2026 07:58:13 +0000 (08:58 +0100)
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 <shane.lontis@oracle.com>
Reviewed-by: Tomas Mraz <tomas@openssl.org>
MergeDate: Fri Feb 13 07:58:28 2026
(Merged from https://github.com/openssl/openssl/pull/29960)

14 files changed:
crypto/evp/evp_local.h
crypto/evp/exchange.c
crypto/evp/keymgmt_lib.c
crypto/evp/keymgmt_meth.c
crypto/evp/p_lib.c
doc/internal/man3/evp_keymgmt_newdata.pod
doc/man7/provider-keymgmt.pod
include/crypto/evp.h
include/internal/threads_common.h
include/openssl/core_dispatch.h
providers/implementations/keymgmt/dh_kmgmt.c
providers/implementations/keymgmt/dsa_kmgmt.c
providers/implementations/keymgmt/ec_kmgmt.c
providers/implementations/keymgmt/rsa_kmgmt.c

index f8550bdeffe5465d318d673f12c34146ebc2dde9..c8ccd6b60613bd716aceee53c7707417f730b7b4 100644 (file)
@@ -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;
index bd1b8f6d3e8ce86fcdd7b4d6cb5d74503a26c3c4..567ce21e9a1338c464d77e4b78ed95fff616fb5b 100644 (file)
@@ -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);
index c4b08c0ed682fce35ad61e8f6e5bee7243523049..87ccae0c43422ec8f949c067b0683ace5c94c912 100644 (file)
@@ -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);
index b57e817e51000a60a07b38062698252bc2592af4..132334f151fccbc9e8491174002e83a7a0113576 100644 (file)
@@ -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)
index b91094504b8a9f85a19a0d5793dafb04ae9d9439..b294cbc0e64761c26db4df3e05b6ffa754106bb9 100644 (file)
@@ -31,6 +31,7 @@
 #include <openssl/param_build.h>
 #include <openssl/encoder.h>
 #include <openssl/core_names.h>
+#include <openssl/provider.h>
 
 #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;
index 9b3f2c55f160d2a55da43aa890a626ca19475dd1..b5815cc5cb55c606b7f3b19d92daa46c69b82eb1 100644 (file)
@@ -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.
 
index 237ea87a7fecbceb45b757dafbd4dbe8ec6a4619..d3ae611222c612881da7418509a8586555264f80 100644 (file)
@@ -16,6 +16,7 @@ provider-keymgmt - The KEYMGMT library E<lt>-E<gt> 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<provctx> 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<keydata>.
 
index 021fac3df118b21e9af971a5aaed43d435c08bff..92eb37e55259f9d8a36fd9a6308ecdbf2ba24686 100644 (file)
@@ -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[]);
index 6c9a5c271d29f69dc9d6561ea30f775273945b8d..660fb1e5c65fbb9111663f0680cf420c09fa0cee 100644 (file)
@@ -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;
 
index 63383d919578552d3b02400faf9eb46c97e1ff68..b1372c86ce52397a949310729268d36dbb7b8856 100644 (file)
@@ -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
index df42a7d1408ef52878b1a950e050a27841ac16f2..01accaea3819b7b715763a55a88fb38bae1dba1f 100644 (file)
 #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 },
index d2d4abf105ab5ff7b9d672fdf3f2aef697050cee..2b00ecc2e426690c308601a8621401855c858f31 100644 (file)
@@ -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 },
index 8fda38999764e481baee7ab21beb73606293f867..2768bc8e00c391dde2fc538609c44ac43c37cd33 100644 (file)
@@ -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 },
index 2d768823b84f5d061d9ea928497f8f4f9e1bbbe9..28c33d425707f807877bf50ec4ed6a6992af07e7 100644 (file)
 #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,