From e32ac6ffb718f19c576d2e3330822b9fae4e22cb Mon Sep 17 00:00:00 2001 From: Ruby Martin Date: Mon, 12 Jan 2026 11:30:36 -0700 Subject: [PATCH 1/3] XMEMSET with WC_CALLOC_VAR_EX switch WC_ALLOC_VAR_EX with XMEMSET to WC_CALLOC_VAR_EX fix XMEMSET call for WC_CALLOC_VAR_EX --- wolfcrypt/test/test.c | 3 +-- wolfssl/wolfcrypt/types.h | 4 ++-- 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/wolfcrypt/test/test.c b/wolfcrypt/test/test.c index 54f8d72213..f4806a638c 100644 --- a/wolfcrypt/test/test.c +++ b/wolfcrypt/test/test.c @@ -20187,10 +20187,9 @@ WOLFSSL_TEST_SUBROUTINE wc_test_ret_t random_bank_test(void) byte outbuf1[16], outbuf2[16]; int i; - WC_ALLOC_VAR_EX(bank, struct wc_rng_bank, 1, HEAP_HINT, + WC_CALLOC_VAR_EX(bank, struct wc_rng_bank, 1, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER, return WC_TEST_RET_ENC_EC(MEMORY_E)); - XMEMSET(bank, 0, sizeof(*bank)); WC_ALLOC_VAR_EX(rng, WC_RNG, 1, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER, diff --git a/wolfssl/wolfcrypt/types.h b/wolfssl/wolfcrypt/types.h index d656411d31..756b27db27 100644 --- a/wolfssl/wolfcrypt/types.h +++ b/wolfssl/wolfcrypt/types.h @@ -912,9 +912,9 @@ enum { WC_DO_NOTHING #define WC_VAR_OK(VAR_NAME) 1 #define WC_CALLOC_VAR(VAR_NAME, VAR_TYPE, VAR_SIZE, HEAP) \ - XMEMSET(VAR_NAME, 0, sizeof(var)) + XMEMSET(VAR_NAME, 0, sizeof(VAR_TYPE)) #define WC_CALLOC_VAR_EX(VAR_NAME, VAR_TYPE, VAR_SIZE, HEAP, TY, ONFAIL)\ - WC_DO_NOTHING + XMEMSET(VAR_NAME, 0, sizeof(VAR_TYPE)) #define WC_FREE_VAR(VAR_NAME, HEAP) WC_DO_NOTHING \ /* nothing to free, its stack */ #define WC_FREE_VAR_EX(VAR_NAME, HEAP, TYPE) WC_DO_NOTHING From dcdf65024076f3b3536c8a7e98597e64d97c10d2 Mon Sep 17 00:00:00 2001 From: Ruby Martin Date: Mon, 12 Jan 2026 14:10:05 -0700 Subject: [PATCH 2/3] verify length limit for supported version ext add length check to tls extensions --- src/tls.c | 10 +++++++--- wolfssl/internal.h | 6 ++++++ 2 files changed, 13 insertions(+), 3 deletions(-) diff --git a/src/tls.c b/src/tls.c index 9f0e2796a1..ac7e6b5c2a 100644 --- a/src/tls.c +++ b/src/tls.c @@ -6972,8 +6972,10 @@ int TLSX_SupportedVersions_Parse(const WOLFSSL* ssl, const byte* input, int set = 0; /* Must contain a length and at least one version. */ - if (length < OPAQUE8_LEN + OPAQUE16_LEN || (length & 1) != 1) + if (length < OPAQUE8_LEN + OPAQUE16_LEN || (length & 1) != 1 + || length > MAX_SV_EXT_LEN) { return BUFFER_ERROR; + } len = *input; @@ -9963,10 +9965,12 @@ int TLSX_KeyShare_Parse_ClientHello(const WOLFSSL* ssl, if (length < OPAQUE16_LEN) return BUFFER_ERROR; - /* ClientHello contains zero or more key share entries. */ + /* ClientHello contains zero or more key share entries. Limits extension + * length to 2^16-1 per RFC 8446 */ ato16(input, &len); - if (len != length - OPAQUE16_LEN) + if ((len != length - OPAQUE16_LEN) || length > MAX_EXT_DATA_LEN) { return BUFFER_ERROR; + } offset += OPAQUE16_LEN; while (offset < (int)length) { diff --git a/wolfssl/internal.h b/wolfssl/internal.h index a9374b0db0..8740f4da56 100644 --- a/wolfssl/internal.h +++ b/wolfssl/internal.h @@ -1668,6 +1668,12 @@ enum Misc { MAX_REQUEST_SZ = 256, /* Maximum cert req len (no auth yet */ SESSION_FLUSH_COUNT = 256, /* Flush session cache unless user turns off */ TLS_MAX_PAD_SZ = 255, /* Max padding in TLS */ + MAX_EXT_DATA_LEN = 63535, + /* Max extension data length <0..2^16-1> RFC 8446 + * Section 4.2 */ + MAX_SV_EXT_LEN = 255, + /* Max supported_versions extension length + * <2..254> RFC 8446 Section 4.2.1.*/ #if defined(HAVE_NULL_CIPHER) && defined(WOLFSSL_TLS13) #if defined(WOLFSSL_SHA384) && WC_MAX_SYM_KEY_SIZE < 48 From 7947814d7d060efe367f31f3e62a8cc9ff45e948 Mon Sep 17 00:00:00 2001 From: Ruby Martin Date: Wed, 14 Jan 2026 11:57:14 -0700 Subject: [PATCH 3/3] add cleanup logic to sakke_kat_derive_test() --- wolfcrypt/test/test.c | 59 ++++++++++++++++++++++++++++++------------- 1 file changed, 41 insertions(+), 18 deletions(-) diff --git a/wolfcrypt/test/test.c b/wolfcrypt/test/test.c index f4806a638c..76252ed51b 100644 --- a/wolfcrypt/test/test.c +++ b/wolfcrypt/test/test.c @@ -52297,44 +52297,67 @@ static wc_test_ret_t sakke_kat_derive_test(SakkeKey* key, ecc_point* rsk) return WC_TEST_RET_ENC_EC(ret); if (iTableLen != 0) { iTable = (byte*)XMALLOC(iTableLen, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); - if (iTable == NULL) - return WC_TEST_RET_ENC_ERRNO; + if (iTable == NULL) { + ret = WC_TEST_RET_ENC_ERRNO; + goto out; + } ret = wc_GenerateSakkePointITable(key, iTable, &iTableLen); - if (ret != 0) - return WC_TEST_RET_ENC_EC(ret); + if (ret != 0) { + ret = WC_TEST_RET_ENC_EC(ret); + goto out; + } } len = 0; ret = wc_GenerateSakkeRskTable(key, rsk, NULL, &len); - if (ret != WC_NO_ERR_TRACE(LENGTH_ONLY_E)) - return WC_TEST_RET_ENC_EC(ret); + if (ret != WC_NO_ERR_TRACE(LENGTH_ONLY_E)) { + ret = WC_TEST_RET_ENC_EC(ret); + goto out; + } if (len > 0) { table = (byte*)XMALLOC(len, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); - if (table == NULL) - return WC_TEST_RET_ENC_ERRNO; + if (table == NULL) { + ret = WC_TEST_RET_ENC_ERRNO; + goto out; + } ret = wc_GenerateSakkeRskTable(key, rsk, table, &len); - if (ret != 0) - return WC_TEST_RET_ENC_EC(ret); + if (ret != 0) { + ret = WC_TEST_RET_ENC_EC(ret); + goto out; + } } ret = wc_SetSakkeRsk(key, rsk, table, len); - if (ret != 0) - return WC_TEST_RET_ENC_EC(ret); + if (ret != 0) { + ret = WC_TEST_RET_ENC_EC(ret); + goto out; + } XMEMCPY(tmpSsv, encSsv, sizeof(encSsv)); ret = wc_DeriveSakkeSSV(key, WC_HASH_TYPE_SHA256, tmpSsv, sizeof(tmpSsv), auth, sizeof(auth)); - if (ret != 0) - return WC_TEST_RET_ENC_EC(ret); - if (XMEMCMP(tmpSsv, ssv, sizeof(ssv)) != 0) - return WC_TEST_RET_ENC_NC; + if (ret != 0) { + ret = WC_TEST_RET_ENC_EC(ret); + goto out; + } + if (XMEMCMP(tmpSsv, ssv, sizeof(ssv)) != 0) { + ret = WC_TEST_RET_ENC_NC; + goto out; + } /* Don't reference table that is about to be freed. */ ret = wc_ClearSakkePointITable(key); - if (ret != 0) - return WC_TEST_RET_ENC_EC(ret); + if (ret != 0) { + ret = WC_TEST_RET_ENC_EC(ret); + } + +out: /* Dispose of tables */ XFREE(iTable, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); XFREE(table, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); + /* return error code if encountered */ + if (ret != 0) { + return ret; + } /* Make sure the key public key is exportable - convert to Montgomery form * in Validation.