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