~ubuntu-branches/ubuntu/saucy/wpasupplicant/saucy

« back to all changes in this revision

Viewing changes to src/eap_server/eap_server_fast.c

  • Committer: Bazaar Package Importer
  • Author(s): Mathieu Trudel-Lapierre
  • Date: 2010-11-22 09:43:43 UTC
  • mfrom: (1.1.16 upstream)
  • Revision ID: james.westby@ubuntu.com-20101122094343-qgsxaojvmswfri77
Tags: 0.7.3-0ubuntu1
* Get wpasupplicant 0.7.3 from Debian's SVN. Leaving 0.7.3-1 as unreleased
  for now.
* Build-Depend on debhelper 8, since the packaging from Debian uses compat 8.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 * EAP-FAST server (RFC 4851)
 
3
 * Copyright (c) 2004-2008, Jouni Malinen <j@w1.fi>
 
4
 *
 
5
 * This program is free software; you can redistribute it and/or modify
 
6
 * it under the terms of the GNU General Public License version 2 as
 
7
 * published by the Free Software Foundation.
 
8
 *
 
9
 * Alternatively, this software may be distributed under the terms of BSD
 
10
 * license.
 
11
 *
 
12
 * See README and COPYING for more details.
 
13
 */
 
14
 
 
15
#include "includes.h"
 
16
 
 
17
#include "common.h"
 
18
#include "crypto/aes_wrap.h"
 
19
#include "crypto/sha1.h"
 
20
#include "crypto/tls.h"
 
21
#include "eap_common/eap_tlv_common.h"
 
22
#include "eap_common/eap_fast_common.h"
 
23
#include "eap_i.h"
 
24
#include "eap_tls_common.h"
 
25
 
 
26
 
 
27
static void eap_fast_reset(struct eap_sm *sm, void *priv);
 
28
 
 
29
 
 
30
/* Private PAC-Opaque TLV types */
 
31
#define PAC_OPAQUE_TYPE_PAD 0
 
32
#define PAC_OPAQUE_TYPE_KEY 1
 
33
#define PAC_OPAQUE_TYPE_LIFETIME 2
 
34
#define PAC_OPAQUE_TYPE_IDENTITY 3
 
35
 
 
36
struct eap_fast_data {
 
37
        struct eap_ssl_data ssl;
 
38
        enum {
 
39
                START, PHASE1, PHASE2_START, PHASE2_ID, PHASE2_METHOD,
 
40
                CRYPTO_BINDING, REQUEST_PAC, SUCCESS, FAILURE
 
41
        } state;
 
42
 
 
43
        int fast_version;
 
44
        const struct eap_method *phase2_method;
 
45
        void *phase2_priv;
 
46
        int force_version;
 
47
        int peer_version;
 
48
 
 
49
        u8 crypto_binding_nonce[32];
 
50
        int final_result;
 
51
 
 
52
        struct eap_fast_key_block_provisioning *key_block_p;
 
53
 
 
54
        u8 simck[EAP_FAST_SIMCK_LEN];
 
55
        u8 cmk[EAP_FAST_CMK_LEN];
 
56
        int simck_idx;
 
57
 
 
58
        u8 pac_opaque_encr[16];
 
59
        u8 *srv_id;
 
60
        size_t srv_id_len;
 
61
        char *srv_id_info;
 
62
 
 
63
        int anon_provisioning;
 
64
        int send_new_pac; /* server triggered re-keying of Tunnel PAC */
 
65
        struct wpabuf *pending_phase2_resp;
 
66
        u8 *identity; /* from PAC-Opaque */
 
67
        size_t identity_len;
 
68
        int eap_seq;
 
69
        int tnc_started;
 
70
 
 
71
        int pac_key_lifetime;
 
72
        int pac_key_refresh_time;
 
73
};
 
74
 
 
75
 
 
76
static int eap_fast_process_phase2_start(struct eap_sm *sm,
 
77
                                         struct eap_fast_data *data);
 
78
 
 
79
 
 
80
static const char * eap_fast_state_txt(int state)
 
81
{
 
82
        switch (state) {
 
83
        case START:
 
84
                return "START";
 
85
        case PHASE1:
 
86
                return "PHASE1";
 
87
        case PHASE2_START:
 
88
                return "PHASE2_START";
 
89
        case PHASE2_ID:
 
90
                return "PHASE2_ID";
 
91
        case PHASE2_METHOD:
 
92
                return "PHASE2_METHOD";
 
93
        case CRYPTO_BINDING:
 
94
                return "CRYPTO_BINDING";
 
95
        case REQUEST_PAC:
 
96
                return "REQUEST_PAC";
 
97
        case SUCCESS:
 
98
                return "SUCCESS";
 
99
        case FAILURE:
 
100
                return "FAILURE";
 
101
        default:
 
102
                return "Unknown?!";
 
103
        }
 
104
}
 
105
 
 
106
 
 
107
static void eap_fast_state(struct eap_fast_data *data, int state)
 
108
{
 
109
        wpa_printf(MSG_DEBUG, "EAP-FAST: %s -> %s",
 
110
                   eap_fast_state_txt(data->state),
 
111
                   eap_fast_state_txt(state));
 
112
        data->state = state;
 
113
}
 
114
 
 
115
 
 
116
static EapType eap_fast_req_failure(struct eap_sm *sm,
 
117
                                    struct eap_fast_data *data)
 
118
{
 
119
        /* TODO: send Result TLV(FAILURE) */
 
120
        eap_fast_state(data, FAILURE);
 
121
        return EAP_TYPE_NONE;
 
122
}
 
123
 
 
124
 
 
125
static int eap_fast_session_ticket_cb(void *ctx, const u8 *ticket, size_t len,
 
126
                                      const u8 *client_random,
 
127
                                      const u8 *server_random,
 
128
                                      u8 *master_secret)
 
129
{
 
130
        struct eap_fast_data *data = ctx;
 
131
        const u8 *pac_opaque;
 
132
        size_t pac_opaque_len;
 
133
        u8 *buf, *pos, *end, *pac_key = NULL;
 
134
        os_time_t lifetime = 0;
 
135
        struct os_time now;
 
136
        u8 *identity = NULL;
 
137
        size_t identity_len = 0;
 
138
 
 
139
        wpa_printf(MSG_DEBUG, "EAP-FAST: SessionTicket callback");
 
140
        wpa_hexdump(MSG_DEBUG, "EAP-FAST: SessionTicket (PAC-Opaque)",
 
141
                    ticket, len);
 
142
 
 
143
        if (len < 4 || WPA_GET_BE16(ticket) != PAC_TYPE_PAC_OPAQUE) {
 
144
                wpa_printf(MSG_DEBUG, "EAP-FAST: Ignore invalid "
 
145
                           "SessionTicket");
 
146
                return 0;
 
147
        }
 
148
 
 
149
        pac_opaque_len = WPA_GET_BE16(ticket + 2);
 
150
        pac_opaque = ticket + 4;
 
151
        if (pac_opaque_len < 8 || pac_opaque_len % 8 ||
 
152
            pac_opaque_len > len - 4) {
 
153
                wpa_printf(MSG_DEBUG, "EAP-FAST: Ignore invalid PAC-Opaque "
 
154
                           "(len=%lu left=%lu)",
 
155
                           (unsigned long) pac_opaque_len,
 
156
                           (unsigned long) len);
 
157
                return 0;
 
158
        }
 
159
        wpa_hexdump(MSG_DEBUG, "EAP-FAST: Received PAC-Opaque",
 
160
                    pac_opaque, pac_opaque_len);
 
161
 
 
162
        buf = os_malloc(pac_opaque_len - 8);
 
163
        if (buf == NULL) {
 
164
                wpa_printf(MSG_DEBUG, "EAP-FAST: Failed to allocate memory "
 
165
                           "for decrypting PAC-Opaque");
 
166
                return 0;
 
167
        }
 
168
 
 
169
        if (aes_unwrap(data->pac_opaque_encr, (pac_opaque_len - 8) / 8,
 
170
                       pac_opaque, buf) < 0) {
 
171
                wpa_printf(MSG_DEBUG, "EAP-FAST: Failed to decrypt "
 
172
                           "PAC-Opaque");
 
173
                os_free(buf);
 
174
                /*
 
175
                 * This may have been caused by server changing the PAC-Opaque
 
176
                 * encryption key, so just ignore this PAC-Opaque instead of
 
177
                 * failing the authentication completely. Provisioning can now
 
178
                 * be used to provision a new PAC.
 
179
                 */
 
180
                return 0;
 
181
        }
 
182
 
 
183
        end = buf + pac_opaque_len - 8;
 
184
        wpa_hexdump_key(MSG_DEBUG, "EAP-FAST: Decrypted PAC-Opaque",
 
185
                        buf, end - buf);
 
186
 
 
187
        pos = buf;
 
188
        while (pos + 1 < end) {
 
189
                if (pos + 2 + pos[1] > end)
 
190
                        break;
 
191
 
 
192
                switch (*pos) {
 
193
                case PAC_OPAQUE_TYPE_PAD:
 
194
                        pos = end;
 
195
                        break;
 
196
                case PAC_OPAQUE_TYPE_KEY:
 
197
                        if (pos[1] != EAP_FAST_PAC_KEY_LEN) {
 
198
                                wpa_printf(MSG_DEBUG, "EAP-FAST: Invalid "
 
199
                                           "PAC-Key length %d", pos[1]);
 
200
                                os_free(buf);
 
201
                                return -1;
 
202
                        }
 
203
                        pac_key = pos + 2;
 
204
                        wpa_hexdump_key(MSG_DEBUG, "EAP-FAST: PAC-Key from "
 
205
                                        "decrypted PAC-Opaque",
 
206
                                        pac_key, EAP_FAST_PAC_KEY_LEN);
 
207
                        break;
 
208
                case PAC_OPAQUE_TYPE_LIFETIME:
 
209
                        if (pos[1] != 4) {
 
210
                                wpa_printf(MSG_DEBUG, "EAP-FAST: Invalid "
 
211
                                           "PAC-Key lifetime length %d",
 
212
                                           pos[1]);
 
213
                                os_free(buf);
 
214
                                return -1;
 
215
                        }
 
216
                        lifetime = WPA_GET_BE32(pos + 2);
 
217
                        break;
 
218
                case PAC_OPAQUE_TYPE_IDENTITY:
 
219
                        identity = pos + 2;
 
220
                        identity_len = pos[1];
 
221
                        break;
 
222
                }
 
223
 
 
224
                pos += 2 + pos[1];
 
225
        }
 
226
 
 
227
        if (pac_key == NULL) {
 
228
                wpa_printf(MSG_DEBUG, "EAP-FAST: No PAC-Key included in "
 
229
                           "PAC-Opaque");
 
230
                os_free(buf);
 
231
                return -1;
 
232
        }
 
233
 
 
234
        if (identity) {
 
235
                wpa_hexdump_ascii(MSG_DEBUG, "EAP-FAST: Identity from "
 
236
                                  "PAC-Opaque", identity, identity_len);
 
237
                os_free(data->identity);
 
238
                data->identity = os_malloc(identity_len);
 
239
                if (data->identity) {
 
240
                        os_memcpy(data->identity, identity, identity_len);
 
241
                        data->identity_len = identity_len;
 
242
                }
 
243
        }
 
244
 
 
245
        if (os_get_time(&now) < 0 || lifetime <= 0 || now.sec > lifetime) {
 
246
                wpa_printf(MSG_DEBUG, "EAP-FAST: PAC-Key not valid anymore "
 
247
                           "(lifetime=%ld now=%ld)", lifetime, now.sec);
 
248
                data->send_new_pac = 2;
 
249
                /*
 
250
                 * Allow PAC to be used to allow a PAC update with some level
 
251
                 * of server authentication (i.e., do not fall back to full TLS
 
252
                 * handshake since we cannot be sure that the peer would be
 
253
                 * able to validate server certificate now). However, reject
 
254
                 * the authentication since the PAC was not valid anymore. Peer
 
255
                 * can connect again with the newly provisioned PAC after this.
 
256
                 */
 
257
        } else if (lifetime - now.sec < data->pac_key_refresh_time) {
 
258
                wpa_printf(MSG_DEBUG, "EAP-FAST: PAC-Key soft timeout; send "
 
259
                           "an update if authentication succeeds");
 
260
                data->send_new_pac = 1;
 
261
        }
 
262
 
 
263
        eap_fast_derive_master_secret(pac_key, server_random, client_random,
 
264
                                      master_secret);
 
265
 
 
266
        os_free(buf);
 
267
 
 
268
        return 1;
 
269
}
 
