iPXE
wpa.c
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2009 Joshua Oreman <oremanj@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., 51 Franklin Street, Fifth Floor, Boston, MA
17  * 02110-1301, USA.
18  */
19 
20 FILE_LICENCE ( GPL2_OR_LATER );
21 
22 #include <ipxe/net80211.h>
23 #include <ipxe/sec80211.h>
24 #include <ipxe/wpa.h>
25 #include <ipxe/eapol.h>
26 #include <ipxe/crypto.h>
27 #include <ipxe/arc4.h>
28 #include <ipxe/crc32.h>
29 #include <ipxe/sha1.h>
30 #include <ipxe/hmac.h>
31 #include <ipxe/list.h>
32 #include <ipxe/ethernet.h>
33 #include <ipxe/rbg.h>
34 #include <stdlib.h>
35 #include <string.h>
36 #include <errno.h>
37 #include <byteswap.h>
38 
39 /** @file
40  *
41  * Handler for the aspects of WPA handshaking that are independent of
42  * 802.1X/PSK or TKIP/CCMP; this mostly involves the 4-Way Handshake.
43  */
44 
45 /** List of WPA contexts in active use. */
47 
48 
49 /**
50  * Return an error code and deauthenticate
51  *
52  * @v ctx WPA common context
53  * @v rc Return status code
54  * @ret rc The passed return status code
55  */
56 static int wpa_fail ( struct wpa_common_ctx *ctx, int rc )
57 {
58  net80211_deauthenticate ( ctx->dev, rc );
59  return rc;
60 }
61 
62 
63 /**
64  * Find a cryptosystem handler structure from a crypto ID
65  *
66  * @v crypt Cryptosystem ID
67  * @ret crypto Cryptosystem handler structure
68  *
69  * If support for @a crypt is not compiled in to iPXE, or if @a crypt
70  * is NET80211_CRYPT_UNKNOWN, returns @c NULL.
71  */
72 static struct net80211_crypto *
74 {
75  struct net80211_crypto *crypto;
76 
78  if ( crypto->algorithm == crypt )
79  return crypto;
80  }
81 
82  return NULL;
83 }
84 
85 
86 /**
87  * Find WPA key integrity and encryption handler from key version field
88  *
89  * @v ver Version bits of EAPOL-Key info field
90  * @ret kie Key integrity and encryption handler
91  */
92 struct wpa_kie * wpa_find_kie ( int version )
93 {
94  struct wpa_kie *kie;
95 
97  if ( kie->version == version )
98  return kie;
99  }
100 
101  return NULL;
102 }
103 
104 
105 /**
106  * Construct RSN or WPA information element
107  *
108  * @v dev 802.11 device
109  * @ret ie_ret RSN or WPA information element
110  * @ret rc Return status code
111  *
112  * This function allocates, fills, and returns a RSN or WPA
113  * information element suitable for including in an association
114  * request frame to the network identified by @c dev->associating.
115  * If it is impossible to construct an information element consistent
116  * with iPXE's capabilities that is compatible with that network, or
117  * if none should be sent because that network's beacon included no
118  * security information, returns an error indication and leaves
119  * @a ie_ret unchanged.
120  *
121  * The returned IE will be of the same type (RSN or WPA) as was
122  * included in the beacon for the network it is destined for.
123  */
124 int wpa_make_rsn_ie ( struct net80211_device *dev, union ieee80211_ie **ie_ret )
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 }
205 
206 
207 /**
208  * Set up generic WPA support to handle 4-Way Handshake
209  *
210  * @v dev 802.11 device
211  * @v ctx WPA common context
212  * @v pmk Pairwise Master Key to use for session
213  * @v pmk_len Length of PMK, almost always 32
214  * @ret rc Return status code
215  */
216 int wpa_start ( struct net80211_device *dev, struct wpa_common_ctx *ctx,
217  const void *pmk, size_t pmk_len )
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 }
253 
254 
255 /**
256  * Disable handling of received WPA handshake frames
257  *
258  * @v dev 802.11 device
259  */
260 void wpa_stop ( struct net80211_device *dev )
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 }
272 
273 
274 /**
275  * Derive pairwise transient key
276  *
277  * @v ctx WPA common context
278  */
279 static void wpa_derive_ptk ( struct wpa_common_ctx *ctx )
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 }
321 
322 
323 /**
324  * Install pairwise transient key
325  *
326  * @v ctx WPA common context
327  * @v len Key length (16 for CCMP, 32 for TKIP)
328  * @ret rc Return status code
329  */
330 static inline int wpa_install_ptk ( struct wpa_common_ctx *ctx, int len )
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 }
339 
340 /**
341  * Install group transient key
342  *
343  * @v ctx WPA common context
344  * @v len Key length (16 for CCMP, 32 for TKIP)
345  * @v rsc Receive sequence counter field in EAPOL-Key packet
346  * @ret rc Return status code
347  */
348 static inline int wpa_install_gtk ( struct wpa_common_ctx *ctx, int len,
349  const void *rsc )
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 }
358 
359 /**
360  * Search for group transient key, and install it if found
361  *
362  * @v ctx WPA common context
363  * @v ie Pointer to first IE in key data field
364  * @v ie_end Pointer to first byte not in key data field
365  * @v rsc Receive sequence counter field in EAPOL-Key packet
366  * @ret rc Return status code
367  */
369  union ieee80211_ie *ie, void *ie_end,
370  const void *rsc )
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 }
400 
401 
402 /**
403  * Allocate I/O buffer for construction of outgoing EAPOL-Key frame
404  *
405  * @v kdlen Maximum number of bytes in the Key Data field
406  * @ret iob Newly allocated I/O buffer
407  *
408  * The returned buffer will have space reserved for the link-layer and
409  * EAPOL headers, and will have @c iob->tail pointing to the start of
410  * the Key Data field. Thus, it is necessary to use iob_put() in
411  * filling the Key Data.
412  */
413 static struct io_buffer * wpa_alloc_frame ( int kdlen )
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 }
427 
428 
429 /**
430  * Send EAPOL-Key packet
431  *
432  * @v iob I/O buffer, with sufficient headroom for headers
433  * @v dev 802.11 device
434  * @v kie Key integrity and encryption handler
435  * @v is_rsn If TRUE, handshake uses new RSN format
436  * @ret rc Return status code
437  *
438  * If a KIE is specified, the MIC will be filled in before transmission.
439  */
440 static int wpa_send_eapol ( struct io_buffer *iob, struct wpa_common_ctx *ctx,
441  struct wpa_kie *kie )
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 }
463 
464 
465 /**
466  * Send second frame in 4-Way Handshake
467  *
468  * @v ctx WPA common context
469  * @v pkt First frame, to which this is a reply
470  * @v is_rsn If TRUE, handshake uses new RSN format
471  * @v kie Key integrity and encryption handler
472  * @ret rc Return status code
473  */
474 static int wpa_send_2_of_4 ( struct wpa_common_ctx *ctx,
475  struct eapol_key_pkt *pkt, int is_rsn,
476  struct wpa_kie *kie )
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 }
499 
500 
501 /**
502  * Handle receipt of first frame in 4-Way Handshake
503  *
504  * @v ctx WPA common context
505  * @v pkt EAPOL-Key packet
506  * @v is_rsn If TRUE, frame uses new RSN format
507  * @v kie Key integrity and encryption handler
508  * @ret rc Return status code
509  */
510 static int wpa_handle_1_of_4 ( struct wpa_common_ctx *ctx,
511  struct eapol_key_pkt *pkt, int is_rsn,
512  struct wpa_kie *kie )
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 }
531 
532 
533 /**
534  * Send fourth frame in 4-Way Handshake, or second in Group Key Handshake
535  *
536  * @v ctx WPA common context
537  * @v pkt EAPOL-Key packet for frame to which we're replying
538  * @v is_rsn If TRUE, frame uses new RSN format
539  * @v kie Key integrity and encryption handler
540  * @ret rc Return status code
541  */
542 static int wpa_send_final ( struct wpa_common_ctx *ctx,
543  struct eapol_key_pkt *pkt, int is_rsn,
544  struct wpa_kie *kie )
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 }
570 
571 
572 /**
573  * Handle receipt of third frame in 4-Way Handshake
574  *
575  * @v ctx WPA common context
576  * @v pkt EAPOL-Key packet
577  * @v is_rsn If TRUE, frame uses new RSN format
578  * @v kie Key integrity and encryption handler
579  * @ret rc Return status code
580  */
581 static int wpa_handle_3_of_4 ( struct wpa_common_ctx *ctx,
582  struct eapol_key_pkt *pkt, int is_rsn,
583  struct wpa_kie *kie )
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 }
689 
690 
691 /**
692  * Handle receipt of first frame in Group Key Handshake
693  *
694  * @v ctx WPA common context
695  * @v pkt EAPOL-Key packet
696  * @v is_rsn If TRUE, frame uses new RSN format
697  * @v kie Key integrity and encryption handler
698  * @ret rc Return status code
699  */
700 static int wpa_handle_1_of_2 ( struct wpa_common_ctx *ctx,
701  struct eapol_key_pkt *pkt, int is_rsn,
702  struct wpa_kie *kie )
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 }
757 
758 
759 /**
760  * Handle receipt of EAPOL-Key frame for WPA
761  *
762  * @v iob I/O buffer
763  * @v netdev Network device
764  * @v ll_dest Link-layer destination address
765  * @v ll_source Source link-layer address
766  */
767 static int eapol_key_rx ( struct io_buffer *iob, struct net_device *netdev,
768  const void *ll_dest __unused,
769  const void *ll_source )
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 }
908 
909 struct eapol_handler eapol_key_handler __eapol_handler = {
910  .type = EAPOL_TYPE_KEY,
911  .rx = eapol_key_rx,
912 };
913 
914 /* WPA always needs EAPOL in order to be useful */
915 REQUIRING_SYMBOL ( eapol_key_handler );
916 REQUIRE_OBJECT ( eapol );
u32 akm_list[1]
List of authentication type IDs for supported types.
Definition: ieee80211.h:821
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 __attribute__(x)
Definition: compiler.h:10
#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
Performing 4-Way Handshake.
Definition: wpa.h:184
struct net80211_device * dev
802.11 device we are authenticating for
Definition: wpa.h:294
Structure representing a probed network.
Definition: net80211.h:1056
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
enum net80211_crypto_alg crypto
Cryptographic algorithm used on the network.
Definition: net80211.h:1087
#define iob_put(iobuf, len)
Definition: iobuf.h:116
static union ieee80211_ie * ieee80211_next_ie(union ieee80211_ie *ie, void *end)
Advance to next 802.11 information element.
Definition: ieee80211.h:1028
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
An EAPOL frame.
Definition: eapol.h:63
#define EAPOL_KEY_INFO_KEY_ENC
Key Encrypted bit; set when the Key Data field is encrypted.
Definition: wpa.h:71
Error codes.
Dummy value used when the cryptosystem can't be detected.
Definition: net80211.h:177
u16 rsn_capab
Security capabilities field (RSN only)
Definition: ieee80211.h:824
#define iob_push(iobuf, len)
Definition: iobuf.h:80
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
void free_iob(struct io_buffer *iobuf)
Free I/O buffer.
Definition: iobuf.c:145
u32 oui
OUI and vendor-specific type byte.
Definition: ieee80211.h:955
enum net80211_security_proto handshaking
Security handshaking method used on the network.
Definition: net80211.h:1084
WPA handshake key integrity and encryption handler.
Definition: wpa.h:371
#define DBGC(...)
Definition: compiler.h:505
An 802.11 data or management frame without QoS or WDS header fields.
Definition: ieee80211.h:300
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
u16 length
Length of payload, in network byte order.
Definition: eapol.h:72
Cryptographic API.
union ieee80211_ie * rsn_ie
RSN or WPA information element to include with association.
Definition: net80211.h:932
struct wpa_gtk gtk
Encapsulated group transient key.
Definition: wpa.h:431
#define EACCES
Permission denied.
Definition: errno.h:298
#define ntohs(value)
Definition: byteswap.h:136
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
void net80211_deauthenticate(struct net80211_device *dev, int rc)
Deauthenticate from current network and try again.
Definition: net80211.c:2390
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
Ready for 4-Way Handshake.
Definition: wpa.h:181
#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
Definitions for general secured-network routines.
#define ENOTSUP
Operation not supported.
Definition: errno.h:589
A doubly-linked list entry (or list head)
Definition: list.h:18
#define EAPOL_KEY_TYPE_WPA
Old EAPOL-Key type field used by WPA1 hardware before 802.11i ratified.
Definition: wpa.h:38
u16 pmkid_count
Number of PMKIDs included (present only in association frames)
Definition: ieee80211.h:827
REQUIRE_OBJECT(eapol)
static int wpa_fail(struct wpa_common_ctx *ctx, int rc)
Return an error code and deauthenticate.
Definition: wpa.c:56
#define list_del(list)
Delete an entry from a list.
Definition: list.h:119
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 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
enum net80211_crypto_alg algorithm
The cryptographic algorithm implemented.
Definition: net80211.h:692
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
#define EAPOL_KEY_TYPE_GTK
Key type field value for a GTK (group) key handshake.
Definition: wpa.h:87
u32 version
Version number.
Definition: ath9k_hw.c:1983
Common definitions for all types of WPA-protected networks.
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
#define EAPOL_KEY_INFO_VERSION
Key descriptor version, indicating WPA or WPA2.
Definition: wpa.h:47
u8 rsc[8]
Receive sequence counter for GTK.
Definition: wpa.h:148
#define EAPOL_THIS_VERSION
Expected EAPOL version field value.
Definition: eapol.h:52
Ethernet protocol.
Keyed-Hashing for Message Authentication.
#define EAPOL_KEY_INFO_KEY_ACK
Key ACK bit; set when a response is required, on all messages except #4.
Definition: wpa.h:56
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
#define list_for_each_entry(pos, head, member)
Iterate over entries in a list.
Definition: list.h:420
#define list_add_tail(new, head)
Add a new entry to the tail of a list.
Definition: list.h:93
struct wpa_kie * wpa_find_kie(int version)
Find WPA key integrity and encryption handler from key version field.
Definition: wpa.c:92
#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
4-Way Handshake succeeded
Definition: wpa.h:187
static struct net_device * netdev
Definition: gdbudp.c:52
REQUIRING_SYMBOL(eapol_key_handler)
#define MAX_LL_HEADER_LEN
Maximum length of a link-layer header.
Definition: netdevice.h:45
#define NET80211_CRYPTOS
Definition: net80211.h:769
int version
Value of version bits in EAPOL-Key info field for which to use.
Definition: wpa.h:376
Common context for WPA security handshaking.
Definition: wpa.h:291
Definitions for EAPOL (Extensible Authentication Protocol over LANs) frames.
#define ieee80211_beacon
Definition: ieee80211.h:1069
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 WPA_NONCE_LEN
Length of a nonce.
Definition: wpa.h:204
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 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
#define EAPOL_KEY_TYPE_RSN
EAPOL-Key type field for modern 802.11i/RSN WPA packets.
Definition: wpa.h:35
RBG mechanism.
An EAPOL frame type handler.
Definition: eapol.h:85
Linked lists.
u16 akm_count
Number of authentication types supported.
Definition: ieee80211.h:818
int wpa_make_rsn_ie(struct net80211_device *dev, union ieee80211_ie **ie_ret)
Construct RSN or WPA information element.
Definition: wpa.c:124
#define IEEE80211_IE_VENDOR
Information element ID for Vendor Specific information element.
Definition: ieee80211.h:960
char * strerror(int errno)
Retrieve string representation of error number.
Definition: strerror.c:78
#define be64_to_cpu(value)
Definition: byteswap.h:117
static void(* free)(struct refcnt *refcnt))
Definition: refcnt.h:54
#define DBGC2_HD(...)
Definition: compiler.h:524
The iPXE 802.11 MAC layer.
u32 pairwise_cipher[1]
List of cipher IDs for supported unicast frame ciphers.
Definition: ieee80211.h:815
const char * eth_ntoa(const void *ll_addr)
Transcribe Ethernet address.
Definition: ethernet.c:175
Waiting for PMK to be set.
Definition: wpa.h:178
u8 version
EAPOL version identifier, always 1.
Definition: eapol.h:66
Structure encapsulating the complete state of an 802.11 device.
Definition: net80211.h:786
#define IEEE80211_IE_RSN
Information element ID for Robust Security Network information element.
Definition: ieee80211.h:834
uint8_t * tmp
Definition: entropy.h:156
#define WPA_KIES
Definition: wpa.h:407
void(* mic)(const void *kck, const void *msg, size_t len, void *mic)
Calculate MIC over message.
Definition: wpa.h:388
struct ieee80211_ie_vendor vendor
Vendor-specific.
Definition: ieee80211.h:1003
#define for_each_table_entry(pointer, table)
Iterate through all entries within a linker table.
Definition: tables.h:358
void wpa_stop(struct net80211_device *dev)
Disable handling of received WPA handshake frames.
Definition: wpa.c:260
A network device.
Definition: netdevice.h:348
FILE_LICENCE(GPL2_OR_LATER)
u8 type
EAPOL archetype identifier indicating format of payload.
Definition: eapol.h:69
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
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
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
u16 pairwise_count
Number of unicast ciphers supported.
Definition: ieee80211.h:812
struct wpa_kde_gtk_encap gtk_encap
For GTK-type KDEs, encapsulated GTK.
Definition: wpa.h:478
#define ETH_ALEN
Definition: if_ether.h:8
Any 802.11 information element.
Definition: ieee80211.h:972
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
void * malloc(size_t size)
Allocate memory.
Definition: malloc.c:583
struct net80211_device * net80211_get(struct net_device *netdev)
Get 802.11 device from wrapping network device.
Definition: net80211.c:624
u8 len
Information element data length.
Definition: ieee80211.h:977
struct net80211_wlan * associating
Network with which we are associating.
Definition: net80211.h:866
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.
Definition: wpa.c:216
uint32_t hdr
Message header.
Definition: intelvf.h:12
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
#define __unused
Declare a variable or data structure as unused.
Definition: compiler.h:573
u8 data[0]
Key data.
Definition: wpa.h:171
802.11 Robust Security Network ("WPA") information element
Definition: ieee80211.h:798
#define iob_reserve(iobuf, len)
Definition: iobuf.h:63
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
#define EAPOL_TYPE_KEY
EAPOL-Key packet.
Definition: eapol.h:43
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
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
uint32_t len
Length.
Definition: ena.h:14
#define DBGC2(...)
Definition: compiler.h:522
struct eapol_handler eapol_key_handler __eapol_handler
Definition: wpa.c:909
SHA-1 algorithm.
net80211_crypto_alg
An 802.11 data encryption algorithm.
Definition: net80211.h:129
void * data
Start of data.
Definition: iobuf.h:44
struct list_head list
List entry.
Definition: wpa.h:362
u8 iv[16]
Initialization vector.
Definition: wpa.h:139
u32 group_cipher
Cipher ID for the cipher used in multicast/broadcast frames.
Definition: ieee80211.h:24
u8 len
Length, not including ie_type and length fields.
Definition: wpa.h:470
#define cpu_to_be64(value)
Definition: byteswap.h:111
#define IEEE80211_RSN_VERSION
802.11 RSN IE: expected version number
Definition: ieee80211.h:873
Any key descriptor element type.
Definition: wpa.h:464
enum net80211_crypto_alg sec80211_rsn_get_net80211_crypt(u32 desc)
Determine net80211 cryptosystem number from RSN descriptor.
Definition: sec80211.c:508
#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
union @16 u
#define EAPOL_KEY_INFO_INSTALL
Key install bit; set on message 3 except when legacy hacks are used.
Definition: wpa.h:53
#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
#define LIST_HEAD_INIT(list)
Initialise a static list head.
Definition: list.h:30
Interface to an 802.11 cryptosystem.
Definition: net80211.h:689
struct io_buffer * beacon
The complete beacon or probe-response frame received.
Definition: net80211.h:1081
static struct io_buffer * wpa_alloc_frame(int kdlen)
Allocate I/O buffer for construction of outgoing EAPOL-Key frame.
Definition: wpa.c:413
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
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
String functions.
#define htons(value)
Definition: byteswap.h:135
uint8_t u8
Definition: stdint.h:19
uint32_t u32
Definition: stdint.h:23
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
static int wpa_install_gtk(struct wpa_common_ctx *ctx, int len, const void *rsc)
Install group transient key.
Definition: wpa.c:348
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
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
u8 type
EAPOL archetype identifier for payload this handler will handle.
Definition: eapol.h:88