1 /*
2  * Copyright (c) 2002-2005 Sam Leffler, Errno Consulting
3  * All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions
7  * are met:
8  * 1. Redistributions of source code must retain the above copyright
9  *    notice, this list of conditions and the following disclaimer.
10  * 2. Redistributions in binary form must reproduce the above copyright
11  *    notice, this list of conditions and the following disclaimer in the
12  *    documentation and/or other materials provided with the distribution.
13  * 3. The name of the author may not be used to endorse or promote products
14  *    derived from this software without specific prior written permission.
15  *
16  * Alternatively, this software may be distributed under the terms of the
17  * GNU General Public License ("GPL") version 2 as published by the Free
18  * Software Foundation.
19  *
20  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
21  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
22  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
23  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
24  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
25  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
26  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
27  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
28  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
29  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30  *
31  * $FreeBSD: src/sys/net80211/ieee80211_crypto_tkip.c,v 1.9.2.2 2005/12/22 19:02:08 sam Exp $
32  * $DragonFly: src/sys/netproto/802_11/wlan_tkip/ieee80211_crypto_tkip.c,v 1.1 2006/05/18 13:51:46 sephe Exp $
33  */
34 
35 /*
36  * IEEE 802.11i TKIP crypto support.
37  *
38  * Part of this module is derived from similar code in the Host
39  * AP driver. The code is used with the consent of the author and
40  * it's license is included below.
41  */
42 #include <sys/param.h>
43 #include <sys/systm.h>
44 #include <sys/mbuf.h>
45 #include <sys/malloc.h>
46 #include <sys/kernel.h>
47 #include <sys/module.h>
48 #include <sys/endian.h>
49 
50 #include <sys/socket.h>
51 
52 #include <net/if.h>
53 #include <net/if_arp.h>
54 #include <net/if_media.h>
55 #include <net/ethernet.h>
56 
57 #include <netproto/802_11/ieee80211_var.h>
58 
59 static	void *tkip_attach(struct ieee80211com *, struct ieee80211_key *);
60 static	void tkip_detach(struct ieee80211_key *);
61 static	int tkip_setkey(struct ieee80211_key *);
62 static	int tkip_encap(struct ieee80211_key *, struct mbuf *m, uint8_t keyid);
63 static	int tkip_enmic(struct ieee80211_key *, struct mbuf *, int);
64 static	int tkip_decap(struct ieee80211_key *, struct mbuf *, int);
65 static	int tkip_demic(struct ieee80211_key *, struct mbuf *, int);
66 
67 static const struct ieee80211_cipher tkip  = {
68 	.ic_name	= "TKIP",
69 	.ic_cipher	= IEEE80211_CIPHER_TKIP,
70 	.ic_header	= IEEE80211_WEP_IVLEN + IEEE80211_WEP_KIDLEN +
71 			  IEEE80211_WEP_EXTIVLEN,
72 	.ic_trailer	= IEEE80211_WEP_CRCLEN,
73 	.ic_miclen	= IEEE80211_WEP_MICLEN,
74 	.ic_attach	= tkip_attach,
75 	.ic_detach	= tkip_detach,
76 	.ic_setkey	= tkip_setkey,
77 	.ic_encap	= tkip_encap,
78 	.ic_decap	= tkip_decap,
79 	.ic_enmic	= tkip_enmic,
80 	.ic_demic	= tkip_demic,
81 };
82 
83 #define	memmove(dst, src, n)	ovbcopy(src, dst, n)
84 
85 struct tkip_ctx {
86 	struct ieee80211com *tc_ic;	/* for diagnostics */
87 
88 	uint16_t	tx_ttak[5];
89 	int		tx_phase1_done;
90 	uint8_t		tx_rc4key[16];		/* XXX for test module; make locals? */
91 
92 	uint16_t	rx_ttak[5];
93 	int		rx_phase1_done;
94 	uint8_t		rx_rc4key[16];		/* XXX for test module; make locals? */
95 	uint64_t	rx_rsc;		/* held until MIC verified */
96 };
97 
98 static	void michael_mic(struct tkip_ctx *, const uint8_t *key,
99 		struct mbuf *m, u_int off, size_t data_len,
100 		uint8_t mic[IEEE80211_WEP_MICLEN]);
101 static	int tkip_encrypt(struct tkip_ctx *, struct ieee80211_key *,
102 		struct mbuf *, int hdr_len);
103 static	int tkip_decrypt(struct tkip_ctx *, struct ieee80211_key *,
104 		struct mbuf *, int hdr_len);
105 
106 /* number of references from net80211 layer */
107 static	int nrefs = 0;
108 
109 static void *
110 tkip_attach(struct ieee80211com *ic, struct ieee80211_key *k)
111 {
112 	struct tkip_ctx *ctx;
113 
114 	ctx = malloc(sizeof(struct tkip_ctx), M_DEVBUF, M_NOWAIT | M_ZERO);
115 	if (ctx == NULL) {
116 		ic->ic_stats.is_crypto_nomem++;
117 		return NULL;
118 	}
119 
120 	ctx->tc_ic = ic;
121 	nrefs++;			/* NB: we assume caller locking */
122 	return ctx;
123 }
124 
125 static void
126 tkip_detach(struct ieee80211_key *k)
127 {
128 	struct tkip_ctx *ctx = k->wk_private;
129 
130 	free(ctx, M_DEVBUF);
131 	KASSERT(nrefs > 0, ("imbalanced attach/detach"));
132 	nrefs--;			/* NB: we assume caller locking */
133 }
134 
135 static int
136 tkip_setkey(struct ieee80211_key *k)
137 {
138 	struct tkip_ctx *ctx = k->wk_private;
139 
140 	if (k->wk_keylen != (128/NBBY)) {
141 		(void) ctx;		/* XXX */
142 		IEEE80211_DPRINTF(ctx->tc_ic, IEEE80211_MSG_CRYPTO,
143 			"%s: Invalid key length %u, expecting %u\n",
144 			__func__, k->wk_keylen, 128/NBBY);
145 		return 0;
146 	}
147 	k->wk_keytsc = 1;		/* TSC starts at 1 */
148 	return 1;
149 }
150 
151 /*
152  * Add privacy headers and do any s/w encryption required.
153  */
154 static int
155 tkip_encap(struct ieee80211_key *k, struct mbuf *m, uint8_t keyid)
156 {
157 	struct tkip_ctx *ctx = k->wk_private;
158 	struct ieee80211com *ic = ctx->tc_ic;
159 	uint8_t *ivp;
160 	int hdrlen;
161 
162 	/*
163 	 * Handle TKIP counter measures requirement.
164 	 */
165 	if (ic->ic_flags & IEEE80211_F_COUNTERM) {
166 #ifdef IEEE80211_DEBUG
167 		struct ieee80211_frame *wh = mtod(m, struct ieee80211_frame *);
168 #endif
169 
170 		IEEE80211_DPRINTF(ic, IEEE80211_MSG_CRYPTO,
171 			"[%6D] Discard frame due to countermeasures (%s)\n",
172 			wh->i_addr2, ":", __func__);
173 		ic->ic_stats.is_crypto_tkipcm++;
174 		return 0;
175 	}
176 	hdrlen = ieee80211_hdrspace(ic, mtod(m, void *));
177 
178 	/*
179 	 * Copy down 802.11 header and add the IV, KeyID, and ExtIV.
180 	 */
181 	M_PREPEND(m, tkip.ic_header, M_NOWAIT);
182 	if (m == NULL)
183 		return 0;
184 	ivp = mtod(m, uint8_t *);
185 	memmove(ivp, ivp + tkip.ic_header, hdrlen);
186 	ivp += hdrlen;
187 
188 	ivp[0] = k->wk_keytsc >> 8;		/* TSC1 */
189 	ivp[1] = (ivp[0] | 0x20) & 0x7f;	/* WEP seed */
190 	ivp[2] = k->wk_keytsc >> 0;		/* TSC0 */
191 	ivp[3] = keyid | IEEE80211_WEP_EXTIV;	/* KeyID | ExtID */
192 	ivp[4] = k->wk_keytsc >> 16;		/* TSC2 */
193 	ivp[5] = k->wk_keytsc >> 24;		/* TSC3 */
194 	ivp[6] = k->wk_keytsc >> 32;		/* TSC4 */
195 	ivp[7] = k->wk_keytsc >> 40;		/* TSC5 */
196 
197 	/*
198 	 * Finally, do software encrypt if neeed.
199 	 */
200 	if (k->wk_flags & IEEE80211_KEY_SWCRYPT) {
201 		if (!tkip_encrypt(ctx, k, m, hdrlen))
202 			return 0;
203 		/* NB: tkip_encrypt handles wk_keytsc */
204 	} else
205 		k->wk_keytsc++;
206 
207 	return 1;
208 }
209 
210 /*
211  * Add MIC to the frame as needed.
212  */
213 static int
214 tkip_enmic(struct ieee80211_key *k, struct mbuf *m, int force)
215 {
216 	struct tkip_ctx *ctx = k->wk_private;
217 
218 	if (force || (k->wk_flags & IEEE80211_KEY_SWMIC)) {
219 		struct ieee80211_frame *wh = mtod(m, struct ieee80211_frame *);
220 		struct ieee80211com *ic = ctx->tc_ic;
221 		int hdrlen;
222 		uint8_t mic[IEEE80211_WEP_MICLEN];
223 
224 		ic->ic_stats.is_crypto_tkipenmic++;
225 
226 		hdrlen = ieee80211_hdrspace(ic, wh);
227 
228 		michael_mic(ctx, k->wk_txmic,
229 			m, hdrlen, m->m_pkthdr.len - hdrlen, mic);
230 		return ieee80211_mbuf_append(m, tkip.ic_miclen, mic);
231 	}
232 	return 1;
233 }
234 
235 static __inline uint64_t
236 READ_6(uint8_t b0, uint8_t b1, uint8_t b2, uint8_t b3, uint8_t b4, uint8_t b5)
237 {
238 	uint32_t iv32 = (b0 << 0) | (b1 << 8) | (b2 << 16) | (b3 << 24);
239 	uint16_t iv16 = (b4 << 0) | (b5 << 8);
240 	return (((uint64_t)iv16) << 32) | iv32;
241 }
242 
243 /*
244  * Validate and strip privacy headers (and trailer) for a
245  * received frame.  If necessary, decrypt the frame using
246  * the specified key.
247  */
248 static int
249 tkip_decap(struct ieee80211_key *k, struct mbuf *m, int hdrlen)
250 {
251 	struct tkip_ctx *ctx = k->wk_private;
252 	struct ieee80211com *ic = ctx->tc_ic;
253 	struct ieee80211_frame *wh;
254 	uint8_t *ivp;
255 
256 	/*
257 	 * Header should have extended IV and sequence number;
258 	 * verify the former and validate the latter.
259 	 */
260 	wh = mtod(m, struct ieee80211_frame *);
261 	ivp = mtod(m, uint8_t *) + hdrlen;
262 	if ((ivp[IEEE80211_WEP_IVLEN] & IEEE80211_WEP_EXTIV) == 0) {
263 		/*
264 		 * No extended IV; discard frame.
265 		 */
266 		IEEE80211_DPRINTF(ctx->tc_ic, IEEE80211_MSG_CRYPTO,
267 			"[%6D] missing ExtIV for TKIP cipher\n",
268 			wh->i_addr2, ":");
269 		ctx->tc_ic->ic_stats.is_rx_tkipformat++;
270 		return 0;
271 	}
272 	/*
273 	 * Handle TKIP counter measures requirement.
274 	 */
275 	if (ic->ic_flags & IEEE80211_F_COUNTERM) {
276 		IEEE80211_DPRINTF(ic, IEEE80211_MSG_CRYPTO,
277 			"[%6D] discard frame due to countermeasures (%s)\n",
278 			wh->i_addr2, ":", __func__);
279 		ic->ic_stats.is_crypto_tkipcm++;
280 		return 0;
281 	}
282 
283 	ctx->rx_rsc = READ_6(ivp[2], ivp[0], ivp[4], ivp[5], ivp[6], ivp[7]);
284 	if (ctx->rx_rsc <= k->wk_keyrsc) {
285 		/*
286 		 * Replay violation; notify upper layer.
287 		 */
288 		ieee80211_notify_replay_failure(ctx->tc_ic, wh, k, ctx->rx_rsc);
289 		ctx->tc_ic->ic_stats.is_rx_tkipreplay++;
290 		return 0;
291 	}
292 	/*
293 	 * NB: We can't update the rsc in the key until MIC is verified.
294 	 *
295 	 * We assume we are not preempted between doing the check above
296 	 * and updating wk_keyrsc when stripping the MIC in tkip_demic.
297 	 * Otherwise we might process another packet and discard it as
298 	 * a replay.
299 	 */
300 
301 	/*
302 	 * Check if the device handled the decrypt in hardware.
303 	 * If so we just strip the header; otherwise we need to
304 	 * handle the decrypt in software.
305 	 */
306 	if ((k->wk_flags & IEEE80211_KEY_SWCRYPT) &&
307 	    !tkip_decrypt(ctx, k, m, hdrlen))
308 		return 0;
309 
310 	/*
311 	 * Copy up 802.11 header and strip crypto bits.
312 	 */
313 	memmove(mtod(m, uint8_t *) + tkip.ic_header, mtod(m, void *), hdrlen);
314 	m_adj(m, tkip.ic_header);
315 	m_adj(m, -tkip.ic_trailer);
316 
317 	return 1;
318 }
319 
320 /*
321  * Verify and strip MIC from the frame.
322  */
323 static int
324 tkip_demic(struct ieee80211_key *k, struct mbuf *m, int force)
325 {
326 	struct tkip_ctx *ctx = k->wk_private;
327 
328 	if (force || (k->wk_flags & IEEE80211_KEY_SWMIC)) {
329 		struct ieee80211_frame *wh = mtod(m, struct ieee80211_frame *);
330 		struct ieee80211com *ic = ctx->tc_ic;
331 		int hdrlen = ieee80211_hdrspace(ic, wh);
332 		uint8_t mic[IEEE80211_WEP_MICLEN];
333 		uint8_t mic0[IEEE80211_WEP_MICLEN];
334 
335 		ic->ic_stats.is_crypto_tkipdemic++;
336 
337 		michael_mic(ctx, k->wk_rxmic,
338 			m, hdrlen, m->m_pkthdr.len - (hdrlen + tkip.ic_miclen),
339 			mic);
340 		m_copydata(m, m->m_pkthdr.len - tkip.ic_miclen,
341 			tkip.ic_miclen, mic0);
342 		if (memcmp(mic, mic0, tkip.ic_miclen)) {
343 			/* NB: 802.11 layer handles statistic and debug msg */
344 			ieee80211_notify_michael_failure(ic, wh,
345 				k->wk_rxkeyix != IEEE80211_KEYIX_NONE ?
346 					k->wk_rxkeyix : k->wk_keyix);
347 			return 0;
348 		}
349 	}
350 	/*
351 	 * Strip MIC from the tail.
352 	 */
353 	m_adj(m, -tkip.ic_miclen);
354 
355 	/*
356 	 * Ok to update rsc now that MIC has been verified.
357 	 */
358 	k->wk_keyrsc = ctx->rx_rsc;
359 
360 	return 1;
361 }
362 
363 /*
364  * Host AP crypt: host-based TKIP encryption implementation for Host AP driver
365  *
366  * Copyright (c) 2003-2004, Jouni Malinen <jkmaline@cc.hut.fi>
367  *
368  * This program is free software; you can redistribute it and/or modify
369  * it under the terms of the GNU General Public License version 2 as
370  * published by the Free Software Foundation. See README and COPYING for
371  * more details.
372  *
373  * Alternatively, this software may be distributed under the terms of BSD
374  * license.
375  */
376 
377 static const uint32_t crc32_table[256] = {
378 	0x00000000L, 0x77073096L, 0xee0e612cL, 0x990951baL, 0x076dc419L,
379 	0x706af48fL, 0xe963a535L, 0x9e6495a3L, 0x0edb8832L, 0x79dcb8a4L,
380 	0xe0d5e91eL, 0x97d2d988L, 0x09b64c2bL, 0x7eb17cbdL, 0xe7b82d07L,
381 	0x90bf1d91L, 0x1db71064L, 0x6ab020f2L, 0xf3b97148L, 0x84be41deL,
382 	0x1adad47dL, 0x6ddde4ebL, 0xf4d4b551L, 0x83d385c7L, 0x136c9856L,
383 	0x646ba8c0L, 0xfd62f97aL, 0x8a65c9ecL, 0x14015c4fL, 0x63066cd9L,
384 	0xfa0f3d63L, 0x8d080df5L, 0x3b6e20c8L, 0x4c69105eL, 0xd56041e4L,
385 	0xa2677172L, 0x3c03e4d1L, 0x4b04d447L, 0xd20d85fdL, 0xa50ab56bL,
386 	0x35b5a8faL, 0x42b2986cL, 0xdbbbc9d6L, 0xacbcf940L, 0x32d86ce3L,
387 	0x45df5c75L, 0xdcd60dcfL, 0xabd13d59L, 0x26d930acL, 0x51de003aL,
388 	0xc8d75180L, 0xbfd06116L, 0x21b4f4b5L, 0x56b3c423L, 0xcfba9599L,
389 	0xb8bda50fL, 0x2802b89eL, 0x5f058808L, 0xc60cd9b2L, 0xb10be924L,
390 	0x2f6f7c87L, 0x58684c11L, 0xc1611dabL, 0xb6662d3dL, 0x76dc4190L,
391 	0x01db7106L, 0x98d220bcL, 0xefd5102aL, 0x71b18589L, 0x06b6b51fL,
392 	0x9fbfe4a5L, 0xe8b8d433L, 0x7807c9a2L, 0x0f00f934L, 0x9609a88eL,
393 	0xe10e9818L, 0x7f6a0dbbL, 0x086d3d2dL, 0x91646c97L, 0xe6635c01L,
394 	0x6b6b51f4L, 0x1c6c6162L, 0x856530d8L, 0xf262004eL, 0x6c0695edL,
395 	0x1b01a57bL, 0x8208f4c1L, 0xf50fc457L, 0x65b0d9c6L, 0x12b7e950L,
396 	0x8bbeb8eaL, 0xfcb9887cL, 0x62dd1ddfL, 0x15da2d49L, 0x8cd37cf3L,
397 	0xfbd44c65L, 0x4db26158L, 0x3ab551ceL, 0xa3bc0074L, 0xd4bb30e2L,
398 	0x4adfa541L, 0x3dd895d7L, 0xa4d1c46dL, 0xd3d6f4fbL, 0x4369e96aL,
399 	0x346ed9fcL, 0xad678846L, 0xda60b8d0L, 0x44042d73L, 0x33031de5L,
400 	0xaa0a4c5fL, 0xdd0d7cc9L, 0x5005713cL, 0x270241aaL, 0xbe0b1010L,
401 	0xc90c2086L, 0x5768b525L, 0x206f85b3L, 0xb966d409L, 0xce61e49fL,
402 	0x5edef90eL, 0x29d9c998L, 0xb0d09822L, 0xc7d7a8b4L, 0x59b33d17L,
403 	0x2eb40d81L, 0xb7bd5c3bL, 0xc0ba6cadL, 0xedb88320L, 0x9abfb3b6L,
404 	0x03b6e20cL, 0x74b1d29aL, 0xead54739L, 0x9dd277afL, 0x04db2615L,
405 	0x73dc1683L, 0xe3630b12L, 0x94643b84L, 0x0d6d6a3eL, 0x7a6a5aa8L,
406 	0xe40ecf0bL, 0x9309ff9dL, 0x0a00ae27L, 0x7d079eb1L, 0xf00f9344L,
407 	0x8708a3d2L, 0x1e01f268L, 0x6906c2feL, 0xf762575dL, 0x806567cbL,
408 	0x196c3671L, 0x6e6b06e7L, 0xfed41b76L, 0x89d32be0L, 0x10da7a5aL,
409 	0x67dd4accL, 0xf9b9df6fL, 0x8ebeeff9L, 0x17b7be43L, 0x60b08ed5L,
410 	0xd6d6a3e8L, 0xa1d1937eL, 0x38d8c2c4L, 0x4fdff252L, 0xd1bb67f1L,
411 	0xa6bc5767L, 0x3fb506ddL, 0x48b2364bL, 0xd80d2bdaL, 0xaf0a1b4cL,
412 	0x36034af6L, 0x41047a60L, 0xdf60efc3L, 0xa867df55L, 0x316e8eefL,
413 	0x4669be79L, 0xcb61b38cL, 0xbc66831aL, 0x256fd2a0L, 0x5268e236L,
414 	0xcc0c7795L, 0xbb0b4703L, 0x220216b9L, 0x5505262fL, 0xc5ba3bbeL,
415 	0xb2bd0b28L, 0x2bb45a92L, 0x5cb36a04L, 0xc2d7ffa7L, 0xb5d0cf31L,
416 	0x2cd99e8bL, 0x5bdeae1dL, 0x9b64c2b0L, 0xec63f226L, 0x756aa39cL,
417 	0x026d930aL, 0x9c0906a9L, 0xeb0e363fL, 0x72076785L, 0x05005713L,
418 	0x95bf4a82L, 0xe2b87a14L, 0x7bb12baeL, 0x0cb61b38L, 0x92d28e9bL,
419 	0xe5d5be0dL, 0x7cdcefb7L, 0x0bdbdf21L, 0x86d3d2d4L, 0xf1d4e242L,
420 	0x68ddb3f8L, 0x1fda836eL, 0x81be16cdL, 0xf6b9265bL, 0x6fb077e1L,
421 	0x18b74777L, 0x88085ae6L, 0xff0f6a70L, 0x66063bcaL, 0x11010b5cL,
422 	0x8f659effL, 0xf862ae69L, 0x616bffd3L, 0x166ccf45L, 0xa00ae278L,
423 	0xd70dd2eeL, 0x4e048354L, 0x3903b3c2L, 0xa7672661L, 0xd06016f7L,
424 	0x4969474dL, 0x3e6e77dbL, 0xaed16a4aL, 0xd9d65adcL, 0x40df0b66L,
425 	0x37d83bf0L, 0xa9bcae53L, 0xdebb9ec5L, 0x47b2cf7fL, 0x30b5ffe9L,
426 	0xbdbdf21cL, 0xcabac28aL, 0x53b39330L, 0x24b4a3a6L, 0xbad03605L,
427 	0xcdd70693L, 0x54de5729L, 0x23d967bfL, 0xb3667a2eL, 0xc4614ab8L,
428 	0x5d681b02L, 0x2a6f2b94L, 0xb40bbe37L, 0xc30c8ea1L, 0x5a05df1bL,
429 	0x2d02ef8dL
430 };
431 
432 static __inline uint16_t
433 RotR1(uint16_t val)
434 {
435 	return (val >> 1) | (val << 15);
436 }
437 
438 static __inline uint8_t
439 Lo8(uint16_t val)
440 {
441 	return val & 0xff;
442 }
443 
444 static __inline uint8_t
445 Hi8(uint16_t val)
446 {
447 	return val >> 8;
448 }
449 
450 static __inline uint16_t
451 Lo16(uint32_t val)
452 {
453 	return val & 0xffff;
454 }
455 
456 static __inline uint16_t
457 Hi16(uint32_t val)
458 {
459 	return val >> 16;
460 }
461 
462 static __inline uint16_t
463 Mk16(uint8_t hi, uint8_t lo)
464 {
465 	return lo | (((uint16_t) hi) << 8);
466 }
467 
468 static __inline uint16_t
469 Mk16_le(const uint16_t *v)
470 {
471 	return le16toh(*v);
472 }
473 
474 static const uint16_t Sbox[256] = {
475 	0xC6A5, 0xF884, 0xEE99, 0xF68D, 0xFF0D, 0xD6BD, 0xDEB1, 0x9154,
476 	0x6050, 0x0203, 0xCEA9, 0x567D, 0xE719, 0xB562, 0x4DE6, 0xEC9A,
477 	0x8F45, 0x1F9D, 0x8940, 0xFA87, 0xEF15, 0xB2EB, 0x8EC9, 0xFB0B,
478 	0x41EC, 0xB367, 0x5FFD, 0x45EA, 0x23BF, 0x53F7, 0xE496, 0x9B5B,
479 	0x75C2, 0xE11C, 0x3DAE, 0x4C6A, 0x6C5A, 0x7E41, 0xF502, 0x834F,
480 	0x685C, 0x51F4, 0xD134, 0xF908, 0xE293, 0xAB73, 0x6253, 0x2A3F,
481 	0x080C, 0x9552, 0x4665, 0x9D5E, 0x3028, 0x37A1, 0x0A0F, 0x2FB5,
482 	0x0E09, 0x2436, 0x1B9B, 0xDF3D, 0xCD26, 0x4E69, 0x7FCD, 0xEA9F,
483 	0x121B, 0x1D9E, 0x5874, 0x342E, 0x362D, 0xDCB2, 0xB4EE, 0x5BFB,
484 	0xA4F6, 0x764D, 0xB761, 0x7DCE, 0x527B, 0xDD3E, 0x5E71, 0x1397,
485 	0xA6F5, 0xB968, 0x0000, 0xC12C, 0x4060, 0xE31F, 0x79C8, 0xB6ED,
486 	0xD4BE, 0x8D46, 0x67D9, 0x724B, 0x94DE, 0x98D4, 0xB0E8, 0x854A,
487 	0xBB6B, 0xC52A, 0x4FE5, 0xED16, 0x86C5, 0x9AD7, 0x6655, 0x1194,
488 	0x8ACF, 0xE910, 0x0406, 0xFE81, 0xA0F0, 0x7844, 0x25BA, 0x4BE3,
489 	0xA2F3, 0x5DFE, 0x80C0, 0x058A, 0x3FAD, 0x21BC, 0x7048, 0xF104,
490 	0x63DF, 0x77C1, 0xAF75, 0x4263, 0x2030, 0xE51A, 0xFD0E, 0xBF6D,
491 	0x814C, 0x1814, 0x2635, 0xC32F, 0xBEE1, 0x35A2, 0x88CC, 0x2E39,
492 	0x9357, 0x55F2, 0xFC82, 0x7A47, 0xC8AC, 0xBAE7, 0x322B, 0xE695,
493 	0xC0A0, 0x1998, 0x9ED1, 0xA37F, 0x4466, 0x547E, 0x3BAB, 0x0B83,
494 	0x8CCA, 0xC729, 0x6BD3, 0x283C, 0xA779, 0xBCE2, 0x161D, 0xAD76,
495 	0xDB3B, 0x6456, 0x744E, 0x141E, 0x92DB, 0x0C0A, 0x486C, 0xB8E4,
496 	0x9F5D, 0xBD6E, 0x43EF, 0xC4A6, 0x39A8, 0x31A4, 0xD337, 0xF28B,
497 	0xD532, 0x8B43, 0x6E59, 0xDAB7, 0x018C, 0xB164, 0x9CD2, 0x49E0,
498 	0xD8B4, 0xACFA, 0xF307, 0xCF25, 0xCAAF, 0xF48E, 0x47E9, 0x1018,
499 	0x6FD5, 0xF088, 0x4A6F, 0x5C72, 0x3824, 0x57F1, 0x73C7, 0x9751,
500 	0xCB23, 0xA17C, 0xE89C, 0x3E21, 0x96DD, 0x61DC, 0x0D86, 0x0F85,
501 	0xE090, 0x7C42, 0x71C4, 0xCCAA, 0x90D8, 0x0605, 0xF701, 0x1C12,
502 	0xC2A3, 0x6A5F, 0xAEF9, 0x69D0, 0x1791, 0x9958, 0x3A27, 0x27B9,
503 	0xD938, 0xEB13, 0x2BB3, 0x2233, 0xD2BB, 0xA970, 0x0789, 0x33A7,
504 	0x2DB6, 0x3C22, 0x1592, 0xC920, 0x8749, 0xAAFF, 0x5078, 0xA57A,
505 	0x038F, 0x59F8, 0x0980, 0x1A17, 0x65DA, 0xD731, 0x84C6, 0xD0B8,
506 	0x82C3, 0x29B0, 0x5A77, 0x1E11, 0x7BCB, 0xA8FC, 0x6DD6, 0x2C3A,
507 };
508 
509 static __inline uint16_t
510 _S_(uint16_t v)
511 {
512 	uint16_t t = Sbox[Hi8(v)];
513 	return Sbox[Lo8(v)] ^ ((t << 8) | (t >> 8));
514 }
515 
516 #define PHASE1_LOOP_COUNT 8
517 
518 static void
519 tkip_mixing_phase1(uint16_t *TTAK, const uint8_t *TK, const uint8_t *TA,
520 		   uint32_t IV32)
521 {
522 	int i, j;
523 
524 	/* Initialize the 80-bit TTAK from TSC (IV32) and TA[0..5] */
525 	TTAK[0] = Lo16(IV32);
526 	TTAK[1] = Hi16(IV32);
527 	TTAK[2] = Mk16(TA[1], TA[0]);
528 	TTAK[3] = Mk16(TA[3], TA[2]);
529 	TTAK[4] = Mk16(TA[5], TA[4]);
530 
531 	for (i = 0; i < PHASE1_LOOP_COUNT; i++) {
532 		j = 2 * (i & 1);
533 		TTAK[0] += _S_(TTAK[4] ^ Mk16(TK[1 + j], TK[0 + j]));
534 		TTAK[1] += _S_(TTAK[0] ^ Mk16(TK[5 + j], TK[4 + j]));
535 		TTAK[2] += _S_(TTAK[1] ^ Mk16(TK[9 + j], TK[8 + j]));
536 		TTAK[3] += _S_(TTAK[2] ^ Mk16(TK[13 + j], TK[12 + j]));
537 		TTAK[4] += _S_(TTAK[3] ^ Mk16(TK[1 + j], TK[0 + j])) + i;
538 	}
539 }
540 
541 #ifndef _BYTE_ORDER
542 #error "Don't know native byte order"
543 #endif
544 
545 static void
546 tkip_mixing_phase2(uint8_t *WEPSeed, const uint8_t *TK, const uint16_t *TTAK,
547 		   uint16_t IV16)
548 {
549 	/* Make temporary area overlap WEP seed so that the final copy can be
550 	 * avoided on little endian hosts. */
551 	uint16_t *PPK = (uint16_t *) &WEPSeed[4];
552 
553 	/* Step 1 - make copy of TTAK and bring in TSC */
554 	PPK[0] = TTAK[0];
555 	PPK[1] = TTAK[1];
556 	PPK[2] = TTAK[2];
557 	PPK[3] = TTAK[3];
558 	PPK[4] = TTAK[4];
559 	PPK[5] = TTAK[4] + IV16;
560 
561 	/* Step 2 - 96-bit bijective mixing using S-box */
562 	PPK[0] += _S_(PPK[5] ^ Mk16_le((const uint16_t *) &TK[0]));
563 	PPK[1] += _S_(PPK[0] ^ Mk16_le((const uint16_t *) &TK[2]));
564 	PPK[2] += _S_(PPK[1] ^ Mk16_le((const uint16_t *) &TK[4]));
565 	PPK[3] += _S_(PPK[2] ^ Mk16_le((const uint16_t *) &TK[6]));
566 	PPK[4] += _S_(PPK[3] ^ Mk16_le((const uint16_t *) &TK[8]));
567 	PPK[5] += _S_(PPK[4] ^ Mk16_le((const uint16_t *) &TK[10]));
568 
569 	PPK[0] += RotR1(PPK[5] ^ Mk16_le((const uint16_t *) &TK[12]));
570 	PPK[1] += RotR1(PPK[0] ^ Mk16_le((const uint16_t *) &TK[14]));
571 	PPK[2] += RotR1(PPK[1]);
572 	PPK[3] += RotR1(PPK[2]);
573 	PPK[4] += RotR1(PPK[3]);
574 	PPK[5] += RotR1(PPK[4]);
575 
576 	/* Step 3 - bring in last of TK bits, assign 24-bit WEP IV value
577 	 * WEPSeed[0..2] is transmitted as WEP IV */
578 	WEPSeed[0] = Hi8(IV16);
579 	WEPSeed[1] = (Hi8(IV16) | 0x20) & 0x7F;
580 	WEPSeed[2] = Lo8(IV16);
581 	WEPSeed[3] = Lo8((PPK[5] ^ Mk16_le((const uint16_t *) &TK[0])) >> 1);
582 
583 #if _BYTE_ORDER == _BIG_ENDIAN
584 	{
585 		int i;
586 		for (i = 0; i < 6; i++)
587 			PPK[i] = (PPK[i] << 8) | (PPK[i] >> 8);
588 	}
589 #endif
590 }
591 
592 static void
593 wep_encrypt(uint8_t *key, struct mbuf *m0, u_int off, size_t data_len,
594 	    uint8_t icv[IEEE80211_WEP_CRCLEN])
595 {
596 	uint32_t i, j, k, crc;
597 	size_t buflen;
598 	uint8_t S[256];
599 	uint8_t *pos;
600 	struct mbuf *m;
601 #define S_SWAP(a,b) do { uint8_t t = S[a]; S[a] = S[b]; S[b] = t; } while(0)
602 
603 	/* Setup RC4 state */
604 	for (i = 0; i < 256; i++)
605 		S[i] = i;
606 	j = 0;
607 	for (i = 0; i < 256; i++) {
608 		j = (j + S[i] + key[i & 0x0f]) & 0xff;
609 		S_SWAP(i, j);
610 	}
611 
612 	/* Compute CRC32 over unencrypted data and apply RC4 to data */
613 	crc = ~0;
614 	i = j = 0;
615 	m = m0;
616 	pos = mtod(m, uint8_t *) + off;
617 	buflen = m->m_len - off;
618 	for (;;) {
619 		if (buflen > data_len)
620 			buflen = data_len;
621 		data_len -= buflen;
622 		for (k = 0; k < buflen; k++) {
623 			crc = crc32_table[(crc ^ *pos) & 0xff] ^ (crc >> 8);
624 			i = (i + 1) & 0xff;
625 			j = (j + S[i]) & 0xff;
626 			S_SWAP(i, j);
627 			*pos++ ^= S[(S[i] + S[j]) & 0xff];
628 		}
629 		m = m->m_next;
630 		if (m == NULL) {
631 			KASSERT(data_len == 0,
632 			    ("out of buffers with data_len %zu\n", data_len));
633 			break;
634 		}
635 		pos = mtod(m, uint8_t *);
636 		buflen = m->m_len;
637 	}
638 	crc = ~crc;
639 
640 	/* Append little-endian CRC32 and encrypt it to produce ICV */
641 	icv[0] = crc;
642 	icv[1] = crc >> 8;
643 	icv[2] = crc >> 16;
644 	icv[3] = crc >> 24;
645 	for (k = 0; k < IEEE80211_WEP_CRCLEN; k++) {
646 		i = (i + 1) & 0xff;
647 		j = (j + S[i]) & 0xff;
648 		S_SWAP(i, j);
649 		icv[k] ^= S[(S[i] + S[j]) & 0xff];
650 	}
651 }
652 
653 static int
654 wep_decrypt(uint8_t *key, struct mbuf *m, u_int off, size_t data_len)
655 {
656 	uint32_t i, j, k, crc;
657 	uint8_t S[256];
658 	uint8_t *pos, icv[4];
659 	size_t buflen;
660 
661 	/* Setup RC4 state */
662 	for (i = 0; i < 256; i++)
663 		S[i] = i;
664 	j = 0;
665 	for (i = 0; i < 256; i++) {
666 		j = (j + S[i] + key[i & 0x0f]) & 0xff;
667 		S_SWAP(i, j);
668 	}
669 
670 	/* Apply RC4 to data and compute CRC32 over decrypted data */
671 	crc = ~0;
672 	i = j = 0;
673 	pos = mtod(m, uint8_t *) + off;
674 	buflen = m->m_len - off;
675 	for (;;) {
676 		if (buflen > data_len)
677 			buflen = data_len;
678 		data_len -= buflen;
679 		for (k = 0; k < buflen; k++) {
680 			i = (i + 1) & 0xff;
681 			j = (j + S[i]) & 0xff;
682 			S_SWAP(i, j);
683 			*pos ^= S[(S[i] + S[j]) & 0xff];
684 			crc = crc32_table[(crc ^ *pos) & 0xff] ^ (crc >> 8);
685 			pos++;
686 		}
687 		m = m->m_next;
688 		if (m == NULL) {
689 			KASSERT(data_len == 0,
690 			    ("out of buffers with data_len %zu\n", data_len));
691 			break;
692 		}
693 		pos = mtod(m, uint8_t *);
694 		buflen = m->m_len;
695 	}
696 	crc = ~crc;
697 
698 	/* Encrypt little-endian CRC32 and verify that it matches with the
699 	 * received ICV */
700 	icv[0] = crc;
701 	icv[1] = crc >> 8;
702 	icv[2] = crc >> 16;
703 	icv[3] = crc >> 24;
704 	for (k = 0; k < 4; k++) {
705 		i = (i + 1) & 0xff;
706 		j = (j + S[i]) & 0xff;
707 		S_SWAP(i, j);
708 		if ((icv[k] ^ S[(S[i] + S[j]) & 0xff]) != *pos++) {
709 			/* ICV mismatch - drop frame */
710 			return -1;
711 		}
712 	}
713 
714 	return 0;
715 }
716 
717 
718 static __inline uint32_t
719 rotl(uint32_t val, int bits)
720 {
721 	return (val << bits) | (val >> (32 - bits));
722 }
723 
724 
725 static __inline uint32_t
726 rotr(uint32_t val, int bits)
727 {
728 	return (val >> bits) | (val << (32 - bits));
729 }
730 
731 
732 static __inline uint32_t
733 xswap(uint32_t val)
734 {
735 	return ((val & 0x00ff00ff) << 8) | ((val & 0xff00ff00) >> 8);
736 }
737 
738 
739 #define michael_block(l, r)	\
740 do {				\
741 	r ^= rotl(l, 17);	\
742 	l += r;			\
743 	r ^= xswap(l);		\
744 	l += r;			\
745 	r ^= rotl(l, 3);	\
746 	l += r;			\
747 	r ^= rotr(l, 2);	\
748 	l += r;			\
749 } while (0)
750 
751 
752 static __inline uint32_t
753 get_le32_split(uint8_t b0, uint8_t b1, uint8_t b2,
754 				   uint8_t b3)
755 {
756 	return b0 | (b1 << 8) | (b2 << 16) | (b3 << 24);
757 }
758 
759 static __inline uint32_t
760 get_le32(const uint8_t *p)
761 {
762 	return get_le32_split(p[0], p[1], p[2], p[3]);
763 }
764 
765 
766 static __inline void
767 put_le32(uint8_t *p, uint32_t v)
768 {
769 	p[0] = v;
770 	p[1] = v >> 8;
771 	p[2] = v >> 16;
772 	p[3] = v >> 24;
773 }
774 
775 /*
776  * Craft pseudo header used to calculate the MIC.
777  */
778 static void
779 michael_mic_hdr(const struct ieee80211_frame *wh0, uint8_t hdr[16])
780 {
781 	const struct ieee80211_frame_addr4 *wh =
782 		(const struct ieee80211_frame_addr4 *) wh0;
783 
784 	switch (wh->i_fc[1] & IEEE80211_FC1_DIR_MASK) {
785 	case IEEE80211_FC1_DIR_NODS:
786 		IEEE80211_ADDR_COPY(hdr, wh->i_addr1); /* DA */
787 		IEEE80211_ADDR_COPY(hdr + IEEE80211_ADDR_LEN, wh->i_addr2);
788 		break;
789 	case IEEE80211_FC1_DIR_TODS:
790 		IEEE80211_ADDR_COPY(hdr, wh->i_addr3); /* DA */
791 		IEEE80211_ADDR_COPY(hdr + IEEE80211_ADDR_LEN, wh->i_addr2);
792 		break;
793 	case IEEE80211_FC1_DIR_FROMDS:
794 		IEEE80211_ADDR_COPY(hdr, wh->i_addr1); /* DA */
795 		IEEE80211_ADDR_COPY(hdr + IEEE80211_ADDR_LEN, wh->i_addr3);
796 		break;
797 	case IEEE80211_FC1_DIR_DSTODS:
798 		IEEE80211_ADDR_COPY(hdr, wh->i_addr3); /* DA */
799 		IEEE80211_ADDR_COPY(hdr + IEEE80211_ADDR_LEN, wh->i_addr4);
800 		break;
801 	}
802 
803 	if (wh->i_fc[0] & IEEE80211_FC0_SUBTYPE_QOS) {
804 		const struct ieee80211_qosframe *qwh =
805 			(const struct ieee80211_qosframe *) wh;
806 		hdr[12] = qwh->i_qos[0] & IEEE80211_QOS_TID;
807 	} else
808 		hdr[12] = 0;
809 	hdr[13] = hdr[14] = hdr[15] = 0; /* reserved */
810 }
811 
812 static void
813 michael_mic(struct tkip_ctx *ctx, const uint8_t *key,
814 	    struct mbuf *m, u_int off, size_t data_len,
815 	    uint8_t mic[IEEE80211_WEP_MICLEN])
816 {
817 	uint8_t hdr[16];
818 	uint32_t l, r;
819 	const uint8_t *data;
820 	u_int space;
821 
822 	michael_mic_hdr(mtod(m, struct ieee80211_frame *), hdr);
823 
824 	l = get_le32(key);
825 	r = get_le32(key + 4);
826 
827 	/* Michael MIC pseudo header: DA, SA, 3 x 0, Priority */
828 	l ^= get_le32(hdr);
829 	michael_block(l, r);
830 	l ^= get_le32(&hdr[4]);
831 	michael_block(l, r);
832 	l ^= get_le32(&hdr[8]);
833 	michael_block(l, r);
834 	l ^= get_le32(&hdr[12]);
835 	michael_block(l, r);
836 
837 	/* first buffer has special handling */
838 	data = mtod(m, const uint8_t *) + off;
839 	space = m->m_len - off;
840 	for (;;) {
841 		if (space > data_len)
842 			space = data_len;
843 		/* collect 32-bit blocks from current buffer */
844 		while (space >= sizeof(uint32_t)) {
845 			l ^= get_le32(data);
846 			michael_block(l, r);
847 			data += sizeof(uint32_t), space -= sizeof(uint32_t);
848 			data_len -= sizeof(uint32_t);
849 		}
850 		if (data_len < sizeof(uint32_t))
851 			break;
852 		m = m->m_next;
853 		if (m == NULL) {
854 			KASSERT(0, ("out of data, data_len %zu\n", data_len));
855 			break;
856 		}
857 		if (space != 0) {
858 			const uint8_t *data_next;
859 			/*
860 			 * Block straddles buffers, split references.
861 			 */
862 			data_next = mtod(m, const uint8_t *);
863 			KASSERT(m->m_len >= sizeof(uint32_t) - space,
864 				("not enough data in following buffer, "
865 				"m_len %u need %zu\n", m->m_len,
866 				sizeof(uint32_t) - space));
867 			switch (space) {
868 			case 1:
869 				l ^= get_le32_split(data[0], data_next[0],
870 					data_next[1], data_next[2]);
871 				data = data_next + 3;
872 				space = m->m_len - 3;
873 				break;
874 			case 2:
875 				l ^= get_le32_split(data[0], data[1],
876 					data_next[0], data_next[1]);
877 				data = data_next + 2;
878 				space = m->m_len - 2;
879 				break;
880 			case 3:
881 				l ^= get_le32_split(data[0], data[1],
882 					data[2], data_next[0]);
883 				data = data_next + 1;
884 				space = m->m_len - 1;
885 				break;
886 			}
887 			michael_block(l, r);
888 			data_len -= sizeof(uint32_t);
889 		} else {
890 			/*
891 			 * Setup for next buffer.
892 			 */
893 			data = mtod(m, const uint8_t *);
894 			space = m->m_len;
895 		}
896 	}
897 	/* Last block and padding (0x5a, 4..7 x 0) */
898 	switch (data_len) {
899 	case 0:
900 		l ^= get_le32_split(0x5a, 0, 0, 0);
901 		break;
902 	case 1:
903 		l ^= get_le32_split(data[0], 0x5a, 0, 0);
904 		break;
905 	case 2:
906 		l ^= get_le32_split(data[0], data[1], 0x5a, 0);
907 		break;
908 	case 3:
909 		l ^= get_le32_split(data[0], data[1], data[2], 0x5a);
910 		break;
911 	}
912 	michael_block(l, r);
913 	/* l ^= 0; */
914 	michael_block(l, r);
915 
916 	put_le32(mic, l);
917 	put_le32(mic + 4, r);
918 }
919 
920 static int
921 tkip_encrypt(struct tkip_ctx *ctx, struct ieee80211_key *key,
922 	struct mbuf *m, int hdrlen)
923 {
924 	struct ieee80211_frame *wh;
925 	uint8_t icv[IEEE80211_WEP_CRCLEN];
926 
927 	ctx->tc_ic->ic_stats.is_crypto_tkip++;
928 
929 	wh = mtod(m, struct ieee80211_frame *);
930 	if (!ctx->tx_phase1_done) {
931 		tkip_mixing_phase1(ctx->tx_ttak, key->wk_key, wh->i_addr2,
932 				   (uint32_t)(key->wk_keytsc >> 16));
933 		ctx->tx_phase1_done = 1;
934 	}
935 	tkip_mixing_phase2(ctx->tx_rc4key, key->wk_key, ctx->tx_ttak,
936 		(uint16_t)key->wk_keytsc);
937 
938 	wep_encrypt(ctx->tx_rc4key,
939 		m, hdrlen + tkip.ic_header,
940 		m->m_pkthdr.len - (hdrlen + tkip.ic_header),
941 		icv);
942 
943 	/* XXX check return */
944 	ieee80211_mbuf_append(m, IEEE80211_WEP_CRCLEN, icv);
945 
946 	key->wk_keytsc++;
947 	if ((uint16_t)(key->wk_keytsc) == 0)
948 		ctx->tx_phase1_done = 0;
949 	return 1;
950 }
951 
952 static int
953 tkip_decrypt(struct tkip_ctx *ctx, struct ieee80211_key *key,
954 	     struct mbuf *m, int hdrlen)
955 {
956 	struct ieee80211_frame *wh;
957 	uint32_t iv32;
958 	uint16_t iv16;
959 
960 	ctx->tc_ic->ic_stats.is_crypto_tkip++;
961 
962 	wh = mtod(m, struct ieee80211_frame *);
963 	/* NB: tkip_decap already verified header and left seq in rx_rsc */
964 	iv16 = (uint16_t)ctx->rx_rsc;
965 	iv32 = (uint32_t)(ctx->rx_rsc >> 16);
966 
967 	if (iv32 != (uint32_t)(key->wk_keyrsc >> 16) || !ctx->rx_phase1_done) {
968 		tkip_mixing_phase1(ctx->rx_ttak, key->wk_key,
969 			wh->i_addr2, iv32);
970 		ctx->rx_phase1_done = 1;
971 	}
972 	tkip_mixing_phase2(ctx->rx_rc4key, key->wk_key, ctx->rx_ttak, iv16);
973 
974 	/* NB: m is unstripped; deduct headers + ICV to get payload */
975 	if (wep_decrypt(ctx->rx_rc4key,
976 		m, hdrlen + tkip.ic_header,
977 	        m->m_pkthdr.len - (hdrlen + tkip.ic_header + tkip.ic_trailer))) {
978 		if (iv32 != (uint32_t)(key->wk_keyrsc >> 16)) {
979 			/* Previously cached Phase1 result was already lost, so
980 			 * it needs to be recalculated for the next packet. */
981 			ctx->rx_phase1_done = 0;
982 		}
983 		IEEE80211_DPRINTF(ctx->tc_ic, IEEE80211_MSG_CRYPTO,
984 		    "[%6D] TKIP ICV mismatch on decrypt\n",
985 		    wh->i_addr2, ":");
986 		ctx->tc_ic->ic_stats.is_rx_tkipicv++;
987 		return 0;
988 	}
989 	return 1;
990 }
991 
992 /*
993  * Module glue.
994  */
995 static int
996 tkip_modevent(module_t mod, int type, void *unused)
997 {
998 	switch (type) {
999 	case MOD_LOAD:
1000 		ieee80211_crypto_register(&tkip);
1001 		return 0;
1002 	case MOD_UNLOAD:
1003 		if (nrefs) {
1004 			printf("wlan_tkip: still in use (%u dynamic refs)\n",
1005 				nrefs);
1006 			return EBUSY;
1007 		}
1008 		ieee80211_crypto_unregister(&tkip);
1009 		return 0;
1010 	}
1011 	return EINVAL;
1012 }
1013 
1014 static moduledata_t tkip_mod = {
1015 	"wlan_tkip",
1016 	tkip_modevent,
1017 	0
1018 };
1019 DECLARE_MODULE(wlan_tkip, tkip_mod, SI_SUB_DRIVERS, SI_ORDER_FIRST);
1020 MODULE_VERSION(wlan_tkip, 1);
1021 MODULE_DEPEND(wlan_tkip, wlan, 1, 1, 1);
1022