diff --git a/crypto/provider_core.c b/crypto/provider_core.c index 36692b6ce4..d17ff93e16 100644 --- a/crypto/provider_core.c +++ b/crypto/provider_core.c @@ -340,9 +340,11 @@ static const OSSL_DISPATCH *core_dispatch; /* Define further down */ /* * Internal version that doesn't affect the store flags, and thereby avoid * locking. Direct callers must remember to set the store flags when - * appropriate + * 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. */ -static int provider_activate(OSSL_PROVIDER *prov) +static int provider_activate(OSSL_PROVIDER *prov, OPENSSL_CTX *libctx) { const OSSL_DISPATCH *provider_dispatch = NULL; @@ -397,6 +399,26 @@ static int provider_activate(OSSL_PROVIDER *prov) #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 if (prov->init_function == NULL || !prov->init_function(prov, core_dispatch, &provider_dispatch, &prov->provctx)) { @@ -438,7 +460,7 @@ static int provider_activate(OSSL_PROVIDER *prov) int ossl_provider_activate(OSSL_PROVIDER *prov) { - if (provider_activate(prov)) { + if (provider_activate(prov, NULL)) { CRYPTO_THREAD_write_lock(prov->store->lock); prov->store->use_fallbacks = 0; CRYPTO_THREAD_unlock(prov->store->lock); @@ -515,7 +537,7 @@ int ossl_provider_forall_loaded(OPENSSL_CTX *ctx, */ if (prov->flag_fallback) { activated_fallback_count++; - provider_activate(prov); + provider_activate(prov, ctx); } } diff --git a/providers/fips/fipsprov.c b/providers/fips/fipsprov.c index 801a9fd045..7842f90f76 100644 --- a/providers/fips/fipsprov.c +++ b/providers/fips/fipsprov.c @@ -178,7 +178,14 @@ int OSSL_provider_init(const OSSL_PROVIDER *provider, /* * The internal init function used when the FIPS module uses EVP to call - * another algorithm also in the FIPS module. + * another algorithm also in the FIPS module. This is a recursive call that has + * been made from within the FIPS module itself. Normally we are responsible for + * providing our own provctx value, but in this recursive case it has been + * pre-populated for us with the same library context that was used in the EVP + * call that initiated this recursive call - so we don't need to do anything + * further with that parameter. This only works because we *know* in the core + * code that the FIPS module uses a library context for its provctx. This is + * not generally true for all providers. */ OSSL_provider_init_fn fips_intern_provider_init; int fips_intern_provider_init(const OSSL_PROVIDER *provider,