1
2
3
4
5
6
7#include "tls.h"
8
9typedef uint8_t byte;
10typedef uint32_t word32;
11#define XMEMSET memset
12#define XMEMCPY memcpy
13
14
15
16#ifdef UNUSED
17static ALWAYS_INLINE void FlattenSzInBits(byte* buf, word32 sz)
18{
19
20
21
22 sz <<= 3;
23
24
25
26
27
28
29 *(uint32_t*)(buf + 0) = 0;
30
31
32
33
34 *(uint32_t*)(buf + 4) = SWAP_BE32(sz);
35}
36#endif
37
38static void RIGHTSHIFTX(byte* x)
39{
40#define l ((unsigned long*)x)
41#if 0
42
43
44 int i;
45 byte carryIn = (x[15] & 0x01) ? 0xE1 : 0;
46 for (i = 0; i < AES_BLOCK_SIZE; i++) {
47 byte carryOut = (x[i] << 7);
48 x[i] = (x[i] >> 1) ^ carryIn;
49 carryIn = carryOut;
50 }
51
52#elif BB_BIG_ENDIAN
53
54
55
56 unsigned long carryIn = (x[15] & 0x01)
57 ? ((unsigned long)0xE1 << (LONG_BIT-8))
58 : 0;
59# if ULONG_MAX <= 0xffffffff
60 int i;
61 for (i = 0; i < AES_BLOCK_SIZE/sizeof(long); i++) {
62 unsigned long carryOut = l[i] << (LONG_BIT-1);
63 l[i] = (l[i] >> 1) ^ carryIn;
64 carryIn = carryOut;
65 }
66# else
67
68 unsigned long carryOut = l[0] << (LONG_BIT-1);
69 l[0] = (l[0] >> 1) ^ carryIn;
70 l[1] = (l[1] >> 1) ^ carryOut;
71# endif
72
73#else
74
75
76
77 unsigned long carryIn = (x[15] & 0x01)
78 ? ((unsigned long)0xE1 << (LONG_BIT-8))
79 : 0;
80# if ULONG_MAX <= 0xffffffff
81 int i;
82 for (i = 0; i < AES_BLOCK_SIZE/sizeof(long); i++) {
83 unsigned long ti = SWAP_BE32(l[i]);
84 unsigned long carryOut = ti << (LONG_BIT-1);
85 ti = (ti >> 1) ^ carryIn;
86 l[i] = SWAP_BE32(ti);
87 carryIn = carryOut;
88 }
89# else
90
91 unsigned long tt = SWAP_BE64(l[0]);
92 unsigned long carryOut = tt << (LONG_BIT-1);
93 tt = (tt >> 1) ^ carryIn; l[0] = SWAP_BE64(tt);
94 tt = SWAP_BE64(l[1]);
95 tt = (tt >> 1) ^ carryOut; l[1] = SWAP_BE64(tt);
96# endif
97
98#endif
99#undef l
100}
101
102
103static void GMULT(byte* X, byte* Y)
104{
105 byte Z[AES_BLOCK_SIZE] ALIGNED_long;
106
107 int i;
108
109 XMEMSET(Z, 0, AES_BLOCK_SIZE);
110
111 for (i = 0; i < AES_BLOCK_SIZE; i++) {
112 uint32_t y = 0x800000 | Y[i];
113 for (;;) {
114 if (y & 0x80) {
115 xorbuf_aligned_AES_BLOCK_SIZE(Z, X);
116 }
117 RIGHTSHIFTX(X);
118 y = y << 1;
119 if ((int32_t)y < 0)
120 break;
121 }
122 }
123 XMEMCPY(X, Z, AES_BLOCK_SIZE);
124}
125
126
127
128
129
130
131
132#define aSz 13
133#define sSz AES_BLOCK_SIZE
134void FAST_FUNC aesgcm_GHASH(byte* h,
135 const byte* a,
136 const byte* c, unsigned cSz,
137 byte* s
138)
139{
140 byte x[AES_BLOCK_SIZE] ALIGNED_long;
141
142 unsigned blocks, partial;
143
144
145
146
147
148
149
150
151
152
153 XMEMCPY(x, a, AES_BLOCK_SIZE);
154 GMULT(x, h);
155
156
157
158
159
160
161
162
163
164
165
166 if (cSz != 0 ) {
167 blocks = cSz / AES_BLOCK_SIZE;
168 partial = cSz % AES_BLOCK_SIZE;
169 while (blocks--) {
170 if (BB_UNALIGNED_MEMACCESS_OK)
171 xorbuf_aligned_AES_BLOCK_SIZE(x, c);
172 else
173 xorbuf(x, c, AES_BLOCK_SIZE);
174 GMULT(x, h);
175 c += AES_BLOCK_SIZE;
176 }
177 if (partial != 0) {
178
179
180
181 xorbuf(x, c, partial);
182 GMULT(x, h);
183 }
184 }
185
186
187
188
189
190
191#define P32(v) ((uint32_t*)v)
192
193 P32(x)[1] ^= SWAP_BE32(aSz * 8);
194
195 P32(x)[3] ^= SWAP_BE32(cSz * 8);
196#undef P32
197
198 GMULT(x, h);
199
200
201 XMEMCPY(s, x, sSz);
202}
203