2 * WPA Supplicant / EAP-FAST (draft-cam-winget-eap-fast-00.txt)
3 * Copyright (c) 2004-2005, Jouni Malinen <jkmaline@cc.hut.fi>
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.
9 * Alternatively, this software may be distributed under the terms of BSD
12 * See README and COPYING for more details.
21 #include "eap_tls_common.h"
22 #include "wpa_supplicant.h"
23 #include "config_ssid.h"
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)
35 #define EAP_FAST_VERSION 1
36 #define EAP_FAST_KEY_LEN 64
37 #define EAP_FAST_PAC_KEY_LEN 32
39 #define TLS_EXT_PAC_OPAQUE 35
41 static const char *pac_file_hdr =
42 "wpa_supplicant EAP-FAST PAC file - version 1";
45 static void eap_fast_deinit(struct eap_sm *sm, void *priv);
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
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];
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];
83 struct eap_fast_pac *next;
85 u8 pac_key[EAP_FAST_PAC_KEY_LEN];
87 size_t pac_opaque_len;
99 struct eap_fast_data {
100 struct eap_ssl_data ssl;
104 const struct eap_method *phase2_method;
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) */
117 u8 key_data[EAP_FAST_KEY_LEN];
120 struct eap_fast_pac *pac;
121 struct eap_fast_pac *current_pac;
123 int tls_master_secret_set;
127 static void eap_fast_free_pac(struct eap_fast_pac *pac)
129 free(pac->pac_opaque);
133 free(pac->a_id_info);
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)
141 struct eap_fast_pac *pac = data->pac;
144 if (pac->a_id_len == a_id_len &&
145 memcmp(pac->a_id, a_id, a_id_len) == 0) {
154 static int eap_fast_add_pac(struct eap_fast_data *data,
155 struct eap_fast_pac *entry)
157 struct eap_fast_pac *pac, *prev;
159 if (entry == NULL || entry->a_id == NULL)
162 /* Remove a possible old entry for the matching A-ID. */
166 if (pac->a_id_len == entry->a_id_len &&
167 memcmp(pac->a_id, entry->a_id, pac->a_id_len) == 0) {
169 data->pac = pac->next;
171 prev->next = pac->next;
173 if (data->current_pac == pac)
174 data->current_pac = NULL;
175 eap_fast_free_pac(pac);
182 /* Allocate a new entry and add it to the list of PACs. */
183 pac = malloc(sizeof(*pac));
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);
195 memcpy(pac->pac_opaque, entry->pac_opaque,
196 entry->pac_opaque_len);
197 pac->pac_opaque_len = entry->pac_opaque_len;
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);
205 memcpy(pac->pac_info, entry->pac_info,
206 entry->pac_info_len);
207 pac->pac_info_len = entry->pac_info_len;
210 pac->a_id = malloc(entry->a_id_len);
211 if (pac->a_id == NULL) {
212 eap_fast_free_pac(pac);
215 memcpy(pac->a_id, entry->a_id,
217 pac->a_id_len = entry->a_id_len;
220 pac->i_id = malloc(entry->i_id_len);
221 if (pac->i_id == NULL) {
222 eap_fast_free_pac(pac);
225 memcpy(pac->i_id, entry->i_id,
227 pac->i_id_len = entry->i_id_len;
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);
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;
239 pac->next = data->pac;
245 struct eap_fast_read_ctx {
251 static int eap_fast_read_line(struct eap_fast_read_ctx *rc, char *buf,
257 if (fgets(buf, buf_len, rc->f) == NULL)
262 if (rc->pos >= rc->end)
265 while (l_end < rc->end && *l_end != '\n')
267 len = l_end - rc->pos;
270 memcpy(buf, rc->pos, len);
275 buf[buf_len - 1] = '\0';
277 while (*pos != '\0') {
278 if (*pos == '\n' || *pos == '\r') {
289 static u8 * eap_fast_parse_hex(const char *value, size_t *len)
296 hlen = strlen(value);
303 if (hexstr2bin(value, buf, *len)) {
311 static int eap_fast_load_pac(struct eap_sm *sm, struct eap_fast_data *data,
312 const char *pac_file)
314 struct eap_fast_read_ctx rc;
315 struct eap_fast_pac *pac = NULL;
318 const int buf_len = 2048;
319 int ret = 0, line = 0;
321 if (pac_file == NULL)
324 memset(&rc, 0, sizeof(rc));
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);
330 wpa_printf(MSG_INFO, "EAP-FAST: No PAC blob '%s' - "
331 "assume no PAC entries have been "
332 "provisioned", pac_file + 7);
335 rc.pos = (char *) blob->data;
336 rc.end = (char *) blob->data + blob->len;
338 rc.f = fopen(pac_file, "r");
340 wpa_printf(MSG_INFO, "EAP-FAST: No PAC file '%s' - "
341 "assume no PAC entries have been "
342 "provisioned", pac_file);
347 buf = malloc(buf_len);
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);
363 while (eap_fast_read_line(&rc, buf, buf_len) == 0) {
365 pos = strchr(buf, '=');
370 if (strcmp(buf, "START") == 0) {
372 wpa_printf(MSG_INFO, "EAP-FAST: START line "
373 "without END in '%s:%d'",
378 pac = malloc(sizeof(*pac));
380 wpa_printf(MSG_INFO, "EAP-FAST: No memory for "
385 memset(pac, 0, sizeof(*pac));
386 } else if (strcmp(buf, "END") == 0) {
388 wpa_printf(MSG_INFO, "EAP-FAST: END line "
389 "without START in '%s:%d'",
394 pac->next = data->pac;
398 } else if (pac && strcmp(buf, "PAC-Key") == 0) {
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);
410 memcpy(pac->pac_key, key, EAP_FAST_PAC_KEY_LEN);
412 } else if (pac && strcmp(buf, "PAC-Opaque") == 0) {
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'",
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);
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);
438 } else if (pac && strcmp(buf, "A-ID-Info") == 0) {
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 "
452 wpa_printf(MSG_INFO, "EAP-FAST: PAC block not terminated with "
453 "END in '%s'", pac_file);
454 eap_fast_free_pac(pac);
463 wpa_printf(MSG_DEBUG, "EAP-FAST: read %d PAC entries from "
464 "'%s'", count, pac_file);
471 static void eap_fast_write(char **buf, char **pos, size_t *buf_len,
472 const char *field, const u8 *data,
478 if (data == NULL || *buf == NULL)
481 need = strlen(field) + len * 2 + 30;
483 need += strlen(field) + len + 20;
485 if (*pos - *buf + need > *buf_len) {
486 char *nbuf = realloc(*buf, *buf_len + need);
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,
501 *pos += snprintf(*pos, *buf + *buf_len - *pos, "\n");
504 *pos += snprintf(*pos, *buf + *buf_len - *pos,
506 for (i = 0; i < len; i++) {
507 *pos += snprintf(*pos, *buf + *buf_len - *pos,
510 *pos += snprintf(*pos, *buf + *buf_len - *pos, "\n");
515 static int eap_fast_save_pac(struct eap_sm *sm, struct eap_fast_data *data,
516 const char *pac_file)
519 struct eap_fast_pac *pac;
524 if (pac_file == NULL)
528 pos = buf = malloc(buf_len);
532 pos += snprintf(pos, buf + buf_len - pos, "%s\n", pac_file_hdr);
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,
545 eap_fast_write(&buf, &pos, &buf_len, "I-ID", pac->i_id,
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");
554 wpa_printf(MSG_DEBUG, "EAP-FAST: No memory for PAC "
560 if (strncmp(pac_file, "blob://", 7) == 0) {
561 struct wpa_config_blob *blob;
562 blob = malloc(sizeof(*blob));
567 memset(blob, 0, sizeof(*blob));
568 blob->data = (u8 *) buf;
569 blob->len = pos - buf;
571 blob->name = strdup(pac_file + 7);
572 if (blob->name == NULL) {
573 wpa_config_free_blob(blob);
576 eap_set_config_blob(sm, blob);
578 f = fopen(pac_file, "w");
580 wpa_printf(MSG_INFO, "EAP-FAST: Failed to open PAC "
581 "file '%s' for writing", pac_file);
585 fprintf(f, "%s", buf);
590 wpa_printf(MSG_DEBUG, "EAP-FAST: wrote %d PAC entries into '%s'",
597 static void * eap_fast_init(struct eap_sm *sm)
599 struct eap_fast_data *data;
600 struct wpa_ssid *config = eap_get_config(sm);
602 data = malloc(sizeof(*data));
605 memset(data, 0, sizeof(*data));
606 data->fast_version = EAP_FAST_VERSION;
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");
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);
622 eap_fast_deinit(sm, data);
625 while (start && *start != '\0') {
626 pos = strstr(start, "auth=");
629 if (start != pos && *(pos - 1) != ' ') {
635 pos = strchr(start, ' ');
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);
644 _methods = realloc(methods, num_methods);
645 if (_methods == NULL) {
648 eap_fast_deinit(sm, data);
652 methods[num_methods - 1] = method;
658 data->phase2_types = methods;
659 data->num_phase2_types = num_methods;
661 if (data->phase2_types == NULL) {
663 eap_get_phase2_types(config, &data->num_phase2_types);
665 if (data->phase2_types == NULL) {
666 wpa_printf(MSG_ERROR, "EAP-FAST: No Phase2 method available");
667 eap_fast_deinit(sm, data);
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;
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);
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);
685 if (eap_fast_load_pac(sm, data, config->pac_file) < 0) {
686 eap_fast_deinit(sm, data);
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);
701 static void eap_fast_deinit(struct eap_sm *sm, void *priv)
703 struct eap_fast_data *data = priv;
704 struct eap_fast_pac *pac, *prev;
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);
720 eap_fast_free_pac(prev);
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)
732 struct eap_hdr *resp;
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);
740 resp->code = EAP_CODE_RESPONSE;
741 resp->identifier = id;
743 pos = (u8 *) (resp + 1);
744 *pos++ = EAP_TYPE_FAST;
745 *pos++ = data->fast_version;
747 res = tls_connection_encrypt(sm->ssl_ctx, data->ssl.conn,
749 pos, data->ssl.tls_out_limit);
751 wpa_printf(MSG_INFO, "EAP-FAST: Failed to encrypt Phase 2 "
757 *out_len = sizeof(struct eap_hdr) + 2 + res;
758 resp->length = host_to_be16(*out_len);
759 *out_data = (u8 *) resp;
764 static int eap_fast_phase2_nak(struct eap_sm *sm,
765 struct eap_fast_data *data,
767 u8 **resp, size_t *resp_len)
769 struct eap_hdr *resp_hdr;
770 u8 *pos = (u8 *) (hdr + 1);
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);
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);
792 static int eap_fast_derive_msk(struct eap_sm *sm, struct eap_fast_data *data)
797 if (data->key_block_a == NULL)
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);
808 wpa_hexdump_key(MSG_DEBUG, "EAP-FAST: Derived key (MSK)",
809 data->key_data, EAP_FAST_KEY_LEN);
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)
821 struct tls_keys keys;
822 u8 master_secret[48], *seed;
823 const u8 *server_random;
824 size_t seed_len, server_random_len;
826 if (data->tls_master_secret_set || !data->current_pac ||
827 tls_connection_get_keys(sm->ssl_ctx, data->ssl.conn, &keys)) {
831 wpa_hexdump(MSG_DEBUG, "EAP-FAST: client_random",
832 keys.client_random, keys.client_random_len);
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.
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)
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);
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);
862 seed_len = keys.client_random_len + server_random_len;
863 seed = malloc(seed_len);
866 memcpy(seed, server_random, server_random_len);
867 memcpy(seed + server_random_len,
868 keys.client_random, keys.client_random_len);
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));
879 wpa_hexdump_key(MSG_DEBUG, "EAP-FAST: TLS pre-master-secret",
880 master_secret, sizeof(master_secret));
882 data->tls_master_secret_set = 1;
884 return tls_connection_set_master_key(sm->ssl_ctx, data->ssl.conn,
886 sizeof(master_secret));
890 static u8 * eap_fast_derive_key(struct eap_sm *sm, struct eap_ssl_data *data,
891 char *label, size_t len)
893 struct tls_keys keys;
898 if (tls_connection_get_keys(sm->ssl_ctx, data->conn, &keys))
900 block_size = tls_connection_get_keyblock_size(sm->ssl_ctx, data->conn);
903 out = malloc(block_size + len);
904 rnd = malloc(keys.client_random_len + keys.server_random_len);
905 if (out == NULL || rnd == NULL) {
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);
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)) {
924 memmove(out, out + block_size, len);
929 static void eap_fast_derive_key_auth(struct eap_sm *sm,
930 struct eap_fast_data *data)
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 "
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));
947 static void eap_fast_derive_key_provisioning(struct eap_sm *sm,
948 struct eap_fast_data *data)
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");
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));
970 static void eap_fast_derive_keys(struct eap_sm *sm, struct eap_fast_data *data)
972 if (data->current_pac) {
973 eap_fast_derive_key_auth(sm, data);
975 eap_fast_derive_key_provisioning(sm, data);
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,
985 u8 **resp, size_t *resp_len)
987 size_t len = be_to_host16(hdr->length);
989 struct eap_method_ret iret;
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);
996 pos = (u8 *) (hdr + 1);
997 wpa_printf(MSG_DEBUG, "EAP-FAST: Phase 2 Request: type=%d", *pos);
999 case EAP_TYPE_IDENTITY:
1000 *resp = eap_sm_buildIdentity(sm, req->identifier, resp_len, 1);
1003 if (data->phase2_type == EAP_TYPE_NONE) {
1005 for (i = 0; i < data->num_phase2_types; i++) {
1006 if (data->phase2_types[i] != *pos)
1009 data->phase2_type = *pos;
1010 wpa_printf(MSG_DEBUG, "EAP-FAST: Selected "
1011 "Phase 2 EAP method %d",
1016 if (*pos != data->phase2_type || *pos == EAP_TYPE_NONE) {
1017 if (eap_fast_phase2_nak(sm, data, hdr, resp, resp_len))
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 =
1029 sm->peer_challenge =
1033 sm->init_phase2 = 1;
1035 data->phase2_method->init(sm);
1036 sm->init_phase2 = 0;
1037 sm->auth_challenge = NULL;
1038 sm->peer_challenge = NULL;
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;
1048 memset(&iret, 0, sizeof(iret));
1049 *resp = data->phase2_method->process(sm, data->phase2_priv,
1050 &iret, (u8 *) hdr, 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;
1071 static u8 * eap_fast_tlv_nak(int vendor_id, int tlv_type, size_t *len)
1073 struct eap_tlv_nak_tlv *nak;
1074 *len = sizeof(*nak);
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);
1086 static u8 * eap_fast_tlv_result(int status, int intermediate, size_t *len)
1088 struct eap_tlv_intermediate_result_tlv *result;
1089 *len = sizeof(*result);
1090 result = malloc(*len);
1093 result->tlv_type = host_to_be16(EAP_TLV_TYPE_MANDATORY |
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;
1103 static u8 * eap_fast_tlv_pac_ack(size_t *len)
1105 struct eap_tlv_result_tlv *res;
1106 struct eap_tlv_pac_ack_tlv *ack;
1108 *len = sizeof(*res) + sizeof(*ack);
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);
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);
1131 static u8 * eap_fast_tlv_eap_payload(u8 *buf, size_t *len)
1133 struct eap_tlv_hdr *tlv;
1135 /* Encapsulate EAP packet in EAP Payload TLV */
1136 tlv = malloc(sizeof(*tlv) + *len);
1138 wpa_printf(MSG_DEBUG, "EAP-FAST: Failed to "
1139 "allocate memory for TLV "
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);
1149 *len += sizeof(*tlv);
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)
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;
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));
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,
1183 resp = eap_fast_tlv_result(EAP_TLV_RESULT_FAILURE, 1,
1189 if (data->provisioning) {
1190 if (data->key_block_p) {
1191 sks = data->key_block_p->session_key_seed;
1194 if (data->key_block_a) {
1195 sks = data->key_block_a->session_key_seed;
1199 wpa_printf(MSG_INFO, "EAP-FAST: No Session Key Seed available "
1200 "for processing Crypto-Binding TLV");
1204 wpa_printf(MSG_DEBUG, "EAP-FAST: Determining CMK for Compound MIC "
1206 wpa_hexdump_key(MSG_MSGDUMP, "EAP-FAST: S-IMCK[0] = SKS", sks, 40);
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 "
1214 if (data->phase2_method->isKeyAvailable && data->phase2_method->getKey)
1216 if (!data->phase2_method->isKeyAvailable(sm, data->phase2_priv)
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");
1224 if (key_len > sizeof(isk))
1225 key_len = sizeof(isk);
1226 /* FIX: which end is being padded? */
1228 memcpy(isk + (sizeof(isk) - key_len), key, key_len);
1230 memcpy(isk, key, key_len);
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);
1240 wpa_hexdump_key(MSG_MSGDUMP, "EAP-FAST: CMK", cmk, 20);
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));
1253 wpa_printf(MSG_INFO, "EAP-FAST: Compound MAC did not match");
1254 resp = eap_fast_tlv_result(EAP_TLV_RESULT_FAILURE, 1,
1256 memcpy(bind->compound_mac, cmac, sizeof(cmac));
1260 *resp_len = sizeof(*rresult) + sizeof(*rbind);
1261 resp = malloc(*resp_len);
1264 memset(resp, 0, *resp_len);
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);
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;
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);
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));
1304 if (final && data->phase2_success) {
1305 wpa_printf(MSG_DEBUG, "EAP-FAST: Authentication completed "
1307 ret->methodState = METHOD_DONE;
1308 ret->decision = DECISION_UNCOND_SUCC;
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)
1319 struct wpa_ssid *config = eap_get_config(sm);
1320 struct pac_tlv_hdr *hdr;
1323 int type, pac_key_found = 0;
1324 struct eap_fast_pac entry;
1326 memset(&entry, 0, sizeof(entry));
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);
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,
1344 case PAC_TYPE_PAC_KEY:
1345 wpa_hexdump_key(MSG_DEBUG, "EAP-FAST: PAC-Key",
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);
1354 memcpy(entry.pac_key, pos, len);
1356 case PAC_TYPE_PAC_OPAQUE:
1357 wpa_hexdump(MSG_DEBUG, "EAP-FAST: PAC-Opaque",
1359 entry.pac_opaque = pos;
1360 entry.pac_opaque_len = len;
1362 case PAC_TYPE_PAC_INFO:
1363 wpa_hexdump(MSG_DEBUG, "EAP-FAST: PAC-Info",
1365 entry.pac_info = pos;
1366 entry.pac_info_len = len;
1369 wpa_printf(MSG_DEBUG, "EAP-FAST: Ignored unknown PAC "
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,
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);
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,
1403 wpa_hexdump_ascii(MSG_DEBUG, "EAP-FAST: PAC-Info - "
1406 entry.a_id_len = len;
1409 wpa_hexdump_ascii(MSG_DEBUG, "EAP-FAST: PAC-Info - "
1412 entry.i_id_len = len;
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;
1421 wpa_printf(MSG_DEBUG, "EAP-FAST: Ignored unknown "
1422 "PAC-Info type %d", type);
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,
1437 eap_fast_add_pac(data, &entry);
1438 eap_fast_save_pac(sm, data, config->pac_file);
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. */
1445 ret->decision = DECISION_FAIL;
1446 wpa_printf(MSG_DEBUG, "EAP-FAST: Send PAC-Acknowledgement TLV "
1447 "- Provisioning completed successfully");
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;
1455 ret->methodState = METHOD_DONE;
1456 return eap_fast_tlv_pac_ack(resp_len);
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)
1466 u8 *in_decrypted, *pos, *end;
1467 int buf_len, len_decrypted, len;
1468 struct eap_hdr *hdr;
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;
1479 int need_more_input;
1481 wpa_printf(MSG_DEBUG, "EAP-FAST: received %lu bytes encrypted data for"
1482 " Phase 2", (unsigned long) in_len);
1484 msg = eap_tls_data_reassemble(sm, &data->ssl, in_data, in_len,
1485 &msg_len, &need_more_input);
1487 return need_more_input ? 1 : -1;
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 "
1502 len_decrypted = tls_connection_decrypt(sm->ssl_ctx, data->ssl.conn,
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 "
1515 wpa_hexdump(MSG_MSGDUMP, "EAP-FAST: Decrypted Phase 2 TLV(s)",
1516 in_decrypted, len_decrypted);
1518 if (len_decrypted < 4) {
1520 wpa_printf(MSG_INFO, "EAP-FAST: Too short Phase 2 "
1521 "TLV frame (len=%d)", len_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;
1531 len = WPA_GET_BE16(pos);
1533 if (pos + len > end) {
1535 wpa_printf(MSG_INFO, "EAP-FAST: TLV overflow");
1538 wpa_printf(MSG_DEBUG, "EAP-FAST: received Phase 2: "
1539 "TLV type %d length %d%s",
1540 tlv_type, len, mandatory ? " (mandatory)" : "");
1543 case EAP_TLV_EAP_PAYLOAD_TLV:
1544 wpa_hexdump(MSG_MSGDUMP, "EAP-FAST: EAP Payload TLV",
1546 eap_payload_tlv = pos;
1547 eap_payload_tlv_len = len;
1549 case EAP_TLV_RESULT_TLV:
1550 wpa_hexdump(MSG_MSGDUMP, "EAP-FAST: Result TLV",
1553 wpa_printf(MSG_DEBUG, "EAP-FAST: Too short "
1555 result = EAP_TLV_RESULT_FAILURE;
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;
1565 wpa_printf(MSG_DEBUG, "EAP-FAST: Result: %s",
1566 result == EAP_TLV_RESULT_SUCCESS ?
1567 "Success" : "Failure");
1569 case EAP_TLV_INTERMEDIATE_RESULT_TLV:
1570 wpa_hexdump(MSG_MSGDUMP, "EAP-FAST: Intermediate "
1571 "Result TLV", pos, len);
1573 wpa_printf(MSG_DEBUG, "EAP-FAST: Too short "
1574 "Intermediate Result TLV");
1575 iresult = EAP_TLV_RESULT_FAILURE;
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;
1585 wpa_printf(MSG_DEBUG,
1586 "EAP-FAST: Intermediate Result: %s",
1587 iresult == EAP_TLV_RESULT_SUCCESS ?
1588 "Success" : "Failure");
1590 case EAP_TLV_CRYPTO_BINDING_TLV_:
1591 wpa_hexdump(MSG_MSGDUMP, "EAP-FAST: Crypto-Binding "
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;
1602 (struct eap_tlv_crypto_binding__tlv *)
1603 (pos - sizeof(struct eap_tlv_hdr));
1605 case EAP_TLV_PAC_TLV:
1606 wpa_hexdump(MSG_MSGDUMP, "EAP-FAST: PAC TLV",
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,
1619 wpa_printf(MSG_DEBUG, "EAP-FAST: ignored "
1620 "unknown optional TLV type %d",
1629 if (!resp && result == EAP_TLV_RESULT_FAILURE) {
1630 resp = eap_fast_tlv_result(EAP_TLV_RESULT_FAILURE, 0,
1638 if (!resp && iresult == EAP_TLV_RESULT_FAILURE) {
1639 resp = eap_fast_tlv_result(EAP_TLV_RESULT_FAILURE, 1,
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);
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");
1660 if (hdr->code == EAP_CODE_REQUEST) {
1661 if (eap_fast_phase2_request(sm, data, ret, req, hdr,
1662 &resp, &resp_len)) {
1664 wpa_printf(MSG_INFO, "EAP-FAST: Phase2 "
1665 "Request processing failed");
1668 resp = eap_fast_tlv_eap_payload(resp, &resp_len);
1674 wpa_printf(MSG_INFO, "EAP-FAST: Unexpected code=%d in "
1675 "Phase 2 EAP header", hdr->code);
1681 if (!resp && crypto_binding) {
1682 int final = result == EAP_TLV_RESULT_SUCCESS;
1683 resp = eap_fast_process_crypto_binding(sm, data, ret,
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,
1704 if (!resp && pac && result == EAP_TLV_RESULT_SUCCESS) {
1705 resp = eap_fast_process_pac(sm, data, ret, pac, pac_len,
1716 wpa_printf(MSG_DEBUG, "EAP-FAST: No recognized TLVs - send "
1717 "empty response packet");
1724 wpa_hexdump(MSG_DEBUG, "EAP-FAST: Encrypting Phase 2 data",
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 "
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)
1742 const struct eap_hdr *req;
1745 u8 flags, *resp, id;
1747 struct eap_fast_data *data = priv;
1749 pos = eap_tls_process_init(sm, &data->ssl, EAP_TYPE_FAST, ret,
1750 reqData, reqDataLen, &left, &flags);
1753 req = (const struct eap_hdr *) reqData;
1754 id = req->identifier;
1756 if (flags & EAP_TLS_FLAGS_START) {
1759 struct pac_tlv_hdr *hdr;
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);
1771 if (left > sizeof(*hdr)) {
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);
1781 wpa_hexdump_ascii(MSG_DEBUG, "EAP-FAST: A-ID", a_id, a_id_len);
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 "
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);
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 "
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");
1804 } else if (data->current_pac) {
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);
1812 hdr = (struct eap_tlv_hdr *) tlv;
1814 host_to_be16(PAC_TYPE_PAC_OPAQUE);
1815 hdr->length = host_to_be16(olen);
1816 memcpy(hdr + 1, data->current_pac->pac_opaque,
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");
1830 if (!data->provisioning_allowed) {
1831 wpa_printf(MSG_DEBUG, "EAP-FAST: No PAC found "
1832 "and provisioning disabled");
1835 wpa_printf(MSG_DEBUG, "EAP-FAST: No PAC found - "
1836 "starting provisioning");
1837 if (tls_connection_set_anon_dh(sm->ssl_ctx,
1839 wpa_printf(MSG_INFO, "EAP-FAST: Could not "
1840 "configure anonymous DH for TLS "
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");
1851 data->provisioning = 1;
1854 left = 0; /* A-ID is not used in further packet processing */
1858 if (tls_connection_established(sm->ssl_ctx, data->ssl.conn) &&
1860 res = eap_fast_decrypt(sm, data, ret, req, pos, left,
1861 &resp, respDataLen);
1863 ret->methodState = METHOD_DONE;
1864 ret->decision = DECISION_FAIL;
1865 /* Ack possible Alert that may have caused failure in
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;
1878 res = eap_tls_process_helper(sm, &data->ssl, EAP_TYPE_FAST,
1879 data->fast_version, id, pos, left,
1880 &resp, respDataLen);
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");
1886 eap_fast_derive_keys(sm, data);
1891 return eap_tls_build_ack(&data->ssl, respDataLen, id,
1892 EAP_TYPE_FAST, data->fast_version);
1898 static Boolean eap_fast_has_reauth_data(struct eap_sm *sm, void *priv)
1900 struct eap_fast_data *data = priv;
1901 return tls_connection_established(sm->ssl_ctx, data->ssl.conn);
1905 static void eap_fast_deinit_for_reauth(struct eap_sm *sm, void *priv)
1910 static void * eap_fast_init_for_reauth(struct eap_sm *sm, void *priv)
1912 struct eap_fast_data *data = priv;
1913 if (eap_tls_reauth_init(sm, &data->ssl)) {
1917 data->phase2_success = 0;
1919 data->provisioning = 0;
1925 static int eap_fast_get_status(struct eap_sm *sm, void *priv, char *buf,
1926 size_t buflen, int verbose)
1928 struct eap_fast_data *data = priv;
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);
1941 static Boolean eap_fast_isKeyAvailable(struct eap_sm *sm, void *priv)
1943 struct eap_fast_data *data = priv;
1944 return data->success;
1948 static u8 * eap_fast_getKey(struct eap_sm *sm, void *priv, size_t *len)
1950 struct eap_fast_data *data = priv;
1956 key = malloc(EAP_FAST_KEY_LEN);
1960 *len = EAP_FAST_KEY_LEN;
1961 memcpy(key, data->key_data, EAP_FAST_KEY_LEN);
1967 const struct eap_method eap_method_fast =
1969 .method = EAP_TYPE_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,
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,