Skip to content

Enable PQC-only TLS builds (ML-KEM + ML-DSA, RSA/ECC/DH disabled)#28

Open
Frauschi wants to merge 1 commit into
masterfrom
claude/wolfssl-pqc-only-patches-dfmaby
Open

Enable PQC-only TLS builds (ML-KEM + ML-DSA, RSA/ECC/DH disabled)#28
Frauschi wants to merge 1 commit into
masterfrom
claude/wolfssl-pqc-only-patches-dfmaby

Conversation

@Frauschi

@Frauschi Frauschi commented Jul 5, 2026

Copy link
Copy Markdown
Owner

Description

Refines and upstreams the two "quantum-safe-only" patches from the wolfSSL EO 14412 blog post (code patch, certs patch) so wolfSSL can build a post-quantum-only TLS 1.3 stackML-KEM for key exchange and ML-DSA for authentication — with RSA, ECC and DH all disabled (the CNSA 2.0 / EO 14412 posture).

The original patches were generated against commit ac01707f (master is ~190 commits ahead). Rather than apply them verbatim, this PR reconciles them with current master and refines them for upstreaming:

Core library (Enable PQC-only TLS builds):

  • internal.h — the "No cipher suites available" #error is an authentication check, so it now treats Falcon and ML-DSA as valid signature algorithms.
  • ssl.c — the "No cipher suites defined" #error is a key-exchange check, so it treats ML-KEM as a valid KEX. (Refinement over the original, which added HAVE_DILITHIUM — a signature alg — to this key-exchange guard.)
  • internal.c — extends the CopyDecodedToX509 pkCurveOID guard to Falcon/ML-DSA. The sibling pkCurveOID guards (WOLFSSL_CTX/WOLFSSL/DecodedCert) and the Dcv13Args block have already converged on master, so those hunks are dropped.
  • tls13.c — silences an unused hashAlgo parameter and refreshes a stale #endif comment.
  • asn.c — guards the RSA/ECC-only cert-signing callback helpers so cert generation compiles cleanly with RSA and ECC disabled.

Examples & tests (use ML-DSA certificates for PQC-only builds):

  • test.h — defaults to TLS 1.3 when no classic auth is built in, and adds ML-DSA cert macros. These reuse the existing self-signed certs/mldsa/mldsa65 material (each self-signed cert is its own trust anchor), so no new certificate files are added — the second (certs) patch is redundant now that master ships certs/mldsa/.
  • client.c/server.c/echoclient.c/echoserver.c — ML-DSA branch in the cert-selection ladders; stop forcing PSK when ML-DSA can authenticate. (The echo examples were not touched by the original patch; extending them makes all TLS examples work in PQC-only mode.)
  • test_tls13.c — selects the ML-DSA cert in the server test setup.

CI (add PQC-only TLS build and handshake test):

  • A focused pqc-only.yml workflow that builds the RSA/ECC/DH-disabled + ML-KEM/ML-DSA config and runs the wolfCrypt self-tests and a TLS 1.3 echo handshake (ML-KEM + ML-DSA only).

Deliberately not included (kept the diff minimal; happy to add on request): the original patches' root-level build.sh/server.sh/client.sh demo scripts (not upstream-appropriate); an --enable-pqc-only umbrella configure option; and a ChangeLog entry (left to maintainers). The equivalent build is one configure line — see Testing.

Testing

Configure/build/verify all done locally on this branch:

  • PQC-only build — compiles cleanly, no #error, no RSA/ECC symbols in libwolfssl:
    ./configure --enable-mlkem --enable-mldsa --enable-tls-mlkem-standalone \
        --disable-rsa --disable-ecc --disable-dh
    make
    
  • Live handshakeexamples/server + examples/client complete a TLS 1.3, ML_KEM_512, server ML-DSA-authenticated handshake (client verifies the ML-DSA cert, no -d bypass); app data flows both ways.
  • ./testsuite/testsuite.test — all wolfCrypt self-tests (incl. MLKEM, ML-DSA) plus the TLS echo handshake pass in the PQC-only config.
  • certgen + -Werror variant (--enable-certgen --enable-certreq CFLAGS=-Werror) — builds clean, confirming the asn.c guards.
  • Regression — default ./configure && make && make check (RSA/ECC enabled) → All tests passed!, so classical builds are unaffected.

