1 /******************************************************************************
4 * Copyright(c) 2007 - 2010 Realtek Corporation. All rights reserved.
5 * Linux device driver for RTL8192SU
7 * This program is free software; you can redistribute it and/or modify it
8 * under the terms of version 2 of the GNU General Public License as
9 * published by the Free Software Foundation.
11 * This program is distributed in the hope that it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
16 * You should have received a copy of the GNU General Public License along with
17 * this program; if not, write to the Free Software Foundation, Inc.,
18 * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
20 * Modifications for inclusion into the Linux staging tree are
21 * Copyright(c) 2010 Larry Finger. All rights reserved.
23 * Contact information:
24 * WLAN FAE <wlanfae@realtek.com>
25 * Larry Finger <Larry.Finger@lwfinger.net>
27 ******************************************************************************/
29 #define _RTL871X_SECURITY_C_
31 #include "osdep_service.h"
32 #include "drv_types.h"
34 #include "osdep_intf.h"
36 /* =====WEP related===== */
38 #define CRC32_POLY 0x04c11db7
46 static void arcfour_init(struct arc4context
*parc4ctx
, u8
* key
, u32 key_len
)
54 state
= parc4ctx
->state
;
57 for (counter
= 0; counter
< 256; counter
++)
58 state
[counter
] = (u8
)counter
;
61 for (counter
= 0; counter
< 256; counter
++) {
63 stateindex
= (stateindex
+ key
[keyindex
] + t
) & 0xff;
64 u
= state
[stateindex
];
65 state
[stateindex
] = (u8
)t
;
66 state
[counter
] = (u8
)u
;
67 if (++keyindex
>= key_len
)
72 static u32
arcfour_byte(struct arc4context
*parc4ctx
)
79 state
= parc4ctx
->state
;
80 x
= (parc4ctx
->x
+ 1) & 0xff;
82 y
= (sx
+ parc4ctx
->y
) & 0xff;
88 return state
[(sx
+ sy
) & 0xff];
91 static void arcfour_encrypt(struct arc4context
*parc4ctx
,
92 u8
*dest
, u8
*src
, u32 len
)
96 for (i
= 0; i
< len
; i
++)
97 dest
[i
] = src
[i
] ^ (unsigned char)arcfour_byte(parc4ctx
);
100 static sint bcrc32initialized
;
101 static u32 crc32_table
[256];
103 static u8
crc32_reverseBit(u8 data
)
105 return ((u8
)(data
<< 7) & 0x80) | ((data
<< 5) & 0x40) | ((data
<< 3)
106 & 0x20) | ((data
<< 1) & 0x10) | ((data
>> 1) & 0x08) |
107 ((data
>> 3) & 0x04) | ((data
>> 5) & 0x02) | ((data
>> 7) &
111 static void crc32_init(void)
113 if (bcrc32initialized
== 1)
118 u8
*p
= (u8
*)&c
, *p1
;
122 for (i
= 0; i
< 256; ++i
) {
123 k
= crc32_reverseBit((u8
)i
);
124 for (c
= ((u32
)k
) << 24, j
= 8; j
> 0; --j
)
125 c
= c
& 0x80000000 ? (c
<< 1) ^ CRC32_POLY
:
127 p1
= (u8
*)&crc32_table
[i
];
128 p1
[0] = crc32_reverseBit(p
[3]);
129 p1
[1] = crc32_reverseBit(p
[2]);
130 p1
[2] = crc32_reverseBit(p
[1]);
131 p1
[3] = crc32_reverseBit(p
[0]);
133 bcrc32initialized
= 1;
137 static u32
getcrc32(u8
*buf
, u32 len
)
142 if (bcrc32initialized
== 0)
144 crc
= 0xffffffff; /* preload shift register, per CRC-32 spec */
145 for (p
= buf
; len
> 0; ++p
, --len
)
146 crc
= crc32_table
[(crc
^ *p
) & 0xff] ^ (crc
>> 8);
147 return ~crc
; /* transmit complement, per CRC-32 spec */
151 Need to consider the fragment situation
153 void r8712_wep_encrypt(struct _adapter
*padapter
, u8
*pxmitframe
)
155 unsigned char crc
[4];
156 struct arc4context mycontext
;
157 u32 curfragnum
, length
, keylength
;
158 u8
*pframe
, *payload
, *iv
; /*,*wepkey*/
160 struct pkt_attrib
*pattrib
= &((struct xmit_frame
*)
162 struct security_priv
*psecuritypriv
= &padapter
->securitypriv
;
163 struct xmit_priv
*pxmitpriv
= &padapter
->xmitpriv
;
165 if (((struct xmit_frame
*)pxmitframe
)->buf_addr
== NULL
)
167 pframe
= ((struct xmit_frame
*)pxmitframe
)->buf_addr
+TXDESC_OFFSET
;
168 /*start to encrypt each fragment*/
169 if ((pattrib
->encrypt
== _WEP40_
) || (pattrib
->encrypt
== _WEP104_
)) {
170 keylength
= psecuritypriv
->DefKeylen
[psecuritypriv
->
172 for (curfragnum
= 0; curfragnum
< pattrib
->nr_frags
;
174 iv
= pframe
+pattrib
->hdrlen
;
175 memcpy(&wepkey
[0], iv
, 3);
176 memcpy(&wepkey
[3], &psecuritypriv
->DefKey
[
177 psecuritypriv
->PrivacyKeyIndex
].skey
[0],
179 payload
= pframe
+pattrib
->iv_len
+pattrib
->hdrlen
;
180 if ((curfragnum
+ 1) == pattrib
->nr_frags
) {
181 length
= pattrib
->last_txcmdsz
-pattrib
->
182 hdrlen
-pattrib
->iv_len
-
184 *((u32
*)crc
) = cpu_to_le32(getcrc32(
186 arcfour_init(&mycontext
, wepkey
, 3 + keylength
);
187 arcfour_encrypt(&mycontext
, payload
, payload
,
189 arcfour_encrypt(&mycontext
, payload
+ length
,
192 length
= pxmitpriv
->frag_len
-pattrib
->hdrlen
-
193 pattrib
->iv_len
-pattrib
->icv_len
;
194 *((u32
*)crc
) = cpu_to_le32(getcrc32(
196 arcfour_init(&mycontext
, wepkey
, 3 + keylength
);
197 arcfour_encrypt(&mycontext
, payload
, payload
,
199 arcfour_encrypt(&mycontext
, payload
+length
,
201 pframe
+= pxmitpriv
->frag_len
;
202 pframe
= (u8
*)RND4((addr_t
)(pframe
));
208 void r8712_wep_decrypt(struct _adapter
*padapter
, u8
*precvframe
)
212 struct arc4context mycontext
;
213 u32 length
, keylength
;
214 u8
*pframe
, *payload
, *iv
, wepkey
[16];
216 struct rx_pkt_attrib
*prxattrib
= &(((union recv_frame
*)
217 precvframe
)->u
.hdr
.attrib
);
218 struct security_priv
*psecuritypriv
= &padapter
->securitypriv
;
220 pframe
= (unsigned char *)((union recv_frame
*)precvframe
)->
222 /* start to decrypt recvframe */
223 if ((prxattrib
->encrypt
== _WEP40_
) || (prxattrib
->encrypt
==
225 iv
= pframe
+ prxattrib
->hdrlen
;
226 keyindex
= (iv
[3] & 0x3);
227 keylength
= psecuritypriv
->DefKeylen
[keyindex
];
228 memcpy(&wepkey
[0], iv
, 3);
229 memcpy(&wepkey
[3], &psecuritypriv
->DefKey
[
230 psecuritypriv
->PrivacyKeyIndex
].skey
[0],
232 length
= ((union recv_frame
*)precvframe
)->
233 u
.hdr
.len
-prxattrib
->hdrlen
-prxattrib
->iv_len
;
234 payload
= pframe
+prxattrib
->iv_len
+prxattrib
->hdrlen
;
235 /* decrypt payload include icv */
236 arcfour_init(&mycontext
, wepkey
, 3 + keylength
);
237 arcfour_encrypt(&mycontext
, payload
, payload
, length
);
238 /* calculate icv and compare the icv */
239 *((u32
*)crc
) = cpu_to_le32(getcrc32(payload
, length
- 4));
244 /* 3 =====TKIP related===== */
246 static u32
secmicgetuint32(u8
*p
)
247 /* Convert from Byte[] to Us4Byte32 in a portable way */
252 for (i
= 0; i
< 4; i
++)
253 res
|= ((u32
)(*p
++)) << (8 * i
);
257 static void secmicputuint32(u8
*p
, u32 val
)
258 /* Convert from Us4Byte32 to Byte[] in a portable way */
261 for (i
= 0; i
< 4; i
++) {
262 *p
++ = (u8
) (val
& 0xff);
267 static void secmicclear(struct mic_data
*pmicdata
)
269 /* Reset the state to the empty message. */
270 pmicdata
->L
= pmicdata
->K0
;
271 pmicdata
->R
= pmicdata
->K1
;
272 pmicdata
->nBytesInM
= 0;
276 void r8712_secmicsetkey(struct mic_data
*pmicdata
, u8
* key
)
279 pmicdata
->K0
= secmicgetuint32(key
);
280 pmicdata
->K1
= secmicgetuint32(key
+ 4);
281 /* and reset the message */
282 secmicclear(pmicdata
);
285 static void secmicappendbyte(struct mic_data
*pmicdata
, u8 b
)
287 /* Append the byte to our word-sized buffer */
288 pmicdata
->M
|= ((u32
)b
) << (8 * pmicdata
->nBytesInM
);
289 pmicdata
->nBytesInM
++;
290 /* Process the word if it is full. */
291 if (pmicdata
->nBytesInM
>= 4) {
292 pmicdata
->L
^= pmicdata
->M
;
293 pmicdata
->R
^= ROL32(pmicdata
->L
, 17);
294 pmicdata
->L
+= pmicdata
->R
;
295 pmicdata
->R
^= ((pmicdata
->L
& 0xff00ff00) >> 8) |
296 ((pmicdata
->L
& 0x00ff00ff) << 8);
297 pmicdata
->L
+= pmicdata
->R
;
298 pmicdata
->R
^= ROL32(pmicdata
->L
, 3);
299 pmicdata
->L
+= pmicdata
->R
;
300 pmicdata
->R
^= ROR32(pmicdata
->L
, 2);
301 pmicdata
->L
+= pmicdata
->R
;
302 /* Clear the buffer */
304 pmicdata
->nBytesInM
= 0;
308 void r8712_secmicappend(struct mic_data
*pmicdata
, u8
* src
, u32 nbytes
)
312 secmicappendbyte(pmicdata
, *src
++);
317 void r8712_secgetmic(struct mic_data
*pmicdata
, u8
*dst
)
319 /* Append the minimum padding */
320 secmicappendbyte(pmicdata
, 0x5a);
321 secmicappendbyte(pmicdata
, 0);
322 secmicappendbyte(pmicdata
, 0);
323 secmicappendbyte(pmicdata
, 0);
324 secmicappendbyte(pmicdata
, 0);
325 /* and then zeroes until the length is a multiple of 4 */
326 while (pmicdata
->nBytesInM
!= 0)
327 secmicappendbyte(pmicdata
, 0);
328 /* The appendByte function has already computed the result. */
329 secmicputuint32(dst
, pmicdata
->L
);
330 secmicputuint32(dst
+ 4, pmicdata
->R
);
331 /* Reset to the empty message. */
332 secmicclear(pmicdata
);
335 void seccalctkipmic(u8
*key
, u8
*header
, u8
*data
, u32 data_len
, u8
*mic_code
,
339 struct mic_data micdata
;
340 u8 priority
[4] = {0x0, 0x0, 0x0, 0x0};
342 r8712_secmicsetkey(&micdata
, key
);
344 /* Michael MIC pseudo header: DA, SA, 3 x 0, Priority */
345 if (header
[1] & 1) { /* ToDS==1 */
346 r8712_secmicappend(&micdata
, &header
[16], 6); /* DA */
347 if (header
[1] & 2) /* From Ds==1 */
348 r8712_secmicappend(&micdata
, &header
[24], 6);
350 r8712_secmicappend(&micdata
, &header
[10], 6);
351 } else { /* ToDS==0 */
352 r8712_secmicappend(&micdata
, &header
[4], 6); /* DA */
353 if (header
[1] & 2) /* From Ds==1 */
354 r8712_secmicappend(&micdata
, &header
[16], 6);
356 r8712_secmicappend(&micdata
, &header
[10], 6);
358 r8712_secmicappend(&micdata
, &priority
[0], 4);
359 r8712_secmicappend(&micdata
, data
, data_len
);
360 r8712_secgetmic(&micdata
, mic_code
);
363 /* macros for extraction/creation of unsigned char/unsigned short values */
364 #define RotR1(v16) ((((v16) >> 1) & 0x7FFF) ^ (((v16) & 1) << 15))
365 #define Lo8(v16) ((u8)((v16) & 0x00FF))
366 #define Hi8(v16) ((u8)(((v16) >> 8) & 0x00FF))
367 #define Lo16(v32) ((u16)((v32) & 0xFFFF))
368 #define Hi16(v32) ((u16)(((v32) >> 16) & 0xFFFF))
369 #define Mk16(hi, lo) ((lo) ^ (((u16)(hi)) << 8))
371 /* select the Nth 16-bit word of the temporal key unsigned char array TK[] */
372 #define TK16(N) Mk16(tk[2 * (N) + 1], tk[2 * (N)])
374 /* S-box lookup: 16 bits --> 16 bits */
375 #define _S_(v16) (Sbox1[0][Lo8(v16)] ^ Sbox1[1][Hi8(v16)])
377 /* fixed algorithm "parameters" */
378 #define PHASE1_LOOP_CNT 8 /* this needs to be "big enough" */
379 #define TA_SIZE 6 /* 48-bit transmitter address */
380 #define TK_SIZE 16 /* 128-bit temporal key */
381 #define P1K_SIZE 10 /* 80-bit Phase1 key */
382 #define RC4_KEY_SIZE 16 /* 128-bit RC4KEY (104 bits unknown) */
385 /* 2-unsigned char by 2-unsigned char subset of the full AES S-box table */
386 static const unsigned short Sbox1
[2][256] = {/* Sbox for hash (can be in ROM) */
388 0xC6A5, 0xF884, 0xEE99, 0xF68D, 0xFF0D, 0xD6BD, 0xDEB1, 0x9154,
389 0x6050, 0x0203, 0xCEA9, 0x567D, 0xE719, 0xB562, 0x4DE6, 0xEC9A,
390 0x8F45, 0x1F9D, 0x8940, 0xFA87, 0xEF15, 0xB2EB, 0x8EC9, 0xFB0B,
391 0x41EC, 0xB367, 0x5FFD, 0x45EA, 0x23BF, 0x53F7, 0xE496, 0x9B5B,
392 0x75C2, 0xE11C, 0x3DAE, 0x4C6A, 0x6C5A, 0x7E41, 0xF502, 0x834F,
393 0x685C, 0x51F4, 0xD134, 0xF908, 0xE293, 0xAB73, 0x6253, 0x2A3F,
394 0x080C, 0x9552, 0x4665, 0x9D5E, 0x3028, 0x37A1, 0x0A0F, 0x2FB5,
395 0x0E09, 0x2436, 0x1B9B, 0xDF3D, 0xCD26, 0x4E69, 0x7FCD, 0xEA9F,
396 0x121B, 0x1D9E, 0x5874, 0x342E, 0x362D, 0xDCB2, 0xB4EE, 0x5BFB,
397 0xA4F6, 0x764D, 0xB761, 0x7DCE, 0x527B, 0xDD3E, 0x5E71, 0x1397,
398 0xA6F5, 0xB968, 0x0000, 0xC12C, 0x4060, 0xE31F, 0x79C8, 0xB6ED,
399 0xD4BE, 0x8D46, 0x67D9, 0x724B, 0x94DE, 0x98D4, 0xB0E8, 0x854A,
400 0xBB6B, 0xC52A, 0x4FE5, 0xED16, 0x86C5, 0x9AD7, 0x6655, 0x1194,
401 0x8ACF, 0xE910, 0x0406, 0xFE81, 0xA0F0, 0x7844, 0x25BA, 0x4BE3,
402 0xA2F3, 0x5DFE, 0x80C0, 0x058A, 0x3FAD, 0x21BC, 0x7048, 0xF104,
403 0x63DF, 0x77C1, 0xAF75, 0x4263, 0x2030, 0xE51A, 0xFD0E, 0xBF6D,
404 0x814C, 0x1814, 0x2635, 0xC32F, 0xBEE1, 0x35A2, 0x88CC, 0x2E39,
405 0x9357, 0x55F2, 0xFC82, 0x7A47, 0xC8AC, 0xBAE7, 0x322B, 0xE695,
406 0xC0A0, 0x1998, 0x9ED1, 0xA37F, 0x4466, 0x547E, 0x3BAB, 0x0B83,
407 0x8CCA, 0xC729, 0x6BD3, 0x283C, 0xA779, 0xBCE2, 0x161D, 0xAD76,
408 0xDB3B, 0x6456, 0x744E, 0x141E, 0x92DB, 0x0C0A, 0x486C, 0xB8E4,
409 0x9F5D, 0xBD6E, 0x43EF, 0xC4A6, 0x39A8, 0x31A4, 0xD337, 0xF28B,
410 0xD532, 0x8B43, 0x6E59, 0xDAB7, 0x018C, 0xB164, 0x9CD2, 0x49E0,
411 0xD8B4, 0xACFA, 0xF307, 0xCF25, 0xCAAF, 0xF48E, 0x47E9, 0x1018,
412 0x6FD5, 0xF088, 0x4A6F, 0x5C72, 0x3824, 0x57F1, 0x73C7, 0x9751,
413 0xCB23, 0xA17C, 0xE89C, 0x3E21, 0x96DD, 0x61DC, 0x0D86, 0x0F85,
414 0xE090, 0x7C42, 0x71C4, 0xCCAA, 0x90D8, 0x0605, 0xF701, 0x1C12,
415 0xC2A3, 0x6A5F, 0xAEF9, 0x69D0, 0x1791, 0x9958, 0x3A27, 0x27B9,
416 0xD938, 0xEB13, 0x2BB3, 0x2233, 0xD2BB, 0xA970, 0x0789, 0x33A7,
417 0x2DB6, 0x3C22, 0x1592, 0xC920, 0x8749, 0xAAFF, 0x5078, 0xA57A,
418 0x038F, 0x59F8, 0x0980, 0x1A17, 0x65DA, 0xD731, 0x84C6, 0xD0B8,
419 0x82C3, 0x29B0, 0x5A77, 0x1E11, 0x7BCB, 0xA8FC, 0x6DD6, 0x2C3A,
421 { /* second half is unsigned char-reversed version of first! */
422 0xA5C6, 0x84F8, 0x99EE, 0x8DF6, 0x0DFF, 0xBDD6, 0xB1DE, 0x5491,
423 0x5060, 0x0302, 0xA9CE, 0x7D56, 0x19E7, 0x62B5, 0xE64D, 0x9AEC,
424 0x458F, 0x9D1F, 0x4089, 0x87FA, 0x15EF, 0xEBB2, 0xC98E, 0x0BFB,
425 0xEC41, 0x67B3, 0xFD5F, 0xEA45, 0xBF23, 0xF753, 0x96E4, 0x5B9B,
426 0xC275, 0x1CE1, 0xAE3D, 0x6A4C, 0x5A6C, 0x417E, 0x02F5, 0x4F83,
427 0x5C68, 0xF451, 0x34D1, 0x08F9, 0x93E2, 0x73AB, 0x5362, 0x3F2A,
428 0x0C08, 0x5295, 0x6546, 0x5E9D, 0x2830, 0xA137, 0x0F0A, 0xB52F,
429 0x090E, 0x3624, 0x9B1B, 0x3DDF, 0x26CD, 0x694E, 0xCD7F, 0x9FEA,
430 0x1B12, 0x9E1D, 0x7458, 0x2E34, 0x2D36, 0xB2DC, 0xEEB4, 0xFB5B,
431 0xF6A4, 0x4D76, 0x61B7, 0xCE7D, 0x7B52, 0x3EDD, 0x715E, 0x9713,
432 0xF5A6, 0x68B9, 0x0000, 0x2CC1, 0x6040, 0x1FE3, 0xC879, 0xEDB6,
433 0xBED4, 0x468D, 0xD967, 0x4B72, 0xDE94, 0xD498, 0xE8B0, 0x4A85,
434 0x6BBB, 0x2AC5, 0xE54F, 0x16ED, 0xC586, 0xD79A, 0x5566, 0x9411,
435 0xCF8A, 0x10E9, 0x0604, 0x81FE, 0xF0A0, 0x4478, 0xBA25, 0xE34B,
436 0xF3A2, 0xFE5D, 0xC080, 0x8A05, 0xAD3F, 0xBC21, 0x4870, 0x04F1,
437 0xDF63, 0xC177, 0x75AF, 0x6342, 0x3020, 0x1AE5, 0x0EFD, 0x6DBF,
438 0x4C81, 0x1418, 0x3526, 0x2FC3, 0xE1BE, 0xA235, 0xCC88, 0x392E,
439 0x5793, 0xF255, 0x82FC, 0x477A, 0xACC8, 0xE7BA, 0x2B32, 0x95E6,
440 0xA0C0, 0x9819, 0xD19E, 0x7FA3, 0x6644, 0x7E54, 0xAB3B, 0x830B,
441 0xCA8C, 0x29C7, 0xD36B, 0x3C28, 0x79A7, 0xE2BC, 0x1D16, 0x76AD,
442 0x3BDB, 0x5664, 0x4E74, 0x1E14, 0xDB92, 0x0A0C, 0x6C48, 0xE4B8,
443 0x5D9F, 0x6EBD, 0xEF43, 0xA6C4, 0xA839, 0xA431, 0x37D3, 0x8BF2,
444 0x32D5, 0x438B, 0x596E, 0xB7DA, 0x8C01, 0x64B1, 0xD29C, 0xE049,
445 0xB4D8, 0xFAAC, 0x07F3, 0x25CF, 0xAFCA, 0x8EF4, 0xE947, 0x1810,
446 0xD56F, 0x88F0, 0x6F4A, 0x725C, 0x2438, 0xF157, 0xC773, 0x5197,
447 0x23CB, 0x7CA1, 0x9CE8, 0x213E, 0xDD96, 0xDC61, 0x860D, 0x850F,
448 0x90E0, 0x427C, 0xC471, 0xAACC, 0xD890, 0x0506, 0x01F7, 0x121C,
449 0xA3C2, 0x5F6A, 0xF9AE, 0xD069, 0x9117, 0x5899, 0x273A, 0xB927,
450 0x38D9, 0x13EB, 0xB32B, 0x3322, 0xBBD2, 0x70A9, 0x8907, 0xA733,
451 0xB62D, 0x223C, 0x9215, 0x20C9, 0x4987, 0xFFAA, 0x7850, 0x7AA5,
452 0x8F03, 0xF859, 0x8009, 0x171A, 0xDA65, 0x31D7, 0xC684, 0xB8D0,
453 0xC382, 0xB029, 0x775A, 0x111E, 0xCB7B, 0xFCA8, 0xD66D, 0x3A2C,
458 **********************************************************************
459 * Routine: Phase 1 -- generate P1K, given TA, TK, IV32
462 * tk[] = temporal key [128 bits]
463 * ta[] = transmitter's MAC address [ 48 bits]
464 * iv32 = upper 32 bits of IV [ 32 bits]
466 * p1k[] = Phase 1 key [ 80 bits]
469 * This function only needs to be called every 2**16 packets,
470 * although in theory it could be called every packet.
472 **********************************************************************
474 static void phase1(u16
*p1k
, const u8
*tk
, const u8
*ta
, u32 iv32
)
478 /* Initialize the 80 bits of P1K[] from IV32 and TA[0..5] */
481 p1k
[2] = Mk16(ta
[1], ta
[0]); /* use TA[] as little-endian */
482 p1k
[3] = Mk16(ta
[3], ta
[2]);
483 p1k
[4] = Mk16(ta
[5], ta
[4]);
484 /* Now compute an unbalanced Feistel cipher with 80-bit block */
485 /* size on the 80-bit block P1K[], using the 128-bit key TK[] */
486 for (i
= 0; i
< PHASE1_LOOP_CNT
; i
++) { /* Each add is mod 2**16 */
487 p1k
[0] += _S_(p1k
[4] ^ TK16((i
&1) + 0));
488 p1k
[1] += _S_(p1k
[0] ^ TK16((i
&1) + 2));
489 p1k
[2] += _S_(p1k
[1] ^ TK16((i
&1) + 4));
490 p1k
[3] += _S_(p1k
[2] ^ TK16((i
&1) + 6));
491 p1k
[4] += _S_(p1k
[3] ^ TK16((i
&1) + 0));
492 p1k
[4] += (unsigned short)i
; /* avoid "slide attacks" */
497 **********************************************************************
498 * Routine: Phase 2 -- generate RC4KEY, given TK, P1K, IV16
501 * tk[] = Temporal key [128 bits]
502 * p1k[] = Phase 1 output key [ 80 bits]
503 * iv16 = low 16 bits of IV counter [ 16 bits]
505 * rc4key[] = the key used to encrypt the packet [128 bits]
508 * The value {TA,IV32,IV16} for Phase1/Phase2 must be unique
509 * across all packets using the same key TK value. Then, for a
510 * given value of TK[], this TKIP48 construction guarantees that
511 * the final RC4KEY value is unique across all packets.
513 * Suggested implementation optimization: if PPK[] is "overlaid"
514 * appropriately on RC4KEY[], there is no need for the final
515 * for loop below that copies the PPK[] result into RC4KEY[].
517 **********************************************************************
519 static void phase2(u8
*rc4key
, const u8
*tk
, const u16
*p1k
, u16 iv16
)
522 u16 PPK
[6]; /* temporary key for mixing */
524 /* Note: all adds in the PPK[] equations below are mod 2**16 */
525 for (i
= 0; i
< 5; i
++)
526 PPK
[i
] = p1k
[i
]; /* first, copy P1K to PPK */
527 PPK
[5] = p1k
[4] + iv16
; /* next, add in IV16 */
528 /* Bijective non-linear mixing of the 96 bits of PPK[0..5] */
529 PPK
[0] += _S_(PPK
[5] ^ TK16(0)); /* Mix key in each "round" */
530 PPK
[1] += _S_(PPK
[0] ^ TK16(1));
531 PPK
[2] += _S_(PPK
[1] ^ TK16(2));
532 PPK
[3] += _S_(PPK
[2] ^ TK16(3));
533 PPK
[4] += _S_(PPK
[3] ^ TK16(4));
534 PPK
[5] += _S_(PPK
[4] ^ TK16(5)); /* Total # S-box lookups == 6 */
535 /* Final sweep: bijective, "linear". Rotates kill LSB correlations */
536 PPK
[0] += RotR1(PPK
[5] ^ TK16(6));
537 PPK
[1] += RotR1(PPK
[0] ^ TK16(7)); /* Use all of TK[] in Phase2 */
538 PPK
[2] += RotR1(PPK
[1]);
539 PPK
[3] += RotR1(PPK
[2]);
540 PPK
[4] += RotR1(PPK
[3]);
541 PPK
[5] += RotR1(PPK
[4]);
542 /* Note: At this point, for a given key TK[0..15], the 96-bit output */
543 /* value PPK[0..5] is guaranteed to be unique, as a function */
544 /* of the 96-bit "input" value {TA,IV32,IV16}. That is, P1K */
545 /* is now a keyed permutation of {TA,IV32,IV16}. */
546 /* Set RC4KEY[0..3], which includes "cleartext" portion of RC4 key */
547 rc4key
[0] = Hi8(iv16
); /* RC4KEY[0..2] is the WEP IV */
548 rc4key
[1] = (Hi8(iv16
) | 0x20) & 0x7F; /* Help avoid weak (FMS) keys */
549 rc4key
[2] = Lo8(iv16
);
550 rc4key
[3] = Lo8((PPK
[5] ^ TK16(0)) >> 1);
551 /* Copy 96 bits of PPK[0..5] to RC4KEY[4..15] (little-endian) */
552 for (i
= 0; i
< 6; i
++) {
553 rc4key
[4 + 2 * i
] = Lo8(PPK
[i
]);
554 rc4key
[5 + 2 * i
] = Hi8(PPK
[i
]);
558 /*The hlen isn't include the IV*/
559 u32
r8712_tkip_encrypt(struct _adapter
*padapter
, u8
*pxmitframe
)
566 struct arc4context mycontext
;
567 u32 curfragnum
, length
, prwskeylen
;
569 u8
*pframe
, *payload
, *iv
, *prwskey
;
571 struct sta_info
*stainfo
;
572 struct pkt_attrib
*pattrib
= &((struct xmit_frame
*)pxmitframe
)->attrib
;
573 struct xmit_priv
*pxmitpriv
= &padapter
->xmitpriv
;
576 if (((struct xmit_frame
*)pxmitframe
)->buf_addr
== NULL
)
579 pframe
= ((struct xmit_frame
*)pxmitframe
)->buf_addr
+TXDESC_OFFSET
;
580 /* 4 start to encrypt each fragment */
581 if (pattrib
->encrypt
== _TKIP_
) {
583 stainfo
= pattrib
->psta
;
585 stainfo
= r8712_get_stainfo(&padapter
->stapriv
,
587 if (stainfo
!= NULL
) {
588 prwskey
= &stainfo
->x_UncstKey
.skey
[0];
590 for (curfragnum
= 0; curfragnum
< pattrib
->nr_frags
;
592 iv
= pframe
+ pattrib
->hdrlen
;
593 payload
= pframe
+pattrib
->iv_len
+
595 GET_TKIP_PN(iv
, txpn
);
596 pnl
= (u16
)(txpn
.val
);
597 pnh
= (u32
)(txpn
.val
>> 16);
598 phase1((u16
*)&ttkey
[0], prwskey
, &pattrib
->
600 phase2(&rc4key
[0], prwskey
, (u16
*)&ttkey
[0],
602 if ((curfragnum
+ 1) == pattrib
->nr_frags
) {
603 /* 4 the last fragment */
604 length
= pattrib
->last_txcmdsz
-
605 pattrib
->hdrlen
-pattrib
->iv_len
-
607 *((u32
*)crc
) = cpu_to_le32(
608 getcrc32(payload
, length
));
609 arcfour_init(&mycontext
, rc4key
, 16);
610 arcfour_encrypt(&mycontext
, payload
,
612 arcfour_encrypt(&mycontext
, payload
+
615 length
= pxmitpriv
->frag_len
-pattrib
->
617 iv_len
-pattrib
->icv_len
;
618 *((u32
*)crc
) = cpu_to_le32(getcrc32(
620 arcfour_init(&mycontext
, rc4key
, 16);
621 arcfour_encrypt(&mycontext
, payload
,
623 arcfour_encrypt(&mycontext
,
624 payload
+length
, crc
, 4);
625 pframe
+= pxmitpriv
->frag_len
;
626 pframe
= (u8
*)RND4((addr_t
)(pframe
));
635 /* The hlen doesn't include the IV */
636 u32
r8712_tkip_decrypt(struct _adapter
*padapter
, u8
*precvframe
)
643 struct arc4context mycontext
;
644 u32 length
, prwskeylen
;
645 u8
*pframe
, *payload
, *iv
, *prwskey
, idx
= 0;
647 struct sta_info
*stainfo
;
648 struct rx_pkt_attrib
*prxattrib
= &((union recv_frame
*)
649 precvframe
)->u
.hdr
.attrib
;
650 struct security_priv
*psecuritypriv
= &padapter
->securitypriv
;
652 pframe
= (unsigned char *)((union recv_frame
*)
653 precvframe
)->u
.hdr
.rx_data
;
654 /* 4 start to decrypt recvframe */
655 if (prxattrib
->encrypt
== _TKIP_
) {
656 stainfo
= r8712_get_stainfo(&padapter
->stapriv
,
658 if (stainfo
!= NULL
) {
659 iv
= pframe
+prxattrib
->hdrlen
;
660 payload
= pframe
+prxattrib
->iv_len
+ prxattrib
->hdrlen
;
661 length
= ((union recv_frame
*)precvframe
)->
662 u
.hdr
.len
- prxattrib
->hdrlen
-
664 if (IS_MCAST(prxattrib
->ra
)) {
666 prwskey
= &psecuritypriv
->XGrpKey
[
667 ((idx
>> 6) & 0x3) - 1].skey
[0];
668 if (psecuritypriv
->binstallGrpkey
== false)
671 prwskey
= &stainfo
->x_UncstKey
.skey
[0];
673 GET_TKIP_PN(iv
, txpn
);
674 pnl
= (u16
)(txpn
.val
);
675 pnh
= (u32
)(txpn
.val
>> 16);
676 phase1((u16
*)&ttkey
[0], prwskey
, &prxattrib
->ta
[0],
678 phase2(&rc4key
[0], prwskey
, (unsigned short *)
680 /* 4 decrypt payload include icv */
681 arcfour_init(&mycontext
, rc4key
, 16);
682 arcfour_encrypt(&mycontext
, payload
, payload
, length
);
683 *((u32
*)crc
) = cpu_to_le32(getcrc32(payload
,
685 if (crc
[3] != payload
[length
- 1] ||
686 crc
[2] != payload
[length
- 2] ||
687 crc
[1] != payload
[length
- 3] ||
688 crc
[0] != payload
[length
- 4])
696 /* 3 =====AES related===== */
698 #define MAX_MSG_SIZE 2048
699 /*****************************/
700 /******** SBOX Table *********/
701 /*****************************/
703 static const u8 sbox_table
[256] = {
704 0x63, 0x7c, 0x77, 0x7b, 0xf2, 0x6b, 0x6f, 0xc5,
705 0x30, 0x01, 0x67, 0x2b, 0xfe, 0xd7, 0xab, 0x76,
706 0xca, 0x82, 0xc9, 0x7d, 0xfa, 0x59, 0x47, 0xf0,
707 0xad, 0xd4, 0xa2, 0xaf, 0x9c, 0xa4, 0x72, 0xc0,
708 0xb7, 0xfd, 0x93, 0x26, 0x36, 0x3f, 0xf7, 0xcc,
709 0x34, 0xa5, 0xe5, 0xf1, 0x71, 0xd8, 0x31, 0x15,
710 0x04, 0xc7, 0x23, 0xc3, 0x18, 0x96, 0x05, 0x9a,
711 0x07, 0x12, 0x80, 0xe2, 0xeb, 0x27, 0xb2, 0x75,
712 0x09, 0x83, 0x2c, 0x1a, 0x1b, 0x6e, 0x5a, 0xa0,
713 0x52, 0x3b, 0xd6, 0xb3, 0x29, 0xe3, 0x2f, 0x84,
714 0x53, 0xd1, 0x00, 0xed, 0x20, 0xfc, 0xb1, 0x5b,
715 0x6a, 0xcb, 0xbe, 0x39, 0x4a, 0x4c, 0x58, 0xcf,
716 0xd0, 0xef, 0xaa, 0xfb, 0x43, 0x4d, 0x33, 0x85,
717 0x45, 0xf9, 0x02, 0x7f, 0x50, 0x3c, 0x9f, 0xa8,
718 0x51, 0xa3, 0x40, 0x8f, 0x92, 0x9d, 0x38, 0xf5,
719 0xbc, 0xb6, 0xda, 0x21, 0x10, 0xff, 0xf3, 0xd2,
720 0xcd, 0x0c, 0x13, 0xec, 0x5f, 0x97, 0x44, 0x17,
721 0xc4, 0xa7, 0x7e, 0x3d, 0x64, 0x5d, 0x19, 0x73,
722 0x60, 0x81, 0x4f, 0xdc, 0x22, 0x2a, 0x90, 0x88,
723 0x46, 0xee, 0xb8, 0x14, 0xde, 0x5e, 0x0b, 0xdb,
724 0xe0, 0x32, 0x3a, 0x0a, 0x49, 0x06, 0x24, 0x5c,
725 0xc2, 0xd3, 0xac, 0x62, 0x91, 0x95, 0xe4, 0x79,
726 0xe7, 0xc8, 0x37, 0x6d, 0x8d, 0xd5, 0x4e, 0xa9,
727 0x6c, 0x56, 0xf4, 0xea, 0x65, 0x7a, 0xae, 0x08,
728 0xba, 0x78, 0x25, 0x2e, 0x1c, 0xa6, 0xb4, 0xc6,
729 0xe8, 0xdd, 0x74, 0x1f, 0x4b, 0xbd, 0x8b, 0x8a,
730 0x70, 0x3e, 0xb5, 0x66, 0x48, 0x03, 0xf6, 0x0e,
731 0x61, 0x35, 0x57, 0xb9, 0x86, 0xc1, 0x1d, 0x9e,
732 0xe1, 0xf8, 0x98, 0x11, 0x69, 0xd9, 0x8e, 0x94,
733 0x9b, 0x1e, 0x87, 0xe9, 0xce, 0x55, 0x28, 0xdf,
734 0x8c, 0xa1, 0x89, 0x0d, 0xbf, 0xe6, 0x42, 0x68,
735 0x41, 0x99, 0x2d, 0x0f, 0xb0, 0x54, 0xbb, 0x16
738 /****************************************/
740 /* Performs a 128 bit AES encrypt with */
742 /****************************************/
743 static void xor_128(u8
*a
, u8
*b
, u8
*out
)
747 for (i
= 0; i
< 16; i
++)
748 out
[i
] = a
[i
] ^ b
[i
];
751 static void xor_32(u8
*a
, u8
*b
, u8
*out
)
754 for (i
= 0; i
< 4; i
++)
755 out
[i
] = a
[i
] ^ b
[i
];
760 return sbox_table
[(sint
)a
];
763 static void next_key(u8
*key
, sint round
)
767 u8 rcon_table
[12] = {
768 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80,
769 0x1b, 0x36, 0x36, 0x36
772 sbox_key
[0] = sbox(key
[13]);
773 sbox_key
[1] = sbox(key
[14]);
774 sbox_key
[2] = sbox(key
[15]);
775 sbox_key
[3] = sbox(key
[12]);
776 rcon
= rcon_table
[round
];
777 xor_32(&key
[0], sbox_key
, &key
[0]);
778 key
[0] = key
[0] ^ rcon
;
779 xor_32(&key
[4], &key
[0], &key
[4]);
780 xor_32(&key
[8], &key
[4], &key
[8]);
781 xor_32(&key
[12], &key
[8], &key
[12]);
784 static void byte_sub(u8
*in
, u8
*out
)
787 for (i
= 0; i
< 16; i
++)
788 out
[i
] = sbox(in
[i
]);
791 static void shift_row(u8
*in
, u8
*out
)
811 static void mix_column(u8
*in
, u8
*out
)
823 for (i
= 0 ; i
< 4; i
++) {
824 if ((in
[i
] & 0x80) == 0x80)
829 swap_halfs
[0] = in
[2]; /* Swap halves */
830 swap_halfs
[1] = in
[3];
831 swap_halfs
[2] = in
[0];
832 swap_halfs
[3] = in
[1];
833 rotl
[0] = in
[3]; /* Rotate left 8 bits */
837 andf7
[0] = in
[0] & 0x7f;
838 andf7
[1] = in
[1] & 0x7f;
839 andf7
[2] = in
[2] & 0x7f;
840 andf7
[3] = in
[3] & 0x7f;
841 for (i
= 3; i
> 0; i
--) { /* logical shift left 1 bit */
842 andf7
[i
] = andf7
[i
] << 1;
843 if ((andf7
[i
-1] & 0x80) == 0x80)
844 andf7
[i
] = (andf7
[i
] | 0x01);
846 andf7
[0] = andf7
[0] << 1;
847 andf7
[0] = andf7
[0] & 0xfe;
848 xor_32(add1b
, andf7
, add1bf7
);
849 xor_32(in
, add1bf7
, rotr
);
850 temp
[0] = rotr
[0]; /* Rotate right 8 bits */
855 xor_32(add1bf7
, rotr
, temp
);
856 xor_32(swap_halfs
, rotl
, tempb
);
857 xor_32(temp
, tempb
, out
);
860 static void aes128k128d(u8
*key
, u8
*data
, u8
*ciphertext
)
864 u8 intermediatea
[16];
865 u8 intermediateb
[16];
868 for (i
= 0; i
< 16; i
++)
869 round_key
[i
] = key
[i
];
870 for (round
= 0; round
< 11; round
++) {
872 xor_128(round_key
, data
, ciphertext
);
873 next_key(round_key
, round
);
874 } else if (round
== 10) {
875 byte_sub(ciphertext
, intermediatea
);
876 shift_row(intermediatea
, intermediateb
);
877 xor_128(intermediateb
, round_key
, ciphertext
);
879 byte_sub(ciphertext
, intermediatea
);
880 shift_row(intermediatea
, intermediateb
);
881 mix_column(&intermediateb
[0], &intermediatea
[0]);
882 mix_column(&intermediateb
[4], &intermediatea
[4]);
883 mix_column(&intermediateb
[8], &intermediatea
[8]);
884 mix_column(&intermediateb
[12], &intermediatea
[12]);
885 xor_128(intermediatea
, round_key
, ciphertext
);
886 next_key(round_key
, round
);
891 /************************************************/
892 /* construct_mic_iv() */
893 /* Builds the MIC IV from header fields and PN */
894 /************************************************/
895 static void construct_mic_iv(u8
*mic_iv
, sint qc_exists
, sint a4_exists
,
896 u8
*mpdu
, uint payload_length
, u8
*pn_vector
)
901 if (qc_exists
&& a4_exists
)
902 mic_iv
[1] = mpdu
[30] & 0x0f; /* QoS_TC */
903 if (qc_exists
&& !a4_exists
)
904 mic_iv
[1] = mpdu
[24] & 0x0f; /* mute bits 7-4 */
907 for (i
= 2; i
< 8; i
++)
908 mic_iv
[i
] = mpdu
[i
+ 8];
909 for (i
= 8; i
< 14; i
++)
910 mic_iv
[i
] = pn_vector
[13 - i
]; /* mic_iv[8:13] = PN[5:0] */
911 mic_iv
[14] = (unsigned char) (payload_length
/ 256);
912 mic_iv
[15] = (unsigned char) (payload_length
% 256);
915 /************************************************/
916 /* construct_mic_header1() */
917 /* Builds the first MIC header block from */
919 /************************************************/
920 static void construct_mic_header1(u8
*mic_header1
, sint header_length
, u8
*mpdu
)
922 mic_header1
[0] = (u8
)((header_length
- 2) / 256);
923 mic_header1
[1] = (u8
)((header_length
- 2) % 256);
924 mic_header1
[2] = mpdu
[0] & 0xcf; /* Mute CF poll & CF ack bits */
925 /* Mute retry, more data and pwr mgt bits */
926 mic_header1
[3] = mpdu
[1] & 0xc7;
927 mic_header1
[4] = mpdu
[4]; /* A1 */
928 mic_header1
[5] = mpdu
[5];
929 mic_header1
[6] = mpdu
[6];
930 mic_header1
[7] = mpdu
[7];
931 mic_header1
[8] = mpdu
[8];
932 mic_header1
[9] = mpdu
[9];
933 mic_header1
[10] = mpdu
[10]; /* A2 */
934 mic_header1
[11] = mpdu
[11];
935 mic_header1
[12] = mpdu
[12];
936 mic_header1
[13] = mpdu
[13];
937 mic_header1
[14] = mpdu
[14];
938 mic_header1
[15] = mpdu
[15];
941 /************************************************/
942 /* construct_mic_header2() */
943 /* Builds the last MIC header block from */
945 /************************************************/
946 static void construct_mic_header2(u8
*mic_header2
, u8
*mpdu
, sint a4_exists
,
951 for (i
= 0; i
< 16; i
++)
952 mic_header2
[i
] = 0x00;
953 mic_header2
[0] = mpdu
[16]; /* A3 */
954 mic_header2
[1] = mpdu
[17];
955 mic_header2
[2] = mpdu
[18];
956 mic_header2
[3] = mpdu
[19];
957 mic_header2
[4] = mpdu
[20];
958 mic_header2
[5] = mpdu
[21];
959 mic_header2
[6] = 0x00;
960 mic_header2
[7] = 0x00; /* mpdu[23]; */
961 if (!qc_exists
&& a4_exists
)
962 for (i
= 0; i
< 6; i
++)
963 mic_header2
[8 + i
] = mpdu
[24 + i
]; /* A4 */
964 if (qc_exists
&& !a4_exists
) {
965 mic_header2
[8] = mpdu
[24] & 0x0f; /* mute bits 15 - 4 */
966 mic_header2
[9] = mpdu
[25] & 0x00;
968 if (qc_exists
&& a4_exists
) {
969 for (i
= 0; i
< 6; i
++)
970 mic_header2
[8 + i
] = mpdu
[24 + i
]; /* A4 */
971 mic_header2
[14] = mpdu
[30] & 0x0f;
972 mic_header2
[15] = mpdu
[31] & 0x00;
976 /************************************************/
977 /* construct_mic_header2() */
978 /* Builds the last MIC header block from */
980 /************************************************/
981 static void construct_ctr_preload(u8
*ctr_preload
, sint a4_exists
, sint qc_exists
,
982 u8
*mpdu
, u8
*pn_vector
, sint c
)
986 for (i
= 0; i
< 16; i
++)
987 ctr_preload
[i
] = 0x00;
989 ctr_preload
[0] = 0x01; /* flag */
990 if (qc_exists
&& a4_exists
)
991 ctr_preload
[1] = mpdu
[30] & 0x0f;
992 if (qc_exists
&& !a4_exists
)
993 ctr_preload
[1] = mpdu
[24] & 0x0f;
994 for (i
= 2; i
< 8; i
++)
995 ctr_preload
[i
] = mpdu
[i
+ 8];
996 for (i
= 8; i
< 14; i
++)
997 ctr_preload
[i
] = pn_vector
[13 - i
];
998 ctr_preload
[14] = (unsigned char) (c
/ 256); /* Ctr */
999 ctr_preload
[15] = (unsigned char) (c
% 256);
1002 /************************************/
1004 /* A 128 bit, bitwise exclusive or */
1005 /************************************/
1006 static void bitwise_xor(u8
*ina
, u8
*inb
, u8
*out
)
1010 for (i
= 0; i
< 16; i
++)
1011 out
[i
] = ina
[i
] ^ inb
[i
];
1014 static sint
aes_cipher(u8
*key
, uint hdrlen
,
1015 u8
*pframe
, uint plen
)
1017 uint qc_exists
, a4_exists
, i
, j
, payload_remainder
;
1018 uint num_blocks
, payload_index
;
1026 /* Intermediate Buffers */
1027 u8 chain_buffer
[16];
1029 u8 padded_buffer
[16];
1031 uint frtype
= GetFrameType(pframe
);
1032 uint frsubtype
= GetFrameSubType(pframe
);
1034 frsubtype
= frsubtype
>> 4;
1035 memset((void *)mic_iv
, 0, 16);
1036 memset((void *)mic_header1
, 0, 16);
1037 memset((void *)mic_header2
, 0, 16);
1038 memset((void *)ctr_preload
, 0, 16);
1039 memset((void *)chain_buffer
, 0, 16);
1040 memset((void *)aes_out
, 0, 16);
1041 memset((void *)padded_buffer
, 0, 16);
1043 if ((hdrlen
== WLAN_HDR_A3_LEN
) || (hdrlen
== WLAN_HDR_A3_QOS_LEN
))
1048 if ((frtype
== WIFI_DATA_CFACK
) ||
1049 (frtype
== WIFI_DATA_CFPOLL
) ||
1050 (frtype
== WIFI_DATA_CFACKPOLL
)) {
1052 if (hdrlen
!= WLAN_HDR_A3_QOS_LEN
)
1054 } else if ((frsubtype
== 0x08) ||
1055 (frsubtype
== 0x09) ||
1056 (frsubtype
== 0x0a) ||
1057 (frsubtype
== 0x0b)) {
1058 if (hdrlen
!= WLAN_HDR_A3_QOS_LEN
)
1063 pn_vector
[0] = pframe
[hdrlen
];
1064 pn_vector
[1] = pframe
[hdrlen
+1];
1065 pn_vector
[2] = pframe
[hdrlen
+4];
1066 pn_vector
[3] = pframe
[hdrlen
+5];
1067 pn_vector
[4] = pframe
[hdrlen
+6];
1068 pn_vector
[5] = pframe
[hdrlen
+7];
1069 construct_mic_iv(mic_iv
, qc_exists
, a4_exists
, pframe
, plen
, pn_vector
);
1070 construct_mic_header1(mic_header1
, hdrlen
, pframe
);
1071 construct_mic_header2(mic_header2
, pframe
, a4_exists
, qc_exists
);
1072 payload_remainder
= plen
% 16;
1073 num_blocks
= plen
/ 16;
1074 /* Find start of payload */
1075 payload_index
= (hdrlen
+ 8);
1077 aes128k128d(key
, mic_iv
, aes_out
);
1078 bitwise_xor(aes_out
, mic_header1
, chain_buffer
);
1079 aes128k128d(key
, chain_buffer
, aes_out
);
1080 bitwise_xor(aes_out
, mic_header2
, chain_buffer
);
1081 aes128k128d(key
, chain_buffer
, aes_out
);
1082 for (i
= 0; i
< num_blocks
; i
++) {
1083 bitwise_xor(aes_out
, &pframe
[payload_index
], chain_buffer
);
1084 payload_index
+= 16;
1085 aes128k128d(key
, chain_buffer
, aes_out
);
1087 /* Add on the final payload block if it needs padding */
1088 if (payload_remainder
> 0) {
1089 for (j
= 0; j
< 16; j
++)
1090 padded_buffer
[j
] = 0x00;
1091 for (j
= 0; j
< payload_remainder
; j
++)
1092 padded_buffer
[j
] = pframe
[payload_index
++];
1093 bitwise_xor(aes_out
, padded_buffer
, chain_buffer
);
1094 aes128k128d(key
, chain_buffer
, aes_out
);
1096 for (j
= 0; j
< 8; j
++)
1097 mic
[j
] = aes_out
[j
];
1098 /* Insert MIC into payload */
1099 for (j
= 0; j
< 8; j
++)
1100 pframe
[payload_index
+j
] = mic
[j
];
1101 payload_index
= hdrlen
+ 8;
1102 for (i
= 0; i
< num_blocks
; i
++) {
1103 construct_ctr_preload(ctr_preload
, a4_exists
, qc_exists
,
1104 pframe
, pn_vector
, i
+ 1);
1105 aes128k128d(key
, ctr_preload
, aes_out
);
1106 bitwise_xor(aes_out
, &pframe
[payload_index
], chain_buffer
);
1107 for (j
= 0; j
< 16; j
++)
1108 pframe
[payload_index
++] = chain_buffer
[j
];
1110 if (payload_remainder
> 0) { /* If short final block, then pad it,*/
1111 /* encrypt and copy unpadded part back */
1112 construct_ctr_preload(ctr_preload
, a4_exists
, qc_exists
,
1113 pframe
, pn_vector
, num_blocks
+1);
1114 for (j
= 0; j
< 16; j
++)
1115 padded_buffer
[j
] = 0x00;
1116 for (j
= 0; j
< payload_remainder
; j
++)
1117 padded_buffer
[j
] = pframe
[payload_index
+j
];
1118 aes128k128d(key
, ctr_preload
, aes_out
);
1119 bitwise_xor(aes_out
, padded_buffer
, chain_buffer
);
1120 for (j
= 0; j
< payload_remainder
; j
++)
1121 pframe
[payload_index
++] = chain_buffer
[j
];
1123 /* Encrypt the MIC */
1124 construct_ctr_preload(ctr_preload
, a4_exists
, qc_exists
,
1125 pframe
, pn_vector
, 0);
1126 for (j
= 0; j
< 16; j
++)
1127 padded_buffer
[j
] = 0x00;
1128 for (j
= 0; j
< 8; j
++)
1129 padded_buffer
[j
] = pframe
[j
+hdrlen
+8+plen
];
1130 aes128k128d(key
, ctr_preload
, aes_out
);
1131 bitwise_xor(aes_out
, padded_buffer
, chain_buffer
);
1132 for (j
= 0; j
< 8; j
++)
1133 pframe
[payload_index
++] = chain_buffer
[j
];
1137 u32
r8712_aes_encrypt(struct _adapter
*padapter
, u8
*pxmitframe
)
1139 /* Intermediate Buffers */
1140 sint curfragnum
, length
;
1142 u8
*pframe
, *prwskey
;
1143 struct sta_info
*stainfo
;
1144 struct pkt_attrib
*pattrib
= &((struct xmit_frame
*)
1145 pxmitframe
)->attrib
;
1146 struct xmit_priv
*pxmitpriv
= &padapter
->xmitpriv
;
1149 if (((struct xmit_frame
*)pxmitframe
)->buf_addr
== NULL
)
1151 pframe
= ((struct xmit_frame
*)pxmitframe
)->buf_addr
+ TXDESC_OFFSET
;
1152 /* 4 start to encrypt each fragment */
1153 if ((pattrib
->encrypt
== _AES_
)) {
1155 stainfo
= pattrib
->psta
;
1157 stainfo
= r8712_get_stainfo(&padapter
->stapriv
,
1159 if (stainfo
!= NULL
) {
1160 prwskey
= &stainfo
->x_UncstKey
.skey
[0];
1162 for (curfragnum
= 0; curfragnum
< pattrib
->nr_frags
;
1164 if ((curfragnum
+ 1) == pattrib
->nr_frags
) {\
1165 length
= pattrib
->last_txcmdsz
-
1169 aes_cipher(prwskey
, pattrib
->
1170 hdrlen
, pframe
, length
);
1172 length
= pxmitpriv
->frag_len
-
1176 aes_cipher(prwskey
, pattrib
->
1177 hdrlen
, pframe
, length
);
1178 pframe
+= pxmitpriv
->frag_len
;
1179 pframe
= (u8
*)RND4((addr_t
)(pframe
));
1188 static sint
aes_decipher(u8
*key
, uint hdrlen
,
1189 u8
*pframe
, uint plen
)
1191 static u8 message
[MAX_MSG_SIZE
];
1192 uint qc_exists
, a4_exists
, i
, j
, payload_remainder
;
1193 uint num_blocks
, payload_index
;
1199 /* Intermediate Buffers */
1200 u8 chain_buffer
[16];
1202 u8 padded_buffer
[16];
1204 uint frtype
= GetFrameType(pframe
);
1205 uint frsubtype
= GetFrameSubType(pframe
);
1207 frsubtype
= frsubtype
>> 4;
1208 memset((void *)mic_iv
, 0, 16);
1209 memset((void *)mic_header1
, 0, 16);
1210 memset((void *)mic_header2
, 0, 16);
1211 memset((void *)ctr_preload
, 0, 16);
1212 memset((void *)chain_buffer
, 0, 16);
1213 memset((void *)aes_out
, 0, 16);
1214 memset((void *)padded_buffer
, 0, 16);
1215 /* start to decrypt the payload */
1216 /*(plen including llc, payload and mic) */
1217 num_blocks
= (plen
- 8) / 16;
1218 payload_remainder
= (plen
-8) % 16;
1219 pn_vector
[0] = pframe
[hdrlen
];
1220 pn_vector
[1] = pframe
[hdrlen
+1];
1221 pn_vector
[2] = pframe
[hdrlen
+4];
1222 pn_vector
[3] = pframe
[hdrlen
+5];
1223 pn_vector
[4] = pframe
[hdrlen
+6];
1224 pn_vector
[5] = pframe
[hdrlen
+7];
1225 if ((hdrlen
== WLAN_HDR_A3_LEN
) || (hdrlen
== WLAN_HDR_A3_QOS_LEN
))
1229 if ((frtype
== WIFI_DATA_CFACK
) ||
1230 (frtype
== WIFI_DATA_CFPOLL
) ||
1231 (frtype
== WIFI_DATA_CFACKPOLL
)) {
1233 if (hdrlen
!= WLAN_HDR_A3_QOS_LEN
)
1235 } else if ((frsubtype
== 0x08) ||
1236 (frsubtype
== 0x09) ||
1237 (frsubtype
== 0x0a) ||
1238 (frsubtype
== 0x0b)) {
1239 if (hdrlen
!= WLAN_HDR_A3_QOS_LEN
)
1244 /* now, decrypt pframe with hdrlen offset and plen long */
1245 payload_index
= hdrlen
+ 8; /* 8 is for extiv */
1246 for (i
= 0; i
< num_blocks
; i
++) {
1247 construct_ctr_preload(ctr_preload
, a4_exists
, qc_exists
,
1248 pframe
, pn_vector
, i
+ 1);
1249 aes128k128d(key
, ctr_preload
, aes_out
);
1250 bitwise_xor(aes_out
, &pframe
[payload_index
], chain_buffer
);
1251 for (j
= 0; j
< 16; j
++)
1252 pframe
[payload_index
++] = chain_buffer
[j
];
1254 if (payload_remainder
> 0) { /* If short final block, pad it,*/
1255 /* encrypt it and copy the unpadded part back */
1256 construct_ctr_preload(ctr_preload
, a4_exists
, qc_exists
,
1257 pframe
, pn_vector
, num_blocks
+1);
1258 for (j
= 0; j
< 16; j
++)
1259 padded_buffer
[j
] = 0x00;
1260 for (j
= 0; j
< payload_remainder
; j
++)
1261 padded_buffer
[j
] = pframe
[payload_index
+ j
];
1262 aes128k128d(key
, ctr_preload
, aes_out
);
1263 bitwise_xor(aes_out
, padded_buffer
, chain_buffer
);
1264 for (j
= 0; j
< payload_remainder
; j
++)
1265 pframe
[payload_index
++] = chain_buffer
[j
];
1267 /* start to calculate the mic */
1268 memcpy((void *)message
, pframe
, (hdrlen
+ plen
+ 8));
1269 pn_vector
[0] = pframe
[hdrlen
];
1270 pn_vector
[1] = pframe
[hdrlen
+1];
1271 pn_vector
[2] = pframe
[hdrlen
+4];
1272 pn_vector
[3] = pframe
[hdrlen
+5];
1273 pn_vector
[4] = pframe
[hdrlen
+6];
1274 pn_vector
[5] = pframe
[hdrlen
+7];
1275 construct_mic_iv(mic_iv
, qc_exists
, a4_exists
, message
, plen
-8,
1277 construct_mic_header1(mic_header1
, hdrlen
, message
);
1278 construct_mic_header2(mic_header2
, message
, a4_exists
, qc_exists
);
1279 payload_remainder
= (plen
- 8) % 16;
1280 num_blocks
= (plen
- 8) / 16;
1281 /* Find start of payload */
1282 payload_index
= (hdrlen
+ 8);
1284 aes128k128d(key
, mic_iv
, aes_out
);
1285 bitwise_xor(aes_out
, mic_header1
, chain_buffer
);
1286 aes128k128d(key
, chain_buffer
, aes_out
);
1287 bitwise_xor(aes_out
, mic_header2
, chain_buffer
);
1288 aes128k128d(key
, chain_buffer
, aes_out
);
1289 for (i
= 0; i
< num_blocks
; i
++) {
1290 bitwise_xor(aes_out
, &message
[payload_index
], chain_buffer
);
1291 payload_index
+= 16;
1292 aes128k128d(key
, chain_buffer
, aes_out
);
1294 /* Add on the final payload block if it needs padding */
1295 if (payload_remainder
> 0) {
1296 for (j
= 0; j
< 16; j
++)
1297 padded_buffer
[j
] = 0x00;
1298 for (j
= 0; j
< payload_remainder
; j
++)
1299 padded_buffer
[j
] = message
[payload_index
++];
1300 bitwise_xor(aes_out
, padded_buffer
, chain_buffer
);
1301 aes128k128d(key
, chain_buffer
, aes_out
);
1303 for (j
= 0 ; j
< 8; j
++)
1304 mic
[j
] = aes_out
[j
];
1305 /* Insert MIC into payload */
1306 for (j
= 0; j
< 8; j
++)
1307 message
[payload_index
+j
] = mic
[j
];
1308 payload_index
= hdrlen
+ 8;
1309 for (i
= 0; i
< num_blocks
; i
++) {
1310 construct_ctr_preload(ctr_preload
, a4_exists
, qc_exists
,
1311 message
, pn_vector
, i
+ 1);
1312 aes128k128d(key
, ctr_preload
, aes_out
);
1313 bitwise_xor(aes_out
, &message
[payload_index
], chain_buffer
);
1314 for (j
= 0; j
< 16; j
++)
1315 message
[payload_index
++] = chain_buffer
[j
];
1317 if (payload_remainder
> 0) { /* If short final block, pad it,*/
1318 /* encrypt and copy unpadded part back */
1319 construct_ctr_preload(ctr_preload
, a4_exists
, qc_exists
,
1320 message
, pn_vector
, num_blocks
+1);
1321 for (j
= 0; j
< 16; j
++)
1322 padded_buffer
[j
] = 0x00;
1323 for (j
= 0; j
< payload_remainder
; j
++)
1324 padded_buffer
[j
] = message
[payload_index
+ j
];
1325 aes128k128d(key
, ctr_preload
, aes_out
);
1326 bitwise_xor(aes_out
, padded_buffer
, chain_buffer
);
1327 for (j
= 0; j
< payload_remainder
; j
++)
1328 message
[payload_index
++] = chain_buffer
[j
];
1330 /* Encrypt the MIC */
1331 construct_ctr_preload(ctr_preload
, a4_exists
, qc_exists
, message
,
1333 for (j
= 0; j
< 16; j
++)
1334 padded_buffer
[j
] = 0x00;
1335 for (j
= 0; j
< 8; j
++)
1336 padded_buffer
[j
] = message
[j
+ hdrlen
+ plen
];
1337 aes128k128d(key
, ctr_preload
, aes_out
);
1338 bitwise_xor(aes_out
, padded_buffer
, chain_buffer
);
1339 for (j
= 0; j
< 8; j
++)
1340 message
[payload_index
++] = chain_buffer
[j
];
1341 /* compare the mic */
1345 u32
r8712_aes_decrypt(struct _adapter
*padapter
, u8
*precvframe
)
1347 /* Intermediate Buffers */
1350 u8
*pframe
, *prwskey
, *iv
, idx
;
1351 struct sta_info
*stainfo
;
1352 struct rx_pkt_attrib
*prxattrib
= &((union recv_frame
*)
1353 precvframe
)->u
.hdr
.attrib
;
1354 struct security_priv
*psecuritypriv
= &padapter
->securitypriv
;
1356 pframe
= (unsigned char *)((union recv_frame
*)precvframe
)->
1358 /* 4 start to encrypt each fragment */
1359 if ((prxattrib
->encrypt
== _AES_
)) {
1360 stainfo
= r8712_get_stainfo(&padapter
->stapriv
,
1362 if (stainfo
!= NULL
) {
1363 if (IS_MCAST(prxattrib
->ra
)) {
1364 iv
= pframe
+prxattrib
->hdrlen
;
1366 prwskey
= &psecuritypriv
->XGrpKey
[
1367 ((idx
>> 6) & 0x3) - 1].skey
[0];
1368 if (psecuritypriv
->binstallGrpkey
== false)
1372 prwskey
= &stainfo
->x_UncstKey
.skey
[0];
1374 length
= ((union recv_frame
*)precvframe
)->
1375 u
.hdr
.len
-prxattrib
->hdrlen
-prxattrib
->iv_len
;
1376 aes_decipher(prwskey
, prxattrib
->hdrlen
, pframe
,
1384 void r8712_use_tkipkey_handler(void *FunctionContext
)
1386 struct _adapter
*padapter
= (struct _adapter
*)FunctionContext
;
1388 padapter
->securitypriv
.busetkipkey
= true;