#include <gpxe/net80211.h>
#include <errno.h>
Go to the source code of this file.
Functions | |
| FILE_LICENCE (GPL2_OR_LATER) | |
| int | _sec80211_detect (struct io_buffer *iob, enum net80211_security_proto *secprot, enum net80211_crypto_alg *crypt) |
| Detect the cryptosystem and handshaking protocol used by an 802.11 network. | |
| static int | sec80211_detect (struct io_buffer *iob, enum net80211_security_proto *secprot, enum net80211_crypto_alg *crypt) |
| Inline safety wrapper for _sec80211_detect(). | |
| int | sec80211_detect_ie (int is_rsn, u8 *start, u8 *end, enum net80211_security_proto *secprot, enum net80211_crypto_alg *crypt) |
| Detect crypto and AKM types from RSN information element. | |
| u8 * | sec80211_find_rsn (union ieee80211_ie *ie, void *ie_end, int *is_rsn, u8 **end) |
| Find the RSN or WPA information element in the provided beacon frame. | |
| int | sec80211_install (struct net80211_crypto **which, enum net80211_crypto_alg crypt, const void *key, int len, const void *rsc) |
| Install 802.11 cryptosystem. | |
| u32 | sec80211_rsn_get_crypto_desc (enum net80211_crypto_alg crypt, int rsnie) |
| Determine RSN descriptor for specified net80211 cryptosystem number. | |
| u32 | sec80211_rsn_get_akm_desc (enum net80211_security_proto secprot, int rsnie) |
| Determine RSN descriptor for specified net80211 handshaker number. | |
| enum net80211_crypto_alg | sec80211_rsn_get_net80211_crypt (u32 desc) |
| Determine net80211 cryptosystem number from RSN descriptor. | |
Any function in this file which may be referenced by code which is not exclusive to encryption-enabled builds (e.g. sec80211_detect(), which is called by net80211_probe_step() to fill the net80211_wlan structure's security fields) must be declared as a weak symbol, using an inline interface similar to that used for sec80211_detect() below. This prevents secure network support from bloating general builds by any more than a few tiny hooks to call crypto functions when crypto structures are non-NULL.
Definition in file sec80211.h.
| FILE_LICENCE | ( | GPL2_OR_LATER | ) |
| int _sec80211_detect | ( | struct io_buffer * | iob, | |
| enum net80211_security_proto * | secprot, | |||
| enum net80211_crypto_alg * | crypt | |||
| ) |
Detect the cryptosystem and handshaking protocol used by an 802.11 network.
| iob | I/O buffer containing beacon frame |
| secprot | Security handshaking protocol used by network | |
| crypt | Cryptosystem used by network | |
| rc | Return status code |
NULL before calling it. If it does not exist, any network with the PRIVACY bit set in beacon->capab should be considered unknown.
Definition at line 391 of file sec80211.c.
References ieee80211_frame::data, io_buffer::data, DBG, DBG_HD, ieee80211_beacon, IEEE80211_CAPAB_PRIVACY, NET80211_CRYPT_NONE, NET80211_CRYPT_UNKNOWN, NET80211_CRYPT_WEP, NET80211_SECPROT_NONE, NET80211_SECPROT_UNKNOWN, sec80211_detect_ie(), sec80211_find_rsn(), io_buffer::tail, and u8.
Referenced by sec80211_detect().
00394 { 00395 struct ieee80211_frame *hdr = iob->data; 00396 struct ieee80211_beacon *beacon = 00397 ( struct ieee80211_beacon * ) hdr->data; 00398 u8 *rsn, *rsn_end; 00399 int is_rsn, rc; 00400 00401 *crypt = NET80211_CRYPT_UNKNOWN; 00402 *secprot = NET80211_SECPROT_UNKNOWN; 00403 00404 /* Find RSN or WPA IE */ 00405 if ( ! ( rsn = sec80211_find_rsn ( beacon->info_element, iob->tail, 00406 &is_rsn, &rsn_end ) ) ) { 00407 /* No security IE at all; either WEP or no security. */ 00408 *secprot = NET80211_SECPROT_NONE; 00409 00410 if ( beacon->capability & IEEE80211_CAPAB_PRIVACY ) 00411 *crypt = NET80211_CRYPT_WEP; 00412 else 00413 *crypt = NET80211_CRYPT_NONE; 00414 00415 return 0; 00416 } 00417 00418 /* Determine type of security */ 00419 if ( ( rc = sec80211_detect_ie ( is_rsn, rsn, rsn_end, secprot, 00420 crypt ) ) == 0 ) 00421 return 0; 00422 00423 /* If we get here, the RSN IE was invalid */ 00424 00425 *crypt = NET80211_CRYPT_UNKNOWN; 00426 *secprot = NET80211_SECPROT_UNKNOWN; 00427 DBG ( "Failed to handle RSN IE:\n" ); 00428 DBG_HD ( rsn, rsn_end - rsn ); 00429 return rc; 00430 }
| static int sec80211_detect | ( | struct io_buffer * | iob, | |
| enum net80211_security_proto * | secprot, | |||
| enum net80211_crypto_alg * | crypt | |||
| ) | [inline, static] |
Inline safety wrapper for _sec80211_detect().
| iob | I/O buffer containing beacon frame |
| secprot | Security handshaking protocol used by network | |
| crypt | Cryptosystem used by network | |
| rc | Return status code |
-ENOTSUP if not.
Definition at line 59 of file sec80211.h.
References _sec80211_detect(), and ENOTSUP.
Referenced by net80211_probe_step().
00061 { 00062 if ( _sec80211_detect ) 00063 return _sec80211_detect ( iob, secprot, crypt ); 00064 return -ENOTSUP; 00065 }
| int sec80211_detect_ie | ( | int | is_rsn, | |
| u8 * | start, | |||
| u8 * | end, | |||
| enum net80211_security_proto * | secprot, | |||
| enum net80211_crypto_alg * | crypt | |||
| ) |
Detect crypto and AKM types from RSN information element.
| is_rsn | If TRUE, IE is a new-style RSN information element | |
| start | Pointer to first byte of version field | |
| end | Pointer to first byte not in the RSN IE |
| secprot | Security handshaking protocol used by network | |
| crypt | Cryptosystem used by network | |
| rc | Return status code |
Definition at line 325 of file sec80211.c.
References cr, DBG, EINVAL, NET80211_CRYPT_CCMP, NET80211_CRYPT_TKIP, NET80211_CRYPTOS, NET80211_HANDSHAKERS, NET80211_SECPROT_EAP, descriptor_map::net80211_type, rsn_pick_desc(), table_end, table_start, and u8.
Referenced by _sec80211_detect(), and wpa_handle_3_of_4().
00328 { 00329 enum net80211_security_proto sp; 00330 enum net80211_crypto_alg cr; 00331 struct descriptor_map *map; 00332 u8 *rsn = start; 00333 00334 /* Set some defaults */ 00335 cr = ( is_rsn ? NET80211_CRYPT_CCMP : NET80211_CRYPT_TKIP ); 00336 sp = NET80211_SECPROT_EAP; 00337 00338 rsn += 2; /* version - already checked */ 00339 rsn += 4; /* group cipher - we don't use it here */ 00340 00341 if ( rsn >= end ) 00342 goto done; 00343 00344 /* Pick crypto algorithm */ 00345 map = rsn_pick_desc ( &rsn, end, rsn_cipher_map, 00346 table_start ( NET80211_CRYPTOS ), 00347 table_end ( NET80211_CRYPTOS ) ); 00348 if ( ! map ) 00349 goto invalid_rsn; 00350 00351 cr = map->net80211_type; 00352 00353 if ( rsn >= end ) 00354 goto done; 00355 00356 /* Pick handshaking algorithm */ 00357 map = rsn_pick_desc ( &rsn, end, rsn_akm_map, 00358 table_start ( NET80211_HANDSHAKERS ), 00359 table_end ( NET80211_HANDSHAKERS ) ); 00360 if ( ! map ) 00361 goto invalid_rsn; 00362 00363 sp = map->net80211_type; 00364 00365 done: 00366 DBG ( "RSN detect: OK, crypto type %d, secprot type %d\n", cr, sp ); 00367 *secprot = sp; 00368 *crypt = cr; 00369 return 0; 00370 00371 invalid_rsn: 00372 DBG ( "RSN detect: invalid RSN IE\n" ); 00373 return -EINVAL; 00374 }
| u8* sec80211_find_rsn | ( | union ieee80211_ie * | ie, | |
| void * | ie_end, | |||
| int * | is_rsn, | |||
| u8 ** | end | |||
| ) |
Find the RSN or WPA information element in the provided beacon frame.
| ie | Pointer to first information element to check | |
| ie_end | Pointer to end of information element space |
| is_rsn | TRUE if returned IE is RSN, FALSE if it's WPA | |
| end | Pointer to byte immediately after last byte of data | |
| data | Pointer to first byte of data (the `version' field) |
If no RSN or WPA infomration element is found, returns NULL and leaves is_rsn and end in an undefined state.
This function will not return a pointer to an information element that states it extends past the tail of the io_buffer, or whose version field is incorrect.
Definition at line 268 of file sec80211.c.
References DBG, ieee80211_ie_bound(), IEEE80211_IE_RSN, IEEE80211_IE_VENDOR, ieee80211_next_ie(), IEEE80211_RSN_VERSION, IEEE80211_WPA_OUI_VEN, NULL, u16, and u8.
Referenced by _sec80211_detect(), wpa_handle_3_of_4(), wpa_make_rsn_ie(), and wpa_start().
00270 { 00271 u8 *rsn = NULL; 00272 00273 if ( ! ieee80211_ie_bound ( ie, ie_end ) ) 00274 return NULL; 00275 00276 while ( ie ) { 00277 if ( ie->id == IEEE80211_IE_VENDOR && 00278 ie->vendor.oui == IEEE80211_WPA_OUI_VEN ) { 00279 DBG ( "RSN detect: old-style WPA IE found\n" ); 00280 rsn = &ie->vendor.data[0]; 00281 *end = rsn + ie->len - 4; 00282 *is_rsn = 0; 00283 } else if ( ie->id == IEEE80211_IE_RSN ) { 00284 DBG ( "RSN detect: 802.11i RSN IE found\n" ); 00285 rsn = ( u8 * ) &ie->rsn.version; 00286 *end = rsn + ie->len; 00287 *is_rsn = 1; 00288 } 00289 00290 if ( rsn && ( *end > ( u8 * ) ie_end || rsn >= *end || 00291 *( u16 * ) rsn != IEEE80211_RSN_VERSION ) ) { 00292 DBG ( "RSN detect: malformed RSN IE or unknown " 00293 "version, keep trying\n" ); 00294 rsn = NULL; 00295 } 00296 00297 if ( rsn ) 00298 break; 00299 00300 ie = ieee80211_next_ie ( ie, ie_end ); 00301 } 00302 00303 if ( ! ie ) { 00304 DBG ( "RSN detect: no RSN IE found\n" ); 00305 return NULL; 00306 } 00307 00308 return rsn; 00309 }
| int sec80211_install | ( | struct net80211_crypto ** | which, | |
| enum net80211_crypto_alg | crypt, | |||
| const void * | key, | |||
| int | len, | |||
| const void * | rsc | |||
| ) |
Install 802.11 cryptosystem.
| which | Pointer to the cryptosystem structure to install in | |
| crypt | Cryptosystem ID number | |
| key | Encryption key to use | |
| len | Length of encryption key | |
| rsc | Initial receive sequence counter, if applicable |
| rc | Return status code |
which must point to either dev->crypto (for the normal case of installing a unicast cryptosystem) or dev->gcrypto (to install a cryptosystem that will be used only for decrypting group-source frames).
Definition at line 98 of file sec80211.c.
References net80211_crypto::algorithm, DBG, ENOMEM, ENOTSUP, EUNIQ_10, for_each_table_entry, free(), net80211_crypto::init, memcpy, NET80211_CRYPT_NONE, NET80211_CRYPTOS, NULL, net80211_crypto::priv, net80211_crypto::priv_len, and zalloc().
Referenced by trivial_init(), wpa_install_gtk(), and wpa_install_ptk().
00101 { 00102 struct net80211_crypto *crypto = *which; 00103 struct net80211_crypto *tbl_crypto; 00104 00105 /* Remove old crypto if it exists */ 00106 free ( *which ); 00107 *which = NULL; 00108 00109 if ( crypt == NET80211_CRYPT_NONE ) { 00110 DBG ( "802.11-Sec not installing null cryptography\n" ); 00111 return 0; 00112 } 00113 00114 /* Find cryptosystem to use */ 00115 for_each_table_entry ( tbl_crypto, NET80211_CRYPTOS ) { 00116 if ( tbl_crypto->algorithm == crypt ) { 00117 crypto = zalloc ( sizeof ( *crypto ) + 00118 tbl_crypto->priv_len ); 00119 if ( ! crypto ) { 00120 DBG ( "802.11-Sec out of memory\n" ); 00121 return -ENOMEM; 00122 } 00123 00124 memcpy ( crypto, tbl_crypto, sizeof ( *crypto ) ); 00125 crypto->priv = ( ( void * ) crypto + 00126 sizeof ( *crypto ) ); 00127 break; 00128 } 00129 } 00130 00131 if ( ! crypto ) { 00132 DBG ( "802.11-Sec no support for cryptosystem %d\n", crypt ); 00133 return -( ENOTSUP | EUNIQ_10 | ( crypt << 8 ) ); 00134 } 00135 00136 *which = crypto; 00137 00138 DBG ( "802.11-Sec installing cryptosystem %d as %p with key of " 00139 "length %d\n", crypt, crypto, len ); 00140 00141 return crypto->init ( crypto, key, len, rsc ); 00142 }
| u32 sec80211_rsn_get_crypto_desc | ( | enum net80211_crypto_alg | crypt, | |
| int | rsnie | |||
| ) |
Determine RSN descriptor for specified net80211 cryptosystem number.
| crypt | Cryptosystem number | |
| rsnie | Whether to return a new-format (RSN IE) descriptor |
| desc | RSN descriptor |
Definition at line 466 of file sec80211.c.
References rsn_get_desc().
Referenced by wpa_make_rsn_ie().
00467 { 00468 return rsn_get_desc ( crypt, rsnie, rsn_cipher_map ); 00469 }
| u32 sec80211_rsn_get_akm_desc | ( | enum net80211_security_proto | secprot, | |
| int | rsnie | |||
| ) |
Determine RSN descriptor for specified net80211 handshaker number.
| secprot | Handshaker number | |
| rsnie | Whether to return a new-format (RSN IE) descriptor |
| desc | RSN descriptor |
Definition at line 481 of file sec80211.c.
References rsn_get_desc().
Referenced by wpa_make_rsn_ie().
00483 { 00484 return rsn_get_desc ( secprot, rsnie, rsn_akm_map ); 00485 }
| enum net80211_crypto_alg sec80211_rsn_get_net80211_crypt | ( | u32 | desc | ) |
Determine net80211 cryptosystem number from RSN descriptor.
| desc | RSN descriptor |
| crypt | net80211 cryptosystem enumeration value |
Definition at line 493 of file sec80211.c.
References END_MAGIC, descriptor_map::net80211_type, descriptor_map::oui_type, and OUI_TYPE_MASK.
Referenced by wpa_handle_3_of_4(), and wpa_make_rsn_ie().
00494 { 00495 struct descriptor_map *map = rsn_cipher_map; 00496 00497 for ( ; map->oui_type != END_MAGIC; map++ ) { 00498 if ( map->oui_type == ( desc & OUI_TYPE_MASK ) ) 00499 break; 00500 } 00501 00502 return map->net80211_type; 00503 }
1.5.7.1