Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
54 changes: 47 additions & 7 deletions wolfcrypt/src/aes.c
Original file line number Diff line number Diff line change
Expand Up @@ -8142,8 +8142,6 @@ static WC_INLINE void IncrementGcmCounter(byte* inOutCtr)
#endif
#endif /* !FREESCALE_LTC_AES_GCM */

#if !defined(WOLFSSL_ARMASM) || defined(__aarch64__) || \
defined(WOLFSSL_ARMASM_NO_HW_CRYPTO)
#if defined(GCM_SMALL) || defined(GCM_TABLE) || defined(GCM_TABLE_4BIT)

static WC_INLINE void FlattenSzInBits(byte* buf, word32 sz)
Expand Down Expand Up @@ -8297,7 +8295,6 @@ void GenerateM0(Gcm* gcm)
}

#endif /* GCM_TABLE */
#endif

#if defined(WOLFSSL_AESNI) && defined(USE_INTEL_SPEEDUP)
#define HAVE_INTEL_AVX1
Expand Down Expand Up @@ -8328,6 +8325,28 @@ void GCM_generate_m0_avx2(const unsigned char *h, unsigned char *m)
#endif
#endif /* WOLFSSL_AESNI && GCM_TABLE_4BIT && WC_C_DYNAMIC_FALLBACK */

#if defined(WOLFSSL_ARMASM) && !defined(__aarch64__) && \
!defined(WOLFSSL_ARMASM_NO_HW_CRYPTO) && defined(HAVE_AESGCM)
/* AES_GCM_set_key_AARCH32 produces H with the bits of each byte reflected -
* the form the PMULL bulk assembly wants. The portable GHASH used for AES-GCM
* streaming needs plain H, so H is kept un-reflected and reflected back only
* around the bulk assembly calls. Reflecting per byte is its own inverse. */
static WC_INLINE void GcmReflectH(byte* h)
{
int i;
int j;
for (i = 0; i < WC_AES_BLOCK_SIZE; i++) {
byte b = h[i];
byte r = 0;
for (j = 0; j < 8; j++) {
r = (byte)((r << 1) | (b & 1));
b >>= 1;
}
h[i] = r;
}
}
#endif

