Commit b5a69ec5a7 for openssl.org

commit b5a69ec5a7c262d477b2b54d82df4fa7fa203ee3
Author: Simo Sorce <simo@redhat.com>
Date:   Mon Mar 2 16:08:59 2026 -0500

    Refactor FIPS parameter and indicator handling

    Consolidate FIPS indicators and self-test parameters into a single
    structure managed by `fipsparams.pm`. Replace individual accessor
    functions with a generic `ossl_fips_config` function that retrieves
    values by name. This removes repetitive boilerplate code and
    simplifies parameter access within the FIPS provider.

    Signed-off-by: Simo Sorce <simo@redhat.com>

    Reviewed-by: Paul Dale <paul.dale@oracle.com>
    Reviewed-by: Shane Lontis <shane.lontis@oracle.com>
    Reviewed-by: Dmitry Belyavskiy <beldmit@gmail.com>
    (Merged from https://github.com/openssl/openssl/pull/30213)

diff --git a/providers/common/include/prov/securitycheck.h b/providers/common/include/prov/securitycheck.h
index 29a2b7fbf8..1976b75b43 100644
--- a/providers/common/include/prov/securitycheck.h
+++ b/providers/common/include/prov/securitycheck.h
@@ -36,4 +36,3 @@ int ossl_digest_get_approved_nid(const EVP_MD *md);

 /* Functions that have different implementations for the FIPS_MODULE */
 int ossl_digest_rsa_sign_get_md_nid(const EVP_MD *md);
-int ossl_fips_config_securitycheck_enabled(OSSL_LIB_CTX *libctx);
diff --git a/providers/common/securitycheck_default.c b/providers/common/securitycheck_default.c
index 42823ffe14..ca8f0b497d 100644
--- a/providers/common/securitycheck_default.c
+++ b/providers/common/securitycheck_default.c
@@ -16,12 +16,6 @@
 #include "prov/securitycheck.h"
 #include "internal/nelem.h"

-/* Disable the security checks in the default provider */
-int ossl_fips_config_securitycheck_enabled(OSSL_LIB_CTX *libctx)
-{
-    return 0;
-}
-
 int ossl_digest_rsa_sign_get_md_nid(const EVP_MD *md)
 {
     int mdnid;
diff --git a/providers/common/securitycheck_fips.c b/providers/common/securitycheck_fips.c
index a83320b72b..aa9136ef09 100644
--- a/providers/common/securitycheck_fips.c
+++ b/providers/common/securitycheck_fips.c
@@ -19,15 +19,6 @@
 #include <openssl/obj_mac.h>
 #include "prov/securitycheck.h"

-int ossl_fips_config_securitycheck_enabled(OSSL_LIB_CTX *libctx)
-{
-#if !defined(OPENSSL_NO_FIPS_SECURITYCHECKS)
-    return ossl_fips_config_security_checks(libctx);
-#else
-    return 0;
-#endif /* OPENSSL_NO_FIPS_SECURITYCHECKS */
-}
-
 int ossl_digest_rsa_sign_get_md_nid(const EVP_MD *md)
 {
     return ossl_digest_get_approved_nid(md);
@@ -41,7 +32,7 @@ int ossl_fips_ind_rsa_key_check(OSSL_FIPS_IND *ind, int id,

     if (!key_approved) {
         if (!ossl_FIPS_IND_on_unapproved(ind, id, libctx, desc, "Key size",
-                ossl_fips_config_securitycheck_enabled)) {
+                FIPS_CONFIG_SECURITY_CHECKS)) {
             ERR_raise_data(ERR_LIB_PROV, PROV_R_INVALID_KEY_LENGTH,
                 "operation: %s", desc);
             return 0;
@@ -66,7 +57,7 @@ int ossl_fips_ind_ec_key_check(OSSL_FIPS_IND *ind, int id,

     if (!strength_allowed || !curve_allowed) {
         if (!ossl_FIPS_IND_on_unapproved(ind, id, libctx, desc, "EC Key",
-                ossl_fips_config_securitycheck_enabled)) {
+                FIPS_CONFIG_SECURITY_CHECKS)) {
             if (!curve_allowed)
                 ERR_raise(ERR_LIB_PROV, PROV_R_INVALID_CURVE);
             if (!strength_allowed)
@@ -87,7 +78,7 @@ int ossl_fips_ind_digest_exch_check(OSSL_FIPS_IND *ind, int id,

     if (!approved) {
         if (!ossl_FIPS_IND_on_unapproved(ind, id, libctx, desc, "Digest",
-                ossl_fips_config_securitycheck_enabled)) {
+                FIPS_CONFIG_SECURITY_CHECKS)) {
             ERR_raise(ERR_LIB_PROV, PROV_R_INVALID_DIGEST);
             return 0;
         }
@@ -100,7 +91,7 @@ int ossl_fips_ind_digest_sign_check(OSSL_FIPS_IND *ind, int id,
     int nid, int sha1_allowed,
     int sha512_trunc_allowed,
     const char *desc,
-    OSSL_FIPS_IND_CHECK_CB *config_check_f)
+    enum fips_config_id config_id)
 {
     int approved;
     const char *op = "none";
@@ -124,8 +115,7 @@ int ossl_fips_ind_digest_sign_check(OSSL_FIPS_IND *ind, int id,
     }

     if (!approved) {
-        if (!ossl_FIPS_IND_on_unapproved(ind, id, libctx, desc, op,
-                config_check_f)) {
+        if (!ossl_FIPS_IND_on_unapproved(ind, id, libctx, desc, op, config_id)) {
             ERR_raise(ERR_LIB_PROV, PROV_R_INVALID_DIGEST);
             return 0;
         }
diff --git a/providers/fips/fipsindicator.c b/providers/fips/fipsindicator.c
index 38323c5d5d..55f287324b 100644
--- a/providers/fips/fipsindicator.c
+++ b/providers/fips/fipsindicator.c
@@ -58,7 +58,7 @@ int ossl_FIPS_IND_get_settable(const OSSL_FIPS_IND *ind, int id)
 int ossl_FIPS_IND_on_unapproved(OSSL_FIPS_IND *ind, int id,
     OSSL_LIB_CTX *libctx,
     const char *algname, const char *opname,
-    OSSL_FIPS_IND_CHECK_CB *config_check_fn)
+    enum fips_config_id config_id)
 {
     /* Set to unapproved. Once unapproved mode is set this will not be reset */
     ind->approved = 0;
@@ -69,8 +69,7 @@ int ossl_FIPS_IND_on_unapproved(OSSL_FIPS_IND *ind, int id,
      * assumed to be strict.
      */
     if (ossl_FIPS_IND_get_settable(ind, id) == OSSL_FIPS_IND_STATE_TOLERANT
-        || (config_check_fn != NULL
-            && config_check_fn(libctx) == OSSL_FIPS_IND_STATE_TOLERANT)) {
+        || (ossl_fips_config(libctx, config_id) == OSSL_FIPS_IND_STATE_TOLERANT)) {
         return ossl_FIPS_IND_callback(libctx, algname, opname);
     }
     /* Strict mode gets here: This returns an error */
diff --git a/providers/fips/fipsparams.inc.in b/providers/fips/fipsparams.inc.in
index 9127cd6f6c..e898c93ee4 100644
--- a/providers/fips/fipsparams.inc.in
+++ b/providers/fips/fipsparams.inc.in
@@ -11,61 +11,53 @@
  * Handles the loading of FIPS algorithm conditional options from a config file
  * passed from the core using OSSL_PARAM.
  *
- * The perl function generates code that:
- *
- * Creates fields in a structure for each item in the list using the first
- * parameter as the base name.
- *
- * Creates a function to properly initialize each field based on the last
- * parameter in each line.
- *
- * Creates a function to retrieve the values from the core.
- *
- * Creates a function to convert the retrieved string values to integer booleans.
- *
- * Creates getter functions for each parameter.
- */
-{- use OpenSSL::fipsparams qw(produce_fips_indicators); -}
-{- produce_fips_indicators(
-        ['security_checks', 'OSSL_PROV_PARAM_SECURITY_CHECKS', '1'],
-        ['tls1_prf_ems_check', 'OSSL_PROV_PARAM_TLS1_PRF_EMS_CHECK', '0'],
-        ['no_short_mac', 'OSSL_PROV_PARAM_NO_SHORT_MAC', '1'],
-        ['hmac_key_check', 'OSSL_PROV_PARAM_HMAC_KEY_CHECK', '0'],
-        ['kmac_key_check', 'OSSL_PROV_PARAM_KMAC_KEY_CHECK', '0'],
-        ['restricted_drbg_digests', 'OSSL_PROV_PARAM_DRBG_TRUNC_DIGEST', '0'],
-        ['signature_digest_check', 'OSSL_PROV_PARAM_SIGNATURE_DIGEST_CHECK', '0'],
-        ['hkdf_digest_check', 'OSSL_PROV_PARAM_HKDF_DIGEST_CHECK', '0'],
-        ['tls13_kdf_digest_check', 'OSSL_PROV_PARAM_TLS13_KDF_DIGEST_CHECK', '0'],
-        ['tls1_prf_digest_check', 'OSSL_PROV_PARAM_TLS1_PRF_DIGEST_CHECK', '0'],
-        ['sshkdf_digest_check', 'OSSL_PROV_PARAM_SSHKDF_DIGEST_CHECK', '0'],
-        ['sskdf_digest_check', 'OSSL_PROV_PARAM_SSKDF_DIGEST_CHECK', '0'],
-        ['x963kdf_digest_check', 'OSSL_PROV_PARAM_X963KDF_DIGEST_CHECK', '0'],
-        ['dsa_sign_disallowed', 'OSSL_PROV_PARAM_DSA_SIGN_DISABLED', '0'],
-        ['tdes_encrypt_disallowed', 'OSSL_PROV_PARAM_TDES_ENCRYPT_DISABLED', '0'],
-        ['rsa_pkcs15_padding_disabled', 'OSSL_PROV_PARAM_RSA_PKCS15_PAD_DISABLED', '0'],
-        ['rsa_pss_saltlen_check', 'OSSL_PROV_PARAM_RSA_PSS_SALTLEN_CHECK', '0'],
-        ['rsa_sign_x931_disallowed', 'OSSL_PROV_PARAM_RSA_SIGN_X931_PAD_DISABLED', '0'],
-        ['hkdf_key_check', 'OSSL_PROV_PARAM_HKDF_KEY_CHECK', '0'],
-        ['kbkdf_key_check', 'OSSL_PROV_PARAM_KBKDF_KEY_CHECK', '0'],
-        ['tls13_kdf_key_check', 'OSSL_PROV_PARAM_TLS13_KDF_KEY_CHECK', '0'],
-        ['tls1_prf_key_check', 'OSSL_PROV_PARAM_TLS1_PRF_KEY_CHECK', '0'],
-        ['sshkdf_key_check', 'OSSL_PROV_PARAM_SSHKDF_KEY_CHECK', '0'],
-        ['sskdf_key_check', 'OSSL_PROV_PARAM_SSKDF_KEY_CHECK', '0'],
-        ['x963kdf_key_check', 'OSSL_PROV_PARAM_X963KDF_KEY_CHECK', '0'],
-        ['x942kdf_key_check', 'OSSL_PROV_PARAM_X942KDF_KEY_CHECK', '0'],
-        ['pbkdf2_lower_bound_check', 'OSSL_PROV_PARAM_PBKDF2_LOWER_BOUND_CHECK', '1'],
-        ['ecdh_cofactor_check', 'OSSL_PROV_PARAM_ECDH_COFACTOR_CHECK', '0']) -}
-/*
- * Handles the loading of FIPS self test parameters from the core using
- * OSSL_PARAM.
- *
- * The perl function generates code that:
- *
- * Creates a function to retrieve the values from the core.
+ * The perl function produce_fips_params() generates code that:
+ * - Defines the FIPS_PARAMS structure with fields for each item.
+ * - Creates a function init_fips_params() to initialize the structure with default values.
+ * - Creates a function fips_get_params_from_core() to retrieve values from the core.
+ * - Defines a macro OSSL_FIPS_PARAMS_DEFN_TYPES listing the parameters.
+ * - Creates a function return_fips_params() to return values to the core.
+ * - Creates accessor functions for parameters marked as 'indicator'.
+ *
+ * The fields of the table below are:
+ * 1. field:       The name of the field in the FIPS_PARAMS structure.
+ * 2. name:        The OSSL_PARAM name used to identify the parameter.
+ * 3. type:        The C type of the field (e.g., "unsigned char" or "const char *").
+ * 4. default:     The default value for the field.
+ * 5. description: A tag indicating usage. If set to 'indicator', an accessor function
+ *                 ossl_fips_config_<field>() is generated.
  */
-{-use OpenSSL::fipsparams qw(produce_fips_selftest_params); -}
-{- produce_fips_selftest_params(
-        ['module_filename', 'OSSL_PROV_PARAM_CORE_MODULE_FILENAME'],
-        ['module_checksum_data', 'OSSL_PROV_FIPS_PARAM_MODULE_MAC'],
-        ['conditional_error_check', 'OSSL_PROV_FIPS_PARAM_CONDITIONAL_ERRORS'],
-        ['defer_tests', 'OSSL_PROV_FIPS_PARAM_DEFER_TESTS']) -}
+{- use OpenSSL::fipsparams qw(produce_fips_params); -}
+{- produce_fips_params(
+        [ 'security_checks', 'SECURITY_CHECKS', 'unsigned char', '1', 'indicator' ],
+        [ 'tls1_prf_ems_check', 'TLS1_PRF_EMS_CHECK', 'unsigned char', '0', 'indicator' ],
+        [ 'no_short_mac', 'NO_SHORT_MAC', 'unsigned char', '1', 'indicator' ],
+        [ 'hmac_key_check', 'HMAC_KEY_CHECK', 'unsigned char', '0', 'indicator' ],
+        [ 'kmac_key_check', 'KMAC_KEY_CHECK', 'unsigned char', '0', 'indicator' ],
+        [ 'restricted_drbg_digests', 'DRBG_TRUNC_DIGEST', 'unsigned char', '0', 'indicator' ],
+        [ 'signature_digest_check', 'SIGNATURE_DIGEST_CHECK', 'unsigned char', '0', 'indicator' ],
+        [ 'hkdf_digest_check', 'HKDF_DIGEST_CHECK', 'unsigned char', '0', 'indicator' ],
+        [ 'tls13_kdf_digest_check', 'TLS13_KDF_DIGEST_CHECK', 'unsigned char', '0', 'indicator' ],
+        [ 'tls1_prf_digest_check', 'TLS1_PRF_DIGEST_CHECK', 'unsigned char', '0', 'indicator' ],
+        [ 'sshkdf_digest_check', 'SSHKDF_DIGEST_CHECK', 'unsigned char', '0', 'indicator' ],
+        [ 'sskdf_digest_check', 'SSKDF_DIGEST_CHECK', 'unsigned char', '0', 'indicator' ],
+        [ 'x963kdf_digest_check', 'X963KDF_DIGEST_CHECK', 'unsigned char', '0', 'indicator' ],
+        [ 'dsa_sign_disallowed', 'DSA_SIGN_DISABLED', 'unsigned char', '0', 'indicator' ],
+        [ 'tdes_encrypt_disallowed', 'TDES_ENCRYPT_DISABLED', 'unsigned char', '0', 'indicator' ],
+        [ 'rsa_pkcs15_padding_disabled', 'RSA_PKCS15_PAD_DISABLED', 'unsigned char', '0', 'indicator' ],
+        [ 'rsa_pss_saltlen_check', 'RSA_PSS_SALTLEN_CHECK', 'unsigned char', '0', 'indicator' ],
+        [ 'rsa_sign_x931_disallowed', 'RSA_SIGN_X931_PAD_DISABLED', 'unsigned char', '0', 'indicator' ],
+        [ 'hkdf_key_check', 'HKDF_KEY_CHECK', 'unsigned char', '0', 'indicator' ],
+        [ 'kbkdf_key_check', 'KBKDF_KEY_CHECK', 'unsigned char', '0', 'indicator' ],
+        [ 'tls13_kdf_key_check', 'TLS13_KDF_KEY_CHECK', 'unsigned char', '0', 'indicator' ],
+        [ 'tls1_prf_key_check', 'TLS1_PRF_KEY_CHECK', 'unsigned char', '0', 'indicator' ],
+        [ 'sshkdf_key_check', 'SSHKDF_KEY_CHECK', 'unsigned char', '0', 'indicator' ],
+        [ 'sskdf_key_check', 'SSKDF_KEY_CHECK', 'unsigned char', '0', 'indicator' ],
+        [ 'x963kdf_key_check', 'X963KDF_KEY_CHECK', 'unsigned char', '0', 'indicator' ],
+        [ 'x942kdf_key_check', 'X942KDF_KEY_CHECK', 'unsigned char', '0', 'indicator' ],
+        [ 'pbkdf2_lower_bound_check', 'PBKDF2_LOWER_BOUND_CHECK', 'unsigned char', '1', 'indicator' ],
+        [ 'ecdh_cofactor_check', 'ECDH_COFACTOR_CHECK', 'unsigned char', '0', 'indicator' ],
+        [ 'module_filename', 'OSSL_PROV_PARAM_CORE_MODULE_FILENAME', 'const char *', 'NULL', 'selftest' ],
+        [ 'module_checksum_data', 'OSSL_PROV_FIPS_PARAM_MODULE_MAC', 'const char *', 'NULL', 'selftest' ],
+        [ 'conditional_error_check', 'OSSL_PROV_FIPS_PARAM_CONDITIONAL_ERRORS', 'unsigned char', '1', 'selftest' ],
+        [ 'defer_tests', 'OSSL_PROV_FIPS_PARAM_DEFER_TESTS', 'unsigned char', '0', 'selftest' ]) -}
diff --git a/providers/fips/fipsprov.c b/providers/fips/fipsprov.c
index 59509da631..cbd2d10539 100644
--- a/providers/fips/fipsprov.c
+++ b/providers/fips/fipsprov.c
@@ -89,30 +89,22 @@ static OSSL_FUNC_self_test_cb_fn *c_stcbfn = NULL;
 static OSSL_FUNC_indicator_cb_fn *c_indcbfn = NULL;
 static OSSL_FUNC_core_get_libctx_fn *c_get_libctx = NULL;

-typedef struct {
-    const char *option;
-    unsigned char enabled;
-} FIPS_OPTION;
-
-typedef struct fips_global_st FIPS_GLOBAL;
-typedef struct fips_indicators_st FIPS_INDICATORS;
-static FIPS_INDICATORS *get_fips_indicators(FIPS_GLOBAL *fgbl);
-#include "fipsparams.inc"
+#include "providers/fips/fipsparams.inc"

 typedef struct fips_global_st {
     const OSSL_CORE_HANDLE *handle;
     SELF_TEST_POST_PARAMS selftest_params;

-    FIPS_INDICATORS fips_indicators;
+    FIPS_PARAMS fips_params;

     /* Guards access to deferred self-test */
     CRYPTO_RWLOCK *deferred_lock;

 } FIPS_GLOBAL;

-static inline FIPS_INDICATORS *get_fips_indicators(FIPS_GLOBAL *fgbl)
+static inline FIPS_PARAMS *get_fips_params(FIPS_GLOBAL *fgbl)
 {
-    return &fgbl->fips_indicators;
+    return &fgbl->fips_params;
 }

 void *ossl_fips_prov_ossl_ctx_new(OSSL_LIB_CTX *libctx)
@@ -122,7 +114,7 @@ void *ossl_fips_prov_ossl_ctx_new(OSSL_LIB_CTX *libctx)
     if (fgbl == NULL)
         return NULL;

-    init_fips_indicators(&fgbl->fips_indicators);
+    init_fips_params(&fgbl->fips_params);

     return fgbl;
 }
@@ -148,31 +140,6 @@ static int fips_random_bytes(ossl_unused void *vprov, int which,
     return RAND_bytes_ex(libctx, buf, n, strength);
 }

-/*
- * Parameters to retrieve from the core provider
- * NOTE: inside core_get_params() these will be loaded from config items
- * stored inside prov->parameters
- */
-static int fips_get_params_from_core(FIPS_GLOBAL *fgbl)
-{
-    OSSL_PARAM core_params[33], *p = core_params;
-
-    /* Parameters required for self testing */
-    p = get_fips_selftest_params_from_core(p, &fgbl->selftest_params);
-
-    /* FIPS indicator options can be enabled or disabled independently */
-    p = get_fips_indicator_params_from_core(p, &fgbl->fips_indicators);
-
-    *p = OSSL_PARAM_construct_end();
-
-    if (!c_get_params(fgbl->handle, core_params)) {
-        ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_GET_PARAMETER);
-        return 0;
-    }
-
-    return set_fips_indicators_from_core(&fgbl->fips_indicators);
-}
-
 static const OSSL_PARAM *fips_gettable_params(void *provctx)
 {
     /* Parameters we provide to the core */
@@ -181,7 +148,7 @@ static const OSSL_PARAM *fips_gettable_params(void *provctx)
         OSSL_PARAM_DEFN(OSSL_PROV_PARAM_VERSION, OSSL_PARAM_UTF8_PTR, NULL, 0),
         OSSL_PARAM_DEFN(OSSL_PROV_PARAM_BUILDINFO, OSSL_PARAM_UTF8_PTR, NULL, 0),
         OSSL_PARAM_DEFN(OSSL_PROV_PARAM_STATUS, OSSL_PARAM_INTEGER, NULL, 0),
-        OSSL_FIPS_INDICATOR_PARAM_TYPES,
+        OSSL_FIPS_PARAMS_DEFN_TYPES,
         OSSL_PARAM_END
     };
     return fips_param_types;
@@ -206,7 +173,7 @@ static int fips_get_params(void *provctx, OSSL_PARAM params[])
     if (p != NULL && !OSSL_PARAM_set_int(p, ossl_prov_is_running()))
         return 0;

-    return get_fips_indicator_params(params, &fgbl->fips_indicators);
+    return return_fips_params(params, &fgbl->fips_params);
 }

 static void set_self_test_cb(FIPS_GLOBAL *fgbl)
@@ -997,27 +964,34 @@ int OSSL_provider_init_int(const OSSL_CORE_HANDLE *handle,
     if (!ossl_provider_activate_fallbacks(libctx))
         goto err;

+    /* Retrieve all FIPS parameters from core so they can be used later */
+    if (!fips_get_params_from_core(fgbl->handle, &fgbl->fips_params)) {
+        ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_GET_PARAMETER);
+        goto err;
+    }
+
+    /* disable security_checks if needed */
+#ifdef OPENSSL_NO_FIPS_SECURITYCHECKS
+    fgbl->fips_params.security_checks = 0;
+#endif
+
     /*
      * We did initial set up of selftest_params in a local copy, because we
      * could not create fgbl until c_CRYPTO_zalloc was defined in the loop
      * above.
      */
     fgbl->selftest_params = selftest_params;
-
+    fgbl->selftest_params.module_filename = fgbl->fips_params.module_filename;
+    fgbl->selftest_params.module_checksum_data = fgbl->fips_params.module_checksum_data;
+    fgbl->selftest_params.defer_tests = fgbl->fips_params.defer_tests;
     fgbl->selftest_params.libctx = libctx;

     set_self_test_cb(fgbl);
-
-    if (!fips_get_params_from_core(fgbl)) {
-        /* Error already raised */
-        goto err;
-    }
     /*
      * Disable the conditional error check if it's disabled in the fips config
      * file.
      */
-    if (fgbl->selftest_params.conditional_error_check != NULL
-        && strcmp(fgbl->selftest_params.conditional_error_check, "0") == 0)
+    if (fgbl->fips_params.conditional_error_check == 0)
         SELF_TEST_disable_conditional_error_state();

     ossl_prov_cache_exported_algorithms(fips_ciphers, exported_fips_ciphers);
diff --git a/providers/fips/include/fips/fipsindicator.h b/providers/fips/include/fips/fipsindicator.h
index d32e7a1542..11c435ac8e 100644
--- a/providers/fips/include/fips/fipsindicator.h
+++ b/providers/fips/include/fips/fipsindicator.h
@@ -67,8 +67,7 @@ void ossl_FIPS_IND_set_approved(OSSL_FIPS_IND *ind);
 void ossl_FIPS_IND_set_settable(OSSL_FIPS_IND *ind, int id, int enable);
 int ossl_FIPS_IND_get_settable(const OSSL_FIPS_IND *ind, int id);
 int ossl_FIPS_IND_on_unapproved(OSSL_FIPS_IND *ind, int id, OSSL_LIB_CTX *libctx,
-    const char *algname, const char *opname,
-    OSSL_FIPS_IND_CHECK_CB *config_check_fn);
+    const char *algname, const char *opname, enum fips_config_id config_id);
 int ossl_FIPS_IND_set_ctx_param(OSSL_FIPS_IND *ind, int id, const OSSL_PARAM *p);
 int ossl_FIPS_IND_set_ctx_param_locate(OSSL_FIPS_IND *ind, int id,
     const OSSL_PARAM params[],
@@ -100,8 +99,8 @@ void ossl_FIPS_IND_copy(OSSL_FIPS_IND *dst, const OSSL_FIPS_IND *src);
  * If there is more than 1 strict check flag per algorithm ctx, the id represents
  * the index.
  */
-#define OSSL_FIPS_IND_ON_UNAPPROVED(ctx, id, libctx, algname, opname, config_check_fn) \
-    ossl_FIPS_IND_on_unapproved(&ctx->indicator, id, libctx, algname, opname, config_check_fn)
+#define OSSL_FIPS_IND_ON_UNAPPROVED(ctx, id, libctx, algname, opname, config_id) \
+    ossl_FIPS_IND_on_unapproved(&ctx->indicator, id, libctx, algname, opname, config_id)

 #define OSSL_FIPS_IND_SETTABLE_CTX_PARAM(name) \
     OSSL_PARAM_int(name, NULL),
@@ -146,7 +145,7 @@ int ossl_fips_ind_digest_sign_check(OSSL_FIPS_IND *ind, int id,
     int nid, int sha1_allowed,
     int sha512_trunc_allowed,
     const char *desc,
-    OSSL_FIPS_IND_CHECK_CB *config_check_f);
+    enum fips_config_id config_id);

 #else
 #define OSSL_FIPS_IND_DECLARE
diff --git a/providers/fips/include/fipscommon.h b/providers/fips/include/fipscommon.h
index ff73ea6d7d..6b646a2558 100644
--- a/providers/fips/include/fipscommon.h
+++ b/providers/fips/include/fipscommon.h
@@ -10,33 +10,10 @@
 #ifdef FIPS_MODULE
 #include <openssl/types.h>

-int ossl_fips_config_security_checks(OSSL_LIB_CTX *libctx);
-int ossl_fips_config_tls1_prf_ems_check(OSSL_LIB_CTX *libctx);
-int ossl_fips_config_no_short_mac(OSSL_LIB_CTX *libctx);
-int ossl_fips_config_hmac_key_check(OSSL_LIB_CTX *libctx);
-int ossl_fips_config_kmac_key_check(OSSL_LIB_CTX *libctx);
-int ossl_fips_config_restricted_drbg_digests(OSSL_LIB_CTX *libctx);
-int ossl_fips_config_signature_digest_check(OSSL_LIB_CTX *libctx);
-int ossl_fips_config_hkdf_digest_check(OSSL_LIB_CTX *libctx);
-int ossl_fips_config_tls13_kdf_digest_check(OSSL_LIB_CTX *libctx);
-int ossl_fips_config_tls1_prf_digest_check(OSSL_LIB_CTX *libctx);
-int ossl_fips_config_sshkdf_digest_check(OSSL_LIB_CTX *libctx);
-int ossl_fips_config_sskdf_digest_check(OSSL_LIB_CTX *libctx);
-int ossl_fips_config_x963kdf_digest_check(OSSL_LIB_CTX *libctx);
-int ossl_fips_config_dsa_sign_disallowed(OSSL_LIB_CTX *libctx);
-int ossl_fips_config_tdes_encrypt_disallowed(OSSL_LIB_CTX *libctx);
-int ossl_fips_config_rsa_pkcs15_padding_disabled(OSSL_LIB_CTX *libctx);
-int ossl_fips_config_rsa_pss_saltlen_check(OSSL_LIB_CTX *libctx);
-int ossl_fips_config_rsa_sign_x931_disallowed(OSSL_LIB_CTX *libctx);
-int ossl_fips_config_hkdf_key_check(OSSL_LIB_CTX *libctx);
-int ossl_fips_config_kbkdf_key_check(OSSL_LIB_CTX *libctx);
-int ossl_fips_config_tls13_kdf_key_check(OSSL_LIB_CTX *libctx);
-int ossl_fips_config_tls1_prf_key_check(OSSL_LIB_CTX *libctx);
-int ossl_fips_config_sshkdf_key_check(OSSL_LIB_CTX *libctx);
-int ossl_fips_config_sskdf_key_check(OSSL_LIB_CTX *libctx);
-int ossl_fips_config_x963kdf_key_check(OSSL_LIB_CTX *libctx);
-int ossl_fips_config_x942kdf_key_check(OSSL_LIB_CTX *libctx);
-int ossl_fips_config_pbkdf2_lower_bound_check(OSSL_LIB_CTX *libctx);
-int ossl_fips_config_ecdh_cofactor_check(OSSL_LIB_CTX *libctx);
+#define FIPSPARAMS_AS_HEADER
+#include "providers/fips/fipsparams.inc"
+#undef FIPSPARAMS_AS_HEADER
+
+int ossl_fips_config(OSSL_LIB_CTX *libctx, enum fips_config_id id);

 #endif
diff --git a/providers/fips/self_test.c b/providers/fips/self_test.c
index b6d0427ba8..2082bf0e03 100644
--- a/providers/fips/self_test.c
+++ b/providers/fips/self_test.c
@@ -358,8 +358,7 @@ int SELF_TEST_post(SELF_TEST_POST_PARAMS *st, void *fips_global,
             goto locked_end;
         }

-        if ((st->defer_tests != NULL)
-            && strcmp(st->defer_tests, "1") == 0) {
+        if (st->defer_tests == 1) {
             /* Mark all non executed tests as deferred */
             for (int i = 0; i < ST_ID_MAX; i++) {
                 if (st_all_tests[i].state == SELF_TEST_STATE_INIT) {
diff --git a/providers/fips/self_test.h b/providers/fips/self_test.h
index e850a74aa0..bed8e96825 100644
--- a/providers/fips/self_test.h
+++ b/providers/fips/self_test.h
@@ -17,11 +17,8 @@ typedef struct self_test_post_params_st {
     const char *module_filename; /* Module file to perform MAC on */
     const char *module_checksum_data; /* Expected module MAC integrity */

-    /* Used for continuous tests */
-    const char *conditional_error_check;
-
     /* Used to decide whether to defer tests or not */
-    const char *defer_tests;
+    unsigned char defer_tests;

     /* BIO callbacks supplied to the FIPS provider */
     OSSL_FUNC_BIO_new_file_fn *bio_new_file_cb;
diff --git a/providers/implementations/asymciphers/rsa_enc.c b/providers/implementations/asymciphers/rsa_enc.c
index 246f68f55d..6baf553408 100644
--- a/providers/implementations/asymciphers/rsa_enc.c
+++ b/providers/implementations/asymciphers/rsa_enc.c
@@ -173,7 +173,7 @@ static int rsa_encrypt(void *vprsactx, unsigned char *out, size_t *outlen,
         && !OSSL_FIPS_IND_ON_UNAPPROVED(prsactx, OSSL_FIPS_IND_SETTABLE1,
             prsactx->libctx, "RSA Encrypt",
             "PKCS#1 v1.5 padding",
-            ossl_fips_config_rsa_pkcs15_padding_disabled)) {
+            FIPS_CONFIG_RSA_PKCS15_PAD_DISABLED)) {
         ERR_raise(ERR_LIB_PROV, PROV_R_INVALID_PADDING_MODE);
         return 0;
     }
diff --git a/providers/implementations/ciphers/cipher_tdes_common.c b/providers/implementations/ciphers/cipher_tdes_common.c
index 432ccade97..20dc77f32c 100644
--- a/providers/implementations/ciphers/cipher_tdes_common.c
+++ b/providers/implementations/ciphers/cipher_tdes_common.c
@@ -65,7 +65,10 @@ void ossl_tdes_freectx(void *vctx)
 static int tdes_encrypt_check_approved(PROV_TDES_CTX *ctx, int enc)
 {
     /* Triple-DES encryption is not approved in FIPS 140-3 */
-    if (enc && !OSSL_FIPS_IND_ON_UNAPPROVED(ctx, OSSL_FIPS_IND_SETTABLE0, ctx->base.libctx, "Triple-DES", "Encryption", ossl_fips_config_tdes_encrypt_disallowed))
+    if (enc
+        && !OSSL_FIPS_IND_ON_UNAPPROVED(ctx, OSSL_FIPS_IND_SETTABLE0,
+            ctx->base.libctx, "Triple-DES", "Encryption",
+            FIPS_CONFIG_TDES_ENCRYPT_DISABLED))
         return 0;
     return 1;
 }
diff --git a/providers/implementations/exchange/dh_exch.c b/providers/implementations/exchange/dh_exch.c
index 6147c36423..6421520821 100644
--- a/providers/implementations/exchange/dh_exch.c
+++ b/providers/implementations/exchange/dh_exch.c
@@ -112,7 +112,7 @@ static int dh_check_key(PROV_DH_CTX *ctx)
     if (!key_approved) {
         if (!OSSL_FIPS_IND_ON_UNAPPROVED(ctx, OSSL_FIPS_IND_SETTABLE0,
                 ctx->libctx, "DH Init", "DH Key",
-                ossl_fips_config_securitycheck_enabled)) {
+                FIPS_CONFIG_SECURITY_CHECKS)) {
             ERR_raise(ERR_LIB_PROV, PROV_R_INVALID_KEY_LENGTH);
             return 0;
         }
diff --git a/providers/implementations/exchange/ecdh_exch.c b/providers/implementations/exchange/ecdh_exch.c
index e69544795d..0355807624 100644
--- a/providers/implementations/exchange/ecdh_exch.c
+++ b/providers/implementations/exchange/ecdh_exch.c
@@ -507,7 +507,7 @@ static ossl_inline int ecdh_plain_derive(void *vpecdhctx, unsigned char *secret,
     if (has_cofactor && !cofactor_approved) {
         if (!OSSL_FIPS_IND_ON_UNAPPROVED(pecdhctx, OSSL_FIPS_IND_SETTABLE2,
                 pecdhctx->libctx, "ECDH", "Cofactor",
-                ossl_fips_config_ecdh_cofactor_check)) {
+                FIPS_CONFIG_ECDH_COFACTOR_CHECK)) {
             ERR_raise(ERR_LIB_PROV, PROV_R_COFACTOR_REQUIRED);
             goto end;
         }
diff --git a/providers/implementations/kdfs/hkdf.c b/providers/implementations/kdfs/hkdf.c
index 6aa17a4f2d..c1a68f08ed 100644
--- a/providers/implementations/kdfs/hkdf.c
+++ b/providers/implementations/kdfs/hkdf.c
@@ -219,7 +219,7 @@ static int fips_hkdf_key_check_passed(KDF_HKDF *ctx)
     if (!key_approved) {
         if (!OSSL_FIPS_IND_ON_UNAPPROVED(ctx, OSSL_FIPS_IND_SETTABLE0,
                 libctx, "HKDF", "Key size",
-                ossl_fips_config_hkdf_key_check)) {
+                FIPS_CONFIG_HKDF_KEY_CHECK)) {
             ERR_raise(ERR_LIB_PROV, PROV_R_INVALID_KEY_LENGTH);
             return 0;
         }
@@ -884,7 +884,7 @@ static int fips_tls1_3_digest_check_passed(KDF_HKDF *ctx, const EVP_MD *md)
     if (digest_unapproved) {
         if (!OSSL_FIPS_IND_ON_UNAPPROVED(ctx, OSSL_FIPS_IND_SETTABLE0,
                 libctx, "TLS13 KDF", "Digest",
-                ossl_fips_config_tls13_kdf_digest_check)) {
+                FIPS_CONFIG_TLS13_KDF_DIGEST_CHECK)) {
             ERR_raise(ERR_LIB_PROV, PROV_R_DIGEST_NOT_ALLOWED);
             return 0;
         }
@@ -920,7 +920,7 @@ static int fips_tls1_3_key_check_passed(KDF_HKDF *ctx)
     if (!key_approved) {
         if (!OSSL_FIPS_IND_ON_UNAPPROVED(ctx, OSSL_FIPS_IND_SETTABLE1,
                 libctx, "TLS13 KDF", "Key size",
-                ossl_fips_config_tls13_kdf_key_check)) {
+                FIPS_CONFIG_TLS13_KDF_KEY_CHECK)) {
             ERR_raise(ERR_LIB_PROV, PROV_R_INVALID_KEY_LENGTH);
             return 0;
         }
diff --git a/providers/implementations/kdfs/kbkdf.c b/providers/implementations/kdfs/kbkdf.c
index e926761514..100d010966 100644
--- a/providers/implementations/kdfs/kbkdf.c
+++ b/providers/implementations/kdfs/kbkdf.c
@@ -205,7 +205,7 @@ static int fips_kbkdf_key_check_passed(KBKDF *ctx)
     if (!key_approved) {
         if (!OSSL_FIPS_IND_ON_UNAPPROVED(ctx, OSSL_FIPS_IND_SETTABLE0,
                 libctx, "KBKDF", "Key size",
-                ossl_fips_config_kbkdf_key_check)) {
+                FIPS_CONFIG_KBKDF_KEY_CHECK)) {
             ERR_raise(ERR_LIB_PROV, PROV_R_INVALID_KEY_LENGTH);
             return 0;
         }
diff --git a/providers/implementations/kdfs/pbkdf2.c b/providers/implementations/kdfs/pbkdf2.c
index 597f2bc3ca..88cb8c73df 100644
--- a/providers/implementations/kdfs/pbkdf2.c
+++ b/providers/implementations/kdfs/pbkdf2.c
@@ -268,7 +268,7 @@ static int fips_lower_bound_check_passed(KDF_PBKDF2 *ctx, int saltlen,
     if (!approved) {
         if (!OSSL_FIPS_IND_ON_UNAPPROVED(ctx, OSSL_FIPS_IND_SETTABLE0, libctx,
                 "PBKDF2", desc,
-                ossl_fips_config_pbkdf2_lower_bound_check)) {
+                FIPS_CONFIG_PBKDF2_LOWER_BOUND_CHECK)) {
             ERR_raise(ERR_LIB_PROV, error);
             return 0;
         }
diff --git a/providers/implementations/kdfs/sshkdf.c b/providers/implementations/kdfs/sshkdf.c
index 1377dccbf6..ee2f75a7c2 100644
--- a/providers/implementations/kdfs/sshkdf.c
+++ b/providers/implementations/kdfs/sshkdf.c
@@ -156,7 +156,7 @@ static int fips_digest_check_passed(KDF_SSHKDF *ctx, const EVP_MD *md)
     if (digest_unapproved) {
         if (!OSSL_FIPS_IND_ON_UNAPPROVED(ctx, OSSL_FIPS_IND_SETTABLE0,
                 libctx, "SSHKDF", "Digest",
-                ossl_fips_config_sshkdf_digest_check)) {
+                FIPS_CONFIG_SSHKDF_DIGEST_CHECK)) {
             ERR_raise(ERR_LIB_PROV, PROV_R_DIGEST_NOT_ALLOWED);
             return 0;
         }
@@ -172,7 +172,7 @@ static int fips_key_check_passed(KDF_SSHKDF *ctx)
     if (!key_approved) {
         if (!OSSL_FIPS_IND_ON_UNAPPROVED(ctx, OSSL_FIPS_IND_SETTABLE1,
                 libctx, "SSHKDF", "Key size",
-                ossl_fips_config_sshkdf_key_check)) {
+                FIPS_CONFIG_SSHKDF_KEY_CHECK)) {
             ERR_raise(ERR_LIB_PROV, PROV_R_INVALID_KEY_LENGTH);
             return 0;
         }
diff --git a/providers/implementations/kdfs/sskdf.c b/providers/implementations/kdfs/sskdf.c
index 11696a5a85..572ef4134f 100644
--- a/providers/implementations/kdfs/sskdf.c
+++ b/providers/implementations/kdfs/sskdf.c
@@ -446,7 +446,7 @@ static int fips_sskdf_key_check_passed(KDF_SSKDF *ctx)
     if (!key_approved) {
         if (!OSSL_FIPS_IND_ON_UNAPPROVED(ctx, OSSL_FIPS_IND_SETTABLE0,
                 libctx, "SSKDF", "Key size",
-                ossl_fips_config_sskdf_key_check)) {
+                FIPS_CONFIG_SSKDF_KEY_CHECK)) {
             ERR_raise(ERR_LIB_PROV, PROV_R_INVALID_KEY_LENGTH);
             return 0;
         }
@@ -541,7 +541,7 @@ static int fips_x963kdf_digest_check_passed(KDF_SSKDF *ctx, const EVP_MD *md)
     if (digest_unapproved) {
         if (!OSSL_FIPS_IND_ON_UNAPPROVED(ctx, OSSL_FIPS_IND_SETTABLE0,
                 libctx, "X963KDF", "Digest",
-                ossl_fips_config_x963kdf_digest_check)) {
+                FIPS_CONFIG_X963KDF_DIGEST_CHECK)) {
             ERR_raise(ERR_LIB_PROV, PROV_R_DIGEST_NOT_ALLOWED);
             return 0;
         }
@@ -557,7 +557,7 @@ static int fips_x963kdf_key_check_passed(KDF_SSKDF *ctx)
     if (!key_approved) {
         if (!OSSL_FIPS_IND_ON_UNAPPROVED(ctx, OSSL_FIPS_IND_SETTABLE1,
                 libctx, "X963KDF", "Key size",
-                ossl_fips_config_x963kdf_key_check)) {
+                FIPS_CONFIG_X963KDF_KEY_CHECK)) {
             ERR_raise(ERR_LIB_PROV, PROV_R_INVALID_KEY_LENGTH);
             return 0;
         }
diff --git a/providers/implementations/kdfs/tls1_prf.c b/providers/implementations/kdfs/tls1_prf.c
index 2abbc08ff1..07fcdd058e 100644
--- a/providers/implementations/kdfs/tls1_prf.c
+++ b/providers/implementations/kdfs/tls1_prf.c
@@ -207,7 +207,7 @@ static int fips_ems_check_passed(TLS1_PRF *ctx)
     if (!ems_approved) {
         if (!OSSL_FIPS_IND_ON_UNAPPROVED(ctx, OSSL_FIPS_IND_SETTABLE0,
                 libctx, "TLS_PRF", "EMS",
-                ossl_fips_config_tls1_prf_ems_check)) {
+                FIPS_CONFIG_TLS1_PRF_EMS_CHECK)) {
             ERR_raise(ERR_LIB_PROV, PROV_R_EMS_NOT_ENABLED);
             return 0;
         }
@@ -232,7 +232,7 @@ static int fips_digest_check_passed(TLS1_PRF *ctx, const EVP_MD *md)
     if (digest_unapproved) {
         if (!OSSL_FIPS_IND_ON_UNAPPROVED(ctx, OSSL_FIPS_IND_SETTABLE1,
                 libctx, "TLS_PRF", "Digest",
-                ossl_fips_config_tls1_prf_digest_check)) {
+                FIPS_CONFIG_TLS1_PRF_DIGEST_CHECK)) {
             ERR_raise(ERR_LIB_PROV, PROV_R_DIGEST_NOT_ALLOWED);
             return 0;
         }
@@ -248,7 +248,7 @@ static int fips_key_check_passed(TLS1_PRF *ctx)
     if (!key_approved) {
         if (!OSSL_FIPS_IND_ON_UNAPPROVED(ctx, OSSL_FIPS_IND_SETTABLE2,
                 libctx, "TLS_PRF", "Key size",
-                ossl_fips_config_tls1_prf_key_check)) {
+                FIPS_CONFIG_TLS1_PRF_KEY_CHECK)) {
             ERR_raise(ERR_LIB_PROV, PROV_R_INVALID_KEY_LENGTH);
             return 0;
         }
diff --git a/providers/implementations/kdfs/x942kdf.c b/providers/implementations/kdfs/x942kdf.c
index 8e3354aa0f..3565243cc9 100644
--- a/providers/implementations/kdfs/x942kdf.c
+++ b/providers/implementations/kdfs/x942kdf.c
@@ -452,7 +452,7 @@ static int fips_x942kdf_key_check_passed(KDF_X942 *ctx)
     if (!key_approved) {
         if (!OSSL_FIPS_IND_ON_UNAPPROVED(ctx, OSSL_FIPS_IND_SETTABLE0,
                 libctx, "X942KDF", "Key size",
-                ossl_fips_config_x942kdf_key_check)) {
+                FIPS_CONFIG_X942KDF_KEY_CHECK)) {
             ERR_raise(ERR_LIB_PROV, PROV_R_INVALID_KEY_LENGTH);
             return 0;
         }
diff --git a/providers/implementations/keymgmt/dsa_kmgmt.c b/providers/implementations/keymgmt/dsa_kmgmt.c
index d03a52af02..3540706b54 100644
--- a/providers/implementations/keymgmt/dsa_kmgmt.c
+++ b/providers/implementations/keymgmt/dsa_kmgmt.c
@@ -626,7 +626,7 @@ static void *dsa_gen(void *genctx, OSSL_CALLBACK *osslcb, void *cbarg)
      */
     if (!OSSL_FIPS_IND_ON_UNAPPROVED(gctx, OSSL_FIPS_IND_SETTABLE0,
             gctx->libctx, "DSA", "Keygen",
-            ossl_fips_config_dsa_sign_disallowed))
+            FIPS_CONFIG_DSA_SIGN_DISABLED))
         return 0;
 #endif

diff --git a/providers/implementations/macs/cmac_prov.c b/providers/implementations/macs/cmac_prov.c
index 9fd6cd8e51..6396e0eac9 100644
--- a/providers/implementations/macs/cmac_prov.c
+++ b/providers/implementations/macs/cmac_prov.c
@@ -139,7 +139,7 @@ static int tdes_check_param(struct cmac_data_st *macctx, OSSL_PARAM *p,
     if (EVP_CIPHER_is_a(cipher, "DES-EDE3-CBC")) {
         if (!OSSL_FIPS_IND_ON_UNAPPROVED(macctx, OSSL_FIPS_IND_SETTABLE0,
                 libctx, "CMAC", "Triple-DES",
-                ossl_fips_config_tdes_encrypt_disallowed))
+                FIPS_CONFIG_TDES_ENCRYPT_DISABLED))
             return 0;
         OSSL_FIPS_IND_GET_PARAM(macctx, p, state, OSSL_FIPS_IND_SETTABLE0,
             OSSL_CIPHER_PARAM_FIPS_ENCRYPT_CHECK)
diff --git a/providers/implementations/macs/hmac_prov.c b/providers/implementations/macs/hmac_prov.c
index 388e95ad8a..f3dcdf962b 100644
--- a/providers/implementations/macs/hmac_prov.c
+++ b/providers/implementations/macs/hmac_prov.c
@@ -171,7 +171,7 @@ static int hmac_setkey(struct hmac_data_st *macctx,
         if (!approved) {
             if (!OSSL_FIPS_IND_ON_UNAPPROVED(macctx, OSSL_FIPS_IND_SETTABLE0,
                     libctx, "HMAC", "keysize",
-                    ossl_fips_config_hmac_key_check)) {
+                    FIPS_CONFIG_HMAC_KEY_CHECK)) {
                 ERR_raise(ERR_LIB_PROV, PROV_R_INVALID_KEY_LENGTH);
                 return 0;
             }
diff --git a/providers/implementations/macs/kmac_prov.c b/providers/implementations/macs/kmac_prov.c
index 41da1bf8c3..97e23261a0 100644
--- a/providers/implementations/macs/kmac_prov.c
+++ b/providers/implementations/macs/kmac_prov.c
@@ -278,7 +278,7 @@ static int kmac_setkey(struct kmac_data_st *kctx, const unsigned char *key,
             if (!OSSL_FIPS_IND_ON_UNAPPROVED(kctx, OSSL_FIPS_IND_SETTABLE1,
                     PROV_LIBCTX_OF(kctx->provctx),
                     "KMAC", "Key size",
-                    ossl_fips_config_kmac_key_check)) {
+                    FIPS_CONFIG_KMAC_KEY_CHECK)) {
                 ERR_raise(ERR_LIB_PROV, PROV_R_INVALID_KEY_LENGTH);
                 return 0;
             }
@@ -463,7 +463,7 @@ static int kmac_set_ctx_params(void *vmacctx, const OSSL_PARAM *params)
             if (!OSSL_FIPS_IND_ON_UNAPPROVED(kctx, OSSL_FIPS_IND_SETTABLE0,
                     PROV_LIBCTX_OF(kctx->provctx),
                     "KMAC", "length",
-                    ossl_fips_config_no_short_mac)) {
+                    FIPS_CONFIG_NO_SHORT_MAC)) {
                 ERR_raise(ERR_LIB_PROV, PROV_R_INVALID_OUTPUT_LENGTH);
                 return 0;
             }
diff --git a/providers/implementations/rands/drbg.c b/providers/implementations/rands/drbg.c
index 9e80ef5b1f..50027b9b0b 100644
--- a/providers/implementations/rands/drbg.c
+++ b/providers/implementations/rands/drbg.c
@@ -1010,7 +1010,7 @@ int ossl_drbg_verify_digest(PROV_DRBG *drbg, OSSL_LIB_CTX *libctx,
     if (!approved) {
         if (!OSSL_FIPS_IND_ON_UNAPPROVED(drbg, OSSL_FIPS_IND_SETTABLE0,
                 libctx, "DRBG", "Digest",
-                ossl_fips_config_restricted_drbg_digests)) {
+                FIPS_CONFIG_DRBG_TRUNC_DIGEST)) {
             ERR_raise(ERR_LIB_PROV, PROV_R_DIGEST_NOT_ALLOWED);
             return 0;
         }
diff --git a/providers/implementations/signature/dsa_sig.c b/providers/implementations/signature/dsa_sig.c
index 72a35beaf3..e2f093b556 100644
--- a/providers/implementations/signature/dsa_sig.c
+++ b/providers/implementations/signature/dsa_sig.c
@@ -202,7 +202,7 @@ static int dsa_setup_md(PROV_DSA_CTX *ctx,
                     OSSL_FIPS_IND_SETTABLE1,
                     ctx->libctx,
                     md_nid, sha1_allowed, 0, desc,
-                    ossl_fips_config_signature_digest_check))
+                    FIPS_CONFIG_SIGNATURE_DIGEST_CHECK))
                 goto err;
         }
 #endif
@@ -260,7 +260,7 @@ static int dsa_sign_check_approved(PROV_DSA_CTX *ctx, int signing,
     if (signing
         && !OSSL_FIPS_IND_ON_UNAPPROVED(ctx, OSSL_FIPS_IND_SETTABLE2,
             ctx->libctx, desc, "DSA",
-            ossl_fips_config_dsa_sign_disallowed))
+            FIPS_CONFIG_DSA_SIGN_DISABLED))
         return 0;
     return 1;
 }
@@ -272,7 +272,7 @@ static int dsa_check_key(PROV_DSA_CTX *ctx, int sign, const char *desc)
     if (!approved) {
         if (!OSSL_FIPS_IND_ON_UNAPPROVED(ctx, OSSL_FIPS_IND_SETTABLE0,
                 ctx->libctx, desc, "DSA Key",
-                ossl_fips_config_signature_digest_check)) {
+                FIPS_CONFIG_SIGNATURE_DIGEST_CHECK)) {
             ERR_raise(ERR_LIB_PROV, PROV_R_INVALID_KEY_LENGTH);
             return 0;
         }
diff --git a/providers/implementations/signature/ecdsa_sig.c b/providers/implementations/signature/ecdsa_sig.c
index 9e30063b3c..8a399a6b29 100644
--- a/providers/implementations/signature/ecdsa_sig.c
+++ b/providers/implementations/signature/ecdsa_sig.c
@@ -248,7 +248,7 @@ static int ecdsa_setup_md(PROV_ECDSA_CTX *ctx,
                 OSSL_FIPS_IND_SETTABLE1,
                 ctx->libctx,
                 md_nid, sha1_allowed, 0, desc,
-                ossl_fips_config_signature_digest_check))
+                FIPS_CONFIG_SIGNATURE_DIGEST_CHECK))
             goto err;
     }
 #endif
diff --git a/providers/implementations/signature/rsa_sig.c b/providers/implementations/signature/rsa_sig.c
index 239ac002ca..a4c5a90741 100644
--- a/providers/implementations/signature/rsa_sig.c
+++ b/providers/implementations/signature/rsa_sig.c
@@ -424,7 +424,7 @@ static int rsa_setup_md(PROV_RSA_CTX *ctx, const char *mdname,
                     OSSL_FIPS_IND_SETTABLE1,
                     ctx->libctx,
                     md_nid, sha1_allowed, 1, desc,
-                    ossl_fips_config_signature_digest_check))
+                    FIPS_CONFIG_SIGNATURE_DIGEST_CHECK))
                 goto err;
         }
 #endif
