Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 6 additions & 1 deletion .github/workflows/pq-all.yml
Original file line number Diff line number Diff line change
Expand Up @@ -225,7 +225,12 @@ jobs:
{"name": "mldsa-verify-only-dynamic-keys", "minutes": 1.2,
"configure": ["--disable-intelasm",
"--enable-dilithium=44,65,87,verify-only",
"CPPFLAGS=-DWOLFSSL_MLDSA_DYNAMIC_KEYS"]}
"CPPFLAGS=-DWOLFSSL_MLDSA_DYNAMIC_KEYS"]},
{"name": "pqc-only", "minutes": 2,
"comment": "PQC-only TLS 1.3: ML-KEM key exchange + ML-DSA auth with RSA, ECC and DH disabled (CNSA 2.0 / EO 14412). Session tickets exercise ML-KEM-only resumption.",
"configure": ["--enable-mlkem", "--enable-mldsa",
"--enable-tls-mlkem-standalone", "--enable-session-ticket",
"--disable-rsa", "--disable-ecc", "--disable-dh"]}
]
EOF
.github/scripts/parallel-make-check.py \
Expand Down
7 changes: 5 additions & 2 deletions examples/client/client.c
Original file line number Diff line number Diff line change
Expand Up @@ -2405,6 +2405,10 @@ THREAD_RETURN WOLFSSL_THREAD client_test(void* args)
verifyCert = caEd448CertFile;
ourCert = cliEd448CertFile;
ourKey = cliEd448KeyFile;
#elif defined(WOLFSSL_HAVE_MLDSA)
verifyCert = caMldsaCertFile;
ourCert = cliMldsaCertFile;
ourKey = cliMldsaKeyFile;
#else
verifyCert = NULL;
ourCert = NULL;
Expand Down Expand Up @@ -3477,8 +3481,7 @@ THREAD_RETURN WOLFSSL_THREAD client_test(void* args)
}
#endif

#if defined(NO_RSA) && !defined(HAVE_ECC) && !defined(HAVE_ED25519) && \
!defined(HAVE_ED448)
#if defined(TEST_NO_CLASSIC_AUTH) && !defined(WOLFSSL_HAVE_MLDSA)
if (!usePsk) {
usePsk = 1;
}
Expand Down
7 changes: 5 additions & 2 deletions examples/echoclient/echoclient.c
Original file line number Diff line number Diff line change
Expand Up @@ -121,8 +121,8 @@ void echoclient_test(void* args)
#ifdef WOLFSSL_LEANPSK
doPSK = 1;
#endif
#if defined(NO_CERTS) || (defined(NO_RSA) && !defined(HAVE_ECC) && \
!defined(HAVE_ED25519) && !defined(HAVE_ED448))
#if defined(NO_CERTS) || \
(defined(TEST_NO_CLASSIC_AUTH) && !defined(WOLFSSL_HAVE_MLDSA))
doPSK = 1;
#endif
(void)doPSK;
Expand Down Expand Up @@ -160,6 +160,9 @@ void echoclient_test(void* args)
#elif defined(HAVE_ED448)
if (SSL_CTX_load_verify_locations(ctx, caEd448CertFile, 0) != WOLFSSL_SUCCESS)
err_sys("can't load ca file, Please run from wolfSSL home dir");
#elif defined(WOLFSSL_HAVE_MLDSA)
if (SSL_CTX_load_verify_locations(ctx, caMldsaCertFile, 0) != WOLFSSL_SUCCESS)
err_sys("can't load ca file, Please run from wolfSSL home dir");
#endif
#elif !defined(NO_CERTS)
if (!doPSK)
Expand Down
15 changes: 13 additions & 2 deletions examples/echoserver/echoserver.c
Original file line number Diff line number Diff line change
Expand Up @@ -124,8 +124,7 @@ THREAD_RETURN WOLFSSL_THREAD echoserver_test(void* args)
((func_args*)args)->return_code = -1; /* error state */

