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