aboutsummaryrefslogtreecommitdiff
path: root/crypto/provider_core.c
diff options
context:
space:
mode:
Diffstat (limited to 'crypto/provider_core.c')
-rw-r--r--crypto/provider_core.c767
1 files changed, 618 insertions, 149 deletions
diff --git a/crypto/provider_core.c b/crypto/provider_core.c
index cb4233eb52fd..490991b5e58b 100644
--- a/crypto/provider_core.c
+++ b/crypto/provider_core.c
@@ -1,5 +1,5 @@
/*
- * Copyright 2019-2024 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright 2019-2025 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
@@ -29,8 +29,10 @@
#include "internal/bio.h"
#include "internal/core.h"
#include "provider_local.h"
+#include "crypto/context.h"
#ifndef FIPS_MODULE
# include <openssl/self_test.h>
+# include <openssl/indicator.h>
#endif
/*
@@ -72,11 +74,10 @@
* The locks available are:
*
* The provider flag_lock: Used to control updates to the various provider
- * "flags" (flag_initialized, flag_activated, flag_fallback) and associated
- * "counts" (activatecnt).
+ * "flags" (flag_initialized and flag_activated).
*
- * The provider refcnt_lock: Only ever used to control updates to the provider
- * refcnt value.
+ * The provider activatecnt_lock: Used to control updates to the provider
+ * activatecnt value.
*
* The provider optbits_lock: Used to control access to the provider's
* operation_bits and operation_bits_sz fields.
@@ -99,12 +100,12 @@
* introducing the possibility of deadlock. The following rules MUST be adhered
* to in order to avoid that:
* - Holding multiple locks at the same time is only allowed for the
- * provider store lock, the provider flag_lock and the provider refcnt_lock.
+ * provider store lock, the provider activatecnt_lock and the provider flag_lock.
* - When holding multiple locks they must be acquired in the following order of
* precedence:
* 1) provider store lock
* 2) provider flag_lock
- * 3) provider refcnt_lock
+ * 3) provider activatecnt_lock
* - When releasing locks they must be released in the reverse order to which
* they were acquired
* - No locks may be held when making an upcall. NOTE: Some common functions
@@ -142,14 +143,13 @@ struct ossl_provider_st {
/* Flag bits */
unsigned int flag_initialized:1;
unsigned int flag_activated:1;
- unsigned int flag_fallback:1; /* Can be used as fallback */
/* Getting and setting the flags require synchronization */
CRYPTO_RWLOCK *flag_lock;
/* OpenSSL library side data */
CRYPTO_REF_COUNT refcnt;
- CRYPTO_RWLOCK *refcnt_lock; /* For the ref counter */
+ CRYPTO_RWLOCK *activatecnt_lock; /* For the activatecnt counter */
int activatecnt;
char *name;
char *path;
@@ -175,6 +175,7 @@ struct ossl_provider_st {
OSSL_FUNC_provider_get_params_fn *get_params;
OSSL_FUNC_provider_get_capabilities_fn *get_capabilities;
OSSL_FUNC_provider_self_test_fn *self_test;
+ OSSL_FUNC_provider_random_bytes_fn *random_bytes;
OSSL_FUNC_provider_query_operation_fn *query_operation;
OSSL_FUNC_provider_unquery_operation_fn *unquery_operation;
@@ -283,7 +284,7 @@ void ossl_provider_info_clear(OSSL_PROVIDER_INFO *info)
sk_INFOPAIR_pop_free(info->parameters, infopair_free);
}
-static void provider_store_free(void *vstore)
+void ossl_provider_store_free(void *vstore)
{
struct provider_store_st *store = vstore;
size_t i;
@@ -305,7 +306,7 @@ static void provider_store_free(void *vstore)
OPENSSL_free(store);
}
-static void *provider_store_new(OSSL_LIB_CTX *ctx)
+void *ossl_provider_store_new(OSSL_LIB_CTX *ctx)
{
struct provider_store_st *store = OPENSSL_zalloc(sizeof(*store));
@@ -316,7 +317,7 @@ static void *provider_store_new(OSSL_LIB_CTX *ctx)
|| (store->child_cbs = sk_OSSL_PROVIDER_CHILD_CB_new_null()) == NULL
#endif
|| (store->lock = CRYPTO_THREAD_lock_new()) == NULL) {
- provider_store_free(store);
+ ossl_provider_store_free(store);
return NULL;
}
store->libctx = ctx;
@@ -325,19 +326,11 @@ static void *provider_store_new(OSSL_LIB_CTX *ctx)
return store;
}
-static const OSSL_LIB_CTX_METHOD provider_store_method = {
- /* Needs to be freed before the child provider data is freed */
- OSSL_LIB_CTX_METHOD_PRIORITY_1,
- provider_store_new,
- provider_store_free,
-};
-
static struct provider_store_st *get_provider_store(OSSL_LIB_CTX *libctx)
{
struct provider_store_st *store = NULL;
- store = ossl_lib_ctx_get_data(libctx, OSSL_LIB_CTX_PROVIDER_STORE_INDEX,
- &provider_store_method);
+ store = ossl_lib_ctx_get_data(libctx, OSSL_LIB_CTX_PROVIDER_STORE_INDEX);
if (store == NULL)
ERR_raise(ERR_LIB_CRYPTO, ERR_R_INTERNAL_ERROR);
return store;
@@ -380,10 +373,8 @@ int ossl_provider_info_add_to_store(OSSL_LIB_CTX *libctx,
if (store->provinfosz == 0) {
store->provinfo = OPENSSL_zalloc(sizeof(*store->provinfo)
* BUILTINS_BLOCK_SIZE);
- if (store->provinfo == NULL) {
- ERR_raise(ERR_LIB_CRYPTO, ERR_R_MALLOC_FAILURE);
+ if (store->provinfo == NULL)
goto err;
- }
store->provinfosz = BUILTINS_BLOCK_SIZE;
} else if (store->numprovinfo == store->provinfosz) {
OSSL_PROVIDER_INFO *tmpbuiltins;
@@ -391,10 +382,8 @@ int ossl_provider_info_add_to_store(OSSL_LIB_CTX *libctx,
tmpbuiltins = OPENSSL_realloc(store->provinfo,
sizeof(*store->provinfo) * newsz);
- if (tmpbuiltins == NULL) {
- ERR_raise(ERR_LIB_CRYPTO, ERR_R_MALLOC_FAILURE);
+ if (tmpbuiltins == NULL)
goto err;
- }
store->provinfo = tmpbuiltins;
store->provinfosz = newsz;
}
@@ -429,12 +418,9 @@ OSSL_PROVIDER *ossl_provider_find(OSSL_LIB_CTX *libctx, const char *name,
#endif
tmpl.name = (char *)name;
- /*
- * A "find" operation can sort the stack, and therefore a write lock is
- * required.
- */
if (!CRYPTO_THREAD_write_lock(store->lock))
return NULL;
+ sk_OSSL_PROVIDER_sort(store->providers);
if ((i = sk_OSSL_PROVIDER_find(store->providers, &tmpl)) != -1)
prov = sk_OSSL_PROVIDER_value(store->providers, i);
CRYPTO_THREAD_unlock(store->lock);
@@ -456,26 +442,29 @@ static OSSL_PROVIDER *provider_new(const char *name,
{
OSSL_PROVIDER *prov = NULL;
- if ((prov = OPENSSL_zalloc(sizeof(*prov))) == NULL
-#ifndef HAVE_ATOMICS
- || (prov->refcnt_lock = CRYPTO_THREAD_lock_new()) == NULL
-#endif
- ) {
+ if ((prov = OPENSSL_zalloc(sizeof(*prov))) == NULL)
+ return NULL;
+ if (!CRYPTO_NEW_REF(&prov->refcnt, 1)) {
OPENSSL_free(prov);
- ERR_raise(ERR_LIB_CRYPTO, ERR_R_MALLOC_FAILURE);
return NULL;
}
-
- prov->refcnt = 1; /* 1 One reference to be returned */
+ if ((prov->activatecnt_lock = CRYPTO_THREAD_lock_new()) == NULL) {
+ ossl_provider_free(prov);
+ ERR_raise(ERR_LIB_CRYPTO, ERR_R_CRYPTO_LIB);
+ return NULL;
+ }
if ((prov->opbits_lock = CRYPTO_THREAD_lock_new()) == NULL
|| (prov->flag_lock = CRYPTO_THREAD_lock_new()) == NULL
- || (prov->name = OPENSSL_strdup(name)) == NULL
|| (prov->parameters = sk_INFOPAIR_deep_copy(parameters,
infopair_copy,
infopair_free)) == NULL) {
ossl_provider_free(prov);
- ERR_raise(ERR_LIB_CRYPTO, ERR_R_MALLOC_FAILURE);
+ ERR_raise(ERR_LIB_CRYPTO, ERR_R_CRYPTO_LIB);
+ return NULL;
+ }
+ if ((prov->name = OPENSSL_strdup(name)) == NULL) {
+ ossl_provider_free(prov);
return NULL;
}
@@ -488,7 +477,7 @@ int ossl_provider_up_ref(OSSL_PROVIDER *prov)
{
int ref = 0;
- if (CRYPTO_UP_REF(&prov->refcnt, &ref, prov->refcnt_lock) <= 0)
+ if (CRYPTO_UP_REF(&prov->refcnt, &ref) <= 0)
return 0;
#ifndef FIPS_MODULE
@@ -529,7 +518,7 @@ static int provider_free_intern(OSSL_PROVIDER *prov, int deactivate)
*/
OSSL_PROVIDER *ossl_provider_new(OSSL_LIB_CTX *libctx, const char *name,
OSSL_provider_init_fn *init_function,
- int noconfig)
+ OSSL_PARAM *params, int noconfig)
{
struct provider_store_st *store = NULL;
OSSL_PROVIDER_INFO template;
@@ -542,33 +531,73 @@ OSSL_PROVIDER *ossl_provider_new(OSSL_LIB_CTX *libctx, const char *name,
if (init_function == NULL) {
const OSSL_PROVIDER_INFO *p;
size_t i;
+ int chosen = 0;
/* Check if this is a predefined builtin provider */
for (p = ossl_predefined_providers; p->name != NULL; p++) {
- if (strcmp(p->name, name) == 0) {
+ if (strcmp(p->name, name) != 0)
+ continue;
+ /* These compile-time templates always have NULL parameters */
+ template = *p;
+ chosen = 1;
+ break;
+ }
+ if (!CRYPTO_THREAD_read_lock(store->lock))
+ return NULL;
+ for (i = 0, p = store->provinfo; i < store->numprovinfo; p++, i++) {
+ if (strcmp(p->name, name) != 0)
+ continue;
+ /* For built-in providers, copy just implicit parameters. */
+ if (!chosen)
template = *p;
+ /*
+ * Explicit parameters override config-file defaults. If an empty
+ * parameter set is desired, a non-NULL empty set must be provided.
+ */
+ if (params != NULL || p->parameters == NULL) {
+ template.parameters = NULL;
break;
}
- }
- if (p->name == NULL) {
- /* Check if this is a user added builtin provider */
- if (!CRYPTO_THREAD_read_lock(store->lock))
+ /* Always copy to avoid sharing/mutation. */
+ template.parameters = sk_INFOPAIR_deep_copy(p->parameters,
+ infopair_copy,
+ infopair_free);
+ if (template.parameters == NULL)
return NULL;
- for (i = 0, p = store->provinfo; i < store->numprovinfo; p++, i++) {
- if (strcmp(p->name, name) == 0) {
- template = *p;
- break;
- }
- }
- CRYPTO_THREAD_unlock(store->lock);
+ break;
}
+ CRYPTO_THREAD_unlock(store->lock);
} else {
template.init = init_function;
}
+ if (params != NULL) {
+ int i;
+
+ /* Don't leak if already non-NULL */
+ if (template.parameters == NULL)
+ template.parameters = sk_INFOPAIR_new_null();
+ if (template.parameters == NULL)
+ return NULL;
+
+ for (i = 0; params[i].key != NULL; i++) {
+ if (params[i].data_type != OSSL_PARAM_UTF8_STRING)
+ continue;
+ if (ossl_provider_info_add_parameter(&template, params[i].key,
+ (char *)params[i].data) <= 0) {
+ sk_INFOPAIR_pop_free(template.parameters, infopair_free);
+ return NULL;
+ }
+ }
+ }
+
/* provider_new() generates an error, so no need here */
prov = provider_new(name, template.init, template.parameters);
+ /* If we copied the parameters, free them */
+ if (template.parameters != NULL)
+ sk_INFOPAIR_pop_free(template.parameters, infopair_free);
+
if (prov == NULL)
return NULL;
@@ -654,7 +683,7 @@ int ossl_provider_add_to_store(OSSL_PROVIDER *prov, OSSL_PROVIDER **actualprov,
if (actualprov != NULL) {
if (!ossl_provider_up_ref(actualtmp)) {
- ERR_raise(ERR_LIB_CRYPTO, ERR_R_MALLOC_FAILURE);
+ ERR_raise(ERR_LIB_CRYPTO, ERR_R_CRYPTO_LIB);
actualtmp = NULL;
return 0;
}
@@ -675,6 +704,15 @@ int ossl_provider_add_to_store(OSSL_PROVIDER *prov, OSSL_PROVIDER **actualprov,
ossl_provider_deactivate(prov, 0);
ossl_provider_free(prov);
}
+#ifndef FIPS_MODULE
+ else {
+ /*
+ * This can be done outside the lock. We tolerate other threads getting
+ * the wrong result briefly when creating OSSL_DECODER_CTXs.
+ */
+ ossl_decoder_cache_flush(prov->libctx);
+ }
+#endif
return 1;
@@ -688,7 +726,7 @@ void ossl_provider_free(OSSL_PROVIDER *prov)
if (prov != NULL) {
int ref = 0;
- CRYPTO_DOWN_REF(&prov->refcnt, &ref, prov->refcnt_lock);
+ CRYPTO_DOWN_REF(&prov->refcnt, &ref);
/*
* When the refcount drops to zero, we clean up the provider.
@@ -730,9 +768,8 @@ void ossl_provider_free(OSSL_PROVIDER *prov)
sk_INFOPAIR_pop_free(prov->parameters, infopair_free);
CRYPTO_THREAD_lock_free(prov->opbits_lock);
CRYPTO_THREAD_lock_free(prov->flag_lock);
-#ifndef HAVE_ATOMICS
- CRYPTO_THREAD_lock_free(prov->refcnt_lock);
-#endif
+ CRYPTO_THREAD_lock_free(prov->activatecnt_lock);
+ CRYPTO_FREE_REF(&prov->refcnt);
OPENSSL_free(prov);
}
#ifndef FIPS_MODULE
@@ -752,7 +789,6 @@ int ossl_provider_set_module_path(OSSL_PROVIDER *prov, const char *module_path)
return 1;
if ((prov->path = OPENSSL_strdup(module_path)) != NULL)
return 1;
- ERR_raise(ERR_LIB_CRYPTO, ERR_R_MALLOC_FAILURE);
return 0;
}
@@ -761,29 +797,84 @@ static int infopair_add(STACK_OF(INFOPAIR) **infopairsk, const char *name,
{
INFOPAIR *pair = NULL;
- if ((pair = OPENSSL_zalloc(sizeof(*pair))) != NULL
- && (*infopairsk != NULL
- || (*infopairsk = sk_INFOPAIR_new_null()) != NULL)
- && (pair->name = OPENSSL_strdup(name)) != NULL
- && (pair->value = OPENSSL_strdup(value)) != NULL
- && sk_INFOPAIR_push(*infopairsk, pair) > 0)
- return 1;
+ if ((pair = OPENSSL_zalloc(sizeof(*pair))) == NULL
+ || (pair->name = OPENSSL_strdup(name)) == NULL
+ || (pair->value = OPENSSL_strdup(value)) == NULL)
+ goto err;
+
+ if ((*infopairsk == NULL
+ && (*infopairsk = sk_INFOPAIR_new_null()) == NULL)
+ || sk_INFOPAIR_push(*infopairsk, pair) <= 0) {
+ ERR_raise(ERR_LIB_CRYPTO, ERR_R_CRYPTO_LIB);
+ goto err;
+ }
+
+ return 1;
+ err:
if (pair != NULL) {
OPENSSL_free(pair->name);
OPENSSL_free(pair->value);
OPENSSL_free(pair);
}
- ERR_raise(ERR_LIB_CRYPTO, ERR_R_MALLOC_FAILURE);
return 0;
}
-int ossl_provider_add_parameter(OSSL_PROVIDER *prov,
- const char *name, const char *value)
+int OSSL_PROVIDER_add_conf_parameter(OSSL_PROVIDER *prov,
+ const char *name, const char *value)
{
return infopair_add(&prov->parameters, name, value);
}
+int OSSL_PROVIDER_get_conf_parameters(const OSSL_PROVIDER *prov,
+ OSSL_PARAM params[])
+{
+ int i;
+
+ if (prov->parameters == NULL)
+ return 1;
+
+ for (i = 0; i < sk_INFOPAIR_num(prov->parameters); i++) {
+ INFOPAIR *pair = sk_INFOPAIR_value(prov->parameters, i);
+ OSSL_PARAM *p = OSSL_PARAM_locate(params, pair->name);
+
+ if (p != NULL
+ && !OSSL_PARAM_set_utf8_ptr(p, pair->value))
+ return 0;
+ }
+ return 1;
+}
+
+int OSSL_PROVIDER_conf_get_bool(const OSSL_PROVIDER *prov,
+ const char *name, int defval)
+{
+ char *val = NULL;
+ OSSL_PARAM param[2] = { OSSL_PARAM_END, OSSL_PARAM_END };
+
+ param[0].key = (char *)name;
+ param[0].data_type = OSSL_PARAM_UTF8_PTR;
+ param[0].data = (void *) &val;
+ param[0].data_size = sizeof(val);
+ param[0].return_size = OSSL_PARAM_UNMODIFIED;
+
+ /* Errors are ignored, returning the default value */
+ if (OSSL_PROVIDER_get_conf_parameters(prov, param)
+ && OSSL_PARAM_modified(param)
+ && val != NULL) {
+ if ((strcmp(val, "1") == 0)
+ || (OPENSSL_strcasecmp(val, "yes") == 0)
+ || (OPENSSL_strcasecmp(val, "true") == 0)
+ || (OPENSSL_strcasecmp(val, "on") == 0))
+ return 1;
+ else if ((strcmp(val, "0") == 0)
+ || (OPENSSL_strcasecmp(val, "no") == 0)
+ || (OPENSSL_strcasecmp(val, "false") == 0)
+ || (OPENSSL_strcasecmp(val, "off") == 0))
+ return 0;
+ }
+ return defval;
+}
+
int ossl_provider_info_add_parameter(OSSL_PROVIDER_INFO *provinfo,
const char *name,
const char *value)
@@ -813,10 +904,8 @@ int OSSL_PROVIDER_set_default_search_path(OSSL_LIB_CTX *libctx,
if (path != NULL) {
p = OPENSSL_strdup(path);
- if (p == NULL) {
- ERR_raise(ERR_LIB_CRYPTO, ERR_R_MALLOC_FAILURE);
+ if (p == NULL)
return 0;
- }
}
if ((store = get_provider_store(libctx)) != NULL
&& CRYPTO_THREAD_write_lock(store->default_path_lock)) {
@@ -829,6 +918,19 @@ int OSSL_PROVIDER_set_default_search_path(OSSL_LIB_CTX *libctx,
return 0;
}
+const char *OSSL_PROVIDER_get0_default_search_path(OSSL_LIB_CTX *libctx)
+{
+ struct provider_store_st *store;
+ char *path = NULL;
+
+ if ((store = get_provider_store(libctx)) != NULL
+ && CRYPTO_THREAD_read_lock(store->default_path_lock)) {
+ path = store->default_path;
+ CRYPTO_THREAD_unlock(store->default_path_lock);
+ }
+ return path;
+}
+
/*
* Internal version that doesn't affect the store flags, and thereby avoid
* locking. Direct callers must remember to set the store flags when
@@ -878,10 +980,8 @@ static int provider_init(OSSL_PROVIDER *prov)
if (store->default_path != NULL) {
allocated_load_dir = OPENSSL_strdup(store->default_path);
CRYPTO_THREAD_unlock(store->default_path_lock);
- if (allocated_load_dir == NULL) {
- ERR_raise(ERR_LIB_CRYPTO, ERR_R_MALLOC_FAILURE);
+ if (allocated_load_dir == NULL)
goto end;
- }
load_dir = allocated_load_dir;
} else {
CRYPTO_THREAD_unlock(store->default_path_lock);
@@ -890,7 +990,7 @@ static int provider_init(OSSL_PROVIDER *prov)
if (load_dir == NULL) {
load_dir = ossl_safe_getenv("OPENSSL_MODULES");
if (load_dir == NULL)
- load_dir = MODULESDIR;
+ load_dir = ossl_get_modulesdir();
}
DSO_ctrl(prov->module, DSO_CTRL_SET_FLAGS,
@@ -933,6 +1033,12 @@ static int provider_init(OSSL_PROVIDER *prov)
prov->name);
goto end;
}
+#ifndef FIPS_MODULE
+ OSSL_TRACE_BEGIN(PROVIDER) {
+ BIO_printf(trc_out,
+ "(provider %s) initalizing\n", prov->name);
+ } OSSL_TRACE_END(PROVIDER);
+#endif
if (!prov->init_function((OSSL_CORE_HANDLE *)prov, core_dispatch,
&provider_dispatch, &tmp_provctx)) {
@@ -962,6 +1068,10 @@ static int provider_init(OSSL_PROVIDER *prov)
prov->self_test =
OSSL_FUNC_provider_self_test(provider_dispatch);
break;
+ case OSSL_FUNC_PROVIDER_RANDOM_BYTES:
+ prov->random_bytes =
+ OSSL_FUNC_provider_random_bytes(provider_dispatch);
+ break;
case OSSL_FUNC_PROVIDER_GET_CAPABILITIES:
prov->get_capabilities =
OSSL_FUNC_provider_get_capabilities(provider_dispatch);
@@ -1059,6 +1169,12 @@ static int provider_deactivate(OSSL_PROVIDER *prov, int upcalls,
if (!ossl_assert(prov != NULL))
return -1;
+#ifndef FIPS_MODULE
+ if (prov->random_bytes != NULL
+ && !ossl_rand_check_random_provider_on_unload(prov->libctx, prov))
+ return -1;
+#endif
+
/*
* No need to lock if we've got no store because we've not been shared with
* other threads.
@@ -1074,8 +1190,16 @@ static int provider_deactivate(OSSL_PROVIDER *prov, int upcalls,
return -1;
}
+ if (!CRYPTO_atomic_add(&prov->activatecnt, -1, &count, prov->activatecnt_lock)) {
+ if (lock) {
+ CRYPTO_THREAD_unlock(prov->flag_lock);
+ CRYPTO_THREAD_unlock(store->lock);
+ }
+ return -1;
+ }
+
#ifndef FIPS_MODULE
- if (prov->activatecnt >= 2 && prov->ischild && upcalls) {
+ if (count >= 1 && prov->ischild && upcalls) {
/*
* We have had a direct activation in this child libctx so we need to
* now down the ref count in the parent provider. We do the actual down
@@ -1086,7 +1210,7 @@ static int provider_deactivate(OSSL_PROVIDER *prov, int upcalls,
}
#endif
- if ((count = --prov->activatecnt) < 1)
+ if (count < 1)
prov->flag_activated = 0;
#ifndef FIPS_MODULE
else
@@ -1107,6 +1231,14 @@ static int provider_deactivate(OSSL_PROVIDER *prov, int upcalls,
if (lock) {
CRYPTO_THREAD_unlock(prov->flag_lock);
CRYPTO_THREAD_unlock(store->lock);
+ /*
+ * This can be done outside the lock. We tolerate other threads getting
+ * the wrong result briefly when creating OSSL_DECODER_CTXs.
+ */
+#ifndef FIPS_MODULE
+ if (count < 1)
+ ossl_decoder_cache_flush(prov->libctx);
+#endif
}
#ifndef FIPS_MODULE
if (freeparent)
@@ -1139,6 +1271,10 @@ static int provider_activate(OSSL_PROVIDER *prov, int lock, int upcalls)
}
#ifndef FIPS_MODULE
+ if (prov->random_bytes != NULL
+ && !ossl_rand_check_random_provider_on_load(prov->libctx, prov))
+ return -1;
+
if (prov->ischild && upcalls && !ossl_provider_up_ref_parent(prov, 1))
return -1;
#endif
@@ -1159,16 +1295,24 @@ static int provider_activate(OSSL_PROVIDER *prov, int lock, int upcalls)
#endif
return -1;
}
+ if (CRYPTO_atomic_add(&prov->activatecnt, 1, &count, prov->activatecnt_lock)) {
+ prov->flag_activated = 1;
- count = ++prov->activatecnt;
- prov->flag_activated = 1;
-
- if (prov->activatecnt == 1 && store != NULL) {
- ret = create_provider_children(prov);
+ if (count == 1 && store != NULL) {
+ ret = create_provider_children(prov);
+ }
}
if (lock) {
CRYPTO_THREAD_unlock(prov->flag_lock);
CRYPTO_THREAD_unlock(store->lock);
+ /*
+ * This can be done outside the lock. We tolerate other threads getting
+ * the wrong result briefly when creating OSSL_DECODER_CTXs.
+ */
+#ifndef FIPS_MODULE
+ if (count == 1)
+ ossl_decoder_cache_flush(prov->libctx);
+#endif
}
if (!ret)
@@ -1314,14 +1458,25 @@ static int provider_activate_fallbacks(struct provider_store_st *store)
for (p = ossl_predefined_providers; p->name != NULL; p++) {
OSSL_PROVIDER *prov = NULL;
+ OSSL_PROVIDER_INFO *info = store->provinfo;
+ STACK_OF(INFOPAIR) *params = NULL;
+ size_t i;
if (!p->is_fallback)
continue;
+
+ for (i = 0; i < store->numprovinfo; info++, i++) {
+ if (strcmp(info->name, p->name) != 0)
+ continue;
+ params = info->parameters;
+ break;
+ }
+
/*
* We use the internal constructor directly here,
* otherwise we get a call loop
*/
- prov = provider_new(p->name, p->init, NULL);
+ prov = provider_new(p->name, p->init, params);
if (prov == NULL)
goto err;
prov->libctx = store->libctx;
@@ -1398,7 +1553,7 @@ int ossl_provider_doall_activated(OSSL_LIB_CTX *ctx,
for (curr = max - 1; curr >= 0; curr--) {
OSSL_PROVIDER *prov = sk_OSSL_PROVIDER_value(provs, curr);
- if (!CRYPTO_THREAD_write_lock(prov->flag_lock))
+ if (!CRYPTO_THREAD_read_lock(prov->flag_lock))
goto err_unlock;
if (prov->flag_activated) {
/*
@@ -1406,20 +1561,19 @@ int ossl_provider_doall_activated(OSSL_LIB_CTX *ctx,
* to avoid upping the ref count on the parent provider, which we
* must not do while holding locks.
*/
- if (CRYPTO_UP_REF(&prov->refcnt, &ref, prov->refcnt_lock) <= 0) {
+ if (CRYPTO_UP_REF(&prov->refcnt, &ref) <= 0) {
CRYPTO_THREAD_unlock(prov->flag_lock);
goto err_unlock;
}
/*
* It's already activated, but we up the activated count to ensure
* it remains activated until after we've called the user callback.
- * We do this with no locking (because we already hold the locks)
- * and no upcalls (which must not be called when locks are held). In
- * theory this could mean the parent provider goes inactive, whilst
- * still activated in the child for a short period. That's ok.
+ * In theory this could mean the parent provider goes inactive,
+ * whilst still activated in the child for a short period. That's ok.
*/
- if (provider_activate(prov, 0, 0) < 0) {
- CRYPTO_DOWN_REF(&prov->refcnt, &ref, prov->refcnt_lock);
+ if (!CRYPTO_atomic_add(&prov->activatecnt, 1, &ref,
+ prov->activatecnt_lock)) {
+ CRYPTO_DOWN_REF(&prov->refcnt, &ref);
CRYPTO_THREAD_unlock(prov->flag_lock);
goto err_unlock;
}
@@ -1458,13 +1612,32 @@ int ossl_provider_doall_activated(OSSL_LIB_CTX *ctx,
for (curr++; curr < max; curr++) {
OSSL_PROVIDER *prov = sk_OSSL_PROVIDER_value(provs, curr);
- provider_deactivate(prov, 0, 1);
+ if (!CRYPTO_atomic_add(&prov->activatecnt, -1, &ref,
+ prov->activatecnt_lock)) {
+ ret = 0;
+ continue;
+ }
+ if (ref < 1) {
+ /*
+ * Looks like we need to deactivate properly. We could just have
+ * done this originally, but it involves taking a write lock so
+ * we avoid it. We up the count again and do a full deactivation
+ */
+ if (CRYPTO_atomic_add(&prov->activatecnt, 1, &ref,
+ prov->activatecnt_lock))
+ provider_deactivate(prov, 0, 1);
+ else
+ ret = 0;
+ }
/*
* As above where we did the up-ref, we don't call ossl_provider_free
* to avoid making upcalls. There should always be at least one ref
* to the provider in the store, so this should never drop to 0.
*/
- CRYPTO_DOWN_REF(&prov->refcnt, &ref, prov->refcnt_lock);
+ if (!CRYPTO_DOWN_REF(&prov->refcnt, &ref)) {
+ ret = 0;
+ continue;
+ }
/*
* Not much we can do if this assert ever fails. So we don't use
* ossl_assert here.
@@ -1495,16 +1668,6 @@ int OSSL_PROVIDER_available(OSSL_LIB_CTX *libctx, const char *name)
return available;
}
-/* Setters of Provider Object data */
-int ossl_provider_set_fallback(OSSL_PROVIDER *prov)
-{
- if (prov == NULL)
- return 0;
-
- prov->flag_fallback = 1;
- return 1;
-}
-
/* Getters of Provider Object data */
const char *ossl_provider_name(const OSSL_PROVIDER *prov)
{
@@ -1535,14 +1698,6 @@ const char *ossl_provider_module_path(const OSSL_PROVIDER *prov)
#endif
}
-void *ossl_provider_prov_ctx(const OSSL_PROVIDER *prov)
-{
- if (prov != NULL)
- return prov->provctx;
-
- return NULL;
-}
-
const OSSL_DISPATCH *ossl_provider_get0_dispatch(const OSSL_PROVIDER *prov)
{
if (prov != NULL)
@@ -1556,59 +1711,256 @@ OSSL_LIB_CTX *ossl_provider_libctx(const OSSL_PROVIDER *prov)
return prov != NULL ? prov->libctx : NULL;
}
-/* Wrappers around calls to the provider */
+/**
+ * @brief Tears down the given provider.
+ *
+ * This function calls the `teardown` callback of the given provider to release
+ * any resources associated with it. The teardown is skipped if the callback is
+ * not defined or, in non-FIPS builds, if the provider is a child.
+ *
+ * @param prov Pointer to the OSSL_PROVIDER structure representing the provider.
+ *
+ * If tracing is enabled, a message is printed indicating that the teardown is
+ * being called.
+ */
void ossl_provider_teardown(const OSSL_PROVIDER *prov)
{
if (prov->teardown != NULL
#ifndef FIPS_MODULE
&& !prov->ischild
#endif
- )
+ ) {
+#ifndef FIPS_MODULE
+ OSSL_TRACE_BEGIN(PROVIDER) {
+ BIO_printf(trc_out, "(provider %s) calling teardown\n",
+ ossl_provider_name(prov));
+ } OSSL_TRACE_END(PROVIDER);
+#endif
prov->teardown(prov->provctx);
+ }
}
+/**
+ * @brief Retrieves the parameters that can be obtained from a provider.
+ *
+ * This function calls the `gettable_params` callback of the given provider to
+ * get a list of parameters that can be retrieved.
+ *
+ * @param prov Pointer to the OSSL_PROVIDER structure representing the provider.
+ *
+ * @return Pointer to an array of OSSL_PARAM structures that represent the
+ * gettable parameters, or NULL if the callback is not defined.
+ *
+ * If tracing is enabled, the gettable parameters are printed for debugging.
+ */
const OSSL_PARAM *ossl_provider_gettable_params(const OSSL_PROVIDER *prov)
{
- return prov->gettable_params == NULL
- ? NULL : prov->gettable_params(prov->provctx);
+ const OSSL_PARAM *ret = NULL;
+
+ if (prov->gettable_params != NULL)
+ ret = prov->gettable_params(prov->provctx);
+
+#ifndef FIPS_MODULE
+ OSSL_TRACE_BEGIN(PROVIDER) {
+ char *buf = NULL;
+
+ BIO_printf(trc_out, "(provider %s) gettable params\n",
+ ossl_provider_name(prov));
+ BIO_printf(trc_out, "Parameters:\n");
+ if (prov->gettable_params != NULL) {
+ if (!OSSL_PARAM_print_to_bio(ret, trc_out, 0))
+ BIO_printf(trc_out, "Failed to parse param values\n");
+ OPENSSL_free(buf);
+ } else {
+ BIO_printf(trc_out, "Provider doesn't implement gettable_params\n");
+ }
+ } OSSL_TRACE_END(PROVIDER);
+#endif
+
+ return ret;
}
+/**
+ * @brief Retrieves parameters from a provider.
+ *
+ * This function calls the `get_params` callback of the given provider to
+ * retrieve its parameters. If the callback is defined, it is invoked with the
+ * provider context and the parameters array.
+ *
+ * @param prov Pointer to the OSSL_PROVIDER structure representing the provider.
+ * @param params Array of OSSL_PARAM structures to store the retrieved parameters.
+ *
+ * @return 1 on success, 0 if the `get_params` callback is not defined or fails.
+ *
+ * If tracing is enabled, the retrieved parameters are printed for debugging.
+ */
int ossl_provider_get_params(const OSSL_PROVIDER *prov, OSSL_PARAM params[])
{
- return prov->get_params == NULL
- ? 0 : prov->get_params(prov->provctx, params);
+ int ret;
+
+ if (prov->get_params == NULL)
+ return 0;
+
+ ret = prov->get_params(prov->provctx, params);
+#ifndef FIPS_MODULE
+ OSSL_TRACE_BEGIN(PROVIDER) {
+
+ BIO_printf(trc_out,
+ "(provider %s) calling get_params\n", prov->name);
+ if (ret == 1) {
+ BIO_printf(trc_out, "Parameters:\n");
+ if (!OSSL_PARAM_print_to_bio(params, trc_out, 1))
+ BIO_printf(trc_out, "Failed to parse param values\n");
+ } else {
+ BIO_printf(trc_out, "get_params call failed\n");
+ }
+ } OSSL_TRACE_END(PROVIDER);
+#endif
+ return ret;
}
+/**
+ * @brief Performs a self-test on the given provider.
+ *
+ * This function calls the `self_test` callback of the given provider to
+ * perform a self-test. If the callback is not defined, it assumes the test
+ * passed.
+ *
+ * @param prov Pointer to the OSSL_PROVIDER structure representing the provider.
+ *
+ * @return 1 if the self-test passes or the callback is not defined, 0 on failure.
+ *
+ * If tracing is enabled, the result of the self-test is printed for debugging.
+ * If the test fails, the provider's store methods are removed.
+ */
int ossl_provider_self_test(const OSSL_PROVIDER *prov)
{
- int ret;
+ int ret = 1;
- if (prov->self_test == NULL)
- return 1;
- ret = prov->self_test(prov->provctx);
+ if (prov->self_test != NULL)
+ ret = prov->self_test(prov->provctx);
+
+#ifndef FIPS_MODULE
+ OSSL_TRACE_BEGIN(PROVIDER) {
+ if (prov->self_test != NULL)
+ BIO_printf(trc_out,
+ "(provider %s) Calling self_test, ret = %d\n",
+ prov->name, ret);
+ else
+ BIO_printf(trc_out,
+ "(provider %s) doesn't implement self_test\n",
+ prov->name);
+ } OSSL_TRACE_END(PROVIDER);
+#endif
if (ret == 0)
(void)provider_remove_store_methods((OSSL_PROVIDER *)prov);
return ret;
}
+/**
+ * @brief Retrieves capabilities from the given provider.
+ *
+ * This function calls the `get_capabilities` callback of the specified provider
+ * to retrieve capabilities information. The callback is invoked with the
+ * provider context, capability name, a callback function, and an argument.
+ *
+ * @param prov Pointer to the OSSL_PROVIDER structure representing the provider.
+ * @param capability String representing the capability to be retrieved.
+ * @param cb Callback function to process the capability data.
+ * @param arg Argument to be passed to the callback function.
+ *
+ * @return 1 if the capabilities are successfully retrieved or if the callback
+ * is not defined, otherwise the value returned by `get_capabilities`.
+ *
+ * If tracing is enabled, a message is printed indicating the requested
+ * capabilities.
+ */
+int ossl_provider_random_bytes(const OSSL_PROVIDER *prov, int which,
+ void *buf, size_t n, unsigned int strength)
+{
+ return prov->random_bytes == NULL ? 0
+ : prov->random_bytes(prov->provctx, which,
+ buf, n, strength);
+}
+
int ossl_provider_get_capabilities(const OSSL_PROVIDER *prov,
const char *capability,
OSSL_CALLBACK *cb,
void *arg)
{
- return prov->get_capabilities == NULL
- ? 1 : prov->get_capabilities(prov->provctx, capability, cb, arg);
+ if (prov->get_capabilities != NULL) {
+#ifndef FIPS_MODULE
+ OSSL_TRACE_BEGIN(PROVIDER) {
+ BIO_printf(trc_out,
+ "(provider %s) Calling get_capabilities "
+ "with capabilities %s\n", prov->name,
+ capability == NULL ? "none" : capability);
+ } OSSL_TRACE_END(PROVIDER);
+#endif
+ return prov->get_capabilities(prov->provctx, capability, cb, arg);
+ }
+ return 1;
}
+/**
+ * @brief Queries the provider for available algorithms for a given operation.
+ *
+ * This function calls the `query_operation` callback of the specified provider
+ * to obtain a list of algorithms that can perform the given operation. It may
+ * also set a flag indicating whether the result should be cached.
+ *
+ * @param prov Pointer to the OSSL_PROVIDER structure representing the provider.
+ * @param operation_id Identifier of the operation to query.
+ * @param no_cache Pointer to an integer flag to indicate whether caching is allowed.
+ *
+ * @return Pointer to an array of OSSL_ALGORITHM structures representing the
+ * available algorithms, or NULL if the callback is not defined or
+ * there are no available algorithms.
+ *
+ * If tracing is enabled, the available algorithms and their properties are
+ * printed for debugging.
+ */
const OSSL_ALGORITHM *ossl_provider_query_operation(const OSSL_PROVIDER *prov,
int operation_id,
int *no_cache)
{
const OSSL_ALGORITHM *res;
- if (prov->query_operation == NULL)
+ if (prov->query_operation == NULL) {
+#ifndef FIPS_MODULE
+ OSSL_TRACE_BEGIN(PROVIDER) {
+ BIO_printf(trc_out, "provider %s lacks query operation!\n",
+ prov->name);
+ } OSSL_TRACE_END(PROVIDER);
+#endif
return NULL;
+ }
+
res = prov->query_operation(prov->provctx, operation_id, no_cache);
+#ifndef FIPS_MODULE
+ OSSL_TRACE_BEGIN(PROVIDER) {
+ const OSSL_ALGORITHM *idx;
+ if (res != NULL) {
+ BIO_printf(trc_out,
+ "(provider %s) Calling query, available algs are:\n", prov->name);
+
+ for (idx = res; idx->algorithm_names != NULL; idx++) {
+ BIO_printf(trc_out,
+ "(provider %s) names %s, prop_def %s, desc %s\n",
+ prov->name,
+ res->algorithm_names == NULL ? "none" :
+ res->algorithm_names,
+ res->property_definition == NULL ? "none" :
+ res->property_definition,
+ res->algorithm_description == NULL ? "none" :
+ res->algorithm_description);
+ }
+ } else {
+ BIO_printf(trc_out, "(provider %s) query_operation failed\n", prov->name);
+ }
+ } OSSL_TRACE_END(PROVIDER);
+#endif
+
#if defined(OPENSSL_NO_CACHED_FETCH)
/* Forcing the non-caching of queries */
if (no_cache != NULL)
@@ -1617,12 +1969,36 @@ const OSSL_ALGORITHM *ossl_provider_query_operation(const OSSL_PROVIDER *prov,
return res;
}
+/**
+ * @brief Releases resources associated with a queried operation.
+ *
+ * This function calls the `unquery_operation` callback of the specified
+ * provider to release any resources related to a previously queried operation.
+ *
+ * @param prov Pointer to the OSSL_PROVIDER structure representing the provider.
+ * @param operation_id Identifier of the operation to unquery.
+ * @param algs Pointer to the OSSL_ALGORITHM structures representing the
+ * algorithms associated with the operation.
+ *
+ * If tracing is enabled, a message is printed indicating that the operation
+ * is being unqueried.
+ */
void ossl_provider_unquery_operation(const OSSL_PROVIDER *prov,
int operation_id,
const OSSL_ALGORITHM *algs)
{
- if (prov->unquery_operation != NULL)
+ if (prov->unquery_operation != NULL) {
+#ifndef FIPS_MODULE
+ OSSL_TRACE_BEGIN(PROVIDER) {
+ BIO_printf(trc_out,
+ "(provider %s) Calling unquery"
+ " with operation %d\n",
+ prov->name,
+ operation_id);
+ } OSSL_TRACE_END(PROVIDER);
+#endif
prov->unquery_operation(prov->provctx, operation_id, algs);
+ }
}
int ossl_provider_set_operation_bit(OSSL_PROVIDER *provider, size_t bitnum)
@@ -1638,7 +2014,6 @@ int ossl_provider_set_operation_bit(OSSL_PROVIDER *provider, size_t bitnum)
if (tmp == NULL) {
CRYPTO_THREAD_unlock(provider->opbits_lock);
- ERR_raise(ERR_LIB_CRYPTO, ERR_R_MALLOC_FAILURE);
return 0;
}
provider->operation_bits = tmp;
@@ -1880,11 +2255,16 @@ OSSL_FUNC_BIO_up_ref_fn ossl_core_bio_up_ref;
OSSL_FUNC_BIO_free_fn ossl_core_bio_free;
OSSL_FUNC_BIO_vprintf_fn ossl_core_bio_vprintf;
OSSL_FUNC_BIO_vsnprintf_fn BIO_vsnprintf;
+static OSSL_FUNC_indicator_cb_fn core_indicator_get_callback;
static OSSL_FUNC_self_test_cb_fn core_self_test_get_callback;
-OSSL_FUNC_get_entropy_fn ossl_rand_get_entropy;
-OSSL_FUNC_cleanup_entropy_fn ossl_rand_cleanup_entropy;
-OSSL_FUNC_get_nonce_fn ossl_rand_get_nonce;
-OSSL_FUNC_cleanup_nonce_fn ossl_rand_cleanup_nonce;
+static OSSL_FUNC_get_entropy_fn rand_get_entropy;
+static OSSL_FUNC_get_user_entropy_fn rand_get_user_entropy;
+static OSSL_FUNC_cleanup_entropy_fn rand_cleanup_entropy;
+static OSSL_FUNC_cleanup_user_entropy_fn rand_cleanup_user_entropy;
+static OSSL_FUNC_get_nonce_fn rand_get_nonce;
+static OSSL_FUNC_get_user_nonce_fn rand_get_user_nonce;
+static OSSL_FUNC_cleanup_nonce_fn rand_cleanup_nonce;
+static OSSL_FUNC_cleanup_user_nonce_fn rand_cleanup_user_nonce;
#endif
OSSL_FUNC_CRYPTO_malloc_fn CRYPTO_malloc;
OSSL_FUNC_CRYPTO_zalloc_fn CRYPTO_zalloc;
@@ -1917,7 +2297,6 @@ static const OSSL_PARAM *core_gettable_params(const OSSL_CORE_HANDLE *handle)
static int core_get_params(const OSSL_CORE_HANDLE *handle, OSSL_PARAM params[])
{
- int i;
OSSL_PARAM *p;
/*
* We created this object originally and we know it is actually an
@@ -1936,16 +2315,7 @@ static int core_get_params(const OSSL_CORE_HANDLE *handle, OSSL_PARAM params[])
OSSL_PARAM_set_utf8_ptr(p, ossl_provider_module_path(prov));
#endif
- if (prov->parameters == NULL)
- return 1;
-
- for (i = 0; i < sk_INFOPAIR_num(prov->parameters); i++) {
- INFOPAIR *pair = sk_INFOPAIR_value(prov->parameters, i);
-
- if ((p = OSSL_PARAM_locate(params, pair->name)) != NULL)
- OSSL_PARAM_set_utf8_ptr(p, pair->value);
- }
- return 1;
+ return OSSL_PROVIDER_get_conf_parameters(prov, params);
}
static OPENSSL_CORE_CTX *core_get_libctx(const OSSL_CORE_HANDLE *handle)
@@ -2039,12 +2409,106 @@ static int core_pop_error_to_mark(const OSSL_CORE_HANDLE *handle)
return ERR_pop_to_mark();
}
+static void core_indicator_get_callback(OPENSSL_CORE_CTX *libctx,
+ OSSL_INDICATOR_CALLBACK **cb)
+{
+ OSSL_INDICATOR_get_callback((OSSL_LIB_CTX *)libctx, cb);
+}
+
static void core_self_test_get_callback(OPENSSL_CORE_CTX *libctx,
OSSL_CALLBACK **cb, void **cbarg)
{
OSSL_SELF_TEST_get_callback((OSSL_LIB_CTX *)libctx, cb, cbarg);
}
+# ifdef OPENSSL_NO_FIPS_JITTER
+static size_t rand_get_entropy(const OSSL_CORE_HANDLE *handle,
+ unsigned char **pout, int entropy,
+ size_t min_len, size_t max_len)
+{
+ return ossl_rand_get_entropy((OSSL_LIB_CTX *)core_get_libctx(handle),
+ pout, entropy, min_len, max_len);
+}
+# else
+/*
+ * OpenSSL FIPS providers prior to 3.2 call rand_get_entropy API from
+ * core, instead of the newer get_user_entropy. Newer API call honors
+ * runtime configuration of random seed source and can be configured
+ * to use os getranom() or another seed source, such as
+ * JITTER. However, 3.0.9 only calls this API. Note that no other
+ * providers known to use this, and it is core <-> provider only
+ * API. Public facing EVP and getrandom bytes already correctly honor
+ * runtime configuration for seed source. There are no other providers
+ * packaged in Wolfi, or even known to exist that use this api. Thus
+ * it is safe to say any caller of this API is in fact 3.0.9 FIPS
+ * provider. Also note that the passed in handle is invalid and cannot
+ * be safely dereferences in such cases. Due to a bug in FIPS
+ * providers 3.0.0, 3.0.8 and 3.0.9. See
+ * https://github.com/openssl/openssl/blob/master/doc/internal/man3/ossl_rand_get_entropy.pod#notes
+ */
+size_t ossl_rand_jitter_get_seed(unsigned char **, int, size_t, size_t);
+static size_t rand_get_entropy(const OSSL_CORE_HANDLE *handle,
+ unsigned char **pout, int entropy,
+ size_t min_len, size_t max_len)
+{
+ return ossl_rand_jitter_get_seed(pout, entropy, min_len, max_len);
+}
+# endif
+
+static size_t rand_get_user_entropy(const OSSL_CORE_HANDLE *handle,
+ unsigned char **pout, int entropy,
+ size_t min_len, size_t max_len)
+{
+ return ossl_rand_get_user_entropy((OSSL_LIB_CTX *)core_get_libctx(handle),
+ pout, entropy, min_len, max_len);
+}
+
+static void rand_cleanup_entropy(const OSSL_CORE_HANDLE *handle,
+ unsigned char *buf, size_t len)
+{
+ ossl_rand_cleanup_entropy((OSSL_LIB_CTX *)core_get_libctx(handle),
+ buf, len);
+}
+
+static void rand_cleanup_user_entropy(const OSSL_CORE_HANDLE *handle,
+ unsigned char *buf, size_t len)
+{
+ ossl_rand_cleanup_user_entropy((OSSL_LIB_CTX *)core_get_libctx(handle),
+ buf, len);
+}
+
+static size_t rand_get_nonce(const OSSL_CORE_HANDLE *handle,
+ unsigned char **pout,
+ size_t min_len, size_t max_len,
+ const void *salt, size_t salt_len)
+{
+ return ossl_rand_get_nonce((OSSL_LIB_CTX *)core_get_libctx(handle),
+ pout, min_len, max_len, salt, salt_len);
+}
+
+static size_t rand_get_user_nonce(const OSSL_CORE_HANDLE *handle,
+ unsigned char **pout,
+ size_t min_len, size_t max_len,
+ const void *salt, size_t salt_len)
+{
+ return ossl_rand_get_user_nonce((OSSL_LIB_CTX *)core_get_libctx(handle),
+ pout, min_len, max_len, salt, salt_len);
+}
+
+static void rand_cleanup_nonce(const OSSL_CORE_HANDLE *handle,
+ unsigned char *buf, size_t len)
+{
+ ossl_rand_cleanup_nonce((OSSL_LIB_CTX *)core_get_libctx(handle),
+ buf, len);
+}
+
+static void rand_cleanup_user_nonce(const OSSL_CORE_HANDLE *handle,
+ unsigned char *buf, size_t len)
+{
+ ossl_rand_cleanup_user_nonce((OSSL_LIB_CTX *)core_get_libctx(handle),
+ buf, len);
+}
+
static const char *core_provider_get0_name(const OSSL_CORE_HANDLE *prov)
{
return OSSL_PROVIDER_get0_name((const OSSL_PROVIDER *)prov);
@@ -2138,10 +2602,15 @@ static const OSSL_DISPATCH core_dispatch_[] = {
{ OSSL_FUNC_BIO_VPRINTF, (void (*)(void))ossl_core_bio_vprintf },
{ OSSL_FUNC_BIO_VSNPRINTF, (void (*)(void))BIO_vsnprintf },
{ OSSL_FUNC_SELF_TEST_CB, (void (*)(void))core_self_test_get_callback },
- { OSSL_FUNC_GET_ENTROPY, (void (*)(void))ossl_rand_get_entropy },
- { OSSL_FUNC_CLEANUP_ENTROPY, (void (*)(void))ossl_rand_cleanup_entropy },
- { OSSL_FUNC_GET_NONCE, (void (*)(void))ossl_rand_get_nonce },
- { OSSL_FUNC_CLEANUP_NONCE, (void (*)(void))ossl_rand_cleanup_nonce },
+ { OSSL_FUNC_INDICATOR_CB, (void (*)(void))core_indicator_get_callback },
+ { OSSL_FUNC_GET_ENTROPY, (void (*)(void))rand_get_entropy },
+ { OSSL_FUNC_GET_USER_ENTROPY, (void (*)(void))rand_get_user_entropy },
+ { OSSL_FUNC_CLEANUP_ENTROPY, (void (*)(void))rand_cleanup_entropy },
+ { OSSL_FUNC_CLEANUP_USER_ENTROPY, (void (*)(void))rand_cleanup_user_entropy },
+ { OSSL_FUNC_GET_NONCE, (void (*)(void))rand_get_nonce },
+ { OSSL_FUNC_GET_USER_NONCE, (void (*)(void))rand_get_user_nonce },
+ { OSSL_FUNC_CLEANUP_NONCE, (void (*)(void))rand_cleanup_nonce },
+ { OSSL_FUNC_CLEANUP_USER_NONCE, (void (*)(void))rand_cleanup_user_nonce },
#endif
{ OSSL_FUNC_CRYPTO_MALLOC, (void (*)(void))CRYPTO_malloc },
{ OSSL_FUNC_CRYPTO_ZALLOC, (void (*)(void))CRYPTO_zalloc },
@@ -2175,6 +2644,6 @@ static const OSSL_DISPATCH core_dispatch_[] = {
{ OSSL_FUNC_CORE_OBJ_ADD_SIGID, (void (*)(void))core_obj_add_sigid },
{ OSSL_FUNC_CORE_OBJ_CREATE, (void (*)(void))core_obj_create },
#endif
- { 0, NULL }
+ OSSL_DISPATCH_END
};
static const OSSL_DISPATCH *core_dispatch = core_dispatch_;