32876 Commits

Author SHA1 Message Date
Gilles Peskine
794e1a89db Add documentation for the new getters and setters
Signed-off-by: Gilles Peskine <Gilles.Peskine@arm.com>
2026-06-16 15:04:35 +02:00
Gilles Peskine
7c28ccf8ab Use functions instead of macros for badmac_seen_or_in_hsfraglen setters
Let the caller handle returning on error. This is less surprising, and it's
more flexible in case the caller needs to perform some cleanup (which is
currently not the case).

Signed-off-by: Gilles Peskine <Gilles.Peskine@arm.com>
2026-06-16 14:56:59 +02:00
Gilles Peskine
93460dafc7 Reject MBEDTLS_SSL_SET_BADMAC_SEEN at compile time if DTLS is disabled
Signed-off-by: Gilles Peskine <Gilles.Peskine@arm.com>
2026-06-15 18:39:19 +02:00
Gilles Peskine
1453fda32c Remove some test cases that are not really meaningful
Remove the "srv" variant of "DTLS proxy: server: get invalid AD record then
accept renego", where the server initiates the renegotiation process by
sending a HelloRequest. The HelloRequest message is not relevant to this
test. The first message of the actual renegotiation is the ClientHello
message from the client, and the interesting part of the test happens when
the client receives the server's response.

Remove "DTLS proxy: server: get invalid AD record then accept early
renego (cli)" and the corresponding "reject" control. This test case doesn't
really do what it is advertised to do, and in particular does not lead to a
call to `ssl_consume_current_message()` in the server. What happens is that
the client sends a ClientHello message to start the renegotiation, then it
blocks until the server has replied. So there is nothing to delay that
ClientHello after:(unlike what happens in the corresponding client-side
test, where the first flight of the renegotiation protocol contains multiple
messages, so we can delay the first of these messages after the second one).
What happens in practice is that the client times out, then resends its
ClientHello, and the proxy sends the delayed ClientHello immediately after
the resent one, which does not cause any interesting behavior in the server.

Signed-off-by: Gilles Peskine <Gilles.Peskine@arm.com>
2026-06-15 18:22:11 +02:00
Gilles Peskine
1db3c1c9a0 Explain the "get invalid AD record .*renego" tests better
Signed-off-by: Gilles Peskine <Gilles.Peskine@arm.com>
2026-06-15 16:14:31 +02:00
Gilles Peskine
a145116bff Don't pass badmac_limit when it would have no effect
Only set `badmac_limit` on the side that actually receives a message with a
bad MAC/tag (injected by the proxy).

Signed-off-by: Gilles Peskine <Gilles.Peskine@arm.com>
2026-06-15 13:37:54 +02:00
Gilles Peskine
a939d850c7 Add DTLS handshake test with badmac_seen=1
Add a test entry point for a handshake with a specially crafted context.
This can be used for defense in depths for scenarios that we think can't
happen, but might actually happen due to a bug, or due to a new feature that
is insufficiently tested. This can also be a proxy for testing aspects of
renegotiation or session resumption in circumstances that are hard to
arrange.

In this commit, use it to test a DTLS handshake with `ssl->badmac_seen`
:(actually `ssl->badmac_seen_or_in_hsfraglen` in the 3.6 branch) set to a
nonzero value. This can't happen, as far as I know (`badmac_seen` can only
be nonzero during renegotiation, not during a nominal handshake or in
session resumption). But it could happen, for example, if
`mbedtls_ssl_session_reset()` failed to reset `badmac_seen`, as was the case
in Mbed TLS 4.0.0 to 4.1.0.

Signed-off-by: Gilles Peskine <Gilles.Peskine@arm.com>
2026-06-15 13:08:43 +02:00
Gilles Peskine
a818c0a8dd Changelog entry for badmac_seen_or_in_hsfraglen confusion
Signed-off-by: Gilles Peskine <Gilles.Peskine@arm.com>
2026-06-05 21:59:07 +02:00
Gilles Peskine
24c2875cb0 Fix confusion between ssl->badmac_seen and ssl->in_hsfraglen
Since Mbed TLS 3.6.3, the field `badmac_seen_or_in_hsfraglen` in the
`mbedtls_ssl_context` structure has a dual purpose: it is the new name of
`badmac_seen` for DTLS, and it has a new meaning `in_hsfraglen` for TLS.
This was done to add support for handshake message fragmentation in TLS
while preserving the library ABI.

There was a bug in some places in the code, which reads the dual-purpose
field in the wrong protocol. Specifically:

* `mbedtls_ssl_prepare_handshake_record()` (beginning): mistakenly reads
  `badmac_seen_or_in_hsfraglen` in DTLS to mean `in_hsfraglen`. (DTLS
  handshake defragmentation does not use `in_hsfraglen`.) As a
  consequence, in DTLS, after receiving a record with a bad MAC, the field
  `ssl->in_hslen` was not correctly updated, which causes problems further
  in handshake message processing.
