iPXE
Functions
sec80211.h File Reference

Definitions for general secured-network routines. More...

#include <ipxe/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. More...
 
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. More...
 
u8sec80211_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. More...
 
int sec80211_install (struct net80211_crypto **which, enum net80211_crypto_alg crypt, const void *key, int len, const void *rsc)
 Install 802.11 cryptosystem. More...
 
u32 sec80211_rsn_get_crypto_desc (enum net80211_crypto_alg crypt, int rsnie)
 Determine RSN descriptor for specified net80211 cryptosystem number. More...
 
u32 sec80211_rsn_get_akm_desc (enum net80211_security_proto secprot, int rsnie)
 Determine RSN descriptor for specified net80211 handshaker number. More...
 
enum net80211_crypto_alg sec80211_rsn_get_net80211_crypt (u32 desc)
 Determine net80211 cryptosystem number from RSN descriptor. More...
 

Detailed Description

Definitions for general secured-network routines.

Definition in file sec80211.h.

Function Documentation

◆ FILE_LICENCE()

FILE_LICENCE ( GPL2_OR_LATER  )

◆ sec80211_detect()

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.

Parameters
iobI/O buffer containing beacon frame
Return values
secprotSecurity handshaking protocol used by network
cryptCryptosystem used by network
rcReturn status code

This function uses weak linkage, as it must be called from generic contexts but should only be linked in if some encryption is supported; you must test its address against 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 406 of file sec80211.c.

409 {
410  struct ieee80211_frame *hdr = iob->data;
411  struct ieee80211_beacon *beacon =
412  ( struct ieee80211_beacon * ) hdr->data;
413  u8 *rsn, *rsn_end;
414  int is_rsn, rc;
415 
416  *crypt = NET80211_CRYPT_UNKNOWN;
417  *secprot = NET80211_SECPROT_UNKNOWN;
418 
419  /* Find RSN or WPA IE */
420  if ( ! ( rsn = sec80211_find_rsn ( beacon->info_element, iob->tail,
421  &is_rsn, &rsn_end ) ) ) {
422  /* No security IE at all; either WEP or no security. */
423  *secprot = NET80211_SECPROT_NONE;
424 
425  if ( beacon->capability & IEEE80211_CAPAB_PRIVACY )
426  *crypt = NET80211_CRYPT_WEP;
427  else
428  *crypt = NET80211_CRYPT_NONE;
429 
430  return 0;
431  }
432 
433  /* Determine type of security */
434  if ( ( rc = sec80211_detect_ie ( is_rsn, rsn, rsn_end, secprot,
435  crypt ) ) == 0 )
436  return 0;
437 
438  /* If we get here, the RSN IE was invalid */
439 
440  *crypt = NET80211_CRYPT_UNKNOWN;
441  *secprot = NET80211_SECPROT_UNKNOWN;
442  DBG ( "Failed to handle RSN IE:\n" );
443  DBG_HD ( rsn, rsn_end - rsn );
444  return rc;
445 }
struct arbelprm_rc_send_wqe rc
Definition: arbel.h:14
No security handshaking.
Definition: net80211.h:102
Dummy value used when the cryptosystem can't be detected.
Definition: net80211.h:177
#define DBG_HD(...)
Definition: compiler.h:500
struct golan_inbox_hdr hdr
Message header.
Definition: CIB_PRM.h:28
#define IEEE80211_CAPAB_PRIVACY
Set if the network is encrypted (by any method)
Definition: ieee80211.h:401
An 802.11 data or management frame without QoS or WDS header fields.
Definition: ieee80211.h:300
Network protected with WEP (awful RC4-based system)
Definition: net80211.h:145
Dummy value used when the handshaking type can't be detected.
Definition: net80211.h:124
void * tail
End of data.
Definition: iobuf.h:50
#define ieee80211_beacon
Definition: ieee80211.h:1069
No security, an "Open" network.
Definition: net80211.h:131
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.
Definition: sec80211.c:340
void * data
Start of data.
Definition: iobuf.h:48
#define DBG(...)
Print a debugging message.
Definition: compiler.h:498
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.
Definition: sec80211.c:283
uint8_t u8
Definition: stdint.h:19
if(natsemi->flags &NATSEMI_64BIT) return 1

