Linux kernel & device driver programming

Cross-Referenced Linux and Device Driver Code

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