* `mbedtls_ssl_prepare_handshake_record()` (end): correctly updates
  `badmac_seen_or_in_hsfraglen` in TLS with the `in_hsfraglen` meaning.
* `ssl_consume_current_message()`: incorrectly read
  `badmac_seen_or_in_hsfraglen` in DTLS to mean `in_hsfraglen`, and thus
  stops processing messages after receiving a record with a bad MAC.
* `ssl_get_next_record()`: accesses `badmac_seen_or_in_hsfraglen` to mean
  `badmac_seen` in DTLS. No bug here.
* `mbedtls_ssl_handle_message_type()`: reads `badmac_seen_or_in_hsfraglen`
   to mean `in_hsfraglen` in TLS. No bug here.
* `mbedtls_ssl_session_reset_msg_layer()`: both fields need to be reset
  when not partial, and a partial reset only applies to DTLS where we do
  want to preserve `badmac_seen` in a partial reset. No bug here.
* `mbedtls_ssl_context_save()`, `mbedtls_ssl_context_load()`: saving
  `badmac_seen` in DTLS is desired and done. Saving `in_hsfraglen` in TLS
  is harmless.

To fix this, in `ssl_msg.c`, always access the dual-purpose field
`badmac_seen_or_in_hsfraglen` through getters and setters that are specific
to one purpose and that check that the purpose matches the protocol.

Signed-off-by: Gilles Peskine <Gilles.Peskine@arm.com>
2026-06-05 15:40:28 +02:00
Gilles Peskine
397db25dc3 Add tests demonstrating badmac_seen_or_in_hsfraglen confusion on the server
Signed-off-by: Gilles Peskine <Gilles.Peskine@arm.com>
2026-06-05 15:40:28 +02:00
Gilles Peskine
305bab2bbc Add renegotiate=2 option to ssl_client2
In `ssl_client2`, the existing option `renegotiate=1` causes the client to
initiate renegotiation immediately after the initial handshake. Add a
variant `renegotiate=2` that initiates renegotiation after one data exchange.

Signed-off-by: Gilles Peskine <Gilles.Peskine@arm.com>
2026-06-05 15:40:28 +02:00
Gilles Peskine
ee9ce31e96 Add tests demonstrating badmac_seen_or_in_hsfraglen confusion on the client
After a message with a bad MAC (invalid application data record), try to
renegotiate:

* Test cases where renegotiation (nominal or delayed) is rejected.
  Nothing bad happens.
* A test where renegotiation is misparsed and rejected.
  The subsequent parsing fails.
* A test where the renegotiation request is delayed.
  This causes a heap buffer overflow in `ssl_buffer_message()`.

Signed-off-by: Gilles Peskine <Gilles.Peskine@arm.com>
2026-06-05 15:40:28 +02:00
Gilles Peskine
9124556b6d Check "refusing renegotiation" log in more renegotiation tests
Signed-off-by: Gilles Peskine <Gilles.Peskine@arm.com>
2026-06-05 15:40:28 +02:00
Gilles Peskine
0fb05d3520 Add badmac_limit option to ssl_client2
Signed-off-by: Gilles Peskine <Gilles.Peskine@arm.com>
2026-06-05 15:40:28 +02:00
Gilles Peskine
a9fa52a025 Add one-shot bad AD options to udp_proxy
Signed-off-by: Gilles Peskine <Gilles.Peskine@arm.com>
2026-06-05 15:40:28 +02:00
Gilles Peskine
e8d780f5af Add udp_proxy options to delay an encrypted handshake message
This can be used to simulate data messages received in the wrong epoch, or
to cause a handshake message to be buffered.

Signed-off-by: Gilles Peskine <Gilles.Peskine@arm.com>
2026-06-05 15:40:28 +02:00
Gilles Peskine
929ce501bd Test DTLS renegotiation when badmac_seen_or_in_hsfraglen != 0
Non-regression test for a bug introduced with TLS handshake defragmentation
support in Mbed TLS 3.6.2, whereby the confusion between the `badmac_seen`
meaning and the `in_hsfraglen` meaning of `ssl->badmac_seen_or_in_hsfraglen`
causes renegotiation to be processed incorrectly after receiving a message
with a bad MAC.

This bug will be fixed in a subsequent commit.

Signed-off-by: Gilles Peskine <Gilles.Peskine@arm.com>
2026-06-05 15:40:28 +02:00
Gilles Peskine
ba656e8f9b Add some hooks in mbedtls_test_ssl_perform_handshake()
Let test code customize the kitchen sink function
`mbedtls_test_ssl_perform_handshake()` at a few points.

