2 * Copyright (C) 2018 Denys Vlasenko
4 * Licensed under GPLv2, see file LICENSE in this source tree.
10 typedef uint32_t word32;
11 #define XMEMSET memset
12 #define XMEMCPY memcpy
14 void FAST_FUNC xorbuf(void* buf, const void* mask, unsigned count)
18 const byte* m = (const byte*)mask;
19 for (i = 0; i < count; i++)
23 /* from wolfssl-3.15.3/wolfcrypt/src/aes.c */
25 static ALWAYS_INLINE void FlattenSzInBits(byte* buf, word32 sz)
27 /* Multiply the sz by 8 */
28 //bbox: these sizes are never even close to 2^32/8
29 // word32 szHi = (sz >> (8*sizeof(sz) - 3));
32 /* copy over the words of the sz into the destination buffer */
33 // buf[0] = (szHi >> 24) & 0xff;
34 // buf[1] = (szHi >> 16) & 0xff;
35 // buf[2] = (szHi >> 8) & 0xff;
36 // buf[3] = szHi & 0xff;
37 *(uint32_t*)(buf + 0) = 0;
38 // buf[4] = (sz >> 24) & 0xff;
39 // buf[5] = (sz >> 16) & 0xff;
40 // buf[6] = (sz >> 8) & 0xff;
41 // buf[7] = sz & 0xff;
42 *(uint32_t*)(buf + 4) = SWAP_BE32(sz);
45 static void RIGHTSHIFTX(byte* x)
50 int borrow = x[15] & 0x01;
52 for (i = 0; i < AES_BLOCK_SIZE; i++) {
53 carryOut = x[i] & 0x01;
54 x[i] = (x[i] >> 1) | (carryIn ? 0x80 : 0);
57 if (borrow) x[0] ^= 0xE1;
60 static void GMULT(byte* X, byte* Y)
62 byte Z[AES_BLOCK_SIZE];
63 byte V[AES_BLOCK_SIZE];
66 XMEMSET(Z, 0, AES_BLOCK_SIZE);
67 XMEMCPY(V, X, AES_BLOCK_SIZE);
68 for (i = 0; i < AES_BLOCK_SIZE; i++)
71 for (j = 0; j < 8; j++)
74 xorbuf(Z, V, AES_BLOCK_SIZE);
81 XMEMCPY(X, Z, AES_BLOCK_SIZE);
85 // for TLS AES-GCM, a (which is AAD) is always 13 bytes long, and bbox code provides
86 // extra 3 zeroed bytes, making it a[16], or a[AES_BLOCK_SIZE].
87 // Resulting auth tag in s[] is also always AES_BLOCK_SIZE bytes.
89 // This allows some simplifications.
90 #define aSz AES_BLOCK_SIZE
91 #define sSz AES_BLOCK_SIZE
92 void FAST_FUNC aesgcm_GHASH(byte* h,
93 const byte* a, //unsigned aSz,
94 const byte* c, unsigned cSz,
95 byte* s //, unsigned sSz
98 byte x[AES_BLOCK_SIZE] ALIGNED(4);
99 byte scratch[AES_BLOCK_SIZE] ALIGNED(4);
100 word32 blocks, partial;
101 //was: byte* h = aes->H;
103 //XMEMSET(x, 0, AES_BLOCK_SIZE);
105 /* Hash in A, the Additional Authentication Data */
106 // if (aSz != 0 && a != NULL) {
107 // blocks = aSz / AES_BLOCK_SIZE;
108 // partial = aSz % AES_BLOCK_SIZE;
109 // while (blocks--) {
110 //xorbuf(x, a, AES_BLOCK_SIZE);
111 XMEMCPY(x, a, AES_BLOCK_SIZE);// memcpy(x,a) = memset(x,0)+xorbuf(x,a)
113 // a += AES_BLOCK_SIZE;
115 // if (partial != 0) {
116 // XMEMSET(scratch, 0, AES_BLOCK_SIZE);
117 // XMEMCPY(scratch, a, partial);
118 // xorbuf(x, scratch, AES_BLOCK_SIZE);
123 /* Hash in C, the Ciphertext */
124 if (cSz != 0 /*&& c != NULL*/) {
125 blocks = cSz / AES_BLOCK_SIZE;
126 partial = cSz % AES_BLOCK_SIZE;
128 xorbuf(x, c, AES_BLOCK_SIZE);
133 XMEMSET(scratch, 0, AES_BLOCK_SIZE);
134 XMEMCPY(scratch, c, partial);
135 xorbuf(x, scratch, AES_BLOCK_SIZE);
140 /* Hash in the lengths of A and C in bits */
141 FlattenSzInBits(&scratch[0], aSz);
142 FlattenSzInBits(&scratch[8], cSz);
143 xorbuf(x, scratch, AES_BLOCK_SIZE);
146 /* Copy the result into s. */