From 3f8a1b81d2a1e687ef7ab00fe847ce1c92ac9de2 Mon Sep 17 00:00:00 2001 From: John Safranek Date: Tue, 20 Jan 2026 11:27:48 -0800 Subject: [PATCH] Coverity: Untrusted divisor 1. The individual bytes of the value read by ato32() are promoted to int values. Added typecasts to word32 for each of the bytes of the 32-bit value so they are treated as unsigned values like the target type. Also shifted each byte separately after masking them and then oring them into a temp. 2. To get the e value from the KexDhInit message, use the GetStringRef() function. 3. Add bounds checking of eSz. Fixes CID: 572837 --- src/internal.c | 20 ++++++-------------- src/misc.c | 12 +++++++++++- 2 files changed, 17 insertions(+), 15 deletions(-) diff --git a/src/internal.c b/src/internal.c index 3107d3f3c..30fe0035c 100644 --- a/src/internal.c +++ b/src/internal.c @@ -4751,7 +4751,7 @@ static int DoKexDhInit(WOLFSSH* ssh, byte* buf, word32 len, word32* idx) * in the message isn't of the DH e value. Treat the Q as e. */ /* DYNTYPE_DH */ - byte* e; + const byte* e; word32 eSz; word32 begin; int ret = WS_SUCCESS; @@ -4770,28 +4770,20 @@ static int DoKexDhInit(WOLFSSH* ssh, byte* buf, word32 len, word32* idx) *idx += len; return WS_SUCCESS; } - } - if (ret == WS_SUCCESS) { begin = *idx; - ret = GetUint32(&eSz, buf, len, &begin); + ret = GetStringRef(&eSz, &e, buf, len, &begin); } if (ret == WS_SUCCESS) { /* Validate eSz */ - if ((len < begin) || (eSz > len - begin)) { - ret = WS_RECV_OVERFLOW_E; - } + if (eSz > (word32)sizeof(ssh->handshake->e) || eSz == 0) + ret = WS_PUBKEY_REJECTED_E; } if (ret == WS_SUCCESS) { - e = buf + begin; - begin += eSz; - - if (eSz <= (word32)sizeof(ssh->handshake->e)) { - WMEMCPY(ssh->handshake->e, e, eSz); - ssh->handshake->eSz = eSz; - } + WMEMCPY(ssh->handshake->e, e, eSz); + ssh->handshake->eSz = eSz; ssh->clientState = CLIENT_KEXDH_INIT_DONE; *idx = begin; diff --git a/src/misc.c b/src/misc.c index 41c4a88b9..f40bba974 100644 --- a/src/misc.c +++ b/src/misc.c @@ -74,7 +74,17 @@ STATIC INLINE word32 min(word32 a, word32 b) /* convert opaque to 32 bit integer */ STATIC INLINE void ato32(const byte* c, word32* u32) { - *u32 = (c[0] << 24) | (c[1] << 16) | (c[2] << 8) | c[3]; + word32 v = 0; + + v |= (word32)(c[0] & 0xFF); + v <<= 8; + v |= (word32)(c[1] & 0xFF); + v <<= 8; + v |= (word32)(c[2] & 0xFF); + v <<= 8; + v |= (word32)(c[3] & 0xFF); + + *u32 = v; }