Signed-off-by: Gilles Peskine <Gilles.Peskine@arm.com>
2026-06-05 15:40:28 +02:00
Gilles Peskine
2aa80688d9 Add a missing dependency
Needed by a test certificate.

Signed-off-by: Gilles Peskine <Gilles.Peskine@arm.com>
2026-06-05 15:40:28 +02:00
Ronald Cron
d774a25bfe Remove unnecessary dependency
Signed-off-by: Ronald Cron <ronald.cron@arm.com>
2026-06-05 12:03:16 +02:00
minosgalanakis
915442dbed
Merge pull request #1614 from yiwu0b11/mbedtls_pk_ecc_set_pubkey-overread-3.6
Backport 3.6: Fix 1-byte overread in ECC key parsing
2026-06-02 10:05:35 +01:00
Ronald Cron
4c70413087
Merge pull request #1555 from gilles-peskine-arm/ssl_tls13_prepare_new_session_ticket-psa_get_random-3.6
Backport 3.6: Fix ssl_tls13_prepare_new_session_ticket returning 1 on an RNG failure
2026-05-29 16:19:37 +02:00
Ronald Cron
14ff18114f
Merge pull request #1635 from valeriosetti/issue1569-backport-3.6
[backport 3.6] TLS 1.3 certificate chain signature algorithm policy gap
2026-05-29 13:34:52 +02:00
Manuel Pégourié-Gonnard
e3aaf2e614
Merge pull request #1625 from mpg/restricted-check-small-factors-3.6
[3.6] Fix timing leak in RSA prime generation
2026-05-28 23:52:59 +02:00
Manuel Pégourié-Gonnard
a03dafab12
Merge pull request #1633 from mpg/restricted-everest-small-order-3.6
[3.6] Everest small order
2026-05-28 23:44:35 +02:00
Gilles Peskine
8b7af9d421 Improve changelog wording
Signed-off-by: Gilles Peskine <Gilles.Peskine@arm.com>
2026-05-28 16:32:09 +02:00
Yi Wu
3208173d3d tests: update compressed EC outcome filters
Signed-off-by: Yi Wu <yi.wu2@arm.com>
2026-05-28 15:10:45 +01:00
Yi Wu
94883a3a85 tests: add EC public key parser coverage
Signed-off-by: Yi Wu <yi.wu2@arm.com>
2026-05-28 15:10:31 +01:00
Yi Wu
0e2d7037db Backport EC public key 1 byte overread
Signed-off-by: Yi Wu <yi.wu2@arm.com>
2026-05-28 15:10:14 +01:00
Valerio Setti
b9c8c9c427 changelog: fix typos
Signed-off-by: Valerio Setti <vsetti@baylibre.com>
2026-05-28 13:19:14 +02:00
Valerio Setti
b66d56bc5f changelog: add note about issue 1569 resolution
Signed-off-by: Valerio Setti <vsetti@baylibre.com>
2026-05-28 13:19:14 +02:00
Valerio Setti
4620095cdd ssl: improve documentation of mbedtls_ssl_conf_sig_algs()
Clarify that the 'sig_algs' set through this function are only enforced
during the key exchange and that 'mbedtls_ssl_conf_cert_profile()' should
instead be used to enforce the same algorithms when verifying certificates.

