From 097ddc19d8d3d8a556441b411fa599cbb7c8c047 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tobias=20Frauenschl=C3=A4ger?= Date: Tue, 21 Jul 2026 15:26:51 +0200 Subject: [PATCH] Use alignment-safe writes in ML-KEM mlkem_vec_compress_10_c The little-endian large-code path of mlkem_vec_compress_10_c cast the output byte buffer to word32* and issued five 32-bit stores through it. That buffer is the caller-supplied ML-KEM ciphertext, which has no alignment guarantee, so on strict-alignment targets the store bus-faults and the cast violates strict aliasing. Write each word with writeUnalignedWord32, which does an alignment-safe byte copy, matching mldsa_encode_w1_88_c and the neighboring ML-KEM sampling code. Fixes F-6782. --- wolfcrypt/src/wc_mlkem_poly.c | 26 +++++++++++++++----------- 1 file changed, 15 insertions(+), 11 deletions(-) diff --git a/wolfcrypt/src/wc_mlkem_poly.c b/wolfcrypt/src/wc_mlkem_poly.c index 15db28e4fa..9737f54f1a 100644 --- a/wolfcrypt/src/wc_mlkem_poly.c +++ b/wolfcrypt/src/wc_mlkem_poly.c @@ -5864,18 +5864,22 @@ static void mlkem_vec_compress_10_c(byte* r, sword16* v, unsigned int k) sword16 t14 = TO_COMP_WORD_10(v, i, j, 14); sword16 t15 = TO_COMP_WORD_10(v, i, j, 15); - word32* r32 = (word32*)r; /* Pack sixteen 10-bit values into byte array. */ - r32[0] = (word32)t0 | ((word32)t1 << 10) | - ((word32)t2 << 20) | ((word32)t3 << 30); - r32[1] = ((word32)t3 >> 2) | ((word32)t4 << 8) | - ((word32)t5 << 18) | ((word32)t6 << 28); - r32[2] = ((word32)t6 >> 4) | ((word32)t7 << 6) | - ((word32)t8 << 16) | ((word32)t9 << 26); - r32[3] = ((word32)t9 >> 6) | ((word32)t10 << 4) | - ((word32)t11 << 14) | ((word32)t12 << 24); - r32[4] = ((word32)t12 >> 8) | ((word32)t13 << 2) | - ((word32)t14 << 12) | ((word32)t15 << 22); + writeUnalignedWord32(r + 0, + (word32)t0 | ((word32)t1 << 10) | + ((word32)t2 << 20) | ((word32)t3 << 30)); + writeUnalignedWord32(r + 4, + ((word32)t3 >> 2) | ((word32)t4 << 8) | + ((word32)t5 << 18) | ((word32)t6 << 28)); + writeUnalignedWord32(r + 8, + ((word32)t6 >> 4) | ((word32)t7 << 6) | + ((word32)t8 << 16) | ((word32)t9 << 26)); + writeUnalignedWord32(r + 12, + ((word32)t9 >> 6) | ((word32)t10 << 4) | + ((word32)t11 << 14) | ((word32)t12 << 24)); + writeUnalignedWord32(r + 16, + ((word32)t12 >> 8) | ((word32)t13 << 2) | + ((word32)t14 << 12) | ((word32)t15 << 22)); /* Move over set bytes. */ r += 20;