1 1.23 maxv /* $NetBSD: ieee80211_crypto.c,v 1.23 2018/05/08 07:02:07 maxv Exp $ */ 2 1.20 maxv 3 1.20 maxv /* 4 1.1 dyoung * Copyright (c) 2001 Atsushi Onoe 5 1.7 dyoung * Copyright (c) 2002-2005 Sam Leffler, Errno Consulting 6 1.1 dyoung * All rights reserved. 7 1.1 dyoung * 8 1.1 dyoung * Redistribution and use in source and binary forms, with or without 9 1.1 dyoung * modification, are permitted provided that the following conditions 10 1.1 dyoung * are met: 11 1.1 dyoung * 1. Redistributions of source code must retain the above copyright 12 1.1 dyoung * notice, this list of conditions and the following disclaimer. 13 1.1 dyoung * 2. Redistributions in binary form must reproduce the above copyright 14 1.1 dyoung * notice, this list of conditions and the following disclaimer in the 15 1.1 dyoung * documentation and/or other materials provided with the distribution. 16 1.1 dyoung * 3. The name of the author may not be used to endorse or promote products 17 1.1 dyoung * derived from this software without specific prior written permission. 18 1.1 dyoung * 19 1.1 dyoung * Alternatively, this software may be distributed under the terms of the 20 1.1 dyoung * GNU General Public License ("GPL") version 2 as published by the Free 21 1.1 dyoung * Software Foundation. 22 1.1 dyoung * 23 1.1 dyoung * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 24 1.1 dyoung * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 25 1.1 dyoung * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 26 1.1 dyoung * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 27 1.1 dyoung * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 28 1.1 dyoung * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 29 1.1 dyoung * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 30 1.1 dyoung * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 31 1.1 dyoung * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 32 1.1 dyoung * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 33 1.1 dyoung */ 34 1.1 dyoung 35 1.1 dyoung #include <sys/cdefs.h> 36 1.3 dyoung #ifdef __FreeBSD__ 37 1.10 skrll __FBSDID("$FreeBSD: src/sys/net80211/ieee80211_crypto.c,v 1.12 2005/08/08 18:46:35 sam Exp $"); 38 1.7 dyoung #endif 39 1.7 dyoung #ifdef __NetBSD__ 40 1.23 maxv __KERNEL_RCSID(0, "$NetBSD: ieee80211_crypto.c,v 1.23 2018/05/08 07:02:07 maxv Exp $"); 41 1.3 dyoung #endif 42 1.1 dyoung 43 1.17 pooka #ifdef _KERNEL_OPT 44 1.1 dyoung #include "opt_inet.h" 45 1.17 pooka #endif 46 1.1 dyoung 47 1.7 dyoung /* 48 1.7 dyoung * IEEE 802.11 generic crypto support. 49 1.7 dyoung */ 50 1.1 dyoung #include <sys/param.h> 51 1.21 maxv #include <sys/mbuf.h> 52 1.7 dyoung 53 1.1 dyoung #include <sys/socket.h> 54 1.1 dyoung #include <sys/sockio.h> 55 1.1 dyoung #include <sys/endian.h> 56 1.1 dyoung #include <sys/errno.h> 57 1.1 dyoung #include <sys/proc.h> 58 1.1 dyoung #include <sys/sysctl.h> 59 1.1 dyoung 60 1.1 dyoung #include <net/if.h> 61 1.1 dyoung #include <net/if_media.h> 62 1.1 dyoung #include <net/if_arp.h> 63 1.4 dyoung #include <net/if_ether.h> 64 1.1 dyoung #include <net/if_llc.h> 65 1.1 dyoung 66 1.7 dyoung #include <net80211/ieee80211_netbsd.h> 67 1.1 dyoung #include <net80211/ieee80211_var.h> 68 1.1 dyoung 69 1.7 dyoung /* 70 1.7 dyoung * Table of registered cipher modules. 71 1.7 dyoung */ 72 1.20 maxv static const struct ieee80211_cipher *ciphers[IEEE80211_CIPHER_MAX]; 73 1.1 dyoung 74 1.1 dyoung #ifdef INET 75 1.21 maxv #include <netinet/in.h> 76 1.4 dyoung #include <net/if_ether.h> 77 1.4 dyoung #endif 78 1.1 dyoung 79 1.20 maxv static int _ieee80211_crypto_delkey(struct ieee80211com *, 80 1.20 maxv struct ieee80211_key *); 81 1.7 dyoung 82 1.7 dyoung /* 83 1.7 dyoung * Default "null" key management routines. 84 1.7 dyoung */ 85 1.7 dyoung static int 86 1.10 skrll null_key_alloc(struct ieee80211com *ic, const struct ieee80211_key *k, 87 1.20 maxv ieee80211_keyix *keyix, ieee80211_keyix *rxkeyix) 88 1.7 dyoung { 89 1.9 dyoung if (!(&ic->ic_nw_keys[0] <= k && 90 1.9 dyoung k < &ic->ic_nw_keys[IEEE80211_WEP_NKID])) { 91 1.9 dyoung /* 92 1.9 dyoung * Not in the global key table, the driver should handle this 93 1.9 dyoung * by allocating a slot in the h/w key table/cache. In 94 1.9 dyoung * lieu of that return key slot 0 for any unicast key 95 1.9 dyoung * request. We disallow the request if this is a group key. 96 1.9 dyoung * This default policy does the right thing for legacy hardware 97 1.9 dyoung * with a 4 key table. It also handles devices that pass 98 1.9 dyoung * packets through untouched when marked with the WEP bit 99 1.9 dyoung * and key index 0. 100 1.9 dyoung */ 101 1.10 skrll if (k->wk_flags & IEEE80211_KEY_GROUP) 102 1.10 skrll return 0; 103 1.10 skrll *keyix = 0; /* NB: use key index 0 for ucast key */ 104 1.10 skrll } else { 105 1.10 skrll *keyix = k - ic->ic_nw_keys; 106 1.9 dyoung } 107 1.10 skrll *rxkeyix = IEEE80211_KEYIX_NONE; /* XXX maybe *keyix? */ 108 1.10 skrll return 1; 109 1.7 dyoung } 110 1.20 maxv 111 1.7 dyoung static int 112 1.20 maxv null_key_delete(struct ieee80211com *ic, const struct ieee80211_key *k) 113 1.7 dyoung { 114 1.7 dyoung return 1; 115 1.7 dyoung } 116 1.20 maxv 117 1.20 maxv static int 118 1.20 maxv null_key_set(struct ieee80211com *ic, const struct ieee80211_key *k, 119 1.14 christos const u_int8_t mac[IEEE80211_ADDR_LEN]) 120 1.7 dyoung { 121 1.7 dyoung return 1; 122 1.7 dyoung } 123 1.20 maxv 124 1.20 maxv static void 125 1.20 maxv null_key_update(struct ieee80211com *ic) 126 1.20 maxv { 127 1.20 maxv ; 128 1.20 maxv } 129 1.7 dyoung 130 1.7 dyoung /* 131 1.7 dyoung * Write-arounds for common operations. 132 1.7 dyoung */ 133 1.7 dyoung static __inline void 134 1.7 dyoung cipher_detach(struct ieee80211_key *key) 135 1.7 dyoung { 136 1.7 dyoung key->wk_cipher->ic_detach(key); 137 1.7 dyoung } 138 1.7 dyoung 139 1.21 maxv /* 140 1.7 dyoung * Wrappers for driver key management methods. 141 1.7 dyoung */ 142 1.7 dyoung static __inline int 143 1.20 maxv dev_key_alloc(struct ieee80211com *ic, const struct ieee80211_key *key, 144 1.20 maxv ieee80211_keyix *keyix, ieee80211_keyix *rxkeyix) 145 1.7 dyoung { 146 1.10 skrll return ic->ic_crypto.cs_key_alloc(ic, key, keyix, rxkeyix); 147 1.7 dyoung } 148 1.7 dyoung 149 1.7 dyoung static __inline int 150 1.20 maxv dev_key_delete(struct ieee80211com *ic, const struct ieee80211_key *key) 151 1.7 dyoung { 152 1.7 dyoung return ic->ic_crypto.cs_key_delete(ic, key); 153 1.7 dyoung } 154 1.1 dyoung 155 1.7 dyoung static __inline int 156 1.7 dyoung dev_key_set(struct ieee80211com *ic, const struct ieee80211_key *key, 157 1.20 maxv const u_int8_t mac[IEEE80211_ADDR_LEN]) 158 1.7 dyoung { 159 1.7 dyoung return ic->ic_crypto.cs_key_set(ic, key, mac); 160 1.7 dyoung } 161 1.1 dyoung 162 1.7 dyoung /* 163 1.7 dyoung * Setup crypto support. 164 1.7 dyoung */ 165 1.1 dyoung void 166 1.7 dyoung ieee80211_crypto_attach(struct ieee80211com *ic) 167 1.1 dyoung { 168 1.7 dyoung struct ieee80211_crypto_state *cs = &ic->ic_crypto; 169 1.7 dyoung int i; 170 1.1 dyoung 171 1.7 dyoung /* NB: we assume everything is pre-zero'd */ 172 1.7 dyoung cs->cs_def_txkey = IEEE80211_KEYIX_NONE; 173 1.10 skrll cs->cs_max_keyix = IEEE80211_WEP_NKID; 174 1.7 dyoung ciphers[IEEE80211_CIPHER_NONE] = &ieee80211_cipher_none; 175 1.7 dyoung for (i = 0; i < IEEE80211_WEP_NKID; i++) 176 1.7 dyoung ieee80211_crypto_resetkey(ic, &cs->cs_nw_keys[i], 177 1.7 dyoung IEEE80211_KEYIX_NONE); 178 1.1 dyoung /* 179 1.7 dyoung * Initialize the driver key support routines to noop entries. 180 1.7 dyoung * This is useful especially for the cipher test modules. 181 1.1 dyoung */ 182 1.7 dyoung cs->cs_key_alloc = null_key_alloc; 183 1.7 dyoung cs->cs_key_set = null_key_set; 184 1.7 dyoung cs->cs_key_delete = null_key_delete; 185 1.7 dyoung cs->cs_key_update_begin = null_key_update; 186 1.7 dyoung cs->cs_key_update_end = null_key_update; 187 1.1 dyoung } 188 1.1 dyoung 189 1.7 dyoung /* 190 1.7 dyoung * Teardown crypto support. 191 1.7 dyoung */ 192 1.1 dyoung void 193 1.7 dyoung ieee80211_crypto_detach(struct ieee80211com *ic) 194 1.1 dyoung { 195 1.7 dyoung ieee80211_crypto_delglobalkeys(ic); 196 1.7 dyoung } 197 1.1 dyoung 198 1.7 dyoung /* 199 1.7 dyoung * Register a crypto cipher module. 200 1.7 dyoung */ 201 1.7 dyoung void 202 1.7 dyoung ieee80211_crypto_register(const struct ieee80211_cipher *cip) 203 1.7 dyoung { 204 1.7 dyoung if (cip->ic_cipher >= IEEE80211_CIPHER_MAX) { 205 1.7 dyoung printf("%s: cipher %s has an invalid cipher index %u\n", 206 1.7 dyoung __func__, cip->ic_name, cip->ic_cipher); 207 1.7 dyoung return; 208 1.7 dyoung } 209 1.7 dyoung if (ciphers[cip->ic_cipher] != NULL && ciphers[cip->ic_cipher] != cip) { 210 1.7 dyoung printf("%s: cipher %s registered with a different template\n", 211 1.7 dyoung __func__, cip->ic_name); 212 1.7 dyoung return; 213 1.1 dyoung } 214 1.7 dyoung ciphers[cip->ic_cipher] = cip; 215 1.1 dyoung } 216 1.1 dyoung 217 1.7 dyoung /* 218 1.7 dyoung * Unregister a crypto cipher module. 219 1.7 dyoung */ 220 1.7 dyoung void 221 1.7 dyoung ieee80211_crypto_unregister(const struct ieee80211_cipher *cip) 222 1.1 dyoung { 223 1.7 dyoung if (cip->ic_cipher >= IEEE80211_CIPHER_MAX) { 224 1.7 dyoung printf("%s: cipher %s has an invalid cipher index %u\n", 225 1.7 dyoung __func__, cip->ic_name, cip->ic_cipher); 226 1.7 dyoung return; 227 1.1 dyoung } 228 1.7 dyoung if (ciphers[cip->ic_cipher] != NULL && ciphers[cip->ic_cipher] != cip) { 229 1.7 dyoung printf("%s: cipher %s registered with a different template\n", 230 1.7 dyoung __func__, cip->ic_name); 231 1.7 dyoung return; 232 1.5 dyoung } 233 1.7 dyoung /* NB: don't complain about not being registered */ 234 1.7 dyoung /* XXX disallow if references */ 235 1.7 dyoung ciphers[cip->ic_cipher] = NULL; 236 1.7 dyoung } 237 1.7 dyoung 238 1.7 dyoung int 239 1.7 dyoung ieee80211_crypto_available(u_int cipher) 240 1.7 dyoung { 241 1.7 dyoung return cipher < IEEE80211_CIPHER_MAX && ciphers[cipher] != NULL; 242 1.7 dyoung } 243 1.7 dyoung 244 1.7 dyoung /* XXX well-known names! */ 245 1.7 dyoung static const char *cipher_modnames[] = { 246 1.7 dyoung "wlan_wep", /* IEEE80211_CIPHER_WEP */ 247 1.7 dyoung "wlan_tkip", /* IEEE80211_CIPHER_TKIP */ 248 1.7 dyoung "wlan_aes_ocb", /* IEEE80211_CIPHER_AES_OCB */ 249 1.7 dyoung "wlan_ccmp", /* IEEE80211_CIPHER_AES_CCM */ 250 1.7 dyoung "wlan_ckip", /* IEEE80211_CIPHER_CKIP */ 251 1.7 dyoung }; 252 1.7 dyoung 253 1.7 dyoung /* 254 1.7 dyoung * Establish a relationship between the specified key and cipher 255 1.7 dyoung * and, if necessary, allocate a hardware index from the driver. 256 1.7 dyoung * Note that when a fixed key index is required it must be specified 257 1.7 dyoung * and we blindly assign it w/o consulting the driver (XXX). 258 1.7 dyoung * 259 1.7 dyoung * This must be the first call applied to a key; all the other key 260 1.7 dyoung * routines assume wk_cipher is setup. 261 1.7 dyoung * 262 1.7 dyoung * Locking must be handled by the caller using: 263 1.7 dyoung * ieee80211_key_update_begin(ic); 264 1.7 dyoung * ieee80211_key_update_end(ic); 265 1.7 dyoung */ 266 1.7 dyoung int 267 1.20 maxv ieee80211_crypto_newkey(struct ieee80211com *ic, int cipher, int flags, 268 1.20 maxv struct ieee80211_key *key) 269 1.7 dyoung { 270 1.7 dyoung #define N(a) (sizeof(a) / sizeof(a[0])) 271 1.7 dyoung const struct ieee80211_cipher *cip; 272 1.10 skrll ieee80211_keyix keyix, rxkeyix; 273 1.7 dyoung void *keyctx; 274 1.7 dyoung int oflags; 275 1.7 dyoung 276 1.7 dyoung /* 277 1.7 dyoung * Validate cipher and set reference to cipher routines. 278 1.7 dyoung */ 279 1.7 dyoung if (cipher >= IEEE80211_CIPHER_MAX) { 280 1.7 dyoung IEEE80211_DPRINTF(ic, IEEE80211_MSG_CRYPTO, 281 1.7 dyoung "%s: invalid cipher %u\n", __func__, cipher); 282 1.7 dyoung ic->ic_stats.is_crypto_badcipher++; 283 1.7 dyoung return 0; 284 1.1 dyoung } 285 1.7 dyoung cip = ciphers[cipher]; 286 1.20 maxv 287 1.7 dyoung if (cip == NULL) { 288 1.1 dyoung /* 289 1.7 dyoung * Auto-load cipher module if we have a well-known name 290 1.7 dyoung * for it. It might be better to use string names rather 291 1.7 dyoung * than numbers and craft a module name based on the cipher 292 1.7 dyoung * name; e.g. wlan_cipher_<cipher-name>. 293 1.1 dyoung */ 294 1.7 dyoung if (cipher < N(cipher_modnames)) { 295 1.7 dyoung IEEE80211_DPRINTF(ic, IEEE80211_MSG_CRYPTO, 296 1.7 dyoung "%s: unregistered cipher %u, load module %s\n", 297 1.7 dyoung __func__, cipher, cipher_modnames[cipher]); 298 1.7 dyoung ieee80211_load_module(cipher_modnames[cipher]); 299 1.7 dyoung /* 300 1.7 dyoung * If cipher module loaded it should immediately 301 1.7 dyoung * call ieee80211_crypto_register which will fill 302 1.7 dyoung * in the entry in the ciphers array. 303 1.7 dyoung */ 304 1.7 dyoung cip = ciphers[cipher]; 305 1.1 dyoung } 306 1.7 dyoung if (cip == NULL) { 307 1.7 dyoung IEEE80211_DPRINTF(ic, IEEE80211_MSG_CRYPTO, 308 1.7 dyoung "%s: unable to load cipher %u, module %s\n", 309 1.7 dyoung __func__, cipher, 310 1.7 dyoung cipher < N(cipher_modnames) ? 311 1.7 dyoung cipher_modnames[cipher] : "<unknown>"); 312 1.7 dyoung ic->ic_stats.is_crypto_nocipher++; 313 1.7 dyoung return 0; 314 1.1 dyoung } 315 1.7 dyoung } 316 1.7 dyoung 317 1.7 dyoung oflags = key->wk_flags; 318 1.7 dyoung flags &= IEEE80211_KEY_COMMON; 319 1.20 maxv 320 1.7 dyoung /* 321 1.7 dyoung * If the hardware does not support the cipher then 322 1.20 maxv * fall back to a host-based implementation. 323 1.7 dyoung */ 324 1.7 dyoung if ((ic->ic_caps & (1<<cipher)) == 0) { 325 1.7 dyoung IEEE80211_DPRINTF(ic, IEEE80211_MSG_CRYPTO, 326 1.7 dyoung "%s: no h/w support for cipher %s, falling back to s/w\n", 327 1.7 dyoung __func__, cip->ic_name); 328 1.7 dyoung flags |= IEEE80211_KEY_SWCRYPT; 329 1.7 dyoung } 330 1.20 maxv 331 1.7 dyoung /* 332 1.7 dyoung * Hardware TKIP with software MIC is an important 333 1.7 dyoung * combination; we handle it by flagging each key, 334 1.7 dyoung * the cipher modules honor it. 335 1.7 dyoung */ 336 1.7 dyoung if (cipher == IEEE80211_CIPHER_TKIP && 337 1.7 dyoung (ic->ic_caps & IEEE80211_C_TKIPMIC) == 0) { 338 1.7 dyoung IEEE80211_DPRINTF(ic, IEEE80211_MSG_CRYPTO, 339 1.7 dyoung "%s: no h/w support for TKIP MIC, falling back to s/w\n", 340 1.7 dyoung __func__); 341 1.7 dyoung flags |= IEEE80211_KEY_SWMIC; 342 1.7 dyoung } 343 1.7 dyoung 344 1.7 dyoung /* 345 1.7 dyoung * Bind cipher to key instance. Note we do this 346 1.7 dyoung * after checking the device capabilities so the 347 1.7 dyoung * cipher module can optimize space usage based on 348 1.7 dyoung * whether or not it needs to do the cipher work. 349 1.7 dyoung */ 350 1.7 dyoung if (key->wk_cipher != cip || key->wk_flags != flags) { 351 1.7 dyoung again: 352 1.7 dyoung /* 353 1.7 dyoung * Fillin the flags so cipher modules can see s/w 354 1.7 dyoung * crypto requirements and potentially allocate 355 1.7 dyoung * different state and/or attach different method 356 1.7 dyoung * pointers. 357 1.7 dyoung * 358 1.7 dyoung * XXX this is not right when s/w crypto fallback 359 1.7 dyoung * fails and we try to restore previous state. 360 1.7 dyoung */ 361 1.7 dyoung key->wk_flags = flags; 362 1.7 dyoung keyctx = cip->ic_attach(ic, key); 363 1.7 dyoung if (keyctx == NULL) { 364 1.7 dyoung IEEE80211_DPRINTF(ic, IEEE80211_MSG_CRYPTO, 365 1.7 dyoung "%s: unable to attach cipher %s\n", 366 1.7 dyoung __func__, cip->ic_name); 367 1.7 dyoung key->wk_flags = oflags; /* restore old flags */ 368 1.7 dyoung ic->ic_stats.is_crypto_attachfail++; 369 1.7 dyoung return 0; 370 1.1 dyoung } 371 1.7 dyoung cipher_detach(key); 372 1.7 dyoung key->wk_cipher = cip; /* XXX refcnt? */ 373 1.7 dyoung key->wk_private = keyctx; 374 1.7 dyoung } 375 1.7 dyoung /* 376 1.7 dyoung * Commit to requested usage so driver can see the flags. 377 1.7 dyoung */ 378 1.7 dyoung key->wk_flags = flags; 379 1.7 dyoung 380 1.7 dyoung /* 381 1.7 dyoung * Ask the driver for a key index if we don't have one. 382 1.7 dyoung * Note that entries in the global key table always have 383 1.7 dyoung * an index; this means it's safe to call this routine 384 1.7 dyoung * for these entries just to setup the reference to the 385 1.7 dyoung * cipher template. Note also that when using software 386 1.7 dyoung * crypto we also call the driver to give us a key index. 387 1.7 dyoung */ 388 1.7 dyoung if (key->wk_keyix == IEEE80211_KEYIX_NONE) { 389 1.10 skrll if (!dev_key_alloc(ic, key, &keyix, &rxkeyix)) { 390 1.7 dyoung /* 391 1.7 dyoung * Driver has no room; fallback to doing crypto 392 1.7 dyoung * in the host. We change the flags and start the 393 1.7 dyoung * procedure over. If we get back here then there's 394 1.7 dyoung * no hope and we bail. Note that this can leave 395 1.7 dyoung * the key in a inconsistent state if the caller 396 1.7 dyoung * continues to use it. 397 1.7 dyoung */ 398 1.7 dyoung if ((key->wk_flags & IEEE80211_KEY_SWCRYPT) == 0) { 399 1.7 dyoung ic->ic_stats.is_crypto_swfallback++; 400 1.7 dyoung IEEE80211_DPRINTF(ic, IEEE80211_MSG_CRYPTO, 401 1.7 dyoung "%s: no h/w resources for cipher %s, " 402 1.7 dyoung "falling back to s/w\n", __func__, 403 1.7 dyoung cip->ic_name); 404 1.7 dyoung oflags = key->wk_flags; 405 1.7 dyoung flags |= IEEE80211_KEY_SWCRYPT; 406 1.7 dyoung if (cipher == IEEE80211_CIPHER_TKIP) 407 1.7 dyoung flags |= IEEE80211_KEY_SWMIC; 408 1.7 dyoung goto again; 409 1.5 dyoung } 410 1.7 dyoung ic->ic_stats.is_crypto_keyfail++; 411 1.7 dyoung IEEE80211_DPRINTF(ic, IEEE80211_MSG_CRYPTO, 412 1.7 dyoung "%s: unable to setup cipher %s\n", 413 1.7 dyoung __func__, cip->ic_name); 414 1.7 dyoung return 0; 415 1.1 dyoung } 416 1.10 skrll key->wk_keyix = keyix; 417 1.10 skrll key->wk_rxkeyix = rxkeyix; 418 1.7 dyoung } 419 1.7 dyoung return 1; 420 1.7 dyoung #undef N 421 1.7 dyoung } 422 1.7 dyoung 423 1.7 dyoung /* 424 1.7 dyoung * Remove the key (no locking, for internal use). 425 1.7 dyoung */ 426 1.7 dyoung static int 427 1.7 dyoung _ieee80211_crypto_delkey(struct ieee80211com *ic, struct ieee80211_key *key) 428 1.7 dyoung { 429 1.10 skrll ieee80211_keyix keyix; 430 1.7 dyoung 431 1.7 dyoung IASSERT(key->wk_cipher != NULL, ("No cipher!")); 432 1.7 dyoung 433 1.7 dyoung IEEE80211_DPRINTF(ic, IEEE80211_MSG_CRYPTO, 434 1.7 dyoung "%s: %s keyix %u flags 0x%x rsc %ju tsc %ju len %u\n", 435 1.7 dyoung __func__, key->wk_cipher->ic_name, 436 1.7 dyoung key->wk_keyix, key->wk_flags, 437 1.7 dyoung key->wk_keyrsc, key->wk_keytsc, key->wk_keylen); 438 1.7 dyoung 439 1.7 dyoung keyix = key->wk_keyix; 440 1.7 dyoung if (keyix != IEEE80211_KEYIX_NONE) { 441 1.7 dyoung /* 442 1.7 dyoung * Remove hardware entry. 443 1.7 dyoung */ 444 1.7 dyoung /* XXX key cache */ 445 1.7 dyoung if (!dev_key_delete(ic, key)) { 446 1.7 dyoung IEEE80211_DPRINTF(ic, IEEE80211_MSG_CRYPTO, 447 1.7 dyoung "%s: driver did not delete key index %u\n", 448 1.7 dyoung __func__, keyix); 449 1.7 dyoung ic->ic_stats.is_crypto_delkey++; 450 1.7 dyoung /* XXX recovery? */ 451 1.1 dyoung } 452 1.1 dyoung } 453 1.7 dyoung cipher_detach(key); 454 1.7 dyoung memset(key, 0, sizeof(*key)); 455 1.7 dyoung ieee80211_crypto_resetkey(ic, key, IEEE80211_KEYIX_NONE); 456 1.7 dyoung return 1; 457 1.7 dyoung } 458 1.7 dyoung 459 1.7 dyoung /* 460 1.7 dyoung * Remove the specified key. 461 1.7 dyoung */ 462 1.7 dyoung int 463 1.7 dyoung ieee80211_crypto_delkey(struct ieee80211com *ic, struct ieee80211_key *key) 464 1.7 dyoung { 465 1.7 dyoung int status; 466 1.1 dyoung 467 1.7 dyoung ieee80211_key_update_begin(ic); 468 1.7 dyoung status = _ieee80211_crypto_delkey(ic, key); 469 1.7 dyoung ieee80211_key_update_end(ic); 470 1.7 dyoung return status; 471 1.1 dyoung } 472 1.1 dyoung 473 1.1 dyoung /* 474 1.7 dyoung * Clear the global key table. 475 1.1 dyoung */ 476 1.7 dyoung void 477 1.7 dyoung ieee80211_crypto_delglobalkeys(struct ieee80211com *ic) 478 1.7 dyoung { 479 1.7 dyoung int i; 480 1.7 dyoung 481 1.7 dyoung ieee80211_key_update_begin(ic); 482 1.7 dyoung for (i = 0; i < IEEE80211_WEP_NKID; i++) 483 1.20 maxv (void)_ieee80211_crypto_delkey(ic, &ic->ic_nw_keys[i]); 484 1.7 dyoung ieee80211_key_update_end(ic); 485 1.7 dyoung } 486 1.7 dyoung 487 1.7 dyoung /* 488 1.7 dyoung * Set the contents of the specified key. 489 1.7 dyoung * 490 1.7 dyoung * Locking must be handled by the caller using: 491 1.7 dyoung * ieee80211_key_update_begin(ic); 492 1.7 dyoung * ieee80211_key_update_end(ic); 493 1.7 dyoung */ 494 1.7 dyoung int 495 1.7 dyoung ieee80211_crypto_setkey(struct ieee80211com *ic, struct ieee80211_key *key, 496 1.20 maxv const u_int8_t macaddr[IEEE80211_ADDR_LEN]) 497 1.7 dyoung { 498 1.7 dyoung const struct ieee80211_cipher *cip = key->wk_cipher; 499 1.7 dyoung 500 1.7 dyoung IASSERT(cip != NULL, ("No cipher!")); 501 1.7 dyoung 502 1.7 dyoung IEEE80211_DPRINTF(ic, IEEE80211_MSG_CRYPTO, 503 1.7 dyoung "%s: %s keyix %u flags 0x%x mac %s rsc %ju tsc %ju len %u\n", 504 1.7 dyoung __func__, cip->ic_name, key->wk_keyix, 505 1.7 dyoung key->wk_flags, ether_sprintf(macaddr), 506 1.7 dyoung key->wk_keyrsc, key->wk_keytsc, key->wk_keylen); 507 1.7 dyoung 508 1.7 dyoung /* 509 1.7 dyoung * Give cipher a chance to validate key contents. 510 1.7 dyoung * XXX should happen before modifying state. 511 1.7 dyoung */ 512 1.7 dyoung if (!cip->ic_setkey(key)) { 513 1.7 dyoung IEEE80211_DPRINTF(ic, IEEE80211_MSG_CRYPTO, 514 1.7 dyoung "%s: cipher %s rejected key index %u len %u flags 0x%x\n", 515 1.7 dyoung __func__, cip->ic_name, key->wk_keyix, 516 1.7 dyoung key->wk_keylen, key->wk_flags); 517 1.7 dyoung ic->ic_stats.is_crypto_setkey_cipher++; 518 1.7 dyoung return 0; 519 1.7 dyoung } 520 1.7 dyoung if (key->wk_keyix == IEEE80211_KEYIX_NONE) { 521 1.7 dyoung /* XXX nothing allocated, should not happen */ 522 1.7 dyoung IEEE80211_DPRINTF(ic, IEEE80211_MSG_CRYPTO, 523 1.7 dyoung "%s: no key index; should not happen!\n", __func__); 524 1.7 dyoung ic->ic_stats.is_crypto_setkey_nokey++; 525 1.7 dyoung return 0; 526 1.7 dyoung } 527 1.7 dyoung return dev_key_set(ic, key, macaddr); 528 1.7 dyoung } 529 1.1 dyoung 530 1.7 dyoung /* 531 1.7 dyoung * Add privacy headers appropriate for the specified key. 532 1.22 maxv * 533 1.22 maxv * XXX XXX XXX: Here we modify 'm', and potentially reallocate it. We 534 1.22 maxv * should pass back to the caller the updated pointer to avoid 535 1.22 maxv * use-after-frees. This can be done by changing the argument to be **m, 536 1.22 maxv * but many drivers will have to be changed accordingly. 537 1.7 dyoung */ 538 1.7 dyoung struct ieee80211_key * 539 1.20 maxv ieee80211_crypto_encap(struct ieee80211com *ic, struct ieee80211_node *ni, 540 1.20 maxv struct mbuf *m) 541 1.7 dyoung { 542 1.7 dyoung struct ieee80211_key *k; 543 1.7 dyoung struct ieee80211_frame *wh; 544 1.7 dyoung const struct ieee80211_cipher *cip; 545 1.20 maxv u_int8_t keyid, *hdr; 546 1.20 maxv int hdrlen; 547 1.1 dyoung 548 1.7 dyoung /* 549 1.7 dyoung * Multicast traffic always uses the multicast key. 550 1.7 dyoung * Otherwise if a unicast key is set we use that and 551 1.7 dyoung * it is always key index 0. When no unicast key is 552 1.7 dyoung * set we fall back to the default transmit key. 553 1.7 dyoung */ 554 1.7 dyoung wh = mtod(m, struct ieee80211_frame *); 555 1.7 dyoung if (IEEE80211_IS_MULTICAST(wh->i_addr1) || 556 1.7 dyoung ni->ni_ucastkey.wk_cipher == &ieee80211_cipher_none) { 557 1.7 dyoung if (ic->ic_def_txkey == IEEE80211_KEYIX_NONE) { 558 1.7 dyoung IEEE80211_DPRINTF(ic, IEEE80211_MSG_CRYPTO, 559 1.7 dyoung "[%s] no default transmit key (%s) deftxkey %u\n", 560 1.7 dyoung ether_sprintf(wh->i_addr1), __func__, 561 1.7 dyoung ic->ic_def_txkey); 562 1.7 dyoung ic->ic_stats.is_tx_nodefkey++; 563 1.10 skrll return NULL; 564 1.1 dyoung } 565 1.7 dyoung keyid = ic->ic_def_txkey; 566 1.7 dyoung k = &ic->ic_nw_keys[ic->ic_def_txkey]; 567 1.7 dyoung } else { 568 1.7 dyoung keyid = 0; 569 1.7 dyoung k = &ni->ni_ucastkey; 570 1.1 dyoung } 571 1.7 dyoung cip = k->wk_cipher; 572 1.20 maxv 573 1.20 maxv /* 574 1.20 maxv * The crypto header is added after the IEEE802.11 header. Prepend 575 1.20 maxv * the size of the crypto header, and move the IEEE802.11 header back 576 1.20 maxv * to the beginning of the mbuf. Ensure everything is contiguous. 577 1.20 maxv */ 578 1.20 maxv hdrlen = ieee80211_hdrspace(ic, mtod(m, void *)); 579 1.20 maxv M_PREPEND(m, cip->ic_header, M_NOWAIT); 580 1.20 maxv if (m && m->m_len < hdrlen + cip->ic_header) { 581 1.20 maxv m = m_pullup(m, hdrlen + cip->ic_header); 582 1.20 maxv } 583 1.20 maxv if (m == NULL) { 584 1.20 maxv return NULL; 585 1.20 maxv } 586 1.20 maxv hdr = mtod(m, u_int8_t *); 587 1.20 maxv memmove(hdr, hdr + cip->ic_header, hdrlen); 588 1.20 maxv 589 1.10 skrll return (cip->ic_encap(k, m, keyid<<6) ? k : NULL); 590 1.1 dyoung } 591 1.1 dyoung 592 1.19 maxv #define IEEE80211_WEP_HDRLEN (IEEE80211_WEP_IVLEN + IEEE80211_WEP_KIDLEN) 593 1.19 maxv #define IEEE80211_WEP_MINLEN \ 594 1.19 maxv (sizeof(struct ieee80211_frame) + \ 595 1.19 maxv IEEE80211_WEP_HDRLEN + IEEE80211_WEP_CRCLEN) 596 1.19 maxv 597 1.1 dyoung /* 598 1.7 dyoung * Validate and strip privacy headers (and trailer) for a 599 1.7 dyoung * received frame that has the WEP/Privacy bit set. 600 1.1 dyoung */ 601 1.7 dyoung struct ieee80211_key * 602 1.7 dyoung ieee80211_crypto_decap(struct ieee80211com *ic, 603 1.20 maxv struct ieee80211_node *ni, struct mbuf **mp, int hdrlen) 604 1.7 dyoung { 605 1.19 maxv const struct ieee80211_cipher *cip; 606 1.7 dyoung struct ieee80211_key *k; 607 1.7 dyoung struct ieee80211_frame *wh; 608 1.18 maxv struct mbuf *m = *mp; 609 1.7 dyoung u_int8_t keyid; 610 1.7 dyoung 611 1.21 maxv KASSERT((m->m_flags & M_PKTHDR) != 0); 612 1.21 maxv 613 1.21 maxv /* 614 1.21 maxv * This minimum size data frame could be bigger. It is re-checked 615 1.21 maxv * below. 616 1.21 maxv */ 617 1.7 dyoung if (m->m_pkthdr.len < IEEE80211_WEP_MINLEN) { 618 1.7 dyoung IEEE80211_DPRINTF(ic, IEEE80211_MSG_ANY, 619 1.7 dyoung "%s: WEP data frame too short, len %u\n", 620 1.7 dyoung __func__, m->m_pkthdr.len); 621 1.19 maxv ic->ic_stats.is_rx_tooshort++; 622 1.7 dyoung return NULL; 623 1.7 dyoung } 624 1.7 dyoung 625 1.7 dyoung /* 626 1.7 dyoung * Locate the key. If unicast and there is no unicast 627 1.7 dyoung * key then we fall back to the key id in the header. 628 1.7 dyoung * This assumes unicast keys are only configured when 629 1.7 dyoung * the key id in the header is meaningless (typically 0). 630 1.7 dyoung */ 631 1.7 dyoung wh = mtod(m, struct ieee80211_frame *); 632 1.11 dyoung m_copydata(m, hdrlen + IEEE80211_WEP_IVLEN, sizeof(keyid), &keyid); 633 1.7 dyoung if (IEEE80211_IS_MULTICAST(wh->i_addr1) || 634 1.19 maxv ni->ni_ucastkey.wk_cipher == &ieee80211_cipher_none) { 635 1.7 dyoung k = &ic->ic_nw_keys[keyid >> 6]; 636 1.19 maxv } else { 637 1.7 dyoung k = &ni->ni_ucastkey; 638 1.19 maxv } 639 1.1 dyoung 640 1.7 dyoung /* 641 1.7 dyoung * Insure crypto header is contiguous for all decap work. 642 1.7 dyoung */ 643 1.7 dyoung cip = k->wk_cipher; 644 1.19 maxv if (m->m_len < hdrlen + cip->ic_header) { 645 1.19 maxv m = m_pullup(m, hdrlen + cip->ic_header); 646 1.19 maxv *mp = m; 647 1.19 maxv } 648 1.19 maxv 649 1.19 maxv if (m == NULL) { 650 1.22 maxv ic->ic_stats.is_rx_tooshort++; 651 1.12 dyoung return NULL; 652 1.7 dyoung } 653 1.1 dyoung 654 1.21 maxv /* 655 1.21 maxv * Ensure there is a header+trailer included. 656 1.21 maxv */ 657 1.21 maxv if (m->m_pkthdr.len < hdrlen + cip->ic_header + cip->ic_trailer) { 658 1.21 maxv IEEE80211_DPRINTF(ic, IEEE80211_MSG_ANY, 659 1.21 maxv "%s: WEP data frame too short, len %u\n", 660 1.21 maxv __func__, m->m_pkthdr.len); 661 1.21 maxv ic->ic_stats.is_rx_tooshort++; 662 1.21 maxv return NULL; 663 1.21 maxv } 664 1.21 maxv 665 1.9 dyoung return (cip->ic_decap(k, m, hdrlen) ? k : NULL); 666 1.1 dyoung } 667