2 * Host AP crypt: host-based TKIP encryption implementation for Host AP driver
4 * Copyright (c) 2003-2004, Jouni Malinen <jkmaline@cc.hut.fi>
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License version 2 as
8 * published by the Free Software Foundation. See README and COPYING for
12 #include <linux/config.h>
13 #include <linux/version.h>
14 #include <linux/module.h>
15 #include <linux/init.h>
16 #include <linux/slab.h>
17 #include <linux/random.h>
18 #include <linux/skbuff.h>
19 #include <linux/netdevice.h>
20 #include <linux/if_ether.h>
21 #include <linux/if_arp.h>
22 #include <asm/string.h>
24 #include <net/ieee80211.h>
26 #include <linux/crypto.h>
27 #include <asm/scatterlist.h>
28 #include <linux/crc32.h>
30 MODULE_AUTHOR("Jouni Malinen");
31 MODULE_DESCRIPTION("Host AP crypt: TKIP");
32 MODULE_LICENSE("GPL");
34 struct ieee80211_tkip_data {
35 #define TKIP_KEY_LEN 32
51 u32 dot11RSNAStatsTKIPReplays;
52 u32 dot11RSNAStatsTKIPICVErrors;
53 u32 dot11RSNAStatsTKIPLocalMICFailures;
57 struct crypto_tfm *tfm_arc4;
58 struct crypto_tfm *tfm_michael;
60 /* scratch buffers for virt_to_page() (crypto API) */
61 u8 rx_hdr[16], tx_hdr[16];
63 struct ieee80211_device *ieee;
66 static void *ieee80211_tkip_init(struct ieee80211_device *ieee, int key_idx)
68 struct ieee80211_tkip_data *priv;
70 priv = kmalloc(sizeof(*priv), GFP_ATOMIC);
73 memset(priv, 0, sizeof(*priv));
77 priv->key_idx = key_idx;
79 priv->tfm_arc4 = crypto_alloc_tfm("arc4", 0);
80 if (priv->tfm_arc4 == NULL) {
81 printk(KERN_DEBUG "ieee80211_crypt_tkip: could not allocate "
86 priv->tfm_michael = crypto_alloc_tfm("michael_mic", 0);
87 if (priv->tfm_michael == NULL) {
88 printk(KERN_DEBUG "ieee80211_crypt_tkip: could not allocate "
89 "crypto API michael_mic\n");
97 if (priv->tfm_michael)
98 crypto_free_tfm(priv->tfm_michael);
100 crypto_free_tfm(priv->tfm_arc4);
107 static void ieee80211_tkip_deinit(void *priv)
109 struct ieee80211_tkip_data *_priv = priv;
110 if (_priv && _priv->tfm_michael)
111 crypto_free_tfm(_priv->tfm_michael);
112 if (_priv && _priv->tfm_arc4)
113 crypto_free_tfm(_priv->tfm_arc4);
117 static inline u16 RotR1(u16 val)
119 return (val >> 1) | (val << 15);
122 static inline u8 Lo8(u16 val)
127 static inline u8 Hi8(u16 val)
132 static inline u16 Lo16(u32 val)
137 static inline u16 Hi16(u32 val)
142 static inline u16 Mk16(u8 hi, u8 lo)
144 return lo | (((u16) hi) << 8);
147 static inline u16 Mk16_le(u16 * v)
149 return le16_to_cpu(*v);
152 static const u16 Sbox[256] = {
153 0xC6A5, 0xF884, 0xEE99, 0xF68D, 0xFF0D, 0xD6BD, 0xDEB1, 0x9154,
154 0x6050, 0x0203, 0xCEA9, 0x567D, 0xE719, 0xB562, 0x4DE6, 0xEC9A,
155 0x8F45, 0x1F9D, 0x8940, 0xFA87, 0xEF15, 0xB2EB, 0x8EC9, 0xFB0B,
156 0x41EC, 0xB367, 0x5FFD, 0x45EA, 0x23BF, 0x53F7, 0xE496, 0x9B5B,
157 0x75C2, 0xE11C, 0x3DAE, 0x4C6A, 0x6C5A, 0x7E41, 0xF502, 0x834F,
158 0x685C, 0x51F4, 0xD134, 0xF908, 0xE293, 0xAB73, 0x6253, 0x2A3F,
159 0x080C, 0x9552, 0x4665, 0x9D5E, 0x3028, 0x37A1, 0x0A0F, 0x2FB5,
160 0x0E09, 0x2436, 0x1B9B, 0xDF3D, 0xCD26, 0x4E69, 0x7FCD, 0xEA9F,
161 0x121B, 0x1D9E, 0x5874, 0x342E, 0x362D, 0xDCB2, 0xB4EE, 0x5BFB,
162 0xA4F6, 0x764D, 0xB761, 0x7DCE, 0x527B, 0xDD3E, 0x5E71, 0x1397,
163 0xA6F5, 0xB968, 0x0000, 0xC12C, 0x4060, 0xE31F, 0x79C8, 0xB6ED,
164 0xD4BE, 0x8D46, 0x67D9, 0x724B, 0x94DE, 0x98D4, 0xB0E8, 0x854A,
165 0xBB6B, 0xC52A, 0x4FE5, 0xED16, 0x86C5, 0x9AD7, 0x6655, 0x1194,
166 0x8ACF, 0xE910, 0x0406, 0xFE81, 0xA0F0, 0x7844, 0x25BA, 0x4BE3,
167 0xA2F3, 0x5DFE, 0x80C0, 0x058A, 0x3FAD, 0x21BC, 0x7048, 0xF104,
168 0x63DF, 0x77C1, 0xAF75, 0x4263, 0x2030, 0xE51A, 0xFD0E, 0xBF6D,
169 0x814C, 0x1814, 0x2635, 0xC32F, 0xBEE1, 0x35A2, 0x88CC, 0x2E39,
170 0x9357, 0x55F2, 0xFC82, 0x7A47, 0xC8AC, 0xBAE7, 0x322B, 0xE695,
171 0xC0A0, 0x1998, 0x9ED1, 0xA37F, 0x4466, 0x547E, 0x3BAB, 0x0B83,
172 0x8CCA, 0xC729, 0x6BD3, 0x283C, 0xA779, 0xBCE2, 0x161D, 0xAD76,
173 0xDB3B, 0x6456, 0x744E, 0x141E, 0x92DB, 0x0C0A, 0x486C, 0xB8E4,
174 0x9F5D, 0xBD6E, 0x43EF, 0xC4A6, 0x39A8, 0x31A4, 0xD337, 0xF28B,
175 0xD532, 0x8B43, 0x6E59, 0xDAB7, 0x018C, 0xB164, 0x9CD2, 0x49E0,
176 0xD8B4, 0xACFA, 0xF307, 0xCF25, 0xCAAF, 0xF48E, 0x47E9, 0x1018,
177 0x6FD5, 0xF088, 0x4A6F, 0x5C72, 0x3824, 0x57F1, 0x73C7, 0x9751,
178 0xCB23, 0xA17C, 0xE89C, 0x3E21, 0x96DD, 0x61DC, 0x0D86, 0x0F85,
179 0xE090, 0x7C42, 0x71C4, 0xCCAA, 0x90D8, 0x0605, 0xF701, 0x1C12,
180 0xC2A3, 0x6A5F, 0xAEF9, 0x69D0, 0x1791, 0x9958, 0x3A27, 0x27B9,
181 0xD938, 0xEB13, 0x2BB3, 0x2233, 0xD2BB, 0xA970, 0x0789, 0x33A7,
182 0x2DB6, 0x3C22, 0x1592, 0xC920, 0x8749, 0xAAFF, 0x5078, 0xA57A,
183 0x038F, 0x59F8, 0x0980, 0x1A17, 0x65DA, 0xD731, 0x84C6, 0xD0B8,
184 0x82C3, 0x29B0, 0x5A77, 0x1E11, 0x7BCB, 0xA8FC, 0x6DD6, 0x2C3A,
187 static inline u16 _S_(u16 v)
189 u16 t = Sbox[Hi8(v)];
190 return Sbox[Lo8(v)] ^ ((t << 8) | (t >> 8));
193 #define PHASE1_LOOP_COUNT 8
195 static void tkip_mixing_phase1(u16 * TTAK, const u8 * TK, const u8 * TA,
200 /* Initialize the 80-bit TTAK from TSC (IV32) and TA[0..5] */
201 TTAK[0] = Lo16(IV32);
202 TTAK[1] = Hi16(IV32);
203 TTAK[2] = Mk16(TA[1], TA[0]);
204 TTAK[3] = Mk16(TA[3], TA[2]);
205 TTAK[4] = Mk16(TA[5], TA[4]);
207 for (i = 0; i < PHASE1_LOOP_COUNT; i++) {
209 TTAK[0] += _S_(TTAK[4] ^ Mk16(TK[1 + j], TK[0 + j]));
210 TTAK[1] += _S_(TTAK[0] ^ Mk16(TK[5 + j], TK[4 + j]));
211 TTAK[2] += _S_(TTAK[1] ^ Mk16(TK[9 + j], TK[8 + j]));
212 TTAK[3] += _S_(TTAK[2] ^ Mk16(TK[13 + j], TK[12 + j]));
213 TTAK[4] += _S_(TTAK[3] ^ Mk16(TK[1 + j], TK[0 + j])) + i;
217 static void tkip_mixing_phase2(u8 * WEPSeed, const u8 * TK, const u16 * TTAK,
220 /* Make temporary area overlap WEP seed so that the final copy can be
221 * avoided on little endian hosts. */
222 u16 *PPK = (u16 *) & WEPSeed[4];
224 /* Step 1 - make copy of TTAK and bring in TSC */
230 PPK[5] = TTAK[4] + IV16;
232 /* Step 2 - 96-bit bijective mixing using S-box */
233 PPK[0] += _S_(PPK[5] ^ Mk16_le((u16 *) & TK[0]));
234 PPK[1] += _S_(PPK[0] ^ Mk16_le((u16 *) & TK[2]));
235 PPK[2] += _S_(PPK[1] ^ Mk16_le((u16 *) & TK[4]));
236 PPK[3] += _S_(PPK[2] ^ Mk16_le((u16 *) & TK[6]));
237 PPK[4] += _S_(PPK[3] ^ Mk16_le((u16 *) & TK[8]));
238 PPK[5] += _S_(PPK[4] ^ Mk16_le((u16 *) & TK[10]));
240 PPK[0] += RotR1(PPK[5] ^ Mk16_le((u16 *) & TK[12]));
241 PPK[1] += RotR1(PPK[0] ^ Mk16_le((u16 *) & TK[14]));
242 PPK[2] += RotR1(PPK[1]);
243 PPK[3] += RotR1(PPK[2]);
244 PPK[4] += RotR1(PPK[3]);
245 PPK[5] += RotR1(PPK[4]);
247 /* Step 3 - bring in last of TK bits, assign 24-bit WEP IV value
248 * WEPSeed[0..2] is transmitted as WEP IV */
249 WEPSeed[0] = Hi8(IV16);
250 WEPSeed[1] = (Hi8(IV16) | 0x20) & 0x7F;
251 WEPSeed[2] = Lo8(IV16);
252 WEPSeed[3] = Lo8((PPK[5] ^ Mk16_le((u16 *) & TK[0])) >> 1);
257 for (i = 0; i < 6; i++)
258 PPK[i] = (PPK[i] << 8) | (PPK[i] >> 8);
263 static int ieee80211_tkip_encrypt(struct sk_buff *skb, int hdr_len, void *priv)
265 struct ieee80211_tkip_data *tkey = priv;
267 u8 rc4key[16], *pos, *icv;
268 struct ieee80211_hdr_4addr *hdr;
270 struct scatterlist sg;
272 hdr = (struct ieee80211_hdr_4addr *)skb->data;
274 if (tkey->ieee->tkip_countermeasures) {
275 if (net_ratelimit()) {
276 printk(KERN_DEBUG "%s: TKIP countermeasures: dropped "
277 "TX packet to " MAC_FMT "\n",
278 tkey->ieee->dev->name, MAC_ARG(hdr->addr1));
283 if (skb_headroom(skb) < 8 || skb_tailroom(skb) < 4 ||
287 if (!tkey->tx_phase1_done) {
288 tkip_mixing_phase1(tkey->tx_ttak, tkey->key, hdr->addr2,
290 tkey->tx_phase1_done = 1;
292 tkip_mixing_phase2(rc4key, tkey->key, tkey->tx_ttak, tkey->tx_iv16);
294 len = skb->len - hdr_len;
295 pos = skb_push(skb, 8);
296 memmove(pos, pos + 8, hdr_len);
298 icv = skb_put(skb, 4);
303 *pos++ = (tkey->key_idx << 6) | (1 << 5) /* Ext IV included */ ;
304 *pos++ = tkey->tx_iv32 & 0xff;
305 *pos++ = (tkey->tx_iv32 >> 8) & 0xff;
306 *pos++ = (tkey->tx_iv32 >> 16) & 0xff;
307 *pos++ = (tkey->tx_iv32 >> 24) & 0xff;
309 crc = ~crc32_le(~0, pos, len);
315 crypto_cipher_setkey(tkey->tfm_arc4, rc4key, 16);
316 sg.page = virt_to_page(pos);
317 sg.offset = offset_in_page(pos);
319 crypto_cipher_encrypt(tkey->tfm_arc4, &sg, &sg, len + 4);
322 if (tkey->tx_iv16 == 0) {
323 tkey->tx_phase1_done = 0;
330 static int ieee80211_tkip_decrypt(struct sk_buff *skb, int hdr_len, void *priv)
332 struct ieee80211_tkip_data *tkey = priv;
337 struct ieee80211_hdr_4addr *hdr;
340 struct scatterlist sg;
343 hdr = (struct ieee80211_hdr_4addr *)skb->data;
345 if (tkey->ieee->tkip_countermeasures) {
346 if (net_ratelimit()) {
347 printk(KERN_DEBUG "%s: TKIP countermeasures: dropped "
348 "received packet from " MAC_FMT "\n",
349 tkey->ieee->dev->name, MAC_ARG(hdr->addr2));
354 if (skb->len < hdr_len + 8 + 4)
357 pos = skb->data + hdr_len;
359 if (!(keyidx & (1 << 5))) {
360 if (net_ratelimit()) {
361 printk(KERN_DEBUG "TKIP: received packet without ExtIV"
362 " flag from " MAC_FMT "\n", MAC_ARG(hdr->addr2));
367 if (tkey->key_idx != keyidx) {
368 printk(KERN_DEBUG "TKIP: RX tkey->key_idx=%d frame "
369 "keyidx=%d priv=%p\n", tkey->key_idx, keyidx, priv);
372 if (!tkey->key_set) {
373 if (net_ratelimit()) {
374 printk(KERN_DEBUG "TKIP: received packet from " MAC_FMT
375 " with keyid=%d that does not have a configured"
376 " key\n", MAC_ARG(hdr->addr2), keyidx);
380 iv16 = (pos[0] << 8) | pos[2];
381 iv32 = pos[4] | (pos[5] << 8) | (pos[6] << 16) | (pos[7] << 24);
384 if (iv32 < tkey->rx_iv32 ||
385 (iv32 == tkey->rx_iv32 && iv16 <= tkey->rx_iv16)) {
386 if (net_ratelimit()) {
387 printk(KERN_DEBUG "TKIP: replay detected: STA=" MAC_FMT
388 " previous TSC %08x%04x received TSC "
389 "%08x%04x\n", MAC_ARG(hdr->addr2),
390 tkey->rx_iv32, tkey->rx_iv16, iv32, iv16);
392 tkey->dot11RSNAStatsTKIPReplays++;
396 if (iv32 != tkey->rx_iv32 || !tkey->rx_phase1_done) {
397 tkip_mixing_phase1(tkey->rx_ttak, tkey->key, hdr->addr2, iv32);
398 tkey->rx_phase1_done = 1;
400 tkip_mixing_phase2(rc4key, tkey->key, tkey->rx_ttak, iv16);
402 plen = skb->len - hdr_len - 12;
404 crypto_cipher_setkey(tkey->tfm_arc4, rc4key, 16);
405 sg.page = virt_to_page(pos);
406 sg.offset = offset_in_page(pos);
407 sg.length = plen + 4;
408 crypto_cipher_decrypt(tkey->tfm_arc4, &sg, &sg, plen + 4);
410 crc = ~crc32_le(~0, pos, plen);
415 if (memcmp(icv, pos + plen, 4) != 0) {
416 if (iv32 != tkey->rx_iv32) {
417 /* Previously cached Phase1 result was already lost, so
418 * it needs to be recalculated for the next packet. */
419 tkey->rx_phase1_done = 0;
421 if (net_ratelimit()) {
422 printk(KERN_DEBUG "TKIP: ICV error detected: STA="
423 MAC_FMT "\n", MAC_ARG(hdr->addr2));
425 tkey->dot11RSNAStatsTKIPICVErrors++;
429 /* Update real counters only after Michael MIC verification has
431 tkey->rx_iv32_new = iv32;
432 tkey->rx_iv16_new = iv16;
434 /* Remove IV and ICV */
435 memmove(skb->data + 8, skb->data, hdr_len);
437 skb_trim(skb, skb->len - 4);
442 static int michael_mic(struct ieee80211_tkip_data *tkey, u8 * key, u8 * hdr,
443 u8 * data, size_t data_len, u8 * mic)
445 struct scatterlist sg[2];
447 if (tkey->tfm_michael == NULL) {
448 printk(KERN_WARNING "michael_mic: tfm_michael == NULL\n");
451 sg[0].page = virt_to_page(hdr);
452 sg[0].offset = offset_in_page(hdr);
455 sg[1].page = virt_to_page(data);
456 sg[1].offset = offset_in_page(data);
457 sg[1].length = data_len;
459 crypto_digest_init(tkey->tfm_michael);
460 crypto_digest_setkey(tkey->tfm_michael, key, 8);
461 crypto_digest_update(tkey->tfm_michael, sg, 2);
462 crypto_digest_final(tkey->tfm_michael, mic);
467 static void michael_mic_hdr(struct sk_buff *skb, u8 * hdr)
469 struct ieee80211_hdr_4addr *hdr11;
471 hdr11 = (struct ieee80211_hdr_4addr *)skb->data;
472 switch (le16_to_cpu(hdr11->frame_ctl) &
473 (IEEE80211_FCTL_FROMDS | IEEE80211_FCTL_TODS)) {
474 case IEEE80211_FCTL_TODS:
475 memcpy(hdr, hdr11->addr3, ETH_ALEN); /* DA */
476 memcpy(hdr + ETH_ALEN, hdr11->addr2, ETH_ALEN); /* SA */
478 case IEEE80211_FCTL_FROMDS:
479 memcpy(hdr, hdr11->addr1, ETH_ALEN); /* DA */
480 memcpy(hdr + ETH_ALEN, hdr11->addr3, ETH_ALEN); /* SA */
482 case IEEE80211_FCTL_FROMDS | IEEE80211_FCTL_TODS:
483 memcpy(hdr, hdr11->addr3, ETH_ALEN); /* DA */
484 memcpy(hdr + ETH_ALEN, hdr11->addr4, ETH_ALEN); /* SA */
487 memcpy(hdr, hdr11->addr1, ETH_ALEN); /* DA */
488 memcpy(hdr + ETH_ALEN, hdr11->addr2, ETH_ALEN); /* SA */
492 hdr[12] = 0; /* priority */
493 hdr[13] = hdr[14] = hdr[15] = 0; /* reserved */
496 static int ieee80211_michael_mic_add(struct sk_buff *skb, int hdr_len,
499 struct ieee80211_tkip_data *tkey = priv;
502 if (skb_tailroom(skb) < 8 || skb->len < hdr_len) {
503 printk(KERN_DEBUG "Invalid packet for Michael MIC add "
504 "(tailroom=%d hdr_len=%d skb->len=%d)\n",
505 skb_tailroom(skb), hdr_len, skb->len);
509 michael_mic_hdr(skb, tkey->tx_hdr);
510 pos = skb_put(skb, 8);
511 if (michael_mic(tkey, &tkey->key[16], tkey->tx_hdr,
512 skb->data + hdr_len, skb->len - 8 - hdr_len, pos))
518 #if WIRELESS_EXT >= 18
519 static void ieee80211_michael_mic_failure(struct net_device *dev,
520 struct ieee80211_hdr_4addr *hdr,
523 union iwreq_data wrqu;
524 struct iw_michaelmicfailure ev;
526 /* TODO: needed parameters: count, keyid, key type, TSC */
527 memset(&ev, 0, sizeof(ev));
528 ev.flags = keyidx & IW_MICFAILURE_KEY_ID;
529 if (hdr->addr1[0] & 0x01)
530 ev.flags |= IW_MICFAILURE_GROUP;
532 ev.flags |= IW_MICFAILURE_PAIRWISE;
533 ev.src_addr.sa_family = ARPHRD_ETHER;
534 memcpy(ev.src_addr.sa_data, hdr->addr2, ETH_ALEN);
535 memset(&wrqu, 0, sizeof(wrqu));
536 wrqu.data.length = sizeof(ev);
537 wireless_send_event(dev, IWEVMICHAELMICFAILURE, &wrqu, (char *)&ev);
539 #elif WIRELESS_EXT >= 15
540 static void ieee80211_michael_mic_failure(struct net_device *dev,
541 struct ieee80211_hdr_4addr *hdr,
544 union iwreq_data wrqu;
547 /* TODO: needed parameters: count, keyid, key type, TSC */
548 sprintf(buf, "MLME-MICHAELMICFAILURE.indication(keyid=%d %scast addr="
549 MAC_FMT ")", keyidx, hdr->addr1[0] & 0x01 ? "broad" : "uni",
550 MAC_ARG(hdr->addr2));
551 memset(&wrqu, 0, sizeof(wrqu));
552 wrqu.data.length = strlen(buf);
553 wireless_send_event(dev, IWEVCUSTOM, &wrqu, buf);
555 #else /* WIRELESS_EXT >= 15 */
556 static inline void ieee80211_michael_mic_failure(struct net_device *dev, struct ieee80211_hdr_4addr
560 #endif /* WIRELESS_EXT >= 15 */
562 static int ieee80211_michael_mic_verify(struct sk_buff *skb, int keyidx,
563 int hdr_len, void *priv)
565 struct ieee80211_tkip_data *tkey = priv;
571 michael_mic_hdr(skb, tkey->rx_hdr);
572 if (michael_mic(tkey, &tkey->key[24], tkey->rx_hdr,
573 skb->data + hdr_len, skb->len - 8 - hdr_len, mic))
575 if (memcmp(mic, skb->data + skb->len - 8, 8) != 0) {
576 struct ieee80211_hdr_4addr *hdr;
577 hdr = (struct ieee80211_hdr_4addr *)skb->data;
578 printk(KERN_DEBUG "%s: Michael MIC verification failed for "
579 "MSDU from " MAC_FMT " keyidx=%d\n",
580 skb->dev ? skb->dev->name : "N/A", MAC_ARG(hdr->addr2),
583 ieee80211_michael_mic_failure(skb->dev, hdr, keyidx);
584 tkey->dot11RSNAStatsTKIPLocalMICFailures++;
588 /* Update TSC counters for RX now that the packet verification has
590 tkey->rx_iv32 = tkey->rx_iv32_new;
591 tkey->rx_iv16 = tkey->rx_iv16_new;
593 skb_trim(skb, skb->len - 8);
598 static int ieee80211_tkip_set_key(void *key, int len, u8 * seq, void *priv)
600 struct ieee80211_tkip_data *tkey = priv;
602 struct crypto_tfm *tfm = tkey->tfm_michael;
603 struct crypto_tfm *tfm2 = tkey->tfm_arc4;
605 keyidx = tkey->key_idx;
606 memset(tkey, 0, sizeof(*tkey));
607 tkey->key_idx = keyidx;
608 tkey->tfm_michael = tfm;
609 tkey->tfm_arc4 = tfm2;
610 if (len == TKIP_KEY_LEN) {
611 memcpy(tkey->key, key, TKIP_KEY_LEN);
613 tkey->tx_iv16 = 1; /* TSC is initialized to 1 */
615 tkey->rx_iv32 = (seq[5] << 24) | (seq[4] << 16) |
616 (seq[3] << 8) | seq[2];
617 tkey->rx_iv16 = (seq[1] << 8) | seq[0];
627 static int ieee80211_tkip_get_key(void *key, int len, u8 * seq, void *priv)
629 struct ieee80211_tkip_data *tkey = priv;
631 if (len < TKIP_KEY_LEN)
636 memcpy(key, tkey->key, TKIP_KEY_LEN);
639 /* Return the sequence number of the last transmitted frame. */
640 u16 iv16 = tkey->tx_iv16;
641 u32 iv32 = tkey->tx_iv32;
645 seq[0] = tkey->tx_iv16;
646 seq[1] = tkey->tx_iv16 >> 8;
647 seq[2] = tkey->tx_iv32;
648 seq[3] = tkey->tx_iv32 >> 8;
649 seq[4] = tkey->tx_iv32 >> 16;
650 seq[5] = tkey->tx_iv32 >> 24;
656 static char *ieee80211_tkip_print_stats(char *p, void *priv)
658 struct ieee80211_tkip_data *tkip = priv;
659 p += sprintf(p, "key[%d] alg=TKIP key_set=%d "
660 "tx_pn=%02x%02x%02x%02x%02x%02x "
661 "rx_pn=%02x%02x%02x%02x%02x%02x "
662 "replays=%d icv_errors=%d local_mic_failures=%d\n",
663 tkip->key_idx, tkip->key_set,
664 (tkip->tx_iv32 >> 24) & 0xff,
665 (tkip->tx_iv32 >> 16) & 0xff,
666 (tkip->tx_iv32 >> 8) & 0xff,
667 tkip->tx_iv32 & 0xff,
668 (tkip->tx_iv16 >> 8) & 0xff,
669 tkip->tx_iv16 & 0xff,
670 (tkip->rx_iv32 >> 24) & 0xff,
671 (tkip->rx_iv32 >> 16) & 0xff,
672 (tkip->rx_iv32 >> 8) & 0xff,
673 tkip->rx_iv32 & 0xff,
674 (tkip->rx_iv16 >> 8) & 0xff,
675 tkip->rx_iv16 & 0xff,
676 tkip->dot11RSNAStatsTKIPReplays,
677 tkip->dot11RSNAStatsTKIPICVErrors,
678 tkip->dot11RSNAStatsTKIPLocalMICFailures);
682 static struct ieee80211_crypto_ops ieee80211_crypt_tkip = {
684 .init = ieee80211_tkip_init,
685 .deinit = ieee80211_tkip_deinit,
686 .encrypt_mpdu = ieee80211_tkip_encrypt,
687 .decrypt_mpdu = ieee80211_tkip_decrypt,
688 .encrypt_msdu = ieee80211_michael_mic_add,
689 .decrypt_msdu = ieee80211_michael_mic_verify,
690 .set_key = ieee80211_tkip_set_key,
691 .get_key = ieee80211_tkip_get_key,
692 .print_stats = ieee80211_tkip_print_stats,
693 .extra_mpdu_prefix_len = 4 + 4, /* IV + ExtIV */
694 .extra_mpdu_postfix_len = 4, /* ICV */
695 .extra_msdu_postfix_len = 8, /* MIC */
696 .owner = THIS_MODULE,
699 static int __init ieee80211_crypto_tkip_init(void)
701 return ieee80211_register_crypto_ops(&ieee80211_crypt_tkip);
704 static void __exit ieee80211_crypto_tkip_exit(void)
706 ieee80211_unregister_crypto_ops(&ieee80211_crypt_tkip);
709 module_init(ieee80211_crypto_tkip_init);
710 module_exit(ieee80211_crypto_tkip_exit);