Commit dd8ac62036 for openssl.org
commit dd8ac62036068437486ca5827adc14471204c182
Author: Neil Horman <nhorman@openssl.org>
Date: Wed Sep 23 12:42:35 2026 -0400
add new_provider_loaded methods to libctx
Add a integer field to the libctx which tracks weather or not we have
constructed methods in this libctx for every operation type.
Reviewed-by: Bob Beck <beck@openssl.org>
Reviewed-by: Nikola Pajkovsky <nikolap@openssl.org>
Merge-date: Mon Oct 26 19:25:23 2026
Merged-from: https://github.com/openssl/openssl/pull/32965
diff --git a/crypto/context.c b/crypto/context.c
index 66d7e42955..1c6fd03da8 100644
--- a/crypto/context.c
+++ b/crypto/context.c
@@ -53,6 +53,7 @@ struct ossl_lib_ctx_st {
int ischild;
int conf_diagnostics;
+ uint64_t new_provider_loaded;
};
int ossl_lib_ctx_write_lock(OSSL_LIB_CTX *ctx)
@@ -128,6 +129,9 @@ static int context_init(OSSL_LIB_CTX *ctx)
goto err;
exdata_done = 1;
+ if (!CRYPTO_atomic_store(&ctx->new_provider_loaded, UINT64_MAX, ctx->lock))
+ goto err;
+
/* P2. We want evp_method_store to be cleaned up before the provider store */
ctx->evp_method_store = ossl_method_store_new(ctx);
if (ctx->evp_method_store == NULL)
@@ -680,6 +684,43 @@ void *ossl_lib_ctx_get_data(OSSL_LIB_CTX *ctx, int index)
}
}
+int ossl_lib_ctx_get_new_providers_loaded(OSSL_LIB_CTX *ctx, int op)
+{
+ uint64_t ret = 0;
+
+ ctx = ossl_lib_ctx_get_concrete(ctx);
+
+ /*
+ * if the atomic read operation fails here, return 1 to pretend like new
+ * providers are loaded, it ensures that we behave as though there are
+ * new providers loaded if we fail.
+ */
+ if (!CRYPTO_atomic_load(&ctx->new_provider_loaded, &ret, ctx->lock))
+ return 1;
+ return !!(ret & (1ULL << op));
+}
+
+int ossl_lib_ctx_set_new_providers_loaded(OSSL_LIB_CTX *ctx)
+{
+ ctx = ossl_lib_ctx_get_concrete(ctx);
+
+ if (!CRYPTO_atomic_store(&ctx->new_provider_loaded, UINT64_MAX, ctx->lock))
+ return 0;
+ return 1;
+}
+
+int ossl_lib_ctx_clear_new_providers_loaded(OSSL_LIB_CTX *ctx, int op)
+{
+ uint64_t val = ~(1ULL << op);
+ uint64_t ret;
+
+ ctx = ossl_lib_ctx_get_concrete(ctx);
+
+ if (!CRYPTO_atomic_and(&ctx->new_provider_loaded, val, &ret, ctx->lock))
+ return 0;
+ return 1;
+}
+
void *OSSL_LIB_CTX_get_data(OSSL_LIB_CTX *ctx, int index)
{
return ossl_lib_ctx_get_data(ctx, index);
diff --git a/include/internal/cryptlib.h b/include/internal/cryptlib.h
index a6a38a53b9..f09d4dddc1 100644
--- a/include/internal/cryptlib.h
+++ b/include/internal/cryptlib.h
@@ -128,6 +128,9 @@ int ossl_lib_ctx_is_global_default(OSSL_LIB_CTX *ctx);
/* Functions to retrieve pointers to data by index */
void *ossl_lib_ctx_get_data(OSSL_LIB_CTX *, int /* index */);
+int ossl_lib_ctx_get_new_providers_loaded(OSSL_LIB_CTX *, int);
+int ossl_lib_ctx_set_new_providers_loaded(OSSL_LIB_CTX *);
+int ossl_lib_ctx_clear_new_providers_loaded(OSSL_LIB_CTX *, int);
void ossl_lib_ctx_default_deinit(void);
OSSL_EX_DATA_GLOBAL *ossl_lib_ctx_get_ex_data_global(OSSL_LIB_CTX *ctx);