]> git.kaiwu.me - haproxy.git/commitdiff
BUG/MEDIUM: ssl: skip TLS 1.3 suites in the FIPS TLS 1.2 cipher check
authorChris Staite <christopher.staite@menlosecurity.com>
Sun, 1 Nov 2026 19:57:37 +0000 (19:57 +0000)
committerWilliam Lallemand <wlallemand@haproxy.com>
Mon, 2 Nov 2026 08:29:46 +0000 (09:29 +0100)
With AWS-LC in FIPS mode, ssl_fips_check_ciphers() walks the list returned
by SSL_CTX_get_ciphers() and rejects any entry whose key exchange is not
ECDHE (or DHE). But AWS-LC documents that this list includes the TLS 1.3
cipher suites as well, and for these SSL_CIPHER_get_kx_nid() returns
NID_kx_any since TLS 1.3 suites do not specify the key exchange. Every
TLS 1.3 suite is thus reported as a non-FIPS cipher, including the
FIPS-approved ones that are set by default:

  FIPS mode active but non-FIPS cipher(s) configured:
  'TLS_AES_128_GCM_SHA256', 'TLS_AES_256_GCM_SHA384'.

Since the internal httpclient server is checked as well, HAProxy refuses
to start in FIPS mode with any configuration, even one without a single
SSL setting. This was observed with AWS-LC FIPS 4.0.0.

TLS 1.3 suites are already validated against their own list by
ssl_fips_check_ciphersuites(), so ssl_fips_check_ciphers() must only
consider TLS 1.2 ciphers. Skip the ciphers whose minimum protocol version
is TLS 1.3 or above. SSL_CIPHER_get_min_version() was preferred over
testing for NID_kx_any because it expresses the intent directly rather
than relying on a side effect of how TLS 1.3 suites are described. Non-FIPS
TLS 1.2 ciphers (e.g. AES128-SHA or ECDHE-RSA-CHACHA20-POLY1305) and
non-FIPS TLS 1.3 suites (e.g. TLS_CHACHA20_POLY1305_SHA256) are still
rejected.

This bug was introduced in 3.5-dev3 by commit 9e2809508 ("MEDIUM: ssl: add
FIPS TLS 1.2 cipher check for AWS-LC"), no backport is needed.

src/fips.c

index 3b4a314189c79821189a6df7e25362472cf92e18..04e14cfc3c7f8e641edb20e266b65b7c6deae526 100644 (file)
@@ -241,6 +241,10 @@ int ssl_fips_check_ciphers(SSL_CTX *ctx, const enum obj_type *obj, char **err)
                cipher     = sk_SSL_CIPHER_value(cipher_list, i);
                cipher_nid = SSL_CIPHER_get_cipher_nid(cipher);
 
+               /* TLS 1.3 ciphersuites are checked by ssl_fips_check_ciphersuites() */
+               if (SSL_CIPHER_get_min_version(cipher) >= TLS1_3_VERSION)
+                       continue;
+
                kx_nid = SSL_CIPHER_get_kx_nid(cipher);
                if (kx_nid == NID_kx_ecdhe
 #ifdef NID_kx_dhe