270
 
 
271
 
 
272
static void eap_fast_derive_key_auth(struct eap_sm *sm,
 
273
                                     struct eap_fast_data *data)
 
274
{
 
275
        u8 *sks;
 
276
 
 
277
        /* RFC 4851, Section 5.1:
 
278
         * Extra key material after TLS key_block: session_key_seed[40]
 
279
         */
 
280
 
 
281
        sks = eap_fast_derive_key(sm->ssl_ctx, data->ssl.conn, "key expansion",
 
282
                                  EAP_FAST_SKS_LEN);
 
283
        if (sks == NULL) {
 
284
                wpa_printf(MSG_DEBUG, "EAP-FAST: Failed to derive "
 
285
                           "session_key_seed");
 
286
                return;
 
287
        }
 
288
 
 
289
        /*
 
290
         * RFC 4851, Section 5.2:
 
291
         * S-IMCK[0] = session_key_seed
 
292
         */
 
293
        wpa_hexdump_key(MSG_DEBUG,
 
294
                        "EAP-FAST: session_key_seed (SKS = S-IMCK[0])",
 
295
                        sks, EAP_FAST_SKS_LEN);
 
296
        data->simck_idx = 0;
 
297
        os_memcpy(data->simck, sks, EAP_FAST_SIMCK_LEN);
 
298
        os_free(sks);
 
299
}
 
300
 
 
301
 
 
302
static void eap_fast_derive_key_provisioning(struct eap_sm *sm,
 
303
                                             struct eap_fast_data *data)
 
304
{
 
305
        os_free(data->key_block_p);
 
306
        data->key_block_p = (struct eap_fast_key_block_provisioning *)
 
307
                eap_fast_derive_key(sm->ssl_ctx, data->ssl.conn,
 
308
                                    "key expansion",
 
309
                                    sizeof(*data->key_block_p));
 
310
        if (data->key_block_p == NULL) {
 
311
                wpa_printf(MSG_DEBUG, "EAP-FAST: Failed to derive key block");
 
312
                return;
 
313
        }
 
314
        /*
 
315
         * RFC 4851, Section 5.2:
 
316
         * S-IMCK[0] = session_key_seed
 
317
         */
 
318
        wpa_hexdump_key(MSG_DEBUG,
 
319
                        "EAP-FAST: session_key_seed (SKS = S-IMCK[0])",
 
320
                        data->key_block_p->session_key_seed,
 
321
                        sizeof(data->key_block_p->session_key_seed));
 
322
        data->simck_idx = 0;
 
323
        os_memcpy(data->simck, data->key_block_p->session_key_seed,
 
324
                  EAP_FAST_SIMCK_LEN);
 
325
        wpa_hexdump_key(MSG_DEBUG, "EAP-FAST: server_challenge",
 
326
                        data->key_block_p->server_challenge,
 
327
                        sizeof(data->key_block_p->server_challenge));
 
328
        wpa_hexdump_key(MSG_DEBUG, "EAP-FAST: client_challenge",
 
329
                        data->key_block_p->client_challenge,
 
330
                        sizeof(data->key_block_p->client_challenge));
 
331
}
 
332
 
 
333
 
 
334
static int eap_fast_get_phase2_key(struct eap_sm *sm,
 
335
                                   struct eap_fast_data *data,
 
336
                                   u8 *isk, size_t isk_len)
 
337
{
 
338
        u8 *key;
 
339
        size_t key_len;
 
340
 
 
341
        os_memset(isk, 0, isk_len);
 
342
 
 
343
        if (data->phase2_method == NULL || data->phase2_priv == NULL) {
 
344
                wpa_printf(MSG_DEBUG, "EAP-FAST: Phase 2 method not "
 
345
                           "available");
 
346
                return -1;
 
347
        }
 
348
 
 
349
        if (data->phase2_method->getKey == NULL)
 
350
                return 0;
 
351
 
 
352
        if ((key = data->phase2_method->getKey(sm, data->phase2_priv,
 
353
                                               &key_len)) == NULL) {
 
354
                wpa_printf(MSG_DEBUG, "EAP-FAST: Could not get key material "
 
355
                           "from Phase 2");
 
356
                return -1;
 
357
        }
 
358
 
 
359
        if (key_len > isk_len)
 
360
                key_len = isk_len;
 
361
        if (key_len == 32 &&
 
362
            data->phase2_method->vendor == EAP_VENDOR_IETF &&
 
363
            data->phase2_method->method == EAP_TYPE_MSCHAPV2) {
 
364
                /*
 
365
                 * EAP-FAST uses reverse order for MS-MPPE keys when deriving
 
366
                 * MSK from EAP-MSCHAPv2. Swap the keys here to get the correct
 
367
                 * ISK for EAP-FAST cryptobinding.
 
368
                 */
 
369
                os_memcpy(isk, key + 16, 16);
 
370
                os_memcpy(isk + 16, key, 16);
 
371
        } else
 
372
                os_memcpy(isk, key, key_len);
 
373
        os_free(key);
 
374
 
 
375
        return 0;
 
376
}
 
377
 
 
378
 
 
379
static int eap_fast_update_icmk(struct eap_sm *sm, struct eap_fast_data *data)
 
380
{
 
381
        u8 isk[32], imck[60];
 
382
 
 
383
        wpa_printf(MSG_DEBUG, "EAP-FAST: Deriving ICMK[%d] (S-IMCK and CMK)",
 
384
                   data->simck_idx + 1);
 
385
 
 
386
        /*
 
387
         * RFC 4851, Section 5.2:
 
388
         * IMCK[j] = T-PRF(S-IMCK[j-1], "Inner Methods Compound Keys",
 
389
         *                 MSK[j], 60)
 
390
         * S-IMCK[j] = first 40 octets of IMCK[j]
 
391
         * CMK[j] = last 20 octets of IMCK[j]
 
392
         */
 
393
 
 
394
        if (eap_fast_get_phase2_key(sm, data, isk, sizeof(isk)) < 0)
 
395
                return -1;
 
396
        wpa_hexdump_key(MSG_MSGDUMP, "EAP-FAST: ISK[j]", isk, sizeof(isk));
 
397
        sha1_t_prf(data->simck, EAP_FAST_SIMCK_LEN,
 
398
                   "Inner Methods Compound Keys",
 
399
                   isk, sizeof(isk), imck, sizeof(imck));
 
400
        data->simck_idx++;
 
401
        os_memcpy(data->simck, imck, EAP_FAST_SIMCK_LEN);
 
402
        wpa_hexdump_key(MSG_MSGDUMP, "EAP-FAST: S-IMCK[j]",
 
403
                        data->simck, EAP_FAST_SIMCK_LEN);
 
404
        os_memcpy(data->cmk, imck + EAP_FAST_SIMCK_LEN, EAP_FAST_CMK_LEN);
 
405
        wpa_hexdump_key(MSG_MSGDUMP, "EAP-FAST: CMK[j]",
 
406
                        data->cmk, EAP_FAST_CMK_LEN);
 
407
 
 
408
        return 0;
 
409
}
 
410
 
 
411
 
 
412
static void * eap_fast_init(struct eap_sm *sm)
 
