blob: 688df85fb619148d07c37adbd14ac92cd56770ff [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{
38 int i;
39 int carryOut = 0;
40 int carryIn = 0;
41 int borrow = x[15] & 0x01;
42
43 for (i = 0; i < AES_BLOCK_SIZE; i++) {
44 carryOut = x[i] & 0x01;
45 x[i] = (x[i] >> 1) | (carryIn ? 0x80 : 0);
46 carryIn = carryOut;
47 }
48 if (borrow) x[0] ^= 0xE1;
49}
50
51static void GMULT(byte* X, byte* Y)
52{
Denys Vlasenko03569bc2018-11-24 14:08:29 +010053 byte Z[AES_BLOCK_SIZE] ALIGNED_long;
54 byte V[AES_BLOCK_SIZE] ALIGNED_long;
Denys Vlasenko83e5c622018-11-23 17:21:38 +010055 int i, j;
56
57 XMEMSET(Z, 0, AES_BLOCK_SIZE);
58 XMEMCPY(V, X, AES_BLOCK_SIZE);
59 for (i = 0; i < AES_BLOCK_SIZE; i++)
60 {
61 byte y = Y[i];
62 for (j = 0; j < 8; j++)
63 {
64 if (y & 0x80) {
Denys Vlasenko03569bc2018-11-24 14:08:29 +010065 xorbuf_aligned_AES_BLOCK_SIZE(Z, V);
Denys Vlasenko83e5c622018-11-23 17:21:38 +010066 }
67
68 RIGHTSHIFTX(V);
69 y = y << 1;
70 }
71 }
72 XMEMCPY(X, Z, AES_BLOCK_SIZE);
73}
74
Denys Vlasenkoecc90902018-11-23 18:31:26 +010075//bbox:
Denys Vlasenkod496b402018-11-23 19:00:12 +010076// for TLS AES-GCM, a (which is AAD) is always 13 bytes long, and bbox code provides
Denys Vlasenkoecc90902018-11-23 18:31:26 +010077// extra 3 zeroed bytes, making it a[16], or a[AES_BLOCK_SIZE].
Denys Vlasenkod496b402018-11-23 19:00:12 +010078// Resulting auth tag in s[] is also always AES_BLOCK_SIZE bytes.
Denys Vlasenkoecc90902018-11-23 18:31:26 +010079//
80// This allows some simplifications.
Denys Vlasenko985702c2018-11-24 13:47:44 +010081#define aSz 13
Denys Vlasenkoecc90902018-11-23 18:31:26 +010082#define sSz AES_BLOCK_SIZE
83void FAST_FUNC aesgcm_GHASH(byte* h,
84 const byte* a, //unsigned aSz,
85 const byte* c, unsigned cSz,
86 byte* s //, unsigned sSz
87)
Denys Vlasenko83e5c622018-11-23 17:21:38 +010088{
Denys Vlasenko03569bc2018-11-24 14:08:29 +010089 byte x[AES_BLOCK_SIZE] ALIGNED_long;
Denys Vlasenkobe5ca422018-11-25 14:03:59 +010090// byte scratch[AES_BLOCK_SIZE] ALIGNED_long;
91 unsigned blocks, partial;
Denys Vlasenko83e5c622018-11-23 17:21:38 +010092 //was: byte* h = aes->H;
93
Denys Vlasenkoecc90902018-11-23 18:31:26 +010094 //XMEMSET(x, 0, AES_BLOCK_SIZE);
Denys Vlasenko83e5c622018-11-23 17:21:38 +010095
96 /* Hash in A, the Additional Authentication Data */
Denys Vlasenkoecc90902018-11-23 18:31:26 +010097// if (aSz != 0 && a != NULL) {
98// blocks = aSz / AES_BLOCK_SIZE;
99// partial = aSz % AES_BLOCK_SIZE;
100// while (blocks--) {
101 //xorbuf(x, a, AES_BLOCK_SIZE);
102 XMEMCPY(x, a, AES_BLOCK_SIZE);// memcpy(x,a) = memset(x,0)+xorbuf(x,a)
Denys Vlasenko83e5c622018-11-23 17:21:38 +0100103 GMULT(x, h);
Denys Vlasenkoecc90902018-11-23 18:31:26 +0100104// a += AES_BLOCK_SIZE;
105// }
106// if (partial != 0) {
107// XMEMSET(scratch, 0, AES_BLOCK_SIZE);
108// XMEMCPY(scratch, a, partial);
109// xorbuf(x, scratch, AES_BLOCK_SIZE);
110// GMULT(x, h);
111// }
112// }
Denys Vlasenko83e5c622018-11-23 17:21:38 +0100113
114 /* Hash in C, the Ciphertext */
Denys Vlasenkoecc90902018-11-23 18:31:26 +0100115 if (cSz != 0 /*&& c != NULL*/) {
Denys Vlasenko83e5c622018-11-23 17:21:38 +0100116 blocks = cSz / AES_BLOCK_SIZE;
117 partial = cSz % AES_BLOCK_SIZE;
118 while (blocks--) {
Denys Vlasenko23d0d8c2018-11-25 12:01:44 +0100119 if (BB_UNALIGNED_MEMACCESS_OK) // c is not guaranteed to be aligned
120 xorbuf_aligned_AES_BLOCK_SIZE(x, c);
121 else
122 xorbuf(x, c, AES_BLOCK_SIZE);
Denys Vlasenko83e5c622018-11-23 17:21:38 +0100123 GMULT(x, h);
124 c += AES_BLOCK_SIZE;
125 }
126 if (partial != 0) {
Denys Vlasenkofbf5e632018-11-23 19:07:05 +0100127 //XMEMSET(scratch, 0, AES_BLOCK_SIZE);
128 //XMEMCPY(scratch, c, partial);
129 //xorbuf(x, scratch, AES_BLOCK_SIZE);
Denys Vlasenko03569bc2018-11-24 14:08:29 +0100130 xorbuf(x, c, partial);//same result as above
Denys Vlasenko83e5c622018-11-23 17:21:38 +0100131 GMULT(x, h);
132 }
133 }
134
135 /* Hash in the lengths of A and C in bits */
Denys Vlasenkobe5ca422018-11-25 14:03:59 +0100136 //FlattenSzInBits(&scratch[0], aSz);
137 //FlattenSzInBits(&scratch[8], cSz);
138 //xorbuf_aligned_AES_BLOCK_SIZE(x, scratch);
139 // simpler:
140#define P32(v) ((uint32_t*)v)
141 //P32(x)[0] ^= 0;
142 P32(x)[1] ^= SWAP_BE32(aSz * 8);
143 //P32(x)[2] ^= 0;
144 P32(x)[3] ^= SWAP_BE32(cSz * 8);
145#undef P32
146
Denys Vlasenko83e5c622018-11-23 17:21:38 +0100147 GMULT(x, h);
148
149 /* Copy the result into s. */
150 XMEMCPY(s, x, sSz);
151}