References io_buffer::data, DBG, DBG_HD, hdr, ieee80211_beacon, IEEE80211_CAPAB_PRIVACY, if(), NET80211_CRYPT_NONE, NET80211_CRYPT_UNKNOWN, NET80211_CRYPT_WEP, NET80211_SECPROT_NONE, NET80211_SECPROT_UNKNOWN, rc, sec80211_detect_ie(), sec80211_find_rsn(), and io_buffer::tail.

◆ sec80211_detect_ie()

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.

Parameters
is_rsnIf TRUE, IE is a new-style RSN information element
startPointer to first byte of version field
endPointer to first byte not in the RSN IE
Return values
secprotSecurity handshaking protocol used by network
cryptCryptosystem used by network
rcReturn status code

If the IE cannot be parsed, returns an error indication and leaves secprot and crypt unchanged.

Definition at line 340 of file sec80211.c.

343 {
345  enum net80211_crypto_alg cr;
346  struct descriptor_map *map;
347  u8 *rsn = start;
348 
349  /* Set some defaults */
350  cr = ( is_rsn ? NET80211_CRYPT_CCMP : NET80211_CRYPT_TKIP );
352 
353  rsn += 2; /* version - already checked */
354  rsn += 4; /* group cipher - we don't use it here */
355 
356  if ( rsn >= end )
357  goto done;
358 
359  /* Pick crypto algorithm */
360  map = rsn_pick_desc ( &rsn, end, rsn_cipher_map,
363  if ( ! map )
364  goto invalid_rsn;
365 
366  cr = map->net80211_type;
367 
368  if ( rsn >= end )
369  goto done;
370 
371  /* Pick handshaking algorithm */
372  map = rsn_pick_desc ( &rsn, end, rsn_akm_map,
375  if ( ! map )
376  goto invalid_rsn;
377 
378  sp = map->net80211_type;
379 
380  done:
381  DBG ( "RSN detect: OK, crypto type %d, secprot type %d\n", cr, sp );
382  *secprot = sp;
383  *crypt = cr;
384  return 0;
385 
386  invalid_rsn:
387  DBG ( "RSN detect: invalid RSN IE\n" );
388  return -EINVAL;
389 }
#define EINVAL
Invalid argument.
Definition: errno.h:428
Network protected with CCMP (AES-based system)
Definition: net80211.h:174
#define table_start(table)
Get start of linker table.
Definition: tables.h:282
net80211_security_proto
An 802.11 security handshaking protocol.
Definition: net80211.h:96
Full EAP 802.1X handshaking.
Definition: net80211.h:121
static struct descriptor_map * rsn_pick_desc(u8 **rsnp, u8 *rsn_end, struct descriptor_map *map, void *tbl_start, void *tbl_end)
Determine net80211 crypto or handshaking type value to return for RSN info.
Definition: sec80211.c:186
uint32_t start
Starting offset.
Definition: netvsc.h:12
#define NET80211_CRYPTOS
Definition: net80211.h:769
Mapping from net80211 crypto/secprot types to RSN OUI descriptors.
Definition: sec80211.c:53
#define NET80211_HANDSHAKERS
Definition: net80211.h:675
static struct descriptor_map rsn_cipher_map[]
Mapping between net80211 cryptosystems and 802.11i cipher IDs.
Definition: sec80211.c:65
static __always_inline int struct dma_mapping * map
Definition: dma.h:181
Definition: sis900.h:22
static struct descriptor_map rsn_akm_map[]
Mapping between net80211 handshakers and 802.11i AKM IDs.
Definition: sec80211.c:83
net80211_crypto_alg
An 802.11 data encryption algorithm.
Definition: net80211.h:129
uint32_t end
Ending offset.
Definition: netvsc.h:18
#define table_end(table)
Get end of linker table.
Definition: tables.h:308
Network protected with TKIP (better RC4-based system)
Definition: net80211.h:163
#define DBG(...)
Print a debugging message.
Definition: compiler.h:498
struct bofm_section_header done
Definition: bofm_test.c:46
uint8_t u8
Definition: stdint.h:19
uint16_t sp
Definition: registers.h:27

References cr, DBG, done, EINVAL, end, map, NET80211_CRYPT_CCMP, NET80211_CRYPT_TKIP, NET80211_CRYPTOS, NET80211_HANDSHAKERS, NET80211_SECPROT_EAP, rsn_akm_map, rsn_cipher_map, rsn_pick_desc(), sp, start, table_end, and table_start.

Referenced by sec80211_detect(), and wpa_handle_3_of_4().

◆ sec80211_find_rsn()

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.

Parameters
iePointer to first information element to check
ie_endPointer to end of information element space
Return values
is_rsnTRUE if returned IE is RSN, FALSE if it's WPA
endPointer to byte immediately after last byte of data
dataPointer to first byte of data (the ‘version’ field)

If both an RSN and a WPA information element are found, this function will return the first one seen, which by ordering rules should always prefer the newer RSN IE.

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 283 of file sec80211.c.

285 {
286  u8 *rsn = NULL;
287 
288  if ( ! ieee80211_ie_bound ( ie, ie_end ) )
289  return NULL;
290 
291  while ( ie ) {
292  if ( ie->id == IEEE80211_IE_VENDOR &&
293  ie->vendor.oui == IEEE80211_WPA_OUI_VEN ) {
294  DBG ( "RSN detect: old-style WPA IE found\n" );
295  rsn = &ie->vendor.data[0];
296  *end = rsn + ie->len - 4;
297  *is_rsn = 0;
298  } else if ( ie->id == IEEE80211_IE_RSN ) {
299  DBG ( "RSN detect: 802.11i RSN IE found\n" );
300  rsn = ( u8 * ) &ie->rsn.version;
301  *end = rsn + ie->len;
302  *is_rsn = 1;
303  }
304 
305  if ( rsn && ( *end > ( u8 * ) ie_end || rsn >= *end ||
306  *( u16 * ) rsn != IEEE80211_RSN_VERSION ) ) {
307  DBG ( "RSN detect: malformed RSN IE or unknown "
308  "version, keep trying\n" );
309  rsn = NULL;
310  }
311 
312  if ( rsn )
313  break;
314 
315  ie = ieee80211_next_ie ( ie, ie_end );
316  }
317 
318  if ( ! ie ) {
319  DBG ( "RSN detect: no RSN IE found\n" );
320  return NULL;
321  }
322 
323  return rsn;
324 }
uint16_t u16
Definition: stdint.h:21
static union ieee80211_ie * ieee80211_next_ie(union ieee80211_ie *ie, void *end)
Advance to next 802.11 information element.
Definition: ieee80211.h:1028
u16 version
RSN information element version.
Definition: ieee80211.h:806
struct ieee80211_ie_rsn rsn
Security information.
Definition: ieee80211.h:1000
u32 oui
OUI and vendor-specific type byte.
Definition: ieee80211.h:955
u8 id
Information element ID.
Definition: ieee80211.h:976
#define IEEE80211_WPA_OUI_VEN
Old vendor-type WPA IE OUI type + subtype.
Definition: ieee80211.h:869
u8 data[0]
Vendor-specific data.
Definition: ieee80211.h:956
#define IEEE80211_IE_VENDOR
Information element ID for Vendor Specific information element.
Definition: ieee80211.h:960
#define IEEE80211_IE_RSN
Information element ID for Robust Security Network information element.
Definition: ieee80211.h:834
struct ieee80211_ie_vendor vendor
Vendor-specific.
Definition: ieee80211.h:1003
static int ieee80211_ie_bound(union ieee80211_ie *ie, void *end)
Check that 802.11 information element is bounded by buffer.
Definition: ieee80211.h:1012
u8 len
Information element data length.
Definition: ieee80211.h:977
uint32_t end
Ending offset.
Definition: netvsc.h:18
#define IEEE80211_RSN_VERSION
802.11 RSN IE: expected version number
Definition: ieee80211.h:873
#define DBG(...)
Print a debugging message.
Definition: compiler.h:498
#define NULL
NULL pointer (VOID *)
Definition: Base.h:321
uint8_t u8
Definition: stdint.h:19

References DBG, end, ieee80211_ie_bound(), IEEE80211_IE_RSN, IEEE80211_IE_VENDOR, ieee80211_next_ie(), IEEE80211_RSN_VERSION, IEEE80211_WPA_OUI_VEN, and NULL.

Referenced by sec80211_detect(), wpa_handle_3_of_4(), wpa_make_rsn_ie(), and wpa_start().

◆ sec80211_install()

int sec80211_install ( struct net80211_crypto **  which,
enum net80211_crypto_alg  crypt,
const void *  key,
int  len,
const void *  rsc 
)

Install 802.11 cryptosystem.

Parameters
whichPointer to the cryptosystem structure to install in
cryptCryptosystem ID number
keyEncryption key to use
lenLength of encryption key
rscInitial receive sequence counter, if applicable
Return values
rcReturn status code

The encryption key will not be accessed via the provided pointer after this function returns, so you may keep it on the stack.

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 113 of file sec80211.c.

116 {
117  struct net80211_crypto *crypto = *which;
118  struct net80211_crypto *tbl_crypto;
119 
120  /* Remove old crypto if it exists */
121  free ( *which );
122  *which = NULL;
123 
124  if ( crypt == NET80211_CRYPT_NONE ) {
125  DBG ( "802.11-Sec not installing null cryptography\n" );
126  return 0;
127  }
128 
129  /* Find cryptosystem to use */
130  for_each_table_entry ( tbl_crypto, NET80211_CRYPTOS ) {
131  if ( tbl_crypto->algorithm == crypt ) {
132  crypto = zalloc ( sizeof ( *crypto ) +
133  tbl_crypto->priv_len );
134  if ( ! crypto ) {
135  DBG ( "802.11-Sec out of memory\n" );
136  return -ENOMEM;
137  }
138 
139  memcpy ( crypto, tbl_crypto, sizeof ( *crypto ) );
140  crypto->priv = ( ( void * ) crypto +
141  sizeof ( *crypto ) );
142  break;
143  }
144  }
145 
146  if ( ! crypto ) {
147  DBG ( "802.11-Sec no support for cryptosystem %d\n", crypt );
148  return -ENOTSUP_CRYPT ( crypt );
149  }
150 
151  *which = crypto;
152 
153  DBG ( "802.11-Sec installing cryptosystem %d as %p with key of "
154  "length %d\n", crypt, crypto, len );
155 
156  return crypto->init ( crypto, key, len, rsc );
157 }
int(* init)(struct net80211_crypto *crypto, const void *key, int keylen, const void *rsc)
Initialize cryptosystem using a given key.
Definition: net80211.h:707
int priv_len
Length of private data requested to be allocated.
Definition: net80211.h:763
#define ENOTSUP_CRYPT(crypt)
Definition: sec80211.c:48
#define ENOMEM
Not enough space.
Definition: errno.h:534
enum net80211_crypto_alg algorithm
The cryptographic algorithm implemented.
Definition: net80211.h:692
void * memcpy(void *dest, const void *src, size_t len) __nonnull
u8 rsc[8]
Receive sequence counter for GTK.
Definition: wpa.h:69
#define NET80211_CRYPTOS
Definition: net80211.h:769
static void(* free)(struct refcnt *refcnt))
Definition: refcnt.h:54
void * zalloc(size_t size)
Allocate cleared memory.
Definition: malloc.c:624
No security, an "Open" network.
Definition: net80211.h:131
#define for_each_table_entry(pointer, table)
Iterate through all entries within a linker table.
Definition: tables.h:385
void * priv
Private data for the algorithm to store key and state info.
Definition: net80211.h:766
#define DBG(...)
Print a debugging message.
Definition: compiler.h:498
Interface to an 802.11 cryptosystem.
Definition: net80211.h:689
uint32_t len
Length.
Definition: ena.h:14
#define NULL
NULL pointer (VOID *)
Definition: Base.h:321
union @383 key
Sense key.
Definition: scsi.h:18

References net80211_crypto::algorithm, DBG, ENOMEM, ENOTSUP_CRYPT, for_each_table_entry, free, net80211_crypto::init, key, len, memcpy(), NET80211_CRYPT_NONE, NET80211_CRYPTOS, NULL, net80211_crypto::priv, net80211_crypto::priv_len, rsc, and zalloc().

Referenced by trivial_init(), wpa_install_gtk(), and wpa_install_ptk().

◆ sec80211_rsn_get_crypto_desc()

u32 sec80211_rsn_get_crypto_desc ( enum net80211_crypto_alg  crypt,
int  rsnie 
)

Determine RSN descriptor for specified net80211 cryptosystem number.

Parameters
cryptCryptosystem number
rsnieWhether to return a new-format (RSN IE) descriptor
Return values
descRSN descriptor

If rsnie is false, returns an old-format (WPA vendor IE) descriptor.

Definition at line 481 of file sec80211.c.

482 {
483  return rsn_get_desc ( crypt, rsnie, rsn_cipher_map );
484 }
static u32 rsn_get_desc(unsigned id, int rsnie, struct descriptor_map *map)
Determine RSN descriptor for specified net80211 ID.
Definition: sec80211.c:459
static struct descriptor_map rsn_cipher_map[]
Mapping between net80211 cryptosystems and 802.11i cipher IDs.
Definition: sec80211.c:65

References rsn_cipher_map, and rsn_get_desc().

Referenced by wpa_make_rsn_ie().

◆ sec80211_rsn_get_akm_desc()

u32 sec80211_rsn_get_akm_desc ( enum net80211_security_proto  secprot,
int  rsnie 
)

Determine RSN descriptor for specified net80211 handshaker number.

Parameters
secprotHandshaker number
rsnieWhether to return a new-format (RSN IE) descriptor
Return values
descRSN descriptor

If rsnie is false, returns an old-format (WPA vendor IE) descriptor.

Definition at line 496 of file sec80211.c.

498 {
499  return rsn_get_desc ( secprot, rsnie, rsn_akm_map );
500 }
static u32 rsn_get_desc(unsigned id, int rsnie, struct descriptor_map *map)
Determine RSN descriptor for specified net80211 ID.
Definition: sec80211.c:459
static struct descriptor_map rsn_akm_map[]
Mapping between net80211 handshakers and 802.11i AKM IDs.
Definition: sec80211.c:83

References rsn_akm_map, and rsn_get_desc().

Referenced by wpa_make_rsn_ie().

◆ sec80211_rsn_get_net80211_crypt()

enum net80211_crypto_alg sec80211_rsn_get_net80211_crypt ( u32  desc)

Determine net80211 cryptosystem number from RSN descriptor.

Parameters
descRSN descriptor
Return values
cryptnet80211 cryptosystem enumeration value

Definition at line 508 of file sec80211.c.

509 {
511 
512  for ( ; map->oui_type != END_MAGIC; map++ ) {
513  if ( map->oui_type == ( desc & OUI_TYPE_MASK ) )
514  break;
515  }
516 
517  return map->net80211_type;
518 }
#define OUI_TYPE_MASK
Definition: ieee80211.h:859
uint64_t desc
Microcode descriptor list physical address.
Definition: ucode.h:12
#define END_MAGIC
Magic number in oui_type showing end of list.
Definition: sec80211.c:62
Mapping from net80211 crypto/secprot types to RSN OUI descriptors.
Definition: sec80211.c:53
static struct descriptor_map rsn_cipher_map[]
Mapping between net80211 cryptosystems and 802.11i cipher IDs.
Definition: sec80211.c:65
static __always_inline int struct dma_mapping * map
Definition: dma.h:181

References desc, END_MAGIC, map, OUI_TYPE_MASK, and rsn_cipher_map.

Referenced by wpa_handle_3_of_4(), and wpa_make_rsn_ie().