From 3298db3e23c4b76c518b391005666f62644b2d1f Mon Sep 17 00:00:00 2001 From: Mark Atwood Date: Wed, 15 Jul 2026 12:15:09 -0700 Subject: [PATCH] fix: signed-shift UB in ML-DSA gamma1_19 encode The 32-bit little-endian path shifts sword32 operands (z1 << 20, z3 << 28) whose values reach 2^20-1, overflowing INT32_MAX (C11 6.5.7p4). Declare the locals word32 with an explicit cast, the same idiom the gamma1_17/w1 encoders already use. Output bits unchanged; ML-DSA KATs pass on 32-bit and 64-bit paths. --- wolfcrypt/src/wc_mldsa.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/wolfcrypt/src/wc_mldsa.c b/wolfcrypt/src/wc_mldsa.c index b564167111e..78fb9f9b76c 100644 --- a/wolfcrypt/src/wc_mldsa.c +++ b/wolfcrypt/src/wc_mldsa.c @@ -1829,10 +1829,10 @@ static void mldsa_encode_gamma1_19_bits_c(const sword32* z, byte* s) /* Step 3. Get 20 bits as a number. */ for (j = 0; j < MLDSA_N; j += 4) { - sword32 z0 = MLDSA_GAMMA1_19 - z[j + 0]; - sword32 z1 = MLDSA_GAMMA1_19 - z[j + 1]; - sword32 z2 = MLDSA_GAMMA1_19 - z[j + 2]; - sword32 z3 = MLDSA_GAMMA1_19 - z[j + 3]; + word32 z0 = (word32)(MLDSA_GAMMA1_19 - z[j + 0]); + word32 z1 = (word32)(MLDSA_GAMMA1_19 - z[j + 1]); + word32 z2 = (word32)(MLDSA_GAMMA1_19 - z[j + 2]); + word32 z3 = (word32)(MLDSA_GAMMA1_19 - z[j + 3]); /* 20 bits per number. * 4 numbers become 10 bytes. (4 * 20 bits = 10 * 8 bits) */