2 * Copyright (c) 2002-2005 Sam Leffler, Errno Consulting
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
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.
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.
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.
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.2 2006/09/05 00:55:49 dillon Exp $
36 * IEEE 802.11i TKIP crypto support.
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.
42 #include <sys/param.h>
43 #include <sys/systm.h>
45 #include <sys/malloc.h>
46 #include <sys/kernel.h>
47 #include <sys/module.h>
48 #include <sys/endian.h>
50 #include <sys/socket.h>
53 #include <net/if_arp.h>
54 #include <net/if_media.h>
55 #include <net/ethernet.h>
57 #include <netproto/802_11/ieee80211_var.h>
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);
67 static const struct ieee80211_cipher 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,
83 #define memmove(dst, src, n) ovbcopy(src, dst, n)
86 struct ieee80211com *tc_ic; /* for diagnostics */
90 uint8_t tx_rc4key[16]; /* XXX for test module; make locals? */
94 uint8_t rx_rc4key[16]; /* XXX for test module; make locals? */
95 uint64_t rx_rsc; /* held until MIC verified */
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);
106 /* number of references from net80211 layer */
107 static int nrefs = 0;
110 tkip_attach(struct ieee80211com *ic, struct ieee80211_key *k)
112 struct tkip_ctx *ctx;
114 ctx = kmalloc(sizeof(struct tkip_ctx), M_DEVBUF, M_NOWAIT | M_ZERO);
116 ic->ic_stats.is_crypto_nomem++;
121 nrefs++; /* NB: we assume caller locking */
126 tkip_detach(struct ieee80211_key *k)
128 struct tkip_ctx *ctx = k->wk_private;
130 kfree(ctx, M_DEVBUF);
131 KASSERT(nrefs > 0, ("imbalanced attach/detach"));
132 nrefs--; /* NB: we assume caller locking */
136 tkip_setkey(struct ieee80211_key *k)
138 struct tkip_ctx *ctx = k->wk_private;
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);
147 k->wk_keytsc = 1; /* TSC starts at 1 */
152 * Add privacy headers and do any s/w encryption required.
155 tkip_encap(struct ieee80211_key *k, struct mbuf *m, uint8_t keyid)
157 struct tkip_ctx *ctx = k->wk_private;
158 struct ieee80211com *ic = ctx->tc_ic;
163 * Handle TKIP counter measures requirement.
165 if (ic->ic_flags & IEEE80211_F_COUNTERM) {
166 #ifdef IEEE80211_DEBUG
167 struct ieee80211_frame *wh = mtod(m, struct ieee80211_frame *);
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++;
176 hdrlen = ieee80211_hdrspace(ic, mtod(m, void *));
179 * Copy down 802.11 header and add the IV, KeyID, and ExtIV.
181 M_PREPEND(m, tkip.ic_header, M_NOWAIT);
184 ivp = mtod(m, uint8_t *);
185 memmove(ivp, ivp + tkip.ic_header, hdrlen);
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 */
198 * Finally, do software encrypt if neeed.
200 if (k->wk_flags & IEEE80211_KEY_SWCRYPT) {
201 if (!tkip_encrypt(ctx, k, m, hdrlen))
203 /* NB: tkip_encrypt handles wk_keytsc */
211 * Add MIC to the frame as needed.
214 tkip_enmic(struct ieee80211_key *k, struct mbuf *m, int force)
216 struct tkip_ctx *ctx = k->wk_private;
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;
222 uint8_t mic[IEEE80211_WEP_MICLEN];
224 ic->ic_stats.is_crypto_tkipenmic++;
226 hdrlen = ieee80211_hdrspace(ic, wh);
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);
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)
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;
244 * Validate and strip privacy headers (and trailer) for a
245 * received frame. If necessary, decrypt the frame using
249 tkip_decap(struct ieee80211_key *k, struct mbuf *m, int hdrlen)
251 struct tkip_ctx *ctx = k->wk_private;
252 struct ieee80211com *ic = ctx->tc_ic;
253 struct ieee80211_frame *wh;
257 * Header should have extended IV and sequence number;
258 * verify the former and validate the latter.
260 wh = mtod(m, struct ieee80211_frame *);
261 ivp = mtod(m, uint8_t *) + hdrlen;
262 if ((ivp[IEEE80211_WEP_IVLEN] & IEEE80211_WEP_EXTIV) == 0) {
264 * No extended IV; discard frame.
266 IEEE80211_DPRINTF(ctx->tc_ic, IEEE80211_MSG_CRYPTO,
267 "[%6D] missing ExtIV for TKIP cipher\n",
269 ctx->tc_ic->ic_stats.is_rx_tkipformat++;
273 * Handle TKIP counter measures requirement.
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++;
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) {
286 * Replay violation; notify upper layer.
288 ieee80211_notify_replay_failure(ctx->tc_ic, wh, k, ctx->rx_rsc);
289 ctx->tc_ic->ic_stats.is_rx_tkipreplay++;
293 * NB: We can't update the rsc in the key until MIC is verified.
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
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.
306 if ((k->wk_flags & IEEE80211_KEY_SWCRYPT) &&
307 !tkip_decrypt(ctx, k, m, hdrlen))
311 * Copy up 802.11 header and strip crypto bits.
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);
321 * Verify and strip MIC from the frame.
324 tkip_demic(struct ieee80211_key *k, struct mbuf *m, int force)
326 struct tkip_ctx *ctx = k->wk_private;
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];
335 ic->ic_stats.is_crypto_tkipdemic++;
337 michael_mic(ctx, k->wk_rxmic,
338 m, hdrlen, m->m_pkthdr.len - (hdrlen + tkip.ic_miclen),
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);
351 * Strip MIC from the tail.
353 m_adj(m, -tkip.ic_miclen);
356 * Ok to update rsc now that MIC has been verified.
358 k->wk_keyrsc = ctx->rx_rsc;
364 * Host AP crypt: host-based TKIP encryption implementation for Host AP driver
366 * Copyright (c) 2003-2004, Jouni Malinen <jkmaline@cc.hut.fi>
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
373 * Alternatively, this software may be distributed under the terms of BSD
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,
432 static __inline uint16_t
435 return (val >> 1) | (val << 15);
438 static __inline uint8_t
444 static __inline uint8_t
450 static __inline uint16_t
456 static __inline uint16_t
462 static __inline uint16_t
463 Mk16(uint8_t hi, uint8_t lo)
465 return lo | (((uint16_t) hi) << 8);
468 static __inline uint16_t
469 Mk16_le(const uint16_t *v)
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,
509 static __inline uint16_t
512 uint16_t t = Sbox[Hi8(v)];
513 return Sbox[Lo8(v)] ^ ((t << 8) | (t >> 8));
516 #define PHASE1_LOOP_COUNT 8
519 tkip_mixing_phase1(uint16_t *TTAK, const uint8_t *TK, const uint8_t *TA,
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]);
531 for (i = 0; i < PHASE1_LOOP_COUNT; i++) {
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;
542 #error "Don't know native byte order"
546 tkip_mixing_phase2(uint8_t *WEPSeed, const uint8_t *TK, const uint16_t *TTAK,
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];
553 /* Step 1 - make copy of TTAK and bring in TSC */
559 PPK[5] = TTAK[4] + IV16;
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]));
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]);
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);
583 #if _BYTE_ORDER == _BIG_ENDIAN
586 for (i = 0; i < 6; i++)
587 PPK[i] = (PPK[i] << 8) | (PPK[i] >> 8);
593 wep_encrypt(uint8_t *key, struct mbuf *m0, u_int off, size_t data_len,
594 uint8_t icv[IEEE80211_WEP_CRCLEN])
596 uint32_t i, j, k, crc;
601 #define S_SWAP(a,b) do { uint8_t t = S[a]; S[a] = S[b]; S[b] = t; } while(0)
603 /* Setup RC4 state */
604 for (i = 0; i < 256; i++)
607 for (i = 0; i < 256; i++) {
608 j = (j + S[i] + key[i & 0x0f]) & 0xff;
612 /* Compute CRC32 over unencrypted data and apply RC4 to data */
616 pos = mtod(m, uint8_t *) + off;
617 buflen = m->m_len - off;
619 if (buflen > data_len)
622 for (k = 0; k < buflen; k++) {
623 crc = crc32_table[(crc ^ *pos) & 0xff] ^ (crc >> 8);
625 j = (j + S[i]) & 0xff;
627 *pos++ ^= S[(S[i] + S[j]) & 0xff];
631 KASSERT(data_len == 0,
632 ("out of buffers with data_len %zu\n", data_len));
635 pos = mtod(m, uint8_t *);
640 /* Append little-endian CRC32 and encrypt it to produce ICV */
645 for (k = 0; k < IEEE80211_WEP_CRCLEN; k++) {
647 j = (j + S[i]) & 0xff;
649 icv[k] ^= S[(S[i] + S[j]) & 0xff];
654 wep_decrypt(uint8_t *key, struct mbuf *m, u_int off, size_t data_len)
656 uint32_t i, j, k, crc;
658 uint8_t *pos, icv[4];
661 /* Setup RC4 state */
662 for (i = 0; i < 256; i++)
665 for (i = 0; i < 256; i++) {
666 j = (j + S[i] + key[i & 0x0f]) & 0xff;
670 /* Apply RC4 to data and compute CRC32 over decrypted data */
673 pos = mtod(m, uint8_t *) + off;
674 buflen = m->m_len - off;
676 if (buflen > data_len)
679 for (k = 0; k < buflen; k++) {
681 j = (j + S[i]) & 0xff;
683 *pos ^= S[(S[i] + S[j]) & 0xff];
684 crc = crc32_table[(crc ^ *pos) & 0xff] ^ (crc >> 8);
689 KASSERT(data_len == 0,
690 ("out of buffers with data_len %zu\n", data_len));
693 pos = mtod(m, uint8_t *);
698 /* Encrypt little-endian CRC32 and verify that it matches with the
704 for (k = 0; k < 4; k++) {
706 j = (j + S[i]) & 0xff;
708 if ((icv[k] ^ S[(S[i] + S[j]) & 0xff]) != *pos++) {
709 /* ICV mismatch - drop frame */
718 static __inline uint32_t
719 rotl(uint32_t val, int bits)
721 return (val << bits) | (val >> (32 - bits));
725 static __inline uint32_t
726 rotr(uint32_t val, int bits)
728 return (val >> bits) | (val << (32 - bits));
732 static __inline uint32_t
735 return ((val & 0x00ff00ff) << 8) | ((val & 0xff00ff00) >> 8);
739 #define michael_block(l, r) \
752 static __inline uint32_t
753 get_le32_split(uint8_t b0, uint8_t b1, uint8_t b2,
756 return b0 | (b1 << 8) | (b2 << 16) | (b3 << 24);
759 static __inline uint32_t
760 get_le32(const uint8_t *p)
762 return get_le32_split(p[0], p[1], p[2], p[3]);
767 put_le32(uint8_t *p, uint32_t v)
776 * Craft pseudo header used to calculate the MIC.
779 michael_mic_hdr(const struct ieee80211_frame *wh0, uint8_t hdr[16])
781 const struct ieee80211_frame_addr4 *wh =
782 (const struct ieee80211_frame_addr4 *) wh0;
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);
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);
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);
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);
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;
809 hdr[13] = hdr[14] = hdr[15] = 0; /* reserved */
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])
822 michael_mic_hdr(mtod(m, struct ieee80211_frame *), hdr);
825 r = get_le32(key + 4);
827 /* Michael MIC pseudo header: DA, SA, 3 x 0, Priority */
830 l ^= get_le32(&hdr[4]);
832 l ^= get_le32(&hdr[8]);
834 l ^= get_le32(&hdr[12]);
837 /* first buffer has special handling */
838 data = mtod(m, const uint8_t *) + off;
839 space = m->m_len - off;
841 if (space > data_len)
843 /* collect 32-bit blocks from current buffer */
844 while (space >= sizeof(uint32_t)) {
847 data += sizeof(uint32_t), space -= sizeof(uint32_t);
848 data_len -= sizeof(uint32_t);
850 if (data_len < sizeof(uint32_t))
854 KASSERT(0, ("out of data, data_len %zu\n", data_len));
858 const uint8_t *data_next;
860 * Block straddles buffers, split references.
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));
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;
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;
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;
888 data_len -= sizeof(uint32_t);
891 * Setup for next buffer.
893 data = mtod(m, const uint8_t *);
897 /* Last block and padding (0x5a, 4..7 x 0) */
900 l ^= get_le32_split(0x5a, 0, 0, 0);
903 l ^= get_le32_split(data[0], 0x5a, 0, 0);
906 l ^= get_le32_split(data[0], data[1], 0x5a, 0);
909 l ^= get_le32_split(data[0], data[1], data[2], 0x5a);
917 put_le32(mic + 4, r);
921 tkip_encrypt(struct tkip_ctx *ctx, struct ieee80211_key *key,
922 struct mbuf *m, int hdrlen)
924 struct ieee80211_frame *wh;
925 uint8_t icv[IEEE80211_WEP_CRCLEN];
927 ctx->tc_ic->ic_stats.is_crypto_tkip++;
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;
935 tkip_mixing_phase2(ctx->tx_rc4key, key->wk_key, ctx->tx_ttak,
936 (uint16_t)key->wk_keytsc);
938 wep_encrypt(ctx->tx_rc4key,
939 m, hdrlen + tkip.ic_header,
940 m->m_pkthdr.len - (hdrlen + tkip.ic_header),
943 /* XXX check return */
944 ieee80211_mbuf_append(m, IEEE80211_WEP_CRCLEN, icv);
947 if ((uint16_t)(key->wk_keytsc) == 0)
948 ctx->tx_phase1_done = 0;
953 tkip_decrypt(struct tkip_ctx *ctx, struct ieee80211_key *key,
954 struct mbuf *m, int hdrlen)
956 struct ieee80211_frame *wh;
960 ctx->tc_ic->ic_stats.is_crypto_tkip++;
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);
967 if (iv32 != (uint32_t)(key->wk_keyrsc >> 16) || !ctx->rx_phase1_done) {
968 tkip_mixing_phase1(ctx->rx_ttak, key->wk_key,
970 ctx->rx_phase1_done = 1;
972 tkip_mixing_phase2(ctx->rx_rc4key, key->wk_key, ctx->rx_ttak, iv16);
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;
983 IEEE80211_DPRINTF(ctx->tc_ic, IEEE80211_MSG_CRYPTO,
984 "[%6D] TKIP ICV mismatch on decrypt\n",
986 ctx->tc_ic->ic_stats.is_rx_tkipicv++;
996 tkip_modevent(module_t mod, int type, void *unused)
1000 ieee80211_crypto_register(&tkip);
1004 printf("wlan_tkip: still in use (%u dynamic refs)\n",
1008 ieee80211_crypto_unregister(&tkip);
1014 static moduledata_t tkip_mod = {
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);