[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