2 * Host AP crypt: host-based TKIP encryption implementation for Host AP driver
4 * Copyright (c) 2003-2004, Jouni Malinen <jkmaline@cc.hut.fi>
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
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>
24 #include "ieee80211.h"
25 #if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,20))
26 //#include "crypto_compat.h"
30 #if (LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0))
31 #include "rtl_crypto.h"
33 #include <linux/crypto.h>
35 //#include <asm/scatterlist.h>
36 #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20)
37 #include <asm/scatterlist.h>
39 #include <linux/scatterlist.h>
42 #include <linux/crc32.h>
44 MODULE_AUTHOR("Jouni Malinen");
45 MODULE_DESCRIPTION("Host AP crypt: TKIP");
46 MODULE_LICENSE("GPL");
49 #define OPENSUSE_SLED 0
52 struct ieee80211_tkip_data {
53 #define TKIP_KEY_LEN 32
69 u32 dot11RSNAStatsTKIPReplays;
70 u32 dot11RSNAStatsTKIPICVErrors;
71 u32 dot11RSNAStatsTKIPLocalMICFailures;
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;
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;
85 /* scratch buffers for virt_to_page() (crypto API) */
86 u8 rx_hdr[16], tx_hdr[16];
89 static void * ieee80211_tkip_init(int key_idx)
91 struct ieee80211_tkip_data *priv;
93 priv = kmalloc(sizeof(*priv), GFP_ATOMIC);
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");
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");
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");
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");
127 priv->tx_tfm_arc4 = crypto_alloc_blkcipher("ecb(arc4)", 0,
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;
136 priv->tx_tfm_michael = crypto_alloc_hash("michael_mic", 0,
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;
145 priv->rx_tfm_arc4 = crypto_alloc_blkcipher("ecb(arc4)", 0,
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;
154 priv->rx_tfm_michael = crypto_alloc_hash("michael_mic", 0,
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;
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);
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);
194 static void ieee80211_tkip_deinit(void *priv)
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);
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);
222 static inline u16 RotR1(u16 val)
224 return (val >> 1) | (val << 15);
228 static inline u8 Lo8(u16 val)
234 static inline u8 Hi8(u16 val)
240 static inline u16 Lo16(u32 val)
246 static inline u16 Hi16(u32 val)
252 static inline u16 Mk16(u8 hi, u8 lo)
254 return lo | (((u16) hi) << 8);
258 static inline u16 Mk16_le(u16 *v)
260 return le16_to_cpu(*v);
264 static const u16 Sbox[256] =
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,
301 static inline u16 _S_(u16 v)
303 u16 t = Sbox[Hi8(v)];
304 return Sbox[Lo8(v)] ^ ((t << 8) | (t >> 8));
308 #define PHASE1_LOOP_COUNT 8
311 static void tkip_mixing_phase1(u16 *TTAK, const u8 *TK, const u8 *TA, u32 IV32)
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]);
322 for (i = 0; i < PHASE1_LOOP_COUNT; i++) {
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;
333 static void tkip_mixing_phase2(u8 *WEPSeed, const u8 *TK, const u16 *TTAK,
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];
340 /* Step 1 - make copy of TTAK and bring in TSC */
346 PPK[5] = TTAK[4] + IV16;
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]));
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]);
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);
373 for (i = 0; i < 6; i++)
374 PPK[i] = (PPK[i] << 8) | (PPK[i] >> 8);
380 static int ieee80211_tkip_encrypt(struct sk_buff *skb, int hdr_len, void *priv)
382 struct ieee80211_tkip_data *tkey = priv;
385 struct ieee80211_hdr_4addr *hdr;
386 cb_desc *tcb_desc = (cb_desc *)(skb->cb + MAX_DEV_ADDR_SIZE);
388 #if((LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,21)) || (OPENSUSE_SLED))
389 struct blkcipher_desc desc = {.tfm = tkey->tx_tfm_arc4};
394 struct scatterlist sg;
396 if (skb_headroom(skb) < 8 || skb_tailroom(skb) < 4 ||
400 hdr = (struct ieee80211_hdr_4addr *) skb->data;
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]);
414 if (!tcb_desc->bHwSec)
416 if (!tkey->tx_phase1_done) {
417 tkip_mixing_phase1(tkey->tx_ttak, tkey->key, hdr->addr2,
419 tkey->tx_phase1_done = 1;
421 tkip_mixing_phase2(rc4key, tkey->key, tkey->tx_ttak, tkey->tx_iv16);
424 tkey->tx_phase1_done = 1;
427 len = skb->len - hdr_len;
428 pos = skb_push(skb, 8);
429 memmove(pos, pos + 8, hdr_len);
432 if (tcb_desc->bHwSec)
434 *pos++ = Hi8(tkey->tx_iv16);
435 *pos++ = (Hi8(tkey->tx_iv16) | 0x20) & 0x7F;
436 *pos++ = Lo8(tkey->tx_iv16);
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;
451 if (!tcb_desc->bHwSec)
453 icv = skb_put(skb, 4);
454 #if (LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0))
455 crc = ~crc32_le(~0, pos, len);
457 crc = ~ether_crc_le(len, pos);
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);
468 crypto_cipher_encrypt(tkey->tx_tfm_arc4, &sg, &sg, len + 4);
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);
476 sg_init_one(&sg, pos, len+4);
478 ret= crypto_blkcipher_encrypt(&desc, &sg, &sg, len + 4);
484 if (tkey->tx_iv16 == 0) {
485 tkey->tx_phase1_done = 0;
489 if (!tcb_desc->bHwSec)
490 #if((LINUX_VERSION_CODE < KERNEL_VERSION(2,6,21)) && (!OPENSUSE_SLED))
501 static int ieee80211_tkip_decrypt(struct sk_buff *skb, int hdr_len, void *priv)
503 struct ieee80211_tkip_data *tkey = priv;
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};
515 struct scatterlist sg;
517 if (skb->len < hdr_len + 8 + 4)
520 hdr = (struct ieee80211_hdr_4addr *) skb->data;
521 pos = skb->data + hdr_len;
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));
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);
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);
544 iv16 = (pos[0] << 8) | pos[2];
545 iv32 = pos[4] | (pos[5] << 8) | (pos[6] << 16) | (pos[7] << 24);
548 if (!tcb_desc->bHwSec)
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);
558 tkey->dot11RSNAStatsTKIPReplays++;
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;
566 tkip_mixing_phase2(rc4key, tkey->key, tkey->rx_ttak, iv16);
568 plen = skb->len - hdr_len - 12;
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);
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;
583 sg_init_one(&sg, pos, plen+4);
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));
595 #if (LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0))
596 crc = ~crc32_le(~0, pos, plen);
598 crc = ~ether_crc_le(plen, pos);
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;
611 if (net_ratelimit()) {
612 printk(KERN_DEBUG "TKIP: ICV error detected: STA="
613 MAC_FMT "\n", MAC_ARG(hdr->addr2));
615 tkey->dot11RSNAStatsTKIPICVErrors++;
621 /* Update real counters only after Michael MIC verification has
623 tkey->rx_iv32_new = iv32;
624 tkey->rx_iv16_new = iv16;
626 /* Remove IV and ICV */
627 memmove(skb->data + 8, skb->data, hdr_len);
629 skb_trim(skb, skb->len - 4);
633 if( ((u16*)skb->data)[0] & 0x4000){
634 printk("@@ rx decrypted skb->data");
636 for(i=0;i<skb->len;i++){
637 if( (i%24)==0 ) printk("\n");
638 printk("%2x ", ((u8*)skb->data)[i]);
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)
651 struct scatterlist sg[2];
652 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20)
653 struct hash_desc desc;
657 if (tfm_michael == NULL){
658 printk(KERN_WARNING "michael_mic: tfm_michael == NULL\n");
661 sg[0].page = virt_to_page(hdr);
662 sg[0].offset = offset_in_page(hdr);
665 sg[1].page = virt_to_page(data);
666 sg[1].offset = offset_in_page(data);
667 sg[1].length = data_len;
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);
677 if (crypto_hash_setkey(tkey->tfm_michael, key, 8))
681 desc.tfm = tkey->tfm_michael;
683 ret = crypto_hash_digest(&desc, sg, data_len + 16, mic);
688 static int michael_mic(struct crypto_hash *tfm_michael, u8 * key, u8 * hdr,
689 u8 * data, size_t data_len, u8 * mic)
691 struct hash_desc desc;
692 struct scatterlist sg[2];
694 if (tfm_michael == NULL) {
695 printk(KERN_WARNING "michael_mic: tfm_michael == NULL\n");
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);
703 sg[1].page = virt_to_page(data);
704 sg[1].offset = offset_in_page(data);
705 sg[1].length = data_len;
707 sg_init_table(sg, 2);
708 sg_set_buf(&sg[0], hdr, 16);
709 sg_set_buf(&sg[1], data, data_len);
712 if (crypto_hash_setkey(tfm_michael, key, 8))
715 desc.tfm = tfm_michael;
717 return crypto_hash_digest(&desc, sg, data_len + 16, mic);
723 static void michael_mic_hdr(struct sk_buff *skb, u8 *hdr)
725 struct ieee80211_hdr_4addr *hdr11;
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 */
734 case IEEE80211_FCTL_FROMDS:
735 memcpy(hdr, hdr11->addr1, ETH_ALEN); /* DA */
736 memcpy(hdr + ETH_ALEN, hdr11->addr3, ETH_ALEN); /* SA */
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 */
743 memcpy(hdr, hdr11->addr1, ETH_ALEN); /* DA */
744 memcpy(hdr + ETH_ALEN, hdr11->addr2, ETH_ALEN); /* SA */
748 hdr[12] = 0; /* priority */
750 hdr[13] = hdr[14] = hdr[15] = 0; /* reserved */
754 static int ieee80211_michael_mic_add(struct sk_buff *skb, int hdr_len, void *priv)
756 struct ieee80211_tkip_data *tkey = priv;
758 struct ieee80211_hdr_4addr *hdr;
760 hdr = (struct ieee80211_hdr_4addr *) skb->data;
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);
769 michael_mic_hdr(skb, tkey->tx_hdr);
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;
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))
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))
791 #if WIRELESS_EXT >= 18
792 static void ieee80211_michael_mic_failure(struct net_device *dev,
793 struct ieee80211_hdr_4addr *hdr,
796 union iwreq_data wrqu;
797 struct iw_michaelmicfailure ev;
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;
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);
812 #elif WIRELESS_EXT >= 15
813 static void ieee80211_michael_mic_failure(struct net_device *dev,
814 struct ieee80211_hdr_4addr *hdr,
817 union iwreq_data wrqu;
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);
828 #else /* WIRELESS_EXT >= 15 */
829 static inline void ieee80211_michael_mic_failure(struct net_device *dev,
830 struct ieee80211_hdr_4addr *hdr,
834 #endif /* WIRELESS_EXT >= 15 */
836 static int ieee80211_michael_mic_verify(struct sk_buff *skb, int keyidx,
837 int hdr_len, void *priv)
839 struct ieee80211_tkip_data *tkey = priv;
841 struct ieee80211_hdr_4addr *hdr;
843 hdr = (struct ieee80211_hdr_4addr *) skb->data;
848 michael_mic_hdr(skb, tkey->rx_hdr);
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;
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))
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))
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),
872 ieee80211_michael_mic_failure(skb->dev, hdr, keyidx);
873 tkey->dot11RSNAStatsTKIPLocalMICFailures++;
877 /* Update TSC counters for RX now that the packet verification has
879 tkey->rx_iv32 = tkey->rx_iv32_new;
880 tkey->rx_iv16 = tkey->rx_iv16_new;
882 skb_trim(skb, skb->len - 8);
888 static int ieee80211_tkip_set_key(void *key, int len, u8 *seq, void *priv)
890 struct ieee80211_tkip_data *tkey = priv;
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;
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;
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;
913 tkey->tx_tfm_michael = tfm;
914 tkey->tx_tfm_arc4 = tfm2;
915 tkey->rx_tfm_michael = tfm3;
916 tkey->rx_tfm_arc4 = tfm4;
919 if (len == TKIP_KEY_LEN) {
920 memcpy(tkey->key, key, TKIP_KEY_LEN);
922 tkey->tx_iv16 = 1; /* TSC is initialized to 1 */
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];
937 static int ieee80211_tkip_get_key(void *key, int len, u8 *seq, void *priv)
939 struct ieee80211_tkip_data *tkey = priv;
941 if (len < TKIP_KEY_LEN)
946 memcpy(key, tkey->key, TKIP_KEY_LEN);
949 /* Return the sequence number of the last transmitted frame. */
950 u16 iv16 = tkey->tx_iv16;
951 u32 iv32 = tkey->tx_iv32;
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;
967 static char * ieee80211_tkip_print_stats(char *p, void *priv)
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);
994 static struct ieee80211_crypto_ops ieee80211_crypt_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,
1011 static int __init ieee80211_crypto_tkip_init(void)
1013 return ieee80211_register_crypto_ops(&ieee80211_crypt_tkip);
1017 static void __exit ieee80211_crypto_tkip_exit(void)
1019 ieee80211_unregister_crypto_ops(&ieee80211_crypt_tkip);
1022 void ieee80211_tkip_null(void)
1024 // printk("============>%s()\n", __FUNCTION__);
1027 #if (LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0))
1028 EXPORT_SYMBOL(ieee80211_tkip_null);
1030 EXPORT_SYMBOL_NOVERS(ieee80211_tkip_null);
1033 module_init(ieee80211_crypto_tkip_init);
1034 module_exit(ieee80211_crypto_tkip_exit);