Skip to content

Add --enable-tinytls13 TLS 1.3-only footprint profile#10751

Open
aidangarske wants to merge 3 commits into
wolfSSL:masterfrom
aidangarske:tinytls13
Open

Add --enable-tinytls13 TLS 1.3-only footprint profile#10751
aidangarske wants to merge 3 commits into
wolfSSL:masterfrom
aidangarske:tinytls13

Conversation

@aidangarske

Copy link
Copy Markdown
Member

Description

Adds --enable-tinytls13, a TLS 1.3-only footprint profile for embedded and resource-constrained targets. It is a translation layer over
existing wolfSSL macros (the WOLFSSL_TINY_TLS13 umbrella in settings.h), so it adds no new feature flags to the core library. Non-FIPS.

Profiles and adders

  • PSK floor (default): PSK + ECDHE, no X.509 (X25519, AES-128-GCM, SHA-256, HKDF). The smallest build.
  • Cert profile (cert): minimal X.509 chain verify (ECDSA P-256). A reduced-security verify (no name constraints, relaxed ASN.1, no CRL) for
    a known or pinned CA, not public-internet PKI. Surfaced in the configure output and docs.
  • Adders (comma-separated): server, mutualauth, staticmem, asm, p256, sha384, mldsa (ML-DSA-65 verify), rsaverify (RSA-PSS verify). For
    example --enable-tinytls13=cert,server,mldsa.

Footprint

Flash of the gc-sectioned linked client (-Os -flto --gc-sections), Cortex-M33:

Config Cortex-M33 x86_64 aarch64
PSK, X25519 (floor) 30.1 KB 54.8 KB 49.5 KB
PSK, P-256 36.5 KB 64.5 KB 57.9 KB
Cert, ECDSA P-256 61.3 KB 108.2 KB 93.2 KB
Mutual TLS 65.0 KB 114.1 KB 97.5 KB

Testing

The added tinytls13.yml workflow builds and tests every profile and adder on a single runner (parallel-make-check.py, ccache, same setup as
psk.yml). Stripped configs that the broad unit suite cannot gate for are build-verified with testwolfcrypt plus
examples/configs/tinytls13_smoke.c, a self-contained in-memory TLS 1.3 handshake that drives PSK, ECDSA, ML-DSA-65 and RSA-PSS chain
verification, plus forced ChaCha20-Poly1305 / AES-256-GCM / X25519MLKEM768.

aidangarske and others added 2 commits June 19, 2026 15:22
Make every --enable-tinytls13 spelling build and pass locally, and grow the
CI matrix to cover them. These are fixes found while testing the configs the
CI workflow had not actually exercised.

- internal.h, internal.c, ssl_load.c: include ML-DSA and Falcon in the
  pkCurveOID member and producer guards so the PSK plus ML-DSA build compiles.
- tls13.c: gate the DoTls13CertificateVerify definition on NO_CERTS to match
  its call site.
- settings.h: let the AES-256 adder survive the floor, default the
  user_settings path to the SHA-256 floor, make WOLFSSL_NO_MALLOC opt-in so
  the test suite still runs, and keep ML-DSA ASN.1 for the cert profile.
- configure.ac: drive ENABLED_ASM and emit WOLFSSL_NO_ASM for the small C
  floor, restrict SP math to P-256, strip ML-DSA ASN.1 only on the PSK floor,
  and print a notice for the reduced security cert verify.
- examples: guard the cert loading paths for NO_CERTS and treat NO_CERTS as
  PSK mode in echoserver and echoclient.
- Add examples/configs/tinytls13_smoke.c, an in memory TLS 1.3 handshake test
  that drives PSK, ECDSA, ML-DSA-65 and RSA-PSS chain verify, plus forced
  cipher suites, for builds with no example or unit test harness.
- certs: add ECDSA leaves signed by the ML-DSA-65 and RSA-PSS CAs so the cert
  profiles drive a real PQC and PSS chain verify in CI.
- .github/workflows/tinytls13.yml: cover every profile and adder, run the
  smoke handshake on the build verified configs, and least privilege the
  workflow token.
@aidangarske aidangarske marked this pull request as ready for review June 22, 2026 20:07
@github-actions

Copy link
Copy Markdown

retest this please

@Frauschi Frauschi left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Great work overall! Only some smaller nits.

#endif

/* ===== PQC ADDERS (valid on either profile; SHA-3/SHAKE pulled in auto) = */
#if 0 /* ML-DSA-65 verify-only. Use with the cert profile (Profile B) for TLS

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why ML-DSA 65 and not 44? In the otherwise default config, we pair that with X25519 / SECP256 and AES 128, so we have zero security benefit over the 44 parameter set.
As we are specifically targeting tiny systems, I'd recommend going with ML-DSA 44 here if there is no hard requirement on the 65 parameter set.

Note: for ML-KEM, the medium parameter set ML-KEM 768 has been the one with the most adoption. So for that, only going with the 768 parameter set (and disabling the others) is suitable.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Makes sense I will do 44 instead for the defualt

* auth: the PSK floor has no certificate to verify, so on Profile A
* this only confirms the umbrella builds. */
#define WOLFSSL_HAVE_MLDSA
#define WOLFSSL_DILITHIUM_VERIFY_ONLY

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Replace DILITHIUM with MLDSA in all these macros.

#endif
#if 0 /* ML-KEM-768 + X25519MLKEM768 hybrid */
#define WOLFSSL_HAVE_MLKEM
#define WOLFSSL_WC_MLKEM

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

WOLFSSL_WC_MLKEM is not required anymore.

But you may want WOLFSSL_NO_ML_KEM_512, WOLFSSL_NO_ML_KEM_1024 and WOLFSSL_MLKEM_DYNAMIC_KEYS instead.

* standard test suite relies on. */
#ifdef WOLFSSL_TINY_TLS13_STATIC_MEM
#undef WOLFSSL_STATIC_MEMORY
#define WOLFSSL_STATIC_MEMORY

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

With only this option enabled, the default values for WOLFMEM_BUCKETS and WOLFMEM_DIST (and some others in memory.h) are used, which are definitely not embedded-friendly. I think for the tiny setup here, we should override these with some more suitable values.

You can use Jacob's tool to determine these with your existing setups I guess.

#undef NO_SESSION_CACHE
#define NO_SESSION_CACHE
#undef SINGLE_THREADED
#define SINGLE_THREADED

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You may also want NO_FILESYSTEM, NO_CLIENT_CACHE, NO_HANDSHAKE_DONE_CB, NO_SIG_WRAPPER, NO_PWDBASED.

…optimizer-measured static-mem bucket guidance, footprint hygiene
@aidangarske

Copy link
Copy Markdown
Member Author

Jenkins retest this please

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.

3 participants