iPXE
Functions | Variables
wpa.c File Reference

Handler for the aspects of WPA handshaking that are independent of 802.1X/PSK or TKIP/CCMP; this mostly involves the 4-Way Handshake. More...

#include <ipxe/net80211.h>
#include <ipxe/sec80211.h>
#include <ipxe/wpa.h>
#include <ipxe/eapol.h>
#include <ipxe/crypto.h>
#include <ipxe/arc4.h>
#include <ipxe/crc32.h>
#include <ipxe/sha1.h>
#include <ipxe/hmac.h>
#include <ipxe/list.h>
#include <ipxe/ethernet.h>
#include <ipxe/rbg.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <byteswap.h>

Go to the source code of this file.

Functions

 FILE_LICENCE (GPL2_OR_LATER)
 
static int wpa_fail (struct wpa_common_ctx *ctx, int rc)
 Return an error code and deauthenticate. More...
 
static struct net80211_cryptowpa_find_cryptosystem (enum net80211_crypto_alg crypt)
 Find a cryptosystem handler structure from a crypto ID. More...
 
struct wpa_kiewpa_find_kie (int version)
 Find WPA key integrity and encryption handler from key version field. More...
 
int wpa_make_rsn_ie (struct net80211_device *dev, union ieee80211_ie **ie_ret)
 Construct RSN or WPA information element. More...
 
int wpa_start (struct net80211_device *dev, struct wpa_common_ctx *ctx, const void *pmk, size_t pmk_len)
 Set up generic WPA support to handle 4-Way Handshake. More...
 
void wpa_stop (struct net80211_device *dev)
 Disable handling of received WPA handshake frames. More...
 
static void wpa_derive_ptk (struct wpa_common_ctx *ctx)
 Derive pairwise transient key. More...
 
static int wpa_install_ptk (struct wpa_common_ctx *ctx, int len)
 Install pairwise transient key. More...
 
static int wpa_install_gtk (struct wpa_common_ctx *ctx, int len, const void *rsc)
 Install group transient key. More...
 
static int wpa_maybe_install_gtk (struct wpa_common_ctx *ctx, union ieee80211_ie *ie, void *ie_end, const void *rsc)
 Search for group transient key, and install it if found. More...
 
static struct io_bufferwpa_alloc_frame (int kdlen)
 Allocate I/O buffer for construction of outgoing EAPOL-Key frame. More...
 
static int wpa_send_eapol (struct io_buffer *iob, struct wpa_common_ctx *ctx, struct wpa_kie *kie)
 Send EAPOL-Key packet. More...
 
static int wpa_send_2_of_4 (struct wpa_common_ctx *ctx, struct eapol_key_pkt *pkt, int is_rsn, struct wpa_kie *kie)
 Send second frame in 4-Way Handshake. More...
 
static int wpa_handle_1_of_4 (struct wpa_common_ctx *ctx, struct eapol_key_pkt *pkt, int is_rsn, struct wpa_kie *kie)
 Handle receipt of first frame in 4-Way Handshake. More...
 
static int wpa_send_final (struct wpa_common_ctx *ctx, struct eapol_key_pkt *pkt, int is_rsn, struct wpa_kie *kie)
 Send fourth frame in 4-Way Handshake, or second in Group Key Handshake. More...
 
static int wpa_handle_3_of_4 (struct wpa_common_ctx *ctx, struct eapol_key_pkt *pkt, int is_rsn, struct wpa_kie *kie)
 Handle receipt of third frame in 4-Way Handshake. More...
 
static int wpa_handle_1_of_2 (struct wpa_common_ctx *ctx, struct eapol_key_pkt *pkt, int is_rsn, struct wpa_kie *kie)
 Handle receipt of first frame in Group Key Handshake. More...
 
static int eapol_key_rx (struct io_buffer *iob, struct net_device *netdev, const void *ll_dest __unused, const void *ll_source)
 Handle receipt of EAPOL-Key frame for WPA. More...
 
 REQUIRING_SYMBOL (eapol_key_handler)
 
 REQUIRE_OBJECT (eapol)
 

Variables

struct list_head wpa_contexts = LIST_HEAD_INIT ( wpa_contexts )
 List of WPA contexts in active use. More...
 
struct eapol_handler eapol_key_handler __eapol_handler
 

Detailed Description

Handler for the aspects of WPA handshaking that are independent of 802.1X/PSK or TKIP/CCMP; this mostly involves the 4-Way Handshake.

Definition in file wpa.c.

Function Documentation

◆ FILE_LICENCE()

FILE_LICENCE ( GPL2_OR_LATER  )

◆ wpa_fail()

static int wpa_fail ( struct wpa_common_ctx ctx,
int  rc 
)
static

Return an error code and deauthenticate.

Parameters
ctxWPA common context
rcReturn status code
Return values
rcThe passed return status code

Definition at line 56 of file wpa.c.

57 {
58  net80211_deauthenticate ( ctx->dev, rc );
59  return rc;
60 }
struct arbelprm_rc_send_wqe rc
Definition: arbel.h:14
struct golan_eq_context ctx
Definition: CIB_PRM.h:28
void net80211_deauthenticate(struct net80211_device *dev, int rc)
Deauthenticate from current network and try again.
Definition: net80211.c:2390

References ctx, net80211_deauthenticate(), and rc.

Referenced by eapol_key_rx(), wpa_handle_1_of_2(), and wpa_handle_3_of_4().

◆ wpa_find_cryptosystem()

static struct net80211_crypto* wpa_find_cryptosystem ( enum net80211_crypto_alg  crypt)
static

Find a cryptosystem handler structure from a crypto ID.

Parameters
cryptCryptosystem ID
Return values
cryptoCryptosystem handler structure

If support for crypt is not compiled in to iPXE, or if crypt is NET80211_CRYPT_UNKNOWN, returns NULL.

Definition at line 73 of file wpa.c.

74 {
75  struct net80211_crypto *crypto;
76 
78  if ( crypto->algorithm == crypt )
79  return crypto;
80  }
81 
82  return NULL;
83 }
enum net80211_crypto_alg algorithm
The cryptographic algorithm implemented.
Definition: net80211.h:692
#define NET80211_CRYPTOS
Definition: net80211.h:769
#define for_each_table_entry(pointer, table)
Iterate through all entries within a linker table.
Definition: tables.h:358
Interface to an 802.11 cryptosystem.
Definition: net80211.h:689
#define NULL
NULL pointer (VOID *)
Definition: Base.h:362

References net80211_crypto::algorithm, for_each_table_entry, NET80211_CRYPTOS, and NULL.

Referenced by wpa_make_rsn_ie().

◆ wpa_find_kie()

struct wpa_kie* wpa_find_kie ( int  version)

Find WPA key integrity and encryption handler from key version field.

Parameters
verVersion bits of EAPOL-Key info field
Return values
kieKey integrity and encryption handler

Definition at line 92 of file wpa.c.

93 {
94  struct wpa_kie *kie;
95 
97  if ( kie->version == version )
98  return kie;
99  }
100 
101  return NULL;
102 }
WPA handshake key integrity and encryption handler.
Definition: wpa.h:371
u32 version
Version number.
Definition: ath9k_hw.c:1983
int version
Value of version bits in EAPOL-Key info field for which to use.
Definition: wpa.h:376
#define WPA_KIES
Definition: wpa.h:407
#define for_each_table_entry(pointer, table)
Iterate through all entries within a linker table.
Definition: tables.h:358
#define NULL
NULL pointer (VOID *)
Definition: Base.h:362

References for_each_table_entry, NULL, wpa_kie::version, version, and WPA_KIES.

Referenced by eapol_key_rx().

◆ wpa_make_rsn_ie()

int wpa_make_rsn_ie ( struct net80211_device dev,
union ieee80211_ie **  ie_ret 
)

Construct RSN or WPA information element.

Parameters
dev802.11 device
Return values
ie_retRSN or WPA information element
rcReturn status code

This function allocates, fills, and returns a RSN or WPA information element suitable for including in an association request frame to the network identified by dev->associating. If it is impossible to construct an information element consistent with iPXE's capabilities that is compatible with that network, or if none should be sent because that network's beacon included no security information, returns an error indication and leaves ie_ret unchanged.

The returned IE will be of the same type (RSN or WPA) as was included in the beacon for the network it is destined for.

Definition at line 124 of file wpa.c.

