]> git.ipfire.org Git - thirdparty/openssl.git/commitdiff
drbg: convert DRBGs to use generated ctx set param decoders
authorPauli <ppzgs1@gmail.com>
Mon, 21 Jul 2025 01:40:35 +0000 (11:40 +1000)
committerPauli <ppzgs1@gmail.com>
Wed, 13 Aug 2025 01:55:49 +0000 (11:55 +1000)
Reviewed-by: Paul Yang <paulyang.inf@gmail.com>
Reviewed-by: Shane Lontis <shane.lontis@oracle.com>
Reviewed-by: Matt Caswell <matt@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/28143)

providers/implementations/include/prov/drbg.h
providers/implementations/rands/drbg.c
providers/implementations/rands/drbg_ctr.c.in
providers/implementations/rands/drbg_hash.c.in
providers/implementations/rands/drbg_hmac.c.in

index 5fac273b990b6be5137437d066a0b31047de1854..a4ae58e1f4aec1776b6562ae670478bb90b942bc 100644 (file)
@@ -216,11 +216,22 @@ OSSL_FUNC_rand_unlock_fn ossl_drbg_unlock;
 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                             \
-    OSSL_PARAM_uint(OSSL_DRBG_PARAM_RESEED_REQUESTS, NULL),             \
-    OSSL_PARAM_uint64(OSSL_DRBG_PARAM_RESEED_TIME_INTERVAL, NULL)
+struct drbg_set_ctx_params_st {
+    OSSL_PARAM *propq;
+    OSSL_PARAM *engine;
+    OSSL_PARAM *cipher;     /* CTR DRBG */
+    OSSL_PARAM *df;         /* CTR DRBG */
+    OSSL_PARAM *digest;     /* HASH and HMAC DRBG */
+    OSSL_PARAM *mac;        /* HMAC DRBG */
+    OSSL_PARAM *ind_d;      /* HASH and HMAC DRBG */
+    OSSL_PARAM *prov;
+    OSSL_PARAM *reseed_req;
+    OSSL_PARAM *reseed_time;
+};
+
+int ossl_drbg_set_ctx_params(PROV_DRBG *drbg,
+                             const struct drbg_set_ctx_params_st *p);
 
 #define OSSL_PARAM_DRBG_GETTABLE_CTX_COMMON                             \
     OSSL_PARAM_int(OSSL_RAND_PARAM_STATE, NULL),                        \
index d58da1abba4424503f81321976b1ea184e4983de..d1666059560d75f848c9b237ddbd19ec2fcbc224 100644 (file)
@@ -972,19 +972,15 @@ int ossl_drbg_get_ctx_params_no_lock(PROV_DRBG *drbg, OSSL_PARAM params[],
     return 1;
 }
 
