blob: a4663cd7945521c785ad39409a0d72a00947089f [file] [log] [blame]
Denys Vlasenko83e5c622018-11-23 17:21:38 +01001/*
2 * Copyright (C) 2018 Denys Vlasenko
3 *
4 * Licensed under GPLv2, see file LICENSE in this source tree.
5 */
6
7#include "tls.h"
8
9typedef uint8_t byte;
10typedef uint32_t word32;
11#define XMEMSET memset
12#define XMEMCPY memcpy
13
Denys Vlasenkoecc90902018-11-23 18:31:26 +010014/* from wolfssl-3.15.3/wolfcrypt/src/aes.c */
Denys Vlasenko83e5c622018-11-23 17:21:38 +010015
Denys Vlasenkoecc90902018-11-23 18:31:26 +010016static ALWAYS_INLINE void FlattenSzInBits(byte* buf, word32 sz)
Denys Vlasenko83e5c622018-11-23 17:21:38 +010017{
18 /* Multiply the sz by 8 */
Denys Vlasenkoecc90902018-11-23 18:31:26 +010019//bbox: these sizes are never even close to 2^32/8
20// word32 szHi = (sz >> (8*sizeof(sz) - 3));
Denys Vlasenko83e5c622018-11-23 17:21:38 +010021 sz <<= 3;
22
23 /* copy over the words of the sz into the destination buffer */
Denys Vlasenkoecc90902018-11-23 18:31:26 +010024// buf[0] = (szHi >> 24) & 0xff;
25// buf[1] = (szHi >> 16) & 0xff;
26// buf[2] = (szHi >> 8) & 0xff;
27// buf[3] = szHi & 0xff;
Denys Vlasenko25569c32018-11-23 18:55:15 +010028 *(uint32_t*)(buf + 0) = 0;
Denys Vlasenkoecc90902018-11-23 18:31:26 +010029// buf[4] = (sz >> 24) & 0xff;
30// buf[5] = (sz >> 16) & 0xff;
31// buf[6] = (sz >> 8) & 0xff;
32// buf[7] = sz & 0xff;
Denys Vlasenko25569c32018-11-23 18:55:15 +010033 *(uint32_t*)(buf + 4) = SWAP_BE32(sz);
Denys Vlasenko83e5c622018-11-23 17:21:38 +010034}
35
36static void RIGHTSHIFTX(byte* x)
37{
Denys Vlasenko9f00a0f2018-12-08 13:34:43 +010038#define l ((unsigned long*)x)
39#if 0
Denys Vlasenko83e5c622018-11-23 17:21:38 +010040
Denys Vlasenko9f00a0f2018-12-08 13:34:43 +010041 // Generic byte-at-a-time algorithm
42 int i;
43 byte carryIn = (x[15] & 0x01) ? 0xE1 : 0;
Denys Vlasenko83e5c622018-11-23 17:21:38 +010044 for (i = 0; i < AES_BLOCK_SIZE; i++) {
Denys Vlasenko9f00a0f2018-12-08 13:34:43 +010045 byte carryOut = (x[i] << 7); // zero, or 0x80
46 x[i] = (x[i] >> 1) ^ carryIn;
Denys Vlasenko83e5c622018-11-23 17:21:38 +010047 carryIn = carryOut;
48 }
Denys Vlasenko9f00a0f2018-12-08 13:34:43 +010049
50#elif BB_BIG_ENDIAN
51
52 // Big-endian can shift-right in larger than byte chunks
53 // (we use the fact that 'x' is long-aligned)
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); // zero, or 0x800..00
61 l[i] = (l[i] >> 1) ^ carryIn;
62 carryIn = carryOut;
63 }
64# else
65 // 64-bit code: need to process only 2 words
66 unsigned long carryOut = l[0] << (LONG_BIT-1); // zero, or 0x800..00
67 l[0] = (l[0] >> 1) ^ carryIn;
68 l[1] = (l[1] >> 1) ^ carryOut;
69# endif
70
71#else /* LITTLE_ENDIAN */
72
73 // In order to use word-sized ops, little-endian needs to byteswap.
74 // On x86, code size increase is ~10 bytes compared to byte-by-byte.
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); // zero, or 0x800..00
83 ti = (ti >> 1) ^ carryIn;
84 l[i] = SWAP_BE32(ti);
85 carryIn = carryOut;
86 }
87# else
88 // 64-bit code: need to process only 2 words
89 unsigned long tt = SWAP_BE64(l[0]);
90 unsigned long carryOut = tt << (LONG_BIT-1); // zero, or 0x800..00
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 /* LITTLE_ENDIAN */
97#undef l
Denys Vlasenko83e5c622018-11-23 17:21:38 +010098}
99
Denys Vlasenko32ec5f12018-12-08 21:24:38 +0100100// Caller guarantees X is aligned
Denys Vlasenko83e5c622018-11-23 17:21:38 +0100101static void GMULT(byte* X, byte* Y)
102{
Denys Vlasenko03569bc2018-11-24 14:08:29 +0100103 byte Z[AES_BLOCK_SIZE] ALIGNED_long;
Denys Vlasenko32ec5f12018-12-08 21:24:38 +0100104 //byte V[AES_BLOCK_SIZE] ALIGNED_long;
105 int i;
Denys Vlasenko83e5c622018-11-23 17:21:38 +0100106
107 XMEMSET(Z, 0, AES_BLOCK_SIZE);
Denys Vlasenko32ec5f12018-12-08 21:24:38 +0100108 //XMEMCPY(V, X, AES_BLOCK_SIZE);
109 for (i = 0; i < AES_BLOCK_SIZE; i++) {
110 uint32_t y = 0x800000 | Y[i];
111 for (;;) { // for every bit in Y[i], from msb to lsb
Denys Vlasenko83e5c622018-11-23 17:21:38 +0100112 if (y & 0x80) {
Denys Vlasenko32ec5f12018-12-08 21:24:38 +0100113 xorbuf_aligned_AES_BLOCK_SIZE(Z, X); // was V, not X
Denys Vlasenko83e5c622018-11-23 17:21:38 +0100114 }
Denys Vlasenko32ec5f12018-12-08 21:24:38 +0100115 RIGHTSHIFTX(X); // was V, not X
Denys Vlasenko83e5c622018-11-23 17:21:38 +0100116 y = y << 1;
Denys Vlasenko32ec5f12018-12-08 21:24:38 +0100117 if ((int32_t)y < 0) // if bit 0x80000000 set = if 8 iterations done
118 break;
Denys Vlasenko83e5c622018-11-23 17:21:38 +0100119 }
120 }
121 XMEMCPY(X, Z, AES_BLOCK_SIZE);
122}
123
Denys Vlasenkoecc90902018-11-23 18:31:26 +0100124//bbox:
Denys Vlasenkod496b402018-11-23 19:00:12 +0100125// for TLS AES-GCM, a (which is AAD) is always 13 bytes long, and bbox code provides
Denys Vlasenkoecc90902018-11-23 18:31:26 +0100126// extra 3 zeroed bytes, making it a[16], or a[AES_BLOCK_SIZE].
Denys Vlasenkod496b402018-11-23 19:00:12 +0100127// Resulting auth tag in s[] is also always AES_BLOCK_SIZE bytes.
Denys Vlasenkoecc90902018-11-23 18:31:26 +0100128//
129// This allows some simplifications.
Denys Vlasenko985702c2018-11-24 13:47:44 +0100130#define aSz 13
Denys Vlasenkoecc90902018-11-23 18:31:26 +0100131#define sSz AES_BLOCK_SIZE
132void FAST_FUNC aesgcm_GHASH(byte* h,
133 const byte* a, //unsigned aSz,
134 const byte* c, unsigned cSz,
135 byte* s //, unsigned sSz
136)
Denys Vlasenko83e5c622018-11-23 17:21:38 +0100137{
Denys Vlasenko03569bc2018-11-24 14:08:29 +0100138 byte x[AES_BLOCK_SIZE] ALIGNED_long;
Denys Vlasenkobe5ca422018-11-25 14:03:59 +0100139// byte scratch[AES_BLOCK_SIZE] ALIGNED_long;
140 unsigned blocks, partial;
Denys Vlasenko83e5c622018-11-23 17:21:38 +0100141 //was: byte* h = aes->H;
142
Denys Vlasenkoecc90902018-11-23 18:31:26 +0100143 //XMEMSET(x, 0, AES_BLOCK_SIZE);
Denys Vlasenko83e5c622018-11-23 17:21:38 +0100144
145 /* Hash in A, the Additional Authentication Data */
Denys Vlasenkoecc90902018-11-23 18:31:26 +0100146// if (aSz != 0 && a != NULL) {
147// blocks = aSz / AES_BLOCK_SIZE;
148// partial = aSz % AES_BLOCK_SIZE;
149// while (blocks--) {
150 //xorbuf(x, a, AES_BLOCK_SIZE);
151 XMEMCPY(x, a, AES_BLOCK_SIZE);// memcpy(x,a) = memset(x,0)+xorbuf(x,a)
Denys Vlasenko83e5c622018-11-23 17:21:38 +0100152 GMULT(x, h);
Denys Vlasenkoecc90902018-11-23 18:31:26 +0100153// a += AES_BLOCK_SIZE;
154// }
155// if (partial != 0) {
156// XMEMSET(scratch, 0, AES_BLOCK_SIZE);
157// XMEMCPY(scratch, a, partial);
158// xorbuf(x, scratch, AES_BLOCK_SIZE);
159// GMULT(x, h);
160// }
161// }
Denys Vlasenko83e5c622018-11-23 17:21:38 +0100162
163 /* Hash in C, the Ciphertext */
Denys Vlasenkoecc90902018-11-23 18:31:26 +0100164 if (cSz != 0 /*&& c != NULL*/) {
Denys Vlasenko83e5c622018-11-23 17:21:38 +0100165 blocks = cSz / AES_BLOCK_SIZE;
166 partial = cSz % AES_BLOCK_SIZE;
167 while (blocks--) {
Denys Vlasenko23d0d8c2018-11-25 12:01:44 +0100168 if (BB_UNALIGNED_MEMACCESS_OK) // c is not guaranteed to be aligned
169 xorbuf_aligned_AES_BLOCK_SIZE(x, c);
170 else
171 xorbuf(x, c, AES_BLOCK_SIZE);
Denys Vlasenko83e5c622018-11-23 17:21:38 +0100172 GMULT(x, h);
173 c += AES_BLOCK_SIZE;
174 }
175 if (partial != 0) {
Denys Vlasenkofbf5e632018-11-23 19:07:05 +0100176 //XMEMSET(scratch, 0, AES_BLOCK_SIZE);
177 //XMEMCPY(scratch, c, partial);
178 //xorbuf(x, scratch, AES_BLOCK_SIZE);
Denys Vlasenko03569bc2018-11-24 14:08:29 +0100179 xorbuf(x, c, partial);//same result as above
Denys Vlasenko83e5c622018-11-23 17:21:38 +0100180 GMULT(x, h);
181 }
182 }
183
184 /* Hash in the lengths of A and C in bits */
Denys Vlasenkobe5ca422018-11-25 14:03:59 +0100185 //FlattenSzInBits(&scratch[0], aSz);
186 //FlattenSzInBits(&scratch[8], cSz);
187 //xorbuf_aligned_AES_BLOCK_SIZE(x, scratch);
188 // simpler:
189#define P32(v) ((uint32_t*)v)
190 //P32(x)[0] ^= 0;
191 P32(x)[1] ^= SWAP_BE32(aSz * 8);
192 //P32(x)[2] ^= 0;
193 P32(x)[3] ^= SWAP_BE32(cSz * 8);
194#undef P32
195
Denys Vlasenko83e5c622018-11-23 17:21:38 +0100196 GMULT(x, h);
197
198 /* Copy the result into s. */
199 XMEMCPY(s, x, sSz);
200}