From 038be95a4ac4832fdf48861419cbb1f116e56515 Mon Sep 17 00:00:00 2001 From: Daniel Pouzzner Date: Fri, 29 Mar 2024 11:44:52 -0500 Subject: [PATCH] wolfssl/wolfcrypt/types.h: add WC_SAFE_SUM_WORD32(). src/internal.c: mitigations for potential integer overflows in figuring allocation sizes. --- src/internal.c | 32 ++++++++++++++++++++++---------- wolfssl/wolfcrypt/types.h | 3 +++ 2 files changed, 25 insertions(+), 10 deletions(-) diff --git a/src/internal.c b/src/internal.c index 6848b47b9..dd0cfd7f0 100644 --- a/src/internal.c +++ b/src/internal.c @@ -10566,8 +10566,7 @@ static WC_INLINE int GrowOutputBuffer(WOLFSSL* ssl, int size) #else const byte align = WOLFSSL_GENERAL_ALIGNMENT; #endif - int newSz = size + ssl->buffers.outputBuffer.idx + - ssl->buffers.outputBuffer.length; + word32 newSz; #if WOLFSSL_GENERAL_ALIGNMENT > 0 /* the encrypted data will be offset from the front of the buffer by @@ -10578,7 +10577,15 @@ static WC_INLINE int GrowOutputBuffer(WOLFSSL* ssl, int size) align *= 2; #endif - tmp = (byte*)XMALLOC(newSz + align, ssl->heap, DYNAMIC_TYPE_OUT_BUFFER); + if (! WC_SAFE_SUM_WORD32(ssl->buffers.outputBuffer.idx, + ssl->buffers.outputBuffer.length, newSz)) + return BUFFER_E; + if (! WC_SAFE_SUM_WORD32(newSz, (word32)size, newSz)) + return BUFFER_E; + if (! WC_SAFE_SUM_WORD32(newSz, align, newSz)) + return BUFFER_E; + tmp = (byte*)XMALLOC(newSz, ssl->heap, DYNAMIC_TYPE_OUT_BUFFER); + newSz -= align; WOLFSSL_MSG("growing output buffer"); if (tmp == NULL) @@ -28389,7 +28396,7 @@ static int SigAlgoCachesMsgs(int sigAlgo) } static int HashSkeData(WOLFSSL* ssl, enum wc_HashType hashType, - const byte* data, int sz, byte sigAlgo) + const byte* data, word32 sz, byte sigAlgo) { int ret = 0; int digest_sz = wc_HashGetDigestSize(hashType); @@ -28399,11 +28406,16 @@ static int HashSkeData(WOLFSSL* ssl, enum wc_HashType hashType, } if (ret == 0) { + word32 new_size = SEED_LEN; /* buffer for signature */ - ssl->buffers.sig.buffer = (byte*)XMALLOC(SEED_LEN + sz, ssl->heap, - DYNAMIC_TYPE_SIGNATURE); - if (ssl->buffers.sig.buffer == NULL) { + if (! WC_SAFE_SUM_WORD32(new_size, sz, new_size)) ret = MEMORY_E; + else { + ssl->buffers.sig.buffer = (byte*)XMALLOC(new_size, ssl->heap, + DYNAMIC_TYPE_SIGNATURE); + if (ssl->buffers.sig.buffer == NULL) { + ret = MEMORY_E; + } } } if (ret == 0) { @@ -30439,14 +30451,14 @@ static int DoServerKeyExchange(WOLFSSL* ssl, const byte* input, ERROR_OUT(NOT_COMPILED_IN, exit_dske); #else enum wc_HashType hashType; - word16 verifySz; + word32 verifySz; byte sigAlgo; if (ssl->options.usingAnon_cipher) { break; } - verifySz = (word16)(args->idx - args->begin); + verifySz = (args->idx - args->begin); if (verifySz > MAX_DH_SZ) { ERROR_OUT(BUFFER_ERROR, exit_dske); } @@ -33382,7 +33394,7 @@ static int DoSessionTicket(WOLFSSL* ssl, const byte* input, word32* inOutIdx, #if defined(HAVE_ECC) || defined(HAVE_CURVE25519) || defined(HAVE_CURVE448) word32 exportSz; #endif - int sendSz; + word32 sendSz; int inputSz; } SskeArgs; diff --git a/wolfssl/wolfcrypt/types.h b/wolfssl/wolfcrypt/types.h index 01ed929f4..f5a279feb 100644 --- a/wolfssl/wolfcrypt/types.h +++ b/wolfssl/wolfcrypt/types.h @@ -430,6 +430,9 @@ typedef struct w64wrapper { #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)) + /* idea to add global alloc override by Moises Guimaraes */ /* default to libc stuff */ /* XREALLOC is used once in normal math lib, not in fast math lib */