125 {
126  u8 *rsn, *rsn_end;
127  int is_rsn;
129  enum net80211_crypto_alg gcrypt;
130  int ie_len;
131  u8 *iep;
132  struct ieee80211_ie_rsn *ie;
133  struct ieee80211_frame *hdr;
134  struct ieee80211_beacon *beacon;
135 
136  if ( ! dev->associating ) {
137  DBG ( "WPA: Can't make RSN IE for a non-associating device\n" );
138  return -EINVAL;
139  }
140 
141  hdr = dev->associating->beacon->data;
142  beacon = ( struct ieee80211_beacon * ) hdr->data;
143  rsn = sec80211_find_rsn ( beacon->info_element,
144  dev->associating->beacon->tail, &is_rsn,
145  &rsn_end );
146  if ( ! rsn ) {
147  DBG ( "WPA: Can't make RSN IE when we didn't get one\n" );
148  return -EINVAL;
149  }
150 
151  rsn += 2; /* skip version */
152  group_cipher = *( u32 * ) rsn;
154 
155  if ( ! wpa_find_cryptosystem ( gcrypt ) ||
157  DBG ( "WPA: No support for (GC:%d, PC:%d)\n",
158  gcrypt, dev->associating->crypto );
159  return -ENOTSUP;
160  }
161 
162  /* Everything looks good - make our IE. */
163 
164  /* WPA IEs need 4 more bytes for the OUI+type */
165  ie_len = ieee80211_rsn_size ( 1, 1, 0, is_rsn ) + ( 4 * ! is_rsn );
166  iep = malloc ( ie_len );
167  if ( ! iep )
168  return -ENOMEM;
169 
170  *ie_ret = ( union ieee80211_ie * ) iep;
171 
172  /* Store ID and length bytes. */
173  *iep++ = ( is_rsn ? IEEE80211_IE_RSN : IEEE80211_IE_VENDOR );
174  *iep++ = ie_len - 2;
175 
176  /* Store OUI+type for WPA IEs. */
177  if ( ! is_rsn ) {
178  *( u32 * ) iep = IEEE80211_WPA_OUI_VEN;
179  iep += 4;
180  }
181 
182  /* If this is a WPA IE, the id and len bytes in the
183  ieee80211_ie_rsn structure will not be valid, but by doing
184  the cast we can fill all the other fields much more
185  readily. */
186 
187  ie = ( struct ieee80211_ie_rsn * ) ( iep - 2 );
190  ie->pairwise_count = 1;
191  ie->pairwise_cipher[0] =
193  is_rsn );
194  ie->akm_count = 1;
195  ie->akm_list[0] =
197  is_rsn );
198  if ( is_rsn ) {
199  ie->rsn_capab = 0;
200  ie->pmkid_count = 0;
201  }
202 
203  return 0;
204 }
u32 akm_list[1]
List of authentication type IDs for supported types.
Definition: ieee80211.h:821
#define EINVAL
Invalid argument.
Definition: errno.h:428
enum net80211_crypto_alg crypto
Cryptographic algorithm used on the network.
Definition: net80211.h:1087
static struct net80211_crypto * wpa_find_cryptosystem(enum net80211_crypto_alg crypt)
Find a cryptosystem handler structure from a crypto ID.
Definition: wpa.c:73
u16 version
RSN information element version.
Definition: ieee80211.h:806
u16 rsn_capab
Security capabilities field (RSN only)
Definition: ieee80211.h:824
enum net80211_security_proto handshaking
Security handshaking method used on the network.
Definition: net80211.h:1084
An 802.11 data or management frame without QoS or WDS header fields.
Definition: ieee80211.h:300
#define ENOTSUP
Operation not supported.
Definition: errno.h:589
u16 pmkid_count
Number of PMKIDs included (present only in association frames)
Definition: ieee80211.h:827
void * tail
End of data.
Definition: iobuf.h:46
#define ENOMEM
Not enough space.
Definition: errno.h:534
static size_t ieee80211_rsn_size(int npair, int nauth, int npmkid, int rsn_ie)
Calculate necessary size of RSN information element.
Definition: ieee80211.h:844
u32 group_cipher
Cipher ID for the cipher used in multicast/broadcast frames.
Definition: ieee80211.h:809
#define IEEE80211_WPA_OUI_VEN
Old vendor-type WPA IE OUI type + subtype.
Definition: ieee80211.h:869
#define ieee80211_beacon
Definition: ieee80211.h:1069
u16 akm_count
Number of authentication types supported.
Definition: ieee80211.h:818
#define IEEE80211_IE_VENDOR
Information element ID for Vendor Specific information element.
Definition: ieee80211.h:960
u32 pairwise_cipher[1]
List of cipher IDs for supported unicast frame ciphers.
Definition: ieee80211.h:815
#define IEEE80211_IE_RSN
Information element ID for Robust Security Network information element.
Definition: ieee80211.h:834
u16 pairwise_count
Number of unicast ciphers supported.
Definition: ieee80211.h:812
Any 802.11 information element.
Definition: ieee80211.h:972
void * malloc(size_t size)
Allocate memory.
Definition: malloc.c:583
struct net80211_wlan * associating
Network with which we are associating.
Definition: net80211.h:866
uint32_t hdr
Message header.
Definition: intelvf.h:12
802.11 Robust Security Network ("WPA") information element
Definition: ieee80211.h:798
u32 sec80211_rsn_get_crypto_desc(enum net80211_crypto_alg crypt, int rsnie)
Determine RSN descriptor for specified net80211 cryptosystem number.
Definition: sec80211.c:481
u32 sec80211_rsn_get_akm_desc(enum net80211_security_proto secprot, int rsnie)
Determine RSN descriptor for specified net80211 handshaker number.
Definition: sec80211.c:496
net80211_crypto_alg
An 802.11 data encryption algorithm.
Definition: net80211.h:129
void * data
Start of data.
Definition: iobuf.h:44
u32 group_cipher
Cipher ID for the cipher used in multicast/broadcast frames.
Definition: ieee80211.h:24
#define IEEE80211_RSN_VERSION
802.11 RSN IE: expected version number
Definition: ieee80211.h:873
enum net80211_crypto_alg sec80211_rsn_get_net80211_crypt(u32 desc)
Determine net80211 cryptosystem number from RSN descriptor.
Definition: sec80211.c:508
#define DBG(...)
Print a debugging message.
Definition: compiler.h:498
struct io_buffer * beacon
The complete beacon or probe-response frame received.
Definition: net80211.h:1081
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
uint32_t u32
Definition: stdint.h:23

References ieee80211_ie_rsn::akm_count, ieee80211_ie_rsn::akm_list, net80211_device::associating, net80211_wlan::beacon, net80211_wlan::crypto, io_buffer::data, DBG, EINVAL, ENOMEM, ENOTSUP, group_cipher, ieee80211_ie_rsn::group_cipher, net80211_wlan::handshaking, hdr, ieee80211_beacon, IEEE80211_IE_RSN, IEEE80211_IE_VENDOR, ieee80211_rsn_size(), IEEE80211_RSN_VERSION, IEEE80211_WPA_OUI_VEN, malloc(), ieee80211_ie_rsn::pairwise_cipher, ieee80211_ie_rsn::pairwise_count, ieee80211_ie_rsn::pmkid_count, ieee80211_ie_rsn::rsn_capab, sec80211_find_rsn(), sec80211_rsn_get_akm_desc(), sec80211_rsn_get_crypto_desc(), sec80211_rsn_get_net80211_crypt(), io_buffer::tail, ieee80211_ie_rsn::version, and wpa_find_cryptosystem().

Referenced by wpa_psk_init().

◆ wpa_start()

int wpa_start ( struct net80211_device dev,
struct wpa_common_ctx ctx,
const void *  pmk,
size_t  pmk_len 
)

Set up generic WPA support to handle 4-Way Handshake.

Parameters
dev802.11 device
ctxWPA common context
pmkPairwise Master Key to use for session
pmk_lenLength of PMK, almost always 32
Return values
rcReturn status code

Definition at line 216 of file wpa.c.

218 {
219  struct io_buffer *iob;
220  struct ieee80211_frame *hdr;
221  struct ieee80211_beacon *beacon;
222  u8 *ap_rsn_ie = NULL, *ap_rsn_ie_end;
223 
224  if ( ! dev->rsn_ie || ! dev->associating )
225  return -EINVAL;
226 
227  ctx->dev = dev;
228  memcpy ( ctx->pmk, pmk, ctx->pmk_len = pmk_len );
229  ctx->state = WPA_READY;
230  ctx->replay = ~0ULL;
231 
232  iob = dev->associating->beacon;
233  hdr = iob->data;
234  beacon = ( struct ieee80211_beacon * ) hdr->data;
235  ap_rsn_ie = sec80211_find_rsn ( beacon->info_element, iob->tail,
236  &ctx->ap_rsn_is_rsn, &ap_rsn_ie_end );
237  if ( ap_rsn_ie ) {
238  ctx->ap_rsn_ie = malloc ( ap_rsn_ie_end - ap_rsn_ie );
239  if ( ! ctx->ap_rsn_ie )
240  return -ENOMEM;
241  memcpy ( ctx->ap_rsn_ie, ap_rsn_ie, ap_rsn_ie_end - ap_rsn_ie );
242  ctx->ap_rsn_ie_len = ap_rsn_ie_end - ap_rsn_ie;
243  } else {
244  return -ENOENT;
245  }
246 
247  ctx->crypt = dev->associating->crypto;
248  ctx->gcrypt = NET80211_CRYPT_UNKNOWN;
249 
250  list_add_tail ( &ctx->list, &wpa_contexts );
251  return 0;
252 }
#define EINVAL
Invalid argument.
Definition: errno.h:428
enum net80211_crypto_alg crypto
Cryptographic algorithm used on the network.
Definition: net80211.h:1087
Dummy value used when the cryptosystem can't be detected.
Definition: net80211.h:177
An 802.11 data or management frame without QoS or WDS header fields.
Definition: ieee80211.h:300
#define ENOENT
No such file or directory.
Definition: errno.h:514
union ieee80211_ie * rsn_ie
RSN or WPA information element to include with association.
Definition: net80211.h:932
struct golan_eq_context ctx
Definition: CIB_PRM.h:28
struct list_head wpa_contexts
List of WPA contexts in active use.
Definition: wpa.c:46
Ready for 4-Way Handshake.
Definition: wpa.h:181
void * tail
End of data.
Definition: iobuf.h:46
#define ENOMEM
Not enough space.
Definition: errno.h:534
void * memcpy(void *dest, const void *src, size_t len) __nonnull
#define list_add_tail(new, head)
Add a new entry to the tail of a list.
Definition: list.h:93
#define ieee80211_beacon
Definition: ieee80211.h:1069
void * malloc(size_t size)
Allocate memory.
Definition: malloc.c:583
struct net80211_wlan * associating
Network with which we are associating.
Definition: net80211.h:866
uint32_t hdr
Message header.
Definition: intelvf.h:12
void * data
Start of data.
Definition: iobuf.h:44
struct io_buffer * beacon
The complete beacon or probe-response frame received.
Definition: net80211.h:1081
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
#define NULL
NULL pointer (VOID *)
Definition: Base.h:362
uint8_t u8
Definition: stdint.h:19
A persistent I/O buffer.
Definition: iobuf.h:32

