1 /******************************************************************************
3 * Copyright(c) 2007 - 2011 Realtek Corporation. All rights reserved.
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.
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
14 * You should have received a copy of the GNU General Public License along with
15 * this program; if not, write to the Free Software Foundation, Inc.,
16 * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
19 ******************************************************************************/
20 #define _RTW_SECURITY_C_
22 #include <osdep_service.h>
23 #include <drv_types.h>
25 #include <osdep_intf.h>
27 /* WEP related ===== */
29 #define CRC32_POLY 0x04c11db7
37 static void arcfour_init(struct arc4context *parc4ctx, u8 *key, u32 key_len)
45 state = parc4ctx->state;
48 for (counter = 0; counter < 256; counter++)
49 state[counter] = (u8)counter;
52 for (counter = 0; counter < 256; counter++) {
54 stateindex = (stateindex + key[keyindex] + t) & 0xff;
55 u = state[stateindex];
56 state[stateindex] = (u8)t;
57 state[counter] = (u8)u;
58 if (++keyindex >= key_len)
64 static u32 arcfour_byte(struct arc4context *parc4ctx)
71 state = parc4ctx->state;
72 x = (parc4ctx->x + 1) & 0xff;
74 y = (sx + parc4ctx->y) & 0xff;
81 return state[(sx + sy) & 0xff];
84 static void arcfour_encrypt(struct arc4context *parc4ctx, u8 *dest, u8 *src, u32 len)
88 for (i = 0; i < len; i++)
89 dest[i] = src[i] ^ (unsigned char)arcfour_byte(parc4ctx);
93 static int bcrc32initialized;
94 static u32 crc32_table[256];
96 static u8 crc32_reverseBit(u8 data)
98 return (u8)((data<<7)&0x80) | ((data<<5)&0x40) | ((data<<3)&0x20) |
99 ((data<<1)&0x10) | ((data>>1)&0x08) | ((data>>3)&0x04) |
100 ((data>>5)&0x02) | ((data>>7)&0x01);
103 static void crc32_init(void)
106 if (bcrc32initialized == 1) {
111 u8 *p = (u8 *)&c, *p1;
116 for (i = 0; i < 256; ++i) {
117 k = crc32_reverseBit((u8)i);
118 for (c = ((u32)k) << 24, j = 8; j > 0; --j)
119 c = c & 0x80000000 ? (c << 1) ^ CRC32_POLY : (c << 1);
120 p1 = (u8 *)&crc32_table[i];
122 p1[0] = crc32_reverseBit(p[3]);
123 p1[1] = crc32_reverseBit(p[2]);
124 p1[2] = crc32_reverseBit(p[1]);
125 p1[3] = crc32_reverseBit(p[0]);
127 bcrc32initialized = 1;
133 static __le32 getcrc32(u8 *buf, int len)
138 if (bcrc32initialized == 0)
141 crc = 0xffffffff; /* preload shift register, per CRC-32 spec */
143 for (p = buf; len > 0; ++p, --len)
144 crc = crc32_table[(crc ^ *p) & 0xff] ^ (crc >> 8);
146 return cpu_to_le32(~crc); /* transmit complement, per CRC-32 spec */
150 Need to consider the fragment situation
152 void rtw_wep_encrypt(struct adapter *padapter, u8 *pxmitframe)
155 unsigned char crc[4];
156 struct arc4context mycontext;
158 int curfragnum, length;
161 u8 *pframe, *payload, *iv; /* wepkey */
163 u8 hw_hdr_offset = 0;
164 struct pkt_attrib *pattrib = &((struct xmit_frame *)pxmitframe)->attrib;
165 struct security_priv *psecuritypriv = &padapter->securitypriv;
166 struct xmit_priv *pxmitpriv = &padapter->xmitpriv;
170 if (((struct xmit_frame *)pxmitframe)->buf_addr == NULL)
173 hw_hdr_offset = TXDESC_SIZE +
174 (((struct xmit_frame *)pxmitframe)->pkt_offset * PACKET_OFFSET_SZ);
176 pframe = ((struct xmit_frame *)pxmitframe)->buf_addr + hw_hdr_offset;
178 /* start to encrypt each fragment */
179 if ((pattrib->encrypt == _WEP40_) || (pattrib->encrypt == _WEP104_)) {
180 keylength = psecuritypriv->dot11DefKeylen[psecuritypriv->dot11PrivacyKeyIndex];
182 for (curfragnum = 0; curfragnum < pattrib->nr_frags; curfragnum++) {
183 iv = pframe+pattrib->hdrlen;
184 memcpy(&wepkey[0], iv, 3);
185 memcpy(&wepkey[3], &psecuritypriv->dot11DefKey[psecuritypriv->dot11PrivacyKeyIndex].skey[0], keylength);
186 payload = pframe+pattrib->iv_len+pattrib->hdrlen;
188 if ((curfragnum+1) == pattrib->nr_frags) { /* the last fragment */
189 length = pattrib->last_txcmdsz-pattrib->hdrlen-pattrib->iv_len-pattrib->icv_len;
191 *((__le32 *)crc) = getcrc32(payload, length);
193 arcfour_init(&mycontext, wepkey, 3+keylength);
194 arcfour_encrypt(&mycontext, payload, payload, length);
195 arcfour_encrypt(&mycontext, payload+length, crc, 4);
197 length = pxmitpriv->frag_len-pattrib->hdrlen-pattrib->iv_len-pattrib->icv_len;
198 *((__le32 *)crc) = getcrc32(payload, length);
199 arcfour_init(&mycontext, wepkey, 3+keylength);
200 arcfour_encrypt(&mycontext, payload, payload, length);
201 arcfour_encrypt(&mycontext, payload+length, crc, 4);
203 pframe += pxmitpriv->frag_len;
204 pframe = (u8 *)RND4((size_t)(pframe));
212 void rtw_wep_decrypt(struct adapter *padapter, u8 *precvframe)
216 struct arc4context mycontext;
219 u8 *pframe, *payload, *iv, wepkey[16];
221 struct rx_pkt_attrib *prxattrib = &(((union recv_frame *)precvframe)->u.hdr.attrib);
222 struct security_priv *psecuritypriv = &padapter->securitypriv;
226 pframe = (unsigned char *)((union recv_frame *)precvframe)->u.hdr.rx_data;
228 /* start to decrypt recvframe */
229 if ((prxattrib->encrypt == _WEP40_) || (prxattrib->encrypt == _WEP104_)) {
230 iv = pframe+prxattrib->hdrlen;
231 keyindex = prxattrib->key_index;
232 keylength = psecuritypriv->dot11DefKeylen[keyindex];
233 memcpy(&wepkey[0], iv, 3);
234 memcpy(&wepkey[3], &psecuritypriv->dot11DefKey[keyindex].skey[0], keylength);
235 length = ((union recv_frame *)precvframe)->u.hdr.len-prxattrib->hdrlen-prxattrib->iv_len;
237 payload = pframe+prxattrib->iv_len+prxattrib->hdrlen;
239 /* decrypt payload include icv */
240 arcfour_init(&mycontext, wepkey, 3+keylength);
241 arcfour_encrypt(&mycontext, payload, payload, length);
243 /* calculate icv and compare the icv */
244 *((__le32 *)crc) = getcrc32(payload, length - 4);
246 if (crc[3] != payload[length-1] ||
247 crc[2] != payload[length-2] ||
248 crc[1] != payload[length-3] ||
249 crc[0] != payload[length-4]) {
250 RT_TRACE(_module_rtl871x_security_c_, _drv_err_,
251 ("rtw_wep_decrypt:icv error crc (%4ph)!=payload (%4ph)\n",
252 &crc, &payload[length-4]));
259 /* 3 ===== TKIP related ===== */
261 static u32 secmicgetuint32(u8 *p)
262 /* Convert from Byte[] to Us3232 in a portable way */
267 for (i = 0; i < 4; i++)
268 res |= ((u32)(*p++)) << (8*i);
273 static void secmicputuint32(u8 *p, u32 val)
274 /* Convert from Us3232 to Byte[] in a portable way */
278 for (i = 0; i < 4; i++) {
279 *p++ = (u8) (val & 0xff);
285 static void secmicclear(struct mic_data *pmicdata)
287 /* Reset the state to the empty message. */
289 pmicdata->L = pmicdata->K0;
290 pmicdata->R = pmicdata->K1;
291 pmicdata->nBytesInM = 0;
296 void rtw_secmicsetkey(struct mic_data *pmicdata, u8 *key)
300 pmicdata->K0 = secmicgetuint32(key);
301 pmicdata->K1 = secmicgetuint32(key + 4);
302 /* and reset the message */
303 secmicclear(pmicdata);
307 void rtw_secmicappendbyte(struct mic_data *pmicdata, u8 b)
310 /* Append the byte to our word-sized buffer */
311 pmicdata->M |= ((unsigned long)b) << (8*pmicdata->nBytesInM);
312 pmicdata->nBytesInM++;
313 /* Process the word if it is full. */
314 if (pmicdata->nBytesInM >= 4) {
315 pmicdata->L ^= pmicdata->M;
316 pmicdata->R ^= ROL32(pmicdata->L, 17);
317 pmicdata->L += pmicdata->R;
318 pmicdata->R ^= ((pmicdata->L & 0xff00ff00) >> 8) | ((pmicdata->L & 0x00ff00ff) << 8);
319 pmicdata->L += pmicdata->R;
320 pmicdata->R ^= ROL32(pmicdata->L, 3);
321 pmicdata->L += pmicdata->R;
322 pmicdata->R ^= ROR32(pmicdata->L, 2);
323 pmicdata->L += pmicdata->R;
324 /* Clear the buffer */
326 pmicdata->nBytesInM = 0;
331 void rtw_secmicappend(struct mic_data *pmicdata, u8 *src, u32 nbytes)
336 rtw_secmicappendbyte(pmicdata, *src++);
342 void rtw_secgetmic(struct mic_data *pmicdata, u8 *dst)
345 /* Append the minimum padding */
346 rtw_secmicappendbyte(pmicdata, 0x5a);
347 rtw_secmicappendbyte(pmicdata, 0);
348 rtw_secmicappendbyte(pmicdata, 0);
349 rtw_secmicappendbyte(pmicdata, 0);
350 rtw_secmicappendbyte(pmicdata, 0);
351 /* and then zeroes until the length is a multiple of 4 */
352 while (pmicdata->nBytesInM != 0)
353 rtw_secmicappendbyte(pmicdata, 0);
354 /* The appendByte function has already computed the result. */
355 secmicputuint32(dst, pmicdata->L);
356 secmicputuint32(dst+4, pmicdata->R);
357 /* Reset to the empty message. */
358 secmicclear(pmicdata);
362 void rtw_seccalctkipmic(u8 *key, u8 *header, u8 *data, u32 data_len, u8 *mic_code, u8 pri)
364 struct mic_data micdata;
365 u8 priority[4] = {0x0, 0x0, 0x0, 0x0};
367 rtw_secmicsetkey(&micdata, key);
370 /* Michael MIC pseudo header: DA, SA, 3 x 0, Priority */
371 if (header[1]&1) { /* ToDS == 1 */
372 rtw_secmicappend(&micdata, &header[16], 6); /* DA */
373 if (header[1]&2) /* From Ds == 1 */
374 rtw_secmicappend(&micdata, &header[24], 6);
376 rtw_secmicappend(&micdata, &header[10], 6);
377 } else { /* ToDS == 0 */
378 rtw_secmicappend(&micdata, &header[4], 6); /* DA */
379 if (header[1]&2) /* From Ds == 1 */
380 rtw_secmicappend(&micdata, &header[16], 6);
382 rtw_secmicappend(&micdata, &header[10], 6);
384 rtw_secmicappend(&micdata, &priority[0], 4);
386 rtw_secmicappend(&micdata, data, data_len);
388 rtw_secgetmic(&micdata, mic_code);
394 /* macros for extraction/creation of unsigned char/unsigned short values */
395 #define RotR1(v16) ((((v16) >> 1) & 0x7FFF) ^ (((v16) & 1) << 15))
396 #define Lo8(v16) ((u8)((v16) & 0x00FF))
397 #define Hi8(v16) ((u8)(((v16) >> 8) & 0x00FF))
398 #define Lo16(v32) ((u16)((v32) & 0xFFFF))
399 #define Hi16(v32) ((u16)(((v32) >> 16) & 0xFFFF))
400 #define Mk16(hi, lo) ((lo) ^ (((u16)(hi)) << 8))
402 /* select the Nth 16-bit word of the temporal key unsigned char array TK[] */
403 #define TK16(N) Mk16(tk[2*(N)+1], tk[2*(N)])
405 /* S-box lookup: 16 bits --> 16 bits */
406 #define _S_(v16) (Sbox1[0][Lo8(v16)] ^ Sbox1[1][Hi8(v16)])
408 /* fixed algorithm "parameters" */
409 #define PHASE1_LOOP_CNT 8 /* this needs to be "big enough" */
410 #define TA_SIZE 6 /* 48-bit transmitter address */
411 #define TK_SIZE 16 /* 128-bit temporal key */
412 #define P1K_SIZE 10 /* 80-bit Phase1 key */
413 #define RC4_KEY_SIZE 16 /* 128-bit RC4KEY (104 bits unknown) */
415 /* 2-unsigned char by 2-unsigned char subset of the full AES S-box table */
416 static const unsigned short Sbox1[2][256] = { /* Sbox for hash (can be in ROM) */
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,
452 { /* second half of table is unsigned char-reversed version of first! */
453 0xA5C6, 0x84F8, 0x99EE, 0x8DF6, 0x0DFF, 0xBDD6, 0xB1DE, 0x5491,
454 0x5060, 0x0302, 0xA9CE, 0x7D56, 0x19E7, 0x62B5, 0xE64D, 0x9AEC,
455 0x458F, 0x9D1F, 0x4089, 0x87FA, 0x15EF, 0xEBB2, 0xC98E, 0x0BFB,
456 0xEC41, 0x67B3, 0xFD5F, 0xEA45, 0xBF23, 0xF753, 0x96E4, 0x5B9B,
457 0xC275, 0x1CE1, 0xAE3D, 0x6A4C, 0x5A6C, 0x417E, 0x02F5, 0x4F83,
458 0x5C68, 0xF451, 0x34D1, 0x08F9, 0x93E2, 0x73AB, 0x5362, 0x3F2A,
459 0x0C08, 0x5295, 0x6546, 0x5E9D, 0x2830, 0xA137, 0x0F0A, 0xB52F,
460 0x090E, 0x3624, 0x9B1B, 0x3DDF, 0x26CD, 0x694E, 0xCD7F, 0x9FEA,
461 0x1B12, 0x9E1D, 0x7458, 0x2E34, 0x2D36, 0xB2DC, 0xEEB4, 0xFB5B,
462 0xF6A4, 0x4D76, 0x61B7, 0xCE7D, 0x7B52, 0x3EDD, 0x715E, 0x9713,
463 0xF5A6, 0x68B9, 0x0000, 0x2CC1, 0x6040, 0x1FE3, 0xC879, 0xEDB6,
464 0xBED4, 0x468D, 0xD967, 0x4B72, 0xDE94, 0xD498, 0xE8B0, 0x4A85,
465 0x6BBB, 0x2AC5, 0xE54F, 0x16ED, 0xC586, 0xD79A, 0x5566, 0x9411,
466 0xCF8A, 0x10E9, 0x0604, 0x81FE, 0xF0A0, 0x4478, 0xBA25, 0xE34B,
467 0xF3A2, 0xFE5D, 0xC080, 0x8A05, 0xAD3F, 0xBC21, 0x4870, 0x04F1,
468 0xDF63, 0xC177, 0x75AF, 0x6342, 0x3020, 0x1AE5, 0x0EFD, 0x6DBF,
469 0x4C81, 0x1418, 0x3526, 0x2FC3, 0xE1BE, 0xA235, 0xCC88, 0x392E,
470 0x5793, 0xF255, 0x82FC, 0x477A, 0xACC8, 0xE7BA, 0x2B32, 0x95E6,
471 0xA0C0, 0x9819, 0xD19E, 0x7FA3, 0x6644, 0x7E54, 0xAB3B, 0x830B,
472 0xCA8C, 0x29C7, 0xD36B, 0x3C28, 0x79A7, 0xE2BC, 0x1D16, 0x76AD,
473 0x3BDB, 0x5664, 0x4E74, 0x1E14, 0xDB92, 0x0A0C, 0x6C48, 0xE4B8,
474 0x5D9F, 0x6EBD, 0xEF43, 0xA6C4, 0xA839, 0xA431, 0x37D3, 0x8BF2,
475 0x32D5, 0x438B, 0x596E, 0xB7DA, 0x8C01, 0x64B1, 0xD29C, 0xE049,
476 0xB4D8, 0xFAAC, 0x07F3, 0x25CF, 0xAFCA, 0x8EF4, 0xE947, 0x1810,
477 0xD56F, 0x88F0, 0x6F4A, 0x725C, 0x2438, 0xF157, 0xC773, 0x5197,
478 0x23CB, 0x7CA1, 0x9CE8, 0x213E, 0xDD96, 0xDC61, 0x860D, 0x850F,
479 0x90E0, 0x427C, 0xC471, 0xAACC, 0xD890, 0x0506, 0x01F7, 0x121C,
480 0xA3C2, 0x5F6A, 0xF9AE, 0xD069, 0x9117, 0x5899, 0x273A, 0xB927,
481 0x38D9, 0x13EB, 0xB32B, 0x3322, 0xBBD2, 0x70A9, 0x8907, 0xA733,
482 0xB62D, 0x223C, 0x9215, 0x20C9, 0x4987, 0xFFAA, 0x7850, 0x7AA5,
483 0x8F03, 0xF859, 0x8009, 0x171A, 0xDA65, 0x31D7, 0xC684, 0xB8D0,
484 0xC382, 0xB029, 0x775A, 0x111E, 0xCB7B, 0xFCA8, 0xD66D, 0x3A2C,
489 **********************************************************************
490 * Routine: Phase 1 -- generate P1K, given TA, TK, IV32
493 * tk[] = temporal key [128 bits]
494 * ta[] = transmitter's MAC address [ 48 bits]
495 * iv32 = upper 32 bits of IV [ 32 bits]
497 * p1k[] = Phase 1 key [ 80 bits]
500 * This function only needs to be called every 2**16 packets,
501 * although in theory it could be called every packet.
503 **********************************************************************
505 static void phase1(u16 *p1k, const u8 *tk, const u8 *ta, u32 iv32)
509 /* Initialize the 80 bits of P1K[] from IV32 and TA[0..5] */
512 p1k[2] = Mk16(ta[1], ta[0]); /* use TA[] as little-endian */
513 p1k[3] = Mk16(ta[3], ta[2]);
514 p1k[4] = Mk16(ta[5], ta[4]);
516 /* Now compute an unbalanced Feistel cipher with 80-bit block */
517 /* size on the 80-bit block P1K[], using the 128-bit key TK[] */
518 for (i = 0; i < PHASE1_LOOP_CNT; i++) { /* 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" */
530 **********************************************************************
531 * Routine: Phase 2 -- generate RC4KEY, given TK, P1K, IV16
534 * tk[] = Temporal key [128 bits]
535 * p1k[] = Phase 1 output key [ 80 bits]
536 * iv16 = low 16 bits of IV counter [ 16 bits]
538 * rc4key[] = the key used to encrypt the packet [128 bits]
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.
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[].
550 **********************************************************************
552 static void phase2(u8 *rc4key, const u8 *tk, const u16 *p1k, u16 iv16)
555 u16 PPK[6]; /* temporary key for mixing */
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 PPK[5] = p1k[4] + iv16; /* next, add in IV16 */
562 /* Bijective non-linear mixing of the 96 bits of PPK[0..5] */
563 PPK[0] += _S_(PPK[5] ^ TK16(0)); /* Mix key in each "round" */
564 PPK[1] += _S_(PPK[0] ^ TK16(1));
565 PPK[2] += _S_(PPK[1] ^ TK16(2));
566 PPK[3] += _S_(PPK[2] ^ TK16(3));
567 PPK[4] += _S_(PPK[3] ^ TK16(4));
568 PPK[5] += _S_(PPK[4] ^ TK16(5)); /* Total # S-box lookups == 6 */
570 /* Final sweep: bijective, "linear". Rotates kill LSB correlations */
571 PPK[0] += RotR1(PPK[5] ^ TK16(6));
572 PPK[1] += RotR1(PPK[0] ^ TK16(7)); /* Use all of TK[] in Phase2 */
573 PPK[2] += RotR1(PPK[1]);
574 PPK[3] += RotR1(PPK[2]);
575 PPK[4] += RotR1(PPK[3]);
576 PPK[5] += RotR1(PPK[4]);
577 /* Note: At this point, for a given key TK[0..15], the 96-bit output */
578 /* value PPK[0..5] is guaranteed to be unique, as a function */
579 /* of the 96-bit "input" value {TA, IV32, IV16}. That is, P1K */
580 /* is now a keyed permutation of {TA, IV32, IV16}. */
582 /* Set RC4KEY[0..3], which includes "cleartext" portion of RC4 key */
583 rc4key[0] = Hi8(iv16); /* RC4KEY[0..2] is the WEP IV */
584 rc4key[1] = (Hi8(iv16) | 0x20) & 0x7F; /* Help avoid weak (FMS) keys */
585 rc4key[2] = Lo8(iv16);
586 rc4key[3] = Lo8((PPK[5] ^ TK16(0)) >> 1);
588 /* Copy 96 bits of PPK[0..5] to RC4KEY[4..15] (little-endian) */
589 for (i = 0; i < 6; i++) {
590 rc4key[4+2*i] = Lo8(PPK[i]);
591 rc4key[5+2*i] = Hi8(PPK[i]);
596 /* The hlen isn't include the IV */
597 u32 rtw_tkip_encrypt(struct adapter *padapter, u8 *pxmitframe)
604 u8 hw_hdr_offset = 0;
605 struct arc4context mycontext;
606 int curfragnum, length;
608 u8 *pframe, *payload, *iv, *prwskey;
609 union pn48 dot11txpn;
610 struct sta_info *stainfo;
611 struct pkt_attrib *pattrib = &((struct xmit_frame *)pxmitframe)->attrib;
612 struct security_priv *psecuritypriv = &padapter->securitypriv;
613 struct xmit_priv *pxmitpriv = &padapter->xmitpriv;
617 if (((struct xmit_frame *)pxmitframe)->buf_addr == NULL)
620 hw_hdr_offset = TXDESC_SIZE +
621 (((struct xmit_frame *)pxmitframe)->pkt_offset * PACKET_OFFSET_SZ);
622 pframe = ((struct xmit_frame *)pxmitframe)->buf_addr + hw_hdr_offset;
623 /* 4 start to encrypt each fragment */
624 if (pattrib->encrypt == _TKIP_) {
626 stainfo = pattrib->psta;
628 stainfo = rtw_get_stainfo(&padapter->stapriv, &pattrib->ra[0]);
630 if (stainfo != NULL) {
631 RT_TRACE(_module_rtl871x_security_c_, _drv_err_, ("rtw_tkip_encrypt: stainfo!= NULL!!!\n"));
633 if (IS_MCAST(pattrib->ra))
634 prwskey = psecuritypriv->dot118021XGrpKey[psecuritypriv->dot118021XGrpKeyid].skey;
636 prwskey = &stainfo->dot118021x_UncstKey.skey[0];
638 for (curfragnum = 0; curfragnum < pattrib->nr_frags; curfragnum++) {
639 iv = pframe+pattrib->hdrlen;
640 payload = pframe+pattrib->iv_len+pattrib->hdrlen;
642 GET_TKIP_PN(iv, dot11txpn);
644 pnl = (u16)(dot11txpn.val);
645 pnh = (u32)(dot11txpn.val>>16);
646 phase1((u16 *)&ttkey[0], prwskey, &pattrib->ta[0], pnh);
647 phase2(&rc4key[0], prwskey, (u16 *)&ttkey[0], pnl);
649 if ((curfragnum+1) == pattrib->nr_frags) { /* 4 the last fragment */
650 length = pattrib->last_txcmdsz-pattrib->hdrlen-pattrib->iv_len-pattrib->icv_len;
651 RT_TRACE(_module_rtl871x_security_c_, _drv_info_,
652 ("pattrib->iv_len=%x, pattrib->icv_len=%x\n",
653 pattrib->iv_len, pattrib->icv_len));
654 *((__le32 *)crc) = getcrc32(payload, length);/* modified by Amy*/
656 arcfour_init(&mycontext, rc4key, 16);
657 arcfour_encrypt(&mycontext, payload, payload, length);
658 arcfour_encrypt(&mycontext, payload+length, crc, 4);
660 length = pxmitpriv->frag_len-pattrib->hdrlen-pattrib->iv_len-pattrib->icv_len ;
661 *((__le32 *)crc) = getcrc32(payload, length);/* modified by Amy*/
662 arcfour_init(&mycontext, rc4key, 16);
663 arcfour_encrypt(&mycontext, payload, payload, length);
664 arcfour_encrypt(&mycontext, payload+length, crc, 4);
666 pframe += pxmitpriv->frag_len;
667 pframe = (u8 *)RND4((size_t)(pframe));
671 RT_TRACE(_module_rtl871x_security_c_, _drv_err_, ("rtw_tkip_encrypt: stainfo==NULL!!!\n"));
679 /* The hlen isn't include the IV */
680 u32 rtw_tkip_decrypt(struct adapter *padapter, u8 *precvframe)
687 struct arc4context mycontext;
690 u8 *pframe, *payload, *iv, *prwskey;
691 union pn48 dot11txpn;
692 struct sta_info *stainfo;
693 struct rx_pkt_attrib *prxattrib = &((union recv_frame *)precvframe)->u.hdr.attrib;
694 struct security_priv *psecuritypriv = &padapter->securitypriv;
699 pframe = (unsigned char *)((union recv_frame *)precvframe)->u.hdr.rx_data;
701 /* 4 start to decrypt recvframe */
702 if (prxattrib->encrypt == _TKIP_) {
703 stainfo = rtw_get_stainfo(&padapter->stapriv, &prxattrib->ta[0]);
704 if (stainfo != NULL) {
705 if (IS_MCAST(prxattrib->ra)) {
706 if (!psecuritypriv->binstallGrpkey) {
708 DBG_88E("%s:rx bc/mc packets, but didn't install group key!!!!!!!!!!\n", __func__);
711 prwskey = psecuritypriv->dot118021XGrpKey[prxattrib->key_index].skey;
713 RT_TRACE(_module_rtl871x_security_c_, _drv_err_, ("rtw_tkip_decrypt: stainfo!= NULL!!!\n"));
714 prwskey = &stainfo->dot118021x_UncstKey.skey[0];
717 iv = pframe+prxattrib->hdrlen;
718 payload = pframe+prxattrib->iv_len+prxattrib->hdrlen;
719 length = ((union recv_frame *)precvframe)->u.hdr.len-prxattrib->hdrlen-prxattrib->iv_len;
721 GET_TKIP_PN(iv, dot11txpn);
723 pnl = (u16)(dot11txpn.val);
724 pnh = (u32)(dot11txpn.val>>16);
726 phase1((u16 *)&ttkey[0], prwskey, &prxattrib->ta[0], pnh);
727 phase2(&rc4key[0], prwskey, (unsigned short *)&ttkey[0], pnl);
729 /* 4 decrypt payload include icv */
731 arcfour_init(&mycontext, rc4key, 16);
732 arcfour_encrypt(&mycontext, payload, payload, length);
734 *((__le32 *)crc) = getcrc32(payload, length-4);
736 if (crc[3] != payload[length-1] ||
737 crc[2] != payload[length-2] ||
738 crc[1] != payload[length-3] ||
739 crc[0] != payload[length-4]) {
740 RT_TRACE(_module_rtl871x_security_c_, _drv_err_,
741 ("rtw_wep_decrypt:icv error crc (%4ph)!=payload (%4ph)\n",
742 &crc, &payload[length-4]));
746 RT_TRACE(_module_rtl871x_security_c_, _drv_err_, ("rtw_tkip_decrypt: stainfo==NULL!!!\n"));
755 /* 3 ===== AES related ===== */
758 #define MAX_MSG_SIZE 2048
759 /*****************************/
760 /******** SBOX Table *********/
761 /*****************************/
763 static u8 sbox_table[256] = {
764 0x63, 0x7c, 0x77, 0x7b, 0xf2, 0x6b, 0x6f, 0xc5,
765 0x30, 0x01, 0x67, 0x2b, 0xfe, 0xd7, 0xab, 0x76,
766 0xca, 0x82, 0xc9, 0x7d, 0xfa, 0x59, 0x47, 0xf0,
767 0xad, 0xd4, 0xa2, 0xaf, 0x9c, 0xa4, 0x72, 0xc0,
768 0xb7, 0xfd, 0x93, 0x26, 0x36, 0x3f, 0xf7, 0xcc,
769 0x34, 0xa5, 0xe5, 0xf1, 0x71, 0xd8, 0x31, 0x15,
770 0x04, 0xc7, 0x23, 0xc3, 0x18, 0x96, 0x05, 0x9a,
771 0x07, 0x12, 0x80, 0xe2, 0xeb, 0x27, 0xb2, 0x75,
772 0x09, 0x83, 0x2c, 0x1a, 0x1b, 0x6e, 0x5a, 0xa0,
773 0x52, 0x3b, 0xd6, 0xb3, 0x29, 0xe3, 0x2f, 0x84,
774 0x53, 0xd1, 0x00, 0xed, 0x20, 0xfc, 0xb1, 0x5b,
775 0x6a, 0xcb, 0xbe, 0x39, 0x4a, 0x4c, 0x58, 0xcf,
776 0xd0, 0xef, 0xaa, 0xfb, 0x43, 0x4d, 0x33, 0x85,
777 0x45, 0xf9, 0x02, 0x7f, 0x50, 0x3c, 0x9f, 0xa8,
778 0x51, 0xa3, 0x40, 0x8f, 0x92, 0x9d, 0x38, 0xf5,
779 0xbc, 0xb6, 0xda, 0x21, 0x10, 0xff, 0xf3, 0xd2,
780 0xcd, 0x0c, 0x13, 0xec, 0x5f, 0x97, 0x44, 0x17,
781 0xc4, 0xa7, 0x7e, 0x3d, 0x64, 0x5d, 0x19, 0x73,
782 0x60, 0x81, 0x4f, 0xdc, 0x22, 0x2a, 0x90, 0x88,
783 0x46, 0xee, 0xb8, 0x14, 0xde, 0x5e, 0x0b, 0xdb,
784 0xe0, 0x32, 0x3a, 0x0a, 0x49, 0x06, 0x24, 0x5c,
785 0xc2, 0xd3, 0xac, 0x62, 0x91, 0x95, 0xe4, 0x79,
786 0xe7, 0xc8, 0x37, 0x6d, 0x8d, 0xd5, 0x4e, 0xa9,
787 0x6c, 0x56, 0xf4, 0xea, 0x65, 0x7a, 0xae, 0x08,
788 0xba, 0x78, 0x25, 0x2e, 0x1c, 0xa6, 0xb4, 0xc6,
789 0xe8, 0xdd, 0x74, 0x1f, 0x4b, 0xbd, 0x8b, 0x8a,
790 0x70, 0x3e, 0xb5, 0x66, 0x48, 0x03, 0xf6, 0x0e,
791 0x61, 0x35, 0x57, 0xb9, 0x86, 0xc1, 0x1d, 0x9e,
792 0xe1, 0xf8, 0x98, 0x11, 0x69, 0xd9, 0x8e, 0x94,
793 0x9b, 0x1e, 0x87, 0xe9, 0xce, 0x55, 0x28, 0xdf,
794 0x8c, 0xa1, 0x89, 0x0d, 0xbf, 0xe6, 0x42, 0x68,
795 0x41, 0x99, 0x2d, 0x0f, 0xb0, 0x54, 0xbb, 0x16
798 /*****************************/
799 /**** Function Prototypes ****/
800 /*****************************/
802 static void bitwise_xor(u8 *ina, u8 *inb, u8 *out);
803 static void construct_mic_iv(u8 *mic_header1, int qc_exists, int a4_exists, u8 *mpdu, uint payload_length, u8 *pn_vector);
804 static void construct_mic_header1(u8 *mic_header1, int header_length, u8 *mpdu);
805 static void construct_mic_header2(u8 *mic_header2, u8 *mpdu, int a4_exists, int qc_exists);
806 static void construct_ctr_preload(u8 *ctr_preload, int a4_exists, int qc_exists, u8 *mpdu, u8 *pn_vector, int c);
807 static void xor_128(u8 *a, u8 *b, u8 *out);
808 static void xor_32(u8 *a, u8 *b, u8 *out);
809 static u8 sbox(u8 a);
810 static void next_key(u8 *key, int round);
811 static void byte_sub(u8 *in, u8 *out);
812 static void shift_row(u8 *in, u8 *out);
813 static void mix_column(u8 *in, u8 *out);
814 static void aes128k128d(u8 *key, u8 *data, u8 *ciphertext);
816 /****************************************/
818 /* Performs a 128 bit AES encrypt with */
820 /****************************************/
821 static void xor_128(u8 *a, u8 *b, u8 *out)
825 for (i = 0; i < 16; i++)
826 out[i] = a[i] ^ b[i];
830 static void xor_32(u8 *a, u8 *b, u8 *out)
834 for (i = 0; i < 4; i++)
835 out[i] = a[i] ^ b[i];
841 return sbox_table[(int)a];
844 static void next_key(u8 *key, int round)
848 u8 rcon_table[12] = {
849 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80,
850 0x1b, 0x36, 0x36, 0x36
853 sbox_key[0] = sbox(key[13]);
854 sbox_key[1] = sbox(key[14]);
855 sbox_key[2] = sbox(key[15]);
856 sbox_key[3] = sbox(key[12]);
858 rcon = rcon_table[round];
860 xor_32(&key[0], sbox_key, &key[0]);
861 key[0] = key[0] ^ rcon;
863 xor_32(&key[4], &key[0], &key[4]);
864 xor_32(&key[8], &key[4], &key[8]);
865 xor_32(&key[12], &key[8], &key[12]);
869 static void byte_sub(u8 *in, u8 *out)
873 for (i = 0; i < 16; i++)
874 out[i] = sbox(in[i]);
878 static void shift_row(u8 *in, u8 *out)
900 static void mix_column(u8 *in, u8 *out)
912 for (i = 0 ; i < 4; i++) {
913 if ((in[i] & 0x80) == 0x80)
919 swap_halfs[0] = in[2]; /* Swap halfs */
920 swap_halfs[1] = in[3];
921 swap_halfs[2] = in[0];
922 swap_halfs[3] = in[1];
924 rotl[0] = in[3]; /* Rotate left 8 bits */
929 andf7[0] = in[0] & 0x7f;
930 andf7[1] = in[1] & 0x7f;
931 andf7[2] = in[2] & 0x7f;
932 andf7[3] = in[3] & 0x7f;
934 for (i = 3; i > 0; i--) { /* logical shift left 1 bit */
935 andf7[i] = andf7[i] << 1;
936 if ((andf7[i-1] & 0x80) == 0x80)
937 andf7[i] = (andf7[i] | 0x01);
939 andf7[0] = andf7[0] << 1;
940 andf7[0] = andf7[0] & 0xfe;
942 xor_32(add1b, andf7, add1bf7);
944 xor_32(in, add1bf7, rotr);
946 temp[0] = rotr[0]; /* Rotate right 8 bits */
952 xor_32(add1bf7, rotr, temp);
953 xor_32(swap_halfs, rotl, tempb);
954 xor_32(temp, tempb, out);
958 static void aes128k128d(u8 *key, u8 *data, u8 *ciphertext)
962 u8 intermediatea[16];
963 u8 intermediateb[16];
966 for (i = 0; i < 16; i++)
967 round_key[i] = key[i];
968 for (round = 0; round < 11; round++) {
970 xor_128(round_key, data, ciphertext);
971 next_key(round_key, round);
972 } else if (round == 10) {
973 byte_sub(ciphertext, intermediatea);
974 shift_row(intermediatea, intermediateb);
975 xor_128(intermediateb, round_key, ciphertext);
977 byte_sub(ciphertext, intermediatea);
978 shift_row(intermediatea, intermediateb);
979 mix_column(&intermediateb[0], &intermediatea[0]);
980 mix_column(&intermediateb[4], &intermediatea[4]);
981 mix_column(&intermediateb[8], &intermediatea[8]);
982 mix_column(&intermediateb[12], &intermediatea[12]);
983 xor_128(intermediatea, round_key, ciphertext);
984 next_key(round_key, round);
990 /************************************************/
991 /* construct_mic_iv() */
992 /* Builds the MIC IV from header fields and PN */
993 /************************************************/
994 static void construct_mic_iv(u8 *mic_iv, int qc_exists, int a4_exists, u8 *mpdu,
995 uint payload_length, u8 *pn_vector)
1000 if (qc_exists && a4_exists)
1001 mic_iv[1] = mpdu[30] & 0x0f; /* QoS_TC */
1002 if (qc_exists && !a4_exists)
1003 mic_iv[1] = mpdu[24] & 0x0f; /* mute bits 7-4 */
1006 for (i = 2; i < 8; i++)
1007 mic_iv[i] = mpdu[i + 8]; /* mic_iv[2:7] = A2[0:5] = mpdu[10:15] */
1008 for (i = 8; i < 14; i++)
1009 mic_iv[i] = pn_vector[13 - i]; /* mic_iv[8:13] = PN[5:0] */
1010 mic_iv[14] = (unsigned char) (payload_length / 256);
1011 mic_iv[15] = (unsigned char) (payload_length % 256);
1015 /************************************************/
1016 /* construct_mic_header1() */
1017 /* Builds the first MIC header block from */
1018 /* header fields. */
1019 /************************************************/
1020 static void construct_mic_header1(u8 *mic_header1, int header_length, u8 *mpdu)
1023 mic_header1[0] = (u8)((header_length - 2) / 256);
1024 mic_header1[1] = (u8)((header_length - 2) % 256);
1025 mic_header1[2] = mpdu[0] & 0xcf; /* Mute CF poll & CF ack bits */
1026 mic_header1[3] = mpdu[1] & 0xc7; /* Mute retry, more data and pwr mgt bits */
1027 mic_header1[4] = mpdu[4]; /* A1 */
1028 mic_header1[5] = mpdu[5];
1029 mic_header1[6] = mpdu[6];
1030 mic_header1[7] = mpdu[7];
1031 mic_header1[8] = mpdu[8];
1032 mic_header1[9] = mpdu[9];
1033 mic_header1[10] = mpdu[10]; /* A2 */
1034 mic_header1[11] = mpdu[11];
1035 mic_header1[12] = mpdu[12];
1036 mic_header1[13] = mpdu[13];
1037 mic_header1[14] = mpdu[14];
1038 mic_header1[15] = mpdu[15];
1042 /************************************************/
1043 /* construct_mic_header2() */
1044 /* Builds the last MIC header block from */
1045 /* header fields. */
1046 /************************************************/
1047 static void construct_mic_header2(u8 *mic_header2, u8 *mpdu, int a4_exists, int qc_exists)
1051 for (i = 0; i < 16; i++)
1052 mic_header2[i] = 0x00;
1054 mic_header2[0] = mpdu[16]; /* A3 */
1055 mic_header2[1] = mpdu[17];
1056 mic_header2[2] = mpdu[18];
1057 mic_header2[3] = mpdu[19];
1058 mic_header2[4] = mpdu[20];
1059 mic_header2[5] = mpdu[21];
1061 mic_header2[6] = 0x00;
1062 mic_header2[7] = 0x00; /* mpdu[23]; */
1064 if (!qc_exists && a4_exists) {
1065 for (i = 0; i < 6; i++)
1066 mic_header2[8+i] = mpdu[24+i]; /* A4 */
1069 if (qc_exists && !a4_exists) {
1070 mic_header2[8] = mpdu[24] & 0x0f; /* mute bits 15 - 4 */
1071 mic_header2[9] = mpdu[25] & 0x00;
1074 if (qc_exists && a4_exists) {
1075 for (i = 0; i < 6; i++)
1076 mic_header2[8+i] = mpdu[24+i]; /* A4 */
1078 mic_header2[14] = mpdu[30] & 0x0f;
1079 mic_header2[15] = mpdu[31] & 0x00;
1085 /************************************************/
1086 /* construct_mic_header2() */
1087 /* Builds the last MIC header block from */
1088 /* header fields. */
1089 /************************************************/
1090 static void construct_ctr_preload(u8 *ctr_preload, int a4_exists, int qc_exists, u8 *mpdu, u8 *pn_vector, int c)
1094 for (i = 0; i < 16; i++)
1095 ctr_preload[i] = 0x00;
1098 ctr_preload[0] = 0x01; /* flag */
1099 if (qc_exists && a4_exists)
1100 ctr_preload[1] = mpdu[30] & 0x0f; /* QoC_Control */
1101 if (qc_exists && !a4_exists)
1102 ctr_preload[1] = mpdu[24] & 0x0f;
1104 for (i = 2; i < 8; i++)
1105 ctr_preload[i] = mpdu[i + 8]; /* ctr_preload[2:7] = A2[0:5] = mpdu[10:15] */
1106 for (i = 8; i < 14; i++)
1107 ctr_preload[i] = pn_vector[13 - i]; /* ctr_preload[8:13] = PN[5:0] */
1108 ctr_preload[14] = (unsigned char) (c / 256); /* Ctr */
1109 ctr_preload[15] = (unsigned char) (c % 256);
1113 /************************************/
1115 /* A 128 bit, bitwise exclusive or */
1116 /************************************/
1117 static void bitwise_xor(u8 *ina, u8 *inb, u8 *out)
1121 for (i = 0; i < 16; i++)
1122 out[i] = ina[i] ^ inb[i];
1126 static int aes_cipher(u8 *key, uint hdrlen, u8 *pframe, uint plen)
1128 uint qc_exists, a4_exists, i, j, payload_remainder,
1129 num_blocks, payload_index;
1137 /* Intermediate Buffers */
1138 u8 chain_buffer[16];
1140 u8 padded_buffer[16];
1142 uint frtype = GetFrameType(pframe);
1143 uint frsubtype = GetFrameSubType(pframe);
1146 frsubtype = frsubtype>>4;
1148 _rtw_memset((void *)mic_iv, 0, 16);
1149 _rtw_memset((void *)mic_header1, 0, 16);
1150 _rtw_memset((void *)mic_header2, 0, 16);
1151 _rtw_memset((void *)ctr_preload, 0, 16);
1152 _rtw_memset((void *)chain_buffer, 0, 16);
1153 _rtw_memset((void *)aes_out, 0, 16);
1154 _rtw_memset((void *)padded_buffer, 0, 16);
1156 if ((hdrlen == WLAN_HDR_A3_LEN) || (hdrlen == WLAN_HDR_A3_QOS_LEN))
1161 if ((frtype == WIFI_DATA_CFACK) || (frtype == WIFI_DATA_CFPOLL) || (frtype == WIFI_DATA_CFACKPOLL)) {
1163 if (hdrlen != WLAN_HDR_A3_QOS_LEN)
1165 } else if ((frsubtype == 0x08) || (frsubtype == 0x09) || (frsubtype == 0x0a) || (frsubtype == 0x0b)) {
1166 if (hdrlen != WLAN_HDR_A3_QOS_LEN)
1173 pn_vector[0] = pframe[hdrlen];
1174 pn_vector[1] = pframe[hdrlen+1];
1175 pn_vector[2] = pframe[hdrlen+4];
1176 pn_vector[3] = pframe[hdrlen+5];
1177 pn_vector[4] = pframe[hdrlen+6];
1178 pn_vector[5] = pframe[hdrlen+7];
1180 construct_mic_iv(mic_iv, qc_exists, a4_exists, pframe, plen, pn_vector);
1182 construct_mic_header1(mic_header1, hdrlen, pframe);
1183 construct_mic_header2(mic_header2, pframe, a4_exists, qc_exists);
1185 payload_remainder = plen % 16;
1186 num_blocks = plen / 16;
1188 /* Find start of payload */
1189 payload_index = (hdrlen + 8);
1192 aes128k128d(key, mic_iv, aes_out);
1193 bitwise_xor(aes_out, mic_header1, chain_buffer);
1194 aes128k128d(key, chain_buffer, aes_out);
1195 bitwise_xor(aes_out, mic_header2, chain_buffer);
1196 aes128k128d(key, chain_buffer, aes_out);
1198 for (i = 0; i < num_blocks; i++) {
1199 bitwise_xor(aes_out, &pframe[payload_index], chain_buffer);/* bitwise_xor(aes_out, &message[payload_index], chain_buffer); */
1201 payload_index += 16;
1202 aes128k128d(key, chain_buffer, aes_out);
1205 /* Add on the final payload block if it needs padding */
1206 if (payload_remainder > 0) {
1207 for (j = 0; j < 16; j++)
1208 padded_buffer[j] = 0x00;
1209 for (j = 0; j < payload_remainder; j++)
1210 padded_buffer[j] = pframe[payload_index++];/* padded_buffer[j] = message[payload_index++]; */
1211 bitwise_xor(aes_out, padded_buffer, chain_buffer);
1212 aes128k128d(key, chain_buffer, aes_out);
1215 for (j = 0; j < 8; j++)
1216 mic[j] = aes_out[j];
1218 /* Insert MIC into payload */
1219 for (j = 0; j < 8; j++)
1220 pframe[payload_index+j] = mic[j]; /* message[payload_index+j] = mic[j]; */
1222 payload_index = hdrlen + 8;
1223 for (i = 0; i < num_blocks; i++) {
1224 construct_ctr_preload(ctr_preload, a4_exists, qc_exists, pframe, pn_vector, i+1);
1225 aes128k128d(key, ctr_preload, aes_out);
1226 bitwise_xor(aes_out, &pframe[payload_index], chain_buffer);
1227 for (j = 0; j < 16; j++)
1228 pframe[payload_index++] = chain_buffer[j];
1231 if (payload_remainder > 0) { /* If there is a short final block, then pad it,*/
1232 /* encrypt it and copy the unpadded part back */
1233 construct_ctr_preload(ctr_preload, a4_exists, qc_exists, pframe, pn_vector, num_blocks+1);
1235 for (j = 0; j < 16; j++)
1236 padded_buffer[j] = 0x00;
1237 for (j = 0; j < payload_remainder; j++)
1238 padded_buffer[j] = pframe[payload_index+j];
1239 aes128k128d(key, ctr_preload, aes_out);
1240 bitwise_xor(aes_out, padded_buffer, chain_buffer);
1241 for (j = 0; j < payload_remainder; j++)
1242 pframe[payload_index++] = chain_buffer[j];
1244 /* Encrypt the MIC */
1245 construct_ctr_preload(ctr_preload, a4_exists, qc_exists, pframe, pn_vector, 0);
1247 for (j = 0; j < 16; j++)
1248 padded_buffer[j] = 0x00;
1249 for (j = 0; j < 8; j++)
1250 padded_buffer[j] = pframe[j+hdrlen+8+plen];
1252 aes128k128d(key, ctr_preload, aes_out);
1253 bitwise_xor(aes_out, padded_buffer, chain_buffer);
1254 for (j = 0; j < 8; j++)
1255 pframe[payload_index++] = chain_buffer[j];
1260 u32 rtw_aes_encrypt(struct adapter *padapter, u8 *pxmitframe)
1264 /* unsigned char message[MAX_MSG_SIZE]; */
1266 /* Intermediate Buffers */
1267 int curfragnum, length;
1268 u8 *pframe, *prwskey; /* *payload,*iv */
1269 u8 hw_hdr_offset = 0;
1270 struct sta_info *stainfo;
1271 struct pkt_attrib *pattrib = &((struct xmit_frame *)pxmitframe)->attrib;
1272 struct security_priv *psecuritypriv = &padapter->securitypriv;
1273 struct xmit_priv *pxmitpriv = &padapter->xmitpriv;
1275 /* uint offset = 0; */
1279 if (((struct xmit_frame *)pxmitframe)->buf_addr == NULL)
1282 hw_hdr_offset = TXDESC_SIZE +
1283 (((struct xmit_frame *)pxmitframe)->pkt_offset * PACKET_OFFSET_SZ);
1285 pframe = ((struct xmit_frame *)pxmitframe)->buf_addr + hw_hdr_offset;
1287 /* 4 start to encrypt each fragment */
1288 if ((pattrib->encrypt == _AES_)) {
1290 stainfo = pattrib->psta;
1292 stainfo = rtw_get_stainfo(&padapter->stapriv, &pattrib->ra[0]);
1294 if (stainfo != NULL) {
1295 RT_TRACE(_module_rtl871x_security_c_, _drv_err_, ("rtw_aes_encrypt: stainfo!= NULL!!!\n"));
1297 if (IS_MCAST(pattrib->ra))
1298 prwskey = psecuritypriv->dot118021XGrpKey[psecuritypriv->dot118021XGrpKeyid].skey;
1300 prwskey = &stainfo->dot118021x_UncstKey.skey[0];
1301 for (curfragnum = 0; curfragnum < pattrib->nr_frags; curfragnum++) {
1302 if ((curfragnum+1) == pattrib->nr_frags) { /* 4 the last fragment */
1303 length = pattrib->last_txcmdsz-pattrib->hdrlen-pattrib->iv_len-pattrib->icv_len;
1305 aes_cipher(prwskey, pattrib->hdrlen, pframe, length);
1307 length = pxmitpriv->frag_len-pattrib->hdrlen-pattrib->iv_len-pattrib->icv_len ;
1309 aes_cipher(prwskey, pattrib->hdrlen, pframe, length);
1310 pframe += pxmitpriv->frag_len;
1311 pframe = (u8 *)RND4((size_t)(pframe));
1315 RT_TRACE(_module_rtl871x_security_c_, _drv_err_, ("rtw_aes_encrypt: stainfo==NULL!!!\n"));
1325 static int aes_decipher(u8 *key, uint hdrlen,
1326 u8 *pframe, uint plen)
1328 static u8 message[MAX_MSG_SIZE];
1329 uint qc_exists, a4_exists, i, j, payload_remainder,
1330 num_blocks, payload_index;
1338 /* Intermediate Buffers */
1339 u8 chain_buffer[16];
1341 u8 padded_buffer[16];
1344 /* uint offset = 0; */
1345 uint frtype = GetFrameType(pframe);
1346 uint frsubtype = GetFrameSubType(pframe);
1348 frsubtype = frsubtype>>4;
1350 _rtw_memset((void *)mic_iv, 0, 16);
1351 _rtw_memset((void *)mic_header1, 0, 16);
1352 _rtw_memset((void *)mic_header2, 0, 16);
1353 _rtw_memset((void *)ctr_preload, 0, 16);
1354 _rtw_memset((void *)chain_buffer, 0, 16);
1355 _rtw_memset((void *)aes_out, 0, 16);
1356 _rtw_memset((void *)padded_buffer, 0, 16);
1358 /* start to decrypt the payload */
1360 num_blocks = (plen-8) / 16; /* plen including llc, payload_length and mic) */
1362 payload_remainder = (plen-8) % 16;
1364 pn_vector[0] = pframe[hdrlen];
1365 pn_vector[1] = pframe[hdrlen+1];
1366 pn_vector[2] = pframe[hdrlen+4];
1367 pn_vector[3] = pframe[hdrlen+5];
1368 pn_vector[4] = pframe[hdrlen+6];
1369 pn_vector[5] = pframe[hdrlen+7];
1371 if ((hdrlen == WLAN_HDR_A3_LEN) || (hdrlen == WLAN_HDR_A3_QOS_LEN))
1376 if ((frtype == WIFI_DATA_CFACK) || (frtype == WIFI_DATA_CFPOLL) ||
1377 (frtype == WIFI_DATA_CFACKPOLL)) {
1379 if (hdrlen != WLAN_HDR_A3_QOS_LEN)
1381 } else if ((frsubtype == 0x08) || (frsubtype == 0x09) ||
1382 (frsubtype == 0x0a) || (frsubtype == 0x0b)) {
1383 if (hdrlen != WLAN_HDR_A3_QOS_LEN)
1390 /* now, decrypt pframe with hdrlen offset and plen long */
1392 payload_index = hdrlen + 8; /* 8 is for extiv */
1394 for (i = 0; i < num_blocks; i++) {
1395 construct_ctr_preload(ctr_preload, a4_exists, qc_exists, pframe, pn_vector, i+1);
1397 aes128k128d(key, ctr_preload, aes_out);
1398 bitwise_xor(aes_out, &pframe[payload_index], chain_buffer);
1400 for (j = 0; j < 16; j++)
1401 pframe[payload_index++] = chain_buffer[j];
1404 if (payload_remainder > 0) { /* If there is a short final block, then pad it,*/
1405 /* encrypt it and copy the unpadded part back */
1406 construct_ctr_preload(ctr_preload, a4_exists, qc_exists, pframe, pn_vector, num_blocks+1);
1408 for (j = 0; j < 16; j++)
1409 padded_buffer[j] = 0x00;
1410 for (j = 0; j < payload_remainder; j++)
1411 padded_buffer[j] = pframe[payload_index+j];
1412 aes128k128d(key, ctr_preload, aes_out);
1413 bitwise_xor(aes_out, padded_buffer, chain_buffer);
1414 for (j = 0; j < payload_remainder; j++)
1415 pframe[payload_index++] = chain_buffer[j];
1418 /* start to calculate the mic */
1419 if ((hdrlen+plen+8) <= MAX_MSG_SIZE)
1420 memcpy(message, pframe, (hdrlen + plen+8)); /* 8 is for ext iv len */
1422 pn_vector[0] = pframe[hdrlen];
1423 pn_vector[1] = pframe[hdrlen+1];
1424 pn_vector[2] = pframe[hdrlen+4];
1425 pn_vector[3] = pframe[hdrlen+5];
1426 pn_vector[4] = pframe[hdrlen+6];
1427 pn_vector[5] = pframe[hdrlen+7];
1428 construct_mic_iv(mic_iv, qc_exists, a4_exists, message, plen-8, pn_vector);
1430 construct_mic_header1(mic_header1, hdrlen, message);
1431 construct_mic_header2(mic_header2, message, a4_exists, qc_exists);
1433 payload_remainder = (plen-8) % 16;
1434 num_blocks = (plen-8) / 16;
1436 /* Find start of payload */
1437 payload_index = (hdrlen + 8);
1440 aes128k128d(key, mic_iv, aes_out);
1441 bitwise_xor(aes_out, mic_header1, chain_buffer);
1442 aes128k128d(key, chain_buffer, aes_out);
1443 bitwise_xor(aes_out, mic_header2, chain_buffer);
1444 aes128k128d(key, chain_buffer, aes_out);
1446 for (i = 0; i < num_blocks; i++) {
1447 bitwise_xor(aes_out, &message[payload_index], chain_buffer);
1449 payload_index += 16;
1450 aes128k128d(key, chain_buffer, aes_out);
1453 /* Add on the final payload block if it needs padding */
1454 if (payload_remainder > 0) {
1455 for (j = 0; j < 16; j++)
1456 padded_buffer[j] = 0x00;
1457 for (j = 0; j < payload_remainder; j++)
1458 padded_buffer[j] = message[payload_index++];
1459 bitwise_xor(aes_out, padded_buffer, chain_buffer);
1460 aes128k128d(key, chain_buffer, aes_out);
1463 for (j = 0 ; j < 8; j++)
1464 mic[j] = aes_out[j];
1466 /* Insert MIC into payload */
1467 for (j = 0; j < 8; j++)
1468 message[payload_index+j] = mic[j];
1470 payload_index = hdrlen + 8;
1471 for (i = 0; i < num_blocks; i++) {
1472 construct_ctr_preload(ctr_preload, a4_exists, qc_exists, message, pn_vector, i+1);
1473 aes128k128d(key, ctr_preload, aes_out);
1474 bitwise_xor(aes_out, &message[payload_index], chain_buffer);
1475 for (j = 0; j < 16; j++)
1476 message[payload_index++] = chain_buffer[j];
1479 if (payload_remainder > 0) { /* If there is a short final block, then pad it,*/
1480 /* encrypt it and copy the unpadded part back */
1481 construct_ctr_preload(ctr_preload, a4_exists, qc_exists, message, pn_vector, num_blocks+1);
1483 for (j = 0; j < 16; j++)
1484 padded_buffer[j] = 0x00;
1485 for (j = 0; j < payload_remainder; j++)
1486 padded_buffer[j] = message[payload_index+j];
1487 aes128k128d(key, ctr_preload, aes_out);
1488 bitwise_xor(aes_out, padded_buffer, chain_buffer);
1489 for (j = 0; j < payload_remainder; j++)
1490 message[payload_index++] = chain_buffer[j];
1493 /* Encrypt the MIC */
1494 construct_ctr_preload(ctr_preload, a4_exists, qc_exists, message, pn_vector, 0);
1496 for (j = 0; j < 16; j++)
1497 padded_buffer[j] = 0x00;
1498 for (j = 0; j < 8; j++)
1499 padded_buffer[j] = message[j+hdrlen+8+plen-8];
1501 aes128k128d(key, ctr_preload, aes_out);
1502 bitwise_xor(aes_out, padded_buffer, chain_buffer);
1503 for (j = 0; j < 8; j++)
1504 message[payload_index++] = chain_buffer[j];
1506 /* compare the mic */
1507 for (i = 0; i < 8; i++) {
1508 if (pframe[hdrlen+8+plen-8+i] != message[hdrlen+8+plen-8+i]) {
1509 RT_TRACE(_module_rtl871x_security_c_, _drv_err_,
1510 ("aes_decipher:mic check error mic[%d]: pframe(%x)!=message(%x)\n",
1511 i, pframe[hdrlen+8+plen-8+i], message[hdrlen+8+plen-8+i]));
1512 DBG_88E("aes_decipher:mic check error mic[%d]: pframe(%x)!=message(%x)\n",
1513 i, pframe[hdrlen+8+plen-8+i], message[hdrlen+8+plen-8+i]);
1521 u32 rtw_aes_decrypt(struct adapter *padapter, u8 *precvframe)
1523 /* Intermediate Buffers */
1525 u8 *pframe, *prwskey; /* *payload,*iv */
1526 struct sta_info *stainfo;
1527 struct rx_pkt_attrib *prxattrib = &((union recv_frame *)precvframe)->u.hdr.attrib;
1528 struct security_priv *psecuritypriv = &padapter->securitypriv;
1531 pframe = (unsigned char *)((union recv_frame *)precvframe)->u.hdr.rx_data;
1532 /* 4 start to encrypt each fragment */
1533 if ((prxattrib->encrypt == _AES_)) {
1534 stainfo = rtw_get_stainfo(&padapter->stapriv, &prxattrib->ta[0]);
1535 if (stainfo != NULL) {
1536 RT_TRACE(_module_rtl871x_security_c_, _drv_err_, ("rtw_aes_decrypt: stainfo!= NULL!!!\n"));
1538 if (IS_MCAST(prxattrib->ra)) {
1539 /* in concurrent we should use sw descrypt in group key, so we remove this message */
1540 if (!psecuritypriv->binstallGrpkey) {
1542 DBG_88E("%s:rx bc/mc packets, but didn't install group key!!!!!!!!!!\n", __func__);
1545 prwskey = psecuritypriv->dot118021XGrpKey[prxattrib->key_index].skey;
1546 if (psecuritypriv->dot118021XGrpKeyid != prxattrib->key_index) {
1547 DBG_88E("not match packet_index=%d, install_index=%d\n",
1548 prxattrib->key_index, psecuritypriv->dot118021XGrpKeyid);
1553 prwskey = &stainfo->dot118021x_UncstKey.skey[0];
1555 length = ((union recv_frame *)precvframe)->u.hdr.len-prxattrib->hdrlen-prxattrib->iv_len;
1556 res = aes_decipher(prwskey, prxattrib->hdrlen, pframe, length);
1558 RT_TRACE(_module_rtl871x_security_c_, _drv_err_, ("rtw_aes_encrypt: stainfo==NULL!!!\n"));
1568 const u32 Te0[256] = {
1569 0xc66363a5U, 0xf87c7c84U, 0xee777799U, 0xf67b7b8dU,
1570 0xfff2f20dU, 0xd66b6bbdU, 0xde6f6fb1U, 0x91c5c554U,
1571 0x60303050U, 0x02010103U, 0xce6767a9U, 0x562b2b7dU,
1572 0xe7fefe19U, 0xb5d7d762U, 0x4dababe6U, 0xec76769aU,
1573 0x8fcaca45U, 0x1f82829dU, 0x89c9c940U, 0xfa7d7d87U,
1574 0xeffafa15U, 0xb25959ebU, 0x8e4747c9U, 0xfbf0f00bU,
1575 0x41adadecU, 0xb3d4d467U, 0x5fa2a2fdU, 0x45afafeaU,
1576 0x239c9cbfU, 0x53a4a4f7U, 0xe4727296U, 0x9bc0c05bU,
1577 0x75b7b7c2U, 0xe1fdfd1cU, 0x3d9393aeU, 0x4c26266aU,
1578 0x6c36365aU, 0x7e3f3f41U, 0xf5f7f702U, 0x83cccc4fU,
1579 0x6834345cU, 0x51a5a5f4U, 0xd1e5e534U, 0xf9f1f108U,
1580 0xe2717193U, 0xabd8d873U, 0x62313153U, 0x2a15153fU,
1581 0x0804040cU, 0x95c7c752U, 0x46232365U, 0x9dc3c35eU,
1582 0x30181828U, 0x379696a1U, 0x0a05050fU, 0x2f9a9ab5U,
1583 0x0e070709U, 0x24121236U, 0x1b80809bU, 0xdfe2e23dU,
1584 0xcdebeb26U, 0x4e272769U, 0x7fb2b2cdU, 0xea75759fU,
1585 0x1209091bU, 0x1d83839eU, 0x582c2c74U, 0x341a1a2eU,
1586 0x361b1b2dU, 0xdc6e6eb2U, 0xb45a5aeeU, 0x5ba0a0fbU,
1587 0xa45252f6U, 0x763b3b4dU, 0xb7d6d661U, 0x7db3b3ceU,
1588 0x5229297bU, 0xdde3e33eU, 0x5e2f2f71U, 0x13848497U,
1589 0xa65353f5U, 0xb9d1d168U, 0x00000000U, 0xc1eded2cU,
1590 0x40202060U, 0xe3fcfc1fU, 0x79b1b1c8U, 0xb65b5bedU,
1591 0xd46a6abeU, 0x8dcbcb46U, 0x67bebed9U, 0x7239394bU,
1592 0x944a4adeU, 0x984c4cd4U, 0xb05858e8U, 0x85cfcf4aU,
1593 0xbbd0d06bU, 0xc5efef2aU, 0x4faaaae5U, 0xedfbfb16U,
1594 0x864343c5U, 0x9a4d4dd7U, 0x66333355U, 0x11858594U,
1595 0x8a4545cfU, 0xe9f9f910U, 0x04020206U, 0xfe7f7f81U,
1596 0xa05050f0U, 0x783c3c44U, 0x259f9fbaU, 0x4ba8a8e3U,
1597 0xa25151f3U, 0x5da3a3feU, 0x804040c0U, 0x058f8f8aU,
1598 0x3f9292adU, 0x219d9dbcU, 0x70383848U, 0xf1f5f504U,
1599 0x63bcbcdfU, 0x77b6b6c1U, 0xafdada75U, 0x42212163U,
1600 0x20101030U, 0xe5ffff1aU, 0xfdf3f30eU, 0xbfd2d26dU,
1601 0x81cdcd4cU, 0x180c0c14U, 0x26131335U, 0xc3ecec2fU,
1602 0xbe5f5fe1U, 0x359797a2U, 0x884444ccU, 0x2e171739U,
1603 0x93c4c457U, 0x55a7a7f2U, 0xfc7e7e82U, 0x7a3d3d47U,
1604 0xc86464acU, 0xba5d5de7U, 0x3219192bU, 0xe6737395U,
1605 0xc06060a0U, 0x19818198U, 0x9e4f4fd1U, 0xa3dcdc7fU,
1606 0x44222266U, 0x542a2a7eU, 0x3b9090abU, 0x0b888883U,
1607 0x8c4646caU, 0xc7eeee29U, 0x6bb8b8d3U, 0x2814143cU,
1608 0xa7dede79U, 0xbc5e5ee2U, 0x160b0b1dU, 0xaddbdb76U,
1609 0xdbe0e03bU, 0x64323256U, 0x743a3a4eU, 0x140a0a1eU,
1610 0x924949dbU, 0x0c06060aU, 0x4824246cU, 0xb85c5ce4U,
1611 0x9fc2c25dU, 0xbdd3d36eU, 0x43acacefU, 0xc46262a6U,
1612 0x399191a8U, 0x319595a4U, 0xd3e4e437U, 0xf279798bU,
1613 0xd5e7e732U, 0x8bc8c843U, 0x6e373759U, 0xda6d6db7U,
1614 0x018d8d8cU, 0xb1d5d564U, 0x9c4e4ed2U, 0x49a9a9e0U,
1615 0xd86c6cb4U, 0xac5656faU, 0xf3f4f407U, 0xcfeaea25U,
1616 0xca6565afU, 0xf47a7a8eU, 0x47aeaee9U, 0x10080818U,
1617 0x6fbabad5U, 0xf0787888U, 0x4a25256fU, 0x5c2e2e72U,
1618 0x381c1c24U, 0x57a6a6f1U, 0x73b4b4c7U, 0x97c6c651U,
1619 0xcbe8e823U, 0xa1dddd7cU, 0xe874749cU, 0x3e1f1f21U,
1620 0x964b4bddU, 0x61bdbddcU, 0x0d8b8b86U, 0x0f8a8a85U,
1621 0xe0707090U, 0x7c3e3e42U, 0x71b5b5c4U, 0xcc6666aaU,
1622 0x904848d8U, 0x06030305U, 0xf7f6f601U, 0x1c0e0e12U,
1623 0xc26161a3U, 0x6a35355fU, 0xae5757f9U, 0x69b9b9d0U,
1624 0x17868691U, 0x99c1c158U, 0x3a1d1d27U, 0x279e9eb9U,
1625 0xd9e1e138U, 0xebf8f813U, 0x2b9898b3U, 0x22111133U,
1626 0xd26969bbU, 0xa9d9d970U, 0x078e8e89U, 0x339494a7U,
1627 0x2d9b9bb6U, 0x3c1e1e22U, 0x15878792U, 0xc9e9e920U,
1628 0x87cece49U, 0xaa5555ffU, 0x50282878U, 0xa5dfdf7aU,
1629 0x038c8c8fU, 0x59a1a1f8U, 0x09898980U, 0x1a0d0d17U,
1630 0x65bfbfdaU, 0xd7e6e631U, 0x844242c6U, 0xd06868b8U,
1631 0x824141c3U, 0x299999b0U, 0x5a2d2d77U, 0x1e0f0f11U,
1632 0x7bb0b0cbU, 0xa85454fcU, 0x6dbbbbd6U, 0x2c16163aU,
1635 const u32 Td0[256] = {
1636 0x51f4a750U, 0x7e416553U, 0x1a17a4c3U, 0x3a275e96U,
1637 0x3bab6bcbU, 0x1f9d45f1U, 0xacfa58abU, 0x4be30393U,
1638 0x2030fa55U, 0xad766df6U, 0x88cc7691U, 0xf5024c25U,
1639 0x4fe5d7fcU, 0xc52acbd7U, 0x26354480U, 0xb562a38fU,
1640 0xdeb15a49U, 0x25ba1b67U, 0x45ea0e98U, 0x5dfec0e1U,
1641 0xc32f7502U, 0x814cf012U, 0x8d4697a3U, 0x6bd3f9c6U,
1642 0x038f5fe7U, 0x15929c95U, 0xbf6d7aebU, 0x955259daU,
1643 0xd4be832dU, 0x587421d3U, 0x49e06929U, 0x8ec9c844U,
1644 0x75c2896aU, 0xf48e7978U, 0x99583e6bU, 0x27b971ddU,
1645 0xbee14fb6U, 0xf088ad17U, 0xc920ac66U, 0x7dce3ab4U,
1646 0x63df4a18U, 0xe51a3182U, 0x97513360U, 0x62537f45U,
1647 0xb16477e0U, 0xbb6bae84U, 0xfe81a01cU, 0xf9082b94U,
1648 0x70486858U, 0x8f45fd19U, 0x94de6c87U, 0x527bf8b7U,
1649 0xab73d323U, 0x724b02e2U, 0xe31f8f57U, 0x6655ab2aU,
1650 0xb2eb2807U, 0x2fb5c203U, 0x86c57b9aU, 0xd33708a5U,
1651 0x302887f2U, 0x23bfa5b2U, 0x02036abaU, 0xed16825cU,
1652 0x8acf1c2bU, 0xa779b492U, 0xf307f2f0U, 0x4e69e2a1U,
1653 0x65daf4cdU, 0x0605bed5U, 0xd134621fU, 0xc4a6fe8aU,
1654 0x342e539dU, 0xa2f355a0U, 0x058ae132U, 0xa4f6eb75U,
1655 0x0b83ec39U, 0x4060efaaU, 0x5e719f06U, 0xbd6e1051U,
1656 0x3e218af9U, 0x96dd063dU, 0xdd3e05aeU, 0x4de6bd46U,
1657 0x91548db5U, 0x71c45d05U, 0x0406d46fU, 0x605015ffU,
1658 0x1998fb24U, 0xd6bde997U, 0x894043ccU, 0x67d99e77U,
1659 0xb0e842bdU, 0x07898b88U, 0xe7195b38U, 0x79c8eedbU,
1660 0xa17c0a47U, 0x7c420fe9U, 0xf8841ec9U, 0x00000000U,
1661 0x09808683U, 0x322bed48U, 0x1e1170acU, 0x6c5a724eU,
1662 0xfd0efffbU, 0x0f853856U, 0x3daed51eU, 0x362d3927U,
1663 0x0a0fd964U, 0x685ca621U, 0x9b5b54d1U, 0x24362e3aU,
1664 0x0c0a67b1U, 0x9357e70fU, 0xb4ee96d2U, 0x1b9b919eU,
1665 0x80c0c54fU, 0x61dc20a2U, 0x5a774b69U, 0x1c121a16U,
1666 0xe293ba0aU, 0xc0a02ae5U, 0x3c22e043U, 0x121b171dU,
1667 0x0e090d0bU, 0xf28bc7adU, 0x2db6a8b9U, 0x141ea9c8U,
1668 0x57f11985U, 0xaf75074cU, 0xee99ddbbU, 0xa37f60fdU,
1669 0xf701269fU, 0x5c72f5bcU, 0x44663bc5U, 0x5bfb7e34U,
1670 0x8b432976U, 0xcb23c6dcU, 0xb6edfc68U, 0xb8e4f163U,
1671 0xd731dccaU, 0x42638510U, 0x13972240U, 0x84c61120U,
1672 0x854a247dU, 0xd2bb3df8U, 0xaef93211U, 0xc729a16dU,
1673 0x1d9e2f4bU, 0xdcb230f3U, 0x0d8652ecU, 0x77c1e3d0U,
1674 0x2bb3166cU, 0xa970b999U, 0x119448faU, 0x47e96422U,
1675 0xa8fc8cc4U, 0xa0f03f1aU, 0x567d2cd8U, 0x223390efU,
1676 0x87494ec7U, 0xd938d1c1U, 0x8ccaa2feU, 0x98d40b36U,
1677 0xa6f581cfU, 0xa57ade28U, 0xdab78e26U, 0x3fadbfa4U,
1678 0x2c3a9de4U, 0x5078920dU, 0x6a5fcc9bU, 0x547e4662U,
1679 0xf68d13c2U, 0x90d8b8e8U, 0x2e39f75eU, 0x82c3aff5U,
1680 0x9f5d80beU, 0x69d0937cU, 0x6fd52da9U, 0xcf2512b3U,
1681 0xc8ac993bU, 0x10187da7U, 0xe89c636eU, 0xdb3bbb7bU,
1682 0xcd267809U, 0x6e5918f4U, 0xec9ab701U, 0x834f9aa8U,
1683 0xe6956e65U, 0xaaffe67eU, 0x21bccf08U, 0xef15e8e6U,
1684 0xbae79bd9U, 0x4a6f36ceU, 0xea9f09d4U, 0x29b07cd6U,
1685 0x31a4b2afU, 0x2a3f2331U, 0xc6a59430U, 0x35a266c0U,
1686 0x744ebc37U, 0xfc82caa6U, 0xe090d0b0U, 0x33a7d815U,
1687 0xf104984aU, 0x41ecdaf7U, 0x7fcd500eU, 0x1791f62fU,
1688 0x764dd68dU, 0x43efb04dU, 0xccaa4d54U, 0xe49604dfU,
1689 0x9ed1b5e3U, 0x4c6a881bU, 0xc12c1fb8U, 0x4665517fU,
1690 0x9d5eea04U, 0x018c355dU, 0xfa877473U, 0xfb0b412eU,
1691 0xb3671d5aU, 0x92dbd252U, 0xe9105633U, 0x6dd64713U,
1692 0x9ad7618cU, 0x37a10c7aU, 0x59f8148eU, 0xeb133c89U,
1693 0xcea927eeU, 0xb761c935U, 0xe11ce5edU, 0x7a47b13cU,
1694 0x9cd2df59U, 0x55f2733fU, 0x1814ce79U, 0x73c737bfU,
1695 0x53f7cdeaU, 0x5ffdaa5bU, 0xdf3d6f14U, 0x7844db86U,
1696 0xcaaff381U, 0xb968c43eU, 0x3824342cU, 0xc2a3405fU,
1697 0x161dc372U, 0xbce2250cU, 0x283c498bU, 0xff0d9541U,
1698 0x39a80171U, 0x080cb3deU, 0xd8b4e49cU, 0x6456c190U,
1699 0x7bcb8461U, 0xd532b670U, 0x486c5c74U, 0xd0b85742U,
1702 const u8 Td4s[256] = {
1703 0x52U, 0x09U, 0x6aU, 0xd5U, 0x30U, 0x36U, 0xa5U, 0x38U,
1704 0xbfU, 0x40U, 0xa3U, 0x9eU, 0x81U, 0xf3U, 0xd7U, 0xfbU,
1705 0x7cU, 0xe3U, 0x39U, 0x82U, 0x9bU, 0x2fU, 0xffU, 0x87U,
1706 0x34U, 0x8eU, 0x43U, 0x44U, 0xc4U, 0xdeU, 0xe9U, 0xcbU,
1707 0x54U, 0x7bU, 0x94U, 0x32U, 0xa6U, 0xc2U, 0x23U, 0x3dU,
1708 0xeeU, 0x4cU, 0x95U, 0x0bU, 0x42U, 0xfaU, 0xc3U, 0x4eU,
1709 0x08U, 0x2eU, 0xa1U, 0x66U, 0x28U, 0xd9U, 0x24U, 0xb2U,
1710 0x76U, 0x5bU, 0xa2U, 0x49U, 0x6dU, 0x8bU, 0xd1U, 0x25U,
1711 0x72U, 0xf8U, 0xf6U, 0x64U, 0x86U, 0x68U, 0x98U, 0x16U,
1712 0xd4U, 0xa4U, 0x5cU, 0xccU, 0x5dU, 0x65U, 0xb6U, 0x92U,
1713 0x6cU, 0x70U, 0x48U, 0x50U, 0xfdU, 0xedU, 0xb9U, 0xdaU,
1714 0x5eU, 0x15U, 0x46U, 0x57U, 0xa7U, 0x8dU, 0x9dU, 0x84U,
1715 0x90U, 0xd8U, 0xabU, 0x00U, 0x8cU, 0xbcU, 0xd3U, 0x0aU,
1716 0xf7U, 0xe4U, 0x58U, 0x05U, 0xb8U, 0xb3U, 0x45U, 0x06U,
1717 0xd0U, 0x2cU, 0x1eU, 0x8fU, 0xcaU, 0x3fU, 0x0fU, 0x02U,
1718 0xc1U, 0xafU, 0xbdU, 0x03U, 0x01U, 0x13U, 0x8aU, 0x6bU,
1719 0x3aU, 0x91U, 0x11U, 0x41U, 0x4fU, 0x67U, 0xdcU, 0xeaU,
1720 0x97U, 0xf2U, 0xcfU, 0xceU, 0xf0U, 0xb4U, 0xe6U, 0x73U,
1721 0x96U, 0xacU, 0x74U, 0x22U, 0xe7U, 0xadU, 0x35U, 0x85U,
1722 0xe2U, 0xf9U, 0x37U, 0xe8U, 0x1cU, 0x75U, 0xdfU, 0x6eU,
1723 0x47U, 0xf1U, 0x1aU, 0x71U, 0x1dU, 0x29U, 0xc5U, 0x89U,
1724 0x6fU, 0xb7U, 0x62U, 0x0eU, 0xaaU, 0x18U, 0xbeU, 0x1bU,
1725 0xfcU, 0x56U, 0x3eU, 0x4bU, 0xc6U, 0xd2U, 0x79U, 0x20U,
1726 0x9aU, 0xdbU, 0xc0U, 0xfeU, 0x78U, 0xcdU, 0x5aU, 0xf4U,
1727 0x1fU, 0xddU, 0xa8U, 0x33U, 0x88U, 0x07U, 0xc7U, 0x31U,
1728 0xb1U, 0x12U, 0x10U, 0x59U, 0x27U, 0x80U, 0xecU, 0x5fU,
1729 0x60U, 0x51U, 0x7fU, 0xa9U, 0x19U, 0xb5U, 0x4aU, 0x0dU,
1730 0x2dU, 0xe5U, 0x7aU, 0x9fU, 0x93U, 0xc9U, 0x9cU, 0xefU,
1731 0xa0U, 0xe0U, 0x3bU, 0x4dU, 0xaeU, 0x2aU, 0xf5U, 0xb0U,
1732 0xc8U, 0xebU, 0xbbU, 0x3cU, 0x83U, 0x53U, 0x99U, 0x61U,
1733 0x17U, 0x2bU, 0x04U, 0x7eU, 0xbaU, 0x77U, 0xd6U, 0x26U,
1734 0xe1U, 0x69U, 0x14U, 0x63U, 0x55U, 0x21U, 0x0cU, 0x7dU,
1736 const u8 rcons[] = {
1737 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x1B, 0x36
1738 /* for 128-bit blocks, Rijndael never uses more than 10 rcon values */
1742 * Expand the cipher key into the encryption key schedule.
1744 * @return the number of rounds for the given cipher key size.
1746 #define ROUND(i, d, s) \
1748 d##0 = TE0(s##0) ^ TE1(s##1) ^ TE2(s##2) ^ TE3(s##3) ^ rk[4 * i]; \
1749 d##1 = TE0(s##1) ^ TE1(s##2) ^ TE2(s##3) ^ TE3(s##0) ^ rk[4 * i + 1]; \
1750 d##2 = TE0(s##2) ^ TE1(s##3) ^ TE2(s##0) ^ TE3(s##1) ^ rk[4 * i + 2]; \
1751 d##3 = TE0(s##3) ^ TE1(s##0) ^ TE2(s##1) ^ TE3(s##2) ^ rk[4 * i + 3]; \
1755 * omac1_aes_128 - One-Key CBC MAC (OMAC1) hash with AES-128 (aka AES-CMAC)
1756 * @key: 128-bit key for the hash operation
1757 * @data: Data buffer for which a MAC is determined
1758 * @data_len: Length of data buffer in bytes
1759 * @mac: Buffer for MAC (128 bits, i.e., 16 bytes)
1760 * Returns: 0 on success, -1 on failure
1762 * This is a mode for using block cipher (AES in this case) for authentication.
1763 * OMAC1 was standardized with the name CMAC by NIST in a Special Publication
1766 void rtw_use_tkipkey_handler(void *FunctionContext)
1768 struct adapter *padapter = (struct adapter *)FunctionContext;
1772 RT_TRACE(_module_rtl871x_security_c_, _drv_err_, ("^^^rtw_use_tkipkey_handler ^^^\n"));
1774 padapter->securitypriv.busetkipkey = true;
1776 RT_TRACE(_module_rtl871x_security_c_, _drv_err_, ("^^^rtw_use_tkipkey_handler padapter->securitypriv.busetkipkey=%d^^^\n", padapter->securitypriv.busetkipkey));