Skip to content

Commit 60c2499

Browse files
committed
wolfssl/wolfcrypt/types.h: when defining fallback do-nothing SAVE_VECTOR_REGISTERS2(), also define SAVE_VECTOR_REGISTERS2_DOES_NOTHING, and likewise for fallback CAN_SAVE_VECTOR_REGISTERS, define CAN_SAVE_VECTOR_REGISTERS_ALWAYS_TRUE;
wolfcrypt/src/aes.c: * when SAVE_VECTOR_REGISTERS2_DOES_NOTHING, define do-nothing VECTOR_REGISTERS_PUSH and VECTOR_REGISTERS_POP, to mollify Coverity CONSTANT_EXPRESSION_RESULT; * in AesGcmDecryptUpdate_aesni(), omit " && (c != NULL)" clause from computation of endA argument to AesGcmAadUpdate_aesni(), to mollify Coverity FORWARD_NULL (impermissible nullness is already checked and BAD_FUNC_ARGed by the sole caller, wc_AesGcmDecryptUpdate()); wolfcrypt/src/misc.c: add readUnalignedWord64(), writeUnalignedWord64(), readUnalignedWords64(), and writeUnalignedWords64(), for safe word64 access to possibly-unaligned data; wolfcrypt/src/wc_kyber_poly.c: use readUnalignedWords64() and readUnalignedWord64() to mitigate sanitizer-reported "load of misaligned address".
1 parent b96e73f commit 60c2499

5 files changed

Lines changed: 107 additions & 50 deletions

File tree

wolfcrypt/src/aes.c

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4759,7 +4759,7 @@ int wc_AesSetIV(Aes* aes, const byte* iv)
47594759

47604760
#ifdef WC_C_DYNAMIC_FALLBACK
47614761

4762-
#define VECTOR_REGISTERS_PUSH { \
4762+
#define VECTOR_REGISTERS_PUSH { \
47634763
int orig_use_aesni = aes->use_aesni; \
47644764
if (aes->use_aesni && (SAVE_VECTOR_REGISTERS2() != 0)) { \
47654765
aes->use_aesni = 0; \
@@ -4774,6 +4774,15 @@ int wc_AesSetIV(Aes* aes, const byte* iv)
47744774
} \
47754775
WC_DO_NOTHING
47764776

4777+
#elif defined(SAVE_VECTOR_REGISTERS2_DOES_NOTHING)
4778+
4779+
#define VECTOR_REGISTERS_PUSH { \
4780+
WC_DO_NOTHING
4781+
4782+
#define VECTOR_REGISTERS_POP \
4783+
} \
4784+
WC_DO_NOTHING
4785+
47774786
#else
47784787

