From 2da09427cd926a2c061017ea6e5ab2005eb6cc97 Mon Sep 17 00:00:00 2001 From: John Safranek Date: Tue, 3 Mar 2026 10:51:24 -0800 Subject: [PATCH 1/6] Operator Precedence Bug Added parens around an assignment to a variable before it is compared to an expected value. Affected function: SetupUserTokenWin. Issue: F-210 --- apps/wolfsshd/auth.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/wolfsshd/auth.c b/apps/wolfsshd/auth.c index 03b15abe6..65a61d641 100644 --- a/apps/wolfsshd/auth.c +++ b/apps/wolfsshd/auth.c @@ -915,7 +915,7 @@ static int SetupUserTokenWin(const char* usr, authName.Buffer = MSV1_0_PACKAGE_NAME; authName.Length = (USHORT)WSTRLEN(MSV1_0_PACKAGE_NAME); authName.MaximumLength = authName.Length + 1; - if (rc = LsaLookupAuthenticationPackage(lsaHandle, &authName, &authId) != STATUS_SUCCESS) { + if ((rc = LsaLookupAuthenticationPackage(lsaHandle, &authName, &authId)) != STATUS_SUCCESS) { wolfSSH_Log(WS_LOG_ERROR, "[SSHD] LSA Lookup Authentication Package Error %d", rc); ret = WSSHD_AUTH_FAILURE; } From b0e424e05d8a8a86a422a9952a42ca9e011ef849 Mon Sep 17 00:00:00 2001 From: John Safranek Date: Tue, 3 Mar 2026 11:04:23 -0800 Subject: [PATCH 2/6] Missing `wc_ecc_init()` Before ECC Key Import 1. Call `wc_ecc_init()` on an ECC key before importing it. 2. Incidental: `PostLock()` and `PostUnlock()` needed their agent pointers tagged as unused. Affected functions: SignHashEcc. PostLock and PostUnlock. Issue: F-211 --- src/agent.c | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/src/agent.c b/src/agent.c index 5cc160d64..765ec38ca 100644 --- a/src/agent.c +++ b/src/agent.c @@ -374,6 +374,7 @@ static int PostLock(WOLFSSH_AGENT_CTX* agent, word32 ppSz; WLOG(WS_LOG_AGENT, "Posting lock to agent %p", agent); + WOLFSSH_UNUSED(agent); ppSz = sizeof(pp) - 1; if (passphraseSz < ppSz) @@ -395,6 +396,7 @@ static int PostUnlock(WOLFSSH_AGENT_CTX* agent, word32 ppSz; WLOG(WS_LOG_AGENT, "Posting unlock to agent %p", agent); + WOLFSSH_UNUSED(agent); ppSz = sizeof(pp) - 1; if (passphraseSz < ppSz) @@ -730,8 +732,12 @@ static int SignHashEcc(WOLFSSH_AGENT_KEY_ECDSA* rawKey, int curveId, ecc_key key; int ret; - ret = wc_ecc_import_private_key_ex(rawKey->d, rawKey->dSz, - rawKey->q, rawKey->qSz, &key, curveId); + ret = wc_ecc_init(&key); + + if (ret == 0) { + ret = wc_ecc_import_private_key_ex(rawKey->d, rawKey->dSz, + rawKey->q, rawKey->qSz, &key, curveId); + } if (ret == 0) { ret = wc_ecc_sign_hash(digest, digestSz, sig, sigSz, rng, &key); From f424d7a7fb637ab641ff6eebda45ead7b618ab9c Mon Sep 17 00:00:00 2001 From: John Safranek Date: Tue, 3 Mar 2026 11:14:11 -0800 Subject: [PATCH 3/6] Unchecked `wc_InitRsaKey` Return Value Check the return value of `wc_InitRsaKey()`. It will initialize the structure provided the pointer is non-null. Since the key is on the stack, the later call to `wc_FreeRsaKey()` will succeed as well. Modified the check for the encoded signature size inside the block where it is set; that check also updates the return value. Affected function: SignHashRsa. Issue: F-212 --- src/agent.c | 35 ++++++++++++++++++----------------- 1 file changed, 18 insertions(+), 17 deletions(-) diff --git a/src/agent.c b/src/agent.c index 765ec38ca..583c9c293 100644 --- a/src/agent.c +++ b/src/agent.c @@ -681,24 +681,25 @@ static int SignHashRsa(WOLFSSH_AGENT_KEY_RSA* rawKey, enum wc_HashType hashType, { RsaKey key; byte encSig[MAX_ENCODED_SIG_SZ]; - int encSigSz; - int ret = 0; - - wc_InitRsaKey(&key, heap); - mp_read_unsigned_bin(&key.n, rawKey->n, rawKey->nSz); - mp_read_unsigned_bin(&key.e, rawKey->e, rawKey->eSz); - mp_read_unsigned_bin(&key.d, rawKey->d, rawKey->dSz); - mp_read_unsigned_bin(&key.p, rawKey->p, rawKey->pSz); - mp_read_unsigned_bin(&key.q, rawKey->q, rawKey->qSz); - mp_read_unsigned_bin(&key.u, rawKey->iqmp, rawKey->iqmpSz); - - encSigSz = wc_EncodeSignature(encSig, digest, digestSz, - wc_HashGetOID(hashType)); - if (encSigSz <= 0) { - WLOG(WS_LOG_DEBUG, "Bad Encode Sig"); - ret = WS_CRYPTO_FAILED; + int encSigSz, ret; + + ret = wc_InitRsaKey(&key, heap); + if (ret == 0) { + mp_read_unsigned_bin(&key.n, rawKey->n, rawKey->nSz); + mp_read_unsigned_bin(&key.e, rawKey->e, rawKey->eSz); + mp_read_unsigned_bin(&key.d, rawKey->d, rawKey->dSz); + mp_read_unsigned_bin(&key.p, rawKey->p, rawKey->pSz); + mp_read_unsigned_bin(&key.q, rawKey->q, rawKey->qSz); + mp_read_unsigned_bin(&key.u, rawKey->iqmp, rawKey->iqmpSz); + + encSigSz = wc_EncodeSignature(encSig, digest, digestSz, + wc_HashGetOID(hashType)); + if (encSigSz <= 0) { + WLOG(WS_LOG_DEBUG, "Bad Encode Sig"); + ret = WS_CRYPTO_FAILED; + } } - else { + if (ret == 0) { WLOG(WS_LOG_INFO, "Signing hash with RSA."); *sigSz = wc_RsaSSL_Sign(encSig, encSigSz, sig, *sigSz, &key, rng); if (*sigSz <= 0) { From 86636797ee8e15441a657071e971e0ed796bd150 Mon Sep 17 00:00:00 2001 From: John Safranek Date: Tue, 3 Mar 2026 11:21:08 -0800 Subject: [PATCH 4/6] Missing break between switch cases Addded a break to the 'J' case of a switch statement that handles terminal display clearing for Windows. It was flowing into case 'K' without an explicit fallthrough tag. Affected function: wolfSSH_DoControlSeq. Issue: F-49 --- src/wolfterm.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/wolfterm.c b/src/wolfterm.c index 5ef630d15..24ce91982 100644 --- a/src/wolfterm.c +++ b/src/wolfterm.c @@ -510,6 +510,7 @@ static int wolfSSH_DoControlSeq(WOLFSSH* ssh, WOLFSSH_HANDLE handle, byte* buf, default: WLOG(WS_LOG_DEBUG, "Unexpected erase value %d", args[0]); } + break; case 'K': if (numArgs == 0) { /* erase start of cursor to end of line */ From 3cfec8b3d244e67f2d6fc7e5fc247215afb986bd Mon Sep 17 00:00:00 2001 From: John Safranek Date: Tue, 3 Mar 2026 11:30:08 -0800 Subject: [PATCH 5/6] Missing ForceZero on plaintext password copy When a copy of the user's password is freed, it wasn't getting force zeroed. It might still exist in the heap after getting freed. Added a call to `ForceZero()`. Affected function: CheckPasswordUnix. Issue: F-56 --- apps/wolfsshd/auth.c | 1 + 1 file changed, 1 insertion(+) diff --git a/apps/wolfsshd/auth.c b/apps/wolfsshd/auth.c index 65a61d641..e5cf6c516 100644 --- a/apps/wolfsshd/auth.c +++ b/apps/wolfsshd/auth.c @@ -430,6 +430,7 @@ static int CheckPasswordUnix(const char* usr, const byte* pw, word32 pwSz, WOLFS } if (pwStr != NULL) { + ForceZero(pwStr, pwSz + 1); WFREE(pwStr, NULL, DYNTYPE_STRING); } if (storedHashCpy != NULL) { From e923235cb90b0387528cf5addf9d226c128c071d Mon Sep 17 00:00:00 2001 From: John Safranek Date: Tue, 3 Mar 2026 10:29:02 -0800 Subject: [PATCH 6/6] Uninitialized `mode` Variable in FatFS `ff_open` Removed the variable. The flags passed to ff_open() are appropriate for ff_open(). Just check that read or write is set. Affected function: ff_open. Issue: F-213 --- src/wolfsftp.c | 32 +++++--------------------------- 1 file changed, 5 insertions(+), 27 deletions(-) diff --git a/src/wolfsftp.c b/src/wolfsftp.c index 90b31c944..586d3a88e 100644 --- a/src/wolfsftp.c +++ b/src/wolfsftp.c @@ -1939,45 +1939,23 @@ struct fd_entry { int used; }; +#define O_ACCMODE (WOLFSSH_O_RDONLY | WOLFSSH_O_WRONLY) + static struct fd_entry fd_pool[WOLFSSH_FATFS_MAX_FILES]; int ff_open(const char *fname, int flag, int perm) { int i; - BYTE mode; WOLFSSH_UNUSED(perm); PRINTF("\r\nfatFS open: %s", fname); - if (flag & WOLFSSH_O_RDONLY) { - mode = FA_READ; - - } else if (flag & WOLFSSH_O_RDWR) { - if ((flag & WOLFSSH_O_CREAT) && - (flag & WOLFSSH_O_TRUNC)) { - mode = FA_READ | FA_WRITE | FA_CREATE_ALWAYS; - - } else if ((flag & WOLFSSH_O_CREAT) && - (flag & WOLFSSH_O_APPEND)) { - mode = FA_READ | FA_WRITE | FA_CREATE_NEW | FA_OPEN_APPEND; - - } else { - mode = AM_ARC; - } - } else if (flag & WOLFSSH_O_WRONLY) { - if ((flag & WOLFSSH_O_CREAT) && - (flag & WOLFSSH_O_TRUNC)) { - mode = FA_READ | FA_CREATE_ALWAYS | FA_WRITE; - } else if ((flag & WOLFSSH_O_CREAT) && - (flag & WOLFSSH_O_APPEND)) { - mode = FA_READ | FA_WRITE | FA_CREATE_NEW | FA_OPEN_APPEND; - } - } else { + /* Make sure the access mode is read or write. */ + if ((flag & O_ACCMODE) == 0) { return -1; } - for (i = 0; i < WOLFSSH_FATFS_MAX_FILES; i++) { if (fd_pool[i].used == 0) { - if (f_open(&(fd_pool[i].f), fname, mode) == FR_OK) { + if (f_open(&(fd_pool[i].f), fname, (BYTE)flag) == FR_OK) { fd_pool[i].used = 1; PRINTF("\r\nfatFS open success: %d", i); return i;