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.
- Retry wolfSSL_write on the same recoverable send errors the plain-UDP
baseline already retries on: EAGAIN/EWOULDBLOCK surface as WANT_WRITE
and ENOBUFS as SOCKET_ERROR_E with errno preserved. The buffered
record is flushed by the retried call without re-encrypting.
- Treat an explicit -? as a help request: print usage to stdout and
exit 0, keeping stderr and a failure exit for genuine option errors.
- Enumerate ciphers with wolfSSL_get_cipher_list() instead of an 8 KiB
stack buffer, and range-check -p and -b like the other numeric
options.
- Document in BuildMessage that the FIPS<2 path overwrites the
explicit-nonce placeholder inside BuildMessage itself, and that the
one path transmitting the bytes as written (ATOMIC_USER MacEncryptCb)
still emits the sequence number that RFC 5288 et al. prescribe.
Fail loudly if clock_gettime() ever fails instead of computing
throughput from uninitialized stack, and warn when -z is combined with
-s since the sink-send only applies to the client.
dtls_bench.c is built whenever DTLS and the example servers are enabled,
including the cross-mingw-all-crypto multi-test scenario, which cross-
compiles for Windows. It directly includes POSIX-only headers
(<sys/socket.h>, <arpa/inet.h>, <netdb.h>, <net/if.h>) that mingw does
not ship, so the build failed there.
Gate the networking includes and the whole benchmark body behind a
DTLS_BENCH_ENABLED check (WOLFSSL_DTLS, not USE_WINDOWS_API, not
WOLFSSL_NO_SOCK). When the platform lacks POSIX BSD sockets, compile a
small stub main() that reports the tool is unsupported, so the source
tree still builds.
Add examples/benchmark/dtls_bench, a DTLS throughput benchmark that
completes a handshake and then measures bulk-send throughput. It
supports DTLS 1.2 and 1.3, selectable cipher suites, an end-to-end
mode, and a -z sink mode that discards records on the server after the
handshake to isolate the sender's record-layer cost. The socket is set
up with wolfSSL_set_dtls_fd_connected.
Optimize the send path exercised by the benchmark:
- wolfio (EmbedSendTo): cache the per-descriptor socket-type probe
(getsockopt SO_TYPE) in WOLFSSL_DTLS_CTX instead of running it on
every send, removing a syscall from the record send path. The cache
is invalidated whenever rfd/wfd is reassigned.
- internal (BuildMessage): for AEAD suites whose explicit nonce is the
8-byte record sequence number, write the sequence number directly as
nonce_explicit instead of drawing it from the RNG. This covers
AES-GCM (RFC 5288 sec 3), AES-CCM (RFC 6655 sec 3), SM4-GCM/CCM
(RFC 8998 sec 3), and Camellia-/ARIA-GCM which inherit the RFC 5288
construction; ChaCha20 uses an implicit nonce and is excluded. A new
read-only PeekSEQ() helper reads the sequence number without advancing
the per-direction counter, leaving the single mandated increment to
writeAeadAuthData().
Also ignore the built dtls_bench binary in .gitignore.
Extend the swdev callback to handle ECC operations: keygen, ECDH, sign,
verify, get-size, get-sig-size.
Relax WOLF_CRYPTO_CB_ONLY_ECC guards in the test suite so that tests run
under swdev, and wire wc_SwDev_Init/Cleanup into testsuite, client, and
server. Two tests are intentionally kept excluded even with swdev because
they call raw ECC math primitives (wc_ecc_mulmod, on-curve validation in
wc_ecc_import_x963) that are stripped below the cryptocb dispatch layer:
- ecc_mulmod_test (wolfcrypt/test/test.c)
- test_wc_ecc_import_x963_off_curve (tests/api/test_ecc.c)
- x509_str: require CA:TRUE unconditionally in wolfSSL_X509_verify_cert;
verify leaf signature even when verify_cb overrides INVALID_CA
- x509_str: align WOLFSSL_X509_V_ERR_INVALID_CA with OpenSSL value (79)
so OPENSSL_COEXIST builds compile; bump WC_OSSL_V509_V_ERR_MAX to 80
and extend error_test() missing-value table for the new gaps
- asn: reject embedded NUL in dNSName / rfc822Name / URI SAN entries
- internal: re-verify restored ticket peer cert against trust store with
CRL/OCSP checks; clear stale state from session cache on verification
failure
- ticket: bind SNI and ALPN into session ticket via compile-time selected
hash (TICKET_BINDING_HASH_TYPE); reject resumption on mismatch in both
TLS 1.3 and TLS 1.2 paths
- ticket: defer SNI/ALPN binding check until after extensions are parsed
by consolidating into VerifyTicketBinding(), called once after
ALPN_Select in DoTls13ClientHello and DoClientHello; the early
per-call sites ran before extensions were parsed and rejected valid
resumptions in nginx, haproxy, grpc, and CPython integration tests
- ssl_sess: free previous session in wolfSSL_d2i_SSL_SESSION before
overwrite
- examples/client: increase SESSION_TICKET_LEN fallback from 256 to 2048
to support larger tickets
- tests: update SAN NUL fixtures and add parse-time rejection coverage;
add test_tls13_ticket_peer_cert_reverify for CA-removal scenario; skip
it under WOLFSSL_NO_DEF_TICKET_ENC_CB
Windows test code pre-picked a random port via GetRandomPort() (returning
a value in [49152, 65535]) before calling bind(), with no check that the
port was free and no retry on collision. Under load this occasionally
collided with an already-bound port and aborted the test with
"tcp bind failed", producing intermittent Jenkins failures (e.g. PRB
windows-test-v2 #17140 in the OCSP responder test).
The Unix path already does the right thing: bind to port 0 (OS-assigned
ephemeral) and read the port back via getsockname(). The same primitives
exist in Winsock 1.1, so drop the USE_WINDOWS_API guard around the
getsockname block in tcp_listen()/udp_accept() and remove the per-caller
GetRandomPort() workarounds in the OCSP responder, server example, and
the api.c / test_ossl_bio.c test sites. socklen_t is already typedef'd
as int on Windows in test.h.
GetRandomPort() itself is left in place since it is a static inline in a
shipped public test header.
RFC 8446 section 8 requires any server instance to accept 0-RTT for a
given ClientHello at most once. Prior to this change wolfSSL's behaviour
diverged from that requirement in several ways:
* ctx->maxEarlyDataSz defaulted to MAX_EARLY_DATA_SZ whenever the
library was built with WOLFSSL_EARLY_DATA, so servers auto-
advertised 0-RTT in NewSessionTicket without the application
asking. RFC 8446 E.5 says 0-RTT MUST NOT be enabled unless
specifically requested.
* The post-accept eviction is compiled out under NO_SESSION_CACHE,
so builds without the cache accepted 0-RTT with no replay defence.
* Stateless self-encrypted tickets do not carry a session ID on the
stateless DoClientTicket decrypt path, so wolfSSL_SSL_CTX_remove_
session could not locate them to evict.
* wolfSSL_SSL_CTX_remove_session always returned 0 on success
regardless of whether the session was actually in the cache,
diverging from OpenSSL's SSL_CTX_remove_session (1 on success,
0 on not-found).
Changes:
* src/internal.c: ctx->maxEarlyDataSz defaults to 0; applications
must opt in with wolfSSL_CTX_set_max_early_data.
* src/tls13.c: #error when WOLFSSL_EARLY_DATA is built with
HAVE_SESSION_TICKET and NO_SESSION_CACHE. Escape hatch
WOLFSSL_EARLY_DATA_NO_ANTI_REPLAY for deployments that take
application-layer responsibility.
* wolfssl/internal.h: imply WOLFSSL_TICKET_HAVE_ID from
WOLFSSL_EARLY_DATA so stateless-ticket issuance populates the
cache under an ID that eviction can find.
* src/ssl_sess.c: wolfSSL_SSL_CTX_remove_session returns 1 when the
session was found (internal-cache hit, or ctx->rem_sess_cb fired
for an external cache), 0 otherwise. Matches OpenSSL semantics.
* src/tls13.c: the 0-RTT acceptance condition in CheckPreSharedKeys
now calls wolfSSL_SSL_CTX_remove_session and checks its return:
the eviction is the check. If the session was in the cache, 0-RTT
is accepted and the single-use requirement is satisfied. If not,
the early_data extension is rejected through the normal path so
the record layer correctly skips in-flight 0-RTT records.
WOLFSSL_MSG at each rejection site.
* doc/dox_comments/header_files/ssl.h: document runtime opt-in.
* tests: four new tests —
test_tls13_0rtt_default_off (fails without default-to-0 fix),
test_tls13_0rtt_stateless_replay (fails without TICKET_HAVE_ID
implication and remove_session gate),
test_tls13_remove_session_return (fails without return-value fix),
test_tls13_0rtt_ext_cache_eviction (fails without ext-cache
counts-as-found fix).
test_tls13_early_data explicitly opts in via
wolfSSL_CTX_set_max_early_data.
tests/api.c: two SSL_CTX_remove_session == 0 assertions updated
to == 1.
scripts/pem.test:
* add setup for WOLFSSL_NO_DER_TO_PEM,
* exit early with skip code if executable dependencies are missing or WOLFSSL_NO_PEM or NO_CODING, and
* add clean skip clauses to convert_to_pem(), compare_pem(), and pem_der_exp(), if WOLFSSL_NO_DER_TO_PEM.
Implement RFC8773bis (draft-ietf-tls-8773bis-13)
cert_with_extern_psk for TLS 1.3, including protocol checks
and API support.
Includes unit tests for API and handshake behavior as well
as tests in the testsuite using extended examples.
* implement legacy compatibility in settings.h and configure.ac (adds --enable-blake2b while retaining --enable-blake2);
* fix incorrect Blake2 gates in wolfcrypt/src/hash.c wc_HashGetDigestSize() and wc_HashGetBlockSize();
* in wolfcrypt/test/test.c hash_test(), backfill missing Blake2 test coverage and separate blake2b from blake2s in typesHashBad[];
* in tests/api/test_hash.c, separate blake2b from blake2s in notCompiledHash[], sizeSupportedHash[], and sizeNotCompiledHash[].