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