1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29#define _RTL871X_SECURITY_C_
30
31#include <linux/compiler.h>
32#include <linux/kernel.h>
33#include <linux/errno.h>
34#include <linux/slab.h>
35#include <linux/module.h>
36#include <linux/kref.h>
37#include <linux/netdevice.h>
38#include <linux/skbuff.h>
39#include <linux/circ_buf.h>
40#include <linux/uaccess.h>
41#include <asm/byteorder.h>
42#include <linux/atomic.h>
43#include <linux/semaphore.h>
44
45#include "osdep_service.h"
46#include "drv_types.h"
47#include "wifi.h"
48#include "osdep_intf.h"
49
50
51
52#define CRC32_POLY 0x04c11db7
53
54struct arc4context {
55 u32 x;
56 u32 y;
57 u8 state[256];
58};
59
60static void arcfour_init(struct arc4context *parc4ctx, u8 *key, u32 key_len)
61{
62 u32 t, u;
63 u32 keyindex;
64 u32 stateindex;
65 u8 *state;
66 u32 counter;
67
68 state = parc4ctx->state;
69 parc4ctx->x = 0;
70 parc4ctx->y = 0;
71 for (counter = 0; counter < 256; counter++)
72 state[counter] = (u8)counter;
73 keyindex = 0;
74 stateindex = 0;
75 for (counter = 0; counter < 256; counter++) {
76 t = state[counter];
77 stateindex = (stateindex + key[keyindex] + t) & 0xff;
78 u = state[stateindex];
79 state[stateindex] = (u8)t;
80 state[counter] = (u8)u;
81 if (++keyindex >= key_len)
82 keyindex = 0;
83 }
84}
85
86static u32 arcfour_byte(struct arc4context *parc4ctx)
87{
88 u32 x;
89 u32 y;
90 u32 sx, sy;
91 u8 *state;
92
93 state = parc4ctx->state;
94 x = (parc4ctx->x + 1) & 0xff;
95 sx = state[x];
96 y = (sx + parc4ctx->y) & 0xff;
97 sy = state[y];
98 parc4ctx->x = x;
99 parc4ctx->y = y;
100 state[y] = (u8)sx;
101 state[x] = (u8)sy;
102 return state[(sx + sy) & 0xff];
103}
104
105static void arcfour_encrypt(struct arc4context *parc4ctx,
106 u8 *dest, u8 *src, u32 len)
107{
108 u32 i;
109
110 for (i = 0; i < len; i++)
111 dest[i] = src[i] ^ (unsigned char)arcfour_byte(parc4ctx);
112}
113
114static sint bcrc32initialized;
115static u32 crc32_table[256];
116
117static u8 crc32_reverseBit(u8 data)
118{
119 return ((u8)(data << 7) & 0x80) | ((data << 5) & 0x40) | ((data << 3)
120 & 0x20) | ((data << 1) & 0x10) | ((data >> 1) & 0x08) |
121 ((data >> 3) & 0x04) | ((data >> 5) & 0x02) | ((data >> 7) &
122 0x01);
123}
124
125static void crc32_init(void)
126{
127 sint i, j;
128 u32 c;
129 u8 *p = (u8 *)&c, *p1;
130 u8 k;
131
132 if (bcrc32initialized == 1)
133 return;
134
135 for (i = 0; i < 256; ++i) {
136 k = crc32_reverseBit((u8)i);
137 for (c = ((u32)k) << 24, j = 8; j > 0; --j)
138 c = c & 0x80000000 ? (c << 1) ^ CRC32_POLY : (c << 1);
139 p1 = (u8 *)&crc32_table[i];
140 p1[0] = crc32_reverseBit(p[3]);
141 p1[1] = crc32_reverseBit(p[2]);
142 p1[2] = crc32_reverseBit(p[1]);
143 p1[3] = crc32_reverseBit(p[0]);
144 }
145 bcrc32initialized = 1;
146}
147
148static u32 getcrc32(u8 *buf, u32 len)
149{
150 u8 *p;
151 u32 crc;
152
153 if (!bcrc32initialized)
154 crc32_init();
155 crc = 0xffffffff;
156 for (p = buf; len > 0; ++p, --len)
157 crc = crc32_table[(crc ^ *p) & 0xff] ^ (crc >> 8);
158 return ~crc;
159}
160
161
162
163
164void r8712_wep_encrypt(struct _adapter *padapter, u8 *pxmitframe)
165{
166 unsigned char crc[4];
167 struct arc4context mycontext;
168 u32 curfragnum, length, keylength;
169 u8 *pframe, *payload, *iv;
170 u8 wepkey[16];
171 struct pkt_attrib *pattrib = &((struct xmit_frame *)
172 pxmitframe)->attrib;
173 struct security_priv *psecuritypriv = &padapter->securitypriv;
174 struct xmit_priv *pxmitpriv = &padapter->xmitpriv;
175
176 if (((struct xmit_frame *)pxmitframe)->buf_addr == NULL)
177 return;
178 pframe = ((struct xmit_frame *)pxmitframe)->buf_addr + TXDESC_OFFSET;
179
180 if ((pattrib->encrypt == _WEP40_) || (pattrib->encrypt == _WEP104_)) {
181 keylength = psecuritypriv->DefKeylen[psecuritypriv->
182 PrivacyKeyIndex];
183 for (curfragnum = 0; curfragnum < pattrib->nr_frags;
184 curfragnum++) {
185 iv = pframe + pattrib->hdrlen;
186 memcpy(&wepkey[0], iv, 3);
187 memcpy(&wepkey[3], &psecuritypriv->DefKey[
188 psecuritypriv->PrivacyKeyIndex].skey[0],
189 keylength);
190 payload = pframe + pattrib->iv_len + pattrib->hdrlen;
191 if ((curfragnum + 1) == pattrib->nr_frags) {
192 length = pattrib->last_txcmdsz - pattrib->
193 hdrlen - pattrib->iv_len -
194 pattrib->icv_len;
195 *((u32 *)crc) = cpu_to_le32(getcrc32(
196 payload, length));
197 arcfour_init(&mycontext, wepkey, 3 + keylength);
198 arcfour_encrypt(&mycontext, payload, payload,
199 length);
200 arcfour_encrypt(&mycontext, payload + length,
201 crc, 4);
202 } else {
203 length = pxmitpriv->frag_len -
204 pattrib->hdrlen - pattrib->iv_len -
205 pattrib->icv_len;
206 *((u32 *)crc) = cpu_to_le32(getcrc32(
207 payload, length));
208 arcfour_init(&mycontext, wepkey, 3 + keylength);
209 arcfour_encrypt(&mycontext, payload, payload,
210 length);
211 arcfour_encrypt(&mycontext, payload + length,
212 crc, 4);
213 pframe += pxmitpriv->frag_len;
214 pframe = (u8 *)RND4((addr_t)(pframe));
215 }
216 }
217 }
218}
219
220void r8712_wep_decrypt(struct _adapter *padapter, u8 *precvframe)
221{
222
223 u8 crc[4];
224 struct arc4context mycontext;
225 u32 length, keylength;
226 u8 *pframe, *payload, *iv, wepkey[16];
227 u8 keyindex;
228 struct rx_pkt_attrib *prxattrib = &(((union recv_frame *)
229 precvframe)->u.hdr.attrib);
230 struct security_priv *psecuritypriv = &padapter->securitypriv;
231
232 pframe = (unsigned char *)((union recv_frame *)precvframe)->
233 u.hdr.rx_data;
234
235 if ((prxattrib->encrypt == _WEP40_) || (prxattrib->encrypt ==
236 _WEP104_)) {
237 iv = pframe + prxattrib->hdrlen;
238 keyindex = (iv[3] & 0x3);
239 keylength = psecuritypriv->DefKeylen[keyindex];
240 memcpy(&wepkey[0], iv, 3);
241 memcpy(&wepkey[3], &psecuritypriv->DefKey[
242 psecuritypriv->PrivacyKeyIndex].skey[0],
243 keylength);
244 length = ((union recv_frame *)precvframe)->
245 u.hdr.len - prxattrib->hdrlen - prxattrib->iv_len;
246 payload = pframe + prxattrib->iv_len + prxattrib->hdrlen;
247
248 arcfour_init(&mycontext, wepkey, 3 + keylength);
249 arcfour_encrypt(&mycontext, payload, payload, length);
250
251 *((u32 *)crc) = cpu_to_le32(getcrc32(payload, length - 4));
252 }
253}
254
255
256
257static u32 secmicgetuint32(u8 *p)
258
259{
260 s32 i;
261 u32 res = 0;
262
263 for (i = 0; i < 4; i++)
264 res |= ((u32)(*p++)) << (8 * i);
265 return res;
266}
267
268static void secmicputuint32(u8 *p, u32 val)
269
270{
271 long i;
272
273 for (i = 0; i < 4; i++) {
274 *p++ = (u8) (val & 0xff);
275 val >>= 8;
276 }
277}
278
279static void secmicclear(struct mic_data *pmicdata)
280{
281
282 pmicdata->L = pmicdata->K0;
283 pmicdata->R = pmicdata->K1;
284 pmicdata->nBytesInM = 0;
285 pmicdata->M = 0;
286}
287
288void r8712_secmicsetkey(struct mic_data *pmicdata, u8 *key)
289{
290
291 pmicdata->K0 = secmicgetuint32(key);
292 pmicdata->K1 = secmicgetuint32(key + 4);
293
294 secmicclear(pmicdata);
295}
296
297static void secmicappendbyte(struct mic_data *pmicdata, u8 b)
298{
299
300 pmicdata->M |= ((u32)b) << (8 * pmicdata->nBytesInM);
301 pmicdata->nBytesInM++;
302
303 if (pmicdata->nBytesInM >= 4) {
304 pmicdata->L ^= pmicdata->M;
305 pmicdata->R ^= ROL32(pmicdata->L, 17);
306 pmicdata->L += pmicdata->R;
307 pmicdata->R ^= ((pmicdata->L & 0xff00ff00) >> 8) |
308 ((pmicdata->L & 0x00ff00ff) << 8);
309 pmicdata->L += pmicdata->R;
310 pmicdata->R ^= ROL32(pmicdata->L, 3);
311 pmicdata->L += pmicdata->R;
312 pmicdata->R ^= ROR32(pmicdata->L, 2);
313 pmicdata->L += pmicdata->R;
314
315 pmicdata->M = 0;
316 pmicdata->nBytesInM = 0;
317 }
318}
319
320void r8712_secmicappend(struct mic_data *pmicdata, u8 *src, u32 nbytes)
321{
322
323 while (nbytes > 0) {
324 secmicappendbyte(pmicdata, *src++);
325 nbytes--;
326 }
327}
328
329void r8712_secgetmic(struct mic_data *pmicdata, u8 *dst)
330{
331
332 secmicappendbyte(pmicdata, 0x5a);
333 secmicappendbyte(pmicdata, 0);
334 secmicappendbyte(pmicdata, 0);
335 secmicappendbyte(pmicdata, 0);
336 secmicappendbyte(pmicdata, 0);
337
338 while (pmicdata->nBytesInM != 0)
339 secmicappendbyte(pmicdata, 0);
340
341 secmicputuint32(dst, pmicdata->L);
342 secmicputuint32(dst + 4, pmicdata->R);
343
344 secmicclear(pmicdata);
345}
346
347void seccalctkipmic(u8 *key, u8 *header, u8 *data, u32 data_len, u8 *mic_code,
348 u8 pri)
349{
350
351 struct mic_data micdata;
352 u8 priority[4] = {0x0, 0x0, 0x0, 0x0};
353
354 r8712_secmicsetkey(&micdata, key);
355 priority[0] = pri;
356
357 if (header[1] & 1) {
358 r8712_secmicappend(&micdata, &header[16], 6);
359 if (header[1] & 2)
360 r8712_secmicappend(&micdata, &header[24], 6);
361 else
362 r8712_secmicappend(&micdata, &header[10], 6);
363 } else {
364 r8712_secmicappend(&micdata, &header[4], 6);
365 if (header[1] & 2)
366 r8712_secmicappend(&micdata, &header[16], 6);
367 else
368 r8712_secmicappend(&micdata, &header[10], 6);
369 }
370 r8712_secmicappend(&micdata, &priority[0], 4);
371 r8712_secmicappend(&micdata, data, data_len);
372 r8712_secgetmic(&micdata, mic_code);
373}
374
375
376#define RotR1(v16) ((((v16) >> 1) & 0x7FFF) ^ (((v16) & 1) << 15))
377#define Lo8(v16) ((u8)((v16) & 0x00FF))
378#define Hi8(v16) ((u8)(((v16) >> 8) & 0x00FF))
379#define Lo16(v32) ((u16)((v32) & 0xFFFF))
380#define Hi16(v32) ((u16)(((v32) >> 16) & 0xFFFF))
381#define Mk16(hi, lo) ((lo) ^ (((u16)(hi)) << 8))
382
383
384#define TK16(N) Mk16(tk[2 * (N) + 1], tk[2 * (N)])
385
386
387#define _S_(v16) (Sbox1[0][Lo8(v16)] ^ Sbox1[1][Hi8(v16)])
388
389
390#define PHASE1_LOOP_CNT 8
391#define TA_SIZE 6
392#define TK_SIZE 16
393#define P1K_SIZE 10
394#define RC4_KEY_SIZE 16
395
396
397
398static const unsigned short Sbox1[2][256] = {
399 {
400 0xC6A5, 0xF884, 0xEE99, 0xF68D, 0xFF0D, 0xD6BD, 0xDEB1, 0x9154,
401 0x6050, 0x0203, 0xCEA9, 0x567D, 0xE719, 0xB562, 0x4DE6, 0xEC9A,
402 0x8F45, 0x1F9D, 0x8940, 0xFA87, 0xEF15, 0xB2EB, 0x8EC9, 0xFB0B,
403 0x41EC, 0xB367, 0x5FFD, 0x45EA, 0x23BF, 0x53F7, 0xE496, 0x9B5B,
404 0x75C2, 0xE11C, 0x3DAE, 0x4C6A, 0x6C5A, 0x7E41, 0xF502, 0x834F,
405 0x685C, 0x51F4, 0xD134, 0xF908, 0xE293, 0xAB73, 0x6253, 0x2A3F,
406 0x080C, 0x9552, 0x4665, 0x9D5E, 0x3028, 0x37A1, 0x0A0F, 0x2FB5,
407 0x0E09, 0x2436, 0x1B9B, 0xDF3D, 0xCD26, 0x4E69, 0x7FCD, 0xEA9F,
408 0x121B, 0x1D9E, 0x5874, 0x342E, 0x362D, 0xDCB2, 0xB4EE, 0x5BFB,
409 0xA4F6, 0x764D, 0xB761, 0x7DCE, 0x527B, 0xDD3E, 0x5E71, 0x1397,
410 0xA6F5, 0xB968, 0x0000, 0xC12C, 0x4060, 0xE31F, 0x79C8, 0xB6ED,
411 0xD4BE, 0x8D46, 0x67D9, 0x724B, 0x94DE, 0x98D4, 0xB0E8, 0x854A,
412 0xBB6B, 0xC52A, 0x4FE5, 0xED16, 0x86C5, 0x9AD7, 0x6655, 0x1194,
413 0x8ACF, 0xE910, 0x0406, 0xFE81, 0xA0F0, 0x7844, 0x25BA, 0x4BE3,
414 0xA2F3, 0x5DFE, 0x80C0, 0x058A, 0x3FAD, 0x21BC, 0x7048, 0xF104,
415 0x63DF, 0x77C1, 0xAF75, 0x4263, 0x2030, 0xE51A, 0xFD0E, 0xBF6D,
416 0x814C, 0x1814, 0x2635, 0xC32F, 0xBEE1, 0x35A2, 0x88CC, 0x2E39,
417 0x9357, 0x55F2, 0xFC82, 0x7A47, 0xC8AC, 0xBAE7, 0x322B, 0xE695,
418 0xC0A0, 0x1998, 0x9ED1, 0xA37F, 0x4466, 0x547E, 0x3BAB, 0x0B83,
419 0x8CCA, 0xC729, 0x6BD3, 0x283C, 0xA779, 0xBCE2, 0x161D, 0xAD76,
420 0xDB3B, 0x6456, 0x744E, 0x141E, 0x92DB, 0x0C0A, 0x486C, 0xB8E4,
421 0x9F5D, 0xBD6E, 0x43EF, 0xC4A6, 0x39A8, 0x31A4, 0xD337, 0xF28B,
422 0xD532, 0x8B43, 0x6E59, 0xDAB7, 0x018C, 0xB164, 0x9CD2, 0x49E0,
423 0xD8B4, 0xACFA, 0xF307, 0xCF25, 0xCAAF, 0xF48E, 0x47E9, 0x1018,
424 0x6FD5, 0xF088, 0x4A6F, 0x5C72, 0x3824, 0x57F1, 0x73C7, 0x9751,
425 0xCB23, 0xA17C, 0xE89C, 0x3E21, 0x96DD, 0x61DC, 0x0D86, 0x0F85,
426 0xE090, 0x7C42, 0x71C4, 0xCCAA, 0x90D8, 0x0605, 0xF701, 0x1C12,
427 0xC2A3, 0x6A5F, 0xAEF9, 0x69D0, 0x1791, 0x9958, 0x3A27, 0x27B9,
428 0xD938, 0xEB13, 0x2BB3, 0x2233, 0xD2BB, 0xA970, 0x0789, 0x33A7,
429 0x2DB6, 0x3C22, 0x1592, 0xC920, 0x8749, 0xAAFF, 0x5078, 0xA57A,
430 0x038F, 0x59F8, 0x0980, 0x1A17, 0x65DA, 0xD731, 0x84C6, 0xD0B8,
431 0x82C3, 0x29B0, 0x5A77, 0x1E11, 0x7BCB, 0xA8FC, 0x6DD6, 0x2C3A,
432 },
433 {
434 0xA5C6, 0x84F8, 0x99EE, 0x8DF6, 0x0DFF, 0xBDD6, 0xB1DE, 0x5491,
435 0x5060, 0x0302, 0xA9CE, 0x7D56, 0x19E7, 0x62B5, 0xE64D, 0x9AEC,
436 0x458F, 0x9D1F, 0x4089, 0x87FA, 0x15EF, 0xEBB2, 0xC98E, 0x0BFB,
437 0xEC41, 0x67B3, 0xFD5F, 0xEA45, 0xBF23, 0xF753, 0x96E4, 0x5B9B,
438 0xC275, 0x1CE1, 0xAE3D, 0x6A4C, 0x5A6C, 0x417E, 0x02F5, 0x4F83,
439 0x5C68, 0xF451, 0x34D1, 0x08F9, 0x93E2, 0x73AB, 0x5362, 0x3F2A,
440 0x0C08, 0x5295, 0x6546, 0x5E9D, 0x2830, 0xA137, 0x0F0A, 0xB52F,
441 0x090E, 0x3624, 0x9B1B, 0x3DDF, 0x26CD, 0x694E, 0xCD7F, 0x9FEA,
442 0x1B12, 0x9E1D, 0x7458, 0x2E34, 0x2D36, 0xB2DC, 0xEEB4, 0xFB5B,
443 0xF6A4, 0x4D76, 0x61B7, 0xCE7D, 0x7B52, 0x3EDD, 0x715E, 0x9713,
444 0xF5A6, 0x68B9, 0x0000, 0x2CC1, 0x6040, 0x1FE3, 0xC879, 0xEDB6,
445 0xBED4, 0x468D, 0xD967, 0x4B72, 0xDE94, 0xD498, 0xE8B0, 0x4A85,
446 0x6BBB, 0x2AC5, 0xE54F, 0x16ED, 0xC586, 0xD79A, 0x5566, 0x9411,
447 0xCF8A, 0x10E9, 0x0604, 0x81FE, 0xF0A0, 0x4478, 0xBA25, 0xE34B,
448 0xF3A2, 0xFE5D, 0xC080, 0x8A05, 0xAD3F, 0xBC21, 0x4870, 0x04F1,
449 0xDF63, 0xC177, 0x75AF, 0x6342, 0x3020, 0x1AE5, 0x0EFD, 0x6DBF,
450 0x4C81, 0x1418, 0x3526, 0x2FC3, 0xE1BE, 0xA235, 0xCC88, 0x392E,
451 0x5793, 0xF255, 0x82FC, 0x477A, 0xACC8, 0xE7BA, 0x2B32, 0x95E6,
452 0xA0C0, 0x9819, 0xD19E, 0x7FA3, 0x6644, 0x7E54, 0xAB3B, 0x830B,
453 0xCA8C, 0x29C7, 0xD36B, 0x3C28, 0x79A7, 0xE2BC, 0x1D16, 0x76AD,
454 0x3BDB, 0x5664, 0x4E74, 0x1E14, 0xDB92, 0x0A0C, 0x6C48, 0xE4B8,
455 0x5D9F, 0x6EBD, 0xEF43, 0xA6C4, 0xA839, 0xA431, 0x37D3, 0x8BF2,
456 0x32D5, 0x438B, 0x596E, 0xB7DA, 0x8C01, 0x64B1, 0xD29C, 0xE049,
457 0xB4D8, 0xFAAC, 0x07F3, 0x25CF, 0xAFCA, 0x8EF4, 0xE947, 0x1810,
458 0xD56F, 0x88F0, 0x6F4A, 0x725C, 0x2438, 0xF157, 0xC773, 0x5197,
459 0x23CB, 0x7CA1, 0x9CE8, 0x213E, 0xDD96, 0xDC61, 0x860D, 0x850F,
460 0x90E0, 0x427C, 0xC471, 0xAACC, 0xD890, 0x0506, 0x01F7, 0x121C,
461 0xA3C2, 0x5F6A, 0xF9AE, 0xD069, 0x9117, 0x5899, 0x273A, 0xB927,
462 0x38D9, 0x13EB, 0xB32B, 0x3322, 0xBBD2, 0x70A9, 0x8907, 0xA733,
463 0xB62D, 0x223C, 0x9215, 0x20C9, 0x4987, 0xFFAA, 0x7850, 0x7AA5,
464 0x8F03, 0xF859, 0x8009, 0x171A, 0xDA65, 0x31D7, 0xC684, 0xB8D0,
465 0xC382, 0xB029, 0x775A, 0x111E, 0xCB7B, 0xFCA8, 0xD66D, 0x3A2C,
466 }
467};
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486static void phase1(u16 *p1k, const u8 *tk, const u8 *ta, u32 iv32)
487{
488 sint i;
489
490
491 p1k[0] = Lo16(iv32);
492 p1k[1] = Hi16(iv32);
493 p1k[2] = Mk16(ta[1], ta[0]);
494 p1k[3] = Mk16(ta[3], ta[2]);
495 p1k[4] = Mk16(ta[5], ta[4]);
496
497
498 for (i = 0; i < PHASE1_LOOP_CNT; i++) {
499 p1k[0] += _S_(p1k[4] ^ TK16((i & 1) + 0));
500 p1k[1] += _S_(p1k[0] ^ TK16((i & 1) + 2));
501 p1k[2] += _S_(p1k[1] ^ TK16((i & 1) + 4));
502 p1k[3] += _S_(p1k[2] ^ TK16((i & 1) + 6));
503 p1k[4] += _S_(p1k[3] ^ TK16((i & 1) + 0));
504 p1k[4] += (unsigned short)i;
505 }
506}
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531static void phase2(u8 *rc4key, const u8 *tk, const u16 *p1k, u16 iv16)
532{
533 sint i;
534 u16 PPK[6];
535
536
537 for (i = 0; i < 5; i++)
538 PPK[i] = p1k[i];
539 PPK[5] = p1k[4] + iv16;
540
541 PPK[0] += _S_(PPK[5] ^ TK16(0));
542 PPK[1] += _S_(PPK[0] ^ TK16(1));
543 PPK[2] += _S_(PPK[1] ^ TK16(2));
544 PPK[3] += _S_(PPK[2] ^ TK16(3));
545 PPK[4] += _S_(PPK[3] ^ TK16(4));
546 PPK[5] += _S_(PPK[4] ^ TK16(5));
547
548 PPK[0] += RotR1(PPK[5] ^ TK16(6));
549 PPK[1] += RotR1(PPK[0] ^ TK16(7));
550 PPK[2] += RotR1(PPK[1]);
551 PPK[3] += RotR1(PPK[2]);
552 PPK[4] += RotR1(PPK[3]);
553 PPK[5] += RotR1(PPK[4]);
554
555
556
557
558
559 rc4key[0] = Hi8(iv16);
560 rc4key[1] = (Hi8(iv16) | 0x20) & 0x7F;
561 rc4key[2] = Lo8(iv16);
562 rc4key[3] = Lo8((PPK[5] ^ TK16(0)) >> 1);
563
564 for (i = 0; i < 6; i++) {
565 rc4key[4 + 2 * i] = Lo8(PPK[i]);
566 rc4key[5 + 2 * i] = Hi8(PPK[i]);
567 }
568}
569
570
571u32 r8712_tkip_encrypt(struct _adapter *padapter, u8 *pxmitframe)
572{
573 u16 pnl;
574 u32 pnh;
575 u8 rc4key[16];
576 u8 ttkey[16];
577 u8 crc[4];
578 struct arc4context mycontext;
579 u32 curfragnum, length;
580
581 u8 *pframe, *payload, *iv, *prwskey;
582 union pn48 txpn;
583 struct sta_info *stainfo;
584 struct pkt_attrib *pattrib = &((struct xmit_frame *)pxmitframe)->attrib;
585 struct xmit_priv *pxmitpriv = &padapter->xmitpriv;
586 u32 res = _SUCCESS;
587
588 if (((struct xmit_frame *)pxmitframe)->buf_addr == NULL)
589 return _FAIL;
590
591 pframe = ((struct xmit_frame *)pxmitframe)->buf_addr + TXDESC_OFFSET;
592
593 if (pattrib->encrypt == _TKIP_) {
594 if (pattrib->psta)
595 stainfo = pattrib->psta;
596 else
597 stainfo = r8712_get_stainfo(&padapter->stapriv,
598 &pattrib->ra[0]);
599 if (stainfo != NULL) {
600 prwskey = &stainfo->x_UncstKey.skey[0];
601 for (curfragnum = 0; curfragnum < pattrib->nr_frags;
602 curfragnum++) {
603 iv = pframe + pattrib->hdrlen;
604 payload = pframe + pattrib->iv_len +
605 pattrib->hdrlen;
606 GET_TKIP_PN(iv, txpn);
607 pnl = (u16)(txpn.val);
608 pnh = (u32)(txpn.val >> 16);
609 phase1((u16 *)&ttkey[0], prwskey, &pattrib->
610 ta[0], pnh);
611 phase2(&rc4key[0], prwskey, (u16 *)&ttkey[0],
612 pnl);
613 if ((curfragnum + 1) == pattrib->nr_frags) {
614
615 length = pattrib->last_txcmdsz -
616 pattrib->hdrlen -
617 pattrib->iv_len -
618 pattrib->icv_len;
619 *((u32 *)crc) = cpu_to_le32(
620 getcrc32(payload, length));
621 arcfour_init(&mycontext, rc4key, 16);
622 arcfour_encrypt(&mycontext, payload,
623 payload, length);
624 arcfour_encrypt(&mycontext, payload +
625 length, crc, 4);
626 } else {
627 length = pxmitpriv->frag_len -
628 pattrib->hdrlen -
629 pattrib->iv_len -
630 pattrib->icv_len;
631 *((u32 *)crc) = cpu_to_le32(getcrc32(
632 payload, length));
633 arcfour_init(&mycontext, rc4key, 16);
634 arcfour_encrypt(&mycontext, payload,
635 payload, length);
636 arcfour_encrypt(&mycontext,
637 payload + length, crc,
638 4);
639 pframe += pxmitpriv->frag_len;
640 pframe = (u8 *)RND4((addr_t)(pframe));
641 }
642 }
643 } else {
644 res = _FAIL;
645 }
646 }
647 return res;
648}
649
650
651u32 r8712_tkip_decrypt(struct _adapter *padapter, u8 *precvframe)
652{
653 u16 pnl;
654 u32 pnh;
655 u8 rc4key[16];
656 u8 ttkey[16];
657 u8 crc[4];
658 struct arc4context mycontext;
659 u32 length;
660 u8 *pframe, *payload, *iv, *prwskey, idx = 0;
661 union pn48 txpn;
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;
666
667 pframe = (unsigned char *)((union recv_frame *)
668 precvframe)->u.hdr.rx_data;
669
670 if (prxattrib->encrypt == _TKIP_) {
671 stainfo = r8712_get_stainfo(&padapter->stapriv,
672 &prxattrib->ta[0]);
673 if (stainfo != NULL) {
674 iv = pframe + prxattrib->hdrlen;
675 payload = pframe + prxattrib->iv_len +
676 prxattrib->hdrlen;
677 length = ((union recv_frame *)precvframe)->
678 u.hdr.len - prxattrib->hdrlen -
679 prxattrib->iv_len;
680 if (IS_MCAST(prxattrib->ra)) {
681 idx = iv[3];
682 prwskey = &psecuritypriv->XGrpKey[
683 ((idx >> 6) & 0x3) - 1].skey[0];
684 if (!psecuritypriv->binstallGrpkey)
685 return _FAIL;
686 } else {
687 prwskey = &stainfo->x_UncstKey.skey[0];
688 }
689 GET_TKIP_PN(iv, txpn);
690 pnl = (u16)(txpn.val);
691 pnh = (u32)(txpn.val >> 16);
692 phase1((u16 *)&ttkey[0], prwskey, &prxattrib->ta[0],
693 pnh);
694 phase2(&rc4key[0], prwskey, (unsigned short *)
695 &ttkey[0], pnl);
696
697 arcfour_init(&mycontext, rc4key, 16);
698 arcfour_encrypt(&mycontext, payload, payload, length);
699 *((u32 *)crc) = cpu_to_le32(getcrc32(payload,
700 length - 4));
701 if (crc[3] != payload[length - 1] ||
702 crc[2] != payload[length - 2] ||
703 crc[1] != payload[length - 3] ||
704 crc[0] != payload[length - 4])
705 return _FAIL;
706 } else {
707 return _FAIL;
708 }
709 }
710 return _SUCCESS;
711}
712
713
714
715#define MAX_MSG_SIZE 2048
716
717
718
719
720static const u8 sbox_table[256] = {
721 0x63, 0x7c, 0x77, 0x7b, 0xf2, 0x6b, 0x6f, 0xc5,
722 0x30, 0x01, 0x67, 0x2b, 0xfe, 0xd7, 0xab, 0x76,
723 0xca, 0x82, 0xc9, 0x7d, 0xfa, 0x59, 0x47, 0xf0,
724 0xad, 0xd4, 0xa2, 0xaf, 0x9c, 0xa4, 0x72, 0xc0,
725 0xb7, 0xfd, 0x93, 0x26, 0x36, 0x3f, 0xf7, 0xcc,
726 0x34, 0xa5, 0xe5, 0xf1, 0x71, 0xd8, 0x31, 0x15,
727 0x04, 0xc7, 0x23, 0xc3, 0x18, 0x96, 0x05, 0x9a,
728 0x07, 0x12, 0x80, 0xe2, 0xeb, 0x27, 0xb2, 0x75,
729 0x09, 0x83, 0x2c, 0x1a, 0x1b, 0x6e, 0x5a, 0xa0,
730 0x52, 0x3b, 0xd6, 0xb3, 0x29, 0xe3, 0x2f, 0x84,
731 0x53, 0xd1, 0x00, 0xed, 0x20, 0xfc, 0xb1, 0x5b,
732 0x6a, 0xcb, 0xbe, 0x39, 0x4a, 0x4c, 0x58, 0xcf,
733 0xd0, 0xef, 0xaa, 0xfb, 0x43, 0x4d, 0x33, 0x85,
734 0x45, 0xf9, 0x02, 0x7f, 0x50, 0x3c, 0x9f, 0xa8,
735 0x51, 0xa3, 0x40, 0x8f, 0x92, 0x9d, 0x38, 0xf5,
736 0xbc, 0xb6, 0xda, 0x21, 0x10, 0xff, 0xf3, 0xd2,
737 0xcd, 0x0c, 0x13, 0xec, 0x5f, 0x97, 0x44, 0x17,
738 0xc4, 0xa7, 0x7e, 0x3d, 0x64, 0x5d, 0x19, 0x73,
739 0x60, 0x81, 0x4f, 0xdc, 0x22, 0x2a, 0x90, 0x88,
740 0x46, 0xee, 0xb8, 0x14, 0xde, 0x5e, 0x0b, 0xdb,
741 0xe0, 0x32, 0x3a, 0x0a, 0x49, 0x06, 0x24, 0x5c,
742 0xc2, 0xd3, 0xac, 0x62, 0x91, 0x95, 0xe4, 0x79,
743 0xe7, 0xc8, 0x37, 0x6d, 0x8d, 0xd5, 0x4e, 0xa9,
744 0x6c, 0x56, 0xf4, 0xea, 0x65, 0x7a, 0xae, 0x08,
745 0xba, 0x78, 0x25, 0x2e, 0x1c, 0xa6, 0xb4, 0xc6,
746 0xe8, 0xdd, 0x74, 0x1f, 0x4b, 0xbd, 0x8b, 0x8a,
747 0x70, 0x3e, 0xb5, 0x66, 0x48, 0x03, 0xf6, 0x0e,
748 0x61, 0x35, 0x57, 0xb9, 0x86, 0xc1, 0x1d, 0x9e,
749 0xe1, 0xf8, 0x98, 0x11, 0x69, 0xd9, 0x8e, 0x94,
750 0x9b, 0x1e, 0x87, 0xe9, 0xce, 0x55, 0x28, 0xdf,
751 0x8c, 0xa1, 0x89, 0x0d, 0xbf, 0xe6, 0x42, 0x68,
752 0x41, 0x99, 0x2d, 0x0f, 0xb0, 0x54, 0xbb, 0x16
753};
754
755
756
757
758
759
760static void xor_128(u8 *a, u8 *b, u8 *out)
761{
762 sint i;
763
764 for (i = 0; i < 16; i++)
765 out[i] = a[i] ^ b[i];
766}
767
768static void xor_32(u8 *a, u8 *b, u8 *out)
769{
770 sint i;
771
772 for (i = 0; i < 4; i++)
773 out[i] = a[i] ^ b[i];
774}
775
776static u8 sbox(u8 a)
777{
778 return sbox_table[(sint)a];
779}
780
781static void next_key(u8 *key, sint round)
782{
783 u8 rcon;
784 u8 sbox_key[4];
785 u8 rcon_table[12] = {
786 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80,
787 0x1b, 0x36, 0x36, 0x36
788 };
789
790 sbox_key[0] = sbox(key[13]);
791 sbox_key[1] = sbox(key[14]);
792 sbox_key[2] = sbox(key[15]);
793 sbox_key[3] = sbox(key[12]);
794 rcon = rcon_table[round];
795 xor_32(&key[0], sbox_key, &key[0]);
796 key[0] = key[0] ^ rcon;
797 xor_32(&key[4], &key[0], &key[4]);
798 xor_32(&key[8], &key[4], &key[8]);
799 xor_32(&key[12], &key[8], &key[12]);
800}
801
802static void byte_sub(u8 *in, u8 *out)
803{
804 sint i;
805
806 for (i = 0; i < 16; i++)
807 out[i] = sbox(in[i]);
808}
809
810static void shift_row(u8 *in, u8 *out)
811{
812 out[0] = in[0];
813 out[1] = in[5];
814 out[2] = in[10];
815 out[3] = in[15];
816 out[4] = in[4];
817 out[5] = in[9];
818 out[6] = in[14];
819 out[7] = in[3];
820 out[8] = in[8];
821 out[9] = in[13];
822 out[10] = in[2];
823 out[11] = in[7];
824 out[12] = in[12];
825 out[13] = in[1];
826 out[14] = in[6];
827 out[15] = in[11];
828}
829
830static void mix_column(u8 *in, u8 *out)
831{
832 sint i;
833 u8 add1b[4];
834 u8 add1bf7[4];
835 u8 rotl[4];
836 u8 swap_halfs[4];
837 u8 andf7[4];
838 u8 rotr[4];
839 u8 temp[4];
840 u8 tempb[4];
841
842 for (i = 0; i < 4; i++) {
843 if ((in[i] & 0x80) == 0x80)
844 add1b[i] = 0x1b;
845 else
846 add1b[i] = 0x00;
847 }
848 swap_halfs[0] = in[2];
849 swap_halfs[1] = in[3];
850 swap_halfs[2] = in[0];
851 swap_halfs[3] = in[1];
852 rotl[0] = in[3];
853 rotl[1] = in[0];
854 rotl[2] = in[1];
855 rotl[3] = in[2];
856 andf7[0] = in[0] & 0x7f;
857 andf7[1] = in[1] & 0x7f;
858 andf7[2] = in[2] & 0x7f;
859 andf7[3] = in[3] & 0x7f;
860 for (i = 3; i > 0; i--) {
861 andf7[i] = andf7[i] << 1;
862 if ((andf7[i - 1] & 0x80) == 0x80)
863 andf7[i] = (andf7[i] | 0x01);
864 }
865 andf7[0] = andf7[0] << 1;
866 andf7[0] = andf7[0] & 0xfe;
867 xor_32(add1b, andf7, add1bf7);
868 xor_32(in, add1bf7, rotr);
869 temp[0] = rotr[0];
870 rotr[0] = rotr[1];
871 rotr[1] = rotr[2];
872 rotr[2] = rotr[3];
873 rotr[3] = temp[0];
874 xor_32(add1bf7, rotr, temp);
875 xor_32(swap_halfs, rotl, tempb);
876 xor_32(temp, tempb, out);
877}
878
879static void aes128k128d(u8 *key, u8 *data, u8 *ciphertext)
880{
881 sint round;
882 sint i;
883 u8 intermediatea[16];
884 u8 intermediateb[16];
885 u8 round_key[16];
886
887 for (i = 0; i < 16; i++)
888 round_key[i] = key[i];
889 for (round = 0; round < 11; round++) {
890 if (round == 0) {
891 xor_128(round_key, data, ciphertext);
892 next_key(round_key, round);
893 } else if (round == 10) {
894 byte_sub(ciphertext, intermediatea);
895 shift_row(intermediatea, intermediateb);
896 xor_128(intermediateb, round_key, ciphertext);
897 } else {
898 byte_sub(ciphertext, intermediatea);
899 shift_row(intermediatea, intermediateb);
900 mix_column(&intermediateb[0], &intermediatea[0]);
901 mix_column(&intermediateb[4], &intermediatea[4]);
902 mix_column(&intermediateb[8], &intermediatea[8]);
903 mix_column(&intermediateb[12], &intermediatea[12]);
904 xor_128(intermediatea, round_key, ciphertext);
905 next_key(round_key, round);
906 }
907 }
908}
909
910
911
912
913
914static void construct_mic_iv(u8 *mic_iv, sint qc_exists, sint a4_exists,
915 u8 *mpdu, uint payload_length, u8 *pn_vector)
916{
917 sint i;
918
919 mic_iv[0] = 0x59;
920 if (qc_exists && a4_exists)
921 mic_iv[1] = mpdu[30] & 0x0f;
922 if (qc_exists && !a4_exists)
923 mic_iv[1] = mpdu[24] & 0x0f;
924 if (!qc_exists)
925 mic_iv[1] = 0x00;
926 for (i = 2; i < 8; i++)
927 mic_iv[i] = mpdu[i + 8];
928 for (i = 8; i < 14; i++)
929 mic_iv[i] = pn_vector[13 - i];
930 mic_iv[14] = (unsigned char) (payload_length / 256);
931 mic_iv[15] = (unsigned char) (payload_length % 256);
932}
933
934
935
936
937
938
939static void construct_mic_header1(u8 *mic_header1, sint header_length, u8 *mpdu)
940{
941 mic_header1[0] = (u8)((header_length - 2) / 256);
942 mic_header1[1] = (u8)((header_length - 2) % 256);
943 mic_header1[2] = mpdu[0] & 0xcf;
944
945 mic_header1[3] = mpdu[1] & 0xc7;
946 mic_header1[4] = mpdu[4];
947 mic_header1[5] = mpdu[5];
948 mic_header1[6] = mpdu[6];
949 mic_header1[7] = mpdu[7];
950 mic_header1[8] = mpdu[8];
951 mic_header1[9] = mpdu[9];
952 mic_header1[10] = mpdu[10];
953 mic_header1[11] = mpdu[11];
954 mic_header1[12] = mpdu[12];
955 mic_header1[13] = mpdu[13];
956 mic_header1[14] = mpdu[14];
957 mic_header1[15] = mpdu[15];
958}
959
960
961
962
963
964
965static void construct_mic_header2(u8 *mic_header2, u8 *mpdu, sint a4_exists,
966 sint qc_exists)
967{
968 sint i;
969
970 for (i = 0; i < 16; i++)
971 mic_header2[i] = 0x00;
972 mic_header2[0] = mpdu[16];
973 mic_header2[1] = mpdu[17];
974 mic_header2[2] = mpdu[18];
975 mic_header2[3] = mpdu[19];
976 mic_header2[4] = mpdu[20];
977 mic_header2[5] = mpdu[21];
978 mic_header2[6] = 0x00;
979 mic_header2[7] = 0x00;
980 if (!qc_exists && a4_exists)
981 for (i = 0; i < 6; i++)
982 mic_header2[8 + i] = mpdu[24 + i];
983 if (qc_exists && !a4_exists) {
984 mic_header2[8] = mpdu[24] & 0x0f;
985 mic_header2[9] = mpdu[25] & 0x00;
986 }
987 if (qc_exists && a4_exists) {
988 for (i = 0; i < 6; i++)
989 mic_header2[8 + i] = mpdu[24 + i];
990 mic_header2[14] = mpdu[30] & 0x0f;
991 mic_header2[15] = mpdu[31] & 0x00;
992 }
993}
994
995
996
997
998
999
1000static void construct_ctr_preload(u8 *ctr_preload, sint a4_exists, sint qc_exists,
1001 u8 *mpdu, u8 *pn_vector, sint c)
1002{
1003 sint i;
1004
1005 for (i = 0; i < 16; i++)
1006 ctr_preload[i] = 0x00;
1007 i = 0;
1008 ctr_preload[0] = 0x01;
1009 if (qc_exists && a4_exists)
1010 ctr_preload[1] = mpdu[30] & 0x0f;
1011 if (qc_exists && !a4_exists)
1012 ctr_preload[1] = mpdu[24] & 0x0f;
1013 for (i = 2; i < 8; i++)
1014 ctr_preload[i] = mpdu[i + 8];
1015 for (i = 8; i < 14; i++)
1016 ctr_preload[i] = pn_vector[13 - i];
1017 ctr_preload[14] = (unsigned char) (c / 256);
1018 ctr_preload[15] = (unsigned char) (c % 256);
1019}
1020
1021
1022
1023
1024
1025static void bitwise_xor(u8 *ina, u8 *inb, u8 *out)
1026{
1027 sint i;
1028
1029 for (i = 0; i < 16; i++)
1030 out[i] = ina[i] ^ inb[i];
1031}
1032
1033static sint aes_cipher(u8 *key, uint hdrlen,
1034 u8 *pframe, uint plen)
1035{
1036 uint qc_exists, a4_exists, i, j, payload_remainder;
1037 uint num_blocks, payload_index;
1038
1039 u8 pn_vector[6];
1040 u8 mic_iv[16];
1041 u8 mic_header1[16];
1042 u8 mic_header2[16];
1043 u8 ctr_preload[16];
1044
1045
1046 u8 chain_buffer[16];
1047 u8 aes_out[16];
1048 u8 padded_buffer[16];
1049 u8 mic[8];
1050 uint frtype = GetFrameType(pframe);
1051 uint frsubtype = GetFrameSubType(pframe);
1052
1053 frsubtype >>= 4;
1054 memset((void *)mic_iv, 0, 16);
1055 memset((void *)mic_header1, 0, 16);
1056 memset((void *)mic_header2, 0, 16);
1057 memset((void *)ctr_preload, 0, 16);
1058 memset((void *)chain_buffer, 0, 16);
1059 memset((void *)aes_out, 0, 16);
1060 memset((void *)padded_buffer, 0, 16);
1061
1062 if ((hdrlen == WLAN_HDR_A3_LEN) || (hdrlen == WLAN_HDR_A3_QOS_LEN))
1063 a4_exists = 0;
1064 else
1065 a4_exists = 1;
1066
1067 if ((frtype == WIFI_DATA_CFACK) ||
1068 (frtype == WIFI_DATA_CFPOLL) ||
1069 (frtype == WIFI_DATA_CFACKPOLL)) {
1070 qc_exists = 1;
1071 if (hdrlen != WLAN_HDR_A3_QOS_LEN)
1072 hdrlen += 2;
1073 } else if ((frsubtype == 0x08) ||
1074 (frsubtype == 0x09) ||
1075 (frsubtype == 0x0a) ||
1076 (frsubtype == 0x0b)) {
1077 if (hdrlen != WLAN_HDR_A3_QOS_LEN)
1078 hdrlen += 2;
1079 qc_exists = 1;
1080 } else {
1081 qc_exists = 0;
1082 }
1083 pn_vector[0] = pframe[hdrlen];
1084 pn_vector[1] = pframe[hdrlen + 1];
1085 pn_vector[2] = pframe[hdrlen + 4];
1086 pn_vector[3] = pframe[hdrlen + 5];
1087 pn_vector[4] = pframe[hdrlen + 6];
1088 pn_vector[5] = pframe[hdrlen + 7];
1089 construct_mic_iv(mic_iv, qc_exists, a4_exists, pframe, plen, pn_vector);
1090 construct_mic_header1(mic_header1, hdrlen, pframe);
1091 construct_mic_header2(mic_header2, pframe, a4_exists, qc_exists);
1092 payload_remainder = plen % 16;
1093 num_blocks = plen / 16;
1094
1095 payload_index = hdrlen + 8;
1096
1097 aes128k128d(key, mic_iv, aes_out);
1098 bitwise_xor(aes_out, mic_header1, chain_buffer);
1099 aes128k128d(key, chain_buffer, aes_out);
1100 bitwise_xor(aes_out, mic_header2, chain_buffer);
1101 aes128k128d(key, chain_buffer, aes_out);
1102 for (i = 0; i < num_blocks; i++) {
1103 bitwise_xor(aes_out, &pframe[payload_index], chain_buffer);
1104 payload_index += 16;
1105 aes128k128d(key, chain_buffer, aes_out);
1106 }
1107
1108 if (payload_remainder > 0) {
1109 for (j = 0; j < 16; j++)
1110 padded_buffer[j] = 0x00;
1111 for (j = 0; j < payload_remainder; j++)
1112 padded_buffer[j] = pframe[payload_index++];
1113 bitwise_xor(aes_out, padded_buffer, chain_buffer);
1114 aes128k128d(key, chain_buffer, aes_out);
1115 }
1116 for (j = 0; j < 8; j++)
1117 mic[j] = aes_out[j];
1118
1119 for (j = 0; j < 8; j++)
1120 pframe[payload_index + j] = mic[j];
1121 payload_index = hdrlen + 8;
1122 for (i = 0; i < num_blocks; i++) {
1123 construct_ctr_preload(ctr_preload, a4_exists, qc_exists,
1124 pframe, pn_vector, i + 1);
1125 aes128k128d(key, ctr_preload, aes_out);
1126 bitwise_xor(aes_out, &pframe[payload_index], chain_buffer);
1127 for (j = 0; j < 16; j++)
1128 pframe[payload_index++] = chain_buffer[j];
1129 }
1130 if (payload_remainder > 0) {
1131
1132 construct_ctr_preload(ctr_preload, a4_exists, qc_exists,
1133 pframe, pn_vector, num_blocks + 1);
1134 for (j = 0; j < 16; j++)
1135 padded_buffer[j] = 0x00;
1136 for (j = 0; j < payload_remainder; j++)
1137 padded_buffer[j] = pframe[payload_index + j];
1138 aes128k128d(key, ctr_preload, aes_out);
1139 bitwise_xor(aes_out, padded_buffer, chain_buffer);
1140 for (j = 0; j < payload_remainder; j++)
1141 pframe[payload_index++] = chain_buffer[j];
1142 }
1143
1144 construct_ctr_preload(ctr_preload, a4_exists, qc_exists,
1145 pframe, pn_vector, 0);
1146 for (j = 0; j < 16; j++)
1147 padded_buffer[j] = 0x00;
1148 for (j = 0; j < 8; j++)
1149 padded_buffer[j] = pframe[j + hdrlen + 8 + plen];
1150 aes128k128d(key, ctr_preload, aes_out);
1151 bitwise_xor(aes_out, padded_buffer, chain_buffer);
1152 for (j = 0; j < 8; j++)
1153 pframe[payload_index++] = chain_buffer[j];
1154 return _SUCCESS;
1155}
1156
1157u32 r8712_aes_encrypt(struct _adapter *padapter, u8 *pxmitframe)
1158{
1159
1160 sint curfragnum, length;
1161 u8 *pframe, *prwskey;
1162 struct sta_info *stainfo;
1163 struct pkt_attrib *pattrib = &((struct xmit_frame *)
1164 pxmitframe)->attrib;
1165 struct xmit_priv *pxmitpriv = &padapter->xmitpriv;
1166 u32 res = _SUCCESS;
1167
1168 if (((struct xmit_frame *)pxmitframe)->buf_addr == NULL)
1169 return _FAIL;
1170 pframe = ((struct xmit_frame *)pxmitframe)->buf_addr + TXDESC_OFFSET;
1171
1172 if (pattrib->encrypt == _AES_) {
1173 if (pattrib->psta)
1174 stainfo = pattrib->psta;
1175 else
1176 stainfo = r8712_get_stainfo(&padapter->stapriv,
1177 &pattrib->ra[0]);
1178 if (stainfo != NULL) {
1179 prwskey = &stainfo->x_UncstKey.skey[0];
1180 for (curfragnum = 0; curfragnum < pattrib->nr_frags;
1181 curfragnum++) {
1182 if ((curfragnum + 1) == pattrib->nr_frags) {
1183 length = pattrib->last_txcmdsz -
1184 pattrib->hdrlen -
1185 pattrib->iv_len -
1186 pattrib->icv_len;
1187 aes_cipher(prwskey, pattrib->
1188 hdrlen, pframe, length);
1189 } else {
1190 length = pxmitpriv->frag_len -
1191 pattrib->hdrlen -
1192 pattrib->iv_len -
1193 pattrib->icv_len;
1194 aes_cipher(prwskey, pattrib->
1195 hdrlen, pframe, length);
1196 pframe += pxmitpriv->frag_len;
1197 pframe = (u8 *)RND4((addr_t)(pframe));
1198 }
1199 }
1200 } else {
1201 res = _FAIL;
1202 }
1203 }
1204 return res;
1205}
1206
1207static sint aes_decipher(u8 *key, uint hdrlen,
1208 u8 *pframe, uint plen)
1209{
1210 static u8 message[MAX_MSG_SIZE];
1211 uint qc_exists, a4_exists, i, j, payload_remainder;
1212 uint num_blocks, payload_index;
1213 u8 pn_vector[6];
1214 u8 mic_iv[16];
1215 u8 mic_header1[16];
1216 u8 mic_header2[16];
1217 u8 ctr_preload[16];
1218
1219 u8 chain_buffer[16];
1220 u8 aes_out[16];
1221 u8 padded_buffer[16];
1222 u8 mic[8];
1223 uint frtype = GetFrameType(pframe);
1224 uint frsubtype = GetFrameSubType(pframe);
1225
1226 frsubtype >>= 4;
1227 memset((void *)mic_iv, 0, 16);
1228 memset((void *)mic_header1, 0, 16);
1229 memset((void *)mic_header2, 0, 16);
1230 memset((void *)ctr_preload, 0, 16);
1231 memset((void *)chain_buffer, 0, 16);
1232 memset((void *)aes_out, 0, 16);
1233 memset((void *)padded_buffer, 0, 16);
1234
1235
1236 num_blocks = (plen - 8) / 16;
1237 payload_remainder = (plen - 8) % 16;
1238 pn_vector[0] = pframe[hdrlen];
1239 pn_vector[1] = pframe[hdrlen + 1];
1240 pn_vector[2] = pframe[hdrlen + 4];
1241 pn_vector[3] = pframe[hdrlen + 5];
1242 pn_vector[4] = pframe[hdrlen + 6];
1243 pn_vector[5] = pframe[hdrlen + 7];
1244 if ((hdrlen == WLAN_HDR_A3_LEN) || (hdrlen == WLAN_HDR_A3_QOS_LEN))
1245 a4_exists = 0;
1246 else
1247 a4_exists = 1;
1248 if ((frtype == WIFI_DATA_CFACK) ||
1249 (frtype == WIFI_DATA_CFPOLL) ||
1250 (frtype == WIFI_DATA_CFACKPOLL)) {
1251 qc_exists = 1;
1252 if (hdrlen != WLAN_HDR_A3_QOS_LEN)
1253 hdrlen += 2;
1254 } else if ((frsubtype == 0x08) ||
1255 (frsubtype == 0x09) ||
1256 (frsubtype == 0x0a) ||
1257 (frsubtype == 0x0b)) {
1258 if (hdrlen != WLAN_HDR_A3_QOS_LEN)
1259 hdrlen += 2;
1260 qc_exists = 1;
1261 } else {
1262 qc_exists = 0;
1263 }
1264
1265 payload_index = hdrlen + 8;
1266 for (i = 0; i < num_blocks; i++) {
1267 construct_ctr_preload(ctr_preload, a4_exists, qc_exists,
1268 pframe, pn_vector, i + 1);
1269 aes128k128d(key, ctr_preload, aes_out);
1270 bitwise_xor(aes_out, &pframe[payload_index], chain_buffer);
1271 for (j = 0; j < 16; j++)
1272 pframe[payload_index++] = chain_buffer[j];
1273 }
1274 if (payload_remainder > 0) {
1275
1276 construct_ctr_preload(ctr_preload, a4_exists, qc_exists,
1277 pframe, pn_vector, num_blocks + 1);
1278 for (j = 0; j < 16; j++)
1279 padded_buffer[j] = 0x00;
1280 for (j = 0; j < payload_remainder; j++)
1281 padded_buffer[j] = pframe[payload_index + j];
1282 aes128k128d(key, ctr_preload, aes_out);
1283 bitwise_xor(aes_out, padded_buffer, chain_buffer);
1284 for (j = 0; j < payload_remainder; j++)
1285 pframe[payload_index++] = chain_buffer[j];
1286 }
1287
1288 memcpy((void *)message, pframe, (hdrlen + plen + 8));
1289 pn_vector[0] = pframe[hdrlen];
1290 pn_vector[1] = pframe[hdrlen + 1];
1291 pn_vector[2] = pframe[hdrlen + 4];
1292 pn_vector[3] = pframe[hdrlen + 5];
1293 pn_vector[4] = pframe[hdrlen + 6];
1294 pn_vector[5] = pframe[hdrlen + 7];
1295 construct_mic_iv(mic_iv, qc_exists, a4_exists, message, plen - 8,
1296 pn_vector);
1297 construct_mic_header1(mic_header1, hdrlen, message);
1298 construct_mic_header2(mic_header2, message, a4_exists, qc_exists);
1299 payload_remainder = (plen - 8) % 16;
1300 num_blocks = (plen - 8) / 16;
1301
1302 payload_index = hdrlen + 8;
1303
1304 aes128k128d(key, mic_iv, aes_out);
1305 bitwise_xor(aes_out, mic_header1, chain_buffer);
1306 aes128k128d(key, chain_buffer, aes_out);
1307 bitwise_xor(aes_out, mic_header2, chain_buffer);
1308 aes128k128d(key, chain_buffer, aes_out);
1309 for (i = 0; i < num_blocks; i++) {
1310 bitwise_xor(aes_out, &message[payload_index], chain_buffer);
1311 payload_index += 16;
1312 aes128k128d(key, chain_buffer, aes_out);
1313 }
1314
1315 if (payload_remainder > 0) {
1316 for (j = 0; j < 16; j++)
1317 padded_buffer[j] = 0x00;
1318 for (j = 0; j < payload_remainder; j++)
1319 padded_buffer[j] = message[payload_index++];
1320 bitwise_xor(aes_out, padded_buffer, chain_buffer);
1321 aes128k128d(key, chain_buffer, aes_out);
1322 }
1323 for (j = 0; j < 8; j++)
1324 mic[j] = aes_out[j];
1325
1326 for (j = 0; j < 8; j++)
1327 message[payload_index + j] = mic[j];
1328 payload_index = hdrlen + 8;
1329 for (i = 0; i < num_blocks; i++) {
1330 construct_ctr_preload(ctr_preload, a4_exists, qc_exists,
1331 message, pn_vector, i + 1);
1332 aes128k128d(key, ctr_preload, aes_out);
1333 bitwise_xor(aes_out, &message[payload_index], chain_buffer);
1334 for (j = 0; j < 16; j++)
1335 message[payload_index++] = chain_buffer[j];
1336 }
1337 if (payload_remainder > 0) {
1338
1339 construct_ctr_preload(ctr_preload, a4_exists, qc_exists,
1340 message, pn_vector, num_blocks + 1);
1341 for (j = 0; j < 16; j++)
1342 padded_buffer[j] = 0x00;
1343 for (j = 0; j < payload_remainder; j++)
1344 padded_buffer[j] = message[payload_index + j];
1345 aes128k128d(key, ctr_preload, aes_out);
1346 bitwise_xor(aes_out, padded_buffer, chain_buffer);
1347 for (j = 0; j < payload_remainder; j++)
1348 message[payload_index++] = chain_buffer[j];
1349 }
1350
1351 construct_ctr_preload(ctr_preload, a4_exists, qc_exists, message,
1352 pn_vector, 0);
1353 for (j = 0; j < 16; j++)
1354 padded_buffer[j] = 0x00;
1355 for (j = 0; j < 8; j++)
1356 padded_buffer[j] = message[j + hdrlen + plen];
1357 aes128k128d(key, ctr_preload, aes_out);
1358 bitwise_xor(aes_out, padded_buffer, chain_buffer);
1359 for (j = 0; j < 8; j++)
1360 message[payload_index++] = chain_buffer[j];
1361
1362 return _SUCCESS;
1363}
1364
1365u32 r8712_aes_decrypt(struct _adapter *padapter, u8 *precvframe)
1366{
1367
1368 sint length;
1369 u8 *pframe, *prwskey, *iv, idx;
1370 struct sta_info *stainfo;
1371 struct rx_pkt_attrib *prxattrib = &((union recv_frame *)
1372 precvframe)->u.hdr.attrib;
1373 struct security_priv *psecuritypriv = &padapter->securitypriv;
1374
1375 pframe = (unsigned char *)((union recv_frame *)precvframe)->
1376 u.hdr.rx_data;
1377
1378 if (prxattrib->encrypt == _AES_) {
1379 stainfo = r8712_get_stainfo(&padapter->stapriv,
1380 &prxattrib->ta[0]);
1381 if (stainfo != NULL) {
1382 if (IS_MCAST(prxattrib->ra)) {
1383 iv = pframe + prxattrib->hdrlen;
1384 idx = iv[3];
1385 prwskey = &psecuritypriv->XGrpKey[
1386 ((idx >> 6) & 0x3) - 1].skey[0];
1387 if (!psecuritypriv->binstallGrpkey)
1388 return _FAIL;
1389
1390 } else {
1391 prwskey = &stainfo->x_UncstKey.skey[0];
1392 }
1393 length = ((union recv_frame *)precvframe)->
1394 u.hdr.len - prxattrib->hdrlen -
1395 prxattrib->iv_len;
1396 aes_decipher(prwskey, prxattrib->hdrlen, pframe,
1397 length);
1398 } else {
1399 return _FAIL;
1400 }
1401 }
1402 return _SUCCESS;
1403}
1404
1405void r8712_use_tkipkey_handler(unsigned long data)
1406{
1407 struct _adapter *padapter = (struct _adapter *)data;
1408
1409 padapter->securitypriv.busetkipkey = true;
1410}
1411