Commit 4fa139e357 for openssl.org

commit 4fa139e357411eba4c5c50888033792ed3ee3076
Author: Neil Horman <nhorman@openssl.org>
Date:   Wed Sep 23 13:17:05 2026 -0400

    Check provider status and, if unmodified, fetch from store

    In ossl_method_construct() check the libctx state to see if any new
    providers have been loaded since last time we constructed a method of
    the requested type.  If nothing new has been loaded, we can query the
    method_store now and avoid the expensive construction.  If not, we do
    the full construction path, and inform the libctx that we've done a
    construction on this operation type since the last provider load.

    Note the non-cahing corner case here.  If we don't find something in the
    method store, even in the fast path, then its likely unfindable, or its
    just non-cachable, in which case we still have to do the full
    construction.

    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/core_fetch.c b/crypto/core_fetch.c
index 2abd32255c..d0a39af4cd 100644
--- a/crypto/core_fetch.c
+++ b/crypto/core_fetch.c
@@ -148,8 +148,36 @@ void *ossl_method_construct(OSSL_LIB_CTX *libctx, int operation_id,
      * ossl_method_construct_postcondition() make sure that the
      * ossl_algorithm_do_all() does very little when methods from
      * a provider have already been constructed.
+     * We can however, check to see if no new providers have been loaded
+     * since the last time we entered this function.  If no new providers have
+     * been loaded then either:
+     * a) It should be in the store, and we can fetch it
+     * or
+     * b) It won't be there (indicating it was non-cachable, and we have to do the
+     * fetch still
      */

+    if (!ossl_lib_ctx_get_new_providers_loaded(libctx, operation_id)) {
+        /*
+         * We've already gone through the full construction path for this
+         * operation type since last we modified our providers list.  Lets
+         * Try get it from the store
+         */
+        method = mcm->get(NULL, (const OSSL_PROVIDER **)provider_rw, mcm_data);
+        if (method != NULL)
+            return method;
+        /*
+         * If we didn't find a method, this must be a non-cachable alg, and
+         * we have to take the very slow path below
+         */
+    } else {
+        /*
+         * We're about to run the full construction for this operation type
+         * Mark us has having done that in the libctx
+         */
+        ossl_lib_ctx_clear_new_providers_loaded(libctx, operation_id);
+    }
+
     cbdata.store = NULL;
     cbdata.force_store = force_store;
     cbdata.mcm = mcm;