-int ossl_drbg_set_ctx_params(PROV_DRBG *drbg, const OSSL_PARAM params[])
+int ossl_drbg_set_ctx_params(PROV_DRBG *drbg,
+                             const struct drbg_set_ctx_params_st *p)
 {
-    const OSSL_PARAM *p;
-
-    if (ossl_param_is_empty(params))
-        return 1;
-
-    p = OSSL_PARAM_locate_const(params, OSSL_DRBG_PARAM_RESEED_REQUESTS);
-    if (p != NULL && !OSSL_PARAM_get_uint(p, &drbg->reseed_interval))
+    if (p->reseed_req != NULL
+            && !OSSL_PARAM_get_uint(p->reseed_req, &drbg->reseed_interval))
         return 0;
 
-    p = OSSL_PARAM_locate_const(params, OSSL_DRBG_PARAM_RESEED_TIME_INTERVAL);
-    if (p != NULL && !OSSL_PARAM_get_time_t(p, &drbg->reseed_time_interval))
+    if (p->reseed_time != NULL
+            && !OSSL_PARAM_get_time_t(p->reseed_time, &drbg->reseed_time_interval))
         return 0;
 
     return 1;
index 1ac985505257dd2621c854bc9085511d809016bb..675713139a37a2be4970326df40ac3868ffea1fe 100644 (file)
@@ -6,6 +6,9 @@
  * in the file LICENSE in the source distribution or at
  * https://www.openssl.org/source/license.html
  */
+{-
+use OpenSSL::paramnames qw(produce_param_decoder);
+-}
 
 #include <stdlib.h>
 #include <string.h>
@@ -37,7 +40,10 @@ static OSSL_FUNC_rand_gettable_ctx_params_fn drbg_ctr_gettable_ctx_params;
 static OSSL_FUNC_rand_get_ctx_params_fn drbg_ctr_get_ctx_params;
 static OSSL_FUNC_rand_verify_zeroization_fn drbg_ctr_verify_zeroization;
 
-static int drbg_ctr_set_ctx_params_locked(void *vctx, const OSSL_PARAM params[]);
+static int drbg_ctr_set_ctx_params_locked(PROV_DRBG *drbg,
+                                          const struct drbg_set_ctx_params_st *p);
+static int drbg_ctr_set_ctx_params_decoder(const OSSL_PARAM params[],
+                                           struct drbg_set_ctx_params_st *p);
 
 /*
  * The state of a DRBG AES-CTR.
@@ -338,13 +344,18 @@ static int drbg_ctr_instantiate_wrapper(void *vdrbg, unsigned int strength,
                                         const OSSL_PARAM params[])
 {
     PROV_DRBG *drbg = (PROV_DRBG *)vdrbg;
+    struct drbg_set_ctx_params_st p;
     int ret = 0;
 
+    if (drbg == NULL || !drbg_ctr_set_ctx_params_decoder(params, &p))
+        return 0;
+
+
     if (drbg->lock != NULL && !CRYPTO_THREAD_write_lock(drbg->lock))
         return 0;
 
     if (!ossl_prov_is_running()
-            || !drbg_ctr_set_ctx_params_locked(drbg, params))
+            || !drbg_ctr_set_ctx_params_locked(drbg, &p))
         goto err;
     ret = ossl_prov_drbg_instantiate(drbg, strength, prediction_resistance,
                                      pstr, pstr_len);
@@ -710,60 +721,56 @@ static const OSSL_PARAM *drbg_ctr_gettable_ctx_params(ossl_unused void *vctx,
     return known_gettable_ctx_params;
 }
 
-static int drbg_ctr_set_ctx_params_locked(void *vctx, const OSSL_PARAM params[])
+static int drbg_ctr_set_ctx_params_locked(PROV_DRBG *ctx,
+                                          const struct drbg_set_ctx_params_st *p)
 {
-    PROV_DRBG *ctx = (PROV_DRBG *)vctx;
     PROV_DRBG_CTR *ctr = (PROV_DRBG_CTR *)ctx->data;
     OSSL_LIB_CTX *libctx = PROV_LIBCTX_OF(ctx->provctx);
     OSSL_PROVIDER *prov = NULL;
-    const OSSL_PARAM *p;
     char *ecb;
     const char *propquery = NULL;
     int i, cipher_init = 0;
 
-    if ((p = OSSL_PARAM_locate_const(params, OSSL_DRBG_PARAM_USE_DF)) != NULL
-            && OSSL_PARAM_get_int(p, &i)) {
+    if (p->df != NULL && OSSL_PARAM_get_int(p->df, &i)) {
         /* FIPS errors out in the drbg_ctr_init() call later */
         ctr->use_df = i != 0;
         cipher_init = 1;
     }
 
-    if ((p = OSSL_PARAM_locate_const(params,
-                                     OSSL_DRBG_PARAM_PROPERTIES)) != NULL) {
-        if (p->data_type != OSSL_PARAM_UTF8_STRING)
+    if (p->propq != NULL) {
+        if (p->propq->data_type != OSSL_PARAM_UTF8_STRING)
             return 0;
-        propquery = (const char *)p->data;
+        propquery = (const char *)p->propq->data;
     }
 
-    if ((p = OSSL_PARAM_locate_const(params,
-                                     OSSL_PROV_PARAM_CORE_PROV_NAME)) != NULL) {
-        if (p->data_type != OSSL_PARAM_UTF8_STRING)
+    if (p->prov != NULL) {
+        if (p->prov->data_type != OSSL_PARAM_UTF8_STRING)
             return 0;
         if ((prov = ossl_provider_find(libctx,
-                                       (const char *)p->data, 1)) == NULL)
+                                       (const char *)p->prov->data, 1)) == NULL)
             return 0;
     }
 
