From 834db022773f8c87ce87f369d22ae2e7230ebea0 Mon Sep 17 00:00:00 2001 From: Kareem Date: Wed, 29 Jul 2026 15:19:10 -0700 Subject: [PATCH 1/2] Fix a couple of issues in DTLS ClientHello parsing. Thanks to the Fuzz0x team for the report. --- src/tls13.c | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/src/tls13.c b/src/tls13.c index 7674cb7f24..482e60f224 100644 --- a/src/tls13.c +++ b/src/tls13.c @@ -7364,6 +7364,9 @@ static int DoTls13SupportedVersions(WOLFSSL* ssl, const byte* input, word32 i, /* Client random */ i += RAN_LEN; /* Session id - not used in TLS v1.3 */ + if (i + OPAQUE8_LEN > helloSz) { + return BUFFER_ERROR; + } b = input[i++]; if (i + b > helloSz) { return BUFFER_ERROR; @@ -7372,6 +7375,9 @@ static int DoTls13SupportedVersions(WOLFSSL* ssl, const byte* input, word32 i, #ifdef WOLFSSL_DTLS13 if (ssl->options.dtls) { /* legacy_cookie - not used in DTLS v1.3 */ + if (i + OPAQUE8_LEN > helloSz) { + return BUFFER_ERROR; + } b = input[i++]; if (i + b > helloSz) { return BUFFER_ERROR; @@ -7745,8 +7751,11 @@ int DoTls13ClientHello(WOLFSSL* ssl, const byte* input, word32* inOutIdx, #ifdef WOLFSSL_DTLS13 /* legacy_cookie */ if (ssl->options.dtls) { + byte cookieLen; + if ((args->idx - args->begin) + OPAQUE8_LEN > helloSz) + ERROR_OUT(BUFFER_ERROR, exit_dch); /* https://www.rfc-editor.org/rfc/rfc9147.html#section-5.3 */ - byte cookieLen = input[args->idx++]; + cookieLen = input[args->idx++]; if (cookieLen != 0) { ERROR_OUT(INVALID_PARAMETER, exit_dch); } From 706f38c918536b22d1fd257087008858d0021ba0 Mon Sep 17 00:00:00 2001 From: Kareem Date: Fri, 31 Jul 2026 16:14:45 -0700 Subject: [PATCH 2/2] Code review feedback --- src/tls13.c | 22 +++++++++++++--------- 1 file changed, 13 insertions(+), 9 deletions(-) diff --git a/src/tls13.c b/src/tls13.c index 482e60f224..b49ceaf8c3 100644 --- a/src/tls13.c +++ b/src/tls13.c @@ -7363,45 +7363,48 @@ static int DoTls13SupportedVersions(WOLFSSL* ssl, const byte* input, word32 i, /* Client random */ i += RAN_LEN; + + if (i > helloSz) + return BUFFER_ERROR; /* Session id - not used in TLS v1.3 */ - if (i + OPAQUE8_LEN > helloSz) { + if (helloSz - i < OPAQUE8_LEN) { return BUFFER_ERROR; } b = input[i++]; - if (i + b > helloSz) { + if (b > helloSz - i) { return BUFFER_ERROR; } i += b; #ifdef WOLFSSL_DTLS13 if (ssl->options.dtls) { /* legacy_cookie - not used in DTLS v1.3 */ - if (i + OPAQUE8_LEN > helloSz) { + if (helloSz - i < OPAQUE8_LEN) { return BUFFER_ERROR; } b = input[i++]; - if (i + b > helloSz) { + if (b > helloSz - i) { return BUFFER_ERROR; } i += b; } #endif /* WOLFSSL_DTLS13 */ /* Cipher suites */ - if (i + OPAQUE16_LEN > helloSz) + if (helloSz - i < OPAQUE16_LEN) return BUFFER_ERROR; ato16(input + i, &suiteSz); i += OPAQUE16_LEN; - if (i + suiteSz + 1 > helloSz) + if ((word32)suiteSz + OPAQUE8_LEN > helloSz - i) return BUFFER_ERROR; i += suiteSz; /* Compression */ b = input[i++]; - if (i + b > helloSz) + if (b > helloSz - i) return BUFFER_ERROR; i += b; /* TLS 1.3 must have extensions */ if (i < helloSz) { - if (i + OPAQUE16_LEN > helloSz) + if (helloSz - i < OPAQUE16_LEN) return BUFFER_ERROR; ato16(&input[i], &totalExtSz); i += OPAQUE16_LEN; @@ -7751,8 +7754,9 @@ int DoTls13ClientHello(WOLFSSL* ssl, const byte* input, word32* inOutIdx, #ifdef WOLFSSL_DTLS13 /* legacy_cookie */ if (ssl->options.dtls) { + word32 rel = args->idx - args->begin; byte cookieLen; - if ((args->idx - args->begin) + OPAQUE8_LEN > helloSz) + if (rel > helloSz || helloSz - rel < OPAQUE8_LEN) ERROR_OUT(BUFFER_ERROR, exit_dch); /* https://www.rfc-editor.org/rfc/rfc9147.html#section-5.3 */ cookieLen = input[args->idx++];