From 5e34dad53026c79f368cdfb36f308026c7cb3816 Mon Sep 17 00:00:00 2001 From: JacobBarthelmeh Date: Wed, 17 Jun 2026 11:02:37 -0600 Subject: [PATCH 1/5] sanity check on read unsigned bin length argument --- wolfcrypt/src/integer.c | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/wolfcrypt/src/integer.c b/wolfcrypt/src/integer.c index 65789c41c75..de943ac12ad 100644 --- a/wolfcrypt/src/integer.c +++ b/wolfcrypt/src/integer.c @@ -762,11 +762,20 @@ int mp_read_unsigned_bin (mp_int * a, const unsigned char *b, int c) int res; int digits_needed; + if (c < 0) { + return MP_VAL; + } + while (c > 0 && b[0] == 0) { c--; b++; } + /* reject sizes where the bit count would overflow an int */ + if (c > (WOLFSSL_MAX_32BIT - (DIGIT_BIT - 1)) / CHAR_BIT) { + return MP_VAL; + } + digits_needed = ((c * CHAR_BIT) + DIGIT_BIT - 1) / DIGIT_BIT; /* make sure there are enough digits available */ From 4d843ad5ea0fd68f7b0304a8d30611b19ba2ae44 Mon Sep 17 00:00:00 2001 From: JacobBarthelmeh Date: Wed, 17 Jun 2026 11:15:39 -0600 Subject: [PATCH 2/5] adjustment to sanity checks for avoiding potential overflow --- wolfcrypt/src/asn.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/wolfcrypt/src/asn.c b/wolfcrypt/src/asn.c index 5d961fc9aaf..ec3f69cf097 100644 --- a/wolfcrypt/src/asn.c +++ b/wolfcrypt/src/asn.c @@ -2461,8 +2461,8 @@ int GetLength_ex(const byte* input, word32* inOutIdx, int* len, word32 maxIdx, *len = 0; /* Check there is at least one byte available containing length information. - */ - if ((idx + 1) > maxIdx) { + * Use >= to avoid a word32 wrap when idx is near UINT_MAX. */ + if (idx >= maxIdx) { WOLFSSL_MSG("GetLength - bad index on input"); return BUFFER_E; } @@ -2495,7 +2495,7 @@ int GetLength_ex(const byte* input, word32* inOutIdx, int* len, word32 maxIdx, } /* Check the number of bytes required are available. */ - if ((idx + (word32)bytes) > maxIdx) { + if ((word32)bytes > (maxIdx - idx)) { WOLFSSL_MSG("GetLength - bad long length"); return BUFFER_E; } @@ -2520,7 +2520,7 @@ int GetLength_ex(const byte* input, word32* inOutIdx, int* len, word32 maxIdx, } /* When requested, check the buffer has at least length bytes left. */ - if (check && ((idx + length) > maxIdx)) { + if (check && (length > (maxIdx - idx))) { WOLFSSL_MSG("GetLength - value exceeds buffer length"); return BUFFER_E; } From a3e8bab10ca2bad0f3f65180120c3efbc5fb7745 Mon Sep 17 00:00:00 2001 From: JacobBarthelmeh Date: Wed, 17 Jun 2026 11:40:28 -0600 Subject: [PATCH 3/5] hardening against potential overflow cases --- src/pk.c | 8 +++++++- wolfcrypt/src/coding.c | 4 ++++ 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/src/pk.c b/src/pk.c index bfc039e5d0f..f4761a74185 100644 --- a/src/pk.c +++ b/src/pk.c @@ -6911,9 +6911,15 @@ static int pem_write_data(const char *name, const char *header, int headerLen; char* pem = NULL; word32 pemLen; - word32 derLen = (word32)len; + word32 derLen; byte* p; + /* Reject lengths that would wrap the PEM size calculation below. */ + if ((len < 0) || ((word32)len >= (WOLFSSL_MAX_32BIT / 4))) { + return BAD_FUNC_ARG; + } + derLen = (word32)len; + nameLen = (int)XSTRLEN(name); headerLen = (int)XSTRLEN(header); diff --git a/wolfcrypt/src/coding.c b/wolfcrypt/src/coding.c index c89dab769c0..b184d77a5b0 100644 --- a/wolfcrypt/src/coding.c +++ b/wolfcrypt/src/coding.c @@ -525,6 +525,10 @@ static int DoBase64_Encode(const byte* in, word32 inLen, byte* out, if (in == NULL && inLen > 0) return BAD_FUNC_ARG; + /* Reject lengths that would wrap the encoded-size calculation below. */ + if (inLen >= (WOLFSSL_MAX_32BIT / 4)) + return BAD_FUNC_ARG; + outSz = (inLen + 3 - 1) / 3 * 4; addSz = (outSz + BASE64_LINE_SZ - 1) / BASE64_LINE_SZ; /* new lines */ From f869e94f92ab586b6b21b0a452ea8f70dcf0ae44 Mon Sep 17 00:00:00 2001 From: JacobBarthelmeh Date: Tue, 7 Jul 2026 16:03:00 -0600 Subject: [PATCH 4/5] adjustment to overflow check --- wolfcrypt/src/integer.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/wolfcrypt/src/integer.c b/wolfcrypt/src/integer.c index de943ac12ad..bcd050c117f 100644 --- a/wolfcrypt/src/integer.c +++ b/wolfcrypt/src/integer.c @@ -771,12 +771,13 @@ int mp_read_unsigned_bin (mp_int * a, const unsigned char *b, int c) b++; } - /* reject sizes where the bit count would overflow an int */ - if (c > (WOLFSSL_MAX_32BIT - (DIGIT_BIT - 1)) / CHAR_BIT) { + /* reject sizes where the bit count would overflow, doing the math in + * word32 so c * CHAR_BIT can't overflow */ + if ((word32)c > (WOLFSSL_MAX_32BIT - (DIGIT_BIT - 1)) / CHAR_BIT) { return MP_VAL; } - digits_needed = ((c * CHAR_BIT) + DIGIT_BIT - 1) / DIGIT_BIT; + digits_needed = (int)(((word32)c * CHAR_BIT + DIGIT_BIT - 1) / DIGIT_BIT); /* make sure there are enough digits available */ if (a->alloc < digits_needed) { From 5e1e4231c5ab282df06b2750445f91ecf937ca5c Mon Sep 17 00:00:00 2001 From: JacobBarthelmeh Date: Thu, 9 Jul 2026 09:54:30 -0600 Subject: [PATCH 5/5] adjust test case for updated sanity check with heap math --- wolfcrypt/test/test.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/wolfcrypt/test/test.c b/wolfcrypt/test/test.c index 66bcfef3916..82a1a63e3ad 100644 --- a/wolfcrypt/test/test.c +++ b/wolfcrypt/test/test.c @@ -27262,11 +27262,9 @@ static wc_test_ret_t rsa_decode_test(RsaKey* keyPub) ret = WC_TEST_RET_ENC_EC(ret); goto done; } -#if defined(USE_INTEGER_HEAP_MATH) - #define RSA_RAW_BADLEN_EXPECT 0 -#else + /* All math backends now reject a negative/oversized length in + * mp_read_unsigned_bin, so a (word32)-1 length fails consistently. */ #define RSA_RAW_BADLEN_EXPECT WC_NO_ERR_TRACE(ASN_GETINT_E) -#endif ret = wc_RsaPublicKeyDecodeRaw(n, (word32)-1, e, sizeof(e), keyPub); if (ret != RSA_RAW_BADLEN_EXPECT) { ret = WC_TEST_RET_ENC_EC(ret);