Skip to content

Fenrir fixes#10230

Open
julek-wolfssl wants to merge 11 commits intowolfSSL:masterfrom
julek-wolfssl:fenrir/20260415
Open

Fenrir fixes#10230
julek-wolfssl wants to merge 11 commits intowolfSSL:masterfrom
julek-wolfssl:fenrir/20260415

Conversation

@julek-wolfssl
Copy link
Copy Markdown
Member

Issue numbers:
1824
2126
2128
2131
2913
2914
2915
2916
2921
2922
2925
2927

@julek-wolfssl julek-wolfssl self-assigned this Apr 15, 2026
Copilot AI review requested due to automatic review settings April 15, 2026 14:59
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

This PR (“Fenrir fixes”) adds regression tests for multiple reported TLS/TLS-extension failure modes (issues 1824, 2126, 2128, 2131, 2913–2916, 2921–2922, 2925, 2927) and hardens several TLS extension size calculations to better handle potential 16-bit length overflows.

Changes:

  • Add new API-level tests covering EMS resumption downgrade, AEAD/tag corruption handling, secure renegotiation verify_data mismatches, TLS 1.3 HRR cipher suite mismatches, and TLS 1.3 ticket age window behavior.
  • Add a new test validating session ticket HMAC verification failure via the ticket key callback.
  • Update multiple TLS extension “GetSize” helpers to use wider intermediates and add overflow checks.

Reviewed changes

Copilot reviewed 4 out of 4 changed files in this pull request and generated 5 comments.

File Description
tests/api/test_tls_ext.h Exposes new TLS extension test prototypes.
tests/api/test_tls_ext.c Implements new TLS/extension negative-path regression tests.
tests/api.c Registers new tests and adds a session-ticket HMAC corruption test.
src/tls.c Adds overflow checks in several TLS extension size calculators and returns LENGTH_ERROR for PSK oversize conditions.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread tests/api/test_tls_ext.c Outdated
Comment thread tests/api/test_tls_ext.c Outdated
Comment thread src/tls.c
Comment thread src/tls.c
Comment thread src/tls.c
@github-actions
Copy link
Copy Markdown

github-actions bot commented Apr 15, 2026

MemBrowse Memory Report

No memory changes detected for:

Match the TLSX_SNI_GetSize pattern: use a word32 accumulator and return
0 if the aggregate size exceeds WOLFSSL_MAX_16BIT, so a large number of
ALPN entries can no longer silently wrap the length computation.
Mirror the TLSX_SNI_GetSize pattern: accumulate into a word32 and
return 0 when the aggregate size exceeds WOLFSSL_MAX_16BIT so large
idSz values or many TCA entries no longer silently wrap to a small
value that undersizes the TLSX_TCA_Write output buffer.
Both TLSX_PreSharedKey_GetSize and TLSX_PreSharedKey_GetSizeBinders
accumulate per-identity bytes into a word16. With enough PSK entries
(or large binderLen/identityLen values) the accumulator wraps silently
and the caller allocates an undersized extension buffer, which
TLSX_PreSharedKey_Write then overflows.

Switch both accumulators to word32 and return LENGTH_ERROR when the
total would exceed the 16-bit wire length field.
The CA Names extension size accumulator was a word16. With enough
CA entries (or large DER-encoded names) the running total can wrap
silently, leaving TLSX_CA_Names_Write to overflow an undersized
extension buffer. Match TLSX_SNI_GetSize: use a word32 accumulator
and return 0 when the total exceeds WOLFSSL_MAX_16BIT.
Covers the HandleResumeHistory check that RFC 7627 Section 5.3 requires:
if the original session used Extended Master Secret, the server MUST
abort when a resumption ClientHello is received without EMS. The new
memio test performs a TLS 1.2 handshake with EMS, saves the session,
disables EMS on a fresh client, resumes with the saved session, and
asserts the server returns EXT_MASTER_SECRET_NEEDED_E.
Cover the Poly1305 ConstantCompare tag check in ChachaAEADDecrypt that
no existing test was hitting (VERIFY_MAC_ERROR never expected in the
suite). A memio-based TLS 1.2 handshake over
ECDHE-RSA-CHACHA20-POLY1305 completes, the server's IORecv is then
replaced with a wrapper that flips the final byte of the next record
body so the forged Poly1305 tag no longer matches. The server's
wolfSSL_read must surface VERIFY_MAC_ERROR.
Tls13IntegrityOnly_Decrypt was completely untouched by existing tests,
so any mutation of its ConstantCompare would pass CI. Add a memio
TLS 1.3 handshake over TLS13-SHA256-SHA256 (integrity-only NULL cipher),
then corrupt the final byte of the next record body via an IORecv
wrapper and assert the server surfaces DECRYPT_ERROR.
Cover both branches of TLSX_SecureRenegotiation_Parse's ConstantCompare
against the cached Finished verify_data: a single memio test loops
over client-side and server-side corruption, renegotiates, and
asserts the offending peer surfaces SECURE_RENEGOTIATION_E.
wolfSSL_TicketKeyCb is the built-in ticket callback registered by the
OpenSSL-compat wolfSSL_CTX_set_tlsext_ticket_key_cb API. Its
ConstantCompare of the ticket HMAC was never reached in any test, so a
deletion of the check would silently accept forged tickets. New test
sets up the compat callback, establishes a TLS 1.2 session, saves it,
flips a byte of the encrypted ticket, and asserts the resumption
attempt does not complete.
DoTls13ClientHello enforces RFC 8446 Section 4.1.4 by comparing the
cipher suite in the second ClientHello to the hrrCipherSuite cached on
the server from the HelloRetryRequest. No existing test covers the
mismatch branch, so a deletion of the check would silently allow a
client to switch cipher suite between CH1 and CH2. Drive a partial
handshake until the server has emitted the HRR, then flip the cached
hrrCipherSuite on the server; processing CH2 must surface
INVALID_PARAMETER.
DoClientTicketCheck's ticket-age bounds (-1000 ms low bound and
MAX_TICKET_AGE_DIFF*1000+1000 ms high bound) were never exercised by
any integration test, so mutations of the constants went undetected.
Establish a TLS 1.3 session, read the NewSessionTicket, then shift the
client's cached ageAdd by well over 1 second so the server's
unobfuscated diff falls outside the valid window on resumption. The
server must reject the PSK — session_reused stays 0.
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