diff --git a/wolfcrypt/src/port/arm/armv8-aes.c b/wolfcrypt/src/port/arm/armv8-aes.c index 455d30bba..871d6b38a 100644 --- a/wolfcrypt/src/port/arm/armv8-aes.c +++ b/wolfcrypt/src/port/arm/armv8-aes.c @@ -16493,9 +16493,11 @@ extern void AES_CBC_decrypt(const unsigned char* in, unsigned char* out, unsigned long len, const unsigned char* ks, int nr, unsigned char* iv); extern void AES_CTR_encrypt(const unsigned char* in, unsigned char* out, unsigned long len, const unsigned char* ks, int nr, unsigned char* ctr); +#if defined(GCM_TABLE) || defined(GCM_TABLE_4BIT) /* in pre-C2x C, constness conflicts for dimensioned arrays can't be resolved. */ extern void GCM_gmult_len(byte* x, /* const */ byte m[32][AES_BLOCK_SIZE], const unsigned char* data, unsigned long len); +#endif extern void AES_GCM_encrypt(const unsigned char* in, unsigned char* out, unsigned long len, const unsigned char* ks, int nr, unsigned char* ctr); @@ -16992,6 +16994,7 @@ static WC_INLINE void RIGHTSHIFTX(byte* x) x[0] ^= borrow; } +#if defined(GCM_TABLE) || defined(GCM_TABLE_4BIT) void GenerateM0(Gcm* gcm) { int i; @@ -17047,6 +17050,7 @@ void GenerateM0(Gcm* gcm) m32[3] = ByteReverseWord32(m32[3]); } } +#endif /* GCM_TABLE */ int wc_AesGcmSetKey(Aes* aes, const byte* key, word32 len) { @@ -17067,7 +17071,9 @@ int wc_AesGcmSetKey(Aes* aes, const byte* key, word32 len) if (ret == 0) { AES_ECB_encrypt(iv, aes->gcm.H, AES_BLOCK_SIZE, (const unsigned char*)aes->key, aes->rounds); - GenerateM0(&aes->gcm); + #if defined(GCM_TABLE) || defined(GCM_TABLE_4BIT) + GenerateM0(&aes->gcm); + #endif /* GCM_TABLE */ } return ret; @@ -17101,6 +17107,44 @@ static WC_INLINE void FlattenSzInBits(byte* buf, word32 sz) buf[7] = sz & 0xff; } +#if defined(GCM_TABLE) || defined(GCM_TABLE_4BIT) + /* GCM_gmult_len implementation in armv8-32-aes-asm or thumb2-aes-asm */ + #define GCM_GMULT_LEN(aes, x, a, len) GCM_gmult_len(x, aes->gcm.M0, a, len) +#elif defined(GCM_SMALL) + static void GCM_gmult_len(byte* x, const byte* h, + const unsigned char* a, unsigned long len) + { + byte Z[AES_BLOCK_SIZE]; + byte V[AES_BLOCK_SIZE]; + int i, j; + + while (len >= AES_BLOCK_SIZE) { + xorbuf(x, a, AES_BLOCK_SIZE); + + XMEMSET(Z, 0, AES_BLOCK_SIZE); + XMEMCPY(V, x, AES_BLOCK_SIZE); + for (i = 0; i < AES_BLOCK_SIZE; i++) { + byte y = h[i]; + for (j = 0; j < 8; j++) { + if (y & 0x80) { + xorbuf(Z, V, AES_BLOCK_SIZE); + } + + RIGHTSHIFTX(V); + y = y << 1; + } + } + XMEMCPY(x, Z, AES_BLOCK_SIZE); + + len -= AES_BLOCK_SIZE; + a += AES_BLOCK_SIZE; + } + } + #define GCM_GMULT_LEN(aes, x, a, len) GCM_gmult_len(x, aes->gcm.H, a, len) +#else + #error ARMv8 AES only supports GCM_TABLE or GCM_TABLE_4BIT or GCM_SMALL +#endif /* GCM_TABLE */ + static void gcm_ghash_arm32(Aes* aes, const byte* a, word32 aSz, const byte* c, word32 cSz, byte* s, word32 sSz) { @@ -17119,13 +17163,13 @@ static void gcm_ghash_arm32(Aes* aes, const byte* a, word32 aSz, const byte* c, blocks = aSz / AES_BLOCK_SIZE; partial = aSz % AES_BLOCK_SIZE; if (blocks > 0) { - GCM_gmult_len(x, aes->gcm.M0, a, blocks * AES_BLOCK_SIZE); + GCM_GMULT_LEN(aes, x, a, blocks * AES_BLOCK_SIZE); a += blocks * AES_BLOCK_SIZE; } if (partial != 0) { XMEMSET(scratch, 0, AES_BLOCK_SIZE); XMEMCPY(scratch, a, partial); - GCM_gmult_len(x, aes->gcm.M0, scratch, AES_BLOCK_SIZE); + GCM_GMULT_LEN(aes, x, scratch, AES_BLOCK_SIZE); } } @@ -17134,20 +17178,20 @@ static void gcm_ghash_arm32(Aes* aes, const byte* a, word32 aSz, const byte* c, blocks = cSz / AES_BLOCK_SIZE; partial = cSz % AES_BLOCK_SIZE; if (blocks > 0) { - GCM_gmult_len(x, aes->gcm.M0, c, blocks * AES_BLOCK_SIZE); + GCM_GMULT_LEN(aes, x, c, blocks * AES_BLOCK_SIZE); c += blocks * AES_BLOCK_SIZE; } if (partial != 0) { XMEMSET(scratch, 0, AES_BLOCK_SIZE); XMEMCPY(scratch, c, partial); - GCM_gmult_len(x, aes->gcm.M0, scratch, AES_BLOCK_SIZE); + GCM_GMULT_LEN(aes, x, scratch, AES_BLOCK_SIZE); } } /* Hash in the lengths of A and C in bits */ FlattenSzInBits(&scratch[0], aSz); FlattenSzInBits(&scratch[8], cSz); - GCM_gmult_len(x, aes->gcm.M0, scratch, AES_BLOCK_SIZE); + GCM_GMULT_LEN(aes, x, scratch, AES_BLOCK_SIZE); /* Copy the result into s. */ XMEMCPY(s, x, sSz); @@ -17198,13 +17242,13 @@ int wc_AesGcmEncrypt(Aes* aes, byte* out, const byte* in, word32 sz, blocks = authInSz / AES_BLOCK_SIZE; partial = authInSz % AES_BLOCK_SIZE; if (blocks > 0) { - GCM_gmult_len(x, aes->gcm.M0, authIn, blocks * AES_BLOCK_SIZE); + GCM_GMULT_LEN(aes, x, authIn, blocks * AES_BLOCK_SIZE); authIn += blocks * AES_BLOCK_SIZE; } if (partial != 0) { XMEMSET(scratch, 0, AES_BLOCK_SIZE); XMEMCPY(scratch, authIn, partial); - GCM_gmult_len(x, aes->gcm.M0, scratch, AES_BLOCK_SIZE); + GCM_GMULT_LEN(aes, x, scratch, AES_BLOCK_SIZE); } } @@ -17214,7 +17258,7 @@ int wc_AesGcmEncrypt(Aes* aes, byte* out, const byte* in, word32 sz, if (blocks > 0) { AES_GCM_encrypt(in, out, blocks * AES_BLOCK_SIZE, (const unsigned char*)aes->key, aes->rounds, counter); - GCM_gmult_len(x, aes->gcm.M0, out, blocks * AES_BLOCK_SIZE); + GCM_GMULT_LEN(aes, x, out, blocks * AES_BLOCK_SIZE); in += blocks * AES_BLOCK_SIZE; out += blocks * AES_BLOCK_SIZE; } @@ -17227,14 +17271,14 @@ int wc_AesGcmEncrypt(Aes* aes, byte* out, const byte* in, word32 sz, XMEMSET(scratch, 0, AES_BLOCK_SIZE); XMEMCPY(scratch, out, partial); - GCM_gmult_len(x, aes->gcm.M0, scratch, AES_BLOCK_SIZE); + GCM_GMULT_LEN(aes, x, scratch, AES_BLOCK_SIZE); } /* Hash in the lengths of A and C in bits */ XMEMSET(scratch, 0, AES_BLOCK_SIZE); FlattenSzInBits(&scratch[0], authInSz); FlattenSzInBits(&scratch[8], sz); - GCM_gmult_len(x, aes->gcm.M0, scratch, AES_BLOCK_SIZE); + GCM_GMULT_LEN(aes, x, scratch, AES_BLOCK_SIZE); if (authTagSz > AES_BLOCK_SIZE) { XMEMCPY(authTag, x, AES_BLOCK_SIZE); } @@ -17286,13 +17330,13 @@ int wc_AesGcmDecrypt(Aes* aes, byte* out, const byte* in, word32 sz, blocks = authInSz / AES_BLOCK_SIZE; partial = authInSz % AES_BLOCK_SIZE; if (blocks > 0) { - GCM_gmult_len(x, aes->gcm.M0, authIn, blocks * AES_BLOCK_SIZE); + GCM_GMULT_LEN(aes, x, authIn, blocks * AES_BLOCK_SIZE); authIn += blocks * AES_BLOCK_SIZE; } if (partial != 0) { XMEMSET(scratch, 0, AES_BLOCK_SIZE); XMEMCPY(scratch, authIn, partial); - GCM_gmult_len(x, aes->gcm.M0, scratch, AES_BLOCK_SIZE); + GCM_GMULT_LEN(aes, x, scratch, AES_BLOCK_SIZE); } } @@ -17300,7 +17344,7 @@ int wc_AesGcmDecrypt(Aes* aes, byte* out, const byte* in, word32 sz, partial = sz % AES_BLOCK_SIZE; /* do as many blocks as possible */ if (blocks > 0) { - GCM_gmult_len(x, aes->gcm.M0, in, blocks * AES_BLOCK_SIZE); + GCM_GMULT_LEN(aes, x, in, blocks * AES_BLOCK_SIZE); AES_GCM_encrypt(in, out, blocks * AES_BLOCK_SIZE, (const unsigned char*)aes->key, aes->rounds, counter); @@ -17310,7 +17354,7 @@ int wc_AesGcmDecrypt(Aes* aes, byte* out, const byte* in, word32 sz, if (partial != 0) { XMEMSET(scratch, 0, AES_BLOCK_SIZE); XMEMCPY(scratch, in, partial); - GCM_gmult_len(x, aes->gcm.M0, scratch, AES_BLOCK_SIZE); + GCM_GMULT_LEN(aes, x, scratch, AES_BLOCK_SIZE); AES_GCM_encrypt(in, scratch, AES_BLOCK_SIZE, (const unsigned char*)aes->key, aes->rounds, counter); @@ -17320,7 +17364,7 @@ int wc_AesGcmDecrypt(Aes* aes, byte* out, const byte* in, word32 sz, XMEMSET(scratch, 0, AES_BLOCK_SIZE); FlattenSzInBits(&scratch[0], authInSz); FlattenSzInBits(&scratch[8], sz); - GCM_gmult_len(x, aes->gcm.M0, scratch, AES_BLOCK_SIZE); + GCM_GMULT_LEN(aes, x, scratch, AES_BLOCK_SIZE); AES_ECB_encrypt(initialCounter, scratch, AES_BLOCK_SIZE, (const unsigned char*)aes->key, aes->rounds); xorbuf(x, scratch, authTagSz);