413
{
 
414
        struct eap_fast_data *data;
 
415
        u8 ciphers[5] = {
 
416
                TLS_CIPHER_ANON_DH_AES128_SHA,
 
417
                TLS_CIPHER_AES128_SHA,
 
418
                TLS_CIPHER_RSA_DHE_AES128_SHA,
 
419
                TLS_CIPHER_RC4_SHA,
 
420
                TLS_CIPHER_NONE
 
421
        };
 
422
 
 
423
        data = os_zalloc(sizeof(*data));
 
424
        if (data == NULL)
 
425
                return NULL;
 
426
        data->fast_version = EAP_FAST_VERSION;
 
427
        data->force_version = -1;
 
428
        if (sm->user && sm->user->force_version >= 0) {
 
429
                data->force_version = sm->user->force_version;
 
430
                wpa_printf(MSG_DEBUG, "EAP-FAST: forcing version %d",
 
431
                           data->force_version);
 
432
                data->fast_version = data->force_version;
 
433
        }
 
434
        data->state = START;
 
435
 
 
436
        if (eap_server_tls_ssl_init(sm, &data->ssl, 0)) {
 
437
                wpa_printf(MSG_INFO, "EAP-FAST: Failed to initialize SSL.");
 
438
                eap_fast_reset(sm, data);
 
439
                return NULL;
 
440
        }
 
441
 
 
442
        if (tls_connection_set_cipher_list(sm->ssl_ctx, data->ssl.conn,
 
443
                                           ciphers) < 0) {
 
444
                wpa_printf(MSG_INFO, "EAP-FAST: Failed to set TLS cipher "
 
445
                           "suites");
 
446
                eap_fast_reset(sm, data);
 
447
                return NULL;
 
448
        }
 
449
 
 
450
        if (tls_connection_set_session_ticket_cb(sm->ssl_ctx, data->ssl.conn,
 
451
                                                 eap_fast_session_ticket_cb,
 
452
                                                 data) < 0) {
 
453
                wpa_printf(MSG_INFO, "EAP-FAST: Failed to set SessionTicket "
 
454
                           "callback");
 
455
                eap_fast_reset(sm, data);
 
456
                return NULL;
 
457
        }
 
458
 
 
459
        if (sm->pac_opaque_encr_key == NULL) {
 
460
                wpa_printf(MSG_INFO, "EAP-FAST: No PAC-Opaque encryption key "
 
461
                           "configured");
 
462
                eap_fast_reset(sm, data);
 
463
                return NULL;
 
464
        }
 
465
        os_memcpy(data->pac_opaque_encr, sm->pac_opaque_encr_key,
 
466
                  sizeof(data->pac_opaque_encr));
 
467
 
 
468
        if (sm->eap_fast_a_id == NULL) {
 
469
                wpa_printf(MSG_INFO, "EAP-FAST: No A-ID configured");
 
470
                eap_fast_reset(sm, data);
 
471
                return NULL;
 
472
        }
 
473
        data->srv_id = os_malloc(sm->eap_fast_a_id_len);
 
474
        if (data->srv_id == NULL) {
 
475
                eap_fast_reset(sm, data);
 
476
                return NULL;
 
477
        }
 
478
        os_memcpy(data->srv_id, sm->eap_fast_a_id, sm->eap_fast_a_id_len);
 
479
        data->srv_id_len = sm->eap_fast_a_id_len;
 
480
 
 
481
        if (sm->eap_fast_a_id_info == NULL) {
 
482
                wpa_printf(MSG_INFO, "EAP-FAST: No A-ID-Info configured");
 
483
                eap_fast_reset(sm, data);
 
484
                return NULL;
 
485
        }
 
486
        data->srv_id_info = os_strdup(sm->eap_fast_a_id_info);
 
487
        if (data->srv_id_info == NULL) {
 
488
                eap_fast_reset(sm, data);
 
489
                return NULL;
 
490
        }
 
491
 
 
492
        /* PAC-Key lifetime in seconds (hard limit) */
 
493
        data->pac_key_lifetime = sm->pac_key_lifetime;
 
494
 
 
495
        /*
 
496
         * PAC-Key refresh time in seconds (soft limit on remaining hard
 
497
         * limit). The server will generate a new PAC-Key when this number of
 
498
         * seconds (or fewer) of the lifetime remains.
 
499
         */
 
500
        data->pac_key_refresh_time = sm->pac_key_refresh_time;
 
501
 
 
502
        return data;
 
503
}
 
504
 
 
505
 
 
506
static void eap_fast_reset(struct eap_sm *sm, void *priv)
 
507
{
 
508
        struct eap_fast_data *data = priv;
 
509
        if (data == NULL)
 
510
                return;
 
511
        if (data->phase2_priv && data->phase2_method)
 
512
                data->phase2_method->reset(sm, data->phase2_priv);
 
513
        eap_server_tls_ssl_deinit(sm, &data->ssl);
 
514
        os_free(data->srv_id);
 
515
        os_free(data->srv_id_info);
 
516
        os_free(data->key_block_p);
 
517
        wpabuf_free(data->pending_phase2_resp);
 
518
        os_free(data->identity);
 
519
        os_free(data);
 
520
}
 
521
 
 
522
 
 
523
static struct wpabuf * eap_fast_build_start(struct eap_sm *sm,
 
524
                                            struct eap_fast_data *data, u8 id)
 
525
{
 
526
        struct wpabuf *req;
 
527
 
 
528
        req = eap_msg_alloc(EAP_VENDOR_IETF, EAP_TYPE_FAST,
 
529
                            1 + sizeof(struct pac_tlv_hdr) + data->srv_id_len,
 
530
                            EAP_CODE_REQUEST, id);
 
531
        if (req == NULL) {
 
532
                wpa_printf(MSG_ERROR, "EAP-FAST: Failed to allocate memory for"
 
533
                           " request");
 
534
                eap_fast_state(data, FAILURE);
 
535
                return NULL;
 
536
        }
 
537
 
 
538
        wpabuf_put_u8(req, EAP_TLS_FLAGS_START | data->fast_version);
 
539
 
 
540
        /* RFC 4851, 4.1.1. Authority ID Data */
 
541
        eap_fast_put_tlv(req, PAC_TYPE_A_ID, data->srv_id, data->srv_id_len);
 
542
 
 
543
        eap_fast_state(data, PHASE1);
 
544
 
 
545
        return req;
 
546
}
 
547
 
 
548
 
 
549
static int eap_fast_phase1_done(struct eap_sm *sm, struct eap_fast_data *data)
 
550
{
 
551
        char cipher[64];
 
552
 
 
553
        wpa_printf(MSG_DEBUG, "EAP-FAST: Phase1 done, starting Phase2");
 
554
 
 
555
        if (tls_get_cipher(sm->ssl_ctx, data->ssl.conn, cipher, sizeof(cipher))
 
556
            < 0) {
 
557
                wpa_printf(MSG_DEBUG, "EAP-FAST: Failed to get cipher "
 
558
                           "information");
 
559
                eap_fast_state(data, FAILURE);
 
560
                return -1;
 
561
        }
 
562
        data->anon_provisioning = os_strstr(cipher, "ADH") != NULL;
 
563
                    
 
564
        if (data->anon_provisioning) {
 
565
                wpa_printf(MSG_DEBUG, "EAP-FAST: Anonymous provisioning");
 
566
                eap_fast_derive_key_provisioning(sm, data);
 
567
        } else
 
568
                eap_fast_derive_key_auth(sm, data);
 
569
 
 
570
        eap_fast_state(data, PHASE2_START);
 
571
 
 
572
        return 0;
 
573
}
 
574
 
 
575
 
 
576
static struct wpabuf * eap_fast_build_phase2_req(struct eap_sm *sm,
 
577
                                                 struct eap_fast_data *data,
 
578
                                                 u8 id)
 
579
{
 
580
        struct wpabuf *req;
 
581
 
 
582
        if (data->phase2_priv == NULL) {
 
583
                wpa_printf(MSG_DEBUG, "EAP-FAST: Phase 2 method not "
 
584
                           "initialized");
 
585
                return NULL;
 
586
        }
 
587
        req = data->phase2_method->buildReq(sm, data->phase2_priv, id);
 
588
        if (req == NULL)
 
589
                return NULL;
 
590
 
 
591
        wpa_hexdump_buf_key(MSG_MSGDUMP, "EAP-FAST: Phase 2 EAP-Request", req);
 
592
        return eap_fast_tlv_eap_payload(req);
 
593
}
 
594
 
 
595
 
 
596
static struct wpabuf * eap_fast_build_crypto_binding(
 
597
        struct eap_sm *sm, struct eap_fast_data *data)
 