/* Software AES - GCM SetKey */
int wc_AesGcmSetKey(Aes* aes, const byte* key, word32 len)
{
Expand Down Expand Up @@ -8402,6 +8421,12 @@ int wc_AesGcmSetKey(Aes* aes, const byte* key, word32 len)
#ifndef WOLFSSL_ARMASM_NO_HW_CRYPTO
#if !defined(__aarch64__)
AES_GCM_set_key_AARCH32(iv, (byte*)aes->key, aes->gcm.H, aes->rounds);
/* Keep H un-reflected so the portable streaming GHASH can use it (and
* M0); the bulk assembly reflects a copy back per call. */
GcmReflectH(aes->gcm.H);
#if defined(GCM_TABLE) || defined(GCM_TABLE_4BIT)
GenerateM0(&aes->gcm);
#endif
#else
if (aes->use_aes_hw_crypto && aes->use_pmull_hw_crypto) {
AES_GCM_set_key_AARCH64(iv, (byte*)aes->key, aes->gcm.H,
Expand Down Expand Up @@ -8602,8 +8627,6 @@ void AES_GCM_decrypt_vaes(const unsigned char *in, unsigned char *out,

#endif /* WOLFSSL_AESNI */

#if !defined(WOLFSSL_ARMASM) || defined(__aarch64__) || \
defined(WOLFSSL_ARMASM_NO_HW_CRYPTO)
#if defined(WOLFSSL_RISCV_SCALAR_CRYPTO_ASM) && defined(HAVE_AESGCM) && \
!defined(WOLFSSL_RISCV_VECTOR_CRYPTO_ASM)
/* GHASH using the RISC-V scalar carryless-multiply (Zbc) helper. Vector crypto
Expand Down Expand Up @@ -8796,7 +8819,9 @@ void GHASH(Gcm* gcm, const byte* a, word32 aSz, const byte* c,

#if defined(WOLFSSL_ARMASM) && (!defined(__aarch64__) || \
defined(WOLFSSL_ARMASM_NO_NEON))
static void GCM_gmult_len_armasm_C(
/* Unused when the batch GHASH is done in assembly (32-bit ARMv8 crypto), which
* only pulls in the streaming software GMULT. */
static WC_MAYBE_UNUSED void GCM_gmult_len_armasm_C(
byte* x, const byte* h, const unsigned char* a, unsigned long len)
{
byte Z[AES_BLOCK_SIZE];
Expand Down Expand Up @@ -9137,6 +9162,15 @@ void GHASH(Gcm* gcm, const byte* a, word32 aSz, const byte* c,
*/
#define GHASH_INIT_EXTRA(aes) WC_DO_NOTHING

#ifdef GCM_GMULT_LEN
/* GHASH one block of data.
*
* @param [in, out] aes AES GCM object.
* @param [in] block Block of AAD or cipher text.
*/
#define GHASH_ONE_BLOCK_SW(aes, block) \
GCM_GMULT_LEN(&(aes)->gcm, AES_TAG(aes), block, WC_AES_BLOCK_SIZE)
#else
/* GHASH one block of data..
*
* XOR block into tag and GMULT with H using pre-computed table.
Expand All @@ -9150,6 +9184,7 @@ void GHASH(Gcm* gcm, const byte* a, word32 aSz, const byte* c,
GMULT(AES_TAG(aes), aes->gcm.M0); \
} \
while (0)
#endif
#endif /* WOLFSSL_AESGCM_STREAM */
/* end GCM_TABLE */
#elif defined(GCM_TABLE_4BIT)
Expand Down Expand Up @@ -10205,7 +10240,6 @@ void GHASH(Gcm* gcm, const byte* a, word32 aSz, const byte* c,
#endif /* LITTLE_ENDIAN_ORDER */
#endif /* WOLFSSL_AESGCM_STREAM */
#endif /* end GCM_WORD32 */
#endif

#if !defined(WOLFSSL_XILINX_CRYPT) && !defined(WOLFSSL_AFALG_XILINX_AES)
#ifdef WOLFSSL_AESGCM_STREAM
Expand Down Expand Up @@ -11067,9 +11101,12 @@ int wc_AesGcmEncrypt(Aes* aes, byte* out, const byte* in, word32 sz,
#if defined(WOLFSSL_ARMASM)
#ifndef WOLFSSL_ARMASM_NO_HW_CRYPTO
#if !defined(__aarch64__)
/* Reflect H back to the form the PMULL assembly wants for this call. */
GcmReflectH(aes->gcm.H);
AES_GCM_encrypt_AARCH32(in, out, sz, iv, ivSz, authTag, authTagSz, authIn,
authInSz, (byte*)aes->key, aes->gcm.H, (byte*)aes->tmp, (byte*)aes->reg,
aes->rounds);
GcmReflectH(aes->gcm.H);
ret = 0;
#else
if (aes->use_aes_hw_crypto && aes->use_pmull_hw_crypto) {
Expand Down Expand Up @@ -11873,9 +11910,12 @@ int wc_AesGcmDecrypt(Aes* aes, byte* out, const byte* in, word32 sz,
word32 reg[WC_AES_BLOCK_SIZE / sizeof(word32)];
XMEMCPY(reg, aes->reg, sizeof(reg));
#endif
/* Reflect H back to the form the PMULL assembly wants for this call. */
GcmReflectH(aes->gcm.H);
ret = AES_GCM_decrypt_AARCH32(in, out, sz, iv, ivSz, authTag, authTagSz,
authIn, authInSz, (byte*)aes->key, aes->gcm.H, (byte*)aes->tmp,
(byte*)aes->reg, aes->rounds);
GcmReflectH(aes->gcm.H);
#ifdef OPENSSL_EXTRA
XMEMCPY(aes->reg, reg, sizeof(reg));
#endif
Expand Down
Loading
Loading