#include <openssl/core_numbers.h>
#include <openssl/params.h>
#include <openssl/opensslv.h>
-#include "internal/cryptlib.h"
+#include "internal/cryptlib_int.h"
#include "internal/nelem.h"
#include "internal/thread_once.h"
#include "internal/provider.h"
DSO *module;
OSSL_provider_init_fn *init_function;
STACK_OF(INFOPAIR) *parameters;
+ OPENSSL_CTX *libctx; /* The library context this instance is in */
struct provider_store_st *store; /* The store this instance belongs to */
/* Provider side functions */
CRYPTOerr(CRYPTO_F_PROVIDER_STORE_NEW, ERR_R_INTERNAL_ERROR);
return NULL;
}
+ prov->libctx = ctx;
prov->store = store;
if(p->is_fallback)
ossl_provider_set_fallback(prov);
CRYPTO_THREAD_write_lock(store->lock);
if ((i = sk_OSSL_PROVIDER_find(store->providers, &tmpl)) == -1
|| (prov = sk_OSSL_PROVIDER_value(store->providers, i)) == NULL
- || !ossl_provider_upref(prov))
+ || !ossl_provider_up_ref(prov))
prov = NULL;
CRYPTO_THREAD_unlock(store->lock);
}
#ifndef HAVE_ATOMICS
|| (prov->refcnt_lock = CRYPTO_THREAD_lock_new()) == NULL
#endif
- || !ossl_provider_upref(prov) /* +1 One reference to be returned */
+ || !ossl_provider_up_ref(prov) /* +1 One reference to be returned */
|| (prov->name = OPENSSL_strdup(name)) == NULL) {
ossl_provider_free(prov);
CRYPTOerr(CRYPTO_F_PROVIDER_NEW, ERR_R_MALLOC_FAILURE);
return prov;
}
-int ossl_provider_upref(OSSL_PROVIDER *prov)
+int ossl_provider_up_ref(OSSL_PROVIDER *prov)
{
int ref = 0;
- CRYPTO_UP_REF(&prov->refcnt, &ref, prov->refcnt_lock);
+ if (CRYPTO_UP_REF(&prov->refcnt, &ref, prov->refcnt_lock) <= 0)
+ return 0;
return ref;
}
return NULL;
CRYPTO_THREAD_write_lock(store->lock);
- if (!ossl_provider_upref(prov)) { /* +1 One reference for the store */
+ if (!ossl_provider_up_ref(prov)) { /* +1 One reference for the store */
ossl_provider_free(prov); /* -1 Reference that was to be returned */
prov = NULL;
} else if (sk_OSSL_PROVIDER_push(store->providers, prov) == 0) {
ossl_provider_free(prov); /* -1 Reference that was to be returned */
prov = NULL;
} else {
+ prov->libctx = libctx;
prov->store = store;
}
CRYPTO_THREAD_unlock(store->lock);
* When that happens, the provider is inactivated.
*/
if (ref < 2 && prov->flag_initialized) {
+#ifndef FIPS_MODE
+ ossl_init_thread_deregister(prov);
+#endif
if (prov->teardown != NULL)
prov->teardown(prov->provctx);
prov->flag_initialized = 0;
/*
* Internal version that doesn't affect the store flags, and thereby avoid
* locking. Direct callers must remember to set the store flags when
- * appropriate. The libctx parameter is only necessary when FIPS_MODE is set
- * (i.e. we are being called from inside the FIPS module) - it is ignored for
- * other uses.
+ * appropriate.
*/
-static int provider_activate(OSSL_PROVIDER *prov, OPENSSL_CTX *libctx)
+static int provider_activate(OSSL_PROVIDER *prov)
{
const OSSL_DISPATCH *provider_dispatch = NULL;
#endif
}
- /*
- * We call the initialise function for the provider.
- *
- * If FIPS_MODE is defined then we are inside the FIPS module and are about
- * to recursively initialise ourselves. We need to do this so that we can
- * get all the provider callback functions set up in order for us to be able
- * to make EVP calls from within the FIPS module itself. Only algorithms
- * from the FIPS module itself are available via the FIPS module EVP
- * interface, i.e. we only ever have one provider available inside the FIPS
- * module - the FIPS provider itself.
- *
- * For modules in general we cannot know what value will be used for the
- * provctx - it is a "black box". But for the FIPS module we know that the
- * provctx is really a library context. We default the provctx value to the
- * same library context as was used for the EVP call that caused this call
- * to "provider_activate".
- */
-#ifdef FIPS_MODE
- prov->provctx = libctx;
-#endif
+ /* Call the initialise function for the provider. */
if (prov->init_function == NULL
|| !prov->init_function(prov, core_dispatch, &provider_dispatch,
&prov->provctx)) {
int ossl_provider_activate(OSSL_PROVIDER *prov)
{
- if (provider_activate(prov, NULL)) {
+ if (provider_activate(prov)) {
CRYPTO_THREAD_write_lock(prov->store->lock);
prov->store->use_fallbacks = 0;
CRYPTO_THREAD_unlock(prov->store->lock);
*/
if (prov->flag_fallback) {
activated_fallback_count++;
- provider_activate(prov, ctx);
+ provider_activate(prov);
}
}
? NULL : prov->get_param_types(prov->provctx);
}
-int ossl_provider_get_params(const OSSL_PROVIDER *prov,
- const OSSL_PARAM params[])
+int ossl_provider_get_params(const OSSL_PROVIDER *prov, OSSL_PARAM params[])
{
return prov->get_params == NULL
? 0 : prov->get_params(prov->provctx, params);
return param_types;
}
-static int core_get_params(const OSSL_PROVIDER *prov, const OSSL_PARAM params[])
+static int core_get_params(const OSSL_PROVIDER *prov, OSSL_PARAM params[])
{
int i;
- const OSSL_PARAM *p;
+ OSSL_PARAM *p;
if ((p = OSSL_PARAM_locate(params, "openssl-version")) != NULL)
OSSL_PARAM_set_utf8_ptr(p, OPENSSL_VERSION_STR);
return 1;
}
+static OSSL_core_get_library_context_fn core_get_libctx; /* Check */
+static OPENSSL_CTX *core_get_libctx(const OSSL_PROVIDER *prov)
+{
+ return prov->libctx;
+}
+
+static int core_thread_start(const OSSL_PROVIDER *prov,
+ OSSL_thread_stop_handler_fn handfn)
+{
+ return ossl_init_thread_start(prov, prov->provctx, handfn);
+}
+
static const OSSL_DISPATCH core_dispatch_[] = {
{ OSSL_FUNC_CORE_GET_PARAM_TYPES, (void (*)(void))core_get_param_types },
{ OSSL_FUNC_CORE_GET_PARAMS, (void (*)(void))core_get_params },
+ { OSSL_FUNC_CORE_GET_LIBRARY_CONTEXT, (void (*)(void))core_get_libctx },
+ { OSSL_FUNC_CORE_THREAD_START, (void (*)(void))core_thread_start },
{ OSSL_FUNC_CORE_PUT_ERROR, (void (*)(void))ERR_put_error },
{ OSSL_FUNC_CORE_ADD_ERROR_VDATA, (void (*)(void))ERR_add_error_vdata },
{ 0, NULL }