Skip to content

Commit ee3aff1

Browse files
authored
Merge pull request #7291 from dgarske/armasm_thumb_gcmsmall
Thumb2 AES GCM support for GCM_SMALL
2 parents 88f0777 + 7c836c8 commit ee3aff1

1 file changed

Lines changed: 60 additions & 16 deletions

File tree

wolfcrypt/src/port/arm/armv8-aes.c

Lines changed: 60 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -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);
1649416494
extern 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. */
1649716498
extern void GCM_gmult_len(byte* x, /* const */ byte m[32][AES_BLOCK_SIZE],
1649816499
const unsigned char* data, unsigned long len);
16500+
#endif
1649916501
extern 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)
1699516998
void 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

1705117055
int 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+
1710417148
static 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

Comments
 (0)