1 // SPDX-License-Identifier: GPL-2.0-only
3 * libipw crypt: host-based TKIP encryption implementation for libipw
5 * Copyright (c) 2003-2004, Jouni Malinen <j@w1.fi>
6 * Copyright (c) 2008, John W. Linville <linville@tuxdriver.com>
9 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
11 #include <linux/err.h>
12 #include <linux/fips.h>
13 #include <linux/module.h>
14 #include <linux/init.h>
15 #include <linux/slab.h>
16 #include <linux/random.h>
17 #include <linux/scatterlist.h>
18 #include <linux/skbuff.h>
19 #include <linux/netdevice.h>
21 #include <linux/if_ether.h>
22 #include <linux/if_arp.h>
23 #include <asm/string.h>
24 #include <linux/wireless.h>
25 #include <linux/ieee80211.h>
26 #include <net/iw_handler.h>
27 #include <crypto/arc4.h>
28 #include <crypto/hash.h>
29 #include <linux/crypto.h>
30 #include <linux/crc32.h>
33 #define TKIP_HDR_LEN 8
35 struct libipw_tkip_data
{
36 #define TKIP_KEY_LEN 32
52 u32 dot11RSNAStatsTKIPReplays
;
53 u32 dot11RSNAStatsTKIPICVErrors
;
54 u32 dot11RSNAStatsTKIPLocalMICFailures
;
58 struct arc4_ctx rx_ctx_arc4
;
59 struct arc4_ctx tx_ctx_arc4
;
60 struct crypto_shash
*rx_tfm_michael
;
61 struct crypto_shash
*tx_tfm_michael
;
63 /* scratch buffers for virt_to_page() (crypto API) */
64 u8 rx_hdr
[16], tx_hdr
[16];
69 static unsigned long libipw_tkip_set_flags(unsigned long flags
, void *priv
)
71 struct libipw_tkip_data
*_priv
= priv
;
72 unsigned long old_flags
= _priv
->flags
;
77 static unsigned long libipw_tkip_get_flags(void *priv
)
79 struct libipw_tkip_data
*_priv
= priv
;
83 static void *libipw_tkip_init(int key_idx
)
85 struct libipw_tkip_data
*priv
;
90 priv
= kzalloc(sizeof(*priv
), GFP_ATOMIC
);
94 priv
->key_idx
= key_idx
;
96 priv
->tx_tfm_michael
= crypto_alloc_shash("michael_mic", 0, 0);
97 if (IS_ERR(priv
->tx_tfm_michael
)) {
98 priv
->tx_tfm_michael
= NULL
;
102 priv
->rx_tfm_michael
= crypto_alloc_shash("michael_mic", 0, 0);
103 if (IS_ERR(priv
->rx_tfm_michael
)) {
104 priv
->rx_tfm_michael
= NULL
;
112 crypto_free_shash(priv
->tx_tfm_michael
);
113 crypto_free_shash(priv
->rx_tfm_michael
);
120 static void libipw_tkip_deinit(void *priv
)
122 struct libipw_tkip_data
*_priv
= priv
;
124 crypto_free_shash(_priv
->tx_tfm_michael
);
125 crypto_free_shash(_priv
->rx_tfm_michael
);
127 kfree_sensitive(priv
);
130 static inline u16
RotR1(u16 val
)
132 return (val
>> 1) | (val
<< 15);
135 static inline u8
Lo8(u16 val
)
140 static inline u8
Hi8(u16 val
)
145 static inline u16
Lo16(u32 val
)
150 static inline u16
Hi16(u32 val
)
155 static inline u16
Mk16(u8 hi
, u8 lo
)
157 return lo
| (((u16
) hi
) << 8);
160 static inline u16
Mk16_le(__le16
* v
)
162 return le16_to_cpu(*v
);
165 static const u16 Sbox
[256] = {
166 0xC6A5, 0xF884, 0xEE99, 0xF68D, 0xFF0D, 0xD6BD, 0xDEB1, 0x9154,
167 0x6050, 0x0203, 0xCEA9, 0x567D, 0xE719, 0xB562, 0x4DE6, 0xEC9A,
168 0x8F45, 0x1F9D, 0x8940, 0xFA87, 0xEF15, 0xB2EB, 0x8EC9, 0xFB0B,
169 0x41EC, 0xB367, 0x5FFD, 0x45EA, 0x23BF, 0x53F7, 0xE496, 0x9B5B,
170 0x75C2, 0xE11C, 0x3DAE, 0x4C6A, 0x6C5A, 0x7E41, 0xF502, 0x834F,
171 0x685C, 0x51F4, 0xD134, 0xF908, 0xE293, 0xAB73, 0x6253, 0x2A3F,
172 0x080C, 0x9552, 0x4665, 0x9D5E, 0x3028, 0x37A1, 0x0A0F, 0x2FB5,
173 0x0E09, 0x2436, 0x1B9B, 0xDF3D, 0xCD26, 0x4E69, 0x7FCD, 0xEA9F,
174 0x121B, 0x1D9E, 0x5874, 0x342E, 0x362D, 0xDCB2, 0xB4EE, 0x5BFB,
175 0xA4F6, 0x764D, 0xB761, 0x7DCE, 0x527B, 0xDD3E, 0x5E71, 0x1397,
176 0xA6F5, 0xB968, 0x0000, 0xC12C, 0x4060, 0xE31F, 0x79C8, 0xB6ED,
177 0xD4BE, 0x8D46, 0x67D9, 0x724B, 0x94DE, 0x98D4, 0xB0E8, 0x854A,
178 0xBB6B, 0xC52A, 0x4FE5, 0xED16, 0x86C5, 0x9AD7, 0x6655, 0x1194,
179 0x8ACF, 0xE910, 0x0406, 0xFE81, 0xA0F0, 0x7844, 0x25BA, 0x4BE3,
180 0xA2F3, 0x5DFE, 0x80C0, 0x058A, 0x3FAD, 0x21BC, 0x7048, 0xF104,
181 0x63DF, 0x77C1, 0xAF75, 0x4263, 0x2030, 0xE51A, 0xFD0E, 0xBF6D,
182 0x814C, 0x1814, 0x2635, 0xC32F, 0xBEE1, 0x35A2, 0x88CC, 0x2E39,
183 0x9357, 0x55F2, 0xFC82, 0x7A47, 0xC8AC, 0xBAE7, 0x322B, 0xE695,
184 0xC0A0, 0x1998, 0x9ED1, 0xA37F, 0x4466, 0x547E, 0x3BAB, 0x0B83,
185 0x8CCA, 0xC729, 0x6BD3, 0x283C, 0xA779, 0xBCE2, 0x161D, 0xAD76,
186 0xDB3B, 0x6456, 0x744E, 0x141E, 0x92DB, 0x0C0A, 0x486C, 0xB8E4,
187 0x9F5D, 0xBD6E, 0x43EF, 0xC4A6, 0x39A8, 0x31A4, 0xD337, 0xF28B,
188 0xD532, 0x8B43, 0x6E59, 0xDAB7, 0x018C, 0xB164, 0x9CD2, 0x49E0,
189 0xD8B4, 0xACFA, 0xF307, 0xCF25, 0xCAAF, 0xF48E, 0x47E9, 0x1018,
190 0x6FD5, 0xF088, 0x4A6F, 0x5C72, 0x3824, 0x57F1, 0x73C7, 0x9751,
191 0xCB23, 0xA17C, 0xE89C, 0x3E21, 0x96DD, 0x61DC, 0x0D86, 0x0F85,
192 0xE090, 0x7C42, 0x71C4, 0xCCAA, 0x90D8, 0x0605, 0xF701, 0x1C12,
193 0xC2A3, 0x6A5F, 0xAEF9, 0x69D0, 0x1791, 0x9958, 0x3A27, 0x27B9,
194 0xD938, 0xEB13, 0x2BB3, 0x2233, 0xD2BB, 0xA970, 0x0789, 0x33A7,
195 0x2DB6, 0x3C22, 0x1592, 0xC920, 0x8749, 0xAAFF, 0x5078, 0xA57A,
196 0x038F, 0x59F8, 0x0980, 0x1A17, 0x65DA, 0xD731, 0x84C6, 0xD0B8,
197 0x82C3, 0x29B0, 0x5A77, 0x1E11, 0x7BCB, 0xA8FC, 0x6DD6, 0x2C3A,
200 static inline u16
_S_(u16 v
)
202 u16 t
= Sbox
[Hi8(v
)];
203 return Sbox
[Lo8(v
)] ^ ((t
<< 8) | (t
>> 8));
206 #define PHASE1_LOOP_COUNT 8
208 static void tkip_mixing_phase1(u16
* TTAK
, const u8
* TK
, const u8
* TA
,
213 /* Initialize the 80-bit TTAK from TSC (IV32) and TA[0..5] */
214 TTAK
[0] = Lo16(IV32
);
215 TTAK
[1] = Hi16(IV32
);
216 TTAK
[2] = Mk16(TA
[1], TA
[0]);
217 TTAK
[3] = Mk16(TA
[3], TA
[2]);
218 TTAK
[4] = Mk16(TA
[5], TA
[4]);
220 for (i
= 0; i
< PHASE1_LOOP_COUNT
; i
++) {
222 TTAK
[0] += _S_(TTAK
[4] ^ Mk16(TK
[1 + j
], TK
[0 + j
]));
223 TTAK
[1] += _S_(TTAK
[0] ^ Mk16(TK
[5 + j
], TK
[4 + j
]));
224 TTAK
[2] += _S_(TTAK
[1] ^ Mk16(TK
[9 + j
], TK
[8 + j
]));
225 TTAK
[3] += _S_(TTAK
[2] ^ Mk16(TK
[13 + j
], TK
[12 + j
]));
226 TTAK
[4] += _S_(TTAK
[3] ^ Mk16(TK
[1 + j
], TK
[0 + j
])) + i
;
230 static void tkip_mixing_phase2(u8
* WEPSeed
, const u8
* TK
, const u16
* TTAK
,
233 /* Make temporary area overlap WEP seed so that the final copy can be
234 * avoided on little endian hosts. */
235 u16
*PPK
= (u16
*) & WEPSeed
[4];
237 /* Step 1 - make copy of TTAK and bring in TSC */
243 PPK
[5] = TTAK
[4] + IV16
;
245 /* Step 2 - 96-bit bijective mixing using S-box */
246 PPK
[0] += _S_(PPK
[5] ^ Mk16_le((__le16
*) & TK
[0]));
247 PPK
[1] += _S_(PPK
[0] ^ Mk16_le((__le16
*) & TK
[2]));
248 PPK
[2] += _S_(PPK
[1] ^ Mk16_le((__le16
*) & TK
[4]));
249 PPK
[3] += _S_(PPK
[2] ^ Mk16_le((__le16
*) & TK
[6]));
250 PPK
[4] += _S_(PPK
[3] ^ Mk16_le((__le16
*) & TK
[8]));
251 PPK
[5] += _S_(PPK
[4] ^ Mk16_le((__le16
*) & TK
[10]));
253 PPK
[0] += RotR1(PPK
[5] ^ Mk16_le((__le16
*) & TK
[12]));
254 PPK
[1] += RotR1(PPK
[0] ^ Mk16_le((__le16
*) & TK
[14]));
255 PPK
[2] += RotR1(PPK
[1]);
256 PPK
[3] += RotR1(PPK
[2]);
257 PPK
[4] += RotR1(PPK
[3]);
258 PPK
[5] += RotR1(PPK
[4]);
260 /* Step 3 - bring in last of TK bits, assign 24-bit WEP IV value
261 * WEPSeed[0..2] is transmitted as WEP IV */
262 WEPSeed
[0] = Hi8(IV16
);
263 WEPSeed
[1] = (Hi8(IV16
) | 0x20) & 0x7F;
264 WEPSeed
[2] = Lo8(IV16
);
265 WEPSeed
[3] = Lo8((PPK
[5] ^ Mk16_le((__le16
*) & TK
[0])) >> 1);
270 for (i
= 0; i
< 6; i
++)
271 PPK
[i
] = (PPK
[i
] << 8) | (PPK
[i
] >> 8);
276 static int libipw_tkip_hdr(struct sk_buff
*skb
, int hdr_len
,
277 u8
* rc4key
, int keylen
, void *priv
)
279 struct libipw_tkip_data
*tkey
= priv
;
281 struct ieee80211_hdr
*hdr
;
283 hdr
= (struct ieee80211_hdr
*)skb
->data
;
285 if (skb_headroom(skb
) < TKIP_HDR_LEN
|| skb
->len
< hdr_len
)
288 if (rc4key
== NULL
|| keylen
< 16)
291 if (!tkey
->tx_phase1_done
) {
292 tkip_mixing_phase1(tkey
->tx_ttak
, tkey
->key
, hdr
->addr2
,
294 tkey
->tx_phase1_done
= 1;
296 tkip_mixing_phase2(rc4key
, tkey
->key
, tkey
->tx_ttak
, tkey
->tx_iv16
);
298 pos
= skb_push(skb
, TKIP_HDR_LEN
);
299 memmove(pos
, pos
+ TKIP_HDR_LEN
, hdr_len
);
303 *pos
++ = *(rc4key
+ 1);
304 *pos
++ = *(rc4key
+ 2);
305 *pos
++ = (tkey
->key_idx
<< 6) | (1 << 5) /* Ext IV included */ ;
306 *pos
++ = tkey
->tx_iv32
& 0xff;
307 *pos
++ = (tkey
->tx_iv32
>> 8) & 0xff;
308 *pos
++ = (tkey
->tx_iv32
>> 16) & 0xff;
309 *pos
++ = (tkey
->tx_iv32
>> 24) & 0xff;
312 if (tkey
->tx_iv16
== 0) {
313 tkey
->tx_phase1_done
= 0;
320 static int libipw_tkip_encrypt(struct sk_buff
*skb
, int hdr_len
, void *priv
)
322 struct libipw_tkip_data
*tkey
= priv
;
324 u8 rc4key
[16], *pos
, *icv
;
327 if (tkey
->flags
& IEEE80211_CRYPTO_TKIP_COUNTERMEASURES
) {
328 struct ieee80211_hdr
*hdr
= (struct ieee80211_hdr
*)skb
->data
;
329 net_dbg_ratelimited("TKIP countermeasures: dropped TX packet to %pM\n",
334 if (skb_tailroom(skb
) < 4 || skb
->len
< hdr_len
)
337 len
= skb
->len
- hdr_len
;
338 pos
= skb
->data
+ hdr_len
;
340 if ((libipw_tkip_hdr(skb
, hdr_len
, rc4key
, 16, priv
)) < 0)
343 crc
= ~crc32_le(~0, pos
, len
);
344 icv
= skb_put(skb
, 4);
350 arc4_setkey(&tkey
->tx_ctx_arc4
, rc4key
, 16);
351 arc4_crypt(&tkey
->tx_ctx_arc4
, pos
, pos
, len
+ 4);
357 * deal with seq counter wrapping correctly.
358 * refer to timer_after() for jiffies wrapping handling
360 static inline int tkip_replay_check(u32 iv32_n
, u16 iv16_n
,
361 u32 iv32_o
, u16 iv16_o
)
363 if ((s32
)iv32_n
- (s32
)iv32_o
< 0 ||
364 (iv32_n
== iv32_o
&& iv16_n
<= iv16_o
))
369 static int libipw_tkip_decrypt(struct sk_buff
*skb
, int hdr_len
, void *priv
)
371 struct libipw_tkip_data
*tkey
= priv
;
376 struct ieee80211_hdr
*hdr
;
381 hdr
= (struct ieee80211_hdr
*)skb
->data
;
383 if (tkey
->flags
& IEEE80211_CRYPTO_TKIP_COUNTERMEASURES
) {
384 net_dbg_ratelimited("TKIP countermeasures: dropped received packet from %pM\n",
389 if (skb
->len
< hdr_len
+ TKIP_HDR_LEN
+ 4)
392 pos
= skb
->data
+ hdr_len
;
394 if (!(keyidx
& (1 << 5))) {
395 net_dbg_ratelimited("TKIP: received packet without ExtIV flag from %pM\n",
400 if (tkey
->key_idx
!= keyidx
) {
401 net_dbg_ratelimited("TKIP: RX tkey->key_idx=%d frame keyidx=%d\n",
402 tkey
->key_idx
, keyidx
);
405 if (!tkey
->key_set
) {
406 net_dbg_ratelimited("TKIP: received packet from %pM with keyid=%d that does not have a configured key\n",
410 iv16
= (pos
[0] << 8) | pos
[2];
411 iv32
= pos
[4] | (pos
[5] << 8) | (pos
[6] << 16) | (pos
[7] << 24);
414 if (tkip_replay_check(iv32
, iv16
, tkey
->rx_iv32
, tkey
->rx_iv16
)) {
415 #ifdef CONFIG_LIBIPW_DEBUG
416 net_dbg_ratelimited("TKIP: replay detected: STA=%pM previous TSC %08x%04x received TSC %08x%04x\n",
417 hdr
->addr2
, tkey
->rx_iv32
, tkey
->rx_iv16
,
420 tkey
->dot11RSNAStatsTKIPReplays
++;
424 if (iv32
!= tkey
->rx_iv32
|| !tkey
->rx_phase1_done
) {
425 tkip_mixing_phase1(tkey
->rx_ttak
, tkey
->key
, hdr
->addr2
, iv32
);
426 tkey
->rx_phase1_done
= 1;
428 tkip_mixing_phase2(rc4key
, tkey
->key
, tkey
->rx_ttak
, iv16
);
430 plen
= skb
->len
- hdr_len
- 12;
432 arc4_setkey(&tkey
->rx_ctx_arc4
, rc4key
, 16);
433 arc4_crypt(&tkey
->rx_ctx_arc4
, pos
, pos
, plen
+ 4);
435 crc
= ~crc32_le(~0, pos
, plen
);
440 if (memcmp(icv
, pos
+ plen
, 4) != 0) {
441 if (iv32
!= tkey
->rx_iv32
) {
442 /* Previously cached Phase1 result was already lost, so
443 * it needs to be recalculated for the next packet. */
444 tkey
->rx_phase1_done
= 0;
446 #ifdef CONFIG_LIBIPW_DEBUG
447 net_dbg_ratelimited("TKIP: ICV error detected: STA=%pM\n",
450 tkey
->dot11RSNAStatsTKIPICVErrors
++;
454 /* Update real counters only after Michael MIC verification has
456 tkey
->rx_iv32_new
= iv32
;
457 tkey
->rx_iv16_new
= iv16
;
459 /* Remove IV and ICV */
460 memmove(skb
->data
+ TKIP_HDR_LEN
, skb
->data
, hdr_len
);
461 skb_pull(skb
, TKIP_HDR_LEN
);
462 skb_trim(skb
, skb
->len
- 4);
467 static int michael_mic(struct crypto_shash
*tfm_michael
, u8
*key
, u8
*hdr
,
468 u8
*data
, size_t data_len
, u8
*mic
)
470 SHASH_DESC_ON_STACK(desc
, tfm_michael
);
473 if (tfm_michael
== NULL
) {
474 pr_warn("%s(): tfm_michael == NULL\n", __func__
);
478 desc
->tfm
= tfm_michael
;
480 if (crypto_shash_setkey(tfm_michael
, key
, 8))
483 err
= crypto_shash_init(desc
);
486 err
= crypto_shash_update(desc
, hdr
, 16);
489 err
= crypto_shash_update(desc
, data
, data_len
);
492 err
= crypto_shash_final(desc
, mic
);
495 shash_desc_zero(desc
);
499 static void michael_mic_hdr(struct sk_buff
*skb
, u8
* hdr
)
501 struct ieee80211_hdr
*hdr11
;
503 hdr11
= (struct ieee80211_hdr
*)skb
->data
;
505 switch (le16_to_cpu(hdr11
->frame_control
) &
506 (IEEE80211_FCTL_FROMDS
| IEEE80211_FCTL_TODS
)) {
507 case IEEE80211_FCTL_TODS
:
508 memcpy(hdr
, hdr11
->addr3
, ETH_ALEN
); /* DA */
509 memcpy(hdr
+ ETH_ALEN
, hdr11
->addr2
, ETH_ALEN
); /* SA */
511 case IEEE80211_FCTL_FROMDS
:
512 memcpy(hdr
, hdr11
->addr1
, ETH_ALEN
); /* DA */
513 memcpy(hdr
+ ETH_ALEN
, hdr11
->addr3
, ETH_ALEN
); /* SA */
515 case IEEE80211_FCTL_FROMDS
| IEEE80211_FCTL_TODS
:
516 memcpy(hdr
, hdr11
->addr3
, ETH_ALEN
); /* DA */
517 memcpy(hdr
+ ETH_ALEN
, hdr11
->addr4
, ETH_ALEN
); /* SA */
520 memcpy(hdr
, hdr11
->addr1
, ETH_ALEN
); /* DA */
521 memcpy(hdr
+ ETH_ALEN
, hdr11
->addr2
, ETH_ALEN
); /* SA */
525 if (ieee80211_is_data_qos(hdr11
->frame_control
)) {
526 hdr
[12] = le16_to_cpu(*((__le16
*)ieee80211_get_qos_ctl(hdr11
)))
527 & IEEE80211_QOS_CTL_TID_MASK
;
529 hdr
[12] = 0; /* priority */
531 hdr
[13] = hdr
[14] = hdr
[15] = 0; /* reserved */
534 static int libipw_michael_mic_add(struct sk_buff
*skb
, int hdr_len
,
537 struct libipw_tkip_data
*tkey
= priv
;
540 if (skb_tailroom(skb
) < 8 || skb
->len
< hdr_len
) {
541 printk(KERN_DEBUG
"Invalid packet for Michael MIC add "
542 "(tailroom=%d hdr_len=%d skb->len=%d)\n",
543 skb_tailroom(skb
), hdr_len
, skb
->len
);
547 michael_mic_hdr(skb
, tkey
->tx_hdr
);
548 pos
= skb_put(skb
, 8);
549 if (michael_mic(tkey
->tx_tfm_michael
, &tkey
->key
[16], tkey
->tx_hdr
,
550 skb
->data
+ hdr_len
, skb
->len
- 8 - hdr_len
, pos
))
556 static void libipw_michael_mic_failure(struct net_device
*dev
,
557 struct ieee80211_hdr
*hdr
,
560 union iwreq_data wrqu
;
561 struct iw_michaelmicfailure ev
;
563 /* TODO: needed parameters: count, keyid, key type, TSC */
564 memset(&ev
, 0, sizeof(ev
));
565 ev
.flags
= keyidx
& IW_MICFAILURE_KEY_ID
;
566 if (hdr
->addr1
[0] & 0x01)
567 ev
.flags
|= IW_MICFAILURE_GROUP
;
569 ev
.flags
|= IW_MICFAILURE_PAIRWISE
;
570 ev
.src_addr
.sa_family
= ARPHRD_ETHER
;
571 memcpy(ev
.src_addr
.sa_data
, hdr
->addr2
, ETH_ALEN
);
572 memset(&wrqu
, 0, sizeof(wrqu
));
573 wrqu
.data
.length
= sizeof(ev
);
574 wireless_send_event(dev
, IWEVMICHAELMICFAILURE
, &wrqu
, (char *)&ev
);
577 static int libipw_michael_mic_verify(struct sk_buff
*skb
, int keyidx
,
578 int hdr_len
, void *priv
)
580 struct libipw_tkip_data
*tkey
= priv
;
586 michael_mic_hdr(skb
, tkey
->rx_hdr
);
587 if (michael_mic(tkey
->rx_tfm_michael
, &tkey
->key
[24], tkey
->rx_hdr
,
588 skb
->data
+ hdr_len
, skb
->len
- 8 - hdr_len
, mic
))
590 if (memcmp(mic
, skb
->data
+ skb
->len
- 8, 8) != 0) {
591 struct ieee80211_hdr
*hdr
;
592 hdr
= (struct ieee80211_hdr
*)skb
->data
;
593 printk(KERN_DEBUG
"%s: Michael MIC verification failed for "
594 "MSDU from %pM keyidx=%d\n",
595 skb
->dev
? skb
->dev
->name
: "N/A", hdr
->addr2
,
598 libipw_michael_mic_failure(skb
->dev
, hdr
, keyidx
);
599 tkey
->dot11RSNAStatsTKIPLocalMICFailures
++;
603 /* Update TSC counters for RX now that the packet verification has
605 tkey
->rx_iv32
= tkey
->rx_iv32_new
;
606 tkey
->rx_iv16
= tkey
->rx_iv16_new
;
608 skb_trim(skb
, skb
->len
- 8);
613 static int libipw_tkip_set_key(void *key
, int len
, u8
* seq
, void *priv
)
615 struct libipw_tkip_data
*tkey
= priv
;
617 struct crypto_shash
*tfm
= tkey
->tx_tfm_michael
;
618 struct arc4_ctx
*tfm2
= &tkey
->tx_ctx_arc4
;
619 struct crypto_shash
*tfm3
= tkey
->rx_tfm_michael
;
620 struct arc4_ctx
*tfm4
= &tkey
->rx_ctx_arc4
;
622 keyidx
= tkey
->key_idx
;
623 memset(tkey
, 0, sizeof(*tkey
));
624 tkey
->key_idx
= keyidx
;
625 tkey
->tx_tfm_michael
= tfm
;
626 tkey
->tx_ctx_arc4
= *tfm2
;
627 tkey
->rx_tfm_michael
= tfm3
;
628 tkey
->rx_ctx_arc4
= *tfm4
;
629 if (len
== TKIP_KEY_LEN
) {
630 memcpy(tkey
->key
, key
, TKIP_KEY_LEN
);
632 tkey
->tx_iv16
= 1; /* TSC is initialized to 1 */
634 tkey
->rx_iv32
= (seq
[5] << 24) | (seq
[4] << 16) |
635 (seq
[3] << 8) | seq
[2];
636 tkey
->rx_iv16
= (seq
[1] << 8) | seq
[0];
646 static int libipw_tkip_get_key(void *key
, int len
, u8
* seq
, void *priv
)
648 struct libipw_tkip_data
*tkey
= priv
;
650 if (len
< TKIP_KEY_LEN
)
655 memcpy(key
, tkey
->key
, TKIP_KEY_LEN
);
659 * Not clear if this should return the value as is
660 * or - as the code previously seemed to partially
661 * have been written as - subtract one from it. It
662 * was working this way for a long time so leave it.
664 seq
[0] = tkey
->tx_iv16
;
665 seq
[1] = tkey
->tx_iv16
>> 8;
666 seq
[2] = tkey
->tx_iv32
;
667 seq
[3] = tkey
->tx_iv32
>> 8;
668 seq
[4] = tkey
->tx_iv32
>> 16;
669 seq
[5] = tkey
->tx_iv32
>> 24;
675 static void libipw_tkip_print_stats(struct seq_file
*m
, void *priv
)
677 struct libipw_tkip_data
*tkip
= priv
;
679 "key[%d] alg=TKIP key_set=%d "
680 "tx_pn=%02x%02x%02x%02x%02x%02x "
681 "rx_pn=%02x%02x%02x%02x%02x%02x "
682 "replays=%d icv_errors=%d local_mic_failures=%d\n",
683 tkip
->key_idx
, tkip
->key_set
,
684 (tkip
->tx_iv32
>> 24) & 0xff,
685 (tkip
->tx_iv32
>> 16) & 0xff,
686 (tkip
->tx_iv32
>> 8) & 0xff,
687 tkip
->tx_iv32
& 0xff,
688 (tkip
->tx_iv16
>> 8) & 0xff,
689 tkip
->tx_iv16
& 0xff,
690 (tkip
->rx_iv32
>> 24) & 0xff,
691 (tkip
->rx_iv32
>> 16) & 0xff,
692 (tkip
->rx_iv32
>> 8) & 0xff,
693 tkip
->rx_iv32
& 0xff,
694 (tkip
->rx_iv16
>> 8) & 0xff,
695 tkip
->rx_iv16
& 0xff,
696 tkip
->dot11RSNAStatsTKIPReplays
,
697 tkip
->dot11RSNAStatsTKIPICVErrors
,
698 tkip
->dot11RSNAStatsTKIPLocalMICFailures
);
701 static const struct libipw_crypto_ops libipw_crypt_tkip
= {
703 .init
= libipw_tkip_init
,
704 .deinit
= libipw_tkip_deinit
,
705 .encrypt_mpdu
= libipw_tkip_encrypt
,
706 .decrypt_mpdu
= libipw_tkip_decrypt
,
707 .encrypt_msdu
= libipw_michael_mic_add
,
708 .decrypt_msdu
= libipw_michael_mic_verify
,
709 .set_key
= libipw_tkip_set_key
,
710 .get_key
= libipw_tkip_get_key
,
711 .print_stats
= libipw_tkip_print_stats
,
712 .extra_mpdu_prefix_len
= 4 + 4, /* IV + ExtIV */
713 .extra_mpdu_postfix_len
= 4, /* ICV */
714 .extra_msdu_postfix_len
= 8, /* MIC */
715 .get_flags
= libipw_tkip_get_flags
,
716 .set_flags
= libipw_tkip_set_flags
,
717 .owner
= THIS_MODULE
,
720 int __init
libipw_crypto_tkip_init(void)
722 return libipw_register_crypto_ops(&libipw_crypt_tkip
);
725 void libipw_crypto_tkip_exit(void)
727 libipw_unregister_crypto_ops(&libipw_crypt_tkip
);