1 /* 2 * Copyright 2007 Sun Microsystems, Inc. All rights reserved. 3 * Use is subject to license terms. 4 */ 5 6 /* 7 * Copyright (c) 2001 Atsushi Onoe 8 * Copyright (c) 2002-2005 Sam Leffler, Errno Consulting 9 * All rights reserved. 10 * 11 * Redistribution and use in source and binary forms, with or without 12 * modification, are permitted provided that the following conditions 13 * are met: 14 * 1. Redistributions of source code must retain the above copyright 15 * notice, this list of conditions and the following disclaimer. 16 * 2. Redistributions in binary form must reproduce the above copyright 17 * notice, this list of conditions and the following disclaimer in the 18 * documentation and/or other materials provided with the distribution. 19 * 3. The name of the author may not be used to endorse or promote products 20 * derived from this software without specific prior written permission. 21 * 22 * Alternatively, this software may be distributed under the terms of the 23 * GNU General Public License ("GPL") version 2 as published by the Free 24 * Software Foundation. 25 * 26 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 27 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 28 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 29 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 30 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 31 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 32 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 33 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 34 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 35 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 36 */ 37 38 #pragma ident "%Z%%M% %I% %E% SMI" 39 40 /* 41 * IEEE 802.11 generic crypto support 42 */ 43 #include <sys/types.h> 44 #include <sys/note.h> 45 #include "net80211_impl.h" 46 47 extern const struct ieee80211_cipher wep; 48 extern const struct ieee80211_cipher tkip; 49 extern const struct ieee80211_cipher ccmp; 50 51 /* 52 * Table of registered cipher modules. 53 */ 54 static const char *cipher_modnames[] = { 55 "wlan_wep", /* IEEE80211_CIPHER_WEP */ 56 "wlan_tkip", /* IEEE80211_CIPHER_TKIP */ 57 "wlan_aes_ocb", /* IEEE80211_CIPHER_AES_OCB */ 58 "wlan_ccmp", /* IEEE80211_CIPHER_AES_CCM */ 59 "wlan_ckip", /* IEEE80211_CIPHER_CKIP */ 60 }; 61 62 /* 63 * Default "null" key management routines. 64 */ 65 /* ARGSUSED */ 66 static int 67 nulldev_key_alloc(ieee80211com_t *ic, const struct ieee80211_key *k, 68 ieee80211_keyix *keyix, ieee80211_keyix *rxkeyix) 69 { 70 *keyix = 0; /* use key index 0 for ucast key */ 71 *rxkeyix = IEEE80211_KEYIX_NONE; 72 return (1); 73 } 74 75 /* ARGSUSED */ 76 static int 77 nulldev_key_delete(ieee80211com_t *ic, const struct ieee80211_key *k) 78 { 79 return (1); 80 } 81 82 /* ARGSUSED */ 83 static int 84 nulldev_key_set(ieee80211com_t *ic, const struct ieee80211_key *k, 85 const uint8_t *mac) 86 { 87 return (1); 88 } 89 90 /* ARGSUSED */ 91 static void 92 nulldev_key_update(ieee80211com_t *ic) 93 { 94 /* noop */ 95 } 96 97 /* 98 * Reset key state to an unused state. The crypto 99 * key allocation mechanism insures other state (e.g. 100 * key data) is properly setup before a key is used. 101 */ 102 void 103 ieee80211_crypto_resetkey(ieee80211com_t *ic, 104 struct ieee80211_key *k, ieee80211_keyix ix) 105 { 106 k->wk_cipher = &ieee80211_cipher_none; 107 k->wk_private = k->wk_cipher->ic_attach(ic, k); 108 k->wk_keyix = ix; 109 k->wk_flags = IEEE80211_KEY_XMIT | IEEE80211_KEY_RECV; 110 } 111 112 /* 113 * Establish a relationship between the specified key and cipher 114 * and, if necessary, allocate a hardware index from the driver. 115 * Note that when a fixed key index is required it must be specified 116 * and we blindly assign it w/o consulting the driver. 117 * 118 * This must be the first call applied to a key; all the other key 119 * routines assume wk_cipher is setup. 120 * 121 * Locking must be handled by the caller using: 122 * ieee80211_key_update_begin(ic); 123 * ieee80211_key_update_end(ic); 124 */ 125 int 126 ieee80211_crypto_newkey(ieee80211com_t *ic, int cipher, int flags, 127 struct ieee80211_key *key) 128 { 129 const struct ieee80211_cipher *cip; 130 ieee80211_keyix keyix, rxkeyix; 131 void *keyctx; 132 uint16_t oflags; 133 134 /* 135 * Validate cipher and set reference to cipher routines. 136 */ 137 if (cipher >= IEEE80211_CIPHER_MAX) { 138 ieee80211_dbg(IEEE80211_MSG_CRYPTO, "ieee80211_crypto_newkey: " 139 "invalid cipher %u\n", cipher); 140 return (0); 141 } 142 cip = ic->ic_ciphers[cipher]; 143 /* already load all the ciphers, cip can't be NULL */ 144 if (cip == NULL) { 145 ieee80211_dbg(IEEE80211_MSG_CRYPTO, "ieee80211_crypto_newkey: " 146 "unable to load cipher %u, module %s\n", 147 cipher, cipher < IEEE80211_N(cipher_modnames) ? 148 cipher_modnames[cipher] : "<unknown>"); 149 return (0); 150 } 151 152 oflags = key->wk_flags; 153 flags &= IEEE80211_KEY_COMMON; 154 /* 155 * If the hardware does not support the cipher then 156 * fallback to a host-based implementation. 157 */ 158 if ((ic->ic_caps & (1<<cipher)) == 0) { 159 ieee80211_dbg(IEEE80211_MSG_CRYPTO, "ieee80211_crypto_newkey: " 160 "no h/w support for cipher %s, falling back to s/w\n", 161 cip->ic_name); 162 flags |= IEEE80211_KEY_SWCRYPT; 163 } 164 /* 165 * Hardware TKIP with software MIC is an important 166 * combination; we handle it by flagging each key, 167 * the cipher modules honor it. 168 */ 169 if (cipher == IEEE80211_CIPHER_TKIP && 170 (ic->ic_caps & IEEE80211_C_TKIPMIC) == 0) { 171 ieee80211_dbg(IEEE80211_MSG_CRYPTO, 172 "no h/w support for TKIP MIC, falling back to s/w\n"); 173 flags |= IEEE80211_KEY_SWMIC; 174 } 175 176 /* 177 * Bind cipher to key instance. Note we do this 178 * after checking the device capabilities so the 179 * cipher module can optimize space usage based on 180 * whether or not it needs to do the cipher work. 181 */ 182 if (key->wk_cipher != cip || key->wk_flags != flags) { 183 again: 184 /* 185 * Fillin the flags so cipher modules can see s/w 186 * crypto requirements and potentially allocate 187 * different state and/or attach different method 188 * pointers. 189 */ 190 key->wk_flags = (uint16_t)flags; 191 keyctx = cip->ic_attach(ic, key); 192 if (keyctx == NULL) { 193 ieee80211_dbg(IEEE80211_MSG_CRYPTO, "crypto_setkey: " 194 "unable to attach cipher %s\n", cip->ic_name); 195 key->wk_flags = oflags; /* restore old flags */ 196 return (0); 197 } 198 CIPHER_DETACH(key); /* Detach old cipher */ 199 key->wk_cipher = cip; 200 key->wk_private = keyctx; 201 } 202 /* 203 * Commit to requested usage so driver can see the flags. 204 */ 205 key->wk_flags = (uint16_t)flags; 206 207 /* 208 * Ask the driver for a key index if we don't have one. 209 * Note that entries in the global key table always have 210 * an index; this means it's safe to call this routine 211 * for these entries just to setup the reference to the 212 * cipher template. Note also that when using software 213 * crypto we also call the driver to give us a key index. 214 */ 215 if (key->wk_keyix == IEEE80211_KEYIX_NONE) { 216 if (!DEV_KEY_ALLOC(ic, key, &keyix, &rxkeyix)) { 217 /* 218 * Driver has no room; fallback to doing crypto 219 * in the host. We change the flags and start the 220 * procedure over. If we get back here then there's 221 * no hope and we bail. Note that this can leave 222 * the key in a inconsistent state if the caller 223 * continues to use it. 224 */ 225 if ((key->wk_flags & IEEE80211_KEY_SWCRYPT) == 0) { 226 ieee80211_dbg(IEEE80211_MSG_CRYPTO, 227 "crypto_setkey: " 228 "no h/w resources for cipher %s, " 229 "falling back to s/w\n", cip->ic_name); 230 oflags = key->wk_flags; 231 flags |= IEEE80211_KEY_SWCRYPT; 232 if (cipher == IEEE80211_CIPHER_TKIP) 233 flags |= IEEE80211_KEY_SWMIC; 234 goto again; 235 } 236 ieee80211_dbg(IEEE80211_MSG_CRYPTO, "crypto_setkey: " 237 "unable to setup cipher %s\n", cip->ic_name); 238 return (0); 239 } 240 key->wk_keyix = keyix; 241 key->wk_rxkeyix = rxkeyix; 242 } 243 return (1); 244 } 245 246 /* 247 * Remove the key (no locking, for internal use). 248 */ 249 static int 250 ieee80211_crypto_delkey_locked(ieee80211com_t *ic, struct ieee80211_key *key) 251 { 252 uint16_t keyix; 253 254 ASSERT(key->wk_cipher != NULL); 255 256 keyix = key->wk_keyix; 257 if (keyix != IEEE80211_KEYIX_NONE) { 258 /* 259 * Remove hardware entry. 260 */ 261 if (!DEV_KEY_DELETE(ic, key)) { 262 ieee80211_dbg(IEEE80211_MSG_CRYPTO, 263 "ieee80211_crypto_delkey_locked: ", 264 "driverdeletes key %u failed\n", keyix); 265 } 266 } 267 CIPHER_DETACH(key); 268 bzero(key, sizeof (struct ieee80211_key)); 269 /* NB: cannot depend on key index to decide this */ 270 ieee80211_crypto_resetkey(ic, key, IEEE80211_KEYIX_NONE); 271 return (1); 272 } 273 274 /* 275 * Remove the specified key. 276 */ 277 int 278 ieee80211_crypto_delkey(ieee80211com_t *ic, struct ieee80211_key *key) 279 { 280 int status; 281 282 KEY_UPDATE_BEGIN(ic); 283 status = ieee80211_crypto_delkey_locked(ic, key); 284 KEY_UPDATE_END(ic); 285 return (status); 286 } 287 288 /* 289 * Clear the global key table. 290 */ 291 static void 292 ieee80211_crypto_delglobalkeys(ieee80211com_t *ic) 293 { 294 int i; 295 296 KEY_UPDATE_BEGIN(ic); 297 for (i = 0; i < IEEE80211_WEP_NKID; i++) 298 (void) ieee80211_crypto_delkey_locked(ic, &ic->ic_nw_keys[i]); 299 KEY_UPDATE_END(ic); 300 } 301 302 /* 303 * Set the contents of the specified key. 304 * 305 * Locking must be handled by the caller using: 306 * ieee80211_key_update_begin(ic); 307 * ieee80211_key_update_end(ic); 308 */ 309 int 310 ieee80211_crypto_setkey(ieee80211com_t *ic, struct ieee80211_key *key, 311 const uint8_t *macaddr) 312 { 313 const struct ieee80211_cipher *cip = key->wk_cipher; 314 315 ASSERT(cip != NULL); 316 317 ieee80211_dbg(IEEE80211_MSG_CRYPTO, "ieee80211_crypto_setkey: " 318 "%s keyix %u flags 0x%x mac %s len %u\n", 319 cip->ic_name, key->wk_keyix, key->wk_flags, 320 ieee80211_macaddr_sprintf(macaddr), key->wk_keylen); 321 322 /* 323 * Give cipher a chance to validate key contents. 324 * should happen before modifying state. 325 */ 326 if (cip->ic_setkey(key) == 0) { 327 ieee80211_dbg(IEEE80211_MSG_CRYPTO, "ieee80211_crypto_setkey: " 328 "cipher %s rejected key index %u len %u flags 0x%x\n", 329 cip->ic_name, key->wk_keyix, key->wk_keylen, 330 key->wk_flags); 331 return (0); 332 } 333 if (key->wk_keyix == IEEE80211_KEYIX_NONE) { 334 ieee80211_dbg(IEEE80211_MSG_CRYPTO, "ieee80211_crypto_setkey: " 335 "no key index; should not happen!\n"); 336 return (0); 337 } 338 return (DEV_KEY_SET(ic, key, macaddr)); 339 } 340 341 /* 342 * Return the transmit key to use in sending a frame. 343 */ 344 struct ieee80211_key * 345 ieee80211_crypto_getkey(ieee80211com_t *ic) 346 { 347 if (ic->ic_def_txkey == IEEE80211_KEYIX_NONE || 348 KEY_UNDEFINED(ic->ic_nw_keys[ic->ic_def_txkey])) 349 return (NULL); 350 return (&ic->ic_nw_keys[ic->ic_def_txkey]); 351 } 352 353 uint8_t 354 ieee80211_crypto_getciphertype(ieee80211com_t *ic) 355 { 356 struct ieee80211_key *key; 357 uint32_t cipher; 358 static const uint8_t ciphermap[] = { 359 WIFI_SEC_WEP, /* IEEE80211_CIPHER_WEP */ 360 WIFI_SEC_WPA, /* IEEE80211_CIPHER_TKIP */ 361 (uint8_t)-1, /* IEEE80211_CIPHER_AES_OCB */ 362 WIFI_SEC_WPA, /* IEEE80211_CIPHER_AES_CCM */ 363 (uint8_t)-1, /* IEEE80211_CIPHER_CKIP */ 364 WIFI_SEC_NONE, /* IEEE80211_CIPHER_NONE */ 365 }; 366 367 if ((ic->ic_flags & IEEE80211_F_PRIVACY) == 0) 368 return (WIFI_SEC_NONE); 369 370 key = ieee80211_crypto_getkey(ic); 371 if (key == NULL) 372 return (WIFI_SEC_NONE); 373 374 cipher = key->wk_cipher->ic_cipher; 375 ASSERT(cipher < IEEE80211_N(ciphermap)); 376 return (ciphermap[cipher]); 377 } 378 379 /* 380 * Add privacy headers appropriate for the specified key. 381 */ 382 struct ieee80211_key * 383 ieee80211_crypto_encap(ieee80211com_t *ic, mblk_t *mp) 384 { 385 struct ieee80211_key *k; 386 const struct ieee80211_cipher *cip; 387 uint8_t keyix; 388 389 if (ic->ic_def_txkey == IEEE80211_KEYIX_NONE) { 390 ieee80211_dbg(IEEE80211_MSG_CRYPTO, 391 "ieee80211_crypto_encap: %s", 392 " No default xmit key for frame\n"); 393 return (NULL); 394 } 395 keyix = ic->ic_def_txkey; 396 k = &ic->ic_nw_keys[ic->ic_def_txkey]; 397 cip = k->wk_cipher; 398 return (cip->ic_encap(k, mp, keyix<<6) ? k : NULL); 399 } 400 401 /* 402 * Validate and strip privacy headers (and trailer) for a 403 * received frame that has the WEP/Privacy bit set. 404 */ 405 struct ieee80211_key * 406 ieee80211_crypto_decap(ieee80211com_t *ic, mblk_t *mp, int hdrlen) 407 { 408 struct ieee80211_key *k; 409 const struct ieee80211_cipher *cip; 410 uint8_t *ivp; 411 uint8_t keyid; 412 413 /* NB: this minimum size data frame could be bigger */ 414 if ((mp->b_wptr - mp->b_rptr) < IEEE80211_WEP_MINLEN) { 415 ieee80211_dbg(IEEE80211_MSG_CRYPTO, "ieee80211_crypto_decap:" 416 " WEP data frame too short, len %u\n", 417 mp->b_wptr - mp->b_rptr); 418 return (NULL); 419 } 420 /* 421 * Locate the key. If unicast and there is no unicast 422 * key then we fall back to the key id in the header. 423 * This assumes unicast keys are only configured when 424 * the key id in the header is meaningless (typically 0). 425 */ 426 ivp = mp->b_rptr + hdrlen; 427 keyid = ivp[IEEE80211_WEP_IVLEN]; 428 k = &ic->ic_nw_keys[keyid >> 6]; 429 430 /* check to avoid panic when wep is on but key is not set */ 431 if (k->wk_cipher == &ieee80211_cipher_none || 432 k->wk_cipher == NULL) 433 return (NULL); 434 435 cip = k->wk_cipher; 436 return ((cip->ic_decap)(k, mp, hdrlen) ? k : NULL); 437 } 438 439 440 /* 441 * Setup crypto support. 442 */ 443 void 444 ieee80211_crypto_attach(ieee80211com_t *ic) 445 { 446 struct ieee80211_crypto_state *cs = &ic->ic_crypto; 447 int i; 448 449 /* NB: we assume everything is pre-zero'd */ 450 cs->cs_def_txkey = IEEE80211_KEYIX_NONE; 451 for (i = 0; i < IEEE80211_WEP_NKID; i++) { 452 ieee80211_crypto_resetkey(ic, &cs->cs_nw_keys[i], 453 IEEE80211_KEYIX_NONE); 454 } 455 456 /* 457 * Initialize the driver key support routines to noop entries. 458 * This is useful especially for the cipher test modules. 459 */ 460 cs->cs_key_alloc = nulldev_key_alloc; 461 cs->cs_key_set = nulldev_key_set; 462 cs->cs_key_delete = nulldev_key_delete; 463 cs->cs_key_update_begin = nulldev_key_update; 464 cs->cs_key_update_end = nulldev_key_update; 465 466 ieee80211_crypto_register(ic, &wep); 467 ieee80211_crypto_register(ic, &tkip); 468 ieee80211_crypto_register(ic, &ccmp); 469 } 470 471 /* 472 * Teardown crypto support. 473 */ 474 void 475 ieee80211_crypto_detach(ieee80211com_t *ic) 476 { 477 ieee80211_crypto_delglobalkeys(ic); 478 479 ieee80211_crypto_unregister(ic, &wep); 480 ieee80211_crypto_unregister(ic, &tkip); 481 ieee80211_crypto_unregister(ic, &ccmp); 482 } 483 484 /* 485 * Register a crypto cipher module. 486 */ 487 void 488 ieee80211_crypto_register(ieee80211com_t *ic, 489 const struct ieee80211_cipher *cip) 490 { 491 if (cip->ic_cipher >= IEEE80211_CIPHER_MAX) { 492 ieee80211_err("ieee80211_crypto_register: " 493 "cipher %s has an invalid cipher index %u\n", 494 cip->ic_name, cip->ic_cipher); 495 return; 496 } 497 if (ic->ic_ciphers[cip->ic_cipher] != NULL && 498 ic->ic_ciphers[cip->ic_cipher] != cip) { 499 ieee80211_err("ieee80211_crypto_register: " 500 "cipher %s registered with a different template\n", 501 cip->ic_name); 502 return; 503 } 504 ic->ic_ciphers[cip->ic_cipher] = cip; 505 } 506 507 /* 508 * Unregister a crypto cipher module. 509 */ 510 void 511 ieee80211_crypto_unregister(ieee80211com_t *ic, 512 const struct ieee80211_cipher *cip) 513 { 514 if (cip->ic_cipher >= IEEE80211_CIPHER_MAX) { 515 ieee80211_err("ieee80211_crypto_unregister: " 516 "cipher %s has an invalid cipher index %u\n", 517 cip->ic_name, cip->ic_cipher); 518 return; 519 } 520 if (ic->ic_ciphers[cip->ic_cipher] != NULL && 521 ic->ic_ciphers[cip->ic_cipher] != cip) { 522 ieee80211_err("ieee80211_crypto_unregister: " 523 "cipher %s registered with a different template\n", 524 cip->ic_name); 525 return; 526 } 527 /* NB: don't complain about not being registered */ 528 ic->ic_ciphers[cip->ic_cipher] = NULL; 529 } 530