@@ -656,7 +656,7 @@ static int rsa_pss_saltlen_check_passed(PROV_RSA_CTX *ctx, const char *algoname,
         if (!OSSL_FIPS_IND_ON_UNAPPROVED(ctx, OSSL_FIPS_IND_SETTABLE3,
                 ctx->libctx,
                 algoname, "PSS Salt Length",
-                ossl_fips_config_rsa_pss_saltlen_check)) {
+                FIPS_CONFIG_RSA_PSS_SALTLEN_CHECK)) {
             ERR_raise(ERR_LIB_PROV, PROV_R_INVALID_SALT_LENGTH);
             return 0;
         }
@@ -1504,7 +1504,7 @@ static int rsa_x931_padding_allowed(PROV_RSA_CTX *ctx)
         if (!OSSL_FIPS_IND_ON_UNAPPROVED(ctx, OSSL_FIPS_IND_SETTABLE2,
                 ctx->libctx,
                 "RSA Sign set ctx", "X931 Padding",
-                ossl_fips_config_rsa_sign_x931_disallowed)) {
+                FIPS_CONFIG_RSA_SIGN_X931_PAD_DISABLED)) {
             ERR_raise(ERR_LIB_PROV,
                 PROV_R_ILLEGAL_OR_UNSUPPORTED_PADDING_MODE);
             return 0;
diff --git a/util/perl/OpenSSL/fipsparams.pm b/util/perl/OpenSSL/fipsparams.pm
old mode 100644
new mode 100755
index b6ea39707c..38ba27b5b1
--- a/util/perl/OpenSSL/fipsparams.pm
+++ b/util/perl/OpenSSL/fipsparams.pm
@@ -13,123 +13,171 @@ use warnings;
 use Exporter;

 our @ISA = qw(Exporter);
-our @EXPORT_OK = qw(produce_fips_indicators produce_fips_selftest_params);
+our @EXPORT_OK = qw(produce_fips_params);

-sub produce_fips_indicators {
+sub produce_fips_params {
     my @params = @_;
     my $s;
     open(local *STDOUT, '>', \$s);

     print "/* Machine generated by util/perl/OpenSSL/fipsparams.pm */\n";
     print "\n";
-    print "typedef struct fips_indicators_st {\n";
+
+    print "#ifdef FIPSPARAMS_AS_HEADER\n";
+    print "enum fips_config_id {\n";
+    my $first = " = 1";
     foreach my $p (@params) {
-        printf "    const char *%s_string;\n", $p->[0];
-        printf "    unsigned char %s_enabled;\n", $p->[0];
+        my $name  = $p->[1];
+        my $use = $p->[4];
+        if ($use eq 'indicator') {
+            print "    FIPS_CONFIG_$name$first,\n";
+            $first = "";
+        }
     }
-    print "} FIPS_INDICATORS;\n";
+    print "};\n";

+    print "#else /* FIPSPARAMS_AS_HEADER */\n";
     print "\n";
-    print "static void init_fips_indicators(FIPS_INDICATORS *indicators)\n";
-    print "{\n";
+    print "typedef struct fips_params_st {\n";
     foreach my $p (@params) {
         my $field = $p->[0];
-        my $name = $p->[1];
-        my $enabled = $p->[2];
-        printf "    indicators->%s_string = \"%s\";\n", $field, $enabled;
-        printf "    indicators->%s_enabled = %s;\n", $field, $enabled;
+        my $type = $p->[2];
+        my $sep = $type =~ /\*$/ ? "" : " ";
+        printf "    $type$sep$field;\n";
     }
-    print "}\n";
+    print "} FIPS_PARAMS;\n";

     print "\n";
-    print "static OSSL_PARAM *get_fips_indicator_params_from_core(\n";
-    print "    OSSL_PARAM *op, FIPS_INDICATORS *fi)\n";
+    print "static void init_fips_params(FIPS_PARAMS *fp)\n";
     print "{\n";
     foreach my $p (@params) {
         my $field = $p->[0];
-        my $name  = $p->[1];
-        print "    *op++ = OSSL_PARAM_construct_utf8_ptr(\n";
-        printf "        $name, (char **)&fi->%s_string,\n", $field;
-        printf "        sizeof(fi->%s_string));\n", $field;
+        my $default = $p->[3];
+        printf "    fp->$field = $default;\n";
     }
-    print "    return op;\n";
     print "}\n";

     print "\n";
-    print "#define OSSL_FIPS_INDICATOR_PARAM_TYPES \\\n";
-    my $cnt = 0;
+    print "/*\n";
+    print " * Parameters to retrieve from the core provider\n";
+    print " * NOTE: inside core_get_params() these will be loaded from config items\n";
+    print " * stored inside prov->parameters\n";
+    print " */\n";
+    print "static int fips_get_params_from_core(\n";
+    print "    const OSSL_CORE_HANDLE *handle, FIPS_PARAMS *fp)\n";
+    print "{\n";
+    foreach my $p (@params) {
+        my $field = $p->[0];
+        print "    const char *$field = NULL;\n";
+    }
+    print "    OSSL_PARAM core_params[] = {\n";
     foreach my $p (@params) {
+        my $field = $p->[0];
         my $name  = $p->[1];
-        print "    OSSL_PARAM_DEFN($name, OSSL_PARAM_INTEGER, NULL, 0)";
-        print "," if ($cnt++ < $#params);
-        print "\\\n";
+        my $type  = $p->[2];
+        my $use = $p->[4];
+        if ($use eq 'indicator') {
+            $name = "OSSL_PROV_PARAM_" . $name;
+        }
+        print "        OSSL_PARAM_construct_utf8_ptr($name,\n";
+        print "            (char **)&$field, 0),\n";
     }
+    print "        OSSL_PARAM_construct_end()\n";
+    print "    };\n";
+    print "    OSSL_PARAM *p = core_params;\n";
     print "\n";
-
+    print "    if (!c_get_params(handle, core_params)) {\n";
+    print "        return 0;\n";
+    print "    }\n";
     print "\n";
-    print "static int get_fips_indicator_params(OSSL_PARAM *params, FIPS_INDICATORS *fi)\n";
-    print "{\n";
-    print "    OSSL_PARAM *p;\n";
+    print "    for (;p->key != NULL; p++) {\n";
+    print "        if (OSSL_PARAM_modified(p)) {\n";
     foreach my $p (@params) {
         my $field = $p->[0];
         my $name  = $p->[1];
-        print "    p = OSSL_PARAM_locate(params, $name);\n";
-        printf "    if (p != NULL && !OSSL_PARAM_set_int(p, fi->%s_enabled))\n", $field;
-        print "        return 0;\n";
+        my $type  = $p->[2];
+        my $use = $p->[4];
+        if ($use eq 'indicator') {
+            $name = "OSSL_PROV_PARAM_" . $name;
+        }
+        print "            if (strcmp($name, p->key) == 0) {\n";
+        if ($type eq 'const char *') {
+            print "                fp->$field = $field;\n";
+        } elsif ($type eq 'unsigned char') {
+            print "                if ($field != NULL\n";
+            print "                    && strcmp($field, \"1\") == 0)\n";
+            print "                    fp->$field = 1;\n";
+            print "                else if ($field != NULL\n";
+            print "                    && strcmp($field, \"0\") == 0)\n";
+            print "                    fp->$field = 0;\n";
+            print "                else\n";
+            print "                    return 0;\n";
+        }
+        print "            }\n";
     }
+    print "        }\n";
+    print "    }\n";
     print "    return 1;\n";
     print "}\n";

     print "\n";
-    print "static int set_fips_indicators_from_core(FIPS_INDICATORS *fi)\n";
-    print "{\n";
+    print "#define OSSL_FIPS_PARAMS_DEFN_TYPES \\\n";
+    my $cnt = 0;
+    my $sep = "";
     foreach my $p (@params) {
-        my $field = $p->[0];
-        printf "    if (fi->%s_string != NULL) {\n", $field;
-        printf "        if (strcmp(fi->%s_string, \"1\") == 0)\n", $field;
-        printf "            fi->%s_enabled = 1;\n", $field;
-        printf "        else if (strcmp(fi->%s_string, \"0\") == 0)\n", $field;
-        printf "            fi->%s_enabled = 0;\n", $field;
-        print "        else\n";
-        print "            return 0;\n";
-        print "    }\n";
+        my $use = $p->[4];
+        if ($use eq 'indicator') {
+            my $name  = "OSSL_PROV_PARAM_" . $p->[1];
+            print "$sep    OSSL_PARAM_DEFN($name, OSSL_PARAM_INTEGER, NULL, 0)";
+            $sep = ", \\\n";
+        }
     }
-    print "    return 1;\n";
-    print "}\n";
+    print "\n";

+    print "\n";
+    print "static int return_fips_params(OSSL_PARAM *params, FIPS_PARAMS *fp)\n";
+    print "{\n";
+    print "    OSSL_PARAM *p = params;\n";
+    print "\n";
+    print "    for (;p->key != NULL; p++) {\n";
     foreach my $p (@params) {
         my $field = $p->[0];
-        print "\n";
-        printf "int ossl_fips_config_%s(OSSL_LIB_CTX *libctx)\n", $field;
-        print "{\n";
-        print "    FIPS_GLOBAL *fgbl = ossl_lib_ctx_get_data(libctx, OSSL_LIB_CTX_FIPS_PROV_INDEX);\n";
-        print "    FIPS_INDICATORS *indicators = get_fips_indicators(fgbl);\n";
-        printf "    return indicators->%s_enabled;\n", $field;
-        print "}\n";
+        my $use = $p->[4];
+        if ($use eq 'indicator') {
+            my $name = "OSSL_PROV_PARAM_" . $p->[1];
+            print "        if (strcmp($name, p->key) == 0)\n";
+            print "            if (!OSSL_PARAM_set_int(p, fp->$field))\n";
+            print "               return 0;\n";
+        }
     }
+    print "    }\n";
+    print "    return 1;\n";
+    print "}\n";

-    return $s;
-}
-
-sub produce_fips_selftest_params {
-    my @params = @_;
-    my $s;
-    open(local *STDOUT, '>', \$s);
-
-    print "/* Machine generated by util/perl/OpenSSL/fipsparams.pm */\n";
-
-    print "static OSSL_PARAM *get_fips_selftest_params_from_core(\n";
-    print "    OSSL_PARAM *op, SELF_TEST_POST_PARAMS *stpp)\n";
+    print "\n";
+    print "struct fips_global_st;\n";
+    print "static FIPS_PARAMS *get_fips_params(struct fips_global_st *fgbl);\n";
+    print "int ossl_fips_config(OSSL_LIB_CTX *libctx, enum fips_config_id id)\n";
     print "{\n";
+    print "    struct fips_global_st *fgbl = ossl_lib_ctx_get_data(libctx, OSSL_LIB_CTX_FIPS_PROV_INDEX);\n";
+    print "    FIPS_PARAMS *params = get_fips_params(fgbl);\n";
+    print "    switch (id) {\n";
     foreach my $p (@params) {
         my $field = $p->[0];
-        my $name  = $p->[1];
-        print "    *op++ = OSSL_PARAM_construct_utf8_ptr(\n";
-        print "        $name, (char **)&stpp->$field,\n";
-        print "        sizeof(stpp->$field));\n";
+        my $use = $p->[4];
+        if ($use eq 'indicator') {
+            my $id = "FIPS_CONFIG_" . $p->[1];
+            print "    case $id:\n";
+            print "        return params->$field;\n";
+        }
     }
-    print "    return op;\n";
+    print "    default:\n";
+    print "        return -1;\n";
+    print "    }\n";
     print "}\n";

+    print "\n";
+    print "#endif /* FIPSPARAMS_AS_HEADER */\n";
+
     return $s;
 }