47794788
#define VECTOR_REGISTERS_PUSH { \
@@ -9796,7 +9805,7 @@ static WARN_UNUSED_RESULT int AesGcmDecryptUpdate_aesni(
97969805
ASSERT_SAVED_VECTOR_REGISTERS();
97979806

97989807
/* Hash in A, the Authentication Data */
9799-
ret = AesGcmAadUpdate_aesni(aes, a, aSz, (cSz > 0) && (c != NULL));
9808+
ret = AesGcmAadUpdate_aesni(aes, a, aSz, cSz > 0);
98009809
if (ret != 0)
98019810
return ret;
98029811

wolfcrypt/src/misc.c

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -211,6 +211,52 @@ WC_MISC_STATIC WC_INLINE void ByteReverseWords(word32* out, const word32* in,
211211

212212
#if defined(WORD64_AVAILABLE) && !defined(WOLFSSL_NO_WORD64_OPS)
213213

214+
WC_MISC_STATIC WC_INLINE word64 readUnalignedWord64(const byte *in)
215+
{
216+
if (((wc_ptr_t)in & (wc_ptr_t)(sizeof(word64) - 1U)) == (wc_ptr_t)0)
217+
return *(word64 *)in;
218+
else {
219+
word64 out;
220+
XMEMCPY(&out, in, sizeof(word64));
221+
return out;
222+
}
223+
}
224+
225+
WC_MISC_STATIC WC_INLINE word64 writeUnalignedWord64(void *out, word64 in)
226+
{
227+
if (((wc_ptr_t)out & (wc_ptr_t)(sizeof(word64) - 1U)) == (wc_ptr_t)0)
228+
*(word64 *)out = in;
229+
else {
230+
XMEMCPY(out, &in, sizeof(word64));
231+
}
232+
return in;
233+
}
234+
235+
WC_MISC_STATIC WC_INLINE void readUnalignedWords64(word64 *out, const byte *in,
236+
size_t count)
237+
{
238+
if (((wc_ptr_t)in & (wc_ptr_t)(sizeof(word64) - 1U)) == (wc_ptr_t)0) {
239+
const word64 *in_word64 = (const word64 *)in;
240+
while (count-- > 0)
241+
*out++ = *in_word64++;
242+
}
243+
else {
244+
XMEMCPY(out, in, count * sizeof(word64));
245+
}
246+
}
247+
248+
WC_MISC_STATIC WC_INLINE void writeUnalignedWords64(byte *out, const word64 *in,
249+
size_t count)
250+
{
251+
if (((wc_ptr_t)out & (wc_ptr_t)(sizeof(word64) - 1U)) == (wc_ptr_t)0) {
252+
word64 *out_word64 = (word64 *)out;
253+
while (count-- > 0)
254+
*out_word64++ = *in++;
255+
}
256+
else {
257+
XMEMCPY(out, in, count * sizeof(word64));
258+
}
259+
}
214260

215261
WC_MISC_STATIC WC_INLINE word64 rotlFixed64(word64 x, word64 y)
216262
{

wolfcrypt/src/wc_kyber_poly.c

Lines changed: 40 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,13 @@
6767

6868
#ifdef WOLFSSL_WC_KYBER
6969

70+
#ifdef NO_INLINE
71+
#include <wolfssl/wolfcrypt/misc.h>
72+
#else
73+
#define WOLFSSL_MISC_INCLUDED
74+
#include <wolfcrypt/src/misc.c>
75+
#endif
76+
7077
/* Declared in wc_kyber.c to stop compiler optimizer from simplifying. */
7178
extern volatile sword16 kyber_opt_blocker;
7279

@@ -1560,14 +1567,11 @@ static int kyber_gen_matrix_k3_avx2(sword16* a, byte* seed, int transposed)
15601567
a += 4 * KYBER_N;
15611568
}
15621569

1563-
state[0] = ((word64*)seed)[0];
1564-
state[1] = ((word64*)seed)[1];
1565-
state[2] = ((word64*)seed)[2];
1566-
state[3] = ((word64*)seed)[3];
1570+
readUnalignedWords64(state, seed, 4);
15671571
/* Transposed value same as not. */
15681572
state[4] = 0x1f0000 + (2 << 8) + 2;
15691573
XMEMSET(state + 5, 0, sizeof(*state) * (25 - 5));
1570-
state[20] = 0x8000000000000000UL;
1574+
state[20] = W64LIT(0x8000000000000000);
15711575
for (i = 0; i < GEN_MATRIX_SIZE; i += SHA3_128_BYTES) {
15721576
if (IS_INTEL_BMI2(cpuid_flags)) {
15731577
sha3_block_bmi2(state);
@@ -1748,14 +1752,11 @@ static int kyber_gen_matrix_k2_aarch64(sword16* a, byte* seed, int transposed)
17481752

17491753
a += 3 * KYBER_N;
17501754

1751-
state[0] = ((word64*)seed)[0];
1752-
state[1] = ((word64*)seed)[1];
1753-
state[2] = ((word64*)seed)[2];
1754-
state[3] = ((word64*)seed)[3];
1755+
readUnalignedWords64(state, seed, 4);
17551756
/* Transposed value same as not. */
17561757
state[4] = 0x1f0000 + (1 << 8) + 1;
17571758
XMEMSET(state + 5, 0, sizeof(*state) * (25 - 5));
1758-
state[20] = 0x8000000000000000UL;
1759+
state[20] = W64LIT(0x8000000000000000);
17591760
BlockSha3(state);
17601761
p = (byte*)state;
17611762
ctr0 = kyber_rej_uniform_neon(a, KYBER_N, p, XOF_BLOCK_SIZE);
@@ -1899,14 +1900,11 @@ static int kyber_gen_matrix_k4_aarch64(sword16* a, byte* seed, int transposed)
18991900
a += 3 * KYBER_N;
19001901
}
19011902

1902-
state[0] = ((word64*)seed)[0];
1903-
state[1] = ((word64*)seed)[1];
1904-
state[2] = ((word64*)seed)[2];
1905-
state[3] = ((word64*)seed)[3];
1903+
readUnalignedWords64(state, seed, 4);
19061904
/* Transposed value same as not. */
19071905
state[4] = 0x1f0000 + (3 << 8) + 3;
19081906
XMEMSET(state + 5, 0, sizeof(*state) * (25 - 5));
1909-
state[20] = 0x8000000000000000UL;
1907+
state[20] = W64LIT(0x8000000000000000);
19101908
BlockSha3(state);
19111909
p = (byte*)state;
19121910
ctr0 = kyber_rej_uniform_neon(a, KYBER_N, p, XOF_BLOCK_SIZE);
@@ -2047,18 +2045,15 @@ static int kyber_prf(wc_Shake* shake256, byte* out, unsigned int outLen,
20472045
const byte* key)
20482046
{
20492047
#ifdef USE_INTEL_SPEEDUP
2050-
int i;
20512048
word64 state[25];
20522049

20532050
(void)shake256;
20542051

2055-
for (i = 0; i < KYBER_SYM_SZ / 8; i++) {
2056-
state[i] = ((word64*)key)[i];
2057-
}
2052+
readUnalignedWords64(state, key, KYBER_SYM_SZ / sizeof(word64));
20582053
state[KYBER_SYM_SZ / 8] = 0x1f00 | key[KYBER_SYM_SZ];
20592054
XMEMSET(state + KYBER_SYM_SZ / 8 + 1, 0,
20602055
(25 - KYBER_SYM_SZ / 8 - 1) * sizeof(word64));
2061-
state[WC_SHA3_256_COUNT - 1] = 0x8000000000000000UL;
2056+
state[WC_SHA3_256_COUNT - 1] = W64LIT(0x8000000000000000);
20622057

20632058
if (IS_INTEL_BMI2(cpuid_flags)) {
20642059
sha3_block_bmi2(state);
@@ -2098,15 +2093,12 @@ static int kyber_prf(wc_Shake* shake256, byte* out, unsigned int outLen,
20982093
int kyber_kdf(byte* seed, int seedLen, byte* out, int outLen)
20992094
{
21002095
word64 state[25];
2101-
int i;
2102-
int len64 = seedLen / 8;
2096+
word32 len64 = seedLen / 8;
21032097

2104-
for (i = 0; i < len64; i++) {
2105-
state[i] = ((word64*)seed)[i];
2106-
}
2098+
readUnalignedWords64(state, seed, len64);
21072099
state[len64] = 0x1f;
21082100
XMEMSET(state + len64 + 1, 0, (25 - len64 - 1) * sizeof(word64));
2109-
state[WC_SHA3_256_COUNT - 1] = 0x8000000000000000UL;
2101+
state[WC_SHA3_256_COUNT - 1] = W64LIT(0x8000000000000000);
21102102

21112103
if (IS_INTEL_BMI2(cpuid_flags)) {
21122104
sha3_block_bmi2(state);
@@ -2136,15 +2128,12 @@ int kyber_kdf(byte* seed, int seedLen, byte* out, int outLen)
21362128
int kyber_kdf(byte* seed, int seedLen, byte* out, int outLen)
21372129
{
21382130
word64 state[25];
2139-
int i;
2140-
int len64 = seedLen / 8;
2131+
word32 len64 = seedLen / 8;
21412132

2142-
for (i = 0; i < len64; i++) {
2143-
state[i] = ((word64*)seed)[i];
2144-
}
2133+
readUnalignedWords64(state, seed, len64);
21452134
state[len64] = 0x1f;
21462135
XMEMSET(state + len64 + 1, 0, (25 - len64 - 1) * sizeof(word64));
2147-
state[WC_SHA3_256_COUNT - 1] = 0x8000000000000000UL;
2136+
state[WC_SHA3_256_COUNT - 1] = W64LIT(0x8000000000000000);
21482137

21492138
BlockSha3(state);
21502139
XMEMCPY(out, state, outLen);
@@ -2199,10 +2188,11 @@ static unsigned int kyber_rej_uniform_c(sword16* p, unsigned int len,
21992188
i = 0;
22002189
for (j = 0; j < minJ; j += 6) {
22012190
/* Use 48 bits (6 bytes) as four 12-bit integers. */
2202-
sword16 v0 = (*(word64*)r) & 0xfff;
2203-
sword16 v1 = ((*(word64*)r) >> 12) & 0xfff;
2204-
sword16 v2 = ((*(word64*)r) >> 24) & 0xfff;
2205-
sword16 v3 = ((*(word64*)r) >> 36) & 0xfff;
2191+
word64 r_word = readUnalignedWord64(r);
2192+
sword16 v0 = r_word & 0xfff;
2193+
sword16 v1 = (r_word >> 12) & 0xfff;
2194+
sword16 v2 = (r_word >> 24) & 0xfff;
2195+
sword16 v3 = (r_word >> 36) & 0xfff;
22062196

22072197
p[i] = v0 & (0 - (v0 < KYBER_Q));
22082198
i += v0 < KYBER_Q;
@@ -2219,10 +2209,11 @@ static unsigned int kyber_rej_uniform_c(sword16* p, unsigned int len,
22192209
if (j < rLen) {
22202210
for (; (i + 4 < len) && (j < rLen); j += 6) {
22212211
/* Use 48 bits (6 bytes) as four 12-bit integers. */
2222-
sword16 v0 = (*(word64*)r) & 0xfff;
2223-
sword16 v1 = ((*(word64*)r) >> 12) & 0xfff;
2224-
sword16 v2 = ((*(word64*)r) >> 24) & 0xfff;
2225-
sword16 v3 = ((*(word64*)r) >> 36) & 0xfff;
2212+
word64 r_word = readUnalignedWord64(r);
2213+
sword16 v0 = r_word & 0xfff;
2214+
sword16 v1 = (r_word >> 12) & 0xfff;
2215+
sword16 v2 = (r_word >> 24) & 0xfff;
2216+
sword16 v3 = (r_word >> 36) & 0xfff;
22262217

22272218
p[i] = v0;
22282219
i += v0 < KYBER_Q;
@@ -2238,10 +2229,11 @@ static unsigned int kyber_rej_uniform_c(sword16* p, unsigned int len,
22382229
}
22392230
for (; (i < len) && (j < rLen); j += 6) {
22402231
/* Use 48 bits (6 bytes) as four 12-bit integers. */
2241-
sword16 v0 = (*(word64*)r) & 0xfff;
2242-
sword16 v1 = ((*(word64*)r) >> 12) & 0xfff;
2243-
sword16 v2 = ((*(word64*)r) >> 24) & 0xfff;
2244-
sword16 v3 = ((*(word64*)r) >> 36) & 0xfff;
2232+
word64 r_word = readUnalignedWord64(r);
2233+
sword16 v0 = r_word & 0xfff;
2234+
sword16 v1 = (r_word >> 12) & 0xfff;
2235+
sword16 v2 = (r_word >> 24) & 0xfff;
2236+
sword16 v3 = (r_word >> 36) & 0xfff;
22452237

22462238
/* Reject first 12-bit integer if greater than or equal to q. */
22472239
if (v0 < KYBER_Q) {
@@ -2511,9 +2503,9 @@ static void kyber_cbd_eta2(sword16* p, const byte* r)
25112503
#endif
25122504
/* Take the next 8 bytes, little endian, as a 64 bit value. */
25132505
#ifdef BIG_ENDIAN_ORDER
2514-
word64 t = ByteReverseWord64(*(word64*)r);
2506+
word64 t = ByteReverseWord64(readUnalignedWord64(r));
25152507
#else
2516-
word64 t = *(word64*)r;
2508+
word64 t = readUnalignedWord64(r);
25172509
#endif
25182510
word64 d;
25192511
/* Add second bits to first. */
@@ -3023,7 +3015,7 @@ static void kyber_get_noise_eta3_aarch64(byte* rand, byte* seed, byte o)
30233015
state[3] = ((word64*)seed)[3];
30243016
state[4] = 0x1f00 + o;
30253017
XMEMSET(state + 5, 0, sizeof(*state) * (25 - 5));
3026-
state[16] = 0x8000000000000000UL;
3018+
state[16] = W64LIT(0x8000000000000000);
30273019
BlockSha3(state);
30283020
XMEMCPY(rand , state, SHA3_256_BYTES);
30293021
BlockSha3(state);
@@ -3083,7 +3075,7 @@ static void kyber_get_noise_eta2_aarch64(byte* rand, byte* seed, byte o)
30833075
/* Transposed value same as not. */
30843076
state[4] = 0x1f00 + o;
30853077
XMEMSET(state + 5, 0, sizeof(*state) * (25 - 5));
3086-
state[16] = 0x8000000000000000UL;
3078+
state[16] = W64LIT(0x8000000000000000);
30873079
BlockSha3(state);
30883080
}
30893081

wolfssl/wolfcrypt/misc.h

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,14 @@ int ConstantCompare(const byte* a, const byte* b, int length);
7676

7777
#ifdef WORD64_AVAILABLE
7878
WOLFSSL_LOCAL
79+
word64 readUnalignedWord64(const byte *in);
80+
WOLFSSL_LOCAL
81+
word64 writeUnalignedWord64(void *out, word64 in);
82+
WOLFSSL_LOCAL
83+
void readUnalignedWords64(word64 *out, const byte *in, size_t count);
84+
WOLFSSL_LOCAL
85+
void writeUnalignedWords64(byte *out, const word64 *in, size_t count);
86+
WOLFSSL_LOCAL
7987
word64 rotlFixed64(word64 x, word64 y);
8088
WOLFSSL_LOCAL
8189
word64 rotrFixed64(word64 x, word64 y);

wolfssl/wolfcrypt/types.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1729,9 +1729,11 @@ typedef struct w64wrapper {
17291729
#endif
17301730
#ifndef SAVE_VECTOR_REGISTERS2
17311731
#define SAVE_VECTOR_REGISTERS2() 0
1732+
#define SAVE_VECTOR_REGISTERS2_DOES_NOTHING
17321733
#endif
17331734
#ifndef CAN_SAVE_VECTOR_REGISTERS
17341735
#define CAN_SAVE_VECTOR_REGISTERS() 1
1736+
#define CAN_SAVE_VECTOR_REGISTERS_ALWAYS_TRUE
17351737
#endif
17361738
#ifndef WC_DEBUG_SET_VECTOR_REGISTERS_RETVAL
17371739
#define WC_DEBUG_SET_VECTOR_REGISTERS_RETVAL(x) WC_DO_NOTHING

0 commit comments

Comments
 (0)