#if defined(NO_CERTS) || defined(WOLFSSL_LEANPSK) || \
(defined(NO_RSA) && !defined(HAVE_ECC) && !defined(HAVE_ED25519) && \
!defined(HAVE_ED448))
(defined(TEST_NO_CLASSIC_AUTH) && !defined(WOLFSSL_HAVE_MLDSA))
doPSK = 1;
#else
doPSK = 0;
Expand Down Expand Up @@ -212,6 +211,18 @@ THREAD_RETURN WOLFSSL_THREAD echoserver_test(void* args)
CERT_FILETYPE) != WOLFSSL_SUCCESS)
err_sys("can't load server key file, "
"Please run from wolfSSL home dir");
#elif defined(WOLFSSL_HAVE_MLDSA) && !defined(NO_CERTS) && \
!defined(WOLFSSL_SNIFFER)
/* ML-DSA (post-quantum-only) */
if (wolfSSL_CTX_use_certificate_chain_file(ctx, mldsaCertFile)
!= WOLFSSL_SUCCESS)
err_sys("can't load server cert file, "
"Please run from wolfSSL home dir");

if (wolfSSL_CTX_use_PrivateKey_file(ctx, mldsaKeyFile, CERT_FILETYPE)
!= WOLFSSL_SUCCESS)
err_sys("can't load server key file, "
"Please run from wolfSSL home dir");
#elif defined(NO_CERTS)
/* do nothing, just don't load cert files */
#else
Expand Down
7 changes: 5 additions & 2 deletions examples/server/server.c
Original file line number Diff line number Diff line change
Expand Up @@ -1895,6 +1895,10 @@ THREAD_RETURN WOLFSSL_THREAD server_test(void* args)
verifyCert = cliEd448CertFile;
ourCert = ed448CertFile;
ourKey = ed448KeyFile;
#elif defined(WOLFSSL_HAVE_MLDSA)
verifyCert = caMldsaCertFile;
ourCert = mldsaCertFile;
ourKey = mldsaKeyFile;
#else
verifyCert = NULL;
ourCert = NULL;
Expand Down Expand Up @@ -2948,8 +2952,7 @@ THREAD_RETURN WOLFSSL_THREAD server_test(void* args)
}
#endif

#if defined(NO_RSA) && !defined(HAVE_ECC) && !defined(HAVE_ED25519) && \
!defined(HAVE_ED448)
#if defined(TEST_NO_CLASSIC_AUTH) && !defined(WOLFSSL_HAVE_MLDSA)
if (!usePsk) {
usePsk = 1;
}
Expand Down
6 changes: 4 additions & 2 deletions src/internal.c
Original file line number Diff line number Diff line change
Expand Up @@ -14531,9 +14531,11 @@ int CopyDecodedToX509(WOLFSSL_X509* x509, DecodedCert* dCert)
ret = MEMORY_E;
}
#endif
#if defined(HAVE_ECC) || defined(HAVE_ED25519) || defined(HAVE_ED448)
#if defined(HAVE_ECC) || defined(HAVE_ED25519) || defined(HAVE_ED448) || \
defined(HAVE_FALCON) || defined(WOLFSSL_HAVE_MLDSA)
x509->pkCurveOID = dCert->pkCurveOID;
#endif /* HAVE_ECC || HAVE_CURVE25519 || HAVE_CURVE448 */
#endif /* HAVE_ECC || HAVE_ED25519 || HAVE_ED448 || HAVE_FALCON ||
* WOLFSSL_HAVE_MLDSA */

#ifdef WOLFSSL_DUAL_ALG_CERTS
/* Copy over alternative sig and pubkey. In this case we will allocate new
Expand Down
4 changes: 3 additions & 1 deletion src/ssl.c
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,9 @@
#if !defined(WOLFSSL_ALLOW_NO_SUITES) && !defined(WOLFCRYPT_ONLY)
#if defined(NO_DH) && !defined(HAVE_ECC) && !defined(WOLFSSL_STATIC_RSA) \
&& !defined(WOLFSSL_STATIC_DH) && !defined(WOLFSSL_STATIC_PSK) \
&& !defined(HAVE_CURVE25519) && !defined(HAVE_CURVE448)
&& !defined(HAVE_CURVE25519) && !defined(HAVE_CURVE448) \
&& (!defined(WOLFSSL_HAVE_MLKEM) || \
defined(WOLFSSL_TLS_NO_MLKEM_STANDALONE))
#error "No cipher suites defined because DH disabled, ECC disabled, " \
"and no static suites defined. Please see top of README"
#endif
Expand Down
4 changes: 3 additions & 1 deletion src/tls.c
Original file line number Diff line number Diff line change
Expand Up @@ -16642,7 +16642,9 @@ int TLSX_PopulateExtensions(WOLFSSL* ssl, byte isServer)
modes = 1 << PSK_KE;
}
#if !defined(NO_DH) || defined(HAVE_ECC) || \
defined(HAVE_CURVE25519) || defined(HAVE_CURVE448)
defined(HAVE_CURVE25519) || defined(HAVE_CURVE448) || \
(defined(WOLFSSL_HAVE_MLKEM) && \
!defined(WOLFSSL_TLS_NO_MLKEM_STANDALONE))
if (!ssl->options.noPskDheKe) {
modes |= 1 << PSK_DHE_KE;
}
Expand Down
4 changes: 3 additions & 1 deletion src/tls13.c
Original file line number Diff line number Diff line change
Expand Up @@ -8696,6 +8696,7 @@ static WC_INLINE void EncodeSigAlg(const WOLFSSL * ssl, byte hashAlgo,
byte hsType, byte* output)
{
(void)ssl;
(void)hashAlgo;
switch (hsType) {
#ifdef HAVE_ECC
case ecc_dsa_sa_algo:
Expand Down Expand Up @@ -11864,7 +11865,8 @@ static int DoTls13CertificateVerify(WOLFSSL* ssl, byte* input,

return ret;
}
#endif /* !NO_RSA || HAVE_ECC */
#endif /* !NO_RSA || HAVE_ECC || HAVE_ED25519 || HAVE_ED448 ||
* HAVE_FALCON || WOLFSSL_HAVE_MLDSA */
#endif /* !NO_CERTS */