References net80211_device::associating, net80211_wlan::beacon, net80211_wlan::crypto, ctx, io_buffer::data, EINVAL, ENOENT, ENOMEM, hdr, ieee80211_beacon, list_add_tail, malloc(), memcpy(), NET80211_CRYPT_UNKNOWN, NULL, net80211_device::rsn_ie, sec80211_find_rsn(), io_buffer::tail, wpa_contexts, and WPA_READY.

Referenced by wpa_psk_start().

◆ wpa_stop()

void wpa_stop ( struct net80211_device dev)

Disable handling of received WPA handshake frames.

Parameters
dev802.11 device

Definition at line 260 of file wpa.c.

261 {
262  struct wpa_common_ctx *ctx, *tmp;
263 
265  if ( ctx->dev == dev ) {
266  free ( ctx->ap_rsn_ie );
267  ctx->ap_rsn_ie = NULL;
268  list_del ( &ctx->list );
269  }
270  }
271 }
struct net80211_device * dev
802.11 device we are authenticating for
Definition: wpa.h:294
struct golan_eq_context ctx
Definition: CIB_PRM.h:28
struct list_head wpa_contexts
List of WPA contexts in active use.
Definition: wpa.c:46
#define list_del(list)
Delete an entry from a list.
Definition: list.h:119
Common context for WPA security handshaking.
Definition: wpa.h:291
#define list_for_each_entry_safe(pos, tmp, head, member)
Iterate over entries in a list, safe against deletion of the current entry.
Definition: list.h:447
static void(* free)(struct refcnt *refcnt))
Definition: refcnt.h:54
uint8_t * tmp
Definition: entropy.h:156
struct list_head list
List entry.
Definition: wpa.h:362
#define NULL
NULL pointer (VOID *)
Definition: Base.h:362

References ctx, wpa_common_ctx::dev, free, wpa_common_ctx::list, list_del, list_for_each_entry_safe, NULL, tmp, and wpa_contexts.

Referenced by wpa_psk_stop().

◆ wpa_derive_ptk()

static void wpa_derive_ptk ( struct wpa_common_ctx ctx)
static

Derive pairwise transient key.

Parameters
ctxWPA common context

Definition at line 279 of file wpa.c.

280 {
281  struct {
282  u8 mac1[ETH_ALEN];
283  u8 mac2[ETH_ALEN];
284  u8 nonce1[WPA_NONCE_LEN];
285  u8 nonce2[WPA_NONCE_LEN];
286  } __attribute__ (( packed )) ptk_data;
287 
288  /* The addresses and nonces are stored in numerical order (!) */
289 
290  if ( memcmp ( ctx->dev->netdev->ll_addr, ctx->dev->bssid,
291  ETH_ALEN ) < 0 ) {
292  memcpy ( ptk_data.mac1, ctx->dev->netdev->ll_addr, ETH_ALEN );
293  memcpy ( ptk_data.mac2, ctx->dev->bssid, ETH_ALEN );
294  } else {
295  memcpy ( ptk_data.mac1, ctx->dev->bssid, ETH_ALEN );
296  memcpy ( ptk_data.mac2, ctx->dev->netdev->ll_addr, ETH_ALEN );
297  }
298 
299  if ( memcmp ( ctx->Anonce, ctx->Snonce, WPA_NONCE_LEN ) < 0 ) {
300  memcpy ( ptk_data.nonce1, ctx->Anonce, WPA_NONCE_LEN );
301  memcpy ( ptk_data.nonce2, ctx->Snonce, WPA_NONCE_LEN );
302  } else {
303  memcpy ( ptk_data.nonce1, ctx->Snonce, WPA_NONCE_LEN );
304  memcpy ( ptk_data.nonce2, ctx->Anonce, WPA_NONCE_LEN );
305  }
306 
307  DBGC2 ( ctx, "WPA %p A1 %s, A2 %s\n", ctx, eth_ntoa ( ptk_data.mac1 ),
308  eth_ntoa ( ptk_data.mac2 ) );
309  DBGC2 ( ctx, "WPA %p Nonce1, Nonce2:\n", ctx );
310  DBGC2_HD ( ctx, ptk_data.nonce1, WPA_NONCE_LEN );
311  DBGC2_HD ( ctx, ptk_data.nonce2, WPA_NONCE_LEN );
312 
313  prf_sha1 ( ctx->pmk, ctx->pmk_len,
314  "Pairwise key expansion",
315  &ptk_data, sizeof ( ptk_data ),
316  &ctx->ptk, sizeof ( ctx->ptk ) );
317 
318  DBGC2 ( ctx, "WPA %p PTK:\n", ctx );
319  DBGC2_HD ( ctx, &ctx->ptk, sizeof ( ctx->ptk ) );
320 }
#define __attribute__(x)
Definition: compiler.h:10
struct golan_eq_context ctx
Definition: CIB_PRM.h:28
void * memcpy(void *dest, const void *src, size_t len) __nonnull
#define WPA_NONCE_LEN
Length of a nonce.
Definition: wpa.h:204
#define DBGC2_HD(...)
Definition: compiler.h:524
const char * eth_ntoa(const void *ll_addr)
Transcribe Ethernet address.
Definition: ethernet.c:175
#define ETH_ALEN
Definition: if_ether.h:8
void prf_sha1(const void *key, size_t key_len, const char *label, const void *data, size_t data_len, void *prf, size_t prf_len)
SHA1 pseudorandom function for creating derived keys.
Definition: sha1extra.c:44
#define DBGC2(...)
Definition: compiler.h:522
int memcmp(const void *first, const void *second, size_t len)
Compare memory regions.
Definition: string.c:98
uint8_t u8
Definition: stdint.h:19

References __attribute__, ctx, DBGC2, DBGC2_HD, ETH_ALEN, eth_ntoa(), memcmp(), memcpy(), prf_sha1(), and WPA_NONCE_LEN.

Referenced by wpa_handle_1_of_4().

◆ wpa_install_ptk()

static int wpa_install_ptk ( struct wpa_common_ctx ctx,
int  len 
)
inlinestatic

Install pairwise transient key.

Parameters
ctxWPA common context
lenKey length (16 for CCMP, 32 for TKIP)
Return values
rcReturn status code

Definition at line 330 of file wpa.c.

331 {
332  DBGC ( ctx, "WPA %p: installing %d-byte pairwise transient key\n",
333  ctx, len );
334  DBGC2_HD ( ctx, &ctx->ptk.tk, len );
335 
336  return sec80211_install ( &ctx->dev->crypto, ctx->crypt,
337  &ctx->ptk.tk, len, NULL );
338 }
#define DBGC(...)
Definition: compiler.h:505
struct golan_eq_context ctx
Definition: CIB_PRM.h:28
int sec80211_install(struct net80211_crypto **which, enum net80211_crypto_alg crypt, const void *key, int len, const void *rsc)
Install 802.11 cryptosystem.
Definition: sec80211.c:113
#define DBGC2_HD(...)
Definition: compiler.h:524
uint32_t len
Length.
Definition: ena.h:14
#define NULL
NULL pointer (VOID *)
Definition: Base.h:362

References ctx, DBGC, DBGC2_HD, len, NULL, and sec80211_install().

Referenced by wpa_handle_3_of_4().

◆ wpa_install_gtk()

static int wpa_install_gtk ( struct wpa_common_ctx ctx,
int  len,
const void *  rsc 
)
inlinestatic

Install group transient key.

Parameters
ctxWPA common context
lenKey length (16 for CCMP, 32 for TKIP)
rscReceive sequence counter field in EAPOL-Key packet
Return values
rcReturn status code

Definition at line 348 of file wpa.c.

350 {
351  DBGC ( ctx, "WPA %p: installing %d-byte group transient key\n",
352  ctx, len );
353  DBGC2_HD ( ctx, &ctx->gtk.tk, len );
354 
355  return sec80211_install ( &ctx->dev->gcrypto, ctx->gcrypt,
356  &ctx->gtk.tk, len, rsc );
357 }
#define DBGC(...)
Definition: compiler.h:505
struct golan_eq_context ctx
Definition: CIB_PRM.h:28
u8 rsc[8]
Receive sequence counter for GTK.
Definition: wpa.h:69
int sec80211_install(struct net80211_crypto **which, enum net80211_crypto_alg crypt, const void *key, int len, const void *rsc)
Install 802.11 cryptosystem.
Definition: sec80211.c:113
#define DBGC2_HD(...)
Definition: compiler.h:524
uint32_t len
Length.
Definition: ena.h:14

References ctx, DBGC, DBGC2_HD, len, rsc, and sec80211_install().

Referenced by wpa_handle_1_of_2(), and wpa_maybe_install_gtk().

◆ wpa_maybe_install_gtk()

static int wpa_maybe_install_gtk ( struct wpa_common_ctx ctx,
union ieee80211_ie ie,
void *  ie_end,
const void *  rsc 
)
static

Search for group transient key, and install it if found.

Parameters
ctxWPA common context
iePointer to first IE in key data field
ie_endPointer to first byte not in key data field
rscReceive sequence counter field in EAPOL-Key packet
Return values
rcReturn status code

Definition at line 368 of file wpa.c.

