[openssl] master update

Dr. Paul Dale pauli at openssl.org
Fri May 7 13:54:20 UTC 2021


The branch master has been updated
       via  9b53932b6fb359ad2063a640a3db3d2c5f44cfaa (commit)
       via  4ed1f0bc70955c1f9874b761777937e2962db382 (commit)
       via  2876528de594308df43301a5f282e7eec69b8ff5 (commit)
       via  ced7df26382e7b1713ac6662958933d31151b4b8 (commit)
       via  0090e50890ce7691f7d6ba4a301b17c2ce58a204 (commit)
      from  43d78564990a685f60e2fc0ab009735161d07434 (commit)


- Log -----------------------------------------------------------------
commit 9b53932b6fb359ad2063a640a3db3d2c5f44cfaa
Author: Pauli <pauli at openssl.org>
Date:   Fri May 7 23:51:27 2021 +1000

    FIPS checksum update
    
    Reviewed-by: Matt Caswell <matt at openssl.org>
    (Merged from https://github.com/openssl/openssl/pull/15042)

commit 4ed1f0bc70955c1f9874b761777937e2962db382
Author: Pauli <pauli at openssl.org>
Date:   Wed May 5 20:47:02 2021 +1000

    provider: use a read lock when looking for a provider
    
    Reviewed-by: Matt Caswell <matt at openssl.org>
    (Merged from https://github.com/openssl/openssl/pull/15042)

commit 2876528de594308df43301a5f282e7eec69b8ff5
Author: Pauli <pauli at openssl.org>
Date:   Wed May 5 11:22:08 2021 +1000

    doc: document the new ossl_provider_clear_all_operation_bits() function
    
    Reviewed-by: Matt Caswell <matt at openssl.org>
    (Merged from https://github.com/openssl/openssl/pull/15042)

commit ced7df26382e7b1713ac6662958933d31151b4b8
Author: Pauli <pauli at openssl.org>
Date:   Tue Apr 27 15:29:16 2021 +1000

    test: add a provider load/unload cache flush test.
    
    Reviewed-by: Matt Caswell <matt at openssl.org>
    (Merged from https://github.com/openssl/openssl/pull/15042)

commit 0090e50890ce7691f7d6ba4a301b17c2ce58a204
Author: Pauli <pauli at openssl.org>
Date:   Tue Apr 27 15:17:25 2021 +1000

    provider: flush the store cache when providers are loaded/unloaded.
    
    When the providers change, the method cache needs to be flushed.  This also
    impacts the cache is full partial flushes and the algorithm flushing by ID.
    
    A new function is introduced to clear all of the operation bits in all
    providers in a library context.
    
    Fixes #15032
    
    Reviewed-by: Matt Caswell <matt at openssl.org>
    (Merged from https://github.com/openssl/openssl/pull/15042)

-----------------------------------------------------------------------

Summary of changes:
 crypto/property/property.c              |  5 ++
 crypto/provider_core.c                  | 95 +++++++++++++++++++++++++++------
 doc/internal/man3/ossl_provider_new.pod | 10 +++-
 include/internal/provider.h             |  1 +
 providers/fips-sources.checksums        |  4 +-
 providers/fips.checksum                 |  2 +-
 test/provider_internal_test.c           | 38 +++++++++++++
 7 files changed, 134 insertions(+), 21 deletions(-)

diff --git a/crypto/property/property.c b/crypto/property/property.c
index b120dbe460..2b841a2204 100644
--- a/crypto/property/property.c
+++ b/crypto/property/property.c
@@ -12,7 +12,9 @@
 #include <stdio.h>
 #include <stdarg.h>
 #include <openssl/crypto.h>
+#include "internal/core.h"
 #include "internal/property.h"
+#include "internal/provider.h"
 #include "crypto/ctype.h"
 #include <openssl/lhash.h>
 #include <openssl/rand.h>
@@ -425,6 +427,7 @@ static void ossl_method_cache_flush(OSSL_METHOD_STORE *store, int nid)
     ALGORITHM *alg = ossl_method_store_retrieve(store, nid);
 
     if (alg != NULL) {
+        ossl_provider_clear_all_operation_bits(store->ctx);
         store->nelem -= lh_QUERY_num_items(alg->cache);
         impl_cache_flush_alg(0, alg, NULL);
     }
@@ -436,6 +439,7 @@ int ossl_method_store_flush_cache(OSSL_METHOD_STORE *store, int all)
 
     if (!ossl_property_write_lock(store))
         return 0;
+    ossl_provider_clear_all_operation_bits(store->ctx);
     ossl_sa_ALGORITHM_doall_arg(store->algs, &impl_cache_flush_alg, arg);
     store->nelem = 0;
     ossl_property_unlock(store);
@@ -500,6 +504,7 @@ static void ossl_method_cache_flush_some(OSSL_METHOD_STORE *store)
     state.nelem = 0;
     if ((state.seed = OPENSSL_rdtsc()) == 0)
         state.seed = 1;
+    ossl_provider_clear_all_operation_bits(store->ctx);
     store->need_flush = 0;
     ossl_sa_ALGORITHM_doall_arg(store->algs, &impl_cache_flush_one_alg, &state);
     store->nelem = state.nelem;
diff --git a/crypto/provider_core.c b/crypto/provider_core.c
index 1ef2cd5ca7..c419e6f644 100644
--- a/crypto/provider_core.c
+++ b/crypto/provider_core.c
@@ -116,6 +116,7 @@ struct provider_store_st {
     CRYPTO_RWLOCK *lock;
     char *default_path;
     unsigned int use_fallbacks:1;
+    unsigned int freeing:1;
 };
 
 /*
@@ -137,6 +138,7 @@ static void provider_store_free(void *vstore)
 
     if (store == NULL)
         return;
+    store->freeing = 1;
     OPENSSL_free(store->default_path);
     sk_OSSL_PROVIDER_pop_free(store->providers, provider_deactivate_free);
     CRYPTO_THREAD_lock_free(store->default_path_lock);
@@ -236,7 +238,7 @@ OSSL_PROVIDER *ossl_provider_find(OSSL_LIB_CTX *libctx, const char *name,
 #endif
 
         tmpl.name = (char *)name;
-        if (!CRYPTO_THREAD_write_lock(store->lock))
+        if (!CRYPTO_THREAD_read_lock(store->lock))
             return NULL;
         if ((i = sk_OSSL_PROVIDER_find(store->providers, &tmpl)) == -1
             || (prov = sk_OSSL_PROVIDER_value(store->providers, i)) == NULL
@@ -676,44 +678,76 @@ static int provider_init(OSSL_PROVIDER *prov, int flag_lock)
     return ok;
 }
 
+/*
+ * Deactivate a provider.
+ * Return -1 on failure and the activation count on success
+ */
 static int provider_deactivate(OSSL_PROVIDER *prov)
 {
+    int count;
+
     if (!ossl_assert(prov != NULL))
-        return 0;
+        return -1;
 
     if (!CRYPTO_THREAD_write_lock(prov->flag_lock))
-        return 0;
+        return -1;
 
-    if (--prov->activatecnt < 1)
+    if ((count = --prov->activatecnt) < 1)
         prov->flag_activated = 0;
 
     CRYPTO_THREAD_unlock(prov->flag_lock);
 
     /* We don't deinit here, that's done in ossl_provider_free() */
-    return 1;
+    return count;
 }
 
+/*
+ * Activate a provider.
+ * Return -1 on failure and the activation count on success
+ */
 static int provider_activate(OSSL_PROVIDER *prov, int flag_lock)
 {
+    int count;
+
     if (provider_init(prov, flag_lock)) {
         if (flag_lock && !CRYPTO_THREAD_write_lock(prov->flag_lock))
-            return 0;
-        prov->activatecnt++;
+            return -1;
+        count = ++prov->activatecnt;
         prov->flag_activated = 1;
         if (flag_lock)
             CRYPTO_THREAD_unlock(prov->flag_lock);
 
-        return 1;
+        return count;
     }
 
-    return 0;
+    return -1;
+}
+
+static int provider_flush_store_cache(const OSSL_PROVIDER *prov)
+{
+    struct provider_store_st *store;
+    int freeing;
+
+    if ((store = get_provider_store(prov->libctx)) == NULL)
+        return 0;
+
+    if (!CRYPTO_THREAD_read_lock(store->lock))
+        return 0;
+    freeing = store->freeing;
+    CRYPTO_THREAD_unlock(store->lock);
+
+    if (!freeing)
+        return evp_method_store_flush(prov->libctx);
+    return 1;
 }
 
 int ossl_provider_activate(OSSL_PROVIDER *prov, int retain_fallbacks)
 {
+    int count;
+
     if (prov == NULL)
         return 0;
-    if (provider_activate(prov, 1)) {
+    if ((count = provider_activate(prov, 1)) > 0) {
         if (!retain_fallbacks) {
             if (!CRYPTO_THREAD_write_lock(prov->store->lock)) {
                 provider_deactivate(prov);
@@ -722,16 +756,18 @@ int ossl_provider_activate(OSSL_PROVIDER *prov, int retain_fallbacks)
             prov->store->use_fallbacks = 0;
             CRYPTO_THREAD_unlock(prov->store->lock);
         }
-        return 1;
+        return count == 1 ? provider_flush_store_cache(prov) : 1;
     }
     return 0;
 }
 
 int ossl_provider_deactivate(OSSL_PROVIDER *prov)
 {
-    if (prov == NULL)
+    int count;
+
+    if (prov == NULL || (count = provider_deactivate(prov)) < 0)
         return 0;
-    return provider_deactivate(prov);
+    return count == 0 ? provider_flush_store_cache(prov) : 1;
 }
 
 void *ossl_provider_ctx(const OSSL_PROVIDER *prov)
@@ -773,7 +809,7 @@ static void provider_activate_fallbacks(struct provider_store_st *store)
 
         if (ossl_provider_up_ref(prov)) {
             if (prov->flag_fallback) {
-                if (provider_activate(prov, 1))
+                if (provider_activate(prov, 1) > 0)
                     activated_fallback_count++;
             }
             ossl_provider_free(prov);
@@ -843,7 +879,7 @@ int ossl_provider_doall_activated(OSSL_LIB_CTX *ctx,
              * It's already activated, but we up the activated count to ensure
              * it remains activated until after we've called the user callback.
              */
-            if (!provider_activate(prov, 0)) {
+            if (provider_activate(prov, 0) < 0) {
                 ossl_provider_free(prov);
                 CRYPTO_THREAD_unlock(prov->flag_lock);
                 goto err_unlock;
@@ -984,7 +1020,7 @@ int ossl_provider_self_test(const OSSL_PROVIDER *prov)
         return 1;
     ret = prov->self_test(prov->provctx);
     if (ret == 0)
-        (void)evp_method_store_flush(ossl_provider_libctx(prov));
+        (void)provider_flush_store_cache(prov);
     return ret;
 }
 
@@ -1022,6 +1058,33 @@ void ossl_provider_unquery_operation(const OSSL_PROVIDER *prov,
         prov->unquery_operation(prov->provctx, operation_id, algs);
 }
 
+int ossl_provider_clear_all_operation_bits(OSSL_LIB_CTX *libctx)
+{
+    struct provider_store_st *store;
+    OSSL_PROVIDER *provider;
+    int i, num, res = 1;
+
+    if ((store = get_provider_store(libctx)) != NULL) {
+        if (!CRYPTO_THREAD_read_lock(store->lock))
+            return 0;
+        num = sk_OSSL_PROVIDER_num(store->providers);
+        for (i = 0; i < num; i++) {
+            provider = sk_OSSL_PROVIDER_value(store->providers, i);
+            if (!CRYPTO_THREAD_write_lock(provider->opbits_lock)) {
+                res = 0;
+                continue;
+            }
+            if (provider->operation_bits != NULL)
+                memset(provider->operation_bits, 0,
+                       provider->operation_bits_sz);
+            CRYPTO_THREAD_unlock(provider->opbits_lock);
+        }
+        CRYPTO_THREAD_unlock(store->lock);
+        return res;
+    }
+    return 0;
+}
+
 int ossl_provider_set_operation_bit(OSSL_PROVIDER *provider, size_t bitnum)
 {
     size_t byte = bitnum / 8;
diff --git a/doc/internal/man3/ossl_provider_new.pod b/doc/internal/man3/ossl_provider_new.pod
index 8506839dee..e83869a9de 100644
--- a/doc/internal/man3/ossl_provider_new.pod
+++ b/doc/internal/man3/ossl_provider_new.pod
@@ -13,7 +13,7 @@ ossl_provider_name, ossl_provider_dso,
 ossl_provider_module_name, ossl_provider_module_path,
 ossl_provider_libctx,
 ossl_provider_teardown, ossl_provider_gettable_params,
-ossl_provider_get_params,
+ossl_provider_get_params, ossl_provider_clear_all_operation_bits,
 ossl_provider_query_operation, ossl_provider_unquery_operation,
 ossl_provider_set_operation_bit, ossl_provider_test_operation_bit,
 ossl_provider_get_capabilities
@@ -80,6 +80,7 @@ ossl_provider_get_capabilities
  int ossl_provider_set_operation_bit(OSSL_PROVIDER *provider, size_t bitnum);
  int ossl_provider_test_operation_bit(OSSL_PROVIDER *provider, size_t bitnum,
                                       int *result);
+ int ossl_provider_clear_all_operation_bits(OSSL_LIB_CTX *libctx);
 
 =head1 DESCRIPTION
 
@@ -245,10 +246,13 @@ that all relevant information has been copied.
 ossl_provider_set_operation_bit() registers a 1 for operation I<bitnum>
 in a bitstring that's internal to I<provider>.
 
-ossl_provider_tests_operation_bit() checks if the bit operation I<bitnum>
+ossl_provider_test_operation_bit() checks if the bit operation I<bitnum>
 is set (1) or not (0) in the internal I<provider> bitstring, and sets
 I<*result> to 1 or 0 accorddingly. 
 
+ossl_provider_clear_all_operation_bits() clears all of the operation bits
+to (0) for all providers in the library context I<libctx>.
+
 =head1 NOTES
 
 Locating a provider module happens as follows:
@@ -319,6 +323,8 @@ If this function isn't available in the provider, 0 is returned.
 ossl_provider_set_operation_bit() and ossl_provider_test_operation_bit()
 return 1 on success, or 0 on error.
 
+ossl_provider_clear_all_operation_bits() returns 1 on success, or 0 on error.
+
 ossl_provider_get_capabilities() returns 1 on success, or 0 on error.
 If this function isn't available in the provider or the provider does not
 support the requested capability then 0 is returned.
diff --git a/include/internal/provider.h b/include/internal/provider.h
index b755f17325..64fe2f1178 100644
--- a/include/internal/provider.h
+++ b/include/internal/provider.h
@@ -91,6 +91,7 @@ void ossl_provider_unquery_operation(const OSSL_PROVIDER *prov,
 int ossl_provider_set_operation_bit(OSSL_PROVIDER *provider, size_t bitnum);
 int ossl_provider_test_operation_bit(OSSL_PROVIDER *provider, size_t bitnum,
                                      int *result);
+int ossl_provider_clear_all_operation_bits(OSSL_LIB_CTX *libctx);
 
 /* Configuration */
 void ossl_provider_add_conf_module(void);
diff --git a/providers/fips-sources.checksums b/providers/fips-sources.checksums
index 7d924a1d74..01968b7e6f 100644
--- a/providers/fips-sources.checksums
+++ b/providers/fips-sources.checksums
@@ -237,10 +237,10 @@ c2fe815fb3fd5efe9a6544cae55f9469063a0f6fb728361737b927f6182ae0bb  crypto/param_b
 d0f6af3e89a693f0327e1bf073666cbec6786220ef3b3688ef0be9539d5ab6bf  crypto/params_from_text.c
 0dd202ec1def47c12852a8ae4bfaadb74f7fe968d68def631fe3ac671aac943f  crypto/passphrase.c
 098d0722daac442b8b6a6fc0aa6c4a4c49f9329426c3e2db9ebf71fe32376e4c  crypto/property/defn_cache.c
-737b1c67d0ee94f084d4b53d06c9561e10b802ddd61cada41f4ca2b7a9f8b4d1  crypto/property/property.c
+87cb2235e335046e04a563551cceb452e2eaf338123f482e76a037e4ffae0902  crypto/property/property.c
 51bc907d992893f03f35774178d2c8dc98cf3cf9503ff839ee1561640e6b274a  crypto/property/property_parse.c
 4941717698573a86d589fbec5002471cb4011e9a1840111a3ddccecc861a3af5  crypto/property/property_string.c
-b02ed771d70b1d2faf17bc3de261e8dfe67d847aa38fd65e1712491ea540d968  crypto/provider_core.c
+8bf84eeb85a16128170eb295c77245c8ba4ecf25fa4d2be907a612245e4b8b24  crypto/provider_core.c
 3ebbf42baa3722f86298960c7b14b49cefc25c38fce326a0c4666546539da231  crypto/provider_predefined.c
 4fec006dc82d1bc5c03aa1b6d011b670bed67fad12b73823eb6767afc4f241f3  crypto/rand/rand_lib.c
 f19876a1ff4ab97f22a926cc59c9ced0cdde69ad2c45ecf546d91104ec5b0dde  crypto/rand/rand_meth.c
diff --git a/providers/fips.checksum b/providers/fips.checksum
index 37b689fe20..e5ff9a8040 100644
--- a/providers/fips.checksum
+++ b/providers/fips.checksum
@@ -1 +1 @@
-701feb062161f63a81338d74c0837f79dee9b5e793778576b750e2037ba136bf  providers/fips-sources.checksums
+2e67c3ed3222fedf2d26e91f47b2b7708a95f39a74bd1489412f324f84daa57d  providers/fips-sources.checksums
diff --git a/test/provider_internal_test.c b/test/provider_internal_test.c
index aeb38339fa..7bf2b8e272 100644
--- a/test/provider_internal_test.c
+++ b/test/provider_internal_test.c
@@ -85,6 +85,43 @@ static int test_configured_provider(void)
 }
 #endif
 
+static int test_cache_flushes(void)
+{
+    OSSL_LIB_CTX *ctx;
+    OSSL_PROVIDER *prov = NULL;
+    EVP_MD *md = NULL;
+    int ret = 0;
+
+    if (!TEST_ptr(ctx = OSSL_LIB_CTX_new())
+            || !TEST_ptr(prov = OSSL_PROVIDER_load(ctx, "default"))
+            || !TEST_true(OSSL_PROVIDER_available(ctx, "default"))
+            || !TEST_ptr(md = EVP_MD_fetch(ctx, "SHA256", NULL)))
+        goto err;
+    EVP_MD_free(md);
+    md = NULL;
+    OSSL_PROVIDER_unload(prov);
+    prov = NULL;
+
+    if (!TEST_false(OSSL_PROVIDER_available(ctx, "default")))
+        goto err;
+
+    if (!TEST_ptr_null(md = EVP_MD_fetch(ctx, "SHA256", NULL))) {
+        const char *provname = OSSL_PROVIDER_name(EVP_MD_provider(md));
+
+        if (OSSL_PROVIDER_available(NULL, provname))
+            TEST_info("%s provider is available\n", provname);
+        else
+            TEST_info("%s provider is not available\n", provname);
+    }
+
+    ret = 1;
+ err:
+    OSSL_PROVIDER_unload(prov);
+    EVP_MD_free(md);
+    OSSL_LIB_CTX_free(ctx);
+    return ret;
+}
+
 int setup_tests(void)
 {
     ADD_TEST(test_builtin_provider);
@@ -92,6 +129,7 @@ int setup_tests(void)
     ADD_TEST(test_loaded_provider);
     ADD_TEST(test_configured_provider);
 #endif
+    ADD_TEST(test_cache_flushes);
     return 1;
 }
 


More information about the openssl-commits mailing list