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", ctx, eth_ntoa ( ptk_data.mac1 ) );
308  DBGC2 ( ctx, ", A2 %s\n", eth_ntoa ( ptk_data.mac2 ) );
309 
310  DBGC2 ( ctx, "WPA %p Nonce1, Nonce2:\n", ctx );
311  DBGC2_HD ( ctx, ptk_data.nonce1, WPA_NONCE_LEN );
312  DBGC2_HD ( ctx, ptk_data.nonce2, WPA_NONCE_LEN );
313 
314  prf_sha1 ( ctx->pmk, ctx->pmk_len,
315  "Pairwise key expansion",
316  &ptk_data, sizeof ( ptk_data ),
317  &ctx->ptk, sizeof ( ctx->ptk ) );
318 
319  DBGC2 ( ctx, "WPA %p PTK:\n", ctx );
320  DBGC2_HD ( ctx, &ctx->ptk, sizeof ( ctx->ptk ) );
321 }
322 
323 
324 /**
325  * Install pairwise transient key
326  *
327  * @v ctx WPA common context
328  * @v len Key length (16 for CCMP, 32 for TKIP)
329  * @ret rc Return status code
330  */
331 static inline int wpa_install_ptk ( struct wpa_common_ctx *ctx, int len )
332 {
333  DBGC ( ctx, "WPA %p: installing %d-byte pairwise transient key\n",
334  ctx, len );
335  DBGC2_HD ( ctx, &ctx->ptk.tk, len );
336 
337  return sec80211_install ( &ctx->dev->crypto, ctx->crypt,
338  &ctx->ptk.tk, len, NULL );
339 }
340 
341 /**
342  * Install group transient key
343  *
344  * @v ctx WPA common context
345  * @v len Key length (16 for CCMP, 32 for TKIP)
346  * @v rsc Receive sequence counter field in EAPOL-Key packet
347  * @ret rc Return status code
348  */
349 static inline int wpa_install_gtk ( struct wpa_common_ctx *ctx, int len,
350  const void *rsc )
351 {
352  DBGC ( ctx, "WPA %p: installing %d-byte group transient key\n",
353  ctx, len );
354  DBGC2_HD ( ctx, &ctx->gtk.tk, len );
355 
356  return sec80211_install ( &ctx->dev->gcrypto, ctx->gcrypt,
357  &ctx->gtk.tk, len, rsc );
358 }
359 
360 /**
361  * Search for group transient key, and install it if found
362  *
363  * @v ctx WPA common context
364  * @v ie Pointer to first IE in key data field
365  * @v ie_end Pointer to first byte not in key data field
366  * @v rsc Receive sequence counter field in EAPOL-Key packet
367  * @ret rc Return status code
368  */
370  union ieee80211_ie *ie, void *ie_end,
371  const void *rsc )
372 {
373  struct wpa_kde *kde;
374 
375  if ( ! ieee80211_ie_bound ( ie, ie_end ) )
376  return -ENOENT;
377 
378  while ( ie ) {
379  if ( ie->id == IEEE80211_IE_VENDOR &&
380  ie->vendor.oui == WPA_KDE_GTK )
381  break;
382 
383  ie = ieee80211_next_ie ( ie, ie_end );
384  }
385 
386  if ( ! ie )
387  return -ENOENT;
388 
389  if ( ie->len - 6u > sizeof ( ctx->gtk.tk ) ) {
390  DBGC ( ctx, "WPA %p: GTK KDE is too long (%d bytes, max %zd)\n",
391  ctx, ie->len - 4, sizeof ( ctx->gtk.tk ) );
392  return -EINVAL;
393  }
394 
395  /* XXX We ignore key ID for now. */
396  kde = ( struct wpa_kde * ) ie;
397  memcpy ( &ctx->gtk.tk, &kde->gtk_encap.gtk, kde->len - 6 );
398 
399  return wpa_install_gtk ( ctx, kde->len - 6, rsc );
400 }
401 
402 
403 /**
404  * Allocate I/O buffer for construction of outgoing EAPOL-Key frame
405  *
406  * @v kdlen Maximum number of bytes in the Key Data field
407  * @ret iob Newly allocated I/O buffer
408  *
409  * The returned buffer will have space reserved for the link-layer and
410  * EAPOL headers, and will have @c iob->tail pointing to the start of
411  * the Key Data field. Thus, it is necessary to use iob_put() in
412  * filling the Key Data.
413  */
414 static struct io_buffer * wpa_alloc_frame ( int kdlen )
415 {
416  struct io_buffer *ret = alloc_iob ( sizeof ( struct eapol_key_pkt ) +
417  kdlen +
418  sizeof ( struct eapol_header ) +
420  if ( ! ret )
421  return NULL;
422 
423  iob_reserve ( ret, MAX_LL_HEADER_LEN + sizeof ( struct eapol_header ) );
424  memset ( iob_put ( ret, sizeof ( struct eapol_key_pkt ) ), 0,
425  sizeof ( struct eapol_key_pkt ) );
426 
427  return ret;
428 }
429 
430 
431 /**
432  * Send EAPOL-Key packet
433  *
434  * @v iob I/O buffer, with sufficient headroom for headers
435  * @v dev 802.11 device
436  * @v kie Key integrity and encryption handler
437  * @v is_rsn If TRUE, handshake uses new RSN format
438  * @ret rc Return status code
439  *
440  * If a KIE is specified, the MIC will be filled in before transmission.
441  */
442 static int wpa_send_eapol ( struct io_buffer *iob, struct wpa_common_ctx *ctx,
443  struct wpa_kie *kie )
444 {
445  struct eapol_key_pkt *pkt = iob->data;
446  struct eapol_header *eapol = iob_push ( iob, sizeof ( *eapol ) );
447 
448  pkt->info = htons ( pkt->info );
449  pkt->keysize = htons ( pkt->keysize );
450  pkt->datalen = htons ( pkt->datalen );
451  pkt->replay = cpu_to_be64 ( pkt->replay );
452  eapol->version = EAPOL_VERSION_2001;
453  eapol->type = EAPOL_TYPE_KEY;
454  eapol->len = htons ( iob->tail - iob->data - sizeof ( *eapol ) );
455 
456  memset ( pkt->mic, 0, sizeof ( pkt->mic ) );
457  if ( kie )
458  kie->mic ( &ctx->ptk.kck, eapol, sizeof ( *eapol ) +
459  sizeof ( *pkt ) + ntohs ( pkt->datalen ),
460  pkt->mic );
461 
462  return net_tx ( iob, ctx->dev->netdev, &eapol_protocol,
463  ctx->dev->bssid, ctx->dev->netdev->ll_addr );
464 }
465 
466 
467 /**
468  * Send second frame in 4-Way Handshake
469  *
470  * @v ctx WPA common context
471  * @v pkt First frame, to which this is a reply
472  * @v is_rsn If TRUE, handshake uses new RSN format
473  * @v kie Key integrity and encryption handler
474  * @ret rc Return status code
475  */
476 static int wpa_send_2_of_4 ( struct wpa_common_ctx *ctx,
477  struct eapol_key_pkt *pkt, int is_rsn,
478  struct wpa_kie *kie )
479 {
480  struct io_buffer *iob = wpa_alloc_frame ( ctx->dev->rsn_ie->len + 2 );
481  struct eapol_key_pkt *npkt;
482 
483  if ( ! iob )
484  return -ENOMEM;
485 
486  npkt = iob->data;
487  memcpy ( npkt, pkt, sizeof ( *pkt ) );
488  npkt->info &= ~EAPOL_KEY_INFO_KEY_ACK;
489  npkt->info |= EAPOL_KEY_INFO_KEY_MIC;
490  if ( is_rsn )
491  npkt->keysize = 0;
492  memcpy ( npkt->nonce, ctx->Snonce, sizeof ( npkt->nonce ) );
493  npkt->datalen = ctx->dev->rsn_ie->len + 2;
494  memcpy ( iob_put ( iob, npkt->datalen ), ctx->dev->rsn_ie,
495  npkt->datalen );
496 
497  DBGC ( ctx, "WPA %p: sending 2/4\n", ctx );
498 
499  return wpa_send_eapol ( iob, ctx, kie );
500 }
501 
502 
503 /**
504  * Handle receipt of first frame in 4-Way Handshake
505  *
506  * @v ctx WPA common context
507  * @v pkt EAPOL-Key packet
508  * @v is_rsn If TRUE, frame uses new RSN format
509  * @v kie Key integrity and encryption handler
510  * @ret rc Return status code
511  */
512 static int wpa_handle_1_of_4 ( struct wpa_common_ctx *ctx,
513  struct eapol_key_pkt *pkt, int is_rsn,
514  struct wpa_kie *kie )
515 {
516  if ( ctx->state == WPA_WAITING )
517  return -EINVAL;
518 
519  ctx->state = WPA_WORKING;
520  memcpy ( ctx->Anonce, pkt->nonce, sizeof ( ctx->Anonce ) );
521  if ( ! ctx->have_Snonce ) {
522  rbg_generate ( NULL, 0, 0, ctx->Snonce,
523  sizeof ( ctx->Snonce ) );
524  ctx->have_Snonce = 1;
525  }
526 
527  DBGC ( ctx, "WPA %p: received 1/4, looks OK\n", ctx );
528 
529  wpa_derive_ptk ( ctx );
530 
531  return wpa_send_2_of_4 ( ctx, pkt, is_rsn, kie );
532 }
533 
534 
535 /**
536  * Send fourth frame in 4-Way Handshake, or second in Group Key Handshake
537  *
538  * @v ctx WPA common context
539  * @v pkt EAPOL-Key packet for frame to which we're replying
540  * @v is_rsn If TRUE, frame uses new RSN format
541  * @v kie Key integrity and encryption handler
542  * @ret rc Return status code
543  */
544 static int wpa_send_final ( struct wpa_common_ctx *ctx,
545  struct eapol_key_pkt *pkt, int is_rsn,
546  struct wpa_kie *kie )
547 {
548  struct io_buffer *iob = wpa_alloc_frame ( 0 );
549  struct eapol_key_pkt *npkt;
550 
551  if ( ! iob )
552  return -ENOMEM;
553 
554  npkt = iob->data;
555  memcpy ( npkt, pkt, sizeof ( *pkt ) );
558  if ( is_rsn )
559  npkt->keysize = 0;
560  memset ( npkt->nonce, 0, sizeof ( npkt->nonce ) );
561  memset ( npkt->iv, 0, sizeof ( npkt->iv ) );
562  npkt->datalen = 0;
563 
564  if ( npkt->info & EAPOL_KEY_INFO_TYPE )
565  DBGC ( ctx, "WPA %p: sending 4/4\n", ctx );
566  else
567  DBGC ( ctx, "WPA %p: sending 2/2\n", ctx );
568 
569  return wpa_send_eapol ( iob, ctx, kie );
570 
571 }
572 
573 
574 /**
575  * Handle receipt of third frame in 4-Way Handshake
576  *
577  * @v ctx WPA common context
578  * @v pkt EAPOL-Key packet
579  * @v is_rsn If TRUE, frame uses new RSN format
580  * @v kie Key integrity and encryption handler
581  * @ret rc Return status code
582  */
583 static int wpa_handle_3_of_4 ( struct wpa_common_ctx *ctx,
584  struct eapol_key_pkt *pkt, int is_rsn,
585  struct wpa_kie *kie )
586 {
587  int rc;
588  u8 *this_rsn, *this_rsn_end;
589  u8 *new_rsn, *new_rsn_end;
590  int this_is_rsn, new_is_rsn;
591 
592  if ( ctx->state == WPA_WAITING )
593  return -EINVAL;
594 
595  ctx->state = WPA_WORKING;
596 
597  /* Check nonce */
598  if ( memcmp ( ctx->Anonce, pkt->nonce, WPA_NONCE_LEN ) != 0 ) {
599  DBGC ( ctx, "WPA %p ALERT: nonce mismatch in 3/4\n", ctx );
600  return wpa_fail ( ctx, -EACCES );
601  }
602 
603  /* Check RSN IE */
604  this_rsn = sec80211_find_rsn ( ( union ieee80211_ie * ) pkt->data,
605  pkt->data + pkt->datalen,
606  &this_is_rsn, &this_rsn_end );
607  if ( this_rsn )
608  new_rsn = sec80211_find_rsn ( ( union ieee80211_ie * )
609  this_rsn_end,
610  pkt->data + pkt->datalen,
611  &new_is_rsn, &new_rsn_end );
612  else
613  new_rsn = NULL;
614 
615  if ( ! ctx->ap_rsn_ie || ! this_rsn ||
616  ctx->ap_rsn_ie_len != ( this_rsn_end - this_rsn ) ||
617  ctx->ap_rsn_is_rsn != this_is_rsn ||
618  memcmp ( ctx->ap_rsn_ie, this_rsn, ctx->ap_rsn_ie_len ) != 0 ) {
619  DBGC ( ctx, "WPA %p ALERT: RSN mismatch in 3/4\n", ctx );
620  DBGC2 ( ctx, "WPA %p RSNs (in 3/4, in beacon):\n", ctx );
621  DBGC2_HD ( ctx, this_rsn, this_rsn_end - this_rsn );
622  DBGC2_HD ( ctx, ctx->ap_rsn_ie, ctx->ap_rsn_ie_len );
623  return wpa_fail ( ctx, -EACCES );
624  }
625 
626  /* Don't switch if they just supplied both styles of IE
627  simultaneously; we need two RSN IEs or two WPA IEs to
628  switch ciphers. They'll be immediately consecutive because
629  of ordering guarantees. */
630  if ( new_rsn && this_is_rsn == new_is_rsn ) {
631  struct net80211_wlan *assoc = ctx->dev->associating;
632  DBGC ( ctx, "WPA %p: accommodating bait-and-switch tactics\n",
633  ctx );
634  DBGC2 ( ctx, "WPA %p RSNs (in 3/4+beacon, new in 3/4):\n",
635  ctx );
636  DBGC2_HD ( ctx, this_rsn, this_rsn_end - this_rsn );
637  DBGC2_HD ( ctx, new_rsn, new_rsn_end - new_rsn );
638 
639  if ( ( rc = sec80211_detect_ie ( new_is_rsn, new_rsn,
640  new_rsn_end,
641  &assoc->handshaking,
642  &assoc->crypto ) ) != 0 )
643  DBGC ( ctx, "WPA %p: bait-and-switch invalid, staying "
644  "with original request\n", ctx );
645  } else {
646  new_rsn = this_rsn;
647  new_is_rsn = this_is_rsn;
648  new_rsn_end = this_rsn_end;
649  }
650 
651  /* Grab group cryptosystem ID */
652  ctx->gcrypt = sec80211_rsn_get_net80211_crypt ( *( u32 * )
653  ( new_rsn + 2 ) );
654 
655  /* Check for a GTK, if info field is encrypted */
656  if ( pkt->info & EAPOL_KEY_INFO_KEY_ENC ) {
658  ( union ieee80211_ie * ) pkt->data,
659  pkt->data + pkt->datalen,
660  pkt->rsc );
661  if ( rc < 0 ) {
662  DBGC ( ctx, "WPA %p did not install GTK in 3/4: %s\n",
663  ctx, strerror ( rc ) );
664  if ( rc != -ENOENT )
665  return wpa_fail ( ctx, rc );
666  }
667  }
668 
669  DBGC ( ctx, "WPA %p: received 3/4, looks OK\n", ctx );
670 
671  /* Send final message */
672  rc = wpa_send_final ( ctx, pkt, is_rsn, kie );
673  if ( rc < 0 )
674  return wpa_fail ( ctx, rc );
675 
676  /* Install PTK */
677  rc = wpa_install_ptk ( ctx, pkt->keysize );
678  if ( rc < 0 ) {
679  DBGC ( ctx, "WPA %p failed to install PTK: %s\n", ctx,
680  strerror ( rc ) );
681  return wpa_fail ( ctx, rc );
682  }
683 
684  /* Mark us as needing a new Snonce if we rekey */
685  ctx->have_Snonce = 0;
686 
687  /* Done! */
688  ctx->state = WPA_SUCCESS;
689  return 0;
690 }
691 
692 
693 /**
694  * Handle receipt of first frame in Group Key Handshake
695  *
696  * @v ctx WPA common context
697  * @v pkt EAPOL-Key packet
698  * @v is_rsn If TRUE, frame uses new RSN format
699  * @v kie Key integrity and encryption handler
700  * @ret rc Return status code
701  */
702 static int wpa_handle_1_of_2 ( struct wpa_common_ctx *ctx,
703  struct eapol_key_pkt *pkt, int is_rsn,
704  struct wpa_kie *kie )
705 {
706  int rc;
707 
708  /*
709  * WPA and RSN do this completely differently.
710  *
711  * The idea of encoding the GTK (or PMKID, or various other
712  * things) into a KDE that looks like an information element
713  * is an RSN innovation; old WPA code never encapsulates
714  * things like that. If it looks like an info element, it
715  * really is (for the WPA IE check in frames 2/4 and 3/4). The
716  * "key data encrypted" bit in the info field is also specific
717  * to RSN.
718  *
719  * So from an old WPA host, 3/4 does not contain an
720  * encapsulated GTK. The first frame of the GK handshake
721  * contains it, encrypted, but without a KDE wrapper, and with
722  * the key ID field (which iPXE doesn't use) shoved away in
723  * the reserved bits in the info field, and the TxRx bit
724  * stealing the Install bit's spot.
725  */
726 
727  if ( is_rsn && ( pkt->info & EAPOL_KEY_INFO_KEY_ENC ) ) {
729  ( union ieee80211_ie * ) pkt->data,
730  pkt->data + pkt->datalen,
731  pkt->rsc );
732  if ( rc < 0 ) {
733  DBGC ( ctx, "WPA %p: failed to install GTK in 1/2: "
734  "%s\n", ctx, strerror ( rc ) );
735  return wpa_fail ( ctx, rc );
736  }
737  } else {
738  rc = kie->decrypt ( &ctx->ptk.kek, pkt->iv, pkt->data,
739  &pkt->datalen );
740  if ( rc < 0 ) {
741  DBGC ( ctx, "WPA %p: failed to decrypt GTK: %s\n",
742  ctx, strerror ( rc ) );
743  return rc; /* non-fatal */
744  }
745  if ( pkt->datalen > sizeof ( ctx->gtk.tk ) ) {
746  DBGC ( ctx, "WPA %p: too much GTK data (%d > %zd)\n",
747  ctx, pkt->datalen, sizeof ( ctx->gtk.tk ) );
748  return wpa_fail ( ctx, -EINVAL );
749  }
750 
751  memcpy ( &ctx->gtk.tk, pkt->data, pkt->datalen );
752  wpa_install_gtk ( ctx, pkt->datalen, pkt->rsc );
753  }
754 
755  DBGC ( ctx, "WPA %p: received 1/2, looks OK\n", ctx );
756 
757  return wpa_send_final ( ctx, pkt, is_rsn, kie );
758 }
759 
760 
761 /**
762  * Handle receipt of EAPOL-Key frame for WPA
763  *
764  * @v iob I/O buffer
765  * @v netdev Network device
766  * @v ll_source Source link-layer address
767  */
768 static int eapol_key_rx ( struct io_buffer *iob, struct net_device *netdev,
769  const void *ll_source )
770 {
771  struct net80211_device *dev = net80211_get ( netdev );
772  struct eapol_header *eapol;
773  struct eapol_key_pkt *pkt;
774  int is_rsn, found_ctx;
775  struct wpa_common_ctx *ctx;
776  int rc = 0;
777  struct wpa_kie *kie;
778  u8 their_mic[16], our_mic[16];
779 
780  eapol = iob->data;
781  pkt = ( ( ( void * ) eapol ) + sizeof ( *eapol ) );
782 
783  if ( pkt->type != EAPOL_KEY_TYPE_WPA &&
784  pkt->type != EAPOL_KEY_TYPE_RSN ) {
785  DBG ( "EAPOL-Key: packet not of 802.11 type\n" );
786  rc = -EINVAL;
787  goto drop;
788  }
789 
790  is_rsn = ( pkt->type == EAPOL_KEY_TYPE_RSN );
791 
792  if ( ! dev ) {
793  DBG ( "EAPOL-Key: packet not from 802.11\n" );
794  rc = -EINVAL;
795  goto drop;
796  }
797 
798  if ( memcmp ( dev->bssid, ll_source, ETH_ALEN ) != 0 ) {
799  DBG ( "EAPOL-Key: packet not from associated AP\n" );
800  rc = -EINVAL;
801  goto drop;
802  }
803 
804  if ( ! ( ntohs ( pkt->info ) & EAPOL_KEY_INFO_KEY_ACK ) ) {
805  DBG ( "EAPOL-Key: packet sent in wrong direction\n" );
806  rc = -EINVAL;
807  goto drop;
808  }
809 
810  found_ctx = 0;
811  list_for_each_entry ( ctx, &wpa_contexts, list ) {
812  if ( ctx->dev == dev ) {
813  found_ctx = 1;
814  break;
815  }
816  }
817 
818  if ( ! found_ctx ) {
819  DBG ( "EAPOL-Key: no WPA context to handle packet for %p\n",
820  dev );
821  rc = -ENOENT;
822  goto drop;
823  }
824 
825  if ( ( void * ) ( pkt + 1 ) + ntohs ( pkt->datalen ) > iob->tail ) {
826  DBGC ( ctx, "WPA %p: packet truncated (has %zd extra bytes, "
827  "states %d)\n", ctx, iob->tail - ( void * ) ( pkt + 1 ),
828  ntohs ( pkt->datalen ) );
829  rc = -EINVAL;
830  goto drop;
831  }
832 
833  /* Get a handle on key integrity/encryption handler */
834  kie = wpa_find_kie ( ntohs ( pkt->info ) & EAPOL_KEY_INFO_VERSION );
835  if ( ! kie ) {
836  DBGC ( ctx, "WPA %p: no support for packet version %d\n", ctx,
837  ntohs ( pkt->info ) & EAPOL_KEY_INFO_VERSION );
838  rc = wpa_fail ( ctx, -ENOTSUP );
839  goto drop;
840  }
841 
842  /* Check MIC */
843  if ( ntohs ( pkt->info ) & EAPOL_KEY_INFO_KEY_MIC ) {
844  memcpy ( their_mic, pkt->mic, sizeof ( pkt->mic ) );
845  memset ( pkt->mic, 0, sizeof ( pkt->mic ) );
846  kie->mic ( &ctx->ptk.kck, eapol,
847  sizeof ( *eapol ) + sizeof ( *pkt ) +
848  ntohs ( pkt->datalen ), our_mic );
849  DBGC2 ( ctx, "WPA %p MIC comparison (theirs, ours):\n", ctx );
850  DBGC2_HD ( ctx, their_mic, 16 );
851  DBGC2_HD ( ctx, our_mic, 16 );
852  if ( memcmp ( their_mic, our_mic, sizeof ( pkt->mic ) ) != 0 ) {
853  DBGC ( ctx, "WPA %p: EAPOL MIC failure\n", ctx );
854  goto drop;
855  }
856  }
857 
858  /* Fix byte order to local */
859  pkt->info = ntohs ( pkt->info );
860  pkt->keysize = ntohs ( pkt->keysize );
861  pkt->datalen = ntohs ( pkt->datalen );
862  pkt->replay = be64_to_cpu ( pkt->replay );
863 
864  /* Check replay counter */
865  if ( ctx->replay != ~0ULL && ctx->replay >= pkt->replay ) {
866  DBGC ( ctx, "WPA %p ALERT: Replay detected! "
867  "(%08x:%08x >= %08x:%08x)\n", ctx,
868  ( u32 ) ( ctx->replay >> 32 ), ( u32 ) ctx->replay,
869  ( u32 ) ( pkt->replay >> 32 ), ( u32 ) pkt->replay );
870  rc = 0; /* ignore without error */
871  goto drop;
872  }
873  ctx->replay = pkt->replay;
874 
875  /* Decrypt key data */
876  if ( pkt->info & EAPOL_KEY_INFO_KEY_ENC ) {
877  rc = kie->decrypt ( &ctx->ptk.kek, pkt->iv, pkt->data,
878  &pkt->datalen );
879  if ( rc < 0 ) {
880  DBGC ( ctx, "WPA %p: failed to decrypt packet: %s\n",
881  ctx, strerror ( rc ) );
882  goto drop;
883  }
884  }
885 
886  /* Hand it off to appropriate handler */
887  switch ( pkt->info & ( EAPOL_KEY_INFO_TYPE |
889  case EAPOL_KEY_TYPE_PTK:
890  rc = wpa_handle_1_of_4 ( ctx, pkt, is_rsn, kie );
891  break;
892 
894  rc = wpa_handle_3_of_4 ( ctx, pkt, is_rsn, kie );
895  break;
896 
898  rc = wpa_handle_1_of_2 ( ctx, pkt, is_rsn, kie );
899  break;
900 
901  default:
902  DBGC ( ctx, "WPA %p: Invalid combination of key flags %04x\n",
903  ctx, pkt->info );
904  rc = -EINVAL;
905  break;
906  }
907 
908  drop:
909  free_iob ( iob );
910  return rc;
911 }
912 
913 struct eapol_handler eapol_key_handler __eapol_handler = {
914  .type = EAPOL_TYPE_KEY,
915  .rx = eapol_key_rx,
916 };
917 
918 /* WPA always needs EAPOL in order to be useful */
919 REQUIRING_SYMBOL ( eapol_key_handler );
920 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:583
#define __attribute__(x)
Definition: compiler.h:10
uint16_t len
Payload length.
Definition: eapol.h:23
#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:442
enum net80211_crypto_alg crypto
Cryptographic algorithm used on the network.
Definition: net80211.h:1087
#define iob_put(iobuf, len)
Definition: iobuf.h:120
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
#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
struct golan_inbox_hdr hdr
Message header.
Definition: CIB_PRM.h:28
u16 rsn_capab
Security capabilities field (RSN only)
Definition: ieee80211.h:824
#define iob_push(iobuf, len)
Definition: iobuf.h:84
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:146
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:331
#define ENOENT
No such file or directory.
Definition: errno.h:514
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:512
Ready for 4-Way Handshake.
Definition: wpa.h:181
struct io_buffer * alloc_iob(size_t len)
Allocate I/O buffer.
Definition: iobuf.c:129
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:50
#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.
EAPoL header.
Definition: eapol.h:17
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
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:476
#define list_for_each_entry(pos, head, member)
Iterate over entries in a list.
Definition: list.h:420
#define EAPOL_TYPE_KEY
EAPoL key.
Definition: eapol.h:33
#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
Extensible Authentication Protocol over LAN (EAPoL)
#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 handler.
Definition: eapol.h:36
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
Structure encapsulating the complete state of an 802.11 device.
Definition: net80211.h:786
#define EAPOL_VERSION_2001
802.1X-2001
Definition: eapol.h:27
#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:385
void wpa_stop(struct net80211_device *dev)
Disable handling of received WPA handshake frames.
Definition: wpa.c:260
A network device.
Definition: netdevice.h:352
FILE_LICENCE(GPL2_OR_LATER)
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:702
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:369
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
uint8_t type
Type.
Definition: eapol.h:21
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
802.11 Robust Security Network ("WPA") information element
Definition: ieee80211.h:798
#define iob_reserve(iobuf, len)
Definition: iobuf.h:67
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
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:1054
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:913
SHA-1 algorithm.
net80211_crypto_alg
An 802.11 data encryption algorithm.
Definition: net80211.h:129
void * data
Start of data.
Definition: iobuf.h:48
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
uint8_t version
Version.
Definition: eapol.h:19
static int eapol_key_rx(struct io_buffer *iob, struct net_device *netdev, const void *ll_source)
Handle receipt of EAPOL-Key frame for WPA.
Definition: wpa.c:768
u8 len
Length, not including ie_type and length fields.
Definition: wpa.h:470
union @17 u
#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
#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:414
int memcmp(const void *first, const void *second, size_t len)
Compare memory regions.
Definition: string.c:114
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
uint8_t type
Type.
Definition: eapol.h:38
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 wpa_install_gtk(struct wpa_common_ctx *ctx, int len, const void *rsc)
Install group transient key.
Definition: wpa.c:349
void * memset(void *dest, int character, size_t len) __nonnull
A persistent I/O buffer.
Definition: iobuf.h:33
#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:544