@@ -16493,9 +16493,11 @@ extern void AES_CBC_decrypt(const unsigned char* in, unsigned char* out,
1649316493 unsigned long len, const unsigned char* ks, int nr, unsigned char* iv);
1649416494extern void AES_CTR_encrypt(const unsigned char* in, unsigned char* out,
1649516495 unsigned long len, const unsigned char* ks, int nr, unsigned char* ctr);
16496+ #if defined(GCM_TABLE) || defined(GCM_TABLE_4BIT)
1649616497/* in pre-C2x C, constness conflicts for dimensioned arrays can't be resolved. */
1649716498extern void GCM_gmult_len(byte* x, /* const */ byte m[32][AES_BLOCK_SIZE],
1649816499 const unsigned char* data, unsigned long len);
16500+ #endif
1649916501extern void AES_GCM_encrypt(const unsigned char* in, unsigned char* out,
1650016502 unsigned long len, const unsigned char* ks, int nr, unsigned char* ctr);
1650116503
@@ -16992,6 +16994,7 @@ static WC_INLINE void RIGHTSHIFTX(byte* x)
1699216994 x[0] ^= borrow;
1699316995}
1699416996
16997+ #if defined(GCM_TABLE) || defined(GCM_TABLE_4BIT)
1699516998void GenerateM0(Gcm* gcm)
1699616999{
1699717000 int i;
@@ -17047,6 +17050,7 @@ void GenerateM0(Gcm* gcm)
1704717050 m32[3] = ByteReverseWord32(m32[3]);
1704817051 }
1704917052}
17053+ #endif /* GCM_TABLE */
1705017054
1705117055int wc_AesGcmSetKey(Aes* aes, const byte* key, word32 len)
1705217056{
@@ -17067,7 +17071,9 @@ int wc_AesGcmSetKey(Aes* aes, const byte* key, word32 len)
1706717071 if (ret == 0) {
1706817072 AES_ECB_encrypt(iv, aes->gcm.H, AES_BLOCK_SIZE,
1706917073 (const unsigned char*)aes->key, aes->rounds);
17070- GenerateM0(&aes->gcm);
17074+ #if defined(GCM_TABLE) || defined(GCM_TABLE_4BIT)
17075+ GenerateM0(&aes->gcm);
17076+ #endif /* GCM_TABLE */
1707117077 }
1707217078
1707317079 return ret;
@@ -17101,6 +17107,44 @@ static WC_INLINE void FlattenSzInBits(byte* buf, word32 sz)
1710117107 buf[7] = sz & 0xff;
1710217108}
1710317109
17110+ #if defined(GCM_TABLE) || defined(GCM_TABLE_4BIT)
17111+ /* GCM_gmult_len implementation in armv8-32-aes-asm or thumb2-aes-asm */
17112+ #define GCM_GMULT_LEN(aes, x, a, len) GCM_gmult_len(x, aes->gcm.M0, a, len)
17113+ #elif defined(GCM_SMALL)
17114+ static void GCM_gmult_len(byte* x, const byte* h,
17115+ const unsigned char* a, unsigned long len)
17116+ {
17117+ byte Z[AES_BLOCK_SIZE];
17118+ byte V[AES_BLOCK_SIZE];
17119+ int i, j;
17120+
17121+ while (len >= AES_BLOCK_SIZE) {
17122+ xorbuf(x, a, AES_BLOCK_SIZE);
17123+
17124+ XMEMSET(Z, 0, AES_BLOCK_SIZE);
17125+ XMEMCPY(V, x, AES_BLOCK_SIZE);
17126+ for (i = 0; i < AES_BLOCK_SIZE; i++) {
17127+ byte y = h[i];
17128+ for (j = 0; j < 8; j++) {
17129+ if (y & 0x80) {
17130+ xorbuf(Z, V, AES_BLOCK_SIZE);
17131+ }
17132+
17133+ RIGHTSHIFTX(V);
17134+ y = y << 1;
17135+ }
17136+ }
17137+ XMEMCPY(x, Z, AES_BLOCK_SIZE);
17138+
17139+ len -= AES_BLOCK_SIZE;
17140+ a += AES_BLOCK_SIZE;
17141+ }
17142+ }
17143+ #define GCM_GMULT_LEN(aes, x, a, len) GCM_gmult_len(x, aes->gcm.H, a, len)
17144+ #else
17145+ #error ARMv8 AES only supports GCM_TABLE or GCM_TABLE_4BIT or GCM_SMALL
17146+ #endif /* GCM_TABLE */
17147+
1710417148static void gcm_ghash_arm32(Aes* aes, const byte* a, word32 aSz, const byte* c,
1710517149 word32 cSz, byte* s, word32 sSz)
1710617150{
@@ -17119,13 +17163,13 @@ static void gcm_ghash_arm32(Aes* aes, const byte* a, word32 aSz, const byte* c,
1711917163 blocks = aSz / AES_BLOCK_SIZE;
1712017164 partial = aSz % AES_BLOCK_SIZE;
1712117165 if (blocks > 0) {
17122- GCM_gmult_len(x, aes->gcm.M0 , a, blocks * AES_BLOCK_SIZE);
17166+ GCM_GMULT_LEN(aes, x , a, blocks * AES_BLOCK_SIZE);
1712317167 a += blocks * AES_BLOCK_SIZE;
1712417168 }
1712517169 if (partial != 0) {
1712617170 XMEMSET(scratch, 0, AES_BLOCK_SIZE);
1712717171 XMEMCPY(scratch, a, partial);
17128- GCM_gmult_len(x, aes->gcm.M0 , scratch, AES_BLOCK_SIZE);
17172+ GCM_GMULT_LEN(aes, x , scratch, AES_BLOCK_SIZE);
1712917173 }
1713017174 }
1713117175
@@ -17134,20 +17178,20 @@ static void gcm_ghash_arm32(Aes* aes, const byte* a, word32 aSz, const byte* c,
1713417178 blocks = cSz / AES_BLOCK_SIZE;
1713517179 partial = cSz % AES_BLOCK_SIZE;
1713617180 if (blocks > 0) {
17137- GCM_gmult_len(x, aes->gcm.M0 , c, blocks * AES_BLOCK_SIZE);
17181+ GCM_GMULT_LEN(aes, x , c, blocks * AES_BLOCK_SIZE);
1713817182 c += blocks * AES_BLOCK_SIZE;
1713917183 }
1714017184 if (partial != 0) {
1714117185 XMEMSET(scratch, 0, AES_BLOCK_SIZE);
1714217186 XMEMCPY(scratch, c, partial);
17143- GCM_gmult_len(x, aes->gcm.M0 , scratch, AES_BLOCK_SIZE);
17187+ GCM_GMULT_LEN(aes, x , scratch, AES_BLOCK_SIZE);
1714417188 }
1714517189 }
1714617190
1714717191 /* Hash in the lengths of A and C in bits */
1714817192 FlattenSzInBits(&scratch[0], aSz);
1714917193 FlattenSzInBits(&scratch[8], cSz);
17150- GCM_gmult_len(x, aes->gcm.M0 , scratch, AES_BLOCK_SIZE);
17194+ GCM_GMULT_LEN(aes, x , scratch, AES_BLOCK_SIZE);
1715117195
1715217196 /* Copy the result into s. */
1715317197 XMEMCPY(s, x, sSz);
@@ -17198,13 +17242,13 @@ int wc_AesGcmEncrypt(Aes* aes, byte* out, const byte* in, word32 sz,
1719817242 blocks = authInSz / AES_BLOCK_SIZE;
1719917243 partial = authInSz % AES_BLOCK_SIZE;
1720017244 if (blocks > 0) {
17201- GCM_gmult_len(x, aes->gcm.M0 , authIn, blocks * AES_BLOCK_SIZE);
17245+ GCM_GMULT_LEN(aes, x , authIn, blocks * AES_BLOCK_SIZE);
1720217246 authIn += blocks * AES_BLOCK_SIZE;
1720317247 }
1720417248 if (partial != 0) {
1720517249 XMEMSET(scratch, 0, AES_BLOCK_SIZE);
1720617250 XMEMCPY(scratch, authIn, partial);
17207- GCM_gmult_len(x, aes->gcm.M0 , scratch, AES_BLOCK_SIZE);
17251+ GCM_GMULT_LEN(aes, x , scratch, AES_BLOCK_SIZE);
1720817252 }
1720917253 }
1721017254
@@ -17214,7 +17258,7 @@ int wc_AesGcmEncrypt(Aes* aes, byte* out, const byte* in, word32 sz,
1721417258 if (blocks > 0) {
1721517259 AES_GCM_encrypt(in, out, blocks * AES_BLOCK_SIZE,
1721617260 (const unsigned char*)aes->key, aes->rounds, counter);
17217- GCM_gmult_len(x, aes->gcm.M0 , out, blocks * AES_BLOCK_SIZE);
17261+ GCM_GMULT_LEN(aes, x , out, blocks * AES_BLOCK_SIZE);
1721817262 in += blocks * AES_BLOCK_SIZE;
1721917263 out += blocks * AES_BLOCK_SIZE;
1722017264 }
@@ -17227,14 +17271,14 @@ int wc_AesGcmEncrypt(Aes* aes, byte* out, const byte* in, word32 sz,
1722717271
1722817272 XMEMSET(scratch, 0, AES_BLOCK_SIZE);
1722917273 XMEMCPY(scratch, out, partial);
17230- GCM_gmult_len(x, aes->gcm.M0 , scratch, AES_BLOCK_SIZE);
17274+ GCM_GMULT_LEN(aes, x , scratch, AES_BLOCK_SIZE);
1723117275 }
1723217276
1723317277 /* Hash in the lengths of A and C in bits */
1723417278 XMEMSET(scratch, 0, AES_BLOCK_SIZE);
1723517279 FlattenSzInBits(&scratch[0], authInSz);
1723617280 FlattenSzInBits(&scratch[8], sz);
17237- GCM_gmult_len(x, aes->gcm.M0 , scratch, AES_BLOCK_SIZE);
17281+ GCM_GMULT_LEN(aes, x , scratch, AES_BLOCK_SIZE);
1723817282 if (authTagSz > AES_BLOCK_SIZE) {
1723917283 XMEMCPY(authTag, x, AES_BLOCK_SIZE);
1724017284 }
@@ -17286,21 +17330,21 @@ int wc_AesGcmDecrypt(Aes* aes, byte* out, const byte* in, word32 sz,
1728617330 blocks = authInSz / AES_BLOCK_SIZE;
1728717331 partial = authInSz % AES_BLOCK_SIZE;
1728817332 if (blocks > 0) {
17289- GCM_gmult_len(x, aes->gcm.M0 , authIn, blocks * AES_BLOCK_SIZE);
17333+ GCM_GMULT_LEN(aes, x , authIn, blocks * AES_BLOCK_SIZE);
1729017334 authIn += blocks * AES_BLOCK_SIZE;
1729117335 }
1729217336 if (partial != 0) {
1729317337 XMEMSET(scratch, 0, AES_BLOCK_SIZE);
1729417338 XMEMCPY(scratch, authIn, partial);
17295- GCM_gmult_len(x, aes->gcm.M0 , scratch, AES_BLOCK_SIZE);
17339+ GCM_GMULT_LEN(aes, x , scratch, AES_BLOCK_SIZE);
1729617340 }
1729717341 }
1729817342
1729917343 blocks = sz / AES_BLOCK_SIZE;
1730017344 partial = sz % AES_BLOCK_SIZE;
1730117345 /* do as many blocks as possible */
1730217346 if (blocks > 0) {
17303- GCM_gmult_len(x, aes->gcm.M0 , in, blocks * AES_BLOCK_SIZE);
17347+ GCM_GMULT_LEN(aes, x , in, blocks * AES_BLOCK_SIZE);
1730417348
1730517349 AES_GCM_encrypt(in, out, blocks * AES_BLOCK_SIZE,
1730617350 (const unsigned char*)aes->key, aes->rounds, counter);
@@ -17310,7 +17354,7 @@ int wc_AesGcmDecrypt(Aes* aes, byte* out, const byte* in, word32 sz,
1731017354 if (partial != 0) {
1731117355 XMEMSET(scratch, 0, AES_BLOCK_SIZE);
1731217356 XMEMCPY(scratch, in, partial);
17313- GCM_gmult_len(x, aes->gcm.M0 , scratch, AES_BLOCK_SIZE);
17357+ GCM_GMULT_LEN(aes, x , scratch, AES_BLOCK_SIZE);
1731417358
1731517359 AES_GCM_encrypt(in, scratch, AES_BLOCK_SIZE,
1731617360 (const unsigned char*)aes->key, aes->rounds, counter);
@@ -17320,7 +17364,7 @@ int wc_AesGcmDecrypt(Aes* aes, byte* out, const byte* in, word32 sz,
1732017364 XMEMSET(scratch, 0, AES_BLOCK_SIZE);
1732117365 FlattenSzInBits(&scratch[0], authInSz);
1732217366 FlattenSzInBits(&scratch[8], sz);
17323- GCM_gmult_len(x, aes->gcm.M0 , scratch, AES_BLOCK_SIZE);
17367+ GCM_GMULT_LEN(aes, x , scratch, AES_BLOCK_SIZE);
1732417368 AES_ECB_encrypt(initialCounter, scratch, AES_BLOCK_SIZE,
1732517369 (const unsigned char*)aes->key, aes->rounds);
1732617370 xorbuf(x, scratch, authTagSz);
0 commit comments