-    if ((p = OSSL_PARAM_locate_const(params, OSSL_DRBG_PARAM_CIPHER)) != NULL) {
-        const char *base = (const char *)p->data;
+    if (p->cipher != NULL) {
+        const char *base = (const char *)p->cipher->data;
         size_t ctr_str_len = sizeof("CTR") - 1;
         size_t ecb_str_len = sizeof("ECB") - 1;
 
-        if (p->data_type != OSSL_PARAM_UTF8_STRING
-                || p->data_size < ctr_str_len) {
+        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->data_size - ctr_str_len) != 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->data_size)) == NULL) {
+        if ((ecb = OPENSSL_strndup(base, p->cipher->data_size)) == NULL) {
             ossl_provider_free(prov);
             return 0;
         }
-        strcpy(ecb + p->data_size - ecb_str_len, "ECB");
+        strcpy(ecb + p->cipher->data_size - ecb_str_len, "ECB");
         EVP_CIPHER_free(ctr->cipher_ecb);
         EVP_CIPHER_free(ctr->cipher_ctr);
         /*
@@ -799,18 +806,33 @@ static int drbg_ctr_set_ctx_params_locked(void *vctx, const OSSL_PARAM params[])
     if (cipher_init && !drbg_ctr_init(ctx))
         return 0;
 
-    return ossl_drbg_set_ctx_params(ctx, params);
+    return ossl_drbg_set_ctx_params(ctx, p);
 }
 
+#define drbg_ctr_set_ctx_params_st  drbg_set_ctx_params_st
+
+{- produce_param_decoder('drbg_ctr_set_ctx_params',
+                         (['DRBG_PARAM_PROPERTIES',           'propq',       'utf8_string'],
+                          ['DRBG_PARAM_CIPHER',               'cipher',      'utf8_string'],
+                          ['DRBG_PARAM_USE_DF',               'df',          'int'],
+                          ['PROV_PARAM_CORE_PROV_NAME',       'prov',        'utf8_string'],
+                          ['DRBG_PARAM_RESEED_REQUESTS',      'reseed_req',  'uint'],
+                          ['DRBG_PARAM_RESEED_TIME_INTERVAL', 'reseed_time', 'uint64'],
+                         )); -}
+
 static int drbg_ctr_set_ctx_params(void *vctx, const OSSL_PARAM params[])
 {
     PROV_DRBG *drbg = (PROV_DRBG *)vctx;
+    struct drbg_set_ctx_params_st p;
     int ret;
 
+    if (drbg == NULL || !drbg_ctr_set_ctx_params_decoder(params, &p))
+        return 0;
+
     if (drbg->lock != NULL && !CRYPTO_THREAD_write_lock(drbg->lock))
         return 0;
 
-    ret = drbg_ctr_set_ctx_params_locked(vctx, params);
+    ret = drbg_ctr_set_ctx_params_locked(drbg, &p);
 
     if (drbg->lock != NULL)
         CRYPTO_THREAD_unlock(drbg->lock);
@@ -821,14 +843,7 @@ static int drbg_ctr_set_ctx_params(void *vctx, const OSSL_PARAM params[])
 static const OSSL_PARAM *drbg_ctr_settable_ctx_params(ossl_unused void *vctx,
                                                       ossl_unused void *provctx)
 {
-    static const OSSL_PARAM known_settable_ctx_params[] = {
-        OSSL_PARAM_utf8_string(OSSL_DRBG_PARAM_PROPERTIES, NULL, 0),
-        OSSL_PARAM_utf8_string(OSSL_DRBG_PARAM_CIPHER, NULL, 0),
-        OSSL_PARAM_int(OSSL_DRBG_PARAM_USE_DF, NULL),
-        OSSL_PARAM_DRBG_SETTABLE_CTX_COMMON,
-        OSSL_PARAM_END
-    };
-    return known_settable_ctx_params;
+    return drbg_ctr_set_ctx_params_list;
 }
 
 const OSSL_DISPATCH ossl_drbg_ctr_functions[] = {
index 5252128ac84d464b3139f460652175d8d9781011..af1e578603e9d319314b47632ea1fbbdbcc512b2 100644 (file)
@@ -6,6 +6,9 @@
  * in the file LICENSE in the source distribution or at
  * https://www.openssl.org/source/license.html
  */
+{-
+use OpenSSL::paramnames qw(produce_param_decoder);
+-}
 
 #include <assert.h>
 #include <stdlib.h>
@@ -16,6 +19,7 @@
 #include <openssl/rand.h>
 #include <openssl/core_dispatch.h>
 #include <openssl/proverr.h>
+#include "internal/cryptlib.h"
 #include "internal/thread_once.h"
 #include "prov/providercommon.h"
 #include "prov/provider_ctx.h"
@@ -38,7 +42,10 @@ static OSSL_FUNC_rand_gettable_ctx_params_fn drbg_hash_gettable_ctx_params;
 static OSSL_FUNC_rand_get_ctx_params_fn drbg_hash_get_ctx_params;
 static OSSL_FUNC_rand_verify_zeroization_fn drbg_hash_verify_zeroization;
 
-static int drbg_hash_set_ctx_params_locked(void *vctx, const OSSL_PARAM params[]);
+static int drbg_hash_set_ctx_params_locked
+        (PROV_DRBG *drbg, const struct drbg_set_ctx_params_st *p);
+static int drbg_hash_set_ctx_params_decoder(const OSSL_PARAM params[],
+                                            struct drbg_set_ctx_params_st *p);
 
 /* 888 bits from SP800-90Ar1 10.1 table 2 */
 #define HASH_PRNG_MAX_SEEDLEN    (888/8)
@@ -275,13 +282,17 @@ static int drbg_hash_instantiate_wrapper(void *vdrbg, unsigned int strength,
                                          const OSSL_PARAM params[])
 {
     PROV_DRBG *drbg = (PROV_DRBG *)vdrbg;
+    struct drbg_set_ctx_params_st p;
     int ret = 0;
 
+    if (drbg == NULL || !drbg_hash_set_ctx_params_decoder(params, &p))
+        return 0;
+
     if (drbg->lock != NULL && !CRYPTO_THREAD_write_lock(drbg->lock))
         return 0;
 
     if (!ossl_prov_is_running()
-            || !drbg_hash_set_ctx_params_locked(drbg, params))
+            || !drbg_hash_set_ctx_params_locked(drbg, &p))
         goto err;
     ret = ossl_prov_drbg_instantiate(drbg, strength, prediction_resistance,
                                      pstr, pstr_len);
@@ -507,36 +518,31 @@ static const OSSL_PARAM *drbg_hash_gettable_ctx_params(ossl_unused void *vctx,
     return known_gettable_ctx_params;
 }
 
-static int drbg_fetch_digest_from_prov(const OSSL_PARAM params[],
+static int drbg_fetch_digest_from_prov(const struct drbg_set_ctx_params_st *p,
                                        OSSL_LIB_CTX *libctx,
                                        EVP_MD **digest)
 {
     OSSL_PROVIDER *prov = NULL;
-    const OSSL_PARAM *p;
     EVP_MD *md = NULL;
     int ret = 0;
 
     if (digest == NULL)
         return 0;
 
-    if ((p = OSSL_PARAM_locate_const(params,
-                                     OSSL_PROV_PARAM_CORE_PROV_NAME)) == NULL)
-        return 0;
-    if (p->data_type != OSSL_PARAM_UTF8_STRING)
+    if (p->prov == NULL || p->prov->data_type != OSSL_PARAM_UTF8_STRING)
         return 0;
-    if ((prov = ossl_provider_find(libctx, (const char *)p->data, 1)) == NULL)
+    if ((prov = ossl_provider_find(libctx, (const char *)p->prov->data, 1)) == NULL)
         return 0;
 
-    p = OSSL_PARAM_locate_const(params, OSSL_ALG_PARAM_DIGEST);
-    if (p == NULL) {
+    if (p->digest == NULL) {
         ret = 1;
         goto done;
     }
 
-    if (p->data_type != OSSL_PARAM_UTF8_STRING)
+    if (p->digest->data_type != OSSL_PARAM_UTF8_STRING)
         goto done;
 
-    md = evp_digest_fetch_from_prov(prov, (const char *)p->data, NULL);
+    md = evp_digest_fetch_from_prov(prov, (const char *)p->digest->data, NULL);
     if (md) {
         EVP_MD_free(*digest);
         *digest = md;
@@ -548,25 +554,25 @@ done:
     return ret;
 }
 
-static int drbg_hash_set_ctx_params_locked(void *vctx, const OSSL_PARAM params[])
+static int drbg_hash_set_ctx_params_locked
+        (PROV_DRBG *ctx, const struct drbg_set_ctx_params_st *p)
 {
-    PROV_DRBG *ctx = (PROV_DRBG *)vctx;
     PROV_DRBG_HASH *hash = (PROV_DRBG_HASH *)ctx->data;
     OSSL_LIB_CTX *libctx = PROV_LIBCTX_OF(ctx->provctx);
     EVP_MD *prov_md = NULL;
     const EVP_MD *md;
     int md_size;
 
-    if (!OSSL_FIPS_IND_SET_CTX_PARAM(ctx, OSSL_FIPS_IND_SETTABLE0, params,
-                                     OSSL_DRBG_PARAM_FIPS_DIGEST_CHECK))
+    if (!OSSL_FIPS_IND_SET_CTX_FROM_PARAM(ctx, OSSL_FIPS_IND_SETTABLE0, p->ind_d))
         return 0;
 
     /* try to fetch digest from provider */
     (void)ERR_set_mark();
-    if (!drbg_fetch_digest_from_prov(params, libctx, &prov_md)) {
+    if (!drbg_fetch_digest_from_prov(p, libctx, &prov_md)) {
         (void)ERR_pop_to_mark();
         /* fall back to full implementation search */
-        if (!ossl_prov_digest_load_from_params(&hash->digest, params, libctx))
+        if (!ossl_prov_digest_load(&hash->digest, p->digest, p->propq,
+                                   p->engine, libctx))
             return 0;
     } else {
         (void)ERR_clear_last_mark();
@@ -597,18 +603,34 @@ static int drbg_hash_set_ctx_params_locked(void *vctx, const OSSL_PARAM params[]
         ctx->min_noncelen = ctx->min_entropylen / 2;
     }
 
-    return ossl_drbg_set_ctx_params(ctx, params);
+    return ossl_drbg_set_ctx_params(ctx, p);
 }
 
+#define drbg_hash_set_ctx_params_st  drbg_set_ctx_params_st
+
+{- produce_param_decoder('drbg_hash_set_ctx_params',
+                         (['DRBG_PARAM_PROPERTIES',           'propq',       'utf8_string'],
+                          ['ALG_PARAM_ENGINE',                'engine',      'utf8_string', 'hidden'],
+                          ['DRBG_PARAM_DIGEST',               'digest',      'utf8_string'],
+                          ['PROV_PARAM_CORE_PROV_NAME',       'prov',        'utf8_string'],
+                          ['DRBG_PARAM_RESEED_REQUESTS',      'reseed_req',  'uint'],
+                          ['DRBG_PARAM_RESEED_TIME_INTERVAL', 'reseed_time', 'uint64'],
+                          ['KDF_PARAM_FIPS_DIGEST_CHECK',     'ind_d',       'int'],
+                         )); -}
+
 static int drbg_hash_set_ctx_params(void *vctx, const OSSL_PARAM params[])
 {
     PROV_DRBG *drbg = (PROV_DRBG *)vctx;
+    struct drbg_set_ctx_params_st p;
     int ret;
 
+    if (drbg == NULL || !drbg_hash_set_ctx_params_decoder(params, &p))
+        return 0;
+
     if (drbg->lock != NULL && !CRYPTO_THREAD_write_lock(drbg->lock))
         return 0;
 
-    ret = drbg_hash_set_ctx_params_locked(vctx, params);
+    ret = drbg_hash_set_ctx_params_locked(drbg, &p);
 
     if (drbg->lock != NULL)
         CRYPTO_THREAD_unlock(drbg->lock);
@@ -619,14 +641,7 @@ static int drbg_hash_set_ctx_params(void *vctx, const OSSL_PARAM params[])
 static const OSSL_PARAM *drbg_hash_settable_ctx_params(ossl_unused void *vctx,
                                                        ossl_unused void *p_ctx)
 {
-    static const OSSL_PARAM known_settable_ctx_params[] = {
-        OSSL_PARAM_utf8_string(OSSL_DRBG_PARAM_PROPERTIES, NULL, 0),
-        OSSL_PARAM_utf8_string(OSSL_DRBG_PARAM_DIGEST, NULL, 0),
-        OSSL_PARAM_DRBG_SETTABLE_CTX_COMMON,
-        OSSL_FIPS_IND_SETTABLE_CTX_PARAM(OSSL_DRBG_PARAM_FIPS_DIGEST_CHECK)
-        OSSL_PARAM_END
-    };
-    return known_settable_ctx_params;
+    return drbg_hash_set_ctx_params_list;
 }
 
 const OSSL_DISPATCH ossl_drbg_hash_functions[] = {
index 4ed64ba5e3df48448ac73c872ab8d89eed20ade2..4b819dadbce04a93e2395ca0078dd1ffb3f775aa 100644 (file)
@@ -6,6 +6,9 @@
  * in the file LICENSE in the source distribution or at
  * https://www.openssl.org/source/license.html
  */
+{-
+use OpenSSL::paramnames qw(produce_param_decoder);
+-}
 
 #include <stdlib.h>
 #include <string.h>
@@ -13,6 +16,7 @@
 #include <openssl/err.h>
 #include <openssl/rand.h>
 #include <openssl/proverr.h>
+#include "internal/cryptlib.h"
 #include "internal/thread_once.h"
 #include "prov/providercommon.h"
 #include "prov/implementations.h"
@@ -35,7 +39,10 @@ static OSSL_FUNC_rand_gettable_ctx_params_fn drbg_hmac_gettable_ctx_params;
 static OSSL_FUNC_rand_get_ctx_params_fn drbg_hmac_get_ctx_params;
 static OSSL_FUNC_rand_verify_zeroization_fn drbg_hmac_verify_zeroization;
 
-static int drbg_hmac_set_ctx_params_locked(void *vctx, const OSSL_PARAM params[]);
+static int drbg_hmac_set_ctx_params_locked
+        (PROV_DRBG *drbg, const struct drbg_set_ctx_params_st *p);
+static int drbg_hmac_set_ctx_params_decoder(const OSSL_PARAM params[],
+                                            struct drbg_set_ctx_params_st *p);
 
 /*
  * Called twice by SP800-90Ar1 10.1.2.2 HMAC_DRBG_Update_Process.
@@ -148,13 +155,17 @@ static int drbg_hmac_instantiate_wrapper(void *vdrbg, unsigned int strength,
                                          const OSSL_PARAM params[])
 {
     PROV_DRBG *drbg = (PROV_DRBG *)vdrbg;
+    struct drbg_set_ctx_params_st p;
     int ret = 0;
 
+    if (drbg == NULL || !drbg_hmac_set_ctx_params_decoder(params, &p))
+        return 0;
+
     if (drbg->lock != NULL && !CRYPTO_THREAD_write_lock(drbg->lock))
         return 0;
 
     if (!ossl_prov_is_running()
-            || !drbg_hmac_set_ctx_params_locked(drbg, params))
+            || !drbg_hmac_set_ctx_params_locked(drbg, &p))
         goto err;
     ret = ossl_prov_drbg_instantiate(drbg, strength, prediction_resistance,
                                      pstr, pstr_len);
@@ -410,13 +421,12 @@ static const OSSL_PARAM *drbg_hmac_gettable_ctx_params(ossl_unused void *vctx,
     return known_gettable_ctx_params;
 }
 
-static int drbg_fetch_algs_from_prov(const OSSL_PARAM params[],
+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)
 {
     OSSL_PROVIDER *prov = NULL;
-    const OSSL_PARAM *p;
     EVP_MD *md = NULL;
     EVP_MAC *mac = NULL;
     int ret = 0;
@@ -424,20 +434,16 @@ static int drbg_fetch_algs_from_prov(const OSSL_PARAM params[],
     if (macctx == NULL || digest == NULL)
         return 0;
 
-    if ((p = OSSL_PARAM_locate_const(params,
-                                     OSSL_PROV_PARAM_CORE_PROV_NAME)) == NULL)
-        return 0;
-    if (p->data_type != OSSL_PARAM_UTF8_STRING)
+    if (p->prov == NULL || p->prov->data_type != OSSL_PARAM_UTF8_STRING)
         return 0;
-    if ((prov = ossl_provider_find(libctx, (const char *)p->data, 1)) == NULL)
+    if ((prov = ossl_provider_find(libctx, (const char *)p->prov->data, 1)) == NULL)
         return 0;
 
-    p = OSSL_PARAM_locate_const(params, OSSL_ALG_PARAM_DIGEST);
-    if (p) {
-        if (p->data_type != OSSL_PARAM_UTF8_STRING)
+    if (p->digest) {
+        if (p->digest->data_type != OSSL_PARAM_UTF8_STRING)
             goto done;
 
-        md = evp_digest_fetch_from_prov(prov, (const char *)p->data, NULL);
+        md = evp_digest_fetch_from_prov(prov, (const char *)p->digest->data, NULL);
         if (md) {
             EVP_MD_free(*digest);
             *digest = md;
@@ -446,19 +452,18 @@ static int drbg_fetch_algs_from_prov(const OSSL_PARAM params[],
         }
     }
 
-    p = OSSL_PARAM_locate_const(params, OSSL_ALG_PARAM_MAC);
-    if (p == NULL) {
+    if (p->mac == NULL) {
         ret = 1;
         goto done;
     }
 
-    if (p->data_type != OSSL_PARAM_UTF8_STRING)
+    if (p->mac->data_type != OSSL_PARAM_UTF8_STRING)
         goto done;
 
     EVP_MAC_CTX_free(*macctx);
     *macctx = NULL;
 
-    mac = evp_mac_fetch_from_prov(prov, (const char *)p->data, NULL);
+    mac = evp_mac_fetch_from_prov(prov, (const char *)p->mac->data, NULL);
     if (mac) {
         *macctx = EVP_MAC_CTX_new(mac);
         /* The context holds on to the MAC */
@@ -471,29 +476,30 @@ done:
     return ret;
 }
 
-static int drbg_hmac_set_ctx_params_locked(void *vctx, const OSSL_PARAM params[])
+static int drbg_hmac_set_ctx_params_locked
+        (PROV_DRBG *ctx, const struct drbg_set_ctx_params_st *p)
 {
-    PROV_DRBG *ctx = (PROV_DRBG *)vctx;
     PROV_DRBG_HMAC *hmac = (PROV_DRBG_HMAC *)ctx->data;
     OSSL_LIB_CTX *libctx = PROV_LIBCTX_OF(ctx->provctx);
     EVP_MD *prov_md = NULL;
     const EVP_MD *md;
     int md_size;
 
-    if (!OSSL_FIPS_IND_SET_CTX_PARAM(ctx, OSSL_FIPS_IND_SETTABLE0, params,
-                                     OSSL_DRBG_PARAM_FIPS_DIGEST_CHECK))
+    if (!OSSL_FIPS_IND_SET_CTX_FROM_PARAM(ctx, OSSL_FIPS_IND_SETTABLE0, p->ind_d))
         return 0;
 
     /* try to fetch mac and digest from provider */
     (void)ERR_set_mark();
-    if (!drbg_fetch_algs_from_prov(params, libctx, &hmac->ctx, &prov_md)) {
+    if (!drbg_fetch_algs_from_prov(p, libctx, &hmac->ctx, &prov_md)) {
         (void)ERR_pop_to_mark();
         /* fall back to full implementation search */
-        if (!ossl_prov_digest_load_from_params(&hmac->digest, params, libctx))
+        if (!ossl_prov_digest_load(&hmac->digest, p->digest, p->propq,
+                                   p->engine, libctx))
             return 0;
 
-        if (!ossl_prov_macctx_load_from_params(&hmac->ctx, params,
-                                               NULL, NULL, NULL, libctx))
+        if (!ossl_prov_macctx_load(&hmac->ctx, p->mac, NULL, p->digest,
+                                   p->propq, p->engine,
+                                   NULL, NULL, NULL, libctx))
             return 0;
     } else {
         (void)ERR_clear_last_mark();
@@ -520,18 +526,35 @@ static int drbg_hmac_set_ctx_params_locked(void *vctx, const OSSL_PARAM params[]
         ctx->min_noncelen = ctx->min_entropylen / 2;
     }
 
-    return ossl_drbg_set_ctx_params(ctx, params);
+    return ossl_drbg_set_ctx_params(ctx, p);
 }
 
+#define drbg_hmac_set_ctx_params_st  drbg_set_ctx_params_st
+
+{- produce_param_decoder('drbg_hmac_set_ctx_params',
+                         (['DRBG_PARAM_PROPERTIES',           'propq',       'utf8_string'],
+                          ['ALG_PARAM_ENGINE',                'engine',      'utf8_string', 'hidden'],
+                          ['DRBG_PARAM_DIGEST',               'digest',      'utf8_string'],
+                          ['DRBG_PARAM_MAC',                  'mac',         'utf8_string'],
+                          ['PROV_PARAM_CORE_PROV_NAME',       'prov',        'utf8_string'],
+                          ['DRBG_PARAM_RESEED_REQUESTS',      'reseed_req',  'uint'],
+                          ['DRBG_PARAM_RESEED_TIME_INTERVAL', 'reseed_time', 'uint64'],
+                          ['KDF_PARAM_FIPS_DIGEST_CHECK',     'ind_d',       'int'],
+                         )); -}
+
 static int drbg_hmac_set_ctx_params(void *vctx, const OSSL_PARAM params[])
 {
     PROV_DRBG *drbg = (PROV_DRBG *)vctx;
+    struct drbg_set_ctx_params_st p;
     int ret;
 
+    if (drbg == NULL || !drbg_hmac_set_ctx_params_decoder(params, &p))
+        return 0;
+
     if (drbg->lock != NULL && !CRYPTO_THREAD_write_lock(drbg->lock))
         return 0;
 
-    ret = drbg_hmac_set_ctx_params_locked(vctx, params);
+    ret = drbg_hmac_set_ctx_params_locked(drbg, &p);
 
     if (drbg->lock != NULL)
         CRYPTO_THREAD_unlock(drbg->lock);
@@ -542,15 +565,7 @@ static int drbg_hmac_set_ctx_params(void *vctx, const OSSL_PARAM params[])
 static const OSSL_PARAM *drbg_hmac_settable_ctx_params(ossl_unused void *vctx,
                                                        ossl_unused void *p_ctx)
 {
-    static const OSSL_PARAM known_settable_ctx_params[] = {
-        OSSL_PARAM_utf8_string(OSSL_DRBG_PARAM_PROPERTIES, NULL, 0),
-        OSSL_PARAM_utf8_string(OSSL_DRBG_PARAM_DIGEST, NULL, 0),
-        OSSL_PARAM_utf8_string(OSSL_DRBG_PARAM_MAC, NULL, 0),
-        OSSL_PARAM_DRBG_SETTABLE_CTX_COMMON,
-        OSSL_FIPS_IND_SETTABLE_CTX_PARAM(OSSL_DRBG_PARAM_FIPS_DIGEST_CHECK)
-        OSSL_PARAM_END
-    };
-    return known_settable_ctx_params;
+    return drbg_hmac_set_ctx_params_list;
 }
 
 const OSSL_DISPATCH ossl_drbg_ossl_hmac_functions[] = {