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/pq-all.yml b/.github/workflows/pq-all.yml
index 73404dda706..fee8d7e076e 100644
--- a/.github/workflows/pq-all.yml
+++ b/.github/workflows/pq-all.yml
@@ -27,6 +27,13 @@ jobs:
'--enable-intelasm --enable-sp-asm --enable-all --enable-testcert --enable-acert --enable-dtls13 --enable-dtls-mtu --enable-dtls-frag-ch --enable-dtlscid --enable-quic --with-sys-crypto-policy --enable-experimental --enable-mlkem=yes,kyber,ml-kem --enable-lms --enable-xmss --enable-dilithium --enable-dual-alg-certs --disable-qt CPPFLAGS="-pedantic -Wdeclaration-after-statement -DWOLFCRYPT_TEST_LINT -DNO_WOLFSSL_CIPHER_SUITE_TEST -DTEST_LIBWOLFSSL_SOURCES_INCLUSION_SEQUENCE -DWOLFSSL_TLSX_PQC_MLKEM_STORE_OBJ"',
'--disable-intelasm --enable-all --enable-testcert --enable-acert --enable-dtls13 --enable-dtls-mtu --enable-dtls-frag-ch --enable-dtlscid --enable-quic --with-sys-crypto-policy --enable-experimental --enable-mlkem=yes,kyber,ml-kem,small --enable-lms=yes,small --enable-xmss=yes,small --enable-dilithium=yes,small --enable-dual-alg-certs --disable-qt CPPFLAGS="-pedantic -Wdeclaration-after-statement -DWOLFCRYPT_TEST_LINT -DNO_WOLFSSL_CIPHER_SUITE_TEST -DTEST_LIBWOLFSSL_SOURCES_INCLUSION_SEQUENCE -DWOLFSSL_MLKEM_MAKEKEY_SMALL_MEM -DWOLFSSL_MLKEM_ENCAPSULATE_SMALL_MEM -DWOLFSSL_MLKEM_NO_LARGE_CODE -DWOLFSSL_DILITHIUM_SIGN_SMALL_MEM -DWOLFSSL_DILITHIUM_VERIFY_SMALL_MEM -DWOLFSSL_DILITHIUM_MAKE_KEY_SMALL_MEM -DWOLFSSL_DILITHIUM_NO_LARGE_CODE"',
'--disable-intelasm --enable-smallstack --enable-smallstackcache --enable-all --enable-testcert --enable-acert --enable-dtls13 --enable-dtls-mtu --enable-dtls-frag-ch --enable-dtlscid --enable-quic --with-sys-crypto-policy --enable-experimental --enable-mlkem=yes,kyber,ml-kem,small --enable-lms=yes,small --enable-xmss=yes,small --enable-dilithium=yes,small --enable-dual-alg-certs --disable-qt CPPFLAGS="-pedantic -Wdeclaration-after-statement -DWOLFCRYPT_TEST_LINT -DNO_WOLFSSL_CIPHER_SUITE_TEST -DTEST_LIBWOLFSSL_SOURCES_INCLUSION_SEQUENCE -DWOLFSSL_MLKEM_MAKEKEY_SMALL_MEM -DWOLFSSL_MLKEM_ENCAPSULATE_SMALL_MEM -DWOLFSSL_MLKEM_NO_LARGE_CODE -DWOLFSSL_DILITHIUM_SIGN_SMALL_MEM -DWOLFSSL_DILITHIUM_VERIFY_SMALL_MEM -DWOLFSSL_DILITHIUM_MAKE_KEY_SMALL_MEM -DWOLFSSL_DILITHIUM_NO_LARGE_CODE"',
+ '--enable-intelasm --enable-sp-asm --enable-all --enable-testcert --enable-dtls13 --enable-dtls-mtu --enable-dtls-frag-ch --enable-dtlscid --enable-mlkem=make,enc,dec,512 --enable-tls-mlkem-standalone --disable-qt CPPFLAGS="-pedantic -Wdeclaration-after-statement -DWOLFCRYPT_TEST_LINT -DNO_WOLFSSL_CIPHER_SUITE_TEST -DTEST_LIBWOLFSSL_SOURCES_INCLUSION_SEQUENCE"',
+ '--enable-intelasm --enable-sp-asm --enable-all --enable-testcert --enable-dtls13 --enable-dtls-mtu --enable-dtls-frag-ch --enable-dtlscid --enable-mlkem=make,enc,dec,768 --disable-qt CPPFLAGS="-pedantic -Wdeclaration-after-statement -DWOLFCRYPT_TEST_LINT -DNO_WOLFSSL_CIPHER_SUITE_TEST -DTEST_LIBWOLFSSL_SOURCES_INCLUSION_SEQUENCE"',
+ '--enable-intelasm --enable-sp-asm --enable-all --enable-testcert --enable-dtls13 --enable-dtls-mtu --enable-dtls-frag-ch --enable-dtlscid --enable-mlkem=make,enc,dec,768 --enable-tls-mlkem-standalone --disable-qt CPPFLAGS="-pedantic -Wdeclaration-after-statement -DWOLFCRYPT_TEST_LINT -DNO_WOLFSSL_CIPHER_SUITE_TEST -DTEST_LIBWOLFSSL_SOURCES_INCLUSION_SEQUENCE"',
+ '--enable-intelasm --enable-sp-asm --enable-all --enable-testcert --enable-dtls13 --enable-dtls-mtu --enable-dtls-frag-ch --enable-dtlscid --enable-mlkem=make,enc,dec,768 --enable-tls-mlkem-standalone --disable-pqc-hybrids --disable-qt CPPFLAGS="-pedantic -Wdeclaration-after-statement -DWOLFCRYPT_TEST_LINT -DNO_WOLFSSL_CIPHER_SUITE_TEST -DTEST_LIBWOLFSSL_SOURCES_INCLUSION_SEQUENCE"',
+ '--enable-intelasm --enable-sp-asm --enable-all --enable-testcert --enable-dtls13 --enable-dtls-mtu --enable-dtls-frag-ch --enable-dtlscid --enable-mlkem=make,enc,dec,1024 --disable-qt CPPFLAGS="-pedantic -Wdeclaration-after-statement -DWOLFCRYPT_TEST_LINT -DNO_WOLFSSL_CIPHER_SUITE_TEST -DTEST_LIBWOLFSSL_SOURCES_INCLUSION_SEQUENCE"',
+ '--enable-intelasm --enable-sp-asm --enable-all --enable-testcert --enable-dtls13 --enable-dtls-mtu --enable-dtls-frag-ch --enable-dtlscid --enable-mlkem=make,enc,dec,1024 --enable-tls-mlkem-standalone --disable-qt CPPFLAGS="-pedantic -Wdeclaration-after-statement -DWOLFCRYPT_TEST_LINT -DNO_WOLFSSL_CIPHER_SUITE_TEST -DTEST_LIBWOLFSSL_SOURCES_INCLUSION_SEQUENCE"',
+ '--enable-intelasm --enable-sp-asm --enable-all --enable-testcert --enable-dtls13 --enable-dtls-mtu --enable-dtls-frag-ch --enable-dtlscid --enable-mlkem=make,enc,dec,1024 --enable-tls-mlkem-standalone --disable-pqc-hybrids --disable-qt CPPFLAGS="-pedantic -Wdeclaration-after-statement -DWOLFCRYPT_TEST_LINT -DNO_WOLFSSL_CIPHER_SUITE_TEST -DTEST_LIBWOLFSSL_SOURCES_INCLUSION_SEQUENCE"',
]
name: make check
if: github.repository_owner == 'wolfssl'
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..b0ed1ed79e6 100644
--- a/.github/workflows/wolfCrypt-Wconversion.yml
+++ b/.github/workflows/wolfCrypt-Wconversion.yml
@@ -23,7 +23,12 @@ 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"',
+ '--disable-intelasm --enable-cryptonly --enable-all-crypto --disable-examples --disable-benchmark --disable-crypttests CPPFLAGS="-DWOLFSSL_MLKEM_ENCAPSULATE_SMALL_MEM -DWOLFSSL_MLKEM_MAKEKEY_SMALL_MEM -Wdeclaration-after-statement -Wconversion -Warith-conversion -Wenum-conversion -Wfloat-conversion -Wsign-conversion" --enable-32bit CFLAGS=-m32',
+ '--disable-intelasm --enable-cryptonly --enable-all-crypto --disable-examples --disable-benchmark --disable-crypttests --enable-mlkem=yes,small CPPFLAGS="-DWOLFSSL_MLKEM_ENCAPSULATE_SMALL_MEM -DWOLFSSL_MLKEM_MAKEKEY_SMALL_MEM -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 9611aed33f3..61df23fb7dc 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 c1ba00568ca..3da2b37c397 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
@@ -410,6 +412,10 @@ extern "C" {
#cmakedefine HAVE_SECRET_CALLBACK
#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 bc0af28bbfe..62cedad7bb2 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,61 @@ 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
+ elif test "$ENABLED_MLKEM768" = "" && test "$ENABLED_MLKEM1024" = ""; then
+ AC_MSG_NOTICE([PQC hybrid combinations require either ML-KEM 768 or ML-KEM 1024, but both disabled.])
+ ENABLED_PQC_HYBRIDS=no
+ else
+ AM_CFLAGS="$AM_CFLAGS -DWOLFSSL_PQC_HYBRIDS"
+ fi
+fi
+
+if test "$ENABLED_MLKEM" != "no"
+then
+ if test "$ENABLED_PQC_HYBRIDS" = "no" && test "$ENABLED_MLKEM_STANDALONE" = "no" && test "$ENABLED_CRYPTONLY" = "no"
+ then
+ AC_MSG_ERROR([Both hybrid PQ/T and standalone ML-KEM are disabled, so no PQC hybrid combinations will be available.])
+ fi
+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 +4508,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 +4526,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 +4544,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)])],
@@ -5645,6 +5741,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)])],
@@ -11857,6 +11962,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 25355943683..85645224fdb 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 cbd651de352..ab7bb3ab108 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 21f5380e73a..b25445272ec 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 59bcc2046d8..7935b9c4d0d 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 eb59f8133ca..bb82e794c2b 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 */
@@ -35087,21 +35096,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:
@@ -35116,6 +35132,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 aa6b8e85156..a0f729f92c1 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";
@@ -16812,22 +16828,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 207c873b466..5cd7055484c 100644
--- a/src/tls.c
+++ b/src/tls.c
@@ -4378,7 +4378,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
@@ -4490,37 +4490,54 @@ 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
- break;
- #endif
+ #endif /* HAVE_CURVE25519 */
+ #endif /* WOLFSSL_EXTRA_PQC_HYBRIDS */
+ break;
+ #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
- break;
- #endif
+ #endif /* HAVE_CURVE448 */
+ #endif /* WOLFSSL_EXTRA_PQC_HYBRIDS */
+ break;
+ #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:
@@ -5827,7 +5844,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);
@@ -5843,7 +5861,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;
@@ -8215,26 +8233,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
@@ -8242,13 +8256,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
@@ -8256,7 +8268,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
@@ -8264,7 +8275,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
@@ -8273,6 +8283,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);
@@ -8466,6 +8485,11 @@ static int mlkem_id2type(int id, int *type)
}
#endif
+#if defined(WOLFSSL_NO_ML_KEM_768) && defined(WOLFSSL_NO_ML_KEM_1024) && \
+ defined(WOLFSSL_PQC_HYBRIDS)
+ #error "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 {
@@ -8477,23 +8501,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},
@@ -8746,6 +8780,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);
@@ -8761,7 +8810,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 */
@@ -9758,7 +9817,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
@@ -9893,6 +9951,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
@@ -9902,36 +9963,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;
}
@@ -9940,7 +10011,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;
@@ -9952,7 +10023,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);
@@ -10058,10 +10129,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
@@ -10198,7 +10271,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
@@ -10460,6 +10533,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;
@@ -10477,7 +10551,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
@@ -10497,7 +10571,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.");
@@ -10521,14 +10594,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);
@@ -10564,10 +10640,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);
@@ -10583,7 +10675,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) {
@@ -10619,9 +10726,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;
@@ -10632,31 +10736,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;
}
@@ -10665,7 +10782,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;
@@ -10680,7 +10797,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;
@@ -10696,6 +10813,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;
@@ -10745,7 +10863,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 &&
@@ -10756,7 +10875,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;
@@ -10774,23 +10893,40 @@ 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,
- data, len);
- if (ret != 0)
- return ret;
+ if (TLSX_IsGroupSupported(group)) {
+ ret = TLSX_KeyShare_HandlePqcHybridKeyServer((WOLFSSL*)ssl,
+ keyShareEntry,
+ data, len);
+ if (ret != 0)
+ return ret;
+ }
+ else {
+ XFREE(keyShareEntry->ke, ssl->heap, DYNAMIC_TYPE_PUBLIC_KEY);
+ keyShareEntry->ke = NULL;
+ keyShareEntry->keLen = 0;
+ }
}
else
+#endif
#endif
if (data != NULL) {
XFREE(keyShareEntry->ke, ssl->heap, DYNAMIC_TYPE_PUBLIC_KEY);
@@ -10838,21 +10974,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
@@ -10861,81 +11015,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,
@@ -10948,27 +11086,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
};
@@ -11005,7 +11129,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 &&
@@ -11385,8 +11510,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;
@@ -11394,6 +11522,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);
@@ -14439,144 +14574,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
@@ -14612,154 +14796,93 @@ static int TLSX_PopulateSupportedGroups(WOLFSSL* ssl, TLSX** extensions)
#endif /* HAVE_ECC */
#ifndef NO_DH
- /* Add FFDHE supported groups. */
- #ifdef HAVE_FFDHE_8192
- if (8192/8 >= ssl->options.minDhKeySz &&
- 8192/8 <= ssl->options.maxDhKeySz) {
- ret = TLSX_UseSupportedCurve(extensions,
- WOLFSSL_FFDHE_8192, ssl->heap);
- if (ret != WOLFSSL_SUCCESS)
- return ret;
- }
- #endif
- #ifdef HAVE_FFDHE_6144
- if (6144/8 >= ssl->options.minDhKeySz &&
- 6144/8 <= ssl->options.maxDhKeySz) {
- ret = TLSX_UseSupportedCurve(extensions,
- WOLFSSL_FFDHE_6144, ssl->heap);
- if (ret != WOLFSSL_SUCCESS)
- return ret;
- }
- #endif
- #ifdef HAVE_FFDHE_4096
- if (4096/8 >= ssl->options.minDhKeySz &&
- 4096/8 <= ssl->options.maxDhKeySz) {
- ret = TLSX_UseSupportedCurve(extensions,
- WOLFSSL_FFDHE_4096, ssl->heap);
- if (ret != WOLFSSL_SUCCESS)
- return ret;
- }
- #endif
- #ifdef HAVE_FFDHE_3072
- if (3072/8 >= ssl->options.minDhKeySz &&
- 3072/8 <= ssl->options.maxDhKeySz) {
- ret = TLSX_UseSupportedCurve(extensions,
- WOLFSSL_FFDHE_3072, ssl->heap);
- if (ret != WOLFSSL_SUCCESS)
- return ret;
- }
- #endif
- #ifdef HAVE_FFDHE_2048
- if (2048/8 >= ssl->options.minDhKeySz &&
- 2048/8 <= ssl->options.maxDhKeySz) {
- ret = TLSX_UseSupportedCurve(extensions,
- WOLFSSL_FFDHE_2048, ssl->heap);
- if (ret != WOLFSSL_SUCCESS)
- return ret;
- }
- #endif
+ /* Add FFDHE supported groups. */
+ #ifdef HAVE_FFDHE_8192
+ if (8192/8 >= ssl->options.minDhKeySz &&
+ 8192/8 <= ssl->options.maxDhKeySz) {
+ ret = TLSX_UseSupportedCurve(extensions,
+ WOLFSSL_FFDHE_8192, ssl->heap);
+ if (ret != WOLFSSL_SUCCESS)
+ return ret;
+ }
+ #endif
+ #ifdef HAVE_FFDHE_6144
+ if (6144/8 >= ssl->options.minDhKeySz &&
+ 6144/8 <= ssl->options.maxDhKeySz) {
+ ret = TLSX_UseSupportedCurve(extensions,
+ WOLFSSL_FFDHE_6144, ssl->heap);
+ if (ret != WOLFSSL_SUCCESS)
+ return ret;
+ }
+ #endif
+ #ifdef HAVE_FFDHE_4096
+ if (4096/8 >= ssl->options.minDhKeySz &&
+ 4096/8 <= ssl->options.maxDhKeySz) {
+ ret = TLSX_UseSupportedCurve(extensions,
+ WOLFSSL_FFDHE_4096, ssl->heap);
+ if (ret != WOLFSSL_SUCCESS)
+ return ret;
+ }
+ #endif
+ #ifdef HAVE_FFDHE_3072
+ if (3072/8 >= ssl->options.minDhKeySz &&
+ 3072/8 <= ssl->options.maxDhKeySz) {
+ ret = TLSX_UseSupportedCurve(extensions,
+ WOLFSSL_FFDHE_3072, ssl->heap);
+ if (ret != WOLFSSL_SUCCESS)
+ return ret;
+ }
+ #endif
+ #ifdef HAVE_FFDHE_2048
+ if (2048/8 >= ssl->options.minDhKeySz &&
+ 2048/8 <= ssl->options.maxDhKeySz) {
+ ret = TLSX_UseSupportedCurve(extensions,
+ WOLFSSL_FFDHE_2048, ssl->heap);
+ if (ret != WOLFSSL_SUCCESS)
+ return ret;
+ }
+ #endif
#endif
#ifdef WOLFSSL_HAVE_MLKEM
#ifndef WOLFSSL_NO_ML_KEM
-#ifdef WOLFSSL_WC_MLKEM
-#ifndef WOLFSSL_NO_ML_KEM_512
- if (ret == WOLFSSL_SUCCESS)
- ret = TLSX_UseSupportedCurve(extensions, WOLFSSL_ML_KEM_512,
- ssl->heap);
- if (ret == WOLFSSL_SUCCESS)
- ret = TLSX_UseSupportedCurve(extensions, WOLFSSL_SECP256R1MLKEM512,
- ssl->heap);
- #if defined(HAVE_CURVE25519) && ECC_MIN_KEY_SZ <= 256
+#if !defined(WOLFSSL_NO_ML_KEM_1024) && \
+ defined(WOLFSSL_EXTRA_PQC_HYBRIDS)
if (ret == WOLFSSL_SUCCESS)
- ret = TLSX_UseSupportedCurve(extensions, WOLFSSL_X25519MLKEM512,
+ ret = TLSX_UseSupportedCurve(extensions, WOLFSSL_SECP521R1MLKEM1024,
ssl->heap);
- #endif
#endif
-#ifndef WOLFSSL_NO_ML_KEM_768
- if (ret == WOLFSSL_SUCCESS)
- ret = TLSX_UseSupportedCurve(extensions, WOLFSSL_ML_KEM_768,
- ssl->heap);
+#if !defined(WOLFSSL_NO_ML_KEM_768) && \
+ defined(WOLFSSL_EXTRA_PQC_HYBRIDS)
if (ret == WOLFSSL_SUCCESS)
ret = TLSX_UseSupportedCurve(extensions, WOLFSSL_SECP384R1MLKEM768,
ssl->heap);
- if (ret == WOLFSSL_SUCCESS)
- ret = TLSX_UseSupportedCurve(extensions, WOLFSSL_SECP256R1MLKEM768,
- ssl->heap);
- #if defined(HAVE_CURVE25519) && ECC_MIN_KEY_SZ <= 256
- if (ret == WOLFSSL_SUCCESS)
- ret = TLSX_UseSupportedCurve(extensions, WOLFSSL_X25519MLKEM768,
- ssl->heap);
- #endif
#if defined(HAVE_CURVE448) && ECC_MIN_KEY_SZ <= 448
if (ret == WOLFSSL_SUCCESS)
ret = TLSX_UseSupportedCurve(extensions, WOLFSSL_X448MLKEM768,
ssl->heap);
- #endif
+ #endif /* HAVE_CURVE448 */
#endif
-#ifndef WOLFSSL_NO_ML_KEM_1024
- if (ret == WOLFSSL_SUCCESS)
- ret = TLSX_UseSupportedCurve(extensions, WOLFSSL_ML_KEM_1024,
- ssl->heap);
- if (ret == WOLFSSL_SUCCESS)
- ret = TLSX_UseSupportedCurve(extensions, WOLFSSL_SECP521R1MLKEM1024,
- ssl->heap);
- if (ret == WOLFSSL_SUCCESS)
- ret = TLSX_UseSupportedCurve(extensions, WOLFSSL_SECP384R1MLKEM1024,
- ssl->heap);
-#endif
-#elif defined(HAVE_LIBOQS)
- ret = TLSX_UseSupportedCurve(extensions, WOLFSSL_ML_KEM_512, ssl->heap);
- if (ret == WOLFSSL_SUCCESS)
- ret = TLSX_UseSupportedCurve(extensions, WOLFSSL_ML_KEM_768,
- ssl->heap);
- if (ret == WOLFSSL_SUCCESS)
- ret = TLSX_UseSupportedCurve(extensions, WOLFSSL_ML_KEM_1024,
- ssl->heap);
+#if !defined(WOLFSSL_NO_ML_KEM_512) && \
+ defined(WOLFSSL_EXTRA_PQC_HYBRIDS)
if (ret == WOLFSSL_SUCCESS)
ret = TLSX_UseSupportedCurve(extensions, WOLFSSL_SECP256R1MLKEM512,
ssl->heap);
- if (ret == WOLFSSL_SUCCESS)
- ret = TLSX_UseSupportedCurve(extensions, WOLFSSL_SECP384R1MLKEM768,
- ssl->heap);
- if (ret == WOLFSSL_SUCCESS)
- ret = TLSX_UseSupportedCurve(extensions, WOLFSSL_SECP256R1MLKEM768,
- ssl->heap);
- if (ret == WOLFSSL_SUCCESS)
- ret = TLSX_UseSupportedCurve(extensions, WOLFSSL_SECP521R1MLKEM1024,
- ssl->heap);
- if (ret == WOLFSSL_SUCCESS)
- ret = TLSX_UseSupportedCurve(extensions, WOLFSSL_SECP384R1MLKEM1024,
- ssl->heap);
#if defined(HAVE_CURVE25519) && ECC_MIN_KEY_SZ <= 256
if (ret == WOLFSSL_SUCCESS)
ret = TLSX_UseSupportedCurve(extensions, WOLFSSL_X25519MLKEM512,
ssl->heap);
- if (ret == WOLFSSL_SUCCESS)
- ret = TLSX_UseSupportedCurve(extensions, WOLFSSL_X25519MLKEM768,
- ssl->heap);
- #endif
- #if defined(HAVE_CURVE448) && ECC_MIN_KEY_SZ <= 448
- if (ret == WOLFSSL_SUCCESS)
- ret = TLSX_UseSupportedCurve(extensions, WOLFSSL_X448MLKEM768,
- ssl->heap);
- #endif
-#endif /* HAVE_LIBOQS */
+ #endif /* HAVE_CURVE25519 */
+#endif
#endif /* !WOLFSSL_NO_ML_KEM */
#ifdef WOLFSSL_MLKEM_KYBER
-#ifdef WOLFSSL_WC_MLKEM
-#ifdef WOLFSSL_KYBER512
- if (ret == WOLFSSL_SUCCESS)
- ret = TLSX_UseSupportedCurve(extensions, WOLFSSL_KYBER_LEVEL1,
- ssl->heap);
+#ifdef WOLFSSL_KYBER1024
if (ret == WOLFSSL_SUCCESS)
- ret = TLSX_UseSupportedCurve(extensions, WOLFSSL_P256_KYBER_LEVEL1,
+ ret = TLSX_UseSupportedCurve(extensions, WOLFSSL_KYBER_LEVEL5,
ssl->heap);
- #if defined(HAVE_CURVE25519) && ECC_MIN_KEY_SZ <= 256
if (ret == WOLFSSL_SUCCESS)
- ret = TLSX_UseSupportedCurve(extensions, WOLFSSL_X25519_KYBER_LEVEL1,
+ ret = TLSX_UseSupportedCurve(extensions, WOLFSSL_P521_KYBER_LEVEL5,
ssl->heap);
- #endif
#endif
#ifdef WOLFSSL_KYBER768
if (ret == WOLFSSL_SUCCESS)
@@ -14782,49 +14905,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 101b31541ad..00162c6241f 100644
--- a/src/tls13.c
+++ b/src/tls13.c
@@ -7128,7 +7128,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;
}
@@ -13861,6 +13870,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 3af30a55422..93a585c2c2c 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
@@ -29095,6 +29096,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);
@@ -29687,6 +29691,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++) {
@@ -29709,6 +29717,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));
@@ -30642,7 +30653,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;
@@ -30651,11 +30662,42 @@ 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)
+ #if !defined(WOLFSSL_NO_KYBER1024)
int group = WOLFSSL_KYBER_LEVEL5;
+ const char *group_name = "KYBER_LEVEL5";
+ #elif !defined(WOLFSSL_NO_KYBER768)
+ int group = WOLFSSL_KYBER_LEVEL3;
+ const char *group_name = "KYBER_LEVEL3";
+ #else
+ int group = WOLFSSL_KYBER_LEVEL1;
+ const char *group_name = "KYBER_LEVEL1";
+#endif
#else
+ #if !defined(WOLFSSL_NO_ML_KEM_1024)
int group = WOLFSSL_ML_KEM_1024;
+ const char *group_name = "ML_KEM_1024";
+ #elif !defined(WOLFSSL_NO_ML_KEM_768)
+ int group = WOLFSSL_ML_KEM_768;
+ const char *group_name = "ML_KEM_768";
+ #else
+ int group = WOLFSSL_ML_KEM_512;
+ const char *group_name = "ML_KEM_512";
+ #endif
+#endif
+#elif defined(WOLFSSL_PQC_HYBRIDS)
+#if defined(HAVE_CURVE25519) && !defined(WOLFSSL_NO_ML_KEM_768)
+ int group = WOLFSSL_X25519MLKEM768;
+ const char *group_name = "X25519MLKEM768";
+#elif !defined(WOLFSSL_NO_ML_KEM_768)
+ int group = WOLFSSL_SECP256R1MLKEM768;
+ const char *group_name = "SecP256r1MLKEM768";
+#else
+ int group = WOLFSSL_SECP384R1MLKEM1024;
+ const char *group_name = "SecP384r1MLKEM1024";
#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,
@@ -30665,13 +30707,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 39c14e8bd3d..8bc199799cf 100644
--- a/tests/api/test_dtls.c
+++ b/tests/api/test_dtls.c
@@ -1614,6 +1614,36 @@ 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) && \
+ !defined(WOLFSSL_NO_ML_KEM_768)
+ WOLFSSL_X25519MLKEM768,
+ #elif defined(HAVE_ECC) && defined(WOLFSSL_PQC_HYBRIDS) && \
+ !defined(WOLFSSL_NO_ML_KEM_768)
+ WOLFSSL_SECP256R1MLKEM768,
+ #elif defined(HAVE_ECC) && defined(WOLFSSL_PQC_HYBRIDS) && \
+ !defined(WOLFSSL_NO_ML_KEM_1024)
+ WOLFSSL_SECP384R1MLKEM1024,
+ #elif !defined(WOLFSSL_NO_ML_KEM_1024) && \
+ !defined(WOLFSSL_TLS_NO_MLKEM_STANDALONE)
+ WOLFSSL_ML_KEM_1024,
+ #elif !defined(WOLFSSL_NO_ML_KEM_768) && \
+ !defined(WOLFSSL_TLS_NO_MLKEM_STANDALONE)
+ WOLFSSL_ML_KEM_768,
+ #else
+ WOLFSSL_ML_KEM_512,
+ #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 +1652,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 +1681,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 9c77126f460..16934f6b068 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,12 @@ 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_PQC_HYBRIDS)
+ ":SecP384r1MLKEM1024"
#endif
#endif
#endif
@@ -173,12 +179,12 @@ int test_tls13_apis(void)
#else
":KYBER_LEVEL5"
#endif
-#else
- #ifndef WOLFSSL_NO_KYBER512
+#elif !defined(WOLFSSL_TLS_NO_MLKEM_STANDALONE)
+ #if !defined(WOLFSSL_NO_ML_KEM_512)
":ML_KEM_512"
- #elif !defined(WOLFSSL_NO_KYBER768)
+ #elif !defined(WOLFSSL_NO_ML_KEM_768)
":ML_KEM_768"
- #else
+ #elif !defined(WOLFSSL_NO_ML_KEM_1024)
":ML_KEM_1024"
#endif
#endif
@@ -188,7 +194,11 @@ int test_tls13_apis(void)
#if defined(WOLFSSL_HAVE_MLKEM) && !defined(WOLFSSL_MLKEM_NO_MALLOC) && \
!defined(WOLFSSL_MLKEM_NO_MAKE_KEY) && \
!defined(WOLFSSL_MLKEM_NO_ENCAPSULATE) && \
- !defined(WOLFSSL_MLKEM_NO_DECAPSULATE)
+ !defined(WOLFSSL_MLKEM_NO_DECAPSULATE) && \
+ defined(HAVE_SUPPORTED_CURVES) && \
+ (!defined(WOLFSSL_TLS_NO_MLKEM_STANDALONE) || \
+ (defined(HAVE_CURVE25519) && !defined(WOLFSSL_NO_ML_KEM_768)) || \
+ (defined(HAVE_ECC) && !defined(WOLFSSL_NO_ML_KEM_768)))
int mlkemLevel;
#endif
@@ -351,8 +361,12 @@ int test_tls13_apis(void)
#if defined(WOLFSSL_HAVE_MLKEM) && !defined(WOLFSSL_MLKEM_NO_MALLOC) && \
!defined(WOLFSSL_MLKEM_NO_MAKE_KEY) && \
!defined(WOLFSSL_MLKEM_NO_ENCAPSULATE) && \
- !defined(WOLFSSL_MLKEM_NO_DECAPSULATE)
+ !defined(WOLFSSL_MLKEM_NO_DECAPSULATE) && \
+ (!defined(WOLFSSL_TLS_NO_MLKEM_STANDALONE) || \
+ (defined(HAVE_CURVE25519) && !defined(WOLFSSL_NO_ML_KEM_768)) || \
+ (defined(HAVE_ECC) && !defined(WOLFSSL_NO_ML_KEM_768)))
#ifndef WOLFSSL_NO_ML_KEM
+#ifndef WOLFSSL_TLS_NO_MLKEM_STANDALONE
#ifndef WOLFSSL_NO_ML_KEM_768
mlkemLevel = WOLFSSL_ML_KEM_768;
#elif !defined(WOLFSSL_NO_ML_KEM_1024)
@@ -361,6 +375,13 @@ int test_tls13_apis(void)
mlkemLevel = WOLFSSL_ML_KEM_512;
#endif
#else
+#if defined(HAVE_CURVE25519) && !defined(WOLFSSL_NO_ML_KEM_768)
+ mlkemLevel = WOLFSSL_X25519MLKEM768;
+#elif defined(HAVE_ECC) && !defined(WOLFSSL_NO_ML_KEM_768)
+ mlkemLevel = WOLFSSL_SECP256R1MLKEM768;
+#endif
+#endif
+#else
#ifndef WOLFSSL_NO_KYBER768
mlkemLevel = WOLFSSL_KYBER_LEVEL3;
#elif !defined(WOLFSSL_NO_KYBER1024)
@@ -1919,9 +1940,13 @@ int test_tls13_rpk_handshake(void)
#if defined(HAVE_IO_TESTS_DEPENDENCIES) && defined(WOLFSSL_TLS13) && \
defined(WOLFSSL_HAVE_MLKEM) && !defined(WOLFSSL_MLKEM_NO_ENCAPSULATE) && \
!defined(WOLFSSL_MLKEM_NO_DECAPSULATE) && \
- !defined(WOLFSSL_MLKEM_NO_MAKE_KEY)
+ !defined(WOLFSSL_MLKEM_NO_MAKE_KEY) && \
+ (!defined(WOLFSSL_TLS_NO_MLKEM_STANDALONE) || \
+ (defined(HAVE_CURVE25519) && !defined(WOLFSSL_NO_ML_KEM_768)) || \
+ (defined(HAVE_ECC) && !defined(WOLFSSL_NO_ML_KEM_768)))
static void test_tls13_pq_groups_ctx_ready(WOLFSSL_CTX* ctx)
{
+#ifndef WOLFSSL_TLS_NO_MLKEM_STANDALONE
#ifndef WOLFSSL_NO_ML_KEM_1024
#ifdef WOLFSSL_MLKEM_KYBER
int group = WOLFSSL_KYBER_LEVEL5;
@@ -1940,6 +1965,11 @@ static void test_tls13_pq_groups_ctx_ready(WOLFSSL_CTX* ctx)
#else
int group = WOLFSSL_ML_KEM_512;
#endif /* WOLFSSL_MLKEM_KYBER */
+#endif
+#elif defined(HAVE_ECC) && !defined(WOLFSSL_NO_ML_KEM_768)
+ int group = WOLFSSL_SECP256R1MLKEM768;
+#elif defined(HAVE_CURVE25519) && !defined(WOLFSSL_NO_ML_KEM_768)
+ int group = WOLFSSL_X25519MLKEM768;
#endif
AssertIntEQ(wolfSSL_CTX_set_groups(ctx, &group, 1), WOLFSSL_SUCCESS);
@@ -1947,6 +1977,7 @@ static void test_tls13_pq_groups_ctx_ready(WOLFSSL_CTX* ctx)
static void test_tls13_pq_groups_on_result(WOLFSSL* ssl)
{
+#ifndef WOLFSSL_TLS_NO_MLKEM_STANDALONE
#ifndef WOLFSSL_NO_ML_KEM_1024
#ifdef WOLFSSL_MLKEM_KYBER
AssertStrEQ(wolfSSL_get_curve_name(ssl), "KYBER_LEVEL5");
@@ -1966,6 +1997,11 @@ static void test_tls13_pq_groups_on_result(WOLFSSL* ssl)
AssertStrEQ(wolfSSL_get_curve_name(ssl), "ML_KEM_512");
#endif /* WOLFSSL_MLKEM_KYBER */
#endif
+#elif defined(HAVE_ECC) && !defined(WOLFSSL_NO_ML_KEM_768)
+ AssertStrEQ(wolfSSL_get_curve_name(ssl), "SecP256r1MLKEM768");
+#elif defined(HAVE_CURVE25519) && !defined(WOLFSSL_NO_ML_KEM_768)
+ AssertStrEQ(wolfSSL_get_curve_name(ssl), "X25519MLKEM768");
+#endif
}
#endif
@@ -1975,7 +2011,10 @@ int test_tls13_pq_groups(void)
#if defined(HAVE_IO_TESTS_DEPENDENCIES) && defined(WOLFSSL_TLS13) && \
defined(WOLFSSL_HAVE_MLKEM) && !defined(WOLFSSL_MLKEM_NO_ENCAPSULATE) && \
!defined(WOLFSSL_MLKEM_NO_DECAPSULATE) && \
- !defined(WOLFSSL_MLKEM_NO_MAKE_KEY)
+ !defined(WOLFSSL_MLKEM_NO_MAKE_KEY) && \
+ (!defined(WOLFSSL_TLS_NO_MLKEM_STANDALONE) || \
+ (defined(HAVE_CURVE25519) && !defined(WOLFSSL_NO_ML_KEM_768)) || \
+ (defined(HAVE_ECC) && !defined(WOLFSSL_NO_ML_KEM_768)))
callback_functions func_cb_client;
callback_functions func_cb_server;
@@ -2160,6 +2199,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 34fe772d275..9c94f13ca87 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 60a0850dc5a..0f5f0dfc88b 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,16 @@ 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) * k * 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 * 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 * MLKEM_N) * sizeof(sword16),
key->heap, DYNAMIC_TYPE_TMP_BUFFER);
#endif
if (e == NULL) {
@@ -557,7 +563,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)
*/
@@ -849,7 +855,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 +876,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 +886,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 +898,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 +909,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 +983,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 +1008,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 +1358,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 +1512,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 +1541,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 +1582,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 +1698,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 +1807,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 +2052,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 +2169,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 b8d11ca3e6a..e677def3d23 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;
@@ -1080,30 +1080,30 @@ static void mlkem_basemul_mont(sword16* r, const sword16* a, const sword16* b)
/* Step 1 */
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 + 0, a + i + 0, b + i + 0, 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 + 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 + 0, a + i + 0, b + i + 0, 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, (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 + 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 + 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 + 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 + 0, a + i + 0, b + i + 0, 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, (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, (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, (sword16)(-zeta[3]));
}
#endif
}
@@ -1136,13 +1136,13 @@ static void mlkem_basemul_mont_add(sword16* r, const sword16* a,
sword16 t0[2];
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(t0, a + i + 0, b + i + 0, 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. */
@@ -1153,19 +1153,19 @@ static void mlkem_basemul_mont_add(sword16* r, const sword16* a,
sword16 t4[2];
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(t4, a + i + 4, b + i + 4, zeta[1]);
- mlkem_basemul(t6, a + i + 6, b + i + 6, -zeta[1]);
+ mlkem_basemul(t0, a + i + 0, b + i + 0, 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, (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. */
@@ -1180,31 +1180,31 @@ static void mlkem_basemul_mont_add(sword16* r, const sword16* a,
sword16 t12[2];
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(t4, a + i + 4, b + i + 4, zeta[1]);
- mlkem_basemul(t6, a + i + 6, b + i + 6, -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(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(t0, a + i + 0, b + i + 0, 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, (sword16)(-zeta[1]));
+ mlkem_basemul(t8, a + i + 8, b + i + 8, 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, (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 +1622,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 +1656,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 +1678,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 +1742,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);
@@ -1820,12 +1820,13 @@ static void mlkem_keygen_c(sword16* s, sword16* t, sword16* e, const sword16* a,
/* 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 * k * MLKEM_N, s,
+ (unsigned int)k);
/* Convert public polynomial to Montgomery form.
* Step 18: ... MontRed(A_hat o s_hat) ... */
for (j = 0; j < MLKEM_N; ++j) {
- sword32 n = t[i * MLKEM_N + j] * (sword32)MLKEM_F;
- t[i * MLKEM_N + j] = MLKEM_MONT_RED(n);
+ sword32 n = t[(unsigned int)i * MLKEM_N + j] * (sword32)MLKEM_F;
+ t[(unsigned int)i * MLKEM_N + j] = MLKEM_MONT_RED(n);
}
/* Transform error values polynomial.
* Step 17: e_hat = NTT(e) */
@@ -1834,8 +1835,9 @@ 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];
- t[i * MLKEM_N + j] = MLKEM_BARRETT_RED(n);
+ sword16 n = (sword16)(t[(unsigned int)i * MLKEM_N + j] +
+ e[(unsigned int)i * MLKEM_N + j]);
+ t[(unsigned int)i * MLKEM_N + j] = MLKEM_BARRETT_RED(n);
}
#else
/* Add errors to public key and reduce.
@@ -1928,12 +1930,12 @@ int mlkem_keygen_seeds(sword16* s, sword16* t, MLKEM_PRF_T* prf,
/* Multiply a by private into public polynomial.
* Step 18: ... A_hat o s_hat ... */
- mlkem_pointwise_acc_mont(t + i * MLKEM_N, ai, s, k);
+ mlkem_pointwise_acc_mont(t + i * MLKEM_N, ai, s, (unsigned int)k);
/* Convert public polynomial to Montgomery form.
* Step 18: ... MontRed(A_hat o s_hat) ... */
for (j = 0; j < MLKEM_N; ++j) {
- sword32 n = t[i * MLKEM_N + j] * (sword32)MLKEM_F;
- t[i * MLKEM_N + j] = MLKEM_MONT_RED(n);
+ sword32 n = t[(unsigned int)i * MLKEM_N + j] * (sword32)MLKEM_F;
+ t[(unsigned int)i * MLKEM_N + j] = MLKEM_MONT_RED(n);
}
/* Generate noise using PRF.
@@ -1949,8 +1951,8 @@ int mlkem_keygen_seeds(sword16* s, sword16* t, MLKEM_PRF_T* prf,
/* 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[j];
- t[i * MLKEM_N + j] = MLKEM_BARRETT_RED(n);
+ sword16 n = (sword16)(t[(unsigned int)i * MLKEM_N + j] + e[j]);
+ t[(unsigned int)i * MLKEM_N + j] = MLKEM_BARRETT_RED(n);
}
#else
/* Add errors to public key and reduce.
@@ -1997,44 +1999,54 @@ static void mlkem_encapsulate_c(const sword16* pub, sword16* u, sword16* v,
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 * k * MLKEM_N, y,
+ (unsigned int)k);
/* 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];
- u[i * MLKEM_N + j] = MLKEM_BARRETT_RED(t);
+ sword16 t = (sword16)(u[(unsigned int)i * MLKEM_N + j] +
+ e1[(unsigned int)i * MLKEM_N + j]);
+ u[(unsigned int)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];
- 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);
- u[i * MLKEM_N + j + 3] = MLKEM_BARRETT_RED(t3);
- u[i * MLKEM_N + j + 4] = MLKEM_BARRETT_RED(t4);
- u[i * MLKEM_N + j + 5] = MLKEM_BARRETT_RED(t5);
- u[i * MLKEM_N + j + 6] = MLKEM_BARRETT_RED(t6);
- u[i * MLKEM_N + j + 7] = MLKEM_BARRETT_RED(t7);
+ sword16 t0 = (sword16)(u[(unsigned int)i * MLKEM_N + j + 0] +
+ e1[(unsigned int)i * MLKEM_N + j + 0]);
+ sword16 t1 = (sword16)(u[(unsigned int)i * MLKEM_N + j + 1] +
+ e1[(unsigned int)i * MLKEM_N + j + 1]);
+ sword16 t2 = (sword16)(u[(unsigned int)i * MLKEM_N + j + 2] +
+ e1[(unsigned int)i * MLKEM_N + j + 2]);
+ sword16 t3 = (sword16)(u[(unsigned int)i * MLKEM_N + j + 3] +
+ e1[(unsigned int)i * MLKEM_N + j + 3]);
+ sword16 t4 = (sword16)(u[(unsigned int)i * MLKEM_N + j + 4] +
+ e1[(unsigned int)i * MLKEM_N + j + 4]);
+ sword16 t5 = (sword16)(u[(unsigned int)i * MLKEM_N + j + 5] +
+ e1[(unsigned int)i * MLKEM_N + j + 5]);
+ sword16 t6 = (sword16)(u[(unsigned int)i * MLKEM_N + j + 6] +
+ e1[(unsigned int)i * MLKEM_N + j + 6]);
+ sword16 t7 = (sword16)(u[(unsigned int)i * MLKEM_N + j + 7] +
+ e1[(unsigned int)i * MLKEM_N + j + 7]);
+ u[(unsigned int)i * MLKEM_N + j + 0] = MLKEM_BARRETT_RED(t0);
+ u[(unsigned int)i * MLKEM_N + j + 1] = MLKEM_BARRETT_RED(t1);
+ u[(unsigned int)i * MLKEM_N + j + 2] = MLKEM_BARRETT_RED(t2);
+ u[(unsigned int)i * MLKEM_N + j + 3] = MLKEM_BARRETT_RED(t3);
+ u[(unsigned int)i * MLKEM_N + j + 4] = MLKEM_BARRETT_RED(t4);
+ u[(unsigned int)i * MLKEM_N + j + 5] = MLKEM_BARRETT_RED(t5);
+ u[(unsigned int)i * MLKEM_N + j + 6] = MLKEM_BARRETT_RED(t6);
+ u[(unsigned int)i * MLKEM_N + j + 7] = MLKEM_BARRETT_RED(t7);
}
#endif
}
/* Multiply public key by y into v polynomial. */
- mlkem_pointwise_acc_mont(v, pub, y, k);
+ mlkem_pointwise_acc_mont(v, pub, y, (unsigned int)k);
/* 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);
}
}
@@ -2109,7 +2121,7 @@ int mlkem_encapsulate_seeds(const sword16* pub, MLKEM_PRF_T* prf, sword16* u,
}
/* Multiply at by y into u polynomial. */
- mlkem_pointwise_acc_mont(u + i * MLKEM_N, a, y, k);
+ mlkem_pointwise_acc_mont(u + i * MLKEM_N, a, y, (unsigned int)k);
/* Inverse transform u polynomial. */
mlkem_invntt(u + i * MLKEM_N);
@@ -2121,58 +2133,66 @@ int mlkem_encapsulate_seeds(const sword16* pub, MLKEM_PRF_T* prf, sword16* u,
/* 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[j];
- u[i * MLKEM_N + j] = MLKEM_BARRETT_RED(t);
+ sword16 t = (sword16)(u[(unsigned int)i * MLKEM_N + j] + e1[j]);
+ u[(unsigned int)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[j + 0];
- sword16 t1 = u[i * MLKEM_N + j + 1] + e1[j + 1];
- sword16 t2 = u[i * MLKEM_N + j + 2] + e1[j + 2];
- sword16 t3 = u[i * MLKEM_N + j + 3] + e1[j + 3];
- sword16 t4 = u[i * MLKEM_N + j + 4] + e1[j + 4];
- sword16 t5 = u[i * MLKEM_N + j + 5] + e1[j + 5];
- sword16 t6 = u[i * MLKEM_N + j + 6] + e1[j + 6];
- sword16 t7 = u[i * MLKEM_N + j + 7] + e1[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);
- u[i * MLKEM_N + j + 3] = MLKEM_BARRETT_RED(t3);
- u[i * MLKEM_N + j + 4] = MLKEM_BARRETT_RED(t4);
- u[i * MLKEM_N + j + 5] = MLKEM_BARRETT_RED(t5);
- u[i * MLKEM_N + j + 6] = MLKEM_BARRETT_RED(t6);
- u[i * MLKEM_N + j + 7] = MLKEM_BARRETT_RED(t7);
+ sword16 t0 = (sword16)(u[(unsigned int)i * MLKEM_N + j + 0] +
+ e1[j + 0]);
+ sword16 t1 = (sword16)(u[(unsigned int)i * MLKEM_N + j + 1] +
+ e1[j + 1]);
+ sword16 t2 = (sword16)(u[(unsigned int)i * MLKEM_N + j + 2] +
+ e1[j + 2]);
+ sword16 t3 = (sword16)(u[(unsigned int)i * MLKEM_N + j + 3] +
+ e1[j + 3]);
+ sword16 t4 = (sword16)(u[(unsigned int)i * MLKEM_N + j + 4] +
+ e1[j + 4]);
+ sword16 t5 = (sword16)(u[(unsigned int)i * MLKEM_N + j + 5] +
+ e1[j + 5]);
+ sword16 t6 = (sword16)(u[(unsigned int)i * MLKEM_N + j + 6] +
+ e1[j + 6]);
+ sword16 t7 = (sword16)(u[(unsigned int)i * MLKEM_N + j + 7] +
+ e1[j + 7]);
+ u[(unsigned int)i * MLKEM_N + j + 0] = MLKEM_BARRETT_RED(t0);
+ u[(unsigned int)i * MLKEM_N + j + 1] = MLKEM_BARRETT_RED(t1);
+ u[(unsigned int)i * MLKEM_N + j + 2] = MLKEM_BARRETT_RED(t2);
+ u[(unsigned int)i * MLKEM_N + j + 3] = MLKEM_BARRETT_RED(t3);
+ u[(unsigned int)i * MLKEM_N + j + 4] = MLKEM_BARRETT_RED(t4);
+ u[(unsigned int)i * MLKEM_N + j + 5] = MLKEM_BARRETT_RED(t5);
+ u[(unsigned int)i * MLKEM_N + j + 6] = MLKEM_BARRETT_RED(t6);
+ u[(unsigned int)i * MLKEM_N + j + 7] = MLKEM_BARRETT_RED(t7);
}
#endif
}
/* Multiply public key by y into v polynomial. */
- mlkem_pointwise_acc_mont(v, pub, y, k);
+ mlkem_pointwise_acc_mont(v, pub, y, (unsigned int)k);
/* Inverse transform v. */
mlkem_invntt(v);
mlkem_from_msg(m, msg);
/* Generate noise using PRF. */
- coins[WC_ML_KEM_SYM_SZ] = 2 * k;
+ coins[WC_ML_KEM_SYM_SZ] = (byte)(2 * k);
ret = mlkem_get_noise_eta2_c(prf, e2, coins);
if (ret == 0) {
/* Add errors and message to v and reduce. */
#if defined(WOLFSSL_MLKEM_SMALL) || defined(WOLFSSL_MLKEM_NO_LARGE_CODE)
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);
}
#else
for (i = 0; i < MLKEM_N; i += 8) {
- sword16 t0 = v[i + 0] + e2[i + 0] + m[i + 0];
- sword16 t1 = v[i + 1] + e2[i + 1] + m[i + 1];
- sword16 t2 = v[i + 2] + e2[i + 2] + m[i + 2];
- sword16 t3 = v[i + 3] + e2[i + 3] + m[i + 3];
- sword16 t4 = v[i + 4] + e2[i + 4] + m[i + 4];
- sword16 t5 = v[i + 5] + e2[i + 5] + m[i + 5];
- sword16 t6 = v[i + 6] + e2[i + 6] + m[i + 6];
- sword16 t7 = v[i + 7] + e2[i + 7] + m[i + 7];
+ sword16 t0 = (sword16)(v[i + 0] + e2[i + 0] + m[i + 0]);
+ sword16 t1 = (sword16)(v[i + 1] + e2[i + 1] + m[i + 1]);
+ sword16 t2 = (sword16)(v[i + 2] + e2[i + 2] + m[i + 2]);
+ sword16 t3 = (sword16)(v[i + 3] + e2[i + 3] + m[i + 3]);
+ sword16 t4 = (sword16)(v[i + 4] + e2[i + 4] + m[i + 4]);
+ sword16 t5 = (sword16)(v[i + 5] + e2[i + 5] + m[i + 5]);
+ sword16 t6 = (sword16)(v[i + 6] + e2[i + 6] + m[i + 6]);
+ sword16 t7 = (sword16)(v[i + 7] + e2[i + 7] + m[i + 7]);
v[i + 0] = MLKEM_BARRETT_RED(t0);
v[i + 1] = MLKEM_BARRETT_RED(t1);
v[i + 2] = MLKEM_BARRETT_RED(t2);
@@ -2219,14 +2239,14 @@ static void mlkem_decapsulate_c(const sword16* s, sword16* w, sword16* u,
/* 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, (unsigned int)k);
/* 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 +2444,13 @@ 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)(0x1f0000 + (((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)(0x1f0000 + (((k*4+i)%3) << 8) +
+ ((k*4+i)/3));
+
}
}
@@ -2577,10 +2600,10 @@ 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)(0x1f0000 + (k << 8) + i);
}
else {
- state[4*4 + i] = 0x1f0000 + (i << 8) + k;
+ state[4*4 + i] = (word64)(0x1f0000 + (i << 8) + k);
}
}
@@ -2881,7 +2904,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 +2922,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 +3476,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 +3678,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 +3739,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 +3855,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 +4116,7 @@ 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)(0x1f00 + i + o);
}
sha3_256_blocksx4_seed_avx2(state, seed);
@@ -4554,7 +4577,7 @@ 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 +4585,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. */
@@ -4692,7 +4716,7 @@ static int mlkem_get_noise_i(MLKEM_PRF_T* prf, int k, sword16* vec2,
mlkem_prf_init(prf);
/* Set index of polynomial of second vector into seed. */
- seed[WC_ML_KEM_SYM_SZ] = k + i;
+ seed[WC_ML_KEM_SYM_SZ] = (byte)(k + i);
#if defined(WOLFSSL_KYBER512) || defined(WOLFSSL_WC_ML_KEM_512)
if ((k == WC_ML_KEM_512_K) && make) {
ret = mlkem_get_noise_eta1_c(prf, vec2, seed, MLKEM_CBD_ETA3);
@@ -4728,7 +4752,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 +4801,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 +4924,8 @@ 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)
+ (sword16)((((MLKEM_V54 << 10) * (word64)(v)[(i) * MLKEM_N + (j) + (k)]) + \
+ MLKEM_V54_HALF) >> 54)
/* Compress value to 11 bits.
*
@@ -4916,8 +4941,8 @@ 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)
+ (sword16)((((MLKEM_V53 << 11) * (word64)(v)[(i) * MLKEM_N + (j) + (k)]) + \
+ MLKEM_V53_HALF) >> 53)
#endif /* CONV_WITH_DIV */
@@ -4972,11 +4997,11 @@ static void mlkem_vec_compress_10_c(byte* r, sword16* v, unsigned int k)
sword16 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. */
@@ -5005,16 +5030,16 @@ static void mlkem_vec_compress_10_c(byte* r, sword16* v, unsigned int k)
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 +5060,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
@@ -5080,17 +5105,17 @@ static void mlkem_vec_compress_11_c(byte* r, sword16* v)
}
/* 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);
@@ -5103,17 +5128,17 @@ static void mlkem_vec_compress_11_c(byte* r, sword16* v)
sword16 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 +5184,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 +5199,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 +5226,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 +5238,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 +5266,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 +5299,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 +5317,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 +5436,7 @@ 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)(p)[(i) + (j)]) + MLKEM_V28_HALF) >> 28)
/* Compress value to 5 bits.
*
@@ -5425,7 +5450,7 @@ 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)(p)[(i) + (j)]) + MLKEM_V27_HALF) >> 27)
#endif /* CONV_WITH_DIV */
@@ -5460,10 +5485,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 +5501,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 +5561,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 +5578,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 +5625,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 +5638,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 +5703,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 +5719,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 +5878,8 @@ 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)
+ (m)[i] |= (byte)((((MLKEM_V31_2 * (word16)(p)[8 * (i) + (j)]) + \
+ MLKEM_V31_HALF) >> 31) << (j))
#endif /* CONV_WITH_DIV */
@@ -6031,11 +6056,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 fa49d76bca2..77461e05c31 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 294c69be411..27215cd31a9 100644
--- a/wolfssl/internal.h
+++ b/wolfssl/internal.h
@@ -1752,7 +1752,7 @@ enum Misc {
ECDHE_SIZE = 32, /* ECDHE server size defaults to 256 bit */
#endif
MAX_EXPORT_ECC_SZ = 256, /* Export ANSI X9.62 max future size */
- MAX_CURVE_NAME_SZ = 18, /* Maximum size of curve name string */
+ MAX_CURVE_NAME_SZ = 20, /* Maximum size of curve name string */
NEW_SA_MAJOR = 8, /* Most significant byte used with new sig algos */
RSA_PSS_RSAE_SHA256_MINOR = 0x04,
@@ -3414,6 +3414,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,
@@ -3622,6 +3623,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 8dd8acde1cd..78bb73d6a0b 100644
--- a/wolfssl/ssl.h
+++ b/wolfssl/ssl.h
@@ -4739,16 +4739,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 1abe00059b1..e1a7b0e9019 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 e9943fb270b..1c33c8232e6 100644
--- a/wolfssl/wolfcrypt/settings.h
+++ b/wolfssl/wolfcrypt/settings.h
@@ -4496,15 +4496,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 6f2606bdbf3..cc333bdaaa7 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
/* ------------------------------------------------------------------------- */