]> git.ipfire.org Git - thirdparty/haproxy.git/commitdiff
MEDIUM: ssl: add fips_mode() config condition predicate
authorWilliam Lallemand <wlallemand@haproxy.com>
Thu, 13 Aug 2026 09:28:05 +0000 (09:28 +0000)
committerWilliam Lallemand <wlallemand@haproxy.com>
Thu, 13 Aug 2026 14:08:06 +0000 (16:08 +0200)
Add a new "fips_mode()" predicate usable in .if/.elif configuration
conditional blocks and with the "-cc" command line option. It
evaluates to true when the loaded SSL library is currently running in
FIPS mode.

The check relies on a new openssl_fips_mode() helper in tools.c,
following the same pattern as openssl_compare_current_version() and
awslc_compare_current_api(). Two APIs are used depending on the SSL
library:

  - FIPS_mode(), implemented by OpenSSL 1.0.x/1.1.x (including
    FIPS-validated builds) and by compatible libraries such as AWS-LC.

  - EVP_default_properties_is_fips_enabled(), for OpenSSL 3.0 and
    above, where FIPS_mode() was removed in favor of a provider-based
    FIPS model. It reports whether the default library context
    currently resolves algorithm fetches to the FIPS provider, which
    is the closest 3.x equivalent.

The predicate is a no-op (always false) with any other SSL library, or
when built without SSL support.

This lets configurations, and reg-tests in particular, detect and
adapt to (or skip) TLS constructs that are rejected by HAProxy's own
FIPS compliance checks (src/fips.c) when FIPS mode is active, e.g.
non-ECDHE TLS 1.2 cipher suites.

doc/configuration.txt
include/haproxy/cfgcond-t.h
include/haproxy/tools.h
src/cfgcond.c
src/tools.c

index 9cc90a9a76c23f2b426f51f82e1d6a1fc54444b7..06a54d09ce1dcc1e60e74916e570b24d368a03fb 100644 (file)
@@ -1208,6 +1208,9 @@ The list of currently supported predicates is the following:
                             in the features list reported by "haproxy -vv"
                             (which means a <name> appears after a '+')
 
+  - fips_mode()           : returns true if the loaded SSL library is
+                            currently running in FIPS mode.
+
   - openssl_version_atleast(<ver>) : returns true if the current openssl
                             version is at least as recent as <ver> otherwise
                             false.
index 73635bfd3e31f7293df4bf2d106f68b2047c80c2..f5e094e1db7cbe96cab6641d6e9e26214386bd62 100644 (file)
@@ -57,6 +57,7 @@ enum cond_predicate {
        CFG_PRED_AWSLC_API_ATLEAST,      // "awslc_api_atleast"
        CFG_PRED_AWSLC_API_BEFORE,       // "awslc_api_before"
        CFG_PRED_ENABLED,                // "enabled"
+       CFG_PRED_FIPS_MODE,              // "fips_mode"
 };
 
 /* types for condition terms */
index c4d95d096e58d5a23787d246e2692e22fea462c9..0cb7f345e80147ace12fc9d5c89e7ffca442b1a3 100644 (file)
@@ -1472,6 +1472,8 @@ int awslc_compare_current_api(const char *version);
 int openssl_compare_current_version(const char *version);
 /* compare the current OpenSSL name to a string */
 int openssl_compare_current_name(const char *name);
+/* returns whether the SSL library is currently running in FIPS mode */
+int openssl_fips_mode(void);
 
 /* vma helpers */
 void vma_set_name(void *addr, size_t size, const char *type, const char *name);
index f012e6040b02242fe79a9b3d25d47005a7af9e61..25a2c547345c6b458120beb8bafbc76fce588eb5 100644 (file)
@@ -32,6 +32,7 @@ const struct cond_pred_kw cond_predicates[] = {
        { "awslc_api_atleast",       CFG_PRED_AWSLC_API_ATLEAST,      ARG1(1, STR)         },
        { "awslc_api_before",        CFG_PRED_AWSLC_API_BEFORE,       ARG1(1, STR)         },
        { "enabled",                 CFG_PRED_ENABLED,                ARG1(1, STR)         },
+       { "fips_mode",               CFG_PRED_FIPS_MODE,              0                    },
        { NULL, CFG_PRED_NONE, 0 }
 };
 
@@ -321,6 +322,15 @@ int cfg_eval_cond_term(const struct cfg_cond_term *term, char **err)
                        ret = cfg_eval_cond_enabled(term->args[0].data.str.area) != 0;
                        break;
                }
+               case CFG_PRED_FIPS_MODE: { // checks if the SSL library is currently running in FIPS mode
+                       int fipsret = openssl_fips_mode();
+
+                       /* < -1 (i.e. -2) means the loaded SSL library doesn't support
+                        * FIPS mode at all, in which case the condition is simply false.
+                        */
+                       ret = fipsret > 0;
+                       break;
+               }
                default:
                        memprintf(err, "internal error: unhandled conditional expression predicate '%s'", term->pred->word);
                        break;
index c19f6fc2792a85c6f1941fcaee83989028a7ae3d..7783a89fc712b732ac29518b8416d66a8acf4c0f 100644 (file)
@@ -7465,6 +7465,32 @@ int openssl_compare_current_name(const char *name)
        return 1;
 }
 
+/*
+ * This function returns whether the SSL library currently loaded is running
+ * in FIPS mode.
+ *
+ * FIPS_mode() is implemented by OpenSSL 1.0.x/1.1.x (including
+ * FIPS-validated builds) as well as by libraries providing a compatible API
+ * such as AWS-LC. It was removed in OpenSSL 3.0, replaced by a provider-based
+ * FIPS model: EVP_default_properties_is_fips_enabled() reports whether the
+ * default library context currently resolves algorithm fetches to the FIPS
+ * provider, which is the closest 3.x equivalent.
+ *
+ *  1 : FIPS mode is enabled
+ *  0 : FIPS mode is disabled
+ * -2 : not applicable, the loaded SSL library does not support FIPS mode
+ */
+int openssl_fips_mode(void)
+{
+#if defined(USE_OPENSSL) && (HA_OPENSSL_VERSION_NUMBER < 0x3000000fL)
+       return FIPS_mode() ? 1 : 0;
+#elif defined(USE_OPENSSL) && (HA_OPENSSL_VERSION_NUMBER >= 0x3000000fL)
+       return EVP_default_properties_is_fips_enabled(NULL) ? 1 : 0;
+#else
+       return -2;
+#endif
+}
+
 /* prctl/PR_SET_VMA wrapper to easily give a name to virtual memory areas,
  * knowing their address and size.
  *