/* Parse and handle a TLS v1.3 Finished message.
Expand Down
3 changes: 3 additions & 0 deletions tests/api/test_tls13.c
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,9 @@ int test_tls13_apis(void)
#elif defined(HAVE_ED448)
const char* ourCert = ed448CertFile;
const char* ourKey = ed448KeyFile;
#elif defined(WOLFSSL_HAVE_MLDSA)
const char* ourCert = mldsaCertFile;
const char* ourKey = mldsaKeyFile;
#endif
#endif
#endif
Expand Down
30 changes: 30 additions & 0 deletions wolfcrypt/src/asn.c
Original file line number Diff line number Diff line change
Expand Up @@ -28648,11 +28648,24 @@ static int SetValidity(byte* before, byte* after, int daysValid)


#if defined(WOLFSSL_CERT_GEN) || defined(WOLFSSL_CERT_REQ)
/* MakeSignatureCb is used both by MakeSignature() (local RSA/ECC signing) and
* by the public wc_SignCert_cb() offload path (WOLFSSL_CERT_SIGN_CB), so it
* must be available whenever either of those is compiled in. */
#if (!defined(NO_RSA) && !defined(WOLFSSL_RSA_PUBLIC_ONLY) && \
!defined(WOLFSSL_RSA_VERIFY_ONLY)) || \
(defined(HAVE_ECC) && defined(HAVE_ECC_SIGN)) || \
defined(WOLFSSL_CERT_SIGN_CB)
/* Forward declaration for internal use */
static int MakeSignatureCb(CertSignCtx* certSignCtx, const byte* buf,
word32 sz, byte* sig, word32 sigSz, int sigAlgoType, int keyType,
wc_SignCertCb signCb, void* signCtx, WC_RNG* rng, void* heap);
#endif /* (!NO_RSA && !WOLFSSL_RSA_PUBLIC_ONLY && !WOLFSSL_RSA_VERIFY_ONLY) ||
* (HAVE_ECC && HAVE_ECC_SIGN) || WOLFSSL_CERT_SIGN_CB */

