File Index
Files and directories
Sign in
FILE

libipw_crypto_tkip.c

File preview with syntax highlighting.

linux-6.19.14/drivers/net/wireless/intel/ipw2x00/libipw_crypto_tkip.c C
  1// SPDX-License-Identifier: GPL-2.0-only
  2/*
  3 * libipw crypt: host-based TKIP encryption implementation for libipw
  4 *
  5 * Copyright (c) 2003-2004, Jouni Malinen <j@w1.fi>
  6 * Copyright (c) 2008, John W. Linville <linville@tuxdriver.com>
  7 */
  8
  9#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
 10
 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>
 20#include <linux/mm.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>
 31#include "libipw.h"
 32
 33#define TKIP_HDR_LEN 8
 34
 35struct libipw_tkip_data {
 36#define TKIP_KEY_LEN 32
 37	u8 key[TKIP_KEY_LEN];
 38	int key_set;
 39
 40	u32 tx_iv32;
 41	u16 tx_iv16;
 42	u16 tx_ttak[5];
 43	int tx_phase1_done;
 44
 45	u32 rx_iv32;
 46	u16 rx_iv16;
 47	u16 rx_ttak[5];
 48	int rx_phase1_done;
 49	u32 rx_iv32_new;
 50	u16 rx_iv16_new;
 51
 52	u32 dot11RSNAStatsTKIPReplays;
 53	u32 dot11RSNAStatsTKIPICVErrors;
 54	u32 dot11RSNAStatsTKIPLocalMICFailures;
 55
 56	int key_idx;
 57
 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;
 62
 63	/* scratch buffers for virt_to_page() (crypto API) */
 64	u8 rx_hdr[16], tx_hdr[16];
 65
 66	unsigned long flags;
 67};
 68
 69static unsigned long libipw_tkip_set_flags(unsigned long flags, void *priv)
 70{
 71	struct libipw_tkip_data *_priv = priv;
 72	unsigned long old_flags = _priv->flags;
 73	_priv->flags = flags;
 74	return old_flags;
 75}
 76
 77static unsigned long libipw_tkip_get_flags(void *priv)
 78{
 79	struct libipw_tkip_data *_priv = priv;
 80	return _priv->flags;
 81}
 82
 83static void *libipw_tkip_init(int key_idx)
 84{
 85	struct libipw_tkip_data *priv;
 86
 87	if (fips_enabled)
 88		return NULL;
 89
 90	priv = kzalloc(sizeof(*priv), GFP_ATOMIC);
 91	if (priv == NULL)
 92		goto fail;
 93
 94	priv->key_idx = key_idx;
 95
 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;
 99		goto fail;
100	}
101
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;
105		goto fail;
106	}
107
108	return priv;
109
110      fail:
111	if (priv) {
112		crypto_free_shash(priv->tx_tfm_michael);
113		crypto_free_shash(priv->rx_tfm_michael);
114		kfree(priv);
115	}
116
117	return NULL;
118}
119
120static void libipw_tkip_deinit(void *priv)
121{
122	struct libipw_tkip_data *_priv = priv;
123	if (_priv) {
124		crypto_free_shash(_priv->tx_tfm_michael);
125		crypto_free_shash(_priv->rx_tfm_michael);
126	}
127	kfree_sensitive(priv);
128}
129
130static inline u16 RotR1(u16 val)
131{
132	return (val >> 1) | (val << 15);
133}
134
135static inline u8 Lo8(u16 val)
136{
137	return val & 0xff;
138}
139
140static inline u8 Hi8(u16 val)
141{
142	return val >> 8;
143}
144
145static inline u16 Lo16(u32 val)
146{
147	return val & 0xffff;
148}
149
150static inline u16 Hi16(u32 val)
151{
152	return val >> 16;
153}
154
155static inline u16 Mk16(u8 hi, u8 lo)
156{
157	return lo | (((u16) hi) << 8);
158}
159
160static inline u16 Mk16_le(__le16 * v)
161{
162	return le16_to_cpu(*v);
163}
164
165static 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,
198};
199
200static inline u16 _S_(u16 v)
201{
202	u16 t = Sbox[Hi8(v)];
203	return Sbox[Lo8(v)] ^ ((t << 8) | (t >> 8));
204}
205
206#define PHASE1_LOOP_COUNT 8
207
208static void tkip_mixing_phase1(u16 * TTAK, const u8 * TK, const u8 * TA,
209			       u32 IV32)
210{
211	int i, j;
212
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]);
219
220	for (i = 0; i < PHASE1_LOOP_COUNT; i++) {
221		j = 2 * (i & 1);
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;
227	}
228}
229
230static void tkip_mixing_phase2(u8 * WEPSeed, const u8 * TK, const u16 * TTAK,
231			       u16 IV16)
232{
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];
236
237	/* Step 1 - make copy of TTAK and bring in TSC */
238	PPK[0] = TTAK[0];
239	PPK[1] = TTAK[1];
240	PPK[2] = TTAK[2];
241	PPK[3] = TTAK[3];
242	PPK[4] = TTAK[4];
243	PPK[5] = TTAK[4] + IV16;
244
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]));
252
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]);
259
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);
266
267#ifdef __BIG_ENDIAN
268	{
269		int i;
270		for (i = 0; i < 6; i++)
271			PPK[i] = (PPK[i] << 8) | (PPK[i] >> 8);
272	}
273#endif
274}
275
276static int libipw_tkip_hdr(struct sk_buff *skb, int hdr_len,
277			      u8 * rc4key, int keylen, void *priv)
278{
279	struct libipw_tkip_data *tkey = priv;
280	u8 *pos;
281	struct ieee80211_hdr *hdr;
282
283	hdr = (struct ieee80211_hdr *)skb->data;
284
285	if (skb_headroom(skb) < TKIP_HDR_LEN || skb->len < hdr_len)
286		return -1;
287
288	if (rc4key == NULL || keylen < 16)
289		return -1;
290
291	if (!tkey->tx_phase1_done) {
292		tkip_mixing_phase1(tkey->tx_ttak, tkey->key, hdr->addr2,
293				   tkey->tx_iv32);
294		tkey->tx_phase1_done = 1;
295	}
296	tkip_mixing_phase2(rc4key, tkey->key, tkey->tx_ttak, tkey->tx_iv16);
297
298	pos = skb_push(skb, TKIP_HDR_LEN);
299	memmove(pos, pos + TKIP_HDR_LEN, hdr_len);
300	pos += hdr_len;
301
302	*pos++ = *rc4key;
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;
310
311	tkey->tx_iv16++;
312	if (tkey->tx_iv16 == 0) {
313		tkey->tx_phase1_done = 0;
314		tkey->tx_iv32++;
315	}
316
317	return TKIP_HDR_LEN;
318}
319
320static int libipw_tkip_encrypt(struct sk_buff *skb, int hdr_len, void *priv)
321{
322	struct libipw_tkip_data *tkey = priv;
323	int len;
324	u8 rc4key[16], *pos, *icv;
325	u32 crc;
326
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",
330				    hdr->addr1);
331		return -1;
332	}
333
334	if (skb_tailroom(skb) < 4 || skb->len < hdr_len)
335		return -1;
336
337	len = skb->len - hdr_len;
338	pos = skb->data + hdr_len;
339
340	if ((libipw_tkip_hdr(skb, hdr_len, rc4key, 16, priv)) < 0)
341		return -1;
342
343	crc = ~crc32_le(~0, pos, len);
344	icv = skb_put(skb, 4);
345	icv[0] = crc;
346	icv[1] = crc >> 8;
347	icv[2] = crc >> 16;
348	icv[3] = crc >> 24;
349
350	arc4_setkey(&tkey->tx_ctx_arc4, rc4key, 16);
351	arc4_crypt(&tkey->tx_ctx_arc4, pos, pos, len + 4);
352
353	return 0;
354}
355
356/*
357 * deal with seq counter wrapping correctly.
358 * refer to timer_after() for jiffies wrapping handling
359 */
360static inline int tkip_replay_check(u32 iv32_n, u16 iv16_n,
361				    u32 iv32_o, u16 iv16_o)
362{
363	if ((s32)iv32_n - (s32)iv32_o < 0 ||
364	    (iv32_n == iv32_o && iv16_n <= iv16_o))
365		return 1;
366	return 0;
367}
368
369static int libipw_tkip_decrypt(struct sk_buff *skb, int hdr_len, void *priv)
370{
371	struct libipw_tkip_data *tkey = priv;
372	u8 rc4key[16];
373	u8 keyidx, *pos;
374	u32 iv32;
375	u16 iv16;
376	struct ieee80211_hdr *hdr;
377	u8 icv[4];
378	u32 crc;
379	int plen;
380
381	hdr = (struct ieee80211_hdr *)skb->data;
382
383	if (tkey->flags & IEEE80211_CRYPTO_TKIP_COUNTERMEASURES) {
384		net_dbg_ratelimited("TKIP countermeasures: dropped received packet from %pM\n",
385				    hdr->addr2);
386		return -1;
387	}
388
389	if (skb->len < hdr_len + TKIP_HDR_LEN + 4)
390		return -1;
391
392	pos = skb->data + hdr_len;
393	keyidx = pos[3];
394	if (!(keyidx & (1 << 5))) {
395		net_dbg_ratelimited("TKIP: received packet without ExtIV flag from %pM\n",
396				    hdr->addr2);
397		return -2;
398	}
399	keyidx >>= 6;
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);
403		return -6;
404	}
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",
407				    hdr->addr2, keyidx);
408		return -3;
409	}
410	iv16 = (pos[0] << 8) | pos[2];
411	iv32 = pos[4] | (pos[5] << 8) | (pos[6] << 16) | (pos[7] << 24);
412	pos += TKIP_HDR_LEN;
413
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,
418				    iv32, iv16);
419#endif
420		tkey->dot11RSNAStatsTKIPReplays++;
421		return -4;
422	}
423
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;
427	}
428	tkip_mixing_phase2(rc4key, tkey->key, tkey->rx_ttak, iv16);
429
430	plen = skb->len - hdr_len - 12;
431
432	arc4_setkey(&tkey->rx_ctx_arc4, rc4key, 16);
433	arc4_crypt(&tkey->rx_ctx_arc4, pos, pos, plen + 4);
434
435	crc = ~crc32_le(~0, pos, plen);
436	icv[0] = crc;
437	icv[1] = crc >> 8;
438	icv[2] = crc >> 16;
439	icv[3] = crc >> 24;
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;
445		}
446#ifdef CONFIG_LIBIPW_DEBUG
447		net_dbg_ratelimited("TKIP: ICV error detected: STA=%pM\n",
448				    hdr->addr2);
449#endif
450		tkey->dot11RSNAStatsTKIPICVErrors++;
451		return -5;
452	}
453
454	/* Update real counters only after Michael MIC verification has
455	 * completed */
456	tkey->rx_iv32_new = iv32;
457	tkey->rx_iv16_new = iv16;
458
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);
463
464	return keyidx;
465}
466
467static int michael_mic(struct crypto_shash *tfm_michael, u8 *key, u8 *hdr,
468		       u8 *data, size_t data_len, u8 *mic)
469{
470	SHASH_DESC_ON_STACK(desc, tfm_michael);
471	int err;
472
473	if (tfm_michael == NULL) {
474		pr_warn("%s(): tfm_michael == NULL\n", __func__);
475		return -1;
476	}
477
478	desc->tfm = tfm_michael;
479
480	if (crypto_shash_setkey(tfm_michael, key, 8))
481		return -1;
482
483	err = crypto_shash_init(desc);
484	if (err)
485		goto out;
486	err = crypto_shash_update(desc, hdr, 16);
487	if (err)
488		goto out;
489	err = crypto_shash_update(desc, data, data_len);
490	if (err)
491		goto out;
492	err = crypto_shash_final(desc, mic);
493
494out:
495	shash_desc_zero(desc);
496	return err;
497}
498
499static void michael_mic_hdr(struct sk_buff *skb, u8 * hdr)
500{
501	struct ieee80211_hdr *hdr11;
502
503	hdr11 = (struct ieee80211_hdr *)skb->data;
504
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 */
510		break;
511	case IEEE80211_FCTL_FROMDS:
512		memcpy(hdr, hdr11->addr1, ETH_ALEN);	/* DA */
513		memcpy(hdr + ETH_ALEN, hdr11->addr3, ETH_ALEN);	/* SA */
514		break;
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 */
518		break;
519	default:
520		memcpy(hdr, hdr11->addr1, ETH_ALEN);	/* DA */
521		memcpy(hdr + ETH_ALEN, hdr11->addr2, ETH_ALEN);	/* SA */
522		break;
523	}
524
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;
528	} else
529		hdr[12] = 0;		/* priority */
530
531	hdr[13] = hdr[14] = hdr[15] = 0;	/* reserved */
532}
533
534static int libipw_michael_mic_add(struct sk_buff *skb, int hdr_len,
535				     void *priv)
536{
537	struct libipw_tkip_data *tkey = priv;
538	u8 *pos;
539
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);
544		return -1;
545	}
546
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))
551		return -1;
552
553	return 0;
554}
555
556static void libipw_michael_mic_failure(struct net_device *dev,
557					  struct ieee80211_hdr *hdr,
558					  int keyidx)
559{
560	union iwreq_data wrqu;
561	struct iw_michaelmicfailure ev;
562
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;
568	else
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);
575}
576
577static int libipw_michael_mic_verify(struct sk_buff *skb, int keyidx,
578					int hdr_len, void *priv)
579{
580	struct libipw_tkip_data *tkey = priv;
581	u8 mic[8];
582
583	if (!tkey->key_set)
584		return -1;
585
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))
589		return -1;
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,
596		       keyidx);
597		if (skb->dev)
598			libipw_michael_mic_failure(skb->dev, hdr, keyidx);
599		tkey->dot11RSNAStatsTKIPLocalMICFailures++;
600		return -1;
601	}
602
603	/* Update TSC counters for RX now that the packet verification has
604	 * completed. */
605	tkey->rx_iv32 = tkey->rx_iv32_new;
606	tkey->rx_iv16 = tkey->rx_iv16_new;
607
608	skb_trim(skb, skb->len - 8);
609
610	return 0;
611}
612
613static int libipw_tkip_set_key(void *key, int len, u8 * seq, void *priv)
614{
615	struct libipw_tkip_data *tkey = priv;
616	int keyidx;
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;
621
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);
631		tkey->key_set = 1;
632		tkey->tx_iv16 = 1;	/* TSC is initialized to 1 */
633		if (seq) {
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];
637		}
638	} else if (len == 0)
639		tkey->key_set = 0;
640	else
641		return -1;
642
643	return 0;
644}
645
646static int libipw_tkip_get_key(void *key, int len, u8 * seq, void *priv)
647{
648	struct libipw_tkip_data *tkey = priv;
649
650	if (len < TKIP_KEY_LEN)
651		return -1;
652
653	if (!tkey->key_set)
654		return 0;
655	memcpy(key, tkey->key, TKIP_KEY_LEN);
656
657	if (seq) {
658		/*
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.
663		 */
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;
670	}
671
672	return TKIP_KEY_LEN;
673}
674
675static void libipw_tkip_print_stats(struct seq_file *m, void *priv)
676{
677	struct libipw_tkip_data *tkip = priv;
678	seq_printf(m,
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);
699}
700
701static const struct libipw_crypto_ops libipw_crypt_tkip = {
702	.name = "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,
718};
719
720int __init libipw_crypto_tkip_init(void)
721{
722	return libipw_register_crypto_ops(&libipw_crypt_tkip);
723}
724
725void libipw_crypto_tkip_exit(void)
726{
727	libipw_unregister_crypto_ops(&libipw_crypt_tkip);
728}
~/ Read-only file preview.