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