Commit 4a08aa1346 for openssl.org

commit 4a08aa1346aa00151b09cc45fb2ce01ddee27230
Author: Eugene Syromiatnikov <esyr@openssl.org>
Date:   Wed May 20 12:24:25 2026 +0200

    Add TLS 1.3 SignatureScheme definitions for SLH-DSA

    In accordance with [1].

    [1] https://datatracker.ietf.org/doc/html/draft-reddy-tls-slhdsa-02

    Resolves: https://github.com/openssl/project/issues/1945
    Signed-off-by: Eugene Syromiatnikov <esyr@openssl.org>

    Reviewed-by: Bob Beck <beck@openssl.org>
    Reviewed-by: Neil Horman <nhorman@openssl.org>
    MergeDate: Tue Jun 23 16:30:01 2026
    (Merged from https://github.com/openssl/openssl/pull/31248)

diff --git a/include/internal/tlssigalgs.h b/include/internal/tlssigalgs.h
index 1d6c9df49f..f5aea80f64 100644
--- a/include/internal/tlssigalgs.h
+++ b/include/internal/tlssigalgs.h
@@ -49,6 +49,19 @@
 #define TLSEXT_SIGALG_mldsa65 0x0905
 #define TLSEXT_SIGALG_mldsa87 0x0906

+#define TLSEXT_SIGALG_slhdsa_sha2_128s 0x0911
+#define TLSEXT_SIGALG_slhdsa_sha2_128f 0x0912
+#define TLSEXT_SIGALG_slhdsa_sha2_192s 0x0913
+#define TLSEXT_SIGALG_slhdsa_sha2_192f 0x0914
+#define TLSEXT_SIGALG_slhdsa_sha2_256s 0x0915
+#define TLSEXT_SIGALG_slhdsa_sha2_256f 0x0916
+#define TLSEXT_SIGALG_slhdsa_shake_128s 0x0917
+#define TLSEXT_SIGALG_slhdsa_shake_128f 0x0918
+#define TLSEXT_SIGALG_slhdsa_shake_192s 0x0919
+#define TLSEXT_SIGALG_slhdsa_shake_192f 0x091a
+#define TLSEXT_SIGALG_slhdsa_shake_256s 0x091b
+#define TLSEXT_SIGALG_slhdsa_shake_256f 0x091c
+
 /* Sigalgs names */
 #define TLSEXT_SIGALG_ecdsa_secp256r1_sha256_name "ecdsa_secp256r1_sha256"
 #define TLSEXT_SIGALG_ecdsa_secp384r1_sha384_name "ecdsa_secp384r1_sha384"
@@ -92,4 +105,17 @@
 #define TLSEXT_SIGALG_mldsa65_name "mldsa65"
 #define TLSEXT_SIGALG_mldsa87_name "mldsa87"

+#define TLSEXT_SIGALG_slhdsa_sha2_128s_name "slhdsa_sha2_128s"
+#define TLSEXT_SIGALG_slhdsa_sha2_128f_name "slhdsa_sha2_128f"
+#define TLSEXT_SIGALG_slhdsa_sha2_192s_name "slhdsa_sha2_192s"
+#define TLSEXT_SIGALG_slhdsa_sha2_192f_name "slhdsa_sha2_192f"
+#define TLSEXT_SIGALG_slhdsa_sha2_256s_name "slhdsa_sha2_256s"
+#define TLSEXT_SIGALG_slhdsa_sha2_256f_name "slhdsa_sha2_256f"
+#define TLSEXT_SIGALG_slhdsa_shake_128s_name "slhdsa_shake_128s"
+#define TLSEXT_SIGALG_slhdsa_shake_128f_name "slhdsa_shake_128f"
+#define TLSEXT_SIGALG_slhdsa_shake_192s_name "slhdsa_shake_192s"
+#define TLSEXT_SIGALG_slhdsa_shake_192f_name "slhdsa_shake_192f"
+#define TLSEXT_SIGALG_slhdsa_shake_256s_name "slhdsa_shake_256s"
+#define TLSEXT_SIGALG_slhdsa_shake_256f_name "slhdsa_shake_256f"
+
 #endif
diff --git a/providers/common/capabilities.c b/providers/common/capabilities.c
index b97d4d6bcd..f461ec222a 100644
--- a/providers/common/capabilities.c
+++ b/providers/common/capabilities.c
@@ -281,7 +281,7 @@ static int tls_group_capability(OSSL_CALLBACK *cb, void *arg)

 /* --------------------------------------------------------------- */

-#if !defined(OPENSSL_NO_ML_DSA) \
+#if !defined(OPENSSL_NO_ML_DSA) || !defined(OPENSSL_NO_SLH_DSA) \
     || (!defined(FIPS_MODULE) && !defined(OPENSSL_NO_SM2) && !defined(OPENSSL_NO_SM3))

 typedef struct tls_sigalg_constants_st {
@@ -297,6 +297,18 @@ static const TLS_SIGALG_CONSTANTS sigalg_constants_list[] = {
     { TLSEXT_SIGALG_mldsa44, 128, TLS1_3_VERSION, 0, -1, -1 },
     { TLSEXT_SIGALG_mldsa65, 192, TLS1_3_VERSION, 0, -1, -1 },
     { TLSEXT_SIGALG_mldsa87, 256, TLS1_3_VERSION, 0, -1, -1 },
+    { TLSEXT_SIGALG_slhdsa_sha2_128s, 128, TLS1_3_VERSION, 0, -1, -1 },
+    { TLSEXT_SIGALG_slhdsa_sha2_128f, 128, TLS1_3_VERSION, 0, -1, -1 },
+    { TLSEXT_SIGALG_slhdsa_sha2_192s, 192, TLS1_3_VERSION, 0, -1, -1 },
+    { TLSEXT_SIGALG_slhdsa_sha2_192f, 192, TLS1_3_VERSION, 0, -1, -1 },
+    { TLSEXT_SIGALG_slhdsa_sha2_256s, 256, TLS1_3_VERSION, 0, -1, -1 },
+    { TLSEXT_SIGALG_slhdsa_sha2_256f, 256, TLS1_3_VERSION, 0, -1, -1 },
+    { TLSEXT_SIGALG_slhdsa_shake_128s, 128, TLS1_3_VERSION, 0, -1, -1 },
+    { TLSEXT_SIGALG_slhdsa_shake_128f, 128, TLS1_3_VERSION, 0, -1, -1 },
+    { TLSEXT_SIGALG_slhdsa_shake_192s, 192, TLS1_3_VERSION, 0, -1, -1 },
+    { TLSEXT_SIGALG_slhdsa_shake_192f, 192, TLS1_3_VERSION, 0, -1, -1 },
+    { TLSEXT_SIGALG_slhdsa_shake_256s, 256, TLS1_3_VERSION, 0, -1, -1 },
+    { TLSEXT_SIGALG_slhdsa_shake_256f, 256, TLS1_3_VERSION, 0, -1, -1 },
     { TLSEXT_SIGALG_sm2sig_sm3, 128, TLS1_3_VERSION, 0, -1, -1 },
 };

@@ -329,8 +341,22 @@ static const OSSL_PARAM param_sigalg_list[][10] = {
     TLS_SIGALG_ENTRY("mldsa65", "ML-DSA-65", "2.16.840.1.101.3.4.3.18", 1),
     TLS_SIGALG_ENTRY("mldsa87", "ML-DSA-87", "2.16.840.1.101.3.4.3.19", 2),
 #endif
+#ifndef OPENSSL_NO_SLH_DSA
+    TLS_SIGALG_ENTRY("slhdsa_sha2_128s", "SLH-DSA-SHA2-128s", "2.16.840.1.101.3.4.3.20", 3),
+    TLS_SIGALG_ENTRY("slhdsa_sha2_128f", "SLH-DSA-SHA2-128f", "2.16.840.1.101.3.4.3.21", 4),
+    TLS_SIGALG_ENTRY("slhdsa_sha2_192s", "SLH-DSA-SHA2-192s", "2.16.840.1.101.3.4.3.22", 5),
+    TLS_SIGALG_ENTRY("slhdsa_sha2_192f", "SLH-DSA-SHA2-192f", "2.16.840.1.101.3.4.3.23", 6),
+    TLS_SIGALG_ENTRY("slhdsa_sha2_256s", "SLH-DSA-SHA2-256s", "2.16.840.1.101.3.4.3.24", 7),
+    TLS_SIGALG_ENTRY("slhdsa_sha2_256f", "SLH-DSA-SHA2-256f", "2.16.840.1.101.3.4.3.25", 8),
+    TLS_SIGALG_ENTRY("slhdsa_shake_128s", "SLH-DSA-SHAKE-128s", "2.16.840.1.101.3.4.3.26", 9),
+    TLS_SIGALG_ENTRY("slhdsa_shake_128f", "SLH-DSA-SHAKE-128f", "2.16.840.1.101.3.4.3.27", 10),
+    TLS_SIGALG_ENTRY("slhdsa_shake_192s", "SLH-DSA-SHAKE-192s", "2.16.840.1.101.3.4.3.28", 11),
+    TLS_SIGALG_ENTRY("slhdsa_shake_192f", "SLH-DSA-SHAKE-192f", "2.16.840.1.101.3.4.3.29", 12),
+    TLS_SIGALG_ENTRY("slhdsa_shake_256s", "SLH-DSA-SHAKE-256s", "2.16.840.1.101.3.4.3.30", 13),
+    TLS_SIGALG_ENTRY("slhdsa_shake_256f", "SLH-DSA-SHAKE-256f", "2.16.840.1.101.3.4.3.31", 14),
+#endif
 #if !defined(FIPS_MODULE) && !defined(OPENSSL_NO_SM2) && !defined(OPENSSL_NO_SM3)
-    TLS_SIGALG_ENTRY("sm2sig_sm3", "SM2", "1.2.156.10197.1 501", 3),
+    TLS_SIGALG_ENTRY("sm2sig_sm3", "SM2", "1.2.156.10197.1 501", 15),
 #endif
 };
 #endif
diff --git a/ssl/t1_trce.c b/ssl/t1_trce.c
index b4d67d9d24..0e8ddbb8f8 100644
--- a/ssl/t1_trce.c
+++ b/ssl/t1_trce.c
@@ -617,6 +617,18 @@ static const ssl_trace_tbl ssl_sigalg_tbl[] = {
     { TLSEXT_SIGALG_mldsa44, TLSEXT_SIGALG_mldsa44_name },
     { TLSEXT_SIGALG_mldsa65, TLSEXT_SIGALG_mldsa65_name },
     { TLSEXT_SIGALG_mldsa87, TLSEXT_SIGALG_mldsa87_name },
+    { TLSEXT_SIGALG_slhdsa_sha2_128s, TLSEXT_SIGALG_slhdsa_sha2_128s_name },
+    { TLSEXT_SIGALG_slhdsa_sha2_128f, TLSEXT_SIGALG_slhdsa_sha2_128f_name },
+    { TLSEXT_SIGALG_slhdsa_sha2_192s, TLSEXT_SIGALG_slhdsa_sha2_192s_name },
+    { TLSEXT_SIGALG_slhdsa_sha2_192f, TLSEXT_SIGALG_slhdsa_sha2_192f_name },
+    { TLSEXT_SIGALG_slhdsa_sha2_256s, TLSEXT_SIGALG_slhdsa_sha2_256s_name },
+    { TLSEXT_SIGALG_slhdsa_sha2_256f, TLSEXT_SIGALG_slhdsa_sha2_256f_name },
+    { TLSEXT_SIGALG_slhdsa_shake_128s, TLSEXT_SIGALG_slhdsa_shake_128s_name },
+    { TLSEXT_SIGALG_slhdsa_shake_128f, TLSEXT_SIGALG_slhdsa_shake_128f_name },
+    { TLSEXT_SIGALG_slhdsa_shake_192s, TLSEXT_SIGALG_slhdsa_shake_192s_name },
+    { TLSEXT_SIGALG_slhdsa_shake_192f, TLSEXT_SIGALG_slhdsa_shake_192f_name },
+    { TLSEXT_SIGALG_slhdsa_shake_256s, TLSEXT_SIGALG_slhdsa_shake_256s_name },
+    { TLSEXT_SIGALG_slhdsa_shake_256f, TLSEXT_SIGALG_slhdsa_shake_256f_name },
 };

 static const ssl_trace_tbl ssl_ctype_tbl[] = {
diff --git a/test/quicapitest.c b/test/quicapitest.c
index c9b0dce585..5b7cdb6a3c 100644
--- a/test/quicapitest.c
+++ b/test/quicapitest.c
@@ -46,7 +46,7 @@ static int qc_init(SSL *qconn, BIO_ADDR *dst_addr);
     && defined(OPENSSL_NO_BROTLI) && defined(OPENSSL_NO_ZSTD)     \
     && !defined(OPENSSL_NO_ECX) && !defined(OPENSSL_NO_DH)        \
     && !defined(OPENSSL_NO_ML_DSA) && !defined(OPENSSL_NO_ML_KEM) \
-    && !defined(OPENSSL_NO_SM2)
+    && !defined(OPENSSL_NO_SLH_DSA) && !defined(OPENSSL_NO_SM2)
 #define DO_SSL_TRACE_TEST
 #endif

diff --git a/test/recipes/75-test_quicapi_data/ssltraceref-zlib.txt b/test/recipes/75-test_quicapi_data/ssltraceref-zlib.txt
index bd8d4c2f6c..1bce022109 100644
--- a/test/recipes/75-test_quicapi_data/ssltraceref-zlib.txt
+++ b/test/recipes/75-test_quicapi_data/ssltraceref-zlib.txt
@@ -55,6 +55,18 @@ Header:
           rsa_pkcs1_sha256 (0x0401)
           rsa_pkcs1_sha384 (0x0501)
           rsa_pkcs1_sha512 (0x0601)
+          slhdsa_sha2_128s (0x0911)
+          slhdsa_sha2_128f (0x0912)
+          slhdsa_sha2_192s (0x0913)
+          slhdsa_sha2_192f (0x0914)
+          slhdsa_sha2_256s (0x0915)
+          slhdsa_sha2_256f (0x0916)
+          slhdsa_shake_128s (0x0917)
+          slhdsa_shake_128f (0x0918)
+          slhdsa_shake_192s (0x0919)
+          slhdsa_shake_192f (0x091a)
+          slhdsa_shake_256s (0x091b)
+          slhdsa_shake_256f (0x091c)
           sm2sig_sm3 (0x0708)
         extension_type=supported_versions(43), length=3
           TLS 1.3 (772)
diff --git a/test/recipes/75-test_quicapi_data/ssltraceref.txt b/test/recipes/75-test_quicapi_data/ssltraceref.txt
index c453344987..300b4ca456 100644
--- a/test/recipes/75-test_quicapi_data/ssltraceref.txt
+++ b/test/recipes/75-test_quicapi_data/ssltraceref.txt
@@ -55,6 +55,18 @@ Header:
           rsa_pkcs1_sha256 (0x0401)
           rsa_pkcs1_sha384 (0x0501)
           rsa_pkcs1_sha512 (0x0601)
+          slhdsa_sha2_128s (0x0911)
+          slhdsa_sha2_128f (0x0912)
+          slhdsa_sha2_192s (0x0913)
+          slhdsa_sha2_192f (0x0914)
+          slhdsa_sha2_256s (0x0915)
+          slhdsa_sha2_256f (0x0916)
+          slhdsa_shake_128s (0x0917)
+          slhdsa_shake_128f (0x0918)
+          slhdsa_shake_192s (0x0919)
+          slhdsa_shake_192f (0x091a)
+          slhdsa_shake_256s (0x091b)
+          slhdsa_shake_256f (0x091c)
           sm2sig_sm3 (0x0708)
         extension_type=supported_versions(43), length=3
           TLS 1.3 (772)
diff --git a/test/recipes/90-test_sslapi_data/ssltraceref-zlib.txt b/test/recipes/90-test_sslapi_data/ssltraceref-zlib.txt
index 68d46c8b38..e6c193fa82 100644
--- a/test/recipes/90-test_sslapi_data/ssltraceref-zlib.txt
+++ b/test/recipes/90-test_sslapi_data/ssltraceref-zlib.txt
@@ -48,6 +48,18 @@ Header:
           rsa_pkcs1_sha256 (0x0401)
           rsa_pkcs1_sha384 (0x0501)
           rsa_pkcs1_sha512 (0x0601)
+          slhdsa_sha2_128s (0x0911)
+          slhdsa_sha2_128f (0x0912)
+          slhdsa_sha2_192s (0x0913)
+          slhdsa_sha2_192f (0x0914)
+          slhdsa_sha2_256s (0x0915)
+          slhdsa_sha2_256f (0x0916)
+          slhdsa_shake_128s (0x0917)
+          slhdsa_shake_128f (0x0918)
+          slhdsa_shake_192s (0x0919)
+          slhdsa_shake_192f (0x091a)
+          slhdsa_shake_256s (0x091b)
+          slhdsa_shake_256f (0x091c)
           sm2sig_sm3 (0x0708)
         extension_type=supported_versions(43), length=3
           TLS 1.3 (772)
diff --git a/test/recipes/90-test_sslapi_data/ssltraceref.txt b/test/recipes/90-test_sslapi_data/ssltraceref.txt
index d84d0e02fb..b5d8931e3d 100644
--- a/test/recipes/90-test_sslapi_data/ssltraceref.txt
+++ b/test/recipes/90-test_sslapi_data/ssltraceref.txt
@@ -48,6 +48,18 @@ Header:
           rsa_pkcs1_sha256 (0x0401)
           rsa_pkcs1_sha384 (0x0501)
           rsa_pkcs1_sha512 (0x0601)
+          slhdsa_sha2_128s (0x0911)
+          slhdsa_sha2_128f (0x0912)
+          slhdsa_sha2_192s (0x0913)
+          slhdsa_sha2_192f (0x0914)
+          slhdsa_sha2_256s (0x0915)
+          slhdsa_sha2_256f (0x0916)
+          slhdsa_shake_128s (0x0917)
+          slhdsa_shake_128f (0x0918)
+          slhdsa_shake_192s (0x0919)
+          slhdsa_shake_192f (0x091a)
+          slhdsa_shake_256s (0x091b)
+          slhdsa_shake_256f (0x091c)
           sm2sig_sm3 (0x0708)
         extension_type=supported_versions(43), length=3
           TLS 1.3 (772)
diff --git a/test/recipes/95-test_external_tlsfuzzer_data/cert.json.in b/test/recipes/95-test_external_tlsfuzzer_data/cert.json.in
index 2ed47253b8..e22ffd2641 100644
--- a/test/recipes/95-test_external_tlsfuzzer_data/cert.json.in
+++ b/test/recipes/95-test_external_tlsfuzzer_data/cert.json.in
@@ -12,12 +12,12 @@
        {"name" : "test-tls13-certificate-verify.py",
         "arguments" : ["-k", "tests/clientX509Key.pem",
                        "-c", "tests/clientX509Cert.pem",
-                       "-s", "9+5 9+6 9+4 ecdsa_secp256r1_sha256 ecdsa_secp384r1_sha384 ecdsa_secp521r1_sha512 ed25519 ed448 8+26 8+27 8+28 rsa_pss_pss_sha256 rsa_pss_pss_sha384 rsa_pss_pss_sha512 rsa_pss_rsae_sha256 rsa_pss_rsae_sha384 rsa_pss_rsae_sha512 rsa_pkcs1_sha256 rsa_pkcs1_sha384 rsa_pkcs1_sha512 7+8",
+                       "-s", "9+5 9+6 9+4 ecdsa_secp256r1_sha256 ecdsa_secp384r1_sha384 ecdsa_secp521r1_sha512 ed25519 ed448 8+26 8+27 8+28 rsa_pss_pss_sha256 rsa_pss_pss_sha384 rsa_pss_pss_sha512 rsa_pss_rsae_sha256 rsa_pss_rsae_sha384 rsa_pss_rsae_sha512 rsa_pkcs1_sha256 rsa_pkcs1_sha384 rsa_pkcs1_sha512 9+17 9+18 9+19 9+20 9+21 9+22 9+23 9+24 9+25 9+26 9+27 9+28 7+8",
                        "-p", "@PORT@"]},
        {"name" : "test-tls13-ecdsa-in-certificate-verify.py",
           "arguments" : ["-k", "tests/serverECKey.pem",
                          "-c", "tests/serverECCert.pem",
-                         "-s", "9+5 9+6 9+4 ecdsa_secp256r1_sha256 ecdsa_secp384r1_sha384 ecdsa_secp521r1_sha512 ed25519 ed448 8+26 8+27 8+28 rsa_pss_pss_sha256 rsa_pss_pss_sha384 rsa_pss_pss_sha512 rsa_pss_rsae_sha256 rsa_pss_rsae_sha384 rsa_pss_rsae_sha512 rsa_pkcs1_sha256 rsa_pkcs1_sha384 rsa_pkcs1_sha512 7+8",
+                         "-s", "9+5 9+6 9+4 ecdsa_secp256r1_sha256 ecdsa_secp384r1_sha384 ecdsa_secp521r1_sha512 ed25519 ed448 8+26 8+27 8+28 rsa_pss_pss_sha256 rsa_pss_pss_sha384 rsa_pss_pss_sha512 rsa_pss_rsae_sha256 rsa_pss_rsae_sha384 rsa_pss_rsae_sha512 rsa_pkcs1_sha256 rsa_pkcs1_sha384 rsa_pkcs1_sha512 9+17 9+18 9+19 9+20 9+21 9+22 9+23 9+24 9+25 9+26 9+27 9+28 7+8",
                          "-p", "@PORT@"]}
      ]
     },
diff --git a/test/sslapitest.c b/test/sslapitest.c
index c1e15c1933..91a2181b61 100644
--- a/test/sslapitest.c
+++ b/test/sslapitest.c
@@ -136,6 +136,7 @@ static const char *ocsp_signer_cert = "subinterCA.pem";
     && defined(OPENSSL_NO_BROTLI) && defined(OPENSSL_NO_ZSTD)     \
     && !defined(OPENSSL_NO_ECX) && !defined(OPENSSL_NO_DH)        \
     && !defined(OPENSSL_NO_ML_DSA) && !defined(OPENSSL_NO_ML_KEM) \
+    && !defined(OPENSSL_NO_SLH_DSA)                               \
     && !defined(OPENSSL_NO_TLS1_3) && !defined(OPENSSL_NO_SM2)
 #define DO_SSL_TRACE_TEST
 #endif