371 {
372  struct wpa_kde *kde;
373 
374  if ( ! ieee80211_ie_bound ( ie, ie_end ) )
375  return -ENOENT;
376 
377  while ( ie ) {
378  if ( ie->id == IEEE80211_IE_VENDOR &&
379  ie->vendor.oui == WPA_KDE_GTK )
380  break;
381 
382  ie = ieee80211_next_ie ( ie, ie_end );
383  }
384 
385  if ( ! ie )
386  return -ENOENT;
387 
388  if ( ie->len - 6u > sizeof ( ctx->gtk.tk ) ) {
389  DBGC ( ctx, "WPA %p: GTK KDE is too long (%d bytes, max %zd)\n",
390  ctx, ie->len - 4, sizeof ( ctx->gtk.tk ) );
391  return -EINVAL;
392  }
393 
394  /* XXX We ignore key ID for now. */
395  kde = ( struct wpa_kde * ) ie;
396  memcpy ( &ctx->gtk.tk, &kde->gtk_encap.gtk, kde->len - 6 );
397 
398  return wpa_install_gtk ( ctx, kde->len - 6, rsc );
399 }
#define EINVAL
Invalid argument.
Definition: errno.h:428
static union ieee80211_ie * ieee80211_next_ie(union ieee80211_ie *ie, void *end)
Advance to next 802.11 information element.
Definition: ieee80211.h:1028
u32 oui
OUI and vendor-specific type byte.
Definition: ieee80211.h:955
#define DBGC(...)
Definition: compiler.h:505
#define ENOENT
No such file or directory.
Definition: errno.h:514
struct wpa_gtk gtk
Encapsulated group transient key.
Definition: wpa.h:431
struct golan_eq_context ctx
Definition: CIB_PRM.h:28
void * memcpy(void *dest, const void *src, size_t len) __nonnull
u8 id
Information element ID.
Definition: ieee80211.h:976
#define WPA_KDE_GTK
KDE type for an encapsulated Group Transient Key (requires encryption)
Definition: wpa.h:442
u8 rsc[8]
Receive sequence counter for GTK.
Definition: wpa.h:69
#define IEEE80211_IE_VENDOR
Information element ID for Vendor Specific information element.
Definition: ieee80211.h:960
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
struct wpa_kde_gtk_encap gtk_encap
For GTK-type KDEs, encapsulated GTK.
Definition: wpa.h:478
u8 len
Information element data length.
Definition: ieee80211.h:977
u8 len
Length, not including ie_type and length fields.
Definition: wpa.h:470
Any key descriptor element type.
Definition: wpa.h:464
union @16 u
static int wpa_install_gtk(struct wpa_common_ctx *ctx, int len, const void *rsc)
Install group transient key.
Definition: wpa.c:348

References ctx, DBGC, EINVAL, ENOENT, wpa_kde_gtk_encap::gtk, wpa_kde::gtk_encap, ieee80211_ie::id, ieee80211_ie_bound(), IEEE80211_IE_VENDOR, ieee80211_next_ie(), wpa_kde::len, ieee80211_ie::len, memcpy(), ieee80211_ie_vendor::oui, rsc, u, ieee80211_ie::vendor, wpa_install_gtk(), and WPA_KDE_GTK.

Referenced by wpa_handle_1_of_2(), and wpa_handle_3_of_4().

◆ wpa_alloc_frame()

static struct io_buffer* wpa_alloc_frame ( int  kdlen)
static

Allocate I/O buffer for construction of outgoing EAPOL-Key frame.

Parameters
kdlenMaximum number of bytes in the Key Data field
Return values
iobNewly allocated I/O buffer

The returned buffer will have space reserved for the link-layer and EAPOL headers, and will have iob->tail pointing to the start of the Key Data field. Thus, it is necessary to use iob_put() in filling the Key Data.

Definition at line 413 of file wpa.c.

