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 u8 *ieee80211_tkip_hdr(struct sk_buff *skb, int hdr_len, void *priv)
265 struct ieee80211_tkip_data *tkey = priv;
267 u8 *rc4key, *pos, *icv;
268 struct ieee80211_hdr_4addr *hdr;
271 hdr = (struct ieee80211_hdr_4addr *)skb->data;
273 if (skb_headroom(skb) < 8 || skb->len < hdr_len)
276 if (!tkey->tx_phase1_done) {
277 tkip_mixing_phase1(tkey->tx_ttak, tkey->key, hdr->addr2,
279 tkey->tx_phase1_done = 1;
281 rc4key = kmalloc(16, GFP_ATOMIC);
284 tkip_mixing_phase2(rc4key, tkey->key, tkey->tx_ttak, tkey->tx_iv16);
286 len = skb->len - hdr_len;
287 pos = skb_push(skb, 8);
288 memmove(pos, pos + 8, hdr_len);
290 icv = skb_put(skb, 4);
293 *pos++ = *(rc4key + 1);
294 *pos++ = *(rc4key + 2);
295 *pos++ = (tkey->key_idx << 6) | (1 << 5) /* Ext IV included */ ;
296 *pos++ = tkey->tx_iv32 & 0xff;
297 *pos++ = (tkey->tx_iv32 >> 8) & 0xff;
298 *pos++ = (tkey->tx_iv32 >> 16) & 0xff;
299 *pos++ = (tkey->tx_iv32 >> 24) & 0xff;
301 crc = ~crc32_le(~0, pos, len);
310 static int ieee80211_tkip_encrypt(struct sk_buff *skb, int hdr_len, void *priv)
312 struct ieee80211_tkip_data *tkey = priv;
316 struct scatterlist sg;
318 if (tkey->ieee->tkip_countermeasures) {
319 if (net_ratelimit()) {
320 struct ieee80211_hdr_4addr *hdr =
321 (struct ieee80211_hdr_4addr *)skb->data;
322 printk(KERN_DEBUG "%s: TKIP countermeasures: dropped "
323 "TX packet to " MAC_FMT "\n",
324 tkey->ieee->dev->name, MAC_ARG(hdr->addr1));
329 if (skb_tailroom(skb) < 4 || skb->len < hdr_len)
332 len = skb->len - hdr_len;
333 pos = skb->data + hdr_len;
335 rc4key = ieee80211_tkip_hdr(skb, hdr_len, priv);
339 crypto_cipher_setkey(tkey->tfm_arc4, rc4key, 16);
340 sg.page = virt_to_page(pos);
341 sg.offset = offset_in_page(pos);
343 crypto_cipher_encrypt(tkey->tfm_arc4, &sg, &sg, len + 4);
346 if (tkey->tx_iv16 == 0) {
347 tkey->tx_phase1_done = 0;
354 static int ieee80211_tkip_decrypt(struct sk_buff *skb, int hdr_len, void *priv)
356 struct ieee80211_tkip_data *tkey = priv;
361 struct ieee80211_hdr_4addr *hdr;
364 struct scatterlist sg;
367 hdr = (struct ieee80211_hdr_4addr *)skb->data;
369 if (tkey->ieee->tkip_countermeasures) {
370 if (net_ratelimit()) {
371 printk(KERN_DEBUG "%s: TKIP countermeasures: dropped "
372 "received packet from " MAC_FMT "\n",
373 tkey->ieee->dev->name, MAC_ARG(hdr->addr2));
378 if (skb->len < hdr_len + 8 + 4)
381 pos = skb->data + hdr_len;
383 if (!(keyidx & (1 << 5))) {
384 if (net_ratelimit()) {
385 printk(KERN_DEBUG "TKIP: received packet without ExtIV"
386 " flag from " MAC_FMT "\n", MAC_ARG(hdr->addr2));
391 if (tkey->key_idx != keyidx) {
392 printk(KERN_DEBUG "TKIP: RX tkey->key_idx=%d frame "
393 "keyidx=%d priv=%p\n", tkey->key_idx, keyidx, priv);
396 if (!tkey->key_set) {
397 if (net_ratelimit()) {
398 printk(KERN_DEBUG "TKIP: received packet from " MAC_FMT
399 " with keyid=%d that does not have a configured"
400 " key\n", MAC_ARG(hdr->addr2), keyidx);
404 iv16 = (pos[0] << 8) | pos[2];
405 iv32 = pos[4] | (pos[5] << 8) | (pos[6] << 16) | (pos[7] << 24);
408 if (iv32 < tkey->rx_iv32 ||
409 (iv32 == tkey->rx_iv32 && iv16 <= tkey->rx_iv16)) {
410 if (net_ratelimit()) {
411 printk(KERN_DEBUG "TKIP: replay detected: STA=" MAC_FMT
412 " previous TSC %08x%04x received TSC "
413 "%08x%04x\n", MAC_ARG(hdr->addr2),
414 tkey->rx_iv32, tkey->rx_iv16, iv32, iv16);
416 tkey->dot11RSNAStatsTKIPReplays++;
420 if (iv32 != tkey->rx_iv32 || !tkey->rx_phase1_done) {
421 tkip_mixing_phase1(tkey->rx_ttak, tkey->key, hdr->addr2, iv32);
422 tkey->rx_phase1_done = 1;
424 tkip_mixing_phase2(rc4key, tkey->key, tkey->rx_ttak, iv16);
426 plen = skb->len - hdr_len - 12;
428 crypto_cipher_setkey(tkey->tfm_arc4, rc4key, 16);
429 sg.page = virt_to_page(pos);
430 sg.offset = offset_in_page(pos);
431 sg.length = plen + 4;
432 crypto_cipher_decrypt(tkey->tfm_arc4, &sg, &sg, plen + 4);
434 crc = ~crc32_le(~0, pos, plen);
439 if (memcmp(icv, pos + plen, 4) != 0) {
440 if (iv32 != tkey->rx_iv32) {
441 /* Previously cached Phase1 result was already lost, so
442 * it needs to be recalculated for the next packet. */
443 tkey->rx_phase1_done = 0;
445 if (net_ratelimit()) {
446 printk(KERN_DEBUG "TKIP: ICV error detected: STA="
447 MAC_FMT "\n", MAC_ARG(hdr->addr2));
449 tkey->dot11RSNAStatsTKIPICVErrors++;
453 /* Update real counters only after Michael MIC verification has
455 tkey->rx_iv32_new = iv32;
456 tkey->rx_iv16_new = iv16;
458 /* Remove IV and ICV */
459 memmove(skb->data + 8, skb->data, hdr_len);
461 skb_trim(skb, skb->len - 4);
466 static int michael_mic(struct ieee80211_tkip_data *tkey, u8 * key, u8 * hdr,
467 u8 * data, size_t data_len, u8 * mic)
469 struct scatterlist sg[2];
471 if (tkey->tfm_michael == NULL) {
472 printk(KERN_WARNING "michael_mic: tfm_michael == NULL\n");
475 sg[0].page = virt_to_page(hdr);
476 sg[0].offset = offset_in_page(hdr);
479 sg[1].page = virt_to_page(data);
480 sg[1].offset = offset_in_page(data);
481 sg[1].length = data_len;
483 crypto_digest_init(tkey->tfm_michael);
484 crypto_digest_setkey(tkey->tfm_michael, key, 8);
485 crypto_digest_update(tkey->tfm_michael, sg, 2);
486 crypto_digest_final(tkey->tfm_michael, mic);
491 static void michael_mic_hdr(struct sk_buff *skb, u8 * hdr)
493 struct ieee80211_hdr_4addr *hdr11;
495 hdr11 = (struct ieee80211_hdr_4addr *)skb->data;
496 switch (le16_to_cpu(hdr11->frame_ctl) &
497 (IEEE80211_FCTL_FROMDS | IEEE80211_FCTL_TODS)) {
498 case IEEE80211_FCTL_TODS:
499 memcpy(hdr, hdr11->addr3, ETH_ALEN); /* DA */
500 memcpy(hdr + ETH_ALEN, hdr11->addr2, ETH_ALEN); /* SA */
502 case IEEE80211_FCTL_FROMDS:
503 memcpy(hdr, hdr11->addr1, ETH_ALEN); /* DA */
504 memcpy(hdr + ETH_ALEN, hdr11->addr3, ETH_ALEN); /* SA */
506 case IEEE80211_FCTL_FROMDS | IEEE80211_FCTL_TODS:
507 memcpy(hdr, hdr11->addr3, ETH_ALEN); /* DA */
508 memcpy(hdr + ETH_ALEN, hdr11->addr4, ETH_ALEN); /* SA */
511 memcpy(hdr, hdr11->addr1, ETH_ALEN); /* DA */
512 memcpy(hdr + ETH_ALEN, hdr11->addr2, ETH_ALEN); /* SA */
516 hdr[12] = 0; /* priority */
517 hdr[13] = hdr[14] = hdr[15] = 0; /* reserved */
520 static int ieee80211_michael_mic_add(struct sk_buff *skb, int hdr_len,
523 struct ieee80211_tkip_data *tkey = priv;
526 if (skb_tailroom(skb) < 8 || skb->len < hdr_len) {
527 printk(KERN_DEBUG "Invalid packet for Michael MIC add "
528 "(tailroom=%d hdr_len=%d skb->len=%d)\n",
529 skb_tailroom(skb), hdr_len, skb->len);
533 michael_mic_hdr(skb, tkey->tx_hdr);
534 pos = skb_put(skb, 8);
535 if (michael_mic(tkey, &tkey->key[16], tkey->tx_hdr,
536 skb->data + hdr_len, skb->len - 8 - hdr_len, pos))
542 static void ieee80211_michael_mic_failure(struct net_device *dev,
543 struct ieee80211_hdr_4addr *hdr,
546 union iwreq_data wrqu;
547 struct iw_michaelmicfailure ev;
549 /* TODO: needed parameters: count, keyid, key type, TSC */
550 memset(&ev, 0, sizeof(ev));
551 ev.flags = keyidx & IW_MICFAILURE_KEY_ID;
552 if (hdr->addr1[0] & 0x01)
553 ev.flags |= IW_MICFAILURE_GROUP;
555 ev.flags |= IW_MICFAILURE_PAIRWISE;
556 ev.src_addr.sa_family = ARPHRD_ETHER;
557 memcpy(ev.src_addr.sa_data, hdr->addr2, ETH_ALEN);
558 memset(&wrqu, 0, sizeof(wrqu));
559 wrqu.data.length = sizeof(ev);
560 wireless_send_event(dev, IWEVMICHAELMICFAILURE, &wrqu, (char *)&ev);
563 static int ieee80211_michael_mic_verify(struct sk_buff *skb, int keyidx,
564 int hdr_len, void *priv)
566 struct ieee80211_tkip_data *tkey = priv;
572 michael_mic_hdr(skb, tkey->rx_hdr);
573 if (michael_mic(tkey, &tkey->key[24], tkey->rx_hdr,
574 skb->data + hdr_len, skb->len - 8 - hdr_len, mic))
576 if (memcmp(mic, skb->data + skb->len - 8, 8) != 0) {
577 struct ieee80211_hdr_4addr *hdr;
578 hdr = (struct ieee80211_hdr_4addr *)skb->data;
579 printk(KERN_DEBUG "%s: Michael MIC verification failed for "
580 "MSDU from " MAC_FMT " keyidx=%d\n",
581 skb->dev ? skb->dev->name : "N/A", MAC_ARG(hdr->addr2),
584 ieee80211_michael_mic_failure(skb->dev, hdr, keyidx);
585 tkey->dot11RSNAStatsTKIPLocalMICFailures++;
589 /* Update TSC counters for RX now that the packet verification has
591 tkey->rx_iv32 = tkey->rx_iv32_new;
592 tkey->rx_iv16 = tkey->rx_iv16_new;
594 skb_trim(skb, skb->len - 8);
599 static int ieee80211_tkip_set_key(void *key, int len, u8 * seq, void *priv)
601 struct ieee80211_tkip_data *tkey = priv;
603 struct crypto_tfm *tfm = tkey->tfm_michael;
604 struct crypto_tfm *tfm2 = tkey->tfm_arc4;
606 keyidx = tkey->key_idx;
607 memset(tkey, 0, sizeof(*tkey));
608 tkey->key_idx = keyidx;
609 tkey->tfm_michael = tfm;
610 tkey->tfm_arc4 = tfm2;
611 if (len == TKIP_KEY_LEN) {
612 memcpy(tkey->key, key, TKIP_KEY_LEN);
614 tkey->tx_iv16 = 1; /* TSC is initialized to 1 */
616 tkey->rx_iv32 = (seq[5] << 24) | (seq[4] << 16) |
617 (seq[3] << 8) | seq[2];
618 tkey->rx_iv16 = (seq[1] << 8) | seq[0];
628 static int ieee80211_tkip_get_key(void *key, int len, u8 * seq, void *priv)
630 struct ieee80211_tkip_data *tkey = priv;
632 if (len < TKIP_KEY_LEN)
637 memcpy(key, tkey->key, TKIP_KEY_LEN);
640 /* Return the sequence number of the last transmitted frame. */
641 u16 iv16 = tkey->tx_iv16;
642 u32 iv32 = tkey->tx_iv32;
646 seq[0] = tkey->tx_iv16;
647 seq[1] = tkey->tx_iv16 >> 8;
648 seq[2] = tkey->tx_iv32;
649 seq[3] = tkey->tx_iv32 >> 8;
650 seq[4] = tkey->tx_iv32 >> 16;
651 seq[5] = tkey->tx_iv32 >> 24;
657 static char *ieee80211_tkip_print_stats(char *p, void *priv)
659 struct ieee80211_tkip_data *tkip = priv;
660 p += sprintf(p, "key[%d] alg=TKIP key_set=%d "
661 "tx_pn=%02x%02x%02x%02x%02x%02x "
662 "rx_pn=%02x%02x%02x%02x%02x%02x "
663 "replays=%d icv_errors=%d local_mic_failures=%d\n",
664 tkip->key_idx, tkip->key_set,
665 (tkip->tx_iv32 >> 24) & 0xff,
666 (tkip->tx_iv32 >> 16) & 0xff,
667 (tkip->tx_iv32 >> 8) & 0xff,
668 tkip->tx_iv32 & 0xff,
669 (tkip->tx_iv16 >> 8) & 0xff,
670 tkip->tx_iv16 & 0xff,
671 (tkip->rx_iv32 >> 24) & 0xff,
672 (tkip->rx_iv32 >> 16) & 0xff,
673 (tkip->rx_iv32 >> 8) & 0xff,
674 tkip->rx_iv32 & 0xff,
675 (tkip->rx_iv16 >> 8) & 0xff,
676 tkip->rx_iv16 & 0xff,
677 tkip->dot11RSNAStatsTKIPReplays,
678 tkip->dot11RSNAStatsTKIPICVErrors,
679 tkip->dot11RSNAStatsTKIPLocalMICFailures);
683 static struct ieee80211_crypto_ops ieee80211_crypt_tkip = {
685 .init = ieee80211_tkip_init,
686 .deinit = ieee80211_tkip_deinit,
687 .encrypt_mpdu = ieee80211_tkip_encrypt,
688 .decrypt_mpdu = ieee80211_tkip_decrypt,
689 .encrypt_msdu = ieee80211_michael_mic_add,
690 .decrypt_msdu = ieee80211_michael_mic_verify,
691 .set_key = ieee80211_tkip_set_key,
692 .get_key = ieee80211_tkip_get_key,
693 .print_stats = ieee80211_tkip_print_stats,
694 .extra_mpdu_prefix_len = 4 + 4, /* IV + ExtIV */
695 .extra_mpdu_postfix_len = 4, /* ICV */
696 .extra_msdu_postfix_len = 8, /* MIC */
697 .owner = THIS_MODULE,
700 static int __init ieee80211_crypto_tkip_init(void)
702 return ieee80211_register_crypto_ops(&ieee80211_crypt_tkip);
705 static void __exit ieee80211_crypto_tkip_exit(void)
707 ieee80211_unregister_crypto_ops(&ieee80211_crypt_tkip);
710 module_init(ieee80211_crypto_tkip_init);
711 module_exit(ieee80211_crypto_tkip_exit);