Home | History | Annotate | Download | only in wpa_supplicant
      1 /*
      2  * EAP peer method: EAP-FAST (draft-cam-winget-eap-fast-03.txt)
      3  * Copyright (c) 2004-2006, Jouni Malinen <j (at) 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 }
   2092