From b5ccd32390d6e31388a01979640d7603b6be33ea Mon Sep 17 00:00:00 2001 From: Gilles Peskine Date: Wed, 5 Mar 2025 17:41:59 +0100 Subject: [PATCH 1/7] Document the limitations of TLS handshake message defragmentation Signed-off-by: Gilles Peskine --- include/mbedtls/ssl.h | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/include/mbedtls/ssl.h b/include/mbedtls/ssl.h index 597da2571f..e34e3af6af 100644 --- a/include/mbedtls/ssl.h +++ b/include/mbedtls/ssl.h @@ -4449,6 +4449,24 @@ void mbedtls_ssl_conf_cert_req_ca_list(mbedtls_ssl_config *conf, * with \c mbedtls_ssl_read()), not handshake messages. * With DTLS, this affects both ApplicationData and handshake. * + * \note Defragmentation of incoming handshake messages in TLS + * (excluding DTLS) is supported with some limitations: + * - On an Mbed TLS server that only accepts TLS 1.2, + * the initial ClientHello message must not be fragmented. + * A TLS 1.2 ClientHello may be fragmented if the server + * also accepts TLS 1.3 connections (meaning + * that #MBEDTLS_SSL_PROTO_TLS1_3 enabled, and the + * accepted versions have not been restricted with + * mbedtls_ssl_conf_max_tls_version() or the like). + * - A ClientHello message that initiates a renegotiation + * must not be fragmented. + * - The first fragment of a handshake message must be + * at least 4 bytes long. + * - Non-handshake records must not be interleaved between + * the fragments of a handshake message. (This is permitted + * in TLS 1.2 but not in TLS 1.3, but Mbed TLS rejects it + * even in TLS 1.2.) + * * \note This sets the maximum length for a record's payload, * excluding record overhead that will be added to it, see * \c mbedtls_ssl_get_record_expansion(). From 1933932e553b53a8844da0a93c1052de5f0d227b Mon Sep 17 00:00:00 2001 From: Gilles Peskine Date: Wed, 5 Mar 2025 17:44:20 +0100 Subject: [PATCH 2/7] Refer to the API documentation for details Signed-off-by: Gilles Peskine --- ChangeLog.d/tls-hs-defrag-in.txt | 17 ++++++----------- 1 file changed, 6 insertions(+), 11 deletions(-) diff --git a/ChangeLog.d/tls-hs-defrag-in.txt b/ChangeLog.d/tls-hs-defrag-in.txt index 4fd4a4e372..748f95c104 100644 --- a/ChangeLog.d/tls-hs-defrag-in.txt +++ b/ChangeLog.d/tls-hs-defrag-in.txt @@ -1,12 +1,7 @@ Bugfix - * Support re-assembly of fragmented handshake messages in TLS, as mandated - by the spec. Lack of support was causing handshake failures with some - servers, especially with TLS 1.3 in practice (though both protocol - version could be affected in principle, and both are fixed now). - The initial fragment for each handshake message must be at least 4 bytes. - - Server-side, defragmentation of the ClientHello message is only - supported if the server accepts TLS 1.3 (regardless of whether the - ClientHello is 1.3 or 1.2). That is, servers configured (either - at compile time or at runtime) to only accept TLS 1.2 will - still fail the handshake if the ClientHello message is fragmented. + * Support re-assembly of fragmented handshake messages in TLS (both + 1.2 and 1.3). The lack of support was causing handshake failures with + some servers, especially with TLS 1.3 in practice. There are a few + limitations, notably a fragmented ClientHello is only supported when + TLS 1.3 support is enabled. See the documentation of + mbedtls_ssl_conf_max_frag_len() for details. From 494e4943b539c070374d97af6328bdd251133bbc Mon Sep 17 00:00:00 2001 From: Gilles Peskine Date: Tue, 11 Mar 2025 13:45:27 +0100 Subject: [PATCH 3/7] Move the defragmentation documentation to mbedtls_ssl_handshake Signed-off-by: Gilles Peskine --- include/mbedtls/ssl.h | 38 +++++++++++++++++++++----------------- 1 file changed, 21 insertions(+), 17 deletions(-) diff --git a/include/mbedtls/ssl.h b/include/mbedtls/ssl.h index e34e3af6af..26b1fd4cdd 100644 --- a/include/mbedtls/ssl.h +++ b/include/mbedtls/ssl.h @@ -4449,23 +4449,9 @@ void mbedtls_ssl_conf_cert_req_ca_list(mbedtls_ssl_config *conf, * with \c mbedtls_ssl_read()), not handshake messages. * With DTLS, this affects both ApplicationData and handshake. * - * \note Defragmentation of incoming handshake messages in TLS - * (excluding DTLS) is supported with some limitations: - * - On an Mbed TLS server that only accepts TLS 1.2, - * the initial ClientHello message must not be fragmented. - * A TLS 1.2 ClientHello may be fragmented if the server - * also accepts TLS 1.3 connections (meaning - * that #MBEDTLS_SSL_PROTO_TLS1_3 enabled, and the - * accepted versions have not been restricted with - * mbedtls_ssl_conf_max_tls_version() or the like). - * - A ClientHello message that initiates a renegotiation - * must not be fragmented. - * - The first fragment of a handshake message must be - * at least 4 bytes long. - * - Non-handshake records must not be interleaved between - * the fragments of a handshake message. (This is permitted - * in TLS 1.2 but not in TLS 1.3, but Mbed TLS rejects it - * even in TLS 1.2.) + * \note Defragmentation of TLS handshake messages is supported + * with some limitations. See the documentation of + * mbedtls_ssl_handshake() for details. * * \note This sets the maximum length for a record's payload, * excluding record overhead that will be added to it, see @@ -4997,6 +4983,24 @@ int mbedtls_ssl_get_session(const mbedtls_ssl_context *ssl, * if a negotiation involving TLS 1.3 takes place (this may * be the case even if TLS 1.3 is offered but eventually * not selected). + * + * \note Defragmentation of incoming handshake messages in TLS + * (excluding DTLS) is supported with some limitations: + * - On an Mbed TLS server that only accepts TLS 1.2, + * the initial ClientHello message must not be fragmented. + * A TLS 1.2 ClientHello may be fragmented if the server + * also accepts TLS 1.3 connections (meaning + * that #MBEDTLS_SSL_PROTO_TLS1_3 enabled, and the + * accepted versions have not been restricted with + * mbedtls_ssl_conf_max_tls_version() or the like). + * - A ClientHello message that initiates a renegotiation + * must not be fragmented. + * - The first fragment of a handshake message must be + * at least 4 bytes long. + * - Non-handshake records must not be interleaved between + * the fragments of a handshake message. (This is permitted + * in TLS 1.2 but not in TLS 1.3, but Mbed TLS rejects it + * even in TLS 1.2.) */ int mbedtls_ssl_handshake(mbedtls_ssl_context *ssl); From c3af2f48c4aa63df3b077a26990ea83c8c6f81b1 Mon Sep 17 00:00:00 2001 From: Gilles Peskine Date: Tue, 11 Mar 2025 13:47:14 +0100 Subject: [PATCH 4/7] ClientHello may be fragmented in renegotiation Signed-off-by: Gilles Peskine --- include/mbedtls/ssl.h | 2 -- 1 file changed, 2 deletions(-) diff --git a/include/mbedtls/ssl.h b/include/mbedtls/ssl.h index 26b1fd4cdd..4d2410e778 100644 --- a/include/mbedtls/ssl.h +++ b/include/mbedtls/ssl.h @@ -4993,8 +4993,6 @@ int mbedtls_ssl_get_session(const mbedtls_ssl_context *ssl, * that #MBEDTLS_SSL_PROTO_TLS1_3 enabled, and the * accepted versions have not been restricted with * mbedtls_ssl_conf_max_tls_version() or the like). - * - A ClientHello message that initiates a renegotiation - * must not be fragmented. * - The first fragment of a handshake message must be * at least 4 bytes long. * - Non-handshake records must not be interleaved between From bc0255592fed525ac19459f6bf7f1f68540b680d Mon Sep 17 00:00:00 2001 From: Gilles Peskine Date: Tue, 11 Mar 2025 13:47:49 +0100 Subject: [PATCH 5/7] Clarify DTLS Signed-off-by: Gilles Peskine --- include/mbedtls/ssl.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/include/mbedtls/ssl.h b/include/mbedtls/ssl.h index 4d2410e778..8fdf6a689d 100644 --- a/include/mbedtls/ssl.h +++ b/include/mbedtls/ssl.h @@ -4985,7 +4985,7 @@ int mbedtls_ssl_get_session(const mbedtls_ssl_context *ssl, * not selected). * * \note Defragmentation of incoming handshake messages in TLS - * (excluding DTLS) is supported with some limitations: + * is supported with some limitations: * - On an Mbed TLS server that only accepts TLS 1.2, * the initial ClientHello message must not be fragmented. * A TLS 1.2 ClientHello may be fragmented if the server @@ -4993,6 +4993,7 @@ int mbedtls_ssl_get_session(const mbedtls_ssl_context *ssl, * that #MBEDTLS_SSL_PROTO_TLS1_3 enabled, and the * accepted versions have not been restricted with * mbedtls_ssl_conf_max_tls_version() or the like). + * This limitation does not apply to DTLS. * - The first fragment of a handshake message must be * at least 4 bytes long. * - Non-handshake records must not be interleaved between From 858900656eb36c7ad8b70e9104a7420529bd36ed Mon Sep 17 00:00:00 2001 From: Gilles Peskine Date: Wed, 12 Mar 2025 10:07:33 +0100 Subject: [PATCH 6/7] State globally that the limitations don't apply to DTLS Signed-off-by: Gilles Peskine --- include/mbedtls/ssl.h | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/include/mbedtls/ssl.h b/include/mbedtls/ssl.h index 8fdf6a689d..97b0dcb380 100644 --- a/include/mbedtls/ssl.h +++ b/include/mbedtls/ssl.h @@ -4984,8 +4984,10 @@ int mbedtls_ssl_get_session(const mbedtls_ssl_context *ssl, * be the case even if TLS 1.3 is offered but eventually * not selected). * - * \note Defragmentation of incoming handshake messages in TLS - * is supported with some limitations: + * \note In TLS, reception of fragmented handshake messages is + * supported with some limitations (those limitations do + * not apply to DTLS, where defragmentation is fully + * supported): * - On an Mbed TLS server that only accepts TLS 1.2, * the initial ClientHello message must not be fragmented. * A TLS 1.2 ClientHello may be fragmented if the server @@ -4993,7 +4995,6 @@ int mbedtls_ssl_get_session(const mbedtls_ssl_context *ssl, * that #MBEDTLS_SSL_PROTO_TLS1_3 enabled, and the * accepted versions have not been restricted with * mbedtls_ssl_conf_max_tls_version() or the like). - * This limitation does not apply to DTLS. * - The first fragment of a handshake message must be * at least 4 bytes long. * - Non-handshake records must not be interleaved between From a7c020d6cbe5fadfe0126e90c077f01223b6e968 Mon Sep 17 00:00:00 2001 From: Gilles Peskine Date: Wed, 12 Mar 2025 10:08:14 +0100 Subject: [PATCH 7/7] Update the location of defragmentation limitations Signed-off-by: Gilles Peskine --- ChangeLog.d/tls-hs-defrag-in.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ChangeLog.d/tls-hs-defrag-in.txt b/ChangeLog.d/tls-hs-defrag-in.txt index 748f95c104..6bab02a029 100644 --- a/ChangeLog.d/tls-hs-defrag-in.txt +++ b/ChangeLog.d/tls-hs-defrag-in.txt @@ -4,4 +4,4 @@ Bugfix some servers, especially with TLS 1.3 in practice. There are a few limitations, notably a fragmented ClientHello is only supported when TLS 1.3 support is enabled. See the documentation of - mbedtls_ssl_conf_max_frag_len() for details. + mbedtls_ssl_handshake() for details.