598
{
 
599
        struct wpabuf *buf;
 
600
        struct eap_tlv_result_tlv *result;
 
601
        struct eap_tlv_crypto_binding_tlv *binding;
 
602
 
 
603
        buf = wpabuf_alloc(2 * sizeof(*result) + sizeof(*binding));
 
604
        if (buf == NULL)
 
605
                return NULL;
 
606
 
 
607
        if (data->send_new_pac || data->anon_provisioning ||
 
608
            data->phase2_method)
 
609
                data->final_result = 0;
 
610
        else
 
611
                data->final_result = 1;
 
612
 
 
613
        if (!data->final_result || data->eap_seq > 1) {
 
614
                /* Intermediate-Result */
 
615
                wpa_printf(MSG_DEBUG, "EAP-FAST: Add Intermediate-Result TLV "
 
616
                           "(status=SUCCESS)");
 
617
                result = wpabuf_put(buf, sizeof(*result));
 
618
                result->tlv_type = host_to_be16(
 
619
                        EAP_TLV_TYPE_MANDATORY |
 
620
                        EAP_TLV_INTERMEDIATE_RESULT_TLV);
 
621
                result->length = host_to_be16(2);
 
622
                result->status = host_to_be16(EAP_TLV_RESULT_SUCCESS);
 
623
        }
 
624
 
 
625
        if (data->final_result) {
 
626
                /* Result TLV */
 
627
                wpa_printf(MSG_DEBUG, "EAP-FAST: Add Result TLV "
 
628
                           "(status=SUCCESS)");
 
629
                result = wpabuf_put(buf, sizeof(*result));
 
630
                result->tlv_type = host_to_be16(EAP_TLV_TYPE_MANDATORY |
 
631
                                                EAP_TLV_RESULT_TLV);
 
632
                result->length = host_to_be16(2);
 
633
                result->status = host_to_be16(EAP_TLV_RESULT_SUCCESS);
 
634
        }
 
635
 
 
636
        /* Crypto-Binding TLV */
 
637
        binding = wpabuf_put(buf, sizeof(*binding));
 
638
        binding->tlv_type = host_to_be16(EAP_TLV_TYPE_MANDATORY |
 
639
                                         EAP_TLV_CRYPTO_BINDING_TLV);
 
640
        binding->length = host_to_be16(sizeof(*binding) -
 
641
                                       sizeof(struct eap_tlv_hdr));
 
642
        binding->version = EAP_FAST_VERSION;
 
643
        binding->received_version = data->peer_version;
 
644
        binding->subtype = EAP_TLV_CRYPTO_BINDING_SUBTYPE_REQUEST;
 
645
        if (os_get_random(binding->nonce, sizeof(binding->nonce)) < 0) {
 
646
                wpabuf_free(buf);
 
647
                return NULL;
 
648
        }
 
649
 
 
650
        /*
 
651
         * RFC 4851, Section 4.2.8:
 
652
         * The nonce in a request MUST have its least significant bit set to 0.
 
653
         */
 
654
        binding->nonce[sizeof(binding->nonce) - 1] &= ~0x01;
 
655
 
 
656
        os_memcpy(data->crypto_binding_nonce, binding->nonce,
 
657
                  sizeof(binding->nonce));
 
658
 
 
659
        /*
 
660
         * RFC 4851, Section 5.3:
 
661
         * CMK = CMK[j]
 
662
         * Compound-MAC = HMAC-SHA1( CMK, Crypto-Binding TLV )
 
663
         */
 
664
 
 
665
        hmac_sha1(data->cmk, EAP_FAST_CMK_LEN,
 
666
                  (u8 *) binding, sizeof(*binding),
 
667
                  binding->compound_mac);
 
668
 
 
669
        wpa_printf(MSG_DEBUG, "EAP-FAST: Add Crypto-Binding TLV: Version %d "
 
670
                   "Received Version %d SubType %d",
 
671
                   binding->version, binding->received_version,
 
672
                   binding->subtype);
 
673
        wpa_hexdump(MSG_MSGDUMP, "EAP-FAST: NONCE",
 
674
                    binding->nonce, sizeof(binding->nonce));
 
675
        wpa_hexdump(MSG_MSGDUMP, "EAP-FAST: Compound MAC",
 
676
                    binding->compound_mac, sizeof(binding->compound_mac));
 
677
 
 
678
        return buf;
 
679
}
 
680
 
 
681
 
 
682
static struct wpabuf * eap_fast_build_pac(struct eap_sm *sm,
 
683
                                          struct eap_fast_data *data)
 
684
{
 
685
        u8 pac_key[EAP_FAST_PAC_KEY_LEN];
 
686
        u8 *pac_buf, *pac_opaque;
 
687
        struct wpabuf *buf;
 
688
        u8 *pos;
 
689
        size_t buf_len, srv_id_info_len, pac_len;
 
690
        struct eap_tlv_hdr *pac_tlv;
 
691
        struct pac_tlv_hdr *pac_info;
 
692
        struct eap_tlv_result_tlv *result;
 
693
        struct os_time now;
 
694
 
 
695
        if (os_get_random(pac_key, EAP_FAST_PAC_KEY_LEN) < 0 ||
 
696
            os_get_time(&now) < 0)
 
697
                return NULL;
 
698
        wpa_hexdump_key(MSG_DEBUG, "EAP-FAST: Generated PAC-Key",
 
699
                        pac_key, EAP_FAST_PAC_KEY_LEN);
 
700
 
 
701
        pac_len = (2 + EAP_FAST_PAC_KEY_LEN) + (2 + 4) +
 
702
                (2 + sm->identity_len) + 8;
 
703
        pac_buf = os_malloc(pac_len);
 
704
        if (pac_buf == NULL)
 
705
                return NULL;
 
706
 
 
707
        srv_id_info_len = os_strlen(data->srv_id_info);
 
708
 
 
709
        pos = pac_buf;
 
710
        *pos++ = PAC_OPAQUE_TYPE_KEY;
 
711
        *pos++ = EAP_FAST_PAC_KEY_LEN;
 
712
        os_memcpy(pos, pac_key, EAP_FAST_PAC_KEY_LEN);
 
713
        pos += EAP_FAST_PAC_KEY_LEN;
 
714
 
 
715
        *pos++ = PAC_OPAQUE_TYPE_LIFETIME;
 
716
        *pos++ = 4;
 
717
        WPA_PUT_BE32(pos, now.sec + data->pac_key_lifetime);
 
718
        pos += 4;
 
719
 
 
720
        if (sm->identity) {
 
721
                *pos++ = PAC_OPAQUE_TYPE_IDENTITY;
 
722
                *pos++ = sm->identity_len;
 
723
                os_memcpy(pos, sm->identity, sm->identity_len);
 
724
                pos += sm->identity_len;
 
725
        }
 
726
 
 
727
        pac_len = pos - pac_buf;
 
728
        while (pac_len % 8) {
 
729
                *pos++ = PAC_OPAQUE_TYPE_PAD;
 
730
                pac_len++;
 
731
        }
 
732
 
 
733
        pac_opaque = os_malloc(pac_len + 8);
 
734
        if (pac_opaque == NULL) {
 
735
                os_free(pac_buf);
 
736
                return NULL;
 
737
        }
 
738
        if (aes_wrap(data->pac_opaque_encr, pac_len / 8, pac_buf,
 
739
                     pac_opaque) < 0) {
 
740
                os_free(pac_buf);
 
741
                os_free(pac_opaque);
 
742
                return NULL;
 
743
        }
 
744
        os_free(pac_buf);
 
745
 
 
746
        pac_len += 8;
 
747
        wpa_hexdump(MSG_DEBUG, "EAP-FAST: PAC-Opaque",
 
748
                    pac_opaque, pac_len);
 
749
 
 
750
        buf_len = sizeof(*pac_tlv) +
 
751
                sizeof(struct pac_tlv_hdr) + EAP_FAST_PAC_KEY_LEN +
 
752
                sizeof(struct pac_tlv_hdr) + pac_len +
 
753
                data->srv_id_len + srv_id_info_len + 100 + sizeof(*result);
 
754
        buf = wpabuf_alloc(buf_len);
 
755
        if (buf == NULL) {
 
756
                os_free(pac_opaque);
 
757
                return NULL;
 
758
        }
 
759
 
 
760
        /* Result TLV */
 
761
        wpa_printf(MSG_DEBUG, "EAP-FAST: Add Result TLV (status=SUCCESS)");
 
762
        result = wpabuf_put(buf, sizeof(*result));
 
763
        WPA_PUT_BE16((u8 *) &result->tlv_type,
 
764
                     EAP_TLV_TYPE_MANDATORY | EAP_TLV_RESULT_TLV);
 
765
        WPA_PUT_BE16((u8 *) &result->length, 2);
 
766
        WPA_PUT_BE16((u8 *) &result->status, EAP_TLV_RESULT_SUCCESS);
 
767
 
 
768
        /* PAC TLV */
 
769
        wpa_printf(MSG_DEBUG, "EAP-FAST: Add PAC TLV");
 
770
        pac_tlv = wpabuf_put(buf, sizeof(*pac_tlv));
 
771
        pac_tlv->tlv_type = host_to_be16(EAP_TLV_TYPE_MANDATORY |
 
772
                                         EAP_TLV_PAC_TLV);
 
773
 
 
774
        /* PAC-Key */
 
775
        eap_fast_put_tlv(buf, PAC_TYPE_PAC_KEY, pac_key, EAP_FAST_PAC_KEY_LEN);
 
776
 
 
777
        /* PAC-Opaque */
 
778
        eap_fast_put_tlv(buf, PAC_TYPE_PAC_OPAQUE, pac_opaque, pac_len);
 
779
        os_free(pac_opaque);
 
780
 
 
781
        /* PAC-Info */
 
782
        pac_info = wpabuf_put(buf, sizeof(*pac_info));
 
783
        pac_info->type = host_to_be16(PAC_TYPE_PAC_INFO);
 
784
 
 
785
        /* PAC-Lifetime (inside PAC-Info) */
 
786
        eap_fast_put_tlv_hdr(buf, PAC_TYPE_CRED_LIFETIME, 4);
 
787
        wpabuf_put_be32(buf, now.sec + data->pac_key_lifetime);
 
788
 
 
789
        /* A-ID (inside PAC-Info) */
 
790
        eap_fast_put_tlv(buf, PAC_TYPE_A_ID, data->srv_id, data->srv_id_len);
 
791
        
 
792
        /* Note: headers may be misaligned after A-ID */
 
793
 
 
794
        if (sm->identity) {
 
795
                eap_fast_put_tlv(buf, PAC_TYPE_I_ID, sm->identity,
 
796
                                 sm->identity_len);
 
797
        }
 
798
 
 
799
        /* A-ID-Info (inside PAC-Info) */
 
800
        eap_fast_put_tlv(buf, PAC_TYPE_A_ID_INFO, data->srv_id_info,
 
801
                         srv_id_info_len);
 
802
 
 
803
        /* PAC-Type (inside PAC-Info) */
 
804
        eap_fast_put_tlv_hdr(buf, PAC_TYPE_PAC_TYPE, 2);
 
805
        wpabuf_put_be16(buf, PAC_TYPE_TUNNEL_PAC);
 
806
 
 
807
        /* Update PAC-Info and PAC TLV Length fields */
 
808
        pos = wpabuf_put(buf, 0);
 
809
        pac_info->len = host_to_be16(pos - (u8 *) (pac_info + 1));
 
810
        pac_tlv->length = host_to_be16(pos - (u8 *) (pac_tlv + 1));
 
811
 
 
812
        return buf;
 
813
}
 
