blob: 442a614a3726bf499f2c166d205d13eec01ee6c8 [file] [log] [blame]
Larry Finger1b509ca2013-08-21 22:33:48 -05001/******************************************************************************
2 *
3 * Copyright(c) 2007 - 2011 Realtek Corporation. All rights reserved.
4 *
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms of version 2 of the GNU General Public License as
7 * published by the Free Software Foundation.
8 *
9 * This program is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
12 * more details.
13 *
Larry Finger1b509ca2013-08-21 22:33:48 -050014 ******************************************************************************/
15#define _RTW_SECURITY_C_
16
17#include <osdep_service.h>
18#include <drv_types.h>
19#include <wifi.h>
20#include <osdep_intf.h>
21
22/* WEP related ===== */
23
24#define CRC32_POLY 0x04c11db7
25
26struct arc4context {
27 u32 x;
28 u32 y;
29 u8 state[256];
30};
31
32static void arcfour_init(struct arc4context *parc4ctx, u8 *key, u32 key_len)
33{
34 u32 t, u;
35 u32 keyindex;
36 u32 stateindex;
37 u8 *state;
38 u32 counter;
Larry Finger1b509ca2013-08-21 22:33:48 -050039 state = parc4ctx->state;
40 parc4ctx->x = 0;
41 parc4ctx->y = 0;
42 for (counter = 0; counter < 256; counter++)
43 state[counter] = (u8)counter;
44 keyindex = 0;
45 stateindex = 0;
46 for (counter = 0; counter < 256; counter++) {
47 t = state[counter];
48 stateindex = (stateindex + key[keyindex] + t) & 0xff;
49 u = state[stateindex];
50 state[stateindex] = (u8)t;
51 state[counter] = (u8)u;
52 if (++keyindex >= key_len)
53 keyindex = 0;
54 }
Larry Finger1b509ca2013-08-21 22:33:48 -050055}
56
57static u32 arcfour_byte(struct arc4context *parc4ctx)
58{
59 u32 x;
60 u32 y;
61 u32 sx, sy;
62 u8 *state;
Larry Finger1b509ca2013-08-21 22:33:48 -050063 state = parc4ctx->state;
64 x = (parc4ctx->x + 1) & 0xff;
65 sx = state[x];
66 y = (sx + parc4ctx->y) & 0xff;
67 sy = state[y];
68 parc4ctx->x = x;
69 parc4ctx->y = y;
70 state[y] = (u8)sx;
71 state[x] = (u8)sy;
Larry Finger1b509ca2013-08-21 22:33:48 -050072 return state[(sx + sy) & 0xff];
73}
74
75static void arcfour_encrypt(struct arc4context *parc4ctx, u8 *dest, u8 *src, u32 len)
76{
77 u32 i;
Larry Finger1b509ca2013-08-21 22:33:48 -050078 for (i = 0; i < len; i++)
79 dest[i] = src[i] ^ (unsigned char)arcfour_byte(parc4ctx);
Larry Finger1b509ca2013-08-21 22:33:48 -050080}
81
82static int bcrc32initialized;
83static u32 crc32_table[256];
84
85static u8 crc32_reverseBit(u8 data)
86{
87 return (u8)((data<<7)&0x80) | ((data<<5)&0x40) | ((data<<3)&0x20) |
88 ((data<<1)&0x10) | ((data>>1)&0x08) | ((data>>3)&0x04) |
89 ((data>>5)&0x02) | ((data>>7)&0x01);
90}
91
92static void crc32_init(void)
93{
Larry Finger1b509ca2013-08-21 22:33:48 -050094 if (bcrc32initialized == 1) {
Larry Fingerf578b5d2014-02-09 15:15:59 -060095 return;
Larry Finger1b509ca2013-08-21 22:33:48 -050096 } else {
97 int i, j;
98 u32 c;
99 u8 *p = (u8 *)&c, *p1;
100 u8 k;
101
102 c = 0x12340000;
103
104 for (i = 0; i < 256; ++i) {
105 k = crc32_reverseBit((u8)i);
106 for (c = ((u32)k) << 24, j = 8; j > 0; --j)
107 c = c & 0x80000000 ? (c << 1) ^ CRC32_POLY : (c << 1);
108 p1 = (u8 *)&crc32_table[i];
109
110 p1[0] = crc32_reverseBit(p[3]);
111 p1[1] = crc32_reverseBit(p[2]);
112 p1[2] = crc32_reverseBit(p[1]);
113 p1[3] = crc32_reverseBit(p[0]);
114 }
115 bcrc32initialized = 1;
116 }
Larry Finger1b509ca2013-08-21 22:33:48 -0500117}
118
119static __le32 getcrc32(u8 *buf, int len)
120{
121 u8 *p;
122 u32 crc;
Larry Finger1b509ca2013-08-21 22:33:48 -0500123 if (bcrc32initialized == 0)
124 crc32_init();
125
126 crc = 0xffffffff; /* preload shift register, per CRC-32 spec */
127
128 for (p = buf; len > 0; ++p, --len)
129 crc = crc32_table[(crc ^ *p) & 0xff] ^ (crc >> 8);
Larry Finger1b509ca2013-08-21 22:33:48 -0500130 return cpu_to_le32(~crc); /* transmit complement, per CRC-32 spec */
131}
132
133/*
134 Need to consider the fragment situation
135*/
136void rtw_wep_encrypt(struct adapter *padapter, u8 *pxmitframe)
137{ /* exclude ICV */
138
139 unsigned char crc[4];
140 struct arc4context mycontext;
141
142 int curfragnum, length;
143 u32 keylength;
144
145 u8 *pframe, *payload, *iv; /* wepkey */
146 u8 wepkey[16];
147 u8 hw_hdr_offset = 0;
148 struct pkt_attrib *pattrib = &((struct xmit_frame *)pxmitframe)->attrib;
149 struct security_priv *psecuritypriv = &padapter->securitypriv;
150 struct xmit_priv *pxmitpriv = &padapter->xmitpriv;
151
Larry Finger1b509ca2013-08-21 22:33:48 -0500152
153 if (((struct xmit_frame *)pxmitframe)->buf_addr == NULL)
154 return;
155
156 hw_hdr_offset = TXDESC_SIZE +
157 (((struct xmit_frame *)pxmitframe)->pkt_offset * PACKET_OFFSET_SZ);
158
159 pframe = ((struct xmit_frame *)pxmitframe)->buf_addr + hw_hdr_offset;
160
161 /* start to encrypt each fragment */
162 if ((pattrib->encrypt == _WEP40_) || (pattrib->encrypt == _WEP104_)) {
163 keylength = psecuritypriv->dot11DefKeylen[psecuritypriv->dot11PrivacyKeyIndex];
164
165 for (curfragnum = 0; curfragnum < pattrib->nr_frags; curfragnum++) {
166 iv = pframe+pattrib->hdrlen;
167 memcpy(&wepkey[0], iv, 3);
168 memcpy(&wepkey[3], &psecuritypriv->dot11DefKey[psecuritypriv->dot11PrivacyKeyIndex].skey[0], keylength);
169 payload = pframe+pattrib->iv_len+pattrib->hdrlen;
170
171 if ((curfragnum+1) == pattrib->nr_frags) { /* the last fragment */
172 length = pattrib->last_txcmdsz-pattrib->hdrlen-pattrib->iv_len-pattrib->icv_len;
173
174 *((__le32 *)crc) = getcrc32(payload, length);
175
176 arcfour_init(&mycontext, wepkey, 3+keylength);
177 arcfour_encrypt(&mycontext, payload, payload, length);
178 arcfour_encrypt(&mycontext, payload+length, crc, 4);
179 } else {
180 length = pxmitpriv->frag_len-pattrib->hdrlen-pattrib->iv_len-pattrib->icv_len;
181 *((__le32 *)crc) = getcrc32(payload, length);
182 arcfour_init(&mycontext, wepkey, 3+keylength);
183 arcfour_encrypt(&mycontext, payload, payload, length);
184 arcfour_encrypt(&mycontext, payload+length, crc, 4);
185
186 pframe += pxmitpriv->frag_len;
Jia He7be921a22014-11-04 09:39:58 +0800187 pframe = (u8 *)round_up((size_t)(pframe), 4);
Larry Finger1b509ca2013-08-21 22:33:48 -0500188 }
189 }
190 }
191
Larry Finger1b509ca2013-08-21 22:33:48 -0500192}
193
194void rtw_wep_decrypt(struct adapter *padapter, u8 *precvframe)
195{
196 /* exclude ICV */
197 u8 crc[4];
198 struct arc4context mycontext;
199 int length;
200 u32 keylength;
201 u8 *pframe, *payload, *iv, wepkey[16];
202 u8 keyindex;
Larry Fingerf31cca82014-02-14 16:54:07 -0600203 struct rx_pkt_attrib *prxattrib = &(((struct recv_frame *)precvframe)->attrib);
Larry Finger1b509ca2013-08-21 22:33:48 -0500204 struct security_priv *psecuritypriv = &padapter->securitypriv;
205
Larry Finger1b509ca2013-08-21 22:33:48 -0500206
Larry Fingerf31cca82014-02-14 16:54:07 -0600207 pframe = (unsigned char *)((struct recv_frame *)precvframe)->rx_data;
Larry Finger1b509ca2013-08-21 22:33:48 -0500208
209 /* start to decrypt recvframe */
210 if ((prxattrib->encrypt == _WEP40_) || (prxattrib->encrypt == _WEP104_)) {
211 iv = pframe+prxattrib->hdrlen;
212 keyindex = prxattrib->key_index;
213 keylength = psecuritypriv->dot11DefKeylen[keyindex];
214 memcpy(&wepkey[0], iv, 3);
215 memcpy(&wepkey[3], &psecuritypriv->dot11DefKey[keyindex].skey[0], keylength);
Larry Fingerf31cca82014-02-14 16:54:07 -0600216 length = ((struct recv_frame *)precvframe)->len-prxattrib->hdrlen-prxattrib->iv_len;
Larry Finger1b509ca2013-08-21 22:33:48 -0500217
218 payload = pframe+prxattrib->iv_len+prxattrib->hdrlen;
219
220 /* decrypt payload include icv */
221 arcfour_init(&mycontext, wepkey, 3+keylength);
222 arcfour_encrypt(&mycontext, payload, payload, length);
223
224 /* calculate icv and compare the icv */
225 *((__le32 *)crc) = getcrc32(payload, length - 4);
226
227 if (crc[3] != payload[length-1] ||
228 crc[2] != payload[length-2] ||
229 crc[1] != payload[length-3] ||
230 crc[0] != payload[length-4]) {
231 RT_TRACE(_module_rtl871x_security_c_, _drv_err_,
232 ("rtw_wep_decrypt:icv error crc (%4ph)!=payload (%4ph)\n",
233 &crc, &payload[length-4]));
234 }
235 }
Larry Finger1b509ca2013-08-21 22:33:48 -0500236 return;
237}
238
239/* 3 ===== TKIP related ===== */
240
241static u32 secmicgetuint32(u8 *p)
242/* Convert from Byte[] to Us3232 in a portable way */
243{
244 s32 i;
245 u32 res = 0;
Larry Finger1b509ca2013-08-21 22:33:48 -0500246 for (i = 0; i < 4; i++)
247 res |= ((u32)(*p++)) << (8*i);
Larry Finger1b509ca2013-08-21 22:33:48 -0500248 return res;
249}
250
251static void secmicputuint32(u8 *p, u32 val)
252/* Convert from Us3232 to Byte[] in a portable way */
253{
254 long i;
Larry Finger1b509ca2013-08-21 22:33:48 -0500255 for (i = 0; i < 4; i++) {
Jia He7be921a22014-11-04 09:39:58 +0800256 *p++ = (u8)(val & 0xff);
Larry Finger1b509ca2013-08-21 22:33:48 -0500257 val >>= 8;
258 }
Larry Finger1b509ca2013-08-21 22:33:48 -0500259}
260
261static void secmicclear(struct mic_data *pmicdata)
262{
263/* Reset the state to the empty message. */
Larry Finger1b509ca2013-08-21 22:33:48 -0500264 pmicdata->L = pmicdata->K0;
265 pmicdata->R = pmicdata->K1;
266 pmicdata->nBytesInM = 0;
267 pmicdata->M = 0;
Larry Finger1b509ca2013-08-21 22:33:48 -0500268}
269
270void rtw_secmicsetkey(struct mic_data *pmicdata, u8 *key)
271{
272 /* Set the key */
Larry Finger1b509ca2013-08-21 22:33:48 -0500273 pmicdata->K0 = secmicgetuint32(key);
274 pmicdata->K1 = secmicgetuint32(key + 4);
275 /* and reset the message */
276 secmicclear(pmicdata);
Larry Finger1b509ca2013-08-21 22:33:48 -0500277}
278
279void rtw_secmicappendbyte(struct mic_data *pmicdata, u8 b)
280{
Larry Finger1b509ca2013-08-21 22:33:48 -0500281 /* Append the byte to our word-sized buffer */
282 pmicdata->M |= ((unsigned long)b) << (8*pmicdata->nBytesInM);
283 pmicdata->nBytesInM++;
284 /* Process the word if it is full. */
285 if (pmicdata->nBytesInM >= 4) {
286 pmicdata->L ^= pmicdata->M;
287 pmicdata->R ^= ROL32(pmicdata->L, 17);
288 pmicdata->L += pmicdata->R;
289 pmicdata->R ^= ((pmicdata->L & 0xff00ff00) >> 8) | ((pmicdata->L & 0x00ff00ff) << 8);
290 pmicdata->L += pmicdata->R;
291 pmicdata->R ^= ROL32(pmicdata->L, 3);
292 pmicdata->L += pmicdata->R;
293 pmicdata->R ^= ROR32(pmicdata->L, 2);
294 pmicdata->L += pmicdata->R;
295 /* Clear the buffer */
296 pmicdata->M = 0;
297 pmicdata->nBytesInM = 0;
298 }
Larry Finger1b509ca2013-08-21 22:33:48 -0500299}
300
301void rtw_secmicappend(struct mic_data *pmicdata, u8 *src, u32 nbytes)
302{
Larry Finger1b509ca2013-08-21 22:33:48 -0500303 /* This is simple */
304 while (nbytes > 0) {
305 rtw_secmicappendbyte(pmicdata, *src++);
306 nbytes--;
307 }
Larry Finger1b509ca2013-08-21 22:33:48 -0500308}
309
310void rtw_secgetmic(struct mic_data *pmicdata, u8 *dst)
311{
Larry Finger1b509ca2013-08-21 22:33:48 -0500312 /* Append the minimum padding */
313 rtw_secmicappendbyte(pmicdata, 0x5a);
314 rtw_secmicappendbyte(pmicdata, 0);
315 rtw_secmicappendbyte(pmicdata, 0);
316 rtw_secmicappendbyte(pmicdata, 0);
317 rtw_secmicappendbyte(pmicdata, 0);
318 /* and then zeroes until the length is a multiple of 4 */
319 while (pmicdata->nBytesInM != 0)
320 rtw_secmicappendbyte(pmicdata, 0);
321 /* The appendByte function has already computed the result. */
322 secmicputuint32(dst, pmicdata->L);
323 secmicputuint32(dst+4, pmicdata->R);
324 /* Reset to the empty message. */
325 secmicclear(pmicdata);
Larry Finger1b509ca2013-08-21 22:33:48 -0500326}
327
328void rtw_seccalctkipmic(u8 *key, u8 *header, u8 *data, u32 data_len, u8 *mic_code, u8 pri)
329{
330 struct mic_data micdata;
331 u8 priority[4] = {0x0, 0x0, 0x0, 0x0};
Larry Finger1b509ca2013-08-21 22:33:48 -0500332 rtw_secmicsetkey(&micdata, key);
333 priority[0] = pri;
334
335 /* Michael MIC pseudo header: DA, SA, 3 x 0, Priority */
336 if (header[1]&1) { /* ToDS == 1 */
337 rtw_secmicappend(&micdata, &header[16], 6); /* DA */
338 if (header[1]&2) /* From Ds == 1 */
339 rtw_secmicappend(&micdata, &header[24], 6);
340 else
341 rtw_secmicappend(&micdata, &header[10], 6);
342 } else { /* ToDS == 0 */
343 rtw_secmicappend(&micdata, &header[4], 6); /* DA */
344 if (header[1]&2) /* From Ds == 1 */
345 rtw_secmicappend(&micdata, &header[16], 6);
346 else
347 rtw_secmicappend(&micdata, &header[10], 6);
348 }
349 rtw_secmicappend(&micdata, &priority[0], 4);
350
351 rtw_secmicappend(&micdata, data, data_len);
352
353 rtw_secgetmic(&micdata, mic_code);
Larry Finger1b509ca2013-08-21 22:33:48 -0500354}
355
356
357
358/* macros for extraction/creation of unsigned char/unsigned short values */
359#define RotR1(v16) ((((v16) >> 1) & 0x7FFF) ^ (((v16) & 1) << 15))
360#define Lo8(v16) ((u8)((v16) & 0x00FF))
361#define Hi8(v16) ((u8)(((v16) >> 8) & 0x00FF))
362#define Lo16(v32) ((u16)((v32) & 0xFFFF))
363#define Hi16(v32) ((u16)(((v32) >> 16) & 0xFFFF))
364#define Mk16(hi, lo) ((lo) ^ (((u16)(hi)) << 8))
365
366/* select the Nth 16-bit word of the temporal key unsigned char array TK[] */
367#define TK16(N) Mk16(tk[2*(N)+1], tk[2*(N)])
368
369/* S-box lookup: 16 bits --> 16 bits */
370#define _S_(v16) (Sbox1[0][Lo8(v16)] ^ Sbox1[1][Hi8(v16)])
371
372/* fixed algorithm "parameters" */
373#define PHASE1_LOOP_CNT 8 /* this needs to be "big enough" */
374#define TA_SIZE 6 /* 48-bit transmitter address */
375#define TK_SIZE 16 /* 128-bit temporal key */
376#define P1K_SIZE 10 /* 80-bit Phase1 key */
377#define RC4_KEY_SIZE 16 /* 128-bit RC4KEY (104 bits unknown) */
378
379/* 2-unsigned char by 2-unsigned char subset of the full AES S-box table */
380static const unsigned short Sbox1[2][256] = { /* Sbox for hash (can be in ROM) */
381{
382 0xC6A5, 0xF884, 0xEE99, 0xF68D, 0xFF0D, 0xD6BD, 0xDEB1, 0x9154,
383 0x6050, 0x0203, 0xCEA9, 0x567D, 0xE719, 0xB562, 0x4DE6, 0xEC9A,
384 0x8F45, 0x1F9D, 0x8940, 0xFA87, 0xEF15, 0xB2EB, 0x8EC9, 0xFB0B,
385 0x41EC, 0xB367, 0x5FFD, 0x45EA, 0x23BF, 0x53F7, 0xE496, 0x9B5B,
386 0x75C2, 0xE11C, 0x3DAE, 0x4C6A, 0x6C5A, 0x7E41, 0xF502, 0x834F,
387 0x685C, 0x51F4, 0xD134, 0xF908, 0xE293, 0xAB73, 0x6253, 0x2A3F,
388 0x080C, 0x9552, 0x4665, 0x9D5E, 0x3028, 0x37A1, 0x0A0F, 0x2FB5,
389 0x0E09, 0x2436, 0x1B9B, 0xDF3D, 0xCD26, 0x4E69, 0x7FCD, 0xEA9F,
390 0x121B, 0x1D9E, 0x5874, 0x342E, 0x362D, 0xDCB2, 0xB4EE, 0x5BFB,
391 0xA4F6, 0x764D, 0xB761, 0x7DCE, 0x527B, 0xDD3E, 0x5E71, 0x1397,
392 0xA6F5, 0xB968, 0x0000, 0xC12C, 0x4060, 0xE31F, 0x79C8, 0xB6ED,
393 0xD4BE, 0x8D46, 0x67D9, 0x724B, 0x94DE, 0x98D4, 0xB0E8, 0x854A,
394 0xBB6B, 0xC52A, 0x4FE5, 0xED16, 0x86C5, 0x9AD7, 0x6655, 0x1194,
395 0x8ACF, 0xE910, 0x0406, 0xFE81, 0xA0F0, 0x7844, 0x25BA, 0x4BE3,
396 0xA2F3, 0x5DFE, 0x80C0, 0x058A, 0x3FAD, 0x21BC, 0x7048, 0xF104,
397 0x63DF, 0x77C1, 0xAF75, 0x4263, 0x2030, 0xE51A, 0xFD0E, 0xBF6D,
398 0x814C, 0x1814, 0x2635, 0xC32F, 0xBEE1, 0x35A2, 0x88CC, 0x2E39,
399 0x9357, 0x55F2, 0xFC82, 0x7A47, 0xC8AC, 0xBAE7, 0x322B, 0xE695,
400 0xC0A0, 0x1998, 0x9ED1, 0xA37F, 0x4466, 0x547E, 0x3BAB, 0x0B83,
401 0x8CCA, 0xC729, 0x6BD3, 0x283C, 0xA779, 0xBCE2, 0x161D, 0xAD76,
402 0xDB3B, 0x6456, 0x744E, 0x141E, 0x92DB, 0x0C0A, 0x486C, 0xB8E4,
403 0x9F5D, 0xBD6E, 0x43EF, 0xC4A6, 0x39A8, 0x31A4, 0xD337, 0xF28B,
404 0xD532, 0x8B43, 0x6E59, 0xDAB7, 0x018C, 0xB164, 0x9CD2, 0x49E0,
405 0xD8B4, 0xACFA, 0xF307, 0xCF25, 0xCAAF, 0xF48E, 0x47E9, 0x1018,
406 0x6FD5, 0xF088, 0x4A6F, 0x5C72, 0x3824, 0x57F1, 0x73C7, 0x9751,
407 0xCB23, 0xA17C, 0xE89C, 0x3E21, 0x96DD, 0x61DC, 0x0D86, 0x0F85,
408 0xE090, 0x7C42, 0x71C4, 0xCCAA, 0x90D8, 0x0605, 0xF701, 0x1C12,
409 0xC2A3, 0x6A5F, 0xAEF9, 0x69D0, 0x1791, 0x9958, 0x3A27, 0x27B9,
410 0xD938, 0xEB13, 0x2BB3, 0x2233, 0xD2BB, 0xA970, 0x0789, 0x33A7,
411 0x2DB6, 0x3C22, 0x1592, 0xC920, 0x8749, 0xAAFF, 0x5078, 0xA57A,
412 0x038F, 0x59F8, 0x0980, 0x1A17, 0x65DA, 0xD731, 0x84C6, 0xD0B8,
413 0x82C3, 0x29B0, 0x5A77, 0x1E11, 0x7BCB, 0xA8FC, 0x6DD6, 0x2C3A,
414 },
415
416 { /* second half of table is unsigned char-reversed version of first! */
417 0xA5C6, 0x84F8, 0x99EE, 0x8DF6, 0x0DFF, 0xBDD6, 0xB1DE, 0x5491,
418 0x5060, 0x0302, 0xA9CE, 0x7D56, 0x19E7, 0x62B5, 0xE64D, 0x9AEC,
419 0x458F, 0x9D1F, 0x4089, 0x87FA, 0x15EF, 0xEBB2, 0xC98E, 0x0BFB,
420 0xEC41, 0x67B3, 0xFD5F, 0xEA45, 0xBF23, 0xF753, 0x96E4, 0x5B9B,
421 0xC275, 0x1CE1, 0xAE3D, 0x6A4C, 0x5A6C, 0x417E, 0x02F5, 0x4F83,
422 0x5C68, 0xF451, 0x34D1, 0x08F9, 0x93E2, 0x73AB, 0x5362, 0x3F2A,
423 0x0C08, 0x5295, 0x6546, 0x5E9D, 0x2830, 0xA137, 0x0F0A, 0xB52F,
424 0x090E, 0x3624, 0x9B1B, 0x3DDF, 0x26CD, 0x694E, 0xCD7F, 0x9FEA,
425 0x1B12, 0x9E1D, 0x7458, 0x2E34, 0x2D36, 0xB2DC, 0xEEB4, 0xFB5B,
426 0xF6A4, 0x4D76, 0x61B7, 0xCE7D, 0x7B52, 0x3EDD, 0x715E, 0x9713,
427 0xF5A6, 0x68B9, 0x0000, 0x2CC1, 0x6040, 0x1FE3, 0xC879, 0xEDB6,
428 0xBED4, 0x468D, 0xD967, 0x4B72, 0xDE94, 0xD498, 0xE8B0, 0x4A85,
429 0x6BBB, 0x2AC5, 0xE54F, 0x16ED, 0xC586, 0xD79A, 0x5566, 0x9411,
430 0xCF8A, 0x10E9, 0x0604, 0x81FE, 0xF0A0, 0x4478, 0xBA25, 0xE34B,
431 0xF3A2, 0xFE5D, 0xC080, 0x8A05, 0xAD3F, 0xBC21, 0x4870, 0x04F1,
432 0xDF63, 0xC177, 0x75AF, 0x6342, 0x3020, 0x1AE5, 0x0EFD, 0x6DBF,
433 0x4C81, 0x1418, 0x3526, 0x2FC3, 0xE1BE, 0xA235, 0xCC88, 0x392E,
434 0x5793, 0xF255, 0x82FC, 0x477A, 0xACC8, 0xE7BA, 0x2B32, 0x95E6,
435 0xA0C0, 0x9819, 0xD19E, 0x7FA3, 0x6644, 0x7E54, 0xAB3B, 0x830B,
436 0xCA8C, 0x29C7, 0xD36B, 0x3C28, 0x79A7, 0xE2BC, 0x1D16, 0x76AD,
437 0x3BDB, 0x5664, 0x4E74, 0x1E14, 0xDB92, 0x0A0C, 0x6C48, 0xE4B8,
438 0x5D9F, 0x6EBD, 0xEF43, 0xA6C4, 0xA839, 0xA431, 0x37D3, 0x8BF2,
439 0x32D5, 0x438B, 0x596E, 0xB7DA, 0x8C01, 0x64B1, 0xD29C, 0xE049,
440 0xB4D8, 0xFAAC, 0x07F3, 0x25CF, 0xAFCA, 0x8EF4, 0xE947, 0x1810,
441 0xD56F, 0x88F0, 0x6F4A, 0x725C, 0x2438, 0xF157, 0xC773, 0x5197,
442 0x23CB, 0x7CA1, 0x9CE8, 0x213E, 0xDD96, 0xDC61, 0x860D, 0x850F,
443 0x90E0, 0x427C, 0xC471, 0xAACC, 0xD890, 0x0506, 0x01F7, 0x121C,
444 0xA3C2, 0x5F6A, 0xF9AE, 0xD069, 0x9117, 0x5899, 0x273A, 0xB927,
445 0x38D9, 0x13EB, 0xB32B, 0x3322, 0xBBD2, 0x70A9, 0x8907, 0xA733,
446 0xB62D, 0x223C, 0x9215, 0x20C9, 0x4987, 0xFFAA, 0x7850, 0x7AA5,
447 0x8F03, 0xF859, 0x8009, 0x171A, 0xDA65, 0x31D7, 0xC684, 0xB8D0,
448 0xC382, 0xB029, 0x775A, 0x111E, 0xCB7B, 0xFCA8, 0xD66D, 0x3A2C,
449 }
450};
451
452 /*
453**********************************************************************
454* Routine: Phase 1 -- generate P1K, given TA, TK, IV32
455*
456* Inputs:
457* tk[] = temporal key [128 bits]
458* ta[] = transmitter's MAC address [ 48 bits]
459* iv32 = upper 32 bits of IV [ 32 bits]
460* Output:
461* p1k[] = Phase 1 key [ 80 bits]
462*
463* Note:
464* This function only needs to be called every 2**16 packets,
465* although in theory it could be called every packet.
466*
467**********************************************************************
468*/
469static void phase1(u16 *p1k, const u8 *tk, const u8 *ta, u32 iv32)
470{
471 int i;
Larry Finger1b509ca2013-08-21 22:33:48 -0500472 /* Initialize the 80 bits of P1K[] from IV32 and TA[0..5] */
473 p1k[0] = Lo16(iv32);
474 p1k[1] = Hi16(iv32);
475 p1k[2] = Mk16(ta[1], ta[0]); /* use TA[] as little-endian */
476 p1k[3] = Mk16(ta[3], ta[2]);
477 p1k[4] = Mk16(ta[5], ta[4]);
478
479 /* Now compute an unbalanced Feistel cipher with 80-bit block */
480 /* size on the 80-bit block P1K[], using the 128-bit key TK[] */
481 for (i = 0; i < PHASE1_LOOP_CNT; i++) { /* Each add operation here is mod 2**16 */
482 p1k[0] += _S_(p1k[4] ^ TK16((i&1)+0));
483 p1k[1] += _S_(p1k[0] ^ TK16((i&1)+2));
484 p1k[2] += _S_(p1k[1] ^ TK16((i&1)+4));
485 p1k[3] += _S_(p1k[2] ^ TK16((i&1)+6));
486 p1k[4] += _S_(p1k[3] ^ TK16((i&1)+0));
487 p1k[4] += (unsigned short)i; /* avoid "slide attacks" */
488 }
Larry Finger1b509ca2013-08-21 22:33:48 -0500489}
490
491/*
492**********************************************************************
493* Routine: Phase 2 -- generate RC4KEY, given TK, P1K, IV16
494*
495* Inputs:
496* tk[] = Temporal key [128 bits]
497* p1k[] = Phase 1 output key [ 80 bits]
498* iv16 = low 16 bits of IV counter [ 16 bits]
499* Output:
500* rc4key[] = the key used to encrypt the packet [128 bits]
501*
502* Note:
503* The value {TA, IV32, IV16} for Phase1/Phase2 must be unique
504* across all packets using the same key TK value. Then, for a
505* given value of TK[], this TKIP48 construction guarantees that
506* the final RC4KEY value is unique across all packets.
507*
508* Suggested implementation optimization: if PPK[] is "overlaid"
509* appropriately on RC4KEY[], there is no need for the final
510* for loop below that copies the PPK[] result into RC4KEY[].
511*
512**********************************************************************
513*/
514static void phase2(u8 *rc4key, const u8 *tk, const u16 *p1k, u16 iv16)
515{
516 int i;
517 u16 PPK[6]; /* temporary key for mixing */
Larry Finger1b509ca2013-08-21 22:33:48 -0500518 /* Note: all adds in the PPK[] equations below are mod 2**16 */
519 for (i = 0; i < 5; i++)
520 PPK[i] = p1k[i]; /* first, copy P1K to PPK */
521 PPK[5] = p1k[4] + iv16; /* next, add in IV16 */
522
523 /* Bijective non-linear mixing of the 96 bits of PPK[0..5] */
524 PPK[0] += _S_(PPK[5] ^ TK16(0)); /* Mix key in each "round" */
525 PPK[1] += _S_(PPK[0] ^ TK16(1));
526 PPK[2] += _S_(PPK[1] ^ TK16(2));
527 PPK[3] += _S_(PPK[2] ^ TK16(3));
528 PPK[4] += _S_(PPK[3] ^ TK16(4));
529 PPK[5] += _S_(PPK[4] ^ TK16(5)); /* Total # S-box lookups == 6 */
530
531 /* Final sweep: bijective, "linear". Rotates kill LSB correlations */
532 PPK[0] += RotR1(PPK[5] ^ TK16(6));
533 PPK[1] += RotR1(PPK[0] ^ TK16(7)); /* Use all of TK[] in Phase2 */
534 PPK[2] += RotR1(PPK[1]);
535 PPK[3] += RotR1(PPK[2]);
536 PPK[4] += RotR1(PPK[3]);
537 PPK[5] += RotR1(PPK[4]);
538 /* Note: At this point, for a given key TK[0..15], the 96-bit output */
539 /* value PPK[0..5] is guaranteed to be unique, as a function */
540 /* of the 96-bit "input" value {TA, IV32, IV16}. That is, P1K */
541 /* is now a keyed permutation of {TA, IV32, IV16}. */
542
543 /* Set RC4KEY[0..3], which includes "cleartext" portion of RC4 key */
544 rc4key[0] = Hi8(iv16); /* RC4KEY[0..2] is the WEP IV */
545 rc4key[1] = (Hi8(iv16) | 0x20) & 0x7F; /* Help avoid weak (FMS) keys */
546 rc4key[2] = Lo8(iv16);
547 rc4key[3] = Lo8((PPK[5] ^ TK16(0)) >> 1);
548
549 /* Copy 96 bits of PPK[0..5] to RC4KEY[4..15] (little-endian) */
550 for (i = 0; i < 6; i++) {
551 rc4key[4+2*i] = Lo8(PPK[i]);
552 rc4key[5+2*i] = Hi8(PPK[i]);
553 }
Larry Finger1b509ca2013-08-21 22:33:48 -0500554}
555
556/* The hlen isn't include the IV */
557u32 rtw_tkip_encrypt(struct adapter *padapter, u8 *pxmitframe)
558{ /* exclude ICV */
559 u16 pnl;
560 u32 pnh;
561 u8 rc4key[16];
562 u8 ttkey[16];
563 u8 crc[4];
564 u8 hw_hdr_offset = 0;
565 struct arc4context mycontext;
566 int curfragnum, length;
567
568 u8 *pframe, *payload, *iv, *prwskey;
569 union pn48 dot11txpn;
570 struct sta_info *stainfo;
571 struct pkt_attrib *pattrib = &((struct xmit_frame *)pxmitframe)->attrib;
572 struct security_priv *psecuritypriv = &padapter->securitypriv;
573 struct xmit_priv *pxmitpriv = &padapter->xmitpriv;
574 u32 res = _SUCCESS;
Larry Finger1b509ca2013-08-21 22:33:48 -0500575
576 if (((struct xmit_frame *)pxmitframe)->buf_addr == NULL)
577 return _FAIL;
578
579 hw_hdr_offset = TXDESC_SIZE +
580 (((struct xmit_frame *)pxmitframe)->pkt_offset * PACKET_OFFSET_SZ);
581 pframe = ((struct xmit_frame *)pxmitframe)->buf_addr + hw_hdr_offset;
582 /* 4 start to encrypt each fragment */
583 if (pattrib->encrypt == _TKIP_) {
584 if (pattrib->psta)
585 stainfo = pattrib->psta;
586 else
587 stainfo = rtw_get_stainfo(&padapter->stapriv, &pattrib->ra[0]);
588
589 if (stainfo != NULL) {
590 RT_TRACE(_module_rtl871x_security_c_, _drv_err_, ("rtw_tkip_encrypt: stainfo!= NULL!!!\n"));
591
592 if (IS_MCAST(pattrib->ra))
593 prwskey = psecuritypriv->dot118021XGrpKey[psecuritypriv->dot118021XGrpKeyid].skey;
594 else
595 prwskey = &stainfo->dot118021x_UncstKey.skey[0];
596
597 for (curfragnum = 0; curfragnum < pattrib->nr_frags; curfragnum++) {
598 iv = pframe+pattrib->hdrlen;
599 payload = pframe+pattrib->iv_len+pattrib->hdrlen;
600
601 GET_TKIP_PN(iv, dot11txpn);
602
603 pnl = (u16)(dot11txpn.val);
604 pnh = (u32)(dot11txpn.val>>16);
605 phase1((u16 *)&ttkey[0], prwskey, &pattrib->ta[0], pnh);
606 phase2(&rc4key[0], prwskey, (u16 *)&ttkey[0], pnl);
607
608 if ((curfragnum+1) == pattrib->nr_frags) { /* 4 the last fragment */
609 length = pattrib->last_txcmdsz-pattrib->hdrlen-pattrib->iv_len-pattrib->icv_len;
610 RT_TRACE(_module_rtl871x_security_c_, _drv_info_,
611 ("pattrib->iv_len=%x, pattrib->icv_len=%x\n",
612 pattrib->iv_len, pattrib->icv_len));
613 *((__le32 *)crc) = getcrc32(payload, length);/* modified by Amy*/
614
615 arcfour_init(&mycontext, rc4key, 16);
616 arcfour_encrypt(&mycontext, payload, payload, length);
617 arcfour_encrypt(&mycontext, payload+length, crc, 4);
618 } else {
Jia He7be921a22014-11-04 09:39:58 +0800619 length = pxmitpriv->frag_len-pattrib->hdrlen-pattrib->iv_len-pattrib->icv_len;
Larry Finger1b509ca2013-08-21 22:33:48 -0500620 *((__le32 *)crc) = getcrc32(payload, length);/* modified by Amy*/
621 arcfour_init(&mycontext, rc4key, 16);
622 arcfour_encrypt(&mycontext, payload, payload, length);
623 arcfour_encrypt(&mycontext, payload+length, crc, 4);
624
625 pframe += pxmitpriv->frag_len;
Jia He7be921a22014-11-04 09:39:58 +0800626 pframe = (u8 *)round_up((size_t)(pframe), 4);
Larry Finger1b509ca2013-08-21 22:33:48 -0500627 }
628 }
629 } else {
630 RT_TRACE(_module_rtl871x_security_c_, _drv_err_, ("rtw_tkip_encrypt: stainfo==NULL!!!\n"));
631 res = _FAIL;
632 }
633 }
Larry Finger1b509ca2013-08-21 22:33:48 -0500634 return res;
635}
636
637/* The hlen isn't include the IV */
638u32 rtw_tkip_decrypt(struct adapter *padapter, u8 *precvframe)
639{ /* exclude ICV */
640 u16 pnl;
641 u32 pnh;
642 u8 rc4key[16];
643 u8 ttkey[16];
644 u8 crc[4];
645 struct arc4context mycontext;
646 int length;
647
648 u8 *pframe, *payload, *iv, *prwskey;
649 union pn48 dot11txpn;
650 struct sta_info *stainfo;
Larry Fingerf31cca82014-02-14 16:54:07 -0600651 struct rx_pkt_attrib *prxattrib = &((struct recv_frame *)precvframe)->attrib;
Larry Finger1b509ca2013-08-21 22:33:48 -0500652 struct security_priv *psecuritypriv = &padapter->securitypriv;
653 u32 res = _SUCCESS;
654
Larry Finger1b509ca2013-08-21 22:33:48 -0500655
Larry Fingerf31cca82014-02-14 16:54:07 -0600656 pframe = (unsigned char *)((struct recv_frame *)precvframe)->rx_data;
Larry Finger1b509ca2013-08-21 22:33:48 -0500657
658 /* 4 start to decrypt recvframe */
659 if (prxattrib->encrypt == _TKIP_) {
660 stainfo = rtw_get_stainfo(&padapter->stapriv, &prxattrib->ta[0]);
661 if (stainfo != NULL) {
662 if (IS_MCAST(prxattrib->ra)) {
663 if (!psecuritypriv->binstallGrpkey) {
664 res = _FAIL;
665 DBG_88E("%s:rx bc/mc packets, but didn't install group key!!!!!!!!!!\n", __func__);
666 goto exit;
667 }
668 prwskey = psecuritypriv->dot118021XGrpKey[prxattrib->key_index].skey;
669 } else {
670 RT_TRACE(_module_rtl871x_security_c_, _drv_err_, ("rtw_tkip_decrypt: stainfo!= NULL!!!\n"));
671 prwskey = &stainfo->dot118021x_UncstKey.skey[0];
672 }
673
674 iv = pframe+prxattrib->hdrlen;
675 payload = pframe+prxattrib->iv_len+prxattrib->hdrlen;
Larry Fingerf31cca82014-02-14 16:54:07 -0600676 length = ((struct recv_frame *)precvframe)->len-prxattrib->hdrlen-prxattrib->iv_len;
Larry Finger1b509ca2013-08-21 22:33:48 -0500677
678 GET_TKIP_PN(iv, dot11txpn);
679
680 pnl = (u16)(dot11txpn.val);
681 pnh = (u32)(dot11txpn.val>>16);
682
683 phase1((u16 *)&ttkey[0], prwskey, &prxattrib->ta[0], pnh);
684 phase2(&rc4key[0], prwskey, (unsigned short *)&ttkey[0], pnl);
685
686 /* 4 decrypt payload include icv */
687
688 arcfour_init(&mycontext, rc4key, 16);
689 arcfour_encrypt(&mycontext, payload, payload, length);
690
691 *((__le32 *)crc) = getcrc32(payload, length-4);
692
693 if (crc[3] != payload[length-1] ||
694 crc[2] != payload[length-2] ||
695 crc[1] != payload[length-3] ||
696 crc[0] != payload[length-4]) {
697 RT_TRACE(_module_rtl871x_security_c_, _drv_err_,
698 ("rtw_wep_decrypt:icv error crc (%4ph)!=payload (%4ph)\n",
699 &crc, &payload[length-4]));
700 res = _FAIL;
701 }
702 } else {
703 RT_TRACE(_module_rtl871x_security_c_, _drv_err_, ("rtw_tkip_decrypt: stainfo==NULL!!!\n"));
704 res = _FAIL;
705 }
706 }
Larry Finger1b509ca2013-08-21 22:33:48 -0500707exit:
708 return res;
709}
710
711/* 3 ===== AES related ===== */
712
713
714#define MAX_MSG_SIZE 2048
715/*****************************/
716/******** SBOX Table *********/
717/*****************************/
718
719static u8 sbox_table[256] = {
720 0x63, 0x7c, 0x77, 0x7b, 0xf2, 0x6b, 0x6f, 0xc5,
721 0x30, 0x01, 0x67, 0x2b, 0xfe, 0xd7, 0xab, 0x76,
722 0xca, 0x82, 0xc9, 0x7d, 0xfa, 0x59, 0x47, 0xf0,
723 0xad, 0xd4, 0xa2, 0xaf, 0x9c, 0xa4, 0x72, 0xc0,
724 0xb7, 0xfd, 0x93, 0x26, 0x36, 0x3f, 0xf7, 0xcc,
725 0x34, 0xa5, 0xe5, 0xf1, 0x71, 0xd8, 0x31, 0x15,
726 0x04, 0xc7, 0x23, 0xc3, 0x18, 0x96, 0x05, 0x9a,
727 0x07, 0x12, 0x80, 0xe2, 0xeb, 0x27, 0xb2, 0x75,
728 0x09, 0x83, 0x2c, 0x1a, 0x1b, 0x6e, 0x5a, 0xa0,
729 0x52, 0x3b, 0xd6, 0xb3, 0x29, 0xe3, 0x2f, 0x84,
730 0x53, 0xd1, 0x00, 0xed, 0x20, 0xfc, 0xb1, 0x5b,
731 0x6a, 0xcb, 0xbe, 0x39, 0x4a, 0x4c, 0x58, 0xcf,
732 0xd0, 0xef, 0xaa, 0xfb, 0x43, 0x4d, 0x33, 0x85,
733 0x45, 0xf9, 0x02, 0x7f, 0x50, 0x3c, 0x9f, 0xa8,
734 0x51, 0xa3, 0x40, 0x8f, 0x92, 0x9d, 0x38, 0xf5,
735 0xbc, 0xb6, 0xda, 0x21, 0x10, 0xff, 0xf3, 0xd2,
736 0xcd, 0x0c, 0x13, 0xec, 0x5f, 0x97, 0x44, 0x17,
737 0xc4, 0xa7, 0x7e, 0x3d, 0x64, 0x5d, 0x19, 0x73,
738 0x60, 0x81, 0x4f, 0xdc, 0x22, 0x2a, 0x90, 0x88,
739 0x46, 0xee, 0xb8, 0x14, 0xde, 0x5e, 0x0b, 0xdb,
740 0xe0, 0x32, 0x3a, 0x0a, 0x49, 0x06, 0x24, 0x5c,
741 0xc2, 0xd3, 0xac, 0x62, 0x91, 0x95, 0xe4, 0x79,
742 0xe7, 0xc8, 0x37, 0x6d, 0x8d, 0xd5, 0x4e, 0xa9,
743 0x6c, 0x56, 0xf4, 0xea, 0x65, 0x7a, 0xae, 0x08,
744 0xba, 0x78, 0x25, 0x2e, 0x1c, 0xa6, 0xb4, 0xc6,
745 0xe8, 0xdd, 0x74, 0x1f, 0x4b, 0xbd, 0x8b, 0x8a,
746 0x70, 0x3e, 0xb5, 0x66, 0x48, 0x03, 0xf6, 0x0e,
747 0x61, 0x35, 0x57, 0xb9, 0x86, 0xc1, 0x1d, 0x9e,
748 0xe1, 0xf8, 0x98, 0x11, 0x69, 0xd9, 0x8e, 0x94,
749 0x9b, 0x1e, 0x87, 0xe9, 0xce, 0x55, 0x28, 0xdf,
750 0x8c, 0xa1, 0x89, 0x0d, 0xbf, 0xe6, 0x42, 0x68,
751 0x41, 0x99, 0x2d, 0x0f, 0xb0, 0x54, 0xbb, 0x16
752};
753
754/*****************************/
755/**** Function Prototypes ****/
756/*****************************/
757
758static void bitwise_xor(u8 *ina, u8 *inb, u8 *out);
759static void construct_mic_iv(u8 *mic_header1, int qc_exists, int a4_exists, u8 *mpdu, uint payload_length, u8 *pn_vector);
760static void construct_mic_header1(u8 *mic_header1, int header_length, u8 *mpdu);
761static void construct_mic_header2(u8 *mic_header2, u8 *mpdu, int a4_exists, int qc_exists);
762static void construct_ctr_preload(u8 *ctr_preload, int a4_exists, int qc_exists, u8 *mpdu, u8 *pn_vector, int c);
763static void xor_128(u8 *a, u8 *b, u8 *out);
764static void xor_32(u8 *a, u8 *b, u8 *out);
765static u8 sbox(u8 a);
766static void next_key(u8 *key, int round);
767static void byte_sub(u8 *in, u8 *out);
768static void shift_row(u8 *in, u8 *out);
769static void mix_column(u8 *in, u8 *out);
770static void aes128k128d(u8 *key, u8 *data, u8 *ciphertext);
771
772/****************************************/
773/* aes128k128d() */
774/* Performs a 128 bit AES encrypt with */
775/* 128 bit data. */
776/****************************************/
777static void xor_128(u8 *a, u8 *b, u8 *out)
778{
779 int i;
Larry Finger1b509ca2013-08-21 22:33:48 -0500780 for (i = 0; i < 16; i++)
781 out[i] = a[i] ^ b[i];
Larry Finger1b509ca2013-08-21 22:33:48 -0500782}
783
784static void xor_32(u8 *a, u8 *b, u8 *out)
785{
786 int i;
Larry Finger1b509ca2013-08-21 22:33:48 -0500787 for (i = 0; i < 4; i++)
788 out[i] = a[i] ^ b[i];
Larry Finger1b509ca2013-08-21 22:33:48 -0500789}
790
791static u8 sbox(u8 a)
792{
793 return sbox_table[(int)a];
794}
795
796static void next_key(u8 *key, int round)
797{
798 u8 rcon;
799 u8 sbox_key[4];
800 u8 rcon_table[12] = {
801 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80,
802 0x1b, 0x36, 0x36, 0x36
803 };
Larry Finger1b509ca2013-08-21 22:33:48 -0500804 sbox_key[0] = sbox(key[13]);
805 sbox_key[1] = sbox(key[14]);
806 sbox_key[2] = sbox(key[15]);
807 sbox_key[3] = sbox(key[12]);
808
809 rcon = rcon_table[round];
810
811 xor_32(&key[0], sbox_key, &key[0]);
812 key[0] = key[0] ^ rcon;
813
814 xor_32(&key[4], &key[0], &key[4]);
815 xor_32(&key[8], &key[4], &key[8]);
816 xor_32(&key[12], &key[8], &key[12]);
Larry Finger1b509ca2013-08-21 22:33:48 -0500817}
818
819static void byte_sub(u8 *in, u8 *out)
820{
821 int i;
Larry Finger1b509ca2013-08-21 22:33:48 -0500822 for (i = 0; i < 16; i++)
823 out[i] = sbox(in[i]);
Larry Finger1b509ca2013-08-21 22:33:48 -0500824}
825
826static void shift_row(u8 *in, u8 *out)
827{
Larry Finger1b509ca2013-08-21 22:33:48 -0500828 out[0] = in[0];
829 out[1] = in[5];
830 out[2] = in[10];
831 out[3] = in[15];
832 out[4] = in[4];
833 out[5] = in[9];
834 out[6] = in[14];
835 out[7] = in[3];
836 out[8] = in[8];
837 out[9] = in[13];
838 out[10] = in[2];
839 out[11] = in[7];
840 out[12] = in[12];
841 out[13] = in[1];
842 out[14] = in[6];
843 out[15] = in[11];
Larry Finger1b509ca2013-08-21 22:33:48 -0500844}
845
846static void mix_column(u8 *in, u8 *out)
847{
848 int i;
849 u8 add1b[4];
850 u8 add1bf7[4];
851 u8 rotl[4];
Ioana Ciorneie7b12692015-03-09 15:43:25 +0200852 u8 swap_halves[4];
Larry Finger1b509ca2013-08-21 22:33:48 -0500853 u8 andf7[4];
854 u8 rotr[4];
855 u8 temp[4];
856 u8 tempb[4];
Larry Finger1b509ca2013-08-21 22:33:48 -0500857 for (i = 0 ; i < 4; i++) {
858 if ((in[i] & 0x80) == 0x80)
859 add1b[i] = 0x1b;
860 else
861 add1b[i] = 0x00;
862 }
863
Ioana Ciorneie7b12692015-03-09 15:43:25 +0200864 swap_halves[0] = in[2]; /* Swap halves */
865 swap_halves[1] = in[3];
866 swap_halves[2] = in[0];
867 swap_halves[3] = in[1];
Larry Finger1b509ca2013-08-21 22:33:48 -0500868
869 rotl[0] = in[3]; /* Rotate left 8 bits */
870 rotl[1] = in[0];
871 rotl[2] = in[1];
872 rotl[3] = in[2];
873
874 andf7[0] = in[0] & 0x7f;
875 andf7[1] = in[1] & 0x7f;
876 andf7[2] = in[2] & 0x7f;
877 andf7[3] = in[3] & 0x7f;
878
879 for (i = 3; i > 0; i--) { /* logical shift left 1 bit */
880 andf7[i] = andf7[i] << 1;
881 if ((andf7[i-1] & 0x80) == 0x80)
882 andf7[i] = (andf7[i] | 0x01);
883 }
884 andf7[0] = andf7[0] << 1;
885 andf7[0] = andf7[0] & 0xfe;
886
887 xor_32(add1b, andf7, add1bf7);
888
889 xor_32(in, add1bf7, rotr);
890
891 temp[0] = rotr[0]; /* Rotate right 8 bits */
892 rotr[0] = rotr[1];
893 rotr[1] = rotr[2];
894 rotr[2] = rotr[3];
895 rotr[3] = temp[0];
896
897 xor_32(add1bf7, rotr, temp);
Ioana Ciorneie7b12692015-03-09 15:43:25 +0200898 xor_32(swap_halves, rotl, tempb);
Larry Finger1b509ca2013-08-21 22:33:48 -0500899 xor_32(temp, tempb, out);
Larry Finger1b509ca2013-08-21 22:33:48 -0500900}
901
902static void aes128k128d(u8 *key, u8 *data, u8 *ciphertext)
903{
904 int round;
905 int i;
906 u8 intermediatea[16];
907 u8 intermediateb[16];
908 u8 round_key[16];
Larry Finger1b509ca2013-08-21 22:33:48 -0500909 for (i = 0; i < 16; i++)
910 round_key[i] = key[i];
911 for (round = 0; round < 11; round++) {
912 if (round == 0) {
913 xor_128(round_key, data, ciphertext);
914 next_key(round_key, round);
915 } else if (round == 10) {
916 byte_sub(ciphertext, intermediatea);
917 shift_row(intermediatea, intermediateb);
918 xor_128(intermediateb, round_key, ciphertext);
919 } else { /* 1 - 9 */
920 byte_sub(ciphertext, intermediatea);
921 shift_row(intermediatea, intermediateb);
922 mix_column(&intermediateb[0], &intermediatea[0]);
923 mix_column(&intermediateb[4], &intermediatea[4]);
924 mix_column(&intermediateb[8], &intermediatea[8]);
925 mix_column(&intermediateb[12], &intermediatea[12]);
926 xor_128(intermediatea, round_key, ciphertext);
927 next_key(round_key, round);
928 }
929 }
Larry Finger1b509ca2013-08-21 22:33:48 -0500930}
931
932/************************************************/
933/* construct_mic_iv() */
934/* Builds the MIC IV from header fields and PN */
935/************************************************/
936static void construct_mic_iv(u8 *mic_iv, int qc_exists, int a4_exists, u8 *mpdu,
937 uint payload_length, u8 *pn_vector)
938{
939 int i;
Larry Finger1b509ca2013-08-21 22:33:48 -0500940 mic_iv[0] = 0x59;
941 if (qc_exists && a4_exists)
942 mic_iv[1] = mpdu[30] & 0x0f; /* QoS_TC */
943 if (qc_exists && !a4_exists)
944 mic_iv[1] = mpdu[24] & 0x0f; /* mute bits 7-4 */
945 if (!qc_exists)
946 mic_iv[1] = 0x00;
947 for (i = 2; i < 8; i++)
948 mic_iv[i] = mpdu[i + 8]; /* mic_iv[2:7] = A2[0:5] = mpdu[10:15] */
949 for (i = 8; i < 14; i++)
950 mic_iv[i] = pn_vector[13 - i]; /* mic_iv[8:13] = PN[5:0] */
Jia He7be921a22014-11-04 09:39:58 +0800951 mic_iv[14] = (unsigned char)(payload_length / 256);
952 mic_iv[15] = (unsigned char)(payload_length % 256);
Larry Finger1b509ca2013-08-21 22:33:48 -0500953}
954
955/************************************************/
956/* construct_mic_header1() */
957/* Builds the first MIC header block from */
958/* header fields. */
959/************************************************/
960static void construct_mic_header1(u8 *mic_header1, int header_length, u8 *mpdu)
961{
Larry Finger1b509ca2013-08-21 22:33:48 -0500962 mic_header1[0] = (u8)((header_length - 2) / 256);
963 mic_header1[1] = (u8)((header_length - 2) % 256);
964 mic_header1[2] = mpdu[0] & 0xcf; /* Mute CF poll & CF ack bits */
965 mic_header1[3] = mpdu[1] & 0xc7; /* Mute retry, more data and pwr mgt bits */
966 mic_header1[4] = mpdu[4]; /* A1 */
967 mic_header1[5] = mpdu[5];
968 mic_header1[6] = mpdu[6];
969 mic_header1[7] = mpdu[7];
970 mic_header1[8] = mpdu[8];
971 mic_header1[9] = mpdu[9];
972 mic_header1[10] = mpdu[10]; /* A2 */
973 mic_header1[11] = mpdu[11];
974 mic_header1[12] = mpdu[12];
975 mic_header1[13] = mpdu[13];
976 mic_header1[14] = mpdu[14];
977 mic_header1[15] = mpdu[15];
Larry Finger1b509ca2013-08-21 22:33:48 -0500978}
979
980/************************************************/
981/* construct_mic_header2() */
982/* Builds the last MIC header block from */
983/* header fields. */
984/************************************************/
985static void construct_mic_header2(u8 *mic_header2, u8 *mpdu, int a4_exists, int qc_exists)
986{
987 int i;
Larry Finger1b509ca2013-08-21 22:33:48 -0500988 for (i = 0; i < 16; i++)
989 mic_header2[i] = 0x00;
990
991 mic_header2[0] = mpdu[16]; /* A3 */
992 mic_header2[1] = mpdu[17];
993 mic_header2[2] = mpdu[18];
994 mic_header2[3] = mpdu[19];
995 mic_header2[4] = mpdu[20];
996 mic_header2[5] = mpdu[21];
997
998 mic_header2[6] = 0x00;
999 mic_header2[7] = 0x00; /* mpdu[23]; */
1000
1001 if (!qc_exists && a4_exists) {
1002 for (i = 0; i < 6; i++)
1003 mic_header2[8+i] = mpdu[24+i]; /* A4 */
1004 }
1005
1006 if (qc_exists && !a4_exists) {
1007 mic_header2[8] = mpdu[24] & 0x0f; /* mute bits 15 - 4 */
1008 mic_header2[9] = mpdu[25] & 0x00;
1009 }
1010
1011 if (qc_exists && a4_exists) {
1012 for (i = 0; i < 6; i++)
1013 mic_header2[8+i] = mpdu[24+i]; /* A4 */
1014
1015 mic_header2[14] = mpdu[30] & 0x0f;
1016 mic_header2[15] = mpdu[31] & 0x00;
1017 }
1018
Larry Finger1b509ca2013-08-21 22:33:48 -05001019}
1020
1021/************************************************/
1022/* construct_mic_header2() */
1023/* Builds the last MIC header block from */
1024/* header fields. */
1025/************************************************/
1026static void construct_ctr_preload(u8 *ctr_preload, int a4_exists, int qc_exists, u8 *mpdu, u8 *pn_vector, int c)
1027{
1028 int i;
Larry Finger1b509ca2013-08-21 22:33:48 -05001029 for (i = 0; i < 16; i++)
1030 ctr_preload[i] = 0x00;
1031 i = 0;
1032
1033 ctr_preload[0] = 0x01; /* flag */
1034 if (qc_exists && a4_exists)
1035 ctr_preload[1] = mpdu[30] & 0x0f; /* QoC_Control */
1036 if (qc_exists && !a4_exists)
1037 ctr_preload[1] = mpdu[24] & 0x0f;
1038
1039 for (i = 2; i < 8; i++)
1040 ctr_preload[i] = mpdu[i + 8]; /* ctr_preload[2:7] = A2[0:5] = mpdu[10:15] */
1041 for (i = 8; i < 14; i++)
1042 ctr_preload[i] = pn_vector[13 - i]; /* ctr_preload[8:13] = PN[5:0] */
Jia He7be921a22014-11-04 09:39:58 +08001043 ctr_preload[14] = (unsigned char)(c / 256); /* Ctr */
1044 ctr_preload[15] = (unsigned char)(c % 256);
Larry Finger1b509ca2013-08-21 22:33:48 -05001045}
1046
1047/************************************/
1048/* bitwise_xor() */
1049/* A 128 bit, bitwise exclusive or */
1050/************************************/
1051static void bitwise_xor(u8 *ina, u8 *inb, u8 *out)
1052{
1053 int i;
Larry Finger1b509ca2013-08-21 22:33:48 -05001054 for (i = 0; i < 16; i++)
1055 out[i] = ina[i] ^ inb[i];
Larry Finger1b509ca2013-08-21 22:33:48 -05001056}
1057
1058static int aes_cipher(u8 *key, uint hdrlen, u8 *pframe, uint plen)
1059{
1060 uint qc_exists, a4_exists, i, j, payload_remainder,
1061 num_blocks, payload_index;
1062
1063 u8 pn_vector[6];
1064 u8 mic_iv[16];
1065 u8 mic_header1[16];
1066 u8 mic_header2[16];
1067 u8 ctr_preload[16];
1068
1069 /* Intermediate Buffers */
1070 u8 chain_buffer[16];
1071 u8 aes_out[16];
1072 u8 padded_buffer[16];
1073 u8 mic[8];
1074 uint frtype = GetFrameType(pframe);
1075 uint frsubtype = GetFrameSubType(pframe);
1076
Aya Mahfouz10a86432015-02-26 11:43:09 +02001077 frsubtype >>= 4;
Larry Finger1b509ca2013-08-21 22:33:48 -05001078
Luca Ceresolid0beccb2015-12-02 22:54:01 +01001079 memset(mic_iv, 0, 16);
1080 memset(mic_header1, 0, 16);
1081 memset(mic_header2, 0, 16);
1082 memset(ctr_preload, 0, 16);
1083 memset(chain_buffer, 0, 16);
1084 memset(aes_out, 0, 16);
1085 memset(padded_buffer, 0, 16);
Larry Finger1b509ca2013-08-21 22:33:48 -05001086
1087 if ((hdrlen == WLAN_HDR_A3_LEN) || (hdrlen == WLAN_HDR_A3_QOS_LEN))
1088 a4_exists = 0;
1089 else
1090 a4_exists = 1;
1091
1092 if ((frtype == WIFI_DATA_CFACK) || (frtype == WIFI_DATA_CFPOLL) || (frtype == WIFI_DATA_CFACKPOLL)) {
1093 qc_exists = 1;
1094 if (hdrlen != WLAN_HDR_A3_QOS_LEN)
1095 hdrlen += 2;
1096 } else if ((frsubtype == 0x08) || (frsubtype == 0x09) || (frsubtype == 0x0a) || (frsubtype == 0x0b)) {
1097 if (hdrlen != WLAN_HDR_A3_QOS_LEN)
1098 hdrlen += 2;
1099 qc_exists = 1;
1100 } else {
1101 qc_exists = 0;
1102 }
1103
1104 pn_vector[0] = pframe[hdrlen];
1105 pn_vector[1] = pframe[hdrlen+1];
1106 pn_vector[2] = pframe[hdrlen+4];
1107 pn_vector[3] = pframe[hdrlen+5];
1108 pn_vector[4] = pframe[hdrlen+6];
1109 pn_vector[5] = pframe[hdrlen+7];
1110
1111 construct_mic_iv(mic_iv, qc_exists, a4_exists, pframe, plen, pn_vector);
1112
1113 construct_mic_header1(mic_header1, hdrlen, pframe);
1114 construct_mic_header2(mic_header2, pframe, a4_exists, qc_exists);
1115
1116 payload_remainder = plen % 16;
1117 num_blocks = plen / 16;
1118
1119 /* Find start of payload */
Tina Johnsondce34ae2015-03-09 12:02:47 +05301120 payload_index = hdrlen + 8;
Larry Finger1b509ca2013-08-21 22:33:48 -05001121
1122 /* Calculate MIC */
1123 aes128k128d(key, mic_iv, aes_out);
1124 bitwise_xor(aes_out, mic_header1, chain_buffer);
1125 aes128k128d(key, chain_buffer, aes_out);
1126 bitwise_xor(aes_out, mic_header2, chain_buffer);
1127 aes128k128d(key, chain_buffer, aes_out);
1128
1129 for (i = 0; i < num_blocks; i++) {
1130 bitwise_xor(aes_out, &pframe[payload_index], chain_buffer);/* bitwise_xor(aes_out, &message[payload_index], chain_buffer); */
1131
1132 payload_index += 16;
1133 aes128k128d(key, chain_buffer, aes_out);
1134 }
1135
1136 /* Add on the final payload block if it needs padding */
1137 if (payload_remainder > 0) {
1138 for (j = 0; j < 16; j++)
1139 padded_buffer[j] = 0x00;
1140 for (j = 0; j < payload_remainder; j++)
1141 padded_buffer[j] = pframe[payload_index++];/* padded_buffer[j] = message[payload_index++]; */
1142 bitwise_xor(aes_out, padded_buffer, chain_buffer);
1143 aes128k128d(key, chain_buffer, aes_out);
1144 }
1145
1146 for (j = 0; j < 8; j++)
1147 mic[j] = aes_out[j];
1148
1149 /* Insert MIC into payload */
1150 for (j = 0; j < 8; j++)
Dan Carpenter50b14a92014-04-29 15:41:01 +03001151 pframe[payload_index+j] = mic[j];
Larry Finger1b509ca2013-08-21 22:33:48 -05001152
1153 payload_index = hdrlen + 8;
1154 for (i = 0; i < num_blocks; i++) {
1155 construct_ctr_preload(ctr_preload, a4_exists, qc_exists, pframe, pn_vector, i+1);
1156 aes128k128d(key, ctr_preload, aes_out);
1157 bitwise_xor(aes_out, &pframe[payload_index], chain_buffer);
1158 for (j = 0; j < 16; j++)
1159 pframe[payload_index++] = chain_buffer[j];
1160 }
1161
1162 if (payload_remainder > 0) { /* If there is a short final block, then pad it,*/
1163 /* encrypt it and copy the unpadded part back */
1164 construct_ctr_preload(ctr_preload, a4_exists, qc_exists, pframe, pn_vector, num_blocks+1);
1165
1166 for (j = 0; j < 16; j++)
1167 padded_buffer[j] = 0x00;
1168 for (j = 0; j < payload_remainder; j++)
1169 padded_buffer[j] = pframe[payload_index+j];
1170 aes128k128d(key, ctr_preload, aes_out);
1171 bitwise_xor(aes_out, padded_buffer, chain_buffer);
1172 for (j = 0; j < payload_remainder; j++)
1173 pframe[payload_index++] = chain_buffer[j];
1174 }
1175 /* Encrypt the MIC */
1176 construct_ctr_preload(ctr_preload, a4_exists, qc_exists, pframe, pn_vector, 0);
1177
1178 for (j = 0; j < 16; j++)
1179 padded_buffer[j] = 0x00;
1180 for (j = 0; j < 8; j++)
1181 padded_buffer[j] = pframe[j+hdrlen+8+plen];
1182
1183 aes128k128d(key, ctr_preload, aes_out);
1184 bitwise_xor(aes_out, padded_buffer, chain_buffer);
1185 for (j = 0; j < 8; j++)
1186 pframe[payload_index++] = chain_buffer[j];
Larry Finger1b509ca2013-08-21 22:33:48 -05001187 return _SUCCESS;
1188}
1189
1190u32 rtw_aes_encrypt(struct adapter *padapter, u8 *pxmitframe)
1191{ /* exclude ICV */
1192
1193 /*static*/
1194/* unsigned char message[MAX_MSG_SIZE]; */
1195
1196 /* Intermediate Buffers */
1197 int curfragnum, length;
1198 u8 *pframe, *prwskey; /* *payload,*iv */
1199 u8 hw_hdr_offset = 0;
1200 struct sta_info *stainfo;
1201 struct pkt_attrib *pattrib = &((struct xmit_frame *)pxmitframe)->attrib;
1202 struct security_priv *psecuritypriv = &padapter->securitypriv;
1203 struct xmit_priv *pxmitpriv = &padapter->xmitpriv;
1204
1205/* uint offset = 0; */
1206 u32 res = _SUCCESS;
Larry Finger1b509ca2013-08-21 22:33:48 -05001207
1208 if (((struct xmit_frame *)pxmitframe)->buf_addr == NULL)
1209 return _FAIL;
1210
1211 hw_hdr_offset = TXDESC_SIZE +
1212 (((struct xmit_frame *)pxmitframe)->pkt_offset * PACKET_OFFSET_SZ);
1213
1214 pframe = ((struct xmit_frame *)pxmitframe)->buf_addr + hw_hdr_offset;
1215
1216 /* 4 start to encrypt each fragment */
Gulsah Kose0d20dac2014-10-29 21:29:56 +02001217 if (pattrib->encrypt == _AES_) {
Larry Finger1b509ca2013-08-21 22:33:48 -05001218 if (pattrib->psta)
1219 stainfo = pattrib->psta;
1220 else
1221 stainfo = rtw_get_stainfo(&padapter->stapriv, &pattrib->ra[0]);
1222
1223 if (stainfo != NULL) {
1224 RT_TRACE(_module_rtl871x_security_c_, _drv_err_, ("rtw_aes_encrypt: stainfo!= NULL!!!\n"));
1225
1226 if (IS_MCAST(pattrib->ra))
1227 prwskey = psecuritypriv->dot118021XGrpKey[psecuritypriv->dot118021XGrpKeyid].skey;
1228 else
1229 prwskey = &stainfo->dot118021x_UncstKey.skey[0];
1230 for (curfragnum = 0; curfragnum < pattrib->nr_frags; curfragnum++) {
1231 if ((curfragnum+1) == pattrib->nr_frags) { /* 4 the last fragment */
1232 length = pattrib->last_txcmdsz-pattrib->hdrlen-pattrib->iv_len-pattrib->icv_len;
1233
1234 aes_cipher(prwskey, pattrib->hdrlen, pframe, length);
1235 } else{
Jia He7be921a22014-11-04 09:39:58 +08001236 length = pxmitpriv->frag_len-pattrib->hdrlen-pattrib->iv_len-pattrib->icv_len;
Larry Finger1b509ca2013-08-21 22:33:48 -05001237
1238 aes_cipher(prwskey, pattrib->hdrlen, pframe, length);
1239 pframe += pxmitpriv->frag_len;
Jia He7be921a22014-11-04 09:39:58 +08001240 pframe = (u8 *)round_up((size_t)(pframe), 8);
Larry Finger1b509ca2013-08-21 22:33:48 -05001241 }
1242 }
1243 } else{
1244 RT_TRACE(_module_rtl871x_security_c_, _drv_err_, ("rtw_aes_encrypt: stainfo==NULL!!!\n"));
1245 res = _FAIL;
1246 }
1247 }
1248
1249
Larry Finger1b509ca2013-08-21 22:33:48 -05001250 return res;
1251}
1252
1253static int aes_decipher(u8 *key, uint hdrlen,
1254 u8 *pframe, uint plen)
1255{
1256 static u8 message[MAX_MSG_SIZE];
1257 uint qc_exists, a4_exists, i, j, payload_remainder,
1258 num_blocks, payload_index;
1259 int res = _SUCCESS;
1260 u8 pn_vector[6];
1261 u8 mic_iv[16];
1262 u8 mic_header1[16];
1263 u8 mic_header2[16];
1264 u8 ctr_preload[16];
1265
1266 /* Intermediate Buffers */
1267 u8 chain_buffer[16];
1268 u8 aes_out[16];
1269 u8 padded_buffer[16];
1270 u8 mic[8];
1271
1272/* uint offset = 0; */
1273 uint frtype = GetFrameType(pframe);
1274 uint frsubtype = GetFrameSubType(pframe);
Aya Mahfouz10a86432015-02-26 11:43:09 +02001275 frsubtype >>= 4;
Larry Finger1b509ca2013-08-21 22:33:48 -05001276
Luca Ceresolid0beccb2015-12-02 22:54:01 +01001277 memset(mic_iv, 0, 16);
1278 memset(mic_header1, 0, 16);
1279 memset(mic_header2, 0, 16);
1280 memset(ctr_preload, 0, 16);
1281 memset(chain_buffer, 0, 16);
1282 memset(aes_out, 0, 16);
1283 memset(padded_buffer, 0, 16);
Larry Finger1b509ca2013-08-21 22:33:48 -05001284
1285 /* start to decrypt the payload */
1286
1287 num_blocks = (plen-8) / 16; /* plen including llc, payload_length and mic) */
1288
1289 payload_remainder = (plen-8) % 16;
1290
1291 pn_vector[0] = pframe[hdrlen];
1292 pn_vector[1] = pframe[hdrlen+1];
1293 pn_vector[2] = pframe[hdrlen+4];
1294 pn_vector[3] = pframe[hdrlen+5];
1295 pn_vector[4] = pframe[hdrlen+6];
1296 pn_vector[5] = pframe[hdrlen+7];
1297
1298 if ((hdrlen == WLAN_HDR_A3_LEN) || (hdrlen == WLAN_HDR_A3_QOS_LEN))
1299 a4_exists = 0;
1300 else
1301 a4_exists = 1;
1302
1303 if ((frtype == WIFI_DATA_CFACK) || (frtype == WIFI_DATA_CFPOLL) ||
1304 (frtype == WIFI_DATA_CFACKPOLL)) {
1305 qc_exists = 1;
1306 if (hdrlen != WLAN_HDR_A3_QOS_LEN)
1307 hdrlen += 2;
1308 } else if ((frsubtype == 0x08) || (frsubtype == 0x09) ||
1309 (frsubtype == 0x0a) || (frsubtype == 0x0b)) {
1310 if (hdrlen != WLAN_HDR_A3_QOS_LEN)
1311 hdrlen += 2;
1312 qc_exists = 1;
1313 } else {
1314 qc_exists = 0;
1315 }
1316
1317 /* now, decrypt pframe with hdrlen offset and plen long */
1318
1319 payload_index = hdrlen + 8; /* 8 is for extiv */
1320
1321 for (i = 0; i < num_blocks; i++) {
1322 construct_ctr_preload(ctr_preload, a4_exists, qc_exists, pframe, pn_vector, i+1);
1323
1324 aes128k128d(key, ctr_preload, aes_out);
1325 bitwise_xor(aes_out, &pframe[payload_index], chain_buffer);
1326
1327 for (j = 0; j < 16; j++)
Mayank Bareja4e0fa712015-08-03 11:23:01 +00001328 pframe[payload_index++] = chain_buffer[j];
Larry Finger1b509ca2013-08-21 22:33:48 -05001329 }
1330
1331 if (payload_remainder > 0) { /* If there is a short final block, then pad it,*/
1332 /* encrypt it and copy the unpadded part back */
1333 construct_ctr_preload(ctr_preload, a4_exists, qc_exists, pframe, pn_vector, num_blocks+1);
1334
1335 for (j = 0; j < 16; j++)
1336 padded_buffer[j] = 0x00;
1337 for (j = 0; j < payload_remainder; j++)
1338 padded_buffer[j] = pframe[payload_index+j];
1339 aes128k128d(key, ctr_preload, aes_out);
1340 bitwise_xor(aes_out, padded_buffer, chain_buffer);
1341 for (j = 0; j < payload_remainder; j++)
1342 pframe[payload_index++] = chain_buffer[j];
1343 }
1344
1345 /* start to calculate the mic */
1346 if ((hdrlen+plen+8) <= MAX_MSG_SIZE)
1347 memcpy(message, pframe, (hdrlen + plen+8)); /* 8 is for ext iv len */
1348
1349 pn_vector[0] = pframe[hdrlen];
1350 pn_vector[1] = pframe[hdrlen+1];
1351 pn_vector[2] = pframe[hdrlen+4];
1352 pn_vector[3] = pframe[hdrlen+5];
1353 pn_vector[4] = pframe[hdrlen+6];
1354 pn_vector[5] = pframe[hdrlen+7];
1355 construct_mic_iv(mic_iv, qc_exists, a4_exists, message, plen-8, pn_vector);
1356
1357 construct_mic_header1(mic_header1, hdrlen, message);
1358 construct_mic_header2(mic_header2, message, a4_exists, qc_exists);
1359
1360 payload_remainder = (plen-8) % 16;
1361 num_blocks = (plen-8) / 16;
1362
1363 /* Find start of payload */
Tina Johnsondce34ae2015-03-09 12:02:47 +05301364 payload_index = hdrlen + 8;
Larry Finger1b509ca2013-08-21 22:33:48 -05001365
1366 /* Calculate MIC */
1367 aes128k128d(key, mic_iv, aes_out);
1368 bitwise_xor(aes_out, mic_header1, chain_buffer);
1369 aes128k128d(key, chain_buffer, aes_out);
1370 bitwise_xor(aes_out, mic_header2, chain_buffer);
1371 aes128k128d(key, chain_buffer, aes_out);
1372
1373 for (i = 0; i < num_blocks; i++) {
1374 bitwise_xor(aes_out, &message[payload_index], chain_buffer);
1375
1376 payload_index += 16;
1377 aes128k128d(key, chain_buffer, aes_out);
1378 }
1379
1380 /* Add on the final payload block if it needs padding */
1381 if (payload_remainder > 0) {
1382 for (j = 0; j < 16; j++)
1383 padded_buffer[j] = 0x00;
1384 for (j = 0; j < payload_remainder; j++)
1385 padded_buffer[j] = message[payload_index++];
1386 bitwise_xor(aes_out, padded_buffer, chain_buffer);
1387 aes128k128d(key, chain_buffer, aes_out);
1388 }
1389
1390 for (j = 0 ; j < 8; j++)
1391 mic[j] = aes_out[j];
1392
1393 /* Insert MIC into payload */
1394 for (j = 0; j < 8; j++)
1395 message[payload_index+j] = mic[j];
1396
1397 payload_index = hdrlen + 8;
1398 for (i = 0; i < num_blocks; i++) {
1399 construct_ctr_preload(ctr_preload, a4_exists, qc_exists, message, pn_vector, i+1);
1400 aes128k128d(key, ctr_preload, aes_out);
1401 bitwise_xor(aes_out, &message[payload_index], chain_buffer);
1402 for (j = 0; j < 16; j++)
1403 message[payload_index++] = chain_buffer[j];
1404 }
1405
1406 if (payload_remainder > 0) { /* If there is a short final block, then pad it,*/
1407 /* encrypt it and copy the unpadded part back */
1408 construct_ctr_preload(ctr_preload, a4_exists, qc_exists, message, pn_vector, num_blocks+1);
1409
1410 for (j = 0; j < 16; j++)
1411 padded_buffer[j] = 0x00;
1412 for (j = 0; j < payload_remainder; j++)
1413 padded_buffer[j] = message[payload_index+j];
1414 aes128k128d(key, ctr_preload, aes_out);
1415 bitwise_xor(aes_out, padded_buffer, chain_buffer);
1416 for (j = 0; j < payload_remainder; j++)
1417 message[payload_index++] = chain_buffer[j];
1418 }
1419
1420 /* Encrypt the MIC */
1421 construct_ctr_preload(ctr_preload, a4_exists, qc_exists, message, pn_vector, 0);
1422
1423 for (j = 0; j < 16; j++)
1424 padded_buffer[j] = 0x00;
1425 for (j = 0; j < 8; j++)
1426 padded_buffer[j] = message[j+hdrlen+8+plen-8];
1427
1428 aes128k128d(key, ctr_preload, aes_out);
1429 bitwise_xor(aes_out, padded_buffer, chain_buffer);
1430 for (j = 0; j < 8; j++)
1431 message[payload_index++] = chain_buffer[j];
1432
1433 /* compare the mic */
1434 for (i = 0; i < 8; i++) {
1435 if (pframe[hdrlen+8+plen-8+i] != message[hdrlen+8+plen-8+i]) {
1436 RT_TRACE(_module_rtl871x_security_c_, _drv_err_,
1437 ("aes_decipher:mic check error mic[%d]: pframe(%x)!=message(%x)\n",
1438 i, pframe[hdrlen+8+plen-8+i], message[hdrlen+8+plen-8+i]));
1439 DBG_88E("aes_decipher:mic check error mic[%d]: pframe(%x)!=message(%x)\n",
1440 i, pframe[hdrlen+8+plen-8+i], message[hdrlen+8+plen-8+i]);
1441 res = _FAIL;
1442 }
1443 }
Larry Finger1b509ca2013-08-21 22:33:48 -05001444 return res;
1445}
1446
1447u32 rtw_aes_decrypt(struct adapter *padapter, u8 *precvframe)
1448{ /* exclude ICV */
1449 /* Intermediate Buffers */
1450 int length;
1451 u8 *pframe, *prwskey; /* *payload,*iv */
1452 struct sta_info *stainfo;
Larry Fingerf31cca82014-02-14 16:54:07 -06001453 struct rx_pkt_attrib *prxattrib = &((struct recv_frame *)precvframe)->attrib;
Larry Finger1b509ca2013-08-21 22:33:48 -05001454 struct security_priv *psecuritypriv = &padapter->securitypriv;
1455 u32 res = _SUCCESS;
Larry Fingerf31cca82014-02-14 16:54:07 -06001456 pframe = (unsigned char *)((struct recv_frame *)precvframe)->rx_data;
Larry Finger1b509ca2013-08-21 22:33:48 -05001457 /* 4 start to encrypt each fragment */
Gulsah Kose0d20dac2014-10-29 21:29:56 +02001458 if (prxattrib->encrypt == _AES_) {
Larry Finger1b509ca2013-08-21 22:33:48 -05001459 stainfo = rtw_get_stainfo(&padapter->stapriv, &prxattrib->ta[0]);
1460 if (stainfo != NULL) {
1461 RT_TRACE(_module_rtl871x_security_c_, _drv_err_, ("rtw_aes_decrypt: stainfo!= NULL!!!\n"));
1462
1463 if (IS_MCAST(prxattrib->ra)) {
1464 /* in concurrent we should use sw descrypt in group key, so we remove this message */
1465 if (!psecuritypriv->binstallGrpkey) {
1466 res = _FAIL;
1467 DBG_88E("%s:rx bc/mc packets, but didn't install group key!!!!!!!!!!\n", __func__);
1468 goto exit;
1469 }
1470 prwskey = psecuritypriv->dot118021XGrpKey[prxattrib->key_index].skey;
1471 if (psecuritypriv->dot118021XGrpKeyid != prxattrib->key_index) {
1472 DBG_88E("not match packet_index=%d, install_index=%d\n",
1473 prxattrib->key_index, psecuritypriv->dot118021XGrpKeyid);
1474 res = _FAIL;
1475 goto exit;
1476 }
1477 } else {
1478 prwskey = &stainfo->dot118021x_UncstKey.skey[0];
1479 }
Larry Fingerf31cca82014-02-14 16:54:07 -06001480 length = ((struct recv_frame *)precvframe)->len-prxattrib->hdrlen-prxattrib->iv_len;
Larry Finger1b509ca2013-08-21 22:33:48 -05001481 res = aes_decipher(prwskey, prxattrib->hdrlen, pframe, length);
1482 } else {
1483 RT_TRACE(_module_rtl871x_security_c_, _drv_err_, ("rtw_aes_encrypt: stainfo==NULL!!!\n"));
1484 res = _FAIL;
1485 }
1486 }
Larry Finger1b509ca2013-08-21 22:33:48 -05001487exit:
1488 return res;
1489}
1490
1491/* AES tables*/
1492const u32 Te0[256] = {
1493 0xc66363a5U, 0xf87c7c84U, 0xee777799U, 0xf67b7b8dU,
1494 0xfff2f20dU, 0xd66b6bbdU, 0xde6f6fb1U, 0x91c5c554U,
1495 0x60303050U, 0x02010103U, 0xce6767a9U, 0x562b2b7dU,
1496 0xe7fefe19U, 0xb5d7d762U, 0x4dababe6U, 0xec76769aU,
1497 0x8fcaca45U, 0x1f82829dU, 0x89c9c940U, 0xfa7d7d87U,
1498 0xeffafa15U, 0xb25959ebU, 0x8e4747c9U, 0xfbf0f00bU,
1499 0x41adadecU, 0xb3d4d467U, 0x5fa2a2fdU, 0x45afafeaU,
1500 0x239c9cbfU, 0x53a4a4f7U, 0xe4727296U, 0x9bc0c05bU,
1501 0x75b7b7c2U, 0xe1fdfd1cU, 0x3d9393aeU, 0x4c26266aU,
1502 0x6c36365aU, 0x7e3f3f41U, 0xf5f7f702U, 0x83cccc4fU,
1503 0x6834345cU, 0x51a5a5f4U, 0xd1e5e534U, 0xf9f1f108U,
1504 0xe2717193U, 0xabd8d873U, 0x62313153U, 0x2a15153fU,
1505 0x0804040cU, 0x95c7c752U, 0x46232365U, 0x9dc3c35eU,
1506 0x30181828U, 0x379696a1U, 0x0a05050fU, 0x2f9a9ab5U,
1507 0x0e070709U, 0x24121236U, 0x1b80809bU, 0xdfe2e23dU,
1508 0xcdebeb26U, 0x4e272769U, 0x7fb2b2cdU, 0xea75759fU,
1509 0x1209091bU, 0x1d83839eU, 0x582c2c74U, 0x341a1a2eU,
1510 0x361b1b2dU, 0xdc6e6eb2U, 0xb45a5aeeU, 0x5ba0a0fbU,
1511 0xa45252f6U, 0x763b3b4dU, 0xb7d6d661U, 0x7db3b3ceU,
1512 0x5229297bU, 0xdde3e33eU, 0x5e2f2f71U, 0x13848497U,
1513 0xa65353f5U, 0xb9d1d168U, 0x00000000U, 0xc1eded2cU,
1514 0x40202060U, 0xe3fcfc1fU, 0x79b1b1c8U, 0xb65b5bedU,
1515 0xd46a6abeU, 0x8dcbcb46U, 0x67bebed9U, 0x7239394bU,
1516 0x944a4adeU, 0x984c4cd4U, 0xb05858e8U, 0x85cfcf4aU,
1517 0xbbd0d06bU, 0xc5efef2aU, 0x4faaaae5U, 0xedfbfb16U,
1518 0x864343c5U, 0x9a4d4dd7U, 0x66333355U, 0x11858594U,
1519 0x8a4545cfU, 0xe9f9f910U, 0x04020206U, 0xfe7f7f81U,
1520 0xa05050f0U, 0x783c3c44U, 0x259f9fbaU, 0x4ba8a8e3U,
1521 0xa25151f3U, 0x5da3a3feU, 0x804040c0U, 0x058f8f8aU,
1522 0x3f9292adU, 0x219d9dbcU, 0x70383848U, 0xf1f5f504U,
1523 0x63bcbcdfU, 0x77b6b6c1U, 0xafdada75U, 0x42212163U,
1524 0x20101030U, 0xe5ffff1aU, 0xfdf3f30eU, 0xbfd2d26dU,
1525 0x81cdcd4cU, 0x180c0c14U, 0x26131335U, 0xc3ecec2fU,
1526 0xbe5f5fe1U, 0x359797a2U, 0x884444ccU, 0x2e171739U,
1527 0x93c4c457U, 0x55a7a7f2U, 0xfc7e7e82U, 0x7a3d3d47U,
1528 0xc86464acU, 0xba5d5de7U, 0x3219192bU, 0xe6737395U,
1529 0xc06060a0U, 0x19818198U, 0x9e4f4fd1U, 0xa3dcdc7fU,
1530 0x44222266U, 0x542a2a7eU, 0x3b9090abU, 0x0b888883U,
1531 0x8c4646caU, 0xc7eeee29U, 0x6bb8b8d3U, 0x2814143cU,
1532 0xa7dede79U, 0xbc5e5ee2U, 0x160b0b1dU, 0xaddbdb76U,
1533 0xdbe0e03bU, 0x64323256U, 0x743a3a4eU, 0x140a0a1eU,
1534 0x924949dbU, 0x0c06060aU, 0x4824246cU, 0xb85c5ce4U,
1535 0x9fc2c25dU, 0xbdd3d36eU, 0x43acacefU, 0xc46262a6U,
1536 0x399191a8U, 0x319595a4U, 0xd3e4e437U, 0xf279798bU,
1537 0xd5e7e732U, 0x8bc8c843U, 0x6e373759U, 0xda6d6db7U,
1538 0x018d8d8cU, 0xb1d5d564U, 0x9c4e4ed2U, 0x49a9a9e0U,
1539 0xd86c6cb4U, 0xac5656faU, 0xf3f4f407U, 0xcfeaea25U,
1540 0xca6565afU, 0xf47a7a8eU, 0x47aeaee9U, 0x10080818U,
1541 0x6fbabad5U, 0xf0787888U, 0x4a25256fU, 0x5c2e2e72U,
1542 0x381c1c24U, 0x57a6a6f1U, 0x73b4b4c7U, 0x97c6c651U,
1543 0xcbe8e823U, 0xa1dddd7cU, 0xe874749cU, 0x3e1f1f21U,
1544 0x964b4bddU, 0x61bdbddcU, 0x0d8b8b86U, 0x0f8a8a85U,
1545 0xe0707090U, 0x7c3e3e42U, 0x71b5b5c4U, 0xcc6666aaU,
1546 0x904848d8U, 0x06030305U, 0xf7f6f601U, 0x1c0e0e12U,
1547 0xc26161a3U, 0x6a35355fU, 0xae5757f9U, 0x69b9b9d0U,
1548 0x17868691U, 0x99c1c158U, 0x3a1d1d27U, 0x279e9eb9U,
1549 0xd9e1e138U, 0xebf8f813U, 0x2b9898b3U, 0x22111133U,
1550 0xd26969bbU, 0xa9d9d970U, 0x078e8e89U, 0x339494a7U,
1551 0x2d9b9bb6U, 0x3c1e1e22U, 0x15878792U, 0xc9e9e920U,
1552 0x87cece49U, 0xaa5555ffU, 0x50282878U, 0xa5dfdf7aU,
1553 0x038c8c8fU, 0x59a1a1f8U, 0x09898980U, 0x1a0d0d17U,
1554 0x65bfbfdaU, 0xd7e6e631U, 0x844242c6U, 0xd06868b8U,
1555 0x824141c3U, 0x299999b0U, 0x5a2d2d77U, 0x1e0f0f11U,
1556 0x7bb0b0cbU, 0xa85454fcU, 0x6dbbbbd6U, 0x2c16163aU,
1557};
1558
1559const u32 Td0[256] = {
1560 0x51f4a750U, 0x7e416553U, 0x1a17a4c3U, 0x3a275e96U,
1561 0x3bab6bcbU, 0x1f9d45f1U, 0xacfa58abU, 0x4be30393U,
1562 0x2030fa55U, 0xad766df6U, 0x88cc7691U, 0xf5024c25U,
1563 0x4fe5d7fcU, 0xc52acbd7U, 0x26354480U, 0xb562a38fU,
1564 0xdeb15a49U, 0x25ba1b67U, 0x45ea0e98U, 0x5dfec0e1U,
1565 0xc32f7502U, 0x814cf012U, 0x8d4697a3U, 0x6bd3f9c6U,
1566 0x038f5fe7U, 0x15929c95U, 0xbf6d7aebU, 0x955259daU,
1567 0xd4be832dU, 0x587421d3U, 0x49e06929U, 0x8ec9c844U,
1568 0x75c2896aU, 0xf48e7978U, 0x99583e6bU, 0x27b971ddU,
1569 0xbee14fb6U, 0xf088ad17U, 0xc920ac66U, 0x7dce3ab4U,
1570 0x63df4a18U, 0xe51a3182U, 0x97513360U, 0x62537f45U,
1571 0xb16477e0U, 0xbb6bae84U, 0xfe81a01cU, 0xf9082b94U,
1572 0x70486858U, 0x8f45fd19U, 0x94de6c87U, 0x527bf8b7U,
1573 0xab73d323U, 0x724b02e2U, 0xe31f8f57U, 0x6655ab2aU,
1574 0xb2eb2807U, 0x2fb5c203U, 0x86c57b9aU, 0xd33708a5U,
1575 0x302887f2U, 0x23bfa5b2U, 0x02036abaU, 0xed16825cU,
1576 0x8acf1c2bU, 0xa779b492U, 0xf307f2f0U, 0x4e69e2a1U,
1577 0x65daf4cdU, 0x0605bed5U, 0xd134621fU, 0xc4a6fe8aU,
1578 0x342e539dU, 0xa2f355a0U, 0x058ae132U, 0xa4f6eb75U,
1579 0x0b83ec39U, 0x4060efaaU, 0x5e719f06U, 0xbd6e1051U,
1580 0x3e218af9U, 0x96dd063dU, 0xdd3e05aeU, 0x4de6bd46U,
1581 0x91548db5U, 0x71c45d05U, 0x0406d46fU, 0x605015ffU,
1582 0x1998fb24U, 0xd6bde997U, 0x894043ccU, 0x67d99e77U,
1583 0xb0e842bdU, 0x07898b88U, 0xe7195b38U, 0x79c8eedbU,
1584 0xa17c0a47U, 0x7c420fe9U, 0xf8841ec9U, 0x00000000U,
1585 0x09808683U, 0x322bed48U, 0x1e1170acU, 0x6c5a724eU,
1586 0xfd0efffbU, 0x0f853856U, 0x3daed51eU, 0x362d3927U,
1587 0x0a0fd964U, 0x685ca621U, 0x9b5b54d1U, 0x24362e3aU,
1588 0x0c0a67b1U, 0x9357e70fU, 0xb4ee96d2U, 0x1b9b919eU,
1589 0x80c0c54fU, 0x61dc20a2U, 0x5a774b69U, 0x1c121a16U,
1590 0xe293ba0aU, 0xc0a02ae5U, 0x3c22e043U, 0x121b171dU,
1591 0x0e090d0bU, 0xf28bc7adU, 0x2db6a8b9U, 0x141ea9c8U,
1592 0x57f11985U, 0xaf75074cU, 0xee99ddbbU, 0xa37f60fdU,
1593 0xf701269fU, 0x5c72f5bcU, 0x44663bc5U, 0x5bfb7e34U,
1594 0x8b432976U, 0xcb23c6dcU, 0xb6edfc68U, 0xb8e4f163U,
1595 0xd731dccaU, 0x42638510U, 0x13972240U, 0x84c61120U,
1596 0x854a247dU, 0xd2bb3df8U, 0xaef93211U, 0xc729a16dU,
1597 0x1d9e2f4bU, 0xdcb230f3U, 0x0d8652ecU, 0x77c1e3d0U,
1598 0x2bb3166cU, 0xa970b999U, 0x119448faU, 0x47e96422U,
1599 0xa8fc8cc4U, 0xa0f03f1aU, 0x567d2cd8U, 0x223390efU,
1600 0x87494ec7U, 0xd938d1c1U, 0x8ccaa2feU, 0x98d40b36U,
1601 0xa6f581cfU, 0xa57ade28U, 0xdab78e26U, 0x3fadbfa4U,
1602 0x2c3a9de4U, 0x5078920dU, 0x6a5fcc9bU, 0x547e4662U,
1603 0xf68d13c2U, 0x90d8b8e8U, 0x2e39f75eU, 0x82c3aff5U,
1604 0x9f5d80beU, 0x69d0937cU, 0x6fd52da9U, 0xcf2512b3U,
1605 0xc8ac993bU, 0x10187da7U, 0xe89c636eU, 0xdb3bbb7bU,
1606 0xcd267809U, 0x6e5918f4U, 0xec9ab701U, 0x834f9aa8U,
1607 0xe6956e65U, 0xaaffe67eU, 0x21bccf08U, 0xef15e8e6U,
1608 0xbae79bd9U, 0x4a6f36ceU, 0xea9f09d4U, 0x29b07cd6U,
1609 0x31a4b2afU, 0x2a3f2331U, 0xc6a59430U, 0x35a266c0U,
1610 0x744ebc37U, 0xfc82caa6U, 0xe090d0b0U, 0x33a7d815U,
1611 0xf104984aU, 0x41ecdaf7U, 0x7fcd500eU, 0x1791f62fU,
1612 0x764dd68dU, 0x43efb04dU, 0xccaa4d54U, 0xe49604dfU,
1613 0x9ed1b5e3U, 0x4c6a881bU, 0xc12c1fb8U, 0x4665517fU,
1614 0x9d5eea04U, 0x018c355dU, 0xfa877473U, 0xfb0b412eU,
1615 0xb3671d5aU, 0x92dbd252U, 0xe9105633U, 0x6dd64713U,
1616 0x9ad7618cU, 0x37a10c7aU, 0x59f8148eU, 0xeb133c89U,
1617 0xcea927eeU, 0xb761c935U, 0xe11ce5edU, 0x7a47b13cU,
1618 0x9cd2df59U, 0x55f2733fU, 0x1814ce79U, 0x73c737bfU,
1619 0x53f7cdeaU, 0x5ffdaa5bU, 0xdf3d6f14U, 0x7844db86U,
1620 0xcaaff381U, 0xb968c43eU, 0x3824342cU, 0xc2a3405fU,
1621 0x161dc372U, 0xbce2250cU, 0x283c498bU, 0xff0d9541U,
1622 0x39a80171U, 0x080cb3deU, 0xd8b4e49cU, 0x6456c190U,
1623 0x7bcb8461U, 0xd532b670U, 0x486c5c74U, 0xd0b85742U,
1624};
1625
1626const u8 Td4s[256] = {
1627 0x52U, 0x09U, 0x6aU, 0xd5U, 0x30U, 0x36U, 0xa5U, 0x38U,
1628 0xbfU, 0x40U, 0xa3U, 0x9eU, 0x81U, 0xf3U, 0xd7U, 0xfbU,
1629 0x7cU, 0xe3U, 0x39U, 0x82U, 0x9bU, 0x2fU, 0xffU, 0x87U,
1630 0x34U, 0x8eU, 0x43U, 0x44U, 0xc4U, 0xdeU, 0xe9U, 0xcbU,
1631 0x54U, 0x7bU, 0x94U, 0x32U, 0xa6U, 0xc2U, 0x23U, 0x3dU,
1632 0xeeU, 0x4cU, 0x95U, 0x0bU, 0x42U, 0xfaU, 0xc3U, 0x4eU,
1633 0x08U, 0x2eU, 0xa1U, 0x66U, 0x28U, 0xd9U, 0x24U, 0xb2U,
1634 0x76U, 0x5bU, 0xa2U, 0x49U, 0x6dU, 0x8bU, 0xd1U, 0x25U,
1635 0x72U, 0xf8U, 0xf6U, 0x64U, 0x86U, 0x68U, 0x98U, 0x16U,
1636 0xd4U, 0xa4U, 0x5cU, 0xccU, 0x5dU, 0x65U, 0xb6U, 0x92U,
1637 0x6cU, 0x70U, 0x48U, 0x50U, 0xfdU, 0xedU, 0xb9U, 0xdaU,
1638 0x5eU, 0x15U, 0x46U, 0x57U, 0xa7U, 0x8dU, 0x9dU, 0x84U,
1639 0x90U, 0xd8U, 0xabU, 0x00U, 0x8cU, 0xbcU, 0xd3U, 0x0aU,
1640 0xf7U, 0xe4U, 0x58U, 0x05U, 0xb8U, 0xb3U, 0x45U, 0x06U,
1641 0xd0U, 0x2cU, 0x1eU, 0x8fU, 0xcaU, 0x3fU, 0x0fU, 0x02U,
1642 0xc1U, 0xafU, 0xbdU, 0x03U, 0x01U, 0x13U, 0x8aU, 0x6bU,
1643 0x3aU, 0x91U, 0x11U, 0x41U, 0x4fU, 0x67U, 0xdcU, 0xeaU,
1644 0x97U, 0xf2U, 0xcfU, 0xceU, 0xf0U, 0xb4U, 0xe6U, 0x73U,
1645 0x96U, 0xacU, 0x74U, 0x22U, 0xe7U, 0xadU, 0x35U, 0x85U,
1646 0xe2U, 0xf9U, 0x37U, 0xe8U, 0x1cU, 0x75U, 0xdfU, 0x6eU,
1647 0x47U, 0xf1U, 0x1aU, 0x71U, 0x1dU, 0x29U, 0xc5U, 0x89U,
1648 0x6fU, 0xb7U, 0x62U, 0x0eU, 0xaaU, 0x18U, 0xbeU, 0x1bU,
1649 0xfcU, 0x56U, 0x3eU, 0x4bU, 0xc6U, 0xd2U, 0x79U, 0x20U,
1650 0x9aU, 0xdbU, 0xc0U, 0xfeU, 0x78U, 0xcdU, 0x5aU, 0xf4U,
1651 0x1fU, 0xddU, 0xa8U, 0x33U, 0x88U, 0x07U, 0xc7U, 0x31U,
1652 0xb1U, 0x12U, 0x10U, 0x59U, 0x27U, 0x80U, 0xecU, 0x5fU,
1653 0x60U, 0x51U, 0x7fU, 0xa9U, 0x19U, 0xb5U, 0x4aU, 0x0dU,
1654 0x2dU, 0xe5U, 0x7aU, 0x9fU, 0x93U, 0xc9U, 0x9cU, 0xefU,
1655 0xa0U, 0xe0U, 0x3bU, 0x4dU, 0xaeU, 0x2aU, 0xf5U, 0xb0U,
1656 0xc8U, 0xebU, 0xbbU, 0x3cU, 0x83U, 0x53U, 0x99U, 0x61U,
1657 0x17U, 0x2bU, 0x04U, 0x7eU, 0xbaU, 0x77U, 0xd6U, 0x26U,
1658 0xe1U, 0x69U, 0x14U, 0x63U, 0x55U, 0x21U, 0x0cU, 0x7dU,
1659};
1660const u8 rcons[] = {
1661 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x1B, 0x36
1662 /* for 128-bit blocks, Rijndael never uses more than 10 rcon values */
1663};
1664
1665/**
1666 * Expand the cipher key into the encryption key schedule.
1667 *
1668 * @return the number of rounds for the given cipher key size.
1669 */
1670#define ROUND(i, d, s) \
1671do { \
1672 d##0 = TE0(s##0) ^ TE1(s##1) ^ TE2(s##2) ^ TE3(s##3) ^ rk[4 * i]; \
1673 d##1 = TE0(s##1) ^ TE1(s##2) ^ TE2(s##3) ^ TE3(s##0) ^ rk[4 * i + 1]; \
1674 d##2 = TE0(s##2) ^ TE1(s##3) ^ TE2(s##0) ^ TE3(s##1) ^ rk[4 * i + 2]; \
1675 d##3 = TE0(s##3) ^ TE1(s##0) ^ TE2(s##1) ^ TE3(s##2) ^ rk[4 * i + 3]; \
1676} while (0);