From 007a0c35d358dfef7859e8d5a4c8618ed55d69cb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tobias=20Frauenschl=C3=A4ger?= Date: Mon, 2 Feb 2026 17:02:59 +0100 Subject: [PATCH] Enable and use ML-KEM by default * Enable ML-KEM by default * Only allow three to-be-standardized hybrid PQ/T combinatations by default * Use X25519MLKEM768 as the default KeyShare in the ClientHello (if user does not override that) * Disable standalone ML-KEM in supported groups by default (enable with --enable-tls-mlkem-standalone) * Disable extra OQS-based hybrid PQ/T curves by default and gate behind --enable-experimental (enable with --enable-extra-pqc-hybrids) * Reorder the SupportedGroups extension to reflect the preferences * Reorder the preferredGroup array to also reflect the same preferences * Enable DTLS1.3 ClientHello fragmentation by default when both DTLS1.3 and ML-KEM are enabled --- .github/workflows/cmake.yml | 9 +- .github/workflows/psk.yml | 6 +- .github/workflows/rust-wrapper.yml | 64 +- CMakeLists.txt | 158 ++-- cmake/options.h.in | 4 + configure.ac | 37 +- examples/benchmark/tls_bench.c | 10 +- examples/client/client.c | 26 +- examples/server/server.c | 26 +- src/internal.c | 6 +- src/ssl.c | 72 +- src/tls.c | 761 +++++++++--------- src/tls13.c | 6 + tests/api/test_tls13.c | 57 +- tests/include.am | 10 +- tests/suites.c | 46 +- tests/test-dtls13-pq-hybrid-extra-frag.conf | 95 +++ ....conf => test-dtls13-pq-hybrid-extra.conf} | 0 tests/test-dtls13-pq-hybrid-frag.conf | 96 --- ...nf => test-dtls13-pq-standalone-frag.conf} | 0 ...pq.conf => test-dtls13-pq-standalone.conf} | 0 tests/test-tls13-pq-hybrid-extra.conf | 119 +++ tests/test-tls13-pq-hybrid.conf | 120 --- ...-pq.conf => test-tls13-pq-standalone.conf} | 0 wolfssl/internal.h | 1 + wolfssl/ssl.h | 11 +- 26 files changed, 941 insertions(+), 799 deletions(-) create mode 100644 tests/test-dtls13-pq-hybrid-extra-frag.conf rename tests/{test-dtls13-pq-hybrid.conf => test-dtls13-pq-hybrid-extra.conf} (100%) rename tests/{test-dtls13-pq-frag.conf => test-dtls13-pq-standalone-frag.conf} (100%) rename tests/{test-dtls13-pq.conf => test-dtls13-pq-standalone.conf} (100%) create mode 100644 tests/test-tls13-pq-hybrid-extra.conf rename tests/{test-tls13-pq.conf => test-tls13-pq-standalone.conf} (100%) diff --git a/.github/workflows/cmake.yml b/.github/workflows/cmake.yml index 0e9b800acc5..881145ee206 100644 --- a/.github/workflows/cmake.yml +++ b/.github/workflows/cmake.yml @@ -51,7 +51,7 @@ jobs: -DWOLFSSL_CURVE448:STRING=yes -DWOLFSSL_DEBUG:BOOL=yes -DWOLFSSL_DES3:BOOL=ON \ -DWOLFSSL_DES3_TLS_SUITES:BOOL=no -DWOLFSSL_DH:STRING=yes -DWOLFSSL_DH_DEFAULT_PARAMS:BOOL=yes \ -DWOLFSSL_DSA:BOOL=yes -DWOLFSSL_DTLS:BOOL=ON -DWOLFSSL_DTLS13:BOOL=yes \ - -DWOLFSSL_DTLS_CID:BOOL=yes -DWOLFSSL_ECC:STRING=yes \ + -DWOLFSSL_DTLS_CID:BOOL=yes -DWOLFSSL_DTLS_CH_FRAG:BOOL=yes -DWOLFSSL_ECC:STRING=yes \ -DWOLFSSL_ECCCUSTCURVES:STRING=all -DWOLFSSL_ECCSHAMIR:BOOL=yes \ -DWOLFSSL_ECH:BOOL=yes -DWOLFSSL_ED25519:BOOL=yes -DWOLFSSL_ED448:STRING=yes \ -DWOLFSSL_ENCKEYS:BOOL=yes -DWOLFSSL_ENC_THEN_MAC:BOOL=yes -DWOLFSSL_ERROR_QUEUE:BOOL=yes \ @@ -77,10 +77,9 @@ jobs: -DWOLFSSL_TICKET_NONCE_MALLOC:BOOL=yes -DWOLFSSL_TLS13:BOOL=yes -DWOLFSSL_TLSV12:BOOL=yes \ -DWOLFSSL_TLSX:BOOL=yes -DWOLFSSL_TPM:BOOL=yes -DWOLFSSL_CLU:BOOL=yes -DWOLFSSL_USER_SETTINGS:BOOL=no \ -DWOLFSSL_USER_SETTINGS_ASM:BOOL=no -DWOLFSSL_WOLFSSH:BOOL=ON -DWOLFSSL_X86_64_BUILD_ASM:BOOL=yes \ - -DWOLFSSL_MLKEM=1 -DWOLFSSL_LMS=1 -DWOLFSSL_LMSSHA256192=1 -DWOLFSSL_EXPERIMENTAL=1 \ - -DWOLFSSL_X963KDF:BOOL=yes -DWOLFSSL_DILITHIUM:BOOL=yes -DWOLFSSL_PKCS11:BOOL=yes \ - -DWOLFSSL_ECCSI:BOOL=yes -DWOLFSSL_SAKKE:BOOL=yes -DWOLFSSL_SIPHASH:BOOL=yes \ - -DCMAKE_C_FLAGS="-DWOLFSSL_DTLS_CH_FRAG" \ + -DWOLFSSL_MLKEM:BOOL=yes -DWOLFSSL_EXTRA_PQC_HYBRIDS:BOOL=yes -DWOLFSSL_LMS:BOOL=yes \ + -DWOLFSSL_LMSSHA256192:BOOL=yes -DWOLFSSL_X963KDF:BOOL=yes -DWOLFSSL_DILITHIUM:BOOL=yes \ + -DWOLFSSL_PKCS11:BOOL=yes -DWOLFSSL_ECCSI:BOOL=yes -DWOLFSSL_SAKKE:BOOL=yes -DWOLFSSL_SIPHASH:BOOL=yes \ .. cmake --build . ctest -j $(nproc) diff --git a/.github/workflows/psk.yml b/.github/workflows/psk.yml index 5026c4bdfc0..097403c4673 100644 --- a/.github/workflows/psk.yml +++ b/.github/workflows/psk.yml @@ -18,9 +18,9 @@ jobs: matrix: config: [ # Add new configs here - '--enable-psk C_EXTRA_FLAGS=-DWOLFSSL_STATIC_PSK --disable-rsa --disable-ecc --disable-dh', - '--disable-oldtls --disable-tls13 --enable-psk -disable-rsa --disable-dh -disable-ecc --disable-asn C_EXTRA_FLAGS=-DWOLFSSL_STATIC_PSK --enable-lowresource --enable-singlethreaded --disable-asm --disable-errorstrings --disable-pkcs12 --disable-sha3 --disable-sha224 --disable-sha384 --disable-sha512 --disable-sha --disable-md5 -disable-aescbc --disable-chacha --disable-poly1305 --disable-coding --disable-sp-math-all', - '--disable-oldtls --disable-tlsv12 --enable-tls13 --enable-psk -disable-rsa --disable-dh -disable-ecc --disable-asn C_EXTRA_FLAGS=-DWOLFSSL_STATIC_PSK --enable-lowresource --enable-singlethreaded --disable-asm --disable-errorstrings --disable-pkcs12 --disable-sha3 --disable-sha224 --disable-sha384 --disable-sha512 --disable-sha --disable-md5 -disable-aescbc --disable-chacha --disable-poly1305 --disable-coding --disable-sp-math-all' + '--enable-psk C_EXTRA_FLAGS=-DWOLFSSL_STATIC_PSK --disable-rsa --disable-ecc --disable-dh --disable-mlkem', + '--disable-oldtls --disable-tls13 --enable-psk -disable-rsa --disable-dh -disable-ecc --disable-asn C_EXTRA_FLAGS=-DWOLFSSL_STATIC_PSK --enable-lowresource --enable-singlethreaded --disable-asm --disable-errorstrings --disable-pkcs12 --disable-sha3 --disable-sha224 --disable-sha384 --disable-sha512 --disable-sha --disable-md5 -disable-aescbc --disable-chacha --disable-poly1305 --disable-coding --disable-sp-math-all --disable-mlkem', + '--disable-oldtls --disable-tlsv12 --enable-tls13 --enable-psk -disable-rsa --disable-dh -disable-ecc --disable-asn C_EXTRA_FLAGS=-DWOLFSSL_STATIC_PSK --enable-lowresource --enable-singlethreaded --disable-asm --disable-errorstrings --disable-pkcs12 --disable-sha3 --disable-sha224 --disable-sha384 --disable-sha512 --disable-sha --disable-md5 -disable-aescbc --disable-chacha --disable-poly1305 --disable-coding --disable-sp-math-all --disable-mlkem' ] name: make check if: github.repository_owner == 'wolfssl' diff --git a/.github/workflows/rust-wrapper.yml b/.github/workflows/rust-wrapper.yml index 218f7d8320a..6e86996020d 100644 --- a/.github/workflows/rust-wrapper.yml +++ b/.github/workflows/rust-wrapper.yml @@ -39,36 +39,36 @@ jobs: '', '--enable-all', '--enable-cryptonly --disable-examples', - '--enable-cryptonly --disable-examples --disable-aes --disable-aesgcm', - '--enable-cryptonly --disable-examples --disable-aescbc', - '--enable-cryptonly --disable-examples --disable-aeseax', - '--enable-cryptonly --disable-examples --disable-aesecb', - '--enable-cryptonly --disable-examples --disable-aesccm', - '--enable-cryptonly --disable-examples --disable-aescfb', - '--enable-cryptonly --disable-examples --disable-aesctr', - '--enable-cryptonly --disable-examples --disable-aescts', - '--enable-cryptonly --disable-examples --disable-aesgcm', - '--enable-cryptonly --disable-examples --disable-aesgcm-stream', - '--enable-cryptonly --disable-examples --disable-aesofb', - '--enable-cryptonly --disable-examples --disable-aesxts', - '--enable-cryptonly --disable-examples --disable-cmac', - '--enable-cryptonly --disable-examples --disable-dh', - '--enable-cryptonly --disable-examples --disable-ecc', - '--enable-cryptonly --disable-examples --disable-ed25519', - '--enable-cryptonly --disable-examples --disable-ed25519-stream', - '--enable-cryptonly --disable-examples --disable-ed448', - '--enable-cryptonly --disable-examples --disable-ed448-stream', - '--enable-cryptonly --disable-examples --disable-hkdf', - '--enable-cryptonly --disable-examples --disable-hmac', - '--enable-cryptonly --disable-examples --disable-rng', - '--enable-cryptonly --disable-examples --disable-rsa', - '--enable-cryptonly --disable-examples --disable-rsapss', - '--enable-cryptonly --disable-examples --disable-sha224', - '--enable-cryptonly --disable-examples --disable-sha3', - '--enable-cryptonly --disable-examples --disable-sha384', - '--enable-cryptonly --disable-examples --disable-sha512', - '--enable-cryptonly --disable-examples --disable-shake128', - '--enable-cryptonly --disable-examples --disable-shake256', - '--enable-cryptonly --disable-examples --disable-srtp-kdf', - '--enable-cryptonly --disable-examples --disable-x963kdf', + '--enable-cryptonly --disable-examples --disable-mlkem --disable-aes --disable-aesgcm', + '--enable-cryptonly --disable-examples --disable-mlkem --disable-aescbc', + '--enable-cryptonly --disable-examples --disable-mlkem --disable-aeseax', + '--enable-cryptonly --disable-examples --disable-mlkem --disable-aesecb', + '--enable-cryptonly --disable-examples --disable-mlkem --disable-aesccm', + '--enable-cryptonly --disable-examples --disable-mlkem --disable-aescfb', + '--enable-cryptonly --disable-examples --disable-mlkem --disable-aesctr', + '--enable-cryptonly --disable-examples --disable-mlkem --disable-aescts', + '--enable-cryptonly --disable-examples --disable-mlkem --disable-aesgcm', + '--enable-cryptonly --disable-examples --disable-mlkem --disable-aesgcm-stream', + '--enable-cryptonly --disable-examples --disable-mlkem --disable-aesofb', + '--enable-cryptonly --disable-examples --disable-mlkem --disable-aesxts', + '--enable-cryptonly --disable-examples --disable-mlkem --disable-cmac', + '--enable-cryptonly --disable-examples --disable-mlkem --disable-dh', + '--enable-cryptonly --disable-examples --disable-mlkem --disable-ecc', + '--enable-cryptonly --disable-examples --disable-mlkem --disable-ed25519', + '--enable-cryptonly --disable-examples --disable-mlkem --disable-ed25519-stream', + '--enable-cryptonly --disable-examples --disable-mlkem --disable-ed448', + '--enable-cryptonly --disable-examples --disable-mlkem --disable-ed448-stream', + '--enable-cryptonly --disable-examples --disable-mlkem --disable-hkdf', + '--enable-cryptonly --disable-examples --disable-mlkem --disable-hmac', + '--enable-cryptonly --disable-examples --disable-mlkem --disable-rng', + '--enable-cryptonly --disable-examples --disable-mlkem --disable-rsa', + '--enable-cryptonly --disable-examples --disable-mlkem --disable-rsapss', + '--enable-cryptonly --disable-examples --disable-mlkem --disable-sha224', + '--enable-cryptonly --disable-examples --disable-mlkem --disable-sha3', + '--enable-cryptonly --disable-examples --disable-mlkem --disable-sha384', + '--enable-cryptonly --disable-examples --disable-mlkem --disable-sha512', + '--enable-cryptonly --disable-examples --disable-mlkem --disable-shake128', + '--enable-cryptonly --disable-examples --disable-mlkem --disable-shake256', + '--enable-cryptonly --disable-examples --disable-mlkem --disable-srtp-kdf', + '--enable-cryptonly --disable-examples --disable-mlkem --disable-x963kdf', ] diff --git a/CMakeLists.txt b/CMakeLists.txt index f6c41c410e6..c2b43313633 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -427,6 +427,18 @@ if(WOLFSSL_DTLS_CID) list(APPEND WOLFSSL_DEFINITIONS "-DWOLFSSL_DTLS_CID") endif() +# DTLS 1.3 ClientHello fragmenting +add_option("WOLFSSL_DTLS_CH_FRAG" + "Enable wolfSSL DTLS 1.3 ClientHello fragmenting (default: disabled)" + "no" "yes;no") + +if(WOLFSSL_DTLS_CH_FRAG) + if(NOT WOLFSSL_DTLS13) + message(FATAL_ERROR "DTLS 1.3 Fragment ClientHello is supported only for DTLSv1.3") + endif() + list(APPEND WOLFSSL_DEFINITIONS "-DWOLFSSL_DTLS_CH_FRAG") +endif() + # RNG add_option("WOLFSSL_RNG" "Enable compiling and using RNG (default: enabled)" @@ -601,13 +613,58 @@ add_option(WOLFSSL_OQS # ML-KEM/Kyber add_option(WOLFSSL_MLKEM "Enable the wolfSSL PQ ML-KEM library (default: disabled)" - "no" "yes;no") + "yes" "yes;no") + +if (WOLFSSL_MLKEM) + list(APPEND WOLFSSL_DEFINITIONS "-DWOLFSSL_HAVE_MLKEM") + list(APPEND WOLFSSL_DEFINITIONS "-DWOLFSSL_WC_MLKEM") + list(APPEND WOLFSSL_DEFINITIONS "-DWOLFSSL_SHA3") + list(APPEND WOLFSSL_DEFINITIONS "-DWOLFSSL_SHAKE128") + list(APPEND WOLFSSL_DEFINITIONS "-DWOLFSSL_SHAKE256") + + set_wolfssl_definitions("WOLFSSL_HAVE_MLKEM" RESULT) + set_wolfssl_definitions("WOLFSSL_WC_MLKEM" RESULT) + set_wolfssl_definitions("WOLFSSL_SHA3" RESULT) + set_wolfssl_definitions("WOLFSSL_SHAKE128" RESULT) + set_wolfssl_definitions("WOLFSSL_SHAKE256" RESULT) +endif() + +# When MLKEM and DTLS 1.3 are both enabled, DTLS ClientHello fragmenting is +# required (PQC keys in ClientHello can exceed MTU), so enable it automatically. +if(WOLFSSL_MLKEM AND WOLFSSL_DTLS13 AND NOT WOLFSSL_DTLS_CH_FRAG) + message(STATUS "MLKEM and DTLS 1.3 are enabled; enabling DTLS ClientHello fragmenting") + override_cache(WOLFSSL_DTLS_CH_FRAG "yes") + list(APPEND WOLFSSL_DEFINITIONS "-DWOLFSSL_DTLS_CH_FRAG") +endif() + +# Disable ML-KEM as standalone TLS key exchange (non-hybrid); when enabled (default), standalone is disabled +add_option(WOLFSSL_TLS_NO_MLKEM_STANDALONE + "Disable ML-KEM as standalone TLS key exchange (non-hybrid) (default: enabled, i.e. standalone disabled)" + "yes" "yes;no") + +if (WOLFSSL_TLS_NO_MLKEM_STANDALONE) + list(APPEND WOLFSSL_DEFINITIONS "-DWOLFSSL_TLS_NO_MLKEM_STANDALONE") +endif() # Dilithium add_option(WOLFSSL_DILITHIUM "Enable the wolfSSL PQ Dilithium (ML-DSA) implementation (default: disabled)" "no" "yes;no") +if (WOLFSSL_DILITHIUM) + list(APPEND WOLFSSL_DEFINITIONS "-DHAVE_DILITHIUM") + list(APPEND WOLFSSL_DEFINITIONS "-DWOLFSSL_WC_DILITHIUM") + list(APPEND WOLFSSL_DEFINITIONS "-DWOLFSSL_SHA3") + list(APPEND WOLFSSL_DEFINITIONS "-DWOLFSSL_SHAKE128") + list(APPEND WOLFSSL_DEFINITIONS "-DWOLFSSL_SHAKE256") + + set_wolfssl_definitions("HAVE_DILITHIUM" RESULT) + set_wolfssl_definitions("WOLFSSL_WC_DILITHIUM" RESULT) + set_wolfssl_definitions("WOLFSSL_SHA3" RESULT) + set_wolfssl_definitions("WOLFSSL_SHAKE128" RESULT) + set_wolfssl_definitions("WOLFSSL_SHAKE256" RESULT) +endif() + # LMS add_option(WOLFSSL_LMS "Enable the PQ LMS Stateful Hash-based Signature Scheme (default: disabled)" @@ -617,11 +674,31 @@ add_option(WOLFSSL_LMSSHA256192 "Enable the LMS SHA_256_192 truncated variant (default: disabled)" "no" "yes;no") +if (WOLFSSL_LMS) + list(APPEND WOLFSSL_DEFINITIONS "-DWOLFSSL_HAVE_LMS") + list(APPEND WOLFSSL_DEFINITIONS "-DWOLFSSL_WC_LMS") + + set_wolfssl_definitions("WOLFSSL_HAVE_LMS" RESULT) + set_wolfssl_definitions("WOLFSSL_WC_LMS" RESULT) + + if (WOLFSSL_LMSSHA256192) + list(APPEND WOLFSSL_DEFINITIONS "-DWOLFSSL_LMS_SHA256_192") + list(APPEND WOLFSSL_DEFINITIONS "-DWOLFSSL_NO_LMS_SHA256_256") + + set_wolfssl_definitions("WOLFSSL_LMS_SHA256_192" RESULT) + set_wolfssl_definitions("WOLFSSL_NO_LMS_SHA256_256" RESULT) + endif() +endif() + # Experimental features add_option(WOLFSSL_EXPERIMENTAL "Enable experimental features (default: disabled)" "no" "yes;no") +add_option(WOLFSSL_EXTRA_PQC_HYBRIDS + "Enable extra PQ/T hybrid combinations (default: disabled)" + "no" "yes;no") + message(STATUS "Looking for WOLFSSL_EXPERIMENTAL") if (WOLFSSL_EXPERIMENTAL) message(STATUS "Looking for WOLFSSL_EXPERIMENTAL - found") @@ -657,75 +734,14 @@ if (WOLFSSL_EXPERIMENTAL) message(STATUS "Looking for WOLFSSL_OQS - not found") endif() - # Checking for experimental feature: WOLFSSL_MLKEM - message(STATUS "Looking for WOLFSSL_MLKEM") - if (WOLFSSL_MLKEM) - set(WOLFSSL_FOUND_EXPERIMENTAL_FEATURE 1) - - message(STATUS "Automatically set related requirements for ML-KEM:") - add_definitions("-DWOLFSSL_HAVE_MLKEM") - add_definitions("-DWOLFSSL_WC_MLKEM") - add_definitions("-DWOLFSSL_SHA3") - add_definitions("-DWOLFSSL_SHAKE128") - add_definitions("-DWOLFSSL_SHAKE256") - - set_wolfssl_definitions("WOLFSSL_HAVE_MLKEM" RESULT) - set_wolfssl_definitions("WOLFSSL_WC_MLKEM" RESULT) - set_wolfssl_definitions("WOLFSSL_SHA3" RESULT) - set_wolfssl_definitions("WOLFSSL_SHAKE128" RESULT) - set_wolfssl_definitions("WOLFSSL_SHAKE256" RESULT) - message(STATUS "Looking for WOLFSSL_MLKEM - found") - else() - message(STATUS "Looking for WOLFSSL_MLKEM - not found") - endif() - - # Checking for experimental feature: WOLFSSL_LMS - message(STATUS "Looking for WOLFSSL_LMS") - if (WOLFSSL_LMS) - set(WOLFSSL_FOUND_EXPERIMENTAL_FEATURE 2) - - message(STATUS "Automatically set related requirements for LMS") - add_definitions("-DWOLFSSL_HAVE_LMS") - add_definitions("-DWOLFSSL_WC_LMS") - set_wolfssl_definitions("WOLFSSL_HAVE_LMS" RESULT) - set_wolfssl_definitions("WOLFSSL_WC_LMS" RESULT) - message(STATUS "Looking for WOLFSSL_LMS - found") - # Checking for experimental feature: WOLFSSL_LMSSHA256192 - if (WOLFSSL_LMSSHA256192) - message(STATUS "Automatically set related requirements for LMS SHA256-192") - add_definitions("-DWOLFSSL_LMS_SHA256_192") - add_definitions("-DWOLFSSL_NO_LMS_SHA256_256") - set_wolfssl_definitions("WOLFSSL_LMS_SHA256_192" RESULT) - set_wolfssl_definitions("WOLFSSL_NO_LMS_SHA256_256" RESULT) - message(STATUS "Looking for WOLFSSL_LMSSHA256192 - found") - else() - message(STATUS "Looking for WOLFSSL_LMSSHA256192 - not found") - endif() - else() - message(STATUS "Looking for WOLFSSL_LMS - not found") - endif() - - # Checking for experimental feature: Dilithium - message(STATUS "Looking for WOLFSSL_DILITHIUM") - if (WOLFSSL_DILITHIUM) + # Checking for experimental feature: extra PQ/T hybrid combinations + message(STATUS "Looking for WOLFSSL_EXTRA_PQC_HYBRIDS") + if (WOLFSSL_EXTRA_PQC_HYBRIDS) set(WOLFSSL_FOUND_EXPERIMENTAL_FEATURE 1) - - message(STATUS "Automatically set related requirements for Dilithium:") - add_definitions("-DHAVE_DILITHIUM") - add_definitions("-DWOLFSSL_WC_DILITHIUM") - add_definitions("-DWOLFSSL_SHA3") - add_definitions("-DWOLFSSL_SHAKE128") - add_definitions("-DWOLFSSL_SHAKE256") - - message(STATUS "Automatically set related requirements for Dilithium:") - set_wolfssl_definitions("HAVE_DILITHIUM" RESULT) - set_wolfssl_definitions("WOLFSSL_WC_DILITHIUM" RESULT) - set_wolfssl_definitions("WOLFSSL_SHA3" RESULT) - set_wolfssl_definitions("WOLFSSL_SHAKE128" RESULT) - set_wolfssl_definitions("WOLFSSL_SHAKE256" RESULT) - message(STATUS "Looking for WOLFSSL_DILITHIUM - found") + message(STATUS "Looking for WOLFSSL_EXTRA_PQC_HYBRIDS - found") + list(APPEND WOLFSSL_DEFINITIONS "-DWOLFSSL_EXTRA_PQC_HYBRIDS") else() - message(STATUS "Looking for WOLFSSL_DILITHIUM - not found") + message(STATUS "Looking for WOLFSSL_EXTRA_PQC_HYBRIDS - not found") endif() # Other experimental feature detection can be added here... @@ -750,12 +766,6 @@ else() if (WOLFSSL_OQS) message(FATAL_ERROR "Error: WOLFSSL_OQS requires WOLFSSL_EXPERIMENTAL at this time.") endif() - if(WOLFSSL_MLKEM) - message(FATAL_ERROR "Error: WOLFSSL_MLKEM requires WOLFSSL_EXPERIMENTAL at this time.") - endif() - if(WOLFSSL_DILITHIUM) - message(FATAL_ERROR "Error: WOLFSSL_DILITHIUM requires WOLFSSL_EXPERIMENTAL at this time.") - endif() endif() # LMS diff --git a/cmake/options.h.in b/cmake/options.h.in index d01b2c79449..65dc9d98541 100644 --- a/cmake/options.h.in +++ b/cmake/options.h.in @@ -374,6 +374,8 @@ extern "C" { #cmakedefine WOLFSSL_HAVE_MLKEM #undef WOLFSSL_WC_MLKEM #cmakedefine WOLFSSL_WC_MLKEM +#undef WOLFSSL_TLS_NO_MLKEM_STANDALONE +#cmakedefine WOLFSSL_TLS_NO_MLKEM_STANDALONE #undef WOLFSSL_WC_DILITHIUM #cmakedefine WOLFSSL_WC_DILITHIUM #undef NO_WOLFSSL_STUB @@ -400,6 +402,8 @@ extern "C" { #cmakedefine WOLFSSL_HAVE_XMSS #undef WOLFSSL_WC_XMSS #cmakedefine WOLFSSL_WC_XMSS +#undef WOLFSSL_EXTRA_PQC_HYBRIDS +#cmakedefine WOLFSSL_EXTRA_PQC_HYBRIDS #ifdef __cplusplus } diff --git a/configure.ac b/configure.ac index 0e987002833..a1fcf560d8f 100644 --- a/configure.ac +++ b/configure.ac @@ -1614,7 +1614,7 @@ AC_ARG_WITH([liboqs], AC_ARG_ENABLE([mlkem], [AS_HELP_STRING([--enable-mlkem],[Enable MLKEM (default: disabled)])], [ ENABLED_MLKEM=$enableval ], - [ ENABLED_MLKEM=no ] + [ ENABLED_MLKEM=yes ] ) # note, inherits default from "mlkem" clause above. AC_ARG_ENABLE([kyber], @@ -1745,8 +1745,32 @@ then fi fi +AC_ARG_ENABLE([tls-mlkem-standalone], + [AS_HELP_STRING([--enable-tls-mlkem-standalone],[Enable ML-KEM as standalone TLS key exchange (non-hybrid) (default: disabled)])], + [ ENABLED_MLKEM_STANDALONE=$enableval ], + [ ENABLED_MLKEM_STANDALONE=no ] + ) + +if test "$ENABLED_MLKEM_STANDALONE" != "yes" +then + AM_CFLAGS="$AM_CFLAGS -DWOLFSSL_TLS_NO_MLKEM_STANDALONE" +fi + +# Extra PQ/T Hybrid combinations +AC_ARG_ENABLE([extra-pqc-hybrids], + [AS_HELP_STRING([--enable-extra-pqc-hybrids],[Enable extra PQ/T hybrid combinations (default: disabled)])], + [ ENABLED_EXTRA_PQC_HYBRIDS=$enableval ], + [ ENABLED_EXTRA_PQC_HYBRIDS=no ] + ) + +if test "$ENABLED_EXTRA_PQC_HYBRIDS" = "yes" +then + AS_IF([ test "$ENABLED_EXPERIMENTAL" != "yes" ],[ AC_MSG_ERROR([extra-pqc-hybrids requires --enable-experimental.]) ]) + AM_CFLAGS="$AM_CFLAGS -DWOLFSSL_EXTRA_PQC_HYBRIDS" +fi + # Dilithium -# - SHA3, Shake128, Shake256 and AES-CTR +# - SHA3, Shake128 and Shake256 AC_ARG_ENABLE([mldsa], [AS_HELP_STRING([--enable-mldsa],[Enable MLDSA (default: disabled)])], [ ENABLED_DILITHIUM=$enableval ], @@ -5594,6 +5618,15 @@ then AM_CFLAGS="$AM_CFLAGS -DWOLFSSL_DTLS_CH_FRAG" fi +# When MLKEM and DTLS 1.3 are both enabled, DTLS ClientHello fragmenting is +# required (PQC keys in ClientHello can exceed MTU), so enable it automatically. +if test "x$ENABLED_MLKEM" != "xno" && test "x$ENABLED_DTLS13" = "xyes" && test "x$ENABLED_DTLS_CH_FRAG" != "xyes" +then + AC_MSG_NOTICE([MLKEM and DTLS 1.3 are enabled; enabling DTLS ClientHello fragmenting]) + ENABLED_DTLS_CH_FRAG=yes + AM_CFLAGS="$AM_CFLAGS -DWOLFSSL_DTLS_CH_FRAG" +fi + # CODING AC_ARG_ENABLE([coding], [AS_HELP_STRING([--enable-coding],[Enable Coding base 16/64 (default: enabled)])], diff --git a/examples/benchmark/tls_bench.c b/examples/benchmark/tls_bench.c index ede7d8fed76..a1f9e2e8a91 100644 --- a/examples/benchmark/tls_bench.c +++ b/examples/benchmark/tls_bench.c @@ -296,17 +296,21 @@ static struct group_info groups[] = { { WOLFSSL_FFDHE_8192, "FFDHE_8192" }, #ifdef HAVE_PQC #ifndef WOLFSSL_NO_ML_KEM + #ifndef WOLFSSL_TLS_NO_MLKEM_STANDALONE { WOLFSSL_ML_KEM_512, "ML_KEM_512" }, { WOLFSSL_ML_KEM_768, "ML_KEM_768" }, { WOLFSSL_ML_KEM_1024, "ML_KEM_1024" }, + #endif /* !WOLFSSL_TLS_NO_MLKEM_STANDALONE */ + { WOLFSSL_SECP256R1MLKEM768, "SecP256r1MLKEM768" }, + { WOLFSSL_SECP384R1MLKEM1024, "SecP384r1MLKEM1024" }, + { WOLFSSL_X25519MLKEM768, "X25519MLKEM768" }, + #ifdef WOLFSSL_EXTRA_PQC_HYBRIDS { WOLFSSL_SECP256R1MLKEM512, "SecP256r1MLKEM512" }, { WOLFSSL_SECP384R1MLKEM768, "SecP384r1MLKEM768" }, - { WOLFSSL_SECP256R1MLKEM768, "SecP256r1MLKEM768" }, { WOLFSSL_SECP521R1MLKEM1024, "SecP521r1MLKEM1024" }, - { WOLFSSL_SECP384R1MLKEM1024, "SecP384r1MLKEM1024" }, { WOLFSSL_X25519MLKEM512, "X25519MLKEM512" }, { WOLFSSL_X448MLKEM768, "X448MLKEM768" }, - { WOLFSSL_X25519MLKEM768, "X25519MLKEM768" }, + #endif /* WOLFSSL_EXTRA_PQC_HYBRIDS */ #endif #ifdef WOLFSSL_MLKEM_KYBER { WOLFSSL_KYBER_LEVEL1, "KYBER_LEVEL1" }, diff --git a/examples/client/client.c b/examples/client/client.c index 11b80d234e2..50549679725 100644 --- a/examples/client/client.c +++ b/examples/client/client.c @@ -422,49 +422,58 @@ static void SetKeyShare(WOLFSSL* ssl, int onlyKeyShare, int useX25519, int group = 0; #ifndef WOLFSSL_NO_ML_KEM - #ifndef WOLFSSL_NO_ML_KEM_512 + #if !defined(WOLFSSL_NO_ML_KEM_512) && !defined(WOLFSSL_TLS_NO_MLKEM_STANDALONE) if (XSTRCMP(pqcAlg, "ML_KEM_512") == 0) { group = WOLFSSL_ML_KEM_512; } else #endif - #ifndef WOLFSSL_NO_ML_KEM_768 + #if !defined(WOLFSSL_NO_ML_KEM_768) && !defined(WOLFSSL_TLS_NO_MLKEM_STANDALONE) if (XSTRCMP(pqcAlg, "ML_KEM_768") == 0) { group = WOLFSSL_ML_KEM_768; } else #endif - #ifndef WOLFSSL_NO_ML_KEM_1024 + #if !defined(WOLFSSL_NO_ML_KEM_1024) && \ + !defined(WOLFSSL_TLS_NO_MLKEM_STANDALONE) if (XSTRCMP(pqcAlg, "ML_KEM_1024") == 0) { group = WOLFSSL_ML_KEM_1024; } else #endif - #ifndef WOLFSSL_NO_ML_KEM_512 + #if !defined(WOLFSSL_NO_ML_KEM_512) && \ + defined(WOLFSSL_EXTRA_PQC_HYBRIDS) if (XSTRCMP(pqcAlg, "SecP256r1MLKEM512") == 0) { group = WOLFSSL_SECP256R1MLKEM512; } else #endif #ifndef WOLFSSL_NO_ML_KEM_768 + #ifdef WOLFSSL_EXTRA_PQC_HYBRIDS if (XSTRCMP(pqcAlg, "SecP384r1MLKEM768") == 0) { group = WOLFSSL_SECP384R1MLKEM768; } - else if (XSTRCMP(pqcAlg, "SecP256r1MLKEM768") == 0) { + else + #endif + if (XSTRCMP(pqcAlg, "SecP256r1MLKEM768") == 0) { group = WOLFSSL_SECP256R1MLKEM768; } else #endif #ifndef WOLFSSL_NO_ML_KEM_1024 + #ifdef WOLFSSL_EXTRA_PQC_HYBRIDS if (XSTRCMP(pqcAlg, "SecP521r1MLKEM1024") == 0) { group = WOLFSSL_SECP521R1MLKEM1024; } - else if (XSTRCMP(pqcAlg, "SecP384r1MLKEM1024") == 0) { + else + #endif + if (XSTRCMP(pqcAlg, "SecP384r1MLKEM1024") == 0) { group = WOLFSSL_SECP384R1MLKEM1024; } else #endif - #if !defined(WOLFSSL_NO_ML_KEM_512) && defined(HAVE_CURVE25519) + #if !defined(WOLFSSL_NO_ML_KEM_512) && defined(HAVE_CURVE25519) && \ + defined(WOLFSSL_EXTRA_PQC_HYBRIDS) if (XSTRCMP(pqcAlg, "X25519MLKEM512") == 0) { group = WOLFSSL_X25519MLKEM512; } @@ -476,7 +485,8 @@ static void SetKeyShare(WOLFSSL* ssl, int onlyKeyShare, int useX25519, } else #endif - #if !defined(WOLFSSL_NO_ML_KEM_768) && defined(HAVE_CURVE448) + #if !defined(WOLFSSL_NO_ML_KEM_768) && defined(HAVE_CURVE448) && \ + defined(WOLFSSL_EXTRA_PQC_HYBRIDS) if (XSTRCMP(pqcAlg, "X448MLKEM768") == 0) { group = WOLFSSL_X448MLKEM768; } diff --git a/examples/server/server.c b/examples/server/server.c index c7c44409d83..527c0f1f166 100644 --- a/examples/server/server.c +++ b/examples/server/server.c @@ -709,49 +709,58 @@ static void SetKeyShare(WOLFSSL* ssl, int onlyKeyShare, int useX25519, #ifdef HAVE_PQC groups[count] = 0; #ifndef WOLFSSL_NO_ML_KEM - #ifndef WOLFSSL_NO_ML_KEM_512 + #if !defined(WOLFSSL_NO_ML_KEM_512) && !defined(WOLFSSL_TLS_NO_MLKEM_STANDALONE) if (XSTRCMP(pqcAlg, "ML_KEM_512") == 0) { groups[count] = WOLFSSL_ML_KEM_512; } else #endif - #ifndef WOLFSSL_NO_ML_KEM_768 + #if !defined(WOLFSSL_NO_ML_KEM_768) && !defined(WOLFSSL_TLS_NO_MLKEM_STANDALONE) if (XSTRCMP(pqcAlg, "ML_KEM_768") == 0) { groups[count] = WOLFSSL_ML_KEM_768; } else #endif - #ifndef WOLFSSL_NO_ML_KEM_1024 + #if !defined(WOLFSSL_NO_ML_KEM_1024) && \ + !defined(WOLFSSL_TLS_NO_MLKEM_STANDALONE) if (XSTRCMP(pqcAlg, "ML_KEM_1024") == 0) { groups[count] = WOLFSSL_ML_KEM_1024; } else #endif - #ifndef WOLFSSL_NO_ML_KEM_512 + #if !defined(WOLFSSL_NO_ML_KEM_512) && \ + defined(WOLFSSL_EXTRA_PQC_HYBRIDS) if (XSTRCMP(pqcAlg, "SecP256r1MLKEM512") == 0) { groups[count] = WOLFSSL_SECP256R1MLKEM512; } else #endif #ifndef WOLFSSL_NO_ML_KEM_768 + #ifdef WOLFSSL_EXTRA_PQC_HYBRIDS if (XSTRCMP(pqcAlg, "SecP384r1MLKEM768") == 0) { groups[count] = WOLFSSL_SECP384R1MLKEM768; } - else if (XSTRCMP(pqcAlg, "SecP256r1MLKEM768") == 0) { + else + #endif + if (XSTRCMP(pqcAlg, "SecP256r1MLKEM768") == 0) { groups[count] = WOLFSSL_SECP256R1MLKEM768; } else #endif #ifndef WOLFSSL_NO_ML_KEM_1024 + #ifdef WOLFSSL_EXTRA_PQC_HYBRIDS if (XSTRCMP(pqcAlg, "SecP521r1MLKEM1024") == 0) { groups[count] = WOLFSSL_SECP521R1MLKEM1024; } - else if (XSTRCMP(pqcAlg, "SecP384r1MLKEM1024") == 0) { + else + #endif + if (XSTRCMP(pqcAlg, "SecP384r1MLKEM1024") == 0) { groups[count] = WOLFSSL_SECP384R1MLKEM1024; } else #endif - #if !defined(WOLFSSL_NO_ML_KEM_512) && defined(HAVE_CURVE25519) + #if !defined(WOLFSSL_NO_ML_KEM_512) && defined(HAVE_CURVE25519) && \ + defined(WOLFSSL_EXTRA_PQC_HYBRIDS) if (XSTRCMP(pqcAlg, "X25519MLKEM512") == 0) { groups[count] = WOLFSSL_X25519MLKEM512; } @@ -763,7 +772,8 @@ static void SetKeyShare(WOLFSSL* ssl, int onlyKeyShare, int useX25519, } else #endif - #if !defined(WOLFSSL_NO_ML_KEM_768) && defined(HAVE_CURVE448) + #if !defined(WOLFSSL_NO_ML_KEM_768) && defined(HAVE_CURVE448) && \ + defined(WOLFSSL_EXTRA_PQC_HYBRIDS) if (XSTRCMP(pqcAlg, "X448MLKEM768") == 0) { groups[count] = WOLFSSL_X448MLKEM768; } diff --git a/src/internal.c b/src/internal.c index 74f59faff90..69d230ad64b 100644 --- a/src/internal.c +++ b/src/internal.c @@ -35011,16 +35011,18 @@ static int DoSessionTicket(WOLFSSL* ssl, const byte* input, word32* inOutIdx, case WOLFSSL_SECP256R1MLKEM768: case WOLFSSL_X25519MLKEM768: case WOLFSSL_SECP384R1MLKEM1024: + #ifdef WOLFSSL_EXTRA_PQC_HYBRIDS case WOLFSSL_SECP256R1MLKEM512: case WOLFSSL_SECP384R1MLKEM768: case WOLFSSL_SECP521R1MLKEM1024: case WOLFSSL_X25519MLKEM512: case WOLFSSL_X448MLKEM768: -#ifdef WOLFSSL_ML_KEM_USE_OLD_IDS + #ifdef WOLFSSL_ML_KEM_USE_OLD_IDS case WOLFSSL_P256_ML_KEM_512_OLD: case WOLFSSL_P384_ML_KEM_768_OLD: case WOLFSSL_P521_ML_KEM_1024_OLD: -#endif + #endif + #endif /* WOLFSSL_EXTRA_PQC_HYBRIDS */ #endif #ifdef WOLFSSL_MLKEM_KYBER case WOLFSSL_P256_KYBER_LEVEL3: diff --git a/src/ssl.c b/src/ssl.c index ff0a4eb0e5f..ffacbe017b5 100644 --- a/src/ssl.c +++ b/src/ssl.c @@ -3755,18 +3755,22 @@ static int isValidCurveGroup(word16 name) #ifdef WOLFSSL_HAVE_MLKEM #ifndef WOLFSSL_NO_ML_KEM + #ifndef WOLFSSL_TLS_NO_MLKEM_STANDALONE case WOLFSSL_ML_KEM_512: case WOLFSSL_ML_KEM_768: case WOLFSSL_ML_KEM_1024: + #endif /* !WOLFSSL_TLS_NO_MLKEM_STANDALONE */ #if defined(WOLFSSL_WC_MLKEM) || defined(HAVE_LIBOQS) + case WOLFSSL_SECP384R1MLKEM1024: + case WOLFSSL_X25519MLKEM768: + case WOLFSSL_SECP256R1MLKEM768: + #ifdef WOLFSSL_EXTRA_PQC_HYBRIDS case WOLFSSL_SECP256R1MLKEM512: case WOLFSSL_SECP384R1MLKEM768: case WOLFSSL_SECP521R1MLKEM1024: - case WOLFSSL_SECP384R1MLKEM1024: case WOLFSSL_X25519MLKEM512: case WOLFSSL_X448MLKEM768: - case WOLFSSL_X25519MLKEM768: - case WOLFSSL_SECP256R1MLKEM768: + #endif /* WOLFSSL_EXTRA_PQC_HYBRIDS */ #endif #endif /* !WOLFSSL_NO_ML_KEM */ #ifdef WOLFSSL_MLKEM_KYBER @@ -15380,49 +15384,55 @@ const char* wolfSSL_get_curve_name(WOLFSSL* ssl) #ifndef WOLFSSL_NO_ML_KEM_512 case WOLFSSL_ML_KEM_512: return "ML_KEM_512"; - case WOLFSSL_SECP256R1MLKEM512: - return "SecP256r1MLKEM512"; -#ifdef WOLFSSL_ML_KEM_USE_OLD_IDS + #ifdef WOLFSSL_EXTRA_PQC_HYBRIDS + #ifdef WOLFSSL_ML_KEM_USE_OLD_IDS case WOLFSSL_P256_ML_KEM_512_OLD: return "P256_ML_KEM_512_OLD"; -#endif + #endif /* WOLFSSL_ML_KEM_USE_OLD_IDS */ + case WOLFSSL_SECP256R1MLKEM512: + return "SecP256r1MLKEM512"; #ifdef HAVE_CURVE25519 case WOLFSSL_X25519MLKEM512: return "X25519MLKEM512"; - #endif - #endif + #endif /* HAVE_CURVE25519 */ + #endif /* WOLFSSL_EXTRA_PQC_HYBRIDS */ + #endif /* WOLFSSL_NO_ML_KEM_512 */ #ifndef WOLFSSL_NO_ML_KEM_768 case WOLFSSL_ML_KEM_768: return "ML_KEM_768"; - case WOLFSSL_SECP384R1MLKEM768: - return "SecP384r1MLKEM768"; -#ifdef WOLFSSL_ML_KEM_USE_OLD_IDS - case WOLFSSL_P384_ML_KEM_768_OLD: - return "P384_ML_KEM_768_OLD"; -#endif case WOLFSSL_SECP256R1MLKEM768: return "SecP256r1MLKEM768"; #ifdef HAVE_CURVE25519 case WOLFSSL_X25519MLKEM768: return "X25519MLKEM768"; #endif + #ifdef WOLFSSL_EXTRA_PQC_HYBRIDS + #ifdef WOLFSSL_ML_KEM_USE_OLD_IDS + case WOLFSSL_P384_ML_KEM_768_OLD: + return "P384_ML_KEM_768_OLD"; + #endif /* WOLFSSL_ML_KEM_USE_OLD_IDS */ + case WOLFSSL_SECP384R1MLKEM768: + return "SecP384r1MLKEM768"; #ifdef HAVE_CURVE448 case WOLFSSL_X448MLKEM768: return "X448MLKEM768"; - #endif - #endif + #endif /* HAVE_CURVE448 */ + #endif /* WOLFSSL_EXTRA_PQC_HYBRIDS */ + #endif /* WOLFSSL_NO_ML_KEM_768 */ #ifndef WOLFSSL_NO_ML_KEM_1024 case WOLFSSL_ML_KEM_1024: return "ML_KEM_1024"; - case WOLFSSL_SECP521R1MLKEM1024: - return "SecP521r1MLKEM1024"; -#ifdef WOLFSSL_ML_KEM_USE_OLD_IDS - case WOLFSSL_P521_ML_KEM_1024_OLD: - return "P521_ML_KEM_1024_OLD"; -#endif case WOLFSSL_SECP384R1MLKEM1024: return "SecP384r1MLKEM1024"; - #endif + #ifdef WOLFSSL_EXTRA_PQC_HYBRIDS + #ifdef WOLFSSL_ML_KEM_USE_OLD_IDS + case WOLFSSL_P521_ML_KEM_1024_OLD: + return "P521_ML_KEM_1024_OLD"; + #endif /* WOLFSSL_ML_KEM_USE_OLD_IDS */ + case WOLFSSL_SECP521R1MLKEM1024: + return "SecP521r1MLKEM1024"; + #endif /* WOLFSSL_EXTRA_PQC_HYBRIDS */ + #endif /* WOLFSSL_NO_ML_KEM_1024 */ #elif defined(HAVE_LIBOQS) case WOLFSSL_ML_KEM_512: return "ML_KEM_512"; @@ -22503,22 +22513,24 @@ const WOLF_EC_NIST_NAME kNistCurves[] = { {CURVE_NAME("ML_KEM_768"), WOLFSSL_ML_KEM_768, WOLFSSL_ML_KEM_768}, {CURVE_NAME("ML_KEM_1024"), WOLFSSL_ML_KEM_1024, WOLFSSL_ML_KEM_1024}, #if (defined(WOLFSSL_WC_MLKEM) || defined(HAVE_LIBOQS)) && defined(HAVE_ECC) + {CURVE_NAME("SecP256r1MLKEM768"), WOLFSSL_SECP256R1MLKEM768, + WOLFSSL_SECP256R1MLKEM768}, + {CURVE_NAME("SecP384r1MLKEM1024"), WOLFSSL_SECP384R1MLKEM1024, + WOLFSSL_SECP384R1MLKEM1024}, + {CURVE_NAME("X25519MLKEM768"), WOLFSSL_X25519MLKEM768, + WOLFSSL_X25519MLKEM768}, + #ifdef WOLFSSL_EXTRA_PQC_HYBRIDS {CURVE_NAME("SecP256r1MLKEM512"), WOLFSSL_SECP256R1MLKEM512, WOLFSSL_SECP256R1MLKEM512}, {CURVE_NAME("SecP384r1MLKEM768"), WOLFSSL_SECP384R1MLKEM768, WOLFSSL_SECP384R1MLKEM768}, - {CURVE_NAME("SecP256r1MLKEM768"), WOLFSSL_SECP256R1MLKEM768, - WOLFSSL_SECP256R1MLKEM768}, {CURVE_NAME("SecP521r1MLKEM1024"), WOLFSSL_SECP521R1MLKEM1024, WOLFSSL_SECP521R1MLKEM1024}, - {CURVE_NAME("SecP384r1MLKEM1024"), WOLFSSL_SECP384R1MLKEM1024, - WOLFSSL_SECP384R1MLKEM1024}, {CURVE_NAME("X25519MLKEM512"), WOLFSSL_X25519MLKEM512, WOLFSSL_X25519MLKEM512}, {CURVE_NAME("X448MLKEM768"), WOLFSSL_X448MLKEM768, WOLFSSL_X448MLKEM768}, - {CURVE_NAME("X25519MLKEM768"), WOLFSSL_X25519MLKEM768, - WOLFSSL_X25519MLKEM768}, + #endif /* WOLFSSL_EXTRA_PQC_HYBRIDS */ #endif #endif /* !WOLFSSL_NO_ML_KEM */ #ifdef WOLFSSL_MLKEM_KYBER diff --git a/src/tls.c b/src/tls.c index 7d7dcea86c2..2b4537be137 100644 --- a/src/tls.c +++ b/src/tls.c @@ -4373,7 +4373,7 @@ static void findEccPqc(int *ecc, int *pqc, int *pqc_first, int group); * namedGroup The named group to check. * returns 1 when supported or 0 otherwise. */ -static int TLSX_IsGroupSupported(int namedGroup) +int TLSX_IsGroupSupported(int namedGroup) { switch (namedGroup) { #ifdef HAVE_FFDHE_2048 @@ -4485,35 +4485,48 @@ static int TLSX_IsGroupSupported(int namedGroup) #ifndef WOLFSSL_NO_ML_KEM #ifdef WOLFSSL_WC_MLKEM #ifndef WOLFSSL_NO_ML_KEM_512 + #ifndef WOLFSSL_TLS_NO_MLKEM_STANDALONE case WOLFSSL_ML_KEM_512: + #endif /* !WOLFSSL_TLS_NO_MLKEM_STANDALONE */ + #ifdef WOLFSSL_EXTRA_PQC_HYBRIDS case WOLFSSL_SECP256R1MLKEM512: - #if defined(HAVE_CURVE25519) && ECC_MIN_KEY_SZ <= 256 + #if defined(HAVE_CURVE25519) && ECC_MIN_KEY_SZ <= 256 case WOLFSSL_X25519MLKEM512: - #endif - #endif + #endif /* HAVE_CURVE25519 */ + #endif /* WOLFSSL_EXTRA_PQC_HYBRIDS */ + #endif /* WOLFSSL_NO_ML_KEM_512 */ #ifndef WOLFSSL_NO_ML_KEM_768 + #ifndef WOLFSSL_TLS_NO_MLKEM_STANDALONE case WOLFSSL_ML_KEM_768: - case WOLFSSL_SECP384R1MLKEM768: + #endif /* !WOLFSSL_TLS_NO_MLKEM_STANDALONE */ case WOLFSSL_SECP256R1MLKEM768: - #if defined(HAVE_CURVE25519) && ECC_MIN_KEY_SZ <= 256 + #if defined(HAVE_CURVE25519) && ECC_MIN_KEY_SZ <= 256 case WOLFSSL_X25519MLKEM768: - #endif - #if defined(HAVE_CURVE448) && ECC_MIN_KEY_SZ <= 448 + #endif /* HAVE_CURVE25519 */ + #ifdef WOLFSSL_EXTRA_PQC_HYBRIDS + case WOLFSSL_SECP384R1MLKEM768: + #if defined(HAVE_CURVE448) && ECC_MIN_KEY_SZ <= 448 case WOLFSSL_X448MLKEM768: - #endif - #endif + #endif /* HAVE_CURVE448 */ + #endif /* WOLFSSL_EXTRA_PQC_HYBRIDS */ + #endif /* WOLFSSL_NO_ML_KEM_768 */ #ifndef WOLFSSL_NO_ML_KEM_1024 + #ifndef WOLFSSL_TLS_NO_MLKEM_STANDALONE case WOLFSSL_ML_KEM_1024: - case WOLFSSL_SECP521R1MLKEM1024: + #endif /* !WOLFSSL_TLS_NO_MLKEM_STANDALONE */ case WOLFSSL_SECP384R1MLKEM1024: + #ifdef WOLFSSL_EXTRA_PQC_HYBRIDS + case WOLFSSL_SECP521R1MLKEM1024: + #endif /* WOLFSSL_EXTRA_PQC_HYBRIDS */ break; #endif -#ifdef WOLFSSL_ML_KEM_USE_OLD_IDS + #if defined(WOLFSSL_ML_KEM_USE_OLD_IDS) && \ + defined (WOLFSSL_EXTRA_PQC_HYBRIDS) case WOLFSSL_P256_ML_KEM_512_OLD: case WOLFSSL_P384_ML_KEM_768_OLD: case WOLFSSL_P521_ML_KEM_1024_OLD: break; -#endif + #endif /* WOLFSSL_ML_KEM_USE_OLD_IDS && WOLFSSL_EXTRA_PQC_HYBRIDS */ #elif defined(HAVE_LIBOQS) case WOLFSSL_ML_KEM_512: case WOLFSSL_ML_KEM_768: @@ -5820,7 +5833,8 @@ int TLSX_UseSupportedCurve(TLSX** extensions, word16 name, void* heap) heap); if (ret != 0) return ret; -#ifdef WOLFSSL_ML_KEM_USE_OLD_IDS + #if defined(WOLFSSL_ML_KEM_USE_OLD_IDS) && \ + defined (WOLFSSL_EXTRA_PQC_HYBRIDS) if (name == WOLFSSL_SECP256R1MLKEM512) { ret = TLSX_SupportedCurve_Append((SupportedCurve*)extension->data, WOLFSSL_P256_ML_KEM_512_OLD, heap); @@ -5836,7 +5850,7 @@ int TLSX_UseSupportedCurve(TLSX** extensions, word16 name, void* heap) if (ret != 0) { return ret; } -#endif + #endif /* WOLFSSL_ML_KEM_USE_OLD_IDS && WOLFSSL_EXTRA_PQC_HYBRIDS */ } return WOLFSSL_SUCCESS; @@ -8166,26 +8180,22 @@ static int TLSX_KeyShare_GenEccKey(WOLFSSL *ssl, KeyShareEntry* kse) word16 curveId = (word16) ECC_CURVE_INVALID; ecc_key* eccKey = (ecc_key*)kse->key; - /* TODO: [TLS13] Get key sizes using wc_ecc_get_curve_size_from_id. */ /* Translate named group to a curve id. */ switch (kse->group) { #if (!defined(NO_ECC256) || defined(HAVE_ALL_CURVES)) && ECC_MIN_KEY_SZ <= 256 #ifndef NO_ECC_SECP case WOLFSSL_ECC_SECP256R1: curveId = ECC_SECP256R1; - keySize = 32; break; #endif /* !NO_ECC_SECP */ #ifdef WOLFSSL_SM2 case WOLFSSL_ECC_SM2P256V1: curveId = ECC_SM2P256V1; - keySize = 32; break; #endif /* !WOLFSSL_SM2 */ #ifdef HAVE_ECC_BRAINPOOL case WOLFSSL_ECC_BRAINPOOLP256R1TLS13: curveId = ECC_BRAINPOOLP256R1; - keySize = 32; break; #endif /* HAVE_ECC_BRAINPOOL */ #endif @@ -8193,13 +8203,11 @@ static int TLSX_KeyShare_GenEccKey(WOLFSSL *ssl, KeyShareEntry* kse) #ifndef NO_ECC_SECP case WOLFSSL_ECC_SECP384R1: curveId = ECC_SECP384R1; - keySize = 48; break; #endif /* !NO_ECC_SECP */ #ifdef HAVE_ECC_BRAINPOOL case WOLFSSL_ECC_BRAINPOOLP384R1TLS13: curveId = ECC_BRAINPOOLP384R1; - keySize = 48; break; #endif /* HAVE_ECC_BRAINPOOL */ #endif @@ -8207,7 +8215,6 @@ static int TLSX_KeyShare_GenEccKey(WOLFSSL *ssl, KeyShareEntry* kse) #ifdef HAVE_ECC_BRAINPOOL case WOLFSSL_ECC_BRAINPOOLP512R1TLS13: curveId = ECC_BRAINPOOLP512R1; - keySize = 64; break; #endif /* HAVE_ECC_BRAINPOOL */ #endif @@ -8215,7 +8222,6 @@ static int TLSX_KeyShare_GenEccKey(WOLFSSL *ssl, KeyShareEntry* kse) #ifndef NO_ECC_SECP case WOLFSSL_ECC_SECP521R1: curveId = ECC_SECP521R1; - keySize = 66; break; #endif /* !NO_ECC_SECP */ #endif @@ -8224,6 +8230,15 @@ static int TLSX_KeyShare_GenEccKey(WOLFSSL *ssl, KeyShareEntry* kse) return BAD_FUNC_ARG; } + { + int size = wc_ecc_get_curve_size_from_id(curveId); + if (size < 0) { + WOLFSSL_ERROR_VERBOSE(size); + return size; + } + keySize = (word32)size; + } + if (kse->key == NULL) { /* Allocate an ECC key to hold private key. */ kse->key = (byte*)XMALLOC(sizeof(ecc_key), ssl->heap, DYNAMIC_TYPE_ECC); @@ -8395,6 +8410,12 @@ static int mlkem_id2type(int id, int *type) } #endif +#if defined(WOLFSSL_NO_ML_KEM_768) && defined(WOLFSSL_NO_ML_KEM_1024) && \ + !defined(WOLFSSL_EXTRA_PQC_HYBRIDS) + #error "Non-experimental PQC hybrid combinations require either " + "ML-KEM 768 or ML-KEM 1024" +#endif + /* Structures and objects needed for hybrid key exchanges using both classic * ECDHE and PQC KEM key material. */ typedef struct PqcHybridMapping { @@ -8406,23 +8427,29 @@ typedef struct PqcHybridMapping { static const PqcHybridMapping pqc_hybrid_mapping[] = { #ifndef WOLFSSL_NO_ML_KEM + {WOLFSSL_SECP256R1MLKEM768, WOLFSSL_ECC_SECP256R1, WOLFSSL_ML_KEM_768, 0}, + {WOLFSSL_SECP384R1MLKEM1024, WOLFSSL_ECC_SECP384R1, WOLFSSL_ML_KEM_1024, 0}, +#ifdef WOLFSSL_EXTRA_PQC_HYBRIDS {WOLFSSL_SECP256R1MLKEM512, WOLFSSL_ECC_SECP256R1, WOLFSSL_ML_KEM_512, 0}, {WOLFSSL_SECP384R1MLKEM768, WOLFSSL_ECC_SECP384R1, WOLFSSL_ML_KEM_768, 0}, - {WOLFSSL_SECP256R1MLKEM768, WOLFSSL_ECC_SECP256R1, WOLFSSL_ML_KEM_768, 0}, {WOLFSSL_SECP521R1MLKEM1024, WOLFSSL_ECC_SECP521R1, WOLFSSL_ML_KEM_1024, 0}, - {WOLFSSL_SECP384R1MLKEM1024, WOLFSSL_ECC_SECP384R1, WOLFSSL_ML_KEM_1024, 0}, #ifdef WOLFSSL_ML_KEM_USE_OLD_IDS {WOLFSSL_P256_ML_KEM_512_OLD, WOLFSSL_ECC_SECP256R1, WOLFSSL_ML_KEM_512, 0}, {WOLFSSL_P384_ML_KEM_768_OLD, WOLFSSL_ECC_SECP384R1, WOLFSSL_ML_KEM_768, 0}, {WOLFSSL_P521_ML_KEM_1024_OLD, WOLFSSL_ECC_SECP521R1, WOLFSSL_ML_KEM_1024, 0}, -#endif +#endif /* WOLFSSL_ML_KEM_USE_OLD_IDS */ +#endif /* WOLFSSL_EXTRA_PQC_HYBRIDS */ #ifdef HAVE_CURVE25519 - {WOLFSSL_X25519MLKEM512, WOLFSSL_ECC_X25519, WOLFSSL_ML_KEM_512, 1}, {WOLFSSL_X25519MLKEM768, WOLFSSL_ECC_X25519, WOLFSSL_ML_KEM_768, 1}, -#endif +#ifdef WOLFSSL_EXTRA_PQC_HYBRIDS + {WOLFSSL_X25519MLKEM512, WOLFSSL_ECC_X25519, WOLFSSL_ML_KEM_512, 1}, +#endif /* WOLFSSL_EXTRA_PQC_HYBRIDS */ +#endif /* HAVE_CURVE25519 */ #ifdef HAVE_CURVE448 +#ifdef WOLFSSL_EXTRA_PQC_HYBRIDS {WOLFSSL_X448MLKEM768, WOLFSSL_ECC_X448, WOLFSSL_ML_KEM_768, 1}, -#endif +#endif /* WOLFSSL_EXTRA_PQC_HYBRIDS */ +#endif /* HAVE_CURVE448 */ #endif /* WOLFSSL_NO_ML_KEM */ #ifdef WOLFSSL_MLKEM_KYBER {WOLFSSL_P256_KYBER_LEVEL1, WOLFSSL_ECC_SECP256R1, WOLFSSL_KYBER_LEVEL1, 0}, @@ -10596,7 +10623,8 @@ int TLSX_KeyShare_Use(const WOLFSSL* ssl, word16 group, word16 len, byte* data, /* Try to find the key share entry with this group. */ keyShareEntry = (KeyShareEntry*)extension->data; while (keyShareEntry != NULL) { -#ifdef WOLFSSL_ML_KEM_USE_OLD_IDS + #if defined(WOLFSSL_ML_KEM_USE_OLD_IDS) && \ + defined (WOLFSSL_EXTRA_PQC_HYBRIDS) if ((group == WOLFSSL_P256_ML_KEM_512_OLD && keyShareEntry->group == WOLFSSL_SECP256R1MLKEM512) || (group == WOLFSSL_P384_ML_KEM_768_OLD && @@ -10607,7 +10635,7 @@ int TLSX_KeyShare_Use(const WOLFSSL* ssl, word16 group, word16 len, byte* data, break; } else -#endif + #endif /* WOLFSSL_ML_KEM_USE_OLD_IDS && WOLFSSL_EXTRA_PQC_HYBRIDS */ if (keyShareEntry->group == group) break; keyShareEntry = keyShareEntry->next; @@ -10625,13 +10653,20 @@ int TLSX_KeyShare_Use(const WOLFSSL* ssl, word16 group, word16 len, byte* data, #if defined(WOLFSSL_HAVE_MLKEM) && !defined(WOLFSSL_MLKEM_NO_ENCAPSULATE) if (ssl->options.side == WOLFSSL_SERVER_END && WOLFSSL_NAMED_GROUP_IS_PQC(group)) { - ret = TLSX_KeyShare_HandlePqcKeyServer((WOLFSSL*)ssl, - keyShareEntry, - data, len, - ssl->arrays->preMasterSecret, - &ssl->arrays->preMasterSz); - if (ret != 0) - return ret; + if (TLSX_IsGroupSupported(group)) { + ret = TLSX_KeyShare_HandlePqcKeyServer((WOLFSSL*)ssl, + keyShareEntry, + data, len, + ssl->arrays->preMasterSecret, + &ssl->arrays->preMasterSz); + if (ret != 0) + return ret; + } + else { + XFREE(keyShareEntry->ke, ssl->heap, DYNAMIC_TYPE_PUBLIC_KEY); + keyShareEntry->ke = NULL; + keyShareEntry->keLen = 0; + } } else if (ssl->options.side == WOLFSSL_SERVER_END && WOLFSSL_NAMED_GROUP_IS_PQC_HYBRID(group)) { @@ -10689,6 +10724,49 @@ int TLSX_KeyShare_Empty(WOLFSSL* ssl) } static const word16 preferredGroup[] = { + /* Sort by strength, but prefer non-experimental PQ/T hybrid groups */ +#if defined(WOLFSSL_HAVE_MLKEM) && !defined(WOLFSSL_NO_ML_KEM) + #if !defined(WOLFSSL_NO_ML_KEM_768) && defined(HAVE_CURVE25519) && \ + ECC_MIN_KEY_SZ <= 256 + WOLFSSL_X25519MLKEM768, + #endif + #if !defined(WOLFSSL_NO_ML_KEM_1024) && defined(HAVE_ECC) && \ + (defined(HAVE_ECC384) || defined(HAVE_ALL_CURVES)) && \ + ECC_MIN_KEY_SZ <= 384 + WOLFSSL_SECP384R1MLKEM1024, + #endif + #if !defined(WOLFSSL_NO_ML_KEM_768) && defined(HAVE_ECC) && \ + (!defined(NO_ECC256) || defined(HAVE_ALL_CURVES)) && \ + ECC_MIN_KEY_SZ <= 256 + WOLFSSL_SECP256R1MLKEM768, + #endif +#endif /* WOLFSSL_HAVE_MLKEM && !WOLFSSL_NO_ML_KEM */ +#if defined(HAVE_ECC) && (!defined(NO_ECC521) || \ + defined(HAVE_ALL_CURVES)) && !defined(NO_ECC_SECP) && ECC_MIN_KEY_SZ <= 521 + WOLFSSL_ECC_SECP521R1, +#endif +#if defined(HAVE_ECC) && defined(HAVE_ECC512) && \ + defined(HAVE_ECC_BRAINPOOL) && ECC_MIN_KEY_SZ <= 512 + WOLFSSL_ECC_BRAINPOOLP512R1TLS13, +#endif +#if defined(WOLFSSL_HAVE_MLKEM) && !defined(WOLFSSL_NO_ML_KEM) && \ + !defined(WOLFSSL_NO_ML_KEM_1024) && !defined(WOLFSSL_TLS_NO_MLKEM_STANDALONE) + WOLFSSL_ML_KEM_1024, +#endif +#if defined(HAVE_ECC) && (!defined(NO_ECC384) || \ + defined(HAVE_ALL_CURVES)) && !defined(NO_ECC_SECP) && ECC_MIN_KEY_SZ <= 384 + WOLFSSL_ECC_SECP384R1, +#if defined(HAVE_ECC_BRAINPOOL) + WOLFSSL_ECC_BRAINPOOLP384R1TLS13, +#endif +#endif +#if defined(HAVE_CURVE448) && ECC_MIN_KEY_SZ <= 448 + WOLFSSL_ECC_X448, +#endif +#if defined(WOLFSSL_HAVE_MLKEM) && !defined(WOLFSSL_NO_ML_KEM) && \ + !defined(WOLFSSL_NO_ML_KEM_768) && !defined(WOLFSSL_TLS_NO_MLKEM_STANDALONE) + WOLFSSL_ML_KEM_768, +#endif #if defined(HAVE_ECC) && (!defined(NO_ECC256) || \ defined(HAVE_ALL_CURVES)) && !defined(NO_ECC_SECP) && ECC_MIN_KEY_SZ <= 256 WOLFSSL_ECC_SECP256R1, @@ -10702,91 +10780,49 @@ static const word16 preferredGroup[] = { #if defined(HAVE_CURVE25519) && ECC_MIN_KEY_SZ <= 256 WOLFSSL_ECC_X25519, #endif -#if defined(HAVE_CURVE448) && ECC_MIN_KEY_SZ <= 448 - WOLFSSL_ECC_X448, -#endif -#if defined(HAVE_ECC) && (!defined(NO_ECC384) || \ - defined(HAVE_ALL_CURVES)) && !defined(NO_ECC_SECP) && ECC_MIN_KEY_SZ <= 384 - WOLFSSL_ECC_SECP384R1, -#if defined(HAVE_ECC_BRAINPOOL) - WOLFSSL_ECC_BRAINPOOLP384R1TLS13, -#endif -#endif -#if defined(HAVE_ECC) && (!defined(NO_ECC521) || \ - defined(HAVE_ALL_CURVES)) && !defined(NO_ECC_SECP) && ECC_MIN_KEY_SZ <= 521 - WOLFSSL_ECC_SECP521R1, -#endif -#if defined(HAVE_ECC) && defined(HAVE_ECC512) && \ - defined(HAVE_ECC_BRAINPOOL) && ECC_MIN_KEY_SZ <= 512 - WOLFSSL_ECC_BRAINPOOLP512R1TLS13, +#if defined(WOLFSSL_HAVE_MLKEM) && !defined(WOLFSSL_NO_ML_KEM) && \ + !defined(WOLFSSL_NO_ML_KEM_512) && !defined(WOLFSSL_TLS_NO_MLKEM_STANDALONE) + WOLFSSL_ML_KEM_512, #endif -#if defined(HAVE_FFDHE_2048) - WOLFSSL_FFDHE_2048, +#if defined(HAVE_FFDHE_8192) + WOLFSSL_FFDHE_8192, #endif -#if defined(HAVE_FFDHE_3072) - WOLFSSL_FFDHE_3072, +#if defined(HAVE_FFDHE_6144) + WOLFSSL_FFDHE_6144, #endif #if defined(HAVE_FFDHE_4096) WOLFSSL_FFDHE_4096, #endif -#if defined(HAVE_FFDHE_6144) - WOLFSSL_FFDHE_6144, +#if defined(HAVE_FFDHE_3072) + WOLFSSL_FFDHE_3072, #endif -#if defined(HAVE_FFDHE_8192) - WOLFSSL_FFDHE_8192, +#if defined(HAVE_FFDHE_2048) + WOLFSSL_FFDHE_2048, #endif #ifndef WOLFSSL_NO_ML_KEM -#ifdef WOLFSSL_WC_MLKEM - #ifndef WOLFSSL_NO_ML_KEM_512 - WOLFSSL_ML_KEM_512, - WOLFSSL_SECP256R1MLKEM512, - #if defined(HAVE_CURVE25519) && ECC_MIN_KEY_SZ <= 256 - WOLFSSL_X25519MLKEM512, - #endif + #if !defined(WOLFSSL_NO_ML_KEM_1024) && \ + defined(WOLFSSL_EXTRA_PQC_HYBRIDS) + WOLFSSL_SECP521R1MLKEM1024, #endif - #ifndef WOLFSSL_NO_ML_KEM_768 - WOLFSSL_ML_KEM_768, + #if !defined(WOLFSSL_NO_ML_KEM_768) && \ + defined(WOLFSSL_EXTRA_PQC_HYBRIDS) WOLFSSL_SECP384R1MLKEM768, - WOLFSSL_SECP256R1MLKEM768, - #if defined(HAVE_CURVE25519) && ECC_MIN_KEY_SZ <= 256 - WOLFSSL_X25519MLKEM768, - #endif #if defined(HAVE_CURVE448) && ECC_MIN_KEY_SZ <= 448 WOLFSSL_X448MLKEM768, + #endif /* HAVE_CURVE448 */ #endif - #endif - #ifndef WOLFSSL_NO_ML_KEM_1024 - WOLFSSL_ML_KEM_1024, - WOLFSSL_SECP521R1MLKEM1024, - WOLFSSL_SECP384R1MLKEM1024, - #endif -#elif defined(HAVE_LIBOQS) - /* These require a runtime call to TLSX_IsGroupSupported to use */ - WOLFSSL_ML_KEM_512, - WOLFSSL_ML_KEM_768, - WOLFSSL_ML_KEM_1024, + #if !defined(WOLFSSL_NO_ML_KEM_512) && \ + defined(WOLFSSL_EXTRA_PQC_HYBRIDS) WOLFSSL_SECP256R1MLKEM512, - WOLFSSL_SECP384R1MLKEM768, - WOLFSSL_SECP256R1MLKEM768, - WOLFSSL_SECP521R1MLKEM1024, - WOLFSSL_SECP384R1MLKEM1024, #if defined(HAVE_CURVE25519) && ECC_MIN_KEY_SZ <= 256 WOLFSSL_X25519MLKEM512, - WOLFSSL_X25519MLKEM768, + #endif /* HAVE_CURVE25519 */ #endif - #if defined(HAVE_CURVE448) && ECC_MIN_KEY_SZ <= 448 - WOLFSSL_X448MLKEM768, - #endif -#endif #endif /* !WOLFSSL_NO_ML_KEM */ #ifdef WOLFSSL_MLKEM_KYBER -#ifdef WOLFSSL_WC_MLKEM - #ifdef WOLFSSL_KYBER512 - WOLFSSL_KYBER_LEVEL1, - WOLFSSL_P256_KYBER_LEVEL1, - #if defined(HAVE_CURVE25519) && ECC_MIN_KEY_SZ <= 256 - WOLFSSL_X25519_KYBER_LEVEL1, - #endif + #ifdef WOLFSSL_KYBER1024 + WOLFSSL_KYBER_LEVEL5, + WOLFSSL_P521_KYBER_LEVEL5, #endif #ifdef WOLFSSL_KYBER768 WOLFSSL_KYBER_LEVEL3, @@ -10799,27 +10835,13 @@ static const word16 preferredGroup[] = { WOLFSSL_X448_KYBER_LEVEL3, #endif #endif - #ifdef WOLFSSL_KYBER1024 - WOLFSSL_KYBER_LEVEL5, - WOLFSSL_P521_KYBER_LEVEL5, - #endif -#elif defined(HAVE_LIBOQS) - /* These require a runtime call to TLSX_IsGroupSupported to use */ + #ifdef WOLFSSL_KYBER512 WOLFSSL_KYBER_LEVEL1, - WOLFSSL_KYBER_LEVEL3, - WOLFSSL_KYBER_LEVEL5, WOLFSSL_P256_KYBER_LEVEL1, - WOLFSSL_P384_KYBER_LEVEL3, - WOLFSSL_P256_KYBER_LEVEL3, - WOLFSSL_P521_KYBER_LEVEL5, #if defined(HAVE_CURVE25519) && ECC_MIN_KEY_SZ <= 256 WOLFSSL_X25519_KYBER_LEVEL1, - WOLFSSL_X25519_KYBER_LEVEL3, #endif - #if defined(HAVE_CURVE448) && ECC_MIN_KEY_SZ <= 448 - WOLFSSL_X448_KYBER_LEVEL3, #endif -#endif #endif /* WOLFSSL_MLKEM_KYBER */ WOLFSSL_NAMED_GROUP_INVALID }; @@ -10856,7 +10878,8 @@ static int TLSX_KeyShare_GroupRank(const WOLFSSL* ssl, int group) #endif for (i = 0; i < numGroups; i++) { -#ifdef WOLFSSL_ML_KEM_USE_OLD_IDS +#if defined(WOLFSSL_ML_KEM_USE_OLD_IDS) && \ + defined (WOLFSSL_EXTRA_PQC_HYBRIDS) if ((group == WOLFSSL_P256_ML_KEM_512_OLD && groups[i] == WOLFSSL_SECP256R1MLKEM512) || (group == WOLFSSL_P384_ML_KEM_768_OLD && @@ -14290,144 +14313,192 @@ static int TLSX_PopulateSupportedGroups(WOLFSSL* ssl, TLSX** extensions) } #endif /* WOLFSSL_TLS13 */ +#if defined(WOLFSSL_HAVE_MLKEM) && !defined(WOLFSSL_NO_ML_KEM) + /* Prefer non-experimental PQ/T hybrid groups */ + #if !defined(WOLFSSL_NO_ML_KEM_768) && defined(HAVE_CURVE25519) && \ + ECC_MIN_KEY_SZ <= 256 + ret = TLSX_UseSupportedCurve(extensions, WOLFSSL_X25519MLKEM768, + ssl->heap); + if (ret != WOLFSSL_SUCCESS) return ret; + #endif + #if !defined(WOLFSSL_NO_ML_KEM_1024) && defined(HAVE_ECC) && \ + (defined(HAVE_ECC384) || defined(HAVE_ALL_CURVES)) && \ + ECC_MIN_KEY_SZ <= 384 + ret = TLSX_UseSupportedCurve(extensions, WOLFSSL_SECP384R1MLKEM1024, + ssl->heap); + if (ret != WOLFSSL_SUCCESS) return ret; + #endif + #if !defined(WOLFSSL_NO_ML_KEM_768) && defined(HAVE_ECC) && \ + (!defined(NO_ECC256) || defined(HAVE_ALL_CURVES)) && \ + ECC_MIN_KEY_SZ <= 256 + ret = TLSX_UseSupportedCurve(extensions, WOLFSSL_SECP256R1MLKEM768, + ssl->heap); + if (ret != WOLFSSL_SUCCESS) return ret; + #endif +#endif /* WOLFSSL_HAVE_MLKEM && !WOLFSSL_NO_ML_KEM */ + #if defined(HAVE_ECC) - /* list in order by strength, since not all servers choose by strength */ - #if (defined(HAVE_ECC521) || defined(HAVE_ALL_CURVES)) && ECC_MIN_KEY_SZ <= 521 - #ifndef NO_ECC_SECP + /* list in order by strength, since not all servers choose by strength */ + #if (defined(HAVE_ECC521) || defined(HAVE_ALL_CURVES)) && ECC_MIN_KEY_SZ <= 521 + #ifndef NO_ECC_SECP + ret = TLSX_UseSupportedCurve(extensions, + WOLFSSL_ECC_SECP521R1, ssl->heap); + if (ret != WOLFSSL_SUCCESS) return ret; + #endif + #endif + #if (defined(HAVE_ECC512) || defined(HAVE_ALL_CURVES)) && ECC_MIN_KEY_SZ <= 512 + #ifdef HAVE_ECC_BRAINPOOL + if (IsAtLeastTLSv1_3(ssl->version)) { + /* TLS 1.3 BrainpoolP512 curve */ + ret = TLSX_UseSupportedCurve(extensions, + WOLFSSL_ECC_BRAINPOOLP512R1TLS13, ssl->heap); + if (ret != WOLFSSL_SUCCESS) return ret; + + /* If TLS 1.2 is allowed, also add the TLS 1.2 curve */ + if (ssl->options.downgrade && + (ssl->options.minDowngrade <= TLSv1_2_MINOR || + ssl->options.minDowngrade <= DTLSv1_2_MINOR)) { ret = TLSX_UseSupportedCurve(extensions, - WOLFSSL_ECC_SECP521R1, ssl->heap); + WOLFSSL_ECC_BRAINPOOLP512R1, ssl->heap); if (ret != WOLFSSL_SUCCESS) return ret; - #endif + } + } + else { + /* TLS 1.2 only */ + ret = TLSX_UseSupportedCurve(extensions, + WOLFSSL_ECC_BRAINPOOLP512R1, ssl->heap); + if (ret != WOLFSSL_SUCCESS) return ret; + } #endif - #if (defined(HAVE_ECC512) || defined(HAVE_ALL_CURVES)) && ECC_MIN_KEY_SZ <= 512 - #ifdef HAVE_ECC_BRAINPOOL - if (IsAtLeastTLSv1_3(ssl->version)) { - /* TLS 1.3 BrainpoolP512 curve */ - ret = TLSX_UseSupportedCurve(extensions, - WOLFSSL_ECC_BRAINPOOLP512R1TLS13, ssl->heap); - if (ret != WOLFSSL_SUCCESS) return ret; - - /* If TLS 1.2 is allowed, also add the TLS 1.2 curve */ - if (ssl->options.downgrade && - (ssl->options.minDowngrade <= TLSv1_2_MINOR || - ssl->options.minDowngrade <= DTLSv1_2_MINOR)) { - ret = TLSX_UseSupportedCurve(extensions, - WOLFSSL_ECC_BRAINPOOLP512R1, ssl->heap); - if (ret != WOLFSSL_SUCCESS) return ret; - } - } - else { - /* TLS 1.2 only */ - ret = TLSX_UseSupportedCurve(extensions, - WOLFSSL_ECC_BRAINPOOLP512R1, ssl->heap); - if (ret != WOLFSSL_SUCCESS) return ret; - } - #endif + #endif +#endif + +#if defined(WOLFSSL_HAVE_MLKEM) && !defined(WOLFSSL_NO_ML_KEM) && \ + !defined(WOLFSSL_NO_ML_KEM_1024) && !defined(WOLFSSL_TLS_NO_MLKEM_STANDALONE) + ret = TLSX_UseSupportedCurve(extensions, WOLFSSL_ML_KEM_1024, + ssl->heap); + if (ret != WOLFSSL_SUCCESS) return ret; +#endif + +#if defined(HAVE_ECC) + #if (defined(HAVE_ECC384) || defined(HAVE_ALL_CURVES)) && ECC_MIN_KEY_SZ <= 384 + #ifndef NO_ECC_SECP + ret = TLSX_UseSupportedCurve(extensions, + WOLFSSL_ECC_SECP384R1, ssl->heap); + if (ret != WOLFSSL_SUCCESS) return ret; #endif - #if (defined(HAVE_ECC384) || defined(HAVE_ALL_CURVES)) && ECC_MIN_KEY_SZ <= 384 - #ifndef NO_ECC_SECP + #ifdef HAVE_ECC_BRAINPOOL + if (IsAtLeastTLSv1_3(ssl->version)) { + /* TLS 1.3 BrainpoolP384 curve */ + ret = TLSX_UseSupportedCurve(extensions, + WOLFSSL_ECC_BRAINPOOLP384R1TLS13, ssl->heap); + if (ret != WOLFSSL_SUCCESS) return ret; + + /* If TLS 1.2 is allowed, also add the TLS 1.2 curve */ + if (ssl->options.downgrade && + (ssl->options.minDowngrade <= TLSv1_2_MINOR || + ssl->options.minDowngrade <= DTLSv1_2_MINOR)) { ret = TLSX_UseSupportedCurve(extensions, - WOLFSSL_ECC_SECP384R1, ssl->heap); + WOLFSSL_ECC_BRAINPOOLP384R1, ssl->heap); if (ret != WOLFSSL_SUCCESS) return ret; - #endif - #ifdef HAVE_ECC_BRAINPOOL - if (IsAtLeastTLSv1_3(ssl->version)) { - /* TLS 1.3 BrainpoolP384 curve */ - ret = TLSX_UseSupportedCurve(extensions, - WOLFSSL_ECC_BRAINPOOLP384R1TLS13, ssl->heap); - if (ret != WOLFSSL_SUCCESS) return ret; - - /* If TLS 1.2 is allowed, also add the TLS 1.2 curve */ - if (ssl->options.downgrade && - (ssl->options.minDowngrade <= TLSv1_2_MINOR || - ssl->options.minDowngrade <= DTLSv1_2_MINOR)) { - ret = TLSX_UseSupportedCurve(extensions, - WOLFSSL_ECC_BRAINPOOLP384R1, ssl->heap); - if (ret != WOLFSSL_SUCCESS) return ret; - } - } - else { - /* TLS 1.2 only */ - ret = TLSX_UseSupportedCurve(extensions, - WOLFSSL_ECC_BRAINPOOLP384R1, ssl->heap); - if (ret != WOLFSSL_SUCCESS) return ret; - } - #endif + } + } + else { + /* TLS 1.2 only */ + ret = TLSX_UseSupportedCurve(extensions, + WOLFSSL_ECC_BRAINPOOLP384R1, ssl->heap); + if (ret != WOLFSSL_SUCCESS) return ret; + } #endif + #endif #endif /* HAVE_ECC */ - #ifndef HAVE_FIPS - #if defined(HAVE_CURVE448) && ECC_MIN_KEY_SZ <= 448 - ret = TLSX_UseSupportedCurve(extensions, - WOLFSSL_ECC_X448, ssl->heap); - if (ret != WOLFSSL_SUCCESS) return ret; - #endif - #endif /* HAVE_FIPS */ +#ifndef HAVE_FIPS + #if defined(HAVE_CURVE448) && ECC_MIN_KEY_SZ <= 448 + ret = TLSX_UseSupportedCurve(extensions, + WOLFSSL_ECC_X448, ssl->heap); + if (ret != WOLFSSL_SUCCESS) return ret; + #endif +#endif /* HAVE_FIPS */ + +#if defined(WOLFSSL_HAVE_MLKEM) && !defined(WOLFSSL_NO_ML_KEM) && \ + !defined(WOLFSSL_NO_ML_KEM_768) && !defined(WOLFSSL_TLS_NO_MLKEM_STANDALONE) + ret = TLSX_UseSupportedCurve(extensions, WOLFSSL_ML_KEM_768, + ssl->heap); + if (ret != WOLFSSL_SUCCESS) return ret; +#endif #if defined(HAVE_ECC) && defined(HAVE_SUPPORTED_CURVES) - #if (!defined(NO_ECC256) || defined(HAVE_ALL_CURVES)) && ECC_MIN_KEY_SZ <= 256 - #ifndef NO_ECC_SECP - ret = TLSX_UseSupportedCurve(extensions, - WOLFSSL_ECC_SECP256R1, ssl->heap); - if (ret != WOLFSSL_SUCCESS) return ret; - #endif - #ifdef HAVE_ECC_KOBLITZ - ret = TLSX_UseSupportedCurve(extensions, - WOLFSSL_ECC_SECP256K1, ssl->heap); - if (ret != WOLFSSL_SUCCESS) return ret; - #endif - #ifdef HAVE_ECC_BRAINPOOL - if (IsAtLeastTLSv1_3(ssl->version)) { - /* TLS 1.3 BrainpoolP256 curve */ - ret = TLSX_UseSupportedCurve(extensions, - WOLFSSL_ECC_BRAINPOOLP256R1TLS13, ssl->heap); - if (ret != WOLFSSL_SUCCESS) return ret; - - /* If TLS 1.2 is allowed, also add the TLS 1.2 curve */ - if (ssl->options.downgrade && - (ssl->options.minDowngrade <= TLSv1_2_MINOR || - ssl->options.minDowngrade <= DTLSv1_2_MINOR)) { - ret = TLSX_UseSupportedCurve(extensions, - WOLFSSL_ECC_BRAINPOOLP256R1, ssl->heap); - if (ret != WOLFSSL_SUCCESS) return ret; - } - } - else { - /* TLS 1.2 only */ - ret = TLSX_UseSupportedCurve(extensions, - WOLFSSL_ECC_BRAINPOOLP256R1, ssl->heap); - if (ret != WOLFSSL_SUCCESS) return ret; - } - #endif - #ifdef WOLFSSL_SM2 + #if (!defined(NO_ECC256) || defined(HAVE_ALL_CURVES)) && ECC_MIN_KEY_SZ <= 256 + #ifndef NO_ECC_SECP + ret = TLSX_UseSupportedCurve(extensions, + WOLFSSL_ECC_SECP256R1, ssl->heap); + if (ret != WOLFSSL_SUCCESS) return ret; + #endif + #ifdef HAVE_ECC_KOBLITZ + ret = TLSX_UseSupportedCurve(extensions, + WOLFSSL_ECC_SECP256K1, ssl->heap); + if (ret != WOLFSSL_SUCCESS) return ret; + #endif + #ifdef HAVE_ECC_BRAINPOOL + if (IsAtLeastTLSv1_3(ssl->version)) { + /* TLS 1.3 BrainpoolP256 curve */ + ret = TLSX_UseSupportedCurve(extensions, + WOLFSSL_ECC_BRAINPOOLP256R1TLS13, ssl->heap); + if (ret != WOLFSSL_SUCCESS) return ret; + + /* If TLS 1.2 is allowed, also add the TLS 1.2 curve */ + if (ssl->options.downgrade && + (ssl->options.minDowngrade <= TLSv1_2_MINOR || + ssl->options.minDowngrade <= DTLSv1_2_MINOR)) { ret = TLSX_UseSupportedCurve(extensions, - WOLFSSL_ECC_SM2P256V1, ssl->heap); + WOLFSSL_ECC_BRAINPOOLP256R1, ssl->heap); if (ret != WOLFSSL_SUCCESS) return ret; - #endif + } + } + else { + /* TLS 1.2 only */ + ret = TLSX_UseSupportedCurve(extensions, + WOLFSSL_ECC_BRAINPOOLP256R1, ssl->heap); + if (ret != WOLFSSL_SUCCESS) return ret; + } + #endif + #ifdef WOLFSSL_SM2 + ret = TLSX_UseSupportedCurve(extensions, + WOLFSSL_ECC_SM2P256V1, ssl->heap); + if (ret != WOLFSSL_SUCCESS) return ret; #endif + #endif #endif /* HAVE_ECC */ - #ifndef HAVE_FIPS - #if defined(HAVE_CURVE25519) && ECC_MIN_KEY_SZ <= 256 - ret = TLSX_UseSupportedCurve(extensions, - WOLFSSL_ECC_X25519, ssl->heap); - if (ret != WOLFSSL_SUCCESS) return ret; - #endif - #endif /* HAVE_FIPS */ +#ifndef HAVE_FIPS + #if defined(HAVE_CURVE25519) && ECC_MIN_KEY_SZ <= 256 + ret = TLSX_UseSupportedCurve(extensions, + WOLFSSL_ECC_X25519, ssl->heap); + if (ret != WOLFSSL_SUCCESS) return ret; + #endif +#endif /* HAVE_FIPS */ + +#if defined(WOLFSSL_HAVE_MLKEM) && !defined(WOLFSSL_NO_ML_KEM) && \ + !defined(WOLFSSL_NO_ML_KEM_512) && !defined(WOLFSSL_TLS_NO_MLKEM_STANDALONE) + ret = TLSX_UseSupportedCurve(extensions, WOLFSSL_ML_KEM_512, + ssl->heap); + if (ret != WOLFSSL_SUCCESS) return ret; +#endif #if defined(HAVE_ECC) && defined(HAVE_SUPPORTED_CURVES) - #if (defined(HAVE_ECC224) || defined(HAVE_ALL_CURVES)) && ECC_MIN_KEY_SZ <= 224 - #ifndef NO_ECC_SECP - ret = TLSX_UseSupportedCurve(extensions, - WOLFSSL_ECC_SECP224R1, ssl->heap); - if (ret != WOLFSSL_SUCCESS) return ret; - #endif - #ifdef HAVE_ECC_KOBLITZ - ret = TLSX_UseSupportedCurve(extensions, - WOLFSSL_ECC_SECP224K1, ssl->heap); - if (ret != WOLFSSL_SUCCESS) return ret; - #endif + #if (defined(HAVE_ECC224) || defined(HAVE_ALL_CURVES)) && ECC_MIN_KEY_SZ <= 224 + #ifndef NO_ECC_SECP + ret = TLSX_UseSupportedCurve(extensions, + WOLFSSL_ECC_SECP224R1, ssl->heap); + if (ret != WOLFSSL_SUCCESS) return ret; + #endif + #ifdef HAVE_ECC_KOBLITZ + ret = TLSX_UseSupportedCurve(extensions, + WOLFSSL_ECC_SECP224K1, ssl->heap); + if (ret != WOLFSSL_SUCCESS) return ret; #endif + #endif #ifndef HAVE_FIPS #if (defined(HAVE_ECC192) || defined(HAVE_ALL_CURVES)) && ECC_MIN_KEY_SZ <= 192 @@ -14463,154 +14534,93 @@ static int TLSX_PopulateSupportedGroups(WOLFSSL* ssl, TLSX** extensions) #endif /* HAVE_ECC */ #ifndef NO_DH - /* Add FFDHE supported groups. */ - #ifdef HAVE_FFDHE_8192 - if (8192/8 >= ssl->options.minDhKeySz && - 8192/8 <= ssl->options.maxDhKeySz) { - ret = TLSX_UseSupportedCurve(extensions, - WOLFSSL_FFDHE_8192, ssl->heap); - if (ret != WOLFSSL_SUCCESS) - return ret; - } - #endif - #ifdef HAVE_FFDHE_6144 - if (6144/8 >= ssl->options.minDhKeySz && - 6144/8 <= ssl->options.maxDhKeySz) { - ret = TLSX_UseSupportedCurve(extensions, - WOLFSSL_FFDHE_6144, ssl->heap); - if (ret != WOLFSSL_SUCCESS) - return ret; - } - #endif - #ifdef HAVE_FFDHE_4096 - if (4096/8 >= ssl->options.minDhKeySz && - 4096/8 <= ssl->options.maxDhKeySz) { - ret = TLSX_UseSupportedCurve(extensions, - WOLFSSL_FFDHE_4096, ssl->heap); - if (ret != WOLFSSL_SUCCESS) - return ret; - } - #endif - #ifdef HAVE_FFDHE_3072 - if (3072/8 >= ssl->options.minDhKeySz && - 3072/8 <= ssl->options.maxDhKeySz) { - ret = TLSX_UseSupportedCurve(extensions, - WOLFSSL_FFDHE_3072, ssl->heap); - if (ret != WOLFSSL_SUCCESS) - return ret; - } - #endif - #ifdef HAVE_FFDHE_2048 - if (2048/8 >= ssl->options.minDhKeySz && - 2048/8 <= ssl->options.maxDhKeySz) { - ret = TLSX_UseSupportedCurve(extensions, - WOLFSSL_FFDHE_2048, ssl->heap); - if (ret != WOLFSSL_SUCCESS) - return ret; - } - #endif + /* Add FFDHE supported groups. */ + #ifdef HAVE_FFDHE_8192 + if (8192/8 >= ssl->options.minDhKeySz && + 8192/8 <= ssl->options.maxDhKeySz) { + ret = TLSX_UseSupportedCurve(extensions, + WOLFSSL_FFDHE_8192, ssl->heap); + if (ret != WOLFSSL_SUCCESS) + return ret; + } + #endif + #ifdef HAVE_FFDHE_6144 + if (6144/8 >= ssl->options.minDhKeySz && + 6144/8 <= ssl->options.maxDhKeySz) { + ret = TLSX_UseSupportedCurve(extensions, + WOLFSSL_FFDHE_6144, ssl->heap); + if (ret != WOLFSSL_SUCCESS) + return ret; + } + #endif + #ifdef HAVE_FFDHE_4096 + if (4096/8 >= ssl->options.minDhKeySz && + 4096/8 <= ssl->options.maxDhKeySz) { + ret = TLSX_UseSupportedCurve(extensions, + WOLFSSL_FFDHE_4096, ssl->heap); + if (ret != WOLFSSL_SUCCESS) + return ret; + } + #endif + #ifdef HAVE_FFDHE_3072 + if (3072/8 >= ssl->options.minDhKeySz && + 3072/8 <= ssl->options.maxDhKeySz) { + ret = TLSX_UseSupportedCurve(extensions, + WOLFSSL_FFDHE_3072, ssl->heap); + if (ret != WOLFSSL_SUCCESS) + return ret; + } + #endif + #ifdef HAVE_FFDHE_2048 + if (2048/8 >= ssl->options.minDhKeySz && + 2048/8 <= ssl->options.maxDhKeySz) { + ret = TLSX_UseSupportedCurve(extensions, + WOLFSSL_FFDHE_2048, ssl->heap); + if (ret != WOLFSSL_SUCCESS) + return ret; + } + #endif #endif #ifdef WOLFSSL_HAVE_MLKEM #ifndef WOLFSSL_NO_ML_KEM -#ifdef WOLFSSL_WC_MLKEM -#ifndef WOLFSSL_NO_ML_KEM_512 - if (ret == WOLFSSL_SUCCESS) - ret = TLSX_UseSupportedCurve(extensions, WOLFSSL_ML_KEM_512, - ssl->heap); - if (ret == WOLFSSL_SUCCESS) - ret = TLSX_UseSupportedCurve(extensions, WOLFSSL_SECP256R1MLKEM512, - ssl->heap); - #if defined(HAVE_CURVE25519) && ECC_MIN_KEY_SZ <= 256 +#if !defined(WOLFSSL_NO_ML_KEM_1024) && \ + defined(WOLFSSL_EXTRA_PQC_HYBRIDS) if (ret == WOLFSSL_SUCCESS) - ret = TLSX_UseSupportedCurve(extensions, WOLFSSL_X25519MLKEM512, + ret = TLSX_UseSupportedCurve(extensions, WOLFSSL_SECP521R1MLKEM1024, ssl->heap); - #endif #endif -#ifndef WOLFSSL_NO_ML_KEM_768 - if (ret == WOLFSSL_SUCCESS) - ret = TLSX_UseSupportedCurve(extensions, WOLFSSL_ML_KEM_768, - ssl->heap); +#if !defined(WOLFSSL_NO_ML_KEM_768) && \ + defined(WOLFSSL_EXTRA_PQC_HYBRIDS) if (ret == WOLFSSL_SUCCESS) ret = TLSX_UseSupportedCurve(extensions, WOLFSSL_SECP384R1MLKEM768, ssl->heap); - if (ret == WOLFSSL_SUCCESS) - ret = TLSX_UseSupportedCurve(extensions, WOLFSSL_SECP256R1MLKEM768, - ssl->heap); - #if defined(HAVE_CURVE25519) && ECC_MIN_KEY_SZ <= 256 - if (ret == WOLFSSL_SUCCESS) - ret = TLSX_UseSupportedCurve(extensions, WOLFSSL_X25519MLKEM768, - ssl->heap); - #endif #if defined(HAVE_CURVE448) && ECC_MIN_KEY_SZ <= 448 if (ret == WOLFSSL_SUCCESS) ret = TLSX_UseSupportedCurve(extensions, WOLFSSL_X448MLKEM768, ssl->heap); - #endif + #endif /* HAVE_CURVE448 */ #endif -#ifndef WOLFSSL_NO_ML_KEM_1024 - if (ret == WOLFSSL_SUCCESS) - ret = TLSX_UseSupportedCurve(extensions, WOLFSSL_ML_KEM_1024, - ssl->heap); - if (ret == WOLFSSL_SUCCESS) - ret = TLSX_UseSupportedCurve(extensions, WOLFSSL_SECP521R1MLKEM1024, - ssl->heap); - if (ret == WOLFSSL_SUCCESS) - ret = TLSX_UseSupportedCurve(extensions, WOLFSSL_SECP384R1MLKEM1024, - ssl->heap); -#endif -#elif defined(HAVE_LIBOQS) - ret = TLSX_UseSupportedCurve(extensions, WOLFSSL_ML_KEM_512, ssl->heap); - if (ret == WOLFSSL_SUCCESS) - ret = TLSX_UseSupportedCurve(extensions, WOLFSSL_ML_KEM_768, - ssl->heap); - if (ret == WOLFSSL_SUCCESS) - ret = TLSX_UseSupportedCurve(extensions, WOLFSSL_ML_KEM_1024, - ssl->heap); +#if !defined(WOLFSSL_NO_ML_KEM_512) && \ + defined(WOLFSSL_EXTRA_PQC_HYBRIDS) if (ret == WOLFSSL_SUCCESS) ret = TLSX_UseSupportedCurve(extensions, WOLFSSL_SECP256R1MLKEM512, ssl->heap); - if (ret == WOLFSSL_SUCCESS) - ret = TLSX_UseSupportedCurve(extensions, WOLFSSL_SECP384R1MLKEM768, - ssl->heap); - if (ret == WOLFSSL_SUCCESS) - ret = TLSX_UseSupportedCurve(extensions, WOLFSSL_SECP256R1MLKEM768, - ssl->heap); - if (ret == WOLFSSL_SUCCESS) - ret = TLSX_UseSupportedCurve(extensions, WOLFSSL_SECP521R1MLKEM1024, - ssl->heap); - if (ret == WOLFSSL_SUCCESS) - ret = TLSX_UseSupportedCurve(extensions, WOLFSSL_SECP384R1MLKEM1024, - ssl->heap); #if defined(HAVE_CURVE25519) && ECC_MIN_KEY_SZ <= 256 if (ret == WOLFSSL_SUCCESS) ret = TLSX_UseSupportedCurve(extensions, WOLFSSL_X25519MLKEM512, ssl->heap); - if (ret == WOLFSSL_SUCCESS) - ret = TLSX_UseSupportedCurve(extensions, WOLFSSL_X25519MLKEM768, - ssl->heap); - #endif - #if defined(HAVE_CURVE448) && ECC_MIN_KEY_SZ <= 448 - if (ret == WOLFSSL_SUCCESS) - ret = TLSX_UseSupportedCurve(extensions, WOLFSSL_X448MLKEM768, - ssl->heap); - #endif -#endif /* HAVE_LIBOQS */ + #endif /* HAVE_CURVE25519 */ +#endif #endif /* !WOLFSSL_NO_ML_KEM */ #ifdef WOLFSSL_MLKEM_KYBER -#ifdef WOLFSSL_WC_MLKEM -#ifdef WOLFSSL_KYBER512 - if (ret == WOLFSSL_SUCCESS) - ret = TLSX_UseSupportedCurve(extensions, WOLFSSL_KYBER_LEVEL1, - ssl->heap); +#ifdef WOLFSSL_KYBER1024 if (ret == WOLFSSL_SUCCESS) - ret = TLSX_UseSupportedCurve(extensions, WOLFSSL_P256_KYBER_LEVEL1, + ret = TLSX_UseSupportedCurve(extensions, WOLFSSL_KYBER_LEVEL5, ssl->heap); - #if defined(HAVE_CURVE25519) && ECC_MIN_KEY_SZ <= 256 if (ret == WOLFSSL_SUCCESS) - ret = TLSX_UseSupportedCurve(extensions, WOLFSSL_X25519_KYBER_LEVEL1, + ret = TLSX_UseSupportedCurve(extensions, WOLFSSL_P521_KYBER_LEVEL5, ssl->heap); - #endif #endif #ifdef WOLFSSL_KYBER768 if (ret == WOLFSSL_SUCCESS) @@ -14633,49 +14643,20 @@ static int TLSX_PopulateSupportedGroups(WOLFSSL* ssl, TLSX** extensions) ssl->heap); #endif #endif -#ifdef WOLFSSL_KYBER1024 - if (ret == WOLFSSL_SUCCESS) - ret = TLSX_UseSupportedCurve(extensions, WOLFSSL_KYBER_LEVEL5, - ssl->heap); - if (ret == WOLFSSL_SUCCESS) - ret = TLSX_UseSupportedCurve(extensions, WOLFSSL_P521_KYBER_LEVEL5, - ssl->heap); -#endif -#elif defined(HAVE_LIBOQS) - ret = TLSX_UseSupportedCurve(extensions, WOLFSSL_KYBER_LEVEL1, ssl->heap); - if (ret == WOLFSSL_SUCCESS) - ret = TLSX_UseSupportedCurve(extensions, WOLFSSL_KYBER_LEVEL3, - ssl->heap); +#ifdef WOLFSSL_KYBER512 if (ret == WOLFSSL_SUCCESS) - ret = TLSX_UseSupportedCurve(extensions, WOLFSSL_KYBER_LEVEL5, + ret = TLSX_UseSupportedCurve(extensions, WOLFSSL_KYBER_LEVEL1, ssl->heap); if (ret == WOLFSSL_SUCCESS) ret = TLSX_UseSupportedCurve(extensions, WOLFSSL_P256_KYBER_LEVEL1, ssl->heap); - if (ret == WOLFSSL_SUCCESS) - ret = TLSX_UseSupportedCurve(extensions, WOLFSSL_P384_KYBER_LEVEL3, - ssl->heap); - if (ret == WOLFSSL_SUCCESS) - ret = TLSX_UseSupportedCurve(extensions, WOLFSSL_P256_KYBER_LEVEL3, - ssl->heap); - if (ret == WOLFSSL_SUCCESS) - ret = TLSX_UseSupportedCurve(extensions, WOLFSSL_P521_KYBER_LEVEL5, - ssl->heap); #if defined(HAVE_CURVE25519) && ECC_MIN_KEY_SZ <= 256 if (ret == WOLFSSL_SUCCESS) ret = TLSX_UseSupportedCurve(extensions, WOLFSSL_X25519_KYBER_LEVEL1, ssl->heap); - if (ret == WOLFSSL_SUCCESS) - ret = TLSX_UseSupportedCurve(extensions, WOLFSSL_X25519_KYBER_LEVEL3, - ssl->heap); #endif - #if defined(HAVE_CURVE448) && ECC_MIN_KEY_SZ <= 448 - if (ret == WOLFSSL_SUCCESS) - ret = TLSX_UseSupportedCurve(extensions, WOLFSSL_X448_KYBER_LEVEL3, - ssl->heap); - #endif -#endif /* HAVE_LIBOQS */ -#endif /* WOLFSSL_MLKEM_KYBER */ +#endif +#endif /* WOLFSSL_HAVE_MLKEM */ #endif /* WOLFSSL_HAVE_MLKEM */ (void)ssl; diff --git a/src/tls13.c b/src/tls13.c index 5b0f098507c..0f4b93cfe92 100644 --- a/src/tls13.c +++ b/src/tls13.c @@ -13848,6 +13848,12 @@ int wolfSSL_UseKeyShare(WOLFSSL* ssl, word16 group) (void)ret; (void)group; #else + /* Check if the group is supported. */ + if (!TLSX_IsGroupSupported(group)) { + WOLFSSL_MSG("Group not supported."); + return BAD_FUNC_ARG; + } + ret = TLSX_KeyShare_Use(ssl, group, 0, NULL, NULL, &ssl->extensions); if (ret != 0) return ret; diff --git a/tests/api/test_tls13.c b/tests/api/test_tls13.c index a70ea09a1cf..5501dc43f17 100644 --- a/tests/api/test_tls13.c +++ b/tests/api/test_tls13.c @@ -102,7 +102,7 @@ int test_tls13_apis(void) #else WOLFSSL_KYBER_LEVEL5 #endif -#else +#elif !defined(WOLFSSL_TLS_NO_MLKEM_STANDALONE) #ifndef WOLFSSL_NO_ML_KEM_512 WOLFSSL_ML_KEM_512 #elif !defined(WOLFSSL_NO_ML_KEM_768) @@ -110,6 +110,12 @@ int test_tls13_apis(void) #else WOLFSSL_ML_KEM_1024 #endif +#else + #ifndef WOLFSSL_NO_ML_KEM_768 + WOLFSSL_SECP256R1MLKEM768 + #else + WOLFSSL_ECC_SECP256R1 + #endif #endif #else WOLFSSL_ECC_SECP256R1 @@ -150,10 +156,10 @@ int test_tls13_apis(void) ":P256_KYBER_LEVEL5" #endif #else - #ifndef WOLFSSL_NO_KYBER512 + #if !defined(WOLFSSL_NO_ML_KEM_512) && defined(WOLFSSL_EXTRA_PQC_HYBRIDS) ":SecP256r1MLKEM512" - #elif !defined(WOLFSSL_NO_KYBER768) - ":SecP384r1MLKEM768" + #elif !defined(WOLFSSL_NO_ML_KEM_768) + ":SecP256r1MLKEM768" #else ":SecP521r1MLKEM1024" #endif @@ -173,7 +179,7 @@ int test_tls13_apis(void) #else ":KYBER_LEVEL5" #endif -#else +#elif !defined(WOLFSSL_TLS_NO_MLKEM_STANDALONE) #ifndef WOLFSSL_NO_KYBER512 ":ML_KEM_512" #elif !defined(WOLFSSL_NO_KYBER768) @@ -188,7 +194,11 @@ int test_tls13_apis(void) #if defined(WOLFSSL_HAVE_MLKEM) && !defined(WOLFSSL_MLKEM_NO_MALLOC) && \ !defined(WOLFSSL_MLKEM_NO_MAKE_KEY) && \ !defined(WOLFSSL_MLKEM_NO_ENCAPSULATE) && \ - !defined(WOLFSSL_MLKEM_NO_DECAPSULATE) + !defined(WOLFSSL_MLKEM_NO_DECAPSULATE) && \ + defined(HAVE_SUPPORTED_CURVES) && \ + (!defined(WOLFSSL_TLS_NO_MLKEM_STANDALONE) || \ + (defined(HAVE_CURVE25519) && !defined(WOLFSSL_NO_ML_KEM_768)) || \ + (defined(HAVE_ECC) && !defined(WOLFSSL_NO_ML_KEM_768))) int mlkemLevel; #endif @@ -351,8 +361,12 @@ int test_tls13_apis(void) #if defined(WOLFSSL_HAVE_MLKEM) && !defined(WOLFSSL_MLKEM_NO_MALLOC) && \ !defined(WOLFSSL_MLKEM_NO_MAKE_KEY) && \ !defined(WOLFSSL_MLKEM_NO_ENCAPSULATE) && \ - !defined(WOLFSSL_MLKEM_NO_DECAPSULATE) + !defined(WOLFSSL_MLKEM_NO_DECAPSULATE) && \ + (!defined(WOLFSSL_TLS_NO_MLKEM_STANDALONE) || \ + (defined(HAVE_CURVE25519) && !defined(WOLFSSL_NO_ML_KEM_768)) || \ + (defined(HAVE_ECC) && !defined(WOLFSSL_NO_ML_KEM_768))) #ifndef WOLFSSL_NO_ML_KEM +#ifndef WOLFSSL_TLS_NO_MLKEM_STANDALONE #ifndef WOLFSSL_NO_ML_KEM_768 mlkemLevel = WOLFSSL_ML_KEM_768; #elif !defined(WOLFSSL_NO_ML_KEM_1024) @@ -361,6 +375,13 @@ int test_tls13_apis(void) mlkemLevel = WOLFSSL_ML_KEM_512; #endif #else +#if defined(HAVE_CURVE25519) && !defined(WOLFSSL_NO_ML_KEM_768) + mlkemLevel = WOLFSSL_X25519MLKEM768; +#elif defined(HAVE_ECC) && !defined(WOLFSSL_NO_ML_KEM_768) + mlkemLevel = WOLFSSL_SECP256R1MLKEM768; +#endif +#endif +#else #ifndef WOLFSSL_NO_KYBER768 mlkemLevel = WOLFSSL_KYBER_LEVEL3; #elif !defined(WOLFSSL_NO_KYBER1024) @@ -1919,9 +1940,13 @@ int test_tls13_rpk_handshake(void) #if defined(HAVE_IO_TESTS_DEPENDENCIES) && defined(WOLFSSL_TLS13) && \ defined(WOLFSSL_HAVE_MLKEM) && !defined(WOLFSSL_MLKEM_NO_ENCAPSULATE) && \ !defined(WOLFSSL_MLKEM_NO_DECAPSULATE) && \ - !defined(WOLFSSL_MLKEM_NO_MAKE_KEY) + !defined(WOLFSSL_MLKEM_NO_MAKE_KEY) && \ + (!defined(WOLFSSL_TLS_NO_MLKEM_STANDALONE) || \ + (defined(HAVE_CURVE25519) && !defined(WOLFSSL_NO_ML_KEM_768)) || \ + (defined(HAVE_ECC) && !defined(WOLFSSL_NO_ML_KEM_768))) static void test_tls13_pq_groups_ctx_ready(WOLFSSL_CTX* ctx) { +#ifndef WOLFSSL_TLS_NO_MLKEM_STANDALONE #ifndef WOLFSSL_NO_ML_KEM_1024 #ifdef WOLFSSL_MLKEM_KYBER int group = WOLFSSL_KYBER_LEVEL5; @@ -1940,6 +1965,11 @@ static void test_tls13_pq_groups_ctx_ready(WOLFSSL_CTX* ctx) #else int group = WOLFSSL_ML_KEM_512; #endif /* WOLFSSL_MLKEM_KYBER */ +#endif +#elif defined(HAVE_ECC) && !defined(WOLFSSL_NO_ML_KEM_768) + int group = WOLFSSL_SECP256R1MLKEM768; +#elif defined(HAVE_CURVE25519) && !defined(WOLFSSL_NO_ML_KEM_768) + int group = WOLFSSL_X25519MLKEM768; #endif AssertIntEQ(wolfSSL_CTX_set_groups(ctx, &group, 1), WOLFSSL_SUCCESS); @@ -1947,6 +1977,7 @@ static void test_tls13_pq_groups_ctx_ready(WOLFSSL_CTX* ctx) static void test_tls13_pq_groups_on_result(WOLFSSL* ssl) { +#ifndef WOLFSSL_TLS_NO_MLKEM_STANDALONE #ifndef WOLFSSL_NO_ML_KEM_1024 #ifdef WOLFSSL_MLKEM_KYBER AssertStrEQ(wolfSSL_get_curve_name(ssl), "KYBER_LEVEL5"); @@ -1966,6 +1997,11 @@ static void test_tls13_pq_groups_on_result(WOLFSSL* ssl) AssertStrEQ(wolfSSL_get_curve_name(ssl), "ML_KEM_512"); #endif /* WOLFSSL_MLKEM_KYBER */ #endif +#elif defined(HAVE_ECC) && !defined(WOLFSSL_NO_ML_KEM_768) + AssertStrEQ(wolfSSL_get_curve_name(ssl), "SecP256r1MLKEM768"); +#elif defined(HAVE_CURVE25519) && !defined(WOLFSSL_NO_ML_KEM_768) + AssertStrEQ(wolfSSL_get_curve_name(ssl), "X25519MLKEM768"); +#endif } #endif @@ -1975,7 +2011,10 @@ int test_tls13_pq_groups(void) #if defined(HAVE_IO_TESTS_DEPENDENCIES) && defined(WOLFSSL_TLS13) && \ defined(WOLFSSL_HAVE_MLKEM) && !defined(WOLFSSL_MLKEM_NO_ENCAPSULATE) && \ !defined(WOLFSSL_MLKEM_NO_DECAPSULATE) && \ - !defined(WOLFSSL_MLKEM_NO_MAKE_KEY) + !defined(WOLFSSL_MLKEM_NO_MAKE_KEY) && \ + (!defined(WOLFSSL_TLS_NO_MLKEM_STANDALONE) || \ + (defined(HAVE_CURVE25519) && !defined(WOLFSSL_NO_ML_KEM_768)) || \ + (defined(HAVE_ECC) && !defined(WOLFSSL_NO_ML_KEM_768))) callback_functions func_cb_client; callback_functions func_cb_server; diff --git a/tests/include.am b/tests/include.am index 7b4e6f17e78..fc1359d3d52 100644 --- a/tests/include.am +++ b/tests/include.am @@ -33,12 +33,14 @@ EXTRA_DIST += tests/unit.h \ tests/test-tls13-down.conf \ tests/test-tls13-ecc.conf \ tests/test-tls13-psk.conf \ - tests/test-tls13-pq.conf \ + tests/test-tls13-pq-standalone.conf \ tests/test-tls13-pq-hybrid.conf \ - tests/test-dtls13-pq.conf \ - tests/test-dtls13-pq-frag.conf \ - tests/test-dtls13-pq-hybrid.conf \ + tests/test-tls13-pq-hybrid-extra.conf \ + tests/test-dtls13-pq-standalone.conf \ + tests/test-dtls13-pq-standalone-frag.conf \ tests/test-dtls13-pq-hybrid-frag.conf \ + tests/test-dtls13-pq-hybrid-extra.conf \ + tests/test-dtls13-pq-hybrid-extra-frag.conf \ tests/test-psk.conf \ tests/test-psk-no-id.conf \ tests/test-psk-no-id-sha2.conf \ diff --git a/tests/suites.c b/tests/suites.c index 60a727ea021..9a7fa2fbee0 100644 --- a/tests/suites.c +++ b/tests/suites.c @@ -1024,8 +1024,9 @@ int SuiteTest(int argc, char** argv) } #endif #ifdef HAVE_PQC - /* add TLSv13 pq tests */ - XSTRLCPY(argv0[1], "tests/test-tls13-pq.conf", sizeof(argv0[1])); + #ifndef WOLFSSL_TLS_NO_MLKEM_STANDALONE + /* add TLSv13 pq standalone tests */ + XSTRLCPY(argv0[1], "tests/test-tls13-pq-standalone.conf", sizeof(argv0[1])); printf("starting TLSv13 post-quantum groups tests\n"); test_harness(&args); if (args.return_code != 0) { @@ -1033,6 +1034,7 @@ int SuiteTest(int argc, char** argv) args.return_code = EXIT_FAILURE; goto exit; } + #endif /* !WOLFSSL_TLS_NO_MLKEM_STANDALONE */ /* add TLSv13 pq hybrid tests */ XSTRLCPY(argv0[1], "tests/test-tls13-pq-hybrid.conf", sizeof(argv0[1])); printf("starting TLSv13 post-quantum groups tests\n"); @@ -1042,10 +1044,22 @@ int SuiteTest(int argc, char** argv) args.return_code = EXIT_FAILURE; goto exit; } + #ifdef WOLFSSL_EXTRA_PQC_HYBRIDS + /* add TLSv13 pq extra hybrid tests */ + XSTRLCPY(argv0[1], "tests/test-tls13-pq-hybrid-extra.conf", sizeof(argv0[1])); + printf("starting TLSv13 post-quantum groups tests\n"); + test_harness(&args); + if (args.return_code != 0) { + printf("error from script %d\n", args.return_code); + args.return_code = EXIT_FAILURE; + goto exit; + } + #endif #endif #if defined(HAVE_PQC) && defined(WOLFSSL_DTLS13) - /* add DTLSv13 pq tests */ - XSTRLCPY(argv0[1], "tests/test-dtls13-pq.conf", sizeof(argv0[1])); + #ifndef WOLFSSL_TLS_NO_MLKEM_STANDALONE + /* add DTLSv13 pq standalone tests */ + XSTRLCPY(argv0[1], "tests/test-dtls13-pq-standalone.conf", sizeof(argv0[1])); printf("starting DTLSv13 post-quantum groups tests\n"); test_harness(&args); if (args.return_code != 0) { @@ -1053,8 +1067,10 @@ int SuiteTest(int argc, char** argv) args.return_code = EXIT_FAILURE; goto exit; } - /* add DTLSv13 pq hybrid tests */ - XSTRLCPY(argv0[1], "tests/test-dtls13-pq-hybrid.conf", sizeof(argv0[1])); + #endif /* !WOLFSSL_TLS_NO_MLKEM_STANDALONE */ + #ifdef WOLFSSL_EXTRA_PQC_HYBRIDS + /* add DTLSv13 pq extra hybrid tests */ + XSTRLCPY(argv0[1], "tests/test-dtls13-pq-hybrid-extra.conf", sizeof(argv0[1])); printf("starting DTLSv13 post-quantum 2 groups tests\n"); test_harness(&args); if (args.return_code != 0) { @@ -1062,9 +1078,11 @@ int SuiteTest(int argc, char** argv) args.return_code = EXIT_FAILURE; goto exit; } + #endif #ifdef WOLFSSL_DTLS_CH_FRAG - /* add DTLSv13 pq frag tests */ - XSTRLCPY(argv0[1], "tests/test-dtls13-pq-frag.conf", sizeof(argv0[1])); + #ifndef WOLFSSL_TLS_NO_MLKEM_STANDALONE + /* add DTLSv13 pq standalone frag tests */ + XSTRLCPY(argv0[1], "tests/test-dtls13-pq-standalone-frag.conf", sizeof(argv0[1])); printf("starting DTLSv13 post-quantum groups tests with fragmentation\n"); test_harness(&args); if (args.return_code != 0) { @@ -1072,6 +1090,7 @@ int SuiteTest(int argc, char** argv) args.return_code = EXIT_FAILURE; goto exit; } + #endif /* !WOLFSSL_TLS_NO_MLKEM_STANDALONE */ /* add DTLSv13 pq hybrid frag tests */ XSTRLCPY(argv0[1], "tests/test-dtls13-pq-hybrid-frag.conf", sizeof(argv0[1])); printf("starting DTLSv13 post-quantum 2 groups tests with fragmentation\n"); @@ -1081,6 +1100,17 @@ int SuiteTest(int argc, char** argv) args.return_code = EXIT_FAILURE; goto exit; } + #ifdef WOLFSSL_EXTRA_PQC_HYBRIDS + /* add DTLSv13 pq extra hybrid frag tests */ + XSTRLCPY(argv0[1], "tests/test-dtls13-pq-hybrid-extra-frag.conf", sizeof(argv0[1])); + printf("starting DTLSv13 post-quantum 2 groups tests with fragmentation\n"); + test_harness(&args); + if (args.return_code != 0) { + printf("error from script %d\n", args.return_code); + args.return_code = EXIT_FAILURE; + goto exit; + } + #endif #endif #endif #endif diff --git a/tests/test-dtls13-pq-hybrid-extra-frag.conf b/tests/test-dtls13-pq-hybrid-extra-frag.conf new file mode 100644 index 00000000000..3048d53ded0 --- /dev/null +++ b/tests/test-dtls13-pq-hybrid-extra-frag.conf @@ -0,0 +1,95 @@ +# server DTLSv1.3 with post-quantum hybrid group +-u +-v 4 +-l TLS13-AES256-GCM-SHA384 +--pqc SecP384r1MLKEM768 + +# client DTLSv1.3 with post-quantum hybrid group +-u +-v 4 +-l TLS13-AES256-GCM-SHA384 +--pqc SecP384r1MLKEM768 + +# server DTLSv1.3 with post-quantum hybrid group +-u +-v 4 +-l TLS13-AES256-GCM-SHA384 +--pqc SecP521r1MLKEM1024 + +# client DTLSv1.3 with post-quantum hybrid group +-u +-v 4 +-l TLS13-AES256-GCM-SHA384 +--pqc SecP521r1MLKEM1024 + +# server DTLSv1.3 with post-quantum hybrid group +-u +-v 4 +-l TLS13-AES256-GCM-SHA384 +--pqc X448MLKEM768 + +# client DTLSv1.3 with post-quantum hybrid group +-u +-v 4 +-l TLS13-AES256-GCM-SHA384 +--pqc X448MLKEM768 + +# server DTLSv1.3 with post-quantum hybrid group +-u +-v 4 +-l TLS13-AES256-GCM-SHA384 +--pqc P384_KYBER_LEVEL3 + +# client DTLSv1.3 with post-quantum hybrid group +-u +-v 4 +-l TLS13-AES256-GCM-SHA384 +--pqc P384_KYBER_LEVEL3 + +# server DTLSv1.3 with post-quantum hybrid group +-u +-v 4 +-l TLS13-AES256-GCM-SHA384 +--pqc P256_KYBER_LEVEL3 + +# client DTLSv1.3 with post-quantum hybrid group +-u +-v 4 +-l TLS13-AES256-GCM-SHA384 +--pqc P256_KYBER_LEVEL3 + +# server DTLSv1.3 with post-quantum hybrid group +-u +-v 4 +-l TLS13-AES256-GCM-SHA384 +--pqc P521_KYBER_LEVEL5 + +# client DTLSv1.3 with post-quantum hybrid group +-u +-v 4 +-l TLS13-AES256-GCM-SHA384 +--pqc P521_KYBER_LEVEL5 + +# server DTLSv1.3 with post-quantum hybrid group +-u +-v 4 +-l TLS13-AES256-GCM-SHA384 +--pqc X25519_KYBER_LEVEL3 + +# client DTLSv1.3 with post-quantum hybrid group +-u +-v 4 +-l TLS13-AES256-GCM-SHA384 +--pqc X25519_KYBER_LEVEL3 + +# server DTLSv1.3 with post-quantum hybrid group +-u +-v 4 +-l TLS13-AES256-GCM-SHA384 +--pqc X448_KYBER_LEVEL3 + +# client DTLSv1.3 with post-quantum hybrid group +-u +-v 4 +-l TLS13-AES256-GCM-SHA384 +--pqc X448_KYBER_LEVEL3 diff --git a/tests/test-dtls13-pq-hybrid.conf b/tests/test-dtls13-pq-hybrid-extra.conf similarity index 100% rename from tests/test-dtls13-pq-hybrid.conf rename to tests/test-dtls13-pq-hybrid-extra.conf diff --git a/tests/test-dtls13-pq-hybrid-frag.conf b/tests/test-dtls13-pq-hybrid-frag.conf index 267468887ef..19aebb0e1a2 100644 --- a/tests/test-dtls13-pq-hybrid-frag.conf +++ b/tests/test-dtls13-pq-hybrid-frag.conf @@ -1,15 +1,3 @@ -# server DTLSv1.3 with post-quantum hybrid group --u --v 4 --l TLS13-AES256-GCM-SHA384 ---pqc SecP384r1MLKEM768 - -# client DTLSv1.3 with post-quantum hybrid group --u --v 4 --l TLS13-AES256-GCM-SHA384 ---pqc SecP384r1MLKEM768 - # server DTLSv1.3 with post-quantum hybrid group -u -v 4 @@ -22,18 +10,6 @@ -l TLS13-AES256-GCM-SHA384 --pqc SecP256r1MLKEM768 -# server DTLSv1.3 with post-quantum hybrid group --u --v 4 --l TLS13-AES256-GCM-SHA384 ---pqc SecP521r1MLKEM1024 - -# client DTLSv1.3 with post-quantum hybrid group --u --v 4 --l TLS13-AES256-GCM-SHA384 ---pqc SecP521r1MLKEM1024 - # server DTLSv1.3 with post-quantum hybrid group -u -v 4 @@ -57,75 +33,3 @@ -v 4 -l TLS13-AES256-GCM-SHA384 --pqc X25519MLKEM768 - -# server DTLSv1.3 with post-quantum hybrid group --u --v 4 --l TLS13-AES256-GCM-SHA384 ---pqc X448MLKEM768 - -# client DTLSv1.3 with post-quantum hybrid group --u --v 4 --l TLS13-AES256-GCM-SHA384 ---pqc X448MLKEM768 - -# server DTLSv1.3 with post-quantum hybrid group --u --v 4 --l TLS13-AES256-GCM-SHA384 ---pqc P384_KYBER_LEVEL3 - -# client DTLSv1.3 with post-quantum hybrid group --u --v 4 --l TLS13-AES256-GCM-SHA384 ---pqc P384_KYBER_LEVEL3 - -# server DTLSv1.3 with post-quantum hybrid group --u --v 4 --l TLS13-AES256-GCM-SHA384 ---pqc P256_KYBER_LEVEL3 - -# client DTLSv1.3 with post-quantum hybrid group --u --v 4 --l TLS13-AES256-GCM-SHA384 ---pqc P256_KYBER_LEVEL3 - -# server DTLSv1.3 with post-quantum hybrid group --u --v 4 --l TLS13-AES256-GCM-SHA384 ---pqc P521_KYBER_LEVEL5 - -# client DTLSv1.3 with post-quantum hybrid group --u --v 4 --l TLS13-AES256-GCM-SHA384 ---pqc P521_KYBER_LEVEL5 - -# server DTLSv1.3 with post-quantum hybrid group --u --v 4 --l TLS13-AES256-GCM-SHA384 ---pqc X25519_KYBER_LEVEL3 - -# client DTLSv1.3 with post-quantum hybrid group --u --v 4 --l TLS13-AES256-GCM-SHA384 ---pqc X25519_KYBER_LEVEL3 - -# server DTLSv1.3 with post-quantum hybrid group --u --v 4 --l TLS13-AES256-GCM-SHA384 ---pqc X448_KYBER_LEVEL3 - -# client DTLSv1.3 with post-quantum hybrid group --u --v 4 --l TLS13-AES256-GCM-SHA384 ---pqc X448_KYBER_LEVEL3 diff --git a/tests/test-dtls13-pq-frag.conf b/tests/test-dtls13-pq-standalone-frag.conf similarity index 100% rename from tests/test-dtls13-pq-frag.conf rename to tests/test-dtls13-pq-standalone-frag.conf diff --git a/tests/test-dtls13-pq.conf b/tests/test-dtls13-pq-standalone.conf similarity index 100% rename from tests/test-dtls13-pq.conf rename to tests/test-dtls13-pq-standalone.conf diff --git a/tests/test-tls13-pq-hybrid-extra.conf b/tests/test-tls13-pq-hybrid-extra.conf new file mode 100644 index 00000000000..2d0e601ce91 --- /dev/null +++ b/tests/test-tls13-pq-hybrid-extra.conf @@ -0,0 +1,119 @@ +# server TLSv1.3 with post-quantum hybrid group +-v 4 +-l TLS13-AES256-GCM-SHA384 +--pqc SecP256r1MLKEM512 + +# client TLSv1.3 with post-quantum hybrid group +-v 4 +-l TLS13-AES256-GCM-SHA384 +--pqc SecP256r1MLKEM512 + +# server TLSv1.3 with post-quantum hybrid group +-v 4 +-l TLS13-AES256-GCM-SHA384 +--pqc SecP384r1MLKEM768 + +# client TLSv1.3 with post-quantum hybrid group +-v 4 +-l TLS13-AES256-GCM-SHA384 +--pqc SecP384r1MLKEM768 + +# server TLSv1.3 with post-quantum hybrid group +-v 4 +-l TLS13-AES256-GCM-SHA384 +--pqc SecP521r1MLKEM1024 + +# client TLSv1.3 with post-quantum hybrid group +-v 4 +-l TLS13-AES256-GCM-SHA384 +--pqc SecP521r1MLKEM1024 + +# server TLSv1.3 with post-quantum hybrid group +-v 4 +-l TLS13-AES256-GCM-SHA384 +--pqc X25519MLKEM512 + +# client TLSv1.3 with post-quantum hybrid group +-v 4 +-l TLS13-AES256-GCM-SHA384 +--pqc X25519MLKEM512 + +# server TLSv1.3 with post-quantum hybrid group +-v 4 +-l TLS13-AES256-GCM-SHA384 +--pqc X448MLKEM768 + +# client TLSv1.3 with post-quantum hybrid group +-v 4 +-l TLS13-AES256-GCM-SHA384 +--pqc X448MLKEM768 + +# server TLSv1.3 with post-quantum hybrid group +-v 4 +-l TLS13-AES256-GCM-SHA384 +--pqc P256_KYBER_LEVEL1 + +# client TLSv1.3 with post-quantum hybrid group +-v 4 +-l TLS13-AES256-GCM-SHA384 +--pqc P256_KYBER_LEVEL1 + +# server TLSv1.3 with post-quantum hybrid group +-v 4 +-l TLS13-AES256-GCM-SHA384 +--pqc P384_KYBER_LEVEL3 + +# client TLSv1.3 with post-quantum hybrid group +-v 4 +-l TLS13-AES256-GCM-SHA384 +--pqc P384_KYBER_LEVEL3 + +# server TLSv1.3 with post-quantum hybrid group +-v 4 +-l TLS13-AES256-GCM-SHA384 +--pqc P256_KYBER_LEVEL3 + +# client TLSv1.3 with post-quantum hybrid group +-v 4 +-l TLS13-AES256-GCM-SHA384 +--pqc P256_KYBER_LEVEL3 + +# server TLSv1.3 with post-quantum hybrid group +-v 4 +-l TLS13-AES256-GCM-SHA384 +--pqc P521_KYBER_LEVEL5 + +# client TLSv1.3 with post-quantum hybrid group +-v 4 +-l TLS13-AES256-GCM-SHA384 +--pqc P521_KYBER_LEVEL5 + +# server TLSv1.3 with post-quantum hybrid group +-v 4 +-l TLS13-AES256-GCM-SHA384 +--pqc X25519_KYBER_LEVEL1 + +# client TLSv1.3 with post-quantum hybrid group +-v 4 +-l TLS13-AES256-GCM-SHA384 +--pqc X25519_KYBER_LEVEL1 + +# server TLSv1.3 with post-quantum hybrid group +-v 4 +-l TLS13-AES256-GCM-SHA384 +--pqc X25519_KYBER_LEVEL3 + +# client TLSv1.3 with post-quantum hybrid group +-v 4 +-l TLS13-AES256-GCM-SHA384 +--pqc X25519_KYBER_LEVEL3 + +# server TLSv1.3 with post-quantum hybrid group +-v 4 +-l TLS13-AES256-GCM-SHA384 +--pqc X448_KYBER_LEVEL3 + +# client TLSv1.3 with post-quantum hybrid group +-v 4 +-l TLS13-AES256-GCM-SHA384 +--pqc X448_KYBER_LEVEL3 diff --git a/tests/test-tls13-pq-hybrid.conf b/tests/test-tls13-pq-hybrid.conf index 76c8e57696f..0c4f4303a8f 100644 --- a/tests/test-tls13-pq-hybrid.conf +++ b/tests/test-tls13-pq-hybrid.conf @@ -1,23 +1,3 @@ -# server TLSv1.3 with post-quantum hybrid group --v 4 --l TLS13-AES256-GCM-SHA384 ---pqc SecP256r1MLKEM512 - -# client TLSv1.3 with post-quantum hybrid group --v 4 --l TLS13-AES256-GCM-SHA384 ---pqc SecP256r1MLKEM512 - -# server TLSv1.3 with post-quantum hybrid group --v 4 --l TLS13-AES256-GCM-SHA384 ---pqc SecP384r1MLKEM768 - -# client TLSv1.3 with post-quantum hybrid group --v 4 --l TLS13-AES256-GCM-SHA384 ---pqc SecP384r1MLKEM768 - # server TLSv1.3 with post-quantum hybrid group -v 4 -l TLS13-AES256-GCM-SHA384 @@ -28,16 +8,6 @@ -l TLS13-AES256-GCM-SHA384 --pqc SecP256r1MLKEM768 -# server TLSv1.3 with post-quantum hybrid group --v 4 --l TLS13-AES256-GCM-SHA384 ---pqc SecP521r1MLKEM1024 - -# client TLSv1.3 with post-quantum hybrid group --v 4 --l TLS13-AES256-GCM-SHA384 ---pqc SecP521r1MLKEM1024 - # server TLSv1.3 with post-quantum hybrid group -v 4 -l TLS13-AES256-GCM-SHA384 @@ -48,16 +18,6 @@ -l TLS13-AES256-GCM-SHA384 --pqc SecP384r1MLKEM1024 -# server TLSv1.3 with post-quantum hybrid group --v 4 --l TLS13-AES256-GCM-SHA384 ---pqc X25519MLKEM512 - -# client TLSv1.3 with post-quantum hybrid group --v 4 --l TLS13-AES256-GCM-SHA384 ---pqc X25519MLKEM512 - # server TLSv1.3 with post-quantum hybrid group -v 4 -l TLS13-AES256-GCM-SHA384 @@ -67,83 +27,3 @@ -v 4 -l TLS13-AES256-GCM-SHA384 --pqc X25519MLKEM768 - -# server TLSv1.3 with post-quantum hybrid group --v 4 --l TLS13-AES256-GCM-SHA384 ---pqc X448MLKEM768 - -# client TLSv1.3 with post-quantum hybrid group --v 4 --l TLS13-AES256-GCM-SHA384 ---pqc X448MLKEM768 - -# server TLSv1.3 with post-quantum hybrid group --v 4 --l TLS13-AES256-GCM-SHA384 ---pqc P256_KYBER_LEVEL1 - -# client TLSv1.3 with post-quantum hybrid group --v 4 --l TLS13-AES256-GCM-SHA384 ---pqc P256_KYBER_LEVEL1 - -# server TLSv1.3 with post-quantum hybrid group --v 4 --l TLS13-AES256-GCM-SHA384 ---pqc P384_KYBER_LEVEL3 - -# client TLSv1.3 with post-quantum hybrid group --v 4 --l TLS13-AES256-GCM-SHA384 ---pqc P384_KYBER_LEVEL3 - -# server TLSv1.3 with post-quantum hybrid group --v 4 --l TLS13-AES256-GCM-SHA384 ---pqc P256_KYBER_LEVEL3 - -# client TLSv1.3 with post-quantum hybrid group --v 4 --l TLS13-AES256-GCM-SHA384 ---pqc P256_KYBER_LEVEL3 - -# server TLSv1.3 with post-quantum hybrid group --v 4 --l TLS13-AES256-GCM-SHA384 ---pqc P521_KYBER_LEVEL5 - -# client TLSv1.3 with post-quantum hybrid group --v 4 --l TLS13-AES256-GCM-SHA384 ---pqc P521_KYBER_LEVEL5 - -# server TLSv1.3 with post-quantum hybrid group --v 4 --l TLS13-AES256-GCM-SHA384 ---pqc X25519_KYBER_LEVEL1 - -# client TLSv1.3 with post-quantum hybrid group --v 4 --l TLS13-AES256-GCM-SHA384 ---pqc X25519_KYBER_LEVEL1 - -# server TLSv1.3 with post-quantum hybrid group --v 4 --l TLS13-AES256-GCM-SHA384 ---pqc X25519_KYBER_LEVEL3 - -# client TLSv1.3 with post-quantum hybrid group --v 4 --l TLS13-AES256-GCM-SHA384 ---pqc X25519_KYBER_LEVEL3 - -# server TLSv1.3 with post-quantum hybrid group --v 4 --l TLS13-AES256-GCM-SHA384 ---pqc X448_KYBER_LEVEL3 - -# client TLSv1.3 with post-quantum hybrid group --v 4 --l TLS13-AES256-GCM-SHA384 ---pqc X448_KYBER_LEVEL3 diff --git a/tests/test-tls13-pq.conf b/tests/test-tls13-pq-standalone.conf similarity index 100% rename from tests/test-tls13-pq.conf rename to tests/test-tls13-pq-standalone.conf diff --git a/wolfssl/internal.h b/wolfssl/internal.h index 59fb268aefd..2afa4aaeb69 100644 --- a/wolfssl/internal.h +++ b/wolfssl/internal.h @@ -3398,6 +3398,7 @@ WOLFSSL_LOCAL int TLSX_UseSupportedCurve(TLSX** extensions, word16 name, WOLFSSL_LOCAL int TLSX_UsePointFormat(TLSX** extensions, byte point, void* heap); +WOLFSSL_LOCAL int TLSX_IsGroupSupported(int namedGroup); #ifndef NO_WOLFSSL_SERVER WOLFSSL_LOCAL int TLSX_ValidateSupportedCurves(const WOLFSSL* ssl, byte first, diff --git a/wolfssl/ssl.h b/wolfssl/ssl.h index 08989907c32..a4a25fdd991 100644 --- a/wolfssl/ssl.h +++ b/wolfssl/ssl.h @@ -4682,21 +4682,21 @@ enum { WOLFSSL_P256_KYBER_LEVEL3 = 25498, #endif /* WOLFSSL_MLKEM_KYBER */ #ifndef WOLFSSL_NO_ML_KEM - /* Taken from draft-connolly-tls-mlkem-key-agreement, see: - * https://github.com/dconnolly/draft-connolly-tls-mlkem-key-agreement/ + /* Taken from draft-ietf-tls-mlkem, see: + * https://datatracker.ietf.org/doc/draft-ietf-tls-mlkem/05/ */ WOLFSSL_ML_KEM_512 = 512, WOLFSSL_ML_KEM_768 = 513, WOLFSSL_ML_KEM_1024 = 514, - /* Taken from draft-kwiatkowski-tls-ecdhe-mlkem. see: - * https://github.com/post-quantum-cryptography/ - * draft-kwiatkowski-tls-ecdhe-mlkem/ + /* Taken from draft-ietf-tls-ecdhe-mlkem. see: + * https://datatracker.ietf.org/doc/draft-ietf-tls-ecdhe-mlkem/03/ */ WOLFSSL_SECP256R1MLKEM768 = 4587, WOLFSSL_X25519MLKEM768 = 4588, WOLFSSL_SECP384R1MLKEM1024 = 4589, +#ifdef WOLFSSL_EXTRA_PQC_HYBRIDS /* Taken from OQS's openssl provider, see: * https://github.com/open-quantum-safe/oqs-provider/blob/main/oqs-template/ * oqs-kem-info.md @@ -4711,6 +4711,7 @@ enum { WOLFSSL_SECP521R1MLKEM1024 = 12109, WOLFSSL_X25519MLKEM512 = 12214, WOLFSSL_X448MLKEM768 = 12215, +#endif /* WOLFSSL_EXTRA_PQC_HYBRIDS */ #endif /* WOLFSSL_NO_ML_KEM */ #endif /* HAVE_PQC */ WOLF_ENUM_DUMMY_LAST_ELEMENT(SSL_H)