From 4c797d42a5dc6c70c69d35731329fdee1ec5e1fc Mon Sep 17 00:00:00 2001 From: Jeremiah Mackey Date: Mon, 6 Apr 2026 22:14:57 +0000 Subject: [PATCH 1/4] fix NULL drbg deref on non-Intel platforms --- wolfcrypt/src/random.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/wolfcrypt/src/random.c b/wolfcrypt/src/random.c index 9fa318c7608..4dcf8da0ec6 100644 --- a/wolfcrypt/src/random.c +++ b/wolfcrypt/src/random.c @@ -496,8 +496,8 @@ int wc_RNG_DRBG_Reseed(WC_RNG* rng, const byte* seed, word32 seedSz) /* using RDRAND not DRBG, so return success */ return 0; } - return BAD_FUNC_ARG; #endif + return BAD_FUNC_ARG; } return Hash_DRBG_Reseed((DRBG_internal *)rng->drbg, seed, seedSz); From 965d8fe4a0de86f8e7dfb645b78ebd348067d48b Mon Sep 17 00:00:00 2001 From: Jeremiah Mackey Date: Mon, 6 Apr 2026 22:15:02 +0000 Subject: [PATCH 2/4] save heap before FreeRsaKey in delete --- wolfcrypt/src/rsa.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/wolfcrypt/src/rsa.c b/wolfcrypt/src/rsa.c index 4fb4393f0b4..32db1e72ffc 100644 --- a/wolfcrypt/src/rsa.c +++ b/wolfcrypt/src/rsa.c @@ -207,10 +207,12 @@ RsaKey* wc_NewRsaKey(void* heap, int devId, int *result_code) int wc_DeleteRsaKey(RsaKey* key, RsaKey** key_p) { + void* heap; if (key == NULL) return BAD_FUNC_ARG; + heap = key->heap; wc_FreeRsaKey(key); - XFREE(key, key->heap, DYNAMIC_TYPE_RSA); + XFREE(key, heap, DYNAMIC_TYPE_RSA); if (key_p != NULL) *key_p = NULL; return 0; From 3e35adbaa51c6ade59394a145c9b62d19b5096a2 Mon Sep 17 00:00:00 2001 From: Jeremiah Mackey Date: Mon, 6 Apr 2026 22:15:07 +0000 Subject: [PATCH 3/4] add NULL checks to Base64 encode/decode --- wolfcrypt/src/coding.c | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/wolfcrypt/src/coding.c b/wolfcrypt/src/coding.c index 6347361ce44..e2ac7d3377f 100644 --- a/wolfcrypt/src/coding.c +++ b/wolfcrypt/src/coding.c @@ -174,6 +174,9 @@ int Base64_Decode_nonCT(const byte* in, word32 inLen, byte* out, word32* outLen) int ret; const byte maxIdx = BASE64DECODE_TABLE_SZ + BASE64_MIN - 1; + if ((in == NULL && inLen > 0) || out == NULL || outLen == NULL) + return BAD_FUNC_ARG; + while (inLen > 3) { int pad3 = 0; int pad4 = 0; @@ -273,6 +276,9 @@ int Base64_Decode(const byte* in, word32 inLen, byte* out, word32* outLen) word32 j = 0; int ret; + if ((in == NULL && inLen > 0) || out == NULL || outLen == NULL) + return BAD_FUNC_ARG; + while (inLen > 3) { int pad3 = 0; int pad4 = 0; @@ -474,6 +480,9 @@ static int DoBase64_Encode(const byte* in, word32 inLen, byte* out, word32 outSz = (inLen + 3 - 1) / 3 * 4; word32 addSz = (outSz + BASE64_LINE_SZ - 1) / BASE64_LINE_SZ; /* new lines */ + if (in == NULL && inLen > 0) + return BAD_FUNC_ARG; + if (escaped == WC_ESC_NL_ENC) addSz *= 3; /* instead of just \n, we're doing %0A triplet */ else if (escaped == WC_NO_NL_ENC) From e8660162d2008305737d732c0bd5f5c9d6545023 Mon Sep 17 00:00:00 2001 From: Jeremiah Mackey Date: Mon, 6 Apr 2026 22:15:13 +0000 Subject: [PATCH 4/4] reject non-block-aligned CBC cipher input --- wolfcrypt/src/camellia.c | 9 ++++++-- wolfcrypt/src/des3.c | 46 ++++++++++++++++++++++++++++------------ wolfcrypt/src/rc2.c | 16 ++++++++++++-- 3 files changed, 53 insertions(+), 18 deletions(-) diff --git a/wolfcrypt/src/camellia.c b/wolfcrypt/src/camellia.c index 1f876e316b1..facc4362650 100644 --- a/wolfcrypt/src/camellia.c +++ b/wolfcrypt/src/camellia.c @@ -64,8 +64,7 @@ #include #endif -/* u32 must be 32bit word */ -typedef unsigned int u32; +typedef word32 u32; typedef unsigned char u8; /* key constants */ @@ -1591,6 +1590,9 @@ int wc_CamelliaCbcEncrypt(wc_Camellia* cam, byte* out, const byte* in, word32 sz if (cam == NULL || out == NULL || in == NULL) { return BAD_FUNC_ARG; } + if (sz % WC_CAMELLIA_BLOCK_SIZE != 0) { + return BAD_LENGTH_E; + } blocks = sz / WC_CAMELLIA_BLOCK_SIZE; while (blocks--) { @@ -1613,6 +1615,9 @@ int wc_CamelliaCbcDecrypt(wc_Camellia* cam, byte* out, const byte* in, word32 sz if (cam == NULL || out == NULL || in == NULL) { return BAD_FUNC_ARG; } + if (sz % WC_CAMELLIA_BLOCK_SIZE != 0) { + return BAD_LENGTH_E; + } blocks = sz / WC_CAMELLIA_BLOCK_SIZE; while (blocks--) { diff --git a/wolfcrypt/src/des3.c b/wolfcrypt/src/des3.c index c3dcdf5efa0..e8683e0b773 100644 --- a/wolfcrypt/src/des3.c +++ b/wolfcrypt/src/des3.c @@ -1234,49 +1234,49 @@ int wc_Des_CbcEncrypt(Des* des, byte* out, const byte* in, word32 sz) { - word32 blocks = sz / DES_BLOCK_SIZE; - if (des == NULL || out == NULL || in == NULL) return BAD_FUNC_ARG; + if (sz % DES_BLOCK_SIZE != 0) + return BAD_LENGTH_E; return wc_Pic32DesCrypt(des->key, DES_KEYLEN, des->reg, DES_IVLEN, - out, in, (blocks * DES_BLOCK_SIZE), + out, in, sz, PIC32_ENCRYPTION, PIC32_ALGO_DES, PIC32_CRYPTOALGO_CBC); } int wc_Des_CbcDecrypt(Des* des, byte* out, const byte* in, word32 sz) { - word32 blocks = sz / DES_BLOCK_SIZE; - if (des == NULL || out == NULL || in == NULL) return BAD_FUNC_ARG; + if (sz % DES_BLOCK_SIZE != 0) + return BAD_LENGTH_E; return wc_Pic32DesCrypt(des->key, DES_KEYLEN, des->reg, DES_IVLEN, - out, in, (blocks * DES_BLOCK_SIZE), + out, in, sz, PIC32_DECRYPTION, PIC32_ALGO_DES, PIC32_CRYPTOALGO_CBC); } int wc_Des3_CbcEncrypt(Des3* des, byte* out, const byte* in, word32 sz) { - word32 blocks = sz / DES_BLOCK_SIZE; - if (des == NULL || out == NULL || in == NULL) return BAD_FUNC_ARG; + if (sz % DES_BLOCK_SIZE != 0) + return BAD_LENGTH_E; return wc_Pic32DesCrypt(des->key[0], DES3_KEYLEN, des->reg, DES3_IVLEN, - out, in, (blocks * DES_BLOCK_SIZE), + out, in, sz, PIC32_ENCRYPTION, PIC32_ALGO_TDES, PIC32_CRYPTOALGO_TCBC); } int wc_Des3_CbcDecrypt(Des3* des, byte* out, const byte* in, word32 sz) { - word32 blocks = sz / DES_BLOCK_SIZE; - if (des == NULL || out == NULL || in == NULL) return BAD_FUNC_ARG; + if (sz % DES_BLOCK_SIZE != 0) + return BAD_LENGTH_E; return wc_Pic32DesCrypt(des->key[0], DES3_KEYLEN, des->reg, DES3_IVLEN, - out, in, (blocks * DES_BLOCK_SIZE), + out, in, sz, PIC32_DECRYPTION, PIC32_ALGO_TDES, PIC32_CRYPTOALGO_TCBC); } @@ -1734,12 +1734,17 @@ int wc_Des_CbcEncrypt(Des* des, byte* out, const byte* in, word32 sz) { - word32 blocks = sz / DES_BLOCK_SIZE; + word32 blocks; if (des == NULL || out == NULL || in == NULL) { return BAD_FUNC_ARG; } + if (sz % DES_BLOCK_SIZE != 0) { + return BAD_LENGTH_E; + } + + blocks = sz / DES_BLOCK_SIZE; while (blocks--) { xorbuf((byte*)des->reg, in, DES_BLOCK_SIZE); DesProcessBlock(des, (byte*)des->reg, (byte*)des->reg); @@ -1753,12 +1758,17 @@ int wc_Des_CbcDecrypt(Des* des, byte* out, const byte* in, word32 sz) { - word32 blocks = sz / DES_BLOCK_SIZE; + word32 blocks; if (des == NULL || out == NULL || in == NULL) { return BAD_FUNC_ARG; } + if (sz % DES_BLOCK_SIZE != 0) { + return BAD_LENGTH_E; + } + + blocks = sz / DES_BLOCK_SIZE; while (blocks--) { XMEMCPY(des->tmp, in, DES_BLOCK_SIZE); DesProcessBlock(des, (byte*)des->tmp, out); @@ -1809,6 +1819,10 @@ } #endif /* WOLFSSL_ASYNC_CRYPT */ + if (sz % DES_BLOCK_SIZE != 0) { + return BAD_LENGTH_E; + } + blocks = sz / DES_BLOCK_SIZE; while (blocks--) { xorbuf((byte*)des->reg, in, DES_BLOCK_SIZE); @@ -1860,6 +1874,10 @@ } #endif /* WOLFSSL_ASYNC_CRYPT */ + if (sz % DES_BLOCK_SIZE != 0) { + return BAD_LENGTH_E; + } + blocks = sz / DES_BLOCK_SIZE; while (blocks--) { XMEMCPY(des->tmp, in, DES_BLOCK_SIZE); diff --git a/wolfcrypt/src/rc2.c b/wolfcrypt/src/rc2.c index dcc9561474f..4816d151658 100644 --- a/wolfcrypt/src/rc2.c +++ b/wolfcrypt/src/rc2.c @@ -279,7 +279,7 @@ int wc_Rc2EcbDecrypt(Rc2* rc2, byte* out, const byte* in, word32 sz) int wc_Rc2CbcEncrypt(Rc2* rc2, byte* out, const byte* in, word32 sz) { int ret; - word32 blocks = (sz / RC2_BLOCK_SIZE); + word32 blocks; if (rc2 == NULL || out == NULL || in == NULL) { return BAD_FUNC_ARG; @@ -289,6 +289,12 @@ int wc_Rc2CbcEncrypt(Rc2* rc2, byte* out, const byte* in, word32 sz) return 0; } + if (sz % RC2_BLOCK_SIZE != 0) { + return BAD_LENGTH_E; + } + + blocks = sz / RC2_BLOCK_SIZE; + while (blocks--) { xorbuf((byte*)rc2->reg, in, RC2_BLOCK_SIZE); ret = wc_Rc2EcbEncrypt(rc2, (byte*)rc2->reg, (byte*)rc2->reg, @@ -308,7 +314,7 @@ int wc_Rc2CbcEncrypt(Rc2* rc2, byte* out, const byte* in, word32 sz) int wc_Rc2CbcDecrypt(Rc2* rc2, byte* out, const byte* in, word32 sz) { int ret; - word32 blocks = (sz / RC2_BLOCK_SIZE); + word32 blocks; if (rc2 == NULL || out == NULL || in == NULL) { return BAD_FUNC_ARG; @@ -318,6 +324,12 @@ int wc_Rc2CbcDecrypt(Rc2* rc2, byte* out, const byte* in, word32 sz) return 0; } + if (sz % RC2_BLOCK_SIZE != 0) { + return BAD_LENGTH_E; + } + + blocks = sz / RC2_BLOCK_SIZE; + while (blocks--) { XMEMCPY(rc2->tmp, in, RC2_BLOCK_SIZE); ret = wc_Rc2EcbDecrypt(rc2, out, (byte*)rc2->tmp, RC2_BLOCK_SIZE);