/* 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;
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);
/* 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;
}
{
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);
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);
*/
if (keymgmt->free == NULL
|| (keymgmt->new == NULL
+ && keymgmt->new_ex == NULL
&& keymgmt->gen == NULL
&& keymgmt->load == NULL)
|| keymgmt->has == NULL
/*
* 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)
#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"
#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,
#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
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;
* 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;
#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[]);
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.
/* 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 */
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>.
/*
* 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[]);
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;
/* 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
#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;
* 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;
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) {
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) {
return dh;
}
+static void *dhx_newdata(void *provctx)
+{
+ return dhx_newdata_ex(provctx, NULL);
+}
+
static void dh_freedata(void *keydata)
{
DH_free(keydata);
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 },
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 },
#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;
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);
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)
return dsa;
}
+static void *dsa_newdata(void *provctx)
+{
+ return dsa_newdata_ex(provctx, NULL);
+}
+
static void dsa_freedata(void *keydata)
{
DSA_free(keydata);
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 },
#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
#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;
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);
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;
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)
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 },
#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;
* 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;
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;
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) {
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;
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) {
return rsa;
}
+static void *rsapss_newdata(void *provctx)
+{
+ return rsapss_newdata_ex(provctx, NULL);
+}
+
static void rsa_freedata(void *keydata)
{
RSA_free(keydata);
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 },
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,