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