From 1f3bea4907956dc85a4552ee7b88700415e5c83a Mon Sep 17 00:00:00 2001 From: night1rider Date: Tue, 24 Feb 2026 13:44:18 -0700 Subject: [PATCH] Fix potential memory leak when copying into existing SHA contexts and zero-initialize temp GetHash contexts --- wolfcrypt/src/sha.c | 2 +- wolfcrypt/src/sha256.c | 22 ++++++++++++++++++++-- wolfcrypt/src/sha512.c | 22 ++++++++++++++++++++-- 3 files changed, 41 insertions(+), 5 deletions(-) diff --git a/wolfcrypt/src/sha.c b/wolfcrypt/src/sha.c index 590a06104d..789876dd7f 100644 --- a/wolfcrypt/src/sha.c +++ b/wolfcrypt/src/sha.c @@ -1137,7 +1137,7 @@ int wc_ShaGetHash(wc_Sha* sha, byte* hash) return BAD_FUNC_ARG; } - WC_ALLOC_VAR_EX(tmpSha, wc_Sha, 1, NULL, DYNAMIC_TYPE_TMP_BUFFER, + WC_CALLOC_VAR_EX(tmpSha, wc_Sha, 1, NULL, DYNAMIC_TYPE_TMP_BUFFER, return MEMORY_E); ret = wc_ShaCopy(sha, tmpSha); diff --git a/wolfcrypt/src/sha256.c b/wolfcrypt/src/sha256.c index 745eb13673..b19a271c28 100644 --- a/wolfcrypt/src/sha256.c +++ b/wolfcrypt/src/sha256.c @@ -2546,7 +2546,7 @@ int wc_Sha224_Grow(wc_Sha224* sha224, const byte* in, int inSz) return BAD_FUNC_ARG; } - WC_ALLOC_VAR_EX(tmpSha224, wc_Sha224, 1, NULL, + WC_CALLOC_VAR_EX(tmpSha224, wc_Sha224, 1, NULL, DYNAMIC_TYPE_TMP_BUFFER, return MEMORY_E); ret = wc_Sha224Copy(sha224, tmpSha224); @@ -2582,6 +2582,15 @@ int wc_Sha224_Grow(wc_Sha224* sha224, const byte* in, int inSz) ret = 0; /* Reset ret to 0 to avoid returning the callback error code */ #endif /* WOLF_CRYPTO_CB && WOLF_CRYPTO_CB_COPY */ + /* Free dst's msg buffer before copy to prevent potential memory leak + * when XMEMCPY overwrites dst with src's pointers. */ + #if defined(WOLFSSL_HASH_KEEP) + if (dst->msg != NULL) { + XFREE(dst->msg, dst->heap, DYNAMIC_TYPE_TMP_BUFFER); + dst->msg = NULL; + } + #endif + XMEMCPY(dst, src, sizeof(wc_Sha224)); #ifdef WOLFSSL_SMALL_STACK_CACHE @@ -2691,7 +2700,7 @@ int wc_Sha256GetHash(wc_Sha256* sha256, byte* hash) return BAD_FUNC_ARG; } - WC_ALLOC_VAR_EX(tmpSha256, wc_Sha256, 1, NULL, DYNAMIC_TYPE_TMP_BUFFER, + WC_CALLOC_VAR_EX(tmpSha256, wc_Sha256, 1, NULL, DYNAMIC_TYPE_TMP_BUFFER, return MEMORY_E); ret = wc_Sha256Copy(sha256, tmpSha256); @@ -2728,6 +2737,15 @@ int wc_Sha256Copy(wc_Sha256* src, wc_Sha256* dst) ret = 0; /* Reset ret to 0 to avoid returning the callback error code */ #endif /* WOLF_CRYPTO_CB && WOLF_CRYPTO_CB_COPY */ + /* Free dst's msg buffer before copy to prevent potential memory leak + * when XMEMCPY overwrites dst with src's pointers. */ +#if defined(WOLFSSL_HASH_KEEP) + if (dst->msg != NULL) { + XFREE(dst->msg, dst->heap, DYNAMIC_TYPE_TMP_BUFFER); + dst->msg = NULL; + } +#endif + XMEMCPY(dst, src, sizeof(wc_Sha256)); #ifdef WOLFSSL_MAXQ10XX_CRYPTO diff --git a/wolfcrypt/src/sha512.c b/wolfcrypt/src/sha512.c index a50e2ebd6a..9ea3cb6e3f 100644 --- a/wolfcrypt/src/sha512.c +++ b/wolfcrypt/src/sha512.c @@ -2206,7 +2206,7 @@ static int Sha512_Family_GetHash(wc_Sha512* sha512, byte* hash, return BAD_FUNC_ARG; } - WC_ALLOC_VAR_EX(tmpSha512, wc_Sha512, 1, NULL, DYNAMIC_TYPE_TMP_BUFFER, + WC_CALLOC_VAR_EX(tmpSha512, wc_Sha512, 1, NULL, DYNAMIC_TYPE_TMP_BUFFER, return MEMORY_E); /* copy this sha512 into tmpSha */ @@ -2249,6 +2249,15 @@ int wc_Sha512Copy(wc_Sha512* src, wc_Sha512* dst) ret = 0; /* Reset ret to 0 to avoid returning the callback error code */ #endif /* WOLF_CRYPTO_CB && WOLF_CRYPTO_CB_COPY */ + /* Free dst's msg buffer before copy to prevent potential memory leak + * when XMEMCPY overwrites dst with src's pointers. */ +#if defined(WOLFSSL_HASH_KEEP) + if (dst->msg != NULL) { + XFREE(dst->msg, dst->heap, DYNAMIC_TYPE_TMP_BUFFER); + dst->msg = NULL; + } +#endif + XMEMCPY(dst, src, sizeof(wc_Sha512)); #ifdef WOLFSSL_SMALL_STACK_CACHE /* This allocation combines the customary W buffer used by @@ -2649,7 +2658,7 @@ int wc_Sha384GetHash(wc_Sha384* sha384, byte* hash) return BAD_FUNC_ARG; } - WC_ALLOC_VAR_EX(tmpSha384, wc_Sha384, 1, NULL, DYNAMIC_TYPE_TMP_BUFFER, + WC_CALLOC_VAR_EX(tmpSha384, wc_Sha384, 1, NULL, DYNAMIC_TYPE_TMP_BUFFER, return MEMORY_E); /* copy this sha384 into tmpSha */ @@ -2687,6 +2696,15 @@ int wc_Sha384Copy(wc_Sha384* src, wc_Sha384* dst) ret = 0; /* Reset ret to 0 to avoid returning the callback error code */ #endif /* WOLF_CRYPTO_CB && WOLF_CRYPTO_CB_COPY */ + /* Free dst's msg buffer before copy to prevent potential memory leak + * when XMEMCPY overwrites dst with src's pointers. */ +#if defined(WOLFSSL_HASH_KEEP) + if (dst->msg != NULL) { + XFREE(dst->msg, dst->heap, DYNAMIC_TYPE_TMP_BUFFER); + dst->msg = NULL; + } +#endif + XMEMCPY(dst, src, sizeof(wc_Sha384)); #ifdef WOLFSSL_SMALL_STACK_CACHE