Signed-off-by: Valerio Setti <vsetti@baylibre.com>
2026-05-28 13:19:14 +02:00
Manuel Pégourié-Gonnard
6cfab6ce95 ecdh: fix off-by-1 in test comments/names
Signed-off-by: Manuel Pégourié-Gonnard <manuel.pegourie-gonnard@arm.com>
2026-05-28 12:24:29 +02:00
Manuel Pégourié-Gonnard
ba5e4c156e Add test for x448 invalid inputs
Signed-off-by: Manuel Pégourié-Gonnard <manuel.pegourie-gonnard@arm.com>
2026-05-28 12:24:29 +02:00
Manuel Pégourié-Gonnard
db94fb0686 Add tests for x25519 non-standard/invalid inputs
We want to reject small order points for two reasons:
- Those give rise to side channels attacks where the underlying field
  arithmetic is not constant time (which our bignum isn't so far),
  see the "May the Fourth" paper mentioned in ecp.
- Those force the shared secret to be all-bytes zero, which is bad for
  protocols that might require contributory behaviour.

Honest peers will never send low-order points anyway.

While at it, test that we are clipping the input to 255 bits (ie, that
we are unsetting bit 256) as required by the RFC.

Again, honest peers will never send strings with bit 256 set. But the
RFC says to accept such strings anyway, so that's what we do.

Signed-off-by: Manuel Pégourié-Gonnard <manuel.pegourie-gonnard@arm.com>
2026-05-28 12:24:29 +02:00
Manuel Pégourié-Gonnard
c6a1f9c838 bignum: fix a typo in a comment
The exact value doesn't matter anyway, but since we mention it, it might
as well be correct.

Signed-off-by: Manuel Pégourié-Gonnard <manuel.pegourie-gonnard@arm.com>
2026-05-26 10:06:50 +02:00
Manuel Pégourié-Gonnard
075e76b65b bignum: compact primality check for small values
Signed-off-by: Manuel Pégourié-Gonnard <manuel.pegourie-gonnard@arm.com>
2026-05-22 00:49:08 +02:00
Manuel Pégourié-Gonnard
1a3cfa5fe7 bignum: make small primes product static
Avoid a heap allocation every time it is used.

Signed-off-by: Manuel Pégourié-Gonnard <manuel.pegourie-gonnard@arm.com>
2026-05-22 00:38:10 +02:00
Manuel Pégourié-Gonnard
7a29052238 Fix side-channel in prime checking/generation
Signed-off-by: Manuel Pégourié-Gonnard <manuel.pegourie-gonnard@arm.com>
2026-05-22 00:35:55 +02:00
Manuel Pégourié-Gonnard
72991252c8
Merge pull request #1621 from mpg/resricted-ecp-modp-polish-3.6
[3.6] Improve ECC optimized modp
2026-05-22 00:01:04 +02:00
Manuel Pégourié-Gonnard
05ce3e90eb ecp: fix a typo in a comment
Signed-off-by: Manuel Pégourié-Gonnard <manuel.pegourie-gonnard@arm.com>
2026-05-21 12:08:44 +02:00
Manuel Pégourié-Gonnard
51f6079c1b ecp: update doc for Koblitz raw quasi-reductions
Those no longer allocate, so they can no longer return that error. This
was missed in the commit that removed heap allocations.

Signed-off-by: Manuel Pégourié-Gonnard <manuel.pegourie-gonnard@arm.com>
2026-05-21 12:07:32 +02:00
Manuel Pégourié-Gonnard
6cf6172ff0 ecp: improve comments in mbedtls_ecp_mod_p256_raw()
Signed-off-by: Manuel Pégourié-Gonnard <manuel.pegourie-gonnard@arm.com>
2026-05-20 13:18:08 +02:00
Manuel Pégourié-Gonnard
ba50c86b7f ecp: minor simplification in ecp_mod_koblitz()
Signed-off-by: Manuel Pégourié-Gonnard <manuel.pegourie-gonnard@arm.com>
2026-05-20 13:18:08 +02:00
Manuel Pégourié-Gonnard
fa157d7d50 ecp: don't re-invent BITS_TO_LIMBS()
Signed-off-by: Manuel Pégourié-Gonnard <manuel.pegourie-gonnard@arm.com>
2026-05-20 13:18:08 +02:00
Manuel Pégourié-Gonnard
a540f097d8 ecp: 2nd pass over mbedtls_ecp_mod_p448_raw()
Signed-off-by: Manuel Pégourié-Gonnard <manuel.pegourie-gonnard@arm.com>
2026-05-20 13:18:08 +02:00
Manuel Pégourié-Gonnard
a4ec1e3e10 ecp: update #endif comment
Signed-off-by: Manuel Pégourié-Gonnard <manuel.pegourie-gonnard@arm.com>
2026-05-20 13:18:08 +02:00
Manuel Pégourié-Gonnard
e1f96dba80 ecp: pass over mbedtls_ecp_mod_p{192,224,256,384}_raw()
Add comments explaining why 3 passes are enough (except for 224 where 1 is enough).

For p256 and p384, this is a bit different
from some other functions as the carry is signed here.

Rm FIPS reference from the documentation, it's about the implementation.

Signed-off-by: Manuel Pégourié-Gonnard <manuel.pegourie-gonnard@arm.com>
2026-05-20 13:18:08 +02:00
Manuel Pégourié-Gonnard
42eac21181 ecp: use loops in mbedtls_ecp_mod_p{192,256,384}_raw()
On principle:
- If the code is written with a loop, the compiler can easily unroll the
  loop at high optimisation levels; if we unroll the loop in the source,
  the compiler is unlikely to roll it up at -Os/-Oz. So loops are more
  adaptable.
- All the other functions are using loops, and there's nothing special
  about those functions that would justify a different treatement.

Signed-off-by: Manuel Pégourié-Gonnard <manuel.pegourie-gonnard@arm.com>
2026-05-20 13:18:08 +02:00
Manuel Pégourié-Gonnard
48e255f31b ecp: pass over mbedtls_ecp_mod_p521_raw()
The comments already explained why the result is in the desired range.

However 2^P521_WIDTH didn't make sense as P521_WIDTH is a number of
limbs no bits, so fix that typo.

Remove the FIPS reference as we're not following it and it doesn't bring
anything useful.

Signed-off-by: Manuel Pégourié-Gonnard <manuel.pegourie-gonnard@arm.com>
2026-05-20 13:18:08 +02:00