814
 
 
815
 
 
816
static int eap_fast_encrypt_phase2(struct eap_sm *sm,
 
817
                                   struct eap_fast_data *data,
 
818
                                   struct wpabuf *plain, int piggyback)
 
819
{
 
820
        struct wpabuf *encr;
 
821
 
 
822
        wpa_hexdump_buf_key(MSG_DEBUG, "EAP-FAST: Encrypting Phase 2 TLVs",
 
823
                            plain);
 
824
        encr = eap_server_tls_encrypt(sm, &data->ssl, plain);
 
825
        wpabuf_free(plain);
 
826
 
 
827
        if (data->ssl.tls_out && piggyback) {
 
828
                wpa_printf(MSG_DEBUG, "EAP-FAST: Piggyback Phase 2 data "
 
829
                           "(len=%d) with last Phase 1 Message (len=%d "
 
830
                           "used=%d)",
 
831
                           (int) wpabuf_len(encr),
 
832
                           (int) wpabuf_len(data->ssl.tls_out),
 
833
                           (int) data->ssl.tls_out_pos);
 
834
                if (wpabuf_resize(&data->ssl.tls_out, wpabuf_len(encr)) < 0) {
 
835
                        wpa_printf(MSG_WARNING, "EAP-FAST: Failed to resize "
 
836
                                   "output buffer");
 
837
                        wpabuf_free(encr);
 
838
                        return -1;
 
839
                }
 
840
                wpabuf_put_buf(data->ssl.tls_out, encr);
 
841
                wpabuf_free(encr);
 
842
        } else {
 
843
                wpabuf_free(data->ssl.tls_out);
 
844
                data->ssl.tls_out_pos = 0;
 
845
                data->ssl.tls_out = encr;
 
846
        }
 
847
 
 
848
        return 0;
 
849
}
 
850
 
 
851
 
 
852
static struct wpabuf * eap_fast_buildReq(struct eap_sm *sm, void *priv, u8 id)
 
853
{
 
854
        struct eap_fast_data *data = priv;
 
855
        struct wpabuf *req = NULL;
 
856
        int piggyback = 0;
 
857
 
 
858
        if (data->ssl.state == FRAG_ACK) {
 
859
                return eap_server_tls_build_ack(id, EAP_TYPE_FAST,
 
860
                                                data->fast_version);
 
861
        }
 
862
 
 
863
        if (data->ssl.state == WAIT_FRAG_ACK) {
 
864
                return eap_server_tls_build_msg(&data->ssl, EAP_TYPE_FAST,
 
865
                                                data->fast_version, id);
 
866
        }
 
867
 
 
868
        switch (data->state) {
 
869
        case START:
 
870
                return eap_fast_build_start(sm, data, id);
 
871
        case PHASE1:
 
872
                if (tls_connection_established(sm->ssl_ctx, data->ssl.conn)) {
 
873
                        if (eap_fast_phase1_done(sm, data) < 0)
 
874
                                return NULL;
 
875
                        if (data->state == PHASE2_START) {
 
876
                                /*
 
877
                                 * Try to generate Phase 2 data to piggyback
 
878
                                 * with the end of Phase 1 to avoid extra
 
879
                                 * roundtrip.
 
880
                                 */
 
881
                                wpa_printf(MSG_DEBUG, "EAP-FAST: Try to start "
 
882
                                           "Phase 2");
 
883
                                if (eap_fast_process_phase2_start(sm, data))
 
884
                                        break;
 
885
                                req = eap_fast_build_phase2_req(sm, data, id);
 
886
                                piggyback = 1;
 
887
                        }
 
888
                }
 
889
                break;
 
890
        case PHASE2_ID:
 
891
        case PHASE2_METHOD:
 
892
                req = eap_fast_build_phase2_req(sm, data, id);
 
893
                break;
 
894
        case CRYPTO_BINDING:
 
895
                req = eap_fast_build_crypto_binding(sm, data);
 
896
                if (data->phase2_method) {
 
897
                        /*
 
898
                         * Include the start of the next EAP method in the
 
899
                         * sequence in the same message with Crypto-Binding to
 
900
                         * save a round-trip.
 
901
                         */
 
902
                        struct wpabuf *eap;
 
903
                        eap = eap_fast_build_phase2_req(sm, data, id);
 
904
                        req = wpabuf_concat(req, eap);
 
905
                        eap_fast_state(data, PHASE2_METHOD);
 
906
                }
 
907
                break;
 
908
        case REQUEST_PAC:
 
909
                req = eap_fast_build_pac(sm, data);
 
910
                break;
 
911
        default:
 
912
                wpa_printf(MSG_DEBUG, "EAP-FAST: %s - unexpected state %d",
 
913
                           __func__, data->state);
 
914
                return NULL;
 
915
        }
 
916
 
 
917
        if (req &&
 
918
            eap_fast_encrypt_phase2(sm, data, req, piggyback) < 0)
 
919
                return NULL;
 
920
 
 
921
        return eap_server_tls_build_msg(&data->ssl, EAP_TYPE_FAST,
 
922
                                        data->fast_version, id);
 
923
}
 
924
 
 
925
 
 
926
static Boolean eap_fast_check(struct eap_sm *sm, void *priv,
 
927
                              struct wpabuf *respData)
 
928
{
 
929
        const u8 *pos;
 
930
        size_t len;
 
931
 
 
932
        pos = eap_hdr_validate(EAP_VENDOR_IETF, EAP_TYPE_FAST, respData, &len);
 
933
        if (pos == NULL || len < 1) {
 
934
                wpa_printf(MSG_INFO, "EAP-FAST: Invalid frame");
 
935
                return TRUE;
 
936
        }
 
937
 
 
938
        return FALSE;
 
939
}
 
940
 
 
941
 
 
942
static int eap_fast_phase2_init(struct eap_sm *sm, struct eap_fast_data *data,
 
943
                                EapType eap_type)
 
944
{
 
945
        if (data->phase2_priv && data->phase2_method) {
 
946
                data->phase2_method->reset(sm, data->phase2_priv);
 
947
                data->phase2_method = NULL;
 
948
                data->phase2_priv = NULL;
 
949
        }
 
950
        data->phase2_method = eap_server_get_eap_method(EAP_VENDOR_IETF,
 
951
                                                        eap_type);
 
952
        if (!data->phase2_method)
 
953
                return -1;
 
954
 
 
955
        if (data->key_block_p) {
 
956
                sm->auth_challenge = data->key_block_p->server_challenge;
 
957
                sm->peer_challenge = data->key_block_p->client_challenge;
 
958
        }
 
959
        sm->init_phase2 = 1;
 
960
        data->phase2_priv = data->phase2_method->init(sm);
 
961
        sm->init_phase2 = 0;
 
962
        sm->auth_challenge = NULL;
 
963
        sm->peer_challenge = NULL;
 
964
 
 
965
        return data->phase2_priv == NULL ? -1 : 0;
 
966
}
 
967
 
 
968
 
 
969
static void eap_fast_process_phase2_response(struct eap_sm *sm,
 
970
                                             struct eap_fast_data *data,
 
971
                                             u8 *in_data, size_t in_len)
 
