From 9986611552e4090f1b4a47e23ec02b4740f28ba4 Mon Sep 17 00:00:00 2001 From: Aidan Keefe Date: Mon, 29 Jun 2026 13:53:58 -0600 Subject: [PATCH] https://fenrir.wolfssl.com/finding/6438 https://fenrir.wolfssl.com/finding/5414 https://fenrir.wolfssl.com/finding/5414 https://fenrir.wolfssl.com/finding/5415 https://fenrir.wolfssl.com/finding/6165 https://fenrir.wolfssl.com/finding/6167 https://fenrir.wolfssl.com/finding/6177 https://fenrir.wolfssl.com/finding/6166 skoll issues --- wolfcrypt/src/ecc.c | 8 +- wolfcrypt/src/pkcs12.c | 8 + .../src/port/Renesas/renesas_fspsm_rsa.c | 4 +- wolfcrypt/src/pwdbased.c | 3 +- wolfcrypt/src/wc_mldsa.c | 118 ++++++----- wolfcrypt/src/wc_slhdsa.c | 186 +++++++++--------- wolfcrypt/src/wc_xmss_impl.c | 45 ++--- 7 files changed, 186 insertions(+), 186 deletions(-) diff --git a/wolfcrypt/src/ecc.c b/wolfcrypt/src/ecc.c index a3476d4e146..fa54805e056 100644 --- a/wolfcrypt/src/ecc.c +++ b/wolfcrypt/src/ecc.c @@ -6405,8 +6405,8 @@ int wc_ecc_init_id(ecc_key* key, unsigned char* id, int len, void* heap, { int ret = 0; #ifdef WOLFSSL_SE050 - /* SE050 TLS users store a word32 at id, need to cast back */ - word32* keyPtr = NULL; + /* SE050 TLS users store a word32 at id, need to read it back */ + word32 keyId = 0; #endif if (key == NULL) @@ -6421,8 +6421,8 @@ int wc_ecc_init_id(ecc_key* key, unsigned char* id, int len, void* heap, #ifdef WOLFSSL_SE050 /* Set SE050 ID from word32, populate ecc_key with public from SE050 */ if (len == (int)sizeof(word32)) { - keyPtr = (word32*)key->id; - ret = wc_ecc_use_key_id(key, *keyPtr, 0); + keyId = readUnalignedWord32(key->id); + ret = wc_ecc_use_key_id(key, keyId, 0); } #endif } diff --git a/wolfcrypt/src/pkcs12.c b/wolfcrypt/src/pkcs12.c index a5d796208ba..df26290abde 100644 --- a/wolfcrypt/src/pkcs12.c +++ b/wolfcrypt/src/pkcs12.c @@ -1355,6 +1355,7 @@ int wc_PKCS12_parse_ex(WC_PKCS12* pkcs12, const char* psw, WC_DerCertList* certList = NULL; WC_DerCertList* tailList = NULL; byte* buf = NULL; + int bufSz = 0; /* allocation length of buf, for zeroization */ word32 i, oid; word32 algId; word32 contentSz = 0; @@ -1462,6 +1463,7 @@ int wc_PKCS12_parse_ex(WC_PKCS12* pkcs12, const char* psw, /* decrypted content overwrites input buffer */ size = (int)(ci->dataSz - idx); + bufSz = size; buf = (byte*)XMALLOC((size_t)size, pkcs12->heap, DYNAMIC_TYPE_PKCS); if (buf == NULL) { ERROR_OUT(MEMORY_E, exit_pk12par); @@ -1780,8 +1782,11 @@ int wc_PKCS12_parse_ex(WC_PKCS12* pkcs12, const char* psw, } /* free temporary buffer */ + if (buf != NULL) + ForceZero(buf, (word32)bufSz); XFREE(buf, pkcs12->heap, DYNAMIC_TYPE_PKCS); buf = NULL; + bufSz = 0; ci = ci->next; WOLFSSL_MSG("Done Parsing PKCS12 Content Info Container"); @@ -1816,6 +1821,9 @@ int wc_PKCS12_parse_ex(WC_PKCS12* pkcs12, const char* psw, XFREE(*pkey, pkcs12->heap, DYNAMIC_TYPE_PUBLIC_KEY); *pkey = NULL; } + /* free temporary buffer */ + if (buf != NULL) + ForceZero(buf, (word32)bufSz); XFREE(buf, pkcs12->heap, DYNAMIC_TYPE_PKCS); buf = NULL; diff --git a/wolfcrypt/src/port/Renesas/renesas_fspsm_rsa.c b/wolfcrypt/src/port/Renesas/renesas_fspsm_rsa.c index 59d05e3edfb..f607ea03151 100644 --- a/wolfcrypt/src/port/Renesas/renesas_fspsm_rsa.c +++ b/wolfcrypt/src/port/Renesas/renesas_fspsm_rsa.c @@ -199,12 +199,12 @@ WOLFSSL_LOCAL int wc_fspsm_RsaFunction(const byte* in, word32 inLen, byte* out, if (keySize == 1024) { ret = FSPSM_RSA1024_PKCSDEC_FUNC(&cipher, &plain, (FSPSM_RSA1024_WPI_KEY*) - key->ctx.wrapped_pri1024_key, &outLen); + key->ctx.wrapped_pri1024_key, outLen); } else { ret = FSPSM_RSA2048_PKCSDEC_FUNC(&cipher, &plain, (FSPSM_RSA2048_WPI_KEY*) - key->ctx.wrapped_pri2048_key, &outLen); + key->ctx.wrapped_pri2048_key, outLen); } } diff --git a/wolfcrypt/src/pwdbased.c b/wolfcrypt/src/pwdbased.c index c27e12515b6..58c883f2102 100644 --- a/wolfcrypt/src/pwdbased.c +++ b/wolfcrypt/src/pwdbased.c @@ -950,7 +950,8 @@ static void scryptROMix(byte* x, byte* v, byte* y, int r, word32 n) #endif #else byte* t = x + (2*r - 1) * 64; - j = (t[0] | (t[1] << 8) | (t[2] << 16) | ((word32)t[3] << 24)) & (n-1); + j = ((word32)t[0] | ((word32)t[1] << 8) | ((word32)t[2] << 16) | + ((word32)t[3] << 24)) & (n-1); #endif #ifdef WORD64_AVAILABLE for (k = 0; k < bSz / 8; k++) diff --git a/wolfcrypt/src/wc_mldsa.c b/wolfcrypt/src/wc_mldsa.c index 578428f2da6..d1fe35e2b12 100644 --- a/wolfcrypt/src/wc_mldsa.c +++ b/wolfcrypt/src/wc_mldsa.c @@ -1400,16 +1400,12 @@ static void mldsa_vec_encode_t0_t1_c(const sword32* t, byte d, byte* t0, /* 13 bits per number. * 8 numbers become 13 bytes. (8 * 13 bits = 13 * 8 bits) */ - #if defined(LITTLE_ENDIAN_ORDER) && (WOLFSSL_MLDSA_ALIGNMENT <= 2) - word32* tp; - #endif #if defined(LITTLE_ENDIAN_ORDER) && (WOLFSSL_MLDSA_ALIGNMENT == 0) - tp = (word32*)t0; - writeUnalignedWord32(tp+0, (n0_0 ) | ((word32)n0_1 << 13) | + writeUnalignedWord32(t0+0, (n0_0 ) | ((word32)n0_1 << 13) | ((word32)n0_2 << 26)); - writeUnalignedWord32(tp+1, (n0_2 >> 6) | ((word32)n0_3 << 7) | + writeUnalignedWord32(t0+4, (n0_2 >> 6) | ((word32)n0_3 << 7) | ((word32)n0_4 << 20)); - writeUnalignedWord32(tp+2, (n0_4 >> 12) | ((word32)n0_5 << 1) | + writeUnalignedWord32(t0+8, (n0_4 >> 12) | ((word32)n0_5 << 1) | ((word32)n0_6 << 14) | ((word32)n0_7 << 27)); #else t0[ 0] = (byte)( (n0_0 << 0)); @@ -1430,10 +1426,9 @@ static void mldsa_vec_encode_t0_t1_c(const sword32* t, byte d, byte* t0, /* 10 bits per number. * 8 bytes become 10 bytes. (8 * 10 bits = 10 * 8 bits) */ #if defined(LITTLE_ENDIAN_ORDER) && (WOLFSSL_MLDSA_ALIGNMENT <= 2) - tp = (word32*)t1; - writeUnalignedWord32(tp+0, (n1_0 ) | ((word32)n1_1 << 10) | + writeUnalignedWord32(t1+0, (n1_0 ) | ((word32)n1_1 << 10) | ((word32)n1_2 << 20) | ((word32)n1_3 << 30)); - writeUnalignedWord32(tp+1, (n1_3 >> 2) | ((word32)n1_4 << 8) | + writeUnalignedWord32(t1+4, (n1_3 >> 2) | ((word32)n1_4 << 8) | ((word32)n1_5 << 18) | ((word32)n1_6 << 28)); #else t1[0] = (byte)( (n1_0 << 0)); @@ -1632,7 +1627,7 @@ static void mldsa_decode_t1_c(const byte* t1, sword32* t) #if defined(LITTLE_ENDIAN_ORDER) && (WOLFSSL_MLDSA_ALIGNMENT == 0) #ifdef WC_64BIT_CPU word64 t64 = readUnalignedWord64(t1); - word16 t16 = *(const word16*)(t1 + 8); + word16 t16 = (word16)(t1[8] | (t1[9] << 8)); t[j+0] = (sword32)( ( t64 & 0x03ff) << MLDSA_D); t[j+1] = (sword32)( ((t64 >> 10) & 0x03ff) << MLDSA_D); t[j+2] = (sword32)( ((t64 >> 20) & 0x03ff) << MLDSA_D); @@ -1768,13 +1763,11 @@ static void mldsa_encode_gamma1_17_bits_c(const sword32* z, byte* s) * 8 numbers become 9 bytes. (8 * 9 bits = 9 * 8 bits) */ #if defined(LITTLE_ENDIAN_ORDER) && (WOLFSSL_MLDSA_ALIGNMENT == 0) #ifdef WC_64BIT_CPU - word64* s64p = (word64*)s; - writeUnalignedWord64(s64p, z0 | ((word64)z1 << 18) | + writeUnalignedWord64(s + 0, z0 | ((word64)z1 << 18) | ((word64)z2 << 36) | ((word64)z3 << 54)); #else - word32* s32p = (word32*)s; - writeUnalignedWord32(s32p+0, z0 | (z1 << 18) ); - writeUnalignedWord32(s32p+1, (z1 >> 14) | (z2 << 4) | (z3 << 22)); + writeUnalignedWord32(s + 0, z0 | (z1 << 18) ); + writeUnalignedWord32(s + 4, (z1 >> 14) | (z2 << 4) | (z3 << 22)); #endif #else s[0] = (byte)( z0 ); @@ -1836,17 +1829,15 @@ static void mldsa_encode_gamma1_19_bits_c(const sword32* z, byte* s) /* 20 bits per number. * 4 numbers become 10 bytes. (4 * 20 bits = 10 * 8 bits) */ #if defined(LITTLE_ENDIAN_ORDER) && (WOLFSSL_MLDSA_ALIGNMENT <= 2) - word16* s16p = (word16*)s; #ifdef WC_64BIT_CPU - word64* s64p = (word64*)s; - writeUnalignedWord64(s64p, (word64)z0 | ((word64)z1 << 20) | + writeUnalignedWord64(s, (word64)z0 | ((word64)z1 << 20) | ((word64)z2 << 40) | ((word64)z3 << 60)); #else - word32* s32p = (word32*)s; - s32p[0] = (word32)( z0 | (z1 << 20) ); - s32p[1] = (word32)((z1 >> 12) | (z2 << 8) | (z3 << 28)); + writeUnalignedWord32(s + 0, (word32)( z0 | (z1 << 20) )); + writeUnalignedWord32(s + 4, (word32)((z1 >> 12) | (z2 << 8) | (z3 << 28))); #endif - s16p[4] = (word16)((z3 >> 4) ); + s[8] = (byte)((z3 >> 4) ); + s[9] = (byte)((z3 >> 12) ); #else s[0] = (byte) z0 ; s[1] = (byte) (z0 >> 8) ; @@ -2085,7 +2076,7 @@ static void mldsa_decode_gamma1_c(const byte* s, int bits, sword32* z) /* 20 bits per number. * 4 numbers from 10 bytes. (4 * 20 bits = 10 * 8 bits) */ #if defined(LITTLE_ENDIAN_ORDER) && (WOLFSSL_MLDSA_ALIGNMENT <= 2) - word16 s16_0 = ((const word16*)s)[4]; + word16 s16_0 = (word16)(s[8] | (s[9] << 8)); #ifdef WC_64BIT_CPU word64 s64_0 = readUnalignedWord64(s); z[i+0] = MLDSA_GAMMA1_19 - ((sword32)( s64_0 & 0xfffff)); @@ -2126,8 +2117,8 @@ static void mldsa_decode_gamma1_c(const byte* s, int bits, sword32* z) /* 20 bits per number. * 8 numbers from 20 bytes. (8 * 20 bits = 20 * 8 bits) */ #if defined(LITTLE_ENDIAN_ORDER) && (WOLFSSL_MLDSA_ALIGNMENT <= 2) - word16 s16_0 = ((const word16*)s)[4]; - word16 s16_1 = ((const word16*)s)[9]; + word16 s16_0 = (word16)(s[ 8] | (s[ 9] << 8)); + word16 s16_1 = (word16)(s[18] | (s[19] << 8)); #ifdef WC_64BIT_CPU word64 s64_0 = readUnalignedWord64(s+0); word64 s64_1 = readUnalignedWord64(s+10); @@ -2289,25 +2280,27 @@ static void mldsa_encode_w1_88_c(const sword32* w1, byte* w1e) /* 6 bits per number. * 16 numbers in 12 bytes. (16 * 6 bits = 12 * 8 bits) */ #if defined(LITTLE_ENDIAN_ORDER) && (WOLFSSL_MLDSA_ALIGNMENT <= 4) - word32* w1e32 = (word32*)w1e; - w1e32[0] = (word32)( (word32)w1[j+ 0] | - ((word32)w1[j+ 1] << 6) | - ((word32)w1[j+ 2] << 12) | - ((word32)w1[j+ 3] << 18) | - ((word32)w1[j+ 4] << 24) | - ((word32)w1[j+ 5] << 30)); - w1e32[1] = (word32)(((word32)w1[j+ 5] >> 2) | - ((word32)w1[j+ 6] << 4) | - ((word32)w1[j+ 7] << 10) | - ((word32)w1[j+ 8] << 16) | - ((word32)w1[j+ 9] << 22) | - ((word32)w1[j+10] << 28)); - w1e32[2] = (word32)(((word32)w1[j+10] >> 4) | - ((word32)w1[j+11] << 2) | - ((word32)w1[j+12] << 8) | - ((word32)w1[j+13] << 14) | - ((word32)w1[j+14] << 20) | - ((word32)w1[j+15] << 26)); + writeUnalignedWord32(w1e + 0, + ( (word32)w1[j+ 0] | + ((word32)w1[j+ 1] << 6) | + ((word32)w1[j+ 2] << 12) | + ((word32)w1[j+ 3] << 18) | + ((word32)w1[j+ 4] << 24) | + ((word32)w1[j+ 5] << 30))); + writeUnalignedWord32(w1e + 4, + (((word32)w1[j+ 5] >> 2) | + ((word32)w1[j+ 6] << 4) | + ((word32)w1[j+ 7] << 10) | + ((word32)w1[j+ 8] << 16) | + ((word32)w1[j+ 9] << 22) | + ((word32)w1[j+10] << 28))); + writeUnalignedWord32(w1e + 8, + (((word32)w1[j+10] >> 4) | + ((word32)w1[j+11] << 2) | + ((word32)w1[j+12] << 8) | + ((word32)w1[j+13] << 14) | + ((word32)w1[j+14] << 20) | + ((word32)w1[j+15] << 26))); #else w1e[ 0] = (byte)( w1[j+ 0] | (w1[j+ 1] << 6)); w1e[ 1] = (byte)((w1[j+ 1] >> 2) | (w1[j+ 2] << 4)); @@ -2375,23 +2368,24 @@ static void mldsa_encode_w1_32_c(const sword32* w1, byte* w1e) /* 4 bits per number. * 16 numbers in 8 bytes. (16 * 4 bits = 8 * 8 bits) */ #if defined(LITTLE_ENDIAN_ORDER) && (WOLFSSL_MLDSA_ALIGNMENT <= 8) - word32* w1e32 = (word32*)w1e; - w1e32[0] = (word32)(((word32)w1[j + 0] << 0) | - ((word32)w1[j + 1] << 4) | - ((word32)w1[j + 2] << 8) | - ((word32)w1[j + 3] << 12) | - ((word32)w1[j + 4] << 16) | - ((word32)w1[j + 5] << 20) | - ((word32)w1[j + 6] << 24) | - ((word32)w1[j + 7] << 28)); - w1e32[1] = (word32)(((word32)w1[j + 8] << 0) | - ((word32)w1[j + 9] << 4) | - ((word32)w1[j + 10] << 8) | - ((word32)w1[j + 11] << 12) | - ((word32)w1[j + 12] << 16) | - ((word32)w1[j + 13] << 20) | - ((word32)w1[j + 14] << 24) | - ((word32)w1[j + 15] << 28)); + writeUnalignedWord32(w1e + 0, + (((word32)w1[j + 0] << 0) | + ((word32)w1[j + 1] << 4) | + ((word32)w1[j + 2] << 8) | + ((word32)w1[j + 3] << 12) | + ((word32)w1[j + 4] << 16) | + ((word32)w1[j + 5] << 20) | + ((word32)w1[j + 6] << 24) | + ((word32)w1[j + 7] << 28))); + writeUnalignedWord32(w1e + 4, + (((word32)w1[j + 8] << 0) | + ((word32)w1[j + 9] << 4) | + ((word32)w1[j + 10] << 8) | + ((word32)w1[j + 11] << 12) | + ((word32)w1[j + 12] << 16) | + ((word32)w1[j + 13] << 20) | + ((word32)w1[j + 14] << 24) | + ((word32)w1[j + 15] << 28))); #else w1e[0] = (byte)(w1[j + 0] | (w1[j + 1] << 4)); w1e[1] = (byte)(w1[j + 2] | (w1[j + 3] << 4)); diff --git a/wolfcrypt/src/wc_slhdsa.c b/wolfcrypt/src/wc_slhdsa.c index 4f14658644d..ba1de8591af 100644 --- a/wolfcrypt/src/wc_slhdsa.c +++ b/wolfcrypt/src/wc_slhdsa.c @@ -1810,14 +1810,14 @@ do { \ */ #define SHAKE256_SET_HASH_X4_16(state, hash) \ do { \ - (state)[24] = ((word64*)((hash) + 0 * 16))[0]; \ - (state)[25] = ((word64*)((hash) + 1 * 16))[0]; \ - (state)[26] = ((word64*)((hash) + 2 * 16))[0]; \ - (state)[27] = ((word64*)((hash) + 3 * 16))[0]; \ - (state)[28] = ((word64*)((hash) + 0 * 16))[1]; \ - (state)[29] = ((word64*)((hash) + 1 * 16))[1]; \ - (state)[30] = ((word64*)((hash) + 2 * 16))[1]; \ - (state)[31] = ((word64*)((hash) + 3 * 16))[1]; \ + (state)[24] = readUnalignedWord64((hash) + 0 * 16 + 0 * 8); \ + (state)[25] = readUnalignedWord64((hash) + 1 * 16 + 0 * 8); \ + (state)[26] = readUnalignedWord64((hash) + 2 * 16 + 0 * 8); \ + (state)[27] = readUnalignedWord64((hash) + 3 * 16 + 0 * 8); \ + (state)[28] = readUnalignedWord64((hash) + 0 * 16 + 1 * 8); \ + (state)[29] = readUnalignedWord64((hash) + 1 * 16 + 1 * 8); \ + (state)[30] = readUnalignedWord64((hash) + 2 * 16 + 1 * 8); \ + (state)[31] = readUnalignedWord64((hash) + 3 * 16 + 1 * 8); \ } while (0) /* Get the four SHAKE-256 16-byte hash results. @@ -1827,14 +1827,14 @@ do { \ */ #define SHAKE256_GET_HASH_X4_16(state, hash) \ do { \ - ((word64*)((hash) + 0 * 16))[0] = (state)[0]; \ - ((word64*)((hash) + 1 * 16))[0] = (state)[1]; \ - ((word64*)((hash) + 2 * 16))[0] = (state)[2]; \ - ((word64*)((hash) + 3 * 16))[0] = (state)[3]; \ - ((word64*)((hash) + 0 * 16))[1] = (state)[4]; \ - ((word64*)((hash) + 1 * 16))[1] = (state)[5]; \ - ((word64*)((hash) + 2 * 16))[1] = (state)[6]; \ - ((word64*)((hash) + 3 * 16))[1] = (state)[7]; \ + writeUnalignedWord64((hash) + 0 * 16 + 0 * 8, (state)[0]); \ + writeUnalignedWord64((hash) + 1 * 16 + 0 * 8, (state)[1]); \ + writeUnalignedWord64((hash) + 2 * 16 + 0 * 8, (state)[2]); \ + writeUnalignedWord64((hash) + 3 * 16 + 0 * 8, (state)[3]); \ + writeUnalignedWord64((hash) + 0 * 16 + 1 * 8, (state)[4]); \ + writeUnalignedWord64((hash) + 1 * 16 + 1 * 8, (state)[5]); \ + writeUnalignedWord64((hash) + 2 * 16 + 1 * 8, (state)[6]); \ + writeUnalignedWord64((hash) + 3 * 16 + 1 * 8, (state)[7]); \ } while (0) #endif @@ -1871,18 +1871,18 @@ do { \ */ #define SHAKE256_SET_HASH_X4_24(state, hash) \ do { \ - (state)[28] = ((word64*)((hash) + 0 * 24))[0]; \ - (state)[29] = ((word64*)((hash) + 1 * 24))[0]; \ - (state)[30] = ((word64*)((hash) + 2 * 24))[0]; \ - (state)[31] = ((word64*)((hash) + 3 * 24))[0]; \ - (state)[32] = ((word64*)((hash) + 0 * 24))[1]; \ - (state)[33] = ((word64*)((hash) + 1 * 24))[1]; \ - (state)[34] = ((word64*)((hash) + 2 * 24))[1]; \ - (state)[35] = ((word64*)((hash) + 3 * 24))[1]; \ - (state)[36] = ((word64*)((hash) + 0 * 24))[2]; \ - (state)[37] = ((word64*)((hash) + 1 * 24))[2]; \ - (state)[38] = ((word64*)((hash) + 2 * 24))[2]; \ - (state)[39] = ((word64*)((hash) + 3 * 24))[2]; \ + (state)[28] = readUnalignedWord64((hash) + 0 * 24 + 0 * 8); \ + (state)[29] = readUnalignedWord64((hash) + 1 * 24 + 0 * 8); \ + (state)[30] = readUnalignedWord64((hash) + 2 * 24 + 0 * 8); \ + (state)[31] = readUnalignedWord64((hash) + 3 * 24 + 0 * 8); \ + (state)[32] = readUnalignedWord64((hash) + 0 * 24 + 1 * 8); \ + (state)[33] = readUnalignedWord64((hash) + 1 * 24 + 1 * 8); \ + (state)[34] = readUnalignedWord64((hash) + 2 * 24 + 1 * 8); \ + (state)[35] = readUnalignedWord64((hash) + 3 * 24 + 1 * 8); \ + (state)[36] = readUnalignedWord64((hash) + 0 * 24 + 2 * 8); \ + (state)[37] = readUnalignedWord64((hash) + 1 * 24 + 2 * 8); \ + (state)[38] = readUnalignedWord64((hash) + 2 * 24 + 2 * 8); \ + (state)[39] = readUnalignedWord64((hash) + 3 * 24 + 2 * 8); \ } while (0) /* Get the four SHAKE-256 24-byte (hash) results. @@ -1892,18 +1892,18 @@ do { \ */ #define SHAKE256_GET_HASH_X4_24(state, hash) \ do { \ - ((word64*)((hash) + 0 * 24))[0] = (state)[ 0]; \ - ((word64*)((hash) + 1 * 24))[0] = (state)[ 1]; \ - ((word64*)((hash) + 2 * 24))[0] = (state)[ 2]; \ - ((word64*)((hash) + 3 * 24))[0] = (state)[ 3]; \ - ((word64*)((hash) + 0 * 24))[1] = (state)[ 4]; \ - ((word64*)((hash) + 1 * 24))[1] = (state)[ 5]; \ - ((word64*)((hash) + 2 * 24))[1] = (state)[ 6]; \ - ((word64*)((hash) + 3 * 24))[1] = (state)[ 7]; \ - ((word64*)((hash) + 0 * 24))[2] = (state)[ 8]; \ - ((word64*)((hash) + 1 * 24))[2] = (state)[ 9]; \ - ((word64*)((hash) + 2 * 24))[2] = (state)[10]; \ - ((word64*)((hash) + 3 * 24))[2] = (state)[11]; \ + writeUnalignedWord64((hash) + 0 * 24 + 0 * 8, (state)[ 0]); \ + writeUnalignedWord64((hash) + 1 * 24 + 0 * 8, (state)[ 1]); \ + writeUnalignedWord64((hash) + 2 * 24 + 0 * 8, (state)[ 2]); \ + writeUnalignedWord64((hash) + 3 * 24 + 0 * 8, (state)[ 3]); \ + writeUnalignedWord64((hash) + 0 * 24 + 1 * 8, (state)[ 4]); \ + writeUnalignedWord64((hash) + 1 * 24 + 1 * 8, (state)[ 5]); \ + writeUnalignedWord64((hash) + 2 * 24 + 1 * 8, (state)[ 6]); \ + writeUnalignedWord64((hash) + 3 * 24 + 1 * 8, (state)[ 7]); \ + writeUnalignedWord64((hash) + 0 * 24 + 2 * 8, (state)[ 8]); \ + writeUnalignedWord64((hash) + 1 * 24 + 2 * 8, (state)[ 9]); \ + writeUnalignedWord64((hash) + 2 * 24 + 2 * 8, (state)[10]); \ + writeUnalignedWord64((hash) + 3 * 24 + 2 * 8, (state)[11]); \ } while (0) #endif @@ -1942,22 +1942,22 @@ do { \ */ #define SHAKE256_SET_HASH_X4_32(state, hash) \ do { \ - (state)[32] = ((word64*)((hash) + 0 * 32))[0]; \ - (state)[33] = ((word64*)((hash) + 1 * 32))[0]; \ - (state)[34] = ((word64*)((hash) + 2 * 32))[0]; \ - (state)[35] = ((word64*)((hash) + 3 * 32))[0]; \ - (state)[36] = ((word64*)((hash) + 0 * 32))[1]; \ - (state)[37] = ((word64*)((hash) + 1 * 32))[1]; \ - (state)[38] = ((word64*)((hash) + 2 * 32))[1]; \ - (state)[39] = ((word64*)((hash) + 3 * 32))[1]; \ - (state)[40] = ((word64*)((hash) + 0 * 32))[2]; \ - (state)[41] = ((word64*)((hash) + 1 * 32))[2]; \ - (state)[42] = ((word64*)((hash) + 2 * 32))[2]; \ - (state)[43] = ((word64*)((hash) + 3 * 32))[2]; \ - (state)[44] = ((word64*)((hash) + 0 * 32))[3]; \ - (state)[45] = ((word64*)((hash) + 1 * 32))[3]; \ - (state)[46] = ((word64*)((hash) + 2 * 32))[3]; \ - (state)[47] = ((word64*)((hash) + 3 * 32))[3]; \ + (state)[32] = readUnalignedWord64((hash) + 0 * 32 + 0 * 8); \ + (state)[33] = readUnalignedWord64((hash) + 1 * 32 + 0 * 8); \ + (state)[34] = readUnalignedWord64((hash) + 2 * 32 + 0 * 8); \ + (state)[35] = readUnalignedWord64((hash) + 3 * 32 + 0 * 8); \ + (state)[36] = readUnalignedWord64((hash) + 0 * 32 + 1 * 8); \ + (state)[37] = readUnalignedWord64((hash) + 1 * 32 + 1 * 8); \ + (state)[38] = readUnalignedWord64((hash) + 2 * 32 + 1 * 8); \ + (state)[39] = readUnalignedWord64((hash) + 3 * 32 + 1 * 8); \ + (state)[40] = readUnalignedWord64((hash) + 0 * 32 + 2 * 8); \ + (state)[41] = readUnalignedWord64((hash) + 1 * 32 + 2 * 8); \ + (state)[42] = readUnalignedWord64((hash) + 2 * 32 + 2 * 8); \ + (state)[43] = readUnalignedWord64((hash) + 3 * 32 + 2 * 8); \ + (state)[44] = readUnalignedWord64((hash) + 0 * 32 + 3 * 8); \ + (state)[45] = readUnalignedWord64((hash) + 1 * 32 + 3 * 8); \ + (state)[46] = readUnalignedWord64((hash) + 2 * 32 + 3 * 8); \ + (state)[47] = readUnalignedWord64((hash) + 3 * 32 + 3 * 8); \ } while (0) /* Get the four SHAKE-256 32-byte hash results. @@ -1967,22 +1967,22 @@ do { \ */ #define SHAKE256_GET_HASH_X4_32(state, hash) \ do { \ - ((word64*)((hash) + 0 * 32))[0] = (state)[ 0]; \ - ((word64*)((hash) + 1 * 32))[0] = (state)[ 1]; \ - ((word64*)((hash) + 2 * 32))[0] = (state)[ 2]; \ - ((word64*)((hash) + 3 * 32))[0] = (state)[ 3]; \ - ((word64*)((hash) + 0 * 32))[1] = (state)[ 4]; \ - ((word64*)((hash) + 1 * 32))[1] = (state)[ 5]; \ - ((word64*)((hash) + 2 * 32))[1] = (state)[ 6]; \ - ((word64*)((hash) + 3 * 32))[1] = (state)[ 7]; \ - ((word64*)((hash) + 0 * 32))[2] = (state)[ 8]; \ - ((word64*)((hash) + 1 * 32))[2] = (state)[ 9]; \ - ((word64*)((hash) + 2 * 32))[2] = (state)[10]; \ - ((word64*)((hash) + 3 * 32))[2] = (state)[11]; \ - ((word64*)((hash) + 0 * 32))[3] = (state)[12]; \ - ((word64*)((hash) + 1 * 32))[3] = (state)[13]; \ - ((word64*)((hash) + 2 * 32))[3] = (state)[14]; \ - ((word64*)((hash) + 3 * 32))[3] = (state)[15]; \ + writeUnalignedWord64((hash) + 0 * 32 + 0 * 8, (state)[ 0]); \ + writeUnalignedWord64((hash) + 1 * 32 + 0 * 8, (state)[ 1]); \ + writeUnalignedWord64((hash) + 2 * 32 + 0 * 8, (state)[ 2]); \ + writeUnalignedWord64((hash) + 3 * 32 + 0 * 8, (state)[ 3]); \ + writeUnalignedWord64((hash) + 0 * 32 + 1 * 8, (state)[ 4]); \ + writeUnalignedWord64((hash) + 1 * 32 + 1 * 8, (state)[ 5]); \ + writeUnalignedWord64((hash) + 2 * 32 + 1 * 8, (state)[ 6]); \ + writeUnalignedWord64((hash) + 3 * 32 + 1 * 8, (state)[ 7]); \ + writeUnalignedWord64((hash) + 0 * 32 + 2 * 8, (state)[ 8]); \ + writeUnalignedWord64((hash) + 1 * 32 + 2 * 8, (state)[ 9]); \ + writeUnalignedWord64((hash) + 2 * 32 + 2 * 8, (state)[10]); \ + writeUnalignedWord64((hash) + 3 * 32 + 2 * 8, (state)[11]); \ + writeUnalignedWord64((hash) + 0 * 32 + 3 * 8, (state)[12]); \ + writeUnalignedWord64((hash) + 1 * 32 + 3 * 8, (state)[13]); \ + writeUnalignedWord64((hash) + 2 * 32 + 3 * 8, (state)[14]); \ + writeUnalignedWord64((hash) + 3 * 32 + 3 * 8, (state)[15]); \ } while (0) #endif @@ -2079,10 +2079,10 @@ static void slhdsakey_shake256_get_hash_x4(const word64* state, byte* hash, int i; for (i = 0; i < (n / 8); i++) { - ((word64*)(hash + 0 * n))[i] = state[4 * i + 0]; - ((word64*)(hash + 1 * n))[i] = state[4 * i + 1]; - ((word64*)(hash + 2 * n))[i] = state[4 * i + 2]; - ((word64*)(hash + 3 * n))[i] = state[4 * i + 3]; + writeUnalignedWord64(hash + 0 * n + i * 8, state[4 * i + 0]); + writeUnalignedWord64(hash + 1 * n + i * 8, state[4 * i + 1]); + writeUnalignedWord64(hash + 2 * n + i * 8, state[4 * i + 2]); + writeUnalignedWord64(hash + 3 * n + i * 8, state[4 * i + 3]); } } @@ -5148,10 +5148,10 @@ static int slhdsakey_hash_f_ti_x4(const byte* pk_seed, byte* addr, byte* node, o = slhdsakey_shake256_set_seed_ha_x4(state, pk_seed, addr, n); SHAKE256_SET_TREE_INDEX(state, o, ti); for (i = 0; i < n / 8; i++) { - state[o + 0] = ((word64*)(node + 0 * n))[i]; - state[o + 1] = ((word64*)(node + 1 * n))[i]; - state[o + 2] = ((word64*)(node + 2 * n))[i]; - state[o + 3] = ((word64*)(node + 3 * n))[i]; + state[o + 0] = readUnalignedWord64(node + 0 * n + i * 8); + state[o + 1] = readUnalignedWord64(node + 1 * n + i * 8); + state[o + 2] = readUnalignedWord64(node + 2 * n + i * 8); + state[o + 3] = readUnalignedWord64(node + 3 * n + i * 8); o += 4; } SHAKE256_SET_END_X4(state, o); @@ -5205,10 +5205,10 @@ static int slhdsakey_hash_h_ti_x4(const byte* pk_seed, byte* addr, o = slhdsakey_shake256_set_seed_ha_x4(state, pk_seed, addr, n); SHAKE256_SET_TREE_INDEX(state, o, ti); for (i = 0; i < 2 * n / 8; i++) { - state[o + 0] = ((const word64*)(m + 0 * n))[i]; - state[o + 1] = ((const word64*)(m + 2 * n))[i]; - state[o + 2] = ((const word64*)(m + 4 * n))[i]; - state[o + 3] = ((const word64*)(m + 6 * n))[i]; + state[o + 0] = readUnalignedWord64(m + 0 * n + i * 8); + state[o + 1] = readUnalignedWord64(m + 2 * n + i * 8); + state[o + 2] = readUnalignedWord64(m + 4 * n + i * 8); + state[o + 3] = readUnalignedWord64(m + 6 * n + i * 8); o += 4; } SHAKE256_SET_END_X4(state, o); @@ -6002,10 +6002,10 @@ static int slhdsakey_hash_f_ti4_x4(const byte* pk_seed, byte* addr, o = slhdsakey_shake256_set_seed_ha_x4(state, pk_seed, addr, n); SHAKE256_SET_TREE_INDEX_IDX(state, o, ti); for (i = 0; i < n / 8; i++) { - state[o + 0] = ((const word64*)(sig_fors + 0 * so * n))[i]; - state[o + 1] = ((const word64*)(sig_fors + 1 * so * n))[i]; - state[o + 2] = ((const word64*)(sig_fors + 2 * so * n))[i]; - state[o + 3] = ((const word64*)(sig_fors + 3 * so * n))[i]; + state[o + 0] = readUnalignedWord64(sig_fors + 0 * so * n + i * 8); + state[o + 1] = readUnalignedWord64(sig_fors + 1 * so * n + i * 8); + state[o + 2] = readUnalignedWord64(sig_fors + 2 * so * n + i * 8); + state[o + 3] = readUnalignedWord64(sig_fors + 3 * so * n + i * 8); o += 4; } SHAKE256_SET_END_X4(state, o); @@ -6067,11 +6067,12 @@ static int slhdsakey_hash_h_2_x4(const byte* pk_seed, byte* addr, byte* node, for (i = 0; i < n / 8; i++) { for (j = 0; j < 4; j++) { if (bit[j] == 0) { - state[o + j] = ((const word64*)(node + j * n))[i]; + state[o + j] = readUnalignedWord64(node + j * n + i * 8); } else { state[o + j] = - ((const word64*)(sig_fors + j * (word32)so * n))[i]; + readUnalignedWord64(sig_fors + j * + (word32)so * n + i * 8); } } o += 4; @@ -6080,10 +6081,11 @@ static int slhdsakey_hash_h_2_x4(const byte* pk_seed, byte* addr, byte* node, for (j = 0; j < 4; j++) { if (bit[j] == 0) { state[o + j] = - ((const word64*)(sig_fors + j * (word32)so * n))[i]; + readUnalignedWord64(sig_fors + j * + (word32)so * n + i * 8); } else { - state[o + j] = ((const word64*)(node + j * n))[i]; + state[o + j] = readUnalignedWord64(node + j * n + i * 8); } } o += 4; diff --git a/wolfcrypt/src/wc_xmss_impl.c b/wolfcrypt/src/wc_xmss_impl.c index d1598c4d372..7d320ae04f2 100644 --- a/wolfcrypt/src/wc_xmss_impl.c +++ b/wolfcrypt/src/wc_xmss_impl.c @@ -476,29 +476,24 @@ do { \ #define XMSS_ADDR_TREE_SET_SUBTREE(a, s) \ XMSS_ADDR_SET_SUBTREE(a, s, WC_XMSS_ADDR_TYPE_TREE) -#ifdef LITTLE_ENDIAN_ORDER - /* Set a byte value into a word of an encoded address. * - * @param [in, out] a Encoded hash address. - * @param [in] i Index of word. - * @param [in] b Byte to set. - */ -#define XMSS_ADDR_SET_BYTE(a, i, b) \ - ((word32*)(a))[i] = (word32)(b) << 24 - -#else - -/* Set a byte value into a word of an encoded address. + * The address is a byte array whose alignment is not guaranteed, so encode the + * word value with byte-wise stores rather than casting to word32* (which can be + * an unaligned access and violates strict aliasing). The word is stored in + * network byte order, so the value occupies the least significant (last) byte. * * @param [in, out] a Encoded hash address. * @param [in] i Index of word. * @param [in] b Byte to set. */ -#define XMSS_ADDR_SET_BYTE(a, i, b) \ - ((word32*)(a))[i] = (b) - -#endif /* LITTLE_ENDIAN_ORDER */ +#define XMSS_ADDR_SET_BYTE(a, i, b) \ + do { \ + (a)[(i) * 4 + 0] = 0; \ + (a)[(i) * 4 + 1] = 0; \ + (a)[(i) * 4 + 2] = 0; \ + (a)[(i) * 4 + 3] = (byte)(b); \ + } while (0) /* Convert hash address to bytes. * @@ -700,7 +695,7 @@ static void wc_xmss_chain_hash_sha256_32(XmssState* state, const byte* tmp, int ret; /* Calculate n-byte key - KEY. */ - ((word32*)addr)[XMSS_ADDR_KEY_MASK] = 0; + XMSS_ADDR_SET_BYTE(addr, XMSS_ADDR_KEY_MASK, 0); /* Copy back state after first 64 bytes. */ XMSS_SHA256_STATE_RESTORE_DATA(state, addr, WC_XMSS_ADDR_LEN, XMSS_HASH_PRF_DATA_LEN_SHA256_32); @@ -760,7 +755,7 @@ static void wc_xmss_chain_hash_sha256_32(XmssState* state, const byte* tmp, byte* bm = key + XMSS_SHA256_32_N; /* Calculate n-byte key - KEY. */ - ((word32*)addr)[XMSS_ADDR_KEY_MASK] = 0; + XMSS_ADDR_SET_BYTE(addr, XMSS_ADDR_KEY_MASK, 0); wc_xmss_hash(state, state->prf_buf, XMSS_HASH_PRF_DATA_LEN_SHA256_32, key); /* Calculate the n-byte mask. */ addr[XMSS_ADDR_KEY_MASK * 4 + 3] = 1; @@ -801,7 +796,7 @@ static void wc_xmss_chain_hash(XmssState* state, const byte* tmp, byte* hash) byte* bm = key + params->n; /* Calculate n-byte key - KEY. */ - ((word32*)addr)[XMSS_ADDR_KEY_MASK] = 0; + XMSS_ADDR_SET_BYTE(addr, XMSS_ADDR_KEY_MASK, 0); wc_xmss_hash(state, state->prf_buf, XMSS_HASH_PRF_DATA_LEN(params), key); /* Calculate n-byte bit mask - BM. */ addr[XMSS_ADDR_KEY_MASK * 4 + 3] = 1; @@ -1450,9 +1445,9 @@ static void wc_xmss_wots_get_wots_sk_sha256_32(XmssState* state, byte* addr_buf = seed + XMSS_SHA256_32_N; int ret; - ((word32*)addr)[XMSS_ADDR_CHAIN] = 0; - ((word32*)addr)[XMSS_ADDR_HASH] = 0; - ((word32*)addr)[XMSS_ADDR_KEY_MASK] = 0; + XMSS_ADDR_SET_BYTE(addr, XMSS_ADDR_CHAIN, 0); + XMSS_ADDR_SET_BYTE(addr, XMSS_ADDR_HASH, 0); + XMSS_ADDR_SET_BYTE(addr, XMSS_ADDR_KEY_MASK, 0); XMSS_PAD_ENC(XMSS_HASH_PADDING_PRF_KEYGEN, pad, XMSS_SHA256_32_PAD_LEN); XMEMCPY(s_xmss, sk_seed, XMSS_SHA256_32_N); @@ -1541,9 +1536,9 @@ static void wc_xmss_wots_get_wots_sk(XmssState* state, const byte* sk_seed, #endif /* XMSS_CALL_PRF_KEYGEN */ /* Ensure hash address fields are 0. */ - ((word32*)addr)[XMSS_ADDR_CHAIN] = 0; - ((word32*)addr)[XMSS_ADDR_HASH] = 0; - ((word32*)addr)[XMSS_ADDR_KEY_MASK] = 0; + XMSS_ADDR_SET_BYTE(addr, XMSS_ADDR_CHAIN, 0); + XMSS_ADDR_SET_BYTE(addr, XMSS_ADDR_HASH, 0); + XMSS_ADDR_SET_BYTE(addr, XMSS_ADDR_KEY_MASK, 0); #ifdef XMSS_CALL_PRF_KEYGEN /* Copy the seed and address into PRF keygen message buffer. */