aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/hostap/hostap_crypt_tkip.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/wireless/hostap/hostap_crypt_tkip.c')
-rw-r--r--drivers/net/wireless/hostap/hostap_crypt_tkip.c697
1 files changed, 0 insertions, 697 deletions
diff --git a/drivers/net/wireless/hostap/hostap_crypt_tkip.c b/drivers/net/wireless/hostap/hostap_crypt_tkip.c
deleted file mode 100644
index fcf1a014f4ac..000000000000
--- a/drivers/net/wireless/hostap/hostap_crypt_tkip.c
+++ /dev/null
@@ -1,697 +0,0 @@
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 <linux/wireless.h>
23#include <net/iw_handler.h>
24#include <asm/string.h>
25
26#include "hostap_crypt.h"
27#include "hostap_wlan.h"
28#include "hostap_80211.h"
29#include "hostap_config.h"
30
31#ifndef CONFIG_CRYPTO
32#error CONFIG_CRYPTO is required to build this module.
33#endif
34#include <linux/crypto.h>
35#include <asm/scatterlist.h>
36#include <linux/crc32.h>
37
38MODULE_AUTHOR("Jouni Malinen");
39MODULE_DESCRIPTION("Host AP crypt: TKIP");
40MODULE_LICENSE("GPL");
41MODULE_VERSION(PRISM2_VERSION);
42
43
44struct hostap_tkip_data {
45#define TKIP_KEY_LEN 32
46 u8 key[TKIP_KEY_LEN];
47 int key_set;
48
49 u32 tx_iv32;
50 u16 tx_iv16;
51 u16 tx_ttak[5];
52 int tx_phase1_done;
53
54 u32 rx_iv32;
55 u16 rx_iv16;
56 u16 rx_ttak[5];
57 int rx_phase1_done;
58 u32 rx_iv32_new;
59 u16 rx_iv16_new;
60
61 u32 dot11RSNAStatsTKIPReplays;
62 u32 dot11RSNAStatsTKIPICVErrors;
63 u32 dot11RSNAStatsTKIPLocalMICFailures;
64
65 int key_idx;
66
67 struct crypto_tfm *tfm_arc4;
68 struct crypto_tfm *tfm_michael;
69
70 /* scratch buffers for virt_to_page() (crypto API) */
71 u8 rx_hdr[16], tx_hdr[16];
72};
73
74
75static void * hostap_tkip_init(int key_idx)
76{
77 struct hostap_tkip_data *priv;
78
79 if (!try_module_get(THIS_MODULE))
80 return NULL;
81
82 priv = (struct hostap_tkip_data *) kmalloc(sizeof(*priv), GFP_ATOMIC);
83 if (priv == NULL)
84 goto fail;
85 memset(priv, 0, sizeof(*priv));
86 priv->key_idx = key_idx;
87
88 priv->tfm_arc4 = crypto_alloc_tfm("arc4", 0);
89 if (priv->tfm_arc4 == NULL) {
90 printk(KERN_DEBUG "hostap_crypt_tkip: could not allocate "
91 "crypto API arc4\n");
92 goto fail;
93 }
94
95 priv->tfm_michael = crypto_alloc_tfm("michael_mic", 0);
96 if (priv->tfm_michael == NULL) {
97 printk(KERN_DEBUG "hostap_crypt_tkip: could not allocate "
98 "crypto API michael_mic\n");
99 goto fail;
100 }
101
102 return priv;
103
104fail:
105 if (priv) {
106 if (priv->tfm_michael)
107 crypto_free_tfm(priv->tfm_michael);
108 if (priv->tfm_arc4)
109 crypto_free_tfm(priv->tfm_arc4);
110 kfree(priv);
111 }
112 module_put(THIS_MODULE);
113 return NULL;
114}
115
116
117static void hostap_tkip_deinit(void *priv)
118{
119 struct hostap_tkip_data *_priv = priv;
120 if (_priv && _priv->tfm_michael)
121 crypto_free_tfm(_priv->tfm_michael);
122 if (_priv && _priv->tfm_arc4)
123 crypto_free_tfm(_priv->tfm_arc4);
124 kfree(priv);
125 module_put(THIS_MODULE);
126}
127
128
129static inline u16 RotR1(u16 val)
130{
131 return (val >> 1) | (val << 15);
132}
133
134
135static inline u8 Lo8(u16 val)
136{
137 return val & 0xff;
138}
139
140
141static inline u8 Hi8(u16 val)
142{
143 return val >> 8;
144}
145
146
147static inline u16 Lo16(u32 val)
148{
149 return val & 0xffff;
150}
151
152
153static inline u16 Hi16(u32 val)
154{
155 return val >> 16;
156}
157
158
159static inline u16 Mk16(u8 hi, u8 lo)
160{
161 return lo | (((u16) hi) << 8);
162}
163
164
165static inline u16 Mk16_le(u16 *v)
166{
167 return le16_to_cpu(*v);
168}
169
170
171static const u16 Sbox[256] =
172{
173 0xC6A5, 0xF884, 0xEE99, 0xF68D, 0xFF0D, 0xD6BD, 0xDEB1, 0x9154,
174 0x6050, 0x0203, 0xCEA9, 0x567D, 0xE719, 0xB562, 0x4DE6, 0xEC9A,
175 0x8F45, 0x1F9D, 0x8940, 0xFA87, 0xEF15, 0xB2EB, 0x8EC9, 0xFB0B,
176 0x41EC, 0xB367, 0x5FFD, 0x45EA, 0x23BF, 0x53F7, 0xE496, 0x9B5B,
177 0x75C2, 0xE11C, 0x3DAE, 0x4C6A, 0x6C5A, 0x7E41, 0xF502, 0x834F,
178 0x685C, 0x51F4, 0xD134, 0xF908, 0xE293, 0xAB73, 0x6253, 0x2A3F,
179 0x080C, 0x9552, 0x4665, 0x9D5E, 0x3028, 0x37A1, 0x0A0F, 0x2FB5,
180 0x0E09, 0x2436, 0x1B9B, 0xDF3D, 0xCD26, 0x4E69, 0x7FCD, 0xEA9F,
181 0x121B, 0x1D9E, 0x5874, 0x342E, 0x362D, 0xDCB2, 0xB4EE, 0x5BFB,
182 0xA4F6, 0x764D, 0xB761, 0x7DCE, 0x527B, 0xDD3E, 0x5E71, 0x1397,
183 0xA6F5, 0xB968, 0x0000, 0xC12C, 0x4060, 0xE31F, 0x79C8, 0xB6ED,
184 0xD4BE, 0x8D46, 0x67D9, 0x724B, 0x94DE, 0x98D4, 0xB0E8, 0x854A,
185 0xBB6B, 0xC52A, 0x4FE5, 0xED16, 0x86C5, 0x9AD7, 0x6655, 0x1194,
186 0x8ACF, 0xE910, 0x0406, 0xFE81, 0xA0F0, 0x7844, 0x25BA, 0x4BE3,
187 0xA2F3, 0x5DFE, 0x80C0, 0x058A, 0x3FAD, 0x21BC, 0x7048, 0xF104,
188 0x63DF, 0x77C1, 0xAF75, 0x4263, 0x2030, 0xE51A, 0xFD0E, 0xBF6D,
189 0x814C, 0x1814, 0x2635, 0xC32F, 0xBEE1, 0x35A2, 0x88CC, 0x2E39,
190 0x9357, 0x55F2, 0xFC82, 0x7A47, 0xC8AC, 0xBAE7, 0x322B, 0xE695,
191 0xC0A0, 0x1998, 0x9ED1, 0xA37F, 0x4466, 0x547E, 0x3BAB, 0x0B83,
192 0x8CCA, 0xC729, 0x6BD3, 0x283C, 0xA779, 0xBCE2, 0x161D, 0xAD76,
193 0xDB3B, 0x6456, 0x744E, 0x141E, 0x92DB, 0x0C0A, 0x486C, 0xB8E4,
194 0x9F5D, 0xBD6E, 0x43EF, 0xC4A6, 0x39A8, 0x31A4, 0xD337, 0xF28B,
195 0xD532, 0x8B43, 0x6E59, 0xDAB7, 0x018C, 0xB164, 0x9CD2, 0x49E0,
196 0xD8B4, 0xACFA, 0xF307, 0xCF25, 0xCAAF, 0xF48E, 0x47E9, 0x1018,
197 0x6FD5, 0xF088, 0x4A6F, 0x5C72, 0x3824, 0x57F1, 0x73C7, 0x9751,
198 0xCB23, 0xA17C, 0xE89C, 0x3E21, 0x96DD, 0x61DC, 0x0D86, 0x0F85,
199 0xE090, 0x7C42, 0x71C4, 0xCCAA, 0x90D8, 0x0605, 0xF701, 0x1C12,
200 0xC2A3, 0x6A5F, 0xAEF9, 0x69D0, 0x1791, 0x9958, 0x3A27, 0x27B9,
201 0xD938, 0xEB13, 0x2BB3, 0x2233, 0xD2BB, 0xA970, 0x0789, 0x33A7,
202 0x2DB6, 0x3C22, 0x1592, 0xC920, 0x8749, 0xAAFF, 0x5078, 0xA57A,
203 0x038F, 0x59F8, 0x0980, 0x1A17, 0x65DA, 0xD731, 0x84C6, 0xD0B8,
204 0x82C3, 0x29B0, 0x5A77, 0x1E11, 0x7BCB, 0xA8FC, 0x6DD6, 0x2C3A,
205};
206
207
208static inline u16 _S_(u16 v)
209{
210 u16 t = Sbox[Hi8(v)];
211 return Sbox[Lo8(v)] ^ ((t << 8) | (t >> 8));
212}
213
214
215#define PHASE1_LOOP_COUNT 8
216
217static void tkip_mixing_phase1(u16 *TTAK, const u8 *TK, const u8 *TA, u32 IV32)
218{
219 int i, j;
220
221 /* Initialize the 80-bit TTAK from TSC (IV32) and TA[0..5] */
222 TTAK[0] = Lo16(IV32);
223 TTAK[1] = Hi16(IV32);
224 TTAK[2] = Mk16(TA[1], TA[0]);
225 TTAK[3] = Mk16(TA[3], TA[2]);
226 TTAK[4] = Mk16(TA[5], TA[4]);
227
228 for (i = 0; i < PHASE1_LOOP_COUNT; i++) {
229 j = 2 * (i & 1);
230 TTAK[0] += _S_(TTAK[4] ^ Mk16(TK[1 + j], TK[0 + j]));
231 TTAK[1] += _S_(TTAK[0] ^ Mk16(TK[5 + j], TK[4 + j]));
232 TTAK[2] += _S_(TTAK[1] ^ Mk16(TK[9 + j], TK[8 + j]));
233 TTAK[3] += _S_(TTAK[2] ^ Mk16(TK[13 + j], TK[12 + j]));
234 TTAK[4] += _S_(TTAK[3] ^ Mk16(TK[1 + j], TK[0 + j])) + i;
235 }
236}
237
238
239static void tkip_mixing_phase2(u8 *WEPSeed, const u8 *TK, const u16 *TTAK,
240 u16 IV16)
241{
242 /* Make temporary area overlap WEP seed so that the final copy can be
243 * avoided on little endian hosts. */
244 u16 *PPK = (u16 *) &WEPSeed[4];
245
246 /* Step 1 - make copy of TTAK and bring in TSC */
247 PPK[0] = TTAK[0];
248 PPK[1] = TTAK[1];
249 PPK[2] = TTAK[2];
250 PPK[3] = TTAK[3];
251 PPK[4] = TTAK[4];
252 PPK[5] = TTAK[4] + IV16;
253
254 /* Step 2 - 96-bit bijective mixing using S-box */
255 PPK[0] += _S_(PPK[5] ^ Mk16_le((u16 *) &TK[0]));
256 PPK[1] += _S_(PPK[0] ^ Mk16_le((u16 *) &TK[2]));
257 PPK[2] += _S_(PPK[1] ^ Mk16_le((u16 *) &TK[4]));
258 PPK[3] += _S_(PPK[2] ^ Mk16_le((u16 *) &TK[6]));
259 PPK[4] += _S_(PPK[3] ^ Mk16_le((u16 *) &TK[8]));
260 PPK[5] += _S_(PPK[4] ^ Mk16_le((u16 *) &TK[10]));
261
262 PPK[0] += RotR1(PPK[5] ^ Mk16_le((u16 *) &TK[12]));
263 PPK[1] += RotR1(PPK[0] ^ Mk16_le((u16 *) &TK[14]));
264 PPK[2] += RotR1(PPK[1]);
265 PPK[3] += RotR1(PPK[2]);
266 PPK[4] += RotR1(PPK[3]);
267 PPK[5] += RotR1(PPK[4]);
268
269 /* Step 3 - bring in last of TK bits, assign 24-bit WEP IV value
270 * WEPSeed[0..2] is transmitted as WEP IV */
271 WEPSeed[0] = Hi8(IV16);
272 WEPSeed[1] = (Hi8(IV16) | 0x20) & 0x7F;
273 WEPSeed[2] = Lo8(IV16);
274 WEPSeed[3] = Lo8((PPK[5] ^ Mk16_le((u16 *) &TK[0])) >> 1);
275
276#ifdef __BIG_ENDIAN
277 {
278 int i;
279 for (i = 0; i < 6; i++)
280 PPK[i] = (PPK[i] << 8) | (PPK[i] >> 8);
281 }
282#endif
283}
284
285
286static int hostap_tkip_encrypt(struct sk_buff *skb, int hdr_len, void *priv)
287{
288 struct hostap_tkip_data *tkey = priv;
289 int len;
290 u8 rc4key[16], *pos, *icv;
291 struct hostap_ieee80211_hdr *hdr;
292 u32 crc;
293 struct scatterlist sg;
294
295 if (skb_headroom(skb) < 8 || skb_tailroom(skb) < 4 ||
296 skb->len < hdr_len)
297 return -1;
298
299 hdr = (struct hostap_ieee80211_hdr *) skb->data;
300 if (!tkey->tx_phase1_done) {
301 tkip_mixing_phase1(tkey->tx_ttak, tkey->key, hdr->addr2,
302 tkey->tx_iv32);
303 tkey->tx_phase1_done = 1;
304 }
305 tkip_mixing_phase2(rc4key, tkey->key, tkey->tx_ttak, tkey->tx_iv16);
306
307 len = skb->len - hdr_len;
308 pos = skb_push(skb, 8);
309 memmove(pos, pos + 8, hdr_len);
310 pos += hdr_len;
311 icv = skb_put(skb, 4);
312
313 *pos++ = rc4key[0];
314 *pos++ = rc4key[1];
315 *pos++ = rc4key[2];
316 *pos++ = (tkey->key_idx << 6) | (1 << 5) /* Ext IV included */;
317 *pos++ = tkey->tx_iv32 & 0xff;
318 *pos++ = (tkey->tx_iv32 >> 8) & 0xff;
319 *pos++ = (tkey->tx_iv32 >> 16) & 0xff;
320 *pos++ = (tkey->tx_iv32 >> 24) & 0xff;
321
322 crc = ~crc32_le(~0, pos, len);
323 icv[0] = crc;
324 icv[1] = crc >> 8;
325 icv[2] = crc >> 16;
326 icv[3] = crc >> 24;
327
328 crypto_cipher_setkey(tkey->tfm_arc4, rc4key, 16);
329 sg.page = virt_to_page(pos);
330 sg.offset = offset_in_page(pos);
331 sg.length = len + 4;
332 crypto_cipher_encrypt(tkey->tfm_arc4, &sg, &sg, len + 4);
333
334 tkey->tx_iv16++;
335 if (tkey->tx_iv16 == 0) {
336 tkey->tx_phase1_done = 0;
337 tkey->tx_iv32++;
338 }
339
340 return 0;
341}
342
343
344static int hostap_tkip_decrypt(struct sk_buff *skb, int hdr_len, void *priv)
345{
346 struct hostap_tkip_data *tkey = priv;
347 u8 rc4key[16];
348 u8 keyidx, *pos, icv[4];
349 u32 iv32;
350 u16 iv16;
351 struct hostap_ieee80211_hdr *hdr;
352 u32 crc;
353 struct scatterlist sg;
354 int plen;
355
356 if (skb->len < hdr_len + 8 + 4)
357 return -1;
358
359 hdr = (struct hostap_ieee80211_hdr *) skb->data;
360 pos = skb->data + hdr_len;
361 keyidx = pos[3];
362 if (!(keyidx & (1 << 5))) {
363 if (net_ratelimit()) {
364 printk(KERN_DEBUG "TKIP: received packet without ExtIV"
365 " flag from " MACSTR "\n", MAC2STR(hdr->addr2));
366 }
367 return -2;
368 }
369 keyidx >>= 6;
370 if (tkey->key_idx != keyidx) {
371 printk(KERN_DEBUG "TKIP: RX tkey->key_idx=%d frame "
372 "keyidx=%d priv=%p\n", tkey->key_idx, keyidx, priv);
373 return -6;
374 }
375 if (!tkey->key_set) {
376 if (net_ratelimit()) {
377 printk(KERN_DEBUG "TKIP: received packet from " MACSTR
378 " with keyid=%d that does not have a configured"
379 " key\n", MAC2STR(hdr->addr2), keyidx);
380 }
381 return -3;
382 }
383 iv16 = (pos[0] << 8) | pos[2];
384 iv32 = pos[4] | (pos[5] << 8) | (pos[6] << 16) | (pos[7] << 24);
385 pos += 8;
386
387 if (iv32 < tkey->rx_iv32 ||
388 (iv32 == tkey->rx_iv32 && iv16 <= tkey->rx_iv16)) {
389 if (net_ratelimit()) {
390 printk(KERN_DEBUG "TKIP: replay detected: STA=" MACSTR
391 " previous TSC %08x%04x received TSC "
392 "%08x%04x\n", MAC2STR(hdr->addr2),
393 tkey->rx_iv32, tkey->rx_iv16, iv32, iv16);
394 }
395 tkey->dot11RSNAStatsTKIPReplays++;
396 return -4;
397 }
398
399 if (iv32 != tkey->rx_iv32 || !tkey->rx_phase1_done) {
400 tkip_mixing_phase1(tkey->rx_ttak, tkey->key, hdr->addr2, iv32);
401 tkey->rx_phase1_done = 1;
402 }
403 tkip_mixing_phase2(rc4key, tkey->key, tkey->rx_ttak, iv16);
404
405 plen = skb->len - hdr_len - 12;
406
407 crypto_cipher_setkey(tkey->tfm_arc4, rc4key, 16);
408 sg.page = virt_to_page(pos);
409 sg.offset = offset_in_page(pos);
410 sg.length = plen + 4;
411 crypto_cipher_decrypt(tkey->tfm_arc4, &sg, &sg, plen + 4);
412
413 crc = ~crc32_le(~0, pos, plen);
414 icv[0] = crc;
415 icv[1] = crc >> 8;
416 icv[2] = crc >> 16;
417 icv[3] = crc >> 24;
418 if (memcmp(icv, pos + plen, 4) != 0) {
419 if (iv32 != tkey->rx_iv32) {
420 /* Previously cached Phase1 result was already lost, so
421 * it needs to be recalculated for the next packet. */
422 tkey->rx_phase1_done = 0;
423 }
424 if (net_ratelimit()) {
425 printk(KERN_DEBUG "TKIP: ICV error detected: STA="
426 MACSTR "\n", MAC2STR(hdr->addr2));
427 }
428 tkey->dot11RSNAStatsTKIPICVErrors++;
429 return -5;
430 }
431
432 /* Update real counters only after Michael MIC verification has
433 * completed */
434 tkey->rx_iv32_new = iv32;
435 tkey->rx_iv16_new = iv16;
436
437 /* Remove IV and ICV */
438 memmove(skb->data + 8, skb->data, hdr_len);
439 skb_pull(skb, 8);
440 skb_trim(skb, skb->len - 4);
441
442 return keyidx;
443}
444
445
446static int michael_mic(struct hostap_tkip_data *tkey, u8 *key, u8 *hdr,
447 u8 *data, size_t data_len, u8 *mic)
448{
449 struct scatterlist sg[2];
450
451 if (tkey->tfm_michael == NULL) {
452 printk(KERN_WARNING "michael_mic: tfm_michael == NULL\n");
453 return -1;
454 }
455 sg[0].page = virt_to_page(hdr);
456 sg[0].offset = offset_in_page(hdr);
457 sg[0].length = 16;
458
459 sg[1].page = virt_to_page(data);
460 sg[1].offset = offset_in_page(data);
461 sg[1].length = data_len;
462
463 crypto_digest_init(tkey->tfm_michael);
464 crypto_digest_setkey(tkey->tfm_michael, key, 8);
465 crypto_digest_update(tkey->tfm_michael, sg, 2);
466 crypto_digest_final(tkey->tfm_michael, mic);
467
468 return 0;
469}
470
471
472static void michael_mic_hdr(struct sk_buff *skb, u8 *hdr)
473{
474 struct hostap_ieee80211_hdr *hdr11;
475
476 hdr11 = (struct hostap_ieee80211_hdr *) skb->data;
477 switch (le16_to_cpu(hdr11->frame_control) &
478 (WLAN_FC_FROMDS | WLAN_FC_TODS)) {
479 case WLAN_FC_TODS:
480 memcpy(hdr, hdr11->addr3, ETH_ALEN); /* DA */
481 memcpy(hdr + ETH_ALEN, hdr11->addr2, ETH_ALEN); /* SA */
482 break;
483 case WLAN_FC_FROMDS:
484 memcpy(hdr, hdr11->addr1, ETH_ALEN); /* DA */
485 memcpy(hdr + ETH_ALEN, hdr11->addr3, ETH_ALEN); /* SA */
486 break;
487 case WLAN_FC_FROMDS | WLAN_FC_TODS:
488 memcpy(hdr, hdr11->addr3, ETH_ALEN); /* DA */
489 memcpy(hdr + ETH_ALEN, hdr11->addr4, ETH_ALEN); /* SA */
490 break;
491 case 0:
492 memcpy(hdr, hdr11->addr1, ETH_ALEN); /* DA */
493 memcpy(hdr + ETH_ALEN, hdr11->addr2, ETH_ALEN); /* SA */
494 break;
495 }
496
497 hdr[12] = 0; /* priority */
498 hdr[13] = hdr[14] = hdr[15] = 0; /* reserved */
499}
500
501
502static int hostap_michael_mic_add(struct sk_buff *skb, int hdr_len, void *priv)
503{
504 struct hostap_tkip_data *tkey = priv;
505 u8 *pos;
506
507 if (skb_tailroom(skb) < 8 || skb->len < hdr_len) {
508 printk(KERN_DEBUG "Invalid packet for Michael MIC add "
509 "(tailroom=%d hdr_len=%d skb->len=%d)\n",
510 skb_tailroom(skb), hdr_len, skb->len);
511 return -1;
512 }
513
514 michael_mic_hdr(skb, tkey->tx_hdr);
515 pos = skb_put(skb, 8);
516 if (michael_mic(tkey, &tkey->key[16], tkey->tx_hdr,
517 skb->data + hdr_len, skb->len - 8 - hdr_len, pos))
518 return -1;
519
520 return 0;
521}
522
523
524static void hostap_michael_mic_failure(struct net_device *dev,
525 struct hostap_ieee80211_hdr *hdr,
526 int keyidx)
527{
528 union iwreq_data wrqu;
529 char buf[128];
530
531 /* TODO: needed parameters: count, keyid, key type, src address, TSC */
532 sprintf(buf, "MLME-MICHAELMICFAILURE.indication(keyid=%d %scast addr="
533 MACSTR ")", keyidx, hdr->addr1[0] & 0x01 ? "broad" : "uni",
534 MAC2STR(hdr->addr2));
535 memset(&wrqu, 0, sizeof(wrqu));
536 wrqu.data.length = strlen(buf);
537 wireless_send_event(dev, IWEVCUSTOM, &wrqu, buf);
538}
539
540
541static int hostap_michael_mic_verify(struct sk_buff *skb, int keyidx,
542 int hdr_len, void *priv)
543{
544 struct hostap_tkip_data *tkey = priv;
545 u8 mic[8];
546
547 if (!tkey->key_set)
548 return -1;
549
550 michael_mic_hdr(skb, tkey->rx_hdr);
551 if (michael_mic(tkey, &tkey->key[24], tkey->rx_hdr,
552 skb->data + hdr_len, skb->len - 8 - hdr_len, mic))
553 return -1;
554 if (memcmp(mic, skb->data + skb->len - 8, 8) != 0) {
555 struct hostap_ieee80211_hdr *hdr;
556 hdr = (struct hostap_ieee80211_hdr *) skb->data;
557 printk(KERN_DEBUG "%s: Michael MIC verification failed for "
558 "MSDU from " MACSTR " keyidx=%d\n",
559 skb->dev ? skb->dev->name : "N/A", MAC2STR(hdr->addr2),
560 keyidx);
561 if (skb->dev)
562 hostap_michael_mic_failure(skb->dev, hdr, keyidx);
563 tkey->dot11RSNAStatsTKIPLocalMICFailures++;
564 return -1;
565 }
566
567 /* Update TSC counters for RX now that the packet verification has
568 * completed. */
569 tkey->rx_iv32 = tkey->rx_iv32_new;
570 tkey->rx_iv16 = tkey->rx_iv16_new;
571
572 skb_trim(skb, skb->len - 8);
573
574 return 0;
575}
576
577
578static int hostap_tkip_set_key(void *key, int len, u8 *seq, void *priv)
579{
580 struct hostap_tkip_data *tkey = priv;
581 int keyidx;
582 struct crypto_tfm *tfm = tkey->tfm_michael;
583 struct crypto_tfm *tfm2 = tkey->tfm_arc4;
584
585 keyidx = tkey->key_idx;
586 memset(tkey, 0, sizeof(*tkey));
587 tkey->key_idx = keyidx;
588 tkey->tfm_michael = tfm;
589 tkey->tfm_arc4 = tfm2;
590 if (len == TKIP_KEY_LEN) {
591 memcpy(tkey->key, key, TKIP_KEY_LEN);
592 tkey->key_set = 1;
593 tkey->tx_iv16 = 1; /* TSC is initialized to 1 */
594 if (seq) {
595 tkey->rx_iv32 = (seq[5] << 24) | (seq[4] << 16) |
596 (seq[3] << 8) | seq[2];
597 tkey->rx_iv16 = (seq[1] << 8) | seq[0];
598 }
599 } else if (len == 0) {
600 tkey->key_set = 0;
601 } else
602 return -1;
603
604 return 0;
605}
606
607
608static int hostap_tkip_get_key(void *key, int len, u8 *seq, void *priv)
609{
610 struct hostap_tkip_data *tkey = priv;
611
612 if (len < TKIP_KEY_LEN)
613 return -1;
614
615 if (!tkey->key_set)
616 return 0;
617 memcpy(key, tkey->key, TKIP_KEY_LEN);
618
619 if (seq) {
620 /* Return the sequence number of the last transmitted frame. */
621 u16 iv16 = tkey->tx_iv16;
622 u32 iv32 = tkey->tx_iv32;
623 if (iv16 == 0)
624 iv32--;
625 iv16--;
626 seq[0] = tkey->tx_iv16;
627 seq[1] = tkey->tx_iv16 >> 8;
628 seq[2] = tkey->tx_iv32;
629 seq[3] = tkey->tx_iv32 >> 8;
630 seq[4] = tkey->tx_iv32 >> 16;
631 seq[5] = tkey->tx_iv32 >> 24;
632 }
633
634 return TKIP_KEY_LEN;
635}
636
637
638static char * hostap_tkip_print_stats(char *p, void *priv)
639{
640 struct hostap_tkip_data *tkip = priv;
641 p += sprintf(p, "key[%d] alg=TKIP key_set=%d "
642 "tx_pn=%02x%02x%02x%02x%02x%02x "
643 "rx_pn=%02x%02x%02x%02x%02x%02x "
644 "replays=%d icv_errors=%d local_mic_failures=%d\n",
645 tkip->key_idx, tkip->key_set,
646 (tkip->tx_iv32 >> 24) & 0xff,
647 (tkip->tx_iv32 >> 16) & 0xff,
648 (tkip->tx_iv32 >> 8) & 0xff,
649 tkip->tx_iv32 & 0xff,
650 (tkip->tx_iv16 >> 8) & 0xff,
651 tkip->tx_iv16 & 0xff,
652 (tkip->rx_iv32 >> 24) & 0xff,
653 (tkip->rx_iv32 >> 16) & 0xff,
654 (tkip->rx_iv32 >> 8) & 0xff,
655 tkip->rx_iv32 & 0xff,
656 (tkip->rx_iv16 >> 8) & 0xff,
657 tkip->rx_iv16 & 0xff,
658 tkip->dot11RSNAStatsTKIPReplays,
659 tkip->dot11RSNAStatsTKIPICVErrors,
660 tkip->dot11RSNAStatsTKIPLocalMICFailures);
661 return p;
662}
663
664
665static struct hostap_crypto_ops hostap_crypt_tkip = {
666 .name = "TKIP",
667 .init = hostap_tkip_init,
668 .deinit = hostap_tkip_deinit,
669 .encrypt_mpdu = hostap_tkip_encrypt,
670 .decrypt_mpdu = hostap_tkip_decrypt,
671 .encrypt_msdu = hostap_michael_mic_add,
672 .decrypt_msdu = hostap_michael_mic_verify,
673 .set_key = hostap_tkip_set_key,
674 .get_key = hostap_tkip_get_key,
675 .print_stats = hostap_tkip_print_stats,
676 .extra_prefix_len = 4 + 4 /* IV + ExtIV */,
677 .extra_postfix_len = 8 + 4 /* MIC + ICV */
678};
679
680
681static int __init hostap_crypto_tkip_init(void)
682{
683 if (hostap_register_crypto_ops(&hostap_crypt_tkip) < 0)
684 return -1;
685
686 return 0;
687}
688
689
690static void __exit hostap_crypto_tkip_exit(void)
691{
692 hostap_unregister_crypto_ops(&hostap_crypt_tkip);
693}
694
695
696module_init(hostap_crypto_tkip_init);
697module_exit(hostap_crypto_tkip_exit);