diff --git a/providers/implementations/rands/drbg.c b/providers/implementations/rands/drbg.c index 4b16873724249..4690d73cca918 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 40d7dbe86d622..c303d03eb0ad2 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 a911840c9b15a..bad20d00fe076 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 4c6482894bba8..3df0c2ac2b007 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 c3df1bc962779..4c815ae2e67b7 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 \