Commit 71ec72702b for openssl.org
commit 71ec72702be26ef9130530624fada6038e59fc01
Author: Neil Horman <nhorman@openssl.org>
Date: Thu Jul 23 17:53:43 2026 -0400
Rework how to fetch components in the drbg
Commit c9a2ce61118c7f73bc4898eedec64c2bde8bb7a0 introduced some code
into the drbg in an effort to get it to select the same provider as is
specified for the drbg. Unfortunately this creates a problem when a
user has altered the identity of a predefined provider (in this case
fips).
The DRBG is passed a set of parameters when instantiating, which
includes the name of the provider. This provider uses the name that the
core knows it as, which may be different than "fips", which the fips
provider always referrs to itself as.
Fix it by skipping the provider name check when operating in the fips
module, as we should only ever get fips approved algs from within that
space
Fixes a customer issue, who noted that since this was introduced, using
identity configurations no longer works.
Reviewed-by: Bob Beck <beck@openssl.org>
Reviewed-by: Simo Sorce <simo@redhat.com>
MergeDate: Wed Aug 12 19:26:01 2026
(Merged from https://github.com/openssl/openssl/pull/32060)
diff --git a/crypto/rand/rand_lib.c b/crypto/rand/rand_lib.c
index 8d4977a1de..a58b0bb9ef 100644
--- a/crypto/rand/rand_lib.c
+++ b/crypto/rand/rand_lib.c
@@ -632,7 +632,6 @@ static EVP_RAND_CTX *rand_new_drbg(OSSL_LIB_CTX *libctx, EVP_RAND_CTX *parent,
EVP_RAND_CTX *ctx;
OSSL_PARAM params[9], *p = params;
const OSSL_PARAM *settables;
- const char *prov_name;
char *name, *cipher;
int use_df = 1;
@@ -644,7 +643,6 @@ static EVP_RAND_CTX *rand_new_drbg(OSSL_LIB_CTX *libctx, EVP_RAND_CTX *parent,
ERR_raise(ERR_LIB_RAND, RAND_R_UNABLE_TO_FETCH_DRBG);
return NULL;
}
- prov_name = ossl_provider_name(EVP_RAND_get0_provider(rand));
ctx = EVP_RAND_CTX_new(rand, parent);
EVP_RAND_free(rand);
if (ctx == NULL) {
@@ -662,9 +660,6 @@ static EVP_RAND_CTX *rand_new_drbg(OSSL_LIB_CTX *libctx, EVP_RAND_CTX *parent,
&& OSSL_PARAM_locate_const(settables, OSSL_DRBG_PARAM_DIGEST))
*p++ = OSSL_PARAM_construct_utf8_string(OSSL_DRBG_PARAM_DIGEST,
dgbl->rng_digest, 0);
- if (prov_name != NULL)
- *p++ = OSSL_PARAM_construct_utf8_string(OSSL_PROV_PARAM_CORE_PROV_NAME,
- (char *)prov_name, 0);
if (dgbl->rng_propq != NULL)
*p++ = OSSL_PARAM_construct_utf8_string(OSSL_DRBG_PARAM_PROPERTIES,
dgbl->rng_propq, 0);
diff --git a/providers/implementations/rands/drbg_ctr.c b/providers/implementations/rands/drbg_ctr.c
index 44237c0f1f..77a0a6a8aa 100644
--- a/providers/implementations/rands/drbg_ctr.c
+++ b/providers/implementations/rands/drbg_ctr.c
@@ -738,7 +738,6 @@ static int drbg_ctr_set_ctx_params_locked(PROV_DRBG *ctx,
{
PROV_DRBG_CTR *ctr = (PROV_DRBG_CTR *)ctx->data;
OSSL_LIB_CTX *libctx = PROV_LIBCTX_OF(ctx->provctx);
- OSSL_PROVIDER *prov = NULL;
char *ecb;
const char *propquery = NULL;
int i, cipher_init = 0;
@@ -749,20 +748,12 @@ static int drbg_ctr_set_ctx_params_locked(PROV_DRBG *ctx,
cipher_init = 1;
}
- if (p->propq != NULL) {
- if (p->propq->data_type != OSSL_PARAM_UTF8_STRING)
- return 0;
+#ifndef FIPS_MODULE
+ propquery = "provider=default";
+ if (p->propq != NULL
+ && p->propq->data_type == OSSL_PARAM_UTF8_STRING)
propquery = (const char *)p->propq->data;
- }
-
- if (p->prov != NULL) {
- if (p->prov->data_type != OSSL_PARAM_UTF8_STRING)
- return 0;
- if ((prov = ossl_provider_find(libctx,
- (const char *)p->prov->data, 1))
- == NULL)
- return 0;
- }
+#endif
if (p->cipher != NULL) {
const char *base = (const char *)p->cipher->data;
@@ -771,50 +762,33 @@ static int drbg_ctr_set_ctx_params_locked(PROV_DRBG *ctx,
if (p->cipher->data_type != OSSL_PARAM_UTF8_STRING
|| p->cipher->data_size < ctr_str_len) {
- ossl_provider_free(prov);
return 0;
}
if (OPENSSL_strcasecmp("CTR", base + p->cipher->data_size - ctr_str_len) != 0) {
ERR_raise(ERR_LIB_PROV, PROV_R_REQUIRE_CTR_MODE_CIPHER);
- ossl_provider_free(prov);
return 0;
}
if ((ecb = OPENSSL_strndup(base, p->cipher->data_size)) == NULL) {
- ossl_provider_free(prov);
return 0;
}
strcpy(ecb + p->cipher->data_size - ecb_str_len, "ECB");
EVP_CIPHER_free(ctr->cipher_ecb);
EVP_CIPHER_free(ctr->cipher_ctr);
+ ctr->cipher_ctr = NULL;
+ ctr->cipher_ecb = NULL;
/*
* Try to fetch algorithms from our own provider code, fallback
* to generic fetch only if that fails
*/
- (void)ERR_set_mark();
- ctr->cipher_ctr = evp_cipher_fetch_from_prov(prov, base, NULL);
- if (ctr->cipher_ctr == NULL) {
- (void)ERR_pop_to_mark();
- ctr->cipher_ctr = EVP_CIPHER_fetch(libctx, base, propquery);
- } else {
- (void)ERR_clear_last_mark();
- }
- (void)ERR_set_mark();
- ctr->cipher_ecb = evp_cipher_fetch_from_prov(prov, ecb, NULL);
- if (ctr->cipher_ecb == NULL) {
- (void)ERR_pop_to_mark();
- ctr->cipher_ecb = EVP_CIPHER_fetch(libctx, ecb, propquery);
- } else {
- (void)ERR_clear_last_mark();
- }
+ ctr->cipher_ctr = EVP_CIPHER_fetch(libctx, base, propquery);
+ ctr->cipher_ecb = EVP_CIPHER_fetch(libctx, ecb, propquery);
OPENSSL_free(ecb);
if (ctr->cipher_ctr == NULL || ctr->cipher_ecb == NULL) {
ERR_raise(ERR_LIB_PROV, PROV_R_UNABLE_TO_FIND_CIPHERS);
- ossl_provider_free(prov);
return 0;
}
cipher_init = 1;
}
- ossl_provider_free(prov);
if (cipher_init && !drbg_ctr_init(ctx))
return 0;
diff --git a/providers/implementations/rands/drbg_hash.c b/providers/implementations/rands/drbg_hash.c
index d024336d58..4188c29381 100644
--- a/providers/implementations/rands/drbg_hash.c
+++ b/providers/implementations/rands/drbg_hash.c
@@ -525,18 +525,21 @@ static const OSSL_PARAM *drbg_hash_gettable_ctx_params(ossl_unused void *vctx,
static int drbg_fetch_digest_from_prov(const struct drbg_set_ctx_params_st *p,
OSSL_LIB_CTX *libctx,
- EVP_MD **digest)
+ EVP_MD **digest,
+ const char *propq)
{
- OSSL_PROVIDER *prov = NULL;
EVP_MD *md = NULL;
int ret = 0;
+ const char *propquery = NULL;
- if (digest == NULL)
- return 0;
+#ifndef FIPS_MODULE
+ if (propq == NULL)
+ propquery = "provider=default";
+ else
+ propquery = propq;
+#endif
- if (p->prov == NULL || p->prov->data_type != OSSL_PARAM_UTF8_STRING)
- return 0;
- if ((prov = ossl_provider_find(libctx, (const char *)p->prov->data, 1)) == NULL)
+ if (digest == NULL)
return 0;
if (p->digest == NULL) {
@@ -547,15 +550,13 @@ static int drbg_fetch_digest_from_prov(const struct drbg_set_ctx_params_st *p,
if (p->digest->data_type != OSSL_PARAM_UTF8_STRING)
goto done;
- md = evp_digest_fetch_from_prov(prov, (const char *)p->digest->data, NULL);
+ md = EVP_MD_fetch(libctx, p->digest->data, propquery);
if (md) {
EVP_MD_free(*digest);
*digest = md;
ret = 1;
}
-
done:
- ossl_provider_free(prov);
return ret;
}
@@ -572,7 +573,8 @@ static int drbg_hash_set_ctx_params_locked(PROV_DRBG *ctx, const struct drbg_set
/* try to fetch digest from provider */
(void)ERR_set_mark();
- if (!drbg_fetch_digest_from_prov(p, libctx, &prov_md)) {
+ if (!drbg_fetch_digest_from_prov(p, libctx, &prov_md,
+ (p->propq != NULL && p->propq->data_type == OSSL_PARAM_UTF8_STRING) ? p->propq->data : NULL)) {
(void)ERR_pop_to_mark();
/* fall back to full implementation search */
if (!ossl_prov_digest_load(&hash->digest, p->digest, p->propq, libctx))
diff --git a/providers/implementations/rands/drbg_hmac.c b/providers/implementations/rands/drbg_hmac.c
index 371767acb2..c576eecdef 100644
--- a/providers/implementations/rands/drbg_hmac.c
+++ b/providers/implementations/rands/drbg_hmac.c
@@ -418,25 +418,26 @@ static const OSSL_PARAM *drbg_hmac_gettable_ctx_params(ossl_unused void *vctx,
static int drbg_fetch_algs_from_prov(const struct drbg_set_ctx_params_st *p,
OSSL_LIB_CTX *libctx,
EVP_MAC_CTX **macctx,
- EVP_MD **digest)
+ EVP_MD **digest, const char *propq)
{
- OSSL_PROVIDER *prov = NULL;
EVP_MD *md = NULL;
int ret = 0;
+ const char *propquery = NULL;
- if (macctx == NULL || digest == NULL)
- return 0;
+#ifndef FIPS_MODULE
+ if (propq == NULL)
+ propquery = "provider=default";
+ else
+ propquery = propq;
+#endif
- if (p->prov == NULL || p->prov->data_type != OSSL_PARAM_UTF8_STRING)
- return 0;
- if ((prov = ossl_provider_find(libctx, (const char *)p->prov->data, 1)) == NULL)
+ if (macctx == NULL || digest == NULL)
return 0;
if (p->digest != NULL) {
if (p->digest->data_type != OSSL_PARAM_UTF8_STRING)
goto done;
-
- md = evp_digest_fetch_from_prov(prov, (const char *)p->digest->data, NULL);
+ md = EVP_MD_fetch(libctx, p->digest->data, propquery);
if (md) {
EVP_MD_free(*digest);
*digest = md;
@@ -451,7 +452,6 @@ static int drbg_fetch_algs_from_prov(const struct drbg_set_ctx_params_st *p,
ret = 1;
done:
- ossl_provider_free(prov);
return ret;
}
@@ -468,7 +468,8 @@ static int drbg_hmac_set_ctx_params_locked(PROV_DRBG *ctx, const struct drbg_set
/* try to fetch mac and digest from provider */
(void)ERR_set_mark();
- if (!drbg_fetch_algs_from_prov(p, libctx, &hmac->ctx, &prov_md)) {
+ if (!drbg_fetch_algs_from_prov(p, libctx, &hmac->ctx, &prov_md,
+ (p->propq != NULL && p->propq->data_type == OSSL_PARAM_UTF8_STRING) ? p->propq->data : NULL)) {
(void)ERR_pop_to_mark();
if (p->digest != NULL) {
/* fall back to full implementation search */