1 // SPDX-License-Identifier: GPL-2.0
2 /******************************************************************************
4 * Copyright(c) 2007 - 2011 Realtek Corporation. All rights reserved.
6 ******************************************************************************/
7 #define _RTW_SECURITY_C_
9 #include <linux/crc32poly.h>
10 #include <drv_types.h>
11 #include <rtw_debug.h>
13 static const char * const _security_type_str[] = {
25 const char *security_type_str(u8 value)
28 return _security_type_str[value];
33 #define WEP_SW_ENC_CNT_INC(sec, ra) \
34 if (is_broadcast_mac_addr(ra)) \
35 sec->wep_sw_enc_cnt_bc++; \
36 else if (is_multicast_mac_addr(ra)) \
37 sec->wep_sw_enc_cnt_mc++; \
39 sec->wep_sw_enc_cnt_uc++;
41 #define WEP_SW_DEC_CNT_INC(sec, ra) \
42 if (is_broadcast_mac_addr(ra)) \
43 sec->wep_sw_dec_cnt_bc++; \
44 else if (is_multicast_mac_addr(ra)) \
45 sec->wep_sw_dec_cnt_mc++; \
47 sec->wep_sw_dec_cnt_uc++;
49 #define TKIP_SW_ENC_CNT_INC(sec, ra) \
50 if (is_broadcast_mac_addr(ra)) \
51 sec->tkip_sw_enc_cnt_bc++; \
52 else if (is_multicast_mac_addr(ra)) \
53 sec->tkip_sw_enc_cnt_mc++; \
55 sec->tkip_sw_enc_cnt_uc++;
57 #define TKIP_SW_DEC_CNT_INC(sec, ra) \
58 if (is_broadcast_mac_addr(ra)) \
59 sec->tkip_sw_dec_cnt_bc++; \
60 else if (is_multicast_mac_addr(ra)) \
61 sec->tkip_sw_dec_cnt_mc++; \
63 sec->tkip_sw_dec_cnt_uc++;
65 #define AES_SW_ENC_CNT_INC(sec, ra) \
66 if (is_broadcast_mac_addr(ra)) \
67 sec->aes_sw_enc_cnt_bc++; \
68 else if (is_multicast_mac_addr(ra)) \
69 sec->aes_sw_enc_cnt_mc++; \
71 sec->aes_sw_enc_cnt_uc++;
73 #define AES_SW_DEC_CNT_INC(sec, ra) \
74 if (is_broadcast_mac_addr(ra)) \
75 sec->aes_sw_dec_cnt_bc++; \
76 else if (is_multicast_mac_addr(ra)) \
77 sec->aes_sw_dec_cnt_mc++; \
79 sec->aes_sw_dec_cnt_uc++;
81 #define WEP_SW_ENC_CNT_INC(sec, ra)
82 #define WEP_SW_DEC_CNT_INC(sec, ra)
83 #define TKIP_SW_ENC_CNT_INC(sec, ra)
84 #define TKIP_SW_DEC_CNT_INC(sec, ra)
85 #define AES_SW_ENC_CNT_INC(sec, ra)
86 #define AES_SW_DEC_CNT_INC(sec, ra)
87 #endif /* DBG_SW_SEC_CNT */
89 /* WEP related ===== */
98 static void arcfour_init(struct arc4context *parc4ctx, u8 *key, u32 key_len)
106 state = parc4ctx->state;
109 for (counter = 0; counter < 256; counter++)
110 state[counter] = (u8)counter;
113 for (counter = 0; counter < 256; counter++) {
115 stateindex = (stateindex + key[keyindex] + t) & 0xff;
116 u = state[stateindex];
117 state[stateindex] = (u8)t;
118 state[counter] = (u8)u;
119 if (++keyindex >= key_len)
124 static u32 arcfour_byte(struct arc4context *parc4ctx)
131 state = parc4ctx->state;
132 x = (parc4ctx->x + 1) & 0xff;
134 y = (sx + parc4ctx->y) & 0xff;
140 return state[(sx + sy) & 0xff];
143 static void arcfour_encrypt(
144 struct arc4context *parc4ctx,
152 for (i = 0; i < len; i++)
153 dest[i] = src[i] ^ (unsigned char)arcfour_byte(parc4ctx);
156 static sint bcrc32initialized;
157 static u32 crc32_table[256];
160 static u8 crc32_reverseBit(u8 data)
162 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));
165 static void crc32_init(void)
167 if (bcrc32initialized == 1)
172 u8 *p = (u8 *)&c, *p1;
177 for (i = 0; i < 256; ++i) {
178 k = crc32_reverseBit((u8)i);
179 for (c = ((u32)k) << 24, j = 8; j > 0; --j) {
180 c = c & 0x80000000 ? (c << 1) ^ CRC32_POLY_BE : (c << 1);
182 p1 = (u8 *)&crc32_table[i];
184 p1[0] = crc32_reverseBit(p[3]);
185 p1[1] = crc32_reverseBit(p[2]);
186 p1[2] = crc32_reverseBit(p[1]);
187 p1[3] = crc32_reverseBit(p[0]);
189 bcrc32initialized = 1;
193 static __le32 getcrc32(u8 *buf, sint len)
198 if (bcrc32initialized == 0)
201 crc = 0xffffffff; /* preload shift register, per CRC-32 spec */
203 for (p = buf; len > 0; ++p, --len) {
204 crc = crc32_table[(crc ^ *p) & 0xff] ^ (crc >> 8);
206 return cpu_to_le32(~crc); /* transmit complement, per CRC-32 spec */
211 Need to consider the fragment situation
213 void rtw_wep_encrypt(struct adapter *padapter, u8 *pxmitframe)
216 unsigned char crc[4];
217 struct arc4context mycontext;
219 sint curfragnum, length;
222 u8 *pframe, *payload, *iv; /* wepkey */
224 u8 hw_hdr_offset = 0;
225 struct pkt_attrib *pattrib = &((struct xmit_frame *)pxmitframe)->attrib;
226 struct security_priv *psecuritypriv = &padapter->securitypriv;
227 struct xmit_priv *pxmitpriv = &padapter->xmitpriv;
229 if (((struct xmit_frame *)pxmitframe)->buf_addr == NULL)
232 hw_hdr_offset = TXDESC_OFFSET;
233 pframe = ((struct xmit_frame *)pxmitframe)->buf_addr + hw_hdr_offset;
235 /* start to encrypt each fragment */
236 if ((pattrib->encrypt == _WEP40_) || (pattrib->encrypt == _WEP104_)) {
237 keylength = psecuritypriv->dot11DefKeylen[psecuritypriv->dot11PrivacyKeyIndex];
239 for (curfragnum = 0; curfragnum < pattrib->nr_frags; curfragnum++) {
240 iv = pframe+pattrib->hdrlen;
241 memcpy(&wepkey[0], iv, 3);
242 memcpy(&wepkey[3], &psecuritypriv->dot11DefKey[psecuritypriv->dot11PrivacyKeyIndex].skey[0], keylength);
243 payload = pframe+pattrib->iv_len+pattrib->hdrlen;
245 if ((curfragnum+1) == pattrib->nr_frags) { /* the last fragment */
247 length = pattrib->last_txcmdsz-pattrib->hdrlen-pattrib->iv_len-pattrib->icv_len;
249 *((__le32 *)crc) = getcrc32(payload, length);
251 arcfour_init(&mycontext, wepkey, 3+keylength);
252 arcfour_encrypt(&mycontext, payload, payload, length);
253 arcfour_encrypt(&mycontext, payload+length, crc, 4);
256 length = pxmitpriv->frag_len-pattrib->hdrlen-pattrib->iv_len-pattrib->icv_len;
257 *((__le32 *)crc) = getcrc32(payload, length);
258 arcfour_init(&mycontext, wepkey, 3+keylength);
259 arcfour_encrypt(&mycontext, payload, payload, length);
260 arcfour_encrypt(&mycontext, payload+length, crc, 4);
262 pframe += pxmitpriv->frag_len;
263 pframe = (u8 *)round_up((SIZE_PTR)(pframe), 4);
267 WEP_SW_ENC_CNT_INC(psecuritypriv, pattrib->ra);
271 void rtw_wep_decrypt(struct adapter *padapter, u8 *precvframe)
275 struct arc4context mycontext;
278 u8 *pframe, *payload, *iv, wepkey[16];
280 struct rx_pkt_attrib *prxattrib = &(((union recv_frame *)precvframe)->u.hdr.attrib);
281 struct security_priv *psecuritypriv = &padapter->securitypriv;
283 pframe = (unsigned char *)((union recv_frame *)precvframe)->u.hdr.rx_data;
285 /* start to decrypt recvframe */
286 if ((prxattrib->encrypt == _WEP40_) || (prxattrib->encrypt == _WEP104_)) {
287 iv = pframe+prxattrib->hdrlen;
288 /* keyindex =(iv[3]&0x3); */
289 keyindex = prxattrib->key_index;
290 keylength = psecuritypriv->dot11DefKeylen[keyindex];
291 memcpy(&wepkey[0], iv, 3);
292 /* memcpy(&wepkey[3], &psecuritypriv->dot11DefKey[psecuritypriv->dot11PrivacyKeyIndex].skey[0], keylength); */
293 memcpy(&wepkey[3], &psecuritypriv->dot11DefKey[keyindex].skey[0], keylength);
294 length = ((union recv_frame *)precvframe)->u.hdr.len-prxattrib->hdrlen-prxattrib->iv_len;
296 payload = pframe+prxattrib->iv_len+prxattrib->hdrlen;
298 /* decrypt payload include icv */
299 arcfour_init(&mycontext, wepkey, 3+keylength);
300 arcfour_encrypt(&mycontext, payload, payload, length);
302 /* calculate icv and compare the icv */
303 *((u32 *)crc) = le32_to_cpu(getcrc32(payload, length-4));
305 if (crc[3] != payload[length-1] || crc[2] != payload[length-2] || crc[1] != payload[length-3] || crc[0] != payload[length-4]) {
306 RT_TRACE(_module_rtl871x_security_c_,
308 ("%s: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",
310 crc[3], payload[length - 1],
311 crc[2], payload[length - 2],
312 crc[1], payload[length - 3],
313 crc[0], payload[length - 4]));
316 WEP_SW_DEC_CNT_INC(psecuritypriv, prxattrib->ra);
320 /* 3 =====TKIP related ===== */
322 static u32 secmicgetuint32(u8 *p)
323 /* Convert from Byte[] to Us3232 in a portable way */
328 for (i = 0; i < 4; i++) {
329 res |= ((u32)(*p++)) << (8*i);
335 static void secmicputuint32(u8 *p, u32 val)
336 /* Convert from Us3232 to Byte[] in a portable way */
340 for (i = 0; i < 4; i++) {
341 *p++ = (u8) (val & 0xff);
346 static void secmicclear(struct mic_data *pmicdata)
348 /* Reset the state to the empty message. */
349 pmicdata->L = pmicdata->K0;
350 pmicdata->R = pmicdata->K1;
351 pmicdata->nBytesInM = 0;
355 void rtw_secmicsetkey(struct mic_data *pmicdata, u8 *key)
358 pmicdata->K0 = secmicgetuint32(key);
359 pmicdata->K1 = secmicgetuint32(key + 4);
360 /* and reset the message */
361 secmicclear(pmicdata);
364 void rtw_secmicappendbyte(struct mic_data *pmicdata, u8 b)
366 /* Append the byte to our word-sized buffer */
367 pmicdata->M |= ((unsigned long)b) << (8*pmicdata->nBytesInM);
368 pmicdata->nBytesInM++;
369 /* Process the word if it is full. */
370 if (pmicdata->nBytesInM >= 4) {
371 pmicdata->L ^= pmicdata->M;
372 pmicdata->R ^= ROL32(pmicdata->L, 17);
373 pmicdata->L += pmicdata->R;
374 pmicdata->R ^= ((pmicdata->L & 0xff00ff00) >> 8) | ((pmicdata->L & 0x00ff00ff) << 8);
375 pmicdata->L += pmicdata->R;
376 pmicdata->R ^= ROL32(pmicdata->L, 3);
377 pmicdata->L += pmicdata->R;
378 pmicdata->R ^= ROR32(pmicdata->L, 2);
379 pmicdata->L += pmicdata->R;
380 /* Clear the buffer */
382 pmicdata->nBytesInM = 0;
386 void rtw_secmicappend(struct mic_data *pmicdata, u8 *src, u32 nbytes)
390 rtw_secmicappendbyte(pmicdata, *src++);
395 void rtw_secgetmic(struct mic_data *pmicdata, u8 *dst)
397 /* Append the minimum padding */
398 rtw_secmicappendbyte(pmicdata, 0x5a);
399 rtw_secmicappendbyte(pmicdata, 0);
400 rtw_secmicappendbyte(pmicdata, 0);
401 rtw_secmicappendbyte(pmicdata, 0);
402 rtw_secmicappendbyte(pmicdata, 0);
403 /* and then zeroes until the length is a multiple of 4 */
404 while (pmicdata->nBytesInM != 0) {
405 rtw_secmicappendbyte(pmicdata, 0);
407 /* The appendByte function has already computed the result. */
408 secmicputuint32(dst, pmicdata->L);
409 secmicputuint32(dst+4, pmicdata->R);
410 /* Reset to the empty message. */
411 secmicclear(pmicdata);
415 void rtw_seccalctkipmic(u8 *key, u8 *header, u8 *data, u32 data_len, u8 *mic_code, u8 pri)
418 struct mic_data micdata;
419 u8 priority[4] = {0x0, 0x0, 0x0, 0x0};
421 rtw_secmicsetkey(&micdata, key);
424 /* Michael MIC pseudo header: DA, SA, 3 x 0, Priority */
425 if (header[1]&1) { /* ToDS == 1 */
426 rtw_secmicappend(&micdata, &header[16], 6); /* DA */
427 if (header[1]&2) /* From Ds == 1 */
428 rtw_secmicappend(&micdata, &header[24], 6);
430 rtw_secmicappend(&micdata, &header[10], 6);
431 } else { /* ToDS == 0 */
432 rtw_secmicappend(&micdata, &header[4], 6); /* DA */
433 if (header[1]&2) /* From Ds == 1 */
434 rtw_secmicappend(&micdata, &header[16], 6);
436 rtw_secmicappend(&micdata, &header[10], 6);
438 rtw_secmicappend(&micdata, &priority[0], 4);
441 rtw_secmicappend(&micdata, data, data_len);
443 rtw_secgetmic(&micdata, mic_code);
446 /* macros for extraction/creation of unsigned char/unsigned short values */
447 #define RotR1(v16) ((((v16) >> 1) & 0x7FFF) ^ (((v16) & 1) << 15))
448 #define Lo8(v16) ((u8)((v16) & 0x00FF))
449 #define Hi8(v16) ((u8)(((v16) >> 8) & 0x00FF))
450 #define Lo16(v32) ((u16)((v32) & 0xFFFF))
451 #define Hi16(v32) ((u16)(((v32) >> 16) & 0xFFFF))
452 #define Mk16(hi, lo) ((lo) ^ (((u16)(hi)) << 8))
454 /* select the Nth 16-bit word of the temporal key unsigned char array TK[] */
455 #define TK16(N) Mk16(tk[2*(N)+1], tk[2*(N)])
457 /* S-box lookup: 16 bits --> 16 bits */
458 #define _S_(v16) (Sbox1[0][Lo8(v16)] ^ Sbox1[1][Hi8(v16)])
460 /* fixed algorithm "parameters" */
461 #define PHASE1_LOOP_CNT 8 /* this needs to be "big enough" */
462 #define TA_SIZE 6 /* 48-bit transmitter address */
463 #define TK_SIZE 16 /* 128-bit temporal key */
464 #define P1K_SIZE 10 /* 80-bit Phase1 key */
465 #define RC4_KEY_SIZE 16 /* 128-bit RC4KEY (104 bits unknown) */
468 /* 2-unsigned char by 2-unsigned char subset of the full AES S-box table */
469 static const unsigned short Sbox1[2][256] = { /* Sbox for hash (can be in ROM) */
471 0xC6A5, 0xF884, 0xEE99, 0xF68D, 0xFF0D, 0xD6BD, 0xDEB1, 0x9154,
472 0x6050, 0x0203, 0xCEA9, 0x567D, 0xE719, 0xB562, 0x4DE6, 0xEC9A,
473 0x8F45, 0x1F9D, 0x8940, 0xFA87, 0xEF15, 0xB2EB, 0x8EC9, 0xFB0B,
474 0x41EC, 0xB367, 0x5FFD, 0x45EA, 0x23BF, 0x53F7, 0xE496, 0x9B5B,
475 0x75C2, 0xE11C, 0x3DAE, 0x4C6A, 0x6C5A, 0x7E41, 0xF502, 0x834F,
476 0x685C, 0x51F4, 0xD134, 0xF908, 0xE293, 0xAB73, 0x6253, 0x2A3F,
477 0x080C, 0x9552, 0x4665, 0x9D5E, 0x3028, 0x37A1, 0x0A0F, 0x2FB5,
478 0x0E09, 0x2436, 0x1B9B, 0xDF3D, 0xCD26, 0x4E69, 0x7FCD, 0xEA9F,
479 0x121B, 0x1D9E, 0x5874, 0x342E, 0x362D, 0xDCB2, 0xB4EE, 0x5BFB,
480 0xA4F6, 0x764D, 0xB761, 0x7DCE, 0x527B, 0xDD3E, 0x5E71, 0x1397,
481 0xA6F5, 0xB968, 0x0000, 0xC12C, 0x4060, 0xE31F, 0x79C8, 0xB6ED,
482 0xD4BE, 0x8D46, 0x67D9, 0x724B, 0x94DE, 0x98D4, 0xB0E8, 0x854A,
483 0xBB6B, 0xC52A, 0x4FE5, 0xED16, 0x86C5, 0x9AD7, 0x6655, 0x1194,
484 0x8ACF, 0xE910, 0x0406, 0xFE81, 0xA0F0, 0x7844, 0x25BA, 0x4BE3,
485 0xA2F3, 0x5DFE, 0x80C0, 0x058A, 0x3FAD, 0x21BC, 0x7048, 0xF104,
486 0x63DF, 0x77C1, 0xAF75, 0x4263, 0x2030, 0xE51A, 0xFD0E, 0xBF6D,
487 0x814C, 0x1814, 0x2635, 0xC32F, 0xBEE1, 0x35A2, 0x88CC, 0x2E39,
488 0x9357, 0x55F2, 0xFC82, 0x7A47, 0xC8AC, 0xBAE7, 0x322B, 0xE695,
489 0xC0A0, 0x1998, 0x9ED1, 0xA37F, 0x4466, 0x547E, 0x3BAB, 0x0B83,
490 0x8CCA, 0xC729, 0x6BD3, 0x283C, 0xA779, 0xBCE2, 0x161D, 0xAD76,
491 0xDB3B, 0x6456, 0x744E, 0x141E, 0x92DB, 0x0C0A, 0x486C, 0xB8E4,
492 0x9F5D, 0xBD6E, 0x43EF, 0xC4A6, 0x39A8, 0x31A4, 0xD337, 0xF28B,
493 0xD532, 0x8B43, 0x6E59, 0xDAB7, 0x018C, 0xB164, 0x9CD2, 0x49E0,
494 0xD8B4, 0xACFA, 0xF307, 0xCF25, 0xCAAF, 0xF48E, 0x47E9, 0x1018,
495 0x6FD5, 0xF088, 0x4A6F, 0x5C72, 0x3824, 0x57F1, 0x73C7, 0x9751,
496 0xCB23, 0xA17C, 0xE89C, 0x3E21, 0x96DD, 0x61DC, 0x0D86, 0x0F85,
497 0xE090, 0x7C42, 0x71C4, 0xCCAA, 0x90D8, 0x0605, 0xF701, 0x1C12,
498 0xC2A3, 0x6A5F, 0xAEF9, 0x69D0, 0x1791, 0x9958, 0x3A27, 0x27B9,
499 0xD938, 0xEB13, 0x2BB3, 0x2233, 0xD2BB, 0xA970, 0x0789, 0x33A7,
500 0x2DB6, 0x3C22, 0x1592, 0xC920, 0x8749, 0xAAFF, 0x5078, 0xA57A,
501 0x038F, 0x59F8, 0x0980, 0x1A17, 0x65DA, 0xD731, 0x84C6, 0xD0B8,
502 0x82C3, 0x29B0, 0x5A77, 0x1E11, 0x7BCB, 0xA8FC, 0x6DD6, 0x2C3A,
506 { /* second half of table is unsigned char-reversed version of first! */
507 0xA5C6, 0x84F8, 0x99EE, 0x8DF6, 0x0DFF, 0xBDD6, 0xB1DE, 0x5491,
508 0x5060, 0x0302, 0xA9CE, 0x7D56, 0x19E7, 0x62B5, 0xE64D, 0x9AEC,
509 0x458F, 0x9D1F, 0x4089, 0x87FA, 0x15EF, 0xEBB2, 0xC98E, 0x0BFB,
510 0xEC41, 0x67B3, 0xFD5F, 0xEA45, 0xBF23, 0xF753, 0x96E4, 0x5B9B,
511 0xC275, 0x1CE1, 0xAE3D, 0x6A4C, 0x5A6C, 0x417E, 0x02F5, 0x4F83,
512 0x5C68, 0xF451, 0x34D1, 0x08F9, 0x93E2, 0x73AB, 0x5362, 0x3F2A,
513 0x0C08, 0x5295, 0x6546, 0x5E9D, 0x2830, 0xA137, 0x0F0A, 0xB52F,
514 0x090E, 0x3624, 0x9B1B, 0x3DDF, 0x26CD, 0x694E, 0xCD7F, 0x9FEA,
515 0x1B12, 0x9E1D, 0x7458, 0x2E34, 0x2D36, 0xB2DC, 0xEEB4, 0xFB5B,
516 0xF6A4, 0x4D76, 0x61B7, 0xCE7D, 0x7B52, 0x3EDD, 0x715E, 0x9713,
517 0xF5A6, 0x68B9, 0x0000, 0x2CC1, 0x6040, 0x1FE3, 0xC879, 0xEDB6,
518 0xBED4, 0x468D, 0xD967, 0x4B72, 0xDE94, 0xD498, 0xE8B0, 0x4A85,
519 0x6BBB, 0x2AC5, 0xE54F, 0x16ED, 0xC586, 0xD79A, 0x5566, 0x9411,
520 0xCF8A, 0x10E9, 0x0604, 0x81FE, 0xF0A0, 0x4478, 0xBA25, 0xE34B,
521 0xF3A2, 0xFE5D, 0xC080, 0x8A05, 0xAD3F, 0xBC21, 0x4870, 0x04F1,
522 0xDF63, 0xC177, 0x75AF, 0x6342, 0x3020, 0x1AE5, 0x0EFD, 0x6DBF,
523 0x4C81, 0x1418, 0x3526, 0x2FC3, 0xE1BE, 0xA235, 0xCC88, 0x392E,
524 0x5793, 0xF255, 0x82FC, 0x477A, 0xACC8, 0xE7BA, 0x2B32, 0x95E6,
525 0xA0C0, 0x9819, 0xD19E, 0x7FA3, 0x6644, 0x7E54, 0xAB3B, 0x830B,
526 0xCA8C, 0x29C7, 0xD36B, 0x3C28, 0x79A7, 0xE2BC, 0x1D16, 0x76AD,
527 0x3BDB, 0x5664, 0x4E74, 0x1E14, 0xDB92, 0x0A0C, 0x6C48, 0xE4B8,
528 0x5D9F, 0x6EBD, 0xEF43, 0xA6C4, 0xA839, 0xA431, 0x37D3, 0x8BF2,
529 0x32D5, 0x438B, 0x596E, 0xB7DA, 0x8C01, 0x64B1, 0xD29C, 0xE049,
530 0xB4D8, 0xFAAC, 0x07F3, 0x25CF, 0xAFCA, 0x8EF4, 0xE947, 0x1810,
531 0xD56F, 0x88F0, 0x6F4A, 0x725C, 0x2438, 0xF157, 0xC773, 0x5197,
532 0x23CB, 0x7CA1, 0x9CE8, 0x213E, 0xDD96, 0xDC61, 0x860D, 0x850F,
533 0x90E0, 0x427C, 0xC471, 0xAACC, 0xD890, 0x0506, 0x01F7, 0x121C,
534 0xA3C2, 0x5F6A, 0xF9AE, 0xD069, 0x9117, 0x5899, 0x273A, 0xB927,
535 0x38D9, 0x13EB, 0xB32B, 0x3322, 0xBBD2, 0x70A9, 0x8907, 0xA733,
536 0xB62D, 0x223C, 0x9215, 0x20C9, 0x4987, 0xFFAA, 0x7850, 0x7AA5,
537 0x8F03, 0xF859, 0x8009, 0x171A, 0xDA65, 0x31D7, 0xC684, 0xB8D0,
538 0xC382, 0xB029, 0x775A, 0x111E, 0xCB7B, 0xFCA8, 0xD66D, 0x3A2C,
543 **********************************************************************
544 * Routine: Phase 1 -- generate P1K, given TA, TK, IV32
547 * tk[] = temporal key [128 bits]
548 * ta[] = transmitter's MAC address [ 48 bits]
549 * iv32 = upper 32 bits of IV [ 32 bits]
551 * p1k[] = Phase 1 key [ 80 bits]
554 * This function only needs to be called every 2**16 packets,
555 * although in theory it could be called every packet.
557 **********************************************************************
559 static void phase1(u16 *p1k, const u8 *tk, const u8 *ta, u32 iv32)
563 /* Initialize the 80 bits of P1K[] from IV32 and TA[0..5] */
566 p1k[2] = Mk16(ta[1], ta[0]); /* use TA[] as little-endian */
567 p1k[3] = Mk16(ta[3], ta[2]);
568 p1k[4] = Mk16(ta[5], ta[4]);
570 /* Now compute an unbalanced Feistel cipher with 80-bit block */
571 /* size on the 80-bit block P1K[], using the 128-bit key TK[] */
572 for (i = 0; i < PHASE1_LOOP_CNT; i++) {
573 /* Each add operation here is mod 2**16 */
574 p1k[0] += _S_(p1k[4] ^ TK16((i&1)+0));
575 p1k[1] += _S_(p1k[0] ^ TK16((i&1)+2));
576 p1k[2] += _S_(p1k[1] ^ TK16((i&1)+4));
577 p1k[3] += _S_(p1k[2] ^ TK16((i&1)+6));
578 p1k[4] += _S_(p1k[3] ^ TK16((i&1)+0));
579 p1k[4] += (unsigned short)i; /* avoid "slide attacks" */
585 **********************************************************************
586 * Routine: Phase 2 -- generate RC4KEY, given TK, P1K, IV16
589 * tk[] = Temporal key [128 bits]
590 * p1k[] = Phase 1 output key [ 80 bits]
591 * iv16 = low 16 bits of IV counter [ 16 bits]
593 * rc4key[] = the key used to encrypt the packet [128 bits]
596 * The value {TA, IV32, IV16} for Phase1/Phase2 must be unique
597 * across all packets using the same key TK value. Then, for a
598 * given value of TK[], this TKIP48 construction guarantees that
599 * the final RC4KEY value is unique across all packets.
601 * Suggested implementation optimization: if PPK[] is "overlaid"
602 * appropriately on RC4KEY[], there is no need for the final
603 * for loop below that copies the PPK[] result into RC4KEY[].
605 **********************************************************************
607 static void phase2(u8 *rc4key, const u8 *tk, const u16 *p1k, u16 iv16)
610 u16 PPK[6]; /* temporary key for mixing */
612 /* Note: all adds in the PPK[] equations below are mod 2**16 */
613 for (i = 0; i < 5; i++)
614 PPK[i] = p1k[i]; /* first, copy P1K to PPK */
616 PPK[5] = p1k[4]+iv16; /* next, add in IV16 */
618 /* Bijective non-linear mixing of the 96 bits of PPK[0..5] */
619 PPK[0] += _S_(PPK[5] ^ TK16(0)); /* Mix key in each "round" */
620 PPK[1] += _S_(PPK[0] ^ TK16(1));
621 PPK[2] += _S_(PPK[1] ^ TK16(2));
622 PPK[3] += _S_(PPK[2] ^ TK16(3));
623 PPK[4] += _S_(PPK[3] ^ TK16(4));
624 PPK[5] += _S_(PPK[4] ^ TK16(5)); /* Total # S-box lookups == 6 */
626 /* Final sweep: bijective, "linear". Rotates kill LSB correlations */
627 PPK[0] += RotR1(PPK[5] ^ TK16(6));
628 PPK[1] += RotR1(PPK[0] ^ TK16(7)); /* Use all of TK[] in Phase2 */
629 PPK[2] += RotR1(PPK[1]);
630 PPK[3] += RotR1(PPK[2]);
631 PPK[4] += RotR1(PPK[3]);
632 PPK[5] += RotR1(PPK[4]);
633 /* Note: At this point, for a given key TK[0..15], the 96-bit output */
634 /* value PPK[0..5] is guaranteed to be unique, as a function */
635 /* of the 96-bit "input" value {TA, IV32, IV16}. That is, P1K */
636 /* is now a keyed permutation of {TA, IV32, IV16}. */
638 /* Set RC4KEY[0..3], which includes "cleartext" portion of RC4 key */
639 rc4key[0] = Hi8(iv16); /* RC4KEY[0..2] is the WEP IV */
640 rc4key[1] = (Hi8(iv16) | 0x20) & 0x7F; /* Help avoid weak (FMS) keys */
641 rc4key[2] = Lo8(iv16);
642 rc4key[3] = Lo8((PPK[5] ^ TK16(0)) >> 1);
645 /* Copy 96 bits of PPK[0..5] to RC4KEY[4..15] (little-endian) */
646 for (i = 0; i < 6; i++) {
647 rc4key[4+2*i] = Lo8(PPK[i]);
648 rc4key[5+2*i] = Hi8(PPK[i]);
653 /* The hlen isn't include the IV */
654 u32 rtw_tkip_encrypt(struct adapter *padapter, u8 *pxmitframe)
661 u8 hw_hdr_offset = 0;
662 struct arc4context mycontext;
663 sint curfragnum, length;
665 u8 *pframe, *payload, *iv, *prwskey;
666 union pn48 dot11txpn;
667 struct pkt_attrib *pattrib = &((struct xmit_frame *)pxmitframe)->attrib;
668 struct security_priv *psecuritypriv = &padapter->securitypriv;
669 struct xmit_priv *pxmitpriv = &padapter->xmitpriv;
672 if (((struct xmit_frame *)pxmitframe)->buf_addr == NULL)
675 hw_hdr_offset = TXDESC_OFFSET;
676 pframe = ((struct xmit_frame *)pxmitframe)->buf_addr + hw_hdr_offset;
678 /* 4 start to encrypt each fragment */
679 if (pattrib->encrypt == _TKIP_) {
682 RT_TRACE(_module_rtl871x_security_c_, _drv_err_, ("%s: stainfo!= NULL!!!\n", __func__));
684 if (IS_MCAST(pattrib->ra))
685 prwskey = psecuritypriv->dot118021XGrpKey[psecuritypriv->dot118021XGrpKeyid].skey;
687 prwskey = pattrib->dot118021x_UncstKey.skey;
689 for (curfragnum = 0; curfragnum < pattrib->nr_frags; curfragnum++) {
690 iv = pframe+pattrib->hdrlen;
691 payload = pframe+pattrib->iv_len+pattrib->hdrlen;
693 GET_TKIP_PN(iv, dot11txpn);
695 pnl = (u16)(dot11txpn.val);
696 pnh = (u32)(dot11txpn.val>>16);
698 phase1((u16 *)&ttkey[0], prwskey, &pattrib->ta[0], pnh);
700 phase2(&rc4key[0], prwskey, (u16 *)&ttkey[0], pnl);
702 if ((curfragnum+1) == pattrib->nr_frags) { /* 4 the last fragment */
703 length = pattrib->last_txcmdsz-pattrib->hdrlen-pattrib->iv_len-pattrib->icv_len;
704 RT_TRACE(_module_rtl871x_security_c_, _drv_info_, ("pattrib->iv_len =%x, pattrib->icv_len =%x\n", pattrib->iv_len, pattrib->icv_len));
705 *((__le32 *)crc) = getcrc32(payload, length);/* modified by Amy*/
707 arcfour_init(&mycontext, rc4key, 16);
708 arcfour_encrypt(&mycontext, payload, payload, length);
709 arcfour_encrypt(&mycontext, payload+length, crc, 4);
712 length = pxmitpriv->frag_len-pattrib->hdrlen-pattrib->iv_len-pattrib->icv_len;
713 *((__le32 *)crc) = getcrc32(payload, length);/* modified by Amy*/
714 arcfour_init(&mycontext, rc4key, 16);
715 arcfour_encrypt(&mycontext, payload, payload, length);
716 arcfour_encrypt(&mycontext, payload+length, crc, 4);
718 pframe += pxmitpriv->frag_len;
719 pframe = (u8 *)round_up((SIZE_PTR)(pframe), 4);
723 TKIP_SW_ENC_CNT_INC(psecuritypriv, pattrib->ra);
730 /* The hlen isn't include the IV */
731 u32 rtw_tkip_decrypt(struct adapter *padapter, u8 *precvframe)
738 struct arc4context mycontext;
741 u8 *pframe, *payload, *iv, *prwskey;
742 union pn48 dot11txpn;
743 struct sta_info *stainfo;
744 struct rx_pkt_attrib *prxattrib = &((union recv_frame *)precvframe)->u.hdr.attrib;
745 struct security_priv *psecuritypriv = &padapter->securitypriv;
748 pframe = (unsigned char *)((union recv_frame *)precvframe)->u.hdr.rx_data;
750 /* 4 start to decrypt recvframe */
751 if (prxattrib->encrypt == _TKIP_) {
752 stainfo = rtw_get_stainfo(&padapter->stapriv, &prxattrib->ta[0]);
753 if (stainfo != NULL) {
754 if (IS_MCAST(prxattrib->ra)) {
755 static unsigned long start;
756 static u32 no_gkey_bc_cnt;
757 static u32 no_gkey_mc_cnt;
759 if (!psecuritypriv->binstallGrpkey) {
765 if (is_broadcast_mac_addr(prxattrib->ra))
770 if (jiffies_to_msecs(jiffies - start) > 1000) {
771 if (no_gkey_bc_cnt || no_gkey_mc_cnt) {
772 DBG_871X_LEVEL(_drv_always_, FUNC_ADPT_FMT" no_gkey_bc_cnt:%u, no_gkey_mc_cnt:%u\n",
773 FUNC_ADPT_ARG(padapter), no_gkey_bc_cnt, no_gkey_mc_cnt);
782 if (no_gkey_bc_cnt || no_gkey_mc_cnt) {
783 DBG_871X_LEVEL(_drv_always_, FUNC_ADPT_FMT" gkey installed. no_gkey_bc_cnt:%u, no_gkey_mc_cnt:%u\n",
784 FUNC_ADPT_ARG(padapter), no_gkey_bc_cnt, no_gkey_mc_cnt);
790 prwskey = psecuritypriv->dot118021XGrpKey[prxattrib->key_index].skey;
792 prwskey = &stainfo->dot118021x_UncstKey.skey[0];
795 iv = pframe+prxattrib->hdrlen;
796 payload = pframe+prxattrib->iv_len+prxattrib->hdrlen;
797 length = ((union recv_frame *)precvframe)->u.hdr.len-prxattrib->hdrlen-prxattrib->iv_len;
799 GET_TKIP_PN(iv, dot11txpn);
801 pnl = (u16)(dot11txpn.val);
802 pnh = (u32)(dot11txpn.val>>16);
804 phase1((u16 *)&ttkey[0], prwskey, &prxattrib->ta[0], pnh);
805 phase2(&rc4key[0], prwskey, (unsigned short *)&ttkey[0], pnl);
807 /* 4 decrypt payload include icv */
809 arcfour_init(&mycontext, rc4key, 16);
810 arcfour_encrypt(&mycontext, payload, payload, length);
812 *((u32 *)crc) = le32_to_cpu(getcrc32(payload, length-4));
814 if (crc[3] != payload[length-1] || crc[2] != payload[length-2] || crc[1] != payload[length-3] || crc[0] != payload[length-4]) {
815 RT_TRACE(_module_rtl871x_security_c_,
817 ("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",
818 crc[3], payload[length - 1],
819 crc[2], payload[length - 2],
820 crc[1], payload[length - 3],
821 crc[0], payload[length - 4]));
825 TKIP_SW_DEC_CNT_INC(psecuritypriv, prxattrib->ra);
827 RT_TRACE(_module_rtl871x_security_c_, _drv_err_, ("%s: stainfo == NULL!!!\n", __func__));
836 /* 3 =====AES related ===== */
840 #define MAX_MSG_SIZE 2048
841 /*****************************/
842 /******** SBOX Table *********/
843 /*****************************/
845 static const u8 sbox_table[256] = {
846 0x63, 0x7c, 0x77, 0x7b, 0xf2, 0x6b, 0x6f, 0xc5,
847 0x30, 0x01, 0x67, 0x2b, 0xfe, 0xd7, 0xab, 0x76,
848 0xca, 0x82, 0xc9, 0x7d, 0xfa, 0x59, 0x47, 0xf0,
849 0xad, 0xd4, 0xa2, 0xaf, 0x9c, 0xa4, 0x72, 0xc0,
850 0xb7, 0xfd, 0x93, 0x26, 0x36, 0x3f, 0xf7, 0xcc,
851 0x34, 0xa5, 0xe5, 0xf1, 0x71, 0xd8, 0x31, 0x15,
852 0x04, 0xc7, 0x23, 0xc3, 0x18, 0x96, 0x05, 0x9a,
853 0x07, 0x12, 0x80, 0xe2, 0xeb, 0x27, 0xb2, 0x75,
854 0x09, 0x83, 0x2c, 0x1a, 0x1b, 0x6e, 0x5a, 0xa0,
855 0x52, 0x3b, 0xd6, 0xb3, 0x29, 0xe3, 0x2f, 0x84,
856 0x53, 0xd1, 0x00, 0xed, 0x20, 0xfc, 0xb1, 0x5b,
857 0x6a, 0xcb, 0xbe, 0x39, 0x4a, 0x4c, 0x58, 0xcf,
858 0xd0, 0xef, 0xaa, 0xfb, 0x43, 0x4d, 0x33, 0x85,
859 0x45, 0xf9, 0x02, 0x7f, 0x50, 0x3c, 0x9f, 0xa8,
860 0x51, 0xa3, 0x40, 0x8f, 0x92, 0x9d, 0x38, 0xf5,
861 0xbc, 0xb6, 0xda, 0x21, 0x10, 0xff, 0xf3, 0xd2,
862 0xcd, 0x0c, 0x13, 0xec, 0x5f, 0x97, 0x44, 0x17,
863 0xc4, 0xa7, 0x7e, 0x3d, 0x64, 0x5d, 0x19, 0x73,
864 0x60, 0x81, 0x4f, 0xdc, 0x22, 0x2a, 0x90, 0x88,
865 0x46, 0xee, 0xb8, 0x14, 0xde, 0x5e, 0x0b, 0xdb,
866 0xe0, 0x32, 0x3a, 0x0a, 0x49, 0x06, 0x24, 0x5c,
867 0xc2, 0xd3, 0xac, 0x62, 0x91, 0x95, 0xe4, 0x79,
868 0xe7, 0xc8, 0x37, 0x6d, 0x8d, 0xd5, 0x4e, 0xa9,
869 0x6c, 0x56, 0xf4, 0xea, 0x65, 0x7a, 0xae, 0x08,
870 0xba, 0x78, 0x25, 0x2e, 0x1c, 0xa6, 0xb4, 0xc6,
871 0xe8, 0xdd, 0x74, 0x1f, 0x4b, 0xbd, 0x8b, 0x8a,
872 0x70, 0x3e, 0xb5, 0x66, 0x48, 0x03, 0xf6, 0x0e,
873 0x61, 0x35, 0x57, 0xb9, 0x86, 0xc1, 0x1d, 0x9e,
874 0xe1, 0xf8, 0x98, 0x11, 0x69, 0xd9, 0x8e, 0x94,
875 0x9b, 0x1e, 0x87, 0xe9, 0xce, 0x55, 0x28, 0xdf,
876 0x8c, 0xa1, 0x89, 0x0d, 0xbf, 0xe6, 0x42, 0x68,
877 0x41, 0x99, 0x2d, 0x0f, 0xb0, 0x54, 0xbb, 0x16
880 /*****************************/
881 /**** Function Prototypes ****/
882 /*****************************/
884 static void bitwise_xor(u8 *ina, u8 *inb, u8 *out);
885 static void construct_mic_iv(
893 );/* add for CONFIG_IEEE80211W, none 11w also can use */
894 static void construct_mic_header1(
899 );/* add for CONFIG_IEEE80211W, none 11w also can use */
900 static void construct_mic_header2(
906 static void construct_ctr_preload(
914 );/* add for CONFIG_IEEE80211W, none 11w also can use */
915 static void xor_128(u8 *a, u8 *b, u8 *out);
916 static void xor_32(u8 *a, u8 *b, u8 *out);
917 static u8 sbox(u8 a);
918 static void next_key(u8 *key, sint round);
919 static void byte_sub(u8 *in, u8 *out);
920 static void shift_row(u8 *in, u8 *out);
921 static void mix_column(u8 *in, u8 *out);
922 static void aes128k128d(u8 *key, u8 *data, u8 *ciphertext);
925 /****************************************/
927 /* Performs a 128 bit AES encrypt with */
929 /****************************************/
930 static void xor_128(u8 *a, u8 *b, u8 *out)
934 for (i = 0; i < 16; i++) {
935 out[i] = a[i] ^ b[i];
940 static void xor_32(u8 *a, u8 *b, u8 *out)
944 for (i = 0; i < 4; i++) {
945 out[i] = a[i] ^ b[i];
952 return sbox_table[(sint)a];
956 static void next_key(u8 *key, sint round)
960 static const u8 rcon_table[12] = {
961 0x01, 0x02, 0x04, 0x08,
962 0x10, 0x20, 0x40, 0x80,
963 0x1b, 0x36, 0x36, 0x36
965 sbox_key[0] = sbox(key[13]);
966 sbox_key[1] = sbox(key[14]);
967 sbox_key[2] = sbox(key[15]);
968 sbox_key[3] = sbox(key[12]);
970 rcon = rcon_table[round];
972 xor_32(&key[0], sbox_key, &key[0]);
973 key[0] = key[0] ^ rcon;
975 xor_32(&key[4], &key[0], &key[4]);
976 xor_32(&key[8], &key[4], &key[8]);
977 xor_32(&key[12], &key[8], &key[12]);
981 static void byte_sub(u8 *in, u8 *out)
985 for (i = 0; i < 16; i++) {
986 out[i] = sbox(in[i]);
991 static void shift_row(u8 *in, u8 *out)
1012 static void mix_column(u8 *in, u8 *out)
1024 for (i = 0; i < 4; i++) {
1025 if ((in[i] & 0x80) == 0x80)
1031 swap_halfs[0] = in[2]; /* Swap halfs */
1032 swap_halfs[1] = in[3];
1033 swap_halfs[2] = in[0];
1034 swap_halfs[3] = in[1];
1036 rotl[0] = in[3]; /* Rotate left 8 bits */
1041 andf7[0] = in[0] & 0x7f;
1042 andf7[1] = in[1] & 0x7f;
1043 andf7[2] = in[2] & 0x7f;
1044 andf7[3] = in[3] & 0x7f;
1046 for (i = 3; i > 0; i--) { /* logical shift left 1 bit */
1047 andf7[i] = andf7[i] << 1;
1048 if ((andf7[i-1] & 0x80) == 0x80)
1049 andf7[i] = (andf7[i] | 0x01);
1051 andf7[0] = andf7[0] << 1;
1052 andf7[0] = andf7[0] & 0xfe;
1054 xor_32(add1b, andf7, add1bf7);
1056 xor_32(in, add1bf7, rotr);
1058 temp[0] = rotr[0]; /* Rotate right 8 bits */
1064 xor_32(add1bf7, rotr, temp);
1065 xor_32(swap_halfs, rotl, tempb);
1066 xor_32(temp, tempb, out);
1069 static void aes128k128d(u8 *key, u8 *data, u8 *ciphertext)
1073 u8 intermediatea[16];
1074 u8 intermediateb[16];
1077 for (i = 0; i < 16; i++)
1078 round_key[i] = key[i];
1080 for (round = 0; round < 11; round++) {
1082 xor_128(round_key, data, ciphertext);
1083 next_key(round_key, round);
1084 } else if (round == 10) {
1085 byte_sub(ciphertext, intermediatea);
1086 shift_row(intermediatea, intermediateb);
1087 xor_128(intermediateb, round_key, ciphertext);
1088 } else { /* 1 - 9 */
1089 byte_sub(ciphertext, intermediatea);
1090 shift_row(intermediatea, intermediateb);
1091 mix_column(&intermediateb[0], &intermediatea[0]);
1092 mix_column(&intermediateb[4], &intermediatea[4]);
1093 mix_column(&intermediateb[8], &intermediatea[8]);
1094 mix_column(&intermediateb[12], &intermediatea[12]);
1095 xor_128(intermediatea, round_key, ciphertext);
1096 next_key(round_key, round);
1102 /************************************************/
1103 /* construct_mic_iv() */
1104 /* Builds the MIC IV from header fields and PN */
1105 /* Baron think the function is construct CCM */
1107 /************************************************/
1108 static void construct_mic_iv(
1113 uint payload_length,
1115 uint frtype/* add for CONFIG_IEEE80211W, none 11w also can use */
1122 if (qc_exists && a4_exists)
1123 mic_iv[1] = mpdu[30] & 0x0f; /* QoS_TC */
1125 if (qc_exists && !a4_exists)
1126 mic_iv[1] = mpdu[24] & 0x0f; /* mute bits 7-4 */
1131 /* 802.11w management frame should set management bit(4) */
1132 if (frtype == WIFI_MGT_TYPE)
1133 mic_iv[1] |= BIT(4);
1135 for (i = 2; i < 8; i++)
1136 mic_iv[i] = mpdu[i + 8]; /* mic_iv[2:7] = A2[0:5] = mpdu[10:15] */
1137 #ifdef CONSISTENT_PN_ORDER
1138 for (i = 8; i < 14; i++)
1139 mic_iv[i] = pn_vector[i - 8]; /* mic_iv[8:13] = PN[0:5] */
1141 for (i = 8; i < 14; i++)
1142 mic_iv[i] = pn_vector[13 - i]; /* mic_iv[8:13] = PN[5:0] */
1144 mic_iv[14] = (unsigned char) (payload_length / 256);
1145 mic_iv[15] = (unsigned char) (payload_length % 256);
1149 /************************************************/
1150 /* construct_mic_header1() */
1151 /* Builds the first MIC header block from */
1152 /* header fields. */
1153 /* Build AAD SC, A1, A2 */
1154 /************************************************/
1155 static void construct_mic_header1(
1159 uint frtype/* add for CONFIG_IEEE80211W, none 11w also can use */
1162 mic_header1[0] = (u8)((header_length - 2) / 256);
1163 mic_header1[1] = (u8)((header_length - 2) % 256);
1165 /* 802.11w management frame don't AND subtype bits 4, 5, 6 of frame control field */
1166 if (frtype == WIFI_MGT_TYPE)
1167 mic_header1[2] = mpdu[0];
1169 mic_header1[2] = mpdu[0] & 0xcf; /* Mute CF poll & CF ack bits */
1171 mic_header1[3] = mpdu[1] & 0xc7; /* Mute retry, more data and pwr mgt bits */
1172 mic_header1[4] = mpdu[4]; /* A1 */
1173 mic_header1[5] = mpdu[5];
1174 mic_header1[6] = mpdu[6];
1175 mic_header1[7] = mpdu[7];
1176 mic_header1[8] = mpdu[8];
1177 mic_header1[9] = mpdu[9];
1178 mic_header1[10] = mpdu[10]; /* A2 */
1179 mic_header1[11] = mpdu[11];
1180 mic_header1[12] = mpdu[12];
1181 mic_header1[13] = mpdu[13];
1182 mic_header1[14] = mpdu[14];
1183 mic_header1[15] = mpdu[15];
1187 /************************************************/
1188 /* construct_mic_header2() */
1189 /* Builds the last MIC header block from */
1190 /* header fields. */
1191 /************************************************/
1192 static void construct_mic_header2(
1201 for (i = 0; i < 16; i++)
1202 mic_header2[i] = 0x00;
1204 mic_header2[0] = mpdu[16]; /* A3 */
1205 mic_header2[1] = mpdu[17];
1206 mic_header2[2] = mpdu[18];
1207 mic_header2[3] = mpdu[19];
1208 mic_header2[4] = mpdu[20];
1209 mic_header2[5] = mpdu[21];
1211 mic_header2[6] = 0x00;
1212 mic_header2[7] = 0x00; /* mpdu[23]; */
1215 if (!qc_exists && a4_exists) {
1216 for (i = 0; i < 6; i++)
1217 mic_header2[8+i] = mpdu[24+i]; /* A4 */
1220 if (qc_exists && !a4_exists) {
1221 mic_header2[8] = mpdu[24] & 0x0f; /* mute bits 15 - 4 */
1222 mic_header2[9] = mpdu[25] & 0x00;
1225 if (qc_exists && a4_exists) {
1226 for (i = 0; i < 6; i++)
1227 mic_header2[8+i] = mpdu[24+i]; /* A4 */
1229 mic_header2[14] = mpdu[30] & 0x0f;
1230 mic_header2[15] = mpdu[31] & 0x00;
1234 /************************************************/
1235 /* construct_mic_header2() */
1236 /* Builds the last MIC header block from */
1237 /* header fields. */
1238 /* Baron think the function is construct CCM */
1240 /************************************************/
1241 static void construct_ctr_preload(
1248 uint frtype /* add for CONFIG_IEEE80211W, none 11w also can use */
1253 for (i = 0; i < 16; i++)
1254 ctr_preload[i] = 0x00;
1257 ctr_preload[0] = 0x01; /* flag */
1258 if (qc_exists && a4_exists)
1259 ctr_preload[1] = mpdu[30] & 0x0f; /* QoC_Control */
1260 if (qc_exists && !a4_exists)
1261 ctr_preload[1] = mpdu[24] & 0x0f;
1263 /* 802.11w management frame should set management bit(4) */
1264 if (frtype == WIFI_MGT_TYPE)
1265 ctr_preload[1] |= BIT(4);
1267 for (i = 2; i < 8; i++)
1268 ctr_preload[i] = mpdu[i + 8]; /* ctr_preload[2:7] = A2[0:5] = mpdu[10:15] */
1269 #ifdef CONSISTENT_PN_ORDER
1270 for (i = 8; i < 14; i++)
1271 ctr_preload[i] = pn_vector[i - 8]; /* ctr_preload[8:13] = PN[0:5] */
1273 for (i = 8; i < 14; i++)
1274 ctr_preload[i] = pn_vector[13 - i]; /* ctr_preload[8:13] = PN[5:0] */
1276 ctr_preload[14] = (unsigned char) (c / 256); /* Ctr */
1277 ctr_preload[15] = (unsigned char) (c % 256);
1281 /************************************/
1283 /* A 128 bit, bitwise exclusive or */
1284 /************************************/
1285 static void bitwise_xor(u8 *ina, u8 *inb, u8 *out)
1289 for (i = 0; i < 16; i++) {
1290 out[i] = ina[i] ^ inb[i];
1295 static sint aes_cipher(u8 *key, uint hdrlen,
1296 u8 *pframe, uint plen)
1298 uint qc_exists, a4_exists, i, j, payload_remainder,
1299 num_blocks, payload_index;
1307 /* Intermediate Buffers */
1308 u8 chain_buffer[16];
1310 u8 padded_buffer[16];
1312 uint frtype = GetFrameType(pframe);
1313 uint frsubtype = GetFrameSubType(pframe);
1315 frsubtype = frsubtype>>4;
1318 memset((void *)mic_iv, 0, 16);
1319 memset((void *)mic_header1, 0, 16);
1320 memset((void *)mic_header2, 0, 16);
1321 memset((void *)ctr_preload, 0, 16);
1322 memset((void *)chain_buffer, 0, 16);
1323 memset((void *)aes_out, 0, 16);
1324 memset((void *)padded_buffer, 0, 16);
1326 if ((hdrlen == WLAN_HDR_A3_LEN) || (hdrlen == WLAN_HDR_A3_QOS_LEN))
1331 if (((frtype|frsubtype) == WIFI_DATA_CFACK) ||
1332 ((frtype|frsubtype) == WIFI_DATA_CFPOLL) ||
1333 ((frtype|frsubtype) == WIFI_DATA_CFACKPOLL)) {
1335 if (hdrlen != WLAN_HDR_A3_QOS_LEN)
1338 } else if ((frtype == WIFI_DATA) && /* add for CONFIG_IEEE80211W, none 11w also can use */
1339 ((frsubtype == 0x08) ||
1340 (frsubtype == 0x09) ||
1341 (frsubtype == 0x0a) ||
1342 (frsubtype == 0x0b))) {
1343 if (hdrlen != WLAN_HDR_A3_QOS_LEN)
1350 pn_vector[0] = pframe[hdrlen];
1351 pn_vector[1] = pframe[hdrlen+1];
1352 pn_vector[2] = pframe[hdrlen+4];
1353 pn_vector[3] = pframe[hdrlen+5];
1354 pn_vector[4] = pframe[hdrlen+6];
1355 pn_vector[5] = pframe[hdrlen+7];
1361 pframe, /* message, */
1364 frtype /* add for CONFIG_IEEE80211W, none 11w also can use */
1367 construct_mic_header1(
1370 pframe, /* message */
1371 frtype /* add for CONFIG_IEEE80211W, none 11w also can use */
1373 construct_mic_header2(
1375 pframe, /* message, */
1381 payload_remainder = plen % 16;
1382 num_blocks = plen / 16;
1384 /* Find start of payload */
1385 payload_index = (hdrlen + 8);
1388 aes128k128d(key, mic_iv, aes_out);
1389 bitwise_xor(aes_out, mic_header1, chain_buffer);
1390 aes128k128d(key, chain_buffer, aes_out);
1391 bitwise_xor(aes_out, mic_header2, chain_buffer);
1392 aes128k128d(key, chain_buffer, aes_out);
1394 for (i = 0; i < num_blocks; i++) {
1395 bitwise_xor(aes_out, &pframe[payload_index], chain_buffer);
1397 payload_index += 16;
1398 aes128k128d(key, chain_buffer, aes_out);
1401 /* Add on the final payload block if it needs padding */
1402 if (payload_remainder > 0) {
1403 for (j = 0; j < 16; j++)
1404 padded_buffer[j] = 0x00;
1405 for (j = 0; j < payload_remainder; j++) {
1406 padded_buffer[j] = pframe[payload_index++];
1408 bitwise_xor(aes_out, padded_buffer, chain_buffer);
1409 aes128k128d(key, chain_buffer, aes_out);
1412 for (j = 0 ; j < 8; j++)
1413 mic[j] = aes_out[j];
1415 /* Insert MIC into payload */
1416 for (j = 0; j < 8; j++)
1417 pframe[payload_index+j] = mic[j];
1419 payload_index = hdrlen + 8;
1420 for (i = 0; i < num_blocks; i++) {
1421 construct_ctr_preload(
1425 pframe, /* message, */
1429 ); /* add for CONFIG_IEEE80211W, none 11w also can use */
1430 aes128k128d(key, ctr_preload, aes_out);
1431 bitwise_xor(aes_out, &pframe[payload_index], chain_buffer);
1432 for (j = 0; j < 16; j++)
1433 pframe[payload_index++] = chain_buffer[j];
1436 if (payload_remainder > 0) {
1437 /* If there is a short final block, then pad it,*/
1438 /* encrypt it and copy the unpadded part back */
1439 construct_ctr_preload(
1443 pframe, /* message, */
1447 ); /* add for CONFIG_IEEE80211W, none 11w also can use */
1449 for (j = 0; j < 16; j++)
1450 padded_buffer[j] = 0x00;
1451 for (j = 0; j < payload_remainder; j++)
1452 padded_buffer[j] = pframe[payload_index+j];
1454 aes128k128d(key, ctr_preload, aes_out);
1455 bitwise_xor(aes_out, padded_buffer, chain_buffer);
1456 for (j = 0; j < payload_remainder; j++)
1457 pframe[payload_index++] = chain_buffer[j];
1460 /* Encrypt the MIC */
1461 construct_ctr_preload(
1465 pframe, /* message, */
1469 ); /* add for CONFIG_IEEE80211W, none 11w also can use */
1471 for (j = 0; j < 16; j++)
1472 padded_buffer[j] = 0x00;
1473 for (j = 0; j < 8; j++)
1474 padded_buffer[j] = pframe[j+hdrlen+8+plen];
1476 aes128k128d(key, ctr_preload, aes_out);
1477 bitwise_xor(aes_out, padded_buffer, chain_buffer);
1478 for (j = 0; j < 8; j++)
1479 pframe[payload_index++] = chain_buffer[j];
1484 u32 rtw_aes_encrypt(struct adapter *padapter, u8 *pxmitframe)
1489 /* unsigned char message[MAX_MSG_SIZE]; */
1491 /* Intermediate Buffers */
1492 sint curfragnum, length;
1493 u8 *pframe, *prwskey; /* *payload,*iv */
1494 u8 hw_hdr_offset = 0;
1495 struct pkt_attrib *pattrib = &((struct xmit_frame *)pxmitframe)->attrib;
1496 struct security_priv *psecuritypriv = &padapter->securitypriv;
1497 struct xmit_priv *pxmitpriv = &padapter->xmitpriv;
1501 if (((struct xmit_frame *)pxmitframe)->buf_addr == NULL)
1504 hw_hdr_offset = TXDESC_OFFSET;
1505 pframe = ((struct xmit_frame *)pxmitframe)->buf_addr + hw_hdr_offset;
1507 /* 4 start to encrypt each fragment */
1508 if (pattrib->encrypt == _AES_) {
1509 RT_TRACE(_module_rtl871x_security_c_, _drv_err_, ("%s: stainfo!= NULL!!!\n", __func__));
1511 if (IS_MCAST(pattrib->ra))
1512 prwskey = psecuritypriv->dot118021XGrpKey[psecuritypriv->dot118021XGrpKeyid].skey;
1514 prwskey = pattrib->dot118021x_UncstKey.skey;
1516 for (curfragnum = 0; curfragnum < pattrib->nr_frags; curfragnum++) {
1517 if ((curfragnum+1) == pattrib->nr_frags) { /* 4 the last fragment */
1518 length = pattrib->last_txcmdsz-pattrib->hdrlen-pattrib->iv_len-pattrib->icv_len;
1520 aes_cipher(prwskey, pattrib->hdrlen, pframe, length);
1522 length = pxmitpriv->frag_len-pattrib->hdrlen-pattrib->iv_len-pattrib->icv_len;
1524 aes_cipher(prwskey, pattrib->hdrlen, pframe, length);
1525 pframe += pxmitpriv->frag_len;
1526 pframe = (u8 *)round_up((SIZE_PTR)(pframe), 4);
1530 AES_SW_ENC_CNT_INC(psecuritypriv, pattrib->ra);
1535 static sint aes_decipher(u8 *key, uint hdrlen,
1536 u8 *pframe, uint plen)
1538 static u8 message[MAX_MSG_SIZE];
1539 uint qc_exists, a4_exists, i, j, payload_remainder,
1540 num_blocks, payload_index;
1541 sint res = _SUCCESS;
1548 /* Intermediate Buffers */
1549 u8 chain_buffer[16];
1551 u8 padded_buffer[16];
1555 uint frtype = GetFrameType(pframe);
1556 uint frsubtype = GetFrameSubType(pframe);
1558 frsubtype = frsubtype>>4;
1561 memset((void *)mic_iv, 0, 16);
1562 memset((void *)mic_header1, 0, 16);
1563 memset((void *)mic_header2, 0, 16);
1564 memset((void *)ctr_preload, 0, 16);
1565 memset((void *)chain_buffer, 0, 16);
1566 memset((void *)aes_out, 0, 16);
1567 memset((void *)padded_buffer, 0, 16);
1569 /* start to decrypt the payload */
1571 num_blocks = (plen-8) / 16; /* plen including LLC, payload_length and mic) */
1573 payload_remainder = (plen-8) % 16;
1575 pn_vector[0] = pframe[hdrlen];
1576 pn_vector[1] = pframe[hdrlen + 1];
1577 pn_vector[2] = pframe[hdrlen + 4];
1578 pn_vector[3] = pframe[hdrlen + 5];
1579 pn_vector[4] = pframe[hdrlen + 6];
1580 pn_vector[5] = pframe[hdrlen + 7];
1582 if ((hdrlen == WLAN_HDR_A3_LEN) || (hdrlen == WLAN_HDR_A3_QOS_LEN))
1587 if (((frtype|frsubtype) == WIFI_DATA_CFACK) ||
1588 ((frtype|frsubtype) == WIFI_DATA_CFPOLL) ||
1589 ((frtype|frsubtype) == WIFI_DATA_CFACKPOLL)) {
1591 if (hdrlen != WLAN_HDR_A3_QOS_LEN) {
1594 } else if ((frtype == WIFI_DATA) && /* only for data packet . add for CONFIG_IEEE80211W, none 11w also can use */
1595 ((frsubtype == 0x08) ||
1596 (frsubtype == 0x09) ||
1597 (frsubtype == 0x0a) ||
1598 (frsubtype == 0x0b))) {
1599 if (hdrlen != WLAN_HDR_A3_QOS_LEN) {
1607 /* now, decrypt pframe with hdrlen offset and plen long */
1609 payload_index = hdrlen + 8; /* 8 is for extiv */
1611 for (i = 0; i < num_blocks; i++) {
1612 construct_ctr_preload(ctr_preload, a4_exists,
1615 frtype); /* add for CONFIG_IEEE80211W, none 11w also can use */
1617 aes128k128d(key, ctr_preload, aes_out);
1618 bitwise_xor(aes_out, &pframe[payload_index], chain_buffer);
1620 for (j = 0; j < 16; j++)
1621 pframe[payload_index++] = chain_buffer[j];
1624 if (payload_remainder > 0) {
1625 /* If there is a short final block, then pad it,*/
1626 /* encrypt it and copy the unpadded part back */
1627 construct_ctr_preload(
1634 frtype /* add for CONFIG_IEEE80211W, none 11w also can use */
1637 for (j = 0; j < 16; j++)
1638 padded_buffer[j] = 0x00;
1639 for (j = 0; j < payload_remainder; j++) {
1640 padded_buffer[j] = pframe[payload_index+j];
1642 aes128k128d(key, ctr_preload, aes_out);
1643 bitwise_xor(aes_out, padded_buffer, chain_buffer);
1644 for (j = 0; j < payload_remainder; j++)
1645 pframe[payload_index++] = chain_buffer[j];
1648 /* start to calculate the mic */
1649 if ((hdrlen + plen+8) <= MAX_MSG_SIZE)
1650 memcpy((void *)message, pframe, (hdrlen + plen+8)); /* 8 is for ext iv len */
1653 pn_vector[0] = pframe[hdrlen];
1654 pn_vector[1] = pframe[hdrlen+1];
1655 pn_vector[2] = pframe[hdrlen+4];
1656 pn_vector[3] = pframe[hdrlen+5];
1657 pn_vector[4] = pframe[hdrlen+6];
1658 pn_vector[5] = pframe[hdrlen+7];
1669 frtype /* add for CONFIG_IEEE80211W, none 11w also can use */
1672 construct_mic_header1(
1676 frtype /* add for CONFIG_IEEE80211W, none 11w also can use */
1678 construct_mic_header2(
1686 payload_remainder = (plen-8) % 16;
1687 num_blocks = (plen-8) / 16;
1689 /* Find start of payload */
1690 payload_index = (hdrlen + 8);
1693 aes128k128d(key, mic_iv, aes_out);
1694 bitwise_xor(aes_out, mic_header1, chain_buffer);
1695 aes128k128d(key, chain_buffer, aes_out);
1696 bitwise_xor(aes_out, mic_header2, chain_buffer);
1697 aes128k128d(key, chain_buffer, aes_out);
1699 for (i = 0; i < num_blocks; i++) {
1700 bitwise_xor(aes_out, &message[payload_index], chain_buffer);
1702 payload_index += 16;
1703 aes128k128d(key, chain_buffer, aes_out);
1706 /* Add on the final payload block if it needs padding */
1707 if (payload_remainder > 0) {
1708 for (j = 0; j < 16; j++)
1709 padded_buffer[j] = 0x00;
1710 for (j = 0; j < payload_remainder; j++) {
1711 padded_buffer[j] = message[payload_index++];
1713 bitwise_xor(aes_out, padded_buffer, chain_buffer);
1714 aes128k128d(key, chain_buffer, aes_out);
1717 for (j = 0; j < 8; j++)
1718 mic[j] = aes_out[j];
1720 /* Insert MIC into payload */
1721 for (j = 0; j < 8; j++)
1722 message[payload_index+j] = mic[j];
1724 payload_index = hdrlen + 8;
1725 for (i = 0; i < num_blocks; i++) {
1726 construct_ctr_preload(
1734 ); /* add for CONFIG_IEEE80211W, none 11w also can use */
1735 aes128k128d(key, ctr_preload, aes_out);
1736 bitwise_xor(aes_out, &message[payload_index], chain_buffer);
1737 for (j = 0; j < 16; j++)
1738 message[payload_index++] = chain_buffer[j];
1741 if (payload_remainder > 0) {
1742 /* If there is a short final block, then pad it,*/
1743 /* encrypt it and copy the unpadded part back */
1744 construct_ctr_preload(
1752 ); /* add for CONFIG_IEEE80211W, none 11w also can use */
1754 for (j = 0; j < 16; j++)
1755 padded_buffer[j] = 0x00;
1756 for (j = 0; j < payload_remainder; j++) {
1757 padded_buffer[j] = message[payload_index+j];
1759 aes128k128d(key, ctr_preload, aes_out);
1760 bitwise_xor(aes_out, padded_buffer, chain_buffer);
1761 for (j = 0; j < payload_remainder; j++)
1762 message[payload_index++] = chain_buffer[j];
1765 /* Encrypt the MIC */
1766 construct_ctr_preload(
1774 ); /* add for CONFIG_IEEE80211W, none 11w also can use */
1776 for (j = 0; j < 16; j++)
1777 padded_buffer[j] = 0x00;
1778 for (j = 0; j < 8; j++) {
1779 padded_buffer[j] = message[j+hdrlen+8+plen-8];
1782 aes128k128d(key, ctr_preload, aes_out);
1783 bitwise_xor(aes_out, padded_buffer, chain_buffer);
1784 for (j = 0; j < 8; j++)
1785 message[payload_index++] = chain_buffer[j];
1787 /* compare the mic */
1788 for (i = 0; i < 8; i++) {
1789 if (pframe[hdrlen+8+plen-8+i] != message[hdrlen+8+plen-8+i]) {
1790 RT_TRACE(_module_rtl871x_security_c_,
1792 ("%s:mic check error mic[%d]: pframe(%x) != message(%x)\n",
1795 pframe[hdrlen + 8 + plen - 8 + i],
1796 message[hdrlen + 8 + plen - 8 + i]));
1797 DBG_871X("%s:mic check error mic[%d]: pframe(%x) != message(%x)\n",
1800 pframe[hdrlen + 8 + plen - 8 + i],
1801 message[hdrlen + 8 + plen - 8 + i]);
1808 u32 rtw_aes_decrypt(struct adapter *padapter, u8 *precvframe)
1813 /* unsigned char message[MAX_MSG_SIZE]; */
1816 /* Intermediate Buffers */
1820 u8 *pframe, *prwskey; /* *payload,*iv */
1821 struct sta_info *stainfo;
1822 struct rx_pkt_attrib *prxattrib = &((union recv_frame *)precvframe)->u.hdr.attrib;
1823 struct security_priv *psecuritypriv = &padapter->securitypriv;
1826 pframe = (unsigned char *)((union recv_frame *)precvframe)->u.hdr.rx_data;
1827 /* 4 start to encrypt each fragment */
1828 if (prxattrib->encrypt == _AES_) {
1829 stainfo = rtw_get_stainfo(&padapter->stapriv, &prxattrib->ta[0]);
1830 if (stainfo != NULL) {
1831 RT_TRACE(_module_rtl871x_security_c_,
1833 ("%s: stainfo!= NULL!!!\n", __func__));
1835 if (IS_MCAST(prxattrib->ra)) {
1836 static unsigned long start;
1837 static u32 no_gkey_bc_cnt;
1838 static u32 no_gkey_mc_cnt;
1840 if (!psecuritypriv->binstallGrpkey) {
1846 if (is_broadcast_mac_addr(prxattrib->ra))
1851 if (jiffies_to_msecs(jiffies - start) > 1000) {
1852 if (no_gkey_bc_cnt || no_gkey_mc_cnt) {
1853 DBG_871X_LEVEL(_drv_always_, FUNC_ADPT_FMT" no_gkey_bc_cnt:%u, no_gkey_mc_cnt:%u\n",
1854 FUNC_ADPT_ARG(padapter), no_gkey_bc_cnt, no_gkey_mc_cnt);
1864 if (no_gkey_bc_cnt || no_gkey_mc_cnt) {
1865 DBG_871X_LEVEL(_drv_always_, FUNC_ADPT_FMT" gkey installed. no_gkey_bc_cnt:%u, no_gkey_mc_cnt:%u\n",
1866 FUNC_ADPT_ARG(padapter), no_gkey_bc_cnt, no_gkey_mc_cnt);
1872 prwskey = psecuritypriv->dot118021XGrpKey[prxattrib->key_index].skey;
1873 if (psecuritypriv->dot118021XGrpKeyid != prxattrib->key_index) {
1874 DBG_871X("not match packet_index =%d, install_index =%d\n"
1875 , prxattrib->key_index, psecuritypriv->dot118021XGrpKeyid);
1880 prwskey = &stainfo->dot118021x_UncstKey.skey[0];
1883 length = ((union recv_frame *)precvframe)->u.hdr.len-prxattrib->hdrlen-prxattrib->iv_len;
1885 res = aes_decipher(prwskey, prxattrib->hdrlen, pframe, length);
1887 AES_SW_DEC_CNT_INC(psecuritypriv, prxattrib->ra);
1889 RT_TRACE(_module_rtl871x_security_c_,
1891 ("%s: stainfo == NULL!!!\n", __func__));
1899 u32 rtw_BIP_verify(struct adapter *padapter, u8 *precvframe)
1901 struct rx_pkt_attrib *pattrib = &((union recv_frame *)precvframe)->u.hdr.attrib;
1906 struct ieee80211_hdr *pwlanhdr;
1908 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
1912 ori_len = pattrib->pkt_len-WLAN_HDR_A3_LEN+BIP_AAD_SIZE;
1913 BIP_AAD = rtw_zmalloc(ori_len);
1915 if (BIP_AAD == NULL) {
1916 DBG_871X("BIP AAD allocate fail\n");
1920 pframe = (unsigned char *)((union recv_frame *)precvframe)->u.hdr.rx_data;
1921 /* mapping to wlan header */
1922 pwlanhdr = (struct ieee80211_hdr *)pframe;
1923 /* save the frame body + MME */
1924 memcpy(BIP_AAD+BIP_AAD_SIZE, pframe+WLAN_HDR_A3_LEN, pattrib->pkt_len-WLAN_HDR_A3_LEN);
1925 /* find MME IE pointer */
1926 p = rtw_get_ie(BIP_AAD+BIP_AAD_SIZE, _MME_IE_, &len, pattrib->pkt_len-WLAN_HDR_A3_LEN);
1931 /* save packet number */
1932 memcpy(&le_tmp64, p+4, 6);
1933 temp_ipn = le64_to_cpu(le_tmp64);
1934 /* BIP packet number should bigger than previous BIP packet */
1935 if (temp_ipn <= pmlmeext->mgnt_80211w_IPN_rx) {
1936 DBG_871X("replay BIP packet\n");
1939 /* copy key index */
1940 memcpy(&le_tmp, p+2, 2);
1941 keyid = le16_to_cpu(le_tmp);
1942 if (keyid != padapter->securitypriv.dot11wBIPKeyid) {
1943 DBG_871X("BIP key index error!\n");
1946 /* clear the MIC field of MME to zero */
1947 memset(p+2+len-8, 0, 8);
1949 /* conscruct AAD, copy frame control field */
1950 memcpy(BIP_AAD, &pwlanhdr->frame_control, 2);
1951 ClearRetry(BIP_AAD);
1952 ClearPwrMgt(BIP_AAD);
1953 ClearMData(BIP_AAD);
1954 /* conscruct AAD, copy address 1 to address 3 */
1955 memcpy(BIP_AAD+2, pwlanhdr->addr1, 18);
1957 if (omac1_aes_128(padapter->securitypriv.dot11wBIPKey[padapter->securitypriv.dot11wBIPKeyid].skey
1958 , BIP_AAD, ori_len, mic))
1961 /* MIC field should be last 8 bytes of packet (packet without FCS) */
1962 if (!memcmp(mic, pframe+pattrib->pkt_len-8, 8)) {
1963 pmlmeext->mgnt_80211w_IPN_rx = temp_ipn;
1966 DBG_871X("BIP MIC error!\n");
1969 res = RTW_RX_HANDLED;
1977 const u32 Te0[256] = {
1978 0xc66363a5U, 0xf87c7c84U, 0xee777799U, 0xf67b7b8dU,
1979 0xfff2f20dU, 0xd66b6bbdU, 0xde6f6fb1U, 0x91c5c554U,
1980 0x60303050U, 0x02010103U, 0xce6767a9U, 0x562b2b7dU,
1981 0xe7fefe19U, 0xb5d7d762U, 0x4dababe6U, 0xec76769aU,
1982 0x8fcaca45U, 0x1f82829dU, 0x89c9c940U, 0xfa7d7d87U,
1983 0xeffafa15U, 0xb25959ebU, 0x8e4747c9U, 0xfbf0f00bU,
1984 0x41adadecU, 0xb3d4d467U, 0x5fa2a2fdU, 0x45afafeaU,
1985 0x239c9cbfU, 0x53a4a4f7U, 0xe4727296U, 0x9bc0c05bU,
1986 0x75b7b7c2U, 0xe1fdfd1cU, 0x3d9393aeU, 0x4c26266aU,
1987 0x6c36365aU, 0x7e3f3f41U, 0xf5f7f702U, 0x83cccc4fU,
1988 0x6834345cU, 0x51a5a5f4U, 0xd1e5e534U, 0xf9f1f108U,
1989 0xe2717193U, 0xabd8d873U, 0x62313153U, 0x2a15153fU,
1990 0x0804040cU, 0x95c7c752U, 0x46232365U, 0x9dc3c35eU,
1991 0x30181828U, 0x379696a1U, 0x0a05050fU, 0x2f9a9ab5U,
1992 0x0e070709U, 0x24121236U, 0x1b80809bU, 0xdfe2e23dU,
1993 0xcdebeb26U, 0x4e272769U, 0x7fb2b2cdU, 0xea75759fU,
1994 0x1209091bU, 0x1d83839eU, 0x582c2c74U, 0x341a1a2eU,
1995 0x361b1b2dU, 0xdc6e6eb2U, 0xb45a5aeeU, 0x5ba0a0fbU,
1996 0xa45252f6U, 0x763b3b4dU, 0xb7d6d661U, 0x7db3b3ceU,
1997 0x5229297bU, 0xdde3e33eU, 0x5e2f2f71U, 0x13848497U,
1998 0xa65353f5U, 0xb9d1d168U, 0x00000000U, 0xc1eded2cU,
1999 0x40202060U, 0xe3fcfc1fU, 0x79b1b1c8U, 0xb65b5bedU,
2000 0xd46a6abeU, 0x8dcbcb46U, 0x67bebed9U, 0x7239394bU,
2001 0x944a4adeU, 0x984c4cd4U, 0xb05858e8U, 0x85cfcf4aU,
2002 0xbbd0d06bU, 0xc5efef2aU, 0x4faaaae5U, 0xedfbfb16U,
2003 0x864343c5U, 0x9a4d4dd7U, 0x66333355U, 0x11858594U,
2004 0x8a4545cfU, 0xe9f9f910U, 0x04020206U, 0xfe7f7f81U,
2005 0xa05050f0U, 0x783c3c44U, 0x259f9fbaU, 0x4ba8a8e3U,
2006 0xa25151f3U, 0x5da3a3feU, 0x804040c0U, 0x058f8f8aU,
2007 0x3f9292adU, 0x219d9dbcU, 0x70383848U, 0xf1f5f504U,
2008 0x63bcbcdfU, 0x77b6b6c1U, 0xafdada75U, 0x42212163U,
2009 0x20101030U, 0xe5ffff1aU, 0xfdf3f30eU, 0xbfd2d26dU,
2010 0x81cdcd4cU, 0x180c0c14U, 0x26131335U, 0xc3ecec2fU,
2011 0xbe5f5fe1U, 0x359797a2U, 0x884444ccU, 0x2e171739U,
2012 0x93c4c457U, 0x55a7a7f2U, 0xfc7e7e82U, 0x7a3d3d47U,
2013 0xc86464acU, 0xba5d5de7U, 0x3219192bU, 0xe6737395U,
2014 0xc06060a0U, 0x19818198U, 0x9e4f4fd1U, 0xa3dcdc7fU,
2015 0x44222266U, 0x542a2a7eU, 0x3b9090abU, 0x0b888883U,
2016 0x8c4646caU, 0xc7eeee29U, 0x6bb8b8d3U, 0x2814143cU,
2017 0xa7dede79U, 0xbc5e5ee2U, 0x160b0b1dU, 0xaddbdb76U,
2018 0xdbe0e03bU, 0x64323256U, 0x743a3a4eU, 0x140a0a1eU,
2019 0x924949dbU, 0x0c06060aU, 0x4824246cU, 0xb85c5ce4U,
2020 0x9fc2c25dU, 0xbdd3d36eU, 0x43acacefU, 0xc46262a6U,
2021 0x399191a8U, 0x319595a4U, 0xd3e4e437U, 0xf279798bU,
2022 0xd5e7e732U, 0x8bc8c843U, 0x6e373759U, 0xda6d6db7U,
2023 0x018d8d8cU, 0xb1d5d564U, 0x9c4e4ed2U, 0x49a9a9e0U,
2024 0xd86c6cb4U, 0xac5656faU, 0xf3f4f407U, 0xcfeaea25U,
2025 0xca6565afU, 0xf47a7a8eU, 0x47aeaee9U, 0x10080818U,
2026 0x6fbabad5U, 0xf0787888U, 0x4a25256fU, 0x5c2e2e72U,
2027 0x381c1c24U, 0x57a6a6f1U, 0x73b4b4c7U, 0x97c6c651U,
2028 0xcbe8e823U, 0xa1dddd7cU, 0xe874749cU, 0x3e1f1f21U,
2029 0x964b4bddU, 0x61bdbddcU, 0x0d8b8b86U, 0x0f8a8a85U,
2030 0xe0707090U, 0x7c3e3e42U, 0x71b5b5c4U, 0xcc6666aaU,
2031 0x904848d8U, 0x06030305U, 0xf7f6f601U, 0x1c0e0e12U,
2032 0xc26161a3U, 0x6a35355fU, 0xae5757f9U, 0x69b9b9d0U,
2033 0x17868691U, 0x99c1c158U, 0x3a1d1d27U, 0x279e9eb9U,
2034 0xd9e1e138U, 0xebf8f813U, 0x2b9898b3U, 0x22111133U,
2035 0xd26969bbU, 0xa9d9d970U, 0x078e8e89U, 0x339494a7U,
2036 0x2d9b9bb6U, 0x3c1e1e22U, 0x15878792U, 0xc9e9e920U,
2037 0x87cece49U, 0xaa5555ffU, 0x50282878U, 0xa5dfdf7aU,
2038 0x038c8c8fU, 0x59a1a1f8U, 0x09898980U, 0x1a0d0d17U,
2039 0x65bfbfdaU, 0xd7e6e631U, 0x844242c6U, 0xd06868b8U,
2040 0x824141c3U, 0x299999b0U, 0x5a2d2d77U, 0x1e0f0f11U,
2041 0x7bb0b0cbU, 0xa85454fcU, 0x6dbbbbd6U, 0x2c16163aU,
2043 const u32 Td0[256] = {
2044 0x51f4a750U, 0x7e416553U, 0x1a17a4c3U, 0x3a275e96U,
2045 0x3bab6bcbU, 0x1f9d45f1U, 0xacfa58abU, 0x4be30393U,
2046 0x2030fa55U, 0xad766df6U, 0x88cc7691U, 0xf5024c25U,
2047 0x4fe5d7fcU, 0xc52acbd7U, 0x26354480U, 0xb562a38fU,
2048 0xdeb15a49U, 0x25ba1b67U, 0x45ea0e98U, 0x5dfec0e1U,
2049 0xc32f7502U, 0x814cf012U, 0x8d4697a3U, 0x6bd3f9c6U,
2050 0x038f5fe7U, 0x15929c95U, 0xbf6d7aebU, 0x955259daU,
2051 0xd4be832dU, 0x587421d3U, 0x49e06929U, 0x8ec9c844U,
2052 0x75c2896aU, 0xf48e7978U, 0x99583e6bU, 0x27b971ddU,
2053 0xbee14fb6U, 0xf088ad17U, 0xc920ac66U, 0x7dce3ab4U,
2054 0x63df4a18U, 0xe51a3182U, 0x97513360U, 0x62537f45U,
2055 0xb16477e0U, 0xbb6bae84U, 0xfe81a01cU, 0xf9082b94U,
2056 0x70486858U, 0x8f45fd19U, 0x94de6c87U, 0x527bf8b7U,
2057 0xab73d323U, 0x724b02e2U, 0xe31f8f57U, 0x6655ab2aU,
2058 0xb2eb2807U, 0x2fb5c203U, 0x86c57b9aU, 0xd33708a5U,
2059 0x302887f2U, 0x23bfa5b2U, 0x02036abaU, 0xed16825cU,
2060 0x8acf1c2bU, 0xa779b492U, 0xf307f2f0U, 0x4e69e2a1U,
2061 0x65daf4cdU, 0x0605bed5U, 0xd134621fU, 0xc4a6fe8aU,
2062 0x342e539dU, 0xa2f355a0U, 0x058ae132U, 0xa4f6eb75U,
2063 0x0b83ec39U, 0x4060efaaU, 0x5e719f06U, 0xbd6e1051U,
2064 0x3e218af9U, 0x96dd063dU, 0xdd3e05aeU, 0x4de6bd46U,
2065 0x91548db5U, 0x71c45d05U, 0x0406d46fU, 0x605015ffU,
2066 0x1998fb24U, 0xd6bde997U, 0x894043ccU, 0x67d99e77U,
2067 0xb0e842bdU, 0x07898b88U, 0xe7195b38U, 0x79c8eedbU,
2068 0xa17c0a47U, 0x7c420fe9U, 0xf8841ec9U, 0x00000000U,
2069 0x09808683U, 0x322bed48U, 0x1e1170acU, 0x6c5a724eU,
2070 0xfd0efffbU, 0x0f853856U, 0x3daed51eU, 0x362d3927U,
2071 0x0a0fd964U, 0x685ca621U, 0x9b5b54d1U, 0x24362e3aU,
2072 0x0c0a67b1U, 0x9357e70fU, 0xb4ee96d2U, 0x1b9b919eU,
2073 0x80c0c54fU, 0x61dc20a2U, 0x5a774b69U, 0x1c121a16U,
2074 0xe293ba0aU, 0xc0a02ae5U, 0x3c22e043U, 0x121b171dU,
2075 0x0e090d0bU, 0xf28bc7adU, 0x2db6a8b9U, 0x141ea9c8U,
2076 0x57f11985U, 0xaf75074cU, 0xee99ddbbU, 0xa37f60fdU,
2077 0xf701269fU, 0x5c72f5bcU, 0x44663bc5U, 0x5bfb7e34U,
2078 0x8b432976U, 0xcb23c6dcU, 0xb6edfc68U, 0xb8e4f163U,
2079 0xd731dccaU, 0x42638510U, 0x13972240U, 0x84c61120U,
2080 0x854a247dU, 0xd2bb3df8U, 0xaef93211U, 0xc729a16dU,
2081 0x1d9e2f4bU, 0xdcb230f3U, 0x0d8652ecU, 0x77c1e3d0U,
2082 0x2bb3166cU, 0xa970b999U, 0x119448faU, 0x47e96422U,
2083 0xa8fc8cc4U, 0xa0f03f1aU, 0x567d2cd8U, 0x223390efU,
2084 0x87494ec7U, 0xd938d1c1U, 0x8ccaa2feU, 0x98d40b36U,
2085 0xa6f581cfU, 0xa57ade28U, 0xdab78e26U, 0x3fadbfa4U,
2086 0x2c3a9de4U, 0x5078920dU, 0x6a5fcc9bU, 0x547e4662U,
2087 0xf68d13c2U, 0x90d8b8e8U, 0x2e39f75eU, 0x82c3aff5U,
2088 0x9f5d80beU, 0x69d0937cU, 0x6fd52da9U, 0xcf2512b3U,
2089 0xc8ac993bU, 0x10187da7U, 0xe89c636eU, 0xdb3bbb7bU,
2090 0xcd267809U, 0x6e5918f4U, 0xec9ab701U, 0x834f9aa8U,
2091 0xe6956e65U, 0xaaffe67eU, 0x21bccf08U, 0xef15e8e6U,
2092 0xbae79bd9U, 0x4a6f36ceU, 0xea9f09d4U, 0x29b07cd6U,
2093 0x31a4b2afU, 0x2a3f2331U, 0xc6a59430U, 0x35a266c0U,
2094 0x744ebc37U, 0xfc82caa6U, 0xe090d0b0U, 0x33a7d815U,
2095 0xf104984aU, 0x41ecdaf7U, 0x7fcd500eU, 0x1791f62fU,
2096 0x764dd68dU, 0x43efb04dU, 0xccaa4d54U, 0xe49604dfU,
2097 0x9ed1b5e3U, 0x4c6a881bU, 0xc12c1fb8U, 0x4665517fU,
2098 0x9d5eea04U, 0x018c355dU, 0xfa877473U, 0xfb0b412eU,
2099 0xb3671d5aU, 0x92dbd252U, 0xe9105633U, 0x6dd64713U,
2100 0x9ad7618cU, 0x37a10c7aU, 0x59f8148eU, 0xeb133c89U,
2101 0xcea927eeU, 0xb761c935U, 0xe11ce5edU, 0x7a47b13cU,
2102 0x9cd2df59U, 0x55f2733fU, 0x1814ce79U, 0x73c737bfU,
2103 0x53f7cdeaU, 0x5ffdaa5bU, 0xdf3d6f14U, 0x7844db86U,
2104 0xcaaff381U, 0xb968c43eU, 0x3824342cU, 0xc2a3405fU,
2105 0x161dc372U, 0xbce2250cU, 0x283c498bU, 0xff0d9541U,
2106 0x39a80171U, 0x080cb3deU, 0xd8b4e49cU, 0x6456c190U,
2107 0x7bcb8461U, 0xd532b670U, 0x486c5c74U, 0xd0b85742U,
2109 const u8 Td4s[256] = {
2110 0x52U, 0x09U, 0x6aU, 0xd5U, 0x30U, 0x36U, 0xa5U, 0x38U,
2111 0xbfU, 0x40U, 0xa3U, 0x9eU, 0x81U, 0xf3U, 0xd7U, 0xfbU,
2112 0x7cU, 0xe3U, 0x39U, 0x82U, 0x9bU, 0x2fU, 0xffU, 0x87U,
2113 0x34U, 0x8eU, 0x43U, 0x44U, 0xc4U, 0xdeU, 0xe9U, 0xcbU,
2114 0x54U, 0x7bU, 0x94U, 0x32U, 0xa6U, 0xc2U, 0x23U, 0x3dU,
2115 0xeeU, 0x4cU, 0x95U, 0x0bU, 0x42U, 0xfaU, 0xc3U, 0x4eU,
2116 0x08U, 0x2eU, 0xa1U, 0x66U, 0x28U, 0xd9U, 0x24U, 0xb2U,
2117 0x76U, 0x5bU, 0xa2U, 0x49U, 0x6dU, 0x8bU, 0xd1U, 0x25U,
2118 0x72U, 0xf8U, 0xf6U, 0x64U, 0x86U, 0x68U, 0x98U, 0x16U,
2119 0xd4U, 0xa4U, 0x5cU, 0xccU, 0x5dU, 0x65U, 0xb6U, 0x92U,
2120 0x6cU, 0x70U, 0x48U, 0x50U, 0xfdU, 0xedU, 0xb9U, 0xdaU,
2121 0x5eU, 0x15U, 0x46U, 0x57U, 0xa7U, 0x8dU, 0x9dU, 0x84U,
2122 0x90U, 0xd8U, 0xabU, 0x00U, 0x8cU, 0xbcU, 0xd3U, 0x0aU,
2123 0xf7U, 0xe4U, 0x58U, 0x05U, 0xb8U, 0xb3U, 0x45U, 0x06U,
2124 0xd0U, 0x2cU, 0x1eU, 0x8fU, 0xcaU, 0x3fU, 0x0fU, 0x02U,
2125 0xc1U, 0xafU, 0xbdU, 0x03U, 0x01U, 0x13U, 0x8aU, 0x6bU,
2126 0x3aU, 0x91U, 0x11U, 0x41U, 0x4fU, 0x67U, 0xdcU, 0xeaU,
2127 0x97U, 0xf2U, 0xcfU, 0xceU, 0xf0U, 0xb4U, 0xe6U, 0x73U,
2128 0x96U, 0xacU, 0x74U, 0x22U, 0xe7U, 0xadU, 0x35U, 0x85U,
2129 0xe2U, 0xf9U, 0x37U, 0xe8U, 0x1cU, 0x75U, 0xdfU, 0x6eU,
2130 0x47U, 0xf1U, 0x1aU, 0x71U, 0x1dU, 0x29U, 0xc5U, 0x89U,
2131 0x6fU, 0xb7U, 0x62U, 0x0eU, 0xaaU, 0x18U, 0xbeU, 0x1bU,
2132 0xfcU, 0x56U, 0x3eU, 0x4bU, 0xc6U, 0xd2U, 0x79U, 0x20U,
2133 0x9aU, 0xdbU, 0xc0U, 0xfeU, 0x78U, 0xcdU, 0x5aU, 0xf4U,
2134 0x1fU, 0xddU, 0xa8U, 0x33U, 0x88U, 0x07U, 0xc7U, 0x31U,
2135 0xb1U, 0x12U, 0x10U, 0x59U, 0x27U, 0x80U, 0xecU, 0x5fU,
2136 0x60U, 0x51U, 0x7fU, 0xa9U, 0x19U, 0xb5U, 0x4aU, 0x0dU,
2137 0x2dU, 0xe5U, 0x7aU, 0x9fU, 0x93U, 0xc9U, 0x9cU, 0xefU,
2138 0xa0U, 0xe0U, 0x3bU, 0x4dU, 0xaeU, 0x2aU, 0xf5U, 0xb0U,
2139 0xc8U, 0xebU, 0xbbU, 0x3cU, 0x83U, 0x53U, 0x99U, 0x61U,
2140 0x17U, 0x2bU, 0x04U, 0x7eU, 0xbaU, 0x77U, 0xd6U, 0x26U,
2141 0xe1U, 0x69U, 0x14U, 0x63U, 0x55U, 0x21U, 0x0cU, 0x7dU,
2143 const u8 rcons[] = {
2144 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x1B, 0x36
2145 /* for 128-bit blocks, Rijndael never uses more than 10 rcon values */
2149 * Expand the cipher key into the encryption key schedule.
2151 * @return the number of rounds for the given cipher key size.
2153 static void rijndaelKeySetupEnc(u32 rk[/*44*/], const u8 cipherKey[])
2158 rk[0] = GETU32(cipherKey);
2159 rk[1] = GETU32(cipherKey + 4);
2160 rk[2] = GETU32(cipherKey + 8);
2161 rk[3] = GETU32(cipherKey + 12);
2162 for (i = 0; i < 10; i++) {
2165 TE421(temp) ^ TE432(temp) ^ TE443(temp) ^ TE414(temp) ^
2167 rk[5] = rk[1] ^ rk[4];
2168 rk[6] = rk[2] ^ rk[5];
2169 rk[7] = rk[3] ^ rk[6];
2174 static void rijndaelEncrypt(u32 rk[/*44*/], u8 pt[16], u8 ct[16])
2176 u32 s0, s1, s2, s3, t0, t1, t2, t3;
2181 * map byte array block to cipher state
2182 * and add initial round key:
2184 s0 = GETU32(pt) ^ rk[0];
2185 s1 = GETU32(pt + 4) ^ rk[1];
2186 s2 = GETU32(pt + 8) ^ rk[2];
2187 s3 = GETU32(pt + 12) ^ rk[3];
2189 #define ROUND(i, d, s) \
2190 d##0 = TE0(s##0) ^ TE1(s##1) ^ TE2(s##2) ^ TE3(s##3) ^ rk[4 * i]; \
2191 d##1 = TE0(s##1) ^ TE1(s##2) ^ TE2(s##3) ^ TE3(s##0) ^ rk[4 * i + 1]; \
2192 d##2 = TE0(s##2) ^ TE1(s##3) ^ TE2(s##0) ^ TE3(s##1) ^ rk[4 * i + 2]; \
2193 d##3 = TE0(s##3) ^ TE1(s##0) ^ TE2(s##1) ^ TE3(s##2) ^ rk[4 * i + 3]
2195 /* Nr - 1 full rounds: */
2208 * apply last round and
2209 * map cipher state to byte array block:
2211 s0 = TE41(t0) ^ TE42(t1) ^ TE43(t2) ^ TE44(t3) ^ rk[0];
2213 s1 = TE41(t1) ^ TE42(t2) ^ TE43(t3) ^ TE44(t0) ^ rk[1];
2215 s2 = TE41(t2) ^ TE42(t3) ^ TE43(t0) ^ TE44(t1) ^ rk[2];
2217 s3 = TE41(t3) ^ TE42(t0) ^ TE43(t1) ^ TE44(t2) ^ rk[3];
2218 PUTU32(ct + 12, s3);
2221 static void *aes_encrypt_init(u8 *key, size_t len)
2226 rk = rtw_malloc(AES_PRIV_SIZE);
2229 rijndaelKeySetupEnc(rk, key);
2233 static void aes_128_encrypt(void *ctx, u8 *plain, u8 *crypt)
2235 rijndaelEncrypt(ctx, plain, crypt);
2239 static void gf_mulx(u8 *pad)
2243 carry = pad[0] & 0x80;
2244 for (i = 0; i < AES_BLOCK_SIZE - 1; i++)
2245 pad[i] = (pad[i] << 1) | (pad[i + 1] >> 7);
2247 pad[AES_BLOCK_SIZE - 1] <<= 1;
2249 pad[AES_BLOCK_SIZE - 1] ^= 0x87;
2252 static void aes_encrypt_deinit(void *ctx)
2254 kfree_sensitive(ctx);
2259 * omac1_aes_128_vector - One-Key CBC MAC (OMAC1) hash with AES-128
2260 * @key: 128-bit key for the hash operation
2261 * @num_elem: Number of elements in the data vector
2262 * @addr: Pointers to the data areas
2263 * @len: Lengths of the data blocks
2264 * @mac: Buffer for MAC (128 bits, i.e., 16 bytes)
2265 * Returns: 0 on success, -1 on failure
2267 * This is a mode for using block cipher (AES in this case) for authentication.
2268 * OMAC1 was standardized with the name CMAC by NIST in a Special Publication
2271 static int omac1_aes_128_vector(u8 *key, size_t num_elem,
2272 u8 *addr[], size_t *len, u8 *mac)
2275 u8 cbc[AES_BLOCK_SIZE], pad[AES_BLOCK_SIZE];
2277 size_t i, e, left, total_len;
2279 ctx = aes_encrypt_init(key, 16);
2282 memset(cbc, 0, AES_BLOCK_SIZE);
2285 for (e = 0; e < num_elem; e++)
2286 total_len += len[e];
2293 while (left >= AES_BLOCK_SIZE) {
2294 for (i = 0; i < AES_BLOCK_SIZE; i++) {
2302 if (left > AES_BLOCK_SIZE)
2303 aes_128_encrypt(ctx, cbc, cbc);
2304 left -= AES_BLOCK_SIZE;
2307 memset(pad, 0, AES_BLOCK_SIZE);
2308 aes_128_encrypt(ctx, pad, pad);
2311 if (left || total_len == 0) {
2312 for (i = 0; i < left; i++) {
2324 for (i = 0; i < AES_BLOCK_SIZE; i++)
2326 aes_128_encrypt(ctx, pad, mac);
2327 aes_encrypt_deinit(ctx);
2333 * omac1_aes_128 - One-Key CBC MAC (OMAC1) hash with AES-128 (aka AES-CMAC)
2334 * @key: 128-bit key for the hash operation
2335 * @data: Data buffer for which a MAC is determined
2336 * @data_len: Length of data buffer in bytes
2337 * @mac: Buffer for MAC (128 bits, i.e., 16 bytes)
2338 * Returns: 0 on success, -1 on failure
2340 * This is a mode for using block cipher (AES in this case) for authentication.
2341 * OMAC1 was standardized with the name CMAC by NIST in a Special Publication
2343 * modify for CONFIG_IEEE80211W */
2344 int omac1_aes_128(u8 *key, u8 *data, size_t data_len, u8 *mac)
2346 return omac1_aes_128_vector(key, 1, &data, &data_len, mac);
2349 /* Restore HW wep key setting according to key_mask */
2350 void rtw_sec_restore_wep_key(struct adapter *adapter)
2352 struct security_priv *securitypriv = &(adapter->securitypriv);
2355 if ((_WEP40_ == securitypriv->dot11PrivacyAlgrthm) || (_WEP104_ == securitypriv->dot11PrivacyAlgrthm)) {
2356 for (keyid = 0; keyid < 4; keyid++) {
2357 if (securitypriv->key_mask & BIT(keyid)) {
2358 if (keyid == securitypriv->dot11PrivacyKeyIndex)
2359 rtw_set_key(adapter, securitypriv, keyid, 1, false);
2361 rtw_set_key(adapter, securitypriv, keyid, 0, false);
2367 u8 rtw_handle_tkip_countermeasure(struct adapter *adapter, const char *caller)
2369 struct security_priv *securitypriv = &(adapter->securitypriv);
2370 u8 status = _SUCCESS;
2372 if (securitypriv->btkip_countermeasure) {
2373 unsigned long passing_ms = jiffies_to_msecs(jiffies - securitypriv->btkip_countermeasure_time);
2374 if (passing_ms > 60*1000) {
2375 DBG_871X_LEVEL(_drv_always_, "%s("ADPT_FMT") countermeasure time:%lus > 60s\n",
2376 caller, ADPT_ARG(adapter), passing_ms/1000);
2377 securitypriv->btkip_countermeasure = false;
2378 securitypriv->btkip_countermeasure_time = 0;
2380 DBG_871X_LEVEL(_drv_always_, "%s("ADPT_FMT") countermeasure time:%lus < 60s\n",
2381 caller, ADPT_ARG(adapter), passing_ms/1000);