summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMatt Caswell <matt@openssl.org>2023-05-15 15:30:10 +0100
committerPauli <pauli@openssl.org>2023-06-02 07:30:04 +1000
commit61f11cad7a0dffc7abd234164a0e74c6ae8e7c2a (patch)
tree032a1d0ac0dc716d00bc1464f91e74ebb534f56c
parent189ad3ab2028babd39241015fc3975e8334c87eb (diff)
Enable obtaining certain DRBG params without a lock
Even if a DRBG has locking enabled on it, there are certain parameters which are still safe to obtain even without a lock. The max_request value is constant for all our DRBGs. The reseed_counter does not matter if we get it wrong - so it is safe to avoid the lock. So if all we are reading are those parameters then we take no lock at all. Partially fixes #20286 Reviewed-by: Tomas Mraz <tomas@openssl.org> Reviewed-by: Todd Short <todd.short@me.com> Reviewed-by: Paul Dale <pauli@openssl.org> (Merged from https://github.com/openssl/openssl/pull/20970)
-rw-r--r--providers/implementations/rands/drbg.c43
-rw-r--r--providers/implementations/rands/drbg_ctr.c8
-rw-r--r--providers/implementations/rands/drbg_hash.c8
-rw-r--r--providers/implementations/rands/drbg_hmac.c8
-rw-r--r--providers/implementations/rands/drbg_local.h2
5 files changed, 59 insertions, 10 deletions
diff --git a/providers/implementations/rands/drbg.c b/providers/implementations/rands/drbg.c
index 4b16873724..4690d73cca 100644
--- a/providers/implementations/rands/drbg.c
+++ b/providers/implementations/rands/drbg.c
@@ -893,10 +893,6 @@ int ossl_drbg_get_ctx_params(PROV_DRBG *drbg, OSSL_PARAM params[])
if (p != NULL && !OSSL_PARAM_set_int(p, drbg->strength))
return 0;
- p = OSSL_PARAM_locate(params, OSSL_RAND_PARAM_MAX_REQUEST);
- if (p != NULL && !OSSL_PARAM_set_size_t(p, drbg->max_request))
- return 0;
-
p = OSSL_PARAM_locate(params, OSSL_DRBG_PARAM_MIN_ENTROPYLEN);
if (p != NULL && !OSSL_PARAM_set_size_t(p, drbg->min_entropylen))
return 0;
@@ -933,10 +929,43 @@ int ossl_drbg_get_ctx_params(PROV_DRBG *drbg, OSSL_PARAM params[])
if (p != NULL && !OSSL_PARAM_set_time_t(p, drbg->reseed_time_interval))
return 0;
+ return 1;
+}
+
+/*
+ * Helper function to get certain params that require no lock to obtain. Sets
+ * *complete to 1 if all the params were processed, or 0 otherwise
+ */
+int ossl_drbg_get_ctx_params_no_lock(PROV_DRBG *drbg, OSSL_PARAM params[],
+ int *complete)
+{
+ size_t cnt = 0;
+ OSSL_PARAM *p;
+
+ /* This value never changes once set */
+ p = OSSL_PARAM_locate(params, OSSL_RAND_PARAM_MAX_REQUEST);
+ if (p != NULL) {
+ if (!OSSL_PARAM_set_size_t(p, drbg->max_request))
+ return 0;
+ cnt++;
+ }
+
+ /*
+ * Can be changed by multiple threads, but we tolerate inaccuracies in this
+ * value.
+ */
p = OSSL_PARAM_locate(params, OSSL_DRBG_PARAM_RESEED_COUNTER);
- if (p != NULL
- && !OSSL_PARAM_set_uint(p, tsan_load(&drbg->reseed_counter)))
- return 0;
+ if (p != NULL) {
+ if (!OSSL_PARAM_set_uint(p, tsan_load(&drbg->reseed_counter)))
+ return 0;
+ cnt++;
+ }
+
+ if (params[cnt].key == NULL)
+ *complete = 1;
+ else
+ *complete = 0;
+
return 1;
}
diff --git a/providers/implementations/rands/drbg_ctr.c b/providers/implementations/rands/drbg_ctr.c
index 40d7dbe86d..c303d03eb0 100644
--- a/providers/implementations/rands/drbg_ctr.c
+++ b/providers/implementations/rands/drbg_ctr.c
@@ -658,7 +658,13 @@ static int drbg_ctr_get_ctx_params(void *vdrbg, OSSL_PARAM params[])
PROV_DRBG *drbg = (PROV_DRBG *)vdrbg;
PROV_DRBG_CTR *ctr = (PROV_DRBG_CTR *)drbg->data;
OSSL_PARAM *p;
- int ret = 0;
+ int ret = 0, complete = 0;
+
+ if (!ossl_drbg_get_ctx_params_no_lock(drbg, params, &complete))
+ return 0;
+
+ if (complete)
+ return 1;
if (drbg->lock != NULL && !CRYPTO_THREAD_read_lock(drbg->lock))
return 0;
diff --git a/providers/implementations/rands/drbg_hash.c b/providers/implementations/rands/drbg_hash.c
index a911840c9b..bad20d00fe 100644
--- a/providers/implementations/rands/drbg_hash.c
+++ b/providers/implementations/rands/drbg_hash.c
@@ -463,7 +463,13 @@ static int drbg_hash_get_ctx_params(void *vdrbg, OSSL_PARAM params[])
PROV_DRBG_HASH *hash = (PROV_DRBG_HASH *)drbg->data;
const EVP_MD *md;
OSSL_PARAM *p;
- int ret = 0;
+ int ret = 0, complete = 0;
+
+ if (!ossl_drbg_get_ctx_params_no_lock(drbg, params, &complete))
+ return 0;
+
+ if (complete)
+ return 1;
if (drbg->lock != NULL && !CRYPTO_THREAD_read_lock(drbg->lock))
return 0;
diff --git a/providers/implementations/rands/drbg_hmac.c b/providers/implementations/rands/drbg_hmac.c
index 4c6482894b..3df0c2ac2b 100644
--- a/providers/implementations/rands/drbg_hmac.c
+++ b/providers/implementations/rands/drbg_hmac.c
@@ -356,7 +356,13 @@ static int drbg_hmac_get_ctx_params(void *vdrbg, OSSL_PARAM params[])
const char *name;
const EVP_MD *md;
OSSL_PARAM *p;
- int ret = 0;
+ int ret = 0, complete = 0;
+
+ if (!ossl_drbg_get_ctx_params_no_lock(drbg, params, &complete))
+ return 0;
+
+ if (complete)
+ return 1;
if (drbg->lock != NULL && !CRYPTO_THREAD_read_lock(drbg->lock))
return 0;
diff --git a/providers/implementations/rands/drbg_local.h b/providers/implementations/rands/drbg_local.h
index c3df1bc962..4c815ae2e6 100644
--- a/providers/implementations/rands/drbg_local.h
+++ b/providers/implementations/rands/drbg_local.h
@@ -222,6 +222,8 @@ OSSL_FUNC_rand_unlock_fn ossl_drbg_unlock;
/* Common parameters for all of our DRBGs */
int ossl_drbg_get_ctx_params(PROV_DRBG *drbg, OSSL_PARAM params[]);
+int ossl_drbg_get_ctx_params_no_lock(PROV_DRBG *drbg, OSSL_PARAM params[],
+ int *complete);
int ossl_drbg_set_ctx_params(PROV_DRBG *drbg, const OSSL_PARAM params[]);
#define OSSL_PARAM_DRBG_SETTABLE_CTX_COMMON \