972
{
 
973
        u8 next_type = EAP_TYPE_NONE;
 
974
        struct eap_hdr *hdr;
 
975
        u8 *pos;
 
976
        size_t left;
 
977
        struct wpabuf buf;
 
978
        const struct eap_method *m = data->phase2_method;
 
979
        void *priv = data->phase2_priv;
 
980
 
 
981
        if (priv == NULL) {
 
982
                wpa_printf(MSG_DEBUG, "EAP-FAST: %s - Phase2 not "
 
983
                           "initialized?!", __func__);
 
984
                return;
 
985
        }
 
986
 
 
987
        hdr = (struct eap_hdr *) in_data;
 
988
        pos = (u8 *) (hdr + 1);
 
989
 
 
990
        if (in_len > sizeof(*hdr) && *pos == EAP_TYPE_NAK) {
 
991
                left = in_len - sizeof(*hdr);
 
992
                wpa_hexdump(MSG_DEBUG, "EAP-FAST: Phase2 type Nak'ed; "
 
993
                            "allowed types", pos + 1, left - 1);
 
994
#ifdef EAP_SERVER_TNC
 
995
                if (m && m->vendor == EAP_VENDOR_IETF &&
 
996
                    m->method == EAP_TYPE_TNC) {
 
997
                        wpa_printf(MSG_DEBUG, "EAP-FAST: Peer Nak'ed required "
 
998
                                   "TNC negotiation");
 
999
                        next_type = eap_fast_req_failure(sm, data);
 
1000
                        eap_fast_phase2_init(sm, data, next_type);
 
1001
                        return;
 
1002
                }
 
1003
#endif /* EAP_SERVER_TNC */
 
1004
                eap_sm_process_nak(sm, pos + 1, left - 1);
 
1005
                if (sm->user && sm->user_eap_method_index < EAP_MAX_METHODS &&
 
1006
                    sm->user->methods[sm->user_eap_method_index].method !=
 
1007
                    EAP_TYPE_NONE) {
 
1008
                        next_type = sm->user->methods[
 
1009
                                sm->user_eap_method_index++].method;
 
1010
                        wpa_printf(MSG_DEBUG, "EAP-FAST: try EAP type %d",
 
1011
                                   next_type);
 
1012
                } else {
 
1013
                        next_type = eap_fast_req_failure(sm, data);
 
1014
                }
 
1015
                eap_fast_phase2_init(sm, data, next_type);
 
1016
                return;
 
1017
        }
 
1018
 
 
1019
        wpabuf_set(&buf, in_data, in_len);
 
1020
 
 
1021
        if (m->check(sm, priv, &buf)) {
 
1022
                wpa_printf(MSG_DEBUG, "EAP-FAST: Phase2 check() asked to "
 
1023
                           "ignore the packet");
 
1024
                next_type = eap_fast_req_failure(sm, data);
 
1025
                return;
 
1026
        }
 
1027
 
 
1028
        m->process(sm, priv, &buf);
 
1029
 
 
1030
        if (!m->isDone(sm, priv))
 
1031
                return;
 
1032
 
 
1033
        if (!m->isSuccess(sm, priv)) {
 
1034
                wpa_printf(MSG_DEBUG, "EAP-FAST: Phase2 method failed");
 
1035
                next_type = eap_fast_req_failure(sm, data);
 
1036
                eap_fast_phase2_init(sm, data, next_type);
 
1037
                return;
 
1038
        }
 
1039
 
 
1040
        switch (data->state) {
 
1041
        case PHASE2_ID:
 
1042
                if (eap_user_get(sm, sm->identity, sm->identity_len, 1) != 0) {
 
1043
                        wpa_hexdump_ascii(MSG_DEBUG, "EAP-FAST: Phase2 "
 
1044
                                          "Identity not found in the user "
 
1045
                                          "database",
 
1046
                                          sm->identity, sm->identity_len);
 
1047
                        next_type = eap_fast_req_failure(sm, data);
 
1048
                        break;
 
1049
                }
 
1050
 
 
1051
                eap_fast_state(data, PHASE2_METHOD);
 
1052
                if (data->anon_provisioning) {
 
1053
                        /*
 
1054
                         * Only EAP-MSCHAPv2 is allowed for anonymous
 
1055
                         * provisioning.
 
1056
                         */
 
1057
                        next_type = EAP_TYPE_MSCHAPV2;
 
1058
                        sm->user_eap_method_index = 0;
 
1059
                } else {
 
1060
                        next_type = sm->user->methods[0].method;
 
1061
                        sm->user_eap_method_index = 1;
 
1062
                }
 
1063
                wpa_printf(MSG_DEBUG, "EAP-FAST: try EAP type %d", next_type);
 
1064
                break;
 
1065
        case PHASE2_METHOD:
 
1066
        case CRYPTO_BINDING:
 
1067
                eap_fast_update_icmk(sm, data);
 
1068
                eap_fast_state(data, CRYPTO_BINDING);
 
1069
                data->eap_seq++;
 
1070
                next_type = EAP_TYPE_NONE;
 
1071
#ifdef EAP_SERVER_TNC
 
1072
                if (sm->tnc && !data->tnc_started) {
 
1073
                        wpa_printf(MSG_DEBUG, "EAP-FAST: Initialize TNC");
 
1074
                        next_type = EAP_TYPE_TNC;
 
1075
                        data->tnc_started = 1;
 
1076
                }
 
1077
#endif /* EAP_SERVER_TNC */
 
1078
                break;
 
1079
        case FAILURE:
 
1080
                break;
 
1081
        default:
 
1082
                wpa_printf(MSG_DEBUG, "EAP-FAST: %s - unexpected state %d",
 
1083
                           __func__, data->state);
 
1084
                break;
 
1085
        }
 
1086
 
 
1087
        eap_fast_phase2_init(sm, data, next_type);
 
1088
}
 
1089
 
 
1090
 
 
1091
static void eap_fast_process_phase2_eap(struct eap_sm *sm,
 
1092
                                        struct eap_fast_data *data,
 
1093
                                        u8 *in_data, size_t in_len)
 
1094
{
 
1095
        struct eap_hdr *hdr;
 
1096
        size_t len;
 
1097
 
 
1098
        hdr = (struct eap_hdr *) in_data;
 
1099
        if (in_len < (int) sizeof(*hdr)) {
 
1100
                wpa_printf(MSG_INFO, "EAP-FAST: Too short Phase 2 "
 
1101
                           "EAP frame (len=%lu)", (unsigned long) in_len);
 
1102
                eap_fast_req_failure(sm, data);
 
1103
                return;
 
1104
        }
 
1105
        len = be_to_host16(hdr->length);
 
1106
        if (len > in_len) {
 
1107
                wpa_printf(MSG_INFO, "EAP-FAST: Length mismatch in "
 
1108
                           "Phase 2 EAP frame (len=%lu hdr->length=%lu)",
 
1109
                           (unsigned long) in_len, (unsigned long) len);
 
1110
                eap_fast_req_failure(sm, data);
 
1111
                return;
 
1112
        }
 
1113
        wpa_printf(MSG_DEBUG, "EAP-FAST: Received Phase 2: code=%d "
 
1114
                   "identifier=%d length=%lu", hdr->code, hdr->identifier,
 
1115
                   (unsigned long) len);
 
1116
        switch (hdr->code) {
 
1117
        case EAP_CODE_RESPONSE:
 
1118
                eap_fast_process_phase2_response(sm, data, (u8 *) hdr, len);
 
1119
                break;
 
1120
        default:
 
1121
                wpa_printf(MSG_INFO, "EAP-FAST: Unexpected code=%d in "
 
1122
                           "Phase 2 EAP header", hdr->code);
 
1123
                break;
 
1124
        }
 
1125
}
 
1126
 
 
1127
 
 
1128
static int eap_fast_parse_tlvs(struct wpabuf *data,
 
1129
                               struct eap_fast_tlv_parse *tlv)
 
1130
{
 
1131
        int mandatory, tlv_type, len, res;
 
1132
        u8 *pos, *end;
 
1133
 
 
1134
        os_memset(tlv, 0, sizeof(*tlv));
 
1135
 
 
1136
        pos = wpabuf_mhead(data);
 
1137
        end = pos + wpabuf_len(data);
 
1138
        while (pos + 4 < end) {
 
1139
                mandatory = pos[0] & 0x80;
 
1140
                tlv_type = WPA_GET_BE16(pos) & 0x3fff;
 
1141
                pos += 2;
 
1142
                len = WPA_GET_BE16(pos);
 
1143
                pos += 2;
 
1144
                if (pos + len > end) {
 
1145
                        wpa_printf(MSG_INFO, "EAP-FAST: TLV overflow");
 
1146
                        return -1;
 
1147
                }
 
1148
                wpa_printf(MSG_DEBUG, "EAP-FAST: Received Phase 2: "
 
1149
                           "TLV type %d length %d%s",
 
1150
                           tlv_type, len, mandatory ? " (mandatory)" : "");
 
1151
 
 
1152
                res = eap_fast_parse_tlv(tlv, tlv_type, pos, len);
 
1153
                if (res == -2)
 
1154
                        break;
 
1155
                if (res < 0) {
 
1156
                        if (mandatory) {
 
1157
                                wpa_printf(MSG_DEBUG, "EAP-FAST: Nak unknown "
 
1158
                                           "mandatory TLV type %d", tlv_type);
 
1159
                                /* TODO: generate Nak TLV */
 
1160
                                break;
 
1161
                        } else {
 
1162
                                wpa_printf(MSG_DEBUG, "EAP-FAST: Ignored "
 
1163
                                           "unknown optional TLV type %d",
 
1164
                                           tlv_type);
 
1165
                        }
 
1166
                }
 
1167
 
 
1168
                pos += len;
 
1169
        }
 
1170
 
 
1171
        return 0;
 
1172
}
 
1173
 
 
1174
 
 
1175
static int eap_fast_validate_crypto_binding(
 
1176
        struct eap_fast_data *data, struct eap_tlv_crypto_binding_tlv *b,
 
1177
        size_t bind_len)
 
1178
{
 
1179
        u8 cmac[SHA1_MAC_LEN];
 
1180
 
 
1181
        wpa_printf(MSG_DEBUG, "EAP-FAST: Reply Crypto-Binding TLV: "
 
1182
                   "Version %d Received Version %d SubType %d",
 
1183
                   b->version, b->received_version, b->subtype);
 
1184
        wpa_hexdump(MSG_MSGDUMP, "EAP-FAST: NONCE",
 
1185
                    b->nonce, sizeof(b->nonce));
 
1186
        wpa_hexdump(MSG_MSGDUMP, "EAP-FAST: Compound MAC",
 
1187
                    b->compound_mac, sizeof(b->compound_mac));
 
1188
 
 
1189
        if (b->version != EAP_FAST_VERSION ||
 
1190
            b->received_version != EAP_FAST_VERSION) {
 
1191
                wpa_printf(MSG_DEBUG, "EAP-FAST: Unexpected version "
 
1192
                           "in Crypto-Binding: version %d "
 
1193
                           "received_version %d", b->version,
 
1194
                           b->received_version);
 
1195
                return -1;
 
1196
        }
 
1197
 
 
1198
        if (b->subtype != EAP_TLV_CRYPTO_BINDING_SUBTYPE_RESPONSE) {
 
1199
                wpa_printf(MSG_DEBUG, "EAP-FAST: Unexpected subtype in "
 
1200
                           "Crypto-Binding: %d", b->subtype);
 
1201
                return -1;
 
1202
        }
 
1203
 
 
1204
        if (os_memcmp(data->crypto_binding_nonce, b->nonce, 31) != 0 ||
 
1205
            (data->crypto_binding_nonce[31] | 1) != b->nonce[31]) {
 
1206
                wpa_printf(MSG_DEBUG, "EAP-FAST: Invalid nonce in "
 
1207
                           "Crypto-Binding");
 
1208
                return -1;
 
1209
        }
 
1210
 
 
1211
        os_memcpy(cmac, b->compound_mac, sizeof(cmac));
 
1212
        os_memset(b->compound_mac, 0, sizeof(cmac));
 
1213
        wpa_hexdump(MSG_MSGDUMP, "EAP-FAST: Crypto-Binding TLV for "
 
1214
                    "Compound MAC calculation",
 
1215
                    (u8 *) b, bind_len);
 
1216
        hmac_sha1(data->cmk, EAP_FAST_CMK_LEN, (u8 *) b, bind_len,
 
1217
                  b->compound_mac);
 
1218
        if (os_memcmp(cmac, b->compound_mac, sizeof(cmac)) != 0) {
 
1219
                wpa_hexdump(MSG_MSGDUMP,
 
1220
                            "EAP-FAST: Calculated Compound MAC",
 
1221
                            b->compound_mac, sizeof(cmac));
 
1222
                wpa_printf(MSG_INFO, "EAP-FAST: Compound MAC did not "
 
1223
                           "match");
 
1224
                return -1;
 
1225
        }
 
1226
 
 
1227
        return 0;
 
1228
}
 
