From c677768375e6f941d60d503f7a612420f384582f Mon Sep 17 00:00:00 2001 From: Kareem Date: Fri, 12 Jun 2026 12:14:48 -0700 Subject: [PATCH 1/9] Zero out buffer on error in AES_GCM_decrypt_C. Fixes F-5393. --- wolfcrypt/src/aes.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/wolfcrypt/src/aes.c b/wolfcrypt/src/aes.c index 4c550632ba..7ae4550a18 100644 --- a/wolfcrypt/src/aes.c +++ b/wolfcrypt/src/aes.c @@ -11445,6 +11445,9 @@ int WARN_UNUSED_RESULT AES_GCM_decrypt_C( ret = (ret & ~res); ret |= (res & WC_NO_ERR_TRACE(AES_GCM_AUTH_E)); #endif + if (ret != 0) { + ForceZero(out, sz); + } return ret; } #elif (defined(__aarch64__) || defined(WOLFSSL_ARMASM_NO_HW_CRYPTO)) || \ From 511f6e1bf0c865a1983fe9427191e358381ccf04 Mon Sep 17 00:00:00 2001 From: Kareem Date: Fri, 12 Jun 2026 12:21:02 -0700 Subject: [PATCH 2/9] Zero out the aead in wc_ChaCha20Poly1305_Encrypt/Decrypt before freeing it. Fixes F-4023. --- wolfcrypt/src/chacha20_poly1305.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/wolfcrypt/src/chacha20_poly1305.c b/wolfcrypt/src/chacha20_poly1305.c index e9e5bb80c4..f3ebb52ff9 100644 --- a/wolfcrypt/src/chacha20_poly1305.c +++ b/wolfcrypt/src/chacha20_poly1305.c @@ -75,6 +75,7 @@ int wc_ChaCha20Poly1305_Encrypt( if (ret == 0) ret = wc_ChaCha20Poly1305_Final(aead, outAuthTag); + ForceZero(aead, sizeof(ChaChaPoly_Aead)); WC_FREE_VAR_EX(aead, NULL, DYNAMIC_TYPE_TMP_BUFFER); return ret; @@ -123,6 +124,7 @@ int wc_ChaCha20Poly1305_Decrypt( /* zero plaintext on error */ ForceZero(outPlaintext, inCiphertextLen); } + ForceZero(aead, sizeof(ChaChaPoly_Aead)); WC_FREE_VAR_EX(aead, NULL, DYNAMIC_TYPE_TMP_BUFFER); return ret; From 84f06392579a62421aabb4145bf58c5f518801f9 Mon Sep 17 00:00:00 2001 From: Kareem Date: Fri, 12 Jun 2026 12:27:15 -0700 Subject: [PATCH 3/9] Limit parsed port to 65535 in wolfIO_DecodeUrl. Fixes F-4228. --- src/wolfio.c | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/src/wolfio.c b/src/wolfio.c index 4ebff95c69..75ff9d47bd 100644 --- a/src/wolfio.c +++ b/src/wolfio.c @@ -1725,7 +1725,7 @@ int wolfIO_DecodeUrl(const char* url, int urlSz, char* outName, char* outPath, /* Need to pick out the path after the domain name */ if (cur < urlSz && url[cur] == ':') { - char port[6]; + char port[5]; int j; word32 bigPort = 0; i = 0; @@ -1733,15 +1733,27 @@ int wolfIO_DecodeUrl(const char* url, int urlSz, char* outName, char* outPath, XMEMSET(port, 0, sizeof(port)); - while (i < 6 && cur < urlSz && url[cur] != 0 && url[cur] != '/') { + while (i < 5 && cur < urlSz && url[cur] != 0 && url[cur] != '/') { port[i] = url[cur]; i++; cur++; } + /* A valid port is at most 5 digits; if more characters remain + * before the path/terminator the port field is malformed (e.g. + * a 6-digit port) and must be rejected rather than parsed from a + * truncated digit string. */ + if (cur < urlSz && url[cur] != 0 && url[cur] != '/') + return WOLFSSL_FATAL_ERROR; + for (j = 0; j < i; j++) { if (port[j] < '0' || port[j] > '9') return WOLFSSL_FATAL_ERROR; bigPort = (bigPort * 10) + (word32)(port[j] - '0'); } + /* Reject out-of-range ports rather than silently truncating to + * word16, which would otherwise wrap (e.g. 65536 -> 0) and + * connect to an unintended port. */ + if (bigPort > 65535) + return WOLFSSL_FATAL_ERROR; if (outPort) *outPort = (word16)bigPort; } From b28490c1cc14fd7ab4b14d03ee9db4bbc7c0ab1e Mon Sep 17 00:00:00 2001 From: Kareem Date: Fri, 12 Jun 2026 12:53:21 -0700 Subject: [PATCH 4/9] Fix length calculations in wolfSSL_BUF_MEM_grow_ex and wolfSSL_BUF_MEM_resize. Also fix a potential overread in wolfSSL_BUF_MEM_grow_ex for the non-realloc case. Fixes F-5730 --- src/ssl.c | 31 ++++++++++++++++--------------- 1 file changed, 16 insertions(+), 15 deletions(-) diff --git a/src/ssl.c b/src/ssl.c index 885c233331..b61a376bf9 100644 --- a/src/ssl.c +++ b/src/ssl.c @@ -15416,20 +15416,20 @@ WOLFSSL_BUF_MEM* wolfSSL_BUF_MEM_new(void) int wolfSSL_BUF_MEM_grow_ex(WOLFSSL_BUF_MEM* buf, size_t len, char zeroFill) { - - int len_int = (int)len; - int mx; + size_t mx; char* tmp; - /* verify provided arguments */ - if (buf == NULL || len_int < 0) { + /* verify provided arguments. The return value is an int holding the + * resulting length, so reject any len that cannot be represented as a + * non-negative int. This also prevents truncating size_t to int. */ + if (buf == NULL || len > (size_t)INT_MAX) { return 0; /* BAD_FUNC_ARG; */ } /* check to see if fits in existing length */ if (buf->length > len) { buf->length = len; - return len_int; + return (int)len; } /* check to see if fits in max buffer */ @@ -15438,11 +15438,11 @@ int wolfSSL_BUF_MEM_grow_ex(WOLFSSL_BUF_MEM* buf, size_t len, XMEMSET(&buf->data[buf->length], 0, len - buf->length); } buf->length = len; - return len_int; + return (int)len; } /* expand size, to handle growth */ - mx = (len_int + 3) / 3 * 4; + mx = (len + 3) / 3 * 4; #ifdef WOLFSSL_NO_REALLOC tmp = (char*)XMALLOC(mx, NULL, DYNAMIC_TYPE_OPENSSL); @@ -15463,12 +15463,12 @@ int wolfSSL_BUF_MEM_grow_ex(WOLFSSL_BUF_MEM* buf, size_t len, } buf->data = tmp; - buf->max = (size_t)mx; + buf->max = mx; if (zeroFill) XMEMSET(&buf->data[buf->length], 0, len - buf->length); buf->length = len; - return len_int; + return (int)len; } @@ -15482,10 +15482,11 @@ int wolfSSL_BUF_MEM_grow(WOLFSSL_BUF_MEM* buf, size_t len) int wolfSSL_BUF_MEM_resize(WOLFSSL_BUF_MEM* buf, size_t len) { char* tmp; - int mx; + size_t mx; - /* verify provided arguments */ - if (buf == NULL || len == 0 || (int)len <= 0) { + /* verify provided arguments. The return value is an int, so reject any + * len that cannot be represented as a positive int. */ + if (buf == NULL || len == 0 || len > (size_t)INT_MAX) { return 0; /* BAD_FUNC_ARG; */ } @@ -15496,7 +15497,7 @@ int wolfSSL_BUF_MEM_resize(WOLFSSL_BUF_MEM* buf, size_t len) return wolfSSL_BUF_MEM_grow_ex(buf, len, 0); /* expand size, to handle growth */ - mx = ((int)len + 3) / 3 * 4; + mx = (len + 3) / 3 * 4; /* We want to shrink the internal buffer */ #ifdef WOLFSSL_NO_REALLOC @@ -15516,7 +15517,7 @@ int wolfSSL_BUF_MEM_resize(WOLFSSL_BUF_MEM* buf, size_t len) buf->data = tmp; buf->length = len; - buf->max = (size_t)mx; + buf->max = mx; return (int)len; } From df81ef1fe3199df1a8a0af08f418303d462a0bcc Mon Sep 17 00:00:00 2001 From: Kareem Date: Fri, 12 Jun 2026 13:25:56 -0700 Subject: [PATCH 5/9] Fix wolfIO_DecodeUrl handling of IPv6 brackets. Fixes F-4285. --- src/wolfio.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/wolfio.c b/src/wolfio.c index 75ff9d47bd..30d2022de4 100644 --- a/src/wolfio.c +++ b/src/wolfio.c @@ -1710,6 +1710,12 @@ int wolfIO_DecodeUrl(const char* url, int urlSz, char* outName, char* outPath, outName[i] = url[cur]; i++; cur++; } + /* A bracketed IPv6 literal must be terminated by ']'. The loop + * above can also stop on end-of-buffer, NUL, or the length cap, + * none of which represent a well-formed host. Reject those cases + * rather than accepting the unterminated tail as the hostname. */ + if (cur >= urlSz || url[cur] != ']') + return WOLFSSL_FATAL_ERROR; cur++; /* skip ']' */ } else { From dba0ba5a07b30bbba0fa20578111c03377c6c08a Mon Sep 17 00:00:00 2001 From: Kareem Date: Mon, 15 Jun 2026 10:14:03 -0700 Subject: [PATCH 6/9] Code review feedback --- wolfcrypt/src/chacha20_poly1305.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/wolfcrypt/src/chacha20_poly1305.c b/wolfcrypt/src/chacha20_poly1305.c index f3ebb52ff9..2a8228adf4 100644 --- a/wolfcrypt/src/chacha20_poly1305.c +++ b/wolfcrypt/src/chacha20_poly1305.c @@ -74,8 +74,10 @@ int wc_ChaCha20Poly1305_Encrypt( inPlaintextLen); if (ret == 0) ret = wc_ChaCha20Poly1305_Final(aead, outAuthTag); - - ForceZero(aead, sizeof(ChaChaPoly_Aead)); + #ifdef WOLFSSL_SMALL_STACK + if (aead != NULL) + #endif + ForceZero(aead, sizeof(ChaChaPoly_Aead)); WC_FREE_VAR_EX(aead, NULL, DYNAMIC_TYPE_TMP_BUFFER); return ret; From 910daaf658fd92dc947b77744512bcabf2fc89f6 Mon Sep 17 00:00:00 2001 From: Kareem Date: Thu, 25 Jun 2026 17:42:05 -0700 Subject: [PATCH 7/9] Code review feedback --- src/ssl.c | 2 +- src/wolfio.c | 2 +- wolfcrypt/src/chacha20_poly1305.c | 5 ++++- 3 files changed, 6 insertions(+), 3 deletions(-) diff --git a/src/ssl.c b/src/ssl.c index b61a376bf9..85c8854973 100644 --- a/src/ssl.c +++ b/src/ssl.c @@ -15486,7 +15486,7 @@ int wolfSSL_BUF_MEM_resize(WOLFSSL_BUF_MEM* buf, size_t len) /* verify provided arguments. The return value is an int, so reject any * len that cannot be represented as a positive int. */ - if (buf == NULL || len == 0 || len > (size_t)INT_MAX) { + if (buf == NULL || len == 0 || len > (size_t)WOLFSSL_MAX_32BIT) { return 0; /* BAD_FUNC_ARG; */ } diff --git a/src/wolfio.c b/src/wolfio.c index 30d2022de4..ab85ecdef8 100644 --- a/src/wolfio.c +++ b/src/wolfio.c @@ -1758,7 +1758,7 @@ int wolfIO_DecodeUrl(const char* url, int urlSz, char* outName, char* outPath, /* Reject out-of-range ports rather than silently truncating to * word16, which would otherwise wrap (e.g. 65536 -> 0) and * connect to an unintended port. */ - if (bigPort > 65535) + if (bigPort > WOLFSSL_MAX_16BIT) return WOLFSSL_FATAL_ERROR; if (outPort) *outPort = (word16)bigPort; diff --git a/wolfcrypt/src/chacha20_poly1305.c b/wolfcrypt/src/chacha20_poly1305.c index 2a8228adf4..7c4218ac57 100644 --- a/wolfcrypt/src/chacha20_poly1305.c +++ b/wolfcrypt/src/chacha20_poly1305.c @@ -126,7 +126,10 @@ int wc_ChaCha20Poly1305_Decrypt( /* zero plaintext on error */ ForceZero(outPlaintext, inCiphertextLen); } - ForceZero(aead, sizeof(ChaChaPoly_Aead)); + #ifdef WOLFSSL_SMALL_STACK + if (aead != NULL) + #endif + ForceZero(aead, sizeof(ChaChaPoly_Aead)); WC_FREE_VAR_EX(aead, NULL, DYNAMIC_TYPE_TMP_BUFFER); return ret; From dd773907d3ba7b0043144e44caccab607f16cbc7 Mon Sep 17 00:00:00 2001 From: Kareem Date: Mon, 6 Jul 2026 10:30:22 -0700 Subject: [PATCH 8/9] Code review feedback --- src/ssl.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ssl.c b/src/ssl.c index 85c8854973..11665a27d4 100644 --- a/src/ssl.c +++ b/src/ssl.c @@ -15486,7 +15486,7 @@ int wolfSSL_BUF_MEM_resize(WOLFSSL_BUF_MEM* buf, size_t len) /* verify provided arguments. The return value is an int, so reject any * len that cannot be represented as a positive int. */ - if (buf == NULL || len == 0 || len > (size_t)WOLFSSL_MAX_32BIT) { + if (buf == NULL || len == 0 || len > (size_t)WC_MAX_SINT_OF(int)) { return 0; /* BAD_FUNC_ARG; */ } From d0897decf38a1ae13fdd0f2950df59ed67b8683d Mon Sep 17 00:00:00 2001 From: Kareem Date: Tue, 7 Jul 2026 16:55:59 -0700 Subject: [PATCH 9/9] Code review feedback --- src/ssl.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ssl.c b/src/ssl.c index 11665a27d4..2e35d8cfe1 100644 --- a/src/ssl.c +++ b/src/ssl.c @@ -15422,7 +15422,7 @@ int wolfSSL_BUF_MEM_grow_ex(WOLFSSL_BUF_MEM* buf, size_t len, /* verify provided arguments. The return value is an int holding the * resulting length, so reject any len that cannot be represented as a * non-negative int. This also prevents truncating size_t to int. */ - if (buf == NULL || len > (size_t)INT_MAX) { + if (buf == NULL || len > (size_t)WC_MAX_SINT_OF(int)) { return 0; /* BAD_FUNC_ARG; */ }