ieee80211_crypto.c (139530) | ieee80211_crypto.c (144960) |
---|---|
1/*- 2 * Copyright (c) 2001 Atsushi Onoe 3 * Copyright (c) 2002-2005 Sam Leffler, Errno Consulting 4 * All rights reserved. 5 * 6 * Redistribution and use in source and binary forms, with or without 7 * modification, are permitted provided that the following conditions 8 * are met: --- 17 unchanged lines hidden (view full) --- 26 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 27 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 28 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 29 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 30 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 31 */ 32 33#include <sys/cdefs.h> | 1/*- 2 * Copyright (c) 2001 Atsushi Onoe 3 * Copyright (c) 2002-2005 Sam Leffler, Errno Consulting 4 * All rights reserved. 5 * 6 * Redistribution and use in source and binary forms, with or without 7 * modification, are permitted provided that the following conditions 8 * are met: --- 17 unchanged lines hidden (view full) --- 26 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 27 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 28 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 29 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 30 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 31 */ 32 33#include <sys/cdefs.h> |
34__FBSDID("$FreeBSD: head/sys/net80211/ieee80211_crypto.c 139530 2004-12-31 22:42:38Z sam $"); | 34__FBSDID("$FreeBSD: head/sys/net80211/ieee80211_crypto.c 144960 2005-04-12 17:55:13Z sam $"); |
35 36/* 37 * IEEE 802.11 generic crypto support. 38 */ 39#include <sys/param.h> 40#include <sys/mbuf.h> 41 42#include <sys/socket.h> --- 80 unchanged lines hidden (view full) --- 123{ 124 struct ieee80211_crypto_state *cs = &ic->ic_crypto; 125 int i; 126 127 /* NB: we assume everything is pre-zero'd */ 128 cs->cs_def_txkey = IEEE80211_KEYIX_NONE; 129 ciphers[IEEE80211_CIPHER_NONE] = &ieee80211_cipher_none; 130 for (i = 0; i < IEEE80211_WEP_NKID; i++) | 35 36/* 37 * IEEE 802.11 generic crypto support. 38 */ 39#include <sys/param.h> 40#include <sys/mbuf.h> 41 42#include <sys/socket.h> --- 80 unchanged lines hidden (view full) --- 123{ 124 struct ieee80211_crypto_state *cs = &ic->ic_crypto; 125 int i; 126 127 /* NB: we assume everything is pre-zero'd */ 128 cs->cs_def_txkey = IEEE80211_KEYIX_NONE; 129 ciphers[IEEE80211_CIPHER_NONE] = &ieee80211_cipher_none; 130 for (i = 0; i < IEEE80211_WEP_NKID; i++) |
131 ieee80211_crypto_resetkey(ic, &cs->cs_nw_keys[i], i); | 131 ieee80211_crypto_resetkey(ic, &cs->cs_nw_keys[i], 132 IEEE80211_KEYIX_NONE); |
132 /* 133 * Initialize the driver key support routines to noop entries. 134 * This is useful especially for the cipher test modules. 135 */ 136 cs->cs_key_alloc = null_key_alloc; 137 cs->cs_key_set = null_key_set; 138 cs->cs_key_delete = null_key_delete; 139 cs->cs_key_update_begin = null_key_update; --- 61 unchanged lines hidden (view full) --- 201 "wlan_tkip", /* IEEE80211_CIPHER_TKIP */ 202 "wlan_aes_ocb", /* IEEE80211_CIPHER_AES_OCB */ 203 "wlan_ccmp", /* IEEE80211_CIPHER_AES_CCM */ 204 "wlan_ckip", /* IEEE80211_CIPHER_CKIP */ 205}; 206 207/* 208 * Establish a relationship between the specified key and cipher | 133 /* 134 * Initialize the driver key support routines to noop entries. 135 * This is useful especially for the cipher test modules. 136 */ 137 cs->cs_key_alloc = null_key_alloc; 138 cs->cs_key_set = null_key_set; 139 cs->cs_key_delete = null_key_delete; 140 cs->cs_key_update_begin = null_key_update; --- 61 unchanged lines hidden (view full) --- 202 "wlan_tkip", /* IEEE80211_CIPHER_TKIP */ 203 "wlan_aes_ocb", /* IEEE80211_CIPHER_AES_OCB */ 204 "wlan_ccmp", /* IEEE80211_CIPHER_AES_CCM */ 205 "wlan_ckip", /* IEEE80211_CIPHER_CKIP */ 206}; 207 208/* 209 * Establish a relationship between the specified key and cipher |
209 * and, if not a global key, allocate a hardware index from the 210 * driver. Note that we may be called for global keys but they 211 * should have a key index already setup so the only work done 212 * is to setup the cipher reference. | 210 * and, if necessary, allocate a hardware index from the driver. 211 * Note that when a fixed key index is required it must be specified 212 * and we blindly assign it w/o consulting the driver (XXX). |
213 * 214 * This must be the first call applied to a key; all the other key 215 * routines assume wk_cipher is setup. 216 * 217 * Locking must be handled by the caller using: 218 * ieee80211_key_update_begin(ic); 219 * ieee80211_key_update_end(ic); 220 */ 221int 222ieee80211_crypto_newkey(struct ieee80211com *ic, | 213 * 214 * This must be the first call applied to a key; all the other key 215 * routines assume wk_cipher is setup. 216 * 217 * Locking must be handled by the caller using: 218 * ieee80211_key_update_begin(ic); 219 * ieee80211_key_update_end(ic); 220 */ 221int 222ieee80211_crypto_newkey(struct ieee80211com *ic, |
223 int cipher, struct ieee80211_key *key) | 223 int cipher, int flags, struct ieee80211_key *key) |
224{ 225#define N(a) (sizeof(a) / sizeof(a[0])) 226 const struct ieee80211_cipher *cip; 227 void *keyctx; 228 int oflags; 229 230 /* 231 * Validate cipher and set reference to cipher routines. --- 31 unchanged lines hidden (view full) --- 263 cipher < N(cipher_modnames) ? 264 cipher_modnames[cipher] : "<unknown>"); 265 ic->ic_stats.is_crypto_nocipher++; 266 return 0; 267 } 268 } 269 270 oflags = key->wk_flags; | 224{ 225#define N(a) (sizeof(a) / sizeof(a[0])) 226 const struct ieee80211_cipher *cip; 227 void *keyctx; 228 int oflags; 229 230 /* 231 * Validate cipher and set reference to cipher routines. --- 31 unchanged lines hidden (view full) --- 263 cipher < N(cipher_modnames) ? 264 cipher_modnames[cipher] : "<unknown>"); 265 ic->ic_stats.is_crypto_nocipher++; 266 return 0; 267 } 268 } 269 270 oflags = key->wk_flags; |
271 flags &= IEEE80211_KEY_COMMON; |
|
271 /* 272 * If the hardware does not support the cipher then 273 * fallback to a host-based implementation. 274 */ | 272 /* 273 * If the hardware does not support the cipher then 274 * fallback to a host-based implementation. 275 */ |
275 key->wk_flags &= ~(IEEE80211_KEY_SWCRYPT|IEEE80211_KEY_SWMIC); | |
276 if ((ic->ic_caps & (1<<cipher)) == 0) { 277 IEEE80211_DPRINTF(ic, IEEE80211_MSG_CRYPTO, 278 "%s: no h/w support for cipher %s, falling back to s/w\n", 279 __func__, cip->ic_name); | 276 if ((ic->ic_caps & (1<<cipher)) == 0) { 277 IEEE80211_DPRINTF(ic, IEEE80211_MSG_CRYPTO, 278 "%s: no h/w support for cipher %s, falling back to s/w\n", 279 __func__, cip->ic_name); |
280 key->wk_flags |= IEEE80211_KEY_SWCRYPT; | 280 flags |= IEEE80211_KEY_SWCRYPT; |
281 } 282 /* 283 * Hardware TKIP with software MIC is an important 284 * combination; we handle it by flagging each key, 285 * the cipher modules honor it. 286 */ 287 if (cipher == IEEE80211_CIPHER_TKIP && 288 (ic->ic_caps & IEEE80211_C_TKIPMIC) == 0) { 289 IEEE80211_DPRINTF(ic, IEEE80211_MSG_CRYPTO, 290 "%s: no h/w support for TKIP MIC, falling back to s/w\n", 291 __func__); | 281 } 282 /* 283 * Hardware TKIP with software MIC is an important 284 * combination; we handle it by flagging each key, 285 * the cipher modules honor it. 286 */ 287 if (cipher == IEEE80211_CIPHER_TKIP && 288 (ic->ic_caps & IEEE80211_C_TKIPMIC) == 0) { 289 IEEE80211_DPRINTF(ic, IEEE80211_MSG_CRYPTO, 290 "%s: no h/w support for TKIP MIC, falling back to s/w\n", 291 __func__); |
292 key->wk_flags |= IEEE80211_KEY_SWMIC; | 292 flags |= IEEE80211_KEY_SWMIC; |
293 } 294 295 /* 296 * Bind cipher to key instance. Note we do this 297 * after checking the device capabilities so the 298 * cipher module can optimize space usage based on 299 * whether or not it needs to do the cipher work. 300 */ | 293 } 294 295 /* 296 * Bind cipher to key instance. Note we do this 297 * after checking the device capabilities so the 298 * cipher module can optimize space usage based on 299 * whether or not it needs to do the cipher work. 300 */ |
301 if (key->wk_cipher != cip || key->wk_flags != oflags) { | 301 if (key->wk_cipher != cip || key->wk_flags != flags) { |
302again: | 302again: |
303 /* 304 * Fillin the flags so cipher modules can see s/w 305 * crypto requirements and potentially allocate 306 * different state and/or attach different method 307 * pointers. 308 * 309 * XXX this is not right when s/w crypto fallback 310 * fails and we try to restore previous state. 311 */ 312 key->wk_flags = flags; |
|
303 keyctx = cip->ic_attach(ic, key); 304 if (keyctx == NULL) { 305 IEEE80211_DPRINTF(ic, IEEE80211_MSG_CRYPTO, 306 "%s: unable to attach cipher %s\n", 307 __func__, cip->ic_name); 308 key->wk_flags = oflags; /* restore old flags */ 309 ic->ic_stats.is_crypto_attachfail++; 310 return 0; 311 } 312 cipher_detach(key); 313 key->wk_cipher = cip; /* XXX refcnt? */ 314 key->wk_private = keyctx; 315 } | 313 keyctx = cip->ic_attach(ic, key); 314 if (keyctx == NULL) { 315 IEEE80211_DPRINTF(ic, IEEE80211_MSG_CRYPTO, 316 "%s: unable to attach cipher %s\n", 317 __func__, cip->ic_name); 318 key->wk_flags = oflags; /* restore old flags */ 319 ic->ic_stats.is_crypto_attachfail++; 320 return 0; 321 } 322 cipher_detach(key); 323 key->wk_cipher = cip; /* XXX refcnt? */ 324 key->wk_private = keyctx; 325 } |
326 /* 327 * Commit to requested usage so driver can see the flags. 328 */ 329 key->wk_flags = flags; |
|
316 317 /* 318 * Ask the driver for a key index if we don't have one. 319 * Note that entries in the global key table always have 320 * an index; this means it's safe to call this routine 321 * for these entries just to setup the reference to the 322 * cipher template. Note also that when using software 323 * crypto we also call the driver to give us a key index. --- 11 unchanged lines hidden (view full) --- 335 */ 336 if ((key->wk_flags & IEEE80211_KEY_SWCRYPT) == 0) { 337 ic->ic_stats.is_crypto_swfallback++; 338 IEEE80211_DPRINTF(ic, IEEE80211_MSG_CRYPTO, 339 "%s: no h/w resources for cipher %s, " 340 "falling back to s/w\n", __func__, 341 cip->ic_name); 342 oflags = key->wk_flags; | 330 331 /* 332 * Ask the driver for a key index if we don't have one. 333 * Note that entries in the global key table always have 334 * an index; this means it's safe to call this routine 335 * for these entries just to setup the reference to the 336 * cipher template. Note also that when using software 337 * crypto we also call the driver to give us a key index. --- 11 unchanged lines hidden (view full) --- 349 */ 350 if ((key->wk_flags & IEEE80211_KEY_SWCRYPT) == 0) { 351 ic->ic_stats.is_crypto_swfallback++; 352 IEEE80211_DPRINTF(ic, IEEE80211_MSG_CRYPTO, 353 "%s: no h/w resources for cipher %s, " 354 "falling back to s/w\n", __func__, 355 cip->ic_name); 356 oflags = key->wk_flags; |
343 key->wk_flags |= IEEE80211_KEY_SWCRYPT; | 357 flags |= IEEE80211_KEY_SWCRYPT; |
344 if (cipher == IEEE80211_CIPHER_TKIP) | 358 if (cipher == IEEE80211_CIPHER_TKIP) |
345 key->wk_flags |= IEEE80211_KEY_SWMIC; | 359 flags |= IEEE80211_KEY_SWMIC; |
346 goto again; 347 } 348 ic->ic_stats.is_crypto_keyfail++; 349 IEEE80211_DPRINTF(ic, IEEE80211_MSG_CRYPTO, 350 "%s: unable to setup cipher %s\n", 351 __func__, cip->ic_name); 352 return 0; 353 } --- 29 unchanged lines hidden (view full) --- 383 "%s: driver did not delete key index %u\n", 384 __func__, keyix); 385 ic->ic_stats.is_crypto_delkey++; 386 /* XXX recovery? */ 387 } 388 } 389 cipher_detach(key); 390 memset(key, 0, sizeof(*key)); | 360 goto again; 361 } 362 ic->ic_stats.is_crypto_keyfail++; 363 IEEE80211_DPRINTF(ic, IEEE80211_MSG_CRYPTO, 364 "%s: unable to setup cipher %s\n", 365 __func__, cip->ic_name); 366 return 0; 367 } --- 29 unchanged lines hidden (view full) --- 397 "%s: driver did not delete key index %u\n", 398 __func__, keyix); 399 ic->ic_stats.is_crypto_delkey++; 400 /* XXX recovery? */ 401 } 402 } 403 cipher_detach(key); 404 memset(key, 0, sizeof(*key)); |
391 key->wk_cipher = &ieee80211_cipher_none; 392 key->wk_private = cipher_attach(ic, key); 393 /* NB: cannot depend on key index to decide this */ 394 if (&ic->ic_nw_keys[0] <= key && 395 key < &ic->ic_nw_keys[IEEE80211_WEP_NKID]) 396 key->wk_keyix = keyix; /* preserve shared key state */ 397 else 398 key->wk_keyix = IEEE80211_KEYIX_NONE; | 405 ieee80211_crypto_resetkey(ic, key, IEEE80211_KEYIX_NONE); |
399 return 1; 400} 401 402/* 403 * Remove the specified key. 404 */ 405int 406ieee80211_crypto_delkey(struct ieee80211com *ic, struct ieee80211_key *key) --- 68 unchanged lines hidden (view full) --- 475 */ 476struct ieee80211_key * 477ieee80211_crypto_encap(struct ieee80211com *ic, 478 struct ieee80211_node *ni, struct mbuf *m) 479{ 480 struct ieee80211_key *k; 481 struct ieee80211_frame *wh; 482 const struct ieee80211_cipher *cip; | 406 return 1; 407} 408 409/* 410 * Remove the specified key. 411 */ 412int 413ieee80211_crypto_delkey(struct ieee80211com *ic, struct ieee80211_key *key) --- 68 unchanged lines hidden (view full) --- 482 */ 483struct ieee80211_key * 484ieee80211_crypto_encap(struct ieee80211com *ic, 485 struct ieee80211_node *ni, struct mbuf *m) 486{ 487 struct ieee80211_key *k; 488 struct ieee80211_frame *wh; 489 const struct ieee80211_cipher *cip; |
483 u_int8_t keyix; | 490 u_int8_t keyid; |
484 485 /* 486 * Multicast traffic always uses the multicast key. 487 * Otherwise if a unicast key is set we use that and 488 * it is always key index 0. When no unicast key is 489 * set we fall back to the default transmit key. 490 */ 491 wh = mtod(m, struct ieee80211_frame *); 492 if (IEEE80211_IS_MULTICAST(wh->i_addr1) || 493 ni->ni_ucastkey.wk_cipher == &ieee80211_cipher_none) { 494 if (ic->ic_def_txkey == IEEE80211_KEYIX_NONE) { 495 IEEE80211_DPRINTF(ic, IEEE80211_MSG_CRYPTO, 496 "[%s] no default transmit key (%s) deftxkey %u\n", 497 ether_sprintf(wh->i_addr1), __func__, 498 ic->ic_def_txkey); 499 ic->ic_stats.is_tx_nodefkey++; 500 return NULL; 501 } | 491 492 /* 493 * Multicast traffic always uses the multicast key. 494 * Otherwise if a unicast key is set we use that and 495 * it is always key index 0. When no unicast key is 496 * set we fall back to the default transmit key. 497 */ 498 wh = mtod(m, struct ieee80211_frame *); 499 if (IEEE80211_IS_MULTICAST(wh->i_addr1) || 500 ni->ni_ucastkey.wk_cipher == &ieee80211_cipher_none) { 501 if (ic->ic_def_txkey == IEEE80211_KEYIX_NONE) { 502 IEEE80211_DPRINTF(ic, IEEE80211_MSG_CRYPTO, 503 "[%s] no default transmit key (%s) deftxkey %u\n", 504 ether_sprintf(wh->i_addr1), __func__, 505 ic->ic_def_txkey); 506 ic->ic_stats.is_tx_nodefkey++; 507 return NULL; 508 } |
502 keyix = ic->ic_def_txkey; | 509 keyid = ic->ic_def_txkey; |
503 k = &ic->ic_nw_keys[ic->ic_def_txkey]; 504 } else { | 510 k = &ic->ic_nw_keys[ic->ic_def_txkey]; 511 } else { |
505 keyix = 0; | 512 keyid = 0; |
506 k = &ni->ni_ucastkey; 507 } 508 cip = k->wk_cipher; | 513 k = &ni->ni_ucastkey; 514 } 515 cip = k->wk_cipher; |
509 return (cip->ic_encap(k, m, keyix<<6) ? k : NULL); | 516 return (cip->ic_encap(k, m, keyid<<6) ? k : NULL); |
510} 511 512/* 513 * Validate and strip privacy headers (and trailer) for a 514 * received frame that has the WEP/Privacy bit set. 515 */ 516struct ieee80211_key * 517ieee80211_crypto_decap(struct ieee80211com *ic, --- 55 unchanged lines hidden --- | 517} 518 519/* 520 * Validate and strip privacy headers (and trailer) for a 521 * received frame that has the WEP/Privacy bit set. 522 */ 523struct ieee80211_key * 524ieee80211_crypto_decap(struct ieee80211com *ic, --- 55 unchanged lines hidden --- |