/* InternalSignCb is only used by MakeSignature()'s local signing path. */
#if (!defined(NO_RSA) && !defined(WOLFSSL_RSA_PUBLIC_ONLY) && \
!defined(WOLFSSL_RSA_VERIFY_ONLY)) || \
(defined(HAVE_ECC) && defined(HAVE_ECC_SIGN))
/* Internal context for default signing operations (when no callback provided) */
typedef struct {
void* key;
Expand Down Expand Up @@ -28739,6 +28752,8 @@ static int InternalSignCb(const byte* in, word32 inLen,

return ret;
}
#endif /* (!NO_RSA && !WOLFSSL_RSA_PUBLIC_ONLY && !WOLFSSL_RSA_VERIFY_ONLY) ||
* (HAVE_ECC && HAVE_ECC_SIGN) */
#endif /* WOLFSSL_CERT_GEN || WOLFSSL_CERT_REQ */


Expand Down Expand Up @@ -29018,10 +29033,13 @@ static int MakeSignature(CertSignCtx* certSignCtx, const byte* buf, word32 sz,
{
int ret = 0;

(void)certSignCtx;
(void)buf;
(void)sz;
(void)sig;
(void)sigSz;
(void)rsaKey;
(void)eccKey;
(void)ed25519Key;
(void)ed448Key;
(void)falconKey;
Expand All @@ -29030,6 +29048,7 @@ static int MakeSignature(CertSignCtx* certSignCtx, const byte* buf, word32 sz,
(void)lmsKey;
(void)xmssKey;
(void)rng;
(void)sigAlgoType;
(void)heap;

/* For RSA and ECC, use the callback path to eliminate duplication */
Expand Down Expand Up @@ -29145,7 +29164,12 @@ static int MakeSignature(CertSignCtx* certSignCtx, const byte* buf, word32 sz,
if (ret == -1)
ret = ALGO_ID_E;

#if (!defined(NO_RSA) && !defined(WOLFSSL_RSA_PUBLIC_ONLY) && \
!defined(WOLFSSL_RSA_VERIFY_ONLY)) || \
(defined(HAVE_ECC) && defined(HAVE_ECC_SIGN))
exit_ms:
#endif /* (!NO_RSA && !WOLFSSL_RSA_PUBLIC_ONLY && !WOLFSSL_RSA_VERIFY_ONLY) ||
* (HAVE_ECC && HAVE_ECC_SIGN) */
if (ret < 0) {
WOLFSSL_ERROR_VERBOSE(ret);
}
Expand Down Expand Up @@ -30141,6 +30165,10 @@ int wc_MakeCertReq(Cert* cert, byte* derBuffer, word32 derSz,


#if defined(WOLFSSL_CERT_GEN) || defined(WOLFSSL_CERT_REQ)
#if (!defined(NO_RSA) && !defined(WOLFSSL_RSA_PUBLIC_ONLY) && \
!defined(WOLFSSL_RSA_VERIFY_ONLY)) || \
(defined(HAVE_ECC) && defined(HAVE_ECC_SIGN)) || \
defined(WOLFSSL_CERT_SIGN_CB)
/* Internal function to create signature using callback
* This allows external signing implementations (e.g., TPM, HSM) without
* requiring the crypto callback infrastructure.
Expand Down Expand Up @@ -30273,6 +30301,8 @@ static int MakeSignatureCb(CertSignCtx* certSignCtx, const byte* buf,

return ret;
}
#endif /* (!NO_RSA && !WOLFSSL_RSA_PUBLIC_ONLY && !WOLFSSL_RSA_VERIFY_ONLY) ||
* (HAVE_ECC && HAVE_ECC_SIGN) || WOLFSSL_CERT_SIGN_CB */
#endif /* WOLFSSL_CERT_GEN || WOLFSSL_CERT_REQ */


Expand Down
3 changes: 2 additions & 1 deletion wolfssl/internal.h
Original file line number Diff line number Diff line change
Expand Up @@ -851,7 +851,8 @@
#if !defined(WOLFCRYPT_ONLY) && defined(NO_PSK) && \
(defined(NO_DH) || !defined(HAVE_ANON)) && \
defined(NO_RSA) && !defined(HAVE_ECC) && \
!defined(HAVE_ED25519) && !defined(HAVE_ED448)
!defined(HAVE_ED25519) && !defined(HAVE_ED448) && \
!defined(HAVE_FALCON) && !defined(WOLFSSL_HAVE_MLDSA)
#error "No cipher suites available with this build"
#endif

Expand Down
86 changes: 80 additions & 6 deletions wolfssl/test.h
Original file line number Diff line number Diff line change
Expand Up @@ -458,18 +458,35 @@ err_sys_with_errno(const char* msg)
} while(0)


#ifndef WOLFSSL_NO_TLS12
#define SERVER_DEFAULT_VERSION 3
#else
/* True when no classic public-key authentication algorithm is compiled in
* (RSA, ECC, Ed25519 and Ed448 all disabled). Shared by the version-default
* logic below and the PSK-fallback logic in the client/server examples so the
* duplicated conditions cannot drift apart. */
#if defined(NO_RSA) && !defined(HAVE_ECC) && !defined(HAVE_ED25519) && \
!defined(HAVE_ED448)
#define TEST_NO_CLASSIC_AUTH
#endif

/* With no classic authentication algorithm, a certificate-authenticated
* handshake relies on a post-quantum signature (ML-DSA), which is TLS 1.3
* only, so default the examples to TLS 1.3 for such post-quantum-only builds.
* A PSK-only build (no ML-DSA) keeps the historic TLS 1.2 default. */
#if defined(WOLFSSL_NO_TLS12) || \
(defined(TEST_NO_CLASSIC_AUTH) && defined(WOLFSSL_TLS13) && \
defined(WOLFSSL_HAVE_MLDSA))
#define SERVER_DEFAULT_VERSION 4
#else
#define SERVER_DEFAULT_VERSION 3
#endif
#define SERVER_DTLS_DEFAULT_VERSION (-2)
#define SERVER_INVALID_VERSION (-99)
#define SERVER_DOWNGRADE_VERSION (-98)
#ifndef WOLFSSL_NO_TLS12
#define CLIENT_DEFAULT_VERSION 3
#else
#if defined(WOLFSSL_NO_TLS12) || \
(defined(TEST_NO_CLASSIC_AUTH) && defined(WOLFSSL_TLS13) && \
defined(WOLFSSL_HAVE_MLDSA))
#define CLIENT_DEFAULT_VERSION 4
#else
#define CLIENT_DEFAULT_VERSION 3
#endif
#define CLIENT_DTLS_DEFAULT_VERSION (-2)
#define CLIENT_INVALID_VERSION (-99)
Expand Down Expand Up @@ -679,6 +696,63 @@ err_sys_with_errno(const char* msg)
#endif
#endif

/* ML-DSA (FIPS 204) certificate material for post-quantum-only TLS 1.3 tests.
* The mldsa<N>-cert files are self-signed, so the same file serves as both the
* peer certificate and the trust anchor (CA) used to verify it.
*
* Defined under the same WOLFSSL_HAVE_MLDSA condition the client/server example
* ladders reference these macros under, so definition and use cannot diverge.
* MLDSA_TEST_LEVEL/MLDSA_TEST_DIR are internal composition helpers: unlike the
* fixed cert paths above, the ML-DSA path depends on whichever level is built
* (WOLFSSL_HAVE_MLDSA does not imply a level) and on the target base path, so
* there is no single literal to inline. They are consumed by the mldsa*File
* macros at point of use and are therefore left defined. */
#if defined(WOLFSSL_HAVE_MLDSA)

#if !defined(WOLFSSL_NO_ML_DSA_65)
#define MLDSA_TEST_LEVEL "mldsa65"
#elif !defined(WOLFSSL_NO_ML_DSA_44)
#define MLDSA_TEST_LEVEL "mldsa44"
#elif !defined(WOLFSSL_NO_ML_DSA_87)
#define MLDSA_TEST_LEVEL "mldsa87"
#else
#error "WOLFSSL_HAVE_MLDSA is set but no ML-DSA parameter level is enabled"
#endif

#if defined(WOLFSSL_NO_CURRDIR) || defined(WOLFSSL_MDK_SHELL)
#define MLDSA_TEST_DIR "certs/mldsa/"
#elif defined(NETOS) && defined(HAVE_FIPS)
#define MLDSA_TEST_DIR FS_VOLUME1_DIR "certs/mldsa/"
#else
#define MLDSA_TEST_DIR "./certs/mldsa/"
#endif

#ifdef WOLFSSL_PEM_TO_DER
#ifndef mldsaCertFile
#define mldsaCertFile MLDSA_TEST_DIR MLDSA_TEST_LEVEL "-cert.pem"
#endif
#ifndef mldsaKeyFile
#define mldsaKeyFile MLDSA_TEST_DIR MLDSA_TEST_LEVEL "-key.pem"
#endif
#else
#ifndef mldsaCertFile
#define mldsaCertFile MLDSA_TEST_DIR MLDSA_TEST_LEVEL "-cert.der"
#endif
#ifndef mldsaKeyFile
#define mldsaKeyFile MLDSA_TEST_DIR MLDSA_TEST_LEVEL "_priv-only.der"
#endif
#endif
#ifndef cliMldsaCertFile
#define cliMldsaCertFile mldsaCertFile
#endif
#ifndef cliMldsaKeyFile
#define cliMldsaKeyFile mldsaKeyFile
#endif
#ifndef caMldsaCertFile
#define caMldsaCertFile mldsaCertFile
#endif
#endif /* WOLFSSL_HAVE_MLDSA */

#ifdef WOLFSSL_PEM_TO_DER
#define CERT_FILETYPE WOLFSSL_FILETYPE_PEM
#else
Expand Down
Loading