1 // SPDX-License-Identifier: GPL-2.0
3 * Host AP crypt: host-based TKIP encryption implementation for Host AP driver
5 * Copyright (c) 2003-2004, Jouni Malinen <jkmaline@cc.hut.fi>
8 #include <linux/fips.h>
9 #include <linux/module.h>
10 #include <linux/init.h>
11 #include <linux/slab.h>
12 #include <linux/random.h>
13 #include <linux/skbuff.h>
14 #include <linux/netdevice.h>
15 #include <linux/if_ether.h>
16 #include <linux/if_arp.h>
17 #include <linux/string.h>
19 #include "ieee80211.h"
21 #include <crypto/arc4.h>
22 #include <crypto/hash.h>
23 #include <linux/crc32.h>
25 MODULE_AUTHOR("Jouni Malinen");
26 MODULE_DESCRIPTION("Host AP crypt: TKIP");
27 MODULE_LICENSE("GPL");
29 struct ieee80211_tkip_data {
30 #define TKIP_KEY_LEN 32
46 u32 dot11RSNAStatsTKIPReplays;
47 u32 dot11RSNAStatsTKIPICVErrors;
48 u32 dot11RSNAStatsTKIPLocalMICFailures;
52 struct arc4_ctx rx_ctx_arc4;
53 struct arc4_ctx tx_ctx_arc4;
54 struct crypto_shash *rx_tfm_michael;
55 struct crypto_shash *tx_tfm_michael;
57 /* scratch buffers for virt_to_page() (crypto API) */
58 u8 rx_hdr[16], tx_hdr[16];
61 static void *ieee80211_tkip_init(int key_idx)
63 struct ieee80211_tkip_data *priv;
68 priv = kzalloc(sizeof(*priv), GFP_KERNEL);
71 priv->key_idx = key_idx;
73 priv->tx_tfm_michael = crypto_alloc_shash("michael_mic", 0, 0);
74 if (IS_ERR(priv->tx_tfm_michael)) {
75 printk(KERN_DEBUG "ieee80211_crypt_tkip: could not allocate "
76 "crypto API michael_mic\n");
77 priv->tx_tfm_michael = NULL;
81 priv->rx_tfm_michael = crypto_alloc_shash("michael_mic", 0, 0);
82 if (IS_ERR(priv->rx_tfm_michael)) {
83 printk(KERN_DEBUG "ieee80211_crypt_tkip: could not allocate "
84 "crypto API michael_mic\n");
85 priv->rx_tfm_michael = NULL;
93 crypto_free_shash(priv->tx_tfm_michael);
94 crypto_free_shash(priv->rx_tfm_michael);
102 static void ieee80211_tkip_deinit(void *priv)
104 struct ieee80211_tkip_data *_priv = priv;
107 crypto_free_shash(_priv->tx_tfm_michael);
108 crypto_free_shash(_priv->rx_tfm_michael);
110 kfree_sensitive(priv);
114 static inline u16 RotR1(u16 val)
116 return (val >> 1) | (val << 15);
120 static inline u8 Lo8(u16 val)
126 static inline u8 Hi8(u16 val)
132 static inline u16 Lo16(u32 val)
138 static inline u16 Hi16(u32 val)
144 static inline u16 Mk16(u8 hi, u8 lo)
146 return lo | (((u16)hi) << 8);
149 static const u16 Sbox[256] = {
150 0xC6A5, 0xF884, 0xEE99, 0xF68D, 0xFF0D, 0xD6BD, 0xDEB1, 0x9154,
151 0x6050, 0x0203, 0xCEA9, 0x567D, 0xE719, 0xB562, 0x4DE6, 0xEC9A,
152 0x8F45, 0x1F9D, 0x8940, 0xFA87, 0xEF15, 0xB2EB, 0x8EC9, 0xFB0B,
153 0x41EC, 0xB367, 0x5FFD, 0x45EA, 0x23BF, 0x53F7, 0xE496, 0x9B5B,
154 0x75C2, 0xE11C, 0x3DAE, 0x4C6A, 0x6C5A, 0x7E41, 0xF502, 0x834F,
155 0x685C, 0x51F4, 0xD134, 0xF908, 0xE293, 0xAB73, 0x6253, 0x2A3F,
156 0x080C, 0x9552, 0x4665, 0x9D5E, 0x3028, 0x37A1, 0x0A0F, 0x2FB5,
157 0x0E09, 0x2436, 0x1B9B, 0xDF3D, 0xCD26, 0x4E69, 0x7FCD, 0xEA9F,
158 0x121B, 0x1D9E, 0x5874, 0x342E, 0x362D, 0xDCB2, 0xB4EE, 0x5BFB,
159 0xA4F6, 0x764D, 0xB761, 0x7DCE, 0x527B, 0xDD3E, 0x5E71, 0x1397,
160 0xA6F5, 0xB968, 0x0000, 0xC12C, 0x4060, 0xE31F, 0x79C8, 0xB6ED,
161 0xD4BE, 0x8D46, 0x67D9, 0x724B, 0x94DE, 0x98D4, 0xB0E8, 0x854A,
162 0xBB6B, 0xC52A, 0x4FE5, 0xED16, 0x86C5, 0x9AD7, 0x6655, 0x1194,
163 0x8ACF, 0xE910, 0x0406, 0xFE81, 0xA0F0, 0x7844, 0x25BA, 0x4BE3,
164 0xA2F3, 0x5DFE, 0x80C0, 0x058A, 0x3FAD, 0x21BC, 0x7048, 0xF104,
165 0x63DF, 0x77C1, 0xAF75, 0x4263, 0x2030, 0xE51A, 0xFD0E, 0xBF6D,
166 0x814C, 0x1814, 0x2635, 0xC32F, 0xBEE1, 0x35A2, 0x88CC, 0x2E39,
167 0x9357, 0x55F2, 0xFC82, 0x7A47, 0xC8AC, 0xBAE7, 0x322B, 0xE695,
168 0xC0A0, 0x1998, 0x9ED1, 0xA37F, 0x4466, 0x547E, 0x3BAB, 0x0B83,
169 0x8CCA, 0xC729, 0x6BD3, 0x283C, 0xA779, 0xBCE2, 0x161D, 0xAD76,
170 0xDB3B, 0x6456, 0x744E, 0x141E, 0x92DB, 0x0C0A, 0x486C, 0xB8E4,
171 0x9F5D, 0xBD6E, 0x43EF, 0xC4A6, 0x39A8, 0x31A4, 0xD337, 0xF28B,
172 0xD532, 0x8B43, 0x6E59, 0xDAB7, 0x018C, 0xB164, 0x9CD2, 0x49E0,
173 0xD8B4, 0xACFA, 0xF307, 0xCF25, 0xCAAF, 0xF48E, 0x47E9, 0x1018,
174 0x6FD5, 0xF088, 0x4A6F, 0x5C72, 0x3824, 0x57F1, 0x73C7, 0x9751,
175 0xCB23, 0xA17C, 0xE89C, 0x3E21, 0x96DD, 0x61DC, 0x0D86, 0x0F85,
176 0xE090, 0x7C42, 0x71C4, 0xCCAA, 0x90D8, 0x0605, 0xF701, 0x1C12,
177 0xC2A3, 0x6A5F, 0xAEF9, 0x69D0, 0x1791, 0x9958, 0x3A27, 0x27B9,
178 0xD938, 0xEB13, 0x2BB3, 0x2233, 0xD2BB, 0xA970, 0x0789, 0x33A7,
179 0x2DB6, 0x3C22, 0x1592, 0xC920, 0x8749, 0xAAFF, 0x5078, 0xA57A,
180 0x038F, 0x59F8, 0x0980, 0x1A17, 0x65DA, 0xD731, 0x84C6, 0xD0B8,
181 0x82C3, 0x29B0, 0x5A77, 0x1E11, 0x7BCB, 0xA8FC, 0x6DD6, 0x2C3A,
185 static inline u16 _S_(u16 v)
187 u16 t = Sbox[Hi8(v)];
188 return Sbox[Lo8(v)] ^ ((t << 8) | (t >> 8));
192 #define PHASE1_LOOP_COUNT 8
195 static void tkip_mixing_phase1(u16 *TTAK, const u8 *TK, const u8 *TA, u32 IV32)
199 /* Initialize the 80-bit TTAK from TSC (IV32) and TA[0..5] */
200 TTAK[0] = Lo16(IV32);
201 TTAK[1] = Hi16(IV32);
202 TTAK[2] = Mk16(TA[1], TA[0]);
203 TTAK[3] = Mk16(TA[3], TA[2]);
204 TTAK[4] = Mk16(TA[5], TA[4]);
206 for (i = 0; i < PHASE1_LOOP_COUNT; i++) {
208 TTAK[0] += _S_(TTAK[4] ^ Mk16(TK[1 + j], TK[0 + j]));
209 TTAK[1] += _S_(TTAK[0] ^ Mk16(TK[5 + j], TK[4 + j]));
210 TTAK[2] += _S_(TTAK[1] ^ Mk16(TK[9 + j], TK[8 + j]));
211 TTAK[3] += _S_(TTAK[2] ^ Mk16(TK[13 + j], TK[12 + j]));
212 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,
221 * Make temporary area overlap WEP seed so that the final copy can be
222 * avoided on little endian hosts.
224 u16 *PPK = (u16 *)&WEPSeed[4];
226 /* Step 1 - make copy of TTAK and bring in TSC */
232 PPK[5] = TTAK[4] + IV16;
234 /* Step 2 - 96-bit bijective mixing using S-box */
235 PPK[0] += _S_(PPK[5] ^ le16_to_cpu(*(__le16 *)(&TK[0])));
236 PPK[1] += _S_(PPK[0] ^ le16_to_cpu(*(__le16 *)(&TK[2])));
237 PPK[2] += _S_(PPK[1] ^ le16_to_cpu(*(__le16 *)(&TK[4])));
238 PPK[3] += _S_(PPK[2] ^ le16_to_cpu(*(__le16 *)(&TK[6])));
239 PPK[4] += _S_(PPK[3] ^ le16_to_cpu(*(__le16 *)(&TK[8])));
240 PPK[5] += _S_(PPK[4] ^ le16_to_cpu(*(__le16 *)(&TK[10])));
242 PPK[0] += RotR1(PPK[5] ^ le16_to_cpu(*(__le16 *)(&TK[12])));
243 PPK[1] += RotR1(PPK[0] ^ le16_to_cpu(*(__le16 *)(&TK[14])));
244 PPK[2] += RotR1(PPK[1]);
245 PPK[3] += RotR1(PPK[2]);
246 PPK[4] += RotR1(PPK[3]);
247 PPK[5] += RotR1(PPK[4]);
250 * Step 3 - bring in last of TK bits, assign 24-bit WEP IV value
251 * WEPSeed[0..2] is transmitted as WEP IV
253 WEPSeed[0] = Hi8(IV16);
254 WEPSeed[1] = (Hi8(IV16) | 0x20) & 0x7F;
255 WEPSeed[2] = Lo8(IV16);
256 WEPSeed[3] = Lo8((PPK[5] ^ le16_to_cpu(*(__le16 *)(&TK[0]))) >> 1);
262 for (i = 0; i < 6; i++)
263 PPK[i] = (PPK[i] << 8) | (PPK[i] >> 8);
269 static int ieee80211_tkip_encrypt(struct sk_buff *skb, int hdr_len, void *priv)
271 struct ieee80211_tkip_data *tkey = priv;
274 struct rtl_80211_hdr_4addr *hdr;
275 struct cb_desc *tcb_desc = (struct cb_desc *)(skb->cb + MAX_DEV_ADDR_SIZE);
279 if (skb_headroom(skb) < 8 || skb_tailroom(skb) < 4 ||
283 hdr = (struct rtl_80211_hdr_4addr *)skb->data;
285 if (!tcb_desc->bHwSec) {
286 if (!tkey->tx_phase1_done) {
287 tkip_mixing_phase1(tkey->tx_ttak, tkey->key, hdr->addr2,
289 tkey->tx_phase1_done = 1;
291 tkip_mixing_phase2(rc4key, tkey->key, tkey->tx_ttak, tkey->tx_iv16);
293 tkey->tx_phase1_done = 1;
296 len = skb->len - hdr_len;
297 pos = skb_push(skb, 8);
298 memmove(pos, pos + 8, hdr_len);
301 if (tcb_desc->bHwSec) {
302 *pos++ = Hi8(tkey->tx_iv16);
303 *pos++ = (Hi8(tkey->tx_iv16) | 0x20) & 0x7F;
304 *pos++ = Lo8(tkey->tx_iv16);
311 *pos++ = (tkey->key_idx << 6) | BIT(5) /* Ext IV included */;
312 *pos++ = tkey->tx_iv32 & 0xff;
313 *pos++ = (tkey->tx_iv32 >> 8) & 0xff;
314 *pos++ = (tkey->tx_iv32 >> 16) & 0xff;
315 *pos++ = (tkey->tx_iv32 >> 24) & 0xff;
317 if (!tcb_desc->bHwSec) {
318 icv = skb_put(skb, 4);
319 crc = ~crc32_le(~0, pos, len);
325 arc4_setkey(&tkey->tx_ctx_arc4, rc4key, 16);
326 arc4_crypt(&tkey->tx_ctx_arc4, pos, pos, len + 4);
330 if (tkey->tx_iv16 == 0) {
331 tkey->tx_phase1_done = 0;
338 static int ieee80211_tkip_decrypt(struct sk_buff *skb, int hdr_len, void *priv)
340 struct ieee80211_tkip_data *tkey = priv;
344 struct rtl_80211_hdr_4addr *hdr;
345 struct cb_desc *tcb_desc = (struct cb_desc *)(skb->cb + MAX_DEV_ADDR_SIZE);
351 if (skb->len < hdr_len + 8 + 4)
354 hdr = (struct rtl_80211_hdr_4addr *)skb->data;
355 pos = skb->data + hdr_len;
357 if (!(keyidx & BIT(5))) {
358 if (net_ratelimit()) {
359 netdev_dbg(skb->dev, "TKIP: received packet without ExtIV"
360 " flag from %pM\n", hdr->addr2);
365 if (tkey->key_idx != keyidx) {
366 netdev_dbg(skb->dev, "TKIP: RX tkey->key_idx=%d frame "
367 "keyidx=%d priv=%p\n", tkey->key_idx, keyidx, priv);
370 if (!tkey->key_set) {
371 if (net_ratelimit()) {
372 netdev_dbg(skb->dev, "TKIP: received packet from %pM"
373 " with keyid=%d that does not have a configured"
374 " key\n", hdr->addr2, keyidx);
378 iv16 = (pos[0] << 8) | pos[2];
379 iv32 = pos[4] | (pos[5] << 8) | (pos[6] << 16) | (pos[7] << 24);
382 if (!tcb_desc->bHwSec) {
383 if (iv32 < tkey->rx_iv32 ||
384 (iv32 == tkey->rx_iv32 && iv16 <= tkey->rx_iv16)) {
385 if (net_ratelimit()) {
386 netdev_dbg(skb->dev, "TKIP: replay detected: STA=%pM"
387 " previous TSC %08x%04x received TSC "
388 "%08x%04x\n", hdr->addr2,
389 tkey->rx_iv32, tkey->rx_iv16, iv32, iv16);
391 tkey->dot11RSNAStatsTKIPReplays++;
395 if (iv32 != tkey->rx_iv32 || !tkey->rx_phase1_done) {
396 tkip_mixing_phase1(tkey->rx_ttak, tkey->key, hdr->addr2, iv32);
397 tkey->rx_phase1_done = 1;
399 tkip_mixing_phase2(rc4key, tkey->key, tkey->rx_ttak, iv16);
401 plen = skb->len - hdr_len - 12;
403 arc4_setkey(&tkey->rx_ctx_arc4, rc4key, 16);
404 arc4_crypt(&tkey->rx_ctx_arc4, pos, pos, plen + 4);
406 crc = ~crc32_le(~0, pos, plen);
412 if (memcmp(icv, pos + plen, 4) != 0) {
413 if (iv32 != tkey->rx_iv32) {
415 * Previously cached Phase1 result was already
416 * lost, so it needs to be recalculated for the
419 tkey->rx_phase1_done = 0;
421 if (net_ratelimit()) {
422 netdev_dbg(skb->dev, "TKIP: ICV error detected: STA="
423 "%pM\n", hdr->addr2);
425 tkey->dot11RSNAStatsTKIPICVErrors++;
432 * Update real counters only after Michael MIC verification has
435 tkey->rx_iv32_new = iv32;
436 tkey->rx_iv16_new = iv16;
438 /* Remove IV and ICV */
439 memmove(skb->data + 8, skb->data, hdr_len);
441 skb_trim(skb, skb->len - 4);
446 static int michael_mic(struct crypto_shash *tfm_michael, u8 *key, u8 *hdr,
447 u8 *data, size_t data_len, u8 *mic)
449 SHASH_DESC_ON_STACK(desc, tfm_michael);
452 desc->tfm = tfm_michael;
454 if (crypto_shash_setkey(tfm_michael, key, 8))
457 err = crypto_shash_init(desc);
460 err = crypto_shash_update(desc, hdr, 16);
463 err = crypto_shash_update(desc, data, data_len);
466 err = crypto_shash_final(desc, mic);
469 shash_desc_zero(desc);
473 static void michael_mic_hdr(struct sk_buff *skb, u8 *hdr)
475 struct rtl_80211_hdr_4addr *hdr11;
477 hdr11 = (struct rtl_80211_hdr_4addr *)skb->data;
478 switch (le16_to_cpu(hdr11->frame_ctl) &
479 (IEEE80211_FCTL_FROMDS | IEEE80211_FCTL_TODS)) {
480 case IEEE80211_FCTL_TODS:
481 memcpy(hdr, hdr11->addr3, ETH_ALEN); /* DA */
482 memcpy(hdr + ETH_ALEN, hdr11->addr2, ETH_ALEN); /* SA */
484 case IEEE80211_FCTL_FROMDS:
485 memcpy(hdr, hdr11->addr1, ETH_ALEN); /* DA */
486 memcpy(hdr + ETH_ALEN, hdr11->addr3, ETH_ALEN); /* SA */
488 case IEEE80211_FCTL_FROMDS | IEEE80211_FCTL_TODS:
489 memcpy(hdr, hdr11->addr3, ETH_ALEN); /* DA */
490 memcpy(hdr + ETH_ALEN, hdr11->addr4, ETH_ALEN); /* SA */
493 memcpy(hdr, hdr11->addr1, ETH_ALEN); /* DA */
494 memcpy(hdr + ETH_ALEN, hdr11->addr2, ETH_ALEN); /* SA */
498 hdr[12] = 0; /* priority */
500 hdr[13] = hdr[14] = hdr[15] = 0; /* reserved */
504 static int ieee80211_michael_mic_add(struct sk_buff *skb, int hdr_len, void *priv)
506 struct ieee80211_tkip_data *tkey = priv;
508 struct rtl_80211_hdr_4addr *hdr;
510 hdr = (struct rtl_80211_hdr_4addr *)skb->data;
512 if (skb_tailroom(skb) < 8 || skb->len < hdr_len) {
513 netdev_dbg(skb->dev, "Invalid packet for Michael MIC add "
514 "(tailroom=%d hdr_len=%d skb->len=%d)\n",
515 skb_tailroom(skb), hdr_len, skb->len);
519 michael_mic_hdr(skb, tkey->tx_hdr);
522 // fix the wpa process with wmm enabled.
523 if (IEEE80211_QOS_HAS_SEQ(le16_to_cpu(hdr->frame_ctl)))
524 tkey->tx_hdr[12] = *(skb->data + hdr_len - 2) & 0x07;
526 pos = skb_put(skb, 8);
528 if (michael_mic(tkey->tx_tfm_michael, &tkey->key[16], tkey->tx_hdr,
529 skb->data + hdr_len, skb->len - 8 - hdr_len, pos))
535 static void ieee80211_michael_mic_failure(struct net_device *dev,
536 struct rtl_80211_hdr_4addr *hdr,
539 union iwreq_data wrqu;
540 struct iw_michaelmicfailure ev;
542 /* TODO: needed parameters: count, keyid, key type, TSC */
543 memset(&ev, 0, sizeof(ev));
544 ev.flags = keyidx & IW_MICFAILURE_KEY_ID;
545 if (hdr->addr1[0] & 0x01)
546 ev.flags |= IW_MICFAILURE_GROUP;
548 ev.flags |= IW_MICFAILURE_PAIRWISE;
549 ev.src_addr.sa_family = ARPHRD_ETHER;
550 memcpy(ev.src_addr.sa_data, hdr->addr2, ETH_ALEN);
551 memset(&wrqu, 0, sizeof(wrqu));
552 wrqu.data.length = sizeof(ev);
553 wireless_send_event(dev, IWEVMICHAELMICFAILURE, &wrqu, (char *)&ev);
556 static int ieee80211_michael_mic_verify(struct sk_buff *skb, int keyidx,
557 int hdr_len, void *priv)
559 struct ieee80211_tkip_data *tkey = priv;
561 struct rtl_80211_hdr_4addr *hdr;
563 hdr = (struct rtl_80211_hdr_4addr *)skb->data;
568 michael_mic_hdr(skb, tkey->rx_hdr);
570 // fix the wpa process with wmm enabled.
571 if (IEEE80211_QOS_HAS_SEQ(le16_to_cpu(hdr->frame_ctl)))
572 tkey->rx_hdr[12] = *(skb->data + hdr_len - 2) & 0x07;
575 if (michael_mic(tkey->rx_tfm_michael, &tkey->key[24], tkey->rx_hdr,
576 skb->data + hdr_len, skb->len - 8 - hdr_len, mic))
578 if (memcmp(mic, skb->data + skb->len - 8, 8) != 0) {
579 struct rtl_80211_hdr_4addr *hdr;
580 hdr = (struct rtl_80211_hdr_4addr *)skb->data;
582 netdev_dbg(skb->dev, "Michael MIC verification failed for "
583 "MSDU from %pM keyidx=%d\n",
586 ieee80211_michael_mic_failure(skb->dev, hdr, keyidx);
587 tkey->dot11RSNAStatsTKIPLocalMICFailures++;
592 * Update TSC counters for RX now that the packet verification has
595 tkey->rx_iv32 = tkey->rx_iv32_new;
596 tkey->rx_iv16 = tkey->rx_iv16_new;
598 skb_trim(skb, skb->len - 8);
604 static int ieee80211_tkip_set_key(void *key, int len, u8 *seq, void *priv)
606 struct ieee80211_tkip_data *tkey = priv;
608 struct crypto_shash *tfm = tkey->tx_tfm_michael;
609 struct crypto_shash *tfm3 = tkey->rx_tfm_michael;
611 keyidx = tkey->key_idx;
612 memset(tkey, 0, sizeof(*tkey));
613 tkey->key_idx = keyidx;
614 tkey->tx_tfm_michael = tfm;
615 tkey->rx_tfm_michael = tfm3;
617 if (len == TKIP_KEY_LEN) {
618 memcpy(tkey->key, key, TKIP_KEY_LEN);
620 tkey->tx_iv16 = 1; /* TSC is initialized to 1 */
622 tkey->rx_iv32 = (seq[5] << 24) | (seq[4] << 16) |
623 (seq[3] << 8) | seq[2];
624 tkey->rx_iv16 = (seq[1] << 8) | seq[0];
635 static int ieee80211_tkip_get_key(void *key, int len, u8 *seq, void *priv)
637 struct ieee80211_tkip_data *tkey = priv;
639 if (len < TKIP_KEY_LEN)
644 memcpy(key, tkey->key, TKIP_KEY_LEN);
647 /* Return the sequence number of the last transmitted frame. */
648 u16 iv16 = tkey->tx_iv16;
649 u32 iv32 = tkey->tx_iv32;
654 seq[0] = tkey->tx_iv16;
655 seq[1] = tkey->tx_iv16 >> 8;
656 seq[2] = tkey->tx_iv32;
657 seq[3] = tkey->tx_iv32 >> 8;
658 seq[4] = tkey->tx_iv32 >> 16;
659 seq[5] = tkey->tx_iv32 >> 24;
666 static char *ieee80211_tkip_print_stats(char *p, void *priv)
668 struct ieee80211_tkip_data *tkip = priv;
670 p += sprintf(p, "key[%d] alg=TKIP key_set=%d "
671 "tx_pn=%02x%02x%02x%02x%02x%02x "
672 "rx_pn=%02x%02x%02x%02x%02x%02x "
673 "replays=%d icv_errors=%d local_mic_failures=%d\n",
674 tkip->key_idx, tkip->key_set,
675 (tkip->tx_iv32 >> 24) & 0xff,
676 (tkip->tx_iv32 >> 16) & 0xff,
677 (tkip->tx_iv32 >> 8) & 0xff,
678 tkip->tx_iv32 & 0xff,
679 (tkip->tx_iv16 >> 8) & 0xff,
680 tkip->tx_iv16 & 0xff,
681 (tkip->rx_iv32 >> 24) & 0xff,
682 (tkip->rx_iv32 >> 16) & 0xff,
683 (tkip->rx_iv32 >> 8) & 0xff,
684 tkip->rx_iv32 & 0xff,
685 (tkip->rx_iv16 >> 8) & 0xff,
686 tkip->rx_iv16 & 0xff,
687 tkip->dot11RSNAStatsTKIPReplays,
688 tkip->dot11RSNAStatsTKIPICVErrors,
689 tkip->dot11RSNAStatsTKIPLocalMICFailures);
694 static struct ieee80211_crypto_ops ieee80211_crypt_tkip = {
696 .init = ieee80211_tkip_init,
697 .deinit = ieee80211_tkip_deinit,
698 .encrypt_mpdu = ieee80211_tkip_encrypt,
699 .decrypt_mpdu = ieee80211_tkip_decrypt,
700 .encrypt_msdu = ieee80211_michael_mic_add,
701 .decrypt_msdu = ieee80211_michael_mic_verify,
702 .set_key = ieee80211_tkip_set_key,
703 .get_key = ieee80211_tkip_get_key,
704 .print_stats = ieee80211_tkip_print_stats,
705 .extra_prefix_len = 4 + 4, /* IV + ExtIV */
706 .extra_postfix_len = 8 + 4, /* MIC + ICV */
707 .owner = THIS_MODULE,
710 int __init ieee80211_crypto_tkip_init(void)
712 return ieee80211_register_crypto_ops(&ieee80211_crypt_tkip);
715 void __exit ieee80211_crypto_tkip_exit(void)
717 ieee80211_unregister_crypto_ops(&ieee80211_crypt_tkip);
720 void ieee80211_tkip_null(void)
722 // printk("============>%s()\n", __func__);