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 ******************************************************************************/
15 #define _RTW_SECURITY_C_
17 #include <drv_types.h>
18 #include <rtw_debug.h>
20 static const char *_security_type_str[] = {
32 const char *security_type_str(u8 value)
35 return _security_type_str[value];
40 #define WEP_SW_ENC_CNT_INC(sec, ra) \
41 if (is_broadcast_mac_addr(ra)) \
42 sec->wep_sw_enc_cnt_bc++; \
43 else if (is_multicast_mac_addr(ra)) \
44 sec->wep_sw_enc_cnt_mc++; \
46 sec->wep_sw_enc_cnt_uc++;
48 #define WEP_SW_DEC_CNT_INC(sec, ra) \
49 if (is_broadcast_mac_addr(ra)) \
50 sec->wep_sw_dec_cnt_bc++; \
51 else if (is_multicast_mac_addr(ra)) \
52 sec->wep_sw_dec_cnt_mc++; \
54 sec->wep_sw_dec_cnt_uc++;
56 #define TKIP_SW_ENC_CNT_INC(sec, ra) \
57 if (is_broadcast_mac_addr(ra)) \
58 sec->tkip_sw_enc_cnt_bc++; \
59 else if (is_multicast_mac_addr(ra)) \
60 sec->tkip_sw_enc_cnt_mc++; \
62 sec->tkip_sw_enc_cnt_uc++;
64 #define TKIP_SW_DEC_CNT_INC(sec, ra) \
65 if (is_broadcast_mac_addr(ra)) \
66 sec->tkip_sw_dec_cnt_bc++; \
67 else if (is_multicast_mac_addr(ra)) \
68 sec->tkip_sw_dec_cnt_mc++; \
70 sec->tkip_sw_dec_cnt_uc++;
72 #define AES_SW_ENC_CNT_INC(sec, ra) \
73 if (is_broadcast_mac_addr(ra)) \
74 sec->aes_sw_enc_cnt_bc++; \
75 else if (is_multicast_mac_addr(ra)) \
76 sec->aes_sw_enc_cnt_mc++; \
78 sec->aes_sw_enc_cnt_uc++;
80 #define AES_SW_DEC_CNT_INC(sec, ra) \
81 if (is_broadcast_mac_addr(ra)) \
82 sec->aes_sw_dec_cnt_bc++; \
83 else if (is_multicast_mac_addr(ra)) \
84 sec->aes_sw_dec_cnt_mc++; \
86 sec->aes_sw_dec_cnt_uc++;
88 #define WEP_SW_ENC_CNT_INC(sec, ra)
89 #define WEP_SW_DEC_CNT_INC(sec, ra)
90 #define TKIP_SW_ENC_CNT_INC(sec, ra)
91 #define TKIP_SW_DEC_CNT_INC(sec, ra)
92 #define AES_SW_ENC_CNT_INC(sec, ra)
93 #define AES_SW_DEC_CNT_INC(sec, ra)
94 #endif /* DBG_SW_SEC_CNT */
96 /* WEP related ===== */
98 #define CRC32_POLY 0x04c11db7
107 static void arcfour_init(struct arc4context *parc4ctx, u8 *key, u32 key_len)
115 state = parc4ctx->state;
118 for (counter = 0; counter < 256; counter++)
119 state[counter] = (u8)counter;
122 for (counter = 0; counter < 256; counter++) {
124 stateindex = (stateindex + key[keyindex] + t) & 0xff;
125 u = state[stateindex];
126 state[stateindex] = (u8)t;
127 state[counter] = (u8)u;
128 if (++keyindex >= key_len)
133 static u32 arcfour_byte(struct arc4context *parc4ctx)
140 state = parc4ctx->state;
141 x = (parc4ctx->x + 1) & 0xff;
143 y = (sx + parc4ctx->y) & 0xff;
149 return state[(sx + sy) & 0xff];
152 static void arcfour_encrypt(
153 struct arc4context *parc4ctx,
161 for (i = 0; i < len; i++)
162 dest[i] = src[i] ^ (unsigned char)arcfour_byte(parc4ctx);
165 static sint bcrc32initialized;
166 static u32 crc32_table[256];
169 static u8 crc32_reverseBit(u8 data)
171 return((u8)((data<<7)&0x80) | ((data<<5)&0x40) | ((data<<3)&0x20) | ((data<<1)&0x10) | ((data>>1)&0x08) | ((data>>3)&0x04) | ((data>>5)&0x02) | ((data>>7)&0x01));
174 static void crc32_init(void)
176 if (bcrc32initialized == 1)
181 u8 *p = (u8 *)&c, *p1;
186 for (i = 0; i < 256; ++i) {
187 k = crc32_reverseBit((u8)i);
188 for (c = ((u32)k) << 24, j = 8; j > 0; --j) {
189 c = c & 0x80000000 ? (c << 1) ^ CRC32_POLY : (c << 1);
191 p1 = (u8 *)&crc32_table[i];
193 p1[0] = crc32_reverseBit(p[3]);
194 p1[1] = crc32_reverseBit(p[2]);
195 p1[2] = crc32_reverseBit(p[1]);
196 p1[3] = crc32_reverseBit(p[0]);
198 bcrc32initialized = 1;
202 static __le32 getcrc32(u8 *buf, sint len)
207 if (bcrc32initialized == 0)
210 crc = 0xffffffff; /* preload shift register, per CRC-32 spec */
212 for (p = buf; len > 0; ++p, --len) {
213 crc = crc32_table[(crc ^ *p) & 0xff] ^ (crc >> 8);
215 return cpu_to_le32(~crc); /* transmit complement, per CRC-32 spec */
220 Need to consider the fragment situation
222 void rtw_wep_encrypt(struct adapter *padapter, u8 *pxmitframe)
225 unsigned char crc[4];
226 struct arc4context mycontext;
228 sint curfragnum, length;
231 u8 *pframe, *payload, *iv; /* wepkey */
233 u8 hw_hdr_offset = 0;
234 struct pkt_attrib *pattrib = &((struct xmit_frame *)pxmitframe)->attrib;
235 struct security_priv *psecuritypriv = &padapter->securitypriv;
236 struct xmit_priv *pxmitpriv = &padapter->xmitpriv;
238 if (((struct xmit_frame *)pxmitframe)->buf_addr == NULL)
241 hw_hdr_offset = TXDESC_OFFSET;
242 pframe = ((struct xmit_frame *)pxmitframe)->buf_addr + hw_hdr_offset;
244 /* start to encrypt each fragment */
245 if ((pattrib->encrypt == _WEP40_) || (pattrib->encrypt == _WEP104_)) {
246 keylength = psecuritypriv->dot11DefKeylen[psecuritypriv->dot11PrivacyKeyIndex];
248 for (curfragnum = 0; curfragnum < pattrib->nr_frags; curfragnum++) {
249 iv = pframe+pattrib->hdrlen;
250 memcpy(&wepkey[0], iv, 3);
251 memcpy(&wepkey[3], &psecuritypriv->dot11DefKey[psecuritypriv->dot11PrivacyKeyIndex].skey[0], keylength);
252 payload = pframe+pattrib->iv_len+pattrib->hdrlen;
254 if ((curfragnum+1) == pattrib->nr_frags) { /* the last fragment */
256 length = pattrib->last_txcmdsz-pattrib->hdrlen-pattrib->iv_len-pattrib->icv_len;
258 *((__le32 *)crc) = getcrc32(payload, length);
260 arcfour_init(&mycontext, wepkey, 3+keylength);
261 arcfour_encrypt(&mycontext, payload, payload, length);
262 arcfour_encrypt(&mycontext, payload+length, crc, 4);
265 length = pxmitpriv->frag_len-pattrib->hdrlen-pattrib->iv_len-pattrib->icv_len;
266 *((__le32 *)crc) = getcrc32(payload, length);
267 arcfour_init(&mycontext, wepkey, 3+keylength);
268 arcfour_encrypt(&mycontext, payload, payload, length);
269 arcfour_encrypt(&mycontext, payload+length, crc, 4);
271 pframe += pxmitpriv->frag_len;
272 pframe = (u8 *)RND4((SIZE_PTR)(pframe));
276 WEP_SW_ENC_CNT_INC(psecuritypriv, pattrib->ra);
280 void rtw_wep_decrypt(struct adapter *padapter, u8 *precvframe)
284 struct arc4context mycontext;
287 u8 *pframe, *payload, *iv, wepkey[16];
289 struct rx_pkt_attrib *prxattrib = &(((union recv_frame *)precvframe)->u.hdr.attrib);
290 struct security_priv *psecuritypriv = &padapter->securitypriv;
292 pframe = (unsigned char *)((union recv_frame *)precvframe)->u.hdr.rx_data;
294 /* start to decrypt recvframe */
295 if ((prxattrib->encrypt == _WEP40_) || (prxattrib->encrypt == _WEP104_)) {
296 iv = pframe+prxattrib->hdrlen;
297 /* keyindex =(iv[3]&0x3); */
298 keyindex = prxattrib->key_index;
299 keylength = psecuritypriv->dot11DefKeylen[keyindex];
300 memcpy(&wepkey[0], iv, 3);
301 /* memcpy(&wepkey[3], &psecuritypriv->dot11DefKey[psecuritypriv->dot11PrivacyKeyIndex].skey[0], keylength); */
302 memcpy(&wepkey[3], &psecuritypriv->dot11DefKey[keyindex].skey[0], keylength);
303 length = ((union recv_frame *)precvframe)->u.hdr.len-prxattrib->hdrlen-prxattrib->iv_len;
305 payload = pframe+prxattrib->iv_len+prxattrib->hdrlen;
307 /* decrypt payload include icv */
308 arcfour_init(&mycontext, wepkey, 3+keylength);
309 arcfour_encrypt(&mycontext, payload, payload, length);
311 /* calculate icv and compare the icv */
312 *((u32 *)crc) = le32_to_cpu(getcrc32(payload, length-4));
314 if (crc[3] != payload[length-1] || crc[2] != payload[length-2] || crc[1] != payload[length-3] || crc[0] != payload[length-4]) {
315 RT_TRACE(_module_rtl871x_security_c_, _drv_err_, ("rtw_wep_decrypt:icv error crc[3](%x)!=payload[length-1](%x) || crc[2](%x)!=payload[length-2](%x) || crc[1](%x)!=payload[length-3](%x) || crc[0](%x)!=payload[length-4](%x)\n",
316 crc[3], payload[length-1], crc[2], payload[length-2], crc[1], payload[length-3], crc[0], payload[length-4]));
319 WEP_SW_DEC_CNT_INC(psecuritypriv, prxattrib->ra);
324 /* 3 =====TKIP related ===== */
326 static u32 secmicgetuint32(u8 *p)
327 /* Convert from Byte[] to Us3232 in a portable way */
332 for (i = 0; i < 4; i++) {
333 res |= ((u32)(*p++)) << (8*i);
339 static void secmicputuint32(u8 *p, u32 val)
340 /* Convert from Us3232 to Byte[] in a portable way */
344 for (i = 0; i < 4; i++) {
345 *p++ = (u8) (val & 0xff);
350 static void secmicclear(struct mic_data *pmicdata)
352 /* Reset the state to the empty message. */
353 pmicdata->L = pmicdata->K0;
354 pmicdata->R = pmicdata->K1;
355 pmicdata->nBytesInM = 0;
359 void rtw_secmicsetkey(struct mic_data *pmicdata, u8 *key)
362 pmicdata->K0 = secmicgetuint32(key);
363 pmicdata->K1 = secmicgetuint32(key + 4);
364 /* and reset the message */
365 secmicclear(pmicdata);
368 void rtw_secmicappendbyte(struct mic_data *pmicdata, u8 b)
370 /* Append the byte to our word-sized buffer */
371 pmicdata->M |= ((unsigned long)b) << (8*pmicdata->nBytesInM);
372 pmicdata->nBytesInM++;
373 /* Process the word if it is full. */
374 if (pmicdata->nBytesInM >= 4) {
375 pmicdata->L ^= pmicdata->M;
376 pmicdata->R ^= ROL32(pmicdata->L, 17);
377 pmicdata->L += pmicdata->R;
378 pmicdata->R ^= ((pmicdata->L & 0xff00ff00) >> 8) | ((pmicdata->L & 0x00ff00ff) << 8);
379 pmicdata->L += pmicdata->R;
380 pmicdata->R ^= ROL32(pmicdata->L, 3);
381 pmicdata->L += pmicdata->R;
382 pmicdata->R ^= ROR32(pmicdata->L, 2);
383 pmicdata->L += pmicdata->R;
384 /* Clear the buffer */
386 pmicdata->nBytesInM = 0;
390 void rtw_secmicappend(struct mic_data *pmicdata, u8 *src, u32 nbytes)
394 rtw_secmicappendbyte(pmicdata, *src++);
399 void rtw_secgetmic(struct mic_data *pmicdata, u8 *dst)
401 /* Append the minimum padding */
402 rtw_secmicappendbyte(pmicdata, 0x5a);
403 rtw_secmicappendbyte(pmicdata, 0);
404 rtw_secmicappendbyte(pmicdata, 0);
405 rtw_secmicappendbyte(pmicdata, 0);
406 rtw_secmicappendbyte(pmicdata, 0);
407 /* and then zeroes until the length is a multiple of 4 */
408 while (pmicdata->nBytesInM != 0) {
409 rtw_secmicappendbyte(pmicdata, 0);
411 /* The appendByte function has already computed the result. */
412 secmicputuint32(dst, pmicdata->L);
413 secmicputuint32(dst+4, pmicdata->R);
414 /* Reset to the empty message. */
415 secmicclear(pmicdata);
419 void rtw_seccalctkipmic(u8 *key, u8 *header, u8 *data, u32 data_len, u8 *mic_code, u8 pri)
422 struct mic_data micdata;
423 u8 priority[4] = {0x0, 0x0, 0x0, 0x0};
425 rtw_secmicsetkey(&micdata, key);
428 /* Michael MIC pseudo header: DA, SA, 3 x 0, Priority */
429 if (header[1]&1) { /* ToDS == 1 */
430 rtw_secmicappend(&micdata, &header[16], 6); /* DA */
431 if (header[1]&2) /* From Ds == 1 */
432 rtw_secmicappend(&micdata, &header[24], 6);
434 rtw_secmicappend(&micdata, &header[10], 6);
435 } else { /* ToDS == 0 */
436 rtw_secmicappend(&micdata, &header[4], 6); /* DA */
437 if (header[1]&2) /* From Ds == 1 */
438 rtw_secmicappend(&micdata, &header[16], 6);
440 rtw_secmicappend(&micdata, &header[10], 6);
443 rtw_secmicappend(&micdata, &priority[0], 4);
446 rtw_secmicappend(&micdata, data, data_len);
448 rtw_secgetmic(&micdata, mic_code);
451 /* macros for extraction/creation of unsigned char/unsigned short values */
452 #define RotR1(v16) ((((v16) >> 1) & 0x7FFF) ^ (((v16) & 1) << 15))
453 #define Lo8(v16) ((u8)((v16) & 0x00FF))
454 #define Hi8(v16) ((u8)(((v16) >> 8) & 0x00FF))
455 #define Lo16(v32) ((u16)((v32) & 0xFFFF))
456 #define Hi16(v32) ((u16)(((v32) >> 16) & 0xFFFF))
457 #define Mk16(hi, lo) ((lo) ^ (((u16)(hi)) << 8))
459 /* select the Nth 16-bit word of the temporal key unsigned char array TK[] */
460 #define TK16(N) Mk16(tk[2*(N)+1], tk[2*(N)])
462 /* S-box lookup: 16 bits --> 16 bits */
463 #define _S_(v16) (Sbox1[0][Lo8(v16)] ^ Sbox1[1][Hi8(v16)])
465 /* fixed algorithm "parameters" */
466 #define PHASE1_LOOP_CNT 8 /* this needs to be "big enough" */
467 #define TA_SIZE 6 /* 48-bit transmitter address */
468 #define TK_SIZE 16 /* 128-bit temporal key */
469 #define P1K_SIZE 10 /* 80-bit Phase1 key */
470 #define RC4_KEY_SIZE 16 /* 128-bit RC4KEY (104 bits unknown) */
473 /* 2-unsigned char by 2-unsigned char subset of the full AES S-box table */
474 static const unsigned short Sbox1[2][256] = { /* Sbox for hash (can be in ROM) */
476 0xC6A5, 0xF884, 0xEE99, 0xF68D, 0xFF0D, 0xD6BD, 0xDEB1, 0x9154,
477 0x6050, 0x0203, 0xCEA9, 0x567D, 0xE719, 0xB562, 0x4DE6, 0xEC9A,
478 0x8F45, 0x1F9D, 0x8940, 0xFA87, 0xEF15, 0xB2EB, 0x8EC9, 0xFB0B,
479 0x41EC, 0xB367, 0x5FFD, 0x45EA, 0x23BF, 0x53F7, 0xE496, 0x9B5B,
480 0x75C2, 0xE11C, 0x3DAE, 0x4C6A, 0x6C5A, 0x7E41, 0xF502, 0x834F,
481 0x685C, 0x51F4, 0xD134, 0xF908, 0xE293, 0xAB73, 0x6253, 0x2A3F,
482 0x080C, 0x9552, 0x4665, 0x9D5E, 0x3028, 0x37A1, 0x0A0F, 0x2FB5,
483 0x0E09, 0x2436, 0x1B9B, 0xDF3D, 0xCD26, 0x4E69, 0x7FCD, 0xEA9F,
484 0x121B, 0x1D9E, 0x5874, 0x342E, 0x362D, 0xDCB2, 0xB4EE, 0x5BFB,
485 0xA4F6, 0x764D, 0xB761, 0x7DCE, 0x527B, 0xDD3E, 0x5E71, 0x1397,
486 0xA6F5, 0xB968, 0x0000, 0xC12C, 0x4060, 0xE31F, 0x79C8, 0xB6ED,
487 0xD4BE, 0x8D46, 0x67D9, 0x724B, 0x94DE, 0x98D4, 0xB0E8, 0x854A,
488 0xBB6B, 0xC52A, 0x4FE5, 0xED16, 0x86C5, 0x9AD7, 0x6655, 0x1194,
489 0x8ACF, 0xE910, 0x0406, 0xFE81, 0xA0F0, 0x7844, 0x25BA, 0x4BE3,
490 0xA2F3, 0x5DFE, 0x80C0, 0x058A, 0x3FAD, 0x21BC, 0x7048, 0xF104,
491 0x63DF, 0x77C1, 0xAF75, 0x4263, 0x2030, 0xE51A, 0xFD0E, 0xBF6D,
492 0x814C, 0x1814, 0x2635, 0xC32F, 0xBEE1, 0x35A2, 0x88CC, 0x2E39,
493 0x9357, 0x55F2, 0xFC82, 0x7A47, 0xC8AC, 0xBAE7, 0x322B, 0xE695,
494 0xC0A0, 0x1998, 0x9ED1, 0xA37F, 0x4466, 0x547E, 0x3BAB, 0x0B83,
495 0x8CCA, 0xC729, 0x6BD3, 0x283C, 0xA779, 0xBCE2, 0x161D, 0xAD76,
496 0xDB3B, 0x6456, 0x744E, 0x141E, 0x92DB, 0x0C0A, 0x486C, 0xB8E4,
497 0x9F5D, 0xBD6E, 0x43EF, 0xC4A6, 0x39A8, 0x31A4, 0xD337, 0xF28B,
498 0xD532, 0x8B43, 0x6E59, 0xDAB7, 0x018C, 0xB164, 0x9CD2, 0x49E0,
499 0xD8B4, 0xACFA, 0xF307, 0xCF25, 0xCAAF, 0xF48E, 0x47E9, 0x1018,
500 0x6FD5, 0xF088, 0x4A6F, 0x5C72, 0x3824, 0x57F1, 0x73C7, 0x9751,
501 0xCB23, 0xA17C, 0xE89C, 0x3E21, 0x96DD, 0x61DC, 0x0D86, 0x0F85,
502 0xE090, 0x7C42, 0x71C4, 0xCCAA, 0x90D8, 0x0605, 0xF701, 0x1C12,
503 0xC2A3, 0x6A5F, 0xAEF9, 0x69D0, 0x1791, 0x9958, 0x3A27, 0x27B9,
504 0xD938, 0xEB13, 0x2BB3, 0x2233, 0xD2BB, 0xA970, 0x0789, 0x33A7,
505 0x2DB6, 0x3C22, 0x1592, 0xC920, 0x8749, 0xAAFF, 0x5078, 0xA57A,
506 0x038F, 0x59F8, 0x0980, 0x1A17, 0x65DA, 0xD731, 0x84C6, 0xD0B8,
507 0x82C3, 0x29B0, 0x5A77, 0x1E11, 0x7BCB, 0xA8FC, 0x6DD6, 0x2C3A,
511 { /* second half of table is unsigned char-reversed version of first! */
512 0xA5C6, 0x84F8, 0x99EE, 0x8DF6, 0x0DFF, 0xBDD6, 0xB1DE, 0x5491,
513 0x5060, 0x0302, 0xA9CE, 0x7D56, 0x19E7, 0x62B5, 0xE64D, 0x9AEC,
514 0x458F, 0x9D1F, 0x4089, 0x87FA, 0x15EF, 0xEBB2, 0xC98E, 0x0BFB,
515 0xEC41, 0x67B3, 0xFD5F, 0xEA45, 0xBF23, 0xF753, 0x96E4, 0x5B9B,
516 0xC275, 0x1CE1, 0xAE3D, 0x6A4C, 0x5A6C, 0x417E, 0x02F5, 0x4F83,
517 0x5C68, 0xF451, 0x34D1, 0x08F9, 0x93E2, 0x73AB, 0x5362, 0x3F2A,
518 0x0C08, 0x5295, 0x6546, 0x5E9D, 0x2830, 0xA137, 0x0F0A, 0xB52F,
519 0x090E, 0x3624, 0x9B1B, 0x3DDF, 0x26CD, 0x694E, 0xCD7F, 0x9FEA,
520 0x1B12, 0x9E1D, 0x7458, 0x2E34, 0x2D36, 0xB2DC, 0xEEB4, 0xFB5B,
521 0xF6A4, 0x4D76, 0x61B7, 0xCE7D, 0x7B52, 0x3EDD, 0x715E, 0x9713,
522 0xF5A6, 0x68B9, 0x0000, 0x2CC1, 0x6040, 0x1FE3, 0xC879, 0xEDB6,
523 0xBED4, 0x468D, 0xD967, 0x4B72, 0xDE94, 0xD498, 0xE8B0, 0x4A85,
524 0x6BBB, 0x2AC5, 0xE54F, 0x16ED, 0xC586, 0xD79A, 0x5566, 0x9411,
525 0xCF8A, 0x10E9, 0x0604, 0x81FE, 0xF0A0, 0x4478, 0xBA25, 0xE34B,
526 0xF3A2, 0xFE5D, 0xC080, 0x8A05, 0xAD3F, 0xBC21, 0x4870, 0x04F1,
527 0xDF63, 0xC177, 0x75AF, 0x6342, 0x3020, 0x1AE5, 0x0EFD, 0x6DBF,
528 0x4C81, 0x1418, 0x3526, 0x2FC3, 0xE1BE, 0xA235, 0xCC88, 0x392E,
529 0x5793, 0xF255, 0x82FC, 0x477A, 0xACC8, 0xE7BA, 0x2B32, 0x95E6,
530 0xA0C0, 0x9819, 0xD19E, 0x7FA3, 0x6644, 0x7E54, 0xAB3B, 0x830B,
531 0xCA8C, 0x29C7, 0xD36B, 0x3C28, 0x79A7, 0xE2BC, 0x1D16, 0x76AD,
532 0x3BDB, 0x5664, 0x4E74, 0x1E14, 0xDB92, 0x0A0C, 0x6C48, 0xE4B8,
533 0x5D9F, 0x6EBD, 0xEF43, 0xA6C4, 0xA839, 0xA431, 0x37D3, 0x8BF2,
534 0x32D5, 0x438B, 0x596E, 0xB7DA, 0x8C01, 0x64B1, 0xD29C, 0xE049,
535 0xB4D8, 0xFAAC, 0x07F3, 0x25CF, 0xAFCA, 0x8EF4, 0xE947, 0x1810,
536 0xD56F, 0x88F0, 0x6F4A, 0x725C, 0x2438, 0xF157, 0xC773, 0x5197,
537 0x23CB, 0x7CA1, 0x9CE8, 0x213E, 0xDD96, 0xDC61, 0x860D, 0x850F,
538 0x90E0, 0x427C, 0xC471, 0xAACC, 0xD890, 0x0506, 0x01F7, 0x121C,
539 0xA3C2, 0x5F6A, 0xF9AE, 0xD069, 0x9117, 0x5899, 0x273A, 0xB927,
540 0x38D9, 0x13EB, 0xB32B, 0x3322, 0xBBD2, 0x70A9, 0x8907, 0xA733,
541 0xB62D, 0x223C, 0x9215, 0x20C9, 0x4987, 0xFFAA, 0x7850, 0x7AA5,
542 0x8F03, 0xF859, 0x8009, 0x171A, 0xDA65, 0x31D7, 0xC684, 0xB8D0,
543 0xC382, 0xB029, 0x775A, 0x111E, 0xCB7B, 0xFCA8, 0xD66D, 0x3A2C,
548 **********************************************************************
549 * Routine: Phase 1 -- generate P1K, given TA, TK, IV32
552 * tk[] = temporal key [128 bits]
553 * ta[] = transmitter's MAC address [ 48 bits]
554 * iv32 = upper 32 bits of IV [ 32 bits]
556 * p1k[] = Phase 1 key [ 80 bits]
559 * This function only needs to be called every 2**16 packets,
560 * although in theory it could be called every packet.
562 **********************************************************************
564 static void phase1(u16 *p1k, const u8 *tk, const u8 *ta, u32 iv32)
568 /* Initialize the 80 bits of P1K[] from IV32 and TA[0..5] */
571 p1k[2] = Mk16(ta[1], ta[0]); /* use TA[] as little-endian */
572 p1k[3] = Mk16(ta[3], ta[2]);
573 p1k[4] = Mk16(ta[5], ta[4]);
575 /* Now compute an unbalanced Feistel cipher with 80-bit block */
576 /* size on the 80-bit block P1K[], using the 128-bit key TK[] */
577 for (i = 0; i < PHASE1_LOOP_CNT; i++) {
578 /* Each add operation here is mod 2**16 */
579 p1k[0] += _S_(p1k[4] ^ TK16((i&1)+0));
580 p1k[1] += _S_(p1k[0] ^ TK16((i&1)+2));
581 p1k[2] += _S_(p1k[1] ^ TK16((i&1)+4));
582 p1k[3] += _S_(p1k[2] ^ TK16((i&1)+6));
583 p1k[4] += _S_(p1k[3] ^ TK16((i&1)+0));
584 p1k[4] += (unsigned short)i; /* avoid "slide attacks" */
590 **********************************************************************
591 * Routine: Phase 2 -- generate RC4KEY, given TK, P1K, IV16
594 * tk[] = Temporal key [128 bits]
595 * p1k[] = Phase 1 output key [ 80 bits]
596 * iv16 = low 16 bits of IV counter [ 16 bits]
598 * rc4key[] = the key used to encrypt the packet [128 bits]
601 * The value {TA, IV32, IV16} for Phase1/Phase2 must be unique
602 * across all packets using the same key TK value. Then, for a
603 * given value of TK[], this TKIP48 construction guarantees that
604 * the final RC4KEY value is unique across all packets.
606 * Suggested implementation optimization: if PPK[] is "overlaid"
607 * appropriately on RC4KEY[], there is no need for the final
608 * for loop below that copies the PPK[] result into RC4KEY[].
610 **********************************************************************
612 static void phase2(u8 *rc4key, const u8 *tk, const u16 *p1k, u16 iv16)
615 u16 PPK[6]; /* temporary key for mixing */
617 /* Note: all adds in the PPK[] equations below are mod 2**16 */
618 for (i = 0; i < 5; i++)
619 PPK[i] = p1k[i]; /* first, copy P1K to PPK */
621 PPK[5] = p1k[4]+iv16; /* next, add in IV16 */
623 /* Bijective non-linear mixing of the 96 bits of PPK[0..5] */
624 PPK[0] += _S_(PPK[5] ^ TK16(0)); /* Mix key in each "round" */
625 PPK[1] += _S_(PPK[0] ^ TK16(1));
626 PPK[2] += _S_(PPK[1] ^ TK16(2));
627 PPK[3] += _S_(PPK[2] ^ TK16(3));
628 PPK[4] += _S_(PPK[3] ^ TK16(4));
629 PPK[5] += _S_(PPK[4] ^ TK16(5)); /* Total # S-box lookups == 6 */
631 /* Final sweep: bijective, "linear". Rotates kill LSB correlations */
632 PPK[0] += RotR1(PPK[5] ^ TK16(6));
633 PPK[1] += RotR1(PPK[0] ^ TK16(7)); /* Use all of TK[] in Phase2 */
634 PPK[2] += RotR1(PPK[1]);
635 PPK[3] += RotR1(PPK[2]);
636 PPK[4] += RotR1(PPK[3]);
637 PPK[5] += RotR1(PPK[4]);
638 /* Note: At this point, for a given key TK[0..15], the 96-bit output */
639 /* value PPK[0..5] is guaranteed to be unique, as a function */
640 /* of the 96-bit "input" value {TA, IV32, IV16}. That is, P1K */
641 /* is now a keyed permutation of {TA, IV32, IV16}. */
643 /* Set RC4KEY[0..3], which includes "cleartext" portion of RC4 key */
644 rc4key[0] = Hi8(iv16); /* RC4KEY[0..2] is the WEP IV */
645 rc4key[1] = (Hi8(iv16) | 0x20) & 0x7F; /* Help avoid weak (FMS) keys */
646 rc4key[2] = Lo8(iv16);
647 rc4key[3] = Lo8((PPK[5] ^ TK16(0)) >> 1);
650 /* Copy 96 bits of PPK[0..5] to RC4KEY[4..15] (little-endian) */
651 for (i = 0; i < 6; i++) {
652 rc4key[4+2*i] = Lo8(PPK[i]);
653 rc4key[5+2*i] = Hi8(PPK[i]);
658 /* The hlen isn't include the IV */
659 u32 rtw_tkip_encrypt(struct adapter *padapter, u8 *pxmitframe)
666 u8 hw_hdr_offset = 0;
667 struct arc4context mycontext;
668 sint curfragnum, length;
671 u8 *pframe, *payload, *iv, *prwskey;
672 union pn48 dot11txpn;
673 /* struct sta_info *stainfo; */
674 struct pkt_attrib *pattrib = &((struct xmit_frame *)pxmitframe)->attrib;
675 struct security_priv *psecuritypriv = &padapter->securitypriv;
676 struct xmit_priv *pxmitpriv = &padapter->xmitpriv;
679 if (((struct xmit_frame *)pxmitframe)->buf_addr == NULL)
682 hw_hdr_offset = TXDESC_OFFSET;
683 pframe = ((struct xmit_frame *)pxmitframe)->buf_addr + hw_hdr_offset;
685 /* 4 start to encrypt each fragment */
686 if (pattrib->encrypt == _TKIP_) {
691 stainfo = pattrib->psta;
695 DBG_871X("%s, call rtw_get_stainfo()\n", __func__);
696 stainfo =rtw_get_stainfo(&padapter->stapriv ,&pattrib->ra[0]);
699 /* if (stainfo!= NULL) */
702 if (!(stainfo->state &_FW_LINKED))
704 DBG_871X("%s, psta->state(0x%x) != _FW_LINKED\n", __func__, stainfo->state);
708 RT_TRACE(_module_rtl871x_security_c_, _drv_err_, ("rtw_tkip_encrypt: stainfo!= NULL!!!\n"));
710 if (IS_MCAST(pattrib->ra))
711 prwskey = psecuritypriv->dot118021XGrpKey[psecuritypriv->dot118021XGrpKeyid].skey;
713 /* prwskey =&stainfo->dot118021x_UncstKey.skey[0]; */
714 prwskey = pattrib->dot118021x_UncstKey.skey;
718 for (curfragnum = 0; curfragnum < pattrib->nr_frags; curfragnum++) {
719 iv = pframe+pattrib->hdrlen;
720 payload = pframe+pattrib->iv_len+pattrib->hdrlen;
722 GET_TKIP_PN(iv, dot11txpn);
724 pnl = (u16)(dot11txpn.val);
725 pnh = (u32)(dot11txpn.val>>16);
727 phase1((u16 *)&ttkey[0], prwskey, &pattrib->ta[0], pnh);
729 phase2(&rc4key[0], prwskey, (u16 *)&ttkey[0], pnl);
731 if ((curfragnum+1) == pattrib->nr_frags) { /* 4 the last fragment */
732 length = pattrib->last_txcmdsz-pattrib->hdrlen-pattrib->iv_len-pattrib->icv_len;
733 RT_TRACE(_module_rtl871x_security_c_, _drv_info_, ("pattrib->iv_len =%x, pattrib->icv_len =%x\n", pattrib->iv_len, pattrib->icv_len));
734 *((__le32 *)crc) = getcrc32(payload, length);/* modified by Amy*/
736 arcfour_init(&mycontext, rc4key, 16);
737 arcfour_encrypt(&mycontext, payload, payload, length);
738 arcfour_encrypt(&mycontext, payload+length, crc, 4);
741 length = pxmitpriv->frag_len-pattrib->hdrlen-pattrib->iv_len-pattrib->icv_len;
742 *((__le32 *)crc) = getcrc32(payload, length);/* modified by Amy*/
743 arcfour_init(&mycontext, rc4key, 16);
744 arcfour_encrypt(&mycontext, payload, payload, length);
745 arcfour_encrypt(&mycontext, payload+length, crc, 4);
747 pframe += pxmitpriv->frag_len;
748 pframe = (u8 *)RND4((SIZE_PTR)(pframe));
752 TKIP_SW_ENC_CNT_INC(psecuritypriv, pattrib->ra);
756 RT_TRACE(_module_rtl871x_security_c_, _drv_err_, ("rtw_tkip_encrypt: stainfo == NULL!!!\n"));
757 DBG_871X("%s, psta ==NUL\n", __func__);
767 /* The hlen isn't include the IV */
768 u32 rtw_tkip_decrypt(struct adapter *padapter, u8 *precvframe)
775 struct arc4context mycontext;
779 u8 *pframe, *payload, *iv, *prwskey;
780 union pn48 dot11txpn;
781 struct sta_info *stainfo;
782 struct rx_pkt_attrib *prxattrib = &((union recv_frame *)precvframe)->u.hdr.attrib;
783 struct security_priv *psecuritypriv = &padapter->securitypriv;
784 /* struct recv_priv *precvpriv =&padapter->recvpriv; */
787 pframe = (unsigned char *)((union recv_frame *)precvframe)->u.hdr.rx_data;
789 /* 4 start to decrypt recvframe */
790 if (prxattrib->encrypt == _TKIP_) {
791 stainfo = rtw_get_stainfo(&padapter->stapriv, &prxattrib->ta[0]);
792 if (stainfo != NULL) {
793 if (IS_MCAST(prxattrib->ra)) {
794 static unsigned long start;
795 static u32 no_gkey_bc_cnt;
796 static u32 no_gkey_mc_cnt;
798 if (psecuritypriv->binstallGrpkey == false) {
804 if (is_broadcast_mac_addr(prxattrib->ra))
809 if (jiffies_to_msecs(jiffies - start) > 1000) {
810 if (no_gkey_bc_cnt || no_gkey_mc_cnt) {
811 DBG_871X_LEVEL(_drv_always_, FUNC_ADPT_FMT" no_gkey_bc_cnt:%u, no_gkey_mc_cnt:%u\n",
812 FUNC_ADPT_ARG(padapter), no_gkey_bc_cnt, no_gkey_mc_cnt);
821 if (no_gkey_bc_cnt || no_gkey_mc_cnt) {
822 DBG_871X_LEVEL(_drv_always_, FUNC_ADPT_FMT" gkey installed. no_gkey_bc_cnt:%u, no_gkey_mc_cnt:%u\n",
823 FUNC_ADPT_ARG(padapter), no_gkey_bc_cnt, no_gkey_mc_cnt);
829 /* DBG_871X("rx bc/mc packets, to perform sw rtw_tkip_decrypt\n"); */
830 /* prwskey = psecuritypriv->dot118021XGrpKey[psecuritypriv->dot118021XGrpKeyid].skey; */
831 prwskey = psecuritypriv->dot118021XGrpKey[prxattrib->key_index].skey;
834 prwskey = &stainfo->dot118021x_UncstKey.skey[0];
838 iv = pframe+prxattrib->hdrlen;
839 payload = pframe+prxattrib->iv_len+prxattrib->hdrlen;
840 length = ((union recv_frame *)precvframe)->u.hdr.len-prxattrib->hdrlen-prxattrib->iv_len;
842 GET_TKIP_PN(iv, dot11txpn);
844 pnl = (u16)(dot11txpn.val);
845 pnh = (u32)(dot11txpn.val>>16);
847 phase1((u16 *)&ttkey[0], prwskey, &prxattrib->ta[0], pnh);
848 phase2(&rc4key[0], prwskey, (unsigned short *)&ttkey[0], pnl);
850 /* 4 decrypt payload include icv */
852 arcfour_init(&mycontext, rc4key, 16);
853 arcfour_encrypt(&mycontext, payload, payload, length);
855 *((u32 *)crc) = le32_to_cpu(getcrc32(payload, length-4));
857 if (crc[3] != payload[length-1] || crc[2] != payload[length-2] || crc[1] != payload[length-3] || crc[0] != payload[length-4]) {
858 RT_TRACE(_module_rtl871x_security_c_, _drv_err_,
859 ("rtw_wep_decrypt:icv error crc[3](%x)!=payload[length-1](%x) || crc[2](%x)!=payload[length-2](%x) || crc[1](%x)!=payload[length-3](%x) || crc[0](%x)!=payload[length-4](%x)\n",
860 crc[3], payload[length-1], crc[2], payload[length-2], crc[1], payload[length-3], crc[0], payload[length-4]));
864 TKIP_SW_DEC_CNT_INC(psecuritypriv, prxattrib->ra);
866 RT_TRACE(_module_rtl871x_security_c_, _drv_err_, ("rtw_tkip_decrypt: stainfo == NULL!!!\n"));
877 /* 3 =====AES related ===== */
881 #define MAX_MSG_SIZE 2048
882 /*****************************/
883 /******** SBOX Table *********/
884 /*****************************/
886 static u8 sbox_table[256] = {
887 0x63, 0x7c, 0x77, 0x7b, 0xf2, 0x6b, 0x6f, 0xc5,
888 0x30, 0x01, 0x67, 0x2b, 0xfe, 0xd7, 0xab, 0x76,
889 0xca, 0x82, 0xc9, 0x7d, 0xfa, 0x59, 0x47, 0xf0,
890 0xad, 0xd4, 0xa2, 0xaf, 0x9c, 0xa4, 0x72, 0xc0,
891 0xb7, 0xfd, 0x93, 0x26, 0x36, 0x3f, 0xf7, 0xcc,
892 0x34, 0xa5, 0xe5, 0xf1, 0x71, 0xd8, 0x31, 0x15,
893 0x04, 0xc7, 0x23, 0xc3, 0x18, 0x96, 0x05, 0x9a,
894 0x07, 0x12, 0x80, 0xe2, 0xeb, 0x27, 0xb2, 0x75,
895 0x09, 0x83, 0x2c, 0x1a, 0x1b, 0x6e, 0x5a, 0xa0,
896 0x52, 0x3b, 0xd6, 0xb3, 0x29, 0xe3, 0x2f, 0x84,
897 0x53, 0xd1, 0x00, 0xed, 0x20, 0xfc, 0xb1, 0x5b,
898 0x6a, 0xcb, 0xbe, 0x39, 0x4a, 0x4c, 0x58, 0xcf,
899 0xd0, 0xef, 0xaa, 0xfb, 0x43, 0x4d, 0x33, 0x85,
900 0x45, 0xf9, 0x02, 0x7f, 0x50, 0x3c, 0x9f, 0xa8,
901 0x51, 0xa3, 0x40, 0x8f, 0x92, 0x9d, 0x38, 0xf5,
902 0xbc, 0xb6, 0xda, 0x21, 0x10, 0xff, 0xf3, 0xd2,
903 0xcd, 0x0c, 0x13, 0xec, 0x5f, 0x97, 0x44, 0x17,
904 0xc4, 0xa7, 0x7e, 0x3d, 0x64, 0x5d, 0x19, 0x73,
905 0x60, 0x81, 0x4f, 0xdc, 0x22, 0x2a, 0x90, 0x88,
906 0x46, 0xee, 0xb8, 0x14, 0xde, 0x5e, 0x0b, 0xdb,
907 0xe0, 0x32, 0x3a, 0x0a, 0x49, 0x06, 0x24, 0x5c,
908 0xc2, 0xd3, 0xac, 0x62, 0x91, 0x95, 0xe4, 0x79,
909 0xe7, 0xc8, 0x37, 0x6d, 0x8d, 0xd5, 0x4e, 0xa9,
910 0x6c, 0x56, 0xf4, 0xea, 0x65, 0x7a, 0xae, 0x08,
911 0xba, 0x78, 0x25, 0x2e, 0x1c, 0xa6, 0xb4, 0xc6,
912 0xe8, 0xdd, 0x74, 0x1f, 0x4b, 0xbd, 0x8b, 0x8a,
913 0x70, 0x3e, 0xb5, 0x66, 0x48, 0x03, 0xf6, 0x0e,
914 0x61, 0x35, 0x57, 0xb9, 0x86, 0xc1, 0x1d, 0x9e,
915 0xe1, 0xf8, 0x98, 0x11, 0x69, 0xd9, 0x8e, 0x94,
916 0x9b, 0x1e, 0x87, 0xe9, 0xce, 0x55, 0x28, 0xdf,
917 0x8c, 0xa1, 0x89, 0x0d, 0xbf, 0xe6, 0x42, 0x68,
918 0x41, 0x99, 0x2d, 0x0f, 0xb0, 0x54, 0xbb, 0x16
921 /*****************************/
922 /**** Function Prototypes ****/
923 /*****************************/
925 static void bitwise_xor(u8 *ina, u8 *inb, u8 *out);
926 static void construct_mic_iv(
934 );/* add for CONFIG_IEEE80211W, none 11w also can use */
935 static void construct_mic_header1(
940 );/* add for CONFIG_IEEE80211W, none 11w also can use */
941 static void construct_mic_header2(
947 static void construct_ctr_preload(
955 );/* add for CONFIG_IEEE80211W, none 11w also can use */
956 static void xor_128(u8 *a, u8 *b, u8 *out);
957 static void xor_32(u8 *a, u8 *b, u8 *out);
958 static u8 sbox(u8 a);
959 static void next_key(u8 *key, sint round);
960 static void byte_sub(u8 *in, u8 *out);
961 static void shift_row(u8 *in, u8 *out);
962 static void mix_column(u8 *in, u8 *out);
963 static void aes128k128d(u8 *key, u8 *data, u8 *ciphertext);
966 /****************************************/
968 /* Performs a 128 bit AES encrypt with */
970 /****************************************/
971 static void xor_128(u8 *a, u8 *b, u8 *out)
975 for (i = 0; i < 16; i++) {
976 out[i] = a[i] ^ b[i];
981 static void xor_32(u8 *a, u8 *b, u8 *out)
985 for (i = 0; i < 4; i++) {
986 out[i] = a[i] ^ b[i];
993 return sbox_table[(sint)a];
997 static void next_key(u8 *key, sint round)
1001 u8 rcon_table[12] = {
1002 0x01, 0x02, 0x04, 0x08,
1003 0x10, 0x20, 0x40, 0x80,
1004 0x1b, 0x36, 0x36, 0x36
1006 sbox_key[0] = sbox(key[13]);
1007 sbox_key[1] = sbox(key[14]);
1008 sbox_key[2] = sbox(key[15]);
1009 sbox_key[3] = sbox(key[12]);
1011 rcon = rcon_table[round];
1013 xor_32(&key[0], sbox_key, &key[0]);
1014 key[0] = key[0] ^ rcon;
1016 xor_32(&key[4], &key[0], &key[4]);
1017 xor_32(&key[8], &key[4], &key[8]);
1018 xor_32(&key[12], &key[8], &key[12]);
1022 static void byte_sub(u8 *in, u8 *out)
1026 for (i = 0; i < 16; i++) {
1027 out[i] = sbox(in[i]);
1032 static void shift_row(u8 *in, u8 *out)
1053 static void mix_column(u8 *in, u8 *out)
1065 for (i = 0; i < 4; i++) {
1066 if ((in[i] & 0x80) == 0x80)
1072 swap_halfs[0] = in[2]; /* Swap halfs */
1073 swap_halfs[1] = in[3];
1074 swap_halfs[2] = in[0];
1075 swap_halfs[3] = in[1];
1077 rotl[0] = in[3]; /* Rotate left 8 bits */
1082 andf7[0] = in[0] & 0x7f;
1083 andf7[1] = in[1] & 0x7f;
1084 andf7[2] = in[2] & 0x7f;
1085 andf7[3] = in[3] & 0x7f;
1087 for (i = 3; i > 0; i--) { /* logical shift left 1 bit */
1088 andf7[i] = andf7[i] << 1;
1089 if ((andf7[i-1] & 0x80) == 0x80)
1090 andf7[i] = (andf7[i] | 0x01);
1092 andf7[0] = andf7[0] << 1;
1093 andf7[0] = andf7[0] & 0xfe;
1095 xor_32(add1b, andf7, add1bf7);
1097 xor_32(in, add1bf7, rotr);
1099 temp[0] = rotr[0]; /* Rotate right 8 bits */
1105 xor_32(add1bf7, rotr, temp);
1106 xor_32(swap_halfs, rotl, tempb);
1107 xor_32(temp, tempb, out);
1110 static void aes128k128d(u8 *key, u8 *data, u8 *ciphertext)
1114 u8 intermediatea[16];
1115 u8 intermediateb[16];
1118 for (i = 0; i < 16; i++)
1119 round_key[i] = key[i];
1121 for (round = 0; round < 11; round++) {
1123 xor_128(round_key, data, ciphertext);
1124 next_key(round_key, round);
1125 } else if (round == 10) {
1126 byte_sub(ciphertext, intermediatea);
1127 shift_row(intermediatea, intermediateb);
1128 xor_128(intermediateb, round_key, ciphertext);
1130 byte_sub(ciphertext, intermediatea);
1131 shift_row(intermediatea, intermediateb);
1132 mix_column(&intermediateb[0], &intermediatea[0]);
1133 mix_column(&intermediateb[4], &intermediatea[4]);
1134 mix_column(&intermediateb[8], &intermediatea[8]);
1135 mix_column(&intermediateb[12], &intermediatea[12]);
1136 xor_128(intermediatea, round_key, ciphertext);
1137 next_key(round_key, round);
1143 /************************************************/
1144 /* construct_mic_iv() */
1145 /* Builds the MIC IV from header fields and PN */
1146 /* Baron think the function is construct CCM */
1148 /************************************************/
1149 static void construct_mic_iv(
1154 uint payload_length,
1156 uint frtype/* add for CONFIG_IEEE80211W, none 11w also can use */
1163 if (qc_exists && a4_exists)
1164 mic_iv[1] = mpdu[30] & 0x0f; /* QoS_TC */
1166 if (qc_exists && !a4_exists)
1167 mic_iv[1] = mpdu[24] & 0x0f; /* mute bits 7-4 */
1172 /* 802.11w management frame should set management bit(4) */
1173 if (frtype == WIFI_MGT_TYPE)
1174 mic_iv[1] |= BIT(4);
1176 for (i = 2; i < 8; i++)
1177 mic_iv[i] = mpdu[i + 8]; /* mic_iv[2:7] = A2[0:5] = mpdu[10:15] */
1178 #ifdef CONSISTENT_PN_ORDER
1179 for (i = 8; i < 14; i++)
1180 mic_iv[i] = pn_vector[i - 8]; /* mic_iv[8:13] = PN[0:5] */
1182 for (i = 8; i < 14; i++)
1183 mic_iv[i] = pn_vector[13 - i]; /* mic_iv[8:13] = PN[5:0] */
1185 mic_iv[14] = (unsigned char) (payload_length / 256);
1186 mic_iv[15] = (unsigned char) (payload_length % 256);
1190 /************************************************/
1191 /* construct_mic_header1() */
1192 /* Builds the first MIC header block from */
1193 /* header fields. */
1194 /* Build AAD SC, A1, A2 */
1195 /************************************************/
1196 static void construct_mic_header1(
1200 uint frtype/* add for CONFIG_IEEE80211W, none 11w also can use */
1203 mic_header1[0] = (u8)((header_length - 2) / 256);
1204 mic_header1[1] = (u8)((header_length - 2) % 256);
1206 /* 802.11w management frame don't AND subtype bits 4, 5, 6 of frame control field */
1207 if (frtype == WIFI_MGT_TYPE)
1208 mic_header1[2] = mpdu[0];
1210 mic_header1[2] = mpdu[0] & 0xcf; /* Mute CF poll & CF ack bits */
1212 mic_header1[3] = mpdu[1] & 0xc7; /* Mute retry, more data and pwr mgt bits */
1213 mic_header1[4] = mpdu[4]; /* A1 */
1214 mic_header1[5] = mpdu[5];
1215 mic_header1[6] = mpdu[6];
1216 mic_header1[7] = mpdu[7];
1217 mic_header1[8] = mpdu[8];
1218 mic_header1[9] = mpdu[9];
1219 mic_header1[10] = mpdu[10]; /* A2 */
1220 mic_header1[11] = mpdu[11];
1221 mic_header1[12] = mpdu[12];
1222 mic_header1[13] = mpdu[13];
1223 mic_header1[14] = mpdu[14];
1224 mic_header1[15] = mpdu[15];
1228 /************************************************/
1229 /* construct_mic_header2() */
1230 /* Builds the last MIC header block from */
1231 /* header fields. */
1232 /************************************************/
1233 static void construct_mic_header2(
1242 for (i = 0; i < 16; i++)
1243 mic_header2[i] = 0x00;
1245 mic_header2[0] = mpdu[16]; /* A3 */
1246 mic_header2[1] = mpdu[17];
1247 mic_header2[2] = mpdu[18];
1248 mic_header2[3] = mpdu[19];
1249 mic_header2[4] = mpdu[20];
1250 mic_header2[5] = mpdu[21];
1252 mic_header2[6] = 0x00;
1253 mic_header2[7] = 0x00; /* mpdu[23]; */
1256 if (!qc_exists && a4_exists) {
1257 for (i = 0; i < 6; i++)
1258 mic_header2[8+i] = mpdu[24+i]; /* A4 */
1262 if (qc_exists && !a4_exists) {
1263 mic_header2[8] = mpdu[24] & 0x0f; /* mute bits 15 - 4 */
1264 mic_header2[9] = mpdu[25] & 0x00;
1267 if (qc_exists && a4_exists) {
1268 for (i = 0; i < 6; i++)
1269 mic_header2[8+i] = mpdu[24+i]; /* A4 */
1271 mic_header2[14] = mpdu[30] & 0x0f;
1272 mic_header2[15] = mpdu[31] & 0x00;
1277 /************************************************/
1278 /* construct_mic_header2() */
1279 /* Builds the last MIC header block from */
1280 /* header fields. */
1281 /* Baron think the function is construct CCM */
1283 /************************************************/
1284 static void construct_ctr_preload(
1291 uint frtype /* add for CONFIG_IEEE80211W, none 11w also can use */
1296 for (i = 0; i < 16; i++)
1297 ctr_preload[i] = 0x00;
1300 ctr_preload[0] = 0x01; /* flag */
1301 if (qc_exists && a4_exists)
1302 ctr_preload[1] = mpdu[30] & 0x0f; /* QoC_Control */
1303 if (qc_exists && !a4_exists)
1304 ctr_preload[1] = mpdu[24] & 0x0f;
1306 /* 802.11w management frame should set management bit(4) */
1307 if (frtype == WIFI_MGT_TYPE)
1308 ctr_preload[1] |= BIT(4);
1310 for (i = 2; i < 8; i++)
1311 ctr_preload[i] = mpdu[i + 8]; /* ctr_preload[2:7] = A2[0:5] = mpdu[10:15] */
1312 #ifdef CONSISTENT_PN_ORDER
1313 for (i = 8; i < 14; i++)
1314 ctr_preload[i] = pn_vector[i - 8]; /* ctr_preload[8:13] = PN[0:5] */
1316 for (i = 8; i < 14; i++)
1317 ctr_preload[i] = pn_vector[13 - i]; /* ctr_preload[8:13] = PN[5:0] */
1319 ctr_preload[14] = (unsigned char) (c / 256); /* Ctr */
1320 ctr_preload[15] = (unsigned char) (c % 256);
1324 /************************************/
1326 /* A 128 bit, bitwise exclusive or */
1327 /************************************/
1328 static void bitwise_xor(u8 *ina, u8 *inb, u8 *out)
1332 for (i = 0; i < 16; i++) {
1333 out[i] = ina[i] ^ inb[i];
1338 static sint aes_cipher(u8 *key, uint hdrlen,
1339 u8 *pframe, uint plen)
1341 uint qc_exists, a4_exists, i, j, payload_remainder,
1342 num_blocks, payload_index;
1350 /* Intermediate Buffers */
1351 u8 chain_buffer[16];
1353 u8 padded_buffer[16];
1355 uint frtype = GetFrameType(pframe);
1356 uint frsubtype = GetFrameSubType(pframe);
1358 frsubtype = frsubtype>>4;
1361 memset((void *)mic_iv, 0, 16);
1362 memset((void *)mic_header1, 0, 16);
1363 memset((void *)mic_header2, 0, 16);
1364 memset((void *)ctr_preload, 0, 16);
1365 memset((void *)chain_buffer, 0, 16);
1366 memset((void *)aes_out, 0, 16);
1367 memset((void *)padded_buffer, 0, 16);
1369 if ((hdrlen == WLAN_HDR_A3_LEN) || (hdrlen == WLAN_HDR_A3_QOS_LEN))
1374 if (((frtype|frsubtype) == WIFI_DATA_CFACK) ||
1375 ((frtype|frsubtype) == WIFI_DATA_CFPOLL) ||
1376 ((frtype|frsubtype) == WIFI_DATA_CFACKPOLL)) {
1378 if (hdrlen != WLAN_HDR_A3_QOS_LEN)
1381 } else if ((frtype == WIFI_DATA) && /* add for CONFIG_IEEE80211W, none 11w also can use */
1382 ((frsubtype == 0x08) ||
1383 (frsubtype == 0x09) ||
1384 (frsubtype == 0x0a) ||
1385 (frsubtype == 0x0b))) {
1386 if (hdrlen != WLAN_HDR_A3_QOS_LEN)
1393 pn_vector[0] = pframe[hdrlen];
1394 pn_vector[1] = pframe[hdrlen+1];
1395 pn_vector[2] = pframe[hdrlen+4];
1396 pn_vector[3] = pframe[hdrlen+5];
1397 pn_vector[4] = pframe[hdrlen+6];
1398 pn_vector[5] = pframe[hdrlen+7];
1404 pframe, /* message, */
1407 frtype /* add for CONFIG_IEEE80211W, none 11w also can use */
1410 construct_mic_header1(
1413 pframe, /* message */
1414 frtype /* add for CONFIG_IEEE80211W, none 11w also can use */
1416 construct_mic_header2(
1418 pframe, /* message, */
1424 payload_remainder = plen % 16;
1425 num_blocks = plen / 16;
1427 /* Find start of payload */
1428 payload_index = (hdrlen + 8);
1431 aes128k128d(key, mic_iv, aes_out);
1432 bitwise_xor(aes_out, mic_header1, chain_buffer);
1433 aes128k128d(key, chain_buffer, aes_out);
1434 bitwise_xor(aes_out, mic_header2, chain_buffer);
1435 aes128k128d(key, chain_buffer, aes_out);
1437 for (i = 0; i < num_blocks; i++) {
1438 bitwise_xor(aes_out, &pframe[payload_index], chain_buffer);/* bitwise_xor(aes_out, &message[payload_index], chain_buffer); */
1440 payload_index += 16;
1441 aes128k128d(key, chain_buffer, aes_out);
1444 /* Add on the final payload block if it needs padding */
1445 if (payload_remainder > 0) {
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++];/* padded_buffer[j] = message[payload_index++]; */
1451 bitwise_xor(aes_out, padded_buffer, chain_buffer);
1452 aes128k128d(key, chain_buffer, aes_out);
1456 for (j = 0 ; j < 8; j++)
1457 mic[j] = aes_out[j];
1459 /* Insert MIC into payload */
1460 for (j = 0; j < 8; j++)
1461 pframe[payload_index+j] = mic[j]; /* message[payload_index+j] = mic[j]; */
1463 payload_index = hdrlen + 8;
1464 for (i = 0; i < num_blocks; i++) {
1465 construct_ctr_preload(
1469 pframe, /* message, */
1473 ); /* add for CONFIG_IEEE80211W, none 11w also can use */
1474 aes128k128d(key, ctr_preload, aes_out);
1475 bitwise_xor(aes_out, &pframe[payload_index], chain_buffer);/* bitwise_xor(aes_out, &message[payload_index], chain_buffer); */
1476 for (j = 0; j < 16; j++)
1477 pframe[payload_index++] = chain_buffer[j];/* for (j = 0; j<16;j++) message[payload_index++] = chain_buffer[j]; */
1480 if (payload_remainder > 0) {
1481 /* If there is a short final block, then pad it,*/
1482 /* encrypt it and copy the unpadded part back */
1483 construct_ctr_preload(
1487 pframe, /* message, */
1491 ); /* add for CONFIG_IEEE80211W, none 11w also can use */
1493 for (j = 0; j < 16; j++)
1494 padded_buffer[j] = 0x00;
1495 for (j = 0; j < payload_remainder; j++)
1496 padded_buffer[j] = pframe[payload_index+j];/* padded_buffer[j] = message[payload_index+j]; */
1498 aes128k128d(key, ctr_preload, aes_out);
1499 bitwise_xor(aes_out, padded_buffer, chain_buffer);
1500 for (j = 0; j < payload_remainder; j++)
1501 pframe[payload_index++] = chain_buffer[j];/* for (j = 0; j<payload_remainder;j++) message[payload_index++] = chain_buffer[j]; */
1504 /* Encrypt the MIC */
1505 construct_ctr_preload(
1509 pframe, /* message, */
1513 ); /* add for CONFIG_IEEE80211W, none 11w also can use */
1515 for (j = 0; j < 16; j++)
1516 padded_buffer[j] = 0x00;
1517 for (j = 0; j < 8; j++)
1518 padded_buffer[j] = pframe[j+hdrlen+8+plen];/* padded_buffer[j] = message[j+hdrlen+8+plen]; */
1520 aes128k128d(key, ctr_preload, aes_out);
1521 bitwise_xor(aes_out, padded_buffer, chain_buffer);
1522 for (j = 0; j < 8; j++)
1523 pframe[payload_index++] = chain_buffer[j];/* for (j = 0; j<8;j++) message[payload_index++] = chain_buffer[j]; */
1528 u32 rtw_aes_encrypt(struct adapter *padapter, u8 *pxmitframe)
1533 /* unsigned char message[MAX_MSG_SIZE]; */
1535 /* Intermediate Buffers */
1536 sint curfragnum, length;
1538 u8 *pframe, *prwskey; /* *payload,*iv */
1539 u8 hw_hdr_offset = 0;
1540 /* struct sta_info *stainfo = NULL; */
1541 struct pkt_attrib *pattrib = &((struct xmit_frame *)pxmitframe)->attrib;
1542 struct security_priv *psecuritypriv = &padapter->securitypriv;
1543 struct xmit_priv *pxmitpriv = &padapter->xmitpriv;
1545 /* uint offset = 0; */
1548 if (((struct xmit_frame *)pxmitframe)->buf_addr == NULL)
1551 hw_hdr_offset = TXDESC_OFFSET;
1552 pframe = ((struct xmit_frame *)pxmitframe)->buf_addr + hw_hdr_offset;
1554 /* 4 start to encrypt each fragment */
1555 if ((pattrib->encrypt == _AES_)) {
1556 RT_TRACE(_module_rtl871x_security_c_, _drv_err_, ("rtw_aes_encrypt: stainfo!= NULL!!!\n"));
1558 if (IS_MCAST(pattrib->ra))
1559 prwskey = psecuritypriv->dot118021XGrpKey[psecuritypriv->dot118021XGrpKeyid].skey;
1561 /* prwskey =&stainfo->dot118021x_UncstKey.skey[0]; */
1562 prwskey = pattrib->dot118021x_UncstKey.skey;
1566 for (curfragnum = 0; curfragnum < pattrib->nr_frags; curfragnum++) {
1567 if ((curfragnum+1) == pattrib->nr_frags) { /* 4 the last fragment */
1568 length = pattrib->last_txcmdsz-pattrib->hdrlen-pattrib->iv_len-pattrib->icv_len;
1570 aes_cipher(prwskey, pattrib->hdrlen, pframe, length);
1572 length = pxmitpriv->frag_len-pattrib->hdrlen-pattrib->iv_len-pattrib->icv_len;
1574 aes_cipher(prwskey, pattrib->hdrlen, pframe, length);
1575 pframe += pxmitpriv->frag_len;
1576 pframe = (u8 *)RND4((SIZE_PTR)(pframe));
1580 AES_SW_ENC_CNT_INC(psecuritypriv, pattrib->ra);
1585 static sint aes_decipher(u8 *key, uint hdrlen,
1586 u8 *pframe, uint plen)
1588 static u8 message[MAX_MSG_SIZE];
1589 uint qc_exists, a4_exists, i, j, payload_remainder,
1590 num_blocks, payload_index;
1591 sint res = _SUCCESS;
1598 /* Intermediate Buffers */
1599 u8 chain_buffer[16];
1601 u8 padded_buffer[16];
1605 /* uint offset = 0; */
1606 uint frtype = GetFrameType(pframe);
1607 uint frsubtype = GetFrameSubType(pframe);
1609 frsubtype = frsubtype>>4;
1612 memset((void *)mic_iv, 0, 16);
1613 memset((void *)mic_header1, 0, 16);
1614 memset((void *)mic_header2, 0, 16);
1615 memset((void *)ctr_preload, 0, 16);
1616 memset((void *)chain_buffer, 0, 16);
1617 memset((void *)aes_out, 0, 16);
1618 memset((void *)padded_buffer, 0, 16);
1620 /* start to decrypt the payload */
1622 num_blocks = (plen-8) / 16; /* plen including LLC, payload_length and mic) */
1624 payload_remainder = (plen-8) % 16;
1626 pn_vector[0] = pframe[hdrlen];
1627 pn_vector[1] = pframe[hdrlen+1];
1628 pn_vector[2] = pframe[hdrlen+4];
1629 pn_vector[3] = pframe[hdrlen+5];
1630 pn_vector[4] = pframe[hdrlen+6];
1631 pn_vector[5] = pframe[hdrlen+7];
1633 if ((hdrlen == WLAN_HDR_A3_LEN) || (hdrlen == WLAN_HDR_A3_QOS_LEN))
1638 if (((frtype|frsubtype) == WIFI_DATA_CFACK) ||
1639 ((frtype|frsubtype) == WIFI_DATA_CFPOLL) ||
1640 ((frtype|frsubtype) == WIFI_DATA_CFACKPOLL)) {
1642 if (hdrlen != WLAN_HDR_A3_QOS_LEN) {
1645 } else if ((frtype == WIFI_DATA) && /* only for data packet . add for CONFIG_IEEE80211W, none 11w also can use */
1646 ((frsubtype == 0x08) ||
1647 (frsubtype == 0x09) ||
1648 (frsubtype == 0x0a) ||
1649 (frsubtype == 0x0b))) {
1650 if (hdrlen != WLAN_HDR_A3_QOS_LEN) {
1658 /* now, decrypt pframe with hdrlen offset and plen long */
1660 payload_index = hdrlen + 8; /* 8 is for extiv */
1662 for (i = 0; i < num_blocks; i++) {
1663 construct_ctr_preload(
1670 frtype /* add for CONFIG_IEEE80211W, none 11w also can use */
1673 aes128k128d(key, ctr_preload, aes_out);
1674 bitwise_xor(aes_out, &pframe[payload_index], chain_buffer);
1676 for (j = 0; j < 16; j++)
1677 pframe[payload_index++] = chain_buffer[j];
1680 if (payload_remainder > 0) {
1681 /* If there is a short final block, then pad it,*/
1682 /* encrypt it and copy the unpadded part back */
1683 construct_ctr_preload(
1690 frtype /* add for CONFIG_IEEE80211W, none 11w also can use */
1693 for (j = 0; j < 16; j++)
1694 padded_buffer[j] = 0x00;
1695 for (j = 0; j < payload_remainder; j++) {
1696 padded_buffer[j] = pframe[payload_index+j];
1698 aes128k128d(key, ctr_preload, aes_out);
1699 bitwise_xor(aes_out, padded_buffer, chain_buffer);
1700 for (j = 0; j < payload_remainder; j++)
1701 pframe[payload_index++] = chain_buffer[j];
1704 /* start to calculate the mic */
1705 if ((hdrlen + plen+8) <= MAX_MSG_SIZE)
1706 memcpy((void *)message, pframe, (hdrlen + plen+8)); /* 8 is for ext iv len */
1709 pn_vector[0] = pframe[hdrlen];
1710 pn_vector[1] = pframe[hdrlen+1];
1711 pn_vector[2] = pframe[hdrlen+4];
1712 pn_vector[3] = pframe[hdrlen+5];
1713 pn_vector[4] = pframe[hdrlen+6];
1714 pn_vector[5] = pframe[hdrlen+7];
1725 frtype /* add for CONFIG_IEEE80211W, none 11w also can use */
1728 construct_mic_header1(
1732 frtype /* add for CONFIG_IEEE80211W, none 11w also can use */
1734 construct_mic_header2(
1742 payload_remainder = (plen-8) % 16;
1743 num_blocks = (plen-8) / 16;
1745 /* Find start of payload */
1746 payload_index = (hdrlen + 8);
1749 aes128k128d(key, mic_iv, aes_out);
1750 bitwise_xor(aes_out, mic_header1, chain_buffer);
1751 aes128k128d(key, chain_buffer, aes_out);
1752 bitwise_xor(aes_out, mic_header2, chain_buffer);
1753 aes128k128d(key, chain_buffer, aes_out);
1755 for (i = 0; i < num_blocks; i++) {
1756 bitwise_xor(aes_out, &message[payload_index], chain_buffer);
1758 payload_index += 16;
1759 aes128k128d(key, chain_buffer, aes_out);
1762 /* Add on the final payload block if it needs padding */
1763 if (payload_remainder > 0) {
1764 for (j = 0; j < 16; j++)
1765 padded_buffer[j] = 0x00;
1766 for (j = 0; j < payload_remainder; j++) {
1767 padded_buffer[j] = message[payload_index++];
1769 bitwise_xor(aes_out, padded_buffer, chain_buffer);
1770 aes128k128d(key, chain_buffer, aes_out);
1774 for (j = 0; j < 8; j++)
1775 mic[j] = aes_out[j];
1777 /* Insert MIC into payload */
1778 for (j = 0; j < 8; j++)
1779 message[payload_index+j] = mic[j];
1781 payload_index = hdrlen + 8;
1782 for (i = 0; i < num_blocks; i++) {
1783 construct_ctr_preload(
1791 ); /* add for CONFIG_IEEE80211W, none 11w also can use */
1792 aes128k128d(key, ctr_preload, aes_out);
1793 bitwise_xor(aes_out, &message[payload_index], chain_buffer);
1794 for (j = 0; j < 16; j++)
1795 message[payload_index++] = chain_buffer[j];
1798 if (payload_remainder > 0) {
1799 /* If there is a short final block, then pad it,*/
1800 /* encrypt it and copy the unpadded part back */
1801 construct_ctr_preload(
1809 ); /* add for CONFIG_IEEE80211W, none 11w also can use */
1811 for (j = 0; j < 16; j++)
1812 padded_buffer[j] = 0x00;
1813 for (j = 0; j < payload_remainder; j++) {
1814 padded_buffer[j] = message[payload_index+j];
1816 aes128k128d(key, ctr_preload, aes_out);
1817 bitwise_xor(aes_out, padded_buffer, chain_buffer);
1818 for (j = 0; j < payload_remainder; j++)
1819 message[payload_index++] = chain_buffer[j];
1822 /* Encrypt the MIC */
1823 construct_ctr_preload(
1831 ); /* add for CONFIG_IEEE80211W, none 11w also can use */
1833 for (j = 0; j < 16; j++)
1834 padded_buffer[j] = 0x00;
1835 for (j = 0; j < 8; j++) {
1836 padded_buffer[j] = message[j+hdrlen+8+plen-8];
1839 aes128k128d(key, ctr_preload, aes_out);
1840 bitwise_xor(aes_out, padded_buffer, chain_buffer);
1841 for (j = 0; j < 8; j++)
1842 message[payload_index++] = chain_buffer[j];
1844 /* compare the mic */
1845 for (i = 0; i < 8; i++) {
1846 if (pframe[hdrlen+8+plen-8+i] != message[hdrlen+8+plen-8+i]) {
1847 RT_TRACE(_module_rtl871x_security_c_, _drv_err_, ("aes_decipher:mic check error mic[%d]: pframe(%x) != message(%x)\n",
1848 i, pframe[hdrlen+8+plen-8+i], message[hdrlen+8+plen-8+i]));
1849 DBG_871X("aes_decipher:mic check error mic[%d]: pframe(%x) != message(%x)\n",
1850 i, pframe[hdrlen+8+plen-8+i], message[hdrlen+8+plen-8+i]);
1857 u32 rtw_aes_decrypt(struct adapter *padapter, u8 *precvframe)
1862 /* unsigned char message[MAX_MSG_SIZE]; */
1865 /* Intermediate Buffers */
1869 u8 *pframe, *prwskey; /* *payload,*iv */
1870 struct sta_info *stainfo;
1871 struct rx_pkt_attrib *prxattrib = &((union recv_frame *)precvframe)->u.hdr.attrib;
1872 struct security_priv *psecuritypriv = &padapter->securitypriv;
1873 /* struct recv_priv *precvpriv =&padapter->recvpriv; */
1876 pframe = (unsigned char *)((union recv_frame *)precvframe)->u.hdr.rx_data;
1877 /* 4 start to encrypt each fragment */
1878 if ((prxattrib->encrypt == _AES_)) {
1880 stainfo = rtw_get_stainfo(&padapter->stapriv, &prxattrib->ta[0]);
1881 if (stainfo != NULL) {
1882 RT_TRACE(_module_rtl871x_security_c_, _drv_err_, ("rtw_aes_decrypt: stainfo!= NULL!!!\n"));
1884 if (IS_MCAST(prxattrib->ra)) {
1885 static unsigned long start;
1886 static u32 no_gkey_bc_cnt;
1887 static u32 no_gkey_mc_cnt;
1889 /* DBG_871X("rx bc/mc packets, to perform sw rtw_aes_decrypt\n"); */
1890 /* prwskey = psecuritypriv->dot118021XGrpKey[psecuritypriv->dot118021XGrpKeyid].skey; */
1891 if (psecuritypriv->binstallGrpkey == false) {
1897 if (is_broadcast_mac_addr(prxattrib->ra))
1902 if (jiffies_to_msecs(jiffies - start) > 1000) {
1903 if (no_gkey_bc_cnt || no_gkey_mc_cnt) {
1904 DBG_871X_LEVEL(_drv_always_, FUNC_ADPT_FMT" no_gkey_bc_cnt:%u, no_gkey_mc_cnt:%u\n",
1905 FUNC_ADPT_ARG(padapter), no_gkey_bc_cnt, no_gkey_mc_cnt);
1915 if (no_gkey_bc_cnt || no_gkey_mc_cnt) {
1916 DBG_871X_LEVEL(_drv_always_, FUNC_ADPT_FMT" gkey installed. no_gkey_bc_cnt:%u, no_gkey_mc_cnt:%u\n",
1917 FUNC_ADPT_ARG(padapter), no_gkey_bc_cnt, no_gkey_mc_cnt);
1923 prwskey = psecuritypriv->dot118021XGrpKey[prxattrib->key_index].skey;
1924 if (psecuritypriv->dot118021XGrpKeyid != prxattrib->key_index) {
1925 DBG_871X("not match packet_index =%d, install_index =%d\n"
1926 , prxattrib->key_index, psecuritypriv->dot118021XGrpKeyid);
1931 prwskey = &stainfo->dot118021x_UncstKey.skey[0];
1934 length = ((union recv_frame *)precvframe)->u.hdr.len-prxattrib->hdrlen-prxattrib->iv_len;
1936 res = aes_decipher(prwskey, prxattrib->hdrlen, pframe, length);
1938 AES_SW_DEC_CNT_INC(psecuritypriv, prxattrib->ra);
1940 RT_TRACE(_module_rtl871x_security_c_, _drv_err_, ("rtw_aes_decrypt: stainfo == NULL!!!\n"));
1948 u32 rtw_BIP_verify(struct adapter *padapter, u8 *precvframe)
1950 struct rx_pkt_attrib *pattrib = &((union recv_frame *)precvframe)->u.hdr.attrib;
1955 struct ieee80211_hdr *pwlanhdr;
1957 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
1961 ori_len = pattrib->pkt_len-WLAN_HDR_A3_LEN+BIP_AAD_SIZE;
1962 BIP_AAD = rtw_zmalloc(ori_len);
1964 if (BIP_AAD == NULL) {
1965 DBG_871X("BIP AAD allocate fail\n");
1969 pframe = (unsigned char *)((union recv_frame *)precvframe)->u.hdr.rx_data;
1970 /* mapping to wlan header */
1971 pwlanhdr = (struct ieee80211_hdr *)pframe;
1972 /* save the frame body + MME */
1973 memcpy(BIP_AAD+BIP_AAD_SIZE, pframe+WLAN_HDR_A3_LEN, pattrib->pkt_len-WLAN_HDR_A3_LEN);
1974 /* find MME IE pointer */
1975 p = rtw_get_ie(BIP_AAD+BIP_AAD_SIZE, _MME_IE_, &len, pattrib->pkt_len-WLAN_HDR_A3_LEN);
1980 /* save packet number */
1981 memcpy(&le_tmp64, p+4, 6);
1982 temp_ipn = le64_to_cpu(le_tmp64);
1983 /* BIP packet number should bigger than previous BIP packet */
1984 if (temp_ipn <= pmlmeext->mgnt_80211w_IPN_rx) {
1985 DBG_871X("replay BIP packet\n");
1988 /* copy key index */
1989 memcpy(&le_tmp, p+2, 2);
1990 keyid = le16_to_cpu(le_tmp);
1991 if (keyid != padapter->securitypriv.dot11wBIPKeyid) {
1992 DBG_871X("BIP key index error!\n");
1995 /* clear the MIC field of MME to zero */
1996 memset(p+2+len-8, 0, 8);
1998 /* conscruct AAD, copy frame control field */
1999 memcpy(BIP_AAD, &pwlanhdr->frame_control, 2);
2000 ClearRetry(BIP_AAD);
2001 ClearPwrMgt(BIP_AAD);
2002 ClearMData(BIP_AAD);
2003 /* conscruct AAD, copy address 1 to address 3 */
2004 memcpy(BIP_AAD+2, pwlanhdr->addr1, 18);
2006 if (omac1_aes_128(padapter->securitypriv.dot11wBIPKey[padapter->securitypriv.dot11wBIPKeyid].skey
2007 , BIP_AAD, ori_len, mic))
2010 /* MIC field should be last 8 bytes of packet (packet without FCS) */
2011 if (!memcmp(mic, pframe+pattrib->pkt_len-8, 8)) {
2012 pmlmeext->mgnt_80211w_IPN_rx = temp_ipn;
2015 DBG_871X("BIP MIC error!\n");
2018 res = RTW_RX_HANDLED;
2026 const u32 Te0[256] = {
2027 0xc66363a5U, 0xf87c7c84U, 0xee777799U, 0xf67b7b8dU,
2028 0xfff2f20dU, 0xd66b6bbdU, 0xde6f6fb1U, 0x91c5c554U,
2029 0x60303050U, 0x02010103U, 0xce6767a9U, 0x562b2b7dU,
2030 0xe7fefe19U, 0xb5d7d762U, 0x4dababe6U, 0xec76769aU,
2031 0x8fcaca45U, 0x1f82829dU, 0x89c9c940U, 0xfa7d7d87U,
2032 0xeffafa15U, 0xb25959ebU, 0x8e4747c9U, 0xfbf0f00bU,
2033 0x41adadecU, 0xb3d4d467U, 0x5fa2a2fdU, 0x45afafeaU,
2034 0x239c9cbfU, 0x53a4a4f7U, 0xe4727296U, 0x9bc0c05bU,
2035 0x75b7b7c2U, 0xe1fdfd1cU, 0x3d9393aeU, 0x4c26266aU,
2036 0x6c36365aU, 0x7e3f3f41U, 0xf5f7f702U, 0x83cccc4fU,
2037 0x6834345cU, 0x51a5a5f4U, 0xd1e5e534U, 0xf9f1f108U,
2038 0xe2717193U, 0xabd8d873U, 0x62313153U, 0x2a15153fU,
2039 0x0804040cU, 0x95c7c752U, 0x46232365U, 0x9dc3c35eU,
2040 0x30181828U, 0x379696a1U, 0x0a05050fU, 0x2f9a9ab5U,
2041 0x0e070709U, 0x24121236U, 0x1b80809bU, 0xdfe2e23dU,
2042 0xcdebeb26U, 0x4e272769U, 0x7fb2b2cdU, 0xea75759fU,
2043 0x1209091bU, 0x1d83839eU, 0x582c2c74U, 0x341a1a2eU,
2044 0x361b1b2dU, 0xdc6e6eb2U, 0xb45a5aeeU, 0x5ba0a0fbU,
2045 0xa45252f6U, 0x763b3b4dU, 0xb7d6d661U, 0x7db3b3ceU,
2046 0x5229297bU, 0xdde3e33eU, 0x5e2f2f71U, 0x13848497U,
2047 0xa65353f5U, 0xb9d1d168U, 0x00000000U, 0xc1eded2cU,
2048 0x40202060U, 0xe3fcfc1fU, 0x79b1b1c8U, 0xb65b5bedU,
2049 0xd46a6abeU, 0x8dcbcb46U, 0x67bebed9U, 0x7239394bU,
2050 0x944a4adeU, 0x984c4cd4U, 0xb05858e8U, 0x85cfcf4aU,
2051 0xbbd0d06bU, 0xc5efef2aU, 0x4faaaae5U, 0xedfbfb16U,
2052 0x864343c5U, 0x9a4d4dd7U, 0x66333355U, 0x11858594U,
2053 0x8a4545cfU, 0xe9f9f910U, 0x04020206U, 0xfe7f7f81U,
2054 0xa05050f0U, 0x783c3c44U, 0x259f9fbaU, 0x4ba8a8e3U,
2055 0xa25151f3U, 0x5da3a3feU, 0x804040c0U, 0x058f8f8aU,
2056 0x3f9292adU, 0x219d9dbcU, 0x70383848U, 0xf1f5f504U,
2057 0x63bcbcdfU, 0x77b6b6c1U, 0xafdada75U, 0x42212163U,
2058 0x20101030U, 0xe5ffff1aU, 0xfdf3f30eU, 0xbfd2d26dU,
2059 0x81cdcd4cU, 0x180c0c14U, 0x26131335U, 0xc3ecec2fU,
2060 0xbe5f5fe1U, 0x359797a2U, 0x884444ccU, 0x2e171739U,
2061 0x93c4c457U, 0x55a7a7f2U, 0xfc7e7e82U, 0x7a3d3d47U,
2062 0xc86464acU, 0xba5d5de7U, 0x3219192bU, 0xe6737395U,
2063 0xc06060a0U, 0x19818198U, 0x9e4f4fd1U, 0xa3dcdc7fU,
2064 0x44222266U, 0x542a2a7eU, 0x3b9090abU, 0x0b888883U,
2065 0x8c4646caU, 0xc7eeee29U, 0x6bb8b8d3U, 0x2814143cU,
2066 0xa7dede79U, 0xbc5e5ee2U, 0x160b0b1dU, 0xaddbdb76U,
2067 0xdbe0e03bU, 0x64323256U, 0x743a3a4eU, 0x140a0a1eU,
2068 0x924949dbU, 0x0c06060aU, 0x4824246cU, 0xb85c5ce4U,
2069 0x9fc2c25dU, 0xbdd3d36eU, 0x43acacefU, 0xc46262a6U,
2070 0x399191a8U, 0x319595a4U, 0xd3e4e437U, 0xf279798bU,
2071 0xd5e7e732U, 0x8bc8c843U, 0x6e373759U, 0xda6d6db7U,
2072 0x018d8d8cU, 0xb1d5d564U, 0x9c4e4ed2U, 0x49a9a9e0U,
2073 0xd86c6cb4U, 0xac5656faU, 0xf3f4f407U, 0xcfeaea25U,
2074 0xca6565afU, 0xf47a7a8eU, 0x47aeaee9U, 0x10080818U,
2075 0x6fbabad5U, 0xf0787888U, 0x4a25256fU, 0x5c2e2e72U,
2076 0x381c1c24U, 0x57a6a6f1U, 0x73b4b4c7U, 0x97c6c651U,
2077 0xcbe8e823U, 0xa1dddd7cU, 0xe874749cU, 0x3e1f1f21U,
2078 0x964b4bddU, 0x61bdbddcU, 0x0d8b8b86U, 0x0f8a8a85U,
2079 0xe0707090U, 0x7c3e3e42U, 0x71b5b5c4U, 0xcc6666aaU,
2080 0x904848d8U, 0x06030305U, 0xf7f6f601U, 0x1c0e0e12U,
2081 0xc26161a3U, 0x6a35355fU, 0xae5757f9U, 0x69b9b9d0U,
2082 0x17868691U, 0x99c1c158U, 0x3a1d1d27U, 0x279e9eb9U,
2083 0xd9e1e138U, 0xebf8f813U, 0x2b9898b3U, 0x22111133U,
2084 0xd26969bbU, 0xa9d9d970U, 0x078e8e89U, 0x339494a7U,
2085 0x2d9b9bb6U, 0x3c1e1e22U, 0x15878792U, 0xc9e9e920U,
2086 0x87cece49U, 0xaa5555ffU, 0x50282878U, 0xa5dfdf7aU,
2087 0x038c8c8fU, 0x59a1a1f8U, 0x09898980U, 0x1a0d0d17U,
2088 0x65bfbfdaU, 0xd7e6e631U, 0x844242c6U, 0xd06868b8U,
2089 0x824141c3U, 0x299999b0U, 0x5a2d2d77U, 0x1e0f0f11U,
2090 0x7bb0b0cbU, 0xa85454fcU, 0x6dbbbbd6U, 0x2c16163aU,
2092 const u32 Td0[256] = {
2093 0x51f4a750U, 0x7e416553U, 0x1a17a4c3U, 0x3a275e96U,
2094 0x3bab6bcbU, 0x1f9d45f1U, 0xacfa58abU, 0x4be30393U,
2095 0x2030fa55U, 0xad766df6U, 0x88cc7691U, 0xf5024c25U,
2096 0x4fe5d7fcU, 0xc52acbd7U, 0x26354480U, 0xb562a38fU,
2097 0xdeb15a49U, 0x25ba1b67U, 0x45ea0e98U, 0x5dfec0e1U,
2098 0xc32f7502U, 0x814cf012U, 0x8d4697a3U, 0x6bd3f9c6U,
2099 0x038f5fe7U, 0x15929c95U, 0xbf6d7aebU, 0x955259daU,
2100 0xd4be832dU, 0x587421d3U, 0x49e06929U, 0x8ec9c844U,
2101 0x75c2896aU, 0xf48e7978U, 0x99583e6bU, 0x27b971ddU,
2102 0xbee14fb6U, 0xf088ad17U, 0xc920ac66U, 0x7dce3ab4U,
2103 0x63df4a18U, 0xe51a3182U, 0x97513360U, 0x62537f45U,
2104 0xb16477e0U, 0xbb6bae84U, 0xfe81a01cU, 0xf9082b94U,
2105 0x70486858U, 0x8f45fd19U, 0x94de6c87U, 0x527bf8b7U,
2106 0xab73d323U, 0x724b02e2U, 0xe31f8f57U, 0x6655ab2aU,
2107 0xb2eb2807U, 0x2fb5c203U, 0x86c57b9aU, 0xd33708a5U,
2108 0x302887f2U, 0x23bfa5b2U, 0x02036abaU, 0xed16825cU,
2109 0x8acf1c2bU, 0xa779b492U, 0xf307f2f0U, 0x4e69e2a1U,
2110 0x65daf4cdU, 0x0605bed5U, 0xd134621fU, 0xc4a6fe8aU,
2111 0x342e539dU, 0xa2f355a0U, 0x058ae132U, 0xa4f6eb75U,
2112 0x0b83ec39U, 0x4060efaaU, 0x5e719f06U, 0xbd6e1051U,
2113 0x3e218af9U, 0x96dd063dU, 0xdd3e05aeU, 0x4de6bd46U,
2114 0x91548db5U, 0x71c45d05U, 0x0406d46fU, 0x605015ffU,
2115 0x1998fb24U, 0xd6bde997U, 0x894043ccU, 0x67d99e77U,
2116 0xb0e842bdU, 0x07898b88U, 0xe7195b38U, 0x79c8eedbU,
2117 0xa17c0a47U, 0x7c420fe9U, 0xf8841ec9U, 0x00000000U,
2118 0x09808683U, 0x322bed48U, 0x1e1170acU, 0x6c5a724eU,
2119 0xfd0efffbU, 0x0f853856U, 0x3daed51eU, 0x362d3927U,
2120 0x0a0fd964U, 0x685ca621U, 0x9b5b54d1U, 0x24362e3aU,
2121 0x0c0a67b1U, 0x9357e70fU, 0xb4ee96d2U, 0x1b9b919eU,
2122 0x80c0c54fU, 0x61dc20a2U, 0x5a774b69U, 0x1c121a16U,
2123 0xe293ba0aU, 0xc0a02ae5U, 0x3c22e043U, 0x121b171dU,
2124 0x0e090d0bU, 0xf28bc7adU, 0x2db6a8b9U, 0x141ea9c8U,
2125 0x57f11985U, 0xaf75074cU, 0xee99ddbbU, 0xa37f60fdU,
2126 0xf701269fU, 0x5c72f5bcU, 0x44663bc5U, 0x5bfb7e34U,
2127 0x8b432976U, 0xcb23c6dcU, 0xb6edfc68U, 0xb8e4f163U,
2128 0xd731dccaU, 0x42638510U, 0x13972240U, 0x84c61120U,
2129 0x854a247dU, 0xd2bb3df8U, 0xaef93211U, 0xc729a16dU,
2130 0x1d9e2f4bU, 0xdcb230f3U, 0x0d8652ecU, 0x77c1e3d0U,
2131 0x2bb3166cU, 0xa970b999U, 0x119448faU, 0x47e96422U,
2132 0xa8fc8cc4U, 0xa0f03f1aU, 0x567d2cd8U, 0x223390efU,
2133 0x87494ec7U, 0xd938d1c1U, 0x8ccaa2feU, 0x98d40b36U,
2134 0xa6f581cfU, 0xa57ade28U, 0xdab78e26U, 0x3fadbfa4U,
2135 0x2c3a9de4U, 0x5078920dU, 0x6a5fcc9bU, 0x547e4662U,
2136 0xf68d13c2U, 0x90d8b8e8U, 0x2e39f75eU, 0x82c3aff5U,
2137 0x9f5d80beU, 0x69d0937cU, 0x6fd52da9U, 0xcf2512b3U,
2138 0xc8ac993bU, 0x10187da7U, 0xe89c636eU, 0xdb3bbb7bU,
2139 0xcd267809U, 0x6e5918f4U, 0xec9ab701U, 0x834f9aa8U,
2140 0xe6956e65U, 0xaaffe67eU, 0x21bccf08U, 0xef15e8e6U,
2141 0xbae79bd9U, 0x4a6f36ceU, 0xea9f09d4U, 0x29b07cd6U,
2142 0x31a4b2afU, 0x2a3f2331U, 0xc6a59430U, 0x35a266c0U,
2143 0x744ebc37U, 0xfc82caa6U, 0xe090d0b0U, 0x33a7d815U,
2144 0xf104984aU, 0x41ecdaf7U, 0x7fcd500eU, 0x1791f62fU,
2145 0x764dd68dU, 0x43efb04dU, 0xccaa4d54U, 0xe49604dfU,
2146 0x9ed1b5e3U, 0x4c6a881bU, 0xc12c1fb8U, 0x4665517fU,
2147 0x9d5eea04U, 0x018c355dU, 0xfa877473U, 0xfb0b412eU,
2148 0xb3671d5aU, 0x92dbd252U, 0xe9105633U, 0x6dd64713U,
2149 0x9ad7618cU, 0x37a10c7aU, 0x59f8148eU, 0xeb133c89U,
2150 0xcea927eeU, 0xb761c935U, 0xe11ce5edU, 0x7a47b13cU,
2151 0x9cd2df59U, 0x55f2733fU, 0x1814ce79U, 0x73c737bfU,
2152 0x53f7cdeaU, 0x5ffdaa5bU, 0xdf3d6f14U, 0x7844db86U,
2153 0xcaaff381U, 0xb968c43eU, 0x3824342cU, 0xc2a3405fU,
2154 0x161dc372U, 0xbce2250cU, 0x283c498bU, 0xff0d9541U,
2155 0x39a80171U, 0x080cb3deU, 0xd8b4e49cU, 0x6456c190U,
2156 0x7bcb8461U, 0xd532b670U, 0x486c5c74U, 0xd0b85742U,
2158 const u8 Td4s[256] = {
2159 0x52U, 0x09U, 0x6aU, 0xd5U, 0x30U, 0x36U, 0xa5U, 0x38U,
2160 0xbfU, 0x40U, 0xa3U, 0x9eU, 0x81U, 0xf3U, 0xd7U, 0xfbU,
2161 0x7cU, 0xe3U, 0x39U, 0x82U, 0x9bU, 0x2fU, 0xffU, 0x87U,
2162 0x34U, 0x8eU, 0x43U, 0x44U, 0xc4U, 0xdeU, 0xe9U, 0xcbU,
2163 0x54U, 0x7bU, 0x94U, 0x32U, 0xa6U, 0xc2U, 0x23U, 0x3dU,
2164 0xeeU, 0x4cU, 0x95U, 0x0bU, 0x42U, 0xfaU, 0xc3U, 0x4eU,
2165 0x08U, 0x2eU, 0xa1U, 0x66U, 0x28U, 0xd9U, 0x24U, 0xb2U,
2166 0x76U, 0x5bU, 0xa2U, 0x49U, 0x6dU, 0x8bU, 0xd1U, 0x25U,
2167 0x72U, 0xf8U, 0xf6U, 0x64U, 0x86U, 0x68U, 0x98U, 0x16U,
2168 0xd4U, 0xa4U, 0x5cU, 0xccU, 0x5dU, 0x65U, 0xb6U, 0x92U,
2169 0x6cU, 0x70U, 0x48U, 0x50U, 0xfdU, 0xedU, 0xb9U, 0xdaU,
2170 0x5eU, 0x15U, 0x46U, 0x57U, 0xa7U, 0x8dU, 0x9dU, 0x84U,
2171 0x90U, 0xd8U, 0xabU, 0x00U, 0x8cU, 0xbcU, 0xd3U, 0x0aU,
2172 0xf7U, 0xe4U, 0x58U, 0x05U, 0xb8U, 0xb3U, 0x45U, 0x06U,
2173 0xd0U, 0x2cU, 0x1eU, 0x8fU, 0xcaU, 0x3fU, 0x0fU, 0x02U,
2174 0xc1U, 0xafU, 0xbdU, 0x03U, 0x01U, 0x13U, 0x8aU, 0x6bU,
2175 0x3aU, 0x91U, 0x11U, 0x41U, 0x4fU, 0x67U, 0xdcU, 0xeaU,
2176 0x97U, 0xf2U, 0xcfU, 0xceU, 0xf0U, 0xb4U, 0xe6U, 0x73U,
2177 0x96U, 0xacU, 0x74U, 0x22U, 0xe7U, 0xadU, 0x35U, 0x85U,
2178 0xe2U, 0xf9U, 0x37U, 0xe8U, 0x1cU, 0x75U, 0xdfU, 0x6eU,
2179 0x47U, 0xf1U, 0x1aU, 0x71U, 0x1dU, 0x29U, 0xc5U, 0x89U,
2180 0x6fU, 0xb7U, 0x62U, 0x0eU, 0xaaU, 0x18U, 0xbeU, 0x1bU,
2181 0xfcU, 0x56U, 0x3eU, 0x4bU, 0xc6U, 0xd2U, 0x79U, 0x20U,
2182 0x9aU, 0xdbU, 0xc0U, 0xfeU, 0x78U, 0xcdU, 0x5aU, 0xf4U,
2183 0x1fU, 0xddU, 0xa8U, 0x33U, 0x88U, 0x07U, 0xc7U, 0x31U,
2184 0xb1U, 0x12U, 0x10U, 0x59U, 0x27U, 0x80U, 0xecU, 0x5fU,
2185 0x60U, 0x51U, 0x7fU, 0xa9U, 0x19U, 0xb5U, 0x4aU, 0x0dU,
2186 0x2dU, 0xe5U, 0x7aU, 0x9fU, 0x93U, 0xc9U, 0x9cU, 0xefU,
2187 0xa0U, 0xe0U, 0x3bU, 0x4dU, 0xaeU, 0x2aU, 0xf5U, 0xb0U,
2188 0xc8U, 0xebU, 0xbbU, 0x3cU, 0x83U, 0x53U, 0x99U, 0x61U,
2189 0x17U, 0x2bU, 0x04U, 0x7eU, 0xbaU, 0x77U, 0xd6U, 0x26U,
2190 0xe1U, 0x69U, 0x14U, 0x63U, 0x55U, 0x21U, 0x0cU, 0x7dU,
2192 const u8 rcons[] = {
2193 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x1B, 0x36
2194 /* for 128-bit blocks, Rijndael never uses more than 10 rcon values */
2198 * Expand the cipher key into the encryption key schedule.
2200 * @return the number of rounds for the given cipher key size.
2202 static void rijndaelKeySetupEnc(u32 rk[/*44*/], const u8 cipherKey[])
2207 rk[0] = GETU32(cipherKey);
2208 rk[1] = GETU32(cipherKey + 4);
2209 rk[2] = GETU32(cipherKey + 8);
2210 rk[3] = GETU32(cipherKey + 12);
2211 for (i = 0; i < 10; i++) {
2214 TE421(temp) ^ TE432(temp) ^ TE443(temp) ^ TE414(temp) ^
2216 rk[5] = rk[1] ^ rk[4];
2217 rk[6] = rk[2] ^ rk[5];
2218 rk[7] = rk[3] ^ rk[6];
2223 static void rijndaelEncrypt(u32 rk[/*44*/], u8 pt[16], u8 ct[16])
2225 u32 s0, s1, s2, s3, t0, t1, t2, t3;
2230 * map byte array block to cipher state
2231 * and add initial round key:
2233 s0 = GETU32(pt) ^ rk[0];
2234 s1 = GETU32(pt + 4) ^ rk[1];
2235 s2 = GETU32(pt + 8) ^ rk[2];
2236 s3 = GETU32(pt + 12) ^ rk[3];
2238 #define ROUND(i, d, s) \
2239 d##0 = TE0(s##0) ^ TE1(s##1) ^ TE2(s##2) ^ TE3(s##3) ^ rk[4 * i]; \
2240 d##1 = TE0(s##1) ^ TE1(s##2) ^ TE2(s##3) ^ TE3(s##0) ^ rk[4 * i + 1]; \
2241 d##2 = TE0(s##2) ^ TE1(s##3) ^ TE2(s##0) ^ TE3(s##1) ^ rk[4 * i + 2]; \
2242 d##3 = TE0(s##3) ^ TE1(s##0) ^ TE2(s##1) ^ TE3(s##2) ^ rk[4 * i + 3]
2244 /* Nr - 1 full rounds: */
2257 * apply last round and
2258 * map cipher state to byte array block:
2260 s0 = TE41(t0) ^ TE42(t1) ^ TE43(t2) ^ TE44(t3) ^ rk[0];
2262 s1 = TE41(t1) ^ TE42(t2) ^ TE43(t3) ^ TE44(t0) ^ rk[1];
2264 s2 = TE41(t2) ^ TE42(t3) ^ TE43(t0) ^ TE44(t1) ^ rk[2];
2266 s3 = TE41(t3) ^ TE42(t0) ^ TE43(t1) ^ TE44(t2) ^ rk[3];
2267 PUTU32(ct + 12, s3);
2270 static void *aes_encrypt_init(u8 *key, size_t len)
2275 rk = (u32 *)rtw_malloc(AES_PRIV_SIZE);
2278 rijndaelKeySetupEnc(rk, key);
2282 static void aes_128_encrypt(void *ctx, u8 *plain, u8 *crypt)
2284 rijndaelEncrypt(ctx, plain, crypt);
2288 static void gf_mulx(u8 *pad)
2292 carry = pad[0] & 0x80;
2293 for (i = 0; i < AES_BLOCK_SIZE - 1; i++)
2294 pad[i] = (pad[i] << 1) | (pad[i + 1] >> 7);
2296 pad[AES_BLOCK_SIZE - 1] <<= 1;
2298 pad[AES_BLOCK_SIZE - 1] ^= 0x87;
2301 static void aes_encrypt_deinit(void *ctx)
2303 memset(ctx, 0, AES_PRIV_SIZE);
2309 * omac1_aes_128_vector - One-Key CBC MAC (OMAC1) hash with AES-128
2310 * @key: 128-bit key for the hash operation
2311 * @num_elem: Number of elements in the data vector
2312 * @addr: Pointers to the data areas
2313 * @len: Lengths of the data blocks
2314 * @mac: Buffer for MAC (128 bits, i.e., 16 bytes)
2315 * Returns: 0 on success, -1 on failure
2317 * This is a mode for using block cipher (AES in this case) for authentication.
2318 * OMAC1 was standardized with the name CMAC by NIST in a Special Publication
2321 static int omac1_aes_128_vector(u8 *key, size_t num_elem,
2322 u8 *addr[], size_t *len, u8 *mac)
2325 u8 cbc[AES_BLOCK_SIZE], pad[AES_BLOCK_SIZE];
2327 size_t i, e, left, total_len;
2329 ctx = aes_encrypt_init(key, 16);
2332 memset(cbc, 0, AES_BLOCK_SIZE);
2335 for (e = 0; e < num_elem; e++)
2336 total_len += len[e];
2343 while (left >= AES_BLOCK_SIZE) {
2344 for (i = 0; i < AES_BLOCK_SIZE; i++) {
2352 if (left > AES_BLOCK_SIZE)
2353 aes_128_encrypt(ctx, cbc, cbc);
2354 left -= AES_BLOCK_SIZE;
2357 memset(pad, 0, AES_BLOCK_SIZE);
2358 aes_128_encrypt(ctx, pad, pad);
2361 if (left || total_len == 0) {
2362 for (i = 0; i < left; i++) {
2374 for (i = 0; i < AES_BLOCK_SIZE; i++)
2376 aes_128_encrypt(ctx, pad, mac);
2377 aes_encrypt_deinit(ctx);
2383 * omac1_aes_128 - One-Key CBC MAC (OMAC1) hash with AES-128 (aka AES-CMAC)
2384 * @key: 128-bit key for the hash operation
2385 * @data: Data buffer for which a MAC is determined
2386 * @data_len: Length of data buffer in bytes
2387 * @mac: Buffer for MAC (128 bits, i.e., 16 bytes)
2388 * Returns: 0 on success, -1 on failure
2390 * This is a mode for using block cipher (AES in this case) for authentication.
2391 * OMAC1 was standardized with the name CMAC by NIST in a Special Publication
2393 * modify for CONFIG_IEEE80211W */
2394 int omac1_aes_128(u8 *key, u8 *data, size_t data_len, u8 *mac)
2396 return omac1_aes_128_vector(key, 1, &data, &data_len, mac);
2399 /* Restore HW wep key setting according to key_mask */
2400 void rtw_sec_restore_wep_key(struct adapter *adapter)
2402 struct security_priv *securitypriv = &(adapter->securitypriv);
2405 if ((_WEP40_ == securitypriv->dot11PrivacyAlgrthm) || (_WEP104_ == securitypriv->dot11PrivacyAlgrthm)) {
2406 for (keyid = 0; keyid < 4; keyid++) {
2407 if (securitypriv->key_mask & BIT(keyid)) {
2408 if (keyid == securitypriv->dot11PrivacyKeyIndex)
2409 rtw_set_key(adapter, securitypriv, keyid, 1, false);
2411 rtw_set_key(adapter, securitypriv, keyid, 0, false);
2417 u8 rtw_handle_tkip_countermeasure(struct adapter *adapter, const char *caller)
2419 struct security_priv *securitypriv = &(adapter->securitypriv);
2420 u8 status = _SUCCESS;
2422 if (securitypriv->btkip_countermeasure == true) {
2423 unsigned long passing_ms = jiffies_to_msecs(jiffies - securitypriv->btkip_countermeasure_time);
2424 if (passing_ms > 60*1000) {
2425 DBG_871X_LEVEL(_drv_always_, "%s("ADPT_FMT") countermeasure time:%lus > 60s\n",
2426 caller, ADPT_ARG(adapter), passing_ms/1000);
2427 securitypriv->btkip_countermeasure = false;
2428 securitypriv->btkip_countermeasure_time = 0;
2430 DBG_871X_LEVEL(_drv_always_, "%s("ADPT_FMT") countermeasure time:%lus < 60s\n",
2431 caller, ADPT_ARG(adapter), passing_ms/1000);