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 <linux/compiler.h>
32 #include <linux/kernel.h>
33 #include <linux/errno.h>
34 #include <linux/init.h>
35 #include <linux/slab.h>
36 #include <linux/module.h>
37 #include <linux/kref.h>
38 #include <linux/netdevice.h>
39 #include <linux/skbuff.h>
40 #include <linux/circ_buf.h>
41 #include <linux/uaccess.h>
42 #include <asm/byteorder.h>
43 #include <linux/atomic.h>
44 #include <linux/semaphore.h>
46 #include "osdep_service.h"
47 #include "drv_types.h"
49 #include "osdep_intf.h"
51 /* =====WEP related===== */
53 #define CRC32_POLY 0x04c11db7
61 static void arcfour_init(struct arc4context
*parc4ctx
, u8
* key
, u32 key_len
)
69 state
= parc4ctx
->state
;
72 for (counter
= 0; counter
< 256; counter
++)
73 state
[counter
] = (u8
)counter
;
76 for (counter
= 0; counter
< 256; counter
++) {
78 stateindex
= (stateindex
+ key
[keyindex
] + t
) & 0xff;
79 u
= state
[stateindex
];
80 state
[stateindex
] = (u8
)t
;
81 state
[counter
] = (u8
)u
;
82 if (++keyindex
>= key_len
)
87 static u32
arcfour_byte(struct arc4context
*parc4ctx
)
94 state
= parc4ctx
->state
;
95 x
= (parc4ctx
->x
+ 1) & 0xff;
97 y
= (sx
+ parc4ctx
->y
) & 0xff;
103 return state
[(sx
+ sy
) & 0xff];
106 static void arcfour_encrypt(struct arc4context
*parc4ctx
,
107 u8
*dest
, u8
*src
, u32 len
)
111 for (i
= 0; i
< len
; i
++)
112 dest
[i
] = src
[i
] ^ (unsigned char)arcfour_byte(parc4ctx
);
115 static sint bcrc32initialized
;
116 static u32 crc32_table
[256];
118 static u8
crc32_reverseBit(u8 data
)
120 return ((u8
)(data
<< 7) & 0x80) | ((data
<< 5) & 0x40) | ((data
<< 3)
121 & 0x20) | ((data
<< 1) & 0x10) | ((data
>> 1) & 0x08) |
122 ((data
>> 3) & 0x04) | ((data
>> 5) & 0x02) | ((data
>> 7) &
126 static void crc32_init(void)
128 if (bcrc32initialized
== 1)
133 u8
*p
= (u8
*)&c
, *p1
;
137 for (i
= 0; i
< 256; ++i
) {
138 k
= crc32_reverseBit((u8
)i
);
139 for (c
= ((u32
)k
) << 24, j
= 8; j
> 0; --j
)
140 c
= c
& 0x80000000 ? (c
<< 1) ^ CRC32_POLY
:
142 p1
= (u8
*)&crc32_table
[i
];
143 p1
[0] = crc32_reverseBit(p
[3]);
144 p1
[1] = crc32_reverseBit(p
[2]);
145 p1
[2] = crc32_reverseBit(p
[1]);
146 p1
[3] = crc32_reverseBit(p
[0]);
148 bcrc32initialized
= 1;
152 static u32
getcrc32(u8
*buf
, u32 len
)
157 if (bcrc32initialized
== 0)
159 crc
= 0xffffffff; /* preload shift register, per CRC-32 spec */
160 for (p
= buf
; len
> 0; ++p
, --len
)
161 crc
= crc32_table
[(crc
^ *p
) & 0xff] ^ (crc
>> 8);
162 return ~crc
; /* transmit complement, per CRC-32 spec */
166 Need to consider the fragment situation
168 void r8712_wep_encrypt(struct _adapter
*padapter
, u8
*pxmitframe
)
170 unsigned char crc
[4];
171 struct arc4context mycontext
;
172 u32 curfragnum
, length
, keylength
;
173 u8
*pframe
, *payload
, *iv
; /*,*wepkey*/
175 struct pkt_attrib
*pattrib
= &((struct xmit_frame
*)
177 struct security_priv
*psecuritypriv
= &padapter
->securitypriv
;
178 struct xmit_priv
*pxmitpriv
= &padapter
->xmitpriv
;
180 if (((struct xmit_frame
*)pxmitframe
)->buf_addr
== NULL
)
182 pframe
= ((struct xmit_frame
*)pxmitframe
)->buf_addr
+TXDESC_OFFSET
;
183 /*start to encrypt each fragment*/
184 if ((pattrib
->encrypt
== _WEP40_
) || (pattrib
->encrypt
== _WEP104_
)) {
185 keylength
= psecuritypriv
->DefKeylen
[psecuritypriv
->
187 for (curfragnum
= 0; curfragnum
< pattrib
->nr_frags
;
189 iv
= pframe
+pattrib
->hdrlen
;
190 memcpy(&wepkey
[0], iv
, 3);
191 memcpy(&wepkey
[3], &psecuritypriv
->DefKey
[
192 psecuritypriv
->PrivacyKeyIndex
].skey
[0],
194 payload
= pframe
+pattrib
->iv_len
+pattrib
->hdrlen
;
195 if ((curfragnum
+ 1) == pattrib
->nr_frags
) {
196 length
= pattrib
->last_txcmdsz
-pattrib
->
197 hdrlen
-pattrib
->iv_len
-
199 *((u32
*)crc
) = cpu_to_le32(getcrc32(
201 arcfour_init(&mycontext
, wepkey
, 3 + keylength
);
202 arcfour_encrypt(&mycontext
, payload
, payload
,
204 arcfour_encrypt(&mycontext
, payload
+ length
,
207 length
= pxmitpriv
->frag_len
-pattrib
->hdrlen
-
208 pattrib
->iv_len
-pattrib
->icv_len
;
209 *((u32
*)crc
) = cpu_to_le32(getcrc32(
211 arcfour_init(&mycontext
, wepkey
, 3 + keylength
);
212 arcfour_encrypt(&mycontext
, payload
, payload
,
214 arcfour_encrypt(&mycontext
, payload
+length
,
216 pframe
+= pxmitpriv
->frag_len
;
217 pframe
= (u8
*)RND4((addr_t
)(pframe
));
223 void r8712_wep_decrypt(struct _adapter
*padapter
, u8
*precvframe
)
227 struct arc4context mycontext
;
228 u32 length
, keylength
;
229 u8
*pframe
, *payload
, *iv
, wepkey
[16];
231 struct rx_pkt_attrib
*prxattrib
= &(((union recv_frame
*)
232 precvframe
)->u
.hdr
.attrib
);
233 struct security_priv
*psecuritypriv
= &padapter
->securitypriv
;
235 pframe
= (unsigned char *)((union recv_frame
*)precvframe
)->
237 /* start to decrypt recvframe */
238 if ((prxattrib
->encrypt
== _WEP40_
) || (prxattrib
->encrypt
==
240 iv
= pframe
+ prxattrib
->hdrlen
;
241 keyindex
= (iv
[3] & 0x3);
242 keylength
= psecuritypriv
->DefKeylen
[keyindex
];
243 memcpy(&wepkey
[0], iv
, 3);
244 memcpy(&wepkey
[3], &psecuritypriv
->DefKey
[
245 psecuritypriv
->PrivacyKeyIndex
].skey
[0],
247 length
= ((union recv_frame
*)precvframe
)->
248 u
.hdr
.len
-prxattrib
->hdrlen
-prxattrib
->iv_len
;
249 payload
= pframe
+prxattrib
->iv_len
+prxattrib
->hdrlen
;
250 /* decrypt payload include icv */
251 arcfour_init(&mycontext
, wepkey
, 3 + keylength
);
252 arcfour_encrypt(&mycontext
, payload
, payload
, length
);
253 /* calculate icv and compare the icv */
254 *((u32
*)crc
) = cpu_to_le32(getcrc32(payload
, length
- 4));
259 /* 3 =====TKIP related===== */
261 static u32
secmicgetuint32(u8
*p
)
262 /* Convert from Byte[] to Us4Byte32 in a portable way */
267 for (i
= 0; i
< 4; i
++)
268 res
|= ((u32
)(*p
++)) << (8 * i
);
272 static void secmicputuint32(u8
*p
, u32 val
)
273 /* Convert from Us4Byte32 to Byte[] in a portable way */
276 for (i
= 0; i
< 4; i
++) {
277 *p
++ = (u8
) (val
& 0xff);
282 static void secmicclear(struct mic_data
*pmicdata
)
284 /* Reset the state to the empty message. */
285 pmicdata
->L
= pmicdata
->K0
;
286 pmicdata
->R
= pmicdata
->K1
;
287 pmicdata
->nBytesInM
= 0;
291 void r8712_secmicsetkey(struct mic_data
*pmicdata
, u8
* key
)
294 pmicdata
->K0
= secmicgetuint32(key
);
295 pmicdata
->K1
= secmicgetuint32(key
+ 4);
296 /* and reset the message */
297 secmicclear(pmicdata
);
300 static void secmicappendbyte(struct mic_data
*pmicdata
, u8 b
)
302 /* Append the byte to our word-sized buffer */
303 pmicdata
->M
|= ((u32
)b
) << (8 * pmicdata
->nBytesInM
);
304 pmicdata
->nBytesInM
++;
305 /* Process the word if it is full. */
306 if (pmicdata
->nBytesInM
>= 4) {
307 pmicdata
->L
^= pmicdata
->M
;
308 pmicdata
->R
^= ROL32(pmicdata
->L
, 17);
309 pmicdata
->L
+= pmicdata
->R
;
310 pmicdata
->R
^= ((pmicdata
->L
& 0xff00ff00) >> 8) |
311 ((pmicdata
->L
& 0x00ff00ff) << 8);
312 pmicdata
->L
+= pmicdata
->R
;
313 pmicdata
->R
^= ROL32(pmicdata
->L
, 3);
314 pmicdata
->L
+= pmicdata
->R
;
315 pmicdata
->R
^= ROR32(pmicdata
->L
, 2);
316 pmicdata
->L
+= pmicdata
->R
;
317 /* Clear the buffer */
319 pmicdata
->nBytesInM
= 0;
323 void r8712_secmicappend(struct mic_data
*pmicdata
, u8
* src
, u32 nbytes
)
327 secmicappendbyte(pmicdata
, *src
++);
332 void r8712_secgetmic(struct mic_data
*pmicdata
, u8
*dst
)
334 /* Append the minimum padding */
335 secmicappendbyte(pmicdata
, 0x5a);
336 secmicappendbyte(pmicdata
, 0);
337 secmicappendbyte(pmicdata
, 0);
338 secmicappendbyte(pmicdata
, 0);
339 secmicappendbyte(pmicdata
, 0);
340 /* and then zeroes until the length is a multiple of 4 */
341 while (pmicdata
->nBytesInM
!= 0)
342 secmicappendbyte(pmicdata
, 0);
343 /* The appendByte function has already computed the result. */
344 secmicputuint32(dst
, pmicdata
->L
);
345 secmicputuint32(dst
+ 4, pmicdata
->R
);
346 /* Reset to the empty message. */
347 secmicclear(pmicdata
);
350 void seccalctkipmic(u8
*key
, u8
*header
, u8
*data
, u32 data_len
, u8
*mic_code
,
354 struct mic_data micdata
;
355 u8 priority
[4] = {0x0, 0x0, 0x0, 0x0};
357 r8712_secmicsetkey(&micdata
, key
);
359 /* Michael MIC pseudo header: DA, SA, 3 x 0, Priority */
360 if (header
[1] & 1) { /* ToDS==1 */
361 r8712_secmicappend(&micdata
, &header
[16], 6); /* DA */
362 if (header
[1] & 2) /* From Ds==1 */
363 r8712_secmicappend(&micdata
, &header
[24], 6);
365 r8712_secmicappend(&micdata
, &header
[10], 6);
366 } else { /* ToDS==0 */
367 r8712_secmicappend(&micdata
, &header
[4], 6); /* DA */
368 if (header
[1] & 2) /* From Ds==1 */
369 r8712_secmicappend(&micdata
, &header
[16], 6);
371 r8712_secmicappend(&micdata
, &header
[10], 6);
373 r8712_secmicappend(&micdata
, &priority
[0], 4);
374 r8712_secmicappend(&micdata
, data
, data_len
);
375 r8712_secgetmic(&micdata
, mic_code
);
378 /* macros for extraction/creation of unsigned char/unsigned short values */
379 #define RotR1(v16) ((((v16) >> 1) & 0x7FFF) ^ (((v16) & 1) << 15))
380 #define Lo8(v16) ((u8)((v16) & 0x00FF))
381 #define Hi8(v16) ((u8)(((v16) >> 8) & 0x00FF))
382 #define Lo16(v32) ((u16)((v32) & 0xFFFF))
383 #define Hi16(v32) ((u16)(((v32) >> 16) & 0xFFFF))
384 #define Mk16(hi, lo) ((lo) ^ (((u16)(hi)) << 8))
386 /* select the Nth 16-bit word of the temporal key unsigned char array TK[] */
387 #define TK16(N) Mk16(tk[2 * (N) + 1], tk[2 * (N)])
389 /* S-box lookup: 16 bits --> 16 bits */
390 #define _S_(v16) (Sbox1[0][Lo8(v16)] ^ Sbox1[1][Hi8(v16)])
392 /* fixed algorithm "parameters" */
393 #define PHASE1_LOOP_CNT 8 /* this needs to be "big enough" */
394 #define TA_SIZE 6 /* 48-bit transmitter address */
395 #define TK_SIZE 16 /* 128-bit temporal key */
396 #define P1K_SIZE 10 /* 80-bit Phase1 key */
397 #define RC4_KEY_SIZE 16 /* 128-bit RC4KEY (104 bits unknown) */
400 /* 2-unsigned char by 2-unsigned char subset of the full AES S-box table */
401 static const unsigned short Sbox1
[2][256] = {/* Sbox for hash (can be in ROM) */
403 0xC6A5, 0xF884, 0xEE99, 0xF68D, 0xFF0D, 0xD6BD, 0xDEB1, 0x9154,
404 0x6050, 0x0203, 0xCEA9, 0x567D, 0xE719, 0xB562, 0x4DE6, 0xEC9A,
405 0x8F45, 0x1F9D, 0x8940, 0xFA87, 0xEF15, 0xB2EB, 0x8EC9, 0xFB0B,
406 0x41EC, 0xB367, 0x5FFD, 0x45EA, 0x23BF, 0x53F7, 0xE496, 0x9B5B,
407 0x75C2, 0xE11C, 0x3DAE, 0x4C6A, 0x6C5A, 0x7E41, 0xF502, 0x834F,
408 0x685C, 0x51F4, 0xD134, 0xF908, 0xE293, 0xAB73, 0x6253, 0x2A3F,
409 0x080C, 0x9552, 0x4665, 0x9D5E, 0x3028, 0x37A1, 0x0A0F, 0x2FB5,
410 0x0E09, 0x2436, 0x1B9B, 0xDF3D, 0xCD26, 0x4E69, 0x7FCD, 0xEA9F,
411 0x121B, 0x1D9E, 0x5874, 0x342E, 0x362D, 0xDCB2, 0xB4EE, 0x5BFB,
412 0xA4F6, 0x764D, 0xB761, 0x7DCE, 0x527B, 0xDD3E, 0x5E71, 0x1397,
413 0xA6F5, 0xB968, 0x0000, 0xC12C, 0x4060, 0xE31F, 0x79C8, 0xB6ED,
414 0xD4BE, 0x8D46, 0x67D9, 0x724B, 0x94DE, 0x98D4, 0xB0E8, 0x854A,
415 0xBB6B, 0xC52A, 0x4FE5, 0xED16, 0x86C5, 0x9AD7, 0x6655, 0x1194,
416 0x8ACF, 0xE910, 0x0406, 0xFE81, 0xA0F0, 0x7844, 0x25BA, 0x4BE3,
417 0xA2F3, 0x5DFE, 0x80C0, 0x058A, 0x3FAD, 0x21BC, 0x7048, 0xF104,
418 0x63DF, 0x77C1, 0xAF75, 0x4263, 0x2030, 0xE51A, 0xFD0E, 0xBF6D,
419 0x814C, 0x1814, 0x2635, 0xC32F, 0xBEE1, 0x35A2, 0x88CC, 0x2E39,
420 0x9357, 0x55F2, 0xFC82, 0x7A47, 0xC8AC, 0xBAE7, 0x322B, 0xE695,
421 0xC0A0, 0x1998, 0x9ED1, 0xA37F, 0x4466, 0x547E, 0x3BAB, 0x0B83,
422 0x8CCA, 0xC729, 0x6BD3, 0x283C, 0xA779, 0xBCE2, 0x161D, 0xAD76,
423 0xDB3B, 0x6456, 0x744E, 0x141E, 0x92DB, 0x0C0A, 0x486C, 0xB8E4,
424 0x9F5D, 0xBD6E, 0x43EF, 0xC4A6, 0x39A8, 0x31A4, 0xD337, 0xF28B,
425 0xD532, 0x8B43, 0x6E59, 0xDAB7, 0x018C, 0xB164, 0x9CD2, 0x49E0,
426 0xD8B4, 0xACFA, 0xF307, 0xCF25, 0xCAAF, 0xF48E, 0x47E9, 0x1018,
427 0x6FD5, 0xF088, 0x4A6F, 0x5C72, 0x3824, 0x57F1, 0x73C7, 0x9751,
428 0xCB23, 0xA17C, 0xE89C, 0x3E21, 0x96DD, 0x61DC, 0x0D86, 0x0F85,
429 0xE090, 0x7C42, 0x71C4, 0xCCAA, 0x90D8, 0x0605, 0xF701, 0x1C12,
430 0xC2A3, 0x6A5F, 0xAEF9, 0x69D0, 0x1791, 0x9958, 0x3A27, 0x27B9,
431 0xD938, 0xEB13, 0x2BB3, 0x2233, 0xD2BB, 0xA970, 0x0789, 0x33A7,
432 0x2DB6, 0x3C22, 0x1592, 0xC920, 0x8749, 0xAAFF, 0x5078, 0xA57A,
433 0x038F, 0x59F8, 0x0980, 0x1A17, 0x65DA, 0xD731, 0x84C6, 0xD0B8,
434 0x82C3, 0x29B0, 0x5A77, 0x1E11, 0x7BCB, 0xA8FC, 0x6DD6, 0x2C3A,
436 { /* second half is unsigned char-reversed version of first! */
437 0xA5C6, 0x84F8, 0x99EE, 0x8DF6, 0x0DFF, 0xBDD6, 0xB1DE, 0x5491,
438 0x5060, 0x0302, 0xA9CE, 0x7D56, 0x19E7, 0x62B5, 0xE64D, 0x9AEC,
439 0x458F, 0x9D1F, 0x4089, 0x87FA, 0x15EF, 0xEBB2, 0xC98E, 0x0BFB,
440 0xEC41, 0x67B3, 0xFD5F, 0xEA45, 0xBF23, 0xF753, 0x96E4, 0x5B9B,
441 0xC275, 0x1CE1, 0xAE3D, 0x6A4C, 0x5A6C, 0x417E, 0x02F5, 0x4F83,
442 0x5C68, 0xF451, 0x34D1, 0x08F9, 0x93E2, 0x73AB, 0x5362, 0x3F2A,
443 0x0C08, 0x5295, 0x6546, 0x5E9D, 0x2830, 0xA137, 0x0F0A, 0xB52F,
444 0x090E, 0x3624, 0x9B1B, 0x3DDF, 0x26CD, 0x694E, 0xCD7F, 0x9FEA,
445 0x1B12, 0x9E1D, 0x7458, 0x2E34, 0x2D36, 0xB2DC, 0xEEB4, 0xFB5B,
446 0xF6A4, 0x4D76, 0x61B7, 0xCE7D, 0x7B52, 0x3EDD, 0x715E, 0x9713,
447 0xF5A6, 0x68B9, 0x0000, 0x2CC1, 0x6040, 0x1FE3, 0xC879, 0xEDB6,
448 0xBED4, 0x468D, 0xD967, 0x4B72, 0xDE94, 0xD498, 0xE8B0, 0x4A85,
449 0x6BBB, 0x2AC5, 0xE54F, 0x16ED, 0xC586, 0xD79A, 0x5566, 0x9411,
450 0xCF8A, 0x10E9, 0x0604, 0x81FE, 0xF0A0, 0x4478, 0xBA25, 0xE34B,
451 0xF3A2, 0xFE5D, 0xC080, 0x8A05, 0xAD3F, 0xBC21, 0x4870, 0x04F1,
452 0xDF63, 0xC177, 0x75AF, 0x6342, 0x3020, 0x1AE5, 0x0EFD, 0x6DBF,
453 0x4C81, 0x1418, 0x3526, 0x2FC3, 0xE1BE, 0xA235, 0xCC88, 0x392E,
454 0x5793, 0xF255, 0x82FC, 0x477A, 0xACC8, 0xE7BA, 0x2B32, 0x95E6,
455 0xA0C0, 0x9819, 0xD19E, 0x7FA3, 0x6644, 0x7E54, 0xAB3B, 0x830B,
456 0xCA8C, 0x29C7, 0xD36B, 0x3C28, 0x79A7, 0xE2BC, 0x1D16, 0x76AD,
457 0x3BDB, 0x5664, 0x4E74, 0x1E14, 0xDB92, 0x0A0C, 0x6C48, 0xE4B8,
458 0x5D9F, 0x6EBD, 0xEF43, 0xA6C4, 0xA839, 0xA431, 0x37D3, 0x8BF2,
459 0x32D5, 0x438B, 0x596E, 0xB7DA, 0x8C01, 0x64B1, 0xD29C, 0xE049,
460 0xB4D8, 0xFAAC, 0x07F3, 0x25CF, 0xAFCA, 0x8EF4, 0xE947, 0x1810,
461 0xD56F, 0x88F0, 0x6F4A, 0x725C, 0x2438, 0xF157, 0xC773, 0x5197,
462 0x23CB, 0x7CA1, 0x9CE8, 0x213E, 0xDD96, 0xDC61, 0x860D, 0x850F,
463 0x90E0, 0x427C, 0xC471, 0xAACC, 0xD890, 0x0506, 0x01F7, 0x121C,
464 0xA3C2, 0x5F6A, 0xF9AE, 0xD069, 0x9117, 0x5899, 0x273A, 0xB927,
465 0x38D9, 0x13EB, 0xB32B, 0x3322, 0xBBD2, 0x70A9, 0x8907, 0xA733,
466 0xB62D, 0x223C, 0x9215, 0x20C9, 0x4987, 0xFFAA, 0x7850, 0x7AA5,
467 0x8F03, 0xF859, 0x8009, 0x171A, 0xDA65, 0x31D7, 0xC684, 0xB8D0,
468 0xC382, 0xB029, 0x775A, 0x111E, 0xCB7B, 0xFCA8, 0xD66D, 0x3A2C,
473 **********************************************************************
474 * Routine: Phase 1 -- generate P1K, given TA, TK, IV32
477 * tk[] = temporal key [128 bits]
478 * ta[] = transmitter's MAC address [ 48 bits]
479 * iv32 = upper 32 bits of IV [ 32 bits]
481 * p1k[] = Phase 1 key [ 80 bits]
484 * This function only needs to be called every 2**16 packets,
485 * although in theory it could be called every packet.
487 **********************************************************************
489 static void phase1(u16
*p1k
, const u8
*tk
, const u8
*ta
, u32 iv32
)
493 /* Initialize the 80 bits of P1K[] from IV32 and TA[0..5] */
496 p1k
[2] = Mk16(ta
[1], ta
[0]); /* use TA[] as little-endian */
497 p1k
[3] = Mk16(ta
[3], ta
[2]);
498 p1k
[4] = Mk16(ta
[5], ta
[4]);
499 /* Now compute an unbalanced Feistel cipher with 80-bit block */
500 /* size on the 80-bit block P1K[], using the 128-bit key TK[] */
501 for (i
= 0; i
< PHASE1_LOOP_CNT
; i
++) { /* Each add is mod 2**16 */
502 p1k
[0] += _S_(p1k
[4] ^ TK16((i
&1) + 0));
503 p1k
[1] += _S_(p1k
[0] ^ TK16((i
&1) + 2));
504 p1k
[2] += _S_(p1k
[1] ^ TK16((i
&1) + 4));
505 p1k
[3] += _S_(p1k
[2] ^ TK16((i
&1) + 6));
506 p1k
[4] += _S_(p1k
[3] ^ TK16((i
&1) + 0));
507 p1k
[4] += (unsigned short)i
; /* avoid "slide attacks" */
512 **********************************************************************
513 * Routine: Phase 2 -- generate RC4KEY, given TK, P1K, IV16
516 * tk[] = Temporal key [128 bits]
517 * p1k[] = Phase 1 output key [ 80 bits]
518 * iv16 = low 16 bits of IV counter [ 16 bits]
520 * rc4key[] = the key used to encrypt the packet [128 bits]
523 * The value {TA,IV32,IV16} for Phase1/Phase2 must be unique
524 * across all packets using the same key TK value. Then, for a
525 * given value of TK[], this TKIP48 construction guarantees that
526 * the final RC4KEY value is unique across all packets.
528 * Suggested implementation optimization: if PPK[] is "overlaid"
529 * appropriately on RC4KEY[], there is no need for the final
530 * for loop below that copies the PPK[] result into RC4KEY[].
532 **********************************************************************
534 static void phase2(u8
*rc4key
, const u8
*tk
, const u16
*p1k
, u16 iv16
)
537 u16 PPK
[6]; /* temporary key for mixing */
539 /* Note: all adds in the PPK[] equations below are mod 2**16 */
540 for (i
= 0; i
< 5; i
++)
541 PPK
[i
] = p1k
[i
]; /* first, copy P1K to PPK */
542 PPK
[5] = p1k
[4] + iv16
; /* next, add in IV16 */
543 /* Bijective non-linear mixing of the 96 bits of PPK[0..5] */
544 PPK
[0] += _S_(PPK
[5] ^ TK16(0)); /* Mix key in each "round" */
545 PPK
[1] += _S_(PPK
[0] ^ TK16(1));
546 PPK
[2] += _S_(PPK
[1] ^ TK16(2));
547 PPK
[3] += _S_(PPK
[2] ^ TK16(3));
548 PPK
[4] += _S_(PPK
[3] ^ TK16(4));
549 PPK
[5] += _S_(PPK
[4] ^ TK16(5)); /* Total # S-box lookups == 6 */
550 /* Final sweep: bijective, "linear". Rotates kill LSB correlations */
551 PPK
[0] += RotR1(PPK
[5] ^ TK16(6));
552 PPK
[1] += RotR1(PPK
[0] ^ TK16(7)); /* Use all of TK[] in Phase2 */
553 PPK
[2] += RotR1(PPK
[1]);
554 PPK
[3] += RotR1(PPK
[2]);
555 PPK
[4] += RotR1(PPK
[3]);
556 PPK
[5] += RotR1(PPK
[4]);
557 /* Note: At this point, for a given key TK[0..15], the 96-bit output */
558 /* value PPK[0..5] is guaranteed to be unique, as a function */
559 /* of the 96-bit "input" value {TA,IV32,IV16}. That is, P1K */
560 /* is now a keyed permutation of {TA,IV32,IV16}. */
561 /* Set RC4KEY[0..3], which includes "cleartext" portion of RC4 key */
562 rc4key
[0] = Hi8(iv16
); /* RC4KEY[0..2] is the WEP IV */
563 rc4key
[1] = (Hi8(iv16
) | 0x20) & 0x7F; /* Help avoid weak (FMS) keys */
564 rc4key
[2] = Lo8(iv16
);
565 rc4key
[3] = Lo8((PPK
[5] ^ TK16(0)) >> 1);
566 /* Copy 96 bits of PPK[0..5] to RC4KEY[4..15] (little-endian) */
567 for (i
= 0; i
< 6; i
++) {
568 rc4key
[4 + 2 * i
] = Lo8(PPK
[i
]);
569 rc4key
[5 + 2 * i
] = Hi8(PPK
[i
]);
573 /*The hlen isn't include the IV*/
574 u32
r8712_tkip_encrypt(struct _adapter
*padapter
, u8
*pxmitframe
)
581 struct arc4context mycontext
;
582 u32 curfragnum
, length
, prwskeylen
;
584 u8
*pframe
, *payload
, *iv
, *prwskey
;
586 struct sta_info
*stainfo
;
587 struct pkt_attrib
*pattrib
= &((struct xmit_frame
*)pxmitframe
)->attrib
;
588 struct xmit_priv
*pxmitpriv
= &padapter
->xmitpriv
;
591 if (((struct xmit_frame
*)pxmitframe
)->buf_addr
== NULL
)
594 pframe
= ((struct xmit_frame
*)pxmitframe
)->buf_addr
+TXDESC_OFFSET
;
595 /* 4 start to encrypt each fragment */
596 if (pattrib
->encrypt
== _TKIP_
) {
598 stainfo
= pattrib
->psta
;
600 stainfo
= r8712_get_stainfo(&padapter
->stapriv
,
602 if (stainfo
!= NULL
) {
603 prwskey
= &stainfo
->x_UncstKey
.skey
[0];
605 for (curfragnum
= 0; curfragnum
< pattrib
->nr_frags
;
607 iv
= pframe
+ pattrib
->hdrlen
;
608 payload
= pframe
+pattrib
->iv_len
+
610 GET_TKIP_PN(iv
, txpn
);
611 pnl
= (u16
)(txpn
.val
);
612 pnh
= (u32
)(txpn
.val
>> 16);
613 phase1((u16
*)&ttkey
[0], prwskey
, &pattrib
->
615 phase2(&rc4key
[0], prwskey
, (u16
*)&ttkey
[0],
617 if ((curfragnum
+ 1) == pattrib
->nr_frags
) {
618 /* 4 the last fragment */
619 length
= pattrib
->last_txcmdsz
-
620 pattrib
->hdrlen
-pattrib
->iv_len
-
622 *((u32
*)crc
) = cpu_to_le32(
623 getcrc32(payload
, length
));
624 arcfour_init(&mycontext
, rc4key
, 16);
625 arcfour_encrypt(&mycontext
, payload
,
627 arcfour_encrypt(&mycontext
, payload
+
630 length
= pxmitpriv
->frag_len
-pattrib
->
632 iv_len
-pattrib
->icv_len
;
633 *((u32
*)crc
) = cpu_to_le32(getcrc32(
635 arcfour_init(&mycontext
, rc4key
, 16);
636 arcfour_encrypt(&mycontext
, payload
,
638 arcfour_encrypt(&mycontext
,
639 payload
+length
, crc
, 4);
640 pframe
+= pxmitpriv
->frag_len
;
641 pframe
= (u8
*)RND4((addr_t
)(pframe
));
650 /* The hlen doesn't include the IV */
651 u32
r8712_tkip_decrypt(struct _adapter
*padapter
, u8
*precvframe
)
658 struct arc4context mycontext
;
659 u32 length
, prwskeylen
;
660 u8
*pframe
, *payload
, *iv
, *prwskey
, idx
= 0;
662 struct sta_info
*stainfo
;
663 struct rx_pkt_attrib
*prxattrib
= &((union recv_frame
*)
664 precvframe
)->u
.hdr
.attrib
;
665 struct security_priv
*psecuritypriv
= &padapter
->securitypriv
;
667 pframe
= (unsigned char *)((union recv_frame
*)
668 precvframe
)->u
.hdr
.rx_data
;
669 /* 4 start to decrypt recvframe */
670 if (prxattrib
->encrypt
== _TKIP_
) {
671 stainfo
= r8712_get_stainfo(&padapter
->stapriv
,
673 if (stainfo
!= NULL
) {
674 iv
= pframe
+prxattrib
->hdrlen
;
675 payload
= pframe
+prxattrib
->iv_len
+ prxattrib
->hdrlen
;
676 length
= ((union recv_frame
*)precvframe
)->
677 u
.hdr
.len
- prxattrib
->hdrlen
-
679 if (IS_MCAST(prxattrib
->ra
)) {
681 prwskey
= &psecuritypriv
->XGrpKey
[
682 ((idx
>> 6) & 0x3) - 1].skey
[0];
683 if (psecuritypriv
->binstallGrpkey
== false)
686 prwskey
= &stainfo
->x_UncstKey
.skey
[0];
688 GET_TKIP_PN(iv
, txpn
);
689 pnl
= (u16
)(txpn
.val
);
690 pnh
= (u32
)(txpn
.val
>> 16);
691 phase1((u16
*)&ttkey
[0], prwskey
, &prxattrib
->ta
[0],
693 phase2(&rc4key
[0], prwskey
, (unsigned short *)
695 /* 4 decrypt payload include icv */
696 arcfour_init(&mycontext
, rc4key
, 16);
697 arcfour_encrypt(&mycontext
, payload
, payload
, length
);
698 *((u32
*)crc
) = cpu_to_le32(getcrc32(payload
,
700 if (crc
[3] != payload
[length
- 1] ||
701 crc
[2] != payload
[length
- 2] ||
702 crc
[1] != payload
[length
- 3] ||
703 crc
[0] != payload
[length
- 4])
711 /* 3 =====AES related===== */
713 #define MAX_MSG_SIZE 2048
714 /*****************************/
715 /******** SBOX Table *********/
716 /*****************************/
718 static const u8 sbox_table
[256] = {
719 0x63, 0x7c, 0x77, 0x7b, 0xf2, 0x6b, 0x6f, 0xc5,
720 0x30, 0x01, 0x67, 0x2b, 0xfe, 0xd7, 0xab, 0x76,
721 0xca, 0x82, 0xc9, 0x7d, 0xfa, 0x59, 0x47, 0xf0,
722 0xad, 0xd4, 0xa2, 0xaf, 0x9c, 0xa4, 0x72, 0xc0,
723 0xb7, 0xfd, 0x93, 0x26, 0x36, 0x3f, 0xf7, 0xcc,
724 0x34, 0xa5, 0xe5, 0xf1, 0x71, 0xd8, 0x31, 0x15,
725 0x04, 0xc7, 0x23, 0xc3, 0x18, 0x96, 0x05, 0x9a,
726 0x07, 0x12, 0x80, 0xe2, 0xeb, 0x27, 0xb2, 0x75,
727 0x09, 0x83, 0x2c, 0x1a, 0x1b, 0x6e, 0x5a, 0xa0,
728 0x52, 0x3b, 0xd6, 0xb3, 0x29, 0xe3, 0x2f, 0x84,
729 0x53, 0xd1, 0x00, 0xed, 0x20, 0xfc, 0xb1, 0x5b,
730 0x6a, 0xcb, 0xbe, 0x39, 0x4a, 0x4c, 0x58, 0xcf,
731 0xd0, 0xef, 0xaa, 0xfb, 0x43, 0x4d, 0x33, 0x85,
732 0x45, 0xf9, 0x02, 0x7f, 0x50, 0x3c, 0x9f, 0xa8,
733 0x51, 0xa3, 0x40, 0x8f, 0x92, 0x9d, 0x38, 0xf5,
734 0xbc, 0xb6, 0xda, 0x21, 0x10, 0xff, 0xf3, 0xd2,
735 0xcd, 0x0c, 0x13, 0xec, 0x5f, 0x97, 0x44, 0x17,
736 0xc4, 0xa7, 0x7e, 0x3d, 0x64, 0x5d, 0x19, 0x73,
737 0x60, 0x81, 0x4f, 0xdc, 0x22, 0x2a, 0x90, 0x88,
738 0x46, 0xee, 0xb8, 0x14, 0xde, 0x5e, 0x0b, 0xdb,
739 0xe0, 0x32, 0x3a, 0x0a, 0x49, 0x06, 0x24, 0x5c,
740 0xc2, 0xd3, 0xac, 0x62, 0x91, 0x95, 0xe4, 0x79,
741 0xe7, 0xc8, 0x37, 0x6d, 0x8d, 0xd5, 0x4e, 0xa9,
742 0x6c, 0x56, 0xf4, 0xea, 0x65, 0x7a, 0xae, 0x08,
743 0xba, 0x78, 0x25, 0x2e, 0x1c, 0xa6, 0xb4, 0xc6,
744 0xe8, 0xdd, 0x74, 0x1f, 0x4b, 0xbd, 0x8b, 0x8a,
745 0x70, 0x3e, 0xb5, 0x66, 0x48, 0x03, 0xf6, 0x0e,
746 0x61, 0x35, 0x57, 0xb9, 0x86, 0xc1, 0x1d, 0x9e,
747 0xe1, 0xf8, 0x98, 0x11, 0x69, 0xd9, 0x8e, 0x94,
748 0x9b, 0x1e, 0x87, 0xe9, 0xce, 0x55, 0x28, 0xdf,
749 0x8c, 0xa1, 0x89, 0x0d, 0xbf, 0xe6, 0x42, 0x68,
750 0x41, 0x99, 0x2d, 0x0f, 0xb0, 0x54, 0xbb, 0x16
753 /****************************************/
755 /* Performs a 128 bit AES encrypt with */
757 /****************************************/
758 static void xor_128(u8
*a
, u8
*b
, u8
*out
)
762 for (i
= 0; i
< 16; i
++)
763 out
[i
] = a
[i
] ^ b
[i
];
766 static void xor_32(u8
*a
, u8
*b
, u8
*out
)
769 for (i
= 0; i
< 4; i
++)
770 out
[i
] = a
[i
] ^ b
[i
];
775 return sbox_table
[(sint
)a
];
778 static void next_key(u8
*key
, sint round
)
782 u8 rcon_table
[12] = {
783 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80,
784 0x1b, 0x36, 0x36, 0x36
787 sbox_key
[0] = sbox(key
[13]);
788 sbox_key
[1] = sbox(key
[14]);
789 sbox_key
[2] = sbox(key
[15]);
790 sbox_key
[3] = sbox(key
[12]);
791 rcon
= rcon_table
[round
];
792 xor_32(&key
[0], sbox_key
, &key
[0]);
793 key
[0] = key
[0] ^ rcon
;
794 xor_32(&key
[4], &key
[0], &key
[4]);
795 xor_32(&key
[8], &key
[4], &key
[8]);
796 xor_32(&key
[12], &key
[8], &key
[12]);
799 static void byte_sub(u8
*in
, u8
*out
)
802 for (i
= 0; i
< 16; i
++)
803 out
[i
] = sbox(in
[i
]);
806 static void shift_row(u8
*in
, u8
*out
)
826 static void mix_column(u8
*in
, u8
*out
)
838 for (i
= 0 ; i
< 4; i
++) {
839 if ((in
[i
] & 0x80) == 0x80)
844 swap_halfs
[0] = in
[2]; /* Swap halves */
845 swap_halfs
[1] = in
[3];
846 swap_halfs
[2] = in
[0];
847 swap_halfs
[3] = in
[1];
848 rotl
[0] = in
[3]; /* Rotate left 8 bits */
852 andf7
[0] = in
[0] & 0x7f;
853 andf7
[1] = in
[1] & 0x7f;
854 andf7
[2] = in
[2] & 0x7f;
855 andf7
[3] = in
[3] & 0x7f;
856 for (i
= 3; i
> 0; i
--) { /* logical shift left 1 bit */
857 andf7
[i
] = andf7
[i
] << 1;
858 if ((andf7
[i
-1] & 0x80) == 0x80)
859 andf7
[i
] = (andf7
[i
] | 0x01);
861 andf7
[0] = andf7
[0] << 1;
862 andf7
[0] = andf7
[0] & 0xfe;
863 xor_32(add1b
, andf7
, add1bf7
);
864 xor_32(in
, add1bf7
, rotr
);
865 temp
[0] = rotr
[0]; /* Rotate right 8 bits */
870 xor_32(add1bf7
, rotr
, temp
);
871 xor_32(swap_halfs
, rotl
, tempb
);
872 xor_32(temp
, tempb
, out
);
875 static void aes128k128d(u8
*key
, u8
*data
, u8
*ciphertext
)
879 u8 intermediatea
[16];
880 u8 intermediateb
[16];
883 for (i
= 0; i
< 16; i
++)
884 round_key
[i
] = key
[i
];
885 for (round
= 0; round
< 11; round
++) {
887 xor_128(round_key
, data
, ciphertext
);
888 next_key(round_key
, round
);
889 } else if (round
== 10) {
890 byte_sub(ciphertext
, intermediatea
);
891 shift_row(intermediatea
, intermediateb
);
892 xor_128(intermediateb
, round_key
, ciphertext
);
894 byte_sub(ciphertext
, intermediatea
);
895 shift_row(intermediatea
, intermediateb
);
896 mix_column(&intermediateb
[0], &intermediatea
[0]);
897 mix_column(&intermediateb
[4], &intermediatea
[4]);
898 mix_column(&intermediateb
[8], &intermediatea
[8]);
899 mix_column(&intermediateb
[12], &intermediatea
[12]);
900 xor_128(intermediatea
, round_key
, ciphertext
);
901 next_key(round_key
, round
);
906 /************************************************/
907 /* construct_mic_iv() */
908 /* Builds the MIC IV from header fields and PN */
909 /************************************************/
910 static void construct_mic_iv(u8
*mic_iv
, sint qc_exists
, sint a4_exists
,
911 u8
*mpdu
, uint payload_length
, u8
*pn_vector
)
916 if (qc_exists
&& a4_exists
)
917 mic_iv
[1] = mpdu
[30] & 0x0f; /* QoS_TC */
918 if (qc_exists
&& !a4_exists
)
919 mic_iv
[1] = mpdu
[24] & 0x0f; /* mute bits 7-4 */
922 for (i
= 2; i
< 8; i
++)
923 mic_iv
[i
] = mpdu
[i
+ 8];
924 for (i
= 8; i
< 14; i
++)
925 mic_iv
[i
] = pn_vector
[13 - i
]; /* mic_iv[8:13] = PN[5:0] */
926 mic_iv
[14] = (unsigned char) (payload_length
/ 256);
927 mic_iv
[15] = (unsigned char) (payload_length
% 256);
930 /************************************************/
931 /* construct_mic_header1() */
932 /* Builds the first MIC header block from */
934 /************************************************/
935 static void construct_mic_header1(u8
*mic_header1
, sint header_length
, u8
*mpdu
)
937 mic_header1
[0] = (u8
)((header_length
- 2) / 256);
938 mic_header1
[1] = (u8
)((header_length
- 2) % 256);
939 mic_header1
[2] = mpdu
[0] & 0xcf; /* Mute CF poll & CF ack bits */
940 /* Mute retry, more data and pwr mgt bits */
941 mic_header1
[3] = mpdu
[1] & 0xc7;
942 mic_header1
[4] = mpdu
[4]; /* A1 */
943 mic_header1
[5] = mpdu
[5];
944 mic_header1
[6] = mpdu
[6];
945 mic_header1
[7] = mpdu
[7];
946 mic_header1
[8] = mpdu
[8];
947 mic_header1
[9] = mpdu
[9];
948 mic_header1
[10] = mpdu
[10]; /* A2 */
949 mic_header1
[11] = mpdu
[11];
950 mic_header1
[12] = mpdu
[12];
951 mic_header1
[13] = mpdu
[13];
952 mic_header1
[14] = mpdu
[14];
953 mic_header1
[15] = mpdu
[15];
956 /************************************************/
957 /* construct_mic_header2() */
958 /* Builds the last MIC header block from */
960 /************************************************/
961 static void construct_mic_header2(u8
*mic_header2
, u8
*mpdu
, sint a4_exists
,
966 for (i
= 0; i
< 16; i
++)
967 mic_header2
[i
] = 0x00;
968 mic_header2
[0] = mpdu
[16]; /* A3 */
969 mic_header2
[1] = mpdu
[17];
970 mic_header2
[2] = mpdu
[18];
971 mic_header2
[3] = mpdu
[19];
972 mic_header2
[4] = mpdu
[20];
973 mic_header2
[5] = mpdu
[21];
974 mic_header2
[6] = 0x00;
975 mic_header2
[7] = 0x00; /* mpdu[23]; */
976 if (!qc_exists
&& a4_exists
)
977 for (i
= 0; i
< 6; i
++)
978 mic_header2
[8 + i
] = mpdu
[24 + i
]; /* A4 */
979 if (qc_exists
&& !a4_exists
) {
980 mic_header2
[8] = mpdu
[24] & 0x0f; /* mute bits 15 - 4 */
981 mic_header2
[9] = mpdu
[25] & 0x00;
983 if (qc_exists
&& a4_exists
) {
984 for (i
= 0; i
< 6; i
++)
985 mic_header2
[8 + i
] = mpdu
[24 + i
]; /* A4 */
986 mic_header2
[14] = mpdu
[30] & 0x0f;
987 mic_header2
[15] = mpdu
[31] & 0x00;
991 /************************************************/
992 /* construct_mic_header2() */
993 /* Builds the last MIC header block from */
995 /************************************************/
996 static void construct_ctr_preload(u8
*ctr_preload
, sint a4_exists
, sint qc_exists
,
997 u8
*mpdu
, u8
*pn_vector
, sint c
)
1001 for (i
= 0; i
< 16; i
++)
1002 ctr_preload
[i
] = 0x00;
1004 ctr_preload
[0] = 0x01; /* flag */
1005 if (qc_exists
&& a4_exists
)
1006 ctr_preload
[1] = mpdu
[30] & 0x0f;
1007 if (qc_exists
&& !a4_exists
)
1008 ctr_preload
[1] = mpdu
[24] & 0x0f;
1009 for (i
= 2; i
< 8; i
++)
1010 ctr_preload
[i
] = mpdu
[i
+ 8];
1011 for (i
= 8; i
< 14; i
++)
1012 ctr_preload
[i
] = pn_vector
[13 - i
];
1013 ctr_preload
[14] = (unsigned char) (c
/ 256); /* Ctr */
1014 ctr_preload
[15] = (unsigned char) (c
% 256);
1017 /************************************/
1019 /* A 128 bit, bitwise exclusive or */
1020 /************************************/
1021 static void bitwise_xor(u8
*ina
, u8
*inb
, u8
*out
)
1025 for (i
= 0; i
< 16; i
++)
1026 out
[i
] = ina
[i
] ^ inb
[i
];
1029 static sint
aes_cipher(u8
*key
, uint hdrlen
,
1030 u8
*pframe
, uint plen
)
1032 uint qc_exists
, a4_exists
, i
, j
, payload_remainder
;
1033 uint num_blocks
, payload_index
;
1041 /* Intermediate Buffers */
1042 u8 chain_buffer
[16];
1044 u8 padded_buffer
[16];
1046 uint frtype
= GetFrameType(pframe
);
1047 uint frsubtype
= GetFrameSubType(pframe
);
1049 frsubtype
= frsubtype
>> 4;
1050 memset((void *)mic_iv
, 0, 16);
1051 memset((void *)mic_header1
, 0, 16);
1052 memset((void *)mic_header2
, 0, 16);
1053 memset((void *)ctr_preload
, 0, 16);
1054 memset((void *)chain_buffer
, 0, 16);
1055 memset((void *)aes_out
, 0, 16);
1056 memset((void *)padded_buffer
, 0, 16);
1058 if ((hdrlen
== WLAN_HDR_A3_LEN
) || (hdrlen
== WLAN_HDR_A3_QOS_LEN
))
1063 if ((frtype
== WIFI_DATA_CFACK
) ||
1064 (frtype
== WIFI_DATA_CFPOLL
) ||
1065 (frtype
== WIFI_DATA_CFACKPOLL
)) {
1067 if (hdrlen
!= WLAN_HDR_A3_QOS_LEN
)
1069 } else if ((frsubtype
== 0x08) ||
1070 (frsubtype
== 0x09) ||
1071 (frsubtype
== 0x0a) ||
1072 (frsubtype
== 0x0b)) {
1073 if (hdrlen
!= WLAN_HDR_A3_QOS_LEN
)
1078 pn_vector
[0] = pframe
[hdrlen
];
1079 pn_vector
[1] = pframe
[hdrlen
+1];
1080 pn_vector
[2] = pframe
[hdrlen
+4];
1081 pn_vector
[3] = pframe
[hdrlen
+5];
1082 pn_vector
[4] = pframe
[hdrlen
+6];
1083 pn_vector
[5] = pframe
[hdrlen
+7];
1084 construct_mic_iv(mic_iv
, qc_exists
, a4_exists
, pframe
, plen
, pn_vector
);
1085 construct_mic_header1(mic_header1
, hdrlen
, pframe
);
1086 construct_mic_header2(mic_header2
, pframe
, a4_exists
, qc_exists
);
1087 payload_remainder
= plen
% 16;
1088 num_blocks
= plen
/ 16;
1089 /* Find start of payload */
1090 payload_index
= (hdrlen
+ 8);
1092 aes128k128d(key
, mic_iv
, aes_out
);
1093 bitwise_xor(aes_out
, mic_header1
, chain_buffer
);
1094 aes128k128d(key
, chain_buffer
, aes_out
);
1095 bitwise_xor(aes_out
, mic_header2
, chain_buffer
);
1096 aes128k128d(key
, chain_buffer
, aes_out
);
1097 for (i
= 0; i
< num_blocks
; i
++) {
1098 bitwise_xor(aes_out
, &pframe
[payload_index
], chain_buffer
);
1099 payload_index
+= 16;
1100 aes128k128d(key
, chain_buffer
, aes_out
);
1102 /* Add on the final payload block if it needs padding */
1103 if (payload_remainder
> 0) {
1104 for (j
= 0; j
< 16; j
++)
1105 padded_buffer
[j
] = 0x00;
1106 for (j
= 0; j
< payload_remainder
; j
++)
1107 padded_buffer
[j
] = pframe
[payload_index
++];
1108 bitwise_xor(aes_out
, padded_buffer
, chain_buffer
);
1109 aes128k128d(key
, chain_buffer
, aes_out
);
1111 for (j
= 0; j
< 8; j
++)
1112 mic
[j
] = aes_out
[j
];
1113 /* Insert MIC into payload */
1114 for (j
= 0; j
< 8; j
++)
1115 pframe
[payload_index
+j
] = mic
[j
];
1116 payload_index
= hdrlen
+ 8;
1117 for (i
= 0; i
< num_blocks
; i
++) {
1118 construct_ctr_preload(ctr_preload
, a4_exists
, qc_exists
,
1119 pframe
, pn_vector
, i
+ 1);
1120 aes128k128d(key
, ctr_preload
, aes_out
);
1121 bitwise_xor(aes_out
, &pframe
[payload_index
], chain_buffer
);
1122 for (j
= 0; j
< 16; j
++)
1123 pframe
[payload_index
++] = chain_buffer
[j
];
1125 if (payload_remainder
> 0) { /* If short final block, then pad it,*/
1126 /* encrypt and copy unpadded part back */
1127 construct_ctr_preload(ctr_preload
, a4_exists
, qc_exists
,
1128 pframe
, pn_vector
, num_blocks
+1);
1129 for (j
= 0; j
< 16; j
++)
1130 padded_buffer
[j
] = 0x00;
1131 for (j
= 0; j
< payload_remainder
; j
++)
1132 padded_buffer
[j
] = pframe
[payload_index
+j
];
1133 aes128k128d(key
, ctr_preload
, aes_out
);
1134 bitwise_xor(aes_out
, padded_buffer
, chain_buffer
);
1135 for (j
= 0; j
< payload_remainder
; j
++)
1136 pframe
[payload_index
++] = chain_buffer
[j
];
1138 /* Encrypt the MIC */
1139 construct_ctr_preload(ctr_preload
, a4_exists
, qc_exists
,
1140 pframe
, pn_vector
, 0);
1141 for (j
= 0; j
< 16; j
++)
1142 padded_buffer
[j
] = 0x00;
1143 for (j
= 0; j
< 8; j
++)
1144 padded_buffer
[j
] = pframe
[j
+hdrlen
+8+plen
];
1145 aes128k128d(key
, ctr_preload
, aes_out
);
1146 bitwise_xor(aes_out
, padded_buffer
, chain_buffer
);
1147 for (j
= 0; j
< 8; j
++)
1148 pframe
[payload_index
++] = chain_buffer
[j
];
1152 u32
r8712_aes_encrypt(struct _adapter
*padapter
, u8
*pxmitframe
)
1154 /* Intermediate Buffers */
1155 sint curfragnum
, length
;
1157 u8
*pframe
, *prwskey
;
1158 struct sta_info
*stainfo
;
1159 struct pkt_attrib
*pattrib
= &((struct xmit_frame
*)
1160 pxmitframe
)->attrib
;
1161 struct xmit_priv
*pxmitpriv
= &padapter
->xmitpriv
;
1164 if (((struct xmit_frame
*)pxmitframe
)->buf_addr
== NULL
)
1166 pframe
= ((struct xmit_frame
*)pxmitframe
)->buf_addr
+ TXDESC_OFFSET
;
1167 /* 4 start to encrypt each fragment */
1168 if ((pattrib
->encrypt
== _AES_
)) {
1170 stainfo
= pattrib
->psta
;
1172 stainfo
= r8712_get_stainfo(&padapter
->stapriv
,
1174 if (stainfo
!= NULL
) {
1175 prwskey
= &stainfo
->x_UncstKey
.skey
[0];
1177 for (curfragnum
= 0; curfragnum
< pattrib
->nr_frags
;
1179 if ((curfragnum
+ 1) == pattrib
->nr_frags
) {\
1180 length
= pattrib
->last_txcmdsz
-
1184 aes_cipher(prwskey
, pattrib
->
1185 hdrlen
, pframe
, length
);
1187 length
= pxmitpriv
->frag_len
-
1191 aes_cipher(prwskey
, pattrib
->
1192 hdrlen
, pframe
, length
);
1193 pframe
+= pxmitpriv
->frag_len
;
1194 pframe
= (u8
*)RND4((addr_t
)(pframe
));
1203 static sint
aes_decipher(u8
*key
, uint hdrlen
,
1204 u8
*pframe
, uint plen
)
1206 static u8 message
[MAX_MSG_SIZE
];
1207 uint qc_exists
, a4_exists
, i
, j
, payload_remainder
;
1208 uint num_blocks
, payload_index
;
1214 /* Intermediate Buffers */
1215 u8 chain_buffer
[16];
1217 u8 padded_buffer
[16];
1219 uint frtype
= GetFrameType(pframe
);
1220 uint frsubtype
= GetFrameSubType(pframe
);
1222 frsubtype
= frsubtype
>> 4;
1223 memset((void *)mic_iv
, 0, 16);
1224 memset((void *)mic_header1
, 0, 16);
1225 memset((void *)mic_header2
, 0, 16);
1226 memset((void *)ctr_preload
, 0, 16);
1227 memset((void *)chain_buffer
, 0, 16);
1228 memset((void *)aes_out
, 0, 16);
1229 memset((void *)padded_buffer
, 0, 16);
1230 /* start to decrypt the payload */
1231 /*(plen including llc, payload and mic) */
1232 num_blocks
= (plen
- 8) / 16;
1233 payload_remainder
= (plen
-8) % 16;
1234 pn_vector
[0] = pframe
[hdrlen
];
1235 pn_vector
[1] = pframe
[hdrlen
+1];
1236 pn_vector
[2] = pframe
[hdrlen
+4];
1237 pn_vector
[3] = pframe
[hdrlen
+5];
1238 pn_vector
[4] = pframe
[hdrlen
+6];
1239 pn_vector
[5] = pframe
[hdrlen
+7];
1240 if ((hdrlen
== WLAN_HDR_A3_LEN
) || (hdrlen
== WLAN_HDR_A3_QOS_LEN
))
1244 if ((frtype
== WIFI_DATA_CFACK
) ||
1245 (frtype
== WIFI_DATA_CFPOLL
) ||
1246 (frtype
== WIFI_DATA_CFACKPOLL
)) {
1248 if (hdrlen
!= WLAN_HDR_A3_QOS_LEN
)
1250 } else if ((frsubtype
== 0x08) ||
1251 (frsubtype
== 0x09) ||
1252 (frsubtype
== 0x0a) ||
1253 (frsubtype
== 0x0b)) {
1254 if (hdrlen
!= WLAN_HDR_A3_QOS_LEN
)
1259 /* now, decrypt pframe with hdrlen offset and plen long */
1260 payload_index
= hdrlen
+ 8; /* 8 is for extiv */
1261 for (i
= 0; i
< num_blocks
; i
++) {
1262 construct_ctr_preload(ctr_preload
, a4_exists
, qc_exists
,
1263 pframe
, pn_vector
, i
+ 1);
1264 aes128k128d(key
, ctr_preload
, aes_out
);
1265 bitwise_xor(aes_out
, &pframe
[payload_index
], chain_buffer
);
1266 for (j
= 0; j
< 16; j
++)
1267 pframe
[payload_index
++] = chain_buffer
[j
];
1269 if (payload_remainder
> 0) { /* If short final block, pad it,*/
1270 /* encrypt it and copy the unpadded part back */
1271 construct_ctr_preload(ctr_preload
, a4_exists
, qc_exists
,
1272 pframe
, pn_vector
, num_blocks
+1);
1273 for (j
= 0; j
< 16; j
++)
1274 padded_buffer
[j
] = 0x00;
1275 for (j
= 0; j
< payload_remainder
; j
++)
1276 padded_buffer
[j
] = pframe
[payload_index
+ j
];
1277 aes128k128d(key
, ctr_preload
, aes_out
);
1278 bitwise_xor(aes_out
, padded_buffer
, chain_buffer
);
1279 for (j
= 0; j
< payload_remainder
; j
++)
1280 pframe
[payload_index
++] = chain_buffer
[j
];
1282 /* start to calculate the mic */
1283 memcpy((void *)message
, pframe
, (hdrlen
+ plen
+ 8));
1284 pn_vector
[0] = pframe
[hdrlen
];
1285 pn_vector
[1] = pframe
[hdrlen
+1];
1286 pn_vector
[2] = pframe
[hdrlen
+4];
1287 pn_vector
[3] = pframe
[hdrlen
+5];
1288 pn_vector
[4] = pframe
[hdrlen
+6];
1289 pn_vector
[5] = pframe
[hdrlen
+7];
1290 construct_mic_iv(mic_iv
, qc_exists
, a4_exists
, message
, plen
-8,
1292 construct_mic_header1(mic_header1
, hdrlen
, message
);
1293 construct_mic_header2(mic_header2
, message
, a4_exists
, qc_exists
);
1294 payload_remainder
= (plen
- 8) % 16;
1295 num_blocks
= (plen
- 8) / 16;
1296 /* Find start of payload */
1297 payload_index
= (hdrlen
+ 8);
1299 aes128k128d(key
, mic_iv
, aes_out
);
1300 bitwise_xor(aes_out
, mic_header1
, chain_buffer
);
1301 aes128k128d(key
, chain_buffer
, aes_out
);
1302 bitwise_xor(aes_out
, mic_header2
, chain_buffer
);
1303 aes128k128d(key
, chain_buffer
, aes_out
);
1304 for (i
= 0; i
< num_blocks
; i
++) {
1305 bitwise_xor(aes_out
, &message
[payload_index
], chain_buffer
);
1306 payload_index
+= 16;
1307 aes128k128d(key
, chain_buffer
, aes_out
);
1309 /* Add on the final payload block if it needs padding */
1310 if (payload_remainder
> 0) {
1311 for (j
= 0; j
< 16; j
++)
1312 padded_buffer
[j
] = 0x00;
1313 for (j
= 0; j
< payload_remainder
; j
++)
1314 padded_buffer
[j
] = message
[payload_index
++];
1315 bitwise_xor(aes_out
, padded_buffer
, chain_buffer
);
1316 aes128k128d(key
, chain_buffer
, aes_out
);
1318 for (j
= 0 ; j
< 8; j
++)
1319 mic
[j
] = aes_out
[j
];
1320 /* Insert MIC into payload */
1321 for (j
= 0; j
< 8; j
++)
1322 message
[payload_index
+j
] = mic
[j
];
1323 payload_index
= hdrlen
+ 8;
1324 for (i
= 0; i
< num_blocks
; i
++) {
1325 construct_ctr_preload(ctr_preload
, a4_exists
, qc_exists
,
1326 message
, pn_vector
, i
+ 1);
1327 aes128k128d(key
, ctr_preload
, aes_out
);
1328 bitwise_xor(aes_out
, &message
[payload_index
], chain_buffer
);
1329 for (j
= 0; j
< 16; j
++)
1330 message
[payload_index
++] = chain_buffer
[j
];
1332 if (payload_remainder
> 0) { /* If short final block, pad it,*/
1333 /* encrypt and copy unpadded part back */
1334 construct_ctr_preload(ctr_preload
, a4_exists
, qc_exists
,
1335 message
, pn_vector
, num_blocks
+1);
1336 for (j
= 0; j
< 16; j
++)
1337 padded_buffer
[j
] = 0x00;
1338 for (j
= 0; j
< payload_remainder
; j
++)
1339 padded_buffer
[j
] = message
[payload_index
+ j
];
1340 aes128k128d(key
, ctr_preload
, aes_out
);
1341 bitwise_xor(aes_out
, padded_buffer
, chain_buffer
);
1342 for (j
= 0; j
< payload_remainder
; j
++)
1343 message
[payload_index
++] = chain_buffer
[j
];
1345 /* Encrypt the MIC */
1346 construct_ctr_preload(ctr_preload
, a4_exists
, qc_exists
, message
,
1348 for (j
= 0; j
< 16; j
++)
1349 padded_buffer
[j
] = 0x00;
1350 for (j
= 0; j
< 8; j
++)
1351 padded_buffer
[j
] = message
[j
+ hdrlen
+ plen
];
1352 aes128k128d(key
, ctr_preload
, aes_out
);
1353 bitwise_xor(aes_out
, padded_buffer
, chain_buffer
);
1354 for (j
= 0; j
< 8; j
++)
1355 message
[payload_index
++] = chain_buffer
[j
];
1356 /* compare the mic */
1360 u32
r8712_aes_decrypt(struct _adapter
*padapter
, u8
*precvframe
)
1362 /* Intermediate Buffers */
1365 u8
*pframe
, *prwskey
, *iv
, idx
;
1366 struct sta_info
*stainfo
;
1367 struct rx_pkt_attrib
*prxattrib
= &((union recv_frame
*)
1368 precvframe
)->u
.hdr
.attrib
;
1369 struct security_priv
*psecuritypriv
= &padapter
->securitypriv
;
1371 pframe
= (unsigned char *)((union recv_frame
*)precvframe
)->
1373 /* 4 start to encrypt each fragment */
1374 if ((prxattrib
->encrypt
== _AES_
)) {
1375 stainfo
= r8712_get_stainfo(&padapter
->stapriv
,
1377 if (stainfo
!= NULL
) {
1378 if (IS_MCAST(prxattrib
->ra
)) {
1379 iv
= pframe
+prxattrib
->hdrlen
;
1381 prwskey
= &psecuritypriv
->XGrpKey
[
1382 ((idx
>> 6) & 0x3) - 1].skey
[0];
1383 if (psecuritypriv
->binstallGrpkey
== false)
1387 prwskey
= &stainfo
->x_UncstKey
.skey
[0];
1389 length
= ((union recv_frame
*)precvframe
)->
1390 u
.hdr
.len
-prxattrib
->hdrlen
-prxattrib
->iv_len
;
1391 aes_decipher(prwskey
, prxattrib
->hdrlen
, pframe
,
1399 void r8712_use_tkipkey_handler(void *FunctionContext
)
1401 struct _adapter
*padapter
= (struct _adapter
*)FunctionContext
;
1403 padapter
->securitypriv
.busetkipkey
= true;