414 {
415  struct io_buffer *ret = alloc_iob ( sizeof ( struct eapol_key_pkt ) +
416  kdlen + EAPOL_HDR_LEN +
418  if ( ! ret )
419  return NULL;
420 
422  memset ( iob_put ( ret, sizeof ( struct eapol_key_pkt ) ), 0,
423  sizeof ( struct eapol_key_pkt ) );
424 
425  return ret;
426 }
An EAPOL-Key packet.
Definition: wpa.h:104
#define iob_put(iobuf, len)
Definition: iobuf.h:116
#define EAPOL_HDR_LEN
Length of an EAPOL frame header.
Definition: eapol.h:55
struct io_buffer * alloc_iob(size_t len)
Allocate I/O buffer.
Definition: iobuf.c:128
#define MAX_LL_HEADER_LEN
Maximum length of a link-layer header.
Definition: netdevice.h:45
#define iob_reserve(iobuf, len)
Definition: iobuf.h:63
#define NULL
NULL pointer (VOID *)
Definition: Base.h:362
void * memset(void *dest, int character, size_t len) __nonnull
A persistent I/O buffer.
Definition: iobuf.h:32

References alloc_iob(), EAPOL_HDR_LEN, iob_put, iob_reserve, MAX_LL_HEADER_LEN, memset(), and NULL.

Referenced by wpa_send_2_of_4(), and wpa_send_final().

◆ wpa_send_eapol()

static int wpa_send_eapol ( struct io_buffer iob,
struct wpa_common_ctx ctx,
struct wpa_kie kie 
)
static

Send EAPOL-Key packet.

Parameters
iobI/O buffer, with sufficient headroom for headers
dev802.11 device
kieKey integrity and encryption handler
is_rsnIf TRUE, handshake uses new RSN format
Return values
rcReturn status code

If a KIE is specified, the MIC will be filled in before transmission.

Definition at line 440 of file wpa.c.

442 {
443  struct eapol_key_pkt *pkt = iob->data;
444  struct eapol_frame *eapol = iob_push ( iob, EAPOL_HDR_LEN );
445 
446  pkt->info = htons ( pkt->info );
447  pkt->keysize = htons ( pkt->keysize );
448  pkt->datalen = htons ( pkt->datalen );
449  pkt->replay = cpu_to_be64 ( pkt->replay );
450  eapol->version = EAPOL_THIS_VERSION;
451  eapol->type = EAPOL_TYPE_KEY;
452  eapol->length = htons ( iob->tail - iob->data - sizeof ( *eapol ) );
453 
454  memset ( pkt->mic, 0, sizeof ( pkt->mic ) );
455  if ( kie )
456  kie->mic ( &ctx->ptk.kck, eapol, EAPOL_HDR_LEN +
457  sizeof ( *pkt ) + ntohs ( pkt->datalen ),
458  pkt->mic );
459 
460  return net_tx ( iob, ctx->dev->netdev, &eapol_protocol,
461  ctx->dev->bssid, ctx->dev->netdev->ll_addr );
462 }
An EAPOL-Key packet.
Definition: wpa.h:104
An EAPOL frame.
Definition: eapol.h:63
#define iob_push(iobuf, len)
Definition: iobuf.h:80
u16 length
Length of payload, in network byte order.
Definition: eapol.h:72
#define ntohs(value)
Definition: byteswap.h:136
struct golan_eq_context ctx
Definition: CIB_PRM.h:28
u16 keysize
Length of encryption key to be used, network byte order.
Definition: wpa.h:116
#define EAPOL_HDR_LEN
Length of an EAPOL frame header.
Definition: eapol.h:55
u8 mic[16]
Message integrity code over the entire EAPOL frame.
Definition: wpa.h:160
void * tail
End of data.
Definition: iobuf.h:46
#define EAPOL_THIS_VERSION
Expected EAPOL version field value.
Definition: eapol.h:52
u16 info
Bitfield of key characteristics, network byte order.
Definition: wpa.h:110
u8 version
EAPOL version identifier, always 1.
Definition: eapol.h:66
void(* mic)(const void *kck, const void *msg, size_t len, void *mic)
Calculate MIC over message.
Definition: wpa.h:388
u8 type
EAPOL archetype identifier indicating format of payload.
Definition: eapol.h:69
u16 datalen
Length of the data field in bytes, network byte order.
Definition: wpa.h:163
#define EAPOL_TYPE_KEY
EAPOL-Key packet.
Definition: eapol.h:43
int net_tx(struct io_buffer *iobuf, struct net_device *netdev, struct net_protocol *net_protocol, const void *ll_dest, const void *ll_source)
Transmit network-layer packet.
Definition: netdevice.c:999
void * data
Start of data.
Definition: iobuf.h:44
#define cpu_to_be64(value)
Definition: byteswap.h:111
u64 replay
Monotonically increasing value for EAPOL-Key conversations.
Definition: wpa.h:124
#define htons(value)
Definition: byteswap.h:135
void * memset(void *dest, int character, size_t len) __nonnull

References cpu_to_be64, ctx, io_buffer::data, eapol_key_pkt::datalen, EAPOL_HDR_LEN, EAPOL_THIS_VERSION, EAPOL_TYPE_KEY, htons, eapol_key_pkt::info, iob_push, eapol_key_pkt::keysize, eapol_frame::length, memset(), eapol_key_pkt::mic, wpa_kie::mic, net_tx(), ntohs, eapol_key_pkt::replay, io_buffer::tail, eapol_frame::type, and eapol_frame::version.

Referenced by wpa_send_2_of_4(), and wpa_send_final().

◆ wpa_send_2_of_4()

static int wpa_send_2_of_4 ( struct wpa_common_ctx ctx,
struct eapol_key_pkt pkt,
int  is_rsn,
struct wpa_kie kie 
)
static

Send second frame in 4-Way Handshake.

Parameters
ctxWPA common context
pktFirst frame, to which this is a reply
is_rsnIf TRUE, handshake uses new RSN format
kieKey integrity and encryption handler
Return values
rcReturn status code

Definition at line 474 of file wpa.c.

477 {
478  struct io_buffer *iob = wpa_alloc_frame ( ctx->dev->rsn_ie->len + 2 );
479  struct eapol_key_pkt *npkt;
480 
481  if ( ! iob )
482  return -ENOMEM;
483 
484  npkt = iob->data;
485  memcpy ( npkt, pkt, sizeof ( *pkt ) );
486  npkt->info &= ~EAPOL_KEY_INFO_KEY_ACK;
487  npkt->info |= EAPOL_KEY_INFO_KEY_MIC;
488  if ( is_rsn )
489  npkt->keysize = 0;
490  memcpy ( npkt->nonce, ctx->Snonce, sizeof ( npkt->nonce ) );
491  npkt->datalen = ctx->dev->rsn_ie->len + 2;
492  memcpy ( iob_put ( iob, npkt->datalen ), ctx->dev->rsn_ie,
493  npkt->datalen );
494 
495  DBGC ( ctx, "WPA %p: sending 2/4\n", ctx );
496 
497  return wpa_send_eapol ( iob, ctx, kie );
498 }
An EAPOL-Key packet.
Definition: wpa.h:104
static int wpa_send_eapol(struct io_buffer *iob, struct wpa_common_ctx *ctx, struct wpa_kie *kie)
Send EAPOL-Key packet.
Definition: wpa.c:440
#define iob_put(iobuf, len)
Definition: iobuf.h:116
#define DBGC(...)
Definition: compiler.h:505
u8 nonce[32]
Nonce value.
Definition: wpa.h:131
struct golan_eq_context ctx
Definition: CIB_PRM.h:28
u16 keysize
Length of encryption key to be used, network byte order.
Definition: wpa.h:116
#define ENOMEM
Not enough space.
Definition: errno.h:534
void * memcpy(void *dest, const void *src, size_t len) __nonnull
#define EAPOL_KEY_INFO_KEY_ACK
Key ACK bit; set when a response is required, on all messages except #4.
Definition: wpa.h:56
u16 info
Bitfield of key characteristics, network byte order.
Definition: wpa.h:110
u16 datalen
Length of the data field in bytes, network byte order.
Definition: wpa.h:163
void * data
Start of data.
Definition: iobuf.h:44
#define EAPOL_KEY_INFO_KEY_MIC
Key MIC bit; set when the MIC field is valid, on messages 3 and 4.
Definition: wpa.h:59
static struct io_buffer * wpa_alloc_frame(int kdlen)
Allocate I/O buffer for construction of outgoing EAPOL-Key frame.
Definition: wpa.c:413
A persistent I/O buffer.
Definition: iobuf.h:32

References ctx, io_buffer::data, eapol_key_pkt::datalen, DBGC, EAPOL_KEY_INFO_KEY_ACK, EAPOL_KEY_INFO_KEY_MIC, ENOMEM, eapol_key_pkt::info, iob_put, eapol_key_pkt::keysize, memcpy(), eapol_key_pkt::nonce, wpa_alloc_frame(), and wpa_send_eapol().

Referenced by wpa_handle_1_of_4().

◆ wpa_handle_1_of_4()

static int wpa_handle_1_of_4 ( struct wpa_common_ctx ctx,
struct eapol_key_pkt pkt,
int  is_rsn,
struct wpa_kie kie 
)
static

Handle receipt of first frame in 4-Way Handshake.

Parameters
ctxWPA common context
pktEAPOL-Key packet
is_rsnIf TRUE, frame uses new RSN format
kieKey integrity and encryption handler
Return values
rcReturn status code

Definition at line 510 of file wpa.c.

513 {
514  if ( ctx->state == WPA_WAITING )
515  return -EINVAL;
516 
517  ctx->state = WPA_WORKING;
518  memcpy ( ctx->Anonce, pkt->nonce, sizeof ( ctx->Anonce ) );
519  if ( ! ctx->have_Snonce ) {
520  rbg_generate ( NULL, 0, 0, ctx->Snonce,
521  sizeof ( ctx->Snonce ) );
522  ctx->have_Snonce = 1;
523  }
524 
525  DBGC ( ctx, "WPA %p: received 1/4, looks OK\n", ctx );
526 
527  wpa_derive_ptk ( ctx );
528 
529  return wpa_send_2_of_4 ( ctx, pkt, is_rsn, kie );
530 }
#define EINVAL
Invalid argument.
Definition: errno.h:428
Performing 4-Way Handshake.
Definition: wpa.h:184
static int rbg_generate(const void *additional, size_t additional_len, int prediction_resist, void *data, size_t len)
Generate bits using RBG.
Definition: rbg.h:36
#define DBGC(...)
Definition: compiler.h:505
u8 nonce[32]
Nonce value.
Definition: wpa.h:131
struct golan_eq_context ctx
Definition: CIB_PRM.h:28
void * memcpy(void *dest, const void *src, size_t len) __nonnull
static void wpa_derive_ptk(struct wpa_common_ctx *ctx)
Derive pairwise transient key.
Definition: wpa.c:279
static int wpa_send_2_of_4(struct wpa_common_ctx *ctx, struct eapol_key_pkt *pkt, int is_rsn, struct wpa_kie *kie)
Send second frame in 4-Way Handshake.
Definition: wpa.c:474
Waiting for PMK to be set.
Definition: wpa.h:178
#define NULL
NULL pointer (VOID *)
Definition: Base.h:362

References ctx, DBGC, EINVAL, memcpy(), eapol_key_pkt::nonce, NULL, rbg_generate(), wpa_derive_ptk(), wpa_send_2_of_4(), WPA_WAITING, and WPA_WORKING.

Referenced by eapol_key_rx().

◆ wpa_send_final()

static int wpa_send_final ( struct wpa_common_ctx ctx,
struct eapol_key_pkt pkt,
int  is_rsn,
struct wpa_kie kie 
)
static

Send fourth frame in 4-Way Handshake, or second in Group Key Handshake.

Parameters
ctxWPA common context
pktEAPOL-Key packet for frame to which we're replying
is_rsnIf TRUE, frame uses new RSN format
kieKey integrity and encryption handler
Return values
rcReturn status code

Definition at line 542 of file wpa.c.

545 {
546  struct io_buffer *iob = wpa_alloc_frame ( 0 );
547  struct eapol_key_pkt *npkt;
548 
549  if ( ! iob )
550  return -ENOMEM;
551 
552  npkt = iob->data;
553  memcpy ( npkt, pkt, sizeof ( *pkt ) );
556  if ( is_rsn )
557  npkt->keysize = 0;
558  memset ( npkt->nonce, 0, sizeof ( npkt->nonce ) );
559  memset ( npkt->iv, 0, sizeof ( npkt->iv ) );
560  npkt->datalen = 0;
561 
562  if ( npkt->info & EAPOL_KEY_INFO_TYPE )
563  DBGC ( ctx, "WPA %p: sending 4/4\n", ctx );
564  else
565  DBGC ( ctx, "WPA %p: sending 2/2\n", ctx );
566 
567  return wpa_send_eapol ( iob, ctx, kie );
568 
569 }
An EAPOL-Key packet.
Definition: wpa.h:104
static int wpa_send_eapol(struct io_buffer *iob, struct wpa_common_ctx *ctx, struct wpa_kie *kie)
Send EAPOL-Key packet.
Definition: wpa.c:440
#define EAPOL_KEY_INFO_KEY_ENC
Key Encrypted bit; set when the Key Data field is encrypted.
Definition: wpa.h:71
#define DBGC(...)
Definition: compiler.h:505
u8 nonce[32]
Nonce value.
Definition: wpa.h:131
struct golan_eq_context ctx
Definition: CIB_PRM.h:28
u16 keysize
Length of encryption key to be used, network byte order.
Definition: wpa.h:116
#define ENOMEM
Not enough space.
Definition: errno.h:534
void * memcpy(void *dest, const void *src, size_t len) __nonnull
#define EAPOL_KEY_INFO_KEY_ACK
Key ACK bit; set when a response is required, on all messages except #4.
Definition: wpa.h:56
u16 info
Bitfield of key characteristics, network byte order.
Definition: wpa.h:110
u16 datalen
Length of the data field in bytes, network byte order.
Definition: wpa.h:163
void * data
Start of data.
Definition: iobuf.h:44
u8 iv[16]
Initialization vector.
Definition: wpa.h:139
#define EAPOL_KEY_INFO_INSTALL
Key install bit; set on message 3 except when legacy hacks are used.
Definition: wpa.h:53
static struct io_buffer * wpa_alloc_frame(int kdlen)
Allocate I/O buffer for construction of outgoing EAPOL-Key frame.
Definition: wpa.c:413
void * memset(void *dest, int character, size_t len) __nonnull
A persistent I/O buffer.
Definition: iobuf.h:32
#define EAPOL_KEY_INFO_TYPE
Key type bit, indicating pairwise or group.
Definition: wpa.h:50

References ctx, io_buffer::data, eapol_key_pkt::datalen, DBGC, EAPOL_KEY_INFO_INSTALL, EAPOL_KEY_INFO_KEY_ACK, EAPOL_KEY_INFO_KEY_ENC, EAPOL_KEY_INFO_TYPE, ENOMEM, eapol_key_pkt::info, eapol_key_pkt::iv, eapol_key_pkt::keysize, memcpy(), memset(), eapol_key_pkt::nonce, wpa_alloc_frame(), and wpa_send_eapol().

Referenced by wpa_handle_1_of_2(), and wpa_handle_3_of_4().

◆ wpa_handle_3_of_4()

static int wpa_handle_3_of_4 ( struct wpa_common_ctx ctx,
struct eapol_key_pkt pkt,
int  is_rsn,
struct wpa_kie kie 
)
static

Handle receipt of third frame in 4-Way Handshake.

Parameters
ctxWPA common context
pktEAPOL-Key packet
is_rsnIf TRUE, frame uses new RSN format
kieKey integrity and encryption handler
Return values
rcReturn status code

Definition at line 581 of file wpa.c.

584 {
585  int rc;
586  u8 *this_rsn, *this_rsn_end;
587  u8 *new_rsn, *new_rsn_end;
588  int this_is_rsn, new_is_rsn;
589 
590  if ( ctx->state == WPA_WAITING )
591  return -EINVAL;
592 
593  ctx->state = WPA_WORKING;
594 
595  /* Check nonce */
596  if ( memcmp ( ctx->Anonce, pkt->nonce, WPA_NONCE_LEN ) != 0 ) {
597  DBGC ( ctx, "WPA %p ALERT: nonce mismatch in 3/4\n", ctx );
598  return wpa_fail ( ctx, -EACCES );
599  }
600 
601  /* Check RSN IE */
602  this_rsn = sec80211_find_rsn ( ( union ieee80211_ie * ) pkt->data,
603  pkt->data + pkt->datalen,
604  &this_is_rsn, &this_rsn_end );
605  if ( this_rsn )
606  new_rsn = sec80211_find_rsn ( ( union ieee80211_ie * )
607  this_rsn_end,
608  pkt->data + pkt->datalen,
609  &new_is_rsn, &new_rsn_end );
610  else
611  new_rsn = NULL;
612 
613  if ( ! ctx->ap_rsn_ie || ! this_rsn ||
614  ctx->ap_rsn_ie_len != ( this_rsn_end - this_rsn ) ||
615  ctx->ap_rsn_is_rsn != this_is_rsn ||
616  memcmp ( ctx->ap_rsn_ie, this_rsn, ctx->ap_rsn_ie_len ) != 0 ) {
617  DBGC ( ctx, "WPA %p ALERT: RSN mismatch in 3/4\n", ctx );
618  DBGC2 ( ctx, "WPA %p RSNs (in 3/4, in beacon):\n", ctx );
619  DBGC2_HD ( ctx, this_rsn, this_rsn_end - this_rsn );
620  DBGC2_HD ( ctx, ctx->ap_rsn_ie, ctx->ap_rsn_ie_len );
621  return wpa_fail ( ctx, -EACCES );
622  }
623 
624  /* Don't switch if they just supplied both styles of IE
625  simultaneously; we need two RSN IEs or two WPA IEs to
626  switch ciphers. They'll be immediately consecutive because
627  of ordering guarantees. */
628  if ( new_rsn && this_is_rsn == new_is_rsn ) {
629  struct net80211_wlan *assoc = ctx->dev->associating;
630  DBGC ( ctx, "WPA %p: accommodating bait-and-switch tactics\n",
631  ctx );
632  DBGC2 ( ctx, "WPA %p RSNs (in 3/4+beacon, new in 3/4):\n",
633  ctx );
634  DBGC2_HD ( ctx, this_rsn, this_rsn_end - this_rsn );
635  DBGC2_HD ( ctx, new_rsn, new_rsn_end - new_rsn );
636 
637  if ( ( rc = sec80211_detect_ie ( new_is_rsn, new_rsn,
638  new_rsn_end,
639  &assoc->handshaking,
640  &assoc->crypto ) ) != 0 )
641  DBGC ( ctx, "WPA %p: bait-and-switch invalid, staying "
642  "with original request\n", ctx );
643  } else {
644  new_rsn = this_rsn;
645  new_is_rsn = this_is_rsn;
646  new_rsn_end = this_rsn_end;
647  }
648 
649  /* Grab group cryptosystem ID */
650  ctx->gcrypt = sec80211_rsn_get_net80211_crypt ( *( u32 * )
651  ( new_rsn + 2 ) );
652 
653  /* Check for a GTK, if info field is encrypted */
654  if ( pkt->info & EAPOL_KEY_INFO_KEY_ENC ) {
656  ( union ieee80211_ie * ) pkt->data,
657  pkt->data + pkt->datalen,
658  pkt->rsc );
659  if ( rc < 0 ) {
660  DBGC ( ctx, "WPA %p did not install GTK in 3/4: %s\n",
661  ctx, strerror ( rc ) );
662  if ( rc != -ENOENT )
663  return wpa_fail ( ctx, rc );
664  }
665  }
666 
667  DBGC ( ctx, "WPA %p: received 3/4, looks OK\n", ctx );
668 
669  /* Send final message */
670  rc = wpa_send_final ( ctx, pkt, is_rsn, kie );
671  if ( rc < 0 )
672  return wpa_fail ( ctx, rc );
673 
674  /* Install PTK */
675  rc = wpa_install_ptk ( ctx, pkt->keysize );
676  if ( rc < 0 ) {
677  DBGC ( ctx, "WPA %p failed to install PTK: %s\n", ctx,
678  strerror ( rc ) );
679  return wpa_fail ( ctx, rc );
680  }
681 
682  /* Mark us as needing a new Snonce if we rekey */
683  ctx->have_Snonce = 0;
684 
685  /* Done! */
686  ctx->state = WPA_SUCCESS;
687  return 0;
688 }
#define EINVAL
Invalid argument.
Definition: errno.h:428
struct arbelprm_rc_send_wqe rc
Definition: arbel.h:14
Performing 4-Way Handshake.
Definition: wpa.h:184
Structure representing a probed network.
Definition: net80211.h:1056
enum net80211_crypto_alg crypto
Cryptographic algorithm used on the network.
Definition: net80211.h:1087
#define EAPOL_KEY_INFO_KEY_ENC
Key Encrypted bit; set when the Key Data field is encrypted.
Definition: wpa.h:71
enum net80211_security_proto handshaking
Security handshaking method used on the network.
Definition: net80211.h:1084
#define DBGC(...)
Definition: compiler.h:505
static int wpa_install_ptk(struct wpa_common_ctx *ctx, int len)
Install pairwise transient key.
Definition: wpa.c:330
#define ENOENT
No such file or directory.
Definition: errno.h:514
#define EACCES
Permission denied.
Definition: errno.h:298
u8 nonce[32]
Nonce value.
Definition: wpa.h:131
struct golan_eq_context ctx
Definition: CIB_PRM.h:28
u16 keysize
Length of encryption key to be used, network byte order.
Definition: wpa.h:116
static int wpa_fail(struct wpa_common_ctx *ctx, int rc)
Return an error code and deauthenticate.
Definition: wpa.c:56
u8 rsc[8]
Receive sequence counter for GTK.
Definition: wpa.h:148
4-Way Handshake succeeded
Definition: wpa.h:187
#define WPA_NONCE_LEN
Length of a nonce.
Definition: wpa.h:204
u16 info
Bitfield of key characteristics, network byte order.
Definition: wpa.h:110
char * strerror(int errno)
Retrieve string representation of error number.
Definition: strerror.c:78
#define DBGC2_HD(...)
Definition: compiler.h:524
Waiting for PMK to be set.
Definition: wpa.h:178
u16 datalen
Length of the data field in bytes, network byte order.
Definition: wpa.h:163
static int wpa_maybe_install_gtk(struct wpa_common_ctx *ctx, union ieee80211_ie *ie, void *ie_end, const void *rsc)
Search for group transient key, and install it if found.
Definition: wpa.c:368
Any 802.11 information element.
Definition: ieee80211.h:972
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
u8 data[0]
Key data.
Definition: wpa.h:171
#define DBGC2(...)
Definition: compiler.h:522
enum net80211_crypto_alg sec80211_rsn_get_net80211_crypt(u32 desc)
Determine net80211 cryptosystem number from RSN descriptor.
Definition: sec80211.c:508
int memcmp(const void *first, const void *second, size_t len)
Compare memory regions.
Definition: string.c:98
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
#define NULL
NULL pointer (VOID *)
Definition: Base.h:362
uint8_t u8
Definition: stdint.h:19
uint32_t u32
Definition: stdint.h:23
static int wpa_send_final(struct wpa_common_ctx *ctx, struct eapol_key_pkt *pkt, int is_rsn, struct wpa_kie *kie)
Send fourth frame in 4-Way Handshake, or second in Group Key Handshake.
Definition: wpa.c:542

