ieee80211_crypt_tkip.c revision 8fc8598e61f6f384f3eaf1d9b09500c12af47b37
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
44MODULE_AUTHOR("Jouni Malinen");
45MODULE_DESCRIPTION("Host AP crypt: TKIP");
46MODULE_LICENSE("GPL");
47
48#ifndef OPENSUSE_SLED
49#define OPENSUSE_SLED 0
50#endif
51
52struct 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
89static 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
165fail:
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
194static 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
222static inline u16 RotR1(u16 val)
223{
224	return (val >> 1) | (val << 15);
225}
226
227
228static inline u8 Lo8(u16 val)
229{
230	return val & 0xff;
231}
232
233
234static inline u8 Hi8(u16 val)
235{
236	return val >> 8;
237}
238
239
240static inline u16 Lo16(u32 val)
241{
242	return val & 0xffff;
243}
244
245
246static inline u16 Hi16(u32 val)
247{
248	return val >> 16;
249}
250
251
252static inline u16 Mk16(u8 hi, u8 lo)
253{
254	return lo | (((u16) hi) << 8);
255}
256
257
258static inline u16 Mk16_le(u16 *v)
259{
260	return le16_to_cpu(*v);
261}
262
263
264static 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
301static 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
311static 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
333static 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
380static 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
403printk("@@ tkey\n");
404printk("%x|", ((u32*)tkey->key)[0]);
405printk("%x|", ((u32*)tkey->key)[1]);
406printk("%x|", ((u32*)tkey->key)[2]);
407printk("%x|", ((u32*)tkey->key)[3]);
408printk("%x|", ((u32*)tkey->key)[4]);
409printk("%x|", ((u32*)tkey->key)[5]);
410printk("%x|", ((u32*)tkey->key)[6]);
411printk("%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
501static 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
633if( ((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))
648static 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
677if (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
688static 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
723static 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
754static 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
792static 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
813static 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 */
829static 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
836static 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
888static 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
937static 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
967static 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
994static 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
1011static int __init ieee80211_crypto_tkip_init(void)
1012{
1013	return ieee80211_register_crypto_ops(&ieee80211_crypt_tkip);
1014}
1015
1016
1017static void __exit ieee80211_crypto_tkip_exit(void)
1018{
1019	ieee80211_unregister_crypto_ops(&ieee80211_crypt_tkip);
1020}
1021
1022void ieee80211_tkip_null(void)
1023{
1024//    printk("============>%s()\n", __FUNCTION__);
1025        return;
1026}
1027#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0))
1028EXPORT_SYMBOL(ieee80211_tkip_null);
1029#else
1030EXPORT_SYMBOL_NOVERS(ieee80211_tkip_null);
1031#endif
1032
1033module_init(ieee80211_crypto_tkip_init);
1034module_exit(ieee80211_crypto_tkip_exit);
1035