1229
 
 
1230
 
 
1231
static int eap_fast_pac_type(u8 *pac, size_t len, u16 type)
 
1232
{
 
1233
        struct eap_tlv_pac_type_tlv *tlv;
 
1234
 
 
1235
        if (pac == NULL || len != sizeof(*tlv))
 
1236
                return 0;
 
1237
 
 
1238
        tlv = (struct eap_tlv_pac_type_tlv *) pac;
 
1239
 
 
1240
        return be_to_host16(tlv->tlv_type) == PAC_TYPE_PAC_TYPE &&
 
1241
                be_to_host16(tlv->length) == 2 &&
 
1242
                be_to_host16(tlv->pac_type) == type;
 
1243
}
 
1244
 
 
1245
 
 
1246
static void eap_fast_process_phase2_tlvs(struct eap_sm *sm,
 
1247
                                         struct eap_fast_data *data,
 
1248
                                         struct wpabuf *in_data)
 
1249
{
 
1250
        struct eap_fast_tlv_parse tlv;
 
1251
        int check_crypto_binding = data->state == CRYPTO_BINDING;
 
1252
 
 
1253
        if (eap_fast_parse_tlvs(in_data, &tlv) < 0) {
 
1254
                wpa_printf(MSG_DEBUG, "EAP-FAST: Failed to parse received "
 
1255
                           "Phase 2 TLVs");
 
1256
                return;
 
1257
        }
 
1258
 
 
1259
        if (tlv.result == EAP_TLV_RESULT_FAILURE) {
 
1260
                wpa_printf(MSG_DEBUG, "EAP-FAST: Result TLV indicated "
 
1261
                           "failure");
 
1262
                eap_fast_state(data, FAILURE);
 
1263
                return;
 
1264
        }
 
1265
 
 
1266
        if (data->state == REQUEST_PAC) {
 
1267
                u16 type, len, res;
 
1268
                if (tlv.pac == NULL || tlv.pac_len < 6) {
 
1269
                        wpa_printf(MSG_DEBUG, "EAP-FAST: No PAC "
 
1270
                                   "Acknowledgement received");
 
1271
                        eap_fast_state(data, FAILURE);
 
1272
                        return;
 
1273
                }
 
1274
 
 
1275
                type = WPA_GET_BE16(tlv.pac);
 
1276
                len = WPA_GET_BE16(tlv.pac + 2);
 
1277
                res = WPA_GET_BE16(tlv.pac + 4);
 
1278
 
 
1279
                if (type != PAC_TYPE_PAC_ACKNOWLEDGEMENT || len != 2 ||
 
1280
                    res != EAP_TLV_RESULT_SUCCESS) {
 
1281
                        wpa_printf(MSG_DEBUG, "EAP-FAST: PAC TLV did not "
 
1282
                                   "contain acknowledgement");
 
1283
                        eap_fast_state(data, FAILURE);
 
1284
                        return;
 
1285
                }
 
1286
 
 
1287
                wpa_printf(MSG_DEBUG, "EAP-FAST: PAC-Acknowledgement received "
 
1288
                           "- PAC provisioning succeeded");
 
1289
                eap_fast_state(data, (data->anon_provisioning ||
 
1290
                                      data->send_new_pac == 2) ?
 
1291
                               FAILURE : SUCCESS);
 
1292
                return;
 
1293
        }
 
1294
 
 
1295
        if (check_crypto_binding) {
 
1296
                if (tlv.crypto_binding == NULL) {
 
1297
                        wpa_printf(MSG_DEBUG, "EAP-FAST: No Crypto-Binding "
 
1298
                                   "TLV received");
 
1299
                        eap_fast_state(data, FAILURE);
 
1300
                        return;
 
1301
                }
 
1302
 
 
1303
                if (data->final_result &&
 
1304
                    tlv.result != EAP_TLV_RESULT_SUCCESS) {
 
1305
                        wpa_printf(MSG_DEBUG, "EAP-FAST: Crypto-Binding TLV "
 
1306
                                   "without Success Result");
 
1307
                        eap_fast_state(data, FAILURE);
 
1308
                        return;
 
1309
                }
 
1310
 
 
1311
                if (!data->final_result &&
 
1312
                    tlv.iresult != EAP_TLV_RESULT_SUCCESS) {
 
1313
                        wpa_printf(MSG_DEBUG, "EAP-FAST: Crypto-Binding TLV "
 
1314
                                   "without intermediate Success Result");
 
1315
                        eap_fast_state(data, FAILURE);
 
1316
                        return;
 
1317
                }
 
1318
 
 
1319
                if (eap_fast_validate_crypto_binding(data, tlv.crypto_binding,
 
1320
                                                     tlv.crypto_binding_len)) {
 
1321
                        eap_fast_state(data, FAILURE);
 
1322
                        return;
 
1323
                }
 
1324
 
 
1325
                wpa_printf(MSG_DEBUG, "EAP-FAST: Valid Crypto-Binding TLV "
 
1326
                           "received");
 
1327
                if (data->final_result) {
 
1328
                        wpa_printf(MSG_DEBUG, "EAP-FAST: Authentication "
 
1329
                                   "completed successfully");
 
1330
                }
 
1331
 
 
1332
                if (data->anon_provisioning &&
 
1333
                    sm->eap_fast_prov != ANON_PROV &&
 
1334
                    sm->eap_fast_prov != BOTH_PROV) {
 
1335
                        wpa_printf(MSG_DEBUG, "EAP-FAST: Client is trying to "
 
1336
                                   "use unauthenticated provisioning which is "
 
1337
                                   "disabled");
 
1338
                        eap_fast_state(data, FAILURE);
 
1339
                        return;
 
1340
                }
 
1341
 
 
1342
                if (sm->eap_fast_prov != AUTH_PROV &&
 
1343
                    sm->eap_fast_prov != BOTH_PROV &&
 
1344
                    tlv.request_action == EAP_TLV_ACTION_PROCESS_TLV &&
 
1345
                    eap_fast_pac_type(tlv.pac, tlv.pac_len,
 
1346
                                      PAC_TYPE_TUNNEL_PAC)) {
 
1347
                        wpa_printf(MSG_DEBUG, "EAP-FAST: Client is trying to "
 
1348
                                   "use authenticated provisioning which is "
 
1349
                                   "disabled");
 
1350
                        eap_fast_state(data, FAILURE);
 
1351
                        return;
 
1352
                }
 
1353
 
 
1354
                if (data->anon_provisioning ||
 
1355
                    (tlv.request_action == EAP_TLV_ACTION_PROCESS_TLV &&
 
1356
                     eap_fast_pac_type(tlv.pac, tlv.pac_len,
 
1357
                                       PAC_TYPE_TUNNEL_PAC))) {
 
1358
                        wpa_printf(MSG_DEBUG, "EAP-FAST: Requested a new "
 
1359
                                   "Tunnel PAC");
 
1360
                        eap_fast_state(data, REQUEST_PAC);
 
1361
                } else if (data->send_new_pac) {
 
1362
                        wpa_printf(MSG_DEBUG, "EAP-FAST: Server triggered "
 
1363
                                   "re-keying of Tunnel PAC");
 
1364
                        eap_fast_state(data, REQUEST_PAC);
 
1365
                } else if (data->final_result)
 
1366
                        eap_fast_state(data, SUCCESS);
 
1367
        }
 
1368
 
 
1369
        if (tlv.eap_payload_tlv) {
 
1370
                eap_fast_process_phase2_eap(sm, data, tlv.eap_payload_tlv,
 
1371
                                            tlv.eap_payload_tlv_len);
 
1372
        }
 
1373
}
 
1374
 
 
1375
 
 
1376
static void eap_fast_process_phase2(struct eap_sm *sm,
 
1377
                                    struct eap_fast_data *data,
 
1378
                                    struct wpabuf *in_buf)
 