References net80211_wlan::crypto, ctx, eapol_key_pkt::data, eapol_key_pkt::datalen, DBGC, DBGC2, DBGC2_HD, EACCES, EAPOL_KEY_INFO_KEY_ENC, EINVAL, ENOENT, net80211_wlan::handshaking, eapol_key_pkt::info, eapol_key_pkt::keysize, memcmp(), eapol_key_pkt::nonce, NULL, rc, eapol_key_pkt::rsc, sec80211_detect_ie(), sec80211_find_rsn(), sec80211_rsn_get_net80211_crypt(), strerror(), wpa_fail(), wpa_install_ptk(), wpa_maybe_install_gtk(), WPA_NONCE_LEN, wpa_send_final(), WPA_SUCCESS, WPA_WAITING, and WPA_WORKING.

Referenced by eapol_key_rx().

◆ wpa_handle_1_of_2()

static int wpa_handle_1_of_2 ( struct wpa_common_ctx ctx,
struct eapol_key_pkt pkt,
int  is_rsn,
struct wpa_kie kie 
)
static

Handle receipt of first frame in Group Key Handshake.

Parameters
ctxWPA common context
pktEAPOL-Key packet
is_rsnIf TRUE, frame uses new RSN format
kieKey integrity and encryption handler
Return values
rcReturn status code

