diff --git a/.github/workflows/async.yml b/.github/workflows/async.yml
index 8a572c328f5..74c073fe1c3 100644
--- a/.github/workflows/async.yml
+++ b/.github/workflows/async.yml
@@ -18,6 +18,10 @@ jobs:
matrix:
config: [
# Add new configs here
+ '--enable-asynccrypt --enable-all --enable-dtls13 --disable-mlkem CFLAGS="-pedantic -Wdeclaration-after-statement -DTEST_LIBWOLFSSL_SOURCES_INCLUSION_SEQUENCE -DWOLFCRYPT_TEST_LINT"',
+ '--enable-asynccrypt-sw --enable-ocspstapling --enable-ocspstapling2 --disable-mlkem CFLAGS="-pedantic -Wdeclaration-after-statement -DTEST_LIBWOLFSSL_SOURCES_INCLUSION_SEQUENCE"',
+ '--enable-asynccrypt --enable-all --enable-dtls13 --disable-pqc-hybrids --enable-tls-mlkem-standalone CFLAGS="-pedantic -Wdeclaration-after-statement -DTEST_LIBWOLFSSL_SOURCES_INCLUSION_SEQUENCE -DWOLFCRYPT_TEST_LINT"',
+ '--enable-asynccrypt-sw --enable-ocspstapling --enable-ocspstapling2 --disable-pqc-hybrids --enable-tls-mlkem-standalone CFLAGS="-pedantic -Wdeclaration-after-statement -DTEST_LIBWOLFSSL_SOURCES_INCLUSION_SEQUENCE"',
'--enable-asynccrypt --enable-all --enable-dtls13 CFLAGS="-pedantic -Wdeclaration-after-statement -DTEST_LIBWOLFSSL_SOURCES_INCLUSION_SEQUENCE -DWOLFCRYPT_TEST_LINT"',
'--enable-asynccrypt-sw --enable-ocspstapling --enable-ocspstapling2 CFLAGS="-pedantic -Wdeclaration-after-statement -DTEST_LIBWOLFSSL_SOURCES_INCLUSION_SEQUENCE"',
'--enable-ocsp CFLAGS="-DTEST_NONBLOCK_CERTS -pedantic -Wdeclaration-after-statement -DTEST_LIBWOLFSSL_SOURCES_INCLUSION_SEQUENCE"',
diff --git a/.github/workflows/cmake.yml b/.github/workflows/cmake.yml
index 9639a7a6e91..55b50b53872 100644
--- a/.github/workflows/cmake.yml
+++ b/.github/workflows/cmake.yml
@@ -69,9 +69,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 \
+ -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 \
-DWOLFSSL_WC_RSA_DIRECT:BOOL=yes -DWOLFSSL_PUBLIC_MP:BOOL=yes \
..
cmake --build .
diff --git a/.github/workflows/os-check.yml b/.github/workflows/os-check.yml
index 763716b027a..ce241896e1b 100644
--- a/.github/workflows/os-check.yml
+++ b/.github/workflows/os-check.yml
@@ -38,6 +38,12 @@ jobs:
'--enable-experimental --enable-kyber --enable-dtls --enable-dtls13
--enable-dtls-frag-ch',
'--enable-all --enable-dtls13 --enable-dtls-frag-ch',
+ '--enable-all --enable-dtls13 --enable-dtls-frag-ch --disable-mlkem',
+ '--enable-all --enable-dtls13 --enable-dtls-frag-ch
+ --enable-tls-mlkem-standalone',
+ '--enable-all --enable-dtls13 --enable-dtls-frag-ch
+ --enable-tls-mlkem-standalone --enable-experimental
+ --enable-extra-pqc-hybrids',
'--enable-dtls --enable-dtls13 --enable-dtls-frag-ch
--enable-dtls-mtu',
'--enable-dtls --enable-dtlscid --enable-dtls13 --enable-secure-renegotiation
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/.github/workflows/wolfCrypt-Wconversion.yml b/.github/workflows/wolfCrypt-Wconversion.yml
index b1a7305e4e3..c96c4407741 100644
--- a/.github/workflows/wolfCrypt-Wconversion.yml
+++ b/.github/workflows/wolfCrypt-Wconversion.yml
@@ -23,7 +23,10 @@ jobs:
'--enable-smallstack --disable-asm --enable-cryptonly --enable-all-crypto --disable-examples --disable-benchmark --disable-crypttests CPPFLAGS="-Wconversion -Warith-conversion -Wenum-conversion -Wfloat-conversion -Wsign-conversion"',
'--enable-smallstack --enable-intelasm --enable-cryptonly --enable-all-crypto --disable-examples --disable-benchmark --disable-crypttests CPPFLAGS="-Wconversion -Warith-conversion -Wenum-conversion -Wfloat-conversion -Wsign-conversion"',
'--enable-cryptonly --enable-all-crypto --disable-examples --disable-benchmark --disable-crypttests CPPFLAGS="-Wconversion -Warith-conversion -Wenum-conversion -Wfloat-conversion -Wsign-conversion -DNO_INT128"',
- '--enable-cryptonly --enable-all-crypto --disable-examples --disable-benchmark --disable-crypttests CPPFLAGS="-Wdeclaration-after-statement -Wconversion -Warith-conversion -Wenum-conversion -Wfloat-conversion -Wsign-conversion" --enable-32bit CFLAGS=-m32'
+ '--enable-cryptonly --enable-all-crypto --disable-examples --disable-benchmark --disable-crypttests CPPFLAGS="-Wdeclaration-after-statement -Wconversion -Warith-conversion -Wenum-conversion -Wfloat-conversion -Wsign-conversion" --enable-32bit CFLAGS=-m32',
+ '--enable-cryptonly --enable-all-crypto --disable-examples --disable-benchmark --disable-crypttests --enable-mlkem=yes,small CPPFLAGS="-Wconversion -Warith-conversion -Wenum-conversion -Wfloat-conversion -Wsign-conversion -DNO_INT128"',
+ '--enable-cryptonly --enable-all-crypto --disable-examples --disable-benchmark --disable-crypttests --enable-mlkem=yes,no-large-code CPPFLAGS="-Wconversion -Warith-conversion -Wenum-conversion -Wfloat-conversion -Wsign-conversion -DNO_INT128"',
+ '--enable-smallstack --enable-cryptonly --enable-all-crypto --disable-examples --disable-benchmark --disable-crypttests --enable-mlkem=yes CPPFLAGS="-Wconversion -Warith-conversion -Wenum-conversion -Wfloat-conversion -Wsign-conversion -DNO_INT128"',
]
name: build library
if: github.repository_owner == 'wolfssl'
diff --git a/.github/workflows/zephyr.yml b/.github/workflows/zephyr.yml
index df1b2e1cddb..922dce92c67 100644
--- a/.github/workflows/zephyr.yml
+++ b/.github/workflows/zephyr.yml
@@ -28,7 +28,7 @@ jobs:
if: github.repository_owner == 'wolfssl'
runs-on: ubuntu-22.04
# This should be a safe limit for the tests to run.
- timeout-minutes: 25
+ timeout-minutes: 45
steps:
- name: Install dependencies
run: |
diff --git a/.wolfssl_known_macro_extras b/.wolfssl_known_macro_extras
index ed414491ca2..dc55899172e 100644
--- a/.wolfssl_known_macro_extras
+++ b/.wolfssl_known_macro_extras
@@ -171,6 +171,7 @@ CONFIG_WOLFSSL_EXAMPLE_NAME_WOLFSSH_ECHOSERVER
CONFIG_WOLFSSL_EXAMPLE_NAME_WOLFSSH_TEMPLATE
CONFIG_WOLFSSL_HKDF
CONFIG_WOLFSSL_MAX_FRAGMENT_LEN
+CONFIG_WOLFSSL_MLKEM
CONFIG_WOLFSSL_NO_ASN_STRICT
CONFIG_WOLFSSL_PSK
CONFIG_WOLFSSL_RSA_PSS
diff --git a/CMakeLists.txt b/CMakeLists.txt
index c915843737e..5af47f228d4 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -610,13 +610,67 @@ 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()
+
+# PQ/T hybrid combinations
+add_option(WOLFSSL_PQC_HYBRIDS
+ "Enable PQ/T hybrid combinations (default: enabled)"
+ "yes" "yes;no")
+
+if (WOLFSSL_PQC_HYBRIDS)
+ list(APPEND WOLFSSL_DEFINITIONS "-DWOLFSSL_PQC_HYBRIDS")
+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)"
@@ -626,11 +680,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")
@@ -666,75 +740,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...
@@ -759,12 +772,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/IDE/WIN10/wolfssl-fips.vcxproj b/IDE/WIN10/wolfssl-fips.vcxproj
index 42d574220fd..eac076eb3ae 100644
--- a/IDE/WIN10/wolfssl-fips.vcxproj
+++ b/IDE/WIN10/wolfssl-fips.vcxproj
@@ -292,6 +292,8 @@
+
+
diff --git a/cmake/options.h.in b/cmake/options.h.in
index 62e5ed57bc2..05bbb9fcc80 100644
--- a/cmake/options.h.in
+++ b/cmake/options.h.in
@@ -380,6 +380,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
@@ -408,6 +410,10 @@ extern "C" {
#cmakedefine WOLFSSL_WC_XMSS
#undef WC_RSA_DIRECT
#cmakedefine WC_RSA_DIRECT
+#undef WOLFSSL_PQC_HYBRIDS
+#cmakedefine WOLFSSL_PQC_HYBRIDS
+#undef WOLFSSL_EXTRA_PQC_HYBRIDS
+#cmakedefine WOLFSSL_EXTRA_PQC_HYBRIDS
#ifdef __cplusplus
}
diff --git a/configure.ac b/configure.ac
index f1e4a010cee..c3beac8a5f4 100644
--- a/configure.ac
+++ b/configure.ac
@@ -1639,16 +1639,23 @@ AC_ARG_WITH([liboqs],
# Used:
# - SHA3, Shake128 and Shake256
AC_ARG_ENABLE([mlkem],
- [AS_HELP_STRING([--enable-mlkem],[Enable MLKEM (default: disabled)])],
+ [AS_HELP_STRING([--enable-mlkem],[Enable MLKEM (default: enabled)])],
[ ENABLED_MLKEM=$enableval ],
- [ ENABLED_MLKEM=no ]
+ [ ENABLED_MLKEM=yes ]
)
# note, inherits default from "mlkem" clause above.
AC_ARG_ENABLE([kyber],
- [AS_HELP_STRING([--enable-kyber],[Enable Kyber/MLKEM (default: disabled)])],
+ [AS_HELP_STRING([--enable-kyber],[Enable Kyber/MLKEM (default: enabled)])],
[ ENABLED_MLKEM=$enableval ]
)
+# FIPS traditionally does not support SHAKE 128 and SHAKE 256 (v6 does), so disable
+# ML-KEM if FIPS is enabled and version is less than 6
+AS_IF([test "x$ENABLED_FIPS" = "xyes" && test $HAVE_FIPS_VERSION -lt 6],[
+ AC_MSG_NOTICE([Disabling MLKEM because FIPS < 6 does not support required SHAKE])
+ ENABLED_MLKEM="no"
+])
+
ENABLED_WC_MLKEM=no
ENABLED_ML_KEM=unset
ENABLED_MLKEM_MAKE_KEY=no
@@ -1677,6 +1684,9 @@ do
small)
AM_CFLAGS="$AM_CFLAGS -DWOLFSSL_MLKEM_SMALL"
;;
+ no-large-code)
+ AM_CFLAGS="$AM_CFLAGS -DWOLFSSL_MLKEM_NO_LARGE_CODE"
+ ;;
cache-a)
AM_CFLAGS="$AM_CFLAGS -DWOLFSSL_MLKEM_CACHE_A"
;;
@@ -1772,8 +1782,55 @@ 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 ]
+ )
+
+AS_IF([ test "$ENABLED_MLKEM_STANDALONE" = "yes" && test "$ENABLED_MLKEM" = "no" ],[AC_MSG_ERROR([ML-KEM as standalone TLS key exchange (non-hybrid) requires ML-KEM.])])
+if test "$ENABLED_MLKEM_STANDALONE" != "yes"
+then
+ AM_CFLAGS="$AM_CFLAGS -DWOLFSSL_TLS_NO_MLKEM_STANDALONE"
+fi
+
+AC_ARG_ENABLE([pqc-hybrids],
+ [AS_HELP_STRING([--enable-pqc-hybrids],[Enable PQ/T hybrid combinations (default: enabled)])],
+ [ ENABLED_PQC_HYBRIDS=$enableval ],
+ [ ENABLED_PQC_HYBRIDS=yes ]
+ )
+
+if test "$ENABLED_PQC_HYBRIDS" = "yes"
+then
+ if test "$ENABLED_MLKEM" = "no"
+ then
+ ENABLED_PQC_HYBRIDS=no
+ else
+ AM_CFLAGS="$AM_CFLAGS -DWOLFSSL_PQC_HYBRIDS"
+ fi
+fi
+
+if test "$ENABLED_MLKEM" = "yes" && test "$ENABLED_TLS13" = "yes" && test "$ENABLED_PQC_HYBRIDS" = "no" && test "$ENABLED_MLKEM_STANDALONE" = "no"
+then
+ AC_MSG_ERROR([Both hybrid PQ/T and standalone ML-KEM are disabled, so no PQC hybrid combinations will be available.])
+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.]) ])
+ AS_IF([ test "$ENABLED_MLKEM" = "no" ],[ AC_MSG_ERROR([extra-pqc-hybrids requires ML-KEM.]) ])
+ 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 ],
@@ -4445,6 +4502,17 @@ then
AM_CFLAGS="$AM_CFLAGS -DWC_SHA3_NO_ASM"
fi
+# MLKEM requires SHA-3. Force-enable SHA-3 when MLKEM is enabled.
+if test "$ENABLED_MLKEM" != "no"
+then
+ if test "$ENABLED_SHA3" = "no"
+ then
+ AC_MSG_NOTICE([MLKEM enabled (not explicitly disabled); overriding --disable-sha3 to enable SHA-3])
+ ENABLED_SHA3=yes
+ enable_sha3=yes
+ fi
+fi
+
# SHAKE128
AC_ARG_ENABLE([shake128],
[AS_HELP_STRING([--enable-shake128],[Enable wolfSSL SHAKE128 support (default: disabled)])],
@@ -4452,6 +4520,17 @@ AC_ARG_ENABLE([shake128],
[ ENABLED_SHAKE128=no ]
)
+# MLKEM requires SHAKE128. Force-enable when MLKEM is enabled.
+if test "$ENABLED_MLKEM" != "no"
+then
+ if test "$ENABLED_SHAKE128" = "no"
+ then
+ AC_MSG_WARN([MLKEM enabled (not explicitly disabled); overriding --disable-shake128 to enable SHAKE128])
+ ENABLED_SHAKE128=yes
+ enable_shake128=yes
+ fi
+fi
+
# SHAKE256
AC_ARG_ENABLE([shake256],
[AS_HELP_STRING([--enable-shake256],[Enable wolfSSL SHAKE256 support (default: disabled)])],
@@ -4459,6 +4538,17 @@ AC_ARG_ENABLE([shake256],
[ ENABLED_SHAKE256=no ]
)
+# MLKEM requires SHAKE256. Force-enable when MLKEM is enabled.
+if test "$ENABLED_MLKEM" != "no"
+then
+ if test "$ENABLED_SHAKE256" = "no"
+ then
+ AC_MSG_WARN([MLKEM enabled (not explicitly disabled); overriding --disable-shake256 to enable SHAKE256])
+ ENABLED_SHAKE256=yes
+ enable_shake256=yes
+ fi
+fi
+
# SHA512
AC_ARG_ENABLE([sha512],
[AS_HELP_STRING([--enable-sha512],[Enable wolfSSL SHA-512 support (default: enabled)])],
@@ -5632,6 +5722,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)])],
@@ -11844,6 +11943,9 @@ echo " * ERR Queues per Thread: $ENABLED_ERRORQUEUEPERTHREAD"
echo " * rwlock: $ENABLED_RWLOCK"
echo " * keylog export: $ENABLED_KEYLOG_EXPORT"
echo " * AutoSAR : $ENABLED_AUTOSAR"
+echo " * ML-KEM standalone: $ENABLED_MLKEM_STANDALONE"
+echo " * PQ/T hybrids: $ENABLED_PQC_HYBRIDS"
+echo " * Extra PQ/T hybrids: $ENABLED_EXTRA_PQC_HYBRIDS"
echo ""
echo "---"
diff --git a/examples/benchmark/tls_bench.c b/examples/benchmark/tls_bench.c
index ede7d8fed76..7cc5b84ecd0 100644
--- a/examples/benchmark/tls_bench.c
+++ b/examples/benchmark/tls_bench.c
@@ -296,17 +296,23 @@ 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 */
+ #ifdef WOLFSSL_PQC_HYBRIDS
+ { WOLFSSL_SECP256R1MLKEM768, "SecP256r1MLKEM768" },
+ { WOLFSSL_SECP384R1MLKEM1024, "SecP384r1MLKEM1024" },
+ { WOLFSSL_X25519MLKEM768, "X25519MLKEM768" },
+ #endif /* WOLFSSL_PQC_HYBRIDS */
+ #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..a156d5dbbe7 100644
--- a/examples/client/client.c
+++ b/examples/client/client.c
@@ -422,61 +422,78 @@ 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 /* WOLFSSL_EXTRA_PQC_HYBRIDS */
+ #ifdef WOLFSSL_PQC_HYBRIDS
+ if (XSTRCMP(pqcAlg, "SecP256r1MLKEM768") == 0) {
group = WOLFSSL_SECP256R1MLKEM768;
}
else
+ #endif /* WOLFSSL_PQC_HYBRIDS */
#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 /* WOLFSSL_EXTRA_PQC_HYBRIDS */
+ #ifdef WOLFSSL_PQC_HYBRIDS
+ if (XSTRCMP(pqcAlg, "SecP384r1MLKEM1024") == 0) {
group = WOLFSSL_SECP384R1MLKEM1024;
}
else
+ #endif /* WOLFSSL_PQC_HYBRIDS */
#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;
}
else
#endif
- #if !defined(WOLFSSL_NO_ML_KEM_768) && defined(HAVE_CURVE25519)
+ #if !defined(WOLFSSL_NO_ML_KEM_768) && defined(HAVE_CURVE25519) && \
+ defined(WOLFSSL_PQC_HYBRIDS)
if (XSTRCMP(pqcAlg, "X25519MLKEM768") == 0) {
group = WOLFSSL_X25519MLKEM768;
}
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;
}
@@ -547,12 +564,29 @@ static void SetKeyShare(WOLFSSL* ssl, int onlyKeyShare, int useX25519,
}
printf("Using Post-Quantum KEM: %s\n", pqcAlg);
- if (wolfSSL_UseKeyShare(ssl, group) == WOLFSSL_SUCCESS) {
- groups[count++] = group;
- }
- else {
- err_sys("unable to use post-quantum KEM");
+ do {
+ ret = wolfSSL_UseKeyShare(ssl, group);
+ if (ret == WOLFSSL_SUCCESS)
+ groups[count++] = group;
+ #ifdef WOLFSSL_ASYNC_CRYPT
+ else if (ret == WC_NO_ERR_TRACE(WC_PENDING_E))
+ wolfSSL_AsyncPoll(ssl, WOLF_POLL_FLAG_CHECK_HW);
+ #endif
+ else
+ err_sys("unable to use post-quantum KEM");
+ } while (ret == WC_NO_ERR_TRACE(WC_PENDING_E));
+
+ #ifdef WOLFSSL_DTLS13
+ if (wolfSSL_dtls(ssl)) {
+ /* When the KeyShare is too large for an unfragmented
+ *ClientHello, DTLS sends an empty KeyShare extension to
+ * use the Hello Retry Request to enable fragmentation.
+ * In order to enforce our desired PQC algorithm in the
+ * second ClientHello, we need to set it as the only one
+ * allowed in the SupportedGroups extension. */
+ setGroups = 1;
}
+ #endif /* WOLFSSL_DTLS13 */
}
}
#endif
@@ -2281,8 +2315,8 @@ THREAD_RETURN WOLFSSL_THREAD client_test(void* args)
#ifdef WOLFSSL_STATIC_MEMORY
- #if (defined(HAVE_ECC) && !defined(ALT_ECC_SIZE)) \
- || defined(SESSION_CERTS)
+ #if (defined(HAVE_ECC) && !defined(ALT_ECC_SIZE)) || \
+ defined(SESSION_CERTS) || defined(WOLFSSL_HAVE_MLKEM)
/* big enough to handle most cases including session certs */
byte memory[320000];
#else
diff --git a/examples/server/server.c b/examples/server/server.c
index c7c44409d83..99d2d036f25 100644
--- a/examples/server/server.c
+++ b/examples/server/server.c
@@ -709,61 +709,78 @@ 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 /* WOLFSSL_EXTRA_PQC_HYBRIDS */
+ #ifdef WOLFSSL_PQC_HYBRIDS
+ if (XSTRCMP(pqcAlg, "SecP256r1MLKEM768") == 0) {
groups[count] = WOLFSSL_SECP256R1MLKEM768;
}
else
+ #endif /* WOLFSSL_PQC_HYBRIDS */
#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 /* WOLFSSL_EXTRA_PQC_HYBRIDS */
+ #ifdef WOLFSSL_PQC_HYBRIDS
+ if (XSTRCMP(pqcAlg, "SecP384r1MLKEM1024") == 0) {
groups[count] = WOLFSSL_SECP384R1MLKEM1024;
}
else
+ #endif /* WOLFSSL_PQC_HYBRIDS */
#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;
}
else
#endif
- #if !defined(WOLFSSL_NO_ML_KEM_768) && defined(HAVE_CURVE25519)
+ #if !defined(WOLFSSL_NO_ML_KEM_768) && defined(HAVE_CURVE25519) && \
+ defined(WOLFSSL_PQC_HYBRIDS)
if (XSTRCMP(pqcAlg, "X25519MLKEM768") == 0) {
groups[count] = WOLFSSL_X25519MLKEM768;
}
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;
}
@@ -837,14 +854,21 @@ static void SetKeyShare(WOLFSSL* ssl, int onlyKeyShare, int useX25519,
err_sys("invalid post-quantum KEM specified");
}
else {
- if (wolfSSL_UseKeyShare(ssl, groups[count]) == WOLFSSL_SUCCESS) {
- printf("Using Post-Quantum KEM: %s\n", pqcAlg);
- count++;
- }
- else {
- groups[count] = 0;
- err_sys("unable to use post-quantum algorithm");
- }
+ do {
+ ret = wolfSSL_UseKeyShare(ssl, groups[count]);
+ if (ret == WOLFSSL_SUCCESS) {
+ printf("Using Post-Quantum KEM: %s\n", pqcAlg);
+ count++;
+ }
+ #ifdef WOLFSSL_ASYNC_CRYPT
+ else if (ret == WC_NO_ERR_TRACE(WC_PENDING_E))
+ wolfSSL_AsyncPoll(ssl, WOLF_POLL_FLAG_CHECK_HW);
+ #endif
+ else {
+ groups[count] = 0;
+ err_sys("unable to use post-quantum algorithm");
+ }
+ } while (ret == WC_NO_ERR_TRACE(WC_PENDING_E));
}
#endif
}
@@ -1741,8 +1765,8 @@ THREAD_RETURN WOLFSSL_THREAD server_test(void* args)
/* Note: Actual memory used is much less, this is the entire buffer buckets,
* which is partitioned into pools of common sizes. To adjust the buckets
* sizes see WOLFMEM_BUCKETS in memory.h */
- #if (defined(HAVE_ECC) && !defined(ALT_ECC_SIZE)) \
- || defined(SESSION_CERTS)
+ #if (defined(HAVE_ECC) && !defined(ALT_ECC_SIZE)) || \
+ defined(SESSION_CERTS) || defined(WOLFSSL_HAVE_MLKEM)
/* big enough to handle most cases including session certs */
#if !defined(WOLFSSL_NO_CLIENT_AUTH) && \
((defined(HAVE_ED25519) && !defined(NO_ED25519_CLIENT_AUTH)) || \
diff --git a/src/dtls.c b/src/dtls.c
index dff1ffab3a8..141457a7d50 100644
--- a/src/dtls.c
+++ b/src/dtls.c
@@ -822,8 +822,36 @@ static int SendStatelessReplyDtls13(const WOLFSSL* ssl, WolfSSL_CH* ch)
ret = TLSX_KeyShare_SetSupported(ssl, &parsedExts);
if (ret != 0)
goto dtls13_cleanup;
+
+#ifdef WOLFSSL_DTLS_CH_FRAG
+ {
+ /* Get the chosen group. If ret == 0 here, we are sure that the
+ * extension is present. */
+ TLSX* ksExt = TLSX_Find(parsedExts, TLSX_KEY_SHARE);
+ KeyShareEntry* kse = (KeyShareEntry*)ksExt->data;
+ if (WOLFSSL_NAMED_GROUP_IS_PQC(kse->group) ||
+ WOLFSSL_NAMED_GROUP_IS_PQC_HYBRID(kse->group)) {
+ /* Allow fragmentation of the second ClientHello due to the
+ * large PQC key share. */
+ wolfSSL_dtls13_allow_ch_frag((WOLFSSL*)ssl, 1);
+ }
+ }
+#endif
}
else {
+#ifdef WOLFSSL_DTLS_CH_FRAG
+ /* Get the chosen group. */
+ TLSX* ksExt = TLSX_Find(parsedExts, TLSX_KEY_SHARE);
+ if (ksExt != NULL) {
+ KeyShareEntry* kse = (KeyShareEntry*)ksExt->data;
+ if (kse != NULL && (WOLFSSL_NAMED_GROUP_IS_PQC(kse->group) ||
+ WOLFSSL_NAMED_GROUP_IS_PQC_HYBRID(kse->group))){
+ /* Allow fragmentation of the second ClientHello due to the
+ * large PQC key share. */
+ wolfSSL_dtls13_allow_ch_frag((WOLFSSL*)ssl, 1);
+ }
+ }
+#endif
/* Need to remove the keyshare ext if we found a common group
* and are not doing curve negotiation. */
TLSX_Remove(&parsedExts, TLSX_KEY_SHARE, ssl->heap);
diff --git a/src/internal.c b/src/internal.c
index 30579538e5e..088e63e1293 100644
--- a/src/internal.c
+++ b/src/internal.c
@@ -2251,6 +2251,15 @@ int InitSSL_Side(WOLFSSL* ssl, word16 side)
WOLFSSL_MSG("DTLS Cookie Secret error");
return ret;
}
+ #if defined(WOLFSSL_DTLS13) && defined(WOLFSSL_SEND_HRR_COOKIE)
+ if (IsAtLeastTLSv1_3(ssl->version)) {
+ ret = wolfSSL_send_hrr_cookie(ssl, NULL, 0);
+ if (ret != WOLFSSL_SUCCESS) {
+ WOLFSSL_MSG("DTLS1.3 Cookie secret error");
+ return ret;
+ }
+ }
+ #endif /* WOLFSSL_DTLS13 && WOLFSSL_SEND_HRR_COOKIE */
}
#endif /* WOLFSSL_DTLS && !NO_WOLFSSL_SERVER */
@@ -35077,21 +35086,28 @@ static int DoSessionTicket(WOLFSSL* ssl, const byte* input, word32* inOutIdx,
/* Returns 1 when the given group is a PQC hybrid group, 0 otherwise. */
int NamedGroupIsPqcHybrid(int group)
{
+ #if defined(WOLFSSL_PQC_HYBRIDS) || defined(WOLFSSL_EXTRA_PQC_HYBRIDS) || \
+ defined(WOLFSSL_MLKEM_KYBER)
+
switch (group) {
#ifndef WOLFSSL_NO_ML_KEM
+ #ifdef WOLFSSL_PQC_HYBRIDS
case WOLFSSL_SECP256R1MLKEM768:
case WOLFSSL_X25519MLKEM768:
case WOLFSSL_SECP384R1MLKEM1024:
+ #endif /* WOLFSSL_PQC_HYBRIDS */
+ #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:
@@ -35106,6 +35122,10 @@ static int DoSessionTicket(WOLFSSL* ssl, const byte* input, word32* inOutIdx,
default:
return 0;
}
+ #else
+ (void)group;
+ return 0;
+ #endif
}
#endif /* WOLFSSL_HAVE_MLKEM */
diff --git a/src/ssl.c b/src/ssl.c
index 09d2e6dcd71..a4f1c0e7649 100644
--- a/src/ssl.c
+++ b/src/ssl.c
@@ -2967,18 +2967,24 @@ 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)
+ #ifdef WOLFSSL_PQC_HYBRIDS
+ case WOLFSSL_SECP384R1MLKEM1024:
+ case WOLFSSL_X25519MLKEM768:
+ case WOLFSSL_SECP256R1MLKEM768:
+ #endif /* WOLFSSL_PQC_HYBRIDS */
+ #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
@@ -10591,49 +10597,59 @@ 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
+ #ifdef WOLFSSL_PQC_HYBRIDS
case WOLFSSL_SECP256R1MLKEM768:
return "SecP256r1MLKEM768";
#ifdef HAVE_CURVE25519
case WOLFSSL_X25519MLKEM768:
return "X25519MLKEM768";
#endif
+ #endif /* WOLFSSL_PQC_HYBRIDS */
+ #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
+ #ifdef WOLFSSL_PQC_HYBRIDS
case WOLFSSL_SECP384R1MLKEM1024:
return "SecP384r1MLKEM1024";
- #endif
+ #endif /* WOLFSSL_PQC_HYBRIDS */
+ #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";
@@ -16813,22 +16829,26 @@ 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)
+ #ifdef WOLFSSL_PQC_HYBRIDS
+ {CURVE_NAME("SecP256r1MLKEM768"), WOLFSSL_SECP256R1MLKEM768,
+ WOLFSSL_SECP256R1MLKEM768},
+ {CURVE_NAME("SecP384r1MLKEM1024"), WOLFSSL_SECP384R1MLKEM1024,
+ WOLFSSL_SECP384R1MLKEM1024},
+ {CURVE_NAME("X25519MLKEM768"), WOLFSSL_X25519MLKEM768,
+ WOLFSSL_X25519MLKEM768},
+ #endif /* WOLFSSL_PQC_HYBRIDS */
+ #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 bcad4e8f3b9..9fa03d4bc6d 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,52 @@ 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 */
+ #ifdef WOLFSSL_PQC_HYBRIDS
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 */
+ #endif /* WOLFSSL_PQC_HYBRIDS */
+ #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 */
+ #ifdef WOLFSSL_PQC_HYBRIDS
case WOLFSSL_SECP384R1MLKEM1024:
+ #endif /* WOLFSSL_PQC_HYBRIDS */
+ #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 +5837,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 +5854,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;
@@ -8208,26 +8226,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
@@ -8235,13 +8249,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
@@ -8249,7 +8261,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
@@ -8257,7 +8268,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
@@ -8266,6 +8276,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);
@@ -8459,6 +8478,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 {
@@ -8470,23 +8495,33 @@ typedef struct PqcHybridMapping {
static const PqcHybridMapping pqc_hybrid_mapping[] = {
#ifndef WOLFSSL_NO_ML_KEM
+#ifdef WOLFSSL_PQC_HYBRIDS
+ {WOLFSSL_SECP256R1MLKEM768, WOLFSSL_ECC_SECP256R1, WOLFSSL_ML_KEM_768, 0},
+ {WOLFSSL_SECP384R1MLKEM1024, WOLFSSL_ECC_SECP384R1, WOLFSSL_ML_KEM_1024, 0},
+#endif /* WOLFSSL_PQC_HYBRIDS */
+#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},
+#ifdef WOLFSSL_PQC_HYBRIDS
{WOLFSSL_X25519MLKEM768, WOLFSSL_ECC_X25519, WOLFSSL_ML_KEM_768, 1},
-#endif
+#endif /* WOLFSSL_PQC_HYBRIDS */
+#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},
@@ -8739,6 +8774,21 @@ static int TLSX_KeyShare_GenPqcHybridKeyClient(WOLFSSL *ssl, KeyShareEntry* kse)
/* Generate ECC key share part */
if (ret == 0) {
ecc_kse->group = ecc_group;
+
+ #ifdef WOLFSSL_ASYNC_CRYPT
+ /* Check if the provided kse already contains an ECC key and the
+ * last error was WC_PENDING_E. In this case, we already tried to
+ * generate an ECC key. Hence, we have to restore it. */
+ if (kse->key != NULL && kse->keyLen > 0 &&
+ kse->lastRet == WC_NO_ERR_TRACE(WC_PENDING_E)) {
+ ecc_kse->key = kse->key;
+ ecc_kse->keyLen = kse->keyLen;
+ ecc_kse->pubKeyLen = kse->pubKeyLen;
+ ecc_kse->lastRet = kse->lastRet;
+ kse->key = NULL;
+ }
+ #endif
+
#ifdef HAVE_CURVE25519
if (ecc_group == WOLFSSL_ECC_X25519) {
ret = TLSX_KeyShare_GenX25519Key(ssl, ecc_kse);
@@ -8754,7 +8804,17 @@ static int TLSX_KeyShare_GenPqcHybridKeyClient(WOLFSSL *ssl, KeyShareEntry* kse)
{
ret = TLSX_KeyShare_GenEccKey(ssl, ecc_kse);
}
- /* No error message, TLSX_KeyShare_Gen*Key will do it. */
+
+ #ifdef WOLFSSL_ASYNC_CRYPT
+ if (ret == WC_NO_ERR_TRACE(WC_PENDING_E)) {
+ /* Store the generated ECC key in the provided kse to later
+ * restore it.*/
+ kse->key = ecc_kse->key;
+ kse->keyLen = ecc_kse->keyLen;
+ kse->pubKeyLen = ecc_kse->pubKeyLen;
+ ecc_kse->key = NULL;
+ }
+ #endif
}
/* Generate PQC key share part */
@@ -9751,7 +9811,6 @@ static int TLSX_KeyShare_ProcessPqcHybridClient(WOLFSSL* ssl,
KeyShareEntry *ecc_kse = NULL;
word32 ctSz = 0;
word32 ssSzPqc = 0;
- word32 ssSzEcc = 0;
if (ssl->options.side == WOLFSSL_SERVER_END) {
/* I am the server, the shared secret has already been generated and
@@ -9886,6 +9945,9 @@ static int TLSX_KeyShare_ProcessPqcHybridClient(WOLFSSL* ssl,
XMEMCPY(ecc_kse->ke, keyShareEntry->ke + offset, ecc_kse->keLen);
}
+ #ifdef WOLFSSL_ASYNC_CRYPT
+ ecc_kse->lastRet = keyShareEntry->lastRet;
+ #endif
}
/* Process ECDH key share part. The generated shared secret is directly
@@ -9895,36 +9957,46 @@ static int TLSX_KeyShare_ProcessPqcHybridClient(WOLFSSL* ssl,
if (ret == 0) {
int offset = 0;
- /* Set the ECC size variable to the initial buffer size */
- ssSzEcc = ssl->arrays->preMasterSz;
-
if (pqc_first)
offset = ssSzPqc;
#ifdef HAVE_CURVE25519
if (ecc_group == WOLFSSL_ECC_X25519) {
ret = TLSX_KeyShare_ProcessX25519_ex(ssl, ecc_kse,
- ssl->arrays->preMasterSecret + offset, &ssSzEcc);
+ ssl->arrays->preMasterSecret + offset,
+ &ssl->arrays->preMasterSz);
}
else
#endif
#ifdef HAVE_CURVE448
if (ecc_group == WOLFSSL_ECC_X448) {
ret = TLSX_KeyShare_ProcessX448_ex(ssl, ecc_kse,
- ssl->arrays->preMasterSecret + offset, &ssSzEcc);
+ ssl->arrays->preMasterSecret + offset,
+ &ssl->arrays->preMasterSz);
}
else
#endif
{
ret = TLSX_KeyShare_ProcessEcc_ex(ssl, ecc_kse,
- ssl->arrays->preMasterSecret + offset, &ssSzEcc);
+ ssl->arrays->preMasterSecret + offset,
+ &ssl->arrays->preMasterSz);
+ }
+
+ #ifdef WOLFSSL_ASYNC_CRYPT
+ if (ret == WC_NO_ERR_TRACE(WC_PENDING_E)) {
+ keyShareEntry->lastRet = WC_PENDING_E;
+ /* Prevent freeing of the ECC and ML-KEM private keys */
+ ecc_kse->key = NULL;
+ pqc_kse->privKey = NULL;
}
+ #endif
}
if (ret == 0) {
keyShareEntry->key = ecc_kse->key;
- if ((ret == 0) && ((ssSzEcc + ssSzPqc) > ENCRYPT_LEN)) {
+ if ((ret == 0) &&
+ ((ssl->arrays->preMasterSz + ssSzPqc) > ENCRYPT_LEN)) {
WOLFSSL_MSG("shared secret is too long.");
ret = LENGTH_ERROR;
}
@@ -9933,7 +10005,7 @@ static int TLSX_KeyShare_ProcessPqcHybridClient(WOLFSSL* ssl,
/* Process PQC KEM key share part. Depending on the pqc_first flag, the
* KEM shared secret part goes before or after the ECDH part. */
if (ret == 0) {
- int offset = ssSzEcc;
+ int offset = ssl->arrays->preMasterSz;
if (pqc_first)
offset = 0;
@@ -9945,7 +10017,7 @@ static int TLSX_KeyShare_ProcessPqcHybridClient(WOLFSSL* ssl,
if (ret == 0) {
keyShareEntry->privKey = (byte*)pqc_kse->key;
- ssl->arrays->preMasterSz = ssSzEcc + ssSzPqc;
+ ssl->arrays->preMasterSz += ssSzPqc;
}
TLSX_KeyShare_FreeAll(ecc_kse, ssl->heap);
@@ -10051,10 +10123,12 @@ static int TLSX_KeyShareEntry_Parse(const WOLFSSL* ssl, const byte* input,
*seenGroupsCnt = i + 1;
}
-#ifdef WOLFSSL_HAVE_MLKEM
- if ((WOLFSSL_NAMED_GROUP_IS_PQC(group) ||
- WOLFSSL_NAMED_GROUP_IS_PQC_HYBRID(group)) &&
- ssl->options.side == WOLFSSL_SERVER_END) {
+#if defined(WOLFSSL_HAVE_MLKEM)
+ if ((WOLFSSL_NAMED_GROUP_IS_PQC(group)
+ #if !defined(WOLFSSL_ASYNC_CRYPT)
+ || WOLFSSL_NAMED_GROUP_IS_PQC_HYBRID(group)
+ #endif
+ ) && ssl->options.side == WOLFSSL_SERVER_END) {
/* When handling a key share containing a KEM public key on the server
* end, we have to perform the encapsulation immediately in order to
* send the resulting ciphertext back to the client in the ServerHello
@@ -10191,7 +10265,7 @@ int TLSX_KeyShare_Parse_ClientHello(const WOLFSSL* ssl,
offset += ret;
}
- if (ssl->hrr_keyshare_group != 0) {
+ if (ssl->hrr_keyshare_group != 0 && seenGroupsCnt > 0) {
/*
* https://datatracker.ietf.org/doc/html/rfc8446#section-4.2.8
* when sending the new ClientHello, the client MUST
@@ -10453,6 +10527,7 @@ static int TLSX_KeyShare_HandlePqcKeyServer(WOLFSSL* ssl,
keyShareEntry->ke = NULL;
keyShareEntry->keLen = 0;
+ XFREE(keyShareEntry->pubKey, ssl->heap, DYNAMIC_TYPE_PUBLIC_KEY);
keyShareEntry->pubKey = ciphertext;
keyShareEntry->pubKeyLen = ctSz;
ciphertext = NULL;
@@ -10470,7 +10545,7 @@ static int TLSX_KeyShare_HandlePqcKeyServer(WOLFSSL* ssl,
return ret;
}
-static int TLSX_KeyShare_HandlePqcHybridKeyServer(WOLFSSL* ssl,
+int TLSX_KeyShare_HandlePqcHybridKeyServer(WOLFSSL* ssl,
KeyShareEntry* keyShareEntry, byte* data, word16 len)
{
/* I am the server. The data parameter is the concatenation of the client's
@@ -10490,7 +10565,6 @@ static int TLSX_KeyShare_HandlePqcHybridKeyServer(WOLFSSL* ssl,
word32 pubSz = 0;
word32 ctSz = 0;
word32 ssSzPqc = 0;
- word32 ssSzEcc = 0;
if (data == NULL) {
WOLFSSL_MSG("No hybrid key share data from the client.");
@@ -10514,14 +10588,17 @@ static int TLSX_KeyShare_HandlePqcHybridKeyServer(WOLFSSL* ssl,
ret = MEMORY_ERROR;
}
}
+ if (ret == 0) {
+ XMEMSET(ecc_kse, 0, sizeof(*ecc_kse));
+ ecc_kse->group = ecc_group;
+ XMEMSET(pqc_kse, 0, sizeof(*pqc_kse));
+ pqc_kse->group = pqc_group;
+ }
/* The ciphertext and shared secret sizes of a KEM are fixed. Hence, we
* decode these sizes to properly concatenate the KEM ciphertext with the
* ECDH public key. */
if (ret == 0) {
- XMEMSET(pqc_kse, 0, sizeof(*pqc_kse));
- pqc_kse->group = pqc_group;
-
/* Allocate a Kyber key to hold private key. */
pqc_kse->key = (KyberKey*) XMALLOC(sizeof(KyberKey), ssl->heap,
DYNAMIC_TYPE_PRIVATE_KEY);
@@ -10557,10 +10634,26 @@ static int TLSX_KeyShare_HandlePqcHybridKeyServer(WOLFSSL* ssl,
}
}
+#ifdef WOLFSSL_ASYNC_CRYPT
+ if (ret == 0) {
+ /* Check if the provided kse already contains ECC data and the
+ * last error was WC_PENDING_E. In this case, we already tried to
+ * process ECC kse data. Hence, we have to restore it. */
+ if (keyShareEntry->key != NULL && keyShareEntry->keyLen > 0 &&
+ keyShareEntry->lastRet == WC_NO_ERR_TRACE(WC_PENDING_E)) {
+ ecc_kse->key = keyShareEntry->key;
+ ecc_kse->keyLen = keyShareEntry->keyLen;
+ ecc_kse->pubKey = keyShareEntry->pubKey;
+ ecc_kse->pubKeyLen = keyShareEntry->pubKeyLen;
+ ecc_kse->lastRet = keyShareEntry->lastRet;
+ keyShareEntry->key = NULL;
+ keyShareEntry->pubKey = NULL;
+ }
+ }
+#endif
+
/* Generate the ECDH key share part to be sent to the client */
- if (ret == 0 && ecc_group != 0) {
- XMEMSET(ecc_kse, 0, sizeof(*ecc_kse));
- ecc_kse->group = ecc_group;
+ if (ret == 0 && ecc_group != 0 && ecc_kse->pubKey == NULL) {
#ifdef HAVE_CURVE25519
if (ecc_group == WOLFSSL_ECC_X25519) {
ret = TLSX_KeyShare_GenX25519Key(ssl, ecc_kse);
@@ -10576,7 +10669,22 @@ static int TLSX_KeyShare_HandlePqcHybridKeyServer(WOLFSSL* ssl,
{
ret = TLSX_KeyShare_GenEccKey(ssl, ecc_kse);
}
- /* No error message, TLSX_KeyShare_GenKey will do it. */
+ #ifdef WOLFSSL_ASYNC_CRYPT
+ if (ret == WC_NO_ERR_TRACE(WC_PENDING_E)) {
+ /* Store the generated ECC key in the provided kse to later
+ * restore it.*/
+ keyShareEntry->key = ecc_kse->key;
+ keyShareEntry->keyLen = ecc_kse->keyLen;
+ keyShareEntry->pubKeyLen = ecc_kse->pubKeyLen;
+ keyShareEntry->lastRet = WC_PENDING_E;
+ ecc_kse->key = NULL;
+ }
+ else if (ret == 0 &&
+ keyShareEntry->lastRet == WC_NO_ERR_TRACE(WC_PENDING_E)) {
+ keyShareEntry->lastRet = 0;
+ ecc_kse->lastRet = 0;
+ }
+ #endif
}
if (ret == 0 && len != pubSz + ecc_kse->pubKeyLen) {
@@ -10612,9 +10720,6 @@ static int TLSX_KeyShare_HandlePqcHybridKeyServer(WOLFSSL* ssl,
int pubOffset = 0;
int ssOffset = 0;
- /* Set the ECC size variable to the initial buffer size */
- ssSzEcc = ssl->arrays->preMasterSz;
-
if (pqc_first) {
pubOffset = pubSz;
ssOffset = ssSzPqc;
@@ -10625,31 +10730,44 @@ static int TLSX_KeyShare_HandlePqcHybridKeyServer(WOLFSSL* ssl,
#ifdef HAVE_CURVE25519
if (ecc_group == WOLFSSL_ECC_X25519) {
ret = TLSX_KeyShare_ProcessX25519_ex(ssl, ecc_kse,
- ssl->arrays->preMasterSecret + ssOffset, &ssSzEcc);
+ ssl->arrays->preMasterSecret + ssOffset,
+ &ssl->arrays->preMasterSz);
}
else
#endif
#ifdef HAVE_CURVE448
if (ecc_group == WOLFSSL_ECC_X448) {
ret = TLSX_KeyShare_ProcessX448_ex(ssl, ecc_kse,
- ssl->arrays->preMasterSecret + ssOffset, &ssSzEcc);
+ ssl->arrays->preMasterSecret + ssOffset,
+ &ssl->arrays->preMasterSz);
}
else
#endif
{
ret = TLSX_KeyShare_ProcessEcc_ex(ssl, ecc_kse,
- ssl->arrays->preMasterSecret + ssOffset, &ssSzEcc);
+ ssl->arrays->preMasterSecret + ssOffset,
+ &ssl->arrays->preMasterSz);
}
}
if (ret == 0) {
- if (ssSzEcc != ecc_kse->keyLen) {
+ if (ssl->arrays->preMasterSz != ecc_kse->keyLen) {
WOLFSSL_MSG("Data length mismatch.");
ret = BAD_FUNC_ARG;
}
}
+ #ifdef WOLFSSL_ASYNC_CRYPT
+ else if (ret == WC_NO_ERR_TRACE(WC_PENDING_E)) {
+ keyShareEntry->lastRet = WC_PENDING_E;
+ keyShareEntry->key = ecc_kse->key;
+ keyShareEntry->pubKey = ecc_kse->pubKey;
+ keyShareEntry->pubKeyLen = ecc_kse->pubKeyLen;
+ ecc_kse->key = NULL;
+ ecc_kse->pubKey = NULL;
+ }
+ #endif
}
- if (ret == 0 && ssSzEcc + ssSzPqc > ENCRYPT_LEN) {
+ if (ret == 0 && ssl->arrays->preMasterSz + ssSzPqc > ENCRYPT_LEN) {
WOLFSSL_MSG("shared secret is too long.");
ret = LENGTH_ERROR;
}
@@ -10658,7 +10776,7 @@ static int TLSX_KeyShare_HandlePqcHybridKeyServer(WOLFSSL* ssl,
* KEM shared secret part goes before or after the ECDH part. */
if (ret == 0) {
int input_offset = ecc_kse->keLen;
- int output_offset = ssSzEcc;
+ int output_offset = ssl->arrays->preMasterSz;
if (pqc_first) {
input_offset = 0;
@@ -10673,7 +10791,7 @@ static int TLSX_KeyShare_HandlePqcHybridKeyServer(WOLFSSL* ssl,
if (ret == 0) {
XFREE(keyShareEntry->ke, ssl->heap, DYNAMIC_TYPE_PUBLIC_KEY);
- ssl->arrays->preMasterSz = ssSzEcc + ssSzPqc;
+ ssl->arrays->preMasterSz += ssSzPqc;
keyShareEntry->ke = NULL;
keyShareEntry->keLen = 0;
@@ -10689,6 +10807,7 @@ static int TLSX_KeyShare_HandlePqcHybridKeyServer(WOLFSSL* ssl,
XMEMCPY(ciphertext + ecc_kse->pubKeyLen, pqc_kse->pubKey, ctSz);
}
+ XFREE(keyShareEntry->pubKey, ssl->heap, DYNAMIC_TYPE_PUBLIC_KEY);
keyShareEntry->pubKey = ciphertext;
keyShareEntry->pubKeyLen = ecc_kse->pubKeyLen + ctSz;
ciphertext = NULL;
@@ -10738,7 +10857,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 &&
@@ -10749,7 +10869,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;
@@ -10767,15 +10887,24 @@ 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 &&
+ else
+#if !defined(WOLFSSL_ASYNC_CRYPT)
+ if (ssl->options.side == WOLFSSL_SERVER_END &&
WOLFSSL_NAMED_GROUP_IS_PQC_HYBRID(group)) {
ret = TLSX_KeyShare_HandlePqcHybridKeyServer((WOLFSSL*)ssl,
keyShareEntry,
@@ -10784,6 +10913,7 @@ int TLSX_KeyShare_Use(const WOLFSSL* ssl, word16 group, word16 len, byte* data,
return ret;
}
else
+#endif
#endif
if (data != NULL) {
XFREE(keyShareEntry->ke, ssl->heap, DYNAMIC_TYPE_PUBLIC_KEY);
@@ -10831,21 +10961,39 @@ int TLSX_KeyShare_Empty(WOLFSSL* ssl)
}
static const word16 preferredGroup[] = {
-#if defined(HAVE_ECC) && (!defined(NO_ECC256) || \
- defined(HAVE_ALL_CURVES)) && !defined(NO_ECC_SECP) && ECC_MIN_KEY_SZ <= 256
- WOLFSSL_ECC_SECP256R1,
-#if !defined(HAVE_FIPS) && defined(WOLFSSL_SM2)
- WOLFSSL_ECC_SM2P256V1,
-#endif
-#if defined(HAVE_ECC_BRAINPOOL)
- WOLFSSL_ECC_BRAINPOOLP256R1TLS13,
+ /* Sort by strength, but prefer non-experimental PQ/T hybrid groups */
+#if defined(WOLFSSL_HAVE_MLKEM) && !defined(WOLFSSL_NO_ML_KEM) && \
+ defined(WOLFSSL_PQC_HYBRIDS)
+ #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 && WOLFSSL_PQC_HYBRIDS */
+#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_ECC521) || \
+ defined(HAVE_ALL_CURVES)) && !defined(NO_ECC_SECP) && ECC_MIN_KEY_SZ <= 521
+ WOLFSSL_ECC_SECP521R1,
#endif
-#if defined(HAVE_CURVE25519) && ECC_MIN_KEY_SZ <= 256
- WOLFSSL_ECC_X25519,
+#if defined(HAVE_ECC) && defined(HAVE_ECC512) && \
+ defined(HAVE_ECC_BRAINPOOL) && ECC_MIN_KEY_SZ <= 512
+ WOLFSSL_ECC_BRAINPOOLP512R1TLS13,
#endif
-#if defined(HAVE_CURVE448) && ECC_MIN_KEY_SZ <= 448
- WOLFSSL_ECC_X448,
+#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_ECC384) || \
defined(HAVE_ALL_CURVES)) && !defined(NO_ECC_SECP) && ECC_MIN_KEY_SZ <= 384
@@ -10854,81 +11002,65 @@ static const word16 preferredGroup[] = {
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,
+#if defined(HAVE_CURVE448) && ECC_MIN_KEY_SZ <= 448
+ WOLFSSL_ECC_X448,
#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_ECC) && (!defined(NO_ECC256) || \
+ defined(HAVE_ALL_CURVES)) && !defined(NO_ECC_SECP) && ECC_MIN_KEY_SZ <= 256
+ WOLFSSL_ECC_SECP256R1,
+#if !defined(HAVE_FIPS) && defined(WOLFSSL_SM2)
+ WOLFSSL_ECC_SM2P256V1,
#endif
-#if defined(HAVE_FFDHE_3072)
- WOLFSSL_FFDHE_3072,
+#if defined(HAVE_ECC_BRAINPOOL)
+ WOLFSSL_ECC_BRAINPOOLP256R1TLS13,
#endif
-#if defined(HAVE_FFDHE_4096)
- WOLFSSL_FFDHE_4096,
#endif
-#if defined(HAVE_FFDHE_6144)
- WOLFSSL_FFDHE_6144,
+#if defined(HAVE_CURVE25519) && ECC_MIN_KEY_SZ <= 256
+ WOLFSSL_ECC_X25519,
#endif
#if defined(HAVE_FFDHE_8192)
WOLFSSL_FFDHE_8192,
#endif
+#if defined(HAVE_FFDHE_6144)
+ WOLFSSL_FFDHE_6144,
+#endif
+#if defined(HAVE_FFDHE_4096)
+ WOLFSSL_FFDHE_4096,
+#endif
+#if defined(HAVE_FFDHE_3072)
+ WOLFSSL_FFDHE_3072,
+#endif
+#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,
@@ -10941,27 +11073,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
};
@@ -10998,7 +11116,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 &&
@@ -11378,8 +11497,11 @@ int TLSX_KeyShare_Setup(WOLFSSL *ssl, KeyShareEntry* clientKSE)
if (clientKSE->key == NULL) {
#ifdef WOLFSSL_HAVE_MLKEM
- if (WOLFSSL_NAMED_GROUP_IS_PQC(clientKSE->group) ||
- WOLFSSL_NAMED_GROUP_IS_PQC_HYBRID(clientKSE->group)) {
+ if (WOLFSSL_NAMED_GROUP_IS_PQC(clientKSE->group)
+ #if !defined(WOLFSSL_ASYNC_CRYPT)
+ || WOLFSSL_NAMED_GROUP_IS_PQC_HYBRID(clientKSE->group)
+ #endif
+ ) {
/* Going to need the public key (AKA ciphertext). */
serverKSE->pubKey = clientKSE->pubKey;
clientKSE->pubKey = NULL;
@@ -11387,6 +11509,13 @@ int TLSX_KeyShare_Setup(WOLFSSL *ssl, KeyShareEntry* clientKSE)
clientKSE->pubKeyLen = 0;
}
else
+ #if defined(WOLFSSL_ASYNC_CRYPT)
+ if (WOLFSSL_NAMED_GROUP_IS_PQC_HYBRID(clientKSE->group)) {
+ ret = TLSX_KeyShare_HandlePqcHybridKeyServer(ssl, serverKSE,
+ clientKSE->ke, clientKSE->keLen);
+ }
+ else
+ #endif
#endif
{
ret = TLSX_KeyShare_GenKey(ssl, serverKSE);
@@ -14432,144 +14561,193 @@ static int TLSX_PopulateSupportedGroups(WOLFSSL* ssl, TLSX** extensions)
}
#endif /* WOLFSSL_TLS13 */
+#if defined(WOLFSSL_HAVE_MLKEM) && !defined(WOLFSSL_NO_ML_KEM) && \
+ defined(WOLFSSL_PQC_HYBRIDS)
+ /* 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 && WOLFSSL_PQC_HYBRIDS */
+
+#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)
- /* 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_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)
+ #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_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(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(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
@@ -14605,154 +14783,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 !defined(WOLFSSL_NO_ML_KEM_1024) && \
+ defined(WOLFSSL_EXTRA_PQC_HYBRIDS)
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 (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)
@@ -14775,49 +14892,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 76a88820800..1d48c75d227 100644
--- a/src/tls13.c
+++ b/src/tls13.c
@@ -7116,7 +7116,16 @@ int DoTls13ClientHello(WOLFSSL* ssl, const byte* input, word32* inOutIdx,
KeyShareEntry* serverKSE = (KeyShareEntry*)extension->data;
if (serverKSE != NULL &&
serverKSE->lastRet == WC_NO_ERR_TRACE(WC_PENDING_E)) {
- ret = TLSX_KeyShare_GenKey(ssl, serverKSE);
+ #if defined(WOLFSSL_HAVE_MLKEM)
+ if (WOLFSSL_NAMED_GROUP_IS_PQC_HYBRID(serverKSE->group)) {
+ ret = TLSX_KeyShare_HandlePqcHybridKeyServer(ssl, serverKSE,
+ serverKSE->ke, serverKSE->keLen);
+ }
+ else
+ #endif
+ {
+ ret = TLSX_KeyShare_GenKey(ssl, serverKSE);
+ }
if (ret != 0)
goto exit_dch;
}
@@ -13849,6 +13858,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.c b/tests/api.c
index 884a9835062..a136f43ff9a 100644
--- a/tests/api.c
+++ b/tests/api.c
@@ -258,7 +258,8 @@
#endif
#if defined(WOLFSSL_STATIC_MEMORY) && !defined(WOLFCRYPT_ONLY)
- #if (defined(HAVE_ECC) && !defined(ALT_ECC_SIZE)) || defined(SESSION_CERTS)
+ #if (defined(HAVE_ECC) && !defined(ALT_ECC_SIZE)) || \
+ defined(SESSION_CERTS) || defined(WOLFSSL_HAVE_MLKEM)
#ifdef OPENSSL_EXTRA
#define TEST_TLS_STATIC_MEMSZ (400000)
#else
@@ -28297,6 +28298,9 @@ static int test_dtls13_bad_epoch_ch(void)
/* resend the CH */
ExpectIntEQ(wolfSSL_dtls_got_timeout(ssl_c), WOLFSSL_SUCCESS);
+ /* Re-enable HRR cookie to account for potential CH fragmentation */
+ ExpectIntEQ(wolfSSL_send_hrr_cookie(ssl_s, NULL, 0), WOLFSSL_SUCCESS);
+
ExpectIntEQ(test_memio_do_handshake(ssl_c, ssl_s, 10, NULL), 0);
wolfSSL_free(ssl_c);
@@ -28889,6 +28893,10 @@ static int test_TLSX_CA_NAMES_bad_extension(void)
0x0d, 0x00, 0x00, 0x11, 0x00, 0x00, 0x0d, 0x00, 0x2f, 0x00, 0x06, 0x00,
0x04, 0x00, 0x03, 0x30, 0x00, 0x13, 0x94, 0x00, 0x06, 0x00, 0x04, 0x02
};
+ int groups[2] = {
+ WOLFSSL_ECC_SECP256R1,
+ WOLFSSL_ECC_SECP521R1,
+ };
int i = 0;
for (i = 0; i < 2; i++) {
@@ -28911,6 +28919,9 @@ static int test_TLSX_CA_NAMES_bad_extension(void)
break;
}
+ /* Ensure the correct groups are used for the test */
+ ExpectIntEQ(wolfSSL_set_groups(ssl_c, groups, 2), WOLFSSL_SUCCESS);
+
ExpectIntEQ(wolfSSL_connect(ssl_c), -1);
#ifndef WOLFSSL_DISABLE_EARLY_SANITY_CHECKS
ExpectIntEQ(wolfSSL_get_error(ssl_c, -1), WC_NO_ERR_TRACE(EXT_MISSING));
@@ -29844,7 +29855,7 @@ static int test_dtls13_frag_ch_pq(void)
{
EXPECT_DECLS;
#if defined(HAVE_MANUAL_MEMIO_TESTS_DEPENDENCIES) && defined(WOLFSSL_DTLS13) \
- && defined(WOLFSSL_DTLS_CH_FRAG) && defined(HAVE_LIBOQS)
+ && defined(WOLFSSL_DTLS_CH_FRAG) && defined(WOLFSSL_HAVE_MLKEM)
WOLFSSL_CTX *ctx_c = NULL;
WOLFSSL_CTX *ctx_s = NULL;
WOLFSSL *ssl_c = NULL;
@@ -29853,11 +29864,23 @@ static int test_dtls13_frag_ch_pq(void)
const char *test_str = "test";
int test_str_size;
byte buf[255];
-#ifdef WOLFSSL_MLKEM_KYBER
+#if !defined(WOLFSSL_TLS_NO_MLKEM_STANDALONE)
+#if defined(WOLFSSL_MLKEM_KYBER)
int group = WOLFSSL_KYBER_LEVEL5;
+ const char *group_name = "KYBER_LEVEL5";
#else
int group = WOLFSSL_ML_KEM_1024;
+ const char *group_name = "ML_KEM_1024";
#endif
+#elif defined(WOLFSSL_PQC_HYBRIDS)
+#if defined(HAVE_CURVE25519)
+ int group = WOLFSSL_X25519MLKEM768;
+ const char *group_name = "X25519MLKEM768";
+#else
+ int group = WOLFSSL_SECP256R1MLKEM768;
+ const char *group_name = "SecP256r1MLKEM768";
+#endif
+#endif /* WOLFSSL_TLS_NO_MLKEM_STANDALONE */
XMEMSET(&test_ctx, 0, sizeof(test_ctx));
ExpectIntEQ(test_memio_setup(&test_ctx, &ctx_c, &ctx_s, &ssl_c, &ssl_s,
@@ -29867,13 +29890,8 @@ static int test_dtls13_frag_ch_pq(void)
ExpectIntEQ(wolfSSL_UseKeyShare(ssl_c, group), WOLFSSL_SUCCESS);
ExpectIntEQ(wolfSSL_dtls13_allow_ch_frag(ssl_s, 1), WOLFSSL_SUCCESS);
ExpectIntEQ(test_memio_do_handshake(ssl_c, ssl_s, 10, NULL), 0);
-#ifdef WOLFSSL_MLKEM_KYBER
- ExpectStrEQ(wolfSSL_get_curve_name(ssl_c), "KYBER_LEVEL5");
- ExpectStrEQ(wolfSSL_get_curve_name(ssl_s), "KYBER_LEVEL5");
-#else
- ExpectStrEQ(wolfSSL_get_curve_name(ssl_c), "ML_KEM_1024");
- ExpectStrEQ(wolfSSL_get_curve_name(ssl_s), "ML_KEM_1024");
-#endif
+ ExpectStrEQ(wolfSSL_get_curve_name(ssl_c), group_name);
+ ExpectStrEQ(wolfSSL_get_curve_name(ssl_s), group_name);
test_str_size = XSTRLEN("test") + 1;
ExpectIntEQ(wolfSSL_write(ssl_c, test_str, test_str_size), test_str_size);
ExpectIntEQ(wolfSSL_read(ssl_s, buf, sizeof(buf)), test_str_size);
diff --git a/tests/api/test_dtls.c b/tests/api/test_dtls.c
index a1f592c7063..a22324a88be 100644
--- a/tests/api/test_dtls.c
+++ b/tests/api/test_dtls.c
@@ -1614,6 +1614,28 @@ int test_dtls_rtx_across_epoch_change(void)
WOLFSSL_CTX *ctx_c = NULL, *ctx_s = NULL;
WOLFSSL *ssl_c = NULL, *ssl_s = NULL;
struct test_memio_ctx test_ctx;
+#if defined(WOLFSSL_HAVE_MLKEM)
+ /* When ML-KEM is used in the key share, the hello messages are fragmented
+ *into two messages */
+ int helloMsgCount = 2;
+ int groups[2] = {
+ #if defined(HAVE_CURVE25519) && defined(WOLFSSL_PQC_HYBRIDS)
+ WOLFSSL_X25519MLKEM768,
+ #elif defined(HAVE_ECC) && defined(WOLFSSL_PQC_HYBRIDS)
+ WOLFSSL_SECP256R1MLKEM768,
+ #elif !defined(WOLFSSL_NO_ML_KEM_1024) && \
+ !defined(WOLFSSL_TLS_NO_MLKEM_STANDALONE)
+ WOLFSSL_ML_KEM_1024,
+ #else
+ WOLFSSL_ML_KEM_768,
+ #endif
+ WOLFSSL_ECC_SECP256R1,
+ };
+#else
+ /* When ECC is used in the key share, the hello messages are not
+ * fragmented */
+ int helloMsgCount = 1;
+#endif
XMEMSET(&test_ctx, 0, sizeof(test_ctx));
@@ -1622,6 +1644,11 @@ int test_dtls_rtx_across_epoch_change(void)
wolfDTLSv1_3_client_method, wolfDTLSv1_3_server_method),
0);
+#if defined(WOLFSSL_HAVE_MLKEM)
+ ExpectIntEQ(wolfSSL_set_groups(ssl_c, groups, 2), WOLFSSL_SUCCESS);
+ ExpectIntEQ(wolfSSL_set_groups(ssl_s, groups, 2), WOLFSSL_SUCCESS);
+#endif
+
/* CH0 */
wolfSSL_SetLoggingPrefix("client:");
ExpectIntEQ(wolfSSL_connect(ssl_c), -1);
@@ -1646,7 +1673,7 @@ int test_dtls_rtx_across_epoch_change(void)
ExpectIntGE(test_ctx.c_msg_count, 2);
/* drop everything but the SH */
- while (test_ctx.c_msg_count > 1 && EXPECT_SUCCESS()) {
+ while (test_ctx.c_msg_count > helloMsgCount && EXPECT_SUCCESS()) {
ExpectIntEQ(test_memio_drop_message(&test_ctx, 1, test_ctx.c_msg_count - 1), 0);
}
diff --git a/tests/api/test_tls13.c b/tests/api/test_tls13.c
index a70ea09a1cf..6dbd1c4cedb 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,12 +156,16 @@ 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"
- #else
- ":SecP521r1MLKEM1024"
+ #elif !defined(WOLFSSL_NO_ML_KEM_768) && defined(WOLFSSL_PQC_HYBRIDS)
+ ":SecP256r1MLKEM768"
+ #elif !defined(WOLFSSL_NO_ML_KEM_1024) && \
+ !defined(WOLFSSL_TLS_NO_MLKEM_STANDALONE)
+ ":ML_KEM_1024"
+ #elif !defined(WOLFSSL_NO_ML_KEM_768) && \
+ !defined(WOLFSSL_TLS_NO_MLKEM_STANDALONE)
+ ":ML_KEM_768"
#endif
#endif
#endif
@@ -173,7 +183,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 +198,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 +365,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 +379,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 +1944,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 +1969,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 +1981,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 +2001,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 +2015,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;
@@ -2160,6 +2203,25 @@ int test_tls13_early_data(void)
ExpectIntEQ(test_memio_setup(&test_ctx, &ctx_c, &ctx_s, &ssl_c,
&ssl_s, params[i].client_meth, params[i].server_meth), 0);
+ if (params[i].isUdp) {
+ /* Early data is incompatible with HRR usage. Hence, we have to make
+ * sure a group is negotiated that does not cause a fragemented CH.
+ */
+ int group[1] = {
+ #ifdef HAVE_ECC
+ WOLFSSL_ECC_SECP256R1,
+ #elif defined(HAVE_CURVE25519)
+ WOLFSSL_ECC_X25519,
+ #elif defined(HAVE_CURVE448)
+ WOLFSSL_ECC_X448,
+ #elif defined(HAVE_FFDHE_2048)
+ WOLFSSL_FFDHE_2048,
+ #endif
+ };
+ ExpectIntEQ(wolfSSL_set_groups(ssl_c, group, 1), WOLFSSL_SUCCESS);
+ ExpectIntEQ(wolfSSL_set_groups(ssl_s, group, 1), WOLFSSL_SUCCESS);
+ }
+
/* Get a ticket so that we can do 0-RTT on the next connection */
ExpectIntEQ(test_memio_do_handshake(ssl_c, ssl_s, 10, NULL), 0);
/* Make sure we read the ticket */
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..1a52d92385b 100644
--- a/tests/suites.c
+++ b/tests/suites.c
@@ -180,7 +180,8 @@ static int IsKyberLevelAvailable(const char* line)
begin += 6;
end = XSTRSTR(begin, " ");
- #ifndef WOLFSSL_NO_ML_KEM
+#ifndef WOLFSSL_NO_ML_KEM
+ #ifndef WOLFSSL_TLS_NO_MLKEM_STANDALONE
if ((size_t)end - (size_t)begin == 10) {
#ifndef WOLFSSL_NO_ML_KEM_512
if (XSTRNCMP(begin, "ML_KEM_512", 10) == 0) {
@@ -200,8 +201,71 @@ static int IsKyberLevelAvailable(const char* line)
}
}
#endif
- #endif
- #ifdef WOLFSSL_MLKEM_KYBER
+ #endif /* !WOLFSSL_TLS_NO_MLKEM_STANDALONE */
+
+ #ifdef WOLFSSL_PQC_HYBRIDS
+ #if !defined(WOLFSSL_NO_ML_KEM_768) && defined(HAVE_ECC)
+ if ((size_t)end - (size_t)begin == 17) {
+ if (XSTRNCMP(begin, "SecP256r1MLKEM768", 17) == 0) {
+ available = 1;
+ }
+ }
+ #endif /* !WOLFSSL_NO_ML_KEM_768 && HAVE_ECC */
+ #if !defined(WOLFSSL_NO_ML_KEM_768) && defined(HAVE_CURVE25519)
+ if ((size_t)end - (size_t)begin == 14) {
+ if (XSTRNCMP(begin, "X25519MLKEM768", 14) == 0) {
+ available = 1;
+ }
+ }
+ #endif /* !WOLFSSL_NO_ML_KEM_768 && HAVE_CURVE25519 */
+ #if !defined(WOLFSSL_NO_ML_KEM_1024) && defined(HAVE_ECC384)
+ if ((size_t)end - (size_t)begin == 18) {
+ if (XSTRNCMP(begin, "SecP384r1MLKEM1024", 18) == 0) {
+ available = 1;
+ }
+ }
+ #endif /* !WOLFSSL_NO_ML_KEM_1024 */
+ #endif /* WOLFSSL_PQC_HYBRIDS */
+
+ #ifdef WOLFSSL_EXTRA_PQC_HYBRIDS
+ #if !defined(WOLFSSL_NO_ML_KEM_512) && defined(HAVE_ECC)
+ if ((size_t)end - (size_t)begin == 17) {
+ if (XSTRNCMP(begin, "SecP256r1MLKEM512", 17) == 0) {
+ available = 1;
+ }
+ }
+ #endif /* !WOLFSSL_NO_ML_KEM_512 && HAVE_ECC */
+ #if !defined(WOLFSSL_NO_ML_KEM_512) && defined(HAVE_CURVE25519)
+ if ((size_t)end - (size_t)begin == 14) {
+ if (XSTRNCMP(begin, "X25519MLKEM512", 14) == 0) {
+ available = 1;
+ }
+ }
+ #endif /* !WOLFSSL_NO_ML_KEM_512 && HAVE_CURVE25519 */
+ #if !defined(WOLFSSL_NO_ML_KEM_768) && defined(HAVE_ECC384)
+ if ((size_t)end - (size_t)begin == 17) {
+ if (XSTRNCMP(begin, "SecP384r1MLKEM768", 17) == 0) {
+ available = 1;
+ }
+ }
+ #endif /* !WOLFSSL_NO_ML_KEM_768 && HAVE_ECC384 */
+ #if !defined(WOLFSSL_NO_ML_KEM_768) && defined(HAVE_CURVE448)
+ if ((size_t)end - (size_t)begin == 12) {
+ if (XSTRNCMP(begin, "X448MLKEM768", 12) == 0) {
+ available = 1;
+ }
+ }
+ #endif /* !WOLFSSL_NO_ML_KEM_768 && HAVE_CURVE448 */
+ #if !defined(WOLFSSL_NO_ML_KEM_1024) && defined(HAVE_ECC521)
+ if ((size_t)end - (size_t)begin == 18) {
+ if (XSTRNCMP(begin, "SecP521r1MLKEM1024", 18) == 0) {
+ available = 1;
+ }
+ }
+ #endif /* !WOLFSSL_NO_ML_KEM_1024 */
+ #endif /* WOLFSSL_EXTRA_PQC_HYBRIDS */
+#endif /* !WOLFSSL_NO_ML_KEM */
+#ifdef WOLFSSL_MLKEM_KYBER
if ((size_t)end - (size_t)begin == 12) {
#ifndef WOLFSSL_NO_KYBER512
if (XSTRNCMP(begin, "KYBER_LEVEL1", 12) == 0) {
@@ -219,7 +283,8 @@ static int IsKyberLevelAvailable(const char* line)
}
#endif
}
- #endif
+#endif /* WOLFSSL_MLKEM_KYBER */
+ (void) end;
}
#if defined(WOLFSSL_MLKEM_NO_MAKE_KEY) || \
@@ -919,7 +984,7 @@ int SuiteTest(int argc, char** argv)
XSTRLCPY(argv0[0], "SuiteTest", sizeof(argv0[0]));
#ifdef WOLFSSL_STATIC_MEMORY
- byte memory[200000];
+ byte memory[320000];
#endif
cipherSuiteCtx = wolfSSL_CTX_new(wolfSSLv23_client_method());
@@ -1024,8 +1089,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 +1099,8 @@ int SuiteTest(int argc, char** argv)
args.return_code = EXIT_FAILURE;
goto exit;
}
+ #endif /* !WOLFSSL_TLS_NO_MLKEM_STANDALONE */
+ #ifdef WOLFSSL_PQC_HYBRIDS
/* 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 +1110,23 @@ int SuiteTest(int argc, char** argv)
args.return_code = EXIT_FAILURE;
goto exit;
}
+ #endif /* WOLFSSL_PQC_HYBRIDS */
+ #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 +1134,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 +1145,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 +1157,8 @@ int SuiteTest(int argc, char** argv)
args.return_code = EXIT_FAILURE;
goto exit;
}
+ #endif /* !WOLFSSL_TLS_NO_MLKEM_STANDALONE */
+ #ifdef WOLFSSL_PQC_HYBRIDS
/* 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 +1168,18 @@ int SuiteTest(int argc, char** argv)
args.return_code = EXIT_FAILURE;
goto exit;
}
+ #endif /* WOLFSSL_PQC_HYBRIDS */
+ #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/wolfcrypt/src/wc_mlkem.c b/wolfcrypt/src/wc_mlkem.c
index 6cd325888a7..842646f3479 100644
--- a/wolfcrypt/src/wc_mlkem.c
+++ b/wolfcrypt/src/wc_mlkem.c
@@ -368,6 +368,7 @@ int wc_MlKemKey_Free(MlKemKey* key)
*/
int wc_MlKemKey_MakeKey(MlKemKey* key, WC_RNG* rng)
{
+#ifndef WC_NO_RNG
int ret = 0;
unsigned char rand[WC_ML_KEM_MAKEKEY_RAND_SZ];
@@ -397,6 +398,11 @@ int wc_MlKemKey_MakeKey(MlKemKey* key, WC_RNG* rng)
/* Step 4: return ret != 0 on falsum or internal key generation failure. */
return ret;
+#else
+ (void)key;
+ (void)rng;
+ return NOT_COMPILED_IN;
+#endif /* WC_NO_RNG */
}
/**
@@ -516,16 +522,17 @@ int wc_MlKemKey_MakeKeyWithRandom(MlKemKey* key, const unsigned char* rand,
#ifndef WOLFSSL_MLKEM_MAKEKEY_SMALL_MEM
#ifndef WOLFSSL_MLKEM_CACHE_A
/* e (v) | a (m) */
- e = (sword16*)XMALLOC((k + 1) * k * MLKEM_N * sizeof(sword16),
+ e = (sword16*)XMALLOC((size_t)(k + 1) * (size_t)k *
+ (size_t)MLKEM_N * sizeof(sword16),
key->heap, DYNAMIC_TYPE_TMP_BUFFER);
#else
/* e (v) */
- e = (sword16*)XMALLOC(k * MLKEM_N * sizeof(sword16),
+ e = (sword16*)XMALLOC((size_t)k * (size_t)MLKEM_N * sizeof(sword16),
key->heap, DYNAMIC_TYPE_TMP_BUFFER);
#endif
#else
/* e (v) */
- e = (sword16*)XMALLOC(k * MLKEM_N * sizeof(sword16),
+ e = (sword16*)XMALLOC((size_t)k * (size_t)MLKEM_N * sizeof(sword16),
key->heap, DYNAMIC_TYPE_TMP_BUFFER);
#endif
if (e == NULL) {
@@ -557,7 +564,7 @@ int wc_MlKemKey_MakeKeyWithRandom(MlKemKey* key, const unsigned char* rand,
#endif
#ifndef WOLFSSL_NO_ML_KEM
{
- buf[0] = k;
+ buf[0] = (byte)k;
/* Expand 33 bytes of random to 32.
* Alg 13: Step 1: (rho,sigma) <- G(d||k)
*/
@@ -582,7 +589,7 @@ int wc_MlKemKey_MakeKeyWithRandom(MlKemKey* key, const unsigned char* rand,
/* Generate noise using PRF.
* Alg 13: Steps 8-15: generate s and e
*/
- ret = mlkem_get_noise(&key->prf, k, s, e, NULL, sigma);
+ ret = mlkem_get_noise(&key->prf, (int)k, s, e, NULL, sigma);
}
if (ret == 0) {
/* Generate the matrix A.
@@ -819,10 +826,12 @@ static int mlkemkey_encapsulate(MlKemKey* key, const byte* m, byte* r, byte* c)
if (ret == 0) {
/* Allocate dynamic memory for all matrices, vectors and polynomials. */
#ifndef WOLFSSL_MLKEM_ENCAPSULATE_SMALL_MEM
- y = (sword16*)XMALLOC(((k + 3) * k + 3) * MLKEM_N * sizeof(sword16),
+ y = (sword16*)XMALLOC(((size_t)(k + 3) * (size_t)k + 3) *
+ (size_t)MLKEM_N * sizeof(sword16),
key->heap, DYNAMIC_TYPE_TMP_BUFFER);
#else
- y = (sword16*)XMALLOC(3 * k * MLKEM_N * sizeof(sword16), key->heap,
+ y = (sword16*)XMALLOC((size_t)3 * (size_t)k *
+ (size_t)MLKEM_N * sizeof(sword16), key->heap,
DYNAMIC_TYPE_TMP_BUFFER);
#endif
if (y == NULL) {
@@ -849,7 +858,7 @@ static int mlkemkey_encapsulate(MlKemKey* key, const byte* m, byte* r, byte* c)
/* Generate noise using PRF.
* Steps 9-17: generate y, e_1, e_2
*/
- ret = mlkem_get_noise(&key->prf, k, y, e1, e2, r);
+ ret = mlkem_get_noise(&key->prf, (int)k, y, e1, e2, r);
}
#ifdef WOLFSSL_MLKEM_CACHE_A
if ((ret == 0) && ((key->flags & MLKEM_FLAG_A_SET) != 0)) {
@@ -870,7 +879,7 @@ static int mlkemkey_encapsulate(MlKemKey* key, const byte* m, byte* r, byte* c)
if (ret == 0) {
/* Generate the transposed matrix.
* Step 4-8: generate matrix A_hat */
- ret = mlkem_gen_matrix(&key->prf, a, k, key->pubSeed, 1);
+ ret = mlkem_gen_matrix(&key->prf, a, (int)k, key->pubSeed, 1);
}
if (ret == 0) {
/* Assign remaining allocated dynamic memory to pointers.
@@ -880,7 +889,7 @@ static int mlkemkey_encapsulate(MlKemKey* key, const byte* m, byte* r, byte* c)
/* Perform encapsulation maths.
* Steps 18-19, 21: calculate u and v */
- mlkem_encapsulate(key->pub, u, v, a, y, e1, e2, mu, k);
+ mlkem_encapsulate(key->pub, u, v, a, y, e1, e2, mu, (int)k);
}
#else /* WOLFSSL_MLKEM_ENCAPSULATE_SMALL_MEM */
if (ret == 0) {
@@ -892,7 +901,7 @@ static int mlkemkey_encapsulate(MlKemKey* key, const byte* m, byte* r, byte* c)
mlkem_prf_init(&key->prf);
/* Generate noise using PRF.
* Steps 9-12: generate y */
- ret = mlkem_get_noise(&key->prf, k, y, NULL, NULL, r);
+ ret = mlkem_get_noise(&key->prf, (int)k, y, NULL, NULL, r);
}
if (ret == 0) {
/* Assign remaining allocated dynamic memory to pointers.
@@ -903,7 +912,7 @@ static int mlkemkey_encapsulate(MlKemKey* key, const byte* m, byte* r, byte* c)
/* Perform encapsulation maths.
* Steps 13-17: generate e_1 and e_2
* Steps 18-19, 21: calculate u and v */
- ret = mlkem_encapsulate_seeds(key->pub, &key->prf, u, a, y, k, m,
+ ret = mlkem_encapsulate_seeds(key->pub, &key->prf, u, a, y, (int)k, m,
key->pubSeed, r);
}
#endif /* WOLFSSL_MLKEM_ENCAPSULATE_SMALL_MEM */
@@ -977,6 +986,7 @@ static int mlkemkey_encapsulate(MlKemKey* key, const byte* m, byte* r, byte* c)
int wc_MlKemKey_Encapsulate(MlKemKey* key, unsigned char* c, unsigned char* k,
WC_RNG* rng)
{
+#ifndef WC_NO_RNG
int ret = 0;
unsigned char m[WC_ML_KEM_ENC_RAND_SZ];
@@ -1001,6 +1011,13 @@ int wc_MlKemKey_Encapsulate(MlKemKey* key, unsigned char* c, unsigned char* k,
/* Step 3: return ret != 0 on falsum or internal key generation failure. */
return ret;
+#else
+ (void)key;
+ (void)c;
+ (void)k;
+ (void)rng;
+ return NOT_COMPILED_IN;
+#endif /* WC_NO_RNG */
}
/**
@@ -1344,7 +1361,7 @@ static MLKEM_NOINLINE int mlkemkey_decapsulate(MlKemKey* key, byte* m,
/* Decapsulate the cipher text into polynomial.
* Step 6: w <- v' - InvNTT(s_hat_trans o NTT(u')) */
- mlkem_decapsulate(key->priv, w, u, v, k);
+ mlkem_decapsulate(key->priv, w, u, v, (int)k);
/* Convert the polynomial into a array of bytes (message).
* Step 7: m <- ByteEncode_1(Compress_1(w)) */
@@ -1498,7 +1515,7 @@ int wc_MlKemKey_Decapsulate(MlKemKey* key, unsigned char* ss,
}
if (ret == 0) {
/* Compare generated cipher text with that passed in. */
- fail = mlkem_cmp(ct, cmp, ctSz);
+ fail = mlkem_cmp(ct, cmp, (int)ctSz);
#if defined(WOLFSSL_MLKEM_KYBER) && !defined(WOLFSSL_NO_ML_KEM)
if (key->type & MLKEM_KYBER)
@@ -1527,7 +1544,7 @@ int wc_MlKemKey_Decapsulate(MlKemKey* key, unsigned char* ss,
if (ret == 0) {
/* Set secret to kr or fake secret on comparison failure. */
for (i = 0; i < WC_ML_KEM_SYM_SZ; i++) {
- ss[i] = kr[i] ^ ((kr[i] ^ msg[i]) & fail);
+ ss[i] = (byte)(kr[i] ^ ((kr[i] ^ msg[i]) & fail));
}
}
}
@@ -1568,7 +1585,7 @@ static void mlkemkey_decode_public(sword16* pub, byte* pubSeed, const byte* p,
/* Decode public key that is vector of polynomials.
* Step 2: t <- ByteDecode_12(ek_PKE[0 : 384k]) */
- mlkem_from_bytes(pub, p, k);
+ mlkem_from_bytes(pub, p, (int)k);
p += k * WC_ML_KEM_POLY_SIZE;
/* Read public key seed.
@@ -1684,7 +1701,7 @@ int wc_MlKemKey_DecodePrivateKey(MlKemKey* key, const unsigned char* in,
/* Decode private key that is vector of polynomials.
* Alg 18 Step 1: dk_PKE <- dk[0 : 384k]
* Alg 15 Step 5: s_hat <- ByteDecode_12(dk_PKE) */
- mlkem_from_bytes(key->priv, p, k);
+ mlkem_from_bytes(key->priv, p, (int)k);
p += k * WC_ML_KEM_POLY_SIZE;
/* Decode the public key that is after the private key. */
@@ -1793,7 +1810,7 @@ int wc_MlKemKey_DecodePublicKey(MlKemKey* key, const unsigned char* in,
if (ret == 0) {
mlkemkey_decode_public(key->pub, key->pubSeed, p, k);
- ret = mlkem_check_public(key->pub, k);
+ ret = mlkem_check_public(key->pub, (int)k);
}
if (ret == 0) {
/* Calculate public hash. */
@@ -2038,7 +2055,7 @@ int wc_MlKemKey_EncodePrivateKey(MlKemKey* key, unsigned char* out, word32 len)
if (ret == 0) {
/* Encode private key that is vector of polynomials. */
- mlkem_to_bytes(p, key->priv, k);
+ mlkem_to_bytes(p, key->priv, (int)k);
p += WC_ML_KEM_POLY_SIZE * k;
/* Encode public key. */
@@ -2155,7 +2172,7 @@ int wc_MlKemKey_EncodePublicKey(MlKemKey* key, unsigned char* out, word32 len)
int i;
/* Encode public key polynomial by polynomial. */
- mlkem_to_bytes(p, key->pub, k);
+ mlkem_to_bytes(p, key->pub, (int)k);
p += k * WC_ML_KEM_POLY_SIZE;
/* Append public seed. */
diff --git a/wolfcrypt/src/wc_mlkem_poly.c b/wolfcrypt/src/wc_mlkem_poly.c
index 6e8ce95f751..11fef5083cc 100644
--- a/wolfcrypt/src/wc_mlkem_poly.c
+++ b/wolfcrypt/src/wc_mlkem_poly.c
@@ -235,9 +235,9 @@ static void mlkem_ntt(sword16* r)
sword16 t = MLKEM_MONT_RED(p);
sword16 rj = r[j];
/* Step 9 */
- r[j + len] = rj - t;
+ r[j + len] = (sword16)(rj - t);
/* Step 10 */
- r[j] = rj + t;
+ r[j] = (sword16)(rj + t);
}
}
}
@@ -258,8 +258,8 @@ static void mlkem_ntt(sword16* r)
sword32 p = (sword32)zeta * r[j + MLKEM_N / 2];
sword16 t = MLKEM_MONT_RED(p);
sword16 rj = r[j];
- r[j + MLKEM_N / 2] = rj - t;
- r[j] = rj + t;
+ r[j + MLKEM_N / 2] = (sword16)(rj - t);
+ r[j] = (sword16)(rj + t);
}
for (len = MLKEM_N / 4; len >= 2; len >>= 1) {
for (start = 0; start < MLKEM_N; start = j + len) {
@@ -268,8 +268,8 @@ static void mlkem_ntt(sword16* r)
sword32 p = (sword32)zeta * r[j + len];
sword16 t = MLKEM_MONT_RED(p);
sword16 rj = r[j];
- r[j + len] = rj - t;
- r[j] = rj + t;
+ r[j + len] = (sword16)(rj - t);
+ r[j] = (sword16)(rj + t);
}
}
}
@@ -389,27 +389,27 @@ static void mlkem_ntt(sword16* r)
t1 = MLKEM_MONT_RED((sword32)zeta128 * r5);
t2 = MLKEM_MONT_RED((sword32)zeta128 * r6);
t3 = MLKEM_MONT_RED((sword32)zeta128 * r7);
- r4 = r0 - t0;
- r5 = r1 - t1;
- r6 = r2 - t2;
- r7 = r3 - t3;
- r0 += t0;
- r1 += t1;
- r2 += t2;
- r3 += t3;
+ r4 = (sword16)(r0 - t0);
+ r5 = (sword16)(r1 - t1);
+ r6 = (sword16)(r2 - t2);
+ r7 = (sword16)(r3 - t3);
+ r0 = (sword16)(r0 + t0);
+ r1 = (sword16)(r1 + t1);
+ r2 = (sword16)(r2 + t2);
+ r3 = (sword16)(r3 + t3);
t0 = MLKEM_MONT_RED((sword32)zeta64_0 * r2);
t1 = MLKEM_MONT_RED((sword32)zeta64_0 * r3);
t2 = MLKEM_MONT_RED((sword32)zeta64_1 * r6);
t3 = MLKEM_MONT_RED((sword32)zeta64_1 * r7);
- r2 = r0 - t0;
- r3 = r1 - t1;
- r6 = r4 - t2;
- r7 = r5 - t3;
- r0 += t0;
- r1 += t1;
- r4 += t2;
- r5 += t3;
+ r2 = (sword16)(r0 - t0);
+ r3 = (sword16)(r1 - t1);
+ r6 = (sword16)(r4 - t2);
+ r7 = (sword16)(r5 - t3);
+ r0 = (sword16)(r0 + t0);
+ r1 = (sword16)(r1 + t1);
+ r4 = (sword16)(r4 + t2);
+ r5 = (sword16)(r5 + t3);
r[j + 0] = r0;
r[j + 32] = r1;
@@ -423,7 +423,7 @@ static void mlkem_ntt(sword16* r)
/* len = 32,16,8 */
for (j = 0; j < MLKEM_N; j += 64) {
- int i;
+ unsigned int i;
sword16 zeta32 = zetas[ 4 + j / 64 + 0];
sword16 zeta16_0 = zetas[ 8 + j / 32 + 0];
sword16 zeta16_1 = zetas[ 8 + j / 32 + 1];
@@ -445,40 +445,40 @@ static void mlkem_ntt(sword16* r)
t1 = MLKEM_MONT_RED((sword32)zeta32 * r5);
t2 = MLKEM_MONT_RED((sword32)zeta32 * r6);
t3 = MLKEM_MONT_RED((sword32)zeta32 * r7);
- r4 = r0 - t0;
- r5 = r1 - t1;
- r6 = r2 - t2;
- r7 = r3 - t3;
- r0 += t0;
- r1 += t1;
- r2 += t2;
- r3 += t3;
+ r4 = (sword16)(r0 - t0);
+ r5 = (sword16)(r1 - t1);
+ r6 = (sword16)(r2 - t2);
+ r7 = (sword16)(r3 - t3);
+ r0 = (sword16)(r0 + t0);
+ r1 = (sword16)(r1 + t1);
+ r2 = (sword16)(r2 + t2);
+ r3 = (sword16)(r3 + t3);
t0 = MLKEM_MONT_RED((sword32)zeta16_0 * r2);
t1 = MLKEM_MONT_RED((sword32)zeta16_0 * r3);
t2 = MLKEM_MONT_RED((sword32)zeta16_1 * r6);
t3 = MLKEM_MONT_RED((sword32)zeta16_1 * r7);
- r2 = r0 - t0;
- r3 = r1 - t1;
- r6 = r4 - t2;
- r7 = r5 - t3;
- r0 += t0;
- r1 += t1;
- r4 += t2;
- r5 += t3;
+ r2 = (sword16)(r0 - t0);
+ r3 = (sword16)(r1 - t1);
+ r6 = (sword16)(r4 - t2);
+ r7 = (sword16)(r5 - t3);
+ r0 = (sword16)(r0 + t0);
+ r1 = (sword16)(r1 + t1);
+ r4 = (sword16)(r4 + t2);
+ r5 = (sword16)(r5 + t3);
t0 = MLKEM_MONT_RED((sword32)zeta8_0 * r1);
t1 = MLKEM_MONT_RED((sword32)zeta8_1 * r3);
t2 = MLKEM_MONT_RED((sword32)zeta8_2 * r5);
t3 = MLKEM_MONT_RED((sword32)zeta8_3 * r7);
- r1 = r0 - t0;
- r3 = r2 - t1;
- r5 = r4 - t2;
- r7 = r6 - t3;
- r0 += t0;
- r2 += t1;
- r4 += t2;
- r6 += t3;
+ r1 = (sword16)(r0 - t0);
+ r3 = (sword16)(r2 - t1);
+ r5 = (sword16)(r4 - t2);
+ r7 = (sword16)(r6 - t3);
+ r0 = (sword16)(r0 + t0);
+ r2 = (sword16)(r2 + t1);
+ r4 = (sword16)(r4 + t2);
+ r6 = (sword16)(r6 + t3);
r[j + i + 0] = r0;
r[j + i + 8] = r1;
@@ -509,27 +509,27 @@ static void mlkem_ntt(sword16* r)
t1 = MLKEM_MONT_RED((sword32)zeta4 * r5);
t2 = MLKEM_MONT_RED((sword32)zeta4 * r6);
t3 = MLKEM_MONT_RED((sword32)zeta4 * r7);
- r4 = r0 - t0;
- r5 = r1 - t1;
- r6 = r2 - t2;
- r7 = r3 - t3;
- r0 += t0;
- r1 += t1;
- r2 += t2;
- r3 += t3;
+ r4 = (sword16)(r0 - t0);
+ r5 = (sword16)(r1 - t1);
+ r6 = (sword16)(r2 - t2);
+ r7 = (sword16)(r3 - t3);
+ r0 = (sword16)(r0 + t0);
+ r1 = (sword16)(r1 + t1);
+ r2 = (sword16)(r2 + t2);
+ r3 = (sword16)(r3 + t3);
t0 = MLKEM_MONT_RED((sword32)zeta2_0 * r2);
t1 = MLKEM_MONT_RED((sword32)zeta2_0 * r3);
t2 = MLKEM_MONT_RED((sword32)zeta2_1 * r6);
t3 = MLKEM_MONT_RED((sword32)zeta2_1 * r7);
- r2 = r0 - t0;
- r3 = r1 - t1;
- r6 = r4 - t2;
- r7 = r5 - t3;
- r0 += t0;
- r1 += t1;
- r4 += t2;
- r5 += t3;
+ r2 = (sword16)(r0 - t0);
+ r3 = (sword16)(r1 - t1);
+ r6 = (sword16)(r4 - t2);
+ r7 = (sword16)(r5 - t3);
+ r0 = (sword16)(r0 + t0);
+ r1 = (sword16)(r1 + t1);
+ r4 = (sword16)(r4 + t2);
+ r5 = (sword16)(r5 + t3);
r[j + 0] = MLKEM_BARRETT_RED(r0);
r[j + 1] = MLKEM_BARRETT_RED(r1);
@@ -612,10 +612,10 @@ static void mlkem_invntt(sword16* r)
sword16 rj = r[j];
sword16 rjl = r[j + len];
/* Step 9 */
- sword16 t = rj + rjl;
+ sword16 t = (sword16)(rj + rjl);
r[j] = MLKEM_BARRETT_RED(t);
/* Step 10 */
- rjl = rj - rjl;
+ rjl = (sword16)(rj - rjl);
p = (sword32)zeta * rjl;
r[j + len] = MLKEM_MONT_RED(p);
}
@@ -645,9 +645,9 @@ static void mlkem_invntt(sword16* r)
sword32 p;
sword16 rj = r[j];
sword16 rjl = r[j + len];
- sword16 t = rj + rjl;
+ sword16 t = (sword16)(rj + rjl);
r[j] = MLKEM_BARRETT_RED(t);
- rjl = rj - rjl;
+ rjl = (sword16)(rj - rjl);
p = (sword32)zeta * rjl;
r[j + len] = MLKEM_MONT_RED(p);
}
@@ -660,10 +660,10 @@ static void mlkem_invntt(sword16* r)
sword32 p;
sword16 rj = r[j];
sword16 rjl = r[j + MLKEM_N / 2];
- sword16 t = rj + rjl;
- rjl = rj - rjl;
+ sword16 t = (sword16)(rj + rjl);
+ rjl = (sword16)(rj - rjl);
p = (sword32)zeta * rjl;
- r[j] = t;
+ r[j] = (sword16)t;
r[j + MLKEM_N / 2] = MLKEM_MONT_RED(p);
p = (sword32)zeta2 * r[j];
@@ -818,10 +818,10 @@ static void mlkem_invntt(sword16* r)
t2 = MLKEM_MONT_RED(p);
p = (sword32)zeta2_1 * (sword16)(r5 - r7);
t3 = MLKEM_MONT_RED(p);
- r0 += r2;
- r1 += r3;
- r4 += r6;
- r5 += r7;
+ r0 = (sword16)(r0 + r2);
+ r1 = (sword16)(r1 + r3);
+ r4 = (sword16)(r4 + r6);
+ r5 = (sword16)(r5 + r7);
r2 = t0;
r3 = t1;
r6 = t2;
@@ -835,10 +835,10 @@ static void mlkem_invntt(sword16* r)
t2 = MLKEM_MONT_RED(p);
p = (sword32)zeta4 * (sword16)(r3 - r7);
t3 = MLKEM_MONT_RED(p);
- r0 += r4;
- r1 += r5;
- r2 += r6;
- r3 += r7;
+ r0 = (sword16)(r0 + r4);
+ r1 = (sword16)(r1 + r5);
+ r2 = (sword16)(r2 + r6);
+ r3 = (sword16)(r3 + r7);
r4 = t0;
r5 = t1;
r6 = t2;
@@ -855,7 +855,7 @@ static void mlkem_invntt(sword16* r)
}
for (j = 0; j < MLKEM_N; j += 64) {
- int i;
+ unsigned int i;
sword16 zeta8_0 = zetas_inv[ 96 + j / 16 + 0];
sword16 zeta8_1 = zetas_inv[ 96 + j / 16 + 1];
sword16 zeta8_2 = zetas_inv[ 96 + j / 16 + 2];
@@ -898,10 +898,10 @@ static void mlkem_invntt(sword16* r)
t2 = MLKEM_MONT_RED(p);
p = (sword32)zeta16_1 * (sword16)(r5 - r7);
t3 = MLKEM_MONT_RED(p);
- r0 += r2;
- r1 += r3;
- r4 += r6;
- r5 += r7;
+ r0 = (sword16)(r0 + r2);
+ r1 = (sword16)(r1 + r3);
+ r4 = (sword16)(r4 + r6);
+ r5 = (sword16)(r5 + r7);
r2 = t0;
r3 = t1;
r6 = t2;
@@ -915,10 +915,10 @@ static void mlkem_invntt(sword16* r)
t2 = MLKEM_MONT_RED(p);
p = (sword32)zeta32 * (sword16)(r3 - r7);
t3 = MLKEM_MONT_RED(p);
- r0 += r4;
- r1 += r5;
- r2 += r6;
- r3 += r7;
+ r0 = (sword16)(r0 + r4);
+ r1 = (sword16)(r1 + r5);
+ r2 = (sword16)(r2 + r6);
+ r3 = (sword16)(r3 + r7);
r4 = t0;
r5 = t1;
r6 = t2;
@@ -974,10 +974,10 @@ static void mlkem_invntt(sword16* r)
t2 = MLKEM_MONT_RED(p);
p = (sword32)zeta128 * (sword16)(r3 - r7);
t3 = MLKEM_MONT_RED(p);
- r0 += r4;
- r1 += r5;
- r2 += r6;
- r3 += r7;
+ r0 = (sword16)(r0 + r4);
+ r1 = (sword16)(r1 + r5);
+ r2 = (sword16)(r2 + r6);
+ r3 = (sword16)(r3 + r7);
r4 = t0;
r5 = t1;
r6 = t2;
@@ -1081,29 +1081,36 @@ static void mlkem_basemul_mont(sword16* r, const sword16* a, const sword16* b)
for (i = 0; i < MLKEM_N; i += 4, zeta++) {
/* Step 2 */
mlkem_basemul(r + i + 0, a + i + 0, b + i + 0, zeta[0]);
- mlkem_basemul(r + i + 2, a + i + 2, b + i + 2, -zeta[0]);
+ mlkem_basemul(r + i + 2, a + i + 2, b + i + 2,
+ (sword16)(-zeta[0]));
}
#elif defined(WOLFSSL_MLKEM_NO_LARGE_CODE)
/* Four multiplications per loop. */
unsigned int i;
for (i = 0; i < MLKEM_N; i += 8, zeta += 2) {
mlkem_basemul(r + i + 0, a + i + 0, b + i + 0, zeta[0]);
- mlkem_basemul(r + i + 2, a + i + 2, b + i + 2, -zeta[0]);
+ mlkem_basemul(r + i + 2, a + i + 2, b + i + 2,
+ (sword16)(-zeta[0]));
mlkem_basemul(r + i + 4, a + i + 4, b + i + 4, zeta[1]);
- mlkem_basemul(r + i + 6, a + i + 6, b + i + 6, -zeta[1]);
+ mlkem_basemul(r + i + 6, a + i + 6, b + i + 6,
+ (sword16)(-zeta[1]));
}
#else
/* Eight multiplications per loop. */
unsigned int i;
for (i = 0; i < MLKEM_N; i += 16, zeta += 4) {
mlkem_basemul(r + i + 0, a + i + 0, b + i + 0, zeta[0]);
- mlkem_basemul(r + i + 2, a + i + 2, b + i + 2, -zeta[0]);
+ mlkem_basemul(r + i + 2, a + i + 2, b + i + 2,
+ (sword16)(-zeta[0]));
mlkem_basemul(r + i + 4, a + i + 4, b + i + 4, zeta[1]);
- mlkem_basemul(r + i + 6, a + i + 6, b + i + 6, -zeta[1]);
+ mlkem_basemul(r + i + 6, a + i + 6, b + i + 6,
+ (sword16)(-zeta[1]));
mlkem_basemul(r + i + 8, a + i + 8, b + i + 8, zeta[2]);
- mlkem_basemul(r + i + 10, a + i + 10, b + i + 10, -zeta[2]);
+ mlkem_basemul(r + i + 10, a + i + 10, b + i + 10,
+ (sword16)(-zeta[2]));
mlkem_basemul(r + i + 12, a + i + 12, b + i + 12, zeta[3]);
- mlkem_basemul(r + i + 14, a + i + 14, b + i + 14, -zeta[3]);
+ mlkem_basemul(r + i + 14, a + i + 14, b + i + 14,
+ (sword16)(-zeta[3]));
}
#endif
}
@@ -1137,12 +1144,12 @@ static void mlkem_basemul_mont_add(sword16* r, const sword16* a,
sword16 t2[2];
mlkem_basemul(t0, a + i + 0, b + i + 0, zeta[0]);
- mlkem_basemul(t2, a + i + 2, b + i + 2, -zeta[0]);
+ mlkem_basemul(t2, a + i + 2, b + i + 2, (sword16)(-zeta[0]));
- r[i + 0] += t0[0];
- r[i + 1] += t0[1];
- r[i + 2] += t2[0];
- r[i + 3] += t2[1];
+ r[i + 0] = (sword16)(r[i + 0] + t0[0]);
+ r[i + 1] = (sword16)(r[i + 1] + t0[1]);
+ r[i + 2] = (sword16)(r[i + 2] + t2[0]);
+ r[i + 3] = (sword16)(r[i + 3] + t2[1]);
}
#elif defined(WOLFSSL_MLKEM_NO_LARGE_CODE)
/* Four multiplications per loop. */
@@ -1154,18 +1161,18 @@ static void mlkem_basemul_mont_add(sword16* r, const sword16* a,
sword16 t6[2];
mlkem_basemul(t0, a + i + 0, b + i + 0, zeta[0]);
- mlkem_basemul(t2, a + i + 2, b + i + 2, -zeta[0]);
+ mlkem_basemul(t2, a + i + 2, b + i + 2, (sword16)(-zeta[0]));
mlkem_basemul(t4, a + i + 4, b + i + 4, zeta[1]);
- mlkem_basemul(t6, a + i + 6, b + i + 6, -zeta[1]);
+ mlkem_basemul(t6, a + i + 6, b + i + 6, (sword16)(-zeta[1]));
- r[i + 0] += t0[0];
- r[i + 1] += t0[1];
- r[i + 2] += t2[0];
- r[i + 3] += t2[1];
- r[i + 4] += t4[0];
- r[i + 5] += t4[1];
- r[i + 6] += t6[0];
- r[i + 7] += t6[1];
+ r[i + 0] = (sword16)(r[i + 0] + t0[0]);
+ r[i + 1] = (sword16)(r[i + 1] + t0[1]);
+ r[i + 2] = (sword16)(r[i + 2] + t2[0]);
+ r[i + 3] = (sword16)(r[i + 3] + t2[1]);
+ r[i + 4] = (sword16)(r[i + 4] + t4[0]);
+ r[i + 5] = (sword16)(r[i + 5] + t4[1]);
+ r[i + 6] = (sword16)(r[i + 6] + t6[0]);
+ r[i + 7] = (sword16)(r[i + 7] + t6[1]);
}
#else
/* Eight multiplications per loop. */
@@ -1181,30 +1188,30 @@ static void mlkem_basemul_mont_add(sword16* r, const sword16* a,
sword16 t14[2];
mlkem_basemul(t0, a + i + 0, b + i + 0, zeta[0]);
- mlkem_basemul(t2, a + i + 2, b + i + 2, -zeta[0]);
+ mlkem_basemul(t2, a + i + 2, b + i + 2, (sword16)(-zeta[0]));
mlkem_basemul(t4, a + i + 4, b + i + 4, zeta[1]);
- mlkem_basemul(t6, a + i + 6, b + i + 6, -zeta[1]);
+ mlkem_basemul(t6, a + i + 6, b + i + 6, (sword16)(-zeta[1]));
mlkem_basemul(t8, a + i + 8, b + i + 8, zeta[2]);
- mlkem_basemul(t10, a + i + 10, b + i + 10, -zeta[2]);
+ mlkem_basemul(t10, a + i + 10, b + i + 10, (sword16)(-zeta[2]));
mlkem_basemul(t12, a + i + 12, b + i + 12, zeta[3]);
- mlkem_basemul(t14, a + i + 14, b + i + 14, -zeta[3]);
-
- r[i + 0] += t0[0];
- r[i + 1] += t0[1];
- r[i + 2] += t2[0];
- r[i + 3] += t2[1];
- r[i + 4] += t4[0];
- r[i + 5] += t4[1];
- r[i + 6] += t6[0];
- r[i + 7] += t6[1];
- r[i + 8] += t8[0];
- r[i + 9] += t8[1];
- r[i + 10] += t10[0];
- r[i + 11] += t10[1];
- r[i + 12] += t12[0];
- r[i + 13] += t12[1];
- r[i + 14] += t14[0];
- r[i + 15] += t14[1];
+ mlkem_basemul(t14, a + i + 14, b + i + 14, (sword16)(-zeta[3]));
+
+ r[i + 0] = (sword16)(r[i + 0] + t0[0]);
+ r[i + 1] = (sword16)(r[i + 1] + t0[1]);
+ r[i + 2] = (sword16)(r[i + 2] + t2[0]);
+ r[i + 3] = (sword16)(r[i + 3] + t2[1]);
+ r[i + 4] = (sword16)(r[i + 4] + t4[0]);
+ r[i + 5] = (sword16)(r[i + 5] + t4[1]);
+ r[i + 6] = (sword16)(r[i + 6] + t6[0]);
+ r[i + 7] = (sword16)(r[i + 7] + t6[1]);
+ r[i + 8] = (sword16)(r[i + 8] + t8[0]);
+ r[i + 9] = (sword16)(r[i + 9] + t8[1]);
+ r[i + 10] = (sword16)(r[i + 10] + t10[0]);
+ r[i + 11] = (sword16)(r[i + 11] + t10[1]);
+ r[i + 12] = (sword16)(r[i + 12] + t12[0]);
+ r[i + 13] = (sword16)(r[i + 13] + t12[1]);
+ r[i + 14] = (sword16)(r[i + 14] + t14[0]);
+ r[i + 15] = (sword16)(r[i + 15] + t14[1]);
}
#endif
}
@@ -1622,27 +1629,27 @@ static void mlkem_ntt_add_to(sword16* r, sword16* a)
t1 = MLKEM_MONT_RED((sword32)zeta128 * r5);
t2 = MLKEM_MONT_RED((sword32)zeta128 * r6);
t3 = MLKEM_MONT_RED((sword32)zeta128 * r7);
- r4 = r0 - t0;
- r5 = r1 - t1;
- r6 = r2 - t2;
- r7 = r3 - t3;
- r0 += t0;
- r1 += t1;
- r2 += t2;
- r3 += t3;
+ r4 = (sword16)(r0 - t0);
+ r5 = (sword16)(r1 - t1);
+ r6 = (sword16)(r2 - t2);
+ r7 = (sword16)(r3 - t3);
+ r0 = (sword16)(r0 + t0);
+ r1 = (sword16)(r1 + t1);
+ r2 = (sword16)(r2 + t2);
+ r3 = (sword16)(r3 + t3);
t0 = MLKEM_MONT_RED((sword32)zeta64_0 * r2);
t1 = MLKEM_MONT_RED((sword32)zeta64_0 * r3);
t2 = MLKEM_MONT_RED((sword32)zeta64_1 * r6);
t3 = MLKEM_MONT_RED((sword32)zeta64_1 * r7);
- r2 = r0 - t0;
- r3 = r1 - t1;
- r6 = r4 - t2;
- r7 = r5 - t3;
- r0 += t0;
- r1 += t1;
- r4 += t2;
- r5 += t3;
+ r2 = (sword16)(r0 - t0);
+ r3 = (sword16)(r1 - t1);
+ r6 = (sword16)(r4 - t2);
+ r7 = (sword16)(r5 - t3);
+ r0 = (sword16)(r0 + t0);
+ r1 = (sword16)(r1 + t1);
+ r4 = (sword16)(r4 + t2);
+ r5 = (sword16)(r5 + t3);
r[j + 0] = r0;
r[j + 32] = r1;
@@ -1656,7 +1663,7 @@ static void mlkem_ntt_add_to(sword16* r, sword16* a)
/* len = 32,16,8 */
for (j = 0; j < MLKEM_N; j += 64) {
- int i;
+ unsigned int i;
sword16 zeta32 = zetas[ 4 + j / 64 + 0];
sword16 zeta16_0 = zetas[ 8 + j / 32 + 0];
sword16 zeta16_1 = zetas[ 8 + j / 32 + 1];
@@ -1678,40 +1685,40 @@ static void mlkem_ntt_add_to(sword16* r, sword16* a)
t1 = MLKEM_MONT_RED((sword32)zeta32 * r5);
t2 = MLKEM_MONT_RED((sword32)zeta32 * r6);
t3 = MLKEM_MONT_RED((sword32)zeta32 * r7);
- r4 = r0 - t0;
- r5 = r1 - t1;
- r6 = r2 - t2;
- r7 = r3 - t3;
- r0 += t0;
- r1 += t1;
- r2 += t2;
- r3 += t3;
+ r4 = (sword16)(r0 - t0);
+ r5 = (sword16)(r1 - t1);
+ r6 = (sword16)(r2 - t2);
+ r7 = (sword16)(r3 - t3);
+ r0 = (sword16)(r0 + t0);
+ r1 = (sword16)(r1 + t1);
+ r2 = (sword16)(r2 + t2);
+ r3 = (sword16)(r3 + t3);
t0 = MLKEM_MONT_RED((sword32)zeta16_0 * r2);
t1 = MLKEM_MONT_RED((sword32)zeta16_0 * r3);
t2 = MLKEM_MONT_RED((sword32)zeta16_1 * r6);
t3 = MLKEM_MONT_RED((sword32)zeta16_1 * r7);
- r2 = r0 - t0;
- r3 = r1 - t1;
- r6 = r4 - t2;
- r7 = r5 - t3;
- r0 += t0;
- r1 += t1;
- r4 += t2;
- r5 += t3;
+ r2 = (sword16)(r0 - t0);
+ r3 = (sword16)(r1 - t1);
+ r6 = (sword16)(r4 - t2);
+ r7 = (sword16)(r5 - t3);
+ r0 = (sword16)(r0 + t0);
+ r1 = (sword16)(r1 + t1);
+ r4 = (sword16)(r4 + t2);
+ r5 = (sword16)(r5 + t3);
t0 = MLKEM_MONT_RED((sword32)zeta8_0 * r1);
t1 = MLKEM_MONT_RED((sword32)zeta8_1 * r3);
t2 = MLKEM_MONT_RED((sword32)zeta8_2 * r5);
t3 = MLKEM_MONT_RED((sword32)zeta8_3 * r7);
- r1 = r0 - t0;
- r3 = r2 - t1;
- r5 = r4 - t2;
- r7 = r6 - t3;
- r0 += t0;
- r2 += t1;
- r4 += t2;
- r6 += t3;
+ r1 = (sword16)(r0 - t0);
+ r3 = (sword16)(r2 - t1);
+ r5 = (sword16)(r4 - t2);
+ r7 = (sword16)(r6 - t3);
+ r0 = (sword16)(r0 + t0);
+ r2 = (sword16)(r2 + t1);
+ r4 = (sword16)(r4 + t2);
+ r6 = (sword16)(r6 + t3);
r[j + i + 0] = r0;
r[j + i + 8] = r1;
@@ -1742,36 +1749,36 @@ static void mlkem_ntt_add_to(sword16* r, sword16* a)
t1 = MLKEM_MONT_RED((sword32)zeta4 * r5);
t2 = MLKEM_MONT_RED((sword32)zeta4 * r6);
t3 = MLKEM_MONT_RED((sword32)zeta4 * r7);
- r4 = r0 - t0;
- r5 = r1 - t1;
- r6 = r2 - t2;
- r7 = r3 - t3;
- r0 += t0;
- r1 += t1;
- r2 += t2;
- r3 += t3;
+ r4 = (sword16)(r0 - t0);
+ r5 = (sword16)(r1 - t1);
+ r6 = (sword16)(r2 - t2);
+ r7 = (sword16)(r3 - t3);
+ r0 = (sword16)(r0 + t0);
+ r1 = (sword16)(r1 + t1);
+ r2 = (sword16)(r2 + t2);
+ r3 = (sword16)(r3 + t3);
t0 = MLKEM_MONT_RED((sword32)zeta2_0 * r2);
t1 = MLKEM_MONT_RED((sword32)zeta2_0 * r3);
t2 = MLKEM_MONT_RED((sword32)zeta2_1 * r6);
t3 = MLKEM_MONT_RED((sword32)zeta2_1 * r7);
- r2 = r0 - t0;
- r3 = r1 - t1;
- r6 = r4 - t2;
- r7 = r5 - t3;
- r0 += t0;
- r1 += t1;
- r4 += t2;
- r5 += t3;
-
- r0 += a[j + 0];
- r1 += a[j + 1];
- r2 += a[j + 2];
- r3 += a[j + 3];
- r4 += a[j + 4];
- r5 += a[j + 5];
- r6 += a[j + 6];
- r7 += a[j + 7];
+ r2 = (sword16)(r0 - t0);
+ r3 = (sword16)(r1 - t1);
+ r6 = (sword16)(r4 - t2);
+ r7 = (sword16)(r5 - t3);
+ r0 = (sword16)(r0 + t0);
+ r1 = (sword16)(r1 + t1);
+ r4 = (sword16)(r4 + t2);
+ r5 = (sword16)(r5 + t3);
+
+ r0 = (sword16)(r0 + a[j + 0]);
+ r1 = (sword16)(r1 + a[j + 1]);
+ r2 = (sword16)(r2 + a[j + 2]);
+ r3 = (sword16)(r3 + a[j + 3]);
+ r4 = (sword16)(r4 + a[j + 4]);
+ r5 = (sword16)(r5 + a[j + 5]);
+ r6 = (sword16)(r6 + a[j + 6]);
+ r7 = (sword16)(r7 + a[j + 7]);
a[j + 0] = MLKEM_BARRETT_RED(r0);
a[j + 1] = MLKEM_BARRETT_RED(r1);
@@ -1805,22 +1812,23 @@ static void mlkem_ntt_add_to(sword16* r, sword16* a)
static void mlkem_keygen_c(sword16* s, sword16* t, sword16* e, const sword16* a,
int k)
{
- int i;
+ unsigned int i;
+ unsigned int uk = (unsigned int)k;
/* Transform private key. All of result used in public key calculation
* Step 16: s_hat = NTT(s) */
- for (i = 0; i < k; ++i) {
+ for (i = 0; i < uk; ++i) {
mlkem_ntt(s + i * MLKEM_N);
}
/* For each polynomial in the vectors.
* Step 17, Step 18: Calculate public from A_hat, s_hat and e_hat. */
- for (i = 0; i < k; ++i) {
+ for (i = 0; i < uk; ++i) {
unsigned int j;
/* Multiply a by private into public polynomial.
* Step 18: ... A_hat o s_hat ... */
- mlkem_pointwise_acc_mont(t + i * MLKEM_N, a + i * k * MLKEM_N, s, k);
+ mlkem_pointwise_acc_mont(t + i * MLKEM_N, a + i * uk * MLKEM_N, s, uk);
/* Convert public polynomial to Montgomery form.
* Step 18: ... MontRed(A_hat o s_hat) ... */
for (j = 0; j < MLKEM_N; ++j) {
@@ -1834,7 +1842,7 @@ static void mlkem_keygen_c(sword16* s, sword16* t, sword16* e, const sword16* a,
/* Add errors to public key and reduce.
* Step 18: t_hat = BarrettRed(MontRed(A_hat o s_hat) + e_hat) */
for (j = 0; j < MLKEM_N; ++j) {
- sword16 n = t[i * MLKEM_N + j] + e[i * MLKEM_N + j];
+ sword16 n = (sword16)(t[i * MLKEM_N + j] + e[i * MLKEM_N + j]);
t[i * MLKEM_N + j] = MLKEM_BARRETT_RED(n);
}
#else
@@ -1985,37 +1993,46 @@ static void mlkem_encapsulate_c(const sword16* pub, sword16* u, sword16* v,
const sword16* a, sword16* y, const sword16* e1, const sword16* e2,
const sword16* m, int k)
{
- int i;
+ unsigned int i;
+ unsigned int uk = (unsigned int)k;
/* Transform y. All of result used in calculation of u and v. */
- for (i = 0; i < k; ++i) {
+ for (i = 0; i < uk; ++i) {
mlkem_ntt(y + i * MLKEM_N);
}
/* For each polynomial in the vectors. */
- for (i = 0; i < k; ++i) {
+ for (i = 0; i < uk; ++i) {
unsigned int j;
/* Multiply at by y into u polynomial. */
- mlkem_pointwise_acc_mont(u + i * MLKEM_N, a + i * k * MLKEM_N, y, k);
+ mlkem_pointwise_acc_mont(u + i * MLKEM_N, a + i * uk * MLKEM_N, y, uk);
/* Inverse transform u polynomial. */
mlkem_invntt(u + i * MLKEM_N);
/* Add errors to u and reduce. */
#if defined(WOLFSSL_MLKEM_SMALL) || defined(WOLFSSL_MLKEM_NO_LARGE_CODE)
for (j = 0; j < MLKEM_N; ++j) {
- sword16 t = u[i * MLKEM_N + j] + e1[i * MLKEM_N + j];
+ sword16 t = (sword16)(u[i * MLKEM_N + j] + e1[i * MLKEM_N + j]);
u[i * MLKEM_N + j] = MLKEM_BARRETT_RED(t);
}
#else
for (j = 0; j < MLKEM_N; j += 8) {
- sword16 t0 = u[i * MLKEM_N + j + 0] + e1[i * MLKEM_N + j + 0];
- sword16 t1 = u[i * MLKEM_N + j + 1] + e1[i * MLKEM_N + j + 1];
- sword16 t2 = u[i * MLKEM_N + j + 2] + e1[i * MLKEM_N + j + 2];
- sword16 t3 = u[i * MLKEM_N + j + 3] + e1[i * MLKEM_N + j + 3];
- sword16 t4 = u[i * MLKEM_N + j + 4] + e1[i * MLKEM_N + j + 4];
- sword16 t5 = u[i * MLKEM_N + j + 5] + e1[i * MLKEM_N + j + 5];
- sword16 t6 = u[i * MLKEM_N + j + 6] + e1[i * MLKEM_N + j + 6];
- sword16 t7 = u[i * MLKEM_N + j + 7] + e1[i * MLKEM_N + j + 7];
+ sword16 t0 = (sword16)(u[i * MLKEM_N + j + 0] +
+ e1[i * MLKEM_N + j + 0]);
+ sword16 t1 = (sword16)(u[i * MLKEM_N + j + 1] +
+ e1[i * MLKEM_N + j + 1]);
+ sword16 t2 = (sword16)(u[i * MLKEM_N + j + 2] +
+ e1[i * MLKEM_N + j + 2]);
+ sword16 t3 = (sword16)(u[i * MLKEM_N + j + 3] +
+ e1[i * MLKEM_N + j + 3]);
+ sword16 t4 = (sword16)(u[i * MLKEM_N + j + 4] +
+ e1[i * MLKEM_N + j + 4]);
+ sword16 t5 = (sword16)(u[i * MLKEM_N + j + 5] +
+ e1[i * MLKEM_N + j + 5]);
+ sword16 t6 = (sword16)(u[i * MLKEM_N + j + 6] +
+ e1[i * MLKEM_N + j + 6]);
+ sword16 t7 = (sword16)(u[i * MLKEM_N + j + 7] +
+ e1[i * MLKEM_N + j + 7]);
u[i * MLKEM_N + j + 0] = MLKEM_BARRETT_RED(t0);
u[i * MLKEM_N + j + 1] = MLKEM_BARRETT_RED(t1);
u[i * MLKEM_N + j + 2] = MLKEM_BARRETT_RED(t2);
@@ -2029,12 +2046,12 @@ static void mlkem_encapsulate_c(const sword16* pub, sword16* u, sword16* v,
}
/* Multiply public key by y into v polynomial. */
- mlkem_pointwise_acc_mont(v, pub, y, k);
+ mlkem_pointwise_acc_mont(v, pub, y, uk);
/* Inverse transform v. */
mlkem_invntt(v);
/* Add errors and message to v and reduce. */
for (i = 0; i < MLKEM_N; ++i) {
- sword16 t = v[i] + e2[i] + m[i];
+ sword16 t = (sword16)(v[i] + e2[i] + m[i]);
v[i] = MLKEM_BARRETT_RED(t);
}
}
@@ -2209,24 +2226,25 @@ int mlkem_encapsulate_seeds(const sword16* pub, MLKEM_PRF_T* prf, sword16* u,
static void mlkem_decapsulate_c(const sword16* s, sword16* w, sword16* u,
const sword16* v, int k)
{
- int i;
+ unsigned int i;
+ unsigned int uk = (unsigned int)k;
/* Transform u. All of result used in calculation of w.
* Step 6: ... NTT(u') */
- for (i = 0; i < k; ++i) {
+ for (i = 0; i < uk; ++i) {
mlkem_ntt(u + i * MLKEM_N);
}
/* Multiply private key by u into w polynomial.
* Step 6: ... s_hat_trans o NTT(u') */
- mlkem_pointwise_acc_mont(w, s, u, k);
+ mlkem_pointwise_acc_mont(w, s, u, uk);
/* Inverse transform w.
* Step 6: ... InvNTT(s_hat_trans o NTT(u')) */
mlkem_invntt(w);
/* Subtract errors (in w) out of v and reduce into w.
* Step 6: w <- v' - InvNTT(s_hat_trans o NTT(u')) */
for (i = 0; i < MLKEM_N; ++i) {
- sword16 t = v[i] - w[i];
+ sword16 t = (sword16)(v[i] - w[i]);
w[i] = MLKEM_BARRETT_RED(t);
}
}
@@ -2424,10 +2442,14 @@ static int mlkem_gen_matrix_k3_avx2(sword16* a, byte* seed, int transposed)
for (k = 0; k < 2; k++) {
for (i = 0; i < 4; i++) {
if (!transposed) {
- state[4*4 + i] = 0x1f0000 + (((k*4+i)/3) << 8) + ((k*4+i)%3);
+ state[4*4 + i] = (word64)0x1f0000U +
+ (word64)(word32)((((k * 4 + i) / 3) << 8) +
+ ((k * 4 + i) % 3));
}
else {
- state[4*4 + i] = 0x1f0000 + (((k*4+i)%3) << 8) + ((k*4+i)/3);
+ state[4*4 + i] = (word64)0x1f0000U +
+ (word64)(word32)((((k * 4 + i) % 3) << 8) +
+ ((k * 4 + i) / 3));
}
}
@@ -2577,10 +2599,12 @@ static int mlkem_gen_matrix_k4_avx2(sword16* a, byte* seed, int transposed)
for (k = 0; k < 4; k++) {
for (i = 0; i < 4; i++) {
if (!transposed) {
- state[4*4 + i] = 0x1f0000 + (k << 8) + i;
+ state[4*4 + i] = (word64)0x1f0000U +
+ (word64)(word32)((k << 8) + i);
}
else {
- state[4*4 + i] = 0x1f0000 + (i << 8) + k;
+ state[4*4 + i] = (word64)0x1f0000U +
+ (word64)(word32)((i << 8) + k);
}
}
@@ -2881,7 +2905,7 @@ static int mlkem_xof_absorb(wc_Shake* shake128, byte* seed, int len)
ret = wc_InitShake128(shake128, NULL, INVALID_DEVID);
if (ret == 0) {
- ret = wc_Shake128_Absorb(shake128, seed, len);
+ ret = wc_Shake128_Absorb(shake128, seed, (word32)len);
}
return ret;
@@ -2899,7 +2923,7 @@ static int mlkem_xof_absorb(wc_Shake* shake128, byte* seed, int len)
*/
static int mlkem_xof_squeezeblocks(wc_Shake* shake128, byte* out, int blocks)
{
- return wc_Shake128_SqueezeBlocks(shake128, out, blocks);
+ return wc_Shake128_SqueezeBlocks(shake128, out, (word32)blocks);
}
#endif
@@ -3453,13 +3477,13 @@ static int mlkem_gen_matrix_c(MLKEM_PRF_T* prf, sword16* a, int k, byte* seed,
for (j = 0; (ret == 0) && (j < k); j++) {
if (transposed) {
/* Alg 14, Step 6: .. rho||i||j ... */
- extSeed[WC_ML_KEM_SYM_SZ + 0] = i;
- extSeed[WC_ML_KEM_SYM_SZ + 1] = j;
+ extSeed[WC_ML_KEM_SYM_SZ + 0] = (byte)i;
+ extSeed[WC_ML_KEM_SYM_SZ + 1] = (byte)j;
}
else {
/* Alg 13, Step 5: .. rho||j||i ... */
- extSeed[WC_ML_KEM_SYM_SZ + 0] = j;
- extSeed[WC_ML_KEM_SYM_SZ + 1] = i;
+ extSeed[WC_ML_KEM_SYM_SZ + 0] = (byte)j;
+ extSeed[WC_ML_KEM_SYM_SZ + 1] = (byte)i;
}
/* Absorb the index specific seed.
* Alg 7, Step 1-2 */
@@ -3655,13 +3679,13 @@ static int mlkem_gen_matrix_i(MLKEM_PRF_T* prf, sword16* a, int k, byte* seed,
for (j = 0; (ret == 0) && (j < k); j++) {
if (transposed) {
/* Alg 14, Step 6: .. rho||i||j ... */
- extSeed[WC_ML_KEM_SYM_SZ + 0] = i;
- extSeed[WC_ML_KEM_SYM_SZ + 1] = j;
+ extSeed[WC_ML_KEM_SYM_SZ + 0] = (byte)i;
+ extSeed[WC_ML_KEM_SYM_SZ + 1] = (byte)j;
}
else {
/* Alg 13, Step 5: .. rho||j||i ... */
- extSeed[WC_ML_KEM_SYM_SZ + 0] = j;
- extSeed[WC_ML_KEM_SYM_SZ + 1] = i;
+ extSeed[WC_ML_KEM_SYM_SZ + 0] = (byte)j;
+ extSeed[WC_ML_KEM_SYM_SZ + 1] = (byte)i;
}
/* Absorb the index specific seed.
* Alg 7, Step 1-2 */
@@ -3716,8 +3740,8 @@ static int mlkem_gen_matrix_i(MLKEM_PRF_T* prf, sword16* a, int k, byte* seed,
* @return Difference of the two values with range 0..2.
*/
#define ETA2_SUB(d, i) \
- (((sword16)(((d) >> ((i) * 4 + 0)) & 0x3)) - \
- ((sword16)(((d) >> ((i) * 4 + 2)) & 0x3)))
+ (sword16)(((sword16)(((d) >> ((i) * 4 + 0)) & 0x3)) - \
+ ((sword16)(((d) >> ((i) * 4 + 2)) & 0x3)))
/* Compute polynomial with coefficients distributed according to a centered
* binomial distribution with parameter eta2 from uniform random bytes.
@@ -3832,8 +3856,8 @@ static void mlkem_cbd_eta2(sword16* p, const byte* r)
* @return Difference of the two values with range 0..3.
*/
#define ETA3_SUB(d, i) \
- (((sword16)(((d) >> ((i) * 6 + 0)) & 0x7)) - \
- ((sword16)(((d) >> ((i) * 6 + 3)) & 0x7)))
+ (sword16)(((sword16)(((d) >> ((i) * 6 + 0)) & 0x7)) - \
+ ((sword16)(((d) >> ((i) * 6 + 3)) & 0x7)))
/* Compute polynomial with coefficients distributed according to a centered
* binomial distribution with parameter eta3 from uniform random bytes.
@@ -4093,7 +4117,8 @@ static void mlkem_get_noise_x4_eta2_avx2(byte* rand, byte* seed, byte o)
word64 state[25 * 4];
for (i = 0; i < 4; i++) {
- state[4*4 + i] = 0x1f00 + i + o;
+ state[4*4 + i] = (word64)0x1f00U + (word64)(word32)i +
+ (word64)(word32)o;
}
sha3_256_blocksx4_seed_avx2(state, seed);
@@ -4554,7 +4579,8 @@ static int mlkem_get_noise_c(MLKEM_PRF_T* prf, int k, sword16* vec1, int eta1,
/* Generate noise as private key. */
for (i = 0; (ret == 0) && (i < k); i++) {
/* Generate noise for each dimension of vector. */
- ret = mlkem_get_noise_eta1_c(prf, vec1 + i * MLKEM_N, seed, eta1);
+ ret = mlkem_get_noise_eta1_c(prf, vec1 + i * MLKEM_N, seed,
+ (byte)eta1);
/* Increment value of appended byte. */
seed[WC_ML_KEM_SYM_SZ]++;
}
@@ -4562,13 +4588,14 @@ static int mlkem_get_noise_c(MLKEM_PRF_T* prf, int k, sword16* vec1, int eta1,
/* Generate noise for error. */
for (i = 0; (ret == 0) && (i < k); i++) {
/* Generate noise for each dimension of vector. */
- ret = mlkem_get_noise_eta1_c(prf, vec2 + i * MLKEM_N, seed, eta2);
+ ret = mlkem_get_noise_eta1_c(prf, vec2 + i * MLKEM_N, seed,
+ (byte)eta2);
/* Increment value of appended byte. */
seed[WC_ML_KEM_SYM_SZ]++;
}
}
else {
- seed[WC_ML_KEM_SYM_SZ] = 2 * k;
+ seed[WC_ML_KEM_SYM_SZ] = (byte)(2 * k);
}
if ((ret == 0) && (poly != NULL)) {
/* Generating random error polynomial. */
@@ -4728,7 +4755,7 @@ static int mlkem_cmp_c(const byte* a, const byte* b, int sz)
for (i = 0; i < sz; i++) {
r |= a[i] ^ b[i];
}
- return 0 - ((-(word32)r) >> 31);
+ return (int)(0 - ((-(word32)r) >> 31));
}
#endif
@@ -4777,9 +4804,10 @@ static MLKEM_NOINLINE void mlkem_csubq_c(sword16* p)
unsigned int i;
for (i = 0; i < MLKEM_N; ++i) {
- sword16 t = p[i] - MLKEM_Q;
+ sword16 t = (sword16)(p[i] - MLKEM_Q);
/* When top bit set, -ve number - need to add q back. */
- p[i] = (sword16)((word16)(-((word16)t >> 15)) & MLKEM_Q) + t;
+ p[i] = (sword16)(((word16)(-((word16)t >> 15)) & MLKEM_Q) +
+ (word16)t);
}
}
@@ -4899,8 +4927,9 @@ static MLKEM_NOINLINE void mlkem_csubq_c(sword16* p)
* @return Compressed value.
*/
#define TO_COMP_WORD_10(v, i, j, k) \
- ((((MLKEM_V54 << 10) * (v)[(i) * MLKEM_N + (j) + (k)]) + \
- MLKEM_V54_HALF) >> 54)
+ (word16)(((((word64)(MLKEM_V54 << 10)) * \
+ (word64)(word16)((v)[(i) * MLKEM_N + (j) + (k)])) + \
+ MLKEM_V54_HALF) >> 54)
/* Compress value to 11 bits.
*
@@ -4916,8 +4945,9 @@ static MLKEM_NOINLINE void mlkem_csubq_c(sword16* p)
* @return Compressed value.
*/
#define TO_COMP_WORD_11(v, i, j, k) \
- ((((MLKEM_V53 << 11) * (v)[(i) * MLKEM_N + (j) + (k)]) + \
- MLKEM_V53_HALF) >> 53)
+ (word16)(((((word64)(MLKEM_V53 << 11)) * \
+ (word64)(word16)((v)[(i) * MLKEM_N + (j) + (k)])) + \
+ MLKEM_V53_HALF) >> 53)
#endif /* CONV_WITH_DIV */
@@ -4966,17 +4996,17 @@ static void mlkem_vec_compress_10_c(byte* r, sword16* v, unsigned int k)
r[ 4] = (t[3] >> 2);
#else
/* Compress four polynomial values to 10 bits each. */
- sword16 t0 = TO_COMP_WORD_10(v, i, j, 0);
- sword16 t1 = TO_COMP_WORD_10(v, i, j, 1);
- sword16 t2 = TO_COMP_WORD_10(v, i, j, 2);
- sword16 t3 = TO_COMP_WORD_10(v, i, j, 3);
+ word16 t0 = TO_COMP_WORD_10(v, i, j, 0);
+ word16 t1 = TO_COMP_WORD_10(v, i, j, 1);
+ word16 t2 = TO_COMP_WORD_10(v, i, j, 2);
+ word16 t3 = TO_COMP_WORD_10(v, i, j, 3);
/* Pack four 10-bit values into byte array. */
- r[ 0] = (t0 >> 0);
- r[ 1] = (t0 >> 8) | (t1 << 2);
- r[ 2] = (t1 >> 6) | (t2 << 4);
- r[ 3] = (t2 >> 4) | (t3 << 6);
- r[ 4] = (t3 >> 2);
+ r[ 0] = (byte)(t0 >> 0);
+ r[ 1] = (byte)((t0 >> 8) | (t1 << 2));
+ r[ 2] = (byte)((t1 >> 6) | (t2 << 4));
+ r[ 3] = (byte)((t2 >> 4) | (t3 << 6));
+ r[ 4] = (byte)(t3 >> 2);
#endif
/* Move over set bytes. */
@@ -4986,35 +5016,35 @@ static void mlkem_vec_compress_10_c(byte* r, sword16* v, unsigned int k)
/* Each 16 polynomial coefficients. */
for (j = 0; j < MLKEM_N; j += 16) {
/* Compress four polynomial values to 10 bits each. */
- sword16 t0 = TO_COMP_WORD_10(v, i, j, 0);
- sword16 t1 = TO_COMP_WORD_10(v, i, j, 1);
- sword16 t2 = TO_COMP_WORD_10(v, i, j, 2);
- sword16 t3 = TO_COMP_WORD_10(v, i, j, 3);
- sword16 t4 = TO_COMP_WORD_10(v, i, j, 4);
- sword16 t5 = TO_COMP_WORD_10(v, i, j, 5);
- sword16 t6 = TO_COMP_WORD_10(v, i, j, 6);
- sword16 t7 = TO_COMP_WORD_10(v, i, j, 7);
- sword16 t8 = TO_COMP_WORD_10(v, i, j, 8);
- sword16 t9 = TO_COMP_WORD_10(v, i, j, 9);
- sword16 t10 = TO_COMP_WORD_10(v, i, j, 10);
- sword16 t11 = TO_COMP_WORD_10(v, i, j, 11);
- sword16 t12 = TO_COMP_WORD_10(v, i, j, 12);
- sword16 t13 = TO_COMP_WORD_10(v, i, j, 13);
- sword16 t14 = TO_COMP_WORD_10(v, i, j, 14);
- sword16 t15 = TO_COMP_WORD_10(v, i, j, 15);
+ word16 t0 = TO_COMP_WORD_10(v, i, j, 0);
+ word16 t1 = TO_COMP_WORD_10(v, i, j, 1);
+ word16 t2 = TO_COMP_WORD_10(v, i, j, 2);
+ word16 t3 = TO_COMP_WORD_10(v, i, j, 3);
+ word16 t4 = TO_COMP_WORD_10(v, i, j, 4);
+ word16 t5 = TO_COMP_WORD_10(v, i, j, 5);
+ word16 t6 = TO_COMP_WORD_10(v, i, j, 6);
+ word16 t7 = TO_COMP_WORD_10(v, i, j, 7);
+ word16 t8 = TO_COMP_WORD_10(v, i, j, 8);
+ word16 t9 = TO_COMP_WORD_10(v, i, j, 9);
+ word16 t10 = TO_COMP_WORD_10(v, i, j, 10);
+ word16 t11 = TO_COMP_WORD_10(v, i, j, 11);
+ word16 t12 = TO_COMP_WORD_10(v, i, j, 12);
+ word16 t13 = TO_COMP_WORD_10(v, i, j, 13);
+ word16 t14 = TO_COMP_WORD_10(v, i, j, 14);
+ word16 t15 = TO_COMP_WORD_10(v, i, j, 15);
word32* r32 = (word32*)r;
/* Pack sixteen 10-bit values into byte array. */
- r32[0] = t0 | ((word32)t1 << 10) | ((word32)t2 << 20) |
- ((word32)t3 << 30);
- r32[1] = (t3 >> 2) | ((word32)t4 << 8) | ((word32)t5 << 18) |
- ((word32)t6 << 28);
- r32[2] = (t6 >> 4) | ((word32)t7 << 6) | ((word32)t8 << 16) |
- ((word32)t9 << 26);
- r32[3] = (t9 >> 6) | ((word32)t10 << 4) | ((word32)t11 << 14) |
- ((word32)t12 << 24);
- r32[4] = (t12 >> 8) | ((word32)t13 << 2) | ((word32)t14 << 12) |
- ((word32)t15 << 22);
+ r32[0] = (word32)t0 | ((word32)t1 << 10) |
+ ((word32)t2 << 20) | ((word32)t3 << 30);
+ r32[1] = (word32)(t3 >> 2) | ((word32)t4 << 8) |
+ ((word32)t5 << 18) | ((word32)t6 << 28);
+ r32[2] = (word32)(t6 >> 4) | ((word32)t7 << 6) |
+ ((word32)t8 << 16) | ((word32)t9 << 26);
+ r32[3] = (word32)(t9 >> 6) | ((word32)t10 << 4) |
+ ((word32)t11 << 14) | ((word32)t12 << 24);
+ r32[4] = (word32)(t12 >> 8) | ((word32)t13 << 2) |
+ ((word32)t14 << 12) | ((word32)t15 << 22);
/* Move over set bytes. */
r += 20;
@@ -5035,7 +5065,7 @@ void mlkem_vec_compress_10(byte* r, sword16* v, unsigned int k)
{
#ifdef USE_INTEL_SPEEDUP
if (IS_INTEL_AVX2(cpuid_flags) && (SAVE_VECTOR_REGISTERS2() == 0)) {
- mlkem_compress_10_avx2(r, v, k);
+ mlkem_compress_10_avx2(r, v, (int)k);
RESTORE_VECTOR_REGISTERS();
}
else
@@ -5073,47 +5103,47 @@ static void mlkem_vec_compress_11_c(byte* r, sword16* v)
/* Each 8 polynomial coefficients. */
for (j = 0; j < MLKEM_N; j += 8) {
#ifdef WOLFSSL_MLKEM_SMALL
- sword16 t[8];
+ word16 t[8];
/* Compress eight polynomial values to 11 bits each. */
for (k = 0; k < 8; k++) {
t[k] = TO_COMP_WORD_11(v, i, j, k);
}
/* Pack eight 11-bit values into byte array. */
- r[ 0] = (t[0] >> 0);
- r[ 1] = (t[0] >> 8) | (t[1] << 3);
- r[ 2] = (t[1] >> 5) | (t[2] << 6);
- r[ 3] = (t[2] >> 2);
- r[ 4] = (t[2] >> 10) | (t[3] << 1);
- r[ 5] = (t[3] >> 7) | (t[4] << 4);
- r[ 6] = (t[4] >> 4) | (t[5] << 7);
- r[ 7] = (t[5] >> 1);
- r[ 8] = (t[5] >> 9) | (t[6] << 2);
- r[ 9] = (t[6] >> 6) | (t[7] << 5);
- r[10] = (t[7] >> 3);
+ r[ 0] = (byte)(t[0] >> 0);
+ r[ 1] = (byte)((t[0] >> 8) | (t[1] << 3));
+ r[ 2] = (byte)((t[1] >> 5) | (t[2] << 6));
+ r[ 3] = (byte)(t[2] >> 2);
+ r[ 4] = (byte)((t[2] >> 10) | (t[3] << 1));
+ r[ 5] = (byte)((t[3] >> 7) | (t[4] << 4));
+ r[ 6] = (byte)((t[4] >> 4) | (t[5] << 7));
+ r[ 7] = (byte)(t[5] >> 1);
+ r[ 8] = (byte)((t[5] >> 9) | (t[6] << 2));
+ r[ 9] = (byte)((t[6] >> 6) | (t[7] << 5));
+ r[10] = (byte)(t[7] >> 3);
#else
/* Compress eight polynomial values to 11 bits each. */
- sword16 t0 = TO_COMP_WORD_11(v, i, j, 0);
- sword16 t1 = TO_COMP_WORD_11(v, i, j, 1);
- sword16 t2 = TO_COMP_WORD_11(v, i, j, 2);
- sword16 t3 = TO_COMP_WORD_11(v, i, j, 3);
- sword16 t4 = TO_COMP_WORD_11(v, i, j, 4);
- sword16 t5 = TO_COMP_WORD_11(v, i, j, 5);
- sword16 t6 = TO_COMP_WORD_11(v, i, j, 6);
- sword16 t7 = TO_COMP_WORD_11(v, i, j, 7);
+ word16 t0 = TO_COMP_WORD_11(v, i, j, 0);
+ word16 t1 = TO_COMP_WORD_11(v, i, j, 1);
+ word16 t2 = TO_COMP_WORD_11(v, i, j, 2);
+ word16 t3 = TO_COMP_WORD_11(v, i, j, 3);
+ word16 t4 = TO_COMP_WORD_11(v, i, j, 4);
+ word16 t5 = TO_COMP_WORD_11(v, i, j, 5);
+ word16 t6 = TO_COMP_WORD_11(v, i, j, 6);
+ word16 t7 = TO_COMP_WORD_11(v, i, j, 7);
/* Pack eight 11-bit values into byte array. */
- r[ 0] = (t0 >> 0);
- r[ 1] = (t0 >> 8) | (t1 << 3);
- r[ 2] = (t1 >> 5) | (t2 << 6);
- r[ 3] = (t2 >> 2);
- r[ 4] = (t2 >> 10) | (t3 << 1);
- r[ 5] = (t3 >> 7) | (t4 << 4);
- r[ 6] = (t4 >> 4) | (t5 << 7);
- r[ 7] = (t5 >> 1);
- r[ 8] = (t5 >> 9) | (t6 << 2);
- r[ 9] = (t6 >> 6) | (t7 << 5);
- r[10] = (t7 >> 3);
+ r[ 0] = (byte)(t0 >> 0);
+ r[ 1] = (byte)((t0 >> 8) | (t1 << 3));
+ r[ 2] = (byte)((t1 >> 5) | (t2 << 6));
+ r[ 3] = (byte)(t2 >> 2);
+ r[ 4] = (byte)((t2 >> 10) | (t3 << 1));
+ r[ 5] = (byte)((t3 >> 7) | (t4 << 4));
+ r[ 6] = (byte)((t4 >> 4) | (t5 << 7));
+ r[ 7] = (byte)(t5 >> 1);
+ r[ 8] = (byte)((t5 >> 9) | (t6 << 2));
+ r[ 9] = (byte)((t6 >> 6) | (t7 << 5));
+ r[10] = (byte)(t7 >> 3);
#endif
/* Move over set bytes. */
@@ -5159,7 +5189,7 @@ void mlkem_vec_compress_11(byte* r, sword16* v)
*/
#define DECOMP_10(v, i, j, k, t) \
v[(i) * MLKEM_N + 4 * (j) + (k)] = \
- (word16)((((word32)((t) & 0x3ff) * MLKEM_Q) + 512) >> 10)
+ (sword16)((((word32)((t) & 0x3ff) * MLKEM_Q) + 512) >> 10)
/* Decompress an 11 bit value.
*
@@ -5174,7 +5204,7 @@ void mlkem_vec_compress_11(byte* r, sword16* v)
*/
#define DECOMP_11(v, i, j, k, t) \
v[(i) * MLKEM_N + 8 * (j) + (k)] = \
- (word16)((((word32)((t) & 0x7ff) * MLKEM_Q) + 1024) >> 11)
+ (sword16)((((word32)((t) & 0x7ff) * MLKEM_Q) + 1024) >> 11)
#if defined(WOLFSSL_KYBER512) || defined(WOLFSSL_WC_ML_KEM_512) || \
defined(WOLFSSL_KYBER768) || defined(WOLFSSL_WC_ML_KEM_768)
@@ -5201,10 +5231,10 @@ static void mlkem_vec_decompress_10_c(sword16* v, const byte* b, unsigned int k)
#ifdef WOLFSSL_MLKEM_SMALL
word16 t[4];
/* Extract out 4 values of 10 bits each. */
- t[0] = (b[0] >> 0) | ((word16)b[ 1] << 8);
- t[1] = (b[1] >> 2) | ((word16)b[ 2] << 6);
- t[2] = (b[2] >> 4) | ((word16)b[ 3] << 4);
- t[3] = (b[3] >> 6) | ((word16)b[ 4] << 2);
+ t[0] = (word16)((b[0] >> 0) | ((word16)b[ 1] << 8));
+ t[1] = (word16)((b[1] >> 2) | ((word16)b[ 2] << 6));
+ t[2] = (word16)((b[2] >> 4) | ((word16)b[ 3] << 4));
+ t[3] = (word16)((b[3] >> 6) | ((word16)b[ 4] << 2));
b += 5;
/* Decompress 4 values. */
@@ -5213,10 +5243,10 @@ static void mlkem_vec_decompress_10_c(sword16* v, const byte* b, unsigned int k)
}
#else
/* Extract out 4 values of 10 bits each. */
- sword16 t0 = (b[0] >> 0) | ((word16)b[ 1] << 8);
- sword16 t1 = (b[1] >> 2) | ((word16)b[ 2] << 6);
- sword16 t2 = (b[2] >> 4) | ((word16)b[ 3] << 4);
- sword16 t3 = (b[3] >> 6) | ((word16)b[ 4] << 2);
+ word16 t0 = (word16)((b[0] >> 0) | ((word16)b[ 1] << 8));
+ word16 t1 = (word16)((b[1] >> 2) | ((word16)b[ 2] << 6));
+ word16 t2 = (word16)((b[2] >> 4) | ((word16)b[ 3] << 4));
+ word16 t3 = (word16)((b[3] >> 6) | ((word16)b[ 4] << 2));
b += 5;
/* Decompress 4 values. */
@@ -5241,7 +5271,7 @@ void mlkem_vec_decompress_10(sword16* v, const byte* b, unsigned int k)
{
#ifdef USE_INTEL_SPEEDUP
if (IS_INTEL_AVX2(cpuid_flags) && (SAVE_VECTOR_REGISTERS2() == 0)) {
- mlkem_decompress_10_avx2(v, b, k);
+ mlkem_decompress_10_avx2(v, b, (int)k);
RESTORE_VECTOR_REGISTERS();
}
else
@@ -5274,16 +5304,16 @@ static void mlkem_vec_decompress_11_c(sword16* v, const byte* b)
#ifdef WOLFSSL_MLKEM_SMALL
word16 t[8];
/* Extract out 8 values of 11 bits each. */
- t[0] = (b[0] >> 0) | ((word16)b[ 1] << 8);
- t[1] = (b[1] >> 3) | ((word16)b[ 2] << 5);
- t[2] = (b[2] >> 6) | ((word16)b[ 3] << 2) |
- ((word16)b[4] << 10);
- t[3] = (b[4] >> 1) | ((word16)b[ 5] << 7);
- t[4] = (b[5] >> 4) | ((word16)b[ 6] << 4);
- t[5] = (b[6] >> 7) | ((word16)b[ 7] << 1) |
- ((word16)b[8] << 9);
- t[6] = (b[8] >> 2) | ((word16)b[ 9] << 6);
- t[7] = (b[9] >> 5) | ((word16)b[10] << 3);
+ t[0] = (word16)((b[0] >> 0) | ((word16)b[ 1] << 8));
+ t[1] = (word16)((b[1] >> 3) | ((word16)b[ 2] << 5));
+ t[2] = (word16)((b[2] >> 6) | ((word16)b[ 3] << 2) |
+ ((word16)b[4] << 10));
+ t[3] = (word16)((b[4] >> 1) | ((word16)b[ 5] << 7));
+ t[4] = (word16)((b[5] >> 4) | ((word16)b[ 6] << 4));
+ t[5] = (word16)((b[6] >> 7) | ((word16)b[ 7] << 1) |
+ ((word16)b[8] << 9));
+ t[6] = (word16)((b[8] >> 2) | ((word16)b[ 9] << 6));
+ t[7] = (word16)((b[9] >> 5) | ((word16)b[10] << 3));
b += 11;
/* Decompress 8 values. */
@@ -5292,16 +5322,16 @@ static void mlkem_vec_decompress_11_c(sword16* v, const byte* b)
}
#else
/* Extract out 8 values of 11 bits each. */
- sword16 t0 = (b[0] >> 0) | ((word16)b[ 1] << 8);
- sword16 t1 = (b[1] >> 3) | ((word16)b[ 2] << 5);
- sword16 t2 = (b[2] >> 6) | ((word16)b[ 3] << 2) |
- ((word16)b[4] << 10);
- sword16 t3 = (b[4] >> 1) | ((word16)b[ 5] << 7);
- sword16 t4 = (b[5] >> 4) | ((word16)b[ 6] << 4);
- sword16 t5 = (b[6] >> 7) | ((word16)b[ 7] << 1) |
- ((word16)b[8] << 9);
- sword16 t6 = (b[8] >> 2) | ((word16)b[ 9] << 6);
- sword16 t7 = (b[9] >> 5) | ((word16)b[10] << 3);
+ word16 t0 = (word16)((b[0] >> 0) | ((word16)b[ 1] << 8));
+ word16 t1 = (word16)((b[1] >> 3) | ((word16)b[ 2] << 5));
+ word16 t2 = (word16)((b[2] >> 6) | ((word16)b[ 3] << 2) |
+ ((word16)b[4] << 10));
+ word16 t3 = (word16)((b[4] >> 1) | ((word16)b[ 5] << 7));
+ word16 t4 = (word16)((b[5] >> 4) | ((word16)b[ 6] << 4));
+ word16 t5 = (word16)((b[6] >> 7) | ((word16)b[ 7] << 1) |
+ ((word16)b[8] << 9));
+ word16 t6 = (word16)((b[8] >> 2) | ((word16)b[ 9] << 6));
+ word16 t7 = (word16)((b[9] >> 5) | ((word16)b[10] << 3));
b += 11;
/* Decompress 8 values. */
@@ -5411,7 +5441,8 @@ void mlkem_vec_decompress_11(sword16* v, const byte* b)
* @return Compressed value.
*/
#define TO_COMP_WORD_4(p, i, j) \
- ((((MLKEM_V28 << 4) * (p)[(i) + (j)]) + MLKEM_V28_HALF) >> 28)
+ (byte)(((((MLKEM_V28 << 4) * (word32)(word16)((p)[(i) + (j)])) + \
+ MLKEM_V28_HALF) >> 28))
/* Compress value to 5 bits.
*
@@ -5425,7 +5456,8 @@ void mlkem_vec_decompress_11(sword16* v, const byte* b)
* @return Compressed value.
*/
#define TO_COMP_WORD_5(p, i, j) \
- ((((MLKEM_V27 << 5) * (p)[(i) + (j)]) + MLKEM_V27_HALF) >> 27)
+ (byte)(((((MLKEM_V27 << 5) * (word32)(word16)((p)[(i) + (j)])) + \
+ MLKEM_V27_HALF) >> 27))
#endif /* CONV_WITH_DIV */
@@ -5460,10 +5492,10 @@ static void mlkem_compress_4_c(byte* b, sword16* p)
t[j] = TO_COMP_WORD_4(p, i, j);
}
- b[0] = t[0] | (t[1] << 4);
- b[1] = t[2] | (t[3] << 4);
- b[2] = t[4] | (t[5] << 4);
- b[3] = t[6] | (t[7] << 4);
+ b[0] = (byte)(t[0] | (t[1] << 4));
+ b[1] = (byte)(t[2] | (t[3] << 4));
+ b[2] = (byte)(t[4] | (t[5] << 4));
+ b[3] = (byte)(t[6] | (t[7] << 4));
#else
/* Compress eight polynomial values to 4 bits each. */
byte t0 = TO_COMP_WORD_4(p, i, 0);
@@ -5476,10 +5508,10 @@ static void mlkem_compress_4_c(byte* b, sword16* p)
byte t7 = TO_COMP_WORD_4(p, i, 7);
/* Pack eight 4-bit values into byte array. */
- b[0] = t0 | (t1 << 4);
- b[1] = t2 | (t3 << 4);
- b[2] = t4 | (t5 << 4);
- b[3] = t6 | (t7 << 4);
+ b[0] = (byte)(t0 | (t1 << 4));
+ b[1] = (byte)(t2 | (t3 << 4));
+ b[2] = (byte)(t4 | (t5 << 4));
+ b[3] = (byte)(t6 | (t7 << 4));
#endif
/* Move over set bytes. */
@@ -5536,11 +5568,11 @@ static void mlkem_compress_5_c(byte* b, sword16* p)
}
/* Pack 5 bits into byte array. */
- b[0] = (t[0] >> 0) | (t[1] << 5);
- b[1] = (t[1] >> 3) | (t[2] << 2) | (t[3] << 7);
- b[2] = (t[3] >> 1) | (t[4] << 4);
- b[3] = (t[4] >> 4) | (t[5] << 1) | (t[6] << 6);
- b[4] = (t[6] >> 2) | (t[7] << 3);
+ b[0] = (byte)((t[0] >> 0) | (t[1] << 5));
+ b[1] = (byte)((t[1] >> 3) | (t[2] << 2) | (t[3] << 7));
+ b[2] = (byte)((t[3] >> 1) | (t[4] << 4));
+ b[3] = (byte)((t[4] >> 4) | (t[5] << 1) | (t[6] << 6));
+ b[4] = (byte)((t[6] >> 2) | (t[7] << 3));
#else
/* Compress eight polynomial values to 5 bits each. */
byte t0 = TO_COMP_WORD_5(p, i, 0);
@@ -5553,11 +5585,11 @@ static void mlkem_compress_5_c(byte* b, sword16* p)
byte t7 = TO_COMP_WORD_5(p, i, 7);
/* Pack eight 5-bit values into byte array. */
- b[0] = (t0 >> 0) | (t1 << 5);
- b[1] = (t1 >> 3) | (t2 << 2) | (t3 << 7);
- b[2] = (t3 >> 1) | (t4 << 4);
- b[3] = (t4 >> 4) | (t5 << 1) | (t6 << 6);
- b[4] = (t6 >> 2) | (t7 << 3);
+ b[0] = (byte)((t0 >> 0) | (t1 << 5));
+ b[1] = (byte)((t1 >> 3) | (t2 << 2) | (t3 << 7));
+ b[2] = (byte)((t3 >> 1) | (t4 << 4));
+ b[3] = (byte)((t4 >> 4) | (t5 << 1) | (t6 << 6));
+ b[4] = (byte)((t6 >> 2) | (t7 << 3));
#endif
/* Move over set bytes. */
@@ -5600,7 +5632,7 @@ void mlkem_compress_5(byte* b, sword16* p)
* @return Decompressed value.
*/
#define DECOMP_4(p, i, j, t) \
- p[(i) + (j)] = ((word16)((t) * MLKEM_Q) + 8) >> 4
+ p[(i) + (j)] = (sword16)(((word16)((t) * MLKEM_Q) + 8) >> 4)
/* Decompress a 5 bit value.
*
@@ -5613,7 +5645,7 @@ void mlkem_compress_5(byte* b, sword16* p)
* @return Decompressed value.
*/
#define DECOMP_5(p, i, j, t) \
- p[(i) + (j)] = (((word32)((t) & 0x1f) * MLKEM_Q) + 16) >> 5
+ p[(i) + (j)] = (sword16)((((word32)((t) & 0x1f) * MLKEM_Q) + 16) >> 5)
#if defined(WOLFSSL_KYBER512) || defined(WOLFSSL_WC_ML_KEM_512) || \
defined(WOLFSSL_KYBER768) || defined(WOLFSSL_WC_ML_KEM_768)
@@ -5678,12 +5710,12 @@ static void mlkem_decompress_5_c(sword16* p, const byte* b)
/* Extract out 8 values of 5 bits each. */
t[0] = (b[0] >> 0);
- t[1] = (b[0] >> 5) | (b[1] << 3);
+ t[1] = (byte)((b[0] >> 5) | (b[1] << 3));
t[2] = (b[1] >> 2);
- t[3] = (b[1] >> 7) | (b[2] << 1);
- t[4] = (b[2] >> 4) | (b[3] << 4);
+ t[3] = (byte)((b[1] >> 7) | (b[2] << 1));
+ t[4] = (byte)((b[2] >> 4) | (b[3] << 4));
t[5] = (b[3] >> 1);
- t[6] = (b[3] >> 6) | (b[4] << 2);
+ t[6] = (byte)((b[3] >> 6) | (b[4] << 2));
t[7] = (b[4] >> 3);
b += 5;
@@ -5694,12 +5726,12 @@ static void mlkem_decompress_5_c(sword16* p, const byte* b)
#else
/* Extract out 8 values of 5 bits each. */
byte t0 = (b[0] >> 0);
- byte t1 = (b[0] >> 5) | (b[1] << 3);
+ byte t1 = (byte)((b[0] >> 5) | (b[1] << 3));
byte t2 = (b[1] >> 2);
- byte t3 = (b[1] >> 7) | (b[2] << 1);
- byte t4 = (b[2] >> 4) | (b[3] << 4);
+ byte t3 = (byte)((b[1] >> 7) | (b[2] << 1));
+ byte t4 = (byte)((b[2] >> 4) | (b[3] << 4));
byte t5 = (b[3] >> 1);
- byte t6 = (b[3] >> 6) | (b[4] << 2);
+ byte t6 = (byte)((b[3] >> 6) | (b[4] << 2));
byte t7 = (b[4] >> 3);
b += 5;
@@ -5853,8 +5885,11 @@ void mlkem_from_msg(sword16* p, const byte* msg)
* @param [in] j Index of bit in byte.
*/
#define TO_MSG_BIT(m, p, i, j) \
- (m)[i] |= ((word32)((MLKEM_V31_2 * (p)[8 * (i) + (j)]) + \
- MLKEM_V31_HALF) >> 31) << (j)
+ do { \
+ word32 _t = ((((word32)(word16)((p)[8 * (i) + (j)])) * MLKEM_V31_2) + \
+ MLKEM_V31_HALF) >> 31; \
+ (m)[i] = (byte)((m)[i] | (byte)((_t & 1U) << (j))); \
+ } while (0)
#endif /* CONV_WITH_DIV */
@@ -6031,11 +6066,11 @@ static void mlkem_to_bytes_c(byte* b, sword16* p, int k)
/* All values are now positive. */
for (i = 0; i < MLKEM_N / 2; i++) {
- word16 t0 = p[2 * i];
- word16 t1 = p[2 * i + 1];
- b[3 * i + 0] = (t0 >> 0);
- b[3 * i + 1] = (t0 >> 8) | t1 << 4;
- b[3 * i + 2] = (t1 >> 4);
+ word16 t0 = (word16)p[2 * i];
+ word16 t1 = (word16)p[2 * i + 1];
+ b[3 * i + 0] = (byte)(t0 >> 0);
+ b[3 * i + 1] = (byte)((t0 >> 8) | (t1 << 4));
+ b[3 * i + 2] = (byte)(t1 >> 4);
}
p += MLKEM_N;
b += WC_ML_KEM_POLY_SIZE;
diff --git a/wolfcrypt/test/test.c b/wolfcrypt/test/test.c
index 8e340899e68..28f66dc7e84 100644
--- a/wolfcrypt/test/test.c
+++ b/wolfcrypt/test/test.c
@@ -46280,8 +46280,10 @@ static wc_test_ret_t mlkem1024_kat(void)
WOLFSSL_TEST_SUBROUTINE wc_test_ret_t mlkem_test(void)
{
wc_test_ret_t ret;
- WC_RNG rng;
int i;
+#ifndef WC_NO_RNG
+ WC_RNG rng;
+#endif
#ifdef WOLFSSL_SMALL_STACK
MlKemKey *key = NULL;
#ifndef WOLFSSL_MLKEM_NO_MAKE_KEY
@@ -46348,6 +46350,30 @@ WOLFSSL_TEST_SUBROUTINE wc_test_ret_t mlkem_test(void)
#endif
#endif
};
+#ifdef WC_NO_RNG
+#ifndef WOLFSSL_MLKEM_NO_MAKE_KEY
+ /* Fake random data for testing (from mlkem768_kat) */
+ WOLFSSL_SMALL_STACK_STATIC const byte make_key_rand[] = {
+ 0x7c, 0x99, 0x35, 0xa0, 0xb0, 0x76, 0x94, 0xaa,
+ 0x0c, 0x6d, 0x10, 0xe4, 0xdb, 0x6b, 0x1a, 0xdd,
+ 0x2f, 0xd8, 0x1a, 0x25, 0xcc, 0xb1, 0x48, 0x03,
+ 0x2d, 0xcd, 0x73, 0x99, 0x36, 0x73, 0x7f, 0x2d,
+ 0x86, 0x26, 0xED, 0x79, 0xD4, 0x51, 0x14, 0x08,
+ 0x00, 0xE0, 0x3B, 0x59, 0xB9, 0x56, 0xF8, 0x21,
+ 0x0E, 0x55, 0x60, 0x67, 0x40, 0x7D, 0x13, 0xDC,
+ 0x90, 0xFA, 0x9E, 0x8B, 0x87, 0x2B, 0xFB, 0x8F
+ };
+#ifndef WOLFSSL_MLKEM_NO_ENCAPSULATE
+ WOLFSSL_SMALL_STACK_STATIC const byte encap_rand[] = {
+ 0x14, 0x7c, 0x03, 0xf7, 0xa5, 0xbe, 0xbb, 0xa4,
+ 0x06, 0xc8, 0xfa, 0xe1, 0x87, 0x4d, 0x7f, 0x13,
+ 0xc8, 0x0e, 0xfe, 0x79, 0xa3, 0xa9, 0xa8, 0x74,
+ 0xcc, 0x09, 0xfe, 0x76, 0xf6, 0x99, 0x76, 0x15
+ };
+#endif
+#endif
+#endif
+
WOLFSSL_ENTER("mlkem_test");
#ifdef WOLFSSL_SMALL_STACK
@@ -46391,6 +46417,7 @@ WOLFSSL_TEST_SUBROUTINE wc_test_ret_t mlkem_test(void)
#endif
#endif
+#ifndef WC_NO_RNG
#ifndef HAVE_FIPS
ret = wc_InitRng_ex(&rng, HEAP_HINT, devId);
#else
@@ -46398,6 +46425,7 @@ WOLFSSL_TEST_SUBROUTINE wc_test_ret_t mlkem_test(void)
#endif
if (ret != 0)
ERROR_OUT(WC_TEST_RET_ENC_EC(ret), out);
+#endif /* WC_NO_RNG */
for (i = 0; i < (int)(sizeof(testData) / sizeof(*testData)); i++) {
ret = wc_MlKemKey_Init(key, testData[i][0], HEAP_HINT, devId);
@@ -46407,7 +46435,12 @@ WOLFSSL_TEST_SUBROUTINE wc_test_ret_t mlkem_test(void)
key_inited = 1;
#ifndef WOLFSSL_MLKEM_NO_MAKE_KEY
+ #ifndef WC_NO_RNG
ret = wc_MlKemKey_MakeKey(key, &rng);
+ #else
+ ret = wc_MlKemKey_MakeKeyWithRandom(key, make_key_rand,
+ sizeof(make_key_rand));
+ #endif
if (ret != 0)
ERROR_OUT(WC_TEST_RET_ENC_I(i), out);
@@ -46428,7 +46461,12 @@ WOLFSSL_TEST_SUBROUTINE wc_test_ret_t mlkem_test(void)
ERROR_OUT(WC_TEST_RET_ENC_I(i), out);
#ifndef WOLFSSL_MLKEM_NO_ENCAPSULATE
+ #ifndef WC_NO_RNG
ret = wc_MlKemKey_Encapsulate(key, ct, ss, &rng);
+ #else
+ ret = wc_MlKemKey_EncapsulateWithRandom(key, ct, ss, encap_rand,
+ sizeof(encap_rand));
+ #endif
if (ret != 0)
ERROR_OUT(WC_TEST_RET_ENC_I(i), out);
#endif
diff --git a/wolfssl/internal.h b/wolfssl/internal.h
index 82073421fa5..57e9aa3d520 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,
@@ -3606,6 +3607,8 @@ WOLFSSL_LOCAL int TLSX_KeyShare_Parse(WOLFSSL* ssl, const byte* input,
word16 length, byte msgType);
WOLFSSL_LOCAL int TLSX_KeyShare_Parse_ClientHello(const WOLFSSL* ssl,
const byte* input, word16 length, TLSX** extensions);
+WOLFSSL_LOCAL int TLSX_KeyShare_HandlePqcHybridKeyServer(WOLFSSL* ssl,
+ KeyShareEntry* keyShareEntry, byte* data, word16 len);
#ifdef WOLFSSL_DUAL_ALG_CERTS
WOLFSSL_LOCAL int TLSX_CKS_Parse(WOLFSSL* ssl, byte* input,
word16 length, TLSX** extensions);
diff --git a/wolfssl/ssl.h b/wolfssl/ssl.h
index ed88c090024..1e2660097c5 100644
--- a/wolfssl/ssl.h
+++ b/wolfssl/ssl.h
@@ -4684,16 +4684,15 @@ 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/07/
*/
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/04/
*/
WOLFSSL_SECP256R1MLKEM768 = 4587,
WOLFSSL_X25519MLKEM768 = 4588,
diff --git a/wolfssl/wolfcrypt/memory.h b/wolfssl/wolfcrypt/memory.h
index bb626504019..4fa63220b7e 100644
--- a/wolfssl/wolfcrypt/memory.h
+++ b/wolfssl/wolfcrypt/memory.h
@@ -175,15 +175,25 @@ WOLFSSL_API int wolfSSL_GetAllocators(wolfSSL_Malloc_cb* mf,
#define WOLFMEM_BUCKETS 64,128,256,512,1024,8192,32768,\
65536,LARGEST_MEM_BUCKET
#endif
+ #elif defined(WOLFSSL_HAVE_MLKEM)
+ /* extra storage in structs for multiple attributes and order */
+ #define WOLFMEM_BUCKETS 64,128,256,512,1024,2432,4096,8192,\
+ LARGEST_MEM_BUCKET
#else
/* default size of chunks of memory to separate into */
#define WOLFMEM_BUCKETS 64,128,256,512,1024,2432,3456,4544,\
LARGEST_MEM_BUCKET
#endif
#elif defined(OPENSSL_EXTRA)
- /* extra storage in structs for multiple attributes and order */
- #define WOLFMEM_BUCKETS 64,128,256,512,1024,2432,3360,4480,\
- LARGEST_MEM_BUCKET
+ #ifdef WOLFSSL_HAVE_MLKEM
+ /* extra storage in structs for multiple attributes and order */
+ #define WOLFMEM_BUCKETS 64,128,256,512,1024,2432,4096,8192,\
+ LARGEST_MEM_BUCKET
+ #else
+ /* extra storage in structs for multiple attributes and order */
+ #define WOLFMEM_BUCKETS 64,128,256,512,1024,2432,3360,4480,\
+ LARGEST_MEM_BUCKET
+ #endif
#elif defined(WOLFSSL_CERT_EXT)
#define WOLFMEM_BUCKETS 64,128,256,512,1024,2432,3456,4544,\
LARGEST_MEM_BUCKET
@@ -204,7 +214,7 @@ WOLFSSL_API int wolfSSL_GetAllocators(wolfSSL_Malloc_cb* mf,
#define WOLFMEM_DIST 30,10,8,15,8,10,8,5,1
#endif
#elif !defined(WOLFSSL_STATIC_MEMORY_SMALL)
- #define WOLFMEM_DIST 49,10,6,14,5,6,9,1,1
+ #define WOLFMEM_DIST 49,10,6,14,5,6,16,1,1
#else
/* Low resource and not RSA */
#define WOLFMEM_DIST 29, 7,6, 9,4,4,0,0,0
diff --git a/wolfssl/wolfcrypt/settings.h b/wolfssl/wolfcrypt/settings.h
index 49301a4d3af..6427c18f45b 100644
--- a/wolfssl/wolfcrypt/settings.h
+++ b/wolfssl/wolfcrypt/settings.h
@@ -4488,15 +4488,20 @@ extern void uITRON4_free(void *p) ;
#define WOLFSSL_DILITHIUM_VERIFY_NO_MALLOC
#endif
-#if defined(HAVE_PQC) && defined(WOLFSSL_DTLS13) && \
- !defined(WOLFSSL_DTLS_CH_FRAG)
-#warning "Using DTLS 1.3 + pqc without WOLFSSL_DTLS_CH_FRAG will probably" \
- "fail.Use --enable-dtls-frag-ch to enable it."
+#if defined(HAVE_PQC) && defined(WOLFSSL_HAVE_MLKEM) && \
+ defined(WOLFSSL_DTLS13) && !defined(WOLFSSL_DTLS_CH_FRAG)
+#define WOLFSSL_DTLS_CH_FRAG
#endif
#if !defined(WOLFSSL_DTLS13) && defined(WOLFSSL_DTLS_CH_FRAG)
#error "WOLFSSL_DTLS_CH_FRAG only works with DTLS 1.3"
#endif
+#if defined(HAVE_PQC) && defined(WOLFSSL_HAVE_MLKEM) && \
+ !defined(WOLFSSL_PQC_HYBRIDS) && defined(WOLFSSL_TLS_NO_MLKEM_STANDALONE)
+#error "Neither PQ/T hybrid combinations nor ML-KEM as standalone TLS key "
+ "exchange are enabled"
+#endif
+
/* SRTP requires DTLS */
#if defined(WOLFSSL_SRTP) && !defined(WOLFSSL_DTLS)
#error The SRTP extension requires DTLS
diff --git a/zephyr/Kconfig b/zephyr/Kconfig
index 9863454ffcd..ea5be59afa2 100644
--- a/zephyr/Kconfig
+++ b/zephyr/Kconfig
@@ -85,6 +85,11 @@ config WOLFSSL_PSK
help
Enable PSK support
+config WOLFSSL_MLKEM
+ bool "wolfSSL PQC ML-KEM support"
+ help
+ Enable PQC ML-KEM support for Key Exchange
+
config WOLFSSL_MAX_FRAGMENT_LEN
int
default 3
diff --git a/zephyr/samples/wolfssl_tls_sock/prj.conf b/zephyr/samples/wolfssl_tls_sock/prj.conf
index 549bc07ab0b..4c61e750626 100644
--- a/zephyr/samples/wolfssl_tls_sock/prj.conf
+++ b/zephyr/samples/wolfssl_tls_sock/prj.conf
@@ -55,3 +55,4 @@ CONFIG_WOLFSSL_KEY_EXCHANGE_ALL_ENABLED=y
CONFIG_WOLFSSL_CIPHER_ALL_ENABLED=y
CONFIG_WOLFSSL_MAC_ALL_ENABLED=y
CONFIG_WOLFSSL_HMAC_DRBG_ENABLED=y
+CONFIG_WOLFSSL_MLKEM=y
diff --git a/zephyr/samples/wolfssl_tls_thread/prj.conf b/zephyr/samples/wolfssl_tls_thread/prj.conf
index 185a7b24c07..5a7024210f7 100644
--- a/zephyr/samples/wolfssl_tls_thread/prj.conf
+++ b/zephyr/samples/wolfssl_tls_thread/prj.conf
@@ -41,3 +41,4 @@ CONFIG_WOLFSSL_KEY_EXCHANGE_ALL_ENABLED=y
CONFIG_WOLFSSL_CIPHER_ALL_ENABLED=y
CONFIG_WOLFSSL_MAC_ALL_ENABLED=y
CONFIG_WOLFSSL_HMAC_DRBG_ENABLED=y
+CONFIG_WOLFSSL_MLKEM=y
diff --git a/zephyr/user_settings.h b/zephyr/user_settings.h
index 4d7e2ebd061..c390aa9f336 100644
--- a/zephyr/user_settings.h
+++ b/zephyr/user_settings.h
@@ -333,9 +333,21 @@ extern "C" {
#define NO_MD4
#define NO_MD5
//#define NO_DES3 /* Necessary for pkcs12 tests */
-#define WOLFSSL_NO_SHAKE128
-#define WOLFSSL_NO_SHAKE256
+/* PQC ML-KEM */
+#if defined(CONFIG_WOLFSSL_MLKEM)
+ #define WOLFSSL_HAVE_MLKEM
+ #define WOLFSSL_WC_MLKEM
+ #define WOLFSSL_MLKEM_NO_LARGE_CODE
+ #define WOLFSSL_MLKEM_SMALL
+ #define WOLFSSL_MLKEM_MAKEKEY_SMALL_MEM
+ #define WOLFSSL_MLKEM_ENCAPSULATE_SMALL_MEM
+ #define WOLFSSL_SHAKE128
+ #define WOLFSSL_SHAKE256
+#else
+ #define WOLFSSL_NO_SHAKE128
+ #define WOLFSSL_NO_SHAKE256
+#endif
/* ------------------------------------------------------------------------- */