Merge from vendor branch GDB:
[dragonfly.git] / contrib / wpa_supplicant-0.4.9 / eap_fast.c
1 /*
2  * WPA Supplicant / EAP-FAST (draft-cam-winget-eap-fast-00.txt)
3  * Copyright (c) 2004-2005, Jouni Malinen <jkmaline@cc.hut.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 <stdlib.h>
16 #include <stdio.h>
17 #include <string.h>
18
19 #include "common.h"
20 #include "eap_i.h"
21 #include "eap_tls_common.h"
22 #include "wpa_supplicant.h"
23 #include "config_ssid.h"
24 #include "tls.h"
25 #include "eap_tlv.h"
26 #include "sha1.h"
27 #include "config.h"
28
29 /* TODO:
30  * - encrypt PAC-Key in the PAC file
31  * - test session resumption and enable it if it interoperates
32  * - password change (pending mschapv2 packet; replay decrypted packet)
33  */
34
35 #define EAP_FAST_VERSION 1
36 #define EAP_FAST_KEY_LEN 64
37 #define EAP_FAST_PAC_KEY_LEN 32
38
39 #define TLS_EXT_PAC_OPAQUE 35
40
41 static const char *pac_file_hdr =
42         "wpa_supplicant EAP-FAST PAC file - version 1";
43
44
45 static void eap_fast_deinit(struct eap_sm *sm, void *priv);
46
47
48 #define PAC_TYPE_PAC_KEY 1
49 #define PAC_TYPE_PAC_OPAQUE 2
50 #define PAC_TYPE_CRED_LIFETIME 3
51 #define PAC_TYPE_A_ID 4
52 #define PAC_TYPE_I_ID 5
53 #define PAC_TYPE_SERVER_PROTECTED_DATA 6
54 #define PAC_TYPE_A_ID_INFO 7
55 #define PAC_TYPE_PAC_ACKNOWLEDGEMENT 8
56 #define PAC_TYPE_PAC_INFO 9
57
58 struct pac_tlv_hdr {
59         u16 type;
60         u16 len;
61 };
62
63
64 /* draft-cam-winget-eap-fast-02.txt:
65  * 6.2 EAP-FAST Authentication Phase 1: Key Derivations */
66 struct eap_fast_key_block_auth {
67         /* Extra key material after TLS key_block */
68         u8 session_key_seed[40];
69 };
70
71
72 /* draft-cam-winget-eap-fast-provisioning-01.txt:
73  * 3.4 Key Derivations Used in the EAP-FAST Provisioning Exchange */
74 struct eap_fast_key_block_provisioning {
75         /* Extra key material after TLS key_block */
76         u8 session_key_seed[40];
77         u8 server_challenge[16];
78         u8 client_challenge[16];
79 };
80
81
82 struct eap_fast_pac {
83         struct eap_fast_pac *next;
84
85         u8 pac_key[EAP_FAST_PAC_KEY_LEN];
86         u8 *pac_opaque;
87         size_t pac_opaque_len;
88         u8 *pac_info;
89         size_t pac_info_len;
90         u8 *a_id;
91         size_t a_id_len;
92         u8 *i_id;
93         size_t i_id_len;
94         u8 *a_id_info;
95         size_t a_id_info_len;
96 };
97
98
99 struct eap_fast_data {
100         struct eap_ssl_data ssl;
101
102         int fast_version;
103
104         const struct eap_method *phase2_method;
105         void *phase2_priv;
106         int phase2_success;
107
108         u8 phase2_type;
109         u8 *phase2_types;
110         size_t num_phase2_types;
111         int resuming; /* starting a resumed session */
112         struct eap_fast_key_block_auth *key_block_a;
113         struct eap_fast_key_block_provisioning *key_block_p;
114         int provisioning_allowed; /* is PAC provisioning allowed */
115         int provisioning; /* doing PAC provisioning (not the normal auth) */
116
117         u8 key_data[EAP_FAST_KEY_LEN];
118         int success;
119
120         struct eap_fast_pac *pac;
121         struct eap_fast_pac *current_pac;
122
123         int tls_master_secret_set;
124 };
125
126
127 static void eap_fast_free_pac(struct eap_fast_pac *pac)
128 {
129         free(pac->pac_opaque);
130         free(pac->pac_info);
131         free(pac->a_id);
132         free(pac->i_id);
133         free(pac->a_id_info);
134         free(pac);
135 }
136
137
138 static struct eap_fast_pac * eap_fast_get_pac(struct eap_fast_data *data,
139                                               const u8 *a_id, size_t a_id_len)
140 {
141         struct eap_fast_pac *pac = data->pac;
142
143         while (pac) {
144                 if (pac->a_id_len == a_id_len &&
145                     memcmp(pac->a_id, a_id, a_id_len) == 0) {
146                         return pac;
147                 }
148                 pac = pac->next;
149         }
150         return NULL;
151 }
152
153
154 static int eap_fast_add_pac(struct eap_fast_data *data,
155                             struct eap_fast_pac *entry)
156 {
157         struct eap_fast_pac *pac, *prev;
158
159         if (entry == NULL || entry->a_id == NULL)
160                 return -1;
161
162         /* Remove a possible old entry for the matching A-ID. */
163         pac = data->pac;
164         prev = NULL;
165         while (pac) {
166                 if (pac->a_id_len == entry->a_id_len &&
167                     memcmp(pac->a_id, entry->a_id, pac->a_id_len) == 0) {
168                         if (prev == NULL) {
169                                 data->pac = pac->next;
170                         } else {
171                                 prev->next = pac->next;
172                         }
173                         if (data->current_pac == pac)
174                                 data->current_pac = NULL;
175                         eap_fast_free_pac(pac);
176                         break;
177                 }
178                 prev = pac;
179                 pac = pac->next;
180         }
181
182         /* Allocate a new entry and add it to the list of PACs. */
183         pac = malloc(sizeof(*pac));
184         if (pac == NULL)
185                 return -1;
186
187         memset(pac, 0, sizeof(*pac));
188         memcpy(pac->pac_key, entry->pac_key, EAP_FAST_PAC_KEY_LEN);
189         if (entry->pac_opaque) {
190                 pac->pac_opaque = malloc(entry->pac_opaque_len);
191                 if (pac->pac_opaque == NULL) {
192                         eap_fast_free_pac(pac);
193                         return -1;
194                 }
195                 memcpy(pac->pac_opaque, entry->pac_opaque,
196                        entry->pac_opaque_len);
197                 pac->pac_opaque_len = entry->pac_opaque_len;
198         }
199         if (entry->pac_info) {
200                 pac->pac_info = malloc(entry->pac_info_len);
201                 if (pac->pac_info == NULL) {
202                         eap_fast_free_pac(pac);
203                         return -1;
204                 }
205                 memcpy(pac->pac_info, entry->pac_info,
206                        entry->pac_info_len);
207                 pac->pac_info_len = entry->pac_info_len;
208         }
209         if (entry->a_id) {
210                 pac->a_id = malloc(entry->a_id_len);
211                 if (pac->a_id == NULL) {
212                         eap_fast_free_pac(pac);
213                         return -1;
214                 }
215                 memcpy(pac->a_id, entry->a_id,
216                        entry->a_id_len);
217                 pac->a_id_len = entry->a_id_len;
218         }
219         if (entry->i_id) {
220                 pac->i_id = malloc(entry->i_id_len);
221                 if (pac->i_id == NULL) {
222                         eap_fast_free_pac(pac);
223                         return -1;
224                 }
225                 memcpy(pac->i_id, entry->i_id,
226                        entry->i_id_len);
227                 pac->i_id_len = entry->i_id_len;
228         }
229         if (entry->a_id_info) {
230                 pac->a_id_info = malloc(entry->a_id_info_len);
231                 if (pac->a_id_info == NULL) {
232                         eap_fast_free_pac(pac);
233                         return -1;
234                 }
235                 memcpy(pac->a_id_info, entry->a_id_info,
236                        entry->a_id_info_len);
237                 pac->a_id_info_len = entry->a_id_info_len;
238         }
239         pac->next = data->pac;
240         data->pac = pac;
241         return 0;
242 }
243
244
245 struct eap_fast_read_ctx {
246         FILE *f;
247         const char *pos;
248         const char *end;
249 };
250
251 static int eap_fast_read_line(struct eap_fast_read_ctx *rc, char *buf,
252                               size_t buf_len)
253 {
254         char *pos;
255
256         if (rc->f) {
257                 if (fgets(buf, buf_len, rc->f) == NULL)
258                         return -1;
259         } else {
260                 const char *l_end;
261                 size_t len;
262                 if (rc->pos >= rc->end)
263                         return -1;
264                 l_end = rc->pos;
265                 while (l_end < rc->end && *l_end != '\n')
266                         l_end++;
267                 len = l_end - rc->pos;
268                 if (len >= buf_len)
269                         len = buf_len - 1;
270                 memcpy(buf, rc->pos, len);
271                 buf[len] = '\0';
272                 rc->pos = l_end + 1;
273         }
274
275         buf[buf_len - 1] = '\0';
276         pos = buf;
277         while (*pos != '\0') {
278                 if (*pos == '\n' || *pos == '\r') {
279                         *pos = '\0';
280                         break;
281                 }
282                 pos++;
283         }
284
285         return 0;
286 }
287
288
289 static u8 * eap_fast_parse_hex(const char *value, size_t *len)
290 {
291         int hlen;
292         u8 *buf;
293
294         if (value == NULL)
295                 return NULL;
296         hlen = strlen(value);
297         if (hlen & 1)
298                 return NULL;
299         *len = hlen / 2;
300         buf = malloc(*len);
301         if (buf == NULL)
302                 return NULL;
303         if (hexstr2bin(value, buf, *len)) {
304                 free(buf);
305                 return NULL;
306         }
307         return buf;
308 }
309
310
311 static int eap_fast_load_pac(struct eap_sm *sm, struct eap_fast_data *data,
312                              const char *pac_file)
313 {
314         struct eap_fast_read_ctx rc;
315         struct eap_fast_pac *pac = NULL;
316         int count = 0;
317         char *buf, *pos;
318         const int buf_len = 2048;
319         int ret = 0, line = 0;
320
321         if (pac_file == NULL)
322                 return -1;
323
324         memset(&rc, 0, sizeof(rc));
325
326         if (strncmp(pac_file, "blob://", 7) == 0) {
327                 const struct wpa_config_blob *blob;
328                 blob = eap_get_config_blob(sm, pac_file + 7);
329                 if (blob == NULL) {
330                         wpa_printf(MSG_INFO, "EAP-FAST: No PAC blob '%s' - "
331                                    "assume no PAC entries have been "
332                                    "provisioned", pac_file + 7);
333                         return 0;
334                 }
335                 rc.pos = (char *) blob->data;
336                 rc.end = (char *) blob->data + blob->len;
337         } else {
338                 rc.f = fopen(pac_file, "r");
339                 if (rc.f == NULL) {
340                         wpa_printf(MSG_INFO, "EAP-FAST: No PAC file '%s' - "
341                                    "assume no PAC entries have been "
342                                    "provisioned", pac_file);
343                         return 0;
344                 }
345         }
346
347         buf = malloc(buf_len);
348         if (buf == NULL) {
349                 return -1;
350         }
351
352         line++;
353         if (eap_fast_read_line(&rc, buf, buf_len) < 0 ||
354             strcmp(pac_file_hdr, buf) != 0) {
355                 wpa_printf(MSG_INFO, "EAP-FAST: Unrecognized header line in "
356                            "PAC file '%s'", pac_file);
357                 free(buf);
358                 if (rc.f)
359                         fclose(rc.f);
360                 return -1;
361         }
362
363         while (eap_fast_read_line(&rc, buf, buf_len) == 0) {
364                 line++;
365                 pos = strchr(buf, '=');
366                 if (pos) {
367                         *pos++ = '\0';
368                 }
369
370                 if (strcmp(buf, "START") == 0) {
371                         if (pac) {
372                                 wpa_printf(MSG_INFO, "EAP-FAST: START line "
373                                            "without END in '%s:%d'",
374                                            pac_file, line);
375                                 ret = -1;
376                                 break;
377                         }
378                         pac = malloc(sizeof(*pac));
379                         if (pac == NULL) {
380                                 wpa_printf(MSG_INFO, "EAP-FAST: No memory for "
381                                            "PAC entry");
382                                 ret = -1;
383                                 break;
384                         }
385                         memset(pac, 0, sizeof(*pac));
386                 } else if (strcmp(buf, "END") == 0) {
387                         if (pac == NULL) {
388                                 wpa_printf(MSG_INFO, "EAP-FAST: END line "
389                                            "without START in '%s:%d'",
390                                            pac_file, line);
391                                 ret = -1;
392                                 break;
393                         }
394                         pac->next = data->pac;
395                         data->pac = pac;
396                         pac = NULL;
397                         count++;
398                 } else if (pac && strcmp(buf, "PAC-Key") == 0) {
399                         u8 *key;
400                         size_t key_len;
401                         key = eap_fast_parse_hex(pos, &key_len);
402                         if (key == NULL || key_len != EAP_FAST_PAC_KEY_LEN) {
403                                 wpa_printf(MSG_INFO, "EAP-FAST: Invalid "
404                                            "PAC-Key '%s:%d'", pac_file, line);
405                                 ret = -1;
406                                 free(key);
407                                 break;
408                         }
409
410                         memcpy(pac->pac_key, key, EAP_FAST_PAC_KEY_LEN);
411                         free(key);
412                 } else if (pac && strcmp(buf, "PAC-Opaque") == 0) {
413                         pac->pac_opaque =
414                                 eap_fast_parse_hex(pos, &pac->pac_opaque_len);
415                         if (pac->pac_opaque == NULL) {
416                                 wpa_printf(MSG_INFO, "EAP-FAST: Invalid "
417                                            "PAC-Opaque '%s:%d'",
418                                            pac_file, line);
419                                 ret = -1;
420                                 break;
421                         }
422                 } else if (pac && strcmp(buf, "A-ID") == 0) {
423                         pac->a_id = eap_fast_parse_hex(pos, &pac->a_id_len);
424                         if (pac->a_id == NULL) {
425                                 wpa_printf(MSG_INFO, "EAP-FAST: Invalid "
426                                            "A-ID '%s:%d'", pac_file, line);
427                                 ret = -1;
428                                 break;
429                         }
430                 } else if (pac && strcmp(buf, "I-ID") == 0) {
431                         pac->i_id = eap_fast_parse_hex(pos, &pac->i_id_len);
432                         if (pac->i_id == NULL) {
433                                 wpa_printf(MSG_INFO, "EAP-FAST: Invalid "
434                                            "I-ID '%s:%d'", pac_file, line);
435                                 ret = -1;
436                                 break;
437                         }
438                 } else if (pac && strcmp(buf, "A-ID-Info") == 0) {
439                         pac->a_id_info =
440                                 eap_fast_parse_hex(pos, &pac->a_id_info_len);
441                         if (pac->a_id_info == NULL) {
442                                 wpa_printf(MSG_INFO, "EAP-FAST: Invalid "
443                                            "A-ID-Info '%s:%d'",
444                                            pac_file, line);
445                                 ret = -1;
446                                 break;
447                         }
448                 }
449         }
450
451         if (pac) {
452                 wpa_printf(MSG_INFO, "EAP-FAST: PAC block not terminated with "
453                            "END in '%s'", pac_file);
454                 eap_fast_free_pac(pac);
455                 ret = -1;
456         }
457
458         free(buf);
459         if (rc.f)
460                 fclose(rc.f);
461
462         if (ret == 0) {
463                 wpa_printf(MSG_DEBUG, "EAP-FAST: read %d PAC entries from "
464                            "'%s'", count, pac_file);
465         }
466
467         return ret;
468 }
469
470
471 static void eap_fast_write(char **buf, char **pos, size_t *buf_len,
472                            const char *field, const u8 *data,
473                            size_t len, int txt)
474 {
475         int i;
476         size_t need;
477
478         if (data == NULL || *buf == NULL)
479                 return;
480
481         need = strlen(field) + len * 2 + 30;
482         if (txt)
483                 need += strlen(field) + len + 20;
484
485         if (*pos - *buf + need > *buf_len) {
486                 char *nbuf = realloc(*buf, *buf_len + need);
487                 if (nbuf == NULL) {
488                         free(*buf);
489                         *buf = NULL;
490                         return;
491                 }
492                 *buf = nbuf;
493                 *buf_len += need;
494         }
495
496         *pos += snprintf(*pos, *buf + *buf_len - *pos, "%s=", field);
497         for (i = 0; i < len; i++) {
498                 *pos += snprintf(*pos, *buf + *buf_len - *pos,
499                                  "%02x", data[i]);
500         }
501         *pos += snprintf(*pos, *buf + *buf_len - *pos, "\n");
502
503         if (txt) {
504                 *pos += snprintf(*pos, *buf + *buf_len - *pos,
505                                  "%s-txt=", field);
506                 for (i = 0; i < len; i++) {
507                         *pos += snprintf(*pos, *buf + *buf_len - *pos,
508                                          "%c", data[i]);
509                 }
510                 *pos += snprintf(*pos, *buf + *buf_len - *pos, "\n");
511         }
512 }
513
514
515 static int eap_fast_save_pac(struct eap_sm *sm, struct eap_fast_data *data,
516                              const char *pac_file)
517 {
518         FILE *f;
519         struct eap_fast_pac *pac;
520         int count = 0;
521         char *buf, *pos;
522         size_t buf_len;
523
524         if (pac_file == NULL)
525                 return -1;
526
527         buf_len = 1024;
528         pos = buf = malloc(buf_len);
529         if (buf == NULL)
530                 return -1;
531
532         pos += snprintf(pos, buf + buf_len - pos, "%s\n", pac_file_hdr);
533
534         pac = data->pac;
535         while (pac) {
536                 pos += snprintf(pos, buf + buf_len - pos, "START\n");
537                 eap_fast_write(&buf, &pos, &buf_len, "PAC-Key", pac->pac_key,
538                                EAP_FAST_PAC_KEY_LEN, 0);
539                 eap_fast_write(&buf, &pos, &buf_len, "PAC-Opaque",
540                                pac->pac_opaque, pac->pac_opaque_len, 0);
541                 eap_fast_write(&buf, &pos, &buf_len, "PAC-Info", pac->pac_info,
542                                pac->pac_info_len, 0);
543                 eap_fast_write(&buf, &pos, &buf_len, "A-ID", pac->a_id,
544                                pac->a_id_len, 0);
545                 eap_fast_write(&buf, &pos, &buf_len, "I-ID", pac->i_id,
546                                pac->i_id_len, 1);
547                 eap_fast_write(&buf, &pos, &buf_len, "A-ID-Info",
548                                pac->a_id_info, pac->a_id_info_len, 1);
549                 pos += snprintf(pos, buf + buf_len - pos, "END\n");
550                 count++;
551                 pac = pac->next;
552
553                 if (buf == NULL) {
554                         wpa_printf(MSG_DEBUG, "EAP-FAST: No memory for PAC "
555                                    "data");
556                         return -1;
557                 }
558         }
559
560         if (strncmp(pac_file, "blob://", 7) == 0) {
561                 struct wpa_config_blob *blob;
562                 blob = malloc(sizeof(*blob));
563                 if (blob == NULL) {
564                         free(buf);
565                         return -1;
566                 }
567                 memset(blob, 0, sizeof(*blob));
568                 blob->data = (u8 *) buf;
569                 blob->len = pos - buf;
570                 buf = NULL;
571                 blob->name = strdup(pac_file + 7);
572                 if (blob->name == NULL) {
573                         wpa_config_free_blob(blob);
574                         return -1;
575                 }
576                 eap_set_config_blob(sm, blob);
577         } else {
578                 f = fopen(pac_file, "w");
579                 if (f == NULL) {
580                         wpa_printf(MSG_INFO, "EAP-FAST: Failed to open PAC "
581                                    "file '%s' for writing", pac_file);
582                         free(buf);
583                         return -1;
584                 }
585                 fprintf(f, "%s", buf);
586                 free(buf);
587                 fclose(f);
588         }
589
590         wpa_printf(MSG_DEBUG, "EAP-FAST: wrote %d PAC entries into '%s'",
591                    count, pac_file);
592
593         return 0;
594 }
595
596
597 static void * eap_fast_init(struct eap_sm *sm)
598 {
599         struct eap_fast_data *data;
600         struct wpa_ssid *config = eap_get_config(sm);
601
602         data = malloc(sizeof(*data));
603         if (data == NULL)
604                 return NULL;
605         memset(data, 0, sizeof(*data));
606         data->fast_version = EAP_FAST_VERSION;
607
608         if (config && config->phase1) {
609                 if (strstr(config->phase1, "fast_provisioning=1")) {
610                         data->provisioning_allowed = 1;
611                         wpa_printf(MSG_DEBUG, "EAP-FAST: Automatic PAC "
612                                    "provisioning is allowed");
613                 }
614         }
615
616         if (config && config->phase2) {
617                 char *start, *pos, *buf;
618                 u8 method, *methods = NULL, *_methods;
619                 size_t num_methods = 0;
620                 start = buf = strdup(config->phase2);
621                 if (buf == NULL) {
622                         eap_fast_deinit(sm, data);
623                         return NULL;
624                 }
625                 while (start && *start != '\0') {
626                         pos = strstr(start, "auth=");
627                         if (pos == NULL)
628                                 break;
629                         if (start != pos && *(pos - 1) != ' ') {
630                                 start = pos + 5;
631                                 continue;
632                         }
633
634                         start = pos + 5;
635                         pos = strchr(start, ' ');
636                         if (pos)
637                                 *pos++ = '\0';
638                         method = eap_get_phase2_type(start);
639                         if (method == EAP_TYPE_NONE) {
640                                 wpa_printf(MSG_ERROR, "EAP-FAST: Unsupported "
641                                            "Phase2 method '%s'", start);
642                         } else {
643                                 num_methods++;
644                                 _methods = realloc(methods, num_methods);
645                                 if (_methods == NULL) {
646                                         free(methods);
647                                         free(buf);
648                                         eap_fast_deinit(sm, data);
649                                         return NULL;
650                                 }
651                                 methods = _methods;
652                                 methods[num_methods - 1] = method;
653                         }
654
655                         start = pos;
656                 }
657                 free(buf);
658                 data->phase2_types = methods;
659                 data->num_phase2_types = num_methods;
660         }
661         if (data->phase2_types == NULL) {
662                 data->phase2_types =
663                         eap_get_phase2_types(config, &data->num_phase2_types);
664         }
665         if (data->phase2_types == NULL) {
666                 wpa_printf(MSG_ERROR, "EAP-FAST: No Phase2 method available");
667                 eap_fast_deinit(sm, data);
668                 return NULL;
669         }
670         wpa_hexdump(MSG_DEBUG, "EAP-FAST: Phase2 EAP types",
671                     data->phase2_types, data->num_phase2_types);
672         data->phase2_type = EAP_TYPE_NONE;
673
674         if (eap_tls_ssl_init(sm, &data->ssl, config)) {
675                 wpa_printf(MSG_INFO, "EAP-FAST: Failed to initialize SSL.");
676                 eap_fast_deinit(sm, data);
677                 return NULL;
678         }
679
680         /* The local RADIUS server in a Cisco AP does not seem to like empty
681          * fragments before data, so disable that workaround for CBC.
682          * TODO: consider making this configurable */
683         tls_connection_enable_workaround(sm->ssl_ctx, data->ssl.conn);
684
685         if (eap_fast_load_pac(sm, data, config->pac_file) < 0) {
686                 eap_fast_deinit(sm, data);
687                 return NULL;
688         }
689
690         if (data->pac == NULL && !data->provisioning_allowed) {
691                 wpa_printf(MSG_INFO, "EAP-FAST: No PAC configured and "
692                            "provisioning disabled");
693                 eap_fast_deinit(sm, data);
694                 return NULL;
695         }
696
697         return data;
698 }
699
700
701 static void eap_fast_deinit(struct eap_sm *sm, void *priv)
702 {
703         struct eap_fast_data *data = priv;
704         struct eap_fast_pac *pac, *prev;
705
706         if (data == NULL)
707                 return;
708         if (data->phase2_priv && data->phase2_method)
709                 data->phase2_method->deinit(sm, data->phase2_priv);
710         free(data->phase2_types);
711         free(data->key_block_a);
712         free(data->key_block_p);
713         eap_tls_ssl_deinit(sm, &data->ssl);
714
715         pac = data->pac;
716         prev = NULL;
717         while (pac) {
718                 prev = pac;
719                 pac = pac->next;
720                 eap_fast_free_pac(prev);
721         }
722         free(data);
723 }
724
725
726 static int eap_fast_encrypt(struct eap_sm *sm, struct eap_fast_data *data,
727                             int id, const u8 *plain, size_t plain_len,
728                             u8 **out_data, size_t *out_len)
729 {
730         int res;
731         u8 *pos;
732         struct eap_hdr *resp;
733
734         /* TODO: add support for fragmentation, if needed. This will need to
735          * add TLS Message Length field, if the frame is fragmented. */
736         resp = malloc(sizeof(struct eap_hdr) + 2 + data->ssl.tls_out_limit);
737         if (resp == NULL)
738                 return 0;
739
740         resp->code = EAP_CODE_RESPONSE;
741         resp->identifier = id;
742
743         pos = (u8 *) (resp + 1);
744         *pos++ = EAP_TYPE_FAST;
745         *pos++ = data->fast_version;
746
747         res = tls_connection_encrypt(sm->ssl_ctx, data->ssl.conn,
748                                      plain, plain_len,
749                                      pos, data->ssl.tls_out_limit);
750         if (res < 0) {
751                 wpa_printf(MSG_INFO, "EAP-FAST: Failed to encrypt Phase 2 "
752                            "data");
753                 free(resp);
754                 return 0;
755         }
756
757         *out_len = sizeof(struct eap_hdr) + 2 + res;
758         resp->length = host_to_be16(*out_len);
759         *out_data = (u8 *) resp;
760         return 0;
761 }
762
763
764 static int eap_fast_phase2_nak(struct eap_sm *sm,
765                                struct eap_fast_data *data,
766                                struct eap_hdr *hdr,
767                                u8 **resp, size_t *resp_len)
768 {
769         struct eap_hdr *resp_hdr;
770         u8 *pos = (u8 *) (hdr + 1);
771
772         wpa_printf(MSG_DEBUG, "EAP-FAST: Phase 2 Request: Nak type=%d", *pos);
773         wpa_hexdump(MSG_DEBUG, "EAP-FAST: Allowed Phase2 EAP types",
774                     data->phase2_types, data->num_phase2_types);
775         *resp_len = sizeof(struct eap_hdr) + 1 + data->num_phase2_types;
776         *resp = malloc(*resp_len);
777         if (*resp == NULL)
778                 return -1;
779
780         resp_hdr = (struct eap_hdr *) (*resp);
781         resp_hdr->code = EAP_CODE_RESPONSE;
782         resp_hdr->identifier = hdr->identifier;
783         resp_hdr->length = host_to_be16(*resp_len);
784         pos = (u8 *) (resp_hdr + 1);
785         *pos++ = EAP_TYPE_NAK;
786         memcpy(pos, data->phase2_types, data->num_phase2_types);
787
788         return 0;
789 }
790
791
792 static int eap_fast_derive_msk(struct eap_sm *sm, struct eap_fast_data *data)
793 {
794         u8 isk[32];
795         u8 imck[60];
796
797         if (data->key_block_a == NULL)
798                 return -1;
799
800         memset(isk, 0, sizeof(isk));
801         sha1_t_prf(data->key_block_a->session_key_seed,
802                    sizeof(data->key_block_a->session_key_seed),
803                    "Inner Methods Compound Keys",
804                    isk, sizeof(isk), imck, sizeof(imck));
805         sha1_t_prf(imck, 40, "Session Key Generating Function", (u8 *) "", 0,
806                    data->key_data, EAP_FAST_KEY_LEN);
807
808         wpa_hexdump_key(MSG_DEBUG, "EAP-FAST: Derived key (MSK)",
809                         data->key_data, EAP_FAST_KEY_LEN);
810
811         data->success = 1;
812
813         return 0;
814 }
815
816
817 static int eap_fast_set_tls_master_secret(struct eap_sm *sm,
818                                           struct eap_fast_data *data,
819                                           const u8 *tls, size_t tls_len)
820 {
821         struct tls_keys keys;
822         u8 master_secret[48], *seed;
823         const u8 *server_random;
824         size_t seed_len, server_random_len;
825
826         if (data->tls_master_secret_set || !data->current_pac ||
827             tls_connection_get_keys(sm->ssl_ctx, data->ssl.conn, &keys)) {
828                 return 0;
829         }
830
831         wpa_hexdump(MSG_DEBUG, "EAP-FAST: client_random",
832                     keys.client_random, keys.client_random_len);
833
834         /* TLS master secret is needed before TLS library has processed this
835          * message which includes both ServerHello and an encrypted handshake
836          * message, so we need to parse server_random from this message before
837          * passing it to TLS library.
838          *
839          * Example TLS packet header:
840          * (16 03 01 00 2a 02 00 00 26 03 01 <32 bytes server_random>)
841          * Content Type: Handshake: 0x16
842          * Version: TLS 1.0 (0x0301)
843          * Lenghth: 42 (0x002a)
844          * Handshake Type: Server Hello: 0x02
845          * Length: 38 (0x000026)
846          * Version TLS 1.0 (0x0301)
847          * Random: 32 bytes
848          */
849         if (tls_len < 43 || tls[0] != 0x16 ||
850             tls[1] != 0x03 || tls[2] != 0x01 ||
851             tls[5] != 0x02 || tls[9] != 0x03 || tls[10] != 0x01) {
852                 wpa_hexdump(MSG_DEBUG, "EAP-FAST: unrecognized TLS "
853                             "ServerHello", tls, tls_len);
854                 return -1;
855         }
856         server_random = tls + 11;
857         server_random_len = 32;
858         wpa_hexdump(MSG_DEBUG, "EAP-FAST: server_random",
859                     server_random, server_random_len);
860
861
862         seed_len = keys.client_random_len + server_random_len;
863         seed = malloc(seed_len);
864         if (seed == NULL)
865                 return -1;
866         memcpy(seed, server_random, server_random_len);
867         memcpy(seed + server_random_len,
868                keys.client_random, keys.client_random_len);
869
870         wpa_hexdump(MSG_MSGDUMP, "EAP-FAST: T-PRF seed", seed, seed_len);
871         wpa_hexdump_key(MSG_MSGDUMP, "EAP-FAST: PAC-Key",
872                         data->current_pac->pac_key, EAP_FAST_PAC_KEY_LEN);
873         /* master_secret = T-PRF(PAC-Key, "PAC to master secret label hash", 
874          * server_random + client_random, 48) */
875         sha1_t_prf(data->current_pac->pac_key, EAP_FAST_PAC_KEY_LEN,
876                    "PAC to master secret label hash",
877                    seed, seed_len, master_secret, sizeof(master_secret));
878         free(seed);
879         wpa_hexdump_key(MSG_DEBUG, "EAP-FAST: TLS pre-master-secret",
880                         master_secret, sizeof(master_secret));
881
882         data->tls_master_secret_set = 1;
883
884         return tls_connection_set_master_key(sm->ssl_ctx, data->ssl.conn,
885                                              master_secret,
886                                              sizeof(master_secret));
887 }
888
889
890 static u8 * eap_fast_derive_key(struct eap_sm *sm, struct eap_ssl_data *data,
891                                 char *label, size_t len)
892 {
893         struct tls_keys keys;
894         u8 *rnd;
895         u8 *out;
896         int block_size;
897
898         if (tls_connection_get_keys(sm->ssl_ctx, data->conn, &keys))
899                 return NULL;
900         block_size = tls_connection_get_keyblock_size(sm->ssl_ctx, data->conn);
901         if (block_size < 0)
902                 return NULL;
903         out = malloc(block_size + len);
904         rnd = malloc(keys.client_random_len + keys.server_random_len);
905         if (out == NULL || rnd == NULL) {
906                 free(out);
907                 free(rnd);
908                 return NULL;
909         }
910         memcpy(rnd, keys.server_random, keys.server_random_len);
911         memcpy(rnd + keys.server_random_len, keys.client_random,
912                keys.client_random_len);
913
914         wpa_hexdump_key(MSG_MSGDUMP, "EAP-FAST: master_secret for key "
915                         "expansion", keys.master_key, keys.master_key_len);
916         if (tls_prf(keys.master_key, keys.master_key_len,
917                     label, rnd, keys.client_random_len +
918                     keys.server_random_len, out, block_size + len)) {
919                 free(rnd);
920                 free(out);
921                 return NULL;
922         }
923         free(rnd);
924         memmove(out, out + block_size, len);
925         return out;
926 }
927
928
929 static void eap_fast_derive_key_auth(struct eap_sm *sm,
930                                      struct eap_fast_data *data)
931 {
932         free(data->key_block_a);
933         data->key_block_a = (struct eap_fast_key_block_auth *)
934                 eap_fast_derive_key(sm, &data->ssl, "key expansion",
935                                     sizeof(*data->key_block_a));
936         if (data->key_block_a == NULL) {
937                 wpa_printf(MSG_DEBUG, "EAP-FAST: Failed to derive "
938                            "session_key_seed");
939                 return;
940         }
941         wpa_hexdump_key(MSG_DEBUG, "EAP-FAST: session_key_seed",
942                         data->key_block_a->session_key_seed,
943                         sizeof(data->key_block_a->session_key_seed));
944 }
945
946
947 static void eap_fast_derive_key_provisioning(struct eap_sm *sm,
948                                              struct eap_fast_data *data)
949 {
950         free(data->key_block_p);
951         data->key_block_p = (struct eap_fast_key_block_provisioning *)
952                 eap_fast_derive_key(sm, &data->ssl, "key expansion",
953                                     sizeof(*data->key_block_p));
954         if (data->key_block_p == NULL) {
955                 wpa_printf(MSG_DEBUG, "EAP-FAST: Failed to derive key block");
956                 return;
957         }
958         wpa_hexdump_key(MSG_DEBUG, "EAP-FAST: session_key_seed",
959                         data->key_block_p->session_key_seed,
960                         sizeof(data->key_block_p->session_key_seed));
961         wpa_hexdump_key(MSG_DEBUG, "EAP-FAST: server_challenge",
962                         data->key_block_p->server_challenge,
963                         sizeof(data->key_block_p->server_challenge));
964         wpa_hexdump_key(MSG_DEBUG, "EAP-FAST: client_challenge",
965                         data->key_block_p->client_challenge,
966                         sizeof(data->key_block_p->client_challenge));
967 }
968
969
970 static void eap_fast_derive_keys(struct eap_sm *sm, struct eap_fast_data *data)
971 {
972         if (data->current_pac) {
973                 eap_fast_derive_key_auth(sm, data);
974         } else {
975                 eap_fast_derive_key_provisioning(sm, data);
976         }
977 }
978
979
980 static int eap_fast_phase2_request(struct eap_sm *sm,
981                                    struct eap_fast_data *data,
982                                    struct eap_method_ret *ret,
983                                    const struct eap_hdr *req,
984                                    struct eap_hdr *hdr,
985                                    u8 **resp, size_t *resp_len)
986 {
987         size_t len = be_to_host16(hdr->length);
988         u8 *pos;
989         struct eap_method_ret iret;
990
991         if (len <= sizeof(struct eap_hdr)) {
992                 wpa_printf(MSG_INFO, "EAP-FAST: too short "
993                            "Phase 2 request (len=%lu)", (unsigned long) len);
994                 return -1;
995         }
996         pos = (u8 *) (hdr + 1);
997         wpa_printf(MSG_DEBUG, "EAP-FAST: Phase 2 Request: type=%d", *pos);
998         switch (*pos) {
999         case EAP_TYPE_IDENTITY:
1000                 *resp = eap_sm_buildIdentity(sm, req->identifier, resp_len, 1);
1001                 break;
1002         default:
1003                 if (data->phase2_type == EAP_TYPE_NONE) {
1004                         int i;
1005                         for (i = 0; i < data->num_phase2_types; i++) {
1006                                 if (data->phase2_types[i] != *pos)
1007                                         continue;
1008
1009                                 data->phase2_type = *pos;
1010                                 wpa_printf(MSG_DEBUG, "EAP-FAST: Selected "
1011                                            "Phase 2 EAP method %d",
1012                                            data->phase2_type);
1013                                 break;
1014                         }
1015                 }
1016                 if (*pos != data->phase2_type || *pos == EAP_TYPE_NONE) {
1017                         if (eap_fast_phase2_nak(sm, data, hdr, resp, resp_len))
1018                                 return -1;
1019                         return 0;
1020                 }
1021
1022                 if (data->phase2_priv == NULL) {
1023                         data->phase2_method = eap_sm_get_eap_methods(*pos);
1024                         if (data->phase2_method) {
1025                                 if (data->key_block_p) {
1026                                         sm->auth_challenge =
1027                                                 data->key_block_p->
1028                                                 server_challenge;
1029                                         sm->peer_challenge =
1030                                                 data->key_block_p->
1031                                                 client_challenge;
1032                                 }
1033                                 sm->init_phase2 = 1;
1034                                 data->phase2_priv =
1035                                         data->phase2_method->init(sm);
1036                                 sm->init_phase2 = 0;
1037                                 sm->auth_challenge = NULL;
1038                                 sm->peer_challenge = NULL;
1039                         }
1040                 }
1041                 if (data->phase2_priv == NULL || data->phase2_method == NULL) {
1042                         wpa_printf(MSG_INFO, "EAP-FAST: failed to initialize "
1043                                    "Phase 2 EAP method %d", *pos);
1044                         ret->methodState = METHOD_DONE;
1045                         ret->decision = DECISION_FAIL;
1046                         return -1;
1047                 }
1048                 memset(&iret, 0, sizeof(iret));
1049                 *resp = data->phase2_method->process(sm, data->phase2_priv,
1050                                                      &iret, (u8 *) hdr, len,
1051                                                      resp_len);
1052                 if (*resp == NULL ||
1053                     (iret.methodState == METHOD_DONE &&
1054                      iret.decision == DECISION_FAIL)) {
1055                         ret->methodState = METHOD_DONE;
1056                         ret->decision = DECISION_FAIL;
1057                 } else if ((iret.methodState == METHOD_DONE ||
1058                             iret.methodState == METHOD_MAY_CONT) &&
1059                            (iret.decision == DECISION_UNCOND_SUCC ||
1060                             iret.decision == DECISION_COND_SUCC)) {
1061                         data->phase2_success = 1;
1062                 }
1063                 if (*resp == NULL)
1064                         return -1;
1065                 break;
1066         }
1067         return 0;
1068 }
1069
1070
1071 static u8 * eap_fast_tlv_nak(int vendor_id, int tlv_type, size_t *len)
1072 {
1073         struct eap_tlv_nak_tlv *nak;
1074         *len = sizeof(*nak);
1075         nak = malloc(*len);
1076         if (nak == NULL)
1077                 return NULL;
1078         nak->tlv_type = host_to_be16(EAP_TLV_TYPE_MANDATORY | EAP_TLV_NAK_TLV);
1079         nak->length = host_to_be16(6);
1080         nak->vendor_id = host_to_be32(vendor_id);
1081         nak->nak_type = host_to_be16(tlv_type);
1082         return (u8 *) nak;
1083 }
1084
1085
1086 static u8 * eap_fast_tlv_result(int status, int intermediate, size_t *len)
1087 {
1088         struct eap_tlv_intermediate_result_tlv *result;
1089         *len = sizeof(*result);
1090         result = malloc(*len);
1091         if (result == NULL)
1092                 return NULL;
1093         result->tlv_type = host_to_be16(EAP_TLV_TYPE_MANDATORY |
1094                                         (intermediate ?
1095                                          EAP_TLV_INTERMEDIATE_RESULT_TLV :
1096                                          EAP_TLV_RESULT_TLV));
1097         result->length = host_to_be16(2);
1098         result->status = host_to_be16(status);
1099         return (u8 *) result;
1100 }
1101
1102
1103 static u8 * eap_fast_tlv_pac_ack(size_t *len)
1104 {
1105         struct eap_tlv_result_tlv *res;
1106         struct eap_tlv_pac_ack_tlv *ack;
1107
1108         *len = sizeof(*res) + sizeof(*ack);
1109         res = malloc(*len);
1110         if (res == NULL)
1111                 return NULL;
1112
1113         memset(res, 0, *len);
1114         res->tlv_type = host_to_be16(EAP_TLV_RESULT_TLV |
1115                                      EAP_TLV_TYPE_MANDATORY);
1116         res->length = host_to_be16(sizeof(*res) - sizeof(struct eap_tlv_hdr));
1117         res->status = host_to_be16(EAP_TLV_RESULT_SUCCESS);
1118
1119         ack = (struct eap_tlv_pac_ack_tlv *) (res + 1);
1120         ack->tlv_type = host_to_be16(EAP_TLV_PAC_TLV |
1121                                      EAP_TLV_TYPE_MANDATORY);
1122         ack->length = host_to_be16(sizeof(*ack) - sizeof(struct eap_tlv_hdr));
1123         ack->pac_type = host_to_be16(PAC_TYPE_PAC_ACKNOWLEDGEMENT);
1124         ack->pac_len = host_to_be16(2);
1125         ack->result = host_to_be16(EAP_TLV_RESULT_SUCCESS);
1126
1127         return (u8 *) res;
1128 }
1129
1130
1131 static u8 * eap_fast_tlv_eap_payload(u8 *buf, size_t *len)
1132 {
1133         struct eap_tlv_hdr *tlv;
1134
1135         /* Encapsulate EAP packet in EAP Payload TLV */
1136         tlv = malloc(sizeof(*tlv) + *len);
1137         if (tlv == NULL) {
1138                 wpa_printf(MSG_DEBUG, "EAP-FAST: Failed to "
1139                            "allocate memory for TLV "
1140                            "encapsulation");
1141                 free(buf);
1142                 return NULL;
1143         }
1144         tlv->tlv_type = host_to_be16(EAP_TLV_TYPE_MANDATORY |
1145                                      EAP_TLV_EAP_PAYLOAD_TLV);
1146         tlv->length = host_to_be16(*len);
1147         memcpy(tlv + 1, buf, *len);
1148         free(buf);
1149         *len += sizeof(*tlv);
1150         return (u8 *) tlv;
1151 }
1152
1153
1154 static u8 * eap_fast_process_crypto_binding(
1155         struct eap_sm *sm, struct eap_fast_data *data,
1156         struct eap_method_ret *ret,
1157         struct eap_tlv_crypto_binding__tlv *bind, size_t bind_len,
1158         size_t *resp_len, int final)
1159 {
1160         u8 *resp, *sks = NULL;
1161         struct eap_tlv_intermediate_result_tlv *rresult;
1162         struct eap_tlv_crypto_binding__tlv *rbind;
1163         u8 isk[32], imck[60], *cmk, cmac[20], *key;
1164         size_t key_len;
1165         int res;
1166
1167         wpa_printf(MSG_DEBUG, "EAP-FAST: Crypto-Binding TLV: Version %d "
1168                    "Received Version %d SubType %d",
1169                    bind->version, bind->received_version, bind->subtype);
1170         wpa_hexdump(MSG_MSGDUMP, "EAP-FAST: NONCE",
1171                     bind->nonce, sizeof(bind->nonce));
1172         wpa_hexdump(MSG_MSGDUMP, "EAP-FAST: Compound MAC",
1173                     bind->compound_mac, sizeof(bind->compound_mac));
1174
1175         if (bind->version != EAP_FAST_VERSION ||
1176             bind->received_version != EAP_FAST_VERSION ||
1177             bind->subtype != EAP_TLV_CRYPTO_BINDING_SUBTYPE_REQUEST) {
1178                 wpa_printf(MSG_INFO, "EAP-FAST: Invalid version/subtype in "
1179                            "Crypto-Binding TLV: Version %d "
1180                            "Received Version %d SubType %d",
1181                            bind->version, bind->received_version,
1182                            bind->subtype);
1183                 resp = eap_fast_tlv_result(EAP_TLV_RESULT_FAILURE, 1,
1184                                            resp_len);
1185                 return resp;
1186         }
1187
1188
1189         if (data->provisioning) {
1190                 if (data->key_block_p) {
1191                         sks = data->key_block_p->session_key_seed;
1192                 }
1193         } else {
1194                 if (data->key_block_a) {
1195                         sks = data->key_block_a->session_key_seed;
1196                 }
1197         }
1198         if (sks == NULL) {
1199                 wpa_printf(MSG_INFO, "EAP-FAST: No Session Key Seed available "
1200                            "for processing Crypto-Binding TLV");
1201                 return NULL;
1202         }
1203
1204         wpa_printf(MSG_DEBUG, "EAP-FAST: Determining CMK for Compound MIC "
1205                    "calculation");
1206         wpa_hexdump_key(MSG_MSGDUMP, "EAP-FAST: S-IMCK[0] = SKS", sks, 40);
1207
1208         memset(isk, 0, sizeof(isk));
1209         if (data->phase2_method == NULL || data->phase2_priv == NULL) {
1210                 wpa_printf(MSG_DEBUG, "EAP-FAST: Phase 2 method not "
1211                            "available");
1212                 return NULL;
1213         }
1214         if (data->phase2_method->isKeyAvailable && data->phase2_method->getKey)
1215         {
1216                 if (!data->phase2_method->isKeyAvailable(sm, data->phase2_priv)
1217                     ||
1218                     (key = data->phase2_method->getKey(sm, data->phase2_priv,
1219                                                        &key_len)) == NULL) {
1220                         wpa_printf(MSG_DEBUG, "EAP-FAST: Could not get key "
1221                                    "material from Phase 2");
1222                         return NULL;
1223                 }
1224                 if (key_len > sizeof(isk))
1225                         key_len = sizeof(isk);
1226                 /* FIX: which end is being padded? */
1227 #if 0
1228                 memcpy(isk + (sizeof(isk) - key_len), key, key_len);
1229 #else
1230                 memcpy(isk, key, key_len);
1231 #endif
1232                 free(key);
1233         }
1234         wpa_hexdump_key(MSG_MSGDUMP, "EAP-FAST: ISK[0]", isk, sizeof(isk));
1235         sha1_t_prf(sks, 40, "Inner Methods Compound Keys",
1236                    isk, sizeof(isk), imck, sizeof(imck));
1237         /* S-IMCK[1] = imkc[0..39] */
1238         wpa_hexdump_key(MSG_MSGDUMP, "EAP-FAST: S-IMCK[1]", imck, 40);
1239         cmk = imck + 40;
1240         wpa_hexdump_key(MSG_MSGDUMP, "EAP-FAST: CMK", cmk, 20);
1241
1242         memcpy(cmac, bind->compound_mac, sizeof(cmac));
1243         memset(bind->compound_mac, 0, sizeof(cmac));
1244         wpa_hexdump(MSG_MSGDUMP, "EAP-FAST: Crypto-Binding TLV for Compound "
1245                     "MAC calculation", (u8 *) bind, bind_len);
1246         hmac_sha1(cmk, 20, (u8 *) bind, bind_len, bind->compound_mac);
1247         res = memcmp(cmac, bind->compound_mac, sizeof(cmac));
1248         wpa_hexdump(MSG_MSGDUMP, "EAP-FAST: Received Compound MAC",
1249                     cmac, sizeof(cmac));
1250         wpa_hexdump(MSG_MSGDUMP, "EAP-FAST: Calculated Compound MAC",
1251                     bind->compound_mac, sizeof(cmac));
1252         if (res != 0) {
1253                 wpa_printf(MSG_INFO, "EAP-FAST: Compound MAC did not match");
1254                 resp = eap_fast_tlv_result(EAP_TLV_RESULT_FAILURE, 1,
1255                                            resp_len);
1256                 memcpy(bind->compound_mac, cmac, sizeof(cmac));
1257                 return resp;
1258         }
1259
1260         *resp_len = sizeof(*rresult) + sizeof(*rbind);
1261         resp = malloc(*resp_len);
1262         if (resp == NULL)
1263                 return NULL;
1264         memset(resp, 0, *resp_len);
1265
1266         /* Both intermediate and final Result TLVs are identical, so ok to use
1267          * the same structure definition for them. */
1268         rresult = (struct eap_tlv_intermediate_result_tlv *) resp;
1269         rresult->tlv_type = host_to_be16(EAP_TLV_TYPE_MANDATORY |
1270                                          (final ? EAP_TLV_RESULT_TLV :
1271                                           EAP_TLV_INTERMEDIATE_RESULT_TLV));
1272         rresult->length = host_to_be16(2);
1273         rresult->status = host_to_be16(EAP_TLV_RESULT_SUCCESS);
1274
1275         if (!data->provisioning && data->phase2_success &&
1276             eap_fast_derive_msk(sm, data) < 0) {
1277                 wpa_printf(MSG_INFO, "EAP-FAST: Failed to generate MSK");
1278                 ret->methodState = METHOD_DONE;
1279                 ret->decision = DECISION_FAIL;
1280                 rresult->status = host_to_be16(EAP_TLV_RESULT_FAILURE);
1281                 data->phase2_success = 0;
1282         }
1283
1284         rbind = (struct eap_tlv_crypto_binding__tlv *) (rresult + 1);
1285         rbind->tlv_type = host_to_be16(EAP_TLV_TYPE_MANDATORY |
1286                                        EAP_TLV_CRYPTO_BINDING_TLV_);
1287         rbind->length = host_to_be16(sizeof(*rbind) -
1288                                      sizeof(struct eap_tlv_hdr));
1289         rbind->version = EAP_FAST_VERSION;
1290         rbind->received_version = bind->version;
1291         rbind->subtype = EAP_TLV_CRYPTO_BINDING_SUBTYPE_RESPONSE;
1292         memcpy(rbind->nonce, bind->nonce, sizeof(bind->nonce));
1293         inc_byte_array(rbind->nonce, sizeof(bind->nonce));
1294         hmac_sha1(cmk, 20, (u8 *) rbind, sizeof(*rbind), rbind->compound_mac);
1295
1296         wpa_printf(MSG_DEBUG, "EAP-FAST: Reply Crypto-Binding TLV: Version %d "
1297                    "Received Version %d SubType %d",
1298                    rbind->version, rbind->received_version, rbind->subtype);
1299         wpa_hexdump(MSG_MSGDUMP, "EAP-FAST: NONCE",
1300                     rbind->nonce, sizeof(rbind->nonce));
1301         wpa_hexdump(MSG_MSGDUMP, "EAP-FAST: Compound MAC",
1302                     rbind->compound_mac, sizeof(rbind->compound_mac));
1303
1304         if (final && data->phase2_success) {
1305                 wpa_printf(MSG_DEBUG, "EAP-FAST: Authentication completed "
1306                            "successfully.");
1307                 ret->methodState = METHOD_DONE;
1308                 ret->decision = DECISION_UNCOND_SUCC;
1309         }
1310
1311         return resp;
1312 }
1313
1314
1315 static u8 * eap_fast_process_pac(struct eap_sm *sm, struct eap_fast_data *data,
1316                                  struct eap_method_ret *ret,
1317                                  u8 *pac, size_t pac_len, size_t *resp_len)
1318 {
1319         struct wpa_ssid *config = eap_get_config(sm);
1320         struct pac_tlv_hdr *hdr;
1321         u8 *pos;
1322         size_t left, len;
1323         int type, pac_key_found = 0;
1324         struct eap_fast_pac entry;
1325
1326         memset(&entry, 0, sizeof(entry));
1327         pos = pac;
1328         left = pac_len;
1329         while (left > sizeof(*hdr)) {
1330                 hdr = (struct pac_tlv_hdr *) pos;
1331                 type = be_to_host16(hdr->type);
1332                 len = be_to_host16(hdr->len);
1333                 pos += sizeof(*hdr);
1334                 left -= sizeof(*hdr);
1335                 if (len > left) {
1336                         wpa_printf(MSG_DEBUG, "EAP-FAST: PAC TLV overrun "
1337                                    "(type=%d len=%lu left=%lu)",
1338                                    type, (unsigned long) len,
1339                                    (unsigned long) left);
1340                         return eap_fast_tlv_result(EAP_TLV_RESULT_FAILURE, 0,
1341                                                    resp_len);
1342                 }
1343                 switch (type) {
1344                 case PAC_TYPE_PAC_KEY:
1345                         wpa_hexdump_key(MSG_DEBUG, "EAP-FAST: PAC-Key",
1346                                         pos, len);
1347                         if (len != EAP_FAST_PAC_KEY_LEN) {
1348                                 wpa_printf(MSG_DEBUG, "EAP-FAST: Invalid "
1349                                            "PAC-Key length %lu",
1350                                            (unsigned long) len);
1351                                 break;
1352                         }
1353                         pac_key_found = 1;
1354                         memcpy(entry.pac_key, pos, len);
1355                         break;
1356                 case PAC_TYPE_PAC_OPAQUE:
1357                         wpa_hexdump(MSG_DEBUG, "EAP-FAST: PAC-Opaque",
1358                                         pos, len);
1359                         entry.pac_opaque = pos;
1360                         entry.pac_opaque_len = len;
1361                         break;
1362                 case PAC_TYPE_PAC_INFO:
1363                         wpa_hexdump(MSG_DEBUG, "EAP-FAST: PAC-Info",
1364                                     pos, len);
1365                         entry.pac_info = pos;
1366                         entry.pac_info_len = len;
1367                         break;
1368                 default:
1369                         wpa_printf(MSG_DEBUG, "EAP-FAST: Ignored unknown PAC "
1370                                    "type %d", type);
1371                         break;
1372                 }
1373
1374                 pos += len;
1375                 left -= len;
1376         }
1377
1378         if (!pac_key_found || !entry.pac_opaque || !entry.pac_info) {
1379                 wpa_printf(MSG_DEBUG, "EAP-FAST: PAC TLV does not include "
1380                            "all the required fields");
1381                 return eap_fast_tlv_result(EAP_TLV_RESULT_FAILURE, 0,
1382                                            resp_len);
1383         }
1384
1385         pos = entry.pac_info;
1386         left = entry.pac_info_len;
1387         while (left > sizeof(*hdr)) {
1388                 hdr = (struct pac_tlv_hdr *) pos;
1389                 type = be_to_host16(hdr->type);
1390                 len = be_to_host16(hdr->len);
1391                 pos += sizeof(*hdr);
1392                 left -= sizeof(*hdr);
1393                 if (len > left) {
1394                         wpa_printf(MSG_DEBUG, "EAP-FAST: PAC-Info overrun "
1395                                    "(type=%d len=%lu left=%lu)",
1396                                    type, (unsigned long) len,
1397                                    (unsigned long) left);
1398                         return eap_fast_tlv_result(EAP_TLV_RESULT_FAILURE, 0,
1399                                                    resp_len);
1400                 }
1401                 switch (type) {
1402                 case PAC_TYPE_A_ID:
1403                         wpa_hexdump_ascii(MSG_DEBUG, "EAP-FAST: PAC-Info - "
1404                                           "A-ID", pos, len);
1405                         entry.a_id = pos;
1406                         entry.a_id_len = len;
1407                         break;
1408                 case PAC_TYPE_I_ID:
1409                         wpa_hexdump_ascii(MSG_DEBUG, "EAP-FAST: PAC-Info - "
1410                                           "I-ID", pos, len);
1411                         entry.i_id = pos;
1412                         entry.i_id_len = len;
1413                         break;
1414                 case PAC_TYPE_A_ID_INFO:
1415                         wpa_hexdump_ascii(MSG_DEBUG, "EAP-FAST: PAC-Info - "
1416                                           "A-ID-Info", pos, len);
1417                         entry.a_id_info = pos;
1418                         entry.a_id_info_len = len;
1419                         break;
1420                 default:
1421                         wpa_printf(MSG_DEBUG, "EAP-FAST: Ignored unknown "
1422                                    "PAC-Info type %d", type);
1423                         break;
1424                 }
1425
1426                 pos += len;
1427                 left -= len;
1428         }
1429
1430         if (entry.a_id == NULL || entry.a_id_info == NULL) {
1431                 wpa_printf(MSG_DEBUG, "EAP-FAST: PAC-Info does not include "
1432                            "all the required fields");
1433                 return eap_fast_tlv_result(EAP_TLV_RESULT_FAILURE, 0,
1434                                            resp_len);
1435         }
1436
1437         eap_fast_add_pac(data, &entry);
1438         eap_fast_save_pac(sm, data, config->pac_file);
1439
1440         if (data->provisioning) {
1441                 /* EAP-FAST provisioning does not provide keying material and
1442                  * must end with an EAP-Failure. Authentication will be done
1443                  * separately after this. */
1444                 data->success = 0;
1445                 ret->decision = DECISION_FAIL;
1446                 wpa_printf(MSG_DEBUG, "EAP-FAST: Send PAC-Acknowledgement TLV "
1447                            "- Provisioning completed successfully");
1448         } else {
1449                 /* This is PAC refreshing, i.e., normal authentication that is
1450                  * expected to be completed with an EAP-Success. */
1451                 wpa_printf(MSG_DEBUG, "EAP-FAST: Send PAC-Acknowledgement TLV "
1452                            "- PAC refreshing completed successfully");
1453                 ret->decision = DECISION_UNCOND_SUCC;
1454         }
1455         ret->methodState = METHOD_DONE;
1456         return eap_fast_tlv_pac_ack(resp_len);
1457 }
1458
1459
1460 static int eap_fast_decrypt(struct eap_sm *sm, struct eap_fast_data *data,
1461                             struct eap_method_ret *ret,
1462                             const struct eap_hdr *req,
1463                             const u8 *in_data, size_t in_len,
1464                             u8 **out_data, size_t *out_len)
1465 {
1466         u8 *in_decrypted, *pos, *end;
1467         int buf_len, len_decrypted, len;
1468         struct eap_hdr *hdr;
1469         u8 *resp = NULL;
1470         size_t resp_len;
1471         int mandatory, tlv_type;
1472         u8 *eap_payload_tlv = NULL, *pac = NULL;
1473         size_t eap_payload_tlv_len = 0, pac_len = 0;
1474         int iresult = 0, result = 0;
1475         struct eap_tlv_crypto_binding__tlv *crypto_binding = NULL;
1476         size_t crypto_binding_len = 0;
1477         const u8 *msg;
1478         size_t msg_len;
1479         int need_more_input;
1480
1481         wpa_printf(MSG_DEBUG, "EAP-FAST: received %lu bytes encrypted data for"
1482                    " Phase 2", (unsigned long) in_len);
1483
1484         msg = eap_tls_data_reassemble(sm, &data->ssl, in_data, in_len,
1485                                       &msg_len, &need_more_input);
1486         if (msg == NULL)
1487                 return need_more_input ? 1 : -1;
1488
1489         buf_len = in_len;
1490         if (data->ssl.tls_in_total > buf_len)
1491                 buf_len = data->ssl.tls_in_total;
1492         in_decrypted = malloc(buf_len);
1493         if (in_decrypted == NULL) {
1494                 free(data->ssl.tls_in);
1495                 data->ssl.tls_in = NULL;
1496                 data->ssl.tls_in_len = 0;
1497                 wpa_printf(MSG_WARNING, "EAP-FAST: failed to allocate memory "
1498                            "for decryption");
1499                 return -1;
1500         }
1501
1502         len_decrypted = tls_connection_decrypt(sm->ssl_ctx, data->ssl.conn,
1503                                                msg, msg_len,
1504                                                in_decrypted, buf_len);
1505         free(data->ssl.tls_in);
1506         data->ssl.tls_in = NULL;
1507         data->ssl.tls_in_len = 0;
1508         if (len_decrypted < 0) {
1509                 wpa_printf(MSG_INFO, "EAP-FAST: Failed to decrypt Phase 2 "
1510                            "data");
1511                 free(in_decrypted);
1512                 return -1;
1513         }
1514
1515         wpa_hexdump(MSG_MSGDUMP, "EAP-FAST: Decrypted Phase 2 TLV(s)",
1516                     in_decrypted, len_decrypted);
1517
1518         if (len_decrypted < 4) {
1519                 free(in_decrypted);
1520                 wpa_printf(MSG_INFO, "EAP-FAST: Too short Phase 2 "
1521                            "TLV frame (len=%d)", len_decrypted);
1522                 return -1;
1523         }
1524
1525         pos = in_decrypted;
1526         end = in_decrypted + len_decrypted;
1527         while (pos + 4 < end) {
1528                 mandatory = pos[0] & 0x80;
1529                 tlv_type = WPA_GET_BE16(pos) & 0x3fff;
1530                 pos += 2;
1531                 len = WPA_GET_BE16(pos);
1532                 pos += 2;
1533                 if (pos + len > end) {
1534                         free(in_decrypted);
1535                         wpa_printf(MSG_INFO, "EAP-FAST: TLV overflow");
1536                         return 0;
1537                 }
1538                 wpa_printf(MSG_DEBUG, "EAP-FAST: received Phase 2: "
1539                            "TLV type %d length %d%s",
1540                            tlv_type, len, mandatory ? " (mandatory)" : "");
1541
1542                 switch (tlv_type) {
1543                 case EAP_TLV_EAP_PAYLOAD_TLV:
1544                         wpa_hexdump(MSG_MSGDUMP, "EAP-FAST: EAP Payload TLV",
1545                                     pos, len);
1546                         eap_payload_tlv = pos;
1547                         eap_payload_tlv_len = len;
1548                         break;
1549                 case EAP_TLV_RESULT_TLV:
1550                         wpa_hexdump(MSG_MSGDUMP, "EAP-FAST: Result TLV",
1551                                     pos, len);
1552                         if (len < 2) {
1553                                 wpa_printf(MSG_DEBUG, "EAP-FAST: Too short "
1554                                            "Result TLV");
1555                                 result = EAP_TLV_RESULT_FAILURE;
1556                                 break;
1557                         }
1558                         result = WPA_GET_BE16(pos);
1559                         if (result != EAP_TLV_RESULT_SUCCESS &&
1560                             result != EAP_TLV_RESULT_FAILURE) {
1561                                 wpa_printf(MSG_DEBUG, "EAP-FAST: Unknown "
1562                                            "Result %d", result);
1563                                 result = EAP_TLV_RESULT_FAILURE;
1564                         }
1565                         wpa_printf(MSG_DEBUG, "EAP-FAST: Result: %s",
1566                                    result == EAP_TLV_RESULT_SUCCESS ?
1567                                    "Success" : "Failure");
1568                         break;
1569                 case EAP_TLV_INTERMEDIATE_RESULT_TLV:
1570                         wpa_hexdump(MSG_MSGDUMP, "EAP-FAST: Intermediate "
1571                                     "Result TLV", pos, len);
1572                         if (len < 2) {
1573                                 wpa_printf(MSG_DEBUG, "EAP-FAST: Too short "
1574                                            "Intermediate Result TLV");
1575                                 iresult = EAP_TLV_RESULT_FAILURE;
1576                                 break;
1577                         }
1578                         iresult = WPA_GET_BE16(pos);
1579                         if (iresult != EAP_TLV_RESULT_SUCCESS &&
1580                             iresult != EAP_TLV_RESULT_FAILURE) {
1581                                 wpa_printf(MSG_DEBUG, "EAP-FAST: Unknown "
1582                                            "Intermediate Result %d", iresult);
1583                                 iresult = EAP_TLV_RESULT_FAILURE;
1584                         }
1585                         wpa_printf(MSG_DEBUG,
1586                                    "EAP-FAST: Intermediate Result: %s",
1587                                    iresult == EAP_TLV_RESULT_SUCCESS ?
1588                                    "Success" : "Failure");
1589                         break;
1590                 case EAP_TLV_CRYPTO_BINDING_TLV_:
1591                         wpa_hexdump(MSG_MSGDUMP, "EAP-FAST: Crypto-Binding "
1592                                     "TLV", pos, len);
1593                         crypto_binding_len = sizeof(struct eap_tlv_hdr) + len;
1594                         if (crypto_binding_len < sizeof(*crypto_binding)) {
1595                                 wpa_printf(MSG_DEBUG, "EAP-FAST: Too short "
1596                                            "Crypto-Binding TLV");
1597                                 iresult = EAP_TLV_RESULT_FAILURE;
1598                                 pos = end;
1599                                 break;
1600                         }
1601                         crypto_binding =
1602                                 (struct eap_tlv_crypto_binding__tlv *)
1603                                 (pos - sizeof(struct eap_tlv_hdr));
1604                         break;
1605                 case EAP_TLV_PAC_TLV:
1606                         wpa_hexdump(MSG_MSGDUMP, "EAP-FAST: PAC TLV",
1607                                     pos, len);
1608                         pac = pos;
1609                         pac_len = len;
1610                         break;
1611                 default:
1612                         if (mandatory) {
1613                                 wpa_printf(MSG_DEBUG, "EAP-FAST: Nak unknown "
1614                                            "mandatory TLV type %d", tlv_type);
1615                                 resp = eap_fast_tlv_nak(0, tlv_type,
1616                                                         &resp_len);
1617                                 pos = end;
1618                         } else {
1619                                 wpa_printf(MSG_DEBUG, "EAP-FAST: ignored "
1620                                            "unknown optional TLV type %d",
1621                                            tlv_type);
1622                         }
1623                         break;
1624                 }
1625
1626                 pos += len;
1627         }
1628
1629         if (!resp && result == EAP_TLV_RESULT_FAILURE) {
1630                 resp = eap_fast_tlv_result(EAP_TLV_RESULT_FAILURE, 0,
1631                                            &resp_len);
1632                 if (!resp) {
1633                         free(in_decrypted);
1634                         return 0;
1635                 }
1636         }
1637
1638         if (!resp && iresult == EAP_TLV_RESULT_FAILURE) {
1639                 resp = eap_fast_tlv_result(EAP_TLV_RESULT_FAILURE, 1,
1640                                            &resp_len);
1641                 if (!resp) {
1642                         free(in_decrypted);
1643                         return 0;
1644                 }
1645         }
1646
1647         if (!resp && eap_payload_tlv) {
1648                 if (eap_payload_tlv_len < sizeof(*hdr)) {
1649                         wpa_printf(MSG_DEBUG, "EAP-FAST: too short EAP "
1650                                    "Payload TLV (len=%lu)",
1651                                    (unsigned long) eap_payload_tlv_len);
1652                         free(in_decrypted);
1653                         return 0;
1654                 }
1655                 hdr = (struct eap_hdr *) eap_payload_tlv;
1656                 if (be_to_host16(hdr->length) > eap_payload_tlv_len) {
1657                         wpa_printf(MSG_DEBUG, "EAP-FAST: EAP packet overflow "
1658                                    "in EAP Payload TLV");
1659                 }
1660                 if (hdr->code == EAP_CODE_REQUEST) {
1661                         if (eap_fast_phase2_request(sm, data, ret, req, hdr,
1662                                                     &resp, &resp_len)) {
1663                                 free(in_decrypted);
1664                                 wpa_printf(MSG_INFO, "EAP-FAST: Phase2 "
1665                                            "Request processing failed");
1666                                 return 0;
1667                         }
1668                         resp = eap_fast_tlv_eap_payload(resp, &resp_len);
1669                         if (resp == NULL) {
1670                                 free(in_decrypted);
1671                                 return 0;
1672                         }
1673                 } else {
1674                         wpa_printf(MSG_INFO, "EAP-FAST: Unexpected code=%d in "
1675                                    "Phase 2 EAP header", hdr->code);
1676                         free(in_decrypted);
1677                         return 0;
1678                 }
1679         }
1680
1681         if (!resp && crypto_binding) {
1682                 int final = result == EAP_TLV_RESULT_SUCCESS;
1683                 resp = eap_fast_process_crypto_binding(sm, data, ret,
1684                                                        crypto_binding,
1685                                                        crypto_binding_len,
1686                                                        &resp_len, final);
1687                 if (!resp) {
1688                         free(in_decrypted);
1689                         return 0;
1690                 }
1691         }
1692
1693         if (!resp && pac && result != EAP_TLV_RESULT_SUCCESS) {
1694                 wpa_printf(MSG_DEBUG, "EAP-FAST: PAC TLV without Result TLV "
1695                            "acknowledging success");
1696                 resp = eap_fast_tlv_result(EAP_TLV_RESULT_FAILURE, 0,
1697                                            &resp_len);
1698                 if (!resp) {
1699                         free(in_decrypted);
1700                         return 0;
1701                 }
1702         }
1703
1704         if (!resp && pac && result == EAP_TLV_RESULT_SUCCESS) {
1705                 resp = eap_fast_process_pac(sm, data, ret, pac, pac_len,
1706                                             &resp_len);
1707                 if (!resp) {
1708                         free(in_decrypted);
1709                         return 0;
1710                 }
1711         }
1712
1713         free(in_decrypted);
1714
1715         if (resp == NULL) {
1716                 wpa_printf(MSG_DEBUG, "EAP-FAST: No recognized TLVs - send "
1717                            "empty response packet");
1718                 resp = malloc(1);
1719                 if (resp == NULL)
1720                         return 0;
1721                 resp_len = 0;
1722         }
1723
1724         wpa_hexdump(MSG_DEBUG, "EAP-FAST: Encrypting Phase 2 data",
1725                     resp, resp_len);
1726         if (eap_fast_encrypt(sm, data, req->identifier, resp, resp_len,
1727                              out_data, out_len)) {
1728                 wpa_printf(MSG_INFO, "EAP-FAST: Failed to encrypt a Phase 2 "
1729                            "frame");
1730         }
1731         free(resp);
1732
1733         return 0;
1734 }
1735
1736
1737 static u8 * eap_fast_process(struct eap_sm *sm, void *priv,
1738                              struct eap_method_ret *ret,
1739                              const u8 *reqData, size_t reqDataLen,
1740                              size_t *respDataLen)
1741 {
1742         const struct eap_hdr *req;
1743         size_t left;
1744         int res;
1745         u8 flags, *resp, id;
1746         const u8 *pos;
1747         struct eap_fast_data *data = priv;
1748
1749         pos = eap_tls_process_init(sm, &data->ssl, EAP_TYPE_FAST, ret,
1750                                    reqData, reqDataLen, &left, &flags);
1751         if (pos == NULL)
1752                 return NULL;
1753         req = (const struct eap_hdr *) reqData;
1754         id = req->identifier;
1755
1756         if (flags & EAP_TLS_FLAGS_START) {
1757                 const u8 *a_id;
1758                 size_t a_id_len;
1759                 struct pac_tlv_hdr *hdr;
1760
1761                 wpa_printf(MSG_DEBUG, "EAP-FAST: Start (server ver=%d, own "
1762                            "ver=%d)", flags & EAP_PEAP_VERSION_MASK,
1763                         data->fast_version);
1764                 if ((flags & EAP_PEAP_VERSION_MASK) < data->fast_version)
1765                         data->fast_version = flags & EAP_PEAP_VERSION_MASK;
1766                 wpa_printf(MSG_DEBUG, "EAP-FAST: Using FAST version %d",
1767                            data->fast_version);
1768
1769                 a_id = pos;
1770                 a_id_len = left;
1771                 if (left > sizeof(*hdr)) {
1772                         int tlen;
1773                         hdr = (struct pac_tlv_hdr *) pos;
1774                         tlen = be_to_host16(hdr->len);
1775                         if (be_to_host16(hdr->type) == PAC_TYPE_A_ID &&
1776                             sizeof(*hdr) + tlen <= left) {
1777                                 a_id = (u8 *) (hdr + 1);
1778                                 a_id_len = tlen;
1779                         }
1780                 }
1781                 wpa_hexdump_ascii(MSG_DEBUG, "EAP-FAST: A-ID", a_id, a_id_len);
1782
1783                 data->current_pac = eap_fast_get_pac(data, a_id, a_id_len);
1784                 if (data->current_pac) {
1785                         wpa_printf(MSG_DEBUG, "EAP-FAST: PAC found for this "
1786                                    "A-ID");
1787                         wpa_hexdump_ascii(MSG_MSGDUMP, "EAP-FAST: A-ID-Info",
1788                                           data->current_pac->a_id_info,
1789                                           data->current_pac->a_id_info_len);
1790                 }
1791
1792                 if (data->resuming && data->current_pac) {
1793                         wpa_printf(MSG_DEBUG, "EAP-FAST: Trying to resume "
1794                                    "session - do not add PAC-Opaque to TLS "
1795                                    "ClientHello");
1796                         if (tls_connection_client_hello_ext(
1797                                     sm->ssl_ctx, data->ssl.conn,
1798                                     TLS_EXT_PAC_OPAQUE, NULL, 0) < 0) {
1799                                 wpa_printf(MSG_DEBUG, "EAP-FAST: Failed to "
1800                                            "remove PAC-Opaque TLS extension");
1801                                 return NULL;
1802                         }
1803
1804                 } else if (data->current_pac) {
1805                         u8 *tlv;
1806                         size_t tlv_len, olen;
1807                         struct eap_tlv_hdr *hdr;
1808                         olen = data->current_pac->pac_opaque_len;
1809                         tlv_len = sizeof(*hdr) + olen;
1810                         tlv = malloc(tlv_len);
1811                         if (tlv) {
1812                                 hdr = (struct eap_tlv_hdr *) tlv;
1813                                 hdr->tlv_type =
1814                                         host_to_be16(PAC_TYPE_PAC_OPAQUE);
1815                                 hdr->length = host_to_be16(olen);
1816                                 memcpy(hdr + 1, data->current_pac->pac_opaque,
1817                                        olen);
1818                         }
1819                         if (tlv == NULL ||
1820                             tls_connection_client_hello_ext(
1821                                     sm->ssl_ctx, data->ssl.conn,
1822                                     TLS_EXT_PAC_OPAQUE, tlv, tlv_len) < 0) {
1823                                 wpa_printf(MSG_DEBUG, "EAP-FAST: Failed to "
1824                                            "add PAC-Opaque TLS extension");
1825                                 free(tlv);
1826                                 return NULL;
1827                         }
1828                         free(tlv);
1829                 } else {
1830                         if (!data->provisioning_allowed) {
1831                                 wpa_printf(MSG_DEBUG, "EAP-FAST: No PAC found "
1832                                            "and provisioning disabled");
1833                                 return NULL;
1834                         }
1835                         wpa_printf(MSG_DEBUG, "EAP-FAST: No PAC found - "
1836                                    "starting provisioning");
1837                         if (tls_connection_set_anon_dh(sm->ssl_ctx,
1838                                                        data->ssl.conn)) {
1839                                 wpa_printf(MSG_INFO, "EAP-FAST: Could not "
1840                                            "configure anonymous DH for TLS "
1841                                            "connection");
1842                                 return NULL;
1843                         }
1844                         if (tls_connection_client_hello_ext(
1845                                     sm->ssl_ctx, data->ssl.conn,
1846                                     TLS_EXT_PAC_OPAQUE, NULL, 0) < 0) {
1847                                 wpa_printf(MSG_DEBUG, "EAP-FAST: Failed to "
1848                                            "remove PAC-Opaque TLS extension");
1849                                 return NULL;
1850                         }
1851                         data->provisioning = 1;
1852                 }
1853
1854                 left = 0; /* A-ID is not used in further packet processing */
1855         }
1856
1857         resp = NULL;
1858         if (tls_connection_established(sm->ssl_ctx, data->ssl.conn) &&
1859             !data->resuming) {
1860                 res = eap_fast_decrypt(sm, data, ret, req, pos, left,
1861                                        &resp, respDataLen);
1862                 if (res < 0) {
1863                         ret->methodState = METHOD_DONE;
1864                         ret->decision = DECISION_FAIL;
1865                         /* Ack possible Alert that may have caused failure in
1866                          * decryption */
1867                         res = 1;
1868                 }
1869         } else {
1870                 if (eap_fast_set_tls_master_secret(sm, data, pos, left) < 0) {
1871                         wpa_printf(MSG_DEBUG, "EAP-FAST: Failed to configure "
1872                                    "TLS master secret");
1873                         ret->methodState = METHOD_DONE;
1874                         ret->decision = DECISION_FAIL;
1875                         return NULL;
1876                 }
1877
1878                 res = eap_tls_process_helper(sm, &data->ssl, EAP_TYPE_FAST,
1879                                              data->fast_version, id, pos, left,
1880                                              &resp, respDataLen);
1881
1882                 if (tls_connection_established(sm->ssl_ctx, data->ssl.conn)) {
1883                         wpa_printf(MSG_DEBUG,
1884                                    "EAP-FAST: TLS done, proceed to Phase 2");
1885                         data->resuming = 0;
1886                         eap_fast_derive_keys(sm, data);
1887                 }
1888         }
1889
1890         if (res == 1)
1891                 return eap_tls_build_ack(&data->ssl, respDataLen, id,
1892                                          EAP_TYPE_FAST, data->fast_version);
1893         return resp;
1894 }
1895
1896
1897 #if 0 /* FIX */
1898 static Boolean eap_fast_has_reauth_data(struct eap_sm *sm, void *priv)
1899 {
1900         struct eap_fast_data *data = priv;
1901         return tls_connection_established(sm->ssl_ctx, data->ssl.conn);
1902 }
1903
1904
1905 static void eap_fast_deinit_for_reauth(struct eap_sm *sm, void *priv)
1906 {
1907 }
1908
1909
1910 static void * eap_fast_init_for_reauth(struct eap_sm *sm, void *priv)
1911 {
1912         struct eap_fast_data *data = priv;
1913         if (eap_tls_reauth_init(sm, &data->ssl)) {
1914                 free(data);
1915                 return NULL;
1916         }
1917         data->phase2_success = 0;
1918         data->resuming = 1;
1919         data->provisioning = 0;
1920         return priv;
1921 }
1922 #endif
1923
1924
1925 static int eap_fast_get_status(struct eap_sm *sm, void *priv, char *buf,
1926                                size_t buflen, int verbose)
1927 {
1928         struct eap_fast_data *data = priv;
1929         int len;
1930
1931         len = eap_tls_status(sm, &data->ssl, buf, buflen, verbose);
1932         if (data->phase2_method) {
1933                 len += snprintf(buf + len, buflen - len,
1934                                 "EAP-FAST Phase2 method=%s\n",
1935                                 data->phase2_method->name);
1936         }
1937         return len;
1938 }
1939
1940
1941 static Boolean eap_fast_isKeyAvailable(struct eap_sm *sm, void *priv)
1942 {
1943         struct eap_fast_data *data = priv;
1944         return data->success;
1945 }
1946
1947
1948 static u8 * eap_fast_getKey(struct eap_sm *sm, void *priv, size_t *len)
1949 {
1950         struct eap_fast_data *data = priv;
1951         u8 *key;
1952
1953         if (!data->success)
1954                 return NULL;
1955
1956         key = malloc(EAP_FAST_KEY_LEN);
1957         if (key == NULL)
1958                 return NULL;
1959
1960         *len = EAP_FAST_KEY_LEN;
1961         memcpy(key, data->key_data, EAP_FAST_KEY_LEN);
1962
1963         return key;
1964 }
1965
1966
1967 const struct eap_method eap_method_fast =
1968 {
1969         .method = EAP_TYPE_FAST,
1970         .name = "FAST",
1971         .init = eap_fast_init,
1972         .deinit = eap_fast_deinit,
1973         .process = eap_fast_process,
1974         .isKeyAvailable = eap_fast_isKeyAvailable,
1975         .getKey = eap_fast_getKey,
1976         .get_status = eap_fast_get_status,
1977 #if 0
1978         .has_reauth_data = eap_fast_has_reauth_data,
1979         .deinit_for_reauth = eap_fast_deinit_for_reauth,
1980         .init_for_reauth = eap_fast_init_for_reauth,
1981 #endif
1982 };