Skip to content

Commit

Permalink
fixes for gating and ARM32 alignment defects:
Browse files Browse the repository at this point in the history
wolfcrypt/src/port/arm/armv8-aes.c: in the WOLFSSL_ARMASM_NO_HW_CRYPTO version of wc_AesSetKey(), copy the supplied userKey to a properly aligned buffer if necessary before calling AES_set_encrypt_key();

src/dtls13.c: in Dtls13GetRnMask(), if defined(WOLFSSL_LINUXKM)), return retval of wc_AesEncryptDirect();

wolfcrypt/src/misc.c: add readUnalignedWord32(), writeUnalignedWord32(), readUnalignedWords32(), and writeUnalignedWords32();

wolfcrypt/src/siphash.c: use readUnalignedWord64(), readUnalignedWord32(), and writeUnalignedWord64(), to avoid unaligned access faults, and fix cast in byte-reversing version of GET_U32().
  • Loading branch information
douzzer committed Oct 26, 2024
1 parent bdd6231 commit 6f87f57
Show file tree
Hide file tree
Showing 6 changed files with 89 additions and 12 deletions.
3 changes: 2 additions & 1 deletion src/dtls13.c
Original file line number Diff line number Diff line change
Expand Up @@ -260,7 +260,8 @@ static int Dtls13GetRnMask(WOLFSSL* ssl, const byte* ciphertext, byte* mask,
if (c->aes == NULL)
return BAD_STATE_E;
#if !defined(HAVE_SELFTEST) && \
(!defined(HAVE_FIPS) || (defined(FIPS_VERSION_GE) && FIPS_VERSION_GE(5,3)))
(!defined(HAVE_FIPS) || (defined(FIPS_VERSION_GE) && FIPS_VERSION_GE(5,3)) \
|| defined(WOLFSSL_LINUXKM))
return wc_AesEncryptDirect(c->aes, mask, ciphertext);
#else
wc_AesEncryptDirect(c->aes, mask, ciphertext);
Expand Down
3 changes: 2 additions & 1 deletion src/ssl_crypto.c
Original file line number Diff line number Diff line change
Expand Up @@ -3002,7 +3002,8 @@ void wolfSSL_AES_encrypt(const unsigned char* input, unsigned char* output,
}
else
#if !defined(HAVE_SELFTEST) && \
(!defined(HAVE_FIPS) || (defined(FIPS_VERSION_GE) && FIPS_VERSION_GE(5,3)))
(!defined(HAVE_FIPS) || (defined(FIPS_VERSION_GE) && FIPS_VERSION_GE(5,3)) \
|| defined(WOLFSSL_LINUXKM))
/* Encrypt a block with wolfCrypt AES. */
if (wc_AesEncryptDirect((Aes*)key, output, input) != 0) {
WOLFSSL_MSG("wc_AesEncryptDirect failed");
Expand Down
57 changes: 52 additions & 5 deletions wolfcrypt/src/misc.c
Original file line number Diff line number Diff line change
Expand Up @@ -209,15 +209,62 @@ WC_MISC_STATIC WC_INLINE void ByteReverseWords(word32* out, const word32* in,
#endif
}

WC_MISC_STATIC WC_INLINE word32 readUnalignedWord32(const byte *in)
{
if (((wc_ptr_t)in & (wc_ptr_t)(sizeof(word32) - 1U)) == (wc_ptr_t)0)
return *(word32 *)in;
else {
word32 out = 0; /* else CONFIG_FORTIFY_SOURCE -Wmaybe-uninitialized */
XMEMCPY(&out, in, sizeof(out));
return out;
}
}

WC_MISC_STATIC WC_INLINE word32 writeUnalignedWord32(void *out, word32 in)
{
if (((wc_ptr_t)out & (wc_ptr_t)(sizeof(word32) - 1U)) == (wc_ptr_t)0)
*(word32 *)out = in;
else {
XMEMCPY(out, &in, sizeof(in));
}
return in;
}

WC_MISC_STATIC WC_INLINE void readUnalignedWords32(word32 *out, const byte *in,
size_t count)
{
if (((wc_ptr_t)in & (wc_ptr_t)(sizeof(word32) - 1U)) == (wc_ptr_t)0) {
const word32 *in_word32 = (const word32 *)in;
while (count-- > 0)
*out++ = *in_word32++;
}
else {
XMEMCPY(out, in, count * sizeof(*out));
}
}

WC_MISC_STATIC WC_INLINE void writeUnalignedWords32(byte *out, const word32 *in,
size_t count)
{
if (((wc_ptr_t)out & (wc_ptr_t)(sizeof(word32) - 1U)) == (wc_ptr_t)0) {
word32 *out_word32 = (word32 *)out;
while (count-- > 0)
*out_word32++ = *in++;
}
else {
XMEMCPY(out, in, count * sizeof(*in));
}
}

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

WC_MISC_STATIC WC_INLINE word64 readUnalignedWord64(const byte *in)
{
if (((wc_ptr_t)in & (wc_ptr_t)(sizeof(word64) - 1U)) == (wc_ptr_t)0)
return *(word64 *)in;
else {
word64 out;
XMEMCPY(&out, in, sizeof(word64));
word64 out = 0; /* else CONFIG_FORTIFY_SOURCE -Wmaybe-uninitialized */
XMEMCPY(&out, in, sizeof(out));
return out;
}
}
Expand All @@ -227,7 +274,7 @@ WC_MISC_STATIC WC_INLINE word64 writeUnalignedWord64(void *out, word64 in)
if (((wc_ptr_t)out & (wc_ptr_t)(sizeof(word64) - 1U)) == (wc_ptr_t)0)
*(word64 *)out = in;
else {
XMEMCPY(out, &in, sizeof(word64));
XMEMCPY(out, &in, sizeof(in));
}
return in;
}
Expand All @@ -241,7 +288,7 @@ WC_MISC_STATIC WC_INLINE void readUnalignedWords64(word64 *out, const byte *in,
*out++ = *in_word64++;
}
else {
XMEMCPY(out, in, count * sizeof(word64));
XMEMCPY(out, in, count * sizeof(*out));
}
}

