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 <osdep_service.h>
18 #include <drv_types.h>
20 #include <osdep_intf.h>
22 /* WEP related ===== */
24 #define CRC32_POLY 0x04c11db7
32 static void arcfour_init(struct arc4context
*parc4ctx
, u8
*key
, u32 key_len
)
40 state
= parc4ctx
->state
;
43 for (counter
= 0; counter
< 256; counter
++)
44 state
[counter
] = (u8
)counter
;
47 for (counter
= 0; counter
< 256; counter
++) {
49 stateindex
= (stateindex
+ key
[keyindex
] + t
) & 0xff;
50 u
= state
[stateindex
];
51 state
[stateindex
] = (u8
)t
;
52 state
[counter
] = (u8
)u
;
53 if (++keyindex
>= key_len
)
59 static u32
arcfour_byte(struct arc4context
*parc4ctx
)
66 state
= parc4ctx
->state
;
67 x
= (parc4ctx
->x
+ 1) & 0xff;
69 y
= (sx
+ parc4ctx
->y
) & 0xff;
76 return state
[(sx
+ sy
) & 0xff];
79 static void arcfour_encrypt(struct arc4context
*parc4ctx
, u8
*dest
,
84 for (i
= 0; i
< len
; i
++)
85 dest
[i
] = src
[i
] ^ (unsigned char)arcfour_byte(parc4ctx
);
88 static int bcrc32initialized
;
89 static u32 crc32_table
[256];
91 static u8
crc32_reverseBit(u8 data
)
93 u8 retval
= ((data
<< 7) & 0x80) | ((data
<< 5) & 0x40) |
94 ((data
<< 3) & 0x20) | ((data
<< 1) & 0x10) |
95 ((data
>> 1) & 0x08) | ((data
>> 3) & 0x04) |
96 ((data
>> 5) & 0x02) | ((data
>> 7) & 0x01);
100 static void crc32_init(void)
107 if (bcrc32initialized
== 1)
113 for (i
= 0; i
< 256; ++i
) {
114 k
= crc32_reverseBit((u8
)i
);
116 for (c
= ((u32
)k
) << 24, j
= 8; j
> 0; --j
)
117 c
= c
& 0x80000000 ? (c
<< 1) ^ CRC32_POLY
: (c
<< 1);
119 p1
= (u8
*)&crc32_table
[i
];
121 p1
[0] = crc32_reverseBit(p
[3]);
122 p1
[1] = crc32_reverseBit(p
[2]);
123 p1
[2] = crc32_reverseBit(p
[1]);
124 p1
[3] = crc32_reverseBit(p
[0]);
127 bcrc32initialized
= 1;
130 static u32
getcrc32(u8
*buf
, int len
)
135 if (bcrc32initialized
== 0)
138 crc
= 0xffffffff; /* preload shift register, per CRC-32 spec */
140 for (p
= buf
; len
> 0; ++p
, --len
)
141 crc
= crc32_table
[(crc
^ *p
) & 0xff] ^ (crc
>> 8);
143 return ~crc
; /* transmit complement, per CRC-32 spec */
146 /* Need to consider the fragment situation */
147 void rtw_wep_encrypt23a(struct rtw_adapter
*padapter
,
148 struct xmit_frame
*pxmitframe
)
151 unsigned char crc
[4];
152 struct arc4context mycontext
;
153 int curfragnum
, length
, index
;
155 u8
*pframe
, *payload
, *iv
; /* wepkey */
157 u8 hw_hdr_offset
= 0;
158 struct pkt_attrib
*pattrib
= &pxmitframe
->attrib
;
159 struct security_priv
*psecuritypriv
= &padapter
->securitypriv
;
160 struct xmit_priv
*pxmitpriv
= &padapter
->xmitpriv
;
162 if (!pxmitframe
->buf_addr
)
165 hw_hdr_offset
= TXDESC_OFFSET
;
167 pframe
= pxmitframe
->buf_addr
+ hw_hdr_offset
;
169 /* start to encrypt each fragment */
170 if (pattrib
->encrypt
!= WLAN_CIPHER_SUITE_WEP40
&&
171 pattrib
->encrypt
!= WLAN_CIPHER_SUITE_WEP104
)
174 index
= psecuritypriv
->dot11PrivacyKeyIndex
;
175 keylength
= psecuritypriv
->wep_key
[index
].keylen
;
177 for (curfragnum
= 0; curfragnum
< pattrib
->nr_frags
; curfragnum
++) {
178 iv
= pframe
+ pattrib
->hdrlen
;
179 memcpy(&wepkey
[0], iv
, 3);
180 memcpy(&wepkey
[3], &psecuritypriv
->wep_key
[index
].key
,
182 payload
= pframe
+ pattrib
->iv_len
+ pattrib
->hdrlen
;
184 if ((curfragnum
+ 1) == pattrib
->nr_frags
) {
185 /* the last fragment */
186 length
= pattrib
->last_txcmdsz
- pattrib
->hdrlen
-
187 pattrib
->iv_len
- pattrib
->icv_len
;
189 *((u32
*)crc
) = cpu_to_le32(getcrc32(payload
, length
));
191 arcfour_init(&mycontext
, wepkey
, 3 + keylength
);
192 arcfour_encrypt(&mycontext
, payload
, payload
, length
);
193 arcfour_encrypt(&mycontext
, payload
+ length
, crc
, 4);
195 length
= pxmitpriv
->frag_len
- pattrib
->hdrlen
-
196 pattrib
->iv_len
- pattrib
->icv_len
;
197 *((u32
*)crc
) = cpu_to_le32(getcrc32(payload
, length
));
198 arcfour_init(&mycontext
, wepkey
, 3 + keylength
);
199 arcfour_encrypt(&mycontext
, payload
, payload
, length
);
200 arcfour_encrypt(&mycontext
, payload
+ length
, crc
, 4);
202 pframe
+= pxmitpriv
->frag_len
;
203 pframe
= PTR_ALIGN(pframe
, 4);
209 void rtw_wep_decrypt23a(struct rtw_adapter
*padapter
,
210 struct recv_frame
*precvframe
)
213 u32 actual_crc
, expected_crc
;
214 struct arc4context mycontext
;
217 u8
*pframe
, *payload
, *iv
, wepkey
[16];
219 struct rx_pkt_attrib
*prxattrib
= &precvframe
->attrib
;
220 struct security_priv
*psecuritypriv
= &padapter
->securitypriv
;
221 struct sk_buff
*skb
= precvframe
->pkt
;
225 /* start to decrypt recvframe */
226 if (prxattrib
->encrypt
!= WLAN_CIPHER_SUITE_WEP40
&&
227 prxattrib
->encrypt
!= WLAN_CIPHER_SUITE_WEP104
)
230 iv
= pframe
+ prxattrib
->hdrlen
;
231 /* keyindex = (iv[3]&0x3); */
232 keyindex
= prxattrib
->key_index
;
233 keylength
= psecuritypriv
->wep_key
[keyindex
].keylen
;
234 memcpy(&wepkey
[0], iv
, 3);
235 /* memcpy(&wepkey[3], &psecuritypriv->dot11DefKey[psecuritypriv->dot11PrivacyKeyIndex].skey[0], keylength); */
236 memcpy(&wepkey
[3], &psecuritypriv
->wep_key
[keyindex
].key
, keylength
);
237 length
= skb
->len
- prxattrib
->hdrlen
- prxattrib
->iv_len
;
239 payload
= pframe
+ prxattrib
->iv_len
+ prxattrib
->hdrlen
;
241 /* decrypt payload include icv */
242 arcfour_init(&mycontext
, wepkey
, 3 + keylength
);
243 arcfour_encrypt(&mycontext
, payload
, payload
, length
);
245 /* calculate icv and compare the icv */
246 actual_crc
= le32_to_cpu(getcrc32(payload
, length
- 4));
247 expected_crc
= le32_to_cpu(get_unaligned_le32(&payload
[length
- 4]));
249 if (actual_crc
!= expected_crc
) {
250 RT_TRACE(_module_rtl871x_security_c_
, _drv_err_
,
251 "%s:icv CRC mismatch: "
252 "actual: %08x, expected: %08x\n",
253 __func__
, actual_crc
, expected_crc
);
257 /* 3 ===== TKIP related ===== */
259 static u32
secmicgetuint32(u8
*p
)
260 /* Convert from Byte[] to u32 in a portable way */
265 for (i
= 0; i
< 4; i
++)
266 res
|= ((u32
)(*p
++)) << (8 * i
);
271 static void secmicputuint32(u8
*p
, u32 val
)
272 /* Convert from long to Byte[] in a portable way */
276 for (i
= 0; i
< 4; i
++) {
277 *p
++ = (u8
) (val
& 0xff);
283 static void secmicclear(struct mic_data
*pmicdata
)
285 /* Reset the state to the empty message. */
287 pmicdata
->L
= pmicdata
->K0
;
288 pmicdata
->R
= pmicdata
->K1
;
289 pmicdata
->nBytesInM
= 0;
294 void rtw_secmicsetkey23a(struct mic_data
*pmicdata
, u8
*key
)
298 pmicdata
->K0
= secmicgetuint32(key
);
299 pmicdata
->K1
= secmicgetuint32(key
+ 4);
300 /* and reset the message */
301 secmicclear(pmicdata
);
305 void rtw_secmicappend23abyte23a(struct mic_data
*pmicdata
, u8 b
)
308 /* Append the byte to our word-sized buffer */
309 pmicdata
->M
|= ((unsigned long)b
) << (8 * pmicdata
->nBytesInM
);
310 pmicdata
->nBytesInM
++;
311 /* Process the word if it is full. */
312 if (pmicdata
->nBytesInM
>= 4) {
313 pmicdata
->L
^= pmicdata
->M
;
314 pmicdata
->R
^= ROL32(pmicdata
->L
, 17);
315 pmicdata
->L
+= pmicdata
->R
;
316 pmicdata
->R
^= ((pmicdata
->L
& 0xff00ff00) >> 8) | ((pmicdata
->L
& 0x00ff00ff) << 8);
317 pmicdata
->L
+= pmicdata
->R
;
318 pmicdata
->R
^= ROL32(pmicdata
->L
, 3);
319 pmicdata
->L
+= pmicdata
->R
;
320 pmicdata
->R
^= ROR32(pmicdata
->L
, 2);
321 pmicdata
->L
+= pmicdata
->R
;
322 /* Clear the buffer */
324 pmicdata
->nBytesInM
= 0;
329 void rtw_secmicappend23a(struct mic_data
*pmicdata
, u8
*src
, u32 nbytes
)
334 rtw_secmicappend23abyte23a(pmicdata
, *src
++);
340 void rtw_secgetmic23a(struct mic_data
*pmicdata
, u8
*dst
)
343 /* Append the minimum padding */
344 rtw_secmicappend23abyte23a(pmicdata
, 0x5a);
345 rtw_secmicappend23abyte23a(pmicdata
, 0);
346 rtw_secmicappend23abyte23a(pmicdata
, 0);
347 rtw_secmicappend23abyte23a(pmicdata
, 0);
348 rtw_secmicappend23abyte23a(pmicdata
, 0);
349 /* and then zeroes until the length is a multiple of 4 */
350 while (pmicdata
->nBytesInM
!= 0)
351 rtw_secmicappend23abyte23a(pmicdata
, 0);
352 /* The appendByte function has already computed the result. */
353 secmicputuint32(dst
, pmicdata
->L
);
354 secmicputuint32(dst
+ 4, pmicdata
->R
);
355 /* Reset to the empty message. */
356 secmicclear(pmicdata
);
360 void rtw_seccalctkipmic23a(u8
*key
, u8
*header
, u8
*data
, u32 data_len
,
361 u8
*mic_code
, u8 pri
)
364 struct mic_data micdata
;
365 u8 priority
[4] = {0x0, 0x0, 0x0, 0x0};
367 rtw_secmicsetkey23a(&micdata
, key
);
370 /* Michael MIC pseudo header: DA, SA, 3 x 0, Priority */
371 if (header
[1]&1) { /* ToDS == 1 */
372 rtw_secmicappend23a(&micdata
, &header
[16], 6); /* DA */
373 if (header
[1]&2) /* From Ds == 1 */
374 rtw_secmicappend23a(&micdata
, &header
[24], 6);
376 rtw_secmicappend23a(&micdata
, &header
[10], 6);
377 } else { /* ToDS == 0 */
378 rtw_secmicappend23a(&micdata
, &header
[4], 6); /* DA */
379 if (header
[1]&2) /* From Ds == 1 */
380 rtw_secmicappend23a(&micdata
, &header
[16], 6);
382 rtw_secmicappend23a(&micdata
, &header
[10], 6);
385 rtw_secmicappend23a(&micdata
, &priority
[0], 4);
387 rtw_secmicappend23a(&micdata
, data
, data_len
);
389 rtw_secgetmic23a(&micdata
, mic_code
);
393 /* macros for extraction/creation of unsigned char/unsigned short values */
394 #define RotR1(v16) ((((v16) >> 1) & 0x7FFF) ^ (((v16) & 1) << 15))
395 #define Lo8(v16) ((u8)((v16) & 0x00FF))
396 #define Hi8(v16) ((u8)(((v16) >> 8) & 0x00FF))
397 #define Lo16(v32) ((u16)((v32) & 0xFFFF))
398 #define Hi16(v32) ((u16)(((v32) >> 16) & 0xFFFF))
399 #define Mk16(hi, lo) ((lo) ^ (((u16)(hi)) << 8))
401 /* select the Nth 16-bit word of the temporal key unsigned char array TK[] */
402 #define TK16(N) Mk16(tk[2 * (N) + 1], tk[2 * (N)])
404 /* S-box lookup: 16 bits --> 16 bits */
405 #define _S_(v16) (Sbox1[0][Lo8(v16)] ^ Sbox1[1][Hi8(v16)])
407 /* fixed algorithm "parameters" */
408 #define PHASE1_LOOP_CNT 8 /* this needs to be "big enough" */
409 #define TA_SIZE 6 /* 48-bit transmitter address */
410 #define TK_SIZE 16 /* 128-bit temporal key */
411 #define P1K_SIZE 10 /* 80-bit Phase1 key */
412 #define RC4_KEY_SIZE 16 /* 128-bit RC4KEY (104 bits unknown) */
414 /* 2-unsigned char by 2-unsigned char subset of the full AES S-box table */
415 static const unsigned short Sbox1
[2][256] = {
416 /* Sbox for hash (can be in ROM) */
418 0xC6A5, 0xF884, 0xEE99, 0xF68D, 0xFF0D, 0xD6BD, 0xDEB1, 0x9154,
419 0x6050, 0x0203, 0xCEA9, 0x567D, 0xE719, 0xB562, 0x4DE6, 0xEC9A,
420 0x8F45, 0x1F9D, 0x8940, 0xFA87, 0xEF15, 0xB2EB, 0x8EC9, 0xFB0B,
421 0x41EC, 0xB367, 0x5FFD, 0x45EA, 0x23BF, 0x53F7, 0xE496, 0x9B5B,
422 0x75C2, 0xE11C, 0x3DAE, 0x4C6A, 0x6C5A, 0x7E41, 0xF502, 0x834F,
423 0x685C, 0x51F4, 0xD134, 0xF908, 0xE293, 0xAB73, 0x6253, 0x2A3F,
424 0x080C, 0x9552, 0x4665, 0x9D5E, 0x3028, 0x37A1, 0x0A0F, 0x2FB5,
425 0x0E09, 0x2436, 0x1B9B, 0xDF3D, 0xCD26, 0x4E69, 0x7FCD, 0xEA9F,
426 0x121B, 0x1D9E, 0x5874, 0x342E, 0x362D, 0xDCB2, 0xB4EE, 0x5BFB,
427 0xA4F6, 0x764D, 0xB761, 0x7DCE, 0x527B, 0xDD3E, 0x5E71, 0x1397,
428 0xA6F5, 0xB968, 0x0000, 0xC12C, 0x4060, 0xE31F, 0x79C8, 0xB6ED,
429 0xD4BE, 0x8D46, 0x67D9, 0x724B, 0x94DE, 0x98D4, 0xB0E8, 0x854A,
430 0xBB6B, 0xC52A, 0x4FE5, 0xED16, 0x86C5, 0x9AD7, 0x6655, 0x1194,
431 0x8ACF, 0xE910, 0x0406, 0xFE81, 0xA0F0, 0x7844, 0x25BA, 0x4BE3,
432 0xA2F3, 0x5DFE, 0x80C0, 0x058A, 0x3FAD, 0x21BC, 0x7048, 0xF104,
433 0x63DF, 0x77C1, 0xAF75, 0x4263, 0x2030, 0xE51A, 0xFD0E, 0xBF6D,
434 0x814C, 0x1814, 0x2635, 0xC32F, 0xBEE1, 0x35A2, 0x88CC, 0x2E39,
435 0x9357, 0x55F2, 0xFC82, 0x7A47, 0xC8AC, 0xBAE7, 0x322B, 0xE695,
436 0xC0A0, 0x1998, 0x9ED1, 0xA37F, 0x4466, 0x547E, 0x3BAB, 0x0B83,
437 0x8CCA, 0xC729, 0x6BD3, 0x283C, 0xA779, 0xBCE2, 0x161D, 0xAD76,
438 0xDB3B, 0x6456, 0x744E, 0x141E, 0x92DB, 0x0C0A, 0x486C, 0xB8E4,
439 0x9F5D, 0xBD6E, 0x43EF, 0xC4A6, 0x39A8, 0x31A4, 0xD337, 0xF28B,
440 0xD532, 0x8B43, 0x6E59, 0xDAB7, 0x018C, 0xB164, 0x9CD2, 0x49E0,
441 0xD8B4, 0xACFA, 0xF307, 0xCF25, 0xCAAF, 0xF48E, 0x47E9, 0x1018,
442 0x6FD5, 0xF088, 0x4A6F, 0x5C72, 0x3824, 0x57F1, 0x73C7, 0x9751,
443 0xCB23, 0xA17C, 0xE89C, 0x3E21, 0x96DD, 0x61DC, 0x0D86, 0x0F85,
444 0xE090, 0x7C42, 0x71C4, 0xCCAA, 0x90D8, 0x0605, 0xF701, 0x1C12,
445 0xC2A3, 0x6A5F, 0xAEF9, 0x69D0, 0x1791, 0x9958, 0x3A27, 0x27B9,
446 0xD938, 0xEB13, 0x2BB3, 0x2233, 0xD2BB, 0xA970, 0x0789, 0x33A7,
447 0x2DB6, 0x3C22, 0x1592, 0xC920, 0x8749, 0xAAFF, 0x5078, 0xA57A,
448 0x038F, 0x59F8, 0x0980, 0x1A17, 0x65DA, 0xD731, 0x84C6, 0xD0B8,
449 0x82C3, 0x29B0, 0x5A77, 0x1E11, 0x7BCB, 0xA8FC, 0x6DD6, 0x2C3A,
451 { /* second half of table is unsigned char-reversed version of first! */
452 0xA5C6, 0x84F8, 0x99EE, 0x8DF6, 0x0DFF, 0xBDD6, 0xB1DE, 0x5491,
453 0x5060, 0x0302, 0xA9CE, 0x7D56, 0x19E7, 0x62B5, 0xE64D, 0x9AEC,
454 0x458F, 0x9D1F, 0x4089, 0x87FA, 0x15EF, 0xEBB2, 0xC98E, 0x0BFB,
455 0xEC41, 0x67B3, 0xFD5F, 0xEA45, 0xBF23, 0xF753, 0x96E4, 0x5B9B,
456 0xC275, 0x1CE1, 0xAE3D, 0x6A4C, 0x5A6C, 0x417E, 0x02F5, 0x4F83,
457 0x5C68, 0xF451, 0x34D1, 0x08F9, 0x93E2, 0x73AB, 0x5362, 0x3F2A,
458 0x0C08, 0x5295, 0x6546, 0x5E9D, 0x2830, 0xA137, 0x0F0A, 0xB52F,
459 0x090E, 0x3624, 0x9B1B, 0x3DDF, 0x26CD, 0x694E, 0xCD7F, 0x9FEA,
460 0x1B12, 0x9E1D, 0x7458, 0x2E34, 0x2D36, 0xB2DC, 0xEEB4, 0xFB5B,
461 0xF6A4, 0x4D76, 0x61B7, 0xCE7D, 0x7B52, 0x3EDD, 0x715E, 0x9713,
462 0xF5A6, 0x68B9, 0x0000, 0x2CC1, 0x6040, 0x1FE3, 0xC879, 0xEDB6,
463 0xBED4, 0x468D, 0xD967, 0x4B72, 0xDE94, 0xD498, 0xE8B0, 0x4A85,
464 0x6BBB, 0x2AC5, 0xE54F, 0x16ED, 0xC586, 0xD79A, 0x5566, 0x9411,
465 0xCF8A, 0x10E9, 0x0604, 0x81FE, 0xF0A0, 0x4478, 0xBA25, 0xE34B,
466 0xF3A2, 0xFE5D, 0xC080, 0x8A05, 0xAD3F, 0xBC21, 0x4870, 0x04F1,
467 0xDF63, 0xC177, 0x75AF, 0x6342, 0x3020, 0x1AE5, 0x0EFD, 0x6DBF,
468 0x4C81, 0x1418, 0x3526, 0x2FC3, 0xE1BE, 0xA235, 0xCC88, 0x392E,
469 0x5793, 0xF255, 0x82FC, 0x477A, 0xACC8, 0xE7BA, 0x2B32, 0x95E6,
470 0xA0C0, 0x9819, 0xD19E, 0x7FA3, 0x6644, 0x7E54, 0xAB3B, 0x830B,
471 0xCA8C, 0x29C7, 0xD36B, 0x3C28, 0x79A7, 0xE2BC, 0x1D16, 0x76AD,
472 0x3BDB, 0x5664, 0x4E74, 0x1E14, 0xDB92, 0x0A0C, 0x6C48, 0xE4B8,
473 0x5D9F, 0x6EBD, 0xEF43, 0xA6C4, 0xA839, 0xA431, 0x37D3, 0x8BF2,
474 0x32D5, 0x438B, 0x596E, 0xB7DA, 0x8C01, 0x64B1, 0xD29C, 0xE049,
475 0xB4D8, 0xFAAC, 0x07F3, 0x25CF, 0xAFCA, 0x8EF4, 0xE947, 0x1810,
476 0xD56F, 0x88F0, 0x6F4A, 0x725C, 0x2438, 0xF157, 0xC773, 0x5197,
477 0x23CB, 0x7CA1, 0x9CE8, 0x213E, 0xDD96, 0xDC61, 0x860D, 0x850F,
478 0x90E0, 0x427C, 0xC471, 0xAACC, 0xD890, 0x0506, 0x01F7, 0x121C,
479 0xA3C2, 0x5F6A, 0xF9AE, 0xD069, 0x9117, 0x5899, 0x273A, 0xB927,
480 0x38D9, 0x13EB, 0xB32B, 0x3322, 0xBBD2, 0x70A9, 0x8907, 0xA733,
481 0xB62D, 0x223C, 0x9215, 0x20C9, 0x4987, 0xFFAA, 0x7850, 0x7AA5,
482 0x8F03, 0xF859, 0x8009, 0x171A, 0xDA65, 0x31D7, 0xC684, 0xB8D0,
483 0xC382, 0xB029, 0x775A, 0x111E, 0xCB7B, 0xFCA8, 0xD66D, 0x3A2C,
488 **********************************************************************
489 * Routine: Phase 1 -- generate P1K, given TA, TK, IV32
492 * tk[] = temporal key [128 bits]
493 * ta[] = transmitter's MAC address [ 48 bits]
494 * iv32 = upper 32 bits of IV [ 32 bits]
496 * p1k[] = Phase 1 key [ 80 bits]
499 * This function only needs to be called every 2**16 packets,
500 * although in theory it could be called every packet.
502 **********************************************************************
504 static void phase1(u16
*p1k
, const u8
*tk
, const u8
*ta
, u32 iv32
)
508 /* Initialize the 80 bits of P1K[] from IV32 and TA[0..5] */
511 p1k
[2] = Mk16(ta
[1], ta
[0]); /* use TA[] as little-endian */
512 p1k
[3] = Mk16(ta
[3], ta
[2]);
513 p1k
[4] = Mk16(ta
[5], ta
[4]);
515 /* Now compute an unbalanced Feistel cipher with 80-bit block */
516 /* size on the 80-bit block P1K[], using the 128-bit key TK[] */
517 for (i
= 0; i
< PHASE1_LOOP_CNT
; i
++) {
518 /* Each add operation here is mod 2**16 */
519 p1k
[0] += _S_(p1k
[4] ^ TK16((i
& 1) + 0));
520 p1k
[1] += _S_(p1k
[0] ^ TK16((i
& 1) + 2));
521 p1k
[2] += _S_(p1k
[1] ^ TK16((i
& 1) + 4));
522 p1k
[3] += _S_(p1k
[2] ^ TK16((i
& 1) + 6));
523 p1k
[4] += _S_(p1k
[3] ^ TK16((i
& 1) + 0));
524 p1k
[4] += (unsigned short) i
; /* avoid "slide attacks" */
530 **********************************************************************
531 * Routine: Phase 2 -- generate RC4KEY, given TK, P1K, IV16
534 * tk[] = Temporal key [128 bits]
535 * p1k[] = Phase 1 output key [ 80 bits]
536 * iv16 = low 16 bits of IV counter [ 16 bits]
538 * rc4key[] = the key used to encrypt the packet [128 bits]
541 * The value {TA, IV32, IV16} for Phase1/Phase2 must be unique
542 * across all packets using the same key TK value. Then, for a
543 * given value of TK[], this TKIP48 construction guarantees that
544 * the final RC4KEY value is unique across all packets.
546 * Suggested implementation optimization: if PPK[] is "overlaid"
547 * appropriately on RC4KEY[], there is no need for the final
548 * for loop below that copies the PPK[] result into RC4KEY[].
550 **********************************************************************
552 static void phase2(u8
*rc4key
, const u8
*tk
, const u16
*p1k
, u16 iv16
)
555 u16 PPK
[6]; /* temporary key for mixing */
557 /* Note: all adds in the PPK[] equations below are mod 2**16 */
558 for (i
= 0; i
< 5; i
++)
559 PPK
[i
] = p1k
[i
]; /* first, copy P1K to PPK */
561 PPK
[5] = p1k
[4] + iv16
; /* next, add in IV16 */
563 /* Bijective non-linear mixing of the 96 bits of PPK[0..5] */
564 PPK
[0] += _S_(PPK
[5] ^ TK16(0)); /* Mix key in each "round" */
565 PPK
[1] += _S_(PPK
[0] ^ TK16(1));
566 PPK
[2] += _S_(PPK
[1] ^ TK16(2));
567 PPK
[3] += _S_(PPK
[2] ^ TK16(3));
568 PPK
[4] += _S_(PPK
[3] ^ TK16(4));
569 PPK
[5] += _S_(PPK
[4] ^ TK16(5)); /* Total # S-box lookups == 6 */
571 /* Final sweep: bijective, "linear". Rotates kill LSB correlations */
572 PPK
[0] += RotR1(PPK
[5] ^ TK16(6));
573 PPK
[1] += RotR1(PPK
[0] ^ TK16(7)); /* Use all of TK[] in Phase2 */
574 PPK
[2] += RotR1(PPK
[1]);
575 PPK
[3] += RotR1(PPK
[2]);
576 PPK
[4] += RotR1(PPK
[3]);
577 PPK
[5] += RotR1(PPK
[4]);
578 /* Note: At this point, for a given key TK[0..15], the 96-bit output */
579 /* value PPK[0..5] is guaranteed to be unique, as a function */
580 /* of the 96-bit "input" value {TA, IV32, IV16}. That is, */
581 /* P1K is now a keyed permutation of {TA, IV32, IV16}. */
583 /* Set RC4KEY[0..3], which includes "cleartext" portion of RC4 key */
584 rc4key
[0] = Hi8(iv16
); /* RC4KEY[0..2] is the WEP IV */
585 rc4key
[1] = (Hi8(iv16
) | 0x20) & 0x7F; /* Help avoid weak (FMS) keys */
586 rc4key
[2] = Lo8(iv16
);
587 rc4key
[3] = Lo8((PPK
[5] ^ TK16(0)) >> 1);
589 /* Copy 96 bits of PPK[0..5] to RC4KEY[4..15] (little-endian) */
590 for (i
= 0; i
< 6; i
++) {
591 rc4key
[4 + 2 * i
] = Lo8(PPK
[i
]);
592 rc4key
[5 + 2 * i
] = Hi8(PPK
[i
]);
597 /* The hlen isn't include the IV */
598 int rtw_tkip_encrypt23a(struct rtw_adapter
*padapter
,
599 struct xmit_frame
*pxmitframe
)
606 u8 hw_hdr_offset
= 0;
607 struct arc4context mycontext
;
608 int curfragnum
, length
;
610 u8
*pframe
, *payload
, *iv
, *prwskey
;
611 union pn48 dot11txpn
;
612 struct sta_info
*stainfo
;
613 struct pkt_attrib
*pattrib
= &pxmitframe
->attrib
;
614 struct security_priv
*psecuritypriv
= &padapter
->securitypriv
;
615 struct xmit_priv
*pxmitpriv
= &padapter
->xmitpriv
;
618 if (pattrib
->encrypt
!= WLAN_CIPHER_SUITE_TKIP
)
621 if (!pxmitframe
->buf_addr
)
624 hw_hdr_offset
= TXDESC_OFFSET
;
626 pframe
= pxmitframe
->buf_addr
+ hw_hdr_offset
;
629 stainfo
= pattrib
->psta
;
631 DBG_8723A("%s, call rtw_get_stainfo()\n", __func__
);
632 stainfo
= rtw_get_stainfo23a(&padapter
->stapriv
,
636 if (stainfo
== NULL
) {
637 RT_TRACE(_module_rtl871x_security_c_
, _drv_err_
,
638 "%s: stainfo == NULL!!!\n", __func__
);
639 DBG_8723A("%s, psta == NUL\n", __func__
);
643 RT_TRACE(_module_rtl871x_security_c_
, _drv_err_
,
644 "%s: stainfo!= NULL!!!\n", __func__
);
646 if (!(stainfo
->state
& _FW_LINKED
)) {
647 DBG_8723A("%s, psta->state(0x%x) != _FW_LINKED\n", __func__
, stainfo
->state
);
651 if (is_multicast_ether_addr(pattrib
->ra
))
652 prwskey
= psecuritypriv
->dot118021XGrpKey
[psecuritypriv
->dot118021XGrpKeyid
].skey
;
654 prwskey
= &stainfo
->dot118021x_UncstKey
.skey
[0];
658 /* 4 start to encrypt each fragment */
659 for (curfragnum
= 0; curfragnum
< pattrib
->nr_frags
; curfragnum
++) {
660 iv
= pframe
+ pattrib
->hdrlen
;
661 payload
= pframe
+ pattrib
->iv_len
+ pattrib
->hdrlen
;
663 GET_TKIP_PN(iv
, dot11txpn
);
665 pnl
= (u16
)(dot11txpn
.val
);
666 pnh
= (u32
)(dot11txpn
.val
>>16);
668 phase1((u16
*)&ttkey
[0], prwskey
, &pattrib
->ta
[0], pnh
);
670 phase2(&rc4key
[0], prwskey
, (u16
*)&ttkey
[0], pnl
);
672 if ((curfragnum
+ 1) == pattrib
->nr_frags
) { /* 4 the last fragment */
673 length
= (pattrib
->last_txcmdsz
-
678 RT_TRACE(_module_rtl871x_security_c_
, _drv_info_
,
679 "pattrib->iv_len =%x, pattrib->icv_len =%x\n",
682 *((u32
*)crc
) = cpu_to_le32(getcrc32(payload
, length
));
684 arcfour_init(&mycontext
, rc4key
, 16);
685 arcfour_encrypt(&mycontext
, payload
, payload
, length
);
686 arcfour_encrypt(&mycontext
, payload
+ length
, crc
, 4);
689 length
= (pxmitpriv
->frag_len
-
694 *((u32
*)crc
) = cpu_to_le32(getcrc32(payload
, length
));
695 arcfour_init(&mycontext
, rc4key
, 16);
696 arcfour_encrypt(&mycontext
, payload
, payload
, length
);
697 arcfour_encrypt(&mycontext
, payload
+ length
, crc
, 4);
699 pframe
+= pxmitpriv
->frag_len
;
700 pframe
= PTR_ALIGN(pframe
, 4);
707 /* The hlen isn't include the IV */
708 int rtw_tkip_decrypt23a(struct rtw_adapter
*padapter
,
709 struct recv_frame
*precvframe
)
715 u32 actual_crc
, expected_crc
;
716 struct arc4context mycontext
;
719 u8
*pframe
, *payload
, *iv
, *prwskey
;
720 union pn48 dot11txpn
;
721 struct sta_info
*stainfo
;
722 struct rx_pkt_attrib
*prxattrib
= &precvframe
->attrib
;
723 struct security_priv
*psecuritypriv
= &padapter
->securitypriv
;
724 struct sk_buff
*skb
= precvframe
->pkt
;
727 if (prxattrib
->encrypt
!= WLAN_CIPHER_SUITE_TKIP
)
732 stainfo
= rtw_get_stainfo23a(&padapter
->stapriv
,
734 if (stainfo
== NULL
) {
735 RT_TRACE(_module_rtl871x_security_c_
, _drv_err_
,
736 "%s: stainfo == NULL!!!\n", __func__
);
740 /* 4 start to decrypt recvframe */
741 if (is_multicast_ether_addr(prxattrib
->ra
)) {
742 if (psecuritypriv
->binstallGrpkey
== 0) {
744 DBG_8723A("%s:rx bc/mc packets, but didn't install group key!!!!!!!!!!\n", __func__
);
747 prwskey
= psecuritypriv
->dot118021XGrpKey
[prxattrib
->key_index
].skey
;
750 RT_TRACE(_module_rtl871x_security_c_
, _drv_err_
,
751 "%s: stainfo!= NULL!!!\n", __func__
);
752 prwskey
= &stainfo
->dot118021x_UncstKey
.skey
[0];
756 iv
= pframe
+ prxattrib
->hdrlen
;
757 payload
= pframe
+ prxattrib
->iv_len
+ prxattrib
->hdrlen
;
758 length
= skb
->len
- prxattrib
->hdrlen
- prxattrib
->iv_len
;
760 GET_TKIP_PN(iv
, dot11txpn
);
762 pnl
= (u16
)(dot11txpn
.val
);
763 pnh
= (u32
)(dot11txpn
.val
>>16);
765 phase1((u16
*)&ttkey
[0], prwskey
, &prxattrib
->ta
[0], pnh
);
766 phase2(&rc4key
[0], prwskey
, (unsigned short *)&ttkey
[0], pnl
);
768 /* 4 decrypt payload include icv */
769 arcfour_init(&mycontext
, rc4key
, 16);
770 arcfour_encrypt(&mycontext
, payload
, payload
, length
);
772 actual_crc
= le32_to_cpu(getcrc32(payload
, length
- 4));
773 expected_crc
= le32_to_cpu(get_unaligned_le32(&payload
[length
- 4]));
775 if (actual_crc
!= expected_crc
) {
776 RT_TRACE(_module_rtl871x_security_c_
, _drv_err_
,
777 "%s:icv CRC mismatch: "
778 "actual: %08x, expected: %08x\n",
779 __func__
, actual_crc
, expected_crc
);
787 /* 3 ===== AES related ===== */
789 #define MAX_MSG_SIZE 2048
790 /*****************************/
791 /******** SBOX Table *********/
792 /*****************************/
794 static u8 sbox_table
[256] = {
795 0x63, 0x7c, 0x77, 0x7b, 0xf2, 0x6b, 0x6f, 0xc5,
796 0x30, 0x01, 0x67, 0x2b, 0xfe, 0xd7, 0xab, 0x76,
797 0xca, 0x82, 0xc9, 0x7d, 0xfa, 0x59, 0x47, 0xf0,
798 0xad, 0xd4, 0xa2, 0xaf, 0x9c, 0xa4, 0x72, 0xc0,
799 0xb7, 0xfd, 0x93, 0x26, 0x36, 0x3f, 0xf7, 0xcc,
800 0x34, 0xa5, 0xe5, 0xf1, 0x71, 0xd8, 0x31, 0x15,
801 0x04, 0xc7, 0x23, 0xc3, 0x18, 0x96, 0x05, 0x9a,
802 0x07, 0x12, 0x80, 0xe2, 0xeb, 0x27, 0xb2, 0x75,
803 0x09, 0x83, 0x2c, 0x1a, 0x1b, 0x6e, 0x5a, 0xa0,
804 0x52, 0x3b, 0xd6, 0xb3, 0x29, 0xe3, 0x2f, 0x84,
805 0x53, 0xd1, 0x00, 0xed, 0x20, 0xfc, 0xb1, 0x5b,
806 0x6a, 0xcb, 0xbe, 0x39, 0x4a, 0x4c, 0x58, 0xcf,
807 0xd0, 0xef, 0xaa, 0xfb, 0x43, 0x4d, 0x33, 0x85,
808 0x45, 0xf9, 0x02, 0x7f, 0x50, 0x3c, 0x9f, 0xa8,
809 0x51, 0xa3, 0x40, 0x8f, 0x92, 0x9d, 0x38, 0xf5,
810 0xbc, 0xb6, 0xda, 0x21, 0x10, 0xff, 0xf3, 0xd2,
811 0xcd, 0x0c, 0x13, 0xec, 0x5f, 0x97, 0x44, 0x17,
812 0xc4, 0xa7, 0x7e, 0x3d, 0x64, 0x5d, 0x19, 0x73,
813 0x60, 0x81, 0x4f, 0xdc, 0x22, 0x2a, 0x90, 0x88,
814 0x46, 0xee, 0xb8, 0x14, 0xde, 0x5e, 0x0b, 0xdb,
815 0xe0, 0x32, 0x3a, 0x0a, 0x49, 0x06, 0x24, 0x5c,
816 0xc2, 0xd3, 0xac, 0x62, 0x91, 0x95, 0xe4, 0x79,
817 0xe7, 0xc8, 0x37, 0x6d, 0x8d, 0xd5, 0x4e, 0xa9,
818 0x6c, 0x56, 0xf4, 0xea, 0x65, 0x7a, 0xae, 0x08,
819 0xba, 0x78, 0x25, 0x2e, 0x1c, 0xa6, 0xb4, 0xc6,
820 0xe8, 0xdd, 0x74, 0x1f, 0x4b, 0xbd, 0x8b, 0x8a,
821 0x70, 0x3e, 0xb5, 0x66, 0x48, 0x03, 0xf6, 0x0e,
822 0x61, 0x35, 0x57, 0xb9, 0x86, 0xc1, 0x1d, 0x9e,
823 0xe1, 0xf8, 0x98, 0x11, 0x69, 0xd9, 0x8e, 0x94,
824 0x9b, 0x1e, 0x87, 0xe9, 0xce, 0x55, 0x28, 0xdf,
825 0x8c, 0xa1, 0x89, 0x0d, 0xbf, 0xe6, 0x42, 0x68,
826 0x41, 0x99, 0x2d, 0x0f, 0xb0, 0x54, 0xbb, 0x16
829 /*****************************/
830 /**** Function Prototypes ****/
831 /*****************************/
833 static void construct_mic_header2(u8
*mic_header2
, u8
*mpdu
, int a4_exists
,
836 static void xor_128(u8
*a
, u8
*b
, u8
*out
)
840 for (i
= 0; i
< 16; i
++)
841 out
[i
] = a
[i
] ^ b
[i
];
844 static void xor_32(u8
*a
, u8
*b
, u8
*out
)
848 for (i
= 0; i
< 4; i
++)
849 out
[i
] = a
[i
] ^ b
[i
];
854 return sbox_table
[(int)a
];
857 static void next_key(u8
*key
, int round
)
861 u8 rcon_table
[12] = {
862 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80,
863 0x1b, 0x36, 0x36, 0x36
866 sbox_key
[0] = sbox(key
[13]);
867 sbox_key
[1] = sbox(key
[14]);
868 sbox_key
[2] = sbox(key
[15]);
869 sbox_key
[3] = sbox(key
[12]);
871 rcon
= rcon_table
[round
];
873 xor_32(&key
[0], sbox_key
, &key
[0]);
874 key
[0] = key
[0] ^ rcon
;
876 xor_32(&key
[4], &key
[0], &key
[4]);
877 xor_32(&key
[8], &key
[4], &key
[8]);
878 xor_32(&key
[12], &key
[8], &key
[12]);
882 static void byte_sub(u8
*in
, u8
*out
)
886 for (i
= 0; i
< 16; i
++)
887 out
[i
] = sbox(in
[i
]);
890 static void shift_row(u8
*in
, u8
*out
)
912 static void mix_column(u8
*in
, u8
*out
)
924 for (i
= 0; i
< 4; i
++) {
925 if ((in
[i
] & 0x80) == 0x80)
931 swap_halfs
[0] = in
[2]; /* Swap halfs */
932 swap_halfs
[1] = in
[3];
933 swap_halfs
[2] = in
[0];
934 swap_halfs
[3] = in
[1];
936 rotl
[0] = in
[3]; /* Rotate left 8 bits */
941 andf7
[0] = in
[0] & 0x7f;
942 andf7
[1] = in
[1] & 0x7f;
943 andf7
[2] = in
[2] & 0x7f;
944 andf7
[3] = in
[3] & 0x7f;
946 for (i
= 3; i
> 0; i
--) { /* logical shift left 1 bit */
947 andf7
[i
] = andf7
[i
] << 1;
948 if ((andf7
[i
- 1] & 0x80) == 0x80)
949 andf7
[i
] = (andf7
[i
] | 0x01);
951 andf7
[0] = andf7
[0] << 1;
952 andf7
[0] = andf7
[0] & 0xfe;
954 xor_32(add1b
, andf7
, add1bf7
);
956 xor_32(in
, add1bf7
, rotr
);
958 temp
[0] = rotr
[0]; /* Rotate right 8 bits */
964 xor_32(add1bf7
, rotr
, temp
);
965 xor_32(swap_halfs
, rotl
, tempb
);
966 xor_32(temp
, tempb
, out
);
970 static void aes128k128d(u8
*key
, u8
*data
, u8
*ciphertext
)
974 u8 intermediatea
[16];
975 u8 intermediateb
[16];
978 for (i
= 0; i
< 16; i
++)
979 round_key
[i
] = key
[i
];
981 for (round
= 0; round
< 11; round
++) {
983 xor_128(round_key
, data
, ciphertext
);
984 next_key(round_key
, round
);
985 } else if (round
== 10) {
986 byte_sub(ciphertext
, intermediatea
);
987 shift_row(intermediatea
, intermediateb
);
988 xor_128(intermediateb
, round_key
, ciphertext
);
990 byte_sub(ciphertext
, intermediatea
);
991 shift_row(intermediatea
, intermediateb
);
992 mix_column(&intermediateb
[0], &intermediatea
[0]);
993 mix_column(&intermediateb
[4], &intermediatea
[4]);
994 mix_column(&intermediateb
[8], &intermediatea
[8]);
995 mix_column(&intermediateb
[12], &intermediatea
[12]);
996 xor_128(intermediatea
, round_key
, ciphertext
);
997 next_key(round_key
, round
);
1003 /************************************************/
1004 /* construct_mic_iv() */
1005 /* Builds the MIC IV from header fields and PN */
1006 /************************************************/
1007 static void construct_mic_iv(u8
*mic_iv
, int qc_exists
, int a4_exists
, u8
*mpdu
,
1008 uint payload_length
, u8
*pn_vector
)
1013 if (qc_exists
&& a4_exists
)
1014 mic_iv
[1] = mpdu
[30] & 0x0f; /* QoS_TC */
1015 if (qc_exists
&& !a4_exists
)
1016 mic_iv
[1] = mpdu
[24] & 0x0f; /* mute bits 7-4 */
1019 for (i
= 2; i
< 8; i
++)
1020 mic_iv
[i
] = mpdu
[i
+ 8]; /* mic_iv[2:7] = A2[0:5] = mpdu[10:15] */
1021 for (i
= 8; i
< 14; i
++)
1022 mic_iv
[i
] = pn_vector
[13 - i
]; /* mic_iv[8:13] = PN[5:0] */
1023 mic_iv
[14] = (unsigned char)(payload_length
/ 256);
1024 mic_iv
[15] = (unsigned char)(payload_length
% 256);
1027 /************************************************/
1028 /* construct_mic_header1() */
1029 /* Builds the first MIC header block from */
1030 /* header fields. */
1031 /************************************************/
1032 static void construct_mic_header1(u8
*mic_header1
, int header_length
, u8
*mpdu
)
1034 mic_header1
[0] = (u8
)((header_length
- 2) / 256);
1035 mic_header1
[1] = (u8
)((header_length
- 2) % 256);
1036 mic_header1
[2] = mpdu
[0] & 0xcf; /* Mute CF poll & CF ack bits */
1037 mic_header1
[3] = mpdu
[1] & 0xc7; /* Mute retry, more data and pwr mgt bits */
1038 mic_header1
[4] = mpdu
[4]; /* A1 */
1039 mic_header1
[5] = mpdu
[5];
1040 mic_header1
[6] = mpdu
[6];
1041 mic_header1
[7] = mpdu
[7];
1042 mic_header1
[8] = mpdu
[8];
1043 mic_header1
[9] = mpdu
[9];
1044 mic_header1
[10] = mpdu
[10]; /* A2 */
1045 mic_header1
[11] = mpdu
[11];
1046 mic_header1
[12] = mpdu
[12];
1047 mic_header1
[13] = mpdu
[13];
1048 mic_header1
[14] = mpdu
[14];
1049 mic_header1
[15] = mpdu
[15];
1053 /************************************************/
1054 /* construct_mic_header2() */
1055 /* Builds the last MIC header block from */
1056 /* header fields. */
1057 /************************************************/
1058 static void construct_mic_header2(u8
*mic_header2
, u8
*mpdu
, int a4_exists
,
1063 for (i
= 0; i
< 16; i
++)
1064 mic_header2
[i
] = 0x00;
1066 mic_header2
[0] = mpdu
[16]; /* A3 */
1067 mic_header2
[1] = mpdu
[17];
1068 mic_header2
[2] = mpdu
[18];
1069 mic_header2
[3] = mpdu
[19];
1070 mic_header2
[4] = mpdu
[20];
1071 mic_header2
[5] = mpdu
[21];
1073 mic_header2
[6] = 0x00;
1074 mic_header2
[7] = 0x00; /* mpdu[23]; */
1076 if (!qc_exists
&& a4_exists
) {
1077 for (i
= 0; i
< 6; i
++)
1078 mic_header2
[8+i
] = mpdu
[24+i
]; /* A4 */
1081 if (qc_exists
&& !a4_exists
) {
1082 mic_header2
[8] = mpdu
[24] & 0x0f; /* mute bits 15 - 4 */
1083 mic_header2
[9] = mpdu
[25] & 0x00;
1086 if (qc_exists
&& a4_exists
) {
1087 for (i
= 0; i
< 6; i
++)
1088 mic_header2
[8+i
] = mpdu
[24+i
]; /* A4 */
1090 mic_header2
[14] = mpdu
[30] & 0x0f;
1091 mic_header2
[15] = mpdu
[31] & 0x00;
1096 /************************************************/
1097 /* construct_mic_header2() */
1098 /* Builds the last MIC header block from */
1099 /* header fields. */
1100 /************************************************/
1101 static void construct_ctr_preload(u8
*ctr_preload
, int a4_exists
, int qc_exists
,
1102 u8
*mpdu
, u8
*pn_vector
, int c
)
1106 for (i
= 0; i
< 16; i
++)
1107 ctr_preload
[i
] = 0x00;
1111 ctr_preload
[0] = 0x01; /* flag */
1112 if (qc_exists
&& a4_exists
)
1113 ctr_preload
[1] = mpdu
[30] & 0x0f; /* QoC_Control */
1114 if (qc_exists
&& !a4_exists
)
1115 ctr_preload
[1] = mpdu
[24] & 0x0f;
1117 for (i
= 2; i
< 8; i
++)
1118 ctr_preload
[i
] = mpdu
[i
+ 8]; /* ctr_preload[2:7] = A2[0:5] = mpdu[10:15] */
1119 for (i
= 8; i
< 14; i
++)
1120 ctr_preload
[i
] = pn_vector
[13 - i
]; /* ctr_preload[8:13] = PN[5:0] */
1121 ctr_preload
[14] = (unsigned char) (c
/ 256); /* Ctr */
1122 ctr_preload
[15] = (unsigned char) (c
% 256);
1126 /************************************/
1128 /* A 128 bit, bitwise exclusive or */
1129 /************************************/
1130 static void bitwise_xor(u8
*ina
, u8
*inb
, u8
*out
)
1134 for (i
= 0; i
< 16; i
++)
1135 out
[i
] = ina
[i
] ^ inb
[i
];
1138 static int aes_cipher(u8
*key
, uint hdrlen
, u8
*pframe
, uint plen
)
1140 uint qc_exists
, a4_exists
, i
, j
, payload_remainder
,
1141 num_blocks
, payload_index
;
1147 /* Intermediate Buffers */
1148 u8 chain_buffer
[16];
1150 u8 padded_buffer
[16];
1152 struct ieee80211_hdr
*hdr
= (struct ieee80211_hdr
*)pframe
;
1153 u16 frsubtype
= le16_to_cpu(hdr
->frame_control
) & IEEE80211_FCTL_STYPE
;
1155 memset((void *)mic_iv
, 0, 16);
1156 memset((void *)mic_header1
, 0, 16);
1157 memset((void *)mic_header2
, 0, 16);
1158 memset((void *)ctr_preload
, 0, 16);
1159 memset((void *)chain_buffer
, 0, 16);
1160 memset((void *)aes_out
, 0, 16);
1161 memset((void *)padded_buffer
, 0, 16);
1163 if ((hdrlen
== sizeof(struct ieee80211_hdr_3addr
) ||
1164 (hdrlen
== sizeof(struct ieee80211_qos_hdr
))))
1169 if (ieee80211_is_data(hdr
->frame_control
)) {
1170 if ((frsubtype
== IEEE80211_STYPE_DATA_CFACK
) ||
1171 (frsubtype
== IEEE80211_STYPE_DATA_CFPOLL
) ||
1172 (frsubtype
== IEEE80211_STYPE_DATA_CFACKPOLL
)) {
1174 if (hdrlen
!= sizeof(struct ieee80211_qos_hdr
))
1176 } else if ((frsubtype
== IEEE80211_STYPE_QOS_DATA
) ||
1177 (frsubtype
== IEEE80211_STYPE_QOS_DATA_CFACK
) ||
1178 (frsubtype
== IEEE80211_STYPE_QOS_DATA_CFPOLL
) ||
1179 (frsubtype
== IEEE80211_STYPE_QOS_DATA_CFACKPOLL
)) {
1180 if (hdrlen
!= sizeof(struct ieee80211_qos_hdr
))
1189 pn_vector
[0] = pframe
[hdrlen
];
1190 pn_vector
[1] = pframe
[hdrlen
+ 1];
1191 pn_vector
[2] = pframe
[hdrlen
+ 4];
1192 pn_vector
[3] = pframe
[hdrlen
+ 5];
1193 pn_vector
[4] = pframe
[hdrlen
+ 6];
1194 pn_vector
[5] = pframe
[hdrlen
+ 7];
1196 construct_mic_iv(mic_iv
, qc_exists
, a4_exists
, pframe
, plen
, pn_vector
);
1198 construct_mic_header1(mic_header1
, hdrlen
, pframe
);
1199 construct_mic_header2(mic_header2
, pframe
, a4_exists
, qc_exists
);
1201 payload_remainder
= plen
% 16;
1202 num_blocks
= plen
/ 16;
1204 /* Find start of payload */
1205 payload_index
= hdrlen
+ 8;
1208 aes128k128d(key
, mic_iv
, aes_out
);
1209 bitwise_xor(aes_out
, mic_header1
, chain_buffer
);
1210 aes128k128d(key
, chain_buffer
, aes_out
);
1211 bitwise_xor(aes_out
, mic_header2
, chain_buffer
);
1212 aes128k128d(key
, chain_buffer
, aes_out
);
1214 for (i
= 0; i
< num_blocks
; i
++) {
1215 bitwise_xor(aes_out
, &pframe
[payload_index
], chain_buffer
);
1217 payload_index
+= 16;
1218 aes128k128d(key
, chain_buffer
, aes_out
);
1221 /* Add on the final payload block if it needs padding */
1222 if (payload_remainder
> 0) {
1223 for (j
= 0; j
< 16; j
++)
1224 padded_buffer
[j
] = 0x00;
1225 for (j
= 0; j
< payload_remainder
; j
++)
1226 padded_buffer
[j
] = pframe
[payload_index
++];
1227 bitwise_xor(aes_out
, padded_buffer
, chain_buffer
);
1228 aes128k128d(key
, chain_buffer
, aes_out
);
1231 for (j
= 0; j
< 8; j
++)
1232 mic
[j
] = aes_out
[j
];
1234 /* Insert MIC into payload */
1235 for (j
= 0; j
< 8; j
++)
1236 pframe
[payload_index
+ j
] = mic
[j
];
1238 payload_index
= hdrlen
+ 8;
1239 for (i
= 0; i
< num_blocks
; i
++) {
1240 construct_ctr_preload(ctr_preload
, a4_exists
, qc_exists
,
1241 pframe
, pn_vector
, i
+ 1);
1242 aes128k128d(key
, ctr_preload
, aes_out
);
1243 bitwise_xor(aes_out
, &pframe
[payload_index
], chain_buffer
);
1244 for (j
= 0; j
< 16; j
++)
1245 pframe
[payload_index
++] = chain_buffer
[j
];
1248 if (payload_remainder
> 0) {
1249 /* If there is a short final block, then pad it,
1250 * encrypt it and copy the unpadded part back
1252 construct_ctr_preload(ctr_preload
, a4_exists
, qc_exists
, pframe
,
1253 pn_vector
, num_blocks
+ 1);
1255 for (j
= 0; j
< 16; j
++)
1256 padded_buffer
[j
] = 0x00;
1257 for (j
= 0; j
< payload_remainder
; j
++)
1258 padded_buffer
[j
] = pframe
[payload_index
+ j
];
1259 aes128k128d(key
, ctr_preload
, aes_out
);
1260 bitwise_xor(aes_out
, padded_buffer
, chain_buffer
);
1261 for (j
= 0; j
< payload_remainder
; j
++)
1262 pframe
[payload_index
++] = chain_buffer
[j
];
1265 /* Encrypt the MIC */
1266 construct_ctr_preload(ctr_preload
, a4_exists
, qc_exists
, pframe
,
1269 for (j
= 0; j
< 16; j
++)
1270 padded_buffer
[j
] = 0x00;
1271 for (j
= 0; j
< 8; j
++)
1272 padded_buffer
[j
] = pframe
[j
+ hdrlen
+ 8 + plen
];
1274 aes128k128d(key
, ctr_preload
, aes_out
);
1275 bitwise_xor(aes_out
, padded_buffer
, chain_buffer
);
1276 for (j
= 0; j
< 8; j
++)
1277 pframe
[payload_index
++] = chain_buffer
[j
];
1282 int rtw_aes_encrypt23a(struct rtw_adapter
*padapter
,
1283 struct xmit_frame
*pxmitframe
)
1285 /* Intermediate Buffers */
1286 int curfragnum
, length
;
1288 u8
*pframe
, *prwskey
;
1289 u8 hw_hdr_offset
= 0;
1290 struct sta_info
*stainfo
;
1291 struct pkt_attrib
*pattrib
= &pxmitframe
->attrib
;
1292 struct security_priv
*psecuritypriv
= &padapter
->securitypriv
;
1293 struct xmit_priv
*pxmitpriv
= &padapter
->xmitpriv
;
1296 if (!pxmitframe
->buf_addr
)
1299 hw_hdr_offset
= TXDESC_OFFSET
;
1301 pframe
= pxmitframe
->buf_addr
+ hw_hdr_offset
;
1303 /* 4 start to encrypt each fragment */
1304 if (pattrib
->encrypt
!= WLAN_CIPHER_SUITE_CCMP
)
1307 if (pattrib
->psta
) {
1308 stainfo
= pattrib
->psta
;
1310 DBG_8723A("%s, call rtw_get_stainfo23a()\n", __func__
);
1311 stainfo
= rtw_get_stainfo23a(&padapter
->stapriv
, &pattrib
->ra
[0]);
1315 RT_TRACE(_module_rtl871x_security_c_
, _drv_err_
,
1316 "%s: stainfo == NULL!!!\n", __func__
);
1317 DBG_8723A("%s, psta == NUL\n", __func__
);
1321 if (!(stainfo
->state
& _FW_LINKED
)) {
1322 DBG_8723A("%s, psta->state(0x%x) != _FW_LINKED\n",
1323 __func__
, stainfo
->state
);
1326 RT_TRACE(_module_rtl871x_security_c_
, _drv_err_
,
1327 "%s: stainfo!= NULL!!!\n", __func__
);
1329 if (is_multicast_ether_addr(pattrib
->ra
))
1330 prwskey
= psecuritypriv
->dot118021XGrpKey
[psecuritypriv
->dot118021XGrpKeyid
].skey
;
1332 prwskey
= &stainfo
->dot118021x_UncstKey
.skey
[0];
1336 for (curfragnum
= 0; curfragnum
< pattrib
->nr_frags
; curfragnum
++) {
1337 /* 4 the last fragment */
1338 if ((curfragnum
+ 1) == pattrib
->nr_frags
) {
1339 length
= pattrib
->last_txcmdsz
-
1340 pattrib
->hdrlen
-pattrib
->iv_len
-
1343 aes_cipher(prwskey
, pattrib
->hdrlen
, pframe
, length
);
1345 length
= pxmitpriv
->frag_len
-pattrib
->hdrlen
-
1346 pattrib
->iv_len
- pattrib
->icv_len
;
1348 aes_cipher(prwskey
, pattrib
->hdrlen
, pframe
, length
);
1349 pframe
+= pxmitpriv
->frag_len
;
1350 pframe
= PTR_ALIGN(pframe
, 4);
1357 static int aes_decipher(u8
*key
, uint hdrlen
, u8
*pframe
, uint plen
)
1359 static u8 message
[MAX_MSG_SIZE
];
1360 uint qc_exists
, a4_exists
, i
, j
, payload_remainder
,
1361 num_blocks
, payload_index
;
1368 /* Intermediate Buffers */
1369 u8 chain_buffer
[16];
1371 u8 padded_buffer
[16];
1373 struct ieee80211_hdr
*hdr
= (struct ieee80211_hdr
*)pframe
;
1374 u16 frsubtype
= le16_to_cpu(hdr
->frame_control
) & IEEE80211_FCTL_STYPE
;
1376 memset((void *)mic_iv
, 0, 16);
1377 memset((void *)mic_header1
, 0, 16);
1378 memset((void *)mic_header2
, 0, 16);
1379 memset((void *)ctr_preload
, 0, 16);
1380 memset((void *)chain_buffer
, 0, 16);
1381 memset((void *)aes_out
, 0, 16);
1382 memset((void *)padded_buffer
, 0, 16);
1384 /* start to decrypt the payload */
1386 num_blocks
= (plen
- 8) / 16; /* plen including llc, payload_length and mic) */
1388 payload_remainder
= (plen
- 8) % 16;
1390 pn_vector
[0] = pframe
[hdrlen
];
1391 pn_vector
[1] = pframe
[hdrlen
+ 1];
1392 pn_vector
[2] = pframe
[hdrlen
+ 4];
1393 pn_vector
[3] = pframe
[hdrlen
+ 5];
1394 pn_vector
[4] = pframe
[hdrlen
+ 6];
1395 pn_vector
[5] = pframe
[hdrlen
+ 7];
1397 if ((hdrlen
== sizeof(struct ieee80211_hdr_3addr
) ||
1398 (hdrlen
== sizeof(struct ieee80211_qos_hdr
))))
1403 if (ieee80211_is_data(hdr
->frame_control
)) {
1404 if ((frsubtype
== IEEE80211_STYPE_DATA_CFACK
) ||
1405 (frsubtype
== IEEE80211_STYPE_DATA_CFPOLL
) ||
1406 (frsubtype
== IEEE80211_STYPE_DATA_CFACKPOLL
)) {
1408 if (hdrlen
!= sizeof(struct ieee80211_hdr_3addr
))
1410 } else if ((frsubtype
== IEEE80211_STYPE_QOS_DATA
) ||
1411 (frsubtype
== IEEE80211_STYPE_QOS_DATA_CFACK
) ||
1412 (frsubtype
== IEEE80211_STYPE_QOS_DATA_CFPOLL
) ||
1413 (frsubtype
== IEEE80211_STYPE_QOS_DATA_CFACKPOLL
)) {
1414 if (hdrlen
!= sizeof(struct ieee80211_hdr_3addr
))
1424 /* now, decrypt pframe with hdrlen offset and plen long */
1426 payload_index
= hdrlen
+ 8; /* 8 is for extiv */
1428 for (i
= 0; i
< num_blocks
; i
++) {
1429 construct_ctr_preload(ctr_preload
, a4_exists
, qc_exists
,
1430 pframe
, pn_vector
, i
+ 1);
1432 aes128k128d(key
, ctr_preload
, aes_out
);
1433 bitwise_xor(aes_out
, &pframe
[payload_index
], chain_buffer
);
1435 for (j
= 0; j
< 16; j
++)
1436 pframe
[payload_index
++] = chain_buffer
[j
];
1439 if (payload_remainder
> 0) {
1440 /* If there is a short final block, then pad it,
1441 * encrypt it and copy the unpadded part back
1443 construct_ctr_preload(ctr_preload
, a4_exists
, qc_exists
, pframe
,
1444 pn_vector
, num_blocks
+ 1);
1446 for (j
= 0; j
< 16; j
++)
1447 padded_buffer
[j
] = 0x00;
1448 for (j
= 0; j
< payload_remainder
; j
++)
1449 padded_buffer
[j
] = pframe
[payload_index
+ j
];
1450 aes128k128d(key
, ctr_preload
, aes_out
);
1451 bitwise_xor(aes_out
, padded_buffer
, chain_buffer
);
1452 for (j
= 0; j
< payload_remainder
; j
++)
1453 pframe
[payload_index
++] = chain_buffer
[j
];
1456 /* start to calculate the mic */
1457 if ((hdrlen
+ plen
+ 8) <= MAX_MSG_SIZE
)
1458 memcpy(message
, pframe
, (hdrlen
+ plen
+ 8)); /* 8 is for ext iv len */
1460 pn_vector
[0] = pframe
[hdrlen
];
1461 pn_vector
[1] = pframe
[hdrlen
+ 1];
1462 pn_vector
[2] = pframe
[hdrlen
+ 4];
1463 pn_vector
[3] = pframe
[hdrlen
+ 5];
1464 pn_vector
[4] = pframe
[hdrlen
+ 6];
1465 pn_vector
[5] = pframe
[hdrlen
+ 7];
1467 construct_mic_iv(mic_iv
, qc_exists
, a4_exists
, message
,
1468 plen
- 8, pn_vector
);
1470 construct_mic_header1(mic_header1
, hdrlen
, message
);
1471 construct_mic_header2(mic_header2
, message
, a4_exists
, qc_exists
);
1473 payload_remainder
= (plen
- 8) % 16;
1474 num_blocks
= (plen
- 8) / 16;
1476 /* Find start of payload */
1477 payload_index
= hdrlen
+ 8;
1480 aes128k128d(key
, mic_iv
, aes_out
);
1481 bitwise_xor(aes_out
, mic_header1
, chain_buffer
);
1482 aes128k128d(key
, chain_buffer
, aes_out
);
1483 bitwise_xor(aes_out
, mic_header2
, chain_buffer
);
1484 aes128k128d(key
, chain_buffer
, aes_out
);
1486 for (i
= 0; i
< num_blocks
; i
++) {
1487 bitwise_xor(aes_out
, &message
[payload_index
], chain_buffer
);
1489 payload_index
+= 16;
1490 aes128k128d(key
, chain_buffer
, aes_out
);
1493 /* Add on the final payload block if it needs padding */
1494 if (payload_remainder
> 0) {
1495 for (j
= 0; j
< 16; j
++)
1496 padded_buffer
[j
] = 0x00;
1497 for (j
= 0; j
< payload_remainder
; j
++)
1498 padded_buffer
[j
] = message
[payload_index
++];
1499 bitwise_xor(aes_out
, padded_buffer
, chain_buffer
);
1500 aes128k128d(key
, chain_buffer
, aes_out
);
1503 for (j
= 0 ; j
< 8; j
++)
1504 mic
[j
] = aes_out
[j
];
1506 /* Insert MIC into payload */
1507 for (j
= 0; j
< 8; j
++)
1508 message
[payload_index
+ j
] = mic
[j
];
1510 payload_index
= hdrlen
+ 8;
1511 for (i
= 0; i
< num_blocks
; i
++) {
1512 construct_ctr_preload(ctr_preload
, a4_exists
, qc_exists
,
1513 message
, pn_vector
, i
+ 1);
1514 aes128k128d(key
, ctr_preload
, aes_out
);
1515 bitwise_xor(aes_out
, &message
[payload_index
], chain_buffer
);
1516 for (j
= 0; j
< 16; j
++)
1517 message
[payload_index
++] = chain_buffer
[j
];
1520 if (payload_remainder
> 0) {
1521 /* If there is a short final block, then pad it,
1522 * encrypt it and copy the unpadded part back
1524 construct_ctr_preload(ctr_preload
, a4_exists
, qc_exists
,
1525 message
, pn_vector
, num_blocks
+ 1);
1527 for (j
= 0; j
< 16; j
++)
1528 padded_buffer
[j
] = 0x00;
1529 for (j
= 0; j
< payload_remainder
; j
++)
1530 padded_buffer
[j
] = message
[payload_index
+ j
];
1531 aes128k128d(key
, ctr_preload
, aes_out
);
1532 bitwise_xor(aes_out
, padded_buffer
, chain_buffer
);
1533 for (j
= 0; j
< payload_remainder
; j
++)
1534 message
[payload_index
++] = chain_buffer
[j
];
1537 /* Encrypt the MIC */
1538 construct_ctr_preload(ctr_preload
, a4_exists
, qc_exists
, message
,
1541 for (j
= 0; j
< 16; j
++)
1542 padded_buffer
[j
] = 0x00;
1543 for (j
= 0; j
< 8; j
++)
1544 padded_buffer
[j
] = message
[j
+ hdrlen
+ 8 + plen
- 8];
1546 aes128k128d(key
, ctr_preload
, aes_out
);
1547 bitwise_xor(aes_out
, padded_buffer
, chain_buffer
);
1548 for (j
= 0; j
< 8; j
++)
1549 message
[payload_index
++] = chain_buffer
[j
];
1551 /* compare the mic */
1552 for (i
= 0; i
< 8; i
++) {
1553 if (pframe
[hdrlen
+ 8 + plen
- 8 + i
] != message
[hdrlen
+ 8 + plen
- 8 + i
]) {
1554 RT_TRACE(_module_rtl871x_security_c_
, _drv_err_
,
1555 "%s:mic check error mic[%d]: pframe(%x) != message(%x)\n",
1557 pframe
[hdrlen
+ 8 + plen
- 8 + i
],
1558 message
[hdrlen
+ 8 + plen
- 8 + i
]);
1559 DBG_8723A("%s:mic check error mic[%d]: pframe(%x) != message(%x)\n",
1561 pframe
[hdrlen
+ 8 + plen
- 8 + i
],
1562 message
[hdrlen
+ 8 + plen
- 8 + i
]);
1569 int rtw_aes_decrypt23a(struct rtw_adapter
*padapter
,
1570 struct recv_frame
*precvframe
)
1572 struct sta_info
*stainfo
;
1573 struct rx_pkt_attrib
*prxattrib
= &precvframe
->attrib
;
1574 struct security_priv
*psecuritypriv
= &padapter
->securitypriv
;
1575 struct sk_buff
*skb
= precvframe
->pkt
;
1577 u8
*pframe
, *prwskey
;
1581 /* 4 start to encrypt each fragment */
1582 if (prxattrib
->encrypt
!= WLAN_CIPHER_SUITE_CCMP
)
1585 stainfo
= rtw_get_stainfo23a(&padapter
->stapriv
, &prxattrib
->ta
[0]);
1587 RT_TRACE(_module_rtl871x_security_c_
, _drv_err_
,
1588 "%s: stainfo == NULL!!!\n", __func__
);
1593 RT_TRACE(_module_rtl871x_security_c_
, _drv_err_
,
1594 "%s: stainfo!= NULL!!!\n", __func__
);
1596 if (is_multicast_ether_addr(prxattrib
->ra
)) {
1597 /* in concurrent we should use sw decrypt in
1598 * group key, so we remove this message
1600 if (!psecuritypriv
->binstallGrpkey
) {
1602 DBG_8723A("%s:rx bc/mc packets, but didn't install "
1603 "group key!!!!!!!!!!\n", __func__
);
1606 prwskey
= psecuritypriv
->dot118021XGrpKey
[prxattrib
->key_index
].skey
;
1607 if (psecuritypriv
->dot118021XGrpKeyid
!= prxattrib
->key_index
) {
1608 DBG_8723A("not match packet_index =%d, install_index ="
1609 "%d\n", prxattrib
->key_index
,
1610 psecuritypriv
->dot118021XGrpKeyid
);
1615 prwskey
= &stainfo
->dot118021x_UncstKey
.skey
[0];
1618 length
= skb
->len
- prxattrib
->hdrlen
- prxattrib
->iv_len
;
1620 res
= aes_decipher(prwskey
, prxattrib
->hdrlen
, pframe
, length
);
1625 void rtw_use_tkipkey_handler23a(void *FunctionContext
)
1627 struct rtw_adapter
*padapter
= (struct rtw_adapter
*)FunctionContext
;
1629 RT_TRACE(_module_rtl871x_security_c_
, _drv_err_
,
1630 "^^^%s ^^^\n", __func__
);
1631 padapter
->securitypriv
.busetkipkey
= 1;
1632 RT_TRACE(_module_rtl871x_security_c_
, _drv_err_
,
1633 "^^^%s padapter->securitypriv.busetkipkey =%d^^^\n",
1634 __func__
, padapter
->securitypriv
.busetkipkey
);