Skip to content

Fenrir fixes#10803

Open
Frauschi wants to merge 8 commits into
wolfSSL:masterfrom
Frauschi:fenrir
Open

Fenrir fixes#10803
Frauschi wants to merge 8 commits into
wolfSSL:masterfrom
Frauschi:fenrir

Conversation

@Frauschi

Copy link
Copy Markdown
Contributor

Fix various Fenrir issues:

  • F-6345: Reject oversized lengths in the memory BIO write path so an inflated length can't grow a short buffer and read past the source.
  • F-6346: Reject oversized lengths in EVP_EncodeBlock to prevent the base64 output-size calculation from overflowing.
  • F-6347: Reject negative and oversized lengths in EVP_EncodeUpdate to stop integer overflow and out-of-bounds input reads.
  • F-6350: Cap the d2i_ASN1_OBJECT parse window to the encoded OID size to avoid reading beyond the object.
  • F-6351: Fix a use-after-free in wolfSSL_ASN1_STRING_set when the string is set from an alias of its own buffer.
  • F-6426: Reject Camellia cipher operations when no key has been set, returning MISSING_KEY instead of running on uninitialized state.
  • F-6427: Reject RC2 cipher operations when no key has been set, consistently across ECB and CBC entry points.
  • F-6547: Reject TLS KeyUpdate messages on QUIC connections (both send and receive) per RFC 9001 §6.

Frauschi added 8 commits June 29, 2026 09:02
The Camellia encrypt and decrypt operations used the key schedule
without checking that a key had ever been configured. A zeroed or
otherwise unkeyed context has a keySz that does not match 128, 192,
or 256, so the underlying block transform hit the default no-op case
and CBC emitted an easily reversible XOR chain while still returning
success. A caller who forgot wc_CamelliaSetKey received a success
code with effectively unencrypted output.

Add a key-state check that accepts only valid Camellia key sizes and
have wc_CamelliaEncryptDirect, wc_CamelliaDecryptDirect,
wc_CamelliaCbcEncrypt, and wc_CamelliaCbcDecrypt return MISSING_KEY
when no key has been set. Mirrors the existing 3DES keySet guard.

Add a regression test covering the unkeyed and garbage key-size paths.
The RC2 encrypt and decrypt operations used the expanded key schedule
without checking that a key had ever been configured. On a zeroed or
otherwise unkeyed context the ECB ops ran over an all-zero schedule and
returned success, and the CBC wrappers inherited the same behavior, so
a caller who skipped wc_Rc2SetKey received ciphertext under an
unintended key with no error signalled.

Guard wc_Rc2EcbEncrypt and wc_Rc2EcbDecrypt on a zero keylen and return
MISSING_KEY when no key has been set. The CBC wrappers call these and
propagate the error. Mirrors the existing 3DES keySet guard.

Add a regression test covering the unkeyed path for all four ops.
wolfSSL_BIO_write rejected negative lengths but allowed a large positive
length through to wolfSSL_BIO_MEMORY_write. On a fresh buffer an INT_MAX
length overflowed the 4/3 buffer growth calculation, so the grow reported
success with a short allocation and the following copy read far past the
small source buffer.

Add an upper bound check that rejects lengths large enough to overflow the
growth math before any allocation or copy, and add a regression test that
drives a huge length through the public BIO_write entry point.
wolfSSL_EVP_EncodeBlock rejected negative input lengths but passed any
large positive length straight to Base64_Encode_NoNl, which read that
many bytes from the caller input buffer and ran past its allocation.

Reject input lengths whose base64 output would overflow a positive int,
which also bounds the read against the caller allocation. The encoded
length is the int return value, so the safe maximum input is
(INT_MAX / 4) * 3.
wolfSSL_EVP_EncodeUpdate did not validate the input length. A large
inl caused the block loop and the residual copy to read far past the
caller's input buffer, and a negative inl was silently treated as
success. Reject negative lengths and lengths whose base64 output would
overflow a positive int before processing any data.
An oversized length argument was passed straight to GetASNHeader as the
buffer bound. A caller supplying a length larger than the real buffer let
the OBJECT_ID header claim more content than was present, driving the OID
validation read past the end of the allocation. Since an ASN1_OBJECT is an
OID, clamp the parse window to the maximum OID encoding so the header
decode cannot read beyond a sane bound.
When the caller passes the object's own data pointer as the source,
wolfSSL_ASN1_STRING_set freed the existing buffer before copying from
it, reading freed memory in the dynamic case and copying cleared bytes
in the fixed-buffer case. Duplicate the source into a temporary buffer
when it aliases the object before disposing of the old buffer, then
free the temporary once the copy completes.
QUIC performs key updates at the packet-protection layer via the Key
Phase bit, so RFC 9001 section 6 requires a QUIC endpoint to reject any
received TLS KeyUpdate handshake message as a fatal unexpected_message
connection error and to never send one. The TLS 1.3 receive path
processed the message normally, rotating traffic secrets and possibly
emitting a prohibited KeyUpdate response, and the send path allowed a
QUIC connection to originate a KeyUpdate.

Guard the key_update case in SanityCheckTls13MsgReceived so a QUIC
connection aborts with a fatal unexpected_message alert, and guard
Tls13UpdateKeys so a QUIC connection cannot send a KeyUpdate. Add a
QUIC unit test that feeds a post-handshake KeyUpdate and confirms the
connection is refused.
@Frauschi Frauschi self-assigned this Jun 29, 2026
@Frauschi Frauschi marked this pull request as ready for review June 29, 2026 12:27
@github-actions

Copy link
Copy Markdown

retest this please

@github-actions

Copy link
Copy Markdown

@Frauschi

Copy link
Copy Markdown
Contributor Author

Jenkins retest this please

@Frauschi Frauschi assigned wolfSSL-Bot and unassigned Frauschi Jun 30, 2026
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