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