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