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