Skip to content

Commit b29b2ee

Browse files
committed
[mbedTLS] Integrate TLS handshake defragmentation PR
1 parent f418603 commit b29b2ee

File tree

7 files changed

+583
-51
lines changed

7 files changed

+583
-51
lines changed

thirdparty/README.md

+1
Original file line numberDiff line numberDiff line change
@@ -627,6 +627,7 @@ File extracted from upstream release tarball:
627627
Patches:
628628

629629
- `0001-msvc-2019-psa-redeclaration.patch` (GH-90535)
630+
- `0002-pr-9949-defragment-incoming-tls-handshake-messages.patch` (GH-)
630631

631632

632633
## meshoptimizer

thirdparty/mbedtls/include/mbedtls/ssl.h

+11-1
Original file line numberDiff line numberDiff line change
@@ -1684,6 +1684,16 @@ struct mbedtls_ssl_config {
16841684
#endif
16851685
};
16861686

1687+
/* We need to add more fields to ssl_context, but can't in this branch (3.6)
1688+
* since we're not allowed to change the ABI. So, put a pointer to this struct
1689+
* in place of on of the existing pointers in ssl_context - picked in_iv
1690+
* because it's one of the least used, so that minimizes the disruption. */
1691+
typedef struct {
1692+
unsigned char *MBEDTLS_PRIVATE(in_iv); /*!< ivlen-byte IV */
1693+
unsigned char *MBEDTLS_PRIVATE(in_hshdr); /*!< original handshake header start */
1694+
size_t MBEDTLS_PRIVATE(in_hsfraglen); /*!< accumulated hs fragments length */
1695+
} mbedtls_ssl_context_in_ext;
1696+
16871697
struct mbedtls_ssl_context {
16881698
const mbedtls_ssl_config *MBEDTLS_PRIVATE(conf); /*!< configuration information */
16891699

@@ -1795,7 +1805,7 @@ struct mbedtls_ssl_context {
17951805
* (the end is marked by in_len). */
17961806
#endif /* MBEDTLS_SSL_DTLS_CONNECTION_ID */
17971807
unsigned char *MBEDTLS_PRIVATE(in_len); /*!< two-bytes message length field */
1798-
unsigned char *MBEDTLS_PRIVATE(in_iv); /*!< ivlen-byte IV */
1808+
unsigned char *MBEDTLS_PRIVATE(in_ext); /*!< extension structure (ABI compat) */
17991809
unsigned char *MBEDTLS_PRIVATE(in_msg); /*!< message contents (in_iv+ivlen) */
18001810
unsigned char *MBEDTLS_PRIVATE(in_offt); /*!< read offset in application data */
18011811

thirdparty/mbedtls/library/ssl_misc.h

+8-2
Original file line numberDiff line numberDiff line change
@@ -408,6 +408,11 @@ uint32_t mbedtls_ssl_get_extension_mask(unsigned int extension_type);
408408
#define MBEDTLS_CLIENT_HELLO_RANDOM_LEN 32
409409
#define MBEDTLS_SERVER_HELLO_RANDOM_LEN 32
410410

411+
static inline mbedtls_ssl_context_in_ext *mbedtls_ssl_get_in_ext(const mbedtls_ssl_context *ssl)
412+
{
413+
return (mbedtls_ssl_context_in_ext *) ssl->in_ext;
414+
}
415+
411416
#if defined(MBEDTLS_SSL_MAX_FRAGMENT_LENGTH)
412417
/**
413418
* \brief Return the maximum fragment length (payload, in bytes) for
@@ -1829,10 +1834,11 @@ void mbedtls_ssl_set_timer(mbedtls_ssl_context *ssl, uint32_t millisecs);
18291834
MBEDTLS_CHECK_RETURN_CRITICAL
18301835
int mbedtls_ssl_check_timer(mbedtls_ssl_context *ssl);
18311836

1832-
void mbedtls_ssl_reset_in_out_pointers(mbedtls_ssl_context *ssl);
1837+
void mbedtls_ssl_reset_in_pointers(mbedtls_ssl_context *ssl);
1838+
void mbedtls_ssl_update_in_pointers(mbedtls_ssl_context *ssl);
1839+
void mbedtls_ssl_reset_out_pointers(mbedtls_ssl_context *ssl);
18331840
void mbedtls_ssl_update_out_pointers(mbedtls_ssl_context *ssl,
18341841
mbedtls_ssl_transform *transform);
1835-
void mbedtls_ssl_update_in_pointers(mbedtls_ssl_context *ssl);
18361842

18371843
MBEDTLS_CHECK_RETURN_CRITICAL
18381844
int mbedtls_ssl_session_reset_int(mbedtls_ssl_context *ssl, int partial);

thirdparty/mbedtls/library/ssl_msg.c

+97-19
Original file line numberDiff line numberDiff line change
@@ -3220,13 +3220,18 @@ static uint32_t ssl_get_hs_total_len(mbedtls_ssl_context const *ssl)
32203220

32213221
int mbedtls_ssl_prepare_handshake_record(mbedtls_ssl_context *ssl)
32223222
{
3223-
if (ssl->in_msglen < mbedtls_ssl_hs_hdr_len(ssl)) {
3223+
/* First handshake fragment must at least include the header. */
3224+
if (ssl->in_msglen < mbedtls_ssl_hs_hdr_len(ssl) && ssl->in_hslen == 0) {
32243225
MBEDTLS_SSL_DEBUG_MSG(1, ("handshake message too short: %" MBEDTLS_PRINTF_SIZET,
32253226
ssl->in_msglen));
32263227
return MBEDTLS_ERR_SSL_INVALID_RECORD;
32273228
}
32283229

3229-
ssl->in_hslen = mbedtls_ssl_hs_hdr_len(ssl) + ssl_get_hs_total_len(ssl);
3230+
if (ssl->in_hslen == 0) {
3231+
ssl->in_hslen = mbedtls_ssl_hs_hdr_len(ssl) + ssl_get_hs_total_len(ssl);
3232+
mbedtls_ssl_get_in_ext(ssl)->in_hsfraglen = 0;
3233+
mbedtls_ssl_get_in_ext(ssl)->in_hshdr = ssl->in_hdr;
3234+
}
32303235

32313236
MBEDTLS_SSL_DEBUG_MSG(3, ("handshake message: msglen ="
32323237
" %" MBEDTLS_PRINTF_SIZET ", type = %u, hslen = %"
@@ -3292,10 +3297,61 @@ int mbedtls_ssl_prepare_handshake_record(mbedtls_ssl_context *ssl)
32923297
}
32933298
} else
32943299
#endif /* MBEDTLS_SSL_PROTO_DTLS */
3295-
/* With TLS we don't handle fragmentation (for now) */
3296-
if (ssl->in_msglen < ssl->in_hslen) {
3297-
MBEDTLS_SSL_DEBUG_MSG(1, ("TLS handshake fragmentation not supported"));
3298-
return MBEDTLS_ERR_SSL_FEATURE_UNAVAILABLE;
3300+
{
3301+
if (mbedtls_ssl_get_in_ext(ssl)->in_hsfraglen > ssl->in_hslen) {
3302+
return MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
3303+
}
3304+
int ret;
3305+
const size_t hs_remain = ssl->in_hslen - mbedtls_ssl_get_in_ext(ssl)->in_hsfraglen;
3306+
MBEDTLS_SSL_DEBUG_MSG(3,
3307+
("handshake fragment: %" MBEDTLS_PRINTF_SIZET " .. %"
3308+
MBEDTLS_PRINTF_SIZET " of %"
3309+
MBEDTLS_PRINTF_SIZET " msglen %" MBEDTLS_PRINTF_SIZET,
3310+
mbedtls_ssl_get_in_ext(ssl)->in_hsfraglen,
3311+
mbedtls_ssl_get_in_ext(ssl)->in_hsfraglen +
3312+
(hs_remain <= ssl->in_msglen ? hs_remain : ssl->in_msglen),
3313+
ssl->in_hslen, ssl->in_msglen));
3314+
if (ssl->in_msglen < hs_remain) {
3315+
mbedtls_ssl_get_in_ext(ssl)->in_hsfraglen += ssl->in_msglen;
3316+
ssl->in_hdr = ssl->in_msg + ssl->in_msglen;
3317+
ssl->in_msglen = 0;
3318+
mbedtls_ssl_update_in_pointers(ssl);
3319+
return MBEDTLS_ERR_SSL_CONTINUE_PROCESSING;
3320+
}
3321+
if (mbedtls_ssl_get_in_ext(ssl)->in_hshdr != ssl->in_hdr) {
3322+
/*
3323+
* At mbedtls_ssl_get_in_ext(ssl)->in_hshdr we have a sequence of records that cover the next handshake
3324+
* record, each with its own record header that we need to remove.
3325+
* Note that the reassembled record size may not equal the size of the message,
3326+
* there maybe bytes from the next message following it.
3327+
*/
3328+
size_t merged_rec_len = 0;
3329+
unsigned char *p = mbedtls_ssl_get_in_ext(ssl)->in_hshdr, *q = NULL;
3330+
do {
3331+
mbedtls_record rec;
3332+
ret = ssl_parse_record_header(ssl, p, mbedtls_ssl_in_hdr_len(ssl), &rec);
3333+
if (ret != 0) {
3334+
return ret;
3335+
}
3336+
merged_rec_len += rec.data_len;
3337+
p = rec.buf + rec.buf_len;
3338+
if (q != NULL) {
3339+
memmove(q, rec.buf + rec.data_offset, rec.data_len);
3340+
q += rec.data_len;
3341+
} else {
3342+
q = p;
3343+
}
3344+
} while (merged_rec_len < ssl->in_hslen);
3345+
ssl->in_hdr = mbedtls_ssl_get_in_ext(ssl)->in_hshdr;
3346+
mbedtls_ssl_update_in_pointers(ssl);
3347+
ssl->in_msglen = merged_rec_len;
3348+
/* Adjust message length. */
3349+
MBEDTLS_PUT_UINT16_BE(merged_rec_len, ssl->in_len, 0);
3350+
mbedtls_ssl_get_in_ext(ssl)->in_hsfraglen = 0;
3351+
mbedtls_ssl_get_in_ext(ssl)->in_hshdr = NULL;
3352+
MBEDTLS_SSL_DEBUG_BUF(4, "reassembled record",
3353+
ssl->in_hdr, mbedtls_ssl_in_hdr_len(ssl) + merged_rec_len);
3354+
}
32993355
}
33003356

33013357
return 0;
@@ -4640,6 +4696,16 @@ static int ssl_consume_current_message(mbedtls_ssl_context *ssl)
46404696
return MBEDTLS_ERR_SSL_INTERNAL_ERROR;
46414697
}
46424698

4699+
if (mbedtls_ssl_get_in_ext(ssl)->in_hsfraglen != 0) {
4700+
/* Not all handshake fragments have arrived, do not consume. */
4701+
MBEDTLS_SSL_DEBUG_MSG(3,
4702+
("waiting for more fragments (%" MBEDTLS_PRINTF_SIZET " of %"
4703+
MBEDTLS_PRINTF_SIZET ", %" MBEDTLS_PRINTF_SIZET " left)",
4704+
mbedtls_ssl_get_in_ext(ssl)->in_hsfraglen, ssl->in_hslen,
4705+
ssl->in_hslen - mbedtls_ssl_get_in_ext(ssl)->in_hsfraglen));
4706+
return 0;
4707+
}
4708+
46434709
/*
46444710
* Get next Handshake message in the current record
46454711
*/
@@ -4665,6 +4731,7 @@ static int ssl_consume_current_message(mbedtls_ssl_context *ssl)
46654731
ssl->in_msglen -= ssl->in_hslen;
46664732
memmove(ssl->in_msg, ssl->in_msg + ssl->in_hslen,
46674733
ssl->in_msglen);
4734+
MBEDTLS_PUT_UINT16_BE(ssl->in_msglen, ssl->in_len, 0);
46684735

46694736
MBEDTLS_SSL_DEBUG_BUF(4, "remaining content in record",
46704737
ssl->in_msg, ssl->in_msglen);
@@ -4888,7 +4955,7 @@ static int ssl_get_next_record(mbedtls_ssl_context *ssl)
48884955
#if defined(MBEDTLS_SSL_DTLS_CONNECTION_ID)
48894956
ssl->in_len = ssl->in_cid + rec.cid_len;
48904957
#endif /* MBEDTLS_SSL_DTLS_CONNECTION_ID */
4891-
ssl->in_iv = ssl->in_msg = ssl->in_len + 2;
4958+
mbedtls_ssl_get_in_ext(ssl)->in_iv = ssl->in_msg = ssl->in_len + 2;
48924959
ssl->in_msglen = rec.data_len;
48934960

48944961
ret = ssl_check_client_reconnect(ssl);
@@ -5007,7 +5074,7 @@ static int ssl_get_next_record(mbedtls_ssl_context *ssl)
50075074
#if defined(MBEDTLS_SSL_DTLS_CONNECTION_ID)
50085075
ssl->in_len = ssl->in_cid + rec.cid_len;
50095076
#endif /* MBEDTLS_SSL_DTLS_CONNECTION_ID */
5010-
ssl->in_iv = ssl->in_len + 2;
5077+
mbedtls_ssl_get_in_ext(ssl)->in_iv = ssl->in_len + 2;
50115078

50125079
/* The record content type may change during decryption,
50135080
* so re-read it. */
@@ -5319,7 +5386,7 @@ void mbedtls_ssl_update_out_pointers(mbedtls_ssl_context *ssl,
53195386
void mbedtls_ssl_update_in_pointers(mbedtls_ssl_context *ssl)
53205387
{
53215388
/* This function sets the pointers to match the case
5322-
* of unprotected TLS/DTLS records, with both ssl->in_iv
5389+
* of unprotected TLS/DTLS records, with both mbedtls_ssl_get_in_ext(ssl)->in_iv
53235390
* and ssl->in_msg pointing to the beginning of the record
53245391
* content.
53255392
*
@@ -5341,44 +5408,55 @@ void mbedtls_ssl_update_in_pointers(mbedtls_ssl_context *ssl)
53415408
#else /* MBEDTLS_SSL_DTLS_CONNECTION_ID */
53425409
ssl->in_len = ssl->in_ctr + MBEDTLS_SSL_SEQUENCE_NUMBER_LEN;
53435410
#endif /* MBEDTLS_SSL_DTLS_CONNECTION_ID */
5344-
ssl->in_iv = ssl->in_len + 2;
5411+
mbedtls_ssl_get_in_ext(ssl)->in_iv = ssl->in_len + 2;
53455412
} else
53465413
#endif
53475414
{
5348-
ssl->in_ctr = ssl->in_hdr - MBEDTLS_SSL_SEQUENCE_NUMBER_LEN;
5415+
ssl->in_ctr = ssl->in_buf;
53495416
ssl->in_len = ssl->in_hdr + 3;
53505417
#if defined(MBEDTLS_SSL_DTLS_CONNECTION_ID)
53515418
ssl->in_cid = ssl->in_len;
53525419
#endif
5353-
ssl->in_iv = ssl->in_hdr + 5;
5420+
mbedtls_ssl_get_in_ext(ssl)->in_iv = ssl->in_hdr + 5;
53545421
}
53555422

53565423
/* This will be adjusted at record decryption time. */
5357-
ssl->in_msg = ssl->in_iv;
5424+
ssl->in_msg = mbedtls_ssl_get_in_ext(ssl)->in_iv;
53585425
}
53595426

53605427
/*
53615428
* Setup an SSL context
53625429
*/
53635430

5364-
void mbedtls_ssl_reset_in_out_pointers(mbedtls_ssl_context *ssl)
5431+
void mbedtls_ssl_reset_in_pointers(mbedtls_ssl_context *ssl)
5432+
{
5433+
#if defined(MBEDTLS_SSL_PROTO_DTLS)
5434+
if (ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM) {
5435+
ssl->in_hdr = ssl->in_buf;
5436+
} else
5437+
#endif /* MBEDTLS_SSL_PROTO_DTLS */
5438+
{
5439+
ssl->in_hdr = ssl->in_buf + MBEDTLS_SSL_SEQUENCE_NUMBER_LEN;
5440+
}
5441+
5442+
/* Derive other internal pointers. */
5443+
mbedtls_ssl_update_in_pointers(ssl);
5444+
}
5445+
5446+
void mbedtls_ssl_reset_out_pointers(mbedtls_ssl_context *ssl)
53655447
{
53665448
/* Set the incoming and outgoing record pointers. */
53675449
#if defined(MBEDTLS_SSL_PROTO_DTLS)
53685450
if (ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM) {
53695451
ssl->out_hdr = ssl->out_buf;
5370-
ssl->in_hdr = ssl->in_buf;
53715452
} else
53725453
#endif /* MBEDTLS_SSL_PROTO_DTLS */
53735454
{
53745455
ssl->out_ctr = ssl->out_buf;
5375-
ssl->out_hdr = ssl->out_buf + 8;
5376-
ssl->in_hdr = ssl->in_buf + 8;
5456+
ssl->out_hdr = ssl->out_buf + MBEDTLS_SSL_SEQUENCE_NUMBER_LEN;
53775457
}
5378-
53795458
/* Derive other internal pointers. */
53805459
mbedtls_ssl_update_out_pointers(ssl, NULL /* no transform enabled */);
5381-
mbedtls_ssl_update_in_pointers(ssl);
53825460
}
53835461

53845462
/*

thirdparty/mbedtls/library/ssl_tls.c

+37-7
Original file line numberDiff line numberDiff line change
@@ -344,12 +344,17 @@ static void handle_buffer_resizing(mbedtls_ssl_context *ssl, int downsizing,
344344
size_t out_buf_new_len)
345345
{
346346
int modified = 0;
347-
size_t written_in = 0, iv_offset_in = 0, len_offset_in = 0;
347+
size_t written_in = 0, iv_offset_in = 0, len_offset_in = 0, hdr_in = 0;
348348
size_t written_out = 0, iv_offset_out = 0, len_offset_out = 0;
349+
size_t hshdr_in = 0;
349350
if (ssl->in_buf != NULL) {
350351
written_in = ssl->in_msg - ssl->in_buf;
351-
iv_offset_in = ssl->in_iv - ssl->in_buf;
352+
iv_offset_in = mbedtls_ssl_get_in_ext(ssl)->in_iv - ssl->in_buf;
352353
len_offset_in = ssl->in_len - ssl->in_buf;
354+
hdr_in = ssl->in_hdr - ssl->in_buf;
355+
if (mbedtls_ssl_get_in_ext(ssl)->in_hshdr != NULL) {
356+
hshdr_in = mbedtls_ssl_get_in_ext(ssl)->in_hshdr - ssl->in_buf;
357+
}
353358
if (downsizing ?
354359
ssl->in_buf_len > in_buf_new_len && ssl->in_left < in_buf_new_len :
355360
ssl->in_buf_len < in_buf_new_len) {
@@ -381,7 +386,10 @@ static void handle_buffer_resizing(mbedtls_ssl_context *ssl, int downsizing,
381386
}
382387
if (modified) {
383388
/* Update pointers here to avoid doing it twice. */
384-
mbedtls_ssl_reset_in_out_pointers(ssl);
389+
ssl->in_hdr = ssl->in_buf + hdr_in;
390+
mbedtls_ssl_update_in_pointers(ssl);
391+
mbedtls_ssl_reset_out_pointers(ssl);
392+
385393
/* Fields below might not be properly updated with record
386394
* splitting or with CID, so they are manually updated here. */
387395
ssl->out_msg = ssl->out_buf + written_out;
@@ -390,7 +398,10 @@ static void handle_buffer_resizing(mbedtls_ssl_context *ssl, int downsizing,
390398

391399
ssl->in_msg = ssl->in_buf + written_in;
392400
ssl->in_len = ssl->in_buf + len_offset_in;
393-
ssl->in_iv = ssl->in_buf + iv_offset_in;
401+
mbedtls_ssl_get_in_ext(ssl)->in_iv = ssl->in_buf + iv_offset_in;
402+
if (mbedtls_ssl_get_in_ext(ssl)->in_hshdr != NULL) {
403+
mbedtls_ssl_get_in_ext(ssl)->in_hshdr = ssl->in_buf + hshdr_in;
404+
}
394405
}
395406
}
396407
#endif /* MBEDTLS_SSL_VARIABLE_BUFFER_LENGTH */
@@ -1398,6 +1409,14 @@ int mbedtls_ssl_setup(mbedtls_ssl_context *ssl,
13981409
ret = MBEDTLS_ERR_SSL_ALLOC_FAILED;
13991410
goto error;
14001411
}
1412+
ssl->in_ext = mbedtls_calloc(1, sizeof(mbedtls_ssl_context_in_ext));
1413+
if (ssl->in_ext == NULL) {
1414+
MBEDTLS_SSL_DEBUG_MSG(1,
1415+
("alloc(%" MBEDTLS_PRINTF_SIZET " bytes) failed",
1416+
sizeof(mbedtls_ssl_context_in_ext)));
1417+
ret = MBEDTLS_ERR_SSL_ALLOC_FAILED;
1418+
goto error;
1419+
}
14011420

14021421
#if defined(MBEDTLS_SSL_VARIABLE_BUFFER_LENGTH)
14031422
ssl->out_buf_len = out_buf_len;
@@ -1409,7 +1428,8 @@ int mbedtls_ssl_setup(mbedtls_ssl_context *ssl,
14091428
goto error;
14101429
}
14111430

1412-
mbedtls_ssl_reset_in_out_pointers(ssl);
1431+
mbedtls_ssl_reset_in_pointers(ssl);
1432+
mbedtls_ssl_reset_out_pointers(ssl);
14131433

14141434
#if defined(MBEDTLS_SSL_DTLS_SRTP)
14151435
memset(&ssl->dtls_srtp_info, 0, sizeof(ssl->dtls_srtp_info));
@@ -1423,6 +1443,7 @@ int mbedtls_ssl_setup(mbedtls_ssl_context *ssl,
14231443

14241444
error:
14251445
mbedtls_free(ssl->in_buf);
1446+
mbedtls_free(ssl->in_ext);
14261447
mbedtls_free(ssl->out_buf);
14271448

14281449
ssl->conf = NULL;
@@ -1432,12 +1453,13 @@ int mbedtls_ssl_setup(mbedtls_ssl_context *ssl,
14321453
ssl->out_buf_len = 0;
14331454
#endif
14341455
ssl->in_buf = NULL;
1456+
ssl->in_ext = NULL;
14351457
ssl->out_buf = NULL;
14361458

14371459
ssl->in_hdr = NULL;
14381460
ssl->in_ctr = NULL;
14391461
ssl->in_len = NULL;
1440-
ssl->in_iv = NULL;
1462+
mbedtls_ssl_get_in_ext(ssl)->in_iv = NULL;
14411463
ssl->in_msg = NULL;
14421464

14431465
ssl->out_hdr = NULL;
@@ -1474,7 +1496,8 @@ void mbedtls_ssl_session_reset_msg_layer(mbedtls_ssl_context *ssl,
14741496
/* Cancel any possibly running timer */
14751497
mbedtls_ssl_set_timer(ssl, 0);
14761498

1477-
mbedtls_ssl_reset_in_out_pointers(ssl);
1499+
mbedtls_ssl_reset_in_pointers(ssl);
1500+
mbedtls_ssl_reset_out_pointers(ssl);
14781501

14791502
/* Reset incoming message parsing */
14801503
ssl->in_offt = NULL;
@@ -1484,6 +1507,8 @@ void mbedtls_ssl_session_reset_msg_layer(mbedtls_ssl_context *ssl,
14841507
ssl->in_hslen = 0;
14851508
ssl->keep_current_message = 0;
14861509
ssl->transform_in = NULL;
1510+
mbedtls_ssl_get_in_ext(ssl)->in_hshdr = NULL;
1511+
mbedtls_ssl_get_in_ext(ssl)->in_hsfraglen = 0;
14871512

14881513
#if defined(MBEDTLS_SSL_PROTO_DTLS)
14891514
ssl->next_record_offset = 0;
@@ -5542,6 +5567,11 @@ void mbedtls_ssl_free(mbedtls_ssl_context *ssl)
55425567
ssl->in_buf = NULL;
55435568
}
55445569

5570+
if (ssl->in_ext != NULL) {
5571+
mbedtls_free(ssl->in_ext);
5572+
ssl->in_ext = NULL;
5573+
}
5574+
55455575
if (ssl->transform) {
55465576
mbedtls_ssl_transform_free(ssl->transform);
55475577
mbedtls_free(ssl->transform);

0 commit comments

Comments
 (0)