Staging: Added Realtek rtl8192u driver to staging
[linux-2.6-block.git] / drivers / staging / rtl8192u / ieee80211 / ieee80211_crypt_tkip.c
CommitLineData
8fc8598e
JC
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);