Definition at line 700 of file wpa.c.

703 {
704  int rc;
705 
706  /*
707  * WPA and RSN do this completely differently.
708  *
709  * The idea of encoding the GTK (or PMKID, or various other
710  * things) into a KDE that looks like an information element
711  * is an RSN innovation; old WPA code never encapsulates
712  * things like that. If it looks like an info element, it
713  * really is (for the WPA IE check in frames 2/4 and 3/4). The
714  * "key data encrypted" bit in the info field is also specific
715  * to RSN.
716  *
717  * So from an old WPA host, 3/4 does not contain an
718  * encapsulated GTK. The first frame of the GK handshake
719  * contains it, encrypted, but without a KDE wrapper, and with
720  * the key ID field (which iPXE doesn't use) shoved away in
721  * the reserved bits in the info field, and the TxRx bit
722  * stealing the Install bit's spot.
723  */
724 
725  if ( is_rsn && ( pkt->info & EAPOL_KEY_INFO_KEY_ENC ) ) {
727  ( union ieee80211_ie * ) pkt->data,
728  pkt->data + pkt->datalen,
729  pkt->rsc );
730  if ( rc < 0 ) {
731  DBGC ( ctx, "WPA %p: failed to install GTK in 1/2: "
732  "%s\n", ctx, strerror ( rc ) );
733  return wpa_fail ( ctx, rc );
734  }
735  } else {
736  rc = kie->decrypt ( &ctx->ptk.kek, pkt->iv, pkt->data,
737  &pkt->datalen );
738  if ( rc < 0 ) {
739  DBGC ( ctx, "WPA %p: failed to decrypt GTK: %s\n",
740  ctx, strerror ( rc ) );
741  return rc; /* non-fatal */
742  }
743  if ( pkt->datalen > sizeof ( ctx->gtk.tk ) ) {
744  DBGC ( ctx, "WPA %p: too much GTK data (%d > %zd)\n",
745  ctx, pkt->datalen, sizeof ( ctx->gtk.tk ) );
746  return wpa_fail ( ctx, -EINVAL );
747  }
748 
749  memcpy ( &ctx->gtk.tk, pkt->data, pkt->datalen );
750  wpa_install_gtk ( ctx, pkt->datalen, pkt->rsc );
751  }
752 
753  DBGC ( ctx, "WPA %p: received 1/2, looks OK\n", ctx );
754 
755  return wpa_send_final ( ctx, pkt, is_rsn, kie );
756 }
#define EINVAL
Invalid argument.
Definition: errno.h:428
struct arbelprm_rc_send_wqe rc
Definition: arbel.h:14
#define EAPOL_KEY_INFO_KEY_ENC
Key Encrypted bit; set when the Key Data field is encrypted.
Definition: wpa.h:71
#define DBGC(...)
Definition: compiler.h:505
struct golan_eq_context ctx
Definition: CIB_PRM.h:28
static int wpa_fail(struct wpa_common_ctx *ctx, int rc)
Return an error code and deauthenticate.
Definition: wpa.c:56
void * memcpy(void *dest, const void *src, size_t len) __nonnull
u8 rsc[8]
Receive sequence counter for GTK.
Definition: wpa.h:148
u16 info
Bitfield of key characteristics, network byte order.
Definition: wpa.h:110
int(* decrypt)(const void *kek, const void *iv, void *msg, u16 *len)
Decrypt key data.
Definition: wpa.h:403
char * strerror(int errno)
Retrieve string representation of error number.
Definition: strerror.c:78
u16 datalen
Length of the data field in bytes, network byte order.
Definition: wpa.h:163
static int wpa_maybe_install_gtk(struct wpa_common_ctx *ctx, union ieee80211_ie *ie, void *ie_end, const void *rsc)
Search for group transient key, and install it if found.
Definition: wpa.c:368
Any 802.11 information element.
Definition: ieee80211.h:972
u8 data[0]
Key data.
Definition: wpa.h:171
u8 iv[16]
Initialization vector.
Definition: wpa.h:139
static int wpa_install_gtk(struct wpa_common_ctx *ctx, int len, const void *rsc)
Install group transient key.
Definition: wpa.c:348
static int wpa_send_final(struct wpa_common_ctx *ctx, struct eapol_key_pkt *pkt, int is_rsn, struct wpa_kie *kie)
Send fourth frame in 4-Way Handshake, or second in Group Key Handshake.
Definition: wpa.c:542

References ctx, eapol_key_pkt::data, eapol_key_pkt::datalen, DBGC, wpa_kie::decrypt, EAPOL_KEY_INFO_KEY_ENC, EINVAL, eapol_key_pkt::info, eapol_key_pkt::iv, memcpy(), rc, eapol_key_pkt::rsc, strerror(), wpa_fail(), wpa_install_gtk(), wpa_maybe_install_gtk(), and wpa_send_final().

Referenced by eapol_key_rx().

◆ eapol_key_rx()

static int eapol_key_rx ( struct io_buffer iob,
struct net_device netdev,
const void *ll_dest  __unused,
const void *  ll_source 
)
static

Handle receipt of EAPOL-Key frame for WPA.

Parameters
iobI/O buffer
netdevNetwork device
ll_destLink-layer destination address
ll_sourceSource link-layer address

Definition at line 767 of file wpa.c.

