Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
23 commits
Select commit Hold shift + click to select a range
00f098e
coding: remove unreachable len operand in Base64_SkipNewline
danielinux Jul 31, 2026
03e40fd
coding: remove unreachable out operand in the Base64 decoders
danielinux Jul 31, 2026
413fcc5
coding: remove unreachable in operand in Base16_Decode
danielinux Jul 31, 2026
fc72ef8
md5: remove unreachable len operand in wc_Md5Update
danielinux Jul 31, 2026
0090560
sha3: remove unreachable len operand in the PSOC6 Update paths
danielinux Jul 31, 2026
f043241
tfm: remove unreachable fp_gcd zero-operand branches
danielinux Jul 31, 2026
e11b5e1
integer: remove unreachable tmpc NULL check in s_mp_add
danielinux Jul 31, 2026
4acfa99
sp_int: remove tautological err check in sp_todecimal
danielinux Jul 31, 2026
d851828
sp_int: remove tautological err check in _sp_lcm
danielinux Jul 31, 2026
738454d
memory: remove unreachable res operand in wolfSSL_Realloc
danielinux Jul 31, 2026
d95bef3
mlkem: remove unreachable BAD_STATE_E re-check in wc_mlkemkey_check_h
danielinux Jul 31, 2026
d1ced3d
mldsa: remove tautological loop operand in mldsa_vec_check_low_c
danielinux Jul 31, 2026
964cc72
mldsa: remove tautological ret operand in wc_MlDsaKey_CheckKey
danielinux Jul 31, 2026
7daf4c3
mldsa: remove tautological ret operand in the small-mem sign entry
danielinux Jul 31, 2026
da46dcf
mldsa: remove tautological ret operand in two break-dominated inner l…
danielinux Jul 31, 2026
a2d8cf1
lms: remove unreachable inited operand in wc_hss_reload_key
danielinux Jul 31, 2026
8d8b255
integer: remove unreachable mp_init failure handling in mp_init_multi
danielinux Jul 31, 2026
611cebd
aes: remove unreachable bit lower-bound in wc_AesFeedbackCFB1
danielinux Jul 31, 2026
7ecbd73
ed448: remove unreachable privKeySet operand in wc_ed448_check_key
danielinux Jul 31, 2026
a17cc4e
ed448: remove unreachable Y == p case in wc_ed448_check_key
danielinux Jul 31, 2026
52b79db
kdf: remove tautological ret operand in the KDA-KDF CMAC loop
danielinux Jul 31, 2026
1ea6e9e
pwdbased: remove unreachable NULL check in DoPKCS12Hash
danielinux Jul 31, 2026
e16466f
tests: retarget the ed448 check_key Y-range stanzas
danielinux Aug 3, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
43 changes: 28 additions & 15 deletions tests/api/test_ed448.c
Original file line number Diff line number Diff line change
Expand Up @@ -1286,7 +1286,8 @@ int test_wc_ed448_import_private_only(void)
* (the is_small_order VALUE operand's independence is already shown by
* test_wc_ed448_reject_small_order_keys()), the (ret == 0 &&
* XMEMCMP(...) != 0) recomputed-vs-stored public key mismatch check in the
* have-private-key branch, and the deep Y-range check's final byte compare.
* have-private-key branch, and both decisions of the Y-range walk: the
* top-byte loop and the 0xFE compare that follows it.
*/
int test_wc_ed448_check_key_decisions(void)
{
Expand Down Expand Up @@ -1336,15 +1337,15 @@ int test_wc_ed448_check_key_decisions(void)
key.p[0] = (byte)(key.p[0] ^ 0xff);

/* Deep Y-range check: a Y value that is not one of
* ed448_is_small_order()'s tabulated points but still forces both
* range-check loops all the way down to the final byte compare (every
* byte except p[0] matches the encoded field prime p). Only reachable
* via a trusted import, which skips wc_ed448_check_key() at import
* time so the crafted (curve-invalid) point can be handed to a
* *direct* wc_ed448_check_key() call below -- same technique as
* test_wc_ed448_reject_small_order_keys(). Whatever the later
* curve-decode step decides is fine; the range-check decision itself
* is what's targeted here. */
* ed448_is_small_order()'s tabulated points but still runs the top-byte
* loop to exhaustion (every byte above the 0xFE position is 0xff), so
* the loop's index operand goes false and the 0xFE compare below it is
* reached and taken. Only reachable via a trusted import, which skips
* wc_ed448_check_key() at import time so the crafted (curve-invalid)
* point can be handed to a *direct* wc_ed448_check_key() call below --
* same technique as test_wc_ed448_reject_small_order_keys(). Whatever
* the later curve-decode step decides is fine; the range-check decision
* itself is what's targeted here. */
XMEMSET(near_p, 0xff, sizeof(near_p));
near_p[28] = 0xfe;
near_p[0] = 0x00;
Expand All @@ -1355,18 +1356,30 @@ int test_wc_ed448_check_key_decisions(void)
ExpectTrue((rc == 0) || (rc == WC_NO_ERR_TRACE(PUBLIC_KEY_E)));
wc_ed448_free(&freshKey);

/* Same construction but with an extra byte (p[1]) perturbed so the
* second range-check loop exits early with ret == 0 before the final
* byte compare runs -- closes that compare's PUBLIC_KEY_E
* guard operand's FALSE side. */
near_p[1] = 0x00;
/* Same construction with a byte inside the walked range cleared, so the
* loop breaks with ret == 0 instead of running out: closes the byte
* compare's TRUE side and the following (ret == PUBLIC_KEY_E) guard's
* FALSE side. */
near_p[29] = 0x00;
ExpectIntEQ(wc_ed448_init(&freshKey), 0);
ExpectIntEQ(wc_ed448_import_public_ex(near_p, ED448_PUB_KEY_SIZE,
&freshKey, 1), 0);
rc = wc_ed448_check_key(&freshKey);
ExpectTrue((rc == 0) || (rc == WC_NO_ERR_TRACE(PUBLIC_KEY_E)));
wc_ed448_free(&freshKey);

/* Every byte 0xff, including the 0xFE position: not a tabulated
* small-order encoding, the walk finds no byte below 0xff and the 0xFE
* compare is false, so the Y value is out of range. Closes that
* compare's FALSE side. */
XMEMSET(near_p, 0xff, sizeof(near_p));
ExpectIntEQ(wc_ed448_init(&freshKey), 0);
ExpectIntEQ(wc_ed448_import_public_ex(near_p, ED448_PUB_KEY_SIZE,
&freshKey, 1), 0);
ExpectIntEQ(wc_ed448_check_key(&freshKey),
WC_NO_ERR_TRACE(PUBLIC_KEY_E));
wc_ed448_free(&freshKey);

DoExpectIntEQ(wc_FreeRng(&rng), 0);
wc_ed448_free(&key);
#endif
Expand Down
2 changes: 1 addition & 1 deletion wolfcrypt/src/aes.c
Original file line number Diff line number Diff line change
Expand Up @@ -16504,7 +16504,7 @@ static WARN_UNUSED_RESULT int wc_AesFeedbackCFB1(
}

if (ret == 0) {
if (bit >= 0 && bit < 7) {
if (bit < 7) {
out[0] = cur;
}
}
Expand Down
8 changes: 4 additions & 4 deletions wolfcrypt/src/coding.c
Original file line number Diff line number Diff line change
Expand Up @@ -134,7 +134,7 @@ int Base64_SkipNewline(const byte* in, word32 *inLen,
curChar = in[++j];
len--;
}
if (len && (curChar == '\r' || curChar == '\n')) {
if (curChar == '\r' || curChar == '\n') {
j++;
len--;
if (curChar == '\r') {
Expand Down Expand Up @@ -278,7 +278,7 @@ int Base64_Decode_nonCT(const byte* in, word32 inLen, byte* out, word32* outLen)
}

/* If the output buffer has a room for an extra byte, add a null terminator */
if (out && *outLen > i)
if (*outLen > i)
out[i]= '\0';

/* Note, *outLen won't reflect the optional terminating null. */
Expand Down Expand Up @@ -392,7 +392,7 @@ int Base64_Decode(const byte* in, word32 inLen, byte* out, word32* outLen)
}

/* If the output buffer has a room for an extra byte, add a null terminator */
if (out && *outLen > i)
if (*outLen > i)
out[i]= '\0';

/* Note, *outLen won't reflect the optional terminating null. */
Expand Down Expand Up @@ -660,7 +660,7 @@ int Base16_Decode(const byte* in, word32 inLen, byte* out, word32* outLen)
if (in == NULL || out == NULL || outLen == NULL)
return BAD_FUNC_ARG;

if (inLen == 1 && *outLen && in) {
if (inLen == 1 && *outLen) {
byte b = (byte)(in[inIdx++] - BASE16_MIN); /* 0 starts at 0x30 */

/* sanity check */
Expand Down
51 changes: 21 additions & 30 deletions wolfcrypt/src/ed448.c
Original file line number Diff line number Diff line change
Expand Up @@ -251,7 +251,10 @@ static int ed448_is_small_order(const byte p[ED448_PUB_KEY_SIZE])
* (fe448_from_bytes) reads bytes 0-55 modulo p with no canonical-form
* check, so y = p decodes to 0 and y = p+1 decodes to 1; both must
* be rejected here. Only {y, y + p} fits in 56 bytes (2p overflows),
* so listing y and y + p exhausts the reachable encodings. */
* so listing y and y + p exhausts the reachable encodings.
* wc_ed448_check_key() depends on the y = p row: its Y-range test
* accepts that encoding, so dropping the row would let a y outside
* [0, p - 1] through. */
static const byte small_order_y[][ED448_PUB_KEY_SIZE] = {
/* order 1: identity y = 1, x = 0 */
{0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
Expand Down Expand Up @@ -1521,41 +1524,29 @@ int wc_ed448_check_key(ed448_key* key)
}
}
/* No private key, check Y is valid. */
else if ((ret == 0) && (!key->privKeySet)) {
else if (ret == 0) {
/* Verify that xQ and yQ are integers in the interval [0, p - 1].
* Only have yQ so check that ordinate.
* p = 2^448-2^224-1 = 0xff..fe..ff
*/
if (ret == 0) {
int i;
ret = PUBLIC_KEY_E;
int i;
ret = PUBLIC_KEY_E;

/* Check top part before 0xFE. */
for (i = ED448_PUB_KEY_SIZE - 1; i > ED448_PUB_KEY_SIZE/2; i--) {
if (key->p[i] < 0xff) {
ret = 0;
break;
}
/* Check top part before 0xFE. */
for (i = ED448_PUB_KEY_SIZE - 1; i > ED448_PUB_KEY_SIZE/2; i--) {
if (key->p[i] < 0xff) {
ret = 0;
break;
}
if (ret == WC_NO_ERR_TRACE(PUBLIC_KEY_E)) {
/* Check against 0xFE. */
if (key->p[ED448_PUB_KEY_SIZE/2] < 0xfe) {
ret = 0;
}
else if (key->p[ED448_PUB_KEY_SIZE/2] == 0xfe) {
/* Check bottom part before last byte. */
for (i = ED448_PUB_KEY_SIZE/2 - 1; i > 0; i--) {
if (key->p[i] != 0xff) {
ret = 0;
break;
}
}
/* Check last byte. */
if ((ret == WC_NO_ERR_TRACE(PUBLIC_KEY_E)) &&
(key->p[0] < 0xff)) {
ret = 0;
}
}
}
if (ret == WC_NO_ERR_TRACE(PUBLIC_KEY_E)) {
Comment thread
danielinux marked this conversation as resolved.
/* Every byte above this one is 0xff here, so y > p whenever this
* byte is 0xff, and y == p is then the only remaining encoding
* outside [0, p - 1]. It is already rejected by
* ed448_is_small_order() above, whose table carries y == p as a
* non-canonical encoding, so the low bytes need no check. */
if (key->p[ED448_PUB_KEY_SIZE/2] <= 0xfe) {
ret = 0;
}
}

Expand Down
46 changes: 13 additions & 33 deletions wolfcrypt/src/integer.c
Original file line number Diff line number Diff line change
Expand Up @@ -98,48 +98,29 @@ word32 CheckRunTimeSettings(void)
}


/* handle up to 6 inits */
/* handle up to 6 inits; returns MP_OKAY */
int mp_init_multi(mp_int* a, mp_int* b, mp_int* c, mp_int* d, mp_int* e,
mp_int* f)
{
int res = MP_OKAY;

if (a) XMEMSET(a, 0, sizeof(mp_int));
if (b) XMEMSET(b, 0, sizeof(mp_int));
if (c) XMEMSET(c, 0, sizeof(mp_int));
if (d) XMEMSET(d, 0, sizeof(mp_int));
if (e) XMEMSET(e, 0, sizeof(mp_int));
if (f) XMEMSET(f, 0, sizeof(mp_int));

if (a && ((res = mp_init(a)) != MP_OKAY))
return res;

if (b && ((res = mp_init(b)) != MP_OKAY)) {
mp_clear(a);
return res;
}

if (c && ((res = mp_init(c)) != MP_OKAY)) {
mp_clear(a); mp_clear(b);
return res;
}
/* mp_init() has exactly one failure mode, a NULL argument, and the guard
* on each call excludes it, so every one of these returns MP_OKAY and the
* result is discarded. Same shape as sp_init_multi() and tfm.c's
* mp_init_multi(), which also return MP_OKAY unconditionally. */
if (a) (void)mp_init(a);
if (b) (void)mp_init(b);
if (c) (void)mp_init(c);
if (d) (void)mp_init(d);
if (e) (void)mp_init(e);
if (f) (void)mp_init(f);

if (d && ((res = mp_init(d)) != MP_OKAY)) {
mp_clear(a); mp_clear(b); mp_clear(c);
return res;
}

if (e && ((res = mp_init(e)) != MP_OKAY)) {
mp_clear(a); mp_clear(b); mp_clear(c); mp_clear(d);
return res;
}

if (f && ((res = mp_init(f)) != MP_OKAY)) {
mp_clear(a); mp_clear(b); mp_clear(c); mp_clear(d); mp_clear(e);
return res;
}

return res;
return MP_OKAY;
}


Expand Down Expand Up @@ -1792,8 +1773,7 @@ int s_mp_add (mp_int * a, mp_int * b, mp_int * c)
tmpc = c->dp;

/* sanity-check dp pointers. */
Comment thread
danielinux marked this conversation as resolved.
if ((min_ab > 0) &&
((tmpa == NULL) || (tmpb == NULL) || (tmpc == NULL)))
if ((min_ab > 0) && ((tmpa == NULL) || (tmpb == NULL)))
{
return MP_VAL;
}
Expand Down
2 changes: 1 addition & 1 deletion wolfcrypt/src/kdf.c
Original file line number Diff line number Diff line change
Expand Up @@ -1633,7 +1633,7 @@ int wc_KDA_KDF_PRF_cmac(const byte* Kin, word32 KinSz,
}
#endif

while (ret == 0 && len_rem >= WC_AES_BLOCK_SIZE) {
while (len_rem >= WC_AES_BLOCK_SIZE) {
/* cmac in place in block size increments */
c32toa(counter, counterBuf);
#ifdef WOLFSSL_DEBUG_KDF
Expand Down
4 changes: 2 additions & 2 deletions wolfcrypt/src/md5.c
Original file line number Diff line number Diff line change
Expand Up @@ -358,8 +358,8 @@ int wc_Md5Update(wc_Md5* md5, const byte* data, word32 len)
if (md5->buffLen >= WC_MD5_BLOCK_SIZE)
return BUFFER_E;

if (data == NULL && len == 0) {
/* valid, but do nothing */
if (data == NULL) {
/* len is 0 here: valid, but do nothing */
return 0;
}

Expand Down
2 changes: 1 addition & 1 deletion wolfcrypt/src/memory.c
Original file line number Diff line number Diff line change
Expand Up @@ -1411,7 +1411,7 @@ void* wolfSSL_Realloc(void *ptr, size_t size, void* heap, int type)
}
}

if (pt != NULL && res == NULL) {
if (pt != NULL) {
word32 prvSz;

res = pt->buffer;
Expand Down
8 changes: 3 additions & 5 deletions wolfcrypt/src/pwdbased.c
Original file line number Diff line number Diff line change
Expand Up @@ -365,18 +365,16 @@ int wc_PBKDF2(byte* output, const byte* passwd, int pLen, const byte* salt,

#ifdef HAVE_PKCS12

/* helper for PKCS12_PBKDF(), does hash operation */
/* helper for PKCS12_PBKDF(), does hash operation.
* buffer and Ai are guaranteed non-NULL by the caller: each is either a stack
* array or an XMALLOC result whose failure returns MEMORY_E before the call. */
static int DoPKCS12Hash(enum wc_HashType hashT, byte* buffer, word32 totalLen,
byte* Ai, word32 u, int iterations)
{
int i;
int ret = 0;
WC_DECLARE_VAR(hash, wc_HashAlg, 1, 0);

if ((buffer == NULL) || (Ai == NULL)) {
return BAD_FUNC_ARG;
}

/* initialize hash */
Comment thread
danielinux marked this conversation as resolved.
WC_ALLOC_VAR_EX(hash, wc_HashAlg, 1, NULL, DYNAMIC_TYPE_HASHCTX,
return MEMORY_E);
Expand Down
12 changes: 6 additions & 6 deletions wolfcrypt/src/sha3.c
Original file line number Diff line number Diff line change
Expand Up @@ -1186,8 +1186,8 @@ static int wc_Sha3Update(wc_Sha3* sha3, const byte* data, word32 len, word32 p)
return BAD_FUNC_ARG;
}

if (data == NULL && len == 0) {
/* valid, but do nothing */
if (data == NULL) {
/* len is 0 here: valid, but do nothing */
return 0;
}

Expand Down Expand Up @@ -1865,8 +1865,8 @@ int wc_Shake128_Update(wc_Shake* shake, const byte* data, word32 len)
return BAD_FUNC_ARG;
}

if (data == NULL && len == 0) {
/* valid, but do nothing */
if (data == NULL) {
/* len is 0 here: valid, but do nothing */
return 0;
}

Expand Down Expand Up @@ -2163,8 +2163,8 @@ int wc_Shake256_Update(wc_Shake* shake, const byte* data, word32 len)
return BAD_FUNC_ARG;
}

if (data == NULL && len == 0) {
/* valid, but do nothing */
if (data == NULL) {
/* len is 0 here: valid, but do nothing */
return 0;
}

Expand Down
18 changes: 7 additions & 11 deletions wolfcrypt/src/sp_int.c
Original file line number Diff line number Diff line change
Expand Up @@ -18906,13 +18906,11 @@ int sp_todecimal(const sp_int* a, char* str)
/* Terminate string. */
str[i] = '\0';

if (err == MP_OKAY) {
/* Reverse string to big endian. */
for (j = 0; j <= (i - 1) / 2; j++) {
int c = (unsigned char)str[j];
str[j] = str[i - 1 - j];
str[i - 1 - j] = (char)c;
}
/* Reverse string to big endian. */
for (j = 0; j <= (i - 1) / 2; j++) {
int c = (unsigned char)str[j];
str[j] = str[i - 1 - j];
str[i - 1 - j] = (char)c;
}
}

Expand Down Expand Up @@ -19950,10 +19948,8 @@ static int _sp_lcm(const sp_int* a, const sp_int* b, sp_int* r)
_sp_init_size(t[0], used);
_sp_init_size(t[1], used);

if (err == MP_OKAY) {
/* 1. t0 = gcd(a, b) */
err = sp_gcd(a, b, t[0]);
}
/* 1. t0 = gcd(a, b) */
err = sp_gcd(a, b, t[0]);

if (err == MP_OKAY) {
/* Divide the greater by the common divisor and multiply by other
Expand Down
12 changes: 2 additions & 10 deletions wolfcrypt/src/tfm.c
Original file line number Diff line number Diff line change
Expand Up @@ -5511,23 +5511,15 @@ int fp_gcd(fp_int *a, fp_int *b, fp_int *c)
}

/* either zero than gcd is the largest */
if (fp_iszero (a) == FP_YES && fp_iszero (b) == FP_NO) {
if (fp_iszero (a) == FP_YES) {
fp_abs (b, c);
return FP_OKAY;
}
if (fp_iszero (a) == FP_NO && fp_iszero (b) == FP_YES) {
if (fp_iszero (b) == FP_YES) {
fp_abs (a, c);
return FP_OKAY;
}

/* optimized. At this point if a == 0 then
* b must equal zero too
*/
if (fp_iszero (a) == FP_YES) {
fp_zero(c);
return FP_OKAY;
}

#ifdef WOLFSSL_SMALL_STACK
u = (fp_int*)XMALLOC(sizeof(fp_int) * 3, NULL, DYNAMIC_TYPE_BIGINT);
if (u == NULL) {
Expand Down
Loading
Loading