1379
{
 
1380
        struct wpabuf *in_decrypted;
 
1381
 
 
1382
        wpa_printf(MSG_DEBUG, "EAP-FAST: Received %lu bytes encrypted data for"
 
1383
                   " Phase 2", (unsigned long) wpabuf_len(in_buf));
 
1384
 
 
1385
        if (data->pending_phase2_resp) {
 
1386
                wpa_printf(MSG_DEBUG, "EAP-PEAP: Pending Phase 2 response - "
 
1387
                           "skip decryption and use old data");
 
1388
                eap_fast_process_phase2_tlvs(sm, data,
 
1389
                                             data->pending_phase2_resp);
 
1390
                wpabuf_free(data->pending_phase2_resp);
 
1391
                data->pending_phase2_resp = NULL;
 
1392
                return;
 
1393
        }
 
1394
 
 
1395
        in_decrypted = tls_connection_decrypt(sm->ssl_ctx, data->ssl.conn,
 
1396
                                              in_buf);
 
1397
        if (in_decrypted == NULL) {
 
1398
                wpa_printf(MSG_INFO, "EAP-FAST: Failed to decrypt Phase 2 "
 
1399
                           "data");
 
1400
                eap_fast_state(data, FAILURE);
 
1401
                return;
 
1402
        }
 
1403
 
 
1404
        wpa_hexdump_buf_key(MSG_DEBUG, "EAP-FAST: Decrypted Phase 2 TLVs",
 
1405
                            in_decrypted);
 
1406
 
 
1407
        eap_fast_process_phase2_tlvs(sm, data, in_decrypted);
 
1408
 
 
1409
        if (sm->method_pending == METHOD_PENDING_WAIT) {
 
1410
                wpa_printf(MSG_DEBUG, "EAP-FAST: Phase2 method is in "
 
1411
                           "pending wait state - save decrypted response");
 
1412
                wpabuf_free(data->pending_phase2_resp);
 
1413
                data->pending_phase2_resp = in_decrypted;
 
1414
                return;
 
1415
        }
 
1416
 
 
1417
        wpabuf_free(in_decrypted);
 
1418
}
 
1419
 
 
1420
 
 
1421
static int eap_fast_process_version(struct eap_sm *sm, void *priv,
 
1422
                                    int peer_version)
 
1423
{
 
1424
        struct eap_fast_data *data = priv;
 
1425
 
 
1426
        data->peer_version = peer_version;
 
1427
 
 
1428
        if (data->force_version >= 0 && peer_version != data->force_version) {
 
1429
                wpa_printf(MSG_INFO, "EAP-FAST: peer did not select the forced"
 
1430
                           " version (forced=%d peer=%d) - reject",
 
1431
                           data->force_version, peer_version);
 
1432
                return -1;
 
1433
        }
 
1434
 
 
1435
        if (peer_version < data->fast_version) {
 
1436
                wpa_printf(MSG_DEBUG, "EAP-FAST: peer ver=%d, own ver=%d; "
 
1437
                           "use version %d",
 
1438
                           peer_version, data->fast_version, peer_version);
 
1439
                data->fast_version = peer_version;
 
1440
        }
 
1441
 
 
1442
        return 0;
 
1443
}
 
1444
 
 
1445
 
 
1446
static int eap_fast_process_phase1(struct eap_sm *sm,
 
1447
                                   struct eap_fast_data *data)
 
1448
{
 
1449
        if (eap_server_tls_phase1(sm, &data->ssl) < 0) {
 
1450
                wpa_printf(MSG_INFO, "EAP-FAST: TLS processing failed");
 
1451
                eap_fast_state(data, FAILURE);
 
1452
                return -1;
 
1453
        }
 
1454
 
 
1455
        if (!tls_connection_established(sm->ssl_ctx, data->ssl.conn) ||
 
1456
            wpabuf_len(data->ssl.tls_out) > 0)
 
1457
                return 1;
 
1458
 
 
1459
        /*
 
1460
         * Phase 1 was completed with the received message (e.g., when using
 
1461
         * abbreviated handshake), so Phase 2 can be started immediately
 
1462
         * without having to send through an empty message to the peer.
 
1463
         */
 
1464
 
 
1465
        return eap_fast_phase1_done(sm, data);
 
1466
}
 
1467
 
 
1468
 
 
1469
static int eap_fast_process_phase2_start(struct eap_sm *sm,
 
1470
                                         struct eap_fast_data *data)
 
1471
{
 
1472
        u8 next_type;
 
1473
 
 
1474
        if (data->identity) {
 
1475
                os_free(sm->identity);
 
1476
                sm->identity = data->identity;
 
1477
                data->identity = NULL;
 
1478
                sm->identity_len = data->identity_len;
 
1479
                data->identity_len = 0;
 
1480
                sm->require_identity_match = 1;
 
1481
                if (eap_user_get(sm, sm->identity, sm->identity_len, 1) != 0) {
 
1482
                        wpa_hexdump_ascii(MSG_DEBUG, "EAP-FAST: "
 
1483
                                          "Phase2 Identity not found "
 
1484
                                          "in the user database",
 
1485
                                          sm->identity, sm->identity_len);
 
1486
                        next_type = eap_fast_req_failure(sm, data);
 
1487
                } else {
 
1488
                        wpa_printf(MSG_DEBUG, "EAP-FAST: Identity already "
 
1489
                                   "known - skip Phase 2 Identity Request");
 
1490
                        next_type = sm->user->methods[0].method;
 
1491
                        sm->user_eap_method_index = 1;
 
1492
                }
 
1493
 
 
1494
                eap_fast_state(data, PHASE2_METHOD);
 
1495
        } else {
 
1496
                eap_fast_state(data, PHASE2_ID);
 
1497
                next_type = EAP_TYPE_IDENTITY;
 
1498
        }
 
1499
 
 
1500
        return eap_fast_phase2_init(sm, data, next_type);
 
1501
}
 
1502
 
 
1503
 
 
1504
static void eap_fast_process_msg(struct eap_sm *sm, void *priv,
 
1505
                                 const struct wpabuf *respData)
 
1506
{
 
1507
        struct eap_fast_data *data = priv;
 
1508
 
 
1509
        switch (data->state) {
 
1510
        case PHASE1:
 
1511
                if (eap_fast_process_phase1(sm, data))
 
1512
                        break;
 
1513
 
 
1514
                /* fall through to PHASE2_START */
 
1515
        case PHASE2_START:
 
1516
                eap_fast_process_phase2_start(sm, data);
 
1517
                break;
 
1518
        case PHASE2_ID:
 
1519
        case PHASE2_METHOD:
 
1520
        case CRYPTO_BINDING:
 
1521
        case REQUEST_PAC:
 
1522
                eap_fast_process_phase2(sm, data, data->ssl.tls_in);
 
1523
                break;
 
1524
        default:
 
1525
                wpa_printf(MSG_DEBUG, "EAP-FAST: Unexpected state %d in %s",
 
1526
                           data->state, __func__);
 
1527
                break;
 
1528
        }
 
1529
}
 
1530
 
 
1531
 
 
1532
static void eap_fast_process(struct eap_sm *sm, void *priv,
 
1533
                             struct wpabuf *respData)
 
1534
{
 
1535
        struct eap_fast_data *data = priv;
 
1536
        if (eap_server_tls_process(sm, &data->ssl, respData, data,
 
1537
                                   EAP_TYPE_FAST, eap_fast_process_version,
 
1538
                                   eap_fast_process_msg) < 0)
 
1539
                eap_fast_state(data, FAILURE);
 
1540
}
 
1541
 
 
1542
 
 
1543
static Boolean eap_fast_isDone(struct eap_sm *sm, void *priv)
 
1544
{
 
1545
        struct eap_fast_data *data = priv;
 
1546
        return data->state == SUCCESS || data->state == FAILURE;
 
1547
}
 
1548
 
 
1549
 
 
1550
static u8 * eap_fast_getKey(struct eap_sm *sm, void *priv, size_t *len)
 
1551
{
 
1552
        struct eap_fast_data *data = priv;
 
1553
        u8 *eapKeyData;
 
1554
 
 
1555
        if (data->state != SUCCESS)
 
1556
                return NULL;
 
1557
 
 
1558
        eapKeyData = os_malloc(EAP_FAST_KEY_LEN);
 
1559
        if (eapKeyData == NULL)
 
1560
                return NULL;
 
1561
 
 
1562
        eap_fast_derive_eap_msk(data->simck, eapKeyData);
 
1563
        *len = EAP_FAST_KEY_LEN;
 
1564
 
 
1565
        return eapKeyData;
 
1566
}
 
1567
 
 
1568
 
 
1569
static u8 * eap_fast_get_emsk(struct eap_sm *sm, void *priv, size_t *len)
 
1570
{
 
1571
        struct eap_fast_data *data = priv;
 
1572
        u8 *eapKeyData;
 
1573
 
 
1574
        if (data->state != SUCCESS)
 
1575
                return NULL;
 
1576
 
 
1577
        eapKeyData = os_malloc(EAP_EMSK_LEN);
 
1578
        if (eapKeyData == NULL)
 
1579
                return NULL;
 
1580
 
 
1581
        eap_fast_derive_eap_emsk(data->simck, eapKeyData);
 
1582
        *len = EAP_EMSK_LEN;
 
1583
 
 
1584
        return eapKeyData;
 
1585
}
 
1586
 
 
1587
 
 
1588
static Boolean eap_fast_isSuccess(struct eap_sm *sm, void *priv)
 
1589
{
 
1590
        struct eap_fast_data *data = priv;
 
1591
        return data->state == SUCCESS;
 
1592
}
 
1593
 
 
1594
 
 
1595
int eap_server_fast_register(void)
 
1596
{
 
1597
        struct eap_method *eap;
 
1598
        int ret;
 
1599
 
 
1600
        eap = eap_server_method_alloc(EAP_SERVER_METHOD_INTERFACE_VERSION,
 
1601
                                      EAP_VENDOR_IETF, EAP_TYPE_FAST, "FAST");
 
1602
        if (eap == NULL)
 
1603
                return -1;
 
1604
 
 
1605
        eap->init = eap_fast_init;
 
1606
        eap->reset = eap_fast_reset;
 
1607
        eap->buildReq = eap_fast_buildReq;
 
1608
        eap->check = eap_fast_check;
 
1609
        eap->process = eap_fast_process;
 
1610
        eap->isDone = eap_fast_isDone;
 
1611
        eap->getKey = eap_fast_getKey;
 
1612
        eap->get_emsk = eap_fast_get_emsk;
 
1613
        eap->isSuccess = eap_fast_isSuccess;
 
1614
 
 
1615
        ret = eap_server_method_register(eap);
 
1616
        if (ret)
 
1617
                eap_server_method_free(eap);
 
1618
        return ret;
 
1619
}