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];
64 static void *ieee80211_tkip_init(int key_idx)
66 struct ieee80211_tkip_data *priv;
68 priv = kmalloc(sizeof(*priv), GFP_ATOMIC);
71 memset(priv, 0, sizeof(*priv));
72 priv->key_idx = key_idx;
74 priv->tfm_arc4 = crypto_alloc_tfm("arc4", 0);
75 if (priv->tfm_arc4 == NULL) {
76 printk(KERN_DEBUG "ieee80211_crypt_tkip: could not allocate "
81 priv->tfm_michael = crypto_alloc_tfm("michael_mic", 0);
82 if (priv->tfm_michael == NULL) {
83 printk(KERN_DEBUG "ieee80211_crypt_tkip: could not allocate "
84 "crypto API michael_mic\n");
92 if (priv->tfm_michael)
93 crypto_free_tfm(priv->tfm_michael);
95 crypto_free_tfm(priv->tfm_arc4);
102 static void ieee80211_tkip_deinit(void *priv)
104 struct ieee80211_tkip_data *_priv = priv;
105 if (_priv && _priv->tfm_michael)
106 crypto_free_tfm(_priv->tfm_michael);
107 if (_priv && _priv->tfm_arc4)
108 crypto_free_tfm(_priv->tfm_arc4);
112 static inline u16 RotR1(u16 val)
114 return (val >> 1) | (val << 15);
117 static inline u8 Lo8(u16 val)
122 static inline u8 Hi8(u16 val)
127 static inline u16 Lo16(u32 val)
132 static inline u16 Hi16(u32 val)
137 static inline u16 Mk16(u8 hi, u8 lo)
139 return lo | (((u16) hi) << 8);
142 static inline u16 Mk16_le(u16 * v)
144 return le16_to_cpu(*v);
147 static const u16 Sbox[256] = {
148 0xC6A5, 0xF884, 0xEE99, 0xF68D, 0xFF0D, 0xD6BD, 0xDEB1, 0x9154,
149 0x6050, 0x0203, 0xCEA9, 0x567D, 0xE719, 0xB562, 0x4DE6, 0xEC9A,
150 0x8F45, 0x1F9D, 0x8940, 0xFA87, 0xEF15, 0xB2EB, 0x8EC9, 0xFB0B,
151 0x41EC, 0xB367, 0x5FFD, 0x45EA, 0x23BF, 0x53F7, 0xE496, 0x9B5B,
152 0x75C2, 0xE11C, 0x3DAE, 0x4C6A, 0x6C5A, 0x7E41, 0xF502, 0x834F,
153 0x685C, 0x51F4, 0xD134, 0xF908, 0xE293, 0xAB73, 0x6253, 0x2A3F,
154 0x080C, 0x9552, 0x4665, 0x9D5E, 0x3028, 0x37A1, 0x0A0F, 0x2FB5,
155 0x0E09, 0x2436, 0x1B9B, 0xDF3D, 0xCD26, 0x4E69, 0x7FCD, 0xEA9F,
156 0x121B, 0x1D9E, 0x5874, 0x342E, 0x362D, 0xDCB2, 0xB4EE, 0x5BFB,
157 0xA4F6, 0x764D, 0xB761, 0x7DCE, 0x527B, 0xDD3E, 0x5E71, 0x1397,
158 0xA6F5, 0xB968, 0x0000, 0xC12C, 0x4060, 0xE31F, 0x79C8, 0xB6ED,
159 0xD4BE, 0x8D46, 0x67D9, 0x724B, 0x94DE, 0x98D4, 0xB0E8, 0x854A,
160 0xBB6B, 0xC52A, 0x4FE5, 0xED16, 0x86C5, 0x9AD7, 0x6655, 0x1194,
161 0x8ACF, 0xE910, 0x0406, 0xFE81, 0xA0F0, 0x7844, 0x25BA, 0x4BE3,
162 0xA2F3, 0x5DFE, 0x80C0, 0x058A, 0x3FAD, 0x21BC, 0x7048, 0xF104,
163 0x63DF, 0x77C1, 0xAF75, 0x4263, 0x2030, 0xE51A, 0xFD0E, 0xBF6D,
164 0x814C, 0x1814, 0x2635, 0xC32F, 0xBEE1, 0x35A2, 0x88CC, 0x2E39,
165 0x9357, 0x55F2, 0xFC82, 0x7A47, 0xC8AC, 0xBAE7, 0x322B, 0xE695,
166 0xC0A0, 0x1998, 0x9ED1, 0xA37F, 0x4466, 0x547E, 0x3BAB, 0x0B83,
167 0x8CCA, 0xC729, 0x6BD3, 0x283C, 0xA779, 0xBCE2, 0x161D, 0xAD76,
168 0xDB3B, 0x6456, 0x744E, 0x141E, 0x92DB, 0x0C0A, 0x486C, 0xB8E4,
169 0x9F5D, 0xBD6E, 0x43EF, 0xC4A6, 0x39A8, 0x31A4, 0xD337, 0xF28B,
170 0xD532, 0x8B43, 0x6E59, 0xDAB7, 0x018C, 0xB164, 0x9CD2, 0x49E0,
171 0xD8B4, 0xACFA, 0xF307, 0xCF25, 0xCAAF, 0xF48E, 0x47E9, 0x1018,
172 0x6FD5, 0xF088, 0x4A6F, 0x5C72, 0x3824, 0x57F1, 0x73C7, 0x9751,
173 0xCB23, 0xA17C, 0xE89C, 0x3E21, 0x96DD, 0x61DC, 0x0D86, 0x0F85,
174 0xE090, 0x7C42, 0x71C4, 0xCCAA, 0x90D8, 0x0605, 0xF701, 0x1C12,
175 0xC2A3, 0x6A5F, 0xAEF9, 0x69D0, 0x1791, 0x9958, 0x3A27, 0x27B9,
176 0xD938, 0xEB13, 0x2BB3, 0x2233, 0xD2BB, 0xA970, 0x0789, 0x33A7,
177 0x2DB6, 0x3C22, 0x1592, 0xC920, 0x8749, 0xAAFF, 0x5078, 0xA57A,
178 0x038F, 0x59F8, 0x0980, 0x1A17, 0x65DA, 0xD731, 0x84C6, 0xD0B8,
179 0x82C3, 0x29B0, 0x5A77, 0x1E11, 0x7BCB, 0xA8FC, 0x6DD6, 0x2C3A,
182 static inline u16 _S_(u16 v)
184 u16 t = Sbox[Hi8(v)];
185 return Sbox[Lo8(v)] ^ ((t << 8) | (t >> 8));
188 #define PHASE1_LOOP_COUNT 8
190 static void tkip_mixing_phase1(u16 * TTAK, const u8 * TK, const u8 * TA,
195 /* Initialize the 80-bit TTAK from TSC (IV32) and TA[0..5] */
196 TTAK[0] = Lo16(IV32);
197 TTAK[1] = Hi16(IV32);
198 TTAK[2] = Mk16(TA[1], TA[0]);
199 TTAK[3] = Mk16(TA[3], TA[2]);
200 TTAK[4] = Mk16(TA[5], TA[4]);
202 for (i = 0; i < PHASE1_LOOP_COUNT; i++) {
204 TTAK[0] += _S_(TTAK[4] ^ Mk16(TK[1 + j], TK[0 + j]));
205 TTAK[1] += _S_(TTAK[0] ^ Mk16(TK[5 + j], TK[4 + j]));
206 TTAK[2] += _S_(TTAK[1] ^ Mk16(TK[9 + j], TK[8 + j]));
207 TTAK[3] += _S_(TTAK[2] ^ Mk16(TK[13 + j], TK[12 + j]));
208 TTAK[4] += _S_(TTAK[3] ^ Mk16(TK[1 + j], TK[0 + j])) + i;
212 static void tkip_mixing_phase2(u8 * WEPSeed, const u8 * TK, const u16 * TTAK,
215 /* Make temporary area overlap WEP seed so that the final copy can be
216 * avoided on little endian hosts. */
217 u16 *PPK = (u16 *) & WEPSeed[4];
219 /* Step 1 - make copy of TTAK and bring in TSC */
225 PPK[5] = TTAK[4] + IV16;
227 /* Step 2 - 96-bit bijective mixing using S-box */
228 PPK[0] += _S_(PPK[5] ^ Mk16_le((u16 *) & TK[0]));
229 PPK[1] += _S_(PPK[0] ^ Mk16_le((u16 *) & TK[2]));
230 PPK[2] += _S_(PPK[1] ^ Mk16_le((u16 *) & TK[4]));
231 PPK[3] += _S_(PPK[2] ^ Mk16_le((u16 *) & TK[6]));
232 PPK[4] += _S_(PPK[3] ^ Mk16_le((u16 *) & TK[8]));
233 PPK[5] += _S_(PPK[4] ^ Mk16_le((u16 *) & TK[10]));
235 PPK[0] += RotR1(PPK[5] ^ Mk16_le((u16 *) & TK[12]));
236 PPK[1] += RotR1(PPK[0] ^ Mk16_le((u16 *) & TK[14]));
237 PPK[2] += RotR1(PPK[1]);
238 PPK[3] += RotR1(PPK[2]);
239 PPK[4] += RotR1(PPK[3]);
240 PPK[5] += RotR1(PPK[4]);
242 /* Step 3 - bring in last of TK bits, assign 24-bit WEP IV value
243 * WEPSeed[0..2] is transmitted as WEP IV */
244 WEPSeed[0] = Hi8(IV16);
245 WEPSeed[1] = (Hi8(IV16) | 0x20) & 0x7F;
246 WEPSeed[2] = Lo8(IV16);
247 WEPSeed[3] = Lo8((PPK[5] ^ Mk16_le((u16 *) & TK[0])) >> 1);
252 for (i = 0; i < 6; i++)
253 PPK[i] = (PPK[i] << 8) | (PPK[i] >> 8);
258 static int ieee80211_tkip_encrypt(struct sk_buff *skb, int hdr_len, void *priv)
260 struct ieee80211_tkip_data *tkey = priv;
262 u8 rc4key[16], *pos, *icv;
263 struct ieee80211_hdr *hdr;
265 struct scatterlist sg;
267 if (skb_headroom(skb) < 8 || skb_tailroom(skb) < 4 ||
271 hdr = (struct ieee80211_hdr *)skb->data;
272 if (!tkey->tx_phase1_done) {
273 tkip_mixing_phase1(tkey->tx_ttak, tkey->key, hdr->addr2,
275 tkey->tx_phase1_done = 1;
277 tkip_mixing_phase2(rc4key, tkey->key, tkey->tx_ttak, tkey->tx_iv16);
279 len = skb->len - hdr_len;
280 pos = skb_push(skb, 8);
281 memmove(pos, pos + 8, hdr_len);
283 icv = skb_put(skb, 4);
288 *pos++ = (tkey->key_idx << 6) | (1 << 5) /* Ext IV included */ ;
289 *pos++ = tkey->tx_iv32 & 0xff;
290 *pos++ = (tkey->tx_iv32 >> 8) & 0xff;
291 *pos++ = (tkey->tx_iv32 >> 16) & 0xff;
292 *pos++ = (tkey->tx_iv32 >> 24) & 0xff;
294 crc = ~crc32_le(~0, pos, len);
300 crypto_cipher_setkey(tkey->tfm_arc4, rc4key, 16);
301 sg.page = virt_to_page(pos);
302 sg.offset = offset_in_page(pos);
304 crypto_cipher_encrypt(tkey->tfm_arc4, &sg, &sg, len + 4);
307 if (tkey->tx_iv16 == 0) {
308 tkey->tx_phase1_done = 0;
315 static int ieee80211_tkip_decrypt(struct sk_buff *skb, int hdr_len, void *priv)
317 struct ieee80211_tkip_data *tkey = priv;
322 struct ieee80211_hdr *hdr;
325 struct scatterlist sg;
328 if (skb->len < hdr_len + 8 + 4)
331 hdr = (struct ieee80211_hdr *)skb->data;
332 pos = skb->data + hdr_len;
334 if (!(keyidx & (1 << 5))) {
335 if (net_ratelimit()) {
336 printk(KERN_DEBUG "TKIP: received packet without ExtIV"
337 " flag from " MAC_FMT "\n", MAC_ARG(hdr->addr2));
342 if (tkey->key_idx != keyidx) {
343 printk(KERN_DEBUG "TKIP: RX tkey->key_idx=%d frame "
344 "keyidx=%d priv=%p\n", tkey->key_idx, keyidx, priv);
347 if (!tkey->key_set) {
348 if (net_ratelimit()) {
349 printk(KERN_DEBUG "TKIP: received packet from " MAC_FMT
350 " with keyid=%d that does not have a configured"
351 " key\n", MAC_ARG(hdr->addr2), keyidx);
355 iv16 = (pos[0] << 8) | pos[2];
356 iv32 = pos[4] | (pos[5] << 8) | (pos[6] << 16) | (pos[7] << 24);
359 if (iv32 < tkey->rx_iv32 ||
360 (iv32 == tkey->rx_iv32 && iv16 <= tkey->rx_iv16)) {
361 if (net_ratelimit()) {
362 printk(KERN_DEBUG "TKIP: replay detected: STA=" MAC_FMT
363 " previous TSC %08x%04x received TSC "
364 "%08x%04x\n", MAC_ARG(hdr->addr2),
365 tkey->rx_iv32, tkey->rx_iv16, iv32, iv16);
367 tkey->dot11RSNAStatsTKIPReplays++;
371 if (iv32 != tkey->rx_iv32 || !tkey->rx_phase1_done) {
372 tkip_mixing_phase1(tkey->rx_ttak, tkey->key, hdr->addr2, iv32);
373 tkey->rx_phase1_done = 1;
375 tkip_mixing_phase2(rc4key, tkey->key, tkey->rx_ttak, iv16);
377 plen = skb->len - hdr_len - 12;
379 crypto_cipher_setkey(tkey->tfm_arc4, rc4key, 16);
380 sg.page = virt_to_page(pos);
381 sg.offset = offset_in_page(pos);
382 sg.length = plen + 4;
383 crypto_cipher_decrypt(tkey->tfm_arc4, &sg, &sg, plen + 4);
385 crc = ~crc32_le(~0, pos, plen);
390 if (memcmp(icv, pos + plen, 4) != 0) {
391 if (iv32 != tkey->rx_iv32) {
392 /* Previously cached Phase1 result was already lost, so
393 * it needs to be recalculated for the next packet. */
394 tkey->rx_phase1_done = 0;
396 if (net_ratelimit()) {
397 printk(KERN_DEBUG "TKIP: ICV error detected: STA="
398 MAC_FMT "\n", MAC_ARG(hdr->addr2));
400 tkey->dot11RSNAStatsTKIPICVErrors++;
404 /* Update real counters only after Michael MIC verification has
406 tkey->rx_iv32_new = iv32;
407 tkey->rx_iv16_new = iv16;
409 /* Remove IV and ICV */
410 memmove(skb->data + 8, skb->data, hdr_len);
412 skb_trim(skb, skb->len - 4);
417 static int michael_mic(struct ieee80211_tkip_data *tkey, u8 * key, u8 * hdr,
418 u8 * data, size_t data_len, u8 * mic)
420 struct scatterlist sg[2];
422 if (tkey->tfm_michael == NULL) {
423 printk(KERN_WARNING "michael_mic: tfm_michael == NULL\n");
426 sg[0].page = virt_to_page(hdr);
427 sg[0].offset = offset_in_page(hdr);
430 sg[1].page = virt_to_page(data);
431 sg[1].offset = offset_in_page(data);
432 sg[1].length = data_len;
434 crypto_digest_init(tkey->tfm_michael);
435 crypto_digest_setkey(tkey->tfm_michael, key, 8);
436 crypto_digest_update(tkey->tfm_michael, sg, 2);
437 crypto_digest_final(tkey->tfm_michael, mic);
442 static void michael_mic_hdr(struct sk_buff *skb, u8 * hdr)
444 struct ieee80211_hdr *hdr11;
446 hdr11 = (struct ieee80211_hdr *)skb->data;
447 switch (le16_to_cpu(hdr11->frame_ctl) &
448 (IEEE80211_FCTL_FROMDS | IEEE80211_FCTL_TODS)) {
449 case IEEE80211_FCTL_TODS:
450 memcpy(hdr, hdr11->addr3, ETH_ALEN); /* DA */
451 memcpy(hdr + ETH_ALEN, hdr11->addr2, ETH_ALEN); /* SA */
453 case IEEE80211_FCTL_FROMDS:
454 memcpy(hdr, hdr11->addr1, ETH_ALEN); /* DA */
455 memcpy(hdr + ETH_ALEN, hdr11->addr3, ETH_ALEN); /* SA */
457 case IEEE80211_FCTL_FROMDS | IEEE80211_FCTL_TODS:
458 memcpy(hdr, hdr11->addr3, ETH_ALEN); /* DA */
459 memcpy(hdr + ETH_ALEN, hdr11->addr4, ETH_ALEN); /* SA */
462 memcpy(hdr, hdr11->addr1, ETH_ALEN); /* DA */
463 memcpy(hdr + ETH_ALEN, hdr11->addr2, ETH_ALEN); /* SA */
467 hdr[12] = 0; /* priority */
468 hdr[13] = hdr[14] = hdr[15] = 0; /* reserved */
471 static int ieee80211_michael_mic_add(struct sk_buff *skb, int hdr_len,
474 struct ieee80211_tkip_data *tkey = priv;
477 if (skb_tailroom(skb) < 8 || skb->len < hdr_len) {
478 printk(KERN_DEBUG "Invalid packet for Michael MIC add "
479 "(tailroom=%d hdr_len=%d skb->len=%d)\n",
480 skb_tailroom(skb), hdr_len, skb->len);
484 michael_mic_hdr(skb, tkey->tx_hdr);
485 pos = skb_put(skb, 8);
486 if (michael_mic(tkey, &tkey->key[16], tkey->tx_hdr,
487 skb->data + hdr_len, skb->len - 8 - hdr_len, pos))
493 #if WIRELESS_EXT >= 18
494 static void ieee80211_michael_mic_failure(struct net_device *dev,
495 struct ieee80211_hdr *hdr, int keyidx)
497 union iwreq_data wrqu;
498 struct iw_michaelmicfailure ev;
500 /* TODO: needed parameters: count, keyid, key type, TSC */
501 memset(&ev, 0, sizeof(ev));
502 ev.flags = keyidx & IW_MICFAILURE_KEY_ID;
503 if (hdr->addr1[0] & 0x01)
504 ev.flags |= IW_MICFAILURE_GROUP;
506 ev.flags |= IW_MICFAILURE_PAIRWISE;
507 ev.src_addr.sa_family = ARPHRD_ETHER;
508 memcpy(ev.src_addr.sa_data, hdr->addr2, ETH_ALEN);
509 memset(&wrqu, 0, sizeof(wrqu));
510 wrqu.data.length = sizeof(ev);
511 wireless_send_event(dev, IWEVMICHAELMICFAILURE, &wrqu, (char *)&ev);
513 #elif WIRELESS_EXT >= 15
514 static void ieee80211_michael_mic_failure(struct net_device *dev,
515 struct ieee80211_hdr *hdr, int keyidx)
517 union iwreq_data wrqu;
520 /* TODO: needed parameters: count, keyid, key type, TSC */
521 sprintf(buf, "MLME-MICHAELMICFAILURE.indication(keyid=%d %scast addr="
522 MAC_FMT ")", keyidx, hdr->addr1[0] & 0x01 ? "broad" : "uni",
523 MAC_ARG(hdr->addr2));
524 memset(&wrqu, 0, sizeof(wrqu));
525 wrqu.data.length = strlen(buf);
526 wireless_send_event(dev, IWEVCUSTOM, &wrqu, buf);
528 #else /* WIRELESS_EXT >= 15 */
529 static inline void ieee80211_michael_mic_failure(struct net_device *dev,
530 struct ieee80211_hdr *hdr,
534 #endif /* WIRELESS_EXT >= 15 */
536 static int ieee80211_michael_mic_verify(struct sk_buff *skb, int keyidx,
537 int hdr_len, void *priv)
539 struct ieee80211_tkip_data *tkey = priv;
545 michael_mic_hdr(skb, tkey->rx_hdr);
546 if (michael_mic(tkey, &tkey->key[24], tkey->rx_hdr,
547 skb->data + hdr_len, skb->len - 8 - hdr_len, mic))
549 if (memcmp(mic, skb->data + skb->len - 8, 8) != 0) {
550 struct ieee80211_hdr *hdr;
551 hdr = (struct ieee80211_hdr *)skb->data;
552 printk(KERN_DEBUG "%s: Michael MIC verification failed for "
553 "MSDU from " MAC_FMT " keyidx=%d\n",
554 skb->dev ? skb->dev->name : "N/A", MAC_ARG(hdr->addr2),
557 ieee80211_michael_mic_failure(skb->dev, hdr, keyidx);
558 tkey->dot11RSNAStatsTKIPLocalMICFailures++;
562 /* Update TSC counters for RX now that the packet verification has
564 tkey->rx_iv32 = tkey->rx_iv32_new;
565 tkey->rx_iv16 = tkey->rx_iv16_new;
567 skb_trim(skb, skb->len - 8);
572 static int ieee80211_tkip_set_key(void *key, int len, u8 * seq, void *priv)
574 struct ieee80211_tkip_data *tkey = priv;
576 struct crypto_tfm *tfm = tkey->tfm_michael;
577 struct crypto_tfm *tfm2 = tkey->tfm_arc4;
579 keyidx = tkey->key_idx;
580 memset(tkey, 0, sizeof(*tkey));
581 tkey->key_idx = keyidx;
582 tkey->tfm_michael = tfm;
583 tkey->tfm_arc4 = tfm2;
584 if (len == TKIP_KEY_LEN) {
585 memcpy(tkey->key, key, TKIP_KEY_LEN);
587 tkey->tx_iv16 = 1; /* TSC is initialized to 1 */
589 tkey->rx_iv32 = (seq[5] << 24) | (seq[4] << 16) |
590 (seq[3] << 8) | seq[2];
591 tkey->rx_iv16 = (seq[1] << 8) | seq[0];
601 static int ieee80211_tkip_get_key(void *key, int len, u8 * seq, void *priv)
603 struct ieee80211_tkip_data *tkey = priv;
605 if (len < TKIP_KEY_LEN)
610 memcpy(key, tkey->key, TKIP_KEY_LEN);
613 /* Return the sequence number of the last transmitted frame. */
614 u16 iv16 = tkey->tx_iv16;
615 u32 iv32 = tkey->tx_iv32;
619 seq[0] = tkey->tx_iv16;
620 seq[1] = tkey->tx_iv16 >> 8;
621 seq[2] = tkey->tx_iv32;
622 seq[3] = tkey->tx_iv32 >> 8;
623 seq[4] = tkey->tx_iv32 >> 16;
624 seq[5] = tkey->tx_iv32 >> 24;
630 static char *ieee80211_tkip_print_stats(char *p, void *priv)
632 struct ieee80211_tkip_data *tkip = priv;
633 p += sprintf(p, "key[%d] alg=TKIP key_set=%d "
634 "tx_pn=%02x%02x%02x%02x%02x%02x "
635 "rx_pn=%02x%02x%02x%02x%02x%02x "
636 "replays=%d icv_errors=%d local_mic_failures=%d\n",
637 tkip->key_idx, tkip->key_set,
638 (tkip->tx_iv32 >> 24) & 0xff,
639 (tkip->tx_iv32 >> 16) & 0xff,
640 (tkip->tx_iv32 >> 8) & 0xff,
641 tkip->tx_iv32 & 0xff,
642 (tkip->tx_iv16 >> 8) & 0xff,
643 tkip->tx_iv16 & 0xff,
644 (tkip->rx_iv32 >> 24) & 0xff,
645 (tkip->rx_iv32 >> 16) & 0xff,
646 (tkip->rx_iv32 >> 8) & 0xff,
647 tkip->rx_iv32 & 0xff,
648 (tkip->rx_iv16 >> 8) & 0xff,
649 tkip->rx_iv16 & 0xff,
650 tkip->dot11RSNAStatsTKIPReplays,
651 tkip->dot11RSNAStatsTKIPICVErrors,
652 tkip->dot11RSNAStatsTKIPLocalMICFailures);
656 static struct ieee80211_crypto_ops ieee80211_crypt_tkip = {
658 .init = ieee80211_tkip_init,
659 .deinit = ieee80211_tkip_deinit,
660 .encrypt_mpdu = ieee80211_tkip_encrypt,
661 .decrypt_mpdu = ieee80211_tkip_decrypt,
662 .encrypt_msdu = ieee80211_michael_mic_add,
663 .decrypt_msdu = ieee80211_michael_mic_verify,
664 .set_key = ieee80211_tkip_set_key,
665 .get_key = ieee80211_tkip_get_key,
666 .print_stats = ieee80211_tkip_print_stats,
667 .extra_prefix_len = 4 + 4, /* IV + ExtIV */
668 .extra_postfix_len = 8 + 4, /* MIC + ICV */
669 .owner = THIS_MODULE,
672 static int __init ieee80211_crypto_tkip_init(void)
674 return ieee80211_register_crypto_ops(&ieee80211_crypt_tkip);
677 static void __exit ieee80211_crypto_tkip_exit(void)
679 ieee80211_unregister_crypto_ops(&ieee80211_crypt_tkip);
682 module_init(ieee80211_crypto_tkip_init);
683 module_exit(ieee80211_crypto_tkip_exit);