~pmdj/ubuntu/trusty/qemu/2.9+applesmc+fadtv3

« back to all changes in this revision

Viewing changes to roms/ipxe/src/net/80211/wpa.c

  • Committer: Phil Dennis-Jordan
  • Date: 2017-07-21 08:03:43 UTC
  • mfrom: (1.1.1)
  • Revision ID: phil@philjordan.eu-20170721080343-2yr2vdj7713czahv
New upstream release 2.9.0.

Show diffs side-by-side

added added

removed removed

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