1 /* 2 * Copyright (c) 2009 Joshua Oreman <oremanj (at) rwcr.net>. 3 * 4 * This program is free software; you can redistribute it and/or 5 * modify it under the terms of the GNU General Public License as 6 * published by the Free Software Foundation; either version 2 of the 7 * License, or any later version. 8 * 9 * This program is distributed in the hope that it will be useful, but 10 * WITHOUT ANY WARRANTY; without even the implied warranty of 11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 * General Public License for more details. 13 * 14 * You should have received a copy of the GNU General Public License 15 * along with this program; if not, write to the Free Software 16 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 17 */ 18 19 FILE_LICENCE ( GPL2_OR_LATER ); 20 21 #include <stdlib.h> 22 #include <string.h> 23 #include <errno.h> 24 #include <gpxe/ieee80211.h> 25 #include <gpxe/net80211.h> 26 #include <gpxe/sec80211.h> 27 28 /** @file 29 * 30 * General secured-network routines required whenever any secure 31 * network support at all is compiled in. This involves things like 32 * installing keys, determining the type of security used by a probed 33 * network, and some small helper functions that take advantage of 34 * static data in this file. 35 */ 36 37 /** Mapping from net80211 crypto/secprot types to RSN OUI descriptors */ 38 struct descriptor_map { 39 /** Value of net80211_crypto_alg or net80211_security_proto */ 40 u32 net80211_type; 41 42 /** OUI+type in appropriate byte order, masked to exclude vendor */ 43 u32 oui_type; 44 }; 45 46 /** Magic number in @a oui_type showing end of list */ 47 #define END_MAGIC 0xFFFFFFFF 48 49 /** Mapping between net80211 cryptosystems and 802.11i cipher IDs */ 50 static struct descriptor_map rsn_cipher_map[] = { 51 { .net80211_type = NET80211_CRYPT_WEP, 52 .oui_type = IEEE80211_RSN_CTYPE_WEP40 }, 53 54 { .net80211_type = NET80211_CRYPT_WEP, 55 .oui_type = IEEE80211_RSN_CTYPE_WEP104 }, 56 57 { .net80211_type = NET80211_CRYPT_TKIP, 58 .oui_type = IEEE80211_RSN_CTYPE_TKIP }, 59 60 { .net80211_type = NET80211_CRYPT_CCMP, 61 .oui_type = IEEE80211_RSN_CTYPE_CCMP }, 62 63 { .net80211_type = NET80211_CRYPT_UNKNOWN, 64 .oui_type = END_MAGIC }, 65 }; 66 67 /** Mapping between net80211 handshakers and 802.11i AKM IDs */ 68 static struct descriptor_map rsn_akm_map[] = { 69 { .net80211_type = NET80211_SECPROT_EAP, 70 .oui_type = IEEE80211_RSN_ATYPE_8021X }, 71 72 { .net80211_type = NET80211_SECPROT_PSK, 73 .oui_type = IEEE80211_RSN_ATYPE_PSK }, 74 75 { .net80211_type = NET80211_SECPROT_UNKNOWN, 76 .oui_type = END_MAGIC }, 77 }; 78 79 80 /** 81 * Install 802.11 cryptosystem 82 * 83 * @v which Pointer to the cryptosystem structure to install in 84 * @v crypt Cryptosystem ID number 85 * @v key Encryption key to use 86 * @v len Length of encryption key 87 * @v rsc Initial receive sequence counter, if applicable 88 * @ret rc Return status code 89 * 90 * The encryption key will not be accessed via the provided pointer 91 * after this function returns, so you may keep it on the stack. 92 * 93 * @a which must point to either @c dev->crypto (for the normal case 94 * of installing a unicast cryptosystem) or @c dev->gcrypto (to 95 * install a cryptosystem that will be used only for decrypting 96 * group-source frames). 97 */ 98 int sec80211_install ( struct net80211_crypto **which, 99 enum net80211_crypto_alg crypt, 100 const void *key, int len, const void *rsc ) 101 { 102 struct net80211_crypto *crypto = *which; 103 struct net80211_crypto *tbl_crypto; 104 105 /* Remove old crypto if it exists */ 106 free ( *which ); 107 *which = NULL; 108 109 if ( crypt == NET80211_CRYPT_NONE ) { 110 DBG ( "802.11-Sec not installing null cryptography\n" ); 111 return 0; 112 } 113 114 /* Find cryptosystem to use */ 115 for_each_table_entry ( tbl_crypto, NET80211_CRYPTOS ) { 116 if ( tbl_crypto->algorithm == crypt ) { 117 crypto = zalloc ( sizeof ( *crypto ) + 118 tbl_crypto->priv_len ); 119 if ( ! crypto ) { 120 DBG ( "802.11-Sec out of memory\n" ); 121 return -ENOMEM; 122 } 123 124 memcpy ( crypto, tbl_crypto, sizeof ( *crypto ) ); 125 crypto->priv = ( ( void * ) crypto + 126 sizeof ( *crypto ) ); 127 break; 128 } 129 } 130 131 if ( ! crypto ) { 132 DBG ( "802.11-Sec no support for cryptosystem %d\n", crypt ); 133 return -( ENOTSUP | EUNIQ_10 | ( crypt << 8 ) ); 134 } 135 136 *which = crypto; 137 138 DBG ( "802.11-Sec installing cryptosystem %d as %p with key of " 139 "length %d\n", crypt, crypto, len ); 140 141 return crypto->init ( crypto, key, len, rsc ); 142 } 143 144 145 /** 146 * Determine net80211 crypto or handshaking type value to return for RSN info 147 * 148 * @v rsnp Pointer to next descriptor count field in RSN IE 149 * @v rsn_end Pointer to end of RSN IE 150 * @v map Descriptor map to use 151 * @v tbl_start Start of linker table to examine for gPXE support 152 * @v tbl_end End of linker table to examine for gPXE support 153 * @ret rsnp Updated to point to first byte after descriptors 154 * @ret map_ent Descriptor map entry of translation to use 155 * 156 * The entries in the linker table must be either net80211_crypto or 157 * net80211_handshaker structures, and @a tbl_stride must be set to 158 * sizeof() the appropriate one. 159 * 160 * This function expects @a rsnp to point at a two-byte descriptor 161 * count followed by a list of four-byte cipher or AKM descriptors; it 162 * will return @c NULL if the input packet is malformed, and otherwise 163 * set @a rsnp to the first byte it has not looked at. It will return 164 * the first cipher in the list that is supported by the current build 165 * of gPXE, or the first of all if none are supported. 166 * 167 * We play rather fast and loose with type checking, because this 168 * function is only called from two well-defined places in the 169 * RSN-checking code. Don't try to use it for anything else. 170 */ 171 static struct descriptor_map * rsn_pick_desc ( u8 **rsnp, u8 *rsn_end, 172 struct descriptor_map *map, 173 void *tbl_start, void *tbl_end ) 174 { 175 int ndesc; 176 int ok = 0; 177 struct descriptor_map *map_ent, *map_ret = NULL; 178 u8 *rsn = *rsnp; 179 void *tblp; 180 size_t tbl_stride = ( map == rsn_cipher_map ? 181 sizeof ( struct net80211_crypto ) : 182 sizeof ( struct net80211_handshaker ) ); 183 184 if ( map != rsn_cipher_map && map != rsn_akm_map ) 185 return NULL; 186 187 /* Determine which types we support */ 188 for ( tblp = tbl_start; tblp < tbl_end; tblp += tbl_stride ) { 189 struct net80211_crypto *crypto = tblp; 190 struct net80211_handshaker *hs = tblp; 191 192 if ( map == rsn_cipher_map ) 193 ok |= ( 1 << crypto->algorithm ); 194 else 195 ok |= ( 1 << hs->protocol ); 196 } 197 198 /* RSN sanity checks */ 199 if ( rsn + 2 > rsn_end ) { 200 DBG ( "RSN detect: malformed descriptor count\n" ); 201 return NULL; 202 } 203 204 ndesc = *( u16 * ) rsn; 205 rsn += 2; 206 207 if ( ! ndesc ) { 208 DBG ( "RSN detect: no descriptors\n" ); 209 return NULL; 210 } 211 212 /* Determine which net80211 crypto types are listed */ 213 while ( ndesc-- ) { 214 u32 desc; 215 216 if ( rsn + 4 > rsn_end ) { 217 DBG ( "RSN detect: malformed descriptor (%d left)\n", 218 ndesc ); 219 return NULL; 220 } 221 222 desc = *( u32 * ) rsn; 223 rsn += 4; 224 225 for ( map_ent = map; map_ent->oui_type != END_MAGIC; map_ent++ ) 226 if ( map_ent->oui_type == ( desc & OUI_TYPE_MASK ) ) 227 break; 228 229 /* Use first cipher as a fallback */ 230 if ( ! map_ret ) 231 map_ret = map_ent; 232 233 /* Once we find one we support, use it */ 234 if ( ok & ( 1 << map_ent->net80211_type ) ) { 235 map_ret = map_ent; 236 break; 237 } 238 } 239 240 if ( ndesc > 0 ) 241 rsn += 4 * ndesc; 242 243 *rsnp = rsn; 244 return map_ret; 245 } 246 247 248 /** 249 * Find the RSN or WPA information element in the provided beacon frame 250 * 251 * @v ie Pointer to first information element to check 252 * @v ie_end Pointer to end of information element space 253 * @ret is_rsn TRUE if returned IE is RSN, FALSE if it's WPA 254 * @ret end Pointer to byte immediately after last byte of data 255 * @ret data Pointer to first byte of data (the `version' field) 256 * 257 * If both an RSN and a WPA information element are found, this 258 * function will return the first one seen, which by ordering rules 259 * should always prefer the newer RSN IE. 260 * 261 * If no RSN or WPA infomration element is found, returns @c NULL and 262 * leaves @a is_rsn and @a end in an undefined state. 263 * 264 * This function will not return a pointer to an information element 265 * that states it extends past the tail of the io_buffer, or whose @a 266 * version field is incorrect. 267 */ 268 u8 * sec80211_find_rsn ( union ieee80211_ie *ie, void *ie_end, 269 int *is_rsn, u8 **end ) 270 { 271 u8 *rsn = NULL; 272 273 if ( ! ieee80211_ie_bound ( ie, ie_end ) ) 274 return NULL; 275 276 while ( ie ) { 277 if ( ie->id == IEEE80211_IE_VENDOR && 278 ie->vendor.oui == IEEE80211_WPA_OUI_VEN ) { 279 DBG ( "RSN detect: old-style WPA IE found\n" ); 280 rsn = &ie->vendor.data[0]; 281 *end = rsn + ie->len - 4; 282 *is_rsn = 0; 283 } else if ( ie->id == IEEE80211_IE_RSN ) { 284 DBG ( "RSN detect: 802.11i RSN IE found\n" ); 285 rsn = ( u8 * ) &ie->rsn.version; 286 *end = rsn + ie->len; 287 *is_rsn = 1; 288 } 289 290 if ( rsn && ( *end > ( u8 * ) ie_end || rsn >= *end || 291 *( u16 * ) rsn != IEEE80211_RSN_VERSION ) ) { 292 DBG ( "RSN detect: malformed RSN IE or unknown " 293 "version, keep trying\n" ); 294 rsn = NULL; 295 } 296 297 if ( rsn ) 298 break; 299 300 ie = ieee80211_next_ie ( ie, ie_end ); 301 } 302 303 if ( ! ie ) { 304 DBG ( "RSN detect: no RSN IE found\n" ); 305 return NULL; 306 } 307 308 return rsn; 309 } 310 311 312 /** 313 * Detect crypto and AKM types from RSN information element 314 * 315 * @v is_rsn If TRUE, IE is a new-style RSN information element 316 * @v start Pointer to first byte of @a version field 317 * @v end Pointer to first byte not in the RSN IE 318 * @ret secprot Security handshaking protocol used by network 319 * @ret crypt Cryptosystem used by network 320 * @ret rc Return status code 321 * 322 * If the IE cannot be parsed, returns an error indication and leaves 323 * @a secprot and @a crypt unchanged. 324 */ 325 int sec80211_detect_ie ( int is_rsn, u8 *start, u8 *end, 326 enum net80211_security_proto *secprot, 327 enum net80211_crypto_alg *crypt ) 328 { 329 enum net80211_security_proto sp; 330 enum net80211_crypto_alg cr; 331 struct descriptor_map *map; 332 u8 *rsn = start; 333 334 /* Set some defaults */ 335 cr = ( is_rsn ? NET80211_CRYPT_CCMP : NET80211_CRYPT_TKIP ); 336 sp = NET80211_SECPROT_EAP; 337 338 rsn += 2; /* version - already checked */ 339 rsn += 4; /* group cipher - we don't use it here */ 340 341 if ( rsn >= end ) 342 goto done; 343 344 /* Pick crypto algorithm */ 345 map = rsn_pick_desc ( &rsn, end, rsn_cipher_map, 346 table_start ( NET80211_CRYPTOS ), 347 table_end ( NET80211_CRYPTOS ) ); 348 if ( ! map ) 349 goto invalid_rsn; 350 351 cr = map->net80211_type; 352 353 if ( rsn >= end ) 354 goto done; 355 356 /* Pick handshaking algorithm */ 357 map = rsn_pick_desc ( &rsn, end, rsn_akm_map, 358 table_start ( NET80211_HANDSHAKERS ), 359 table_end ( NET80211_HANDSHAKERS ) ); 360 if ( ! map ) 361 goto invalid_rsn; 362 363 sp = map->net80211_type; 364 365 done: 366 DBG ( "RSN detect: OK, crypto type %d, secprot type %d\n", cr, sp ); 367 *secprot = sp; 368 *crypt = cr; 369 return 0; 370 371 invalid_rsn: 372 DBG ( "RSN detect: invalid RSN IE\n" ); 373 return -EINVAL; 374 } 375 376 377 /** 378 * Detect the cryptosystem and handshaking protocol used by an 802.11 network 379 * 380 * @v iob I/O buffer containing beacon frame 381 * @ret secprot Security handshaking protocol used by network 382 * @ret crypt Cryptosystem used by network 383 * @ret rc Return status code 384 * 385 * This function uses weak linkage, as it must be called from generic 386 * contexts but should only be linked in if some encryption is 387 * supported; you must test its address against @c NULL before calling 388 * it. If it does not exist, any network with the PRIVACY bit set in 389 * beacon->capab should be considered unknown. 390 */ 391 int _sec80211_detect ( struct io_buffer *iob, 392 enum net80211_security_proto *secprot, 393 enum net80211_crypto_alg *crypt ) 394 { 395 struct ieee80211_frame *hdr = iob->data; 396 struct ieee80211_beacon *beacon = 397 ( struct ieee80211_beacon * ) hdr->data; 398 u8 *rsn, *rsn_end; 399 int is_rsn, rc; 400 401 *crypt = NET80211_CRYPT_UNKNOWN; 402 *secprot = NET80211_SECPROT_UNKNOWN; 403 404 /* Find RSN or WPA IE */ 405 if ( ! ( rsn = sec80211_find_rsn ( beacon->info_element, iob->tail, 406 &is_rsn, &rsn_end ) ) ) { 407 /* No security IE at all; either WEP or no security. */ 408 *secprot = NET80211_SECPROT_NONE; 409 410 if ( beacon->capability & IEEE80211_CAPAB_PRIVACY ) 411 *crypt = NET80211_CRYPT_WEP; 412 else 413 *crypt = NET80211_CRYPT_NONE; 414 415 return 0; 416 } 417 418 /* Determine type of security */ 419 if ( ( rc = sec80211_detect_ie ( is_rsn, rsn, rsn_end, secprot, 420 crypt ) ) == 0 ) 421 return 0; 422 423 /* If we get here, the RSN IE was invalid */ 424 425 *crypt = NET80211_CRYPT_UNKNOWN; 426 *secprot = NET80211_SECPROT_UNKNOWN; 427 DBG ( "Failed to handle RSN IE:\n" ); 428 DBG_HD ( rsn, rsn_end - rsn ); 429 return rc; 430 } 431 432 433 /** 434 * Determine RSN descriptor for specified net80211 ID 435 * 436 * @v id net80211 ID value 437 * @v rsnie Whether to return a new-format (RSN IE) descriptor 438 * @v map Map to use in translation 439 * @ret desc RSN descriptor, or 0 on error 440 * 441 * If @a rsnie is false, returns an old-format (WPA vendor IE) 442 * descriptor. 443 */ 444 static u32 rsn_get_desc ( unsigned id, int rsnie, struct descriptor_map *map ) 445 { 446 u32 vendor = ( rsnie ? IEEE80211_RSN_OUI : IEEE80211_WPA_OUI ); 447 448 for ( ; map->oui_type != END_MAGIC; map++ ) { 449 if ( map->net80211_type == id ) 450 return map->oui_type | vendor; 451 } 452 453 return 0; 454 } 455 456 /** 457 * Determine RSN descriptor for specified net80211 cryptosystem number 458 * 459 * @v crypt Cryptosystem number 460 * @v rsnie Whether to return a new-format (RSN IE) descriptor 461 * @ret desc RSN descriptor 462 * 463 * If @a rsnie is false, returns an old-format (WPA vendor IE) 464 * descriptor. 465 */ 466 u32 sec80211_rsn_get_crypto_desc ( enum net80211_crypto_alg crypt, int rsnie ) 467 { 468 return rsn_get_desc ( crypt, rsnie, rsn_cipher_map ); 469 } 470 471 /** 472 * Determine RSN descriptor for specified net80211 handshaker number 473 * 474 * @v secprot Handshaker number 475 * @v rsnie Whether to return a new-format (RSN IE) descriptor 476 * @ret desc RSN descriptor 477 * 478 * If @a rsnie is false, returns an old-format (WPA vendor IE) 479 * descriptor. 480 */ 481 u32 sec80211_rsn_get_akm_desc ( enum net80211_security_proto secprot, 482 int rsnie ) 483 { 484 return rsn_get_desc ( secprot, rsnie, rsn_akm_map ); 485 } 486 487 /** 488 * Determine net80211 cryptosystem number from RSN descriptor 489 * 490 * @v desc RSN descriptor 491 * @ret crypt net80211 cryptosystem enumeration value 492 */ 493 enum net80211_crypto_alg sec80211_rsn_get_net80211_crypt ( u32 desc ) 494 { 495 struct descriptor_map *map = rsn_cipher_map; 496 497 for ( ; map->oui_type != END_MAGIC; map++ ) { 498 if ( map->oui_type == ( desc & OUI_TYPE_MASK ) ) 499 break; 500 } 501 502 return map->net80211_type; 503 } 504