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