Blame view

net/wireless/lib80211_crypt_tkip.c 19.2 KB
21042e414   Thomas Gleixner   treewide: Replace...
1
  // SPDX-License-Identifier: GPL-2.0-only
b453872c3   Jeff Garzik   [NET] ieee80211 s...
2
  /*
274bfb8dc   John W. Linville   lib80211: absorb ...
3
   * lib80211 crypt: host-based TKIP encryption implementation for lib80211
b453872c3   Jeff Garzik   [NET] ieee80211 s...
4
   *
85d32e7b0   Jouni Malinen   [PATCH] Update my...
5
   * Copyright (c) 2003-2004, Jouni Malinen <j@w1.fi>
274bfb8dc   John W. Linville   lib80211: absorb ...
6
   * Copyright (c) 2008, John W. Linville <linville@tuxdriver.com>
b453872c3   Jeff Garzik   [NET] ieee80211 s...
7
   */
e9c0268f0   Joe Perches   net/wireless: Use...
8
  #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
f12cc2090   Herbert Xu   [CRYPTO] users: U...
9
  #include <linux/err.h>
4be297016   Ard Biesheuvel   net/lib80211: mov...
10
  #include <linux/fips.h>
b453872c3   Jeff Garzik   [NET] ieee80211 s...
11
12
13
14
  #include <linux/module.h>
  #include <linux/init.h>
  #include <linux/slab.h>
  #include <linux/random.h>
117636092   Ralf Baechle   [PATCH] Fix break...
15
  #include <linux/scatterlist.h>
b453872c3   Jeff Garzik   [NET] ieee80211 s...
16
17
  #include <linux/skbuff.h>
  #include <linux/netdevice.h>
d7fe0f241   Al Viro   [PATCH] severing ...
18
  #include <linux/mm.h>
b453872c3   Jeff Garzik   [NET] ieee80211 s...
19
20
21
  #include <linux/if_ether.h>
  #include <linux/if_arp.h>
  #include <asm/string.h>
274bfb8dc   John W. Linville   lib80211: absorb ...
22
23
24
  #include <linux/wireless.h>
  #include <linux/ieee80211.h>
  #include <net/iw_handler.h>
b453872c3   Jeff Garzik   [NET] ieee80211 s...
25

4be297016   Ard Biesheuvel   net/lib80211: mov...
26
  #include <crypto/arc4.h>
608fb34cf   Herbert Xu   lib80211: Use skc...
27
  #include <crypto/hash.h>
b802a5d6f   Johannes Berg   lib80211: don't u...
28
  #include <linux/crypto.h>
b453872c3   Jeff Garzik   [NET] ieee80211 s...
29
  #include <linux/crc32.h>
274bfb8dc   John W. Linville   lib80211: absorb ...
30
  #include <net/lib80211.h>
b453872c3   Jeff Garzik   [NET] ieee80211 s...
31
  MODULE_AUTHOR("Jouni Malinen");
274bfb8dc   John W. Linville   lib80211: absorb ...
32
  MODULE_DESCRIPTION("lib80211 crypt: TKIP");
b453872c3   Jeff Garzik   [NET] ieee80211 s...
33
  MODULE_LICENSE("GPL");
299af9d3d   Andriy Tkachuk   lib80211: Introdu...
34
  #define TKIP_HDR_LEN 8
274bfb8dc   John W. Linville   lib80211: absorb ...
35
  struct lib80211_tkip_data {
b453872c3   Jeff Garzik   [NET] ieee80211 s...
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
  #define TKIP_KEY_LEN 32
  	u8 key[TKIP_KEY_LEN];
  	int key_set;
  
  	u32 tx_iv32;
  	u16 tx_iv16;
  	u16 tx_ttak[5];
  	int tx_phase1_done;
  
  	u32 rx_iv32;
  	u16 rx_iv16;
  	u16 rx_ttak[5];
  	int rx_phase1_done;
  	u32 rx_iv32_new;
  	u16 rx_iv16_new;
  
  	u32 dot11RSNAStatsTKIPReplays;
  	u32 dot11RSNAStatsTKIPICVErrors;
  	u32 dot11RSNAStatsTKIPLocalMICFailures;
  
  	int key_idx;
4be297016   Ard Biesheuvel   net/lib80211: mov...
57
58
  	struct arc4_ctx rx_ctx_arc4;
  	struct arc4_ctx tx_ctx_arc4;
d17504b16   Kees Cook   wireless/lib80211...
59
  	struct crypto_shash *rx_tfm_michael;
d17504b16   Kees Cook   wireless/lib80211...
60
  	struct crypto_shash *tx_tfm_michael;
b453872c3   Jeff Garzik   [NET] ieee80211 s...
61
62
63
  
  	/* scratch buffers for virt_to_page() (crypto API) */
  	u8 rx_hdr[16], tx_hdr[16];
20d64713a   James Ketrenos   [PATCH] ieee80211...
64

6eb6edf04   James Ketrenos   [PATCH] ieee80211...
65
  	unsigned long flags;
b453872c3   Jeff Garzik   [NET] ieee80211 s...
66
  };
274bfb8dc   John W. Linville   lib80211: absorb ...
67
  static unsigned long lib80211_tkip_set_flags(unsigned long flags, void *priv)
6eb6edf04   James Ketrenos   [PATCH] ieee80211...
68
  {
274bfb8dc   John W. Linville   lib80211: absorb ...
69
  	struct lib80211_tkip_data *_priv = priv;
6eb6edf04   James Ketrenos   [PATCH] ieee80211...
70
71
72
73
  	unsigned long old_flags = _priv->flags;
  	_priv->flags = flags;
  	return old_flags;
  }
274bfb8dc   John W. Linville   lib80211: absorb ...
74
  static unsigned long lib80211_tkip_get_flags(void *priv)
6eb6edf04   James Ketrenos   [PATCH] ieee80211...
75
  {
274bfb8dc   John W. Linville   lib80211: absorb ...
76
  	struct lib80211_tkip_data *_priv = priv;
6eb6edf04   James Ketrenos   [PATCH] ieee80211...
77
78
  	return _priv->flags;
  }
274bfb8dc   John W. Linville   lib80211: absorb ...
79
  static void *lib80211_tkip_init(int key_idx)
