Add the rt linux 4.1.3-rt3 as base
[kvmfornfv.git] / kernel / drivers / staging / rtl8723au / core / rtw_security.c
1 /******************************************************************************
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  *
14  ******************************************************************************/
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
26 struct arc4context {
27         u32 x;
28         u32 y;
29         u8 state[256];
30 };
31
32 static 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;
39
40         state = parc4ctx->state;
41         parc4ctx->x = 0;
42         parc4ctx->y = 0;
43         for (counter = 0; counter < 256; counter++)
44                 state[counter] = (u8)counter;
45         keyindex = 0;
46         stateindex = 0;
47         for (counter = 0; counter < 256; counter++) {
48                 t = state[counter];
49                 stateindex = (stateindex + key[keyindex] + t) & 0xff;
50                 u = state[stateindex];
51                 state[stateindex] = (u8)t;
52                 state[counter] = (u8)u;
53                 if (++keyindex >= key_len)
54                         keyindex = 0;
55         }
56
57 }
58
59 static u32 arcfour_byte(struct arc4context *parc4ctx)
60 {
61         u32 x;
62         u32 y;
63         u32 sx, sy;
64         u8 *state;
65
66         state = parc4ctx->state;
67         x = (parc4ctx->x + 1) & 0xff;
68         sx = state[x];
69         y = (sx + parc4ctx->y) & 0xff;
70         sy = state[y];
71         parc4ctx->x = x;
72         parc4ctx->y = y;
73         state[y] = (u8)sx;
74         state[x] = (u8)sy;
75
76         return state[(sx + sy) & 0xff];
77 }
78
79 static void arcfour_encrypt(struct arc4context *parc4ctx, u8 *dest,
80                             u8 *src, u32 len)
81 {
82         u32 i;
83
84         for (i = 0; i < len; i++)
85                 dest[i] = src[i] ^ (unsigned char)arcfour_byte(parc4ctx);
86 }
87
88 static int bcrc32initialized;
89 static u32 crc32_table[256];
90
91 static u8 crc32_reverseBit(u8 data)
92 {
93         u8 retval = ((data << 7) & 0x80) | ((data << 5) & 0x40) |
94                 ((data << 3) & 0x20) | ((data << 1) & 0x10) |
95                 ((data >> 1) & 0x08) | ((data >> 3) & 0x04) |
96                 ((data >> 5) & 0x02) | ((data >> 7) & 0x01);
97         return retval;
98 }
99
100 static void crc32_init(void)
101 {
102         int i, j;
103         u32 c;
104         u8 *p, *p1;
105         u8 k;
106
107         if (bcrc32initialized == 1)
108                 return;
109
110         p = (u8 *) &c;
111         c = 0x12340000;
112
113         for (i = 0; i < 256; ++i) {
114                 k = crc32_reverseBit((u8)i);
115
116                 for (c = ((u32)k) << 24, j = 8; j > 0; --j)
117                         c = c & 0x80000000 ? (c << 1) ^ CRC32_POLY : (c << 1);
118
119                 p1 = (u8 *)&crc32_table[i];
120
121                 p1[0] = crc32_reverseBit(p[3]);
122                 p1[1] = crc32_reverseBit(p[2]);
123                 p1[2] = crc32_reverseBit(p[1]);
124                 p1[3] = crc32_reverseBit(p[0]);
125         }
126
127         bcrc32initialized = 1;
128 }
129
130 static u32 getcrc32(u8 *buf, int len)
131 {
132         u8 *p;
133         u32 crc;
134
135         if (bcrc32initialized == 0)
136                 crc32_init();
137
138         crc = 0xffffffff; /* preload shift register, per CRC-32 spec */
139
140         for (p = buf; len > 0; ++p, --len)
141                 crc = crc32_table[(crc ^ *p) & 0xff] ^ (crc >> 8);
142
143         return ~crc; /* transmit complement, per CRC-32 spec */
144 }
145
146 /* Need to consider the fragment  situation */
147 void rtw_wep_encrypt23a(struct rtw_adapter *padapter,
148                      struct xmit_frame *pxmitframe)
149 {
150         /*  exclude ICV */
151         unsigned char crc[4];
152         struct arc4context mycontext;
153         int curfragnum, length, index;
154         u32 keylength;
155         u8 *pframe, *payload, *iv; /* wepkey */
156         u8 wepkey[16];
157         u8 hw_hdr_offset = 0;
158         struct pkt_attrib *pattrib = &pxmitframe->attrib;
159         struct security_priv *psecuritypriv = &padapter->securitypriv;
160         struct xmit_priv *pxmitpriv = &padapter->xmitpriv;
161
162         if (!pxmitframe->buf_addr)
163                 return;
164
165         hw_hdr_offset = TXDESC_OFFSET;
166
167         pframe = pxmitframe->buf_addr + hw_hdr_offset;
168
169         /* start to encrypt each fragment */
170         if (pattrib->encrypt != WLAN_CIPHER_SUITE_WEP40 &&
171             pattrib->encrypt != WLAN_CIPHER_SUITE_WEP104)
172                 return;
173
174         index = psecuritypriv->dot11PrivacyKeyIndex;
175         keylength = psecuritypriv->wep_key[index].keylen;
176
177         for (curfragnum = 0; curfragnum < pattrib->nr_frags ; curfragnum++) {
178                 iv = pframe + pattrib->hdrlen;
179                 memcpy(&wepkey[0], iv, 3);
180                 memcpy(&wepkey[3], &psecuritypriv->wep_key[index].key,
181                        keylength);
182                 payload = pframe + pattrib->iv_len + pattrib->hdrlen;
183
184                 if ((curfragnum + 1) == pattrib->nr_frags) {
185                         /* the last fragment */
186                         length = pattrib->last_txcmdsz - pattrib->hdrlen -
187                                 pattrib->iv_len - pattrib->icv_len;
188
189                         *((u32 *)crc) = cpu_to_le32(getcrc32(payload, length));
190
191                         arcfour_init(&mycontext, wepkey, 3 + keylength);
192                         arcfour_encrypt(&mycontext, payload, payload, length);
193                         arcfour_encrypt(&mycontext, payload + length, crc, 4);
194                 } else {
195                         length = pxmitpriv->frag_len - pattrib->hdrlen -
196                                 pattrib->iv_len - pattrib->icv_len;
197                         *((u32 *)crc) = cpu_to_le32(getcrc32(payload, length));
198                         arcfour_init(&mycontext, wepkey, 3 + keylength);
199                         arcfour_encrypt(&mycontext, payload, payload, length);
200                         arcfour_encrypt(&mycontext, payload + length, crc, 4);
201
202                         pframe += pxmitpriv->frag_len;
203                         pframe = PTR_ALIGN(pframe, 4);
204                 }
205         }
206
207 }
208
209 void rtw_wep_decrypt23a(struct rtw_adapter *padapter,
210                      struct recv_frame *precvframe)
211 {
212         /*  exclude ICV */
213         u32 actual_crc, expected_crc;
214         struct arc4context mycontext;
215         int length;
216         u32 keylength;
217         u8 *pframe, *payload, *iv, wepkey[16];
218         u8 keyindex;
219         struct rx_pkt_attrib *prxattrib = &precvframe->attrib;
220         struct security_priv *psecuritypriv = &padapter->securitypriv;
221         struct sk_buff *skb = precvframe->pkt;
222
223         pframe = skb->data;
224
225         /* start to decrypt recvframe */
226         if (prxattrib->encrypt != WLAN_CIPHER_SUITE_WEP40 &&
227             prxattrib->encrypt != WLAN_CIPHER_SUITE_WEP104)
228                 return;
229
230         iv = pframe + prxattrib->hdrlen;
231         /* keyindex = (iv[3]&0x3); */
232         keyindex = prxattrib->key_index;
233         keylength = psecuritypriv->wep_key[keyindex].keylen;
234         memcpy(&wepkey[0], iv, 3);
235         /* memcpy(&wepkey[3], &psecuritypriv->dot11DefKey[psecuritypriv->dot11PrivacyKeyIndex].skey[0], keylength); */
236         memcpy(&wepkey[3], &psecuritypriv->wep_key[keyindex].key, keylength);
237         length = skb->len - prxattrib->hdrlen - prxattrib->iv_len;
238
239         payload = pframe + prxattrib->iv_len + prxattrib->hdrlen;
240
241         /* decrypt payload include icv */
242         arcfour_init(&mycontext, wepkey, 3 + keylength);
243         arcfour_encrypt(&mycontext, payload, payload, length);
244
245         /* calculate icv and compare the icv */
246         actual_crc = le32_to_cpu(getcrc32(payload, length - 4));
247         expected_crc = le32_to_cpu(get_unaligned_le32(&payload[length - 4]));
248
249         if (actual_crc != expected_crc) {
250                 RT_TRACE(_module_rtl871x_security_c_, _drv_err_,
251                          "%s:icv CRC mismatch: "
252                          "actual: %08x, expected: %08x\n",
253                          __func__, actual_crc, expected_crc);
254         }
255 }
256
257 /* 3            ===== TKIP related ===== */
258
259 static u32 secmicgetuint32(u8 *p)
260 /*  Convert from Byte[] to u32 in a portable way */
261 {
262         s32 i;
263         u32 res = 0;
264
265         for (i = 0; i < 4; i++)
266                 res |= ((u32)(*p++)) << (8 * i);
267
268         return res;
269 }
270
271 static void secmicputuint32(u8 *p, u32 val)
272 /*  Convert from long to Byte[] in a portable way */
273 {
274         long i;
275
276         for (i = 0; i < 4; i++) {
277                 *p++ = (u8) (val & 0xff);
278                 val >>= 8;
279         }
280
281 }
282
283 static void secmicclear(struct mic_data *pmicdata)
284 {
285 /*  Reset the state to the empty message. */
286
287         pmicdata->L = pmicdata->K0;
288         pmicdata->R = pmicdata->K1;
289         pmicdata->nBytesInM = 0;
290         pmicdata->M = 0;
291
292 }
293
294 void rtw_secmicsetkey23a(struct mic_data *pmicdata, u8 *key)
295 {
296         /*  Set the key */
297
298         pmicdata->K0 = secmicgetuint32(key);
299         pmicdata->K1 = secmicgetuint32(key + 4);
300         /*  and reset the message */
301         secmicclear(pmicdata);
302
303 }
304
305 void rtw_secmicappend23abyte23a(struct mic_data *pmicdata, u8 b)
306 {
307
308         /*  Append the byte to our word-sized buffer */
309         pmicdata->M |= ((unsigned long)b) << (8 * pmicdata->nBytesInM);
310         pmicdata->nBytesInM++;
311         /*  Process the word if it is full. */
312         if (pmicdata->nBytesInM >= 4) {
313                 pmicdata->L ^= pmicdata->M;
314                 pmicdata->R ^= ROL32(pmicdata->L, 17);
315                 pmicdata->L += pmicdata->R;
316                 pmicdata->R ^= ((pmicdata->L & 0xff00ff00) >> 8) | ((pmicdata->L & 0x00ff00ff) << 8);
317                 pmicdata->L += pmicdata->R;
318                 pmicdata->R ^= ROL32(pmicdata->L, 3);
319                 pmicdata->L += pmicdata->R;
320                 pmicdata->R ^= ROR32(pmicdata->L, 2);
321                 pmicdata->L += pmicdata->R;
322                 /*  Clear the buffer */
323                 pmicdata->M = 0;
324                 pmicdata->nBytesInM = 0;
325         }
326
327 }
328
329 void rtw_secmicappend23a(struct mic_data *pmicdata, u8 *src, u32 nbytes)
330 {
331
332         /*  This is simple */
333         while (nbytes > 0) {
334                 rtw_secmicappend23abyte23a(pmicdata, *src++);
335                 nbytes--;
336         }
337
338 }
339
340 void rtw_secgetmic23a(struct mic_data *pmicdata, u8 *dst)
341 {
342
343         /*  Append the minimum padding */
344         rtw_secmicappend23abyte23a(pmicdata, 0x5a);
345         rtw_secmicappend23abyte23a(pmicdata, 0);
346         rtw_secmicappend23abyte23a(pmicdata, 0);
347         rtw_secmicappend23abyte23a(pmicdata, 0);
348         rtw_secmicappend23abyte23a(pmicdata, 0);
349         /*  and then zeroes until the length is a multiple of 4 */
350         while (pmicdata->nBytesInM != 0)
351                 rtw_secmicappend23abyte23a(pmicdata, 0);
352         /*  The appendByte function has already computed the result. */
353         secmicputuint32(dst, pmicdata->L);
354         secmicputuint32(dst + 4, pmicdata->R);
355         /*  Reset to the empty message. */
356         secmicclear(pmicdata);
357
358 }
359
360 void rtw_seccalctkipmic23a(u8 *key, u8 *header, u8 *data, u32 data_len,
361                            u8 *mic_code, u8 pri)
362 {
363
364         struct mic_data micdata;
365         u8 priority[4] = {0x0, 0x0, 0x0, 0x0};
366
367         rtw_secmicsetkey23a(&micdata, key);
368         priority[0] = pri;
369
370         /* Michael MIC pseudo header: DA, SA, 3 x 0, Priority */
371         if (header[1]&1) { /* ToDS == 1 */
372                         rtw_secmicappend23a(&micdata, &header[16], 6); /* DA */
373                 if (header[1]&2) /* From Ds == 1 */
374                         rtw_secmicappend23a(&micdata, &header[24], 6);
375                 else
376                         rtw_secmicappend23a(&micdata, &header[10], 6);
377         } else { /* ToDS == 0 */
378                 rtw_secmicappend23a(&micdata, &header[4], 6); /* DA */
379                 if (header[1]&2) /* From Ds == 1 */
380                         rtw_secmicappend23a(&micdata, &header[16], 6);
381                 else
382                         rtw_secmicappend23a(&micdata, &header[10], 6);
383
384         }
385         rtw_secmicappend23a(&micdata, &priority[0], 4);
386
387         rtw_secmicappend23a(&micdata, data, data_len);
388
389         rtw_secgetmic23a(&micdata, mic_code);
390
391 }
392
393 /* macros for extraction/creation of unsigned char/unsigned short values  */
394 #define RotR1(v16)   ((((v16) >> 1) & 0x7FFF) ^ (((v16) & 1) << 15))
395 #define   Lo8(v16)   ((u8)((v16)       & 0x00FF))
396 #define   Hi8(v16)   ((u8)(((v16) >> 8) & 0x00FF))
397 #define  Lo16(v32)   ((u16)((v32)       & 0xFFFF))
398 #define  Hi16(v32)   ((u16)(((v32) >> 16) & 0xFFFF))
399 #define  Mk16(hi, lo) ((lo) ^ (((u16)(hi)) << 8))
400
401 /* select the Nth 16-bit word of the temporal key unsigned char array TK[] */
402 #define  TK16(N)     Mk16(tk[2 * (N) + 1], tk[2 * (N)])
403
404 /* S-box lookup: 16 bits --> 16 bits */
405 #define _S_(v16)     (Sbox1[0][Lo8(v16)] ^ Sbox1[1][Hi8(v16)])
406
407 /* fixed algorithm "parameters" */
408 #define PHASE1_LOOP_CNT   8    /* this needs to be "big enough"     */
409 #define TA_SIZE           6    /*  48-bit transmitter address       */
410 #define TK_SIZE          16    /* 128-bit temporal key              */
411 #define P1K_SIZE         10    /*  80-bit Phase1 key                */
412 #define RC4_KEY_SIZE     16    /* 128-bit RC4KEY (104 bits unknown) */
413
414 /* 2-unsigned char by 2-unsigned char subset of the full AES S-box table */
415 static const unsigned short Sbox1[2][256] = {
416         /* Sbox for hash (can be in ROM) */
417         {
418                 0xC6A5, 0xF884, 0xEE99, 0xF68D, 0xFF0D, 0xD6BD, 0xDEB1, 0x9154,
419                 0x6050, 0x0203, 0xCEA9, 0x567D, 0xE719, 0xB562, 0x4DE6, 0xEC9A,
420                 0x8F45, 0x1F9D, 0x8940, 0xFA87, 0xEF15, 0xB2EB, 0x8EC9, 0xFB0B,
421                 0x41EC, 0xB367, 0x5FFD, 0x45EA, 0x23BF, 0x53F7, 0xE496, 0x9B5B,
422                 0x75C2, 0xE11C, 0x3DAE, 0x4C6A, 0x6C5A, 0x7E41, 0xF502, 0x834F,
423                 0x685C, 0x51F4, 0xD134, 0xF908, 0xE293, 0xAB73, 0x6253, 0x2A3F,
424                 0x080C, 0x9552, 0x4665, 0x9D5E, 0x3028, 0x37A1, 0x0A0F, 0x2FB5,
425                 0x0E09, 0x2436, 0x1B9B, 0xDF3D, 0xCD26, 0x4E69, 0x7FCD, 0xEA9F,
426                 0x121B, 0x1D9E, 0x5874, 0x342E, 0x362D, 0xDCB2, 0xB4EE, 0x5BFB,
427                 0xA4F6, 0x764D, 0xB761, 0x7DCE, 0x527B, 0xDD3E, 0x5E71, 0x1397,
428                 0xA6F5, 0xB968, 0x0000, 0xC12C, 0x4060, 0xE31F, 0x79C8, 0xB6ED,
429                 0xD4BE, 0x8D46, 0x67D9, 0x724B, 0x94DE, 0x98D4, 0xB0E8, 0x854A,
430                 0xBB6B, 0xC52A, 0x4FE5, 0xED16, 0x86C5, 0x9AD7, 0x6655, 0x1194,
431                 0x8ACF, 0xE910, 0x0406, 0xFE81, 0xA0F0, 0x7844, 0x25BA, 0x4BE3,
432                 0xA2F3, 0x5DFE, 0x80C0, 0x058A, 0x3FAD, 0x21BC, 0x7048, 0xF104,
433                 0x63DF, 0x77C1, 0xAF75, 0x4263, 0x2030, 0xE51A, 0xFD0E, 0xBF6D,
434                 0x814C, 0x1814, 0x2635, 0xC32F, 0xBEE1, 0x35A2, 0x88CC, 0x2E39,
435                 0x9357, 0x55F2, 0xFC82, 0x7A47, 0xC8AC, 0xBAE7, 0x322B, 0xE695,
436                 0xC0A0, 0x1998, 0x9ED1, 0xA37F, 0x4466, 0x547E, 0x3BAB, 0x0B83,
437                 0x8CCA, 0xC729, 0x6BD3, 0x283C, 0xA779, 0xBCE2, 0x161D, 0xAD76,
438                 0xDB3B, 0x6456, 0x744E, 0x141E, 0x92DB, 0x0C0A, 0x486C, 0xB8E4,
439                 0x9F5D, 0xBD6E, 0x43EF, 0xC4A6, 0x39A8, 0x31A4, 0xD337, 0xF28B,
440                 0xD532, 0x8B43, 0x6E59, 0xDAB7, 0x018C, 0xB164, 0x9CD2, 0x49E0,
441                 0xD8B4, 0xACFA, 0xF307, 0xCF25, 0xCAAF, 0xF48E, 0x47E9, 0x1018,
442                 0x6FD5, 0xF088, 0x4A6F, 0x5C72, 0x3824, 0x57F1, 0x73C7, 0x9751,
443                 0xCB23, 0xA17C, 0xE89C, 0x3E21, 0x96DD, 0x61DC, 0x0D86, 0x0F85,
444                 0xE090, 0x7C42, 0x71C4, 0xCCAA, 0x90D8, 0x0605, 0xF701, 0x1C12,
445                 0xC2A3, 0x6A5F, 0xAEF9, 0x69D0, 0x1791, 0x9958, 0x3A27, 0x27B9,
446                 0xD938, 0xEB13, 0x2BB3, 0x2233, 0xD2BB, 0xA970, 0x0789, 0x33A7,
447                 0x2DB6, 0x3C22, 0x1592, 0xC920, 0x8749, 0xAAFF, 0x5078, 0xA57A,
448                 0x038F, 0x59F8, 0x0980, 0x1A17, 0x65DA, 0xD731, 0x84C6, 0xD0B8,
449                 0x82C3, 0x29B0, 0x5A77, 0x1E11, 0x7BCB, 0xA8FC, 0x6DD6, 0x2C3A,
450         },
451         { /* second half of table is unsigned char-reversed version of first! */
452                 0xA5C6, 0x84F8, 0x99EE, 0x8DF6, 0x0DFF, 0xBDD6, 0xB1DE, 0x5491,
453                 0x5060, 0x0302, 0xA9CE, 0x7D56, 0x19E7, 0x62B5, 0xE64D, 0x9AEC,
454                 0x458F, 0x9D1F, 0x4089, 0x87FA, 0x15EF, 0xEBB2, 0xC98E, 0x0BFB,
455                 0xEC41, 0x67B3, 0xFD5F, 0xEA45, 0xBF23, 0xF753, 0x96E4, 0x5B9B,
456                 0xC275, 0x1CE1, 0xAE3D, 0x6A4C, 0x5A6C, 0x417E, 0x02F5, 0x4F83,
457                 0x5C68, 0xF451, 0x34D1, 0x08F9, 0x93E2, 0x73AB, 0x5362, 0x3F2A,
458                 0x0C08, 0x5295, 0x6546, 0x5E9D, 0x2830, 0xA137, 0x0F0A, 0xB52F,
459                 0x090E, 0x3624, 0x9B1B, 0x3DDF, 0x26CD, 0x694E, 0xCD7F, 0x9FEA,
460                 0x1B12, 0x9E1D, 0x7458, 0x2E34, 0x2D36, 0xB2DC, 0xEEB4, 0xFB5B,
461                 0xF6A4, 0x4D76, 0x61B7, 0xCE7D, 0x7B52, 0x3EDD, 0x715E, 0x9713,
462                 0xF5A6, 0x68B9, 0x0000, 0x2CC1, 0x6040, 0x1FE3, 0xC879, 0xEDB6,
463                 0xBED4, 0x468D, 0xD967, 0x4B72, 0xDE94, 0xD498, 0xE8B0, 0x4A85,
464                 0x6BBB, 0x2AC5, 0xE54F, 0x16ED, 0xC586, 0xD79A, 0x5566, 0x9411,
465                 0xCF8A, 0x10E9, 0x0604, 0x81FE, 0xF0A0, 0x4478, 0xBA25, 0xE34B,
466                 0xF3A2, 0xFE5D, 0xC080, 0x8A05, 0xAD3F, 0xBC21, 0x4870, 0x04F1,
467                 0xDF63, 0xC177, 0x75AF, 0x6342, 0x3020, 0x1AE5, 0x0EFD, 0x6DBF,
468                 0x4C81, 0x1418, 0x3526, 0x2FC3, 0xE1BE, 0xA235, 0xCC88, 0x392E,
469                 0x5793, 0xF255, 0x82FC, 0x477A, 0xACC8, 0xE7BA, 0x2B32, 0x95E6,
470                 0xA0C0, 0x9819, 0xD19E, 0x7FA3, 0x6644, 0x7E54, 0xAB3B, 0x830B,
471                 0xCA8C, 0x29C7, 0xD36B, 0x3C28, 0x79A7, 0xE2BC, 0x1D16, 0x76AD,
472                 0x3BDB, 0x5664, 0x4E74, 0x1E14, 0xDB92, 0x0A0C, 0x6C48, 0xE4B8,
473                 0x5D9F, 0x6EBD, 0xEF43, 0xA6C4, 0xA839, 0xA431, 0x37D3, 0x8BF2,
474                 0x32D5, 0x438B, 0x596E, 0xB7DA, 0x8C01, 0x64B1, 0xD29C, 0xE049,
475                 0xB4D8, 0xFAAC, 0x07F3, 0x25CF, 0xAFCA, 0x8EF4, 0xE947, 0x1810,
476                 0xD56F, 0x88F0, 0x6F4A, 0x725C, 0x2438, 0xF157, 0xC773, 0x5197,
477                 0x23CB, 0x7CA1, 0x9CE8, 0x213E, 0xDD96, 0xDC61, 0x860D, 0x850F,
478                 0x90E0, 0x427C, 0xC471, 0xAACC, 0xD890, 0x0506, 0x01F7, 0x121C,
479                 0xA3C2, 0x5F6A, 0xF9AE, 0xD069, 0x9117, 0x5899, 0x273A, 0xB927,
480                 0x38D9, 0x13EB, 0xB32B, 0x3322, 0xBBD2, 0x70A9, 0x8907, 0xA733,
481                 0xB62D, 0x223C, 0x9215, 0x20C9, 0x4987, 0xFFAA, 0x7850, 0x7AA5,
482                 0x8F03, 0xF859, 0x8009, 0x171A, 0xDA65, 0x31D7, 0xC684, 0xB8D0,
483                 0xC382, 0xB029, 0x775A, 0x111E, 0xCB7B, 0xFCA8, 0xD66D, 0x3A2C,
484         }
485 };
486
487  /*
488 **********************************************************************
489 * Routine: Phase 1 -- generate P1K, given TA, TK, IV32
490 *
491 * Inputs:
492 *     tk[]      = temporal key                         [128 bits]
493 *     ta[]      = transmitter's MAC address            [ 48 bits]
494 *     iv32      = upper 32 bits of IV                  [ 32 bits]
495 * Output:
496 *     p1k[]     = Phase 1 key                          [ 80 bits]
497 *
498 * Note:
499 *     This function only needs to be called every 2**16 packets,
500 *     although in theory it could be called every packet.
501 *
502 **********************************************************************
503 */
504 static void phase1(u16 *p1k, const u8 *tk, const u8 *ta, u32 iv32)
505 {
506         int  i;
507
508         /* Initialize the 80 bits of P1K[] from IV32 and TA[0..5] */
509         p1k[0]      = Lo16(iv32);
510         p1k[1]      = Hi16(iv32);
511         p1k[2]      = Mk16(ta[1], ta[0]); /* use TA[] as little-endian */
512         p1k[3]      = Mk16(ta[3], ta[2]);
513         p1k[4]      = Mk16(ta[5], ta[4]);
514
515         /* Now compute an unbalanced Feistel cipher with 80-bit block */
516         /* size on the 80-bit block P1K[], using the 128-bit key TK[] */
517         for (i = 0; i < PHASE1_LOOP_CNT; i++) {
518                 /* Each add operation here is mod 2**16 */
519                 p1k[0] += _S_(p1k[4] ^ TK16((i & 1) + 0));
520                 p1k[1] += _S_(p1k[0] ^ TK16((i & 1) + 2));
521                 p1k[2] += _S_(p1k[1] ^ TK16((i & 1) + 4));
522                 p1k[3] += _S_(p1k[2] ^ TK16((i & 1) + 6));
523                 p1k[4] += _S_(p1k[3] ^ TK16((i & 1) + 0));
524                 p1k[4] +=  (unsigned short) i; /* avoid "slide attacks" */
525                 }
526
527 }
528
529 /*
530 **********************************************************************
531 * Routine: Phase 2 -- generate RC4KEY, given TK, P1K, IV16
532 *
533 * Inputs:
534 *     tk[]      = Temporal key                         [128 bits]
535 *     p1k[]     = Phase 1 output key                   [ 80 bits]
536 *     iv16      = low 16 bits of IV counter            [ 16 bits]
537 * Output:
538 *     rc4key[]  = the key used to encrypt the packet   [128 bits]
539 *
540 * Note:
541 *     The value {TA, IV32, IV16} for Phase1/Phase2 must be unique
542 *     across all packets using the same key TK value. Then, for a
543 *     given value of TK[], this TKIP48 construction guarantees that
544 *     the final RC4KEY value is unique across all packets.
545 *
546 * Suggested implementation optimization: if PPK[] is "overlaid"
547 *     appropriately on RC4KEY[], there is no need for the final
548 *     for loop below that copies the PPK[] result into RC4KEY[].
549 *
550 **********************************************************************
551 */
552 static void phase2(u8 *rc4key, const u8 *tk, const u16 *p1k, u16 iv16)
553 {
554         int  i;
555         u16 PPK[6]; /* temporary key for mixing    */
556
557         /* Note: all adds in the PPK[] equations below are mod 2**16 */
558         for (i = 0; i < 5; i++)
559                 PPK[i] = p1k[i]; /* first, copy P1K to PPK */
560
561         PPK[5] = p1k[4] + iv16; /* next,  add in IV16 */
562
563         /* Bijective non-linear mixing of the 96 bits of PPK[0..5] */
564         PPK[0] += _S_(PPK[5] ^ TK16(0)); /* Mix key in each "round" */
565         PPK[1] += _S_(PPK[0] ^ TK16(1));
566         PPK[2] += _S_(PPK[1] ^ TK16(2));
567         PPK[3] += _S_(PPK[2] ^ TK16(3));
568         PPK[4] += _S_(PPK[3] ^ TK16(4));
569         PPK[5] += _S_(PPK[4] ^ TK16(5)); /* Total # S-box lookups == 6 */
570
571         /* Final sweep: bijective, "linear". Rotates kill LSB correlations */
572         PPK[0] +=  RotR1(PPK[5] ^ TK16(6));
573         PPK[1] +=  RotR1(PPK[0] ^ TK16(7)); /* Use all of TK[] in Phase2 */
574         PPK[2] +=  RotR1(PPK[1]);
575         PPK[3] +=  RotR1(PPK[2]);
576         PPK[4] +=  RotR1(PPK[3]);
577         PPK[5] +=  RotR1(PPK[4]);
578         /* Note: At this point, for a given key TK[0..15], the 96-bit output */
579         /*       value PPK[0..5] is guaranteed to be unique, as a function   */
580         /*       of the 96-bit "input" value   {TA, IV32, IV16}. That is,    */
581         /*       P1K is now a keyed permutation of {TA, IV32, IV16}.         */
582
583         /* Set RC4KEY[0..3], which includes "cleartext" portion of RC4 key   */
584         rc4key[0] = Hi8(iv16);                 /* RC4KEY[0..2] is the WEP IV */
585         rc4key[1] = (Hi8(iv16) | 0x20) & 0x7F; /* Help avoid weak (FMS) keys */
586         rc4key[2] = Lo8(iv16);
587         rc4key[3] = Lo8((PPK[5] ^ TK16(0)) >> 1);
588
589         /* Copy 96 bits of PPK[0..5] to RC4KEY[4..15]  (little-endian) */
590         for (i = 0; i < 6; i++) {
591                 rc4key[4 + 2 * i] = Lo8(PPK[i]);
592                 rc4key[5 + 2 * i] = Hi8(PPK[i]);
593         }
594
595 }
596
597 /* The hlen isn't include the IV */
598 int rtw_tkip_encrypt23a(struct rtw_adapter *padapter,
599                         struct xmit_frame *pxmitframe)
600 {
601         u16 pnl;
602         u32 pnh;
603         u8 rc4key[16];
604         u8 ttkey[16];
605         u8 crc[4];
606         u8 hw_hdr_offset = 0;
607         struct arc4context mycontext;
608         int curfragnum, length;
609         u32 prwskeylen;
610         u8 *pframe, *payload, *iv, *prwskey;
611         union pn48 dot11txpn;
612         struct sta_info *stainfo;
613         struct pkt_attrib *pattrib = &pxmitframe->attrib;
614         struct security_priv *psecuritypriv = &padapter->securitypriv;
615         struct xmit_priv *pxmitpriv = &padapter->xmitpriv;
616         int res = _SUCCESS;
617
618         if (pattrib->encrypt != WLAN_CIPHER_SUITE_TKIP)
619                 return _FAIL;
620
621         if (!pxmitframe->buf_addr)
622                 return _FAIL;
623
624         hw_hdr_offset = TXDESC_OFFSET;
625
626         pframe = pxmitframe->buf_addr + hw_hdr_offset;
627
628         if (pattrib->psta)
629                 stainfo = pattrib->psta;
630         else {
631                 DBG_8723A("%s, call rtw_get_stainfo()\n", __func__);
632                 stainfo = rtw_get_stainfo23a(&padapter->stapriv,
633                                              &pattrib->ra[0]);
634         }
635
636         if (stainfo == NULL) {
637                 RT_TRACE(_module_rtl871x_security_c_, _drv_err_,
638                          "%s: stainfo == NULL!!!\n", __func__);
639                 DBG_8723A("%s, psta == NUL\n", __func__);
640                 return _FAIL;
641         }
642
643         RT_TRACE(_module_rtl871x_security_c_, _drv_err_,
644                  "%s: stainfo!= NULL!!!\n", __func__);
645
646         if (!(stainfo->state & _FW_LINKED)) {
647                 DBG_8723A("%s, psta->state(0x%x) != _FW_LINKED\n", __func__, stainfo->state);
648                 return _FAIL;
649         }
650
651         if (is_multicast_ether_addr(pattrib->ra))
652                 prwskey = psecuritypriv->dot118021XGrpKey[psecuritypriv->dot118021XGrpKeyid].skey;
653         else
654                 prwskey = &stainfo->dot118021x_UncstKey.skey[0];
655
656         prwskeylen = 16;
657
658         /* 4 start to encrypt each fragment */
659         for (curfragnum = 0; curfragnum < pattrib->nr_frags; curfragnum++) {
660                 iv = pframe + pattrib->hdrlen;
661                 payload = pframe + pattrib->iv_len + pattrib->hdrlen;
662
663                 GET_TKIP_PN(iv, dot11txpn);
664
665                 pnl = (u16)(dot11txpn.val);
666                 pnh = (u32)(dot11txpn.val>>16);
667
668                 phase1((u16 *)&ttkey[0], prwskey, &pattrib->ta[0], pnh);
669
670                 phase2(&rc4key[0], prwskey, (u16 *)&ttkey[0], pnl);
671
672                 if ((curfragnum + 1) == pattrib->nr_frags) { /* 4 the last fragment */
673                         length = (pattrib->last_txcmdsz -
674                                   pattrib->hdrlen -
675                                   pattrib->iv_len -
676                                   pattrib->icv_len);
677
678                         RT_TRACE(_module_rtl871x_security_c_, _drv_info_,
679                                  "pattrib->iv_len =%x, pattrib->icv_len =%x\n",
680                                  pattrib->iv_len,
681                                  pattrib->icv_len);
682                         *((u32 *)crc) = cpu_to_le32(getcrc32(payload, length));
683
684                         arcfour_init(&mycontext, rc4key, 16);
685                         arcfour_encrypt(&mycontext, payload, payload, length);
686                         arcfour_encrypt(&mycontext, payload + length, crc, 4);
687
688                 } else {
689                         length = (pxmitpriv->frag_len -
690                                   pattrib->hdrlen -
691                                   pattrib->iv_len -
692                                   pattrib->icv_len);
693
694                         *((u32 *)crc) = cpu_to_le32(getcrc32(payload, length));
695                         arcfour_init(&mycontext, rc4key, 16);
696                         arcfour_encrypt(&mycontext, payload, payload, length);
697                         arcfour_encrypt(&mycontext, payload + length, crc, 4);
698
699                         pframe += pxmitpriv->frag_len;
700                         pframe  = PTR_ALIGN(pframe, 4);
701                 }
702         }
703
704         return res;
705 }
706
707 /* The hlen isn't include the IV */
708 int rtw_tkip_decrypt23a(struct rtw_adapter *padapter,
709                         struct recv_frame *precvframe)
710 {
711         u16 pnl;
712         u32 pnh;
713         u8 rc4key[16];
714         u8 ttkey[16];
715         u32 actual_crc, expected_crc;
716         struct arc4context mycontext;
717         int length;
718         u32 prwskeylen;
719         u8 *pframe, *payload, *iv, *prwskey;
720         union pn48 dot11txpn;
721         struct sta_info *stainfo;
722         struct rx_pkt_attrib *prxattrib = &precvframe->attrib;
723         struct security_priv *psecuritypriv = &padapter->securitypriv;
724         struct sk_buff *skb = precvframe->pkt;
725         int res = _SUCCESS;
726
727         if (prxattrib->encrypt != WLAN_CIPHER_SUITE_TKIP)
728                 return _FAIL;
729
730         pframe = skb->data;
731
732         stainfo = rtw_get_stainfo23a(&padapter->stapriv,
733                                      &prxattrib->ta[0]);
734         if (stainfo == NULL) {
735                 RT_TRACE(_module_rtl871x_security_c_, _drv_err_,
736                          "%s: stainfo == NULL!!!\n", __func__);
737                 return _FAIL;
738         }
739
740         /* 4 start to decrypt recvframe */
741         if (is_multicast_ether_addr(prxattrib->ra)) {
742                 if (psecuritypriv->binstallGrpkey == 0) {
743                         res = _FAIL;
744                         DBG_8723A("%s:rx bc/mc packets, but didn't install group key!!!!!!!!!!\n", __func__);
745                         goto exit;
746                 }
747                 prwskey = psecuritypriv->dot118021XGrpKey[prxattrib->key_index].skey;
748                 prwskeylen = 16;
749         } else {
750                 RT_TRACE(_module_rtl871x_security_c_, _drv_err_,
751                          "%s: stainfo!= NULL!!!\n", __func__);
752                 prwskey = &stainfo->dot118021x_UncstKey.skey[0];
753                 prwskeylen = 16;
754         }
755
756         iv = pframe + prxattrib->hdrlen;
757         payload = pframe + prxattrib->iv_len + prxattrib->hdrlen;
758         length = skb->len - prxattrib->hdrlen - prxattrib->iv_len;
759
760         GET_TKIP_PN(iv, dot11txpn);
761
762         pnl = (u16)(dot11txpn.val);
763         pnh = (u32)(dot11txpn.val>>16);
764
765         phase1((u16 *)&ttkey[0], prwskey, &prxattrib->ta[0], pnh);
766         phase2(&rc4key[0], prwskey, (unsigned short *)&ttkey[0], pnl);
767
768         /* 4 decrypt payload include icv */
769         arcfour_init(&mycontext, rc4key, 16);
770         arcfour_encrypt(&mycontext, payload, payload, length);
771
772         actual_crc = le32_to_cpu(getcrc32(payload, length - 4));
773         expected_crc = le32_to_cpu(get_unaligned_le32(&payload[length - 4]));
774
775         if (actual_crc != expected_crc) {
776                 RT_TRACE(_module_rtl871x_security_c_, _drv_err_,
777                          "%s:icv CRC mismatch: "
778                          "actual: %08x, expected: %08x\n",
779                          __func__, actual_crc, expected_crc);
780                 res = _FAIL;
781         }
782
783 exit:
784         return res;
785 }
786
787 /* 3                    ===== AES related ===== */
788
789 #define MAX_MSG_SIZE    2048
790 /*****************************/
791 /******** SBOX Table *********/
792 /*****************************/
793
794 static  u8 sbox_table[256] = {
795         0x63, 0x7c, 0x77, 0x7b, 0xf2, 0x6b, 0x6f, 0xc5,
796         0x30, 0x01, 0x67, 0x2b, 0xfe, 0xd7, 0xab, 0x76,
797         0xca, 0x82, 0xc9, 0x7d, 0xfa, 0x59, 0x47, 0xf0,
798         0xad, 0xd4, 0xa2, 0xaf, 0x9c, 0xa4, 0x72, 0xc0,
799         0xb7, 0xfd, 0x93, 0x26, 0x36, 0x3f, 0xf7, 0xcc,
800         0x34, 0xa5, 0xe5, 0xf1, 0x71, 0xd8, 0x31, 0x15,
801         0x04, 0xc7, 0x23, 0xc3, 0x18, 0x96, 0x05, 0x9a,
802         0x07, 0x12, 0x80, 0xe2, 0xeb, 0x27, 0xb2, 0x75,
803         0x09, 0x83, 0x2c, 0x1a, 0x1b, 0x6e, 0x5a, 0xa0,
804         0x52, 0x3b, 0xd6, 0xb3, 0x29, 0xe3, 0x2f, 0x84,
805         0x53, 0xd1, 0x00, 0xed, 0x20, 0xfc, 0xb1, 0x5b,
806         0x6a, 0xcb, 0xbe, 0x39, 0x4a, 0x4c, 0x58, 0xcf,
807         0xd0, 0xef, 0xaa, 0xfb, 0x43, 0x4d, 0x33, 0x85,
808         0x45, 0xf9, 0x02, 0x7f, 0x50, 0x3c, 0x9f, 0xa8,
809         0x51, 0xa3, 0x40, 0x8f, 0x92, 0x9d, 0x38, 0xf5,
810         0xbc, 0xb6, 0xda, 0x21, 0x10, 0xff, 0xf3, 0xd2,
811         0xcd, 0x0c, 0x13, 0xec, 0x5f, 0x97, 0x44, 0x17,
812         0xc4, 0xa7, 0x7e, 0x3d, 0x64, 0x5d, 0x19, 0x73,
813         0x60, 0x81, 0x4f, 0xdc, 0x22, 0x2a, 0x90, 0x88,
814         0x46, 0xee, 0xb8, 0x14, 0xde, 0x5e, 0x0b, 0xdb,
815         0xe0, 0x32, 0x3a, 0x0a, 0x49, 0x06, 0x24, 0x5c,
816         0xc2, 0xd3, 0xac, 0x62, 0x91, 0x95, 0xe4, 0x79,
817         0xe7, 0xc8, 0x37, 0x6d, 0x8d, 0xd5, 0x4e, 0xa9,
818         0x6c, 0x56, 0xf4, 0xea, 0x65, 0x7a, 0xae, 0x08,
819         0xba, 0x78, 0x25, 0x2e, 0x1c, 0xa6, 0xb4, 0xc6,
820         0xe8, 0xdd, 0x74, 0x1f, 0x4b, 0xbd, 0x8b, 0x8a,
821         0x70, 0x3e, 0xb5, 0x66, 0x48, 0x03, 0xf6, 0x0e,
822         0x61, 0x35, 0x57, 0xb9, 0x86, 0xc1, 0x1d, 0x9e,
823         0xe1, 0xf8, 0x98, 0x11, 0x69, 0xd9, 0x8e, 0x94,
824         0x9b, 0x1e, 0x87, 0xe9, 0xce, 0x55, 0x28, 0xdf,
825         0x8c, 0xa1, 0x89, 0x0d, 0xbf, 0xe6, 0x42, 0x68,
826         0x41, 0x99, 0x2d, 0x0f, 0xb0, 0x54, 0xbb, 0x16
827 };
828
829 /*****************************/
830 /**** Function Prototypes ****/
831 /*****************************/
832
833 static void construct_mic_header2(u8 *mic_header2, u8 *mpdu, int a4_exists,
834                                   int qc_exists);
835
836 static void xor_128(u8 *a, u8 *b, u8 *out)
837 {
838         int i;
839
840         for (i = 0; i < 16; i++)
841                 out[i] = a[i] ^ b[i];
842 }
843
844 static void xor_32(u8 *a, u8 *b, u8 *out)
845 {
846         int i;
847
848         for (i = 0; i < 4; i++)
849                 out[i] = a[i] ^ b[i];
850 }
851
852 static u8 sbox(u8 a)
853 {
854         return sbox_table[(int)a];
855 }
856
857 static void next_key(u8 *key, int round)
858 {
859         u8 rcon;
860         u8 sbox_key[4];
861         u8 rcon_table[12] = {
862                 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80,
863                 0x1b, 0x36, 0x36, 0x36
864         };
865
866         sbox_key[0] = sbox(key[13]);
867         sbox_key[1] = sbox(key[14]);
868         sbox_key[2] = sbox(key[15]);
869         sbox_key[3] = sbox(key[12]);
870
871         rcon = rcon_table[round];
872
873         xor_32(&key[0], sbox_key, &key[0]);
874         key[0] = key[0] ^ rcon;
875
876         xor_32(&key[4], &key[0], &key[4]);
877         xor_32(&key[8], &key[4], &key[8]);
878         xor_32(&key[12], &key[8], &key[12]);
879
880 }
881
882 static void byte_sub(u8 *in, u8 *out)
883 {
884         int i;
885
886         for (i = 0; i < 16; i++)
887                 out[i] = sbox(in[i]);
888 }
889
890 static void shift_row(u8 *in, u8 *out)
891 {
892
893         out[0] =  in[0];
894         out[1] =  in[5];
895         out[2] =  in[10];
896         out[3] =  in[15];
897         out[4] =  in[4];
898         out[5] =  in[9];
899         out[6] =  in[14];
900         out[7] =  in[3];
901         out[8] =  in[8];
902         out[9] =  in[13];
903         out[10] = in[2];
904         out[11] = in[7];
905         out[12] = in[12];
906         out[13] = in[1];
907         out[14] = in[6];
908         out[15] = in[11];
909
910 }
911
912 static void mix_column(u8 *in, u8 *out)
913 {
914         int i;
915         u8 add1b[4];
916         u8 add1bf7[4];
917         u8 rotl[4];
918         u8 swap_halfs[4];
919         u8 andf7[4];
920         u8 rotr[4];
921         u8 temp[4];
922         u8 tempb[4];
923
924         for (i = 0; i < 4; i++) {
925                 if ((in[i] & 0x80) == 0x80)
926                         add1b[i] = 0x1b;
927                 else
928                         add1b[i] = 0x00;
929         }
930
931         swap_halfs[0] = in[2]; /* Swap halfs */
932         swap_halfs[1] = in[3];
933         swap_halfs[2] = in[0];
934         swap_halfs[3] = in[1];
935
936         rotl[0] = in[3]; /* Rotate left 8 bits */
937         rotl[1] = in[0];
938         rotl[2] = in[1];
939         rotl[3] = in[2];
940
941         andf7[0] = in[0] & 0x7f;
942         andf7[1] = in[1] & 0x7f;
943         andf7[2] = in[2] & 0x7f;
944         andf7[3] = in[3] & 0x7f;
945
946         for (i = 3; i > 0; i--) { /* logical shift left 1 bit */
947                 andf7[i] = andf7[i] << 1;
948                 if ((andf7[i - 1] & 0x80) == 0x80)
949                         andf7[i] = (andf7[i] | 0x01);
950         }
951         andf7[0] = andf7[0] << 1;
952         andf7[0] = andf7[0] & 0xfe;
953
954         xor_32(add1b, andf7, add1bf7);
955
956         xor_32(in, add1bf7, rotr);
957
958         temp[0] = rotr[0]; /* Rotate right 8 bits */
959         rotr[0] = rotr[1];
960         rotr[1] = rotr[2];
961         rotr[2] = rotr[3];
962         rotr[3] = temp[0];
963
964         xor_32(add1bf7, rotr, temp);
965         xor_32(swap_halfs, rotl, tempb);
966         xor_32(temp, tempb, out);
967
968 }
969
970 static void aes128k128d(u8 *key, u8 *data, u8 *ciphertext)
971 {
972         int round;
973         int i;
974         u8 intermediatea[16];
975         u8 intermediateb[16];
976         u8 round_key[16];
977
978         for (i = 0; i < 16; i++)
979                 round_key[i] = key[i];
980
981         for (round = 0; round < 11; round++) {
982                 if (round == 0) {
983                         xor_128(round_key, data, ciphertext);
984                         next_key(round_key, round);
985                 } else if (round == 10) {
986                         byte_sub(ciphertext, intermediatea);
987                         shift_row(intermediatea, intermediateb);
988                         xor_128(intermediateb, round_key, ciphertext);
989                 } else { /* 1 - 9 */
990                         byte_sub(ciphertext, intermediatea);
991                         shift_row(intermediatea, intermediateb);
992                         mix_column(&intermediateb[0], &intermediatea[0]);
993                         mix_column(&intermediateb[4], &intermediatea[4]);
994                         mix_column(&intermediateb[8], &intermediatea[8]);
995                         mix_column(&intermediateb[12], &intermediatea[12]);
996                         xor_128(intermediatea, round_key, ciphertext);
997                         next_key(round_key, round);
998                 }
999         }
1000
1001 }
1002
1003 /************************************************/
1004 /* construct_mic_iv()                           */
1005 /* Builds the MIC IV from header fields and PN  */
1006 /************************************************/
1007 static void construct_mic_iv(u8 *mic_iv, int qc_exists, int a4_exists, u8 *mpdu,
1008                              uint payload_length, u8 *pn_vector)
1009 {
1010         int i;
1011
1012         mic_iv[0] = 0x59;
1013         if (qc_exists && a4_exists)
1014                 mic_iv[1] = mpdu[30] & 0x0f; /* QoS_TC        */
1015         if (qc_exists && !a4_exists)
1016                 mic_iv[1] = mpdu[24] & 0x0f; /* mute bits 7-4 */
1017         if (!qc_exists)
1018                 mic_iv[1] = 0x00;
1019         for (i = 2; i < 8; i++)
1020                 mic_iv[i] = mpdu[i + 8]; /* mic_iv[2:7] = A2[0:5] = mpdu[10:15] */
1021         for (i = 8; i < 14; i++)
1022                 mic_iv[i] = pn_vector[13 - i]; /* mic_iv[8:13] = PN[5:0] */
1023         mic_iv[14] = (unsigned char)(payload_length / 256);
1024         mic_iv[15] = (unsigned char)(payload_length % 256);
1025 }
1026
1027 /************************************************/
1028 /* construct_mic_header1()                      */
1029 /* Builds the first MIC header block from       */
1030 /* header fields.                               */
1031 /************************************************/
1032 static void construct_mic_header1(u8 *mic_header1, int header_length, u8 *mpdu)
1033 {
1034         mic_header1[0] = (u8)((header_length - 2) / 256);
1035         mic_header1[1] = (u8)((header_length - 2) % 256);
1036         mic_header1[2] = mpdu[0] & 0xcf; /* Mute CF poll & CF ack bits */
1037         mic_header1[3] = mpdu[1] & 0xc7; /* Mute retry, more data and pwr mgt bits */
1038         mic_header1[4] = mpdu[4]; /* A1 */
1039         mic_header1[5] = mpdu[5];
1040         mic_header1[6] = mpdu[6];
1041         mic_header1[7] = mpdu[7];
1042         mic_header1[8] = mpdu[8];
1043         mic_header1[9] = mpdu[9];
1044         mic_header1[10] = mpdu[10]; /* A2 */
1045         mic_header1[11] = mpdu[11];
1046         mic_header1[12] = mpdu[12];
1047         mic_header1[13] = mpdu[13];
1048         mic_header1[14] = mpdu[14];
1049         mic_header1[15] = mpdu[15];
1050
1051 }
1052
1053 /************************************************/
1054 /* construct_mic_header2()                      */
1055 /* Builds the last MIC header block from        */
1056 /* header fields.                               */
1057 /************************************************/
1058 static void construct_mic_header2(u8 *mic_header2, u8 *mpdu, int a4_exists,
1059                                   int qc_exists)
1060 {
1061         int i;
1062
1063         for (i = 0; i < 16; i++)
1064                 mic_header2[i] = 0x00;
1065
1066         mic_header2[0] = mpdu[16]; /* A3 */
1067         mic_header2[1] = mpdu[17];
1068         mic_header2[2] = mpdu[18];
1069         mic_header2[3] = mpdu[19];
1070         mic_header2[4] = mpdu[20];
1071         mic_header2[5] = mpdu[21];
1072
1073         mic_header2[6] = 0x00;
1074         mic_header2[7] = 0x00; /* mpdu[23]; */
1075
1076         if (!qc_exists && a4_exists) {
1077                 for (i = 0; i < 6; i++)
1078                         mic_header2[8+i] = mpdu[24+i]; /* A4 */
1079         }
1080
1081         if (qc_exists && !a4_exists) {
1082                 mic_header2[8] = mpdu[24] & 0x0f; /* mute bits 15 - 4 */
1083                 mic_header2[9] = mpdu[25] & 0x00;
1084         }
1085
1086         if (qc_exists && a4_exists) {
1087                 for (i = 0; i < 6; i++)
1088                         mic_header2[8+i] = mpdu[24+i]; /* A4 */
1089
1090                 mic_header2[14] = mpdu[30] & 0x0f;
1091                 mic_header2[15] = mpdu[31] & 0x00;
1092         }
1093
1094 }
1095
1096 /************************************************/
1097 /* construct_mic_header2()                      */
1098 /* Builds the last MIC header block from        */
1099 /* header fields.                               */
1100 /************************************************/
1101 static void construct_ctr_preload(u8 *ctr_preload, int a4_exists, int qc_exists,
1102                                   u8 *mpdu, u8 *pn_vector, int c)
1103 {
1104         int i = 0;
1105
1106         for (i = 0; i < 16; i++)
1107                 ctr_preload[i] = 0x00;
1108
1109         i = 0;
1110
1111         ctr_preload[0] = 0x01; /* flag */
1112         if (qc_exists && a4_exists)
1113                 ctr_preload[1] = mpdu[30] & 0x0f; /* QoC_Control */
1114         if (qc_exists && !a4_exists)
1115                 ctr_preload[1] = mpdu[24] & 0x0f;
1116
1117         for (i = 2; i < 8; i++)
1118                 ctr_preload[i] = mpdu[i + 8]; /* ctr_preload[2:7] = A2[0:5] = mpdu[10:15] */
1119         for (i = 8; i < 14; i++)
1120                 ctr_preload[i] = pn_vector[13 - i]; /* ctr_preload[8:13] = PN[5:0] */
1121         ctr_preload[14] =  (unsigned char) (c / 256); /* Ctr */
1122         ctr_preload[15] =  (unsigned char) (c % 256);
1123
1124 }
1125
1126 /************************************/
1127 /* bitwise_xor()                    */
1128 /* A 128 bit, bitwise exclusive or  */
1129 /************************************/
1130 static void bitwise_xor(u8 *ina, u8 *inb, u8 *out)
1131 {
1132         int i;
1133
1134         for (i = 0; i < 16; i++)
1135                 out[i] = ina[i] ^ inb[i];
1136 }
1137
1138 static int aes_cipher(u8 *key, uint hdrlen, u8 *pframe, uint plen)
1139 {
1140         uint qc_exists, a4_exists, i, j, payload_remainder,
1141              num_blocks, payload_index;
1142         u8 pn_vector[6];
1143         u8 mic_iv[16];
1144         u8 mic_header1[16];
1145         u8 mic_header2[16];
1146         u8 ctr_preload[16];
1147         /* Intermediate Buffers */
1148         u8 chain_buffer[16];
1149         u8 aes_out[16];
1150         u8 padded_buffer[16];
1151         u8 mic[8];
1152         struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)pframe;
1153         u16 frsubtype = le16_to_cpu(hdr->frame_control) & IEEE80211_FCTL_STYPE;
1154
1155         memset((void *)mic_iv, 0, 16);
1156         memset((void *)mic_header1, 0, 16);
1157         memset((void *)mic_header2, 0, 16);
1158         memset((void *)ctr_preload, 0, 16);
1159         memset((void *)chain_buffer, 0, 16);
1160         memset((void *)aes_out, 0, 16);
1161         memset((void *)padded_buffer, 0, 16);
1162
1163         if ((hdrlen == sizeof(struct ieee80211_hdr_3addr) ||
1164             (hdrlen == sizeof(struct ieee80211_qos_hdr))))
1165                 a4_exists = 0;
1166         else
1167                 a4_exists = 1;
1168
1169         if (ieee80211_is_data(hdr->frame_control)) {
1170                 if ((frsubtype == IEEE80211_STYPE_DATA_CFACK) ||
1171                     (frsubtype == IEEE80211_STYPE_DATA_CFPOLL) ||
1172                     (frsubtype == IEEE80211_STYPE_DATA_CFACKPOLL)) {
1173                         qc_exists = 1;
1174                         if (hdrlen != sizeof(struct ieee80211_qos_hdr))
1175                                 hdrlen += 2;
1176                 } else if ((frsubtype == IEEE80211_STYPE_QOS_DATA) ||
1177                            (frsubtype == IEEE80211_STYPE_QOS_DATA_CFACK) ||
1178                            (frsubtype == IEEE80211_STYPE_QOS_DATA_CFPOLL) ||
1179                            (frsubtype == IEEE80211_STYPE_QOS_DATA_CFACKPOLL)) {
1180                         if (hdrlen != sizeof(struct ieee80211_qos_hdr))
1181                                 hdrlen += 2;
1182                         qc_exists = 1;
1183                 } else {
1184                         qc_exists = 0;
1185                 }
1186         } else {
1187                 qc_exists = 0;
1188         }
1189         pn_vector[0] = pframe[hdrlen];
1190         pn_vector[1] = pframe[hdrlen + 1];
1191         pn_vector[2] = pframe[hdrlen + 4];
1192         pn_vector[3] = pframe[hdrlen + 5];
1193         pn_vector[4] = pframe[hdrlen + 6];
1194         pn_vector[5] = pframe[hdrlen + 7];
1195
1196         construct_mic_iv(mic_iv, qc_exists, a4_exists, pframe, plen, pn_vector);
1197
1198         construct_mic_header1(mic_header1, hdrlen, pframe);
1199         construct_mic_header2(mic_header2, pframe, a4_exists, qc_exists);
1200
1201         payload_remainder = plen % 16;
1202         num_blocks = plen / 16;
1203
1204         /* Find start of payload */
1205         payload_index = hdrlen + 8;
1206
1207         /* Calculate MIC */
1208         aes128k128d(key, mic_iv, aes_out);
1209         bitwise_xor(aes_out, mic_header1, chain_buffer);
1210         aes128k128d(key, chain_buffer, aes_out);
1211         bitwise_xor(aes_out, mic_header2, chain_buffer);
1212         aes128k128d(key, chain_buffer, aes_out);
1213
1214         for (i = 0; i < num_blocks; i++) {
1215                 bitwise_xor(aes_out, &pframe[payload_index], chain_buffer);
1216
1217                 payload_index += 16;
1218                 aes128k128d(key, chain_buffer, aes_out);
1219         }
1220
1221         /* Add on the final payload block if it needs padding */
1222         if (payload_remainder > 0) {
1223                 for (j = 0; j < 16; j++)
1224                         padded_buffer[j] = 0x00;
1225                 for (j = 0; j < payload_remainder; j++)
1226                         padded_buffer[j] = pframe[payload_index++];
1227                 bitwise_xor(aes_out, padded_buffer, chain_buffer);
1228                 aes128k128d(key, chain_buffer, aes_out);
1229         }
1230
1231         for (j = 0; j < 8; j++)
1232                 mic[j] = aes_out[j];
1233
1234         /* Insert MIC into payload */
1235         for (j = 0; j < 8; j++)
1236                 pframe[payload_index + j] = mic[j];
1237
1238         payload_index = hdrlen + 8;
1239         for (i = 0; i < num_blocks; i++) {
1240                 construct_ctr_preload(ctr_preload, a4_exists, qc_exists,
1241                                       pframe, pn_vector, i + 1);
1242                 aes128k128d(key, ctr_preload, aes_out);
1243                 bitwise_xor(aes_out, &pframe[payload_index], chain_buffer);
1244                 for (j = 0; j < 16; j++)
1245                         pframe[payload_index++] = chain_buffer[j];
1246         }
1247
1248         if (payload_remainder > 0) {
1249                 /* If there is a short final block, then pad it,
1250                  * encrypt it and copy the unpadded part back
1251                  */
1252                 construct_ctr_preload(ctr_preload, a4_exists, qc_exists, pframe,
1253                                       pn_vector, num_blocks + 1);
1254
1255                 for (j = 0; j < 16; j++)
1256                         padded_buffer[j] = 0x00;
1257                 for (j = 0; j < payload_remainder; j++)
1258                         padded_buffer[j] = pframe[payload_index + j];
1259                 aes128k128d(key, ctr_preload, aes_out);
1260                 bitwise_xor(aes_out, padded_buffer, chain_buffer);
1261                 for (j = 0; j < payload_remainder; j++)
1262                         pframe[payload_index++] = chain_buffer[j];
1263         }
1264
1265         /* Encrypt the MIC */
1266         construct_ctr_preload(ctr_preload, a4_exists, qc_exists, pframe,
1267                               pn_vector, 0);
1268
1269         for (j = 0; j < 16; j++)
1270                 padded_buffer[j] = 0x00;
1271         for (j = 0; j < 8; j++)
1272                 padded_buffer[j] = pframe[j + hdrlen + 8 + plen];
1273
1274         aes128k128d(key, ctr_preload, aes_out);
1275         bitwise_xor(aes_out, padded_buffer, chain_buffer);
1276         for (j = 0; j < 8; j++)
1277                 pframe[payload_index++] = chain_buffer[j];
1278
1279         return _SUCCESS;
1280 }
1281
1282 int rtw_aes_encrypt23a(struct rtw_adapter *padapter,
1283                        struct xmit_frame *pxmitframe)
1284 {       /* exclude ICV */
1285         /* Intermediate Buffers */
1286         int curfragnum, length;
1287         u32 prwskeylen;
1288         u8 *pframe, *prwskey;
1289         u8 hw_hdr_offset = 0;
1290         struct sta_info *stainfo;
1291         struct pkt_attrib *pattrib = &pxmitframe->attrib;
1292         struct security_priv *psecuritypriv = &padapter->securitypriv;
1293         struct xmit_priv *pxmitpriv = &padapter->xmitpriv;
1294         int res = _SUCCESS;
1295
1296         if (!pxmitframe->buf_addr)
1297                 return _FAIL;
1298
1299         hw_hdr_offset = TXDESC_OFFSET;
1300
1301         pframe = pxmitframe->buf_addr + hw_hdr_offset;
1302
1303         /* 4 start to encrypt each fragment */
1304         if (pattrib->encrypt != WLAN_CIPHER_SUITE_CCMP)
1305                 return _FAIL;
1306
1307         if (pattrib->psta) {
1308                 stainfo = pattrib->psta;
1309         } else {
1310                 DBG_8723A("%s, call rtw_get_stainfo23a()\n", __func__);
1311                 stainfo = rtw_get_stainfo23a(&padapter->stapriv, &pattrib->ra[0]);
1312         }
1313
1314         if (!stainfo) {
1315                 RT_TRACE(_module_rtl871x_security_c_, _drv_err_,
1316                          "%s: stainfo == NULL!!!\n", __func__);
1317                 DBG_8723A("%s, psta == NUL\n", __func__);
1318                 res = _FAIL;
1319                 goto out;
1320         }
1321         if (!(stainfo->state & _FW_LINKED)) {
1322                 DBG_8723A("%s, psta->state(0x%x) != _FW_LINKED\n",
1323                           __func__, stainfo->state);
1324                 return _FAIL;
1325         }
1326         RT_TRACE(_module_rtl871x_security_c_, _drv_err_,
1327                  "%s: stainfo!= NULL!!!\n", __func__);
1328
1329         if (is_multicast_ether_addr(pattrib->ra))
1330                 prwskey = psecuritypriv->dot118021XGrpKey[psecuritypriv->dot118021XGrpKeyid].skey;
1331         else
1332                 prwskey = &stainfo->dot118021x_UncstKey.skey[0];
1333
1334         prwskeylen = 16;
1335
1336         for (curfragnum = 0; curfragnum < pattrib->nr_frags; curfragnum++) {
1337                 /* 4 the last fragment */
1338                 if ((curfragnum + 1) == pattrib->nr_frags) {
1339                         length = pattrib->last_txcmdsz -
1340                                 pattrib->hdrlen-pattrib->iv_len -
1341                                 pattrib->icv_len;
1342
1343                         aes_cipher(prwskey, pattrib->hdrlen, pframe, length);
1344                 } else {
1345                         length = pxmitpriv->frag_len-pattrib->hdrlen -
1346                                 pattrib->iv_len - pattrib->icv_len;
1347
1348                         aes_cipher(prwskey, pattrib->hdrlen, pframe, length);
1349                         pframe += pxmitpriv->frag_len;
1350                         pframe = PTR_ALIGN(pframe, 4);
1351                 }
1352         }
1353 out:
1354         return res;
1355 }
1356
1357 static int aes_decipher(u8 *key, uint hdrlen, u8 *pframe, uint plen)
1358 {
1359         static u8 message[MAX_MSG_SIZE];
1360         uint qc_exists, a4_exists, i, j, payload_remainder,
1361              num_blocks, payload_index;
1362         int res = _SUCCESS;
1363         u8 pn_vector[6];
1364         u8 mic_iv[16];
1365         u8 mic_header1[16];
1366         u8 mic_header2[16];
1367         u8 ctr_preload[16];
1368         /* Intermediate Buffers */
1369         u8 chain_buffer[16];
1370         u8 aes_out[16];
1371         u8 padded_buffer[16];
1372         u8 mic[8];
1373         struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)pframe;
1374         u16 frsubtype = le16_to_cpu(hdr->frame_control) & IEEE80211_FCTL_STYPE;
1375
1376         memset((void *)mic_iv, 0, 16);
1377         memset((void *)mic_header1, 0, 16);
1378         memset((void *)mic_header2, 0, 16);
1379         memset((void *)ctr_preload, 0, 16);
1380         memset((void *)chain_buffer, 0, 16);
1381         memset((void *)aes_out, 0, 16);
1382         memset((void *)padded_buffer, 0, 16);
1383
1384         /* start to decrypt the payload */
1385
1386         num_blocks = (plen - 8) / 16; /* plen including llc, payload_length and mic) */
1387
1388         payload_remainder = (plen - 8) % 16;
1389
1390         pn_vector[0]  = pframe[hdrlen];
1391         pn_vector[1]  = pframe[hdrlen + 1];
1392         pn_vector[2]  = pframe[hdrlen + 4];
1393         pn_vector[3]  = pframe[hdrlen + 5];
1394         pn_vector[4]  = pframe[hdrlen + 6];
1395         pn_vector[5]  = pframe[hdrlen + 7];
1396
1397         if ((hdrlen == sizeof(struct ieee80211_hdr_3addr) ||
1398             (hdrlen == sizeof(struct ieee80211_qos_hdr))))
1399                 a4_exists = 0;
1400         else
1401                 a4_exists = 1;
1402
1403         if (ieee80211_is_data(hdr->frame_control)) {
1404                 if ((frsubtype == IEEE80211_STYPE_DATA_CFACK) ||
1405                     (frsubtype == IEEE80211_STYPE_DATA_CFPOLL) ||
1406                     (frsubtype == IEEE80211_STYPE_DATA_CFACKPOLL)) {
1407                         qc_exists = 1;
1408                         if (hdrlen != sizeof(struct ieee80211_hdr_3addr))
1409                                 hdrlen += 2;
1410                 } else if ((frsubtype == IEEE80211_STYPE_QOS_DATA) ||
1411                            (frsubtype == IEEE80211_STYPE_QOS_DATA_CFACK) ||
1412                            (frsubtype == IEEE80211_STYPE_QOS_DATA_CFPOLL) ||
1413                            (frsubtype == IEEE80211_STYPE_QOS_DATA_CFACKPOLL)) {
1414                         if (hdrlen != sizeof(struct ieee80211_hdr_3addr))
1415                                 hdrlen += 2;
1416                         qc_exists = 1;
1417                 } else {
1418                         qc_exists = 0;
1419                 }
1420         } else {
1421                 qc_exists = 0;
1422         }
1423
1424         /* now, decrypt pframe with hdrlen offset and plen long */
1425
1426         payload_index = hdrlen + 8; /*  8 is for extiv */
1427
1428         for (i = 0; i < num_blocks; i++) {
1429                 construct_ctr_preload(ctr_preload, a4_exists, qc_exists,
1430                                       pframe, pn_vector, i + 1);
1431
1432                 aes128k128d(key, ctr_preload, aes_out);
1433                 bitwise_xor(aes_out, &pframe[payload_index], chain_buffer);
1434
1435                 for (j = 0; j < 16; j++)
1436                         pframe[payload_index++] = chain_buffer[j];
1437         }
1438
1439         if (payload_remainder > 0) {
1440                 /* If there is a short final block, then pad it,
1441                  * encrypt it and copy the unpadded part back
1442                  */
1443                 construct_ctr_preload(ctr_preload, a4_exists, qc_exists, pframe,
1444                                       pn_vector, num_blocks + 1);
1445
1446                 for (j = 0; j < 16; j++)
1447                         padded_buffer[j] = 0x00;
1448                 for (j = 0; j < payload_remainder; j++)
1449                         padded_buffer[j] = pframe[payload_index + j];
1450                 aes128k128d(key, ctr_preload, aes_out);
1451                 bitwise_xor(aes_out, padded_buffer, chain_buffer);
1452                 for (j = 0; j < payload_remainder; j++)
1453                         pframe[payload_index++] = chain_buffer[j];
1454         }
1455
1456         /* start to calculate the mic */
1457         if ((hdrlen + plen + 8) <= MAX_MSG_SIZE)
1458                 memcpy(message, pframe, (hdrlen + plen + 8)); /* 8 is for ext iv len */
1459
1460         pn_vector[0] = pframe[hdrlen];
1461         pn_vector[1] = pframe[hdrlen + 1];
1462         pn_vector[2] = pframe[hdrlen + 4];
1463         pn_vector[3] = pframe[hdrlen + 5];
1464         pn_vector[4] = pframe[hdrlen + 6];
1465         pn_vector[5] = pframe[hdrlen + 7];
1466
1467         construct_mic_iv(mic_iv, qc_exists, a4_exists, message,
1468                          plen - 8, pn_vector);
1469
1470         construct_mic_header1(mic_header1, hdrlen, message);
1471         construct_mic_header2(mic_header2, message, a4_exists, qc_exists);
1472
1473         payload_remainder = (plen - 8) % 16;
1474         num_blocks = (plen - 8) / 16;
1475
1476         /* Find start of payload */
1477         payload_index = hdrlen + 8;
1478
1479         /* Calculate MIC */
1480         aes128k128d(key, mic_iv, aes_out);
1481         bitwise_xor(aes_out, mic_header1, chain_buffer);
1482         aes128k128d(key, chain_buffer, aes_out);
1483         bitwise_xor(aes_out, mic_header2, chain_buffer);
1484         aes128k128d(key, chain_buffer, aes_out);
1485
1486         for (i = 0; i < num_blocks; i++) {
1487                 bitwise_xor(aes_out, &message[payload_index], chain_buffer);
1488
1489                 payload_index += 16;
1490                 aes128k128d(key, chain_buffer, aes_out);
1491         }
1492
1493         /* Add on the final payload block if it needs padding */
1494         if (payload_remainder > 0) {
1495                 for (j = 0; j < 16; j++)
1496                         padded_buffer[j] = 0x00;
1497                 for (j = 0; j < payload_remainder; j++)
1498                         padded_buffer[j] = message[payload_index++];
1499                 bitwise_xor(aes_out, padded_buffer, chain_buffer);
1500                 aes128k128d(key, chain_buffer, aes_out);
1501         }
1502
1503         for (j = 0 ; j < 8; j++)
1504                 mic[j] = aes_out[j];
1505
1506         /* Insert MIC into payload */
1507         for (j = 0; j < 8; j++)
1508                 message[payload_index + j] = mic[j];
1509
1510         payload_index = hdrlen + 8;
1511         for (i = 0; i < num_blocks; i++) {
1512                 construct_ctr_preload(ctr_preload, a4_exists, qc_exists,
1513                                       message, pn_vector, i + 1);
1514                 aes128k128d(key, ctr_preload, aes_out);
1515                 bitwise_xor(aes_out, &message[payload_index], chain_buffer);
1516                 for (j = 0; j < 16; j++)
1517                         message[payload_index++] = chain_buffer[j];
1518         }
1519
1520         if (payload_remainder > 0) {
1521                 /* If there is a short final block, then pad it,
1522                  * encrypt it and copy the unpadded part back
1523                  */
1524                 construct_ctr_preload(ctr_preload, a4_exists, qc_exists,
1525                                       message, pn_vector, num_blocks + 1);
1526
1527                 for (j = 0; j < 16; j++)
1528                         padded_buffer[j] = 0x00;
1529                 for (j = 0; j < payload_remainder; j++)
1530                         padded_buffer[j] = message[payload_index + j];
1531                 aes128k128d(key, ctr_preload, aes_out);
1532                 bitwise_xor(aes_out, padded_buffer, chain_buffer);
1533                 for (j = 0; j < payload_remainder; j++)
1534                         message[payload_index++] = chain_buffer[j];
1535         }
1536
1537         /* Encrypt the MIC */
1538         construct_ctr_preload(ctr_preload, a4_exists, qc_exists, message,
1539                               pn_vector, 0);
1540
1541         for (j = 0; j < 16; j++)
1542                 padded_buffer[j] = 0x00;
1543         for (j = 0; j < 8; j++)
1544                 padded_buffer[j] = message[j + hdrlen + 8 + plen - 8];
1545
1546         aes128k128d(key, ctr_preload, aes_out);
1547         bitwise_xor(aes_out, padded_buffer, chain_buffer);
1548         for (j = 0; j < 8; j++)
1549                 message[payload_index++] = chain_buffer[j];
1550
1551         /* compare the mic */
1552         for (i = 0; i < 8; i++) {
1553                 if (pframe[hdrlen + 8 + plen - 8 + i] != message[hdrlen + 8 + plen - 8 + i]) {
1554                         RT_TRACE(_module_rtl871x_security_c_, _drv_err_,
1555                                  "%s:mic check error mic[%d]: pframe(%x) != message(%x)\n",
1556                                  __func__, i,
1557                                  pframe[hdrlen + 8 + plen - 8 + i],
1558                                  message[hdrlen + 8 + plen - 8 + i]);
1559                         DBG_8723A("%s:mic check error mic[%d]: pframe(%x) != message(%x)\n",
1560                                   __func__, i,
1561                                   pframe[hdrlen + 8 + plen - 8 + i],
1562                                   message[hdrlen + 8 + plen - 8 + i]);
1563                         res = _FAIL;
1564                 }
1565         }
1566         return res;
1567 }
1568
1569 int rtw_aes_decrypt23a(struct rtw_adapter *padapter,
1570                        struct recv_frame *precvframe)
1571 {       /*  exclude ICV */
1572         struct sta_info *stainfo;
1573         struct rx_pkt_attrib *prxattrib = &precvframe->attrib;
1574         struct security_priv *psecuritypriv = &padapter->securitypriv;
1575         struct sk_buff *skb = precvframe->pkt;
1576         int length;
1577         u8 *pframe, *prwskey;
1578         int res = _SUCCESS;
1579
1580         pframe = skb->data;
1581         /* 4 start to encrypt each fragment */
1582         if (prxattrib->encrypt != WLAN_CIPHER_SUITE_CCMP)
1583                 return _FAIL;
1584
1585         stainfo = rtw_get_stainfo23a(&padapter->stapriv, &prxattrib->ta[0]);
1586         if (!stainfo) {
1587                 RT_TRACE(_module_rtl871x_security_c_, _drv_err_,
1588                          "%s: stainfo == NULL!!!\n", __func__);
1589                 res = _FAIL;
1590                 goto exit;
1591         }
1592
1593         RT_TRACE(_module_rtl871x_security_c_, _drv_err_,
1594                  "%s: stainfo!= NULL!!!\n", __func__);
1595
1596         if (is_multicast_ether_addr(prxattrib->ra)) {
1597                 /* in concurrent we should use sw decrypt in
1598                  * group key, so we remove this message
1599                  */
1600                 if (!psecuritypriv->binstallGrpkey) {
1601                         res = _FAIL;
1602                         DBG_8723A("%s:rx bc/mc packets, but didn't install "
1603                                   "group key!!!!!!!!!!\n", __func__);
1604                         goto exit;
1605                 }
1606                 prwskey = psecuritypriv->dot118021XGrpKey[prxattrib->key_index].skey;
1607                 if (psecuritypriv->dot118021XGrpKeyid != prxattrib->key_index) {
1608                         DBG_8723A("not match packet_index =%d, install_index ="
1609                                   "%d\n", prxattrib->key_index,
1610                                   psecuritypriv->dot118021XGrpKeyid);
1611                         res = _FAIL;
1612                         goto exit;
1613                 }
1614         } else {
1615                 prwskey = &stainfo->dot118021x_UncstKey.skey[0];
1616         }
1617
1618         length = skb->len - prxattrib->hdrlen - prxattrib->iv_len;
1619
1620         res = aes_decipher(prwskey, prxattrib->hdrlen, pframe, length);
1621 exit:
1622         return res;
1623 }
1624
1625 void rtw_use_tkipkey_handler23a(void *FunctionContext)
1626 {
1627         struct rtw_adapter *padapter = (struct rtw_adapter *)FunctionContext;
1628
1629         RT_TRACE(_module_rtl871x_security_c_, _drv_err_,
1630                  "^^^%s ^^^\n", __func__);
1631         padapter->securitypriv.busetkipkey = 1;
1632         RT_TRACE(_module_rtl871x_security_c_, _drv_err_,
1633                  "^^^%s padapter->securitypriv.busetkipkey =%d^^^\n",
1634                  __func__, padapter->securitypriv.busetkipkey);
1635 }