Expand All @@ -254,7 +301,7 @@ WC_MISC_STATIC WC_INLINE void writeUnalignedWords64(byte *out, const word64 *in,
*out_word64++ = *in++;
}
else {
XMEMCPY(out, in, count * sizeof(word64));
XMEMCPY(out, in, count * sizeof(*in));
}
}

Expand Down
21 changes: 20 additions & 1 deletion wolfcrypt/src/port/arm/armv8-aes.c
Original file line number Diff line number Diff line change
Expand Up @@ -16561,6 +16561,7 @@ int wc_AesSetKey(Aes* aes, const byte* userKey, word32 keylen,
{
#if defined(AES_MAX_KEY_SIZE)
const word32 max_key_len = (AES_MAX_KEY_SIZE / 8);
word32 userKey_aligned[AES_MAX_KEY_SIZE / WOLFSSL_BIT_SIZE / sizeof(word32)];
#endif

if (((keylen != 16) && (keylen != 24) && (keylen != 32)) ||
Expand All @@ -16574,6 +16575,14 @@ int wc_AesSetKey(Aes* aes, const byte* userKey, word32 keylen,
return BAD_FUNC_ARG;
}
#endif

#if !defined(AES_MAX_KEY_SIZE)
/* Check alignment */
if ((unsigned long)userKey & (sizeof(aes->key[0]) - 1U)) {
return BAD_FUNC_ARG;
}
#endif

#ifdef WOLF_CRYPTO_CB
if (aes->devId != INVALID_DEVID) {
if (keylen > sizeof(aes->devKey)) {
Expand All @@ -16590,7 +16599,17 @@ int wc_AesSetKey(Aes* aes, const byte* userKey, word32 keylen,
aes->keylen = keylen;
aes->rounds = keylen/4 + 6;

AES_set_encrypt_key(userKey, keylen * 8, (byte*)aes->key);
#if defined(AES_MAX_KEY_SIZE)
if ((unsigned long)userKey & (sizeof(aes->key[0]) - 1U)) {
XMEMCPY(userKey_aligned, userKey, keylen);
AES_set_encrypt_key((byte *)userKey_aligned, keylen * 8, (byte*)aes->key);
}
else
#endif
{
AES_set_encrypt_key(userKey, keylen * 8, (byte*)aes->key);
}

#ifdef HAVE_AES_DECRYPT
if (dir == AES_DECRYPTION) {
AES_invert_key((byte*)aes->key, aes->rounds);
Expand Down
8 changes: 4 additions & 4 deletions wolfcrypt/src/siphash.c
Original file line number Diff line number Diff line change
Expand Up @@ -69,14 +69,14 @@
* @param [in] a Little-endian byte array.
* @return 64-bit number.
*/
#define GET_U64(a) (*(word64*)(a))
#define GET_U64(a) readUnalignedWord64(a)
/**
* Decode little-endian byte array to 32-bit number.
*
* @param [in] a Little-endian byte array.
* @return 32-bit number.
*/
#define GET_U32(a) (*(word32*)(a))
#define GET_U32(a) readUnalignedWord32(a)
/**
* Decode little-endian byte array to 16-bit number.
*
Expand All @@ -90,7 +90,7 @@
* @param [out] a Byte array to write into.
* @param [in] n Number to encode.
*/
#define SET_U64(a, n) ((*(word64*)(a)) = (n))
#define SET_U64(a, n) writeUnalignedWord64(a, n)
#else
/**
* Decode little-endian byte array to 64-bit number.
Expand All @@ -112,7 +112,7 @@
* @param [in] a Little-endian byte array.
* @return 32-bit number.
*/
#define GET_U32(a) (((word64)((a)[3]) << 24) | \
#define GET_U32(a) (((word32)((a)[3]) << 24) | \
((word32)((a)[2]) << 16) | \
((word32)((a)[1]) << 8) | \
((word32)((a)[0]) ))
Expand Down
9 changes: 9 additions & 0 deletions wolfssl/wolfcrypt/misc.h
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,15 @@ void ForceZero(void* mem, word32 len);
WOLFSSL_LOCAL
int ConstantCompare(const byte* a, const byte* b, int length);

WOLFSSL_LOCAL
word32 readUnalignedWord32(const byte *in);
WOLFSSL_LOCAL
word32 writeUnalignedWord32(void *out, word32 in);
WOLFSSL_LOCAL
void readUnalignedWords32(word32 *out, const byte *in, size_t count);
WOLFSSL_LOCAL
void writeUnalignedWords32(byte *out, const word32 *in, size_t count);

#ifdef WORD64_AVAILABLE
WOLFSSL_LOCAL
word64 readUnalignedWord64(const byte *in);
Expand Down

0 comments on commit 6f87f57

Please sign in to comment.