b453872c3   Jeff Garzik   [NET] ieee80211 s...
80
  {
274bfb8dc   John W. Linville   lib80211: absorb ...
81
  	struct lib80211_tkip_data *priv;
b453872c3   Jeff Garzik   [NET] ieee80211 s...
82

4be297016   Ard Biesheuvel   net/lib80211: mov...
83
84
  	if (fips_enabled)
  		return NULL;
8aa914b74   Zhu Yi   [PATCH] ieee80211...
85
  	priv = kzalloc(sizeof(*priv), GFP_ATOMIC);
b453872c3   Jeff Garzik   [NET] ieee80211 s...
86
87
  	if (priv == NULL)
  		goto fail;
20d64713a   James Ketrenos   [PATCH] ieee80211...
88

b453872c3   Jeff Garzik   [NET] ieee80211 s...
89
  	priv->key_idx = key_idx;
d17504b16   Kees Cook   wireless/lib80211...
90
  	priv->tx_tfm_michael = crypto_alloc_shash("michael_mic", 0, 0);
28eb177df   Jeff Garzik   Merge branch 'mas...
91
  	if (IS_ERR(priv->tx_tfm_michael)) {
183798799   Jeff Garzik   net/ieee80211: fi...
92
  		priv->tx_tfm_michael = NULL;
5a6569497   Zhu Yi   [PATCH] ieee80211...
93
94
  		goto fail;
  	}
d17504b16   Kees Cook   wireless/lib80211...
95
  	priv->rx_tfm_michael = crypto_alloc_shash("michael_mic", 0, 0);
28eb177df   Jeff Garzik   Merge branch 'mas...
96
  	if (IS_ERR(priv->rx_tfm_michael)) {
183798799   Jeff Garzik   net/ieee80211: fi...
97
  		priv->rx_tfm_michael = NULL;
b453872c3   Jeff Garzik   [NET] ieee80211 s...
98
99
100
101
  		goto fail;
  	}
  
  	return priv;
0edd5b449   Jeff Garzik   [wireless ieee802...
102
        fail:
b453872c3   Jeff Garzik   [NET] ieee80211 s...
103
  	if (priv) {
d17504b16   Kees Cook   wireless/lib80211...
104
  		crypto_free_shash(priv->tx_tfm_michael);
d17504b16   Kees Cook   wireless/lib80211...
105
  		crypto_free_shash(priv->rx_tfm_michael);
b453872c3   Jeff Garzik   [NET] ieee80211 s...
106
107
108
109
110
  		kfree(priv);
  	}
  
  	return NULL;
  }
274bfb8dc   John W. Linville   lib80211: absorb ...
111
  static void lib80211_tkip_deinit(void *priv)
b453872c3   Jeff Garzik   [NET] ieee80211 s...
112
  {
274bfb8dc   John W. Linville   lib80211: absorb ...
113
  	struct lib80211_tkip_data *_priv = priv;
5a6569497   Zhu Yi   [PATCH] ieee80211...
114
  	if (_priv) {
d17504b16   Kees Cook   wireless/lib80211...
115
  		crypto_free_shash(_priv->tx_tfm_michael);
d17504b16   Kees Cook   wireless/lib80211...
116
  		crypto_free_shash(_priv->rx_tfm_michael);
5a6569497   Zhu Yi   [PATCH] ieee80211...
117
  	}
453431a54   Waiman Long   mm, treewide: ren...
118
  	kfree_sensitive(priv);
b453872c3   Jeff Garzik   [NET] ieee80211 s...
119
  }
b453872c3   Jeff Garzik   [NET] ieee80211 s...
120
121
122
123
  static inline u16 RotR1(u16 val)
  {
  	return (val >> 1) | (val << 15);
  }
b453872c3   Jeff Garzik   [NET] ieee80211 s...
124
125
126
127
  static inline u8 Lo8(u16 val)
  {
  	return val & 0xff;
  }
b453872c3   Jeff Garzik   [NET] ieee80211 s...
128
129
130
131
  static inline u8 Hi8(u16 val)
  {
  	return val >> 8;
  }
b453872c3   Jeff Garzik   [NET] ieee80211 s...
132
133
134
135
  static inline u16 Lo16(u32 val)
  {
  	return val & 0xffff;
  }
b453872c3   Jeff Garzik   [NET] ieee80211 s...
136
137
138
139
  static inline u16 Hi16(u32 val)
  {
  	return val >> 16;
  }
b453872c3   Jeff Garzik   [NET] ieee80211 s...
140
141
142
143
  static inline u16 Mk16(u8 hi, u8 lo)
  {
  	return lo | (((u16) hi) << 8);
  }
d9e94d564   Al Viro   ieee80211: fix mi...
144
  static inline u16 Mk16_le(__le16 * v)
b453872c3   Jeff Garzik   [NET] ieee80211 s...
145
146
147
  {
  	return le16_to_cpu(*v);
  }
0edd5b449   Jeff Garzik   [wireless ieee802...
148
  static const u16 Sbox[256] = {
b453872c3   Jeff Garzik   [NET] ieee80211 s...
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
  	0xC6A5, 0xF884, 0xEE99, 0xF68D, 0xFF0D, 0xD6BD, 0xDEB1, 0x9154,
  	0x6050, 0x0203, 0xCEA9, 0x567D, 0xE719, 0xB562, 0x4DE6, 0xEC9A,
  	0x8F45, 0x1F9D, 0x8940, 0xFA87, 0xEF15, 0xB2EB, 0x8EC9, 0xFB0B,
  	0x41EC, 0xB367, 0x5FFD, 0x45EA, 0x23BF, 0x53F7, 0xE496, 0x9B5B,
  	0x75C2, 0xE11C, 0x3DAE, 0x4C6A, 0x6C5A, 0x7E41, 0xF502, 0x834F,
  	0x685C, 0x51F4, 0xD134, 0xF908, 0xE293, 0xAB73, 0x6253, 0x2A3F,
  	0x080C, 0x9552, 0x4665, 0x9D5E, 0x3028, 0x37A1, 0x0A0F, 0x2FB5,
  	0x0E09, 0x2436, 0x1B9B, 0xDF3D, 0xCD26, 0x4E69, 0x7FCD, 0xEA9F,
  	0x121B, 0x1D9E, 0x5874, 0x342E, 0x362D, 0xDCB2, 0xB4EE, 0x5BFB,
  	0xA4F6, 0x764D, 0xB761, 0x7DCE, 0x527B, 0xDD3E, 0x5E71, 0x1397,
  	0xA6F5, 0xB968, 0x0000, 0xC12C, 0x4060, 0xE31F, 0x79C8, 0xB6ED,
  	0xD4BE, 0x8D46, 0x67D9, 0x724B, 0x94DE, 0x98D4, 0xB0E8, 0x854A,
  	0xBB6B, 0xC52A, 0x4FE5, 0xED16, 0x86C5, 0x9AD7, 0x6655, 0x1194,
  	0x8ACF, 0xE910, 0x0406, 0xFE81, 0xA0F0, 0x7844, 0x25BA, 0x4BE3,
  	0xA2F3, 0x5DFE, 0x80C0, 0x058A, 0x3FAD, 0x21BC, 0x7048, 0xF104,
  	0x63DF, 0x77C1, 0xAF75, 0x4263, 0x2030, 0xE51A, 0xFD0E, 0xBF6D,
  	0x814C, 0x1814, 0x2635, 0xC32F, 0xBEE1, 0x35A2, 0x88CC, 0x2E39,
  	0x9357, 0x55F2, 0xFC82, 0x7A47, 0xC8AC, 0xBAE7, 0x322B, 0xE695,
  	0xC0A0, 0x1998, 0x9ED1, 0xA37F, 0x4466, 0x547E, 0x3BAB, 0x0B83,
  	0x8CCA, 0xC729, 0x6BD3, 0x283C, 0xA779, 0xBCE2, 0x161D, 0xAD76,
  	0xDB3B, 0x6456, 0x744E, 0x141E, 0x92DB, 0x0C0A, 0x486C, 0xB8E4,
  	0x9F5D, 0xBD6E, 0x43EF, 0xC4A6, 0x39A8, 0x31A4, 0xD337, 0xF28B,
  	0xD532, 0x8B43, 0x6E59, 0xDAB7, 0x018C, 0xB164, 0x9CD2, 0x49E0,
  	0xD8B4, 0xACFA, 0xF307, 0xCF25, 0xCAAF, 0xF48E, 0x47E9, 0x1018,
  	0x6FD5, 0xF088, 0x4A6F, 0x5C72, 0x3824, 0x57F1, 0x73C7, 0x9751,
  	0xCB23, 0xA17C, 0xE89C, 0x3E21, 0x96DD, 0x61DC, 0x0D86, 0x0F85,
  	0xE090, 0x7C42, 0x71C4, 0xCCAA, 0x90D8, 0x0605, 0xF701, 0x1C12,
  	0xC2A3, 0x6A5F, 0xAEF9, 0x69D0, 0x1791, 0x9958, 0x3A27, 0x27B9,
  	0xD938, 0xEB13, 0x2BB3, 0x2233, 0xD2BB, 0xA970, 0x0789, 0x33A7,
  	0x2DB6, 0x3C22, 0x1592, 0xC920, 0x8749, 0xAAFF, 0x5078, 0xA57A,
  	0x038F, 0x59F8, 0x0980, 0x1A17, 0x65DA, 0xD731, 0x84C6, 0xD0B8,
  	0x82C3, 0x29B0, 0x5A77, 0x1E11, 0x7BCB, 0xA8FC, 0x6DD6, 0x2C3A,
  };
b453872c3   Jeff Garzik   [NET] ieee80211 s...
182
183
184
185
186
  static inline u16 _S_(u16 v)
  {
  	u16 t = Sbox[Hi8(v)];
  	return Sbox[Lo8(v)] ^ ((t << 8) | (t >> 8));
  }
b453872c3   Jeff Garzik   [NET] ieee80211 s...
187
  #define PHASE1_LOOP_COUNT 8
0edd5b449   Jeff Garzik   [wireless ieee802...
188
189
  static void tkip_mixing_phase1(u16 * TTAK, const u8 * TK, const u8 * TA,
  			       u32 IV32)
b453872c3   Jeff Garzik   [NET] ieee80211 s...
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
  {
  	int i, j;
  
  	/* Initialize the 80-bit TTAK from TSC (IV32) and TA[0..5] */
  	TTAK[0] = Lo16(IV32);
  	TTAK[1] = Hi16(IV32);
  	TTAK[2] = Mk16(TA[1], TA[0]);
  	TTAK[3] = Mk16(TA[3], TA[2]);
  	TTAK[4] = Mk16(TA[5], TA[4]);
  
  	for (i = 0; i < PHASE1_LOOP_COUNT; i++) {
  		j = 2 * (i & 1);
  		TTAK[0] += _S_(TTAK[4] ^ Mk16(TK[1 + j], TK[0 + j]));
  		TTAK[1] += _S_(TTAK[0] ^ Mk16(TK[5 + j], TK[4 + j]));
  		TTAK[2] += _S_(TTAK[1] ^ Mk16(TK[9 + j], TK[8 + j]));
  		TTAK[3] += _S_(TTAK[2] ^ Mk16(TK[13 + j], TK[12 + j]));
  		TTAK[4] += _S_(TTAK[3] ^ Mk16(TK[1 + j], TK[0 + j])) + i;
  	}
  }
0edd5b449   Jeff Garzik   [wireless ieee802...
209
  static void tkip_mixing_phase2(u8 * WEPSeed, const u8 * TK, const u16 * TTAK,
b453872c3   Jeff Garzik   [NET] ieee80211 s...
210
211
212
213
  			       u16 IV16)
  {
  	/* Make temporary area overlap WEP seed so that the final copy can be
  	 * avoided on little endian hosts. */
0edd5b449   Jeff Garzik   [wireless ieee802...
214
  	u16 *PPK = (u16 *) & WEPSeed[4];
b453872c3   Jeff Garzik   [NET] ieee80211 s...
215
216
217
218
219
220
221
222
223
224
  
  	/* Step 1 - make copy of TTAK and bring in TSC */
  	PPK[0] = TTAK[0];
  	PPK[1] = TTAK[1];
  	PPK[2] = TTAK[2];
  	PPK[3] = TTAK[3];
  	PPK[4] = TTAK[4];
  	PPK[5] = TTAK[4] + IV16;
  
  	/* Step 2 - 96-bit bijective mixing using S-box */
d9e94d564   Al Viro   ieee80211: fix mi...
225
226
227
228
229
230
231
232
233
  	PPK[0] += _S_(PPK[5] ^ Mk16_le((__le16 *) & TK[0]));
  	PPK[1] += _S_(PPK[0] ^ Mk16_le((__le16 *) & TK[2]));
  	PPK[2] += _S_(PPK[1] ^ Mk16_le((__le16 *) & TK[4]));
  	PPK[3] += _S_(PPK[2] ^ Mk16_le((__le16 *) & TK[6]));
  	PPK[4] += _S_(PPK[3] ^ Mk16_le((__le16 *) & TK[8]));
  	PPK[5] += _S_(PPK[4] ^ Mk16_le((__le16 *) & TK[10]));
  
  	PPK[0] += RotR1(PPK[5] ^ Mk16_le((__le16 *) & TK[12]));
  	PPK[1] += RotR1(PPK[0] ^ Mk16_le((__le16 *) & TK[14]));
b453872c3   Jeff Garzik   [NET] ieee80211 s...
234
235
236
237
238
239
240
241
242
243
  	PPK[2] += RotR1(PPK[1]);
  	PPK[3] += RotR1(PPK[2]);
  	PPK[4] += RotR1(PPK[3]);
  	PPK[5] += RotR1(PPK[4]);
  
  	/* Step 3 - bring in last of TK bits, assign 24-bit WEP IV value
  	 * WEPSeed[0..2] is transmitted as WEP IV */
  	WEPSeed[0] = Hi8(IV16);
  	WEPSeed[1] = (Hi8(IV16) | 0x20) & 0x7F;
  	WEPSeed[2] = Lo8(IV16);
d9e94d564   Al Viro   ieee80211: fix mi...
244
  	WEPSeed[3] = Lo8((PPK[5] ^ Mk16_le((__le16 *) & TK[0])) >> 1);
b453872c3   Jeff Garzik   [NET] ieee80211 s...
245
246
247
248
249
250
251
252
253
  
  #ifdef __BIG_ENDIAN
  	{
  		int i;
  		for (i = 0; i < 6; i++)
  			PPK[i] = (PPK[i] << 8) | (PPK[i] >> 8);
  	}
  #endif
  }
274bfb8dc   John W. Linville   lib80211: absorb ...
254
  static int lib80211_tkip_hdr(struct sk_buff *skb, int hdr_len,
9184d9348   Zhu Yi   [PATCH] ieee80211...
255
  			      u8 * rc4key, int keylen, void *priv)
b453872c3   Jeff Garzik   [NET] ieee80211 s...
256
  {
274bfb8dc   John W. Linville   lib80211: absorb ...
257
  	struct lib80211_tkip_data *tkey = priv;
9184d9348   Zhu Yi   [PATCH] ieee80211...
258
  	u8 *pos;
274bfb8dc   John W. Linville   lib80211: absorb ...
259
  	struct ieee80211_hdr *hdr;
b453872c3   Jeff Garzik   [NET] ieee80211 s...
260

274bfb8dc   John W. Linville   lib80211: absorb ...
261
  	hdr = (struct ieee80211_hdr *)skb->data;
20d64713a   James Ketrenos   [PATCH] ieee80211...
262

299af9d3d   Andriy Tkachuk   lib80211: Introdu...
263
  	if (skb_headroom(skb) < TKIP_HDR_LEN || skb->len < hdr_len)
9184d9348   Zhu Yi   [PATCH] ieee80211...
264
265
266
267
  		return -1;
  
  	if (rc4key == NULL || keylen < 16)
  		return -1;
b453872c3   Jeff Garzik   [NET] ieee80211 s...
268

b453872c3   Jeff Garzik   [NET] ieee80211 s...
269
270
271
272
273
274
  	if (!tkey->tx_phase1_done) {
  		tkip_mixing_phase1(tkey->tx_ttak, tkey->key, hdr->addr2,
  				   tkey->tx_iv32);
  		tkey->tx_phase1_done = 1;
  	}
  	tkip_mixing_phase2(rc4key, tkey->key, tkey->tx_ttak, tkey->tx_iv16);
299af9d3d   Andriy Tkachuk   lib80211: Introdu...
275
276
  	pos = skb_push(skb, TKIP_HDR_LEN);
  	memmove(pos, pos + TKIP_HDR_LEN, hdr_len);
b453872c3   Jeff Garzik   [NET] ieee80211 s...
277
  	pos += hdr_len;
b453872c3   Jeff Garzik   [NET] ieee80211 s...
278

31b59eaee   James Ketrenos   [PATCH] ieee80211...
279
280
281
  	*pos++ = *rc4key;
  	*pos++ = *(rc4key + 1);
  	*pos++ = *(rc4key + 2);
0edd5b449   Jeff Garzik   [wireless ieee802...
282
  	*pos++ = (tkey->key_idx << 6) | (1 << 5) /* Ext IV included */ ;
b453872c3   Jeff Garzik   [NET] ieee80211 s...
283
284
285
286
  	*pos++ = tkey->tx_iv32 & 0xff;
  	*pos++ = (tkey->tx_iv32 >> 8) & 0xff;
  	*pos++ = (tkey->tx_iv32 >> 16) & 0xff;
  	*pos++ = (tkey->tx_iv32 >> 24) & 0xff;
9184d9348   Zhu Yi   [PATCH] ieee80211...
287
288
289
290
291
  	tkey->tx_iv16++;
  	if (tkey->tx_iv16 == 0) {
  		tkey->tx_phase1_done = 0;
  		tkey->tx_iv32++;
  	}
b453872c3   Jeff Garzik   [NET] ieee80211 s...
292

299af9d3d   Andriy Tkachuk   lib80211: Introdu...
293
  	return TKIP_HDR_LEN;
31b59eaee   James Ketrenos   [PATCH] ieee80211...
294
  }
274bfb8dc   John W. Linville   lib80211: absorb ...
295
  static int lib80211_tkip_encrypt(struct sk_buff *skb, int hdr_len, void *priv)
31b59eaee   James Ketrenos   [PATCH] ieee80211...
296
  {
274bfb8dc   John W. Linville   lib80211: absorb ...
297
  	struct lib80211_tkip_data *tkey = priv;
31b59eaee   James Ketrenos   [PATCH] ieee80211...
298
  	int len;
9184d9348   Zhu Yi   [PATCH] ieee80211...
299
300
  	u8 rc4key[16], *pos, *icv;
  	u32 crc;
31b59eaee   James Ketrenos   [PATCH] ieee80211...
301

6eb6edf04   James Ketrenos   [PATCH] ieee80211...
302
  	if (tkey->flags & IEEE80211_CRYPTO_TKIP_COUNTERMEASURES) {
e87cc4728   Joe Perches   net: Convert net_...
303
304
305
306
  		struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data;
  		net_dbg_ratelimited("TKIP countermeasures: dropped TX packet to %pM
  ",
  				    hdr->addr1);
31b59eaee   James Ketrenos   [PATCH] ieee80211...
307
308
309
310
311
312
313
314
  		return -1;
  	}
  
  	if (skb_tailroom(skb) < 4 || skb->len < hdr_len)
  		return -1;
  
  	len = skb->len - hdr_len;
  	pos = skb->data + hdr_len;
274bfb8dc   John W. Linville   lib80211: absorb ...
315
  	if ((lib80211_tkip_hdr(skb, hdr_len, rc4key, 16, priv)) < 0)
31b59eaee   James Ketrenos   [PATCH] ieee80211...
316
  		return -1;
9184d9348   Zhu Yi   [PATCH] ieee80211...
317
  	crc = ~crc32_le(~0, pos, len);
d0833a6a2   Andriy Tkachuk   lib80211: Cosmeti...
318
  	icv = skb_put(skb, 4);
9184d9348   Zhu Yi   [PATCH] ieee80211...
319
320
321
322
  	icv[0] = crc;
  	icv[1] = crc >> 8;
  	icv[2] = crc >> 16;
  	icv[3] = crc >> 24;
4be297016   Ard Biesheuvel   net/lib80211: mov...
323
324
  	arc4_setkey(&tkey->tx_ctx_arc4, rc4key, 16);
  	arc4_crypt(&tkey->tx_ctx_arc4, pos, pos, len + 4);
b802a5d6f   Johannes Berg   lib80211: don't u...
325
  	return 0;
b4328d87e   Zhu Yi   [PATCH] ieee80211...
326
  }
183798799   Jeff Garzik   net/ieee80211: fi...
327
328
329
330
331
332
333
334
335
336
337
338
  /*
   * deal with seq counter wrapping correctly.
   * refer to timer_after() for jiffies wrapping handling
   */
  static inline int tkip_replay_check(u32 iv32_n, u16 iv16_n,
  				    u32 iv32_o, u16 iv16_o)
  {
  	if ((s32)iv32_n - (s32)iv32_o < 0 ||
  	    (iv32_n == iv32_o && iv16_n <= iv16_o))
  		return 1;
  	return 0;
  }
274bfb8dc   John W. Linville   lib80211: absorb ...
339
  static int lib80211_tkip_decrypt(struct sk_buff *skb, int hdr_len, void *priv)
b453872c3   Jeff Garzik   [NET] ieee80211 s...
340
  {
274bfb8dc   John W. Linville   lib80211: absorb ...
341
  	struct lib80211_tkip_data *tkey = priv;
b453872c3   Jeff Garzik   [NET] ieee80211 s...
342
343
344
345
  	u8 rc4key[16];
  	u8 keyidx, *pos;
  	u32 iv32;
  	u16 iv16;
274bfb8dc   John W. Linville   lib80211: absorb ...
346
  	struct ieee80211_hdr *hdr;
b453872c3   Jeff Garzik   [NET] ieee80211 s...
347
348
  	u8 icv[4];
  	u32 crc;
b453872c3   Jeff Garzik   [NET] ieee80211 s...
349
  	int plen;
274bfb8dc   John W. Linville   lib80211: absorb ...
350
  	hdr = (struct ieee80211_hdr *)skb->data;
20d64713a   James Ketrenos   [PATCH] ieee80211...
351

6eb6edf04   James Ketrenos   [PATCH] ieee80211...
352
  	if (tkey->flags & IEEE80211_CRYPTO_TKIP_COUNTERMEASURES) {
e87cc4728   Joe Perches   net: Convert net_...
353
354
355
  		net_dbg_ratelimited("TKIP countermeasures: dropped received packet from %pM
  ",
  				    hdr->addr2);
20d64713a   James Ketrenos   [PATCH] ieee80211...
356
357
  		return -1;
  	}
299af9d3d   Andriy Tkachuk   lib80211: Introdu...
358
  	if (skb->len < hdr_len + TKIP_HDR_LEN + 4)
b453872c3   Jeff Garzik   [NET] ieee80211 s...
359
  		return -1;
b453872c3   Jeff Garzik   [NET] ieee80211 s...
360
361
362
  	pos = skb->data + hdr_len;
  	keyidx = pos[3];
  	if (!(keyidx & (1 << 5))) {
e87cc4728   Joe Perches   net: Convert net_...
363
364
365
  		net_dbg_ratelimited("TKIP: received packet without ExtIV flag from %pM
  ",
  				    hdr->addr2);
b453872c3   Jeff Garzik   [NET] ieee80211 s...
366
367
368
369
  		return -2;
  	}
  	keyidx >>= 6;
  	if (tkey->key_idx != keyidx) {
996bf99c7   Johannes Berg   lib80211: ratelim...
370
371
372
  		net_dbg_ratelimited("TKIP: RX tkey->key_idx=%d frame keyidx=%d
  ",
  				    tkey->key_idx, keyidx);
b453872c3   Jeff Garzik   [NET] ieee80211 s...
373
374
375
  		return -6;
  	}
  	if (!tkey->key_set) {
e87cc4728   Joe Perches   net: Convert net_...
376
377
378
  		net_dbg_ratelimited("TKIP: received packet from %pM with keyid=%d that does not have a configured key
  ",
  				    hdr->addr2, keyidx);
b453872c3   Jeff Garzik   [NET] ieee80211 s...
379
380
381
382
  		return -3;
  	}
  	iv16 = (pos[0] << 8) | pos[2];
  	iv32 = pos[4] | (pos[5] << 8) | (pos[6] << 16) | (pos[7] << 24);
299af9d3d   Andriy Tkachuk   lib80211: Introdu...
383
  	pos += TKIP_HDR_LEN;
b453872c3   Jeff Garzik   [NET] ieee80211 s...
384

b4328d87e   Zhu Yi   [PATCH] ieee80211...
385
  	if (tkip_replay_check(iv32, iv16, tkey->rx_iv32, tkey->rx_iv16)) {
6f16bf3bd   John W. Linville   lib80211: silence...
386
  #ifdef CONFIG_LIB80211_DEBUG
e87cc4728   Joe Perches   net: Convert net_...
387
388
389
390
  		net_dbg_ratelimited("TKIP: replay detected: STA=%pM previous TSC %08x%04x received TSC %08x%04x
  ",
  				    hdr->addr2, tkey->rx_iv32, tkey->rx_iv16,
  				    iv32, iv16);
6f16bf3bd   John W. Linville   lib80211: silence...
391
  #endif
b453872c3   Jeff Garzik   [NET] ieee80211 s...
392
393
394
395
396
397
398
399
400
401
402
  		tkey->dot11RSNAStatsTKIPReplays++;
  		return -4;
  	}
  
  	if (iv32 != tkey->rx_iv32 || !tkey->rx_phase1_done) {
  		tkip_mixing_phase1(tkey->rx_ttak, tkey->key, hdr->addr2, iv32);
  		tkey->rx_phase1_done = 1;
  	}
  	tkip_mixing_phase2(rc4key, tkey->key, tkey->rx_ttak, iv16);
  
  	plen = skb->len - hdr_len - 12;
4be297016   Ard Biesheuvel   net/lib80211: mov...
403
404
  	arc4_setkey(&tkey->rx_ctx_arc4, rc4key, 16);
  	arc4_crypt(&tkey->rx_ctx_arc4, pos, pos, plen + 4);
b453872c3   Jeff Garzik   [NET] ieee80211 s...
405
406
407
408
409
410
411
412
413
414
415
416
  
  	crc = ~crc32_le(~0, pos, plen);
  	icv[0] = crc;
  	icv[1] = crc >> 8;
  	icv[2] = crc >> 16;
  	icv[3] = crc >> 24;
  	if (memcmp(icv, pos + plen, 4) != 0) {
  		if (iv32 != tkey->rx_iv32) {
  			/* Previously cached Phase1 result was already lost, so
  			 * it needs to be recalculated for the next packet. */
  			tkey->rx_phase1_done = 0;
  		}
6f16bf3bd   John W. Linville   lib80211: silence...
417
  #ifdef CONFIG_LIB80211_DEBUG
e87cc4728   Joe Perches   net: Convert net_...
418
419
420
  		net_dbg_ratelimited("TKIP: ICV error detected: STA=%pM
  ",
  				    hdr->addr2);
6f16bf3bd   John W. Linville   lib80211: silence...
421
  #endif
b453872c3   Jeff Garzik   [NET] ieee80211 s...
422
423
424
425
426
427
428
429
430
431
  		tkey->dot11RSNAStatsTKIPICVErrors++;
  		return -5;
  	}
  
  	/* Update real counters only after Michael MIC verification has
  	 * completed */
  	tkey->rx_iv32_new = iv32;
  	tkey->rx_iv16_new = iv16;
  
  	/* Remove IV and ICV */
299af9d3d   Andriy Tkachuk   lib80211: Introdu...
432
433
  	memmove(skb->data + TKIP_HDR_LEN, skb->data, hdr_len);
  	skb_pull(skb, TKIP_HDR_LEN);
b453872c3   Jeff Garzik   [NET] ieee80211 s...
434
435
436
437
  	skb_trim(skb, skb->len - 4);
  
  	return keyidx;
  }
d17504b16   Kees Cook   wireless/lib80211...
438
439
  static int michael_mic(struct crypto_shash *tfm_michael, u8 *key, u8 *hdr,
  		       u8 *data, size_t data_len, u8 *mic)
b453872c3   Jeff Garzik   [NET] ieee80211 s...
440
  {
d17504b16   Kees Cook   wireless/lib80211...
441
  	SHASH_DESC_ON_STACK(desc, tfm_michael);
608fb34cf   Herbert Xu   lib80211: Use skc...
442
  	int err;
b453872c3   Jeff Garzik   [NET] ieee80211 s...
443

5a6569497   Zhu Yi   [PATCH] ieee80211...
444
  	if (tfm_michael == NULL) {
e9c0268f0   Joe Perches   net/wireless: Use...
445
446
  		pr_warn("%s(): tfm_michael == NULL
  ", __func__);
b453872c3   Jeff Garzik   [NET] ieee80211 s...
447
448
  		return -1;
  	}
b453872c3   Jeff Garzik   [NET] ieee80211 s...
449

d17504b16   Kees Cook   wireless/lib80211...
450
  	desc->tfm = tfm_michael;
d17504b16   Kees Cook   wireless/lib80211...
451
452
  
  	if (crypto_shash_setkey(tfm_michael, key, 8))
350586879   Herbert Xu   [CRYPTO] users: U...
453
  		return -1;
b453872c3   Jeff Garzik   [NET] ieee80211 s...
454

d17504b16   Kees Cook   wireless/lib80211...
455
456
457
458
459
460
461
462
463
464
465
466
467
  	err = crypto_shash_init(desc);
  	if (err)
  		goto out;
  	err = crypto_shash_update(desc, hdr, 16);
  	if (err)
  		goto out;
  	err = crypto_shash_update(desc, data, data_len);
  	if (err)
  		goto out;
  	err = crypto_shash_final(desc, mic);
  
  out:
  	shash_desc_zero(desc);
608fb34cf   Herbert Xu   lib80211: Use skc...
468
  	return err;
b453872c3   Jeff Garzik   [NET] ieee80211 s...
469
  }
0edd5b449   Jeff Garzik   [wireless ieee802...
470
  static void michael_mic_hdr(struct sk_buff *skb, u8 * hdr)
b453872c3   Jeff Garzik   [NET] ieee80211 s...
471
  {
274bfb8dc   John W. Linville   lib80211: absorb ...
472
  	struct ieee80211_hdr *hdr11;
b453872c3   Jeff Garzik   [NET] ieee80211 s...
473

274bfb8dc   John W. Linville   lib80211: absorb ...
474
  	hdr11 = (struct ieee80211_hdr *)skb->data;
ea2841521   Zhu Yi   [PATCH] ieee80211...
475

274bfb8dc   John W. Linville   lib80211: absorb ...
476
  	switch (le16_to_cpu(hdr11->frame_control) &
b453872c3   Jeff Garzik   [NET] ieee80211 s...
477
478
  		(IEEE80211_FCTL_FROMDS | IEEE80211_FCTL_TODS)) {
  	case IEEE80211_FCTL_TODS:
0edd5b449   Jeff Garzik   [wireless ieee802...
479
480
  		memcpy(hdr, hdr11->addr3, ETH_ALEN);	/* DA */
  		memcpy(hdr + ETH_ALEN, hdr11->addr2, ETH_ALEN);	/* SA */
b453872c3   Jeff Garzik   [NET] ieee80211 s...
481
482
  		break;
  	case IEEE80211_FCTL_FROMDS:
0edd5b449   Jeff Garzik   [wireless ieee802...
483
484
  		memcpy(hdr, hdr11->addr1, ETH_ALEN);	/* DA */
  		memcpy(hdr + ETH_ALEN, hdr11->addr3, ETH_ALEN);	/* SA */
b453872c3   Jeff Garzik   [NET] ieee80211 s...
485
486
  		break;
  	case IEEE80211_FCTL_FROMDS | IEEE80211_FCTL_TODS:
0edd5b449   Jeff Garzik   [wireless ieee802...
487
488
  		memcpy(hdr, hdr11->addr3, ETH_ALEN);	/* DA */
  		memcpy(hdr + ETH_ALEN, hdr11->addr4, ETH_ALEN);	/* SA */
b453872c3   Jeff Garzik   [NET] ieee80211 s...
489
  		break;
10f3366b4   Arnd Bergmann   wireless: fix bog...
490
  	default:
0edd5b449   Jeff Garzik   [wireless ieee802...
491
492
  		memcpy(hdr, hdr11->addr1, ETH_ALEN);	/* DA */
  		memcpy(hdr + ETH_ALEN, hdr11->addr2, ETH_ALEN);	/* SA */
b453872c3   Jeff Garzik   [NET] ieee80211 s...
493
494
  		break;
  	}
274bfb8dc   John W. Linville   lib80211: absorb ...
495
  	if (ieee80211_is_data_qos(hdr11->frame_control)) {
3f6ff6bac   John W. Linville   wireless: correct...
496
  		hdr[12] = le16_to_cpu(*((__le16 *)ieee80211_get_qos_ctl(hdr11)))
274bfb8dc   John W. Linville   lib80211: absorb ...
497
  			& IEEE80211_QOS_CTL_TID_MASK;
ea2841521   Zhu Yi   [PATCH] ieee80211...
498
499
  	} else
  		hdr[12] = 0;		/* priority */
0edd5b449   Jeff Garzik   [wireless ieee802...
500
  	hdr[13] = hdr[14] = hdr[15] = 0;	/* reserved */
b453872c3   Jeff Garzik   [NET] ieee80211 s...
501
  }
274bfb8dc   John W. Linville   lib80211: absorb ...
502
  static int lib80211_michael_mic_add(struct sk_buff *skb, int hdr_len,
0edd5b449   Jeff Garzik   [wireless ieee802...
503
  				     void *priv)
b453872c3   Jeff Garzik   [NET] ieee80211 s...
504
  {
274bfb8dc   John W. Linville   lib80211: absorb ...
505
  	struct lib80211_tkip_data *tkey = priv;
b453872c3   Jeff Garzik   [NET] ieee80211 s...
506
507
508
509
510
511
512
513
514
515
516
517
  	u8 *pos;
  
  	if (skb_tailroom(skb) < 8 || skb->len < hdr_len) {
  		printk(KERN_DEBUG "Invalid packet for Michael MIC add "
  		       "(tailroom=%d hdr_len=%d skb->len=%d)
  ",
  		       skb_tailroom(skb), hdr_len, skb->len);
  		return -1;
  	}
  
  	michael_mic_hdr(skb, tkey->tx_hdr);
  	pos = skb_put(skb, 8);
5a6569497   Zhu Yi   [PATCH] ieee80211...
518
  	if (michael_mic(tkey->tx_tfm_michael, &tkey->key[16], tkey->tx_hdr,
b453872c3   Jeff Garzik   [NET] ieee80211 s...
519
520
521
522
523
  			skb->data + hdr_len, skb->len - 8 - hdr_len, pos))
  		return -1;
  
  	return 0;
  }
274bfb8dc   John W. Linville   lib80211: absorb ...
524
525
  static void lib80211_michael_mic_failure(struct net_device *dev,
  					  struct ieee80211_hdr *hdr,
ee34af37c   James Ketrenos   [PATCH] ieee80211...
526
  					  int keyidx)
b453872c3   Jeff Garzik   [NET] ieee80211 s...
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
  {
  	union iwreq_data wrqu;
  	struct iw_michaelmicfailure ev;
  
  	/* TODO: needed parameters: count, keyid, key type, TSC */
  	memset(&ev, 0, sizeof(ev));
  	ev.flags = keyidx & IW_MICFAILURE_KEY_ID;
  	if (hdr->addr1[0] & 0x01)
  		ev.flags |= IW_MICFAILURE_GROUP;
  	else
  		ev.flags |= IW_MICFAILURE_PAIRWISE;
  	ev.src_addr.sa_family = ARPHRD_ETHER;
  	memcpy(ev.src_addr.sa_data, hdr->addr2, ETH_ALEN);
  	memset(&wrqu, 0, sizeof(wrqu));
  	wrqu.data.length = sizeof(ev);
0edd5b449   Jeff Garzik   [wireless ieee802...
542
  	wireless_send_event(dev, IWEVMICHAELMICFAILURE, &wrqu, (char *)&ev);
b453872c3   Jeff Garzik   [NET] ieee80211 s...
543
  }
b453872c3   Jeff Garzik   [NET] ieee80211 s...
544

274bfb8dc   John W. Linville   lib80211: absorb ...
545
  static int lib80211_michael_mic_verify(struct sk_buff *skb, int keyidx,
0edd5b449   Jeff Garzik   [wireless ieee802...
546
  					int hdr_len, void *priv)
b453872c3   Jeff Garzik   [NET] ieee80211 s...
547
  {
274bfb8dc   John W. Linville   lib80211: absorb ...
548
  	struct lib80211_tkip_data *tkey = priv;
b453872c3   Jeff Garzik   [NET] ieee80211 s...
549
550
551
552
553
554
  	u8 mic[8];
  
  	if (!tkey->key_set)
  		return -1;
  
  	michael_mic_hdr(skb, tkey->rx_hdr);
5a6569497   Zhu Yi   [PATCH] ieee80211...
555
  	if (michael_mic(tkey->rx_tfm_michael, &tkey->key[24], tkey->rx_hdr,
b453872c3   Jeff Garzik   [NET] ieee80211 s...
556
557
558
  			skb->data + hdr_len, skb->len - 8 - hdr_len, mic))
  		return -1;
  	if (memcmp(mic, skb->data + skb->len - 8, 8) != 0) {
274bfb8dc   John W. Linville   lib80211: absorb ...
559
560
  		struct ieee80211_hdr *hdr;
  		hdr = (struct ieee80211_hdr *)skb->data;
b453872c3   Jeff Garzik   [NET] ieee80211 s...
561
  		printk(KERN_DEBUG "%s: Michael MIC verification failed for "
e174961ca   Johannes Berg   net: convert prin...
562
563
564
  		       "MSDU from %pM keyidx=%d
  ",
  		       skb->dev ? skb->dev->name : "N/A", hdr->addr2,
b453872c3   Jeff Garzik   [NET] ieee80211 s...
565
566
  		       keyidx);
  		if (skb->dev)
274bfb8dc   John W. Linville   lib80211: absorb ...
567
  			lib80211_michael_mic_failure(skb->dev, hdr, keyidx);
b453872c3   Jeff Garzik   [NET] ieee80211 s...
568
569
570
571
572
573
574
575
576
577
578
579
580
  		tkey->dot11RSNAStatsTKIPLocalMICFailures++;
  		return -1;
  	}
  
  	/* Update TSC counters for RX now that the packet verification has
  	 * completed. */
  	tkey->rx_iv32 = tkey->rx_iv32_new;
  	tkey->rx_iv16 = tkey->rx_iv16_new;
  
  	skb_trim(skb, skb->len - 8);
  
  	return 0;
  }
274bfb8dc   John W. Linville   lib80211: absorb ...
581
  static int lib80211_tkip_set_key(void *key, int len, u8 * seq, void *priv)
b453872c3   Jeff Garzik   [NET] ieee80211 s...
582
  {
274bfb8dc   John W. Linville   lib80211: absorb ...
583
  	struct lib80211_tkip_data *tkey = priv;
b453872c3   Jeff Garzik   [NET] ieee80211 s...
584
  	int keyidx;
d17504b16   Kees Cook   wireless/lib80211...
585
  	struct crypto_shash *tfm = tkey->tx_tfm_michael;
4be297016   Ard Biesheuvel   net/lib80211: mov...
586
  	struct arc4_ctx *tfm2 = &tkey->tx_ctx_arc4;
d17504b16   Kees Cook   wireless/lib80211...
587
  	struct crypto_shash *tfm3 = tkey->rx_tfm_michael;
4be297016   Ard Biesheuvel   net/lib80211: mov...
588
  	struct arc4_ctx *tfm4 = &tkey->rx_ctx_arc4;
b453872c3   Jeff Garzik   [NET] ieee80211 s...
589
590
591
592
  
  	keyidx = tkey->key_idx;
  	memset(tkey, 0, sizeof(*tkey));
  	tkey->key_idx = keyidx;
5a6569497   Zhu Yi   [PATCH] ieee80211...
593
  	tkey->tx_tfm_michael = tfm;
4be297016   Ard Biesheuvel   net/lib80211: mov...
594
  	tkey->tx_ctx_arc4 = *tfm2;
5a6569497   Zhu Yi   [PATCH] ieee80211...
595
  	tkey->rx_tfm_michael = tfm3;
4be297016   Ard Biesheuvel   net/lib80211: mov...
596
  	tkey->rx_ctx_arc4 = *tfm4;
b453872c3   Jeff Garzik   [NET] ieee80211 s...
597
598
599
  	if (len == TKIP_KEY_LEN) {
  		memcpy(tkey->key, key, TKIP_KEY_LEN);
  		tkey->key_set = 1;
0edd5b449   Jeff Garzik   [wireless ieee802...
600
  		tkey->tx_iv16 = 1;	/* TSC is initialized to 1 */
b453872c3   Jeff Garzik   [NET] ieee80211 s...
601
602
  		if (seq) {
  			tkey->rx_iv32 = (seq[5] << 24) | (seq[4] << 16) |
0edd5b449   Jeff Garzik   [wireless ieee802...
603
  			    (seq[3] << 8) | seq[2];
b453872c3   Jeff Garzik   [NET] ieee80211 s...
604
605
606
607
608
609
610
611
612
  			tkey->rx_iv16 = (seq[1] << 8) | seq[0];
  		}
  	} else if (len == 0)
  		tkey->key_set = 0;
  	else
  		return -1;
  
  	return 0;
  }
274bfb8dc   John W. Linville   lib80211: absorb ...
613
  static int lib80211_tkip_get_key(void *key, int len, u8 * seq, void *priv)
b453872c3   Jeff Garzik   [NET] ieee80211 s...
614
  {
274bfb8dc   John W. Linville   lib80211: absorb ...
615
  	struct lib80211_tkip_data *tkey = priv;
b453872c3   Jeff Garzik   [NET] ieee80211 s...
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
  
  	if (len < TKIP_KEY_LEN)
  		return -1;
  
  	if (!tkey->key_set)
  		return 0;
  	memcpy(key, tkey->key, TKIP_KEY_LEN);
  
  	if (seq) {
  		/* Return the sequence number of the last transmitted frame. */
  		u16 iv16 = tkey->tx_iv16;
  		u32 iv32 = tkey->tx_iv32;
  		if (iv16 == 0)
  			iv32--;
  		iv16--;
  		seq[0] = tkey->tx_iv16;
  		seq[1] = tkey->tx_iv16 >> 8;
  		seq[2] = tkey->tx_iv32;
  		seq[3] = tkey->tx_iv32 >> 8;
  		seq[4] = tkey->tx_iv32 >> 16;
  		seq[5] = tkey->tx_iv32 >> 24;
  	}
  
  	return TKIP_KEY_LEN;
  }
6bbefe867   David Howells   hostap: Don't use...
641
  static void lib80211_tkip_print_stats(struct seq_file *m, void *priv)
b453872c3   Jeff Garzik   [NET] ieee80211 s...
642
  {
274bfb8dc   John W. Linville   lib80211: absorb ...
643
  	struct lib80211_tkip_data *tkip = priv;
6bbefe867   David Howells   hostap: Don't use...
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
  	seq_printf(m,
  		   "key[%d] alg=TKIP key_set=%d "
  		   "tx_pn=%02x%02x%02x%02x%02x%02x "
  		   "rx_pn=%02x%02x%02x%02x%02x%02x "
  		   "replays=%d icv_errors=%d local_mic_failures=%d
  ",
  		   tkip->key_idx, tkip->key_set,
  		   (tkip->tx_iv32 >> 24) & 0xff,
  		   (tkip->tx_iv32 >> 16) & 0xff,
  		   (tkip->tx_iv32 >> 8) & 0xff,
  		   tkip->tx_iv32 & 0xff,
  		   (tkip->tx_iv16 >> 8) & 0xff,
  		   tkip->tx_iv16 & 0xff,
  		   (tkip->rx_iv32 >> 24) & 0xff,
  		   (tkip->rx_iv32 >> 16) & 0xff,
  		   (tkip->rx_iv32 >> 8) & 0xff,
  		   tkip->rx_iv32 & 0xff,
  		   (tkip->rx_iv16 >> 8) & 0xff,
  		   tkip->rx_iv16 & 0xff,
  		   tkip->dot11RSNAStatsTKIPReplays,
  		   tkip->dot11RSNAStatsTKIPICVErrors,
  		   tkip->dot11RSNAStatsTKIPLocalMICFailures);
b453872c3   Jeff Garzik   [NET] ieee80211 s...
666
  }
274bfb8dc   John W. Linville   lib80211: absorb ...
667
  static struct lib80211_crypto_ops lib80211_crypt_tkip = {
74079fdce   James Ketrenos   [PATCH] ieee80211...
668
  	.name = "TKIP",
274bfb8dc   John W. Linville   lib80211: absorb ...
669
670
  	.init = lib80211_tkip_init,
  	.deinit = lib80211_tkip_deinit,
274bfb8dc   John W. Linville   lib80211: absorb ...
671
672
673
674
675
676
677
  	.encrypt_mpdu = lib80211_tkip_encrypt,
  	.decrypt_mpdu = lib80211_tkip_decrypt,
  	.encrypt_msdu = lib80211_michael_mic_add,
  	.decrypt_msdu = lib80211_michael_mic_verify,
  	.set_key = lib80211_tkip_set_key,
  	.get_key = lib80211_tkip_get_key,
  	.print_stats = lib80211_tkip_print_stats,
1264fc049   James Ketrenos   [PATCH] ieee80211...
678
679
680
  	.extra_mpdu_prefix_len = 4 + 4,	/* IV + ExtIV */
  	.extra_mpdu_postfix_len = 4,	/* ICV */
  	.extra_msdu_postfix_len = 8,	/* MIC */
274bfb8dc   John W. Linville   lib80211: absorb ...
681
682
  	.get_flags = lib80211_tkip_get_flags,
  	.set_flags = lib80211_tkip_set_flags,
74079fdce   James Ketrenos   [PATCH] ieee80211...
683
  	.owner = THIS_MODULE,
b453872c3   Jeff Garzik   [NET] ieee80211 s...
684
  };
274bfb8dc   John W. Linville   lib80211: absorb ...
685
  static int __init lib80211_crypto_tkip_init(void)
b453872c3   Jeff Garzik   [NET] ieee80211 s...
686
  {
274bfb8dc   John W. Linville   lib80211: absorb ...
687
  	return lib80211_register_crypto_ops(&lib80211_crypt_tkip);
b453872c3   Jeff Garzik   [NET] ieee80211 s...
688
  }
274bfb8dc   John W. Linville   lib80211: absorb ...
689
  static void __exit lib80211_crypto_tkip_exit(void)
b453872c3   Jeff Garzik   [NET] ieee80211 s...
690
  {
274bfb8dc   John W. Linville   lib80211: absorb ...
691
  	lib80211_unregister_crypto_ops(&lib80211_crypt_tkip);
b453872c3   Jeff Garzik   [NET] ieee80211 s...
692
  }
274bfb8dc   John W. Linville   lib80211: absorb ...
693
694
  module_init(lib80211_crypto_tkip_init);
  module_exit(lib80211_crypto_tkip_exit);