From 014f55fe10b33c85da9e52e4998e7eae94a778e1 Mon Sep 17 00:00:00 2001 From: Daniel Pouzzner Date: Tue, 14 Oct 2025 16:28:32 -0500 Subject: [PATCH 1/6] wolfssl/wolfcrypt/types.h: add WC_WUR_INT(), MAX_UINT_OF(), MAX_SINT_OF(), MIN_SINT_OF(), WC_SAFE_SUM_UNSIGNED(), and WC_SAFE_SUM_SIGNED(). --- wolfcrypt/src/aes.c | 21 ++++++++---- wolfssl/wolfcrypt/types.h | 71 +++++++++++++++++++++++++++++++++++++-- 2 files changed, 84 insertions(+), 8 deletions(-) diff --git a/wolfcrypt/src/aes.c b/wolfcrypt/src/aes.c index 46531f28b..1b9726f8c 100644 --- a/wolfcrypt/src/aes.c +++ b/wolfcrypt/src/aes.c @@ -13706,8 +13706,12 @@ static int AesXtsEncryptUpdate(XtsAes* xaes, byte* out, const byte* in, word32 s } #ifndef WC_AESXTS_STREAM_NO_REQUEST_ACCOUNTING - (void)WC_SAFE_SUM_WORD32(stream->bytes_crypted_with_this_tweak, sz, - stream->bytes_crypted_with_this_tweak); + if (! WC_SAFE_SUM_WORD32(stream->bytes_crypted_with_this_tweak, sz, + stream->bytes_crypted_with_this_tweak)) + { + WOLFSSL_MSG("Overflow of stream->bytes_crypted_with_this_tweak " + "in AesXtsEncryptUpdate()."); + } #endif #if FIPS_VERSION3_GE(6,0,0) /* SP800-38E - Restrict data unit to 2^20 blocks per key. A block is @@ -14144,15 +14148,20 @@ static int AesXtsDecryptUpdate(XtsAes* xaes, byte* out, const byte* in, word32 s return BAD_FUNC_ARG; } - if (stream->bytes_crypted_with_this_tweak & ((word32)WC_AES_BLOCK_SIZE - 1U)) + if (stream->bytes_crypted_with_this_tweak & + ((word32)WC_AES_BLOCK_SIZE - 1U)) { - WOLFSSL_MSG("Call to AesXtsDecryptUpdate after previous finalizing call"); + WOLFSSL_MSG("AesXtsDecryptUpdate after previous finalizing call"); return BAD_FUNC_ARG; } #ifndef WC_AESXTS_STREAM_NO_REQUEST_ACCOUNTING - (void)WC_SAFE_SUM_WORD32(stream->bytes_crypted_with_this_tweak, sz, - stream->bytes_crypted_with_this_tweak); + if (! WC_SAFE_SUM_WORD32(stream->bytes_crypted_with_this_tweak, sz, + stream->bytes_crypted_with_this_tweak)) + { + WOLFSSL_MSG("Overflow of stream->bytes_crypted_with_this_tweak " + "in AesXtsDecryptUpdate()."); + } #endif { diff --git a/wolfssl/wolfcrypt/types.h b/wolfssl/wolfcrypt/types.h index d2dbe0466..997d43ae0 100644 --- a/wolfssl/wolfcrypt/types.h +++ b/wolfssl/wolfcrypt/types.h @@ -462,8 +462,75 @@ enum { #define XELEM_CNT(x) (sizeof((x))/sizeof(*(x))) -#define WC_SAFE_SUM_WORD32(in1, in2, out) ((in2) <= 0xffffffffU - (in1) ? \ - ((out) = (in1) + (in2), 1) : ((out) = 0xffffffffU, 0)) +#ifdef NO_INLINE + #define WC_WUR_INT(x) (x) +#else + WC_INLINE WARN_UNUSED_RESULT int WC_WUR_INT(int x) { return x; } +#endif + +#ifdef WORD64_AVAILABLE + #define MAX_UINT_OF(x) \ + ((((word64)1 << ((sizeof(x) * (word64)CHAR_BIT) - \ + (word64)1)) - (word64)1) \ + | \ + ((word64)1 << ((sizeof(x) * (word64)CHAR_BIT) - (word64)1))) + #define MAX_SINT_OF(x) \ + ((sword64)((((word64)1 << ((sizeof(x) * (word64)CHAR_BIT) - \ + (word64)2)) - (word64)1) \ + | \ + ((word64)1 << ((sizeof(x) * (word64)CHAR_BIT) - \ + (word64)2)))) + #define MIN_SINT_OF(x) \ + ((sword64)((word64)1 << ((sizeof(x) * (word64)CHAR_BIT) - \ + (word64)1))) +#else + #define MAX_UINT_OF(x) \ + ((((word32)1 << ((sizeof(x) * (word32)CHAR_BIT) - \ + (word32)1)) - (word32)1) \ + | \ + ((word32)1 << ((sizeof(x) * (word32)CHAR_BIT) - (word32)1))) + #define MAX_SINT_OF(x) \ + ((sword32)((((word32)1 << ((sizeof(x) * (word32)CHAR_BIT) - \ + (word32)2)) - (word32)1) \ + | \ + ((word32)1 << ((sizeof(x) * (word32)CHAR_BIT) - \ + (word32)2)))) + #define MIN_SINT_OF(x) \ + ((sword32)((word32)1 << ((sizeof(x) * (word32)CHAR_BIT) - \ + (word32)1))) +#endif + +#define WC_SAFE_SUM_UNSIGNED_NO_WUR(type, in1, in2, out) \ + ((in2) <= (MAX_UINT_OF(type) - (in1)) ? \ + ((out) = (in1) + (in2), 1) : \ + ((out) = MAX_UINT_OF(type), 0)) + +#define WC_SAFE_SUM_UNSIGNED(type, in1, in2, out) \ + WC_WUR_INT(WC_SAFE_SUM_UNSIGNED_NO_WUR(type, in1, in2, out)) + +#if defined(HAVE_SELFTEST) || (defined(HAVE_FIPS) && FIPS_VERSION3_LE(6,0,0)) + #define WC_SAFE_SUM_WORD32(in1, in2, out) \ + WC_SAFE_SUM_UNSIGNED_NO_WUR(word32, in1, in2, out) +#else + #define WC_SAFE_SUM_WORD32(in1, in2, out) \ + WC_SAFE_SUM_UNSIGNED(word32, in1, in2, out) +#endif + +#define WC_SAFE_SUM_SIGNED_NO_WUR(type, in1, in2, out) \ + ((((in1) > 0) && ((in2) > 0)) ? \ + ((in2) <= MAX_SINT_OF(type) - (in1) ? \ + ((out) = (in1) + (in2), 1) : \ + ((out) = (type)MAX_SINT_OF(type), 0)) \ + : \ + ((((in1) < 0) && ((in2) < 0)) ? \ + ((in2) >= MIN_SINT_OF(type) - (in1) ? \ + ((out) = (in1) + (in2), 1) : \ + ((out) = (type)MIN_SINT_OF(type), 0)) \ + : \ + ((out) = (in1) + (in2), 1))) + +#define WC_SAFE_SUM_SIGNED(type, in1, in2, out) \ + WC_WUR_INT(WC_SAFE_SUM_SIGNED_NO_WUR(type, in1, in2, out)) #if defined(HAVE_IO_POOL) WOLFSSL_API void* XMALLOC(size_t n, void* heap, int type); From 204eb96d2f2d46250362ec5901fdfcbafbcd9fbd Mon Sep 17 00:00:00 2001 From: Daniel Pouzzner Date: Tue, 14 Oct 2025 16:29:15 -0500 Subject: [PATCH 2/6] src/ssl.c: fix overflow/overrun defect in wolfSSL_writev(). --- src/ssl.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/src/ssl.c b/src/ssl.c index 9241ae5c1..0f0f5a5ad 100644 --- a/src/ssl.c +++ b/src/ssl.c @@ -11549,15 +11549,17 @@ int wolfSSL_set_compression(WOLFSSL* ssl) #endif byte* myBuffer = staticBuffer; int dynamic = 0; - word32 sending = 0; - int idx = 0; + size_t sending = 0; + size_t idx = 0; int i; int ret; WOLFSSL_ENTER("wolfSSL_writev"); for (i = 0; i < iovcnt; i++) - sending += iov[i].iov_len; + if (! WC_SAFE_SUM_UNSIGNED(size_t, sending, iov[i].iov_len, + sending)) + return BUFFER_E; if (sending > sizeof(staticBuffer)) { myBuffer = (byte*)XMALLOC(sending, ssl->heap, From 7c7040da244631493fda4c1288764fea8c06445c Mon Sep 17 00:00:00 2001 From: Daniel Pouzzner Date: Tue, 14 Oct 2025 17:38:12 -0500 Subject: [PATCH 3/6] src/internal.c: fix -Wnull-dereference in LoadCertByIssuer(). --- src/internal.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/internal.c b/src/internal.c index f104cf7ce..8b8aa7ba0 100644 --- a/src/internal.c +++ b/src/internal.c @@ -14705,7 +14705,10 @@ int LoadCertByIssuer(WOLFSSL_X509_STORE* store, X509_NAME* issuer, int type) if (idx >= 0) { WOLFSSL_MSG("find hashed CRL in list"); ph = wolfSSL_sk_BY_DIR_HASH_value(entry->hashes, idx); - suffix = ph->last_suffix; + if (ph) + suffix = ph->last_suffix; + else + suffix = 0; } else { ph = NULL; suffix = 0; From 1602ed2f3a2dcd5755e16dc85d41f999c54ce7e0 Mon Sep 17 00:00:00 2001 From: Daniel Pouzzner Date: Tue, 14 Oct 2025 18:27:02 -0500 Subject: [PATCH 4/6] wolfcrypt/src/asn.c: rearrange check for null cname in EncodeName() to fix false positive -Wnull-dereference. src/internal.c: suppress -Wnull-dereference locally in ProcessPeerCertParse() to fix false positive. --- src/internal.c | 5 +++++ wolfcrypt/src/asn.c | 23 +++++++++++------------ 2 files changed, 16 insertions(+), 12 deletions(-) diff --git a/src/internal.c b/src/internal.c index 8b8aa7ba0..0f77fb2d3 100644 --- a/src/internal.c +++ b/src/internal.c @@ -10613,8 +10613,11 @@ static void AddHandShakeHeader(byte* output, word32 length, if (hs == NULL) return; + PRAGMA_GCC_DIAG_PUSH; + PRAGMA_GCC("GCC diagnostic ignored \"-Wnull-dereference\""); hs->type = type; c32to24(length, hs->length); /* type and length same for each */ + PRAGMA_GCC_DIAG_POP; #ifdef WOLFSSL_DTLS if (ssl->options.dtls) { DtlsHandShakeHeader* dtls; @@ -23312,6 +23315,8 @@ int SendChangeCipher(WOLFSSL* ssl) /* get output buffer */ output = GetOutputBuffer(ssl); + if (output == NULL) + return BUFFER_E; AddRecordHeader(output, 1, change_cipher_spec, ssl, CUR_ORDER); diff --git a/wolfcrypt/src/asn.c b/wolfcrypt/src/asn.c index 7611eb242..cddb408f3 100644 --- a/wolfcrypt/src/asn.c +++ b/wolfcrypt/src/asn.c @@ -29915,19 +29915,18 @@ static int EncodeName(EncodedName* name, const char* nameStr, ret = BAD_FUNC_ARG; } -#ifdef WOLFSSL_CUSTOM_OID - if (ret == 0 && type == ASN_CUSTOM_NAME) { - if (cname == NULL || cname->custom.oidSz == 0) { - name->used = 0; - return 0; - } - } -#else - (void)cname; -#endif - - CALLOC_ASNSETDATA(dataASN, rdnASN_Length, ret, NULL); if (ret == 0) { + #ifdef WOLFSSL_CUSTOM_OID + if (type == ASN_CUSTOM_NAME) { + if (cname == NULL || cname->custom.oidSz == 0) { + name->used = 0; + return 0; + } + } + #else + (void)cname; + #endif + CALLOC_ASNSETDATA(dataASN, rdnASN_Length, ret, NULL); nameSz = (word32)XSTRLEN(nameStr); /* Copy the RDN encoding template. ASN.1 tag for the name string is set * based on type. */ From 21a66ec36b1cf3d3f47dddfeb93c4c91189bbab7 Mon Sep 17 00:00:00 2001 From: Daniel Pouzzner Date: Tue, 14 Oct 2025 19:10:15 -0500 Subject: [PATCH 5/6] wolfssl/wolfcrypt/types.h: add missing static attribute to WC_WUR_INT(). --- wolfssl/wolfcrypt/types.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/wolfssl/wolfcrypt/types.h b/wolfssl/wolfcrypt/types.h index 997d43ae0..58774e2e5 100644 --- a/wolfssl/wolfcrypt/types.h +++ b/wolfssl/wolfcrypt/types.h @@ -465,7 +465,7 @@ enum { #ifdef NO_INLINE #define WC_WUR_INT(x) (x) #else - WC_INLINE WARN_UNUSED_RESULT int WC_WUR_INT(int x) { return x; } + static WC_INLINE WARN_UNUSED_RESULT int WC_WUR_INT(int x) { return x; } #endif #ifdef WORD64_AVAILABLE From c771167127052d1769f5e1f0ae3fbcf70cb54581 Mon Sep 17 00:00:00 2001 From: Daniel Pouzzner Date: Tue, 14 Oct 2025 19:16:21 -0500 Subject: [PATCH 6/6] add WC_ prefixes to MAX_UINT_OF() and friends, to avoid collision with wolfSentry macros. --- wolfssl/wolfcrypt/types.h | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/wolfssl/wolfcrypt/types.h b/wolfssl/wolfcrypt/types.h index 58774e2e5..e9ac4451a 100644 --- a/wolfssl/wolfcrypt/types.h +++ b/wolfssl/wolfcrypt/types.h @@ -469,41 +469,41 @@ enum { #endif #ifdef WORD64_AVAILABLE - #define MAX_UINT_OF(x) \ + #define WC_MAX_UINT_OF(x) \ ((((word64)1 << ((sizeof(x) * (word64)CHAR_BIT) - \ (word64)1)) - (word64)1) \ | \ ((word64)1 << ((sizeof(x) * (word64)CHAR_BIT) - (word64)1))) - #define MAX_SINT_OF(x) \ + #define WC_MAX_SINT_OF(x) \ ((sword64)((((word64)1 << ((sizeof(x) * (word64)CHAR_BIT) - \ (word64)2)) - (word64)1) \ | \ ((word64)1 << ((sizeof(x) * (word64)CHAR_BIT) - \ (word64)2)))) - #define MIN_SINT_OF(x) \ + #define WC_MIN_SINT_OF(x) \ ((sword64)((word64)1 << ((sizeof(x) * (word64)CHAR_BIT) - \ (word64)1))) #else - #define MAX_UINT_OF(x) \ + #define WC_MAX_UINT_OF(x) \ ((((word32)1 << ((sizeof(x) * (word32)CHAR_BIT) - \ (word32)1)) - (word32)1) \ | \ ((word32)1 << ((sizeof(x) * (word32)CHAR_BIT) - (word32)1))) - #define MAX_SINT_OF(x) \ + #define WC_MAX_SINT_OF(x) \ ((sword32)((((word32)1 << ((sizeof(x) * (word32)CHAR_BIT) - \ (word32)2)) - (word32)1) \ | \ ((word32)1 << ((sizeof(x) * (word32)CHAR_BIT) - \ (word32)2)))) - #define MIN_SINT_OF(x) \ + #define WC_MIN_SINT_OF(x) \ ((sword32)((word32)1 << ((sizeof(x) * (word32)CHAR_BIT) - \ (word32)1))) #endif #define WC_SAFE_SUM_UNSIGNED_NO_WUR(type, in1, in2, out) \ - ((in2) <= (MAX_UINT_OF(type) - (in1)) ? \ + ((in2) <= (WC_MAX_UINT_OF(type) - (in1)) ? \ ((out) = (in1) + (in2), 1) : \ - ((out) = MAX_UINT_OF(type), 0)) + ((out) = WC_MAX_UINT_OF(type), 0)) #define WC_SAFE_SUM_UNSIGNED(type, in1, in2, out) \ WC_WUR_INT(WC_SAFE_SUM_UNSIGNED_NO_WUR(type, in1, in2, out)) @@ -518,14 +518,14 @@ enum { #define WC_SAFE_SUM_SIGNED_NO_WUR(type, in1, in2, out) \ ((((in1) > 0) && ((in2) > 0)) ? \ - ((in2) <= MAX_SINT_OF(type) - (in1) ? \ + ((in2) <= WC_MAX_SINT_OF(type) - (in1) ? \ ((out) = (in1) + (in2), 1) : \ - ((out) = (type)MAX_SINT_OF(type), 0)) \ + ((out) = (type)WC_MAX_SINT_OF(type), 0)) \ : \ ((((in1) < 0) && ((in2) < 0)) ? \ - ((in2) >= MIN_SINT_OF(type) - (in1) ? \ + ((in2) >= WC_MIN_SINT_OF(type) - (in1) ? \ ((out) = (in1) + (in2), 1) : \ - ((out) = (type)MIN_SINT_OF(type), 0)) \ + ((out) = (type)WC_MIN_SINT_OF(type), 0)) \ : \ ((out) = (in1) + (in2), 1)))