770 {
771  struct net80211_device *dev = net80211_get ( netdev );
772  struct eapol_key_pkt *pkt = iob->data;
773  int is_rsn, found_ctx;
774  struct wpa_common_ctx *ctx;
775  int rc = 0;
776  struct wpa_kie *kie;
777  u8 their_mic[16], our_mic[16];
778 
779  if ( pkt->type != EAPOL_KEY_TYPE_WPA &&
780  pkt->type != EAPOL_KEY_TYPE_RSN ) {
781  DBG ( "EAPOL-Key: packet not of 802.11 type\n" );
782  rc = -EINVAL;
783  goto drop;
784  }
785 
786  is_rsn = ( pkt->type == EAPOL_KEY_TYPE_RSN );
787 
788  if ( ! dev ) {
789  DBG ( "EAPOL-Key: packet not from 802.11\n" );
790  rc = -EINVAL;
791  goto drop;
792  }
793 
794  if ( memcmp ( dev->bssid, ll_source, ETH_ALEN ) != 0 ) {
795  DBG ( "EAPOL-Key: packet not from associated AP\n" );
796  rc = -EINVAL;
797  goto drop;
798  }
799 
800  if ( ! ( ntohs ( pkt->info ) & EAPOL_KEY_INFO_KEY_ACK ) ) {
801  DBG ( "EAPOL-Key: packet sent in wrong direction\n" );
802  rc = -EINVAL;
803  goto drop;
804  }
805 
806  found_ctx = 0;
807  list_for_each_entry ( ctx, &wpa_contexts, list ) {
808  if ( ctx->dev == dev ) {
809  found_ctx = 1;
810  break;
811  }
812  }
813 
814  if ( ! found_ctx ) {
815  DBG ( "EAPOL-Key: no WPA context to handle packet for %p\n",
816  dev );
817  rc = -ENOENT;
818  goto drop;
819  }
820 
821  if ( ( void * ) ( pkt + 1 ) + ntohs ( pkt->datalen ) > iob->tail ) {
822  DBGC ( ctx, "WPA %p: packet truncated (has %zd extra bytes, "
823  "states %d)\n", ctx, iob->tail - ( void * ) ( pkt + 1 ),
824  ntohs ( pkt->datalen ) );
825  rc = -EINVAL;
826  goto drop;
827  }
828 
829  /* Get a handle on key integrity/encryption handler */
830  kie = wpa_find_kie ( ntohs ( pkt->info ) & EAPOL_KEY_INFO_VERSION );
831  if ( ! kie ) {
832  DBGC ( ctx, "WPA %p: no support for packet version %d\n", ctx,
833  ntohs ( pkt->info ) & EAPOL_KEY_INFO_VERSION );
834  rc = wpa_fail ( ctx, -ENOTSUP );
835  goto drop;
836  }
837 
838  /* Check MIC */
839  if ( ntohs ( pkt->info ) & EAPOL_KEY_INFO_KEY_MIC ) {
840  memcpy ( their_mic, pkt->mic, sizeof ( pkt->mic ) );
841  memset ( pkt->mic, 0, sizeof ( pkt->mic ) );
842  kie->mic ( &ctx->ptk.kck, ( void * ) pkt - EAPOL_HDR_LEN,
843  EAPOL_HDR_LEN + sizeof ( *pkt ) +
844  ntohs ( pkt->datalen ), our_mic );
845  DBGC2 ( ctx, "WPA %p MIC comparison (theirs, ours):\n", ctx );
846  DBGC2_HD ( ctx, their_mic, 16 );
847  DBGC2_HD ( ctx, our_mic, 16 );
848  if ( memcmp ( their_mic, our_mic, sizeof ( pkt->mic ) ) != 0 ) {
849  DBGC ( ctx, "WPA %p: EAPOL MIC failure\n", ctx );
850  goto drop;
851  }
852  }
853 
854  /* Fix byte order to local */
855  pkt->info = ntohs ( pkt->info );
856  pkt->keysize = ntohs ( pkt->keysize );
857  pkt->datalen = ntohs ( pkt->datalen );
858  pkt->replay = be64_to_cpu ( pkt->replay );
859 
860  /* Check replay counter */
861  if ( ctx->replay != ~0ULL && ctx->replay >= pkt->replay ) {
862  DBGC ( ctx, "WPA %p ALERT: Replay detected! "
863  "(%08x:%08x >= %08x:%08x)\n", ctx,
864  ( u32 ) ( ctx->replay >> 32 ), ( u32 ) ctx->replay,
865  ( u32 ) ( pkt->replay >> 32 ), ( u32 ) pkt->replay );
866  rc = 0; /* ignore without error */
867  goto drop;
868  }
869  ctx->replay = pkt->replay;
870 
871  /* Decrypt key data */
872  if ( pkt->info & EAPOL_KEY_INFO_KEY_ENC ) {
873  rc = kie->decrypt ( &ctx->ptk.kek, pkt->iv, pkt->data,
874  &pkt->datalen );
875  if ( rc < 0 ) {
876  DBGC ( ctx, "WPA %p: failed to decrypt packet: %s\n",
877  ctx, strerror ( rc ) );
878  goto drop;
879  }
880  }
881 
882  /* Hand it off to appropriate handler */
883  switch ( pkt->info & ( EAPOL_KEY_INFO_TYPE |
885  case EAPOL_KEY_TYPE_PTK:
886  rc = wpa_handle_1_of_4 ( ctx, pkt, is_rsn, kie );
887  break;
888 
890  rc = wpa_handle_3_of_4 ( ctx, pkt, is_rsn, kie );
891  break;
892 
894  rc = wpa_handle_1_of_2 ( ctx, pkt, is_rsn, kie );
895  break;
896 
897  default:
898  DBGC ( ctx, "WPA %p: Invalid combination of key flags %04x\n",
899  ctx, pkt->info );
900  rc = -EINVAL;
901  break;
902  }
903 
904  drop:
905  free_iob ( iob );
906  return rc;
907 }
static int wpa_handle_3_of_4(struct wpa_common_ctx *ctx, struct eapol_key_pkt *pkt, int is_rsn, struct wpa_kie *kie)
Handle receipt of third frame in 4-Way Handshake.
Definition: wpa.c:581
#define EINVAL
Invalid argument.
Definition: errno.h:428
u8 type
One of the EAPOL_KEY_TYPE_* defines.
Definition: wpa.h:107
struct arbelprm_rc_send_wqe rc
Definition: arbel.h:14
An EAPOL-Key packet.
Definition: wpa.h:104
#define EAPOL_KEY_INFO_KEY_ENC
Key Encrypted bit; set when the Key Data field is encrypted.
Definition: wpa.h:71
void free_iob(struct io_buffer *iobuf)
Free I/O buffer.
Definition: iobuf.c:145
WPA handshake key integrity and encryption handler.
Definition: wpa.h:371
#define DBGC(...)
Definition: compiler.h:505
#define ENOENT
No such file or directory.
Definition: errno.h:514
#define ntohs(value)
Definition: byteswap.h:136
struct golan_eq_context ctx
Definition: CIB_PRM.h:28
u16 keysize
Length of encryption key to be used, network byte order.
Definition: wpa.h:116
struct list_head wpa_contexts
List of WPA contexts in active use.
Definition: wpa.c:46
static int wpa_handle_1_of_4(struct wpa_common_ctx *ctx, struct eapol_key_pkt *pkt, int is_rsn, struct wpa_kie *kie)
Handle receipt of first frame in 4-Way Handshake.
Definition: wpa.c:510
#define EAPOL_HDR_LEN
Length of an EAPOL frame header.
Definition: eapol.h:55
#define ENOTSUP
Operation not supported.
Definition: errno.h:589
#define EAPOL_KEY_TYPE_WPA
Old EAPOL-Key type field used by WPA1 hardware before 802.11i ratified.
Definition: wpa.h:38
static int wpa_fail(struct wpa_common_ctx *ctx, int rc)
Return an error code and deauthenticate.
Definition: wpa.c:56
u8 mic[16]
Message integrity code over the entire EAPOL frame.
Definition: wpa.h:160
void * tail
End of data.
Definition: iobuf.h:46
void * memcpy(void *dest, const void *src, size_t len) __nonnull
#define EAPOL_KEY_TYPE_GTK
Key type field value for a GTK (group) key handshake.
Definition: wpa.h:87
#define EAPOL_KEY_INFO_VERSION
Key descriptor version, indicating WPA or WPA2.
Definition: wpa.h:47
#define EAPOL_KEY_INFO_KEY_ACK
Key ACK bit; set when a response is required, on all messages except #4.
Definition: wpa.h:56
#define list_for_each_entry(pos, head, member)
Iterate over entries in a list.
Definition: list.h:420
struct wpa_kie * wpa_find_kie(int version)
Find WPA key integrity and encryption handler from key version field.
Definition: wpa.c:92
static struct net_device * netdev
Definition: gdbudp.c:52
Common context for WPA security handshaking.
Definition: wpa.h:291
u16 info
Bitfield of key characteristics, network byte order.
Definition: wpa.h:110
int(* decrypt)(const void *kek, const void *iv, void *msg, u16 *len)
Decrypt key data.
Definition: wpa.h:403
#define EAPOL_KEY_TYPE_RSN
EAPOL-Key type field for modern 802.11i/RSN WPA packets.
Definition: wpa.h:35
char * strerror(int errno)
Retrieve string representation of error number.
Definition: strerror.c:78
#define be64_to_cpu(value)
Definition: byteswap.h:117
#define DBGC2_HD(...)
Definition: compiler.h:524
Structure encapsulating the complete state of an 802.11 device.
Definition: net80211.h:786
void(* mic)(const void *kck, const void *msg, size_t len, void *mic)
Calculate MIC over message.
Definition: wpa.h:388
static int wpa_handle_1_of_2(struct wpa_common_ctx *ctx, struct eapol_key_pkt *pkt, int is_rsn, struct wpa_kie *kie)
Handle receipt of first frame in Group Key Handshake.
Definition: wpa.c:700
u16 datalen
Length of the data field in bytes, network byte order.
Definition: wpa.h:163
#define ETH_ALEN
Definition: if_ether.h:8
struct net80211_device * net80211_get(struct net_device *netdev)
Get 802.11 device from wrapping network device.
Definition: net80211.c:624
u8 data[0]
Key data.
Definition: wpa.h:171
#define DBGC2(...)
Definition: compiler.h:522
void * data
Start of data.
Definition: iobuf.h:44
u8 iv[16]
Initialization vector.
Definition: wpa.h:139
#define EAPOL_KEY_INFO_KEY_MIC
Key MIC bit; set when the MIC field is valid, on messages 3 and 4.
Definition: wpa.h:59
u8 bssid[ETH_ALEN]
MAC address of the access point most recently associated.
Definition: net80211.h:954
#define EAPOL_KEY_TYPE_PTK
Key type field value for a PTK (pairwise) key handshake.
Definition: wpa.h:84
#define DBG(...)
Print a debugging message.
Definition: compiler.h:498
int memcmp(const void *first, const void *second, size_t len)
Compare memory regions.
Definition: string.c:98
u64 replay
Monotonically increasing value for EAPOL-Key conversations.
Definition: wpa.h:124
uint8_t u8
Definition: stdint.h:19
uint32_t u32
Definition: stdint.h:23
void * memset(void *dest, int character, size_t len) __nonnull
#define EAPOL_KEY_INFO_TYPE
Key type bit, indicating pairwise or group.
Definition: wpa.h:50

References be64_to_cpu, net80211_device::bssid, ctx, io_buffer::data, eapol_key_pkt::data, eapol_key_pkt::datalen, DBG, DBGC, DBGC2, DBGC2_HD, wpa_kie::decrypt, EAPOL_HDR_LEN, EAPOL_KEY_INFO_KEY_ACK, EAPOL_KEY_INFO_KEY_ENC, EAPOL_KEY_INFO_KEY_MIC, EAPOL_KEY_INFO_TYPE, EAPOL_KEY_INFO_VERSION, EAPOL_KEY_TYPE_GTK, EAPOL_KEY_TYPE_PTK, EAPOL_KEY_TYPE_RSN, EAPOL_KEY_TYPE_WPA, EINVAL, ENOENT, ENOTSUP, ETH_ALEN, free_iob(), eapol_key_pkt::info, eapol_key_pkt::iv, eapol_key_pkt::keysize, list_for_each_entry, memcmp(), memcpy(), memset(), eapol_key_pkt::mic, wpa_kie::mic, net80211_get(), netdev, ntohs, rc, eapol_key_pkt::replay, strerror(), io_buffer::tail, eapol_key_pkt::type, wpa_contexts, wpa_fail(), wpa_find_kie(), wpa_handle_1_of_2(), wpa_handle_1_of_4(), and wpa_handle_3_of_4().

◆ REQUIRING_SYMBOL()

REQUIRING_SYMBOL ( eapol_key_handler  )

◆ REQUIRE_OBJECT()

REQUIRE_OBJECT ( eapol  )

Variable Documentation

◆ wpa_contexts

struct list_head wpa_contexts = LIST_HEAD_INIT ( wpa_contexts )

List of WPA contexts in active use.

Definition at line 46 of file wpa.c.

Referenced by eapol_key_rx(), wpa_start(), and wpa_stop().

◆ __eapol_handler

struct eapol_handler eapol_key_handler __eapol_handler
Initial value:
= {
.type = EAPOL_TYPE_KEY,
.rx = eapol_key_rx,
}
#define EAPOL_TYPE_KEY
EAPOL-Key packet.
Definition: eapol.h:43
static int eapol_key_rx(struct io_buffer *iob, struct net_device *netdev, const void *ll_dest __unused, const void *ll_source)
Handle receipt of EAPOL-Key frame for WPA.
Definition: wpa.c:767

Definition at line 909 of file wpa.c.