]> git.karo-electronics.de Git - mv-sheeva.git/blob - drivers/staging/rtl8192e/ieee80211/ieee80211_crypt_tkip.c
Merge git://git.kernel.org/pub/scm/linux/kernel/git/herbert/crypto-2.6
[mv-sheeva.git] / drivers / staging / rtl8192e / ieee80211 / ieee80211_crypt_tkip.c
1 /*
2  * Host AP crypt: host-based TKIP encryption implementation for Host AP driver
3  *
4  * Copyright (c) 2003-2004, Jouni Malinen <jkmaline@cc.hut.fi>
5  *
6  * This program is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License version 2 as
8  * published by the Free Software Foundation. See README and COPYING for
9  * more details.
10  */
11
12 //#include <linux/config.h>
13 #include <linux/version.h>
14 #include <linux/module.h>
15 #include <linux/init.h>
16 #include <linux/slab.h>
17 #include <linux/random.h>
18 #include <linux/skbuff.h>
19 #include <linux/netdevice.h>
20 #include <linux/if_ether.h>
21 #include <linux/if_arp.h>
22 #include <asm/string.h>
23
24 #include "ieee80211.h"
25
26
27 #if (LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0))
28 #include "rtl_crypto.h"
29 #else
30 #include <linux/crypto.h>
31 #endif
32 //#include <asm/scatterlist.h>
33 #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20)
34     #include <asm/scatterlist.h>
35 #else
36         #include <linux/scatterlist.h>
37 #endif
38
39 #include <linux/crc32.h>
40
41 MODULE_AUTHOR("Jouni Malinen");
42 MODULE_DESCRIPTION("Host AP crypt: TKIP");
43 MODULE_LICENSE("GPL");
44
45 #ifndef OPENSUSE_SLED
46 #define OPENSUSE_SLED 0
47 #endif
48
49 struct ieee80211_tkip_data {
50 #define TKIP_KEY_LEN 32
51         u8 key[TKIP_KEY_LEN];
52         int key_set;
53
54         u32 tx_iv32;
55         u16 tx_iv16;
56         u16 tx_ttak[5];
57         int tx_phase1_done;
58
59         u32 rx_iv32;
60         u16 rx_iv16;
61         u16 rx_ttak[5];
62         int rx_phase1_done;
63         u32 rx_iv32_new;
64         u16 rx_iv16_new;
65
66         u32 dot11RSNAStatsTKIPReplays;
67         u32 dot11RSNAStatsTKIPICVErrors;
68         u32 dot11RSNAStatsTKIPLocalMICFailures;
69
70         int key_idx;
71 #if((LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,21)) || (OPENSUSE_SLED))
72         struct crypto_blkcipher *rx_tfm_arc4;
73         struct crypto_hash *rx_tfm_michael;
74         struct crypto_blkcipher *tx_tfm_arc4;
75         struct crypto_hash *tx_tfm_michael;
76 #else
77         struct crypto_tfm *tx_tfm_arc4;
78         struct crypto_tfm *tx_tfm_michael;
79         struct crypto_tfm *rx_tfm_arc4;
80         struct crypto_tfm *rx_tfm_michael;
81 #endif
82         /* scratch buffers for virt_to_page() (crypto API) */
83         u8 rx_hdr[16], tx_hdr[16];
84 };
85
86 static void * ieee80211_tkip_init(int key_idx)
87 {
88         struct ieee80211_tkip_data *priv;
89
90         priv = kmalloc(sizeof(*priv), GFP_ATOMIC);
91         if (priv == NULL)
92                 goto fail;
93         memset(priv, 0, sizeof(*priv));
94         priv->key_idx = key_idx;
95 #if((LINUX_VERSION_CODE < KERNEL_VERSION(2,6,21)) && (!OPENSUSE_SLED))
96         priv->tx_tfm_arc4 = crypto_alloc_tfm("arc4", 0);
97         if (priv->tx_tfm_arc4 == NULL) {
98                 printk(KERN_DEBUG "ieee80211_crypt_tkip: could not allocate "
99                                 "crypto API arc4\n");
100                 goto fail;
101         }
102
103         priv->tx_tfm_michael = crypto_alloc_tfm("michael_mic", 0);
104         if (priv->tx_tfm_michael == NULL) {
105                 printk(KERN_DEBUG "ieee80211_crypt_tkip: could not allocate "
106                                 "crypto API michael_mic\n");
107                 goto fail;
108         }
109
110         priv->rx_tfm_arc4 = crypto_alloc_tfm("arc4", 0);
111         if (priv->rx_tfm_arc4 == NULL) {
112                 printk(KERN_DEBUG "ieee80211_crypt_tkip: could not allocate "
113                                 "crypto API arc4\n");
114                 goto fail;
115         }
116
117         priv->rx_tfm_michael = crypto_alloc_tfm("michael_mic", 0);
118         if (priv->rx_tfm_michael == NULL) {
119                 printk(KERN_DEBUG "ieee80211_crypt_tkip: could not allocate "
120                                 "crypto API michael_mic\n");
121                 goto fail;
122         }
123 #else
124         priv->tx_tfm_arc4 = crypto_alloc_blkcipher("ecb(arc4)", 0,
125                         CRYPTO_ALG_ASYNC);
126         if (IS_ERR(priv->tx_tfm_arc4)) {
127                 printk(KERN_DEBUG "ieee80211_crypt_tkip: could not allocate "
128                                 "crypto API arc4\n");
129                 priv->tx_tfm_arc4 = NULL;
130                 goto fail;
131         }
132
133         priv->tx_tfm_michael = crypto_alloc_hash("michael_mic", 0,
134                         CRYPTO_ALG_ASYNC);
135         if (IS_ERR(priv->tx_tfm_michael)) {
136                 printk(KERN_DEBUG "ieee80211_crypt_tkip: could not allocate "
137                                 "crypto API michael_mic\n");
138                 priv->tx_tfm_michael = NULL;
139                 goto fail;
140         }
141
142         priv->rx_tfm_arc4 = crypto_alloc_blkcipher("ecb(arc4)", 0,
143                         CRYPTO_ALG_ASYNC);
144         if (IS_ERR(priv->rx_tfm_arc4)) {
145                 printk(KERN_DEBUG "ieee80211_crypt_tkip: could not allocate "
146                                 "crypto API arc4\n");
147                 priv->rx_tfm_arc4 = NULL;
148                 goto fail;
149         }
150
151         priv->rx_tfm_michael = crypto_alloc_hash("michael_mic", 0,
152                         CRYPTO_ALG_ASYNC);
153         if (IS_ERR(priv->rx_tfm_michael)) {
154                 printk(KERN_DEBUG "ieee80211_crypt_tkip: could not allocate "
155                                 "crypto API michael_mic\n");
156                 priv->rx_tfm_michael = NULL;
157                 goto fail;
158         }
159 #endif
160         return priv;
161
162 fail:
163         if (priv) {
164 #if((LINUX_VERSION_CODE < KERNEL_VERSION(2,6,21)) && (!OPENSUSE_SLED))
165                 if (priv->tx_tfm_michael)
166                         crypto_free_tfm(priv->tx_tfm_michael);
167                 if (priv->tx_tfm_arc4)
168                         crypto_free_tfm(priv->tx_tfm_arc4);
169                 if (priv->rx_tfm_michael)
170                         crypto_free_tfm(priv->rx_tfm_michael);
171                 if (priv->rx_tfm_arc4)
172                         crypto_free_tfm(priv->rx_tfm_arc4);
173
174 #else
175                 if (priv->tx_tfm_michael)
176                         crypto_free_hash(priv->tx_tfm_michael);
177                 if (priv->tx_tfm_arc4)
178                         crypto_free_blkcipher(priv->tx_tfm_arc4);
179                 if (priv->rx_tfm_michael)
180                         crypto_free_hash(priv->rx_tfm_michael);
181                 if (priv->rx_tfm_arc4)
182                         crypto_free_blkcipher(priv->rx_tfm_arc4);
183 #endif
184                 kfree(priv);
185         }
186
187         return NULL;
188 }
189
190
191 static void ieee80211_tkip_deinit(void *priv)
192 {
193         struct ieee80211_tkip_data *_priv = priv;
194 #if((LINUX_VERSION_CODE < KERNEL_VERSION(2,6,21)) && (!OPENSUSE_SLED))
195         if (_priv->tx_tfm_michael)
196                 crypto_free_tfm(_priv->tx_tfm_michael);
197         if (_priv->tx_tfm_arc4)
198                 crypto_free_tfm(_priv->tx_tfm_arc4);
199         if (_priv->rx_tfm_michael)
200                 crypto_free_tfm(_priv->rx_tfm_michael);
201         if (_priv->rx_tfm_arc4)
202                 crypto_free_tfm(_priv->rx_tfm_arc4);
203 #else
204         if (_priv) {
205                 if (_priv->tx_tfm_michael)
206                         crypto_free_hash(_priv->tx_tfm_michael);
207                 if (_priv->tx_tfm_arc4)
208                         crypto_free_blkcipher(_priv->tx_tfm_arc4);
209                 if (_priv->rx_tfm_michael)
210                         crypto_free_hash(_priv->rx_tfm_michael);
211                 if (_priv->rx_tfm_arc4)
212                         crypto_free_blkcipher(_priv->rx_tfm_arc4);
213         }
214 #endif
215         kfree(priv);
216 }
217
218
219 static inline u16 RotR1(u16 val)
220 {
221         return (val >> 1) | (val << 15);
222 }
223
224
225 static inline u8 Lo8(u16 val)
226 {
227         return val & 0xff;
228 }
229
230
231 static inline u8 Hi8(u16 val)
232 {
233         return val >> 8;
234 }
235
236
237 static inline u16 Lo16(u32 val)
238 {
239         return val & 0xffff;
240 }
241
242
243 static inline u16 Hi16(u32 val)
244 {
245         return val >> 16;
246 }
247
248
249 static inline u16 Mk16(u8 hi, u8 lo)
250 {
251         return lo | (((u16) hi) << 8);
252 }
253
254
255 static inline u16 Mk16_le(u16 *v)
256 {
257         return le16_to_cpu(*v);
258 }
259
260
261 static const u16 Sbox[256] =
262 {
263         0xC6A5, 0xF884, 0xEE99, 0xF68D, 0xFF0D, 0xD6BD, 0xDEB1, 0x9154,
264         0x6050, 0x0203, 0xCEA9, 0x567D, 0xE719, 0xB562, 0x4DE6, 0xEC9A,
265         0x8F45, 0x1F9D, 0x8940, 0xFA87, 0xEF15, 0xB2EB, 0x8EC9, 0xFB0B,
266         0x41EC, 0xB367, 0x5FFD, 0x45EA, 0x23BF, 0x53F7, 0xE496, 0x9B5B,
267         0x75C2, 0xE11C, 0x3DAE, 0x4C6A, 0x6C5A, 0x7E41, 0xF502, 0x834F,
268         0x685C, 0x51F4, 0xD134, 0xF908, 0xE293, 0xAB73, 0x6253, 0x2A3F,
269         0x080C, 0x9552, 0x4665, 0x9D5E, 0x3028, 0x37A1, 0x0A0F, 0x2FB5,
270         0x0E09, 0x2436, 0x1B9B, 0xDF3D, 0xCD26, 0x4E69, 0x7FCD, 0xEA9F,
271         0x121B, 0x1D9E, 0x5874, 0x342E, 0x362D, 0xDCB2, 0xB4EE, 0x5BFB,
272         0xA4F6, 0x764D, 0xB761, 0x7DCE, 0x527B, 0xDD3E, 0x5E71, 0x1397,
273         0xA6F5, 0xB968, 0x0000, 0xC12C, 0x4060, 0xE31F, 0x79C8, 0xB6ED,
274         0xD4BE, 0x8D46, 0x67D9, 0x724B, 0x94DE, 0x98D4, 0xB0E8, 0x854A,
275         0xBB6B, 0xC52A, 0x4FE5, 0xED16, 0x86C5, 0x9AD7, 0x6655, 0x1194,
276         0x8ACF, 0xE910, 0x0406, 0xFE81, 0xA0F0, 0x7844, 0x25BA, 0x4BE3,
277         0xA2F3, 0x5DFE, 0x80C0, 0x058A, 0x3FAD, 0x21BC, 0x7048, 0xF104,
278         0x63DF, 0x77C1, 0xAF75, 0x4263, 0x2030, 0xE51A, 0xFD0E, 0xBF6D,
279         0x814C, 0x1814, 0x2635, 0xC32F, 0xBEE1, 0x35A2, 0x88CC, 0x2E39,
280         0x9357, 0x55F2, 0xFC82, 0x7A47, 0xC8AC, 0xBAE7, 0x322B, 0xE695,
281         0xC0A0, 0x1998, 0x9ED1, 0xA37F, 0x4466, 0x547E, 0x3BAB, 0x0B83,
282         0x8CCA, 0xC729, 0x6BD3, 0x283C, 0xA779, 0xBCE2, 0x161D, 0xAD76,
283         0xDB3B, 0x6456, 0x744E, 0x141E, 0x92DB, 0x0C0A, 0x486C, 0xB8E4,
284         0x9F5D, 0xBD6E, 0x43EF, 0xC4A6, 0x39A8, 0x31A4, 0xD337, 0xF28B,
285         0xD532, 0x8B43, 0x6E59, 0xDAB7, 0x018C, 0xB164, 0x9CD2, 0x49E0,
286         0xD8B4, 0xACFA, 0xF307, 0xCF25, 0xCAAF, 0xF48E, 0x47E9, 0x1018,
287         0x6FD5, 0xF088, 0x4A6F, 0x5C72, 0x3824, 0x57F1, 0x73C7, 0x9751,
288         0xCB23, 0xA17C, 0xE89C, 0x3E21, 0x96DD, 0x61DC, 0x0D86, 0x0F85,
289         0xE090, 0x7C42, 0x71C4, 0xCCAA, 0x90D8, 0x0605, 0xF701, 0x1C12,
290         0xC2A3, 0x6A5F, 0xAEF9, 0x69D0, 0x1791, 0x9958, 0x3A27, 0x27B9,
291         0xD938, 0xEB13, 0x2BB3, 0x2233, 0xD2BB, 0xA970, 0x0789, 0x33A7,
292         0x2DB6, 0x3C22, 0x1592, 0xC920, 0x8749, 0xAAFF, 0x5078, 0xA57A,
293         0x038F, 0x59F8, 0x0980, 0x1A17, 0x65DA, 0xD731, 0x84C6, 0xD0B8,
294         0x82C3, 0x29B0, 0x5A77, 0x1E11, 0x7BCB, 0xA8FC, 0x6DD6, 0x2C3A,
295 };
296
297
298 static inline u16 _S_(u16 v)
299 {
300         u16 t = Sbox[Hi8(v)];
301         return Sbox[Lo8(v)] ^ ((t << 8) | (t >> 8));
302 }
303
304
305 #define PHASE1_LOOP_COUNT 8
306
307
308 static void tkip_mixing_phase1(u16 *TTAK, const u8 *TK, const u8 *TA, u32 IV32)
309 {
310         int i, j;
311
312         /* Initialize the 80-bit TTAK from TSC (IV32) and TA[0..5] */
313         TTAK[0] = Lo16(IV32);
314         TTAK[1] = Hi16(IV32);
315         TTAK[2] = Mk16(TA[1], TA[0]);
316         TTAK[3] = Mk16(TA[3], TA[2]);
317         TTAK[4] = Mk16(TA[5], TA[4]);
318
319         for (i = 0; i < PHASE1_LOOP_COUNT; i++) {
320                 j = 2 * (i & 1);
321                 TTAK[0] += _S_(TTAK[4] ^ Mk16(TK[1 + j], TK[0 + j]));
322                 TTAK[1] += _S_(TTAK[0] ^ Mk16(TK[5 + j], TK[4 + j]));
323                 TTAK[2] += _S_(TTAK[1] ^ Mk16(TK[9 + j], TK[8 + j]));
324                 TTAK[3] += _S_(TTAK[2] ^ Mk16(TK[13 + j], TK[12 + j]));
325                 TTAK[4] += _S_(TTAK[3] ^ Mk16(TK[1 + j], TK[0 + j])) + i;
326         }
327 }
328
329
330 static void tkip_mixing_phase2(u8 *WEPSeed, const u8 *TK, const u16 *TTAK,
331                                u16 IV16)
332 {
333         /* Make temporary area overlap WEP seed so that the final copy can be
334          * avoided on little endian hosts. */
335         u16 *PPK = (u16 *) &WEPSeed[4];
336
337         /* Step 1 - make copy of TTAK and bring in TSC */
338         PPK[0] = TTAK[0];
339         PPK[1] = TTAK[1];
340         PPK[2] = TTAK[2];
341         PPK[3] = TTAK[3];
342         PPK[4] = TTAK[4];
343         PPK[5] = TTAK[4] + IV16;
344
345         /* Step 2 - 96-bit bijective mixing using S-box */
346         PPK[0] += _S_(PPK[5] ^ Mk16_le((u16 *) &TK[0]));
347         PPK[1] += _S_(PPK[0] ^ Mk16_le((u16 *) &TK[2]));
348         PPK[2] += _S_(PPK[1] ^ Mk16_le((u16 *) &TK[4]));
349         PPK[3] += _S_(PPK[2] ^ Mk16_le((u16 *) &TK[6]));
350         PPK[4] += _S_(PPK[3] ^ Mk16_le((u16 *) &TK[8]));
351         PPK[5] += _S_(PPK[4] ^ Mk16_le((u16 *) &TK[10]));
352
353         PPK[0] += RotR1(PPK[5] ^ Mk16_le((u16 *) &TK[12]));
354         PPK[1] += RotR1(PPK[0] ^ Mk16_le((u16 *) &TK[14]));
355         PPK[2] += RotR1(PPK[1]);
356         PPK[3] += RotR1(PPK[2]);
357         PPK[4] += RotR1(PPK[3]);
358         PPK[5] += RotR1(PPK[4]);
359
360         /* Step 3 - bring in last of TK bits, assign 24-bit WEP IV value
361          * WEPSeed[0..2] is transmitted as WEP IV */
362         WEPSeed[0] = Hi8(IV16);
363         WEPSeed[1] = (Hi8(IV16) | 0x20) & 0x7F;
364         WEPSeed[2] = Lo8(IV16);
365         WEPSeed[3] = Lo8((PPK[5] ^ Mk16_le((u16 *) &TK[0])) >> 1);
366
367 #ifdef __BIG_ENDIAN
368         {
369                 int i;
370                 for (i = 0; i < 6; i++)
371                         PPK[i] = (PPK[i] << 8) | (PPK[i] >> 8);
372         }
373 #endif
374 }
375
376
377 static int ieee80211_tkip_encrypt(struct sk_buff *skb, int hdr_len, void *priv)
378 {
379         struct ieee80211_tkip_data *tkey = priv;
380                 int len;
381         u8 *pos;
382         struct ieee80211_hdr_4addr *hdr;
383         cb_desc *tcb_desc = (cb_desc *)(skb->cb + MAX_DEV_ADDR_SIZE);
384
385         #if((LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,21)) || (OPENSUSE_SLED))
386         struct blkcipher_desc desc = {.tfm = tkey->tx_tfm_arc4};
387         int ret = 0;
388         #endif
389         u8 rc4key[16],  *icv;
390         u32 crc;
391         struct scatterlist sg;
392
393         if (skb_headroom(skb) < 8 || skb_tailroom(skb) < 4 ||
394             skb->len < hdr_len)
395                 return -1;
396
397         hdr = (struct ieee80211_hdr_4addr *) skb->data;
398
399 #if 0
400 printk("@@ tkey\n");
401 printk("%x|", ((u32*)tkey->key)[0]);
402 printk("%x|", ((u32*)tkey->key)[1]);
403 printk("%x|", ((u32*)tkey->key)[2]);
404 printk("%x|", ((u32*)tkey->key)[3]);
405 printk("%x|", ((u32*)tkey->key)[4]);
406 printk("%x|", ((u32*)tkey->key)[5]);
407 printk("%x|", ((u32*)tkey->key)[6]);
408 printk("%x\n", ((u32*)tkey->key)[7]);
409 #endif
410
411         if (!tcb_desc->bHwSec)
412         {
413                 if (!tkey->tx_phase1_done) {
414                         tkip_mixing_phase1(tkey->tx_ttak, tkey->key, hdr->addr2,
415                                         tkey->tx_iv32);
416                         tkey->tx_phase1_done = 1;
417                 }
418                 tkip_mixing_phase2(rc4key, tkey->key, tkey->tx_ttak, tkey->tx_iv16);
419         }
420         else
421         tkey->tx_phase1_done = 1;
422
423
424         len = skb->len - hdr_len;
425         pos = skb_push(skb, 8);
426         memmove(pos, pos + 8, hdr_len);
427         pos += hdr_len;
428
429         if (tcb_desc->bHwSec)
430         {
431                 *pos++ = Hi8(tkey->tx_iv16);
432                 *pos++ = (Hi8(tkey->tx_iv16) | 0x20) & 0x7F;
433                 *pos++ = Lo8(tkey->tx_iv16);
434         }
435         else
436         {
437                 *pos++ = rc4key[0];
438                 *pos++ = rc4key[1];
439                 *pos++ = rc4key[2];
440         }
441
442         *pos++ = (tkey->key_idx << 6) | (1 << 5) /* Ext IV included */;
443         *pos++ = tkey->tx_iv32 & 0xff;
444         *pos++ = (tkey->tx_iv32 >> 8) & 0xff;
445         *pos++ = (tkey->tx_iv32 >> 16) & 0xff;
446         *pos++ = (tkey->tx_iv32 >> 24) & 0xff;
447
448         if (!tcb_desc->bHwSec)
449         {
450                 icv = skb_put(skb, 4);
451 #if (LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0))
452                 crc = ~crc32_le(~0, pos, len);
453 #else
454                 crc = ~ether_crc_le(len, pos);
455 #endif
456                 icv[0] = crc;
457                 icv[1] = crc >> 8;
458                 icv[2] = crc >> 16;
459                 icv[3] = crc >> 24;
460 #if((LINUX_VERSION_CODE < KERNEL_VERSION(2,6,21)) && (!OPENSUSE_SLED))
461                 crypto_cipher_setkey(tkey->tx_tfm_arc4, rc4key, 16);
462                 sg.page = virt_to_page(pos);
463                 sg.offset = offset_in_page(pos);
464                 sg.length = len + 4;
465                 crypto_cipher_encrypt(tkey->tx_tfm_arc4, &sg, &sg, len + 4);
466 #else
467                 crypto_blkcipher_setkey(tkey->tx_tfm_arc4, rc4key, 16);
468 #if(LINUX_VERSION_CODE < KERNEL_VERSION(2,6,24))
469                 sg.page = virt_to_page(pos);
470                 sg.offset = offset_in_page(pos);
471                 sg.length = len + 4;
472 #else
473                 sg_init_one(&sg, pos, len+4);
474 #endif
475                 ret= crypto_blkcipher_encrypt(&desc, &sg, &sg, len + 4);
476 #endif
477
478         }
479
480         tkey->tx_iv16++;
481         if (tkey->tx_iv16 == 0) {
482                 tkey->tx_phase1_done = 0;
483                 tkey->tx_iv32++;
484         }
485
486         if (!tcb_desc->bHwSec)
487 #if((LINUX_VERSION_CODE < KERNEL_VERSION(2,6,21)) && (!OPENSUSE_SLED))
488                 return 0;
489         #else
490                 return ret;
491         #endif
492         else
493                 return 0;
494
495
496 }
497
498 static int ieee80211_tkip_decrypt(struct sk_buff *skb, int hdr_len, void *priv)
499 {
500         struct ieee80211_tkip_data *tkey = priv;
501         u8 keyidx, *pos;
502         u32 iv32;
503         u16 iv16;
504         struct ieee80211_hdr_4addr *hdr;
505         cb_desc *tcb_desc = (cb_desc *)(skb->cb + MAX_DEV_ADDR_SIZE);
506         #if((LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,21)) || (OPENSUSE_SLED))
507         struct blkcipher_desc desc = {.tfm = tkey->rx_tfm_arc4};
508         #endif
509         u8 rc4key[16];
510         u8 icv[4];
511         u32 crc;
512         struct scatterlist sg;
513         int plen;
514         if (skb->len < hdr_len + 8 + 4)
515                 return -1;
516
517         hdr = (struct ieee80211_hdr_4addr *) skb->data;
518         pos = skb->data + hdr_len;
519         keyidx = pos[3];
520         if (!(keyidx & (1 << 5))) {
521                 if (net_ratelimit()) {
522                         printk(KERN_DEBUG "TKIP: received packet without ExtIV"
523                                " flag from %pM\n", hdr->addr2);
524                 }
525                 return -2;
526         }
527         keyidx >>= 6;
528         if (tkey->key_idx != keyidx) {
529                 printk(KERN_DEBUG "TKIP: RX tkey->key_idx=%d frame "
530                        "keyidx=%d priv=%p\n", tkey->key_idx, keyidx, priv);
531                 return -6;
532         }
533         if (!tkey->key_set) {
534                 if (net_ratelimit()) {
535                         printk(KERN_DEBUG "TKIP: received packet from %pM"
536                                " with keyid=%d that does not have a configured"
537                                " key\n", hdr->addr2, keyidx);
538                 }
539                 return -3;
540         }
541         iv16 = (pos[0] << 8) | pos[2];
542         iv32 = pos[4] | (pos[5] << 8) | (pos[6] << 16) | (pos[7] << 24);
543         pos += 8;
544
545         if (!tcb_desc->bHwSec)
546         {
547                 if (iv32 < tkey->rx_iv32 ||
548                 (iv32 == tkey->rx_iv32 && iv16 <= tkey->rx_iv16)) {
549                         if (net_ratelimit()) {
550                                 printk(KERN_DEBUG "TKIP: replay detected: STA=%pM"
551                                 " previous TSC %08x%04x received TSC "
552                                 "%08x%04x\n", hdr->addr2,
553                                 tkey->rx_iv32, tkey->rx_iv16, iv32, iv16);
554                         }
555                         tkey->dot11RSNAStatsTKIPReplays++;
556                         return -4;
557                 }
558
559                 if (iv32 != tkey->rx_iv32 || !tkey->rx_phase1_done) {
560                         tkip_mixing_phase1(tkey->rx_ttak, tkey->key, hdr->addr2, iv32);
561                         tkey->rx_phase1_done = 1;
562                 }
563                 tkip_mixing_phase2(rc4key, tkey->key, tkey->rx_ttak, iv16);
564
565                 plen = skb->len - hdr_len - 12;
566
567 #if((LINUX_VERSION_CODE < KERNEL_VERSION(2,6,21)) && (!OPENSUSE_SLED))
568                 crypto_cipher_setkey(tkey->rx_tfm_arc4, rc4key, 16);
569                 sg.page = virt_to_page(pos);
570                 sg.offset = offset_in_page(pos);
571                 sg.length = plen + 4;
572                 crypto_cipher_decrypt(tkey->rx_tfm_arc4, &sg, &sg, plen + 4);
573 #else
574                 crypto_blkcipher_setkey(tkey->rx_tfm_arc4, rc4key, 16);
575 #if(LINUX_VERSION_CODE < KERNEL_VERSION(2,6,24))
576                 sg.page = virt_to_page(pos);
577                 sg.offset = offset_in_page(pos);
578                 sg.length = plen + 4;
579 #else
580                 sg_init_one(&sg, pos, plen+4);
581 #endif
582                 if (crypto_blkcipher_decrypt(&desc, &sg, &sg, plen + 4)) {
583                         if (net_ratelimit()) {
584                                 printk(KERN_DEBUG ": TKIP: failed to decrypt "
585                                                 "received packet from %pM\n",
586                                                 hdr->addr2);
587                         }
588                         return -7;
589                 }
590 #endif
591
592         #if (LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0))
593                 crc = ~crc32_le(~0, pos, plen);
594         #else
595                 crc = ~ether_crc_le(plen, pos);
596         #endif
597                 icv[0] = crc;
598                 icv[1] = crc >> 8;
599                 icv[2] = crc >> 16;
600                 icv[3] = crc >> 24;
601
602                 if (memcmp(icv, pos + plen, 4) != 0) {
603                         if (iv32 != tkey->rx_iv32) {
604                                 /* Previously cached Phase1 result was already lost, so
605                                 * it needs to be recalculated for the next packet. */
606                                 tkey->rx_phase1_done = 0;
607                         }
608                         if (net_ratelimit()) {
609                                 printk(KERN_DEBUG
610                                        "TKIP: ICV error detected: STA=%pM\n",
611                                        hdr->addr2);
612                         }
613                         tkey->dot11RSNAStatsTKIPICVErrors++;
614                         return -5;
615                 }
616
617         }
618
619         /* Update real counters only after Michael MIC verification has
620          * completed */
621         tkey->rx_iv32_new = iv32;
622         tkey->rx_iv16_new = iv16;
623
624         /* Remove IV and ICV */
625         memmove(skb->data + 8, skb->data, hdr_len);
626         skb_pull(skb, 8);
627         skb_trim(skb, skb->len - 4);
628
629 //john's test
630 #ifdef JOHN_DUMP
631 if( ((u16*)skb->data)[0] & 0x4000){
632         printk("@@ rx decrypted skb->data");
633         int i;
634         for(i=0;i<skb->len;i++){
635                 if( (i%24)==0 ) printk("\n");
636                 printk("%2x ", ((u8*)skb->data)[i]);
637         }
638         printk("\n");
639 }
640 #endif /*JOHN_DUMP*/
641         return keyidx;
642 }
643
644
645 #if((LINUX_VERSION_CODE < KERNEL_VERSION(2,6,21)) && (!OPENSUSE_SLED))
646 static int michael_mic(struct crypto_tfm * tfm_michael, u8 *key, u8 *hdr,
647                        u8 *data, size_t data_len, u8 *mic)
648 {
649         struct scatterlist sg[2];
650 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20)
651         struct hash_desc desc;
652         int ret = 0;
653 #endif
654
655         if (tfm_michael == NULL){
656                 printk(KERN_WARNING "michael_mic: tfm_michael == NULL\n");
657                 return -1;
658         }
659         sg[0].page = virt_to_page(hdr);
660         sg[0].offset = offset_in_page(hdr);
661         sg[0].length = 16;
662
663         sg[1].page = virt_to_page(data);
664         sg[1].offset = offset_in_page(data);
665         sg[1].length = data_len;
666
667
668 #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20)
669         crypto_digest_init(tfm_michael);
670         crypto_digest_setkey(tfm_michael, key, 8);
671         crypto_digest_update(tfm_michael, sg, 2);
672         crypto_digest_final(tfm_michael, mic);
673         return 0;
674 #else
675 if (crypto_hash_setkey(tkey->tfm_michael, key, 8))
676                 return -1;
677
678 //      return 0;
679               desc.tfm = tkey->tfm_michael;
680               desc.flags = 0;
681               ret = crypto_hash_digest(&desc, sg, data_len + 16, mic);
682               return ret;
683 #endif
684 }
685 #else
686 static int michael_mic(struct crypto_hash *tfm_michael, u8 * key, u8 * hdr,
687                        u8 * data, size_t data_len, u8 * mic)
688 {
689         struct hash_desc desc;
690         struct scatterlist sg[2];
691
692         if (tfm_michael == NULL) {
693                 printk(KERN_WARNING "michael_mic: tfm_michael == NULL\n");
694                 return -1;
695         }
696 #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,24)
697         sg[0].page = virt_to_page(hdr);
698         sg[0].offset = offset_in_page(hdr);
699         sg[0].length = 16;
700
701         sg[1].page = virt_to_page(data);
702         sg[1].offset = offset_in_page(data);
703         sg[1].length = data_len;
704 #else
705         sg_init_table(sg, 2);
706         sg_set_buf(&sg[0], hdr, 16);
707         sg_set_buf(&sg[1], data, data_len);
708 #endif
709
710         if (crypto_hash_setkey(tfm_michael, key, 8))
711                 return -1;
712
713         desc.tfm = tfm_michael;
714         desc.flags = 0;
715         return crypto_hash_digest(&desc, sg, data_len + 16, mic);
716 }
717 #endif
718
719
720
721 static void michael_mic_hdr(struct sk_buff *skb, u8 *hdr)
722 {
723         struct ieee80211_hdr_4addr *hdr11;
724
725         hdr11 = (struct ieee80211_hdr_4addr *) skb->data;
726         switch (le16_to_cpu(hdr11->frame_ctl) &
727                 (IEEE80211_FCTL_FROMDS | IEEE80211_FCTL_TODS)) {
728         case IEEE80211_FCTL_TODS:
729                 memcpy(hdr, hdr11->addr3, ETH_ALEN); /* DA */
730                 memcpy(hdr + ETH_ALEN, hdr11->addr2, ETH_ALEN); /* SA */
731                 break;
732         case IEEE80211_FCTL_FROMDS:
733                 memcpy(hdr, hdr11->addr1, ETH_ALEN); /* DA */
734                 memcpy(hdr + ETH_ALEN, hdr11->addr3, ETH_ALEN); /* SA */
735                 break;
736         case IEEE80211_FCTL_FROMDS | IEEE80211_FCTL_TODS:
737                 memcpy(hdr, hdr11->addr3, ETH_ALEN); /* DA */
738                 memcpy(hdr + ETH_ALEN, hdr11->addr4, ETH_ALEN); /* SA */
739                 break;
740         case 0:
741                 memcpy(hdr, hdr11->addr1, ETH_ALEN); /* DA */
742                 memcpy(hdr + ETH_ALEN, hdr11->addr2, ETH_ALEN); /* SA */
743                 break;
744         }
745
746         hdr[12] = 0; /* priority */
747
748         hdr[13] = hdr[14] = hdr[15] = 0; /* reserved */
749 }
750
751
752 static int ieee80211_michael_mic_add(struct sk_buff *skb, int hdr_len, void *priv)
753 {
754         struct ieee80211_tkip_data *tkey = priv;
755         u8 *pos;
756         struct ieee80211_hdr_4addr *hdr;
757
758         hdr = (struct ieee80211_hdr_4addr *) skb->data;
759
760         if (skb_tailroom(skb) < 8 || skb->len < hdr_len) {
761                 printk(KERN_DEBUG "Invalid packet for Michael MIC add "
762                        "(tailroom=%d hdr_len=%d skb->len=%d)\n",
763                        skb_tailroom(skb), hdr_len, skb->len);
764                 return -1;
765         }
766
767         michael_mic_hdr(skb, tkey->tx_hdr);
768
769         // { david, 2006.9.1
770         // fix the wpa process with wmm enabled.
771         if(IEEE80211_QOS_HAS_SEQ(le16_to_cpu(hdr->frame_ctl))) {
772                 tkey->tx_hdr[12] = *(skb->data + hdr_len - 2) & 0x07;
773         }
774         // }
775         pos = skb_put(skb, 8);
776 #if((LINUX_VERSION_CODE < KERNEL_VERSION(2,6,21)) && (!OPENSUSE_SLED))
777         if (michael_mic(tkey->tx_tfm_michael, &tkey->key[16], tkey->tx_hdr,
778                                 skb->data + hdr_len, skb->len - 8 - hdr_len, pos))
779 #else
780         if (michael_mic(tkey->tx_tfm_michael, &tkey->key[16], tkey->tx_hdr,
781                                 skb->data + hdr_len, skb->len - 8 - hdr_len, pos))
782 #endif
783                 return -1;
784
785         return 0;
786 }
787
788
789 #if WIRELESS_EXT >= 18
790 static void ieee80211_michael_mic_failure(struct net_device *dev,
791                                        struct ieee80211_hdr_4addr *hdr,
792                                        int keyidx)
793 {
794         union iwreq_data wrqu;
795         struct iw_michaelmicfailure ev;
796
797         /* TODO: needed parameters: count, keyid, key type, TSC */
798         memset(&ev, 0, sizeof(ev));
799         ev.flags = keyidx & IW_MICFAILURE_KEY_ID;
800         if (hdr->addr1[0] & 0x01)
801                 ev.flags |= IW_MICFAILURE_GROUP;
802         else
803                 ev.flags |= IW_MICFAILURE_PAIRWISE;
804         ev.src_addr.sa_family = ARPHRD_ETHER;
805         memcpy(ev.src_addr.sa_data, hdr->addr2, ETH_ALEN);
806         memset(&wrqu, 0, sizeof(wrqu));
807         wrqu.data.length = sizeof(ev);
808         wireless_send_event(dev, IWEVMICHAELMICFAILURE, &wrqu, (char *) &ev);
809 }
810 #elif WIRELESS_EXT >= 15
811 static void ieee80211_michael_mic_failure(struct net_device *dev,
812                                        struct ieee80211_hdr_4addr *hdr,
813                                        int keyidx)
814 {
815         union iwreq_data wrqu;
816         char buf[128];
817
818         /* TODO: needed parameters: count, keyid, key type, TSC */
819         sprintf(buf, "MLME-MICHAELMICFAILURE.indication(keyid=%d %scast addr="
820                 "%pM)", keyidx, hdr->addr1[0] & 0x01 ? "broad" : "uni",
821                 hdr->addr2);
822         memset(&wrqu, 0, sizeof(wrqu));
823         wrqu.data.length = strlen(buf);
824         wireless_send_event(dev, IWEVCUSTOM, &wrqu, buf);
825 }
826 #else /* WIRELESS_EXT >= 15 */
827 static inline void ieee80211_michael_mic_failure(struct net_device *dev,
828                                               struct ieee80211_hdr_4addr *hdr,
829                                               int keyidx)
830 {
831 }
832 #endif /* WIRELESS_EXT >= 15 */
833
834 static int ieee80211_michael_mic_verify(struct sk_buff *skb, int keyidx,
835                                      int hdr_len, void *priv)
836 {
837         struct ieee80211_tkip_data *tkey = priv;
838         u8 mic[8];
839         struct ieee80211_hdr_4addr *hdr;
840
841         hdr = (struct ieee80211_hdr_4addr *) skb->data;
842
843         if (!tkey->key_set)
844                 return -1;
845
846         michael_mic_hdr(skb, tkey->rx_hdr);
847         // { david, 2006.9.1
848         // fix the wpa process with wmm enabled.
849         if(IEEE80211_QOS_HAS_SEQ(le16_to_cpu(hdr->frame_ctl))) {
850                 tkey->rx_hdr[12] = *(skb->data + hdr_len - 2) & 0x07;
851         }
852         // }
853
854 #if((LINUX_VERSION_CODE < KERNEL_VERSION(2,6,21)) && (!OPENSUSE_SLED))
855         if (michael_mic(tkey->rx_tfm_michael, &tkey->key[24], tkey->rx_hdr,
856                                 skb->data + hdr_len, skb->len - 8 - hdr_len, mic))
857 #else
858         if (michael_mic(tkey->rx_tfm_michael, &tkey->key[24], tkey->rx_hdr,
859                                 skb->data + hdr_len, skb->len - 8 - hdr_len, mic))
860 #endif
861                 return -1;
862         if (memcmp(mic, skb->data + skb->len - 8, 8) != 0) {
863                 struct ieee80211_hdr_4addr *hdr;
864                 hdr = (struct ieee80211_hdr_4addr *) skb->data;
865                 printk(KERN_DEBUG "%s: Michael MIC verification failed for "
866                        "MSDU from %pM keyidx=%d\n",
867                        skb->dev ? skb->dev->name : "N/A", hdr->addr2,
868                        keyidx);
869                 if (skb->dev)
870                         ieee80211_michael_mic_failure(skb->dev, hdr, keyidx);
871                 tkey->dot11RSNAStatsTKIPLocalMICFailures++;
872                 return -1;
873         }
874
875         /* Update TSC counters for RX now that the packet verification has
876          * completed. */
877         tkey->rx_iv32 = tkey->rx_iv32_new;
878         tkey->rx_iv16 = tkey->rx_iv16_new;
879
880         skb_trim(skb, skb->len - 8);
881
882         return 0;
883 }
884
885
886 static int ieee80211_tkip_set_key(void *key, int len, u8 *seq, void *priv)
887 {
888         struct ieee80211_tkip_data *tkey = priv;
889         int keyidx;
890 #if((LINUX_VERSION_CODE < KERNEL_VERSION(2,6,21)) && (!OPENSUSE_SLED))
891         struct crypto_tfm *tfm = tkey->tx_tfm_michael;
892         struct crypto_tfm *tfm2 = tkey->tx_tfm_arc4;
893         struct crypto_tfm *tfm3 = tkey->rx_tfm_michael;
894         struct crypto_tfm *tfm4 = tkey->rx_tfm_arc4;
895 #else
896         struct crypto_hash *tfm = tkey->tx_tfm_michael;
897         struct crypto_blkcipher *tfm2 = tkey->tx_tfm_arc4;
898         struct crypto_hash *tfm3 = tkey->rx_tfm_michael;
899         struct crypto_blkcipher *tfm4 = tkey->rx_tfm_arc4;
900 #endif
901
902         keyidx = tkey->key_idx;
903         memset(tkey, 0, sizeof(*tkey));
904         tkey->key_idx = keyidx;
905 #if((LINUX_VERSION_CODE < KERNEL_VERSION(2,6,21)) && (!OPENSUSE_SLED))
906         tkey->tx_tfm_michael = tfm;
907         tkey->tx_tfm_arc4 = tfm2;
908         tkey->rx_tfm_michael = tfm3;
909         tkey->rx_tfm_arc4 = tfm4;
910 #else
911         tkey->tx_tfm_michael = tfm;
912         tkey->tx_tfm_arc4 = tfm2;
913         tkey->rx_tfm_michael = tfm3;
914         tkey->rx_tfm_arc4 = tfm4;
915 #endif
916
917         if (len == TKIP_KEY_LEN) {
918                 memcpy(tkey->key, key, TKIP_KEY_LEN);
919                 tkey->key_set = 1;
920                 tkey->tx_iv16 = 1; /* TSC is initialized to 1 */
921                 if (seq) {
922                         tkey->rx_iv32 = (seq[5] << 24) | (seq[4] << 16) |
923                                 (seq[3] << 8) | seq[2];
924                         tkey->rx_iv16 = (seq[1] << 8) | seq[0];
925                 }
926         } else if (len == 0)
927                 tkey->key_set = 0;
928         else
929                 return -1;
930
931         return 0;
932 }
933
934
935 static int ieee80211_tkip_get_key(void *key, int len, u8 *seq, void *priv)
936 {
937         struct ieee80211_tkip_data *tkey = priv;
938
939         if (len < TKIP_KEY_LEN)
940                 return -1;
941
942         if (!tkey->key_set)
943                 return 0;
944         memcpy(key, tkey->key, TKIP_KEY_LEN);
945
946         if (seq) {
947                 /* Return the sequence number of the last transmitted frame. */
948                 u16 iv16 = tkey->tx_iv16;
949                 u32 iv32 = tkey->tx_iv32;
950                 if (iv16 == 0)
951                         iv32--;
952                 iv16--;
953                 seq[0] = tkey->tx_iv16;
954                 seq[1] = tkey->tx_iv16 >> 8;
955                 seq[2] = tkey->tx_iv32;
956                 seq[3] = tkey->tx_iv32 >> 8;
957                 seq[4] = tkey->tx_iv32 >> 16;
958                 seq[5] = tkey->tx_iv32 >> 24;
959         }
960
961         return TKIP_KEY_LEN;
962 }
963
964
965 static char * ieee80211_tkip_print_stats(char *p, void *priv)
966 {
967         struct ieee80211_tkip_data *tkip = priv;
968         p += sprintf(p, "key[%d] alg=TKIP key_set=%d "
969                      "tx_pn=%02x%02x%02x%02x%02x%02x "
970                      "rx_pn=%02x%02x%02x%02x%02x%02x "
971                      "replays=%d icv_errors=%d local_mic_failures=%d\n",
972                      tkip->key_idx, tkip->key_set,
973                      (tkip->tx_iv32 >> 24) & 0xff,
974                      (tkip->tx_iv32 >> 16) & 0xff,
975                      (tkip->tx_iv32 >> 8) & 0xff,
976                      tkip->tx_iv32 & 0xff,
977                      (tkip->tx_iv16 >> 8) & 0xff,
978                      tkip->tx_iv16 & 0xff,
979                      (tkip->rx_iv32 >> 24) & 0xff,
980                      (tkip->rx_iv32 >> 16) & 0xff,
981                      (tkip->rx_iv32 >> 8) & 0xff,
982                      tkip->rx_iv32 & 0xff,
983                      (tkip->rx_iv16 >> 8) & 0xff,
984                      tkip->rx_iv16 & 0xff,
985                      tkip->dot11RSNAStatsTKIPReplays,
986                      tkip->dot11RSNAStatsTKIPICVErrors,
987                      tkip->dot11RSNAStatsTKIPLocalMICFailures);
988         return p;
989 }
990
991
992 static struct ieee80211_crypto_ops ieee80211_crypt_tkip = {
993         .name                   = "TKIP",
994         .init                   = ieee80211_tkip_init,
995         .deinit                 = ieee80211_tkip_deinit,
996         .encrypt_mpdu           = ieee80211_tkip_encrypt,
997         .decrypt_mpdu           = ieee80211_tkip_decrypt,
998         .encrypt_msdu           = ieee80211_michael_mic_add,
999         .decrypt_msdu           = ieee80211_michael_mic_verify,
1000         .set_key                = ieee80211_tkip_set_key,
1001         .get_key                = ieee80211_tkip_get_key,
1002         .print_stats            = ieee80211_tkip_print_stats,
1003         .extra_prefix_len       = 4 + 4, /* IV + ExtIV */
1004         .extra_postfix_len      = 8 + 4, /* MIC + ICV */
1005         .owner                  = THIS_MODULE,
1006 };
1007
1008
1009 int __init ieee80211_crypto_tkip_init(void)
1010 {
1011         return ieee80211_register_crypto_ops(&ieee80211_crypt_tkip);
1012 }
1013
1014
1015 void ieee80211_crypto_tkip_exit(void)
1016 {
1017         ieee80211_unregister_crypto_ops(&ieee80211_crypt_tkip);
1018 }
1019
1020 void ieee80211_tkip_null(void)
1021 {
1022 //    printk("============>%s()\n", __FUNCTION__);
1023         return;
1024 }
1025 #if (LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0))
1026 //EXPORT_SYMBOL(ieee80211_tkip_null);
1027 #else
1028 EXPORT_SYMBOL_NOVERS(ieee80211_tkip_null);
1029 #endif
1030
1031 //module_init(ieee80211_crypto_tkip_init);
1032 //module_exit(ieee80211_crypto_tkip_exit);