tls: typo fix in comment
[oweals/busybox.git] / networking / tls_aesgcm.c
1 /*
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
9 typedef uint8_t byte;
10 typedef uint32_t word32;
11 #define XMEMSET memset
12 #define XMEMCPY memcpy
13
14 void FAST_FUNC xorbuf(void* buf, const void* mask, unsigned count)
15 {
16     word32 i;
17     byte*       b = (byte*)buf;
18     const byte* m = (const byte*)mask;
19     for (i = 0; i < count; i++)
20         b[i] ^= m[i];
21 }
22
23 /* from wolfssl-3.15.3/wolfcrypt/src/aes.c */
24
25 static ALWAYS_INLINE void FlattenSzInBits(byte* buf, word32 sz)
26 {
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));
30     sz <<= 3;
31
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);
43 }
44
45 static void RIGHTSHIFTX(byte* x)
46 {
47     int i;
48     int carryOut = 0;
49     int carryIn = 0;
50     int borrow = x[15] & 0x01;
51
52     for (i = 0; i < AES_BLOCK_SIZE; i++) {
53         carryOut = x[i] & 0x01;
54         x[i] = (x[i] >> 1) | (carryIn ? 0x80 : 0);
55         carryIn = carryOut;
56     }
57     if (borrow) x[0] ^= 0xE1;
58 }
59
60 static void GMULT(byte* X, byte* Y)
61 {
62     byte Z[AES_BLOCK_SIZE];
63     byte V[AES_BLOCK_SIZE];
64     int i, j;
65
66     XMEMSET(Z, 0, AES_BLOCK_SIZE);
67     XMEMCPY(V, X, AES_BLOCK_SIZE);
68     for (i = 0; i < AES_BLOCK_SIZE; i++)
69     {
70         byte y = Y[i];
71         for (j = 0; j < 8; j++)
72         {
73             if (y & 0x80) {
74                 xorbuf(Z, V, AES_BLOCK_SIZE);
75             }
76
77             RIGHTSHIFTX(V);
78             y = y << 1;
79         }
80     }
81     XMEMCPY(X, Z, AES_BLOCK_SIZE);
82 }
83
84 //bbox:
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.
88 //
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
96 )
97 {
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;
102
103     //XMEMSET(x, 0, AES_BLOCK_SIZE);
104
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)
112             GMULT(x, h);
113 //            a += AES_BLOCK_SIZE;
114 //        }
115 //        if (partial != 0) {
116 //            XMEMSET(scratch, 0, AES_BLOCK_SIZE);
117 //            XMEMCPY(scratch, a, partial);
118 //            xorbuf(x, scratch, AES_BLOCK_SIZE);
119 //            GMULT(x, h);
120 //        }
121 //    }
122
123     /* Hash in C, the Ciphertext */
124     if (cSz != 0 /*&& c != NULL*/) {
125         blocks = cSz / AES_BLOCK_SIZE;
126         partial = cSz % AES_BLOCK_SIZE;
127         while (blocks--) {
128             xorbuf(x, c, AES_BLOCK_SIZE);
129             GMULT(x, h);
130             c += AES_BLOCK_SIZE;
131         }
132         if (partial != 0) {
133             XMEMSET(scratch, 0, AES_BLOCK_SIZE);
134             XMEMCPY(scratch, c, partial);
135             xorbuf(x, scratch, AES_BLOCK_SIZE);
136             GMULT(x, h);
137         }
138     }
139
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);
144     GMULT(x, h);
145
146     /* Copy the result into s. */
147     XMEMCPY(s, x, sSz);
148 }