Known limitation (out of scope, pre-existing): TLS 1.3 session-ticket resumption (scripts/resume.test) fails with an AES-GCM auth error in this profile, unrelated to the auth/KEX guard changes — hence the dedicated build+handshake workflow rather than a full make check entry.

Checklist

  • added tests (CI workflow + ML-DSA path in test_tls13.c; reuses existing certs/mldsa/)
  • updated/added doxygen
  • updated appropriate READMEs
  • Updated manual and documentation

🤖 Generated with Claude Code

https://claude.ai/code/session_01FnWzwJUrkZ7LroWXiQnM8S


Generated by Claude Code

@Frauschi Frauschi force-pushed the claude/wolfssl-pqc-only-patches-dfmaby branch from 0e199cc to 17c6002 Compare July 7, 2026 21:15
Allow wolfSSL to build and run a quantum-safe-only TLS 1.3 stack - ML-KEM
for key exchange and ML-DSA (FIPS 204) for authentication - with RSA, ECC
and DH all disabled (the CNSA 2.0 / EO 14412 posture).

Core enablement:
- internal.h: the "No cipher suites available" #error is an authentication
  check, so treat Falcon and ML-DSA as valid signature algorithms.
- ssl.c: the "No cipher suites defined" #error is a key-exchange check, so
  treat a usable standalone ML-KEM group as a valid key exchange
  (WOLFSSL_HAVE_MLKEM && !WOLFSSL_TLS_NO_MLKEM_STANDALONE).
- internal.c: extend the CopyDecodedToX509 pkCurveOID guard to Falcon/ML-DSA
  to match the sibling struct-field guards.
- tls13.c: silence an unused hashAlgo parameter in EncodeSigAlg and refresh a
  stale #endif comment.
- asn.c: guard the RSA/ECC-only certificate signing callback helpers so cert
  generation compiles cleanly with RSA and ECC disabled, while keeping
  MakeSignatureCb available for the WOLFSSL_CERT_SIGN_CB (TPM/HSM) offload path.

TLS 1.3 session-ticket resumption:
- tls.c: advertise the psk_dhe_ke pre-shared-key exchange mode when a usable
  standalone ML-KEM group is available, not only for classic (EC)DHE groups.
  Without this an ML-KEM-only build fell back to psk_ke, the resumption key
  schedules diverged, and the first AEAD record failed to authenticate
  (AES_GCM_AUTH_E), breaking resumption whenever ECC and DH were disabled.

Examples and tests:
- test.h: default to TLS 1.3 when no classic authentication algorithm is built
  in (ML-DSA is TLS 1.3 only), factor the shared "no classic auth" condition
  into TEST_NO_CLASSIC_AUTH, and add ML-DSA cert macros that track the enabled
  level, target base path and PEM/DER encoding. These reuse the existing
  self-signed certs/mldsa material; no new certificate files are added.
- client.c/server.c/echoclient.c/echoserver.c/test_tls13.c: add an ML-DSA
  branch to the certificate-selection ladders and stop forcing PSK when ML-DSA
  can authenticate.

CI:
- Add a PQC-only (RSA/ECC/DH-disabled, ML-KEM + ML-DSA, session tickets) entry
  to the pq-all.yml matrix so the build, a full TLS 1.3 handshake, and
  ML-KEM-only session-ticket resumption are exercised by make check.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01FnWzwJUrkZ7LroWXiQnM8S
@Frauschi Frauschi force-pushed the claude/wolfssl-pqc-only-patches-dfmaby branch from 17c6002 to 7a7c87c Compare July 7, 2026 21:24
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants