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
20FILE_LICENCE ( GPL2_OR_LATER );
21FILE_SECBOOT ( FORBIDDEN );
22
23#include <ipxe/net80211.h>
24#include <ipxe/sec80211.h>
25#include <ipxe/wpa.h>
26#include <ipxe/eapol.h>
27#include <ipxe/crypto.h>
28#include <ipxe/arc4.h>
29#include <ipxe/crc32.h>
30#include <ipxe/sha1.h>
31#include <ipxe/hmac.h>
32#include <ipxe/list.h>
33#include <ipxe/ethernet.h>
34#include <ipxe/rbg.h>
35#include <stdlib.h>
36#include <string.h>
37#include <errno.h>
38#include <byteswap.h>
39
40/** @file
41 *
42 * Handler for the aspects of WPA handshaking that are independent of
43 * 802.1X/PSK or TKIP/CCMP; this mostly involves the 4-Way Handshake.
44 */
45
46/** List of WPA contexts in active use. */
48
49
50/**
51 * Return an error code and deauthenticate
52 *
53 * @v ctx WPA common context
54 * @v rc Return status code
55 * @ret rc The passed return status code
56 */
57static int wpa_fail ( struct wpa_common_ctx *ctx, int rc )
58{
60 return rc;
61}
62
63
64/**
65 * Find a cryptosystem handler structure from a crypto ID
66 *
67 * @v crypt Cryptosystem ID
68 * @ret crypto Cryptosystem handler structure
69 *
70 * If support for @a crypt is not compiled in to iPXE, or if @a crypt
71 * is NET80211_CRYPT_UNKNOWN, returns @c NULL.
72 */
73static struct net80211_crypto *
75{
76 struct net80211_crypto *crypto;
77
79 if ( crypto->algorithm == crypt )
80 return crypto;
81 }
82
83 return NULL;
84}
85
86
87/**
88 * Find WPA key integrity and encryption handler from key version field
89 *
90 * @v ver Version bits of EAPOL-Key info field
91 * @ret kie Key integrity and encryption handler
92 */
94{
95 struct wpa_kie *kie;
96
98 if ( kie->version == version )
99 return kie;
100 }
101
102 return NULL;
103}
104
105
106/**
107 * Construct RSN or WPA information element
108 *
109 * @v dev 802.11 device
110 * @ret ie_ret RSN or WPA information element
111 * @ret rc Return status code
112 *
113 * This function allocates, fills, and returns a RSN or WPA
114 * information element suitable for including in an association
115 * request frame to the network identified by @c dev->associating.
116 * If it is impossible to construct an information element consistent
117 * with iPXE's capabilities that is compatible with that network, or
118 * if none should be sent because that network's beacon included no
119 * security information, returns an error indication and leaves
120 * @a ie_ret unchanged.
121 *
122 * The returned IE will be of the same type (RSN or WPA) as was
123 * included in the beacon for the network it is destined for.
124 */
125int wpa_make_rsn_ie ( struct net80211_device *dev, union ieee80211_ie **ie_ret )
126{
127 u8 *rsn, *rsn_end;
128 int is_rsn;
130 enum net80211_crypto_alg gcrypt;
131 int ie_len;
132 u8 *iep;
133 struct ieee80211_ie_rsn *ie;
134 struct ieee80211_frame *hdr;
135 struct ieee80211_beacon *beacon;
136
137 if ( ! dev->associating ) {
138 DBG ( "WPA: Can't make RSN IE for a non-associating device\n" );
139 return -EINVAL;
140 }
141
142 hdr = dev->associating->beacon->data;
143 beacon = ( struct ieee80211_beacon * ) hdr->data;
144 rsn = sec80211_find_rsn ( beacon->info_element,
145 dev->associating->beacon->tail, &is_rsn,
146 &rsn_end );
147 if ( ! rsn ) {
148 DBG ( "WPA: Can't make RSN IE when we didn't get one\n" );
149 return -EINVAL;
150 }
151
152 rsn += 2; /* skip version */
153 group_cipher = *( u32 * ) rsn;
155
156 if ( ! wpa_find_cryptosystem ( gcrypt ) ||
158 DBG ( "WPA: No support for (GC:%d, PC:%d)\n",
159 gcrypt, dev->associating->crypto );
160 return -ENOTSUP;
161 }
162
163 /* Everything looks good - make our IE. */
164
165 /* WPA IEs need 4 more bytes for the OUI+type */
166 ie_len = ieee80211_rsn_size ( 1, 1, 0, is_rsn ) + ( 4 * ! is_rsn );
167 iep = malloc ( ie_len );
168 if ( ! iep )
169 return -ENOMEM;
170
171 *ie_ret = ( union ieee80211_ie * ) iep;
172
173 /* Store ID and length bytes. */
174 *iep++ = ( is_rsn ? IEEE80211_IE_RSN : IEEE80211_IE_VENDOR );
175 *iep++ = ie_len - 2;
176
177 /* Store OUI+type for WPA IEs. */
178 if ( ! is_rsn ) {
179 *( u32 * ) iep = IEEE80211_WPA_OUI_VEN;
180 iep += 4;
181 }
182
183 /* If this is a WPA IE, the id and len bytes in the
184 ieee80211_ie_rsn structure will not be valid, but by doing
185 the cast we can fill all the other fields much more
186 readily. */
187
188 ie = ( struct ieee80211_ie_rsn * ) ( iep - 2 );
191 ie->pairwise_count = 1;
192 ie->pairwise_cipher[0] =
194 is_rsn );
195 ie->akm_count = 1;
196 ie->akm_list[0] =
198 is_rsn );
199 if ( is_rsn ) {
200 ie->rsn_capab = 0;
201 ie->pmkid_count = 0;
202 }
203
204 return 0;
205}
206
207
208/**
209 * Set up generic WPA support to handle 4-Way Handshake
210 *
211 * @v dev 802.11 device
212 * @v ctx WPA common context
213 * @v pmk Pairwise Master Key to use for session
214 * @v pmk_len Length of PMK, almost always 32
215 * @ret rc Return status code
216 */
217int wpa_start ( struct net80211_device *dev, struct wpa_common_ctx *ctx,
218 const void *pmk, size_t pmk_len )
219{
220 struct io_buffer *iob;
221 struct ieee80211_frame *hdr;
222 struct ieee80211_beacon *beacon;
223 u8 *ap_rsn_ie = NULL, *ap_rsn_ie_end;
224
225 if ( ! dev->rsn_ie || ! dev->associating )
226 return -EINVAL;
227
228 ctx->dev = dev;
229 memcpy ( ctx->pmk, pmk, ctx->pmk_len = pmk_len );
230 ctx->state = WPA_READY;
231 ctx->replay = ~0ULL;
232
233 iob = dev->associating->beacon;
234 hdr = iob->data;
235 beacon = ( struct ieee80211_beacon * ) hdr->data;
236 ap_rsn_ie = sec80211_find_rsn ( beacon->info_element, iob->tail,
237 &ctx->ap_rsn_is_rsn, &ap_rsn_ie_end );
238 if ( ap_rsn_ie ) {
239 ctx->ap_rsn_ie = malloc ( ap_rsn_ie_end - ap_rsn_ie );
240 if ( ! ctx->ap_rsn_ie )
241 return -ENOMEM;
242 memcpy ( ctx->ap_rsn_ie, ap_rsn_ie, ap_rsn_ie_end - ap_rsn_ie );
243 ctx->ap_rsn_ie_len = ap_rsn_ie_end - ap_rsn_ie;
244 } else {
245 return -ENOENT;
246 }
247
248 ctx->crypt = dev->associating->crypto;
249 ctx->gcrypt = NET80211_CRYPT_UNKNOWN;
250
251 list_add_tail ( &ctx->list, &wpa_contexts );
252 return 0;
253}
254
255
256/**
257 * Disable handling of received WPA handshake frames
258 *
259 * @v dev 802.11 device
260 */
261void wpa_stop ( struct net80211_device *dev )
262{
263 struct wpa_common_ctx *ctx, *tmp;
264
266 if ( ctx->dev == dev ) {
267 free ( ctx->ap_rsn_ie );
268 ctx->ap_rsn_ie = NULL;
269 list_del ( &ctx->list );
270 }
271 }
272}
273
274
275/**
276 * Derive pairwise transient key
277 *
278 * @v ctx WPA common context
279 */
280static void wpa_derive_ptk ( struct wpa_common_ctx *ctx )
281{
282 struct {
283 u8 mac1[ETH_ALEN];
284 u8 mac2[ETH_ALEN];
285 u8 nonce1[WPA_NONCE_LEN];
286 u8 nonce2[WPA_NONCE_LEN];
287 } __attribute__ (( packed )) ptk_data;
288
289 /* The addresses and nonces are stored in numerical order (!) */
290
291 if ( memcmp ( ctx->dev->netdev->ll_addr, ctx->dev->bssid,
292 ETH_ALEN ) < 0 ) {
293 memcpy ( ptk_data.mac1, ctx->dev->netdev->ll_addr, ETH_ALEN );
294 memcpy ( ptk_data.mac2, ctx->dev->bssid, ETH_ALEN );
295 } else {
296 memcpy ( ptk_data.mac1, ctx->dev->bssid, ETH_ALEN );
297 memcpy ( ptk_data.mac2, ctx->dev->netdev->ll_addr, ETH_ALEN );
298 }
299
300 if ( memcmp ( ctx->Anonce, ctx->Snonce, WPA_NONCE_LEN ) < 0 ) {
301 memcpy ( ptk_data.nonce1, ctx->Anonce, WPA_NONCE_LEN );
302 memcpy ( ptk_data.nonce2, ctx->Snonce, WPA_NONCE_LEN );
303 } else {
304 memcpy ( ptk_data.nonce1, ctx->Snonce, WPA_NONCE_LEN );
305 memcpy ( ptk_data.nonce2, ctx->Anonce, WPA_NONCE_LEN );
306 }
307
308 DBGC2 ( ctx, "WPA %p A1 %s", ctx, eth_ntoa ( ptk_data.mac1 ) );
309 DBGC2 ( ctx, ", A2 %s\n", eth_ntoa ( ptk_data.mac2 ) );
310
311 DBGC2 ( ctx, "WPA %p Nonce1, Nonce2:\n", ctx );
312 DBGC2_HD ( ctx, ptk_data.nonce1, WPA_NONCE_LEN );
313 DBGC2_HD ( ctx, ptk_data.nonce2, WPA_NONCE_LEN );
314
315 prf_sha1 ( ctx->pmk, ctx->pmk_len,
316 "Pairwise key expansion",
317 &ptk_data, sizeof ( ptk_data ),
318 &ctx->ptk, sizeof ( ctx->ptk ) );
319
320 DBGC2 ( ctx, "WPA %p PTK:\n", ctx );
321 DBGC2_HD ( ctx, &ctx->ptk, sizeof ( ctx->ptk ) );
322}
323
324
325/**
326 * Install pairwise transient key
327 *
328 * @v ctx WPA common context
329 * @v len Key length (16 for CCMP, 32 for TKIP)
330 * @ret rc Return status code
331 */
332static inline int wpa_install_ptk ( struct wpa_common_ctx *ctx, int len )
333{
334 DBGC ( ctx, "WPA %p: installing %d-byte pairwise transient key\n",
335 ctx, len );
336 DBGC2_HD ( ctx, &ctx->ptk.tk, len );
337
338 return sec80211_install ( &ctx->dev->crypto, ctx->crypt,
339 &ctx->ptk.tk, len, NULL );
340}
341
342/**
343 * Install group transient key
344 *
345 * @v ctx WPA common context
346 * @v len Key length (16 for CCMP, 32 for TKIP)
347 * @v rsc Receive sequence counter field in EAPOL-Key packet
348 * @ret rc Return status code
349 */
350static inline int wpa_install_gtk ( struct wpa_common_ctx *ctx, int len,
351 const void *rsc )
352{
353 DBGC ( ctx, "WPA %p: installing %d-byte group transient key\n",
354 ctx, len );
355 DBGC2_HD ( ctx, &ctx->gtk.tk, len );
356
357 return sec80211_install ( &ctx->dev->gcrypto, ctx->gcrypt,
358 &ctx->gtk.tk, len, rsc );
359}
360
361/**
362 * Search for group transient key, and install it if found
363 *
364 * @v ctx WPA common context
365 * @v ie Pointer to first IE in key data field
366 * @v ie_end Pointer to first byte not in key data field
367 * @v rsc Receive sequence counter field in EAPOL-Key packet
368 * @ret rc Return status code
369 */
371 union ieee80211_ie *ie, void *ie_end,
372 const void *rsc )
373{
374 struct wpa_kde *kde;
375
376 if ( ! ieee80211_ie_bound ( ie, ie_end ) )
377 return -ENOENT;
378
379 while ( ie ) {
380 if ( ie->id == IEEE80211_IE_VENDOR &&
381 ie->vendor.oui == WPA_KDE_GTK )
382 break;
383
384 ie = ieee80211_next_ie ( ie, ie_end );
385 }
386
387 if ( ! ie )
388 return -ENOENT;
389
390 if ( ie->len - 6u > sizeof ( ctx->gtk.tk ) ) {
391 DBGC ( ctx, "WPA %p: GTK KDE is too long (%d bytes, max %zd)\n",
392 ctx, ie->len - 4, sizeof ( ctx->gtk.tk ) );
393 return -EINVAL;
394 }
395
396 /* XXX We ignore key ID for now. */
397 kde = ( struct wpa_kde * ) ie;
398 memcpy ( &ctx->gtk.tk, &kde->gtk_encap.gtk, kde->len - 6 );
399
400 return wpa_install_gtk ( ctx, kde->len - 6, rsc );
401}
402
403
404/**
405 * Allocate I/O buffer for construction of outgoing EAPOL-Key frame
406 *
407 * @v kdlen Maximum number of bytes in the Key Data field
408 * @ret iob Newly allocated I/O buffer
409 *
410 * The returned buffer will have space reserved for the link-layer and
411 * EAPOL headers, and will have @c iob->tail pointing to the start of
412 * the Key Data field. Thus, it is necessary to use iob_put() in
413 * filling the Key Data.
414 */
415static struct io_buffer * wpa_alloc_frame ( int kdlen )
416{
417 struct io_buffer *ret = alloc_iob ( sizeof ( struct eapol_key_pkt ) +
418 kdlen +
419 sizeof ( struct eapol_header ) +
421 if ( ! ret )
422 return NULL;
423
424 iob_reserve ( ret, MAX_LL_HEADER_LEN + sizeof ( struct eapol_header ) );
425 memset ( iob_put ( ret, sizeof ( struct eapol_key_pkt ) ), 0,
426 sizeof ( struct eapol_key_pkt ) );
427
428 return ret;
429}
430
431
432/**
433 * Send EAPOL-Key packet
434 *
435 * @v iob I/O buffer, with sufficient headroom for headers
436 * @v dev 802.11 device
437 * @v kie Key integrity and encryption handler
438 * @v is_rsn If TRUE, handshake uses new RSN format
439 * @ret rc Return status code
440 *
441 * If a KIE is specified, the MIC will be filled in before transmission.
442 */
443static int wpa_send_eapol ( struct io_buffer *iob, struct wpa_common_ctx *ctx,
444 struct wpa_kie *kie )
445{
446 struct eapol_key_pkt *pkt = iob->data;
447 struct eapol_header *eapol = iob_push ( iob, sizeof ( *eapol ) );
448
449 pkt->info = htons ( pkt->info );
450 pkt->keysize = htons ( pkt->keysize );
451 pkt->datalen = htons ( pkt->datalen );
452 pkt->replay = cpu_to_be64 ( pkt->replay );
454 eapol->type = EAPOL_TYPE_KEY;
455 eapol->len = htons ( iob->tail - iob->data - sizeof ( *eapol ) );
456
457 memset ( pkt->mic, 0, sizeof ( pkt->mic ) );
458 if ( kie )
459 kie->mic ( &ctx->ptk.kck, eapol, sizeof ( *eapol ) +
460 sizeof ( *pkt ) + ntohs ( pkt->datalen ),
461 pkt->mic );
462
463 return net_tx ( iob, ctx->dev->netdev, &eapol_protocol,
464 ctx->dev->bssid, ctx->dev->netdev->ll_addr );
465}
466
467
468/**
469 * Send second frame in 4-Way Handshake
470 *
471 * @v ctx WPA common context
472 * @v pkt First frame, to which this is a reply
473 * @v is_rsn If TRUE, handshake uses new RSN format
474 * @v kie Key integrity and encryption handler
475 * @ret rc Return status code
476 */
477static int wpa_send_2_of_4 ( struct wpa_common_ctx *ctx,
478 struct eapol_key_pkt *pkt, int is_rsn,
479 struct wpa_kie *kie )
480{
481 struct io_buffer *iob = wpa_alloc_frame ( ctx->dev->rsn_ie->len + 2 );
482 struct eapol_key_pkt *npkt;
483
484 if ( ! iob )
485 return -ENOMEM;
486
487 npkt = iob->data;
488 memcpy ( npkt, pkt, sizeof ( *pkt ) );
491 if ( is_rsn )
492 npkt->keysize = 0;
493 memcpy ( npkt->nonce, ctx->Snonce, sizeof ( npkt->nonce ) );
494 npkt->datalen = ctx->dev->rsn_ie->len + 2;
495 memcpy ( iob_put ( iob, npkt->datalen ), ctx->dev->rsn_ie,
496 npkt->datalen );
497
498 DBGC ( ctx, "WPA %p: sending 2/4\n", ctx );
499
500 return wpa_send_eapol ( iob, ctx, kie );
501}
502
503
504/**
505 * Handle receipt of first frame in 4-Way Handshake
506 *
507 * @v ctx WPA common context
508 * @v pkt EAPOL-Key packet
509 * @v is_rsn If TRUE, frame uses new RSN format
510 * @v kie Key integrity and encryption handler
511 * @ret rc Return status code
512 */
514 struct eapol_key_pkt *pkt, int is_rsn,
515 struct wpa_kie *kie )
516{
517 if ( ctx->state == WPA_WAITING )
518 return -EINVAL;
519
520 ctx->state = WPA_WORKING;
521 memcpy ( ctx->Anonce, pkt->nonce, sizeof ( ctx->Anonce ) );
522 if ( ! ctx->have_Snonce ) {
523 rbg_generate ( NULL, 0, 0, ctx->Snonce,
524 sizeof ( ctx->Snonce ) );
525 ctx->have_Snonce = 1;
526 }
527
528 DBGC ( ctx, "WPA %p: received 1/4, looks OK\n", ctx );
529
531
532 return wpa_send_2_of_4 ( ctx, pkt, is_rsn, kie );
533}
534
535
536/**
537 * Send fourth frame in 4-Way Handshake, or second in Group Key Handshake
538 *
539 * @v ctx WPA common context
540 * @v pkt EAPOL-Key packet for frame to which we're replying
541 * @v is_rsn If TRUE, frame uses new RSN format
542 * @v kie Key integrity and encryption handler
543 * @ret rc Return status code
544 */
545static int wpa_send_final ( struct wpa_common_ctx *ctx,
546 struct eapol_key_pkt *pkt, int is_rsn,
547 struct wpa_kie *kie )
548{
549 struct io_buffer *iob = wpa_alloc_frame ( 0 );
550 struct eapol_key_pkt *npkt;
551
552 if ( ! iob )
553 return -ENOMEM;
554
555 npkt = iob->data;
556 memcpy ( npkt, pkt, sizeof ( *pkt ) );
559 if ( is_rsn )
560 npkt->keysize = 0;
561 memset ( npkt->nonce, 0, sizeof ( npkt->nonce ) );
562 memset ( npkt->iv, 0, sizeof ( npkt->iv ) );
563 npkt->datalen = 0;
564
565 if ( npkt->info & EAPOL_KEY_INFO_TYPE )
566 DBGC ( ctx, "WPA %p: sending 4/4\n", ctx );
567 else
568 DBGC ( ctx, "WPA %p: sending 2/2\n", ctx );
569
570 return wpa_send_eapol ( iob, ctx, kie );
571
572}
573
574
575/**
576 * Handle receipt of third frame in 4-Way Handshake
577 *
578 * @v ctx WPA common context
579 * @v pkt EAPOL-Key packet
580 * @v is_rsn If TRUE, frame uses new RSN format
581 * @v kie Key integrity and encryption handler
582 * @ret rc Return status code
583 */
585 struct eapol_key_pkt *pkt, int is_rsn,
586 struct wpa_kie *kie )
587{
588 int rc;
589 u8 *this_rsn, *this_rsn_end;
590 u8 *new_rsn, *new_rsn_end;
591 int this_is_rsn, new_is_rsn;
592
593 if ( ctx->state == WPA_WAITING )
594 return -EINVAL;
595
596 ctx->state = WPA_WORKING;
597
598 /* Check nonce */
599 if ( memcmp ( ctx->Anonce, pkt->nonce, WPA_NONCE_LEN ) != 0 ) {
600 DBGC ( ctx, "WPA %p ALERT: nonce mismatch in 3/4\n", ctx );
601 return wpa_fail ( ctx, -EACCES );
602 }
603
604 /* Check RSN IE */
605 this_rsn = sec80211_find_rsn ( ( union ieee80211_ie * ) pkt->data,
606 pkt->data + pkt->datalen,
607 &this_is_rsn, &this_rsn_end );
608 if ( this_rsn )
609 new_rsn = sec80211_find_rsn ( ( union ieee80211_ie * )
610 this_rsn_end,
611 pkt->data + pkt->datalen,
612 &new_is_rsn, &new_rsn_end );
613 else
614 new_rsn = NULL;
615
616 if ( ! ctx->ap_rsn_ie || ! this_rsn ||
617 ctx->ap_rsn_ie_len != ( this_rsn_end - this_rsn ) ||
618 ctx->ap_rsn_is_rsn != this_is_rsn ||
619 memcmp ( ctx->ap_rsn_ie, this_rsn, ctx->ap_rsn_ie_len ) != 0 ) {
620 DBGC ( ctx, "WPA %p ALERT: RSN mismatch in 3/4\n", ctx );
621 DBGC2 ( ctx, "WPA %p RSNs (in 3/4, in beacon):\n", ctx );
622 DBGC2_HD ( ctx, this_rsn, this_rsn_end - this_rsn );
623 DBGC2_HD ( ctx, ctx->ap_rsn_ie, ctx->ap_rsn_ie_len );
624 return wpa_fail ( ctx, -EACCES );
625 }
626
627 /* Don't switch if they just supplied both styles of IE
628 simultaneously; we need two RSN IEs or two WPA IEs to
629 switch ciphers. They'll be immediately consecutive because
630 of ordering guarantees. */
631 if ( new_rsn && this_is_rsn == new_is_rsn ) {
632 struct net80211_wlan *assoc = ctx->dev->associating;
633 DBGC ( ctx, "WPA %p: accommodating bait-and-switch tactics\n",
634 ctx );
635 DBGC2 ( ctx, "WPA %p RSNs (in 3/4+beacon, new in 3/4):\n",
636 ctx );
637 DBGC2_HD ( ctx, this_rsn, this_rsn_end - this_rsn );
638 DBGC2_HD ( ctx, new_rsn, new_rsn_end - new_rsn );
639
640 if ( ( rc = sec80211_detect_ie ( new_is_rsn, new_rsn,
641 new_rsn_end,
642 &assoc->handshaking,
643 &assoc->crypto ) ) != 0 )
644 DBGC ( ctx, "WPA %p: bait-and-switch invalid, staying "
645 "with original request\n", ctx );
646 } else {
647 new_rsn = this_rsn;
648 new_is_rsn = this_is_rsn;
649 new_rsn_end = this_rsn_end;
650 }
651
652 /* Grab group cryptosystem ID */
653 ctx->gcrypt = sec80211_rsn_get_net80211_crypt ( *( u32 * )
654 ( new_rsn + 2 ) );
655
656 /* Check for a GTK, if info field is encrypted */
657 if ( pkt->info & EAPOL_KEY_INFO_KEY_ENC ) {
659 ( union ieee80211_ie * ) pkt->data,
660 pkt->data + pkt->datalen,
661 pkt->rsc );
662 if ( rc < 0 ) {
663 DBGC ( ctx, "WPA %p did not install GTK in 3/4: %s\n",
664 ctx, strerror ( rc ) );
665 if ( rc != -ENOENT )
666 return wpa_fail ( ctx, rc );
667 }
668 }
669
670 DBGC ( ctx, "WPA %p: received 3/4, looks OK\n", ctx );
671
672 /* Send final message */
673 rc = wpa_send_final ( ctx, pkt, is_rsn, kie );
674 if ( rc < 0 )
675 return wpa_fail ( ctx, rc );
676
677 /* Install PTK */
678 rc = wpa_install_ptk ( ctx, pkt->keysize );
679 if ( rc < 0 ) {
680 DBGC ( ctx, "WPA %p failed to install PTK: %s\n", ctx,
681 strerror ( rc ) );
682 return wpa_fail ( ctx, rc );
683 }
684
685 /* Mark us as needing a new Snonce if we rekey */
686 ctx->have_Snonce = 0;
687
688 /* Done! */
689 ctx->state = WPA_SUCCESS;
690 return 0;
691}
692
693
694/**
695 * Handle receipt of first frame in Group Key Handshake
696 *
697 * @v ctx WPA common context
698 * @v pkt EAPOL-Key packet
699 * @v is_rsn If TRUE, frame uses new RSN format
700 * @v kie Key integrity and encryption handler
701 * @ret rc Return status code
702 */
704 struct eapol_key_pkt *pkt, int is_rsn,
705 struct wpa_kie *kie )
706{
707 int rc;
708
709 /*
710 * WPA and RSN do this completely differently.
711 *
712 * The idea of encoding the GTK (or PMKID, or various other
713 * things) into a KDE that looks like an information element
714 * is an RSN innovation; old WPA code never encapsulates
715 * things like that. If it looks like an info element, it
716 * really is (for the WPA IE check in frames 2/4 and 3/4). The
717 * "key data encrypted" bit in the info field is also specific
718 * to RSN.
719 *
720 * So from an old WPA host, 3/4 does not contain an
721 * encapsulated GTK. The first frame of the GK handshake
722 * contains it, encrypted, but without a KDE wrapper, and with
723 * the key ID field (which iPXE doesn't use) shoved away in
724 * the reserved bits in the info field, and the TxRx bit
725 * stealing the Install bit's spot.
726 */
727
728 if ( is_rsn && ( pkt->info & EAPOL_KEY_INFO_KEY_ENC ) ) {
730 ( union ieee80211_ie * ) pkt->data,
731 pkt->data + pkt->datalen,
732 pkt->rsc );
733 if ( rc < 0 ) {
734 DBGC ( ctx, "WPA %p: failed to install GTK in 1/2: "
735 "%s\n", ctx, strerror ( rc ) );
736 return wpa_fail ( ctx, rc );
737 }
738 } else {
739 rc = kie->decrypt ( &ctx->ptk.kek, pkt->iv, pkt->data,
740 &pkt->datalen );
741 if ( rc < 0 ) {
742 DBGC ( ctx, "WPA %p: failed to decrypt GTK: %s\n",
743 ctx, strerror ( rc ) );
744 return rc; /* non-fatal */
745 }
746 if ( pkt->datalen > sizeof ( ctx->gtk.tk ) ) {
747 DBGC ( ctx, "WPA %p: too much GTK data (%d > %zd)\n",
748 ctx, pkt->datalen, sizeof ( ctx->gtk.tk ) );
749 return wpa_fail ( ctx, -EINVAL );
750 }
751
752 memcpy ( &ctx->gtk.tk, pkt->data, pkt->datalen );
753 wpa_install_gtk ( ctx, pkt->datalen, pkt->rsc );
754 }
755
756 DBGC ( ctx, "WPA %p: received 1/2, looks OK\n", ctx );
757
758 return wpa_send_final ( ctx, pkt, is_rsn, kie );
759}
760
761
762/**
763 * Handle receipt of EAPOL-Key frame for WPA
764 *
765 * @v supplicant EAPoL supplicant
766 * @v iob I/O buffer
767 * @v ll_source Source link-layer address
768 */
769static int eapol_key_rx ( struct eapol_supplicant *supplicant,
770 struct io_buffer *iob, const void *ll_source )
771{
772 struct net_device *netdev = supplicant->eap.netdev;
773 struct net80211_device *dev = net80211_get ( netdev );
774 struct eapol_header *eapol;
775 struct eapol_key_pkt *pkt;
776 int is_rsn, found_ctx;
777 struct wpa_common_ctx *ctx;
778 int rc = 0;
779 struct wpa_kie *kie;
780 u8 their_mic[16], our_mic[16];
781
782 eapol = iob->data;
783 pkt = ( ( ( void * ) eapol ) + sizeof ( *eapol ) );
784
785 if ( pkt->type != EAPOL_KEY_TYPE_WPA &&
786 pkt->type != EAPOL_KEY_TYPE_RSN ) {
787 DBG ( "EAPOL-Key: packet not of 802.11 type\n" );
788 rc = -EINVAL;
789 goto drop;
790 }
791
792 is_rsn = ( pkt->type == EAPOL_KEY_TYPE_RSN );
793
794 if ( ! dev ) {
795 DBG ( "EAPOL-Key: packet not from 802.11\n" );
796 rc = -EINVAL;
797 goto drop;
798 }
799
800 if ( memcmp ( dev->bssid, ll_source, ETH_ALEN ) != 0 ) {
801 DBG ( "EAPOL-Key: packet not from associated AP\n" );
802 rc = -EINVAL;
803 goto drop;
804 }
805
806 if ( ! ( ntohs ( pkt->info ) & EAPOL_KEY_INFO_KEY_ACK ) ) {
807 DBG ( "EAPOL-Key: packet sent in wrong direction\n" );
808 rc = -EINVAL;
809 goto drop;
810 }
811
812 found_ctx = 0;
814 if ( ctx->dev == dev ) {
815 found_ctx = 1;
816 break;
817 }
818 }
819
820 if ( ! found_ctx ) {
821 DBG ( "EAPOL-Key: no WPA context to handle packet for %p\n",
822 dev );
823 rc = -ENOENT;
824 goto drop;
825 }
826
827 if ( ( void * ) ( pkt + 1 ) + ntohs ( pkt->datalen ) > iob->tail ) {
828 DBGC ( ctx, "WPA %p: packet truncated (has %zd extra bytes, "
829 "states %d)\n", ctx, iob->tail - ( void * ) ( pkt + 1 ),
830 ntohs ( pkt->datalen ) );
831 rc = -EINVAL;
832 goto drop;
833 }
834
835 /* Get a handle on key integrity/encryption handler */
836 kie = wpa_find_kie ( ntohs ( pkt->info ) & EAPOL_KEY_INFO_VERSION );
837 if ( ! kie ) {
838 DBGC ( ctx, "WPA %p: no support for packet version %d\n", ctx,
839 ntohs ( pkt->info ) & EAPOL_KEY_INFO_VERSION );
840 rc = wpa_fail ( ctx, -ENOTSUP );
841 goto drop;
842 }
843
844 /* Check MIC */
845 if ( ntohs ( pkt->info ) & EAPOL_KEY_INFO_KEY_MIC ) {
846 memcpy ( their_mic, pkt->mic, sizeof ( pkt->mic ) );
847 memset ( pkt->mic, 0, sizeof ( pkt->mic ) );
848 kie->mic ( &ctx->ptk.kck, eapol,
849 sizeof ( *eapol ) + sizeof ( *pkt ) +
850 ntohs ( pkt->datalen ), our_mic );
851 DBGC2 ( ctx, "WPA %p MIC comparison (theirs, ours):\n", ctx );
852 DBGC2_HD ( ctx, their_mic, 16 );
853 DBGC2_HD ( ctx, our_mic, 16 );
854 if ( memcmp ( their_mic, our_mic, sizeof ( pkt->mic ) ) != 0 ) {
855 DBGC ( ctx, "WPA %p: EAPOL MIC failure\n", ctx );
856 goto drop;
857 }
858 }
859
860 /* Fix byte order to local */
861 pkt->info = ntohs ( pkt->info );
862 pkt->keysize = ntohs ( pkt->keysize );
863 pkt->datalen = ntohs ( pkt->datalen );
864 pkt->replay = be64_to_cpu ( pkt->replay );
865
866 /* Check replay counter */
867 if ( ctx->replay != ~0ULL && ctx->replay >= pkt->replay ) {
868 DBGC ( ctx, "WPA %p ALERT: Replay detected! "
869 "(%08x:%08x >= %08x:%08x)\n", ctx,
870 ( u32 ) ( ctx->replay >> 32 ), ( u32 ) ctx->replay,
871 ( u32 ) ( pkt->replay >> 32 ), ( u32 ) pkt->replay );
872 rc = 0; /* ignore without error */
873 goto drop;
874 }
875 ctx->replay = pkt->replay;
876
877 /* Decrypt key data */
878 if ( pkt->info & EAPOL_KEY_INFO_KEY_ENC ) {
879 rc = kie->decrypt ( &ctx->ptk.kek, pkt->iv, pkt->data,
880 &pkt->datalen );
881 if ( rc < 0 ) {
882 DBGC ( ctx, "WPA %p: failed to decrypt packet: %s\n",
883 ctx, strerror ( rc ) );
884 goto drop;
885 }
886 }
887
888 /* Hand it off to appropriate handler */
889 switch ( pkt->info & ( EAPOL_KEY_INFO_TYPE |
892 rc = wpa_handle_1_of_4 ( ctx, pkt, is_rsn, kie );
893 break;
894
896 rc = wpa_handle_3_of_4 ( ctx, pkt, is_rsn, kie );
897 break;
898
900 rc = wpa_handle_1_of_2 ( ctx, pkt, is_rsn, kie );
901 break;
902
903 default:
904 DBGC ( ctx, "WPA %p: Invalid combination of key flags %04x\n",
905 ctx, pkt->info );
906 rc = -EINVAL;
907 break;
908 }
909
910 drop:
911 free_iob ( iob );
912 return rc;
913}
914
915struct eapol_handler eapol_key_handler __eapol_handler = {
916 .type = EAPOL_TYPE_KEY,
917 .rx = eapol_key_rx,
918};
919
920/* WPA always needs EAPOL in order to be useful */
921REQUIRING_SYMBOL ( eapol_key_handler );
#define NULL
NULL pointer (VOID *)
Definition Base.h:322
struct golan_eq_context ctx
Definition CIB_PRM.h:0
struct golan_inbox_hdr hdr
Message header.
Definition CIB_PRM.h:0
struct arbelprm_rc_send_wqe rc
Definition arbel.h:3
u32 version
Driver version.
Definition ath9k_hw.c:1985
ring len
Length.
Definition dwmac.h:226
Extensible Authentication Protocol over LAN (EAPoL)
#define __eapol_handler
Declare an EAPoL handler.
Definition eapol.h:78
#define EAPOL_VERSION_2001
802.1X-2001
Definition eapol.h:29
#define EAPOL_TYPE_KEY
EAPoL key.
Definition eapol.h:38
Error codes.
const char * eth_ntoa(const void *ll_addr)
Transcribe Ethernet address.
Definition ethernet.c:176
Ethernet protocol.
static struct net_device * netdev
Definition gdbudp.c:53
#define DBGC2(...)
Definition compiler.h:522
#define DBGC2_HD(...)
Definition compiler.h:524
#define DBGC(...)
Definition compiler.h:505
#define DBG(...)
Print a debugging message.
Definition compiler.h:498
#define EAPOL_KEY_INFO_KEY_ENC
Key Encrypted bit; set when the Key Data field is encrypted.
Definition wpa.h:71
#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
#define EAPOL_KEY_TYPE_PTK
Key type field value for a PTK (pairwise) key handshake.
Definition wpa.h:84
#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_INFO_TYPE
Key type bit, indicating pairwise or group.
Definition wpa.h:50
#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 EAPOL_KEY_TYPE_GTK
Key type field value for a GTK (group) key handshake.
Definition wpa.h:87
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
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
#define IEEE80211_WPA_OUI_VEN
Old vendor-type WPA IE OUI type + subtype.
Definition ieee80211.h:869
#define IEEE80211_IE_VENDOR
Information element ID for Vendor Specific information element.
Definition ieee80211.h:960
#define IEEE80211_RSN_VERSION
802.11 RSN IE: expected version number
Definition ieee80211.h:873
static union ieee80211_ie * ieee80211_next_ie(union ieee80211_ie *ie, void *end)
Advance to next 802.11 information element.
Definition ieee80211.h:1028
#define IEEE80211_IE_RSN
Information element ID for Robust Security Network information element.
Definition ieee80211.h:834
#define ieee80211_beacon
Definition ieee80211.h:1069
#define FILE_LICENCE(_licence)
Declare a particular licence as applying to a file.
Definition compiler.h:896
void net80211_deauthenticate(struct net80211_device *dev, int rc)
Deauthenticate from current network and try again.
Definition net80211.c:2391
struct net80211_device * net80211_get(struct net_device *netdev)
Get 802.11 device from wrapping network device.
Definition net80211.c:625
#define REQUIRE_OBJECT(object)
Require an object.
Definition compiler.h:202
#define ENOENT
No such file or directory.
Definition errno.h:515
#define EINVAL
Invalid argument.
Definition errno.h:429
#define ENOMEM
Not enough space.
Definition errno.h:535
#define ENOTSUP
Operation not supported.
Definition errno.h:590
#define EACCES
Permission denied.
Definition errno.h:299
#define FILE_SECBOOT(_status)
Declare a file's UEFI Secure Boot permission status.
Definition compiler.h:926
#define REQUIRING_SYMBOL(symbol)
Specify the file's requiring symbol.
Definition compiler.h:140
#define WPA_KDE_GTK
KDE type for an encapsulated Group Transient Key (requires encryption)
Definition wpa.h:442
Keyed-Hashing for Message Authentication.
u32 group_cipher
Cipher ID for the cipher used in multicast/broadcast frames.
Definition ieee80211.h:10
#define ETH_ALEN
Definition if_ether.h:9
#define u8
Definition igbvf_osdep.h:40
#define htons(value)
Definition byteswap.h:136
#define ntohs(value)
Definition byteswap.h:137
#define cpu_to_be64(value)
Definition byteswap.h:112
#define be64_to_cpu(value)
Definition byteswap.h:118
#define __attribute__(x)
Definition compiler.h:10
Cryptographic API.
String functions.
void * memcpy(void *dest, const void *src, size_t len) __nonnull
void * memset(void *dest, int character, size_t len) __nonnull
void free_iob(struct io_buffer *iobuf)
Free I/O buffer.
Definition iobuf.c:153
struct io_buffer * alloc_iob(size_t len)
Allocate I/O buffer.
Definition iobuf.c:131
#define iob_push(iobuf, len)
Definition iobuf.h:89
#define iob_put(iobuf, len)
Definition iobuf.h:125
#define iob_reserve(iobuf, len)
Definition iobuf.h:72
unsigned long tmp
Definition linux_pci.h:65
Linked lists.
#define LIST_HEAD_INIT(list)
Initialise a static list head.
Definition list.h:31
#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:459
#define list_add_tail(new, head)
Add a new entry to the tail of a list.
Definition list.h:94
#define list_for_each_entry(pos, head, member)
Iterate over entries in a list.
Definition list.h:432
#define list_del(list)
Delete an entry from a list.
Definition list.h:120
void * malloc(size_t size)
Allocate memory.
Definition malloc.c:621
The iPXE 802.11 MAC layer.
net80211_crypto_alg
An 802.11 data encryption algorithm.
Definition net80211.h:129
@ NET80211_CRYPT_UNKNOWN
Dummy value used when the cryptosystem can't be detected.
Definition net80211.h:177
#define NET80211_CRYPTOS
Definition net80211.h:769
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:1074
#define MAX_LL_HEADER_LEN
Maximum length of a link-layer header.
Definition netdevice.h:46
int rbg_generate(const void *additional, size_t additional_len, int prediction_resist, void *data, size_t len)
Generate bits using RBG.
Definition rbg.c:117
RBG mechanism.
static void(* free)(struct refcnt *refcnt))
Definition refcnt.h:55
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:284
enum net80211_crypto_alg sec80211_rsn_get_net80211_crypt(u32 desc)
Determine net80211 cryptosystem number from RSN descriptor.
Definition sec80211.c:509
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:114
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:341
u32 sec80211_rsn_get_crypto_desc(enum net80211_crypto_alg crypt, int rsnie)
Determine RSN descriptor for specified net80211 cryptosystem number.
Definition sec80211.c:482
u32 sec80211_rsn_get_akm_desc(enum net80211_security_proto secprot, int rsnie)
Determine RSN descriptor for specified net80211 handshaker number.
Definition sec80211.c:497
Definitions for general secured-network routines.
SHA-1 algorithm.
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
char * strerror(int errno)
Retrieve string representation of error number.
Definition strerror.c:79
int memcmp(const void *first, const void *second, size_t len)
Compare memory regions.
Definition string.c:115
struct net_device * netdev
Network device.
Definition eap.h:141
An EAPoL handler.
Definition eapol.h:57
EAPoL header.
Definition eapol.h:19
uint8_t version
Version.
Definition eapol.h:21
uint8_t type
Type.
Definition eapol.h:23
uint16_t len
Payload length.
Definition eapol.h:25
An EAPOL-Key packet.
Definition wpa.h:105
u8 data[0]
Key data.
Definition wpa.h:171
u8 iv[16]
Initialization vector.
Definition wpa.h:139
u16 keysize
Length of encryption key to be used, network byte order.
Definition wpa.h:116
u8 rsc[8]
Receive sequence counter for GTK.
Definition wpa.h:148
u8 nonce[32]
Nonce value.
Definition wpa.h:131
u8 mic[16]
Message integrity code over the entire EAPOL frame.
Definition wpa.h:160
u16 info
Bitfield of key characteristics, network byte order.
Definition wpa.h:110
u8 type
One of the EAPOL_KEY_TYPE_* defines.
Definition wpa.h:107
u16 datalen
Length of the data field in bytes, network byte order.
Definition wpa.h:163
u64 replay
Monotonically increasing value for EAPOL-Key conversations.
Definition wpa.h:124
An EAPoL supplicant.
Definition eapol.h:41
struct eap_supplicant eap
EAP supplicant.
Definition eapol.h:43
An 802.11 data or management frame without QoS or WDS header fields.
Definition ieee80211.h:301
802.11 Robust Security Network ("WPA") information element
Definition ieee80211.h:798
u16 akm_count
Number of authentication types supported.
Definition ieee80211.h:818
u16 pairwise_count
Number of unicast ciphers supported.
Definition ieee80211.h:812
u32 akm_list[1]
List of authentication type IDs for supported types.
Definition ieee80211.h:821
u32 pairwise_cipher[1]
List of cipher IDs for supported unicast frame ciphers.
Definition ieee80211.h:815
u16 rsn_capab
Security capabilities field (RSN only)
Definition ieee80211.h:824
u32 group_cipher
Cipher ID for the cipher used in multicast/broadcast frames.
Definition ieee80211.h:809
u16 pmkid_count
Number of PMKIDs included (present only in association frames)
Definition ieee80211.h:827
u16 version
RSN information element version.
Definition ieee80211.h:806
u32 oui
OUI and vendor-specific type byte.
Definition ieee80211.h:955
A persistent I/O buffer.
Definition iobuf.h:38
void * data
Start of data.
Definition iobuf.h:53
void * tail
End of data.
Definition iobuf.h:55
A doubly-linked list entry (or list head)
Definition list.h:19
Interface to an 802.11 cryptosystem.
Definition net80211.h:690
enum net80211_crypto_alg algorithm
The cryptographic algorithm implemented.
Definition net80211.h:692
Structure encapsulating the complete state of an 802.11 device.
Definition net80211.h:787
union ieee80211_ie * rsn_ie
RSN or WPA information element to include with association.
Definition net80211.h:932
struct net80211_wlan * associating
Network with which we are associating.
Definition net80211.h:866
u8 bssid[ETH_ALEN]
MAC address of the access point most recently associated.
Definition net80211.h:954
Structure representing a probed network.
Definition net80211.h:1057
struct io_buffer * beacon
The complete beacon or probe-response frame received.
Definition net80211.h:1081
enum net80211_crypto_alg crypto
Cryptographic algorithm used on the network.
Definition net80211.h:1087
enum net80211_security_proto handshaking
Security handshaking method used on the network.
Definition net80211.h:1084
A network device.
Definition netdevice.h:353
Common context for WPA security handshaking.
Definition wpa.h:292
struct list_head list
List entry.
Definition wpa.h:362
struct net80211_device * dev
802.11 device we are authenticating for
Definition wpa.h:294
struct wpa_gtk gtk
Encapsulated group transient key.
Definition wpa.h:431
Any key descriptor element type.
Definition wpa.h:465
u8 len
Length, not including ie_type and length fields.
Definition wpa.h:470
struct wpa_kde_gtk_encap gtk_encap
For GTK-type KDEs, encapsulated GTK.
Definition wpa.h:478
WPA handshake key integrity and encryption handler.
Definition wpa.h:371
int version
Value of version bits in EAPOL-Key info field for which to use.
Definition wpa.h:376
int(* decrypt)(const void *kek, const void *iv, void *msg, u16 *len)
Decrypt key data.
Definition wpa.h:403
void(* mic)(const void *kck, const void *msg, size_t len, void *mic)
Calculate MIC over message.
Definition wpa.h:388
#define for_each_table_entry(pointer, table)
Iterate through all entries within a linker table.
Definition tables.h:386
Any 802.11 information element.
Definition ieee80211.h:973
u8 len
Information element data length.
Definition ieee80211.h:977
struct ieee80211_ie_vendor vendor
Vendor-specific.
Definition ieee80211.h:1003
u8 id
Information element ID.
Definition ieee80211.h:976
#define u32
Definition vga.h:21
static int wpa_install_ptk(struct wpa_common_ctx *ctx, int len)
Install pairwise transient key.
Definition wpa.c:332
int wpa_make_rsn_ie(struct net80211_device *dev, union ieee80211_ie **ie_ret)
Construct RSN or WPA information element.
Definition wpa.c:125
static int wpa_fail(struct wpa_common_ctx *ctx, int rc)
Return an error code and deauthenticate.
Definition wpa.c:57
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:370
void wpa_stop(struct net80211_device *dev)
Disable handling of received WPA handshake frames.
Definition wpa.c:261
struct wpa_kie * wpa_find_kie(int version)
Find WPA key integrity and encryption handler from key version field.
Definition wpa.c:93
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:545
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:584
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:703
struct list_head wpa_contexts
List of WPA contexts in active use.
Definition wpa.c:47
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:477
static int eapol_key_rx(struct eapol_supplicant *supplicant, struct io_buffer *iob, const void *ll_source)
Handle receipt of EAPOL-Key frame for WPA.
Definition wpa.c:769
static int wpa_install_gtk(struct wpa_common_ctx *ctx, int len, const void *rsc)
Install group transient key.
Definition wpa.c:350
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:513
static void wpa_derive_ptk(struct wpa_common_ctx *ctx)
Derive pairwise transient key.
Definition wpa.c:280
static struct net80211_crypto * wpa_find_cryptosystem(enum net80211_crypto_alg crypt)
Find a cryptosystem handler structure from a crypto ID.
Definition wpa.c:74
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:217
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:443
static struct io_buffer * wpa_alloc_frame(int kdlen)
Allocate I/O buffer for construction of outgoing EAPOL-Key frame.
Definition wpa.c:415
Common definitions for all types of WPA-protected networks.
#define EAPOL_KEY_TYPE_WPA
Old EAPOL-Key type field used by WPA1 hardware before 802.11i ratified.
Definition wpa.h:38
u8 rsc[8]
Receive sequence counter for GTK.
Definition wpa.h:42
#define WPA_NONCE_LEN
Length of a nonce.
Definition wpa.h:204
#define EAPOL_KEY_TYPE_RSN
EAPOL-Key type field for modern 802.11i/RSN WPA packets.
Definition wpa.h:35
@ WPA_WAITING
Waiting for PMK to be set.
Definition wpa.h:178
@ WPA_WORKING
Performing 4-Way Handshake.
Definition wpa.h:184
@ WPA_SUCCESS
4-Way Handshake succeeded
Definition wpa.h:187
@ WPA_READY
Ready for 4-Way Handshake.
Definition wpa.h:181
#define WPA_KIES
Definition wpa.h:407