Home | History | Annotate | Download | only in eap_server
      1 /*
      2  * hostapd / EAP-PEAP (draft-josefsson-pppext-eap-tls-eap-10.txt)
      3  * Copyright (c) 2004-2008, Jouni Malinen <j (at) w1.fi>
      4  *
      5  * This software may be distributed under the terms of the BSD license.
      6  * See README for more details.
      7  */
      8 
      9 #include "includes.h"
     10 
     11 #include "common.h"
     12 #include "crypto/sha1.h"
     13 #include "crypto/tls.h"
     14 #include "crypto/random.h"
     15 #include "eap_i.h"
     16 #include "eap_tls_common.h"
     17 #include "eap_common/eap_tlv_common.h"
     18 #include "eap_common/eap_peap_common.h"
     19 #include "tncs.h"
     20 
     21 
     22 /* Maximum supported PEAP version
     23  * 0 = Microsoft's PEAP version 0; draft-kamath-pppext-peapv0-00.txt
     24  * 1 = draft-josefsson-ppext-eap-tls-eap-05.txt
     25  * 2 = draft-josefsson-ppext-eap-tls-eap-10.txt
     26  */
     27 #define EAP_PEAP_VERSION 1
     28 
     29 
     30 static void eap_peap_reset(struct eap_sm *sm, void *priv);
     31 
     32 
     33 struct eap_peap_data {
     34 	struct eap_ssl_data ssl;
     35 	enum {
     36 		START, PHASE1, PHASE1_ID2, PHASE2_START, PHASE2_ID,
     37 		PHASE2_METHOD, PHASE2_SOH,
     38 		PHASE2_TLV, SUCCESS_REQ, FAILURE_REQ, SUCCESS, FAILURE
     39 	} state;
     40 
     41 	int peap_version;
     42 	int recv_version;
     43 	const struct eap_method *phase2_method;
     44 	void *phase2_priv;
     45 	int force_version;
     46 	struct wpabuf *pending_phase2_resp;
     47 	enum { TLV_REQ_NONE, TLV_REQ_SUCCESS, TLV_REQ_FAILURE } tlv_request;
     48 	int crypto_binding_sent;
     49 	int crypto_binding_used;
     50 	enum { NO_BINDING, OPTIONAL_BINDING, REQUIRE_BINDING } crypto_binding;
     51 	u8 binding_nonce[32];
     52 	u8 ipmk[40];
     53 	u8 cmk[20];
     54 	u8 *phase2_key;
     55 	size_t phase2_key_len;
     56 	struct wpabuf *soh_response;
     57 };
     58 
     59 
     60 static const char * eap_peap_state_txt(int state)
     61 {
     62 	switch (state) {
     63 	case START:
     64 		return "START";
     65 	case PHASE1:
     66 		return "PHASE1";
     67 	case PHASE1_ID2:
     68 		return "PHASE1_ID2";
     69 	case PHASE2_START:
     70 		return "PHASE2_START";
     71 	case PHASE2_ID:
     72 		return "PHASE2_ID";
     73 	case PHASE2_METHOD:
     74 		return "PHASE2_METHOD";
     75 	case PHASE2_SOH:
     76 		return "PHASE2_SOH";
     77 	case PHASE2_TLV:
     78 		return "PHASE2_TLV";
     79 	case SUCCESS_REQ:
     80 		return "SUCCESS_REQ";
     81 	case FAILURE_REQ:
     82 		return "FAILURE_REQ";
     83 	case SUCCESS:
     84 		return "SUCCESS";
     85 	case FAILURE:
     86 		return "FAILURE";
     87 	default:
     88 		return "Unknown?!";
     89 	}
     90 }
     91 
     92 
     93 static void eap_peap_state(struct eap_peap_data *data, int state)
     94 {
     95 	wpa_printf(MSG_DEBUG, "EAP-PEAP: %s -> %s",
     96 		   eap_peap_state_txt(data->state),
     97 		   eap_peap_state_txt(state));
     98 	data->state = state;
     99 }
    100 
    101 
    102 static struct wpabuf * eap_peapv2_tlv_eap_payload(struct wpabuf *buf)
    103 {
    104 	struct wpabuf *e;
    105 	struct eap_tlv_hdr *tlv;
    106 
    107 	if (buf == NULL)
    108 		return NULL;
    109 
    110 	/* Encapsulate EAP packet in EAP-Payload TLV */
    111 	wpa_printf(MSG_DEBUG, "EAP-PEAPv2: Add EAP-Payload TLV");
    112 	e = wpabuf_alloc(sizeof(*tlv) + wpabuf_len(buf));
    113 	if (e == NULL) {
    114 		wpa_printf(MSG_DEBUG, "EAP-PEAPv2: Failed to allocate memory "
    115 			   "for TLV encapsulation");
    116 		wpabuf_free(buf);
    117 		return NULL;
    118 	}
    119 	tlv = wpabuf_put(e, sizeof(*tlv));
    120 	tlv->tlv_type = host_to_be16(EAP_TLV_TYPE_MANDATORY |
    121 				     EAP_TLV_EAP_PAYLOAD_TLV);
    122 	tlv->length = host_to_be16(wpabuf_len(buf));
    123 	wpabuf_put_buf(e, buf);
    124 	wpabuf_free(buf);
    125 	return e;
    126 }
    127 
    128 
    129 static void eap_peap_req_success(struct eap_sm *sm,
    130 				 struct eap_peap_data *data)
    131 {
    132 	if (data->state == FAILURE || data->state == FAILURE_REQ) {
    133 		eap_peap_state(data, FAILURE);
    134 		return;
    135 	}
    136 
    137 	if (data->peap_version == 0) {
    138 		data->tlv_request = TLV_REQ_SUCCESS;
    139 		eap_peap_state(data, PHASE2_TLV);
    140 	} else {
    141 		eap_peap_state(data, SUCCESS_REQ);
    142 	}
    143 }
    144 
    145 
    146 static void eap_peap_req_failure(struct eap_sm *sm,
    147 				 struct eap_peap_data *data)
    148 {
    149 	if (data->state == FAILURE || data->state == FAILURE_REQ ||
    150 	    data->state == SUCCESS_REQ || data->tlv_request != TLV_REQ_NONE) {
    151 		eap_peap_state(data, FAILURE);
    152 		return;
    153 	}
    154 
    155 	if (data->peap_version == 0) {
    156 		data->tlv_request = TLV_REQ_FAILURE;
    157 		eap_peap_state(data, PHASE2_TLV);
    158 	} else {
    159 		eap_peap_state(data, FAILURE_REQ);
    160 	}
    161 }
    162 
    163 
    164 static void * eap_peap_init(struct eap_sm *sm)
    165 {
    166 	struct eap_peap_data *data;
    167 
    168 	data = os_zalloc(sizeof(*data));
    169 	if (data == NULL)
    170 		return NULL;
    171 	data->peap_version = EAP_PEAP_VERSION;
    172 	data->force_version = -1;
    173 	if (sm->user && sm->user->force_version >= 0) {
    174 		data->force_version = sm->user->force_version;
    175 		wpa_printf(MSG_DEBUG, "EAP-PEAP: forcing version %d",
    176 			   data->force_version);
    177 		data->peap_version = data->force_version;
    178 	}
    179 	data->state = START;
    180 	data->crypto_binding = OPTIONAL_BINDING;
    181 
    182 	if (eap_server_tls_ssl_init(sm, &data->ssl, 0)) {
    183 		wpa_printf(MSG_INFO, "EAP-PEAP: Failed to initialize SSL.");
    184 		eap_peap_reset(sm, data);
    185 		return NULL;
    186 	}
    187 
    188 	return data;
    189 }
    190 
    191 
    192 static void eap_peap_reset(struct eap_sm *sm, void *priv)
    193 {
    194 	struct eap_peap_data *data = priv;
    195 	if (data == NULL)
    196 		return;
    197 	if (data->phase2_priv && data->phase2_method)
    198 		data->phase2_method->reset(sm, data->phase2_priv);
    199 	eap_server_tls_ssl_deinit(sm, &data->ssl);
    200 	wpabuf_free(data->pending_phase2_resp);
    201 	os_free(data->phase2_key);
    202 	wpabuf_free(data->soh_response);
    203 	os_free(data);
    204 }
    205 
    206 
    207 static struct wpabuf * eap_peap_build_start(struct eap_sm *sm,
    208 					    struct eap_peap_data *data, u8 id)
    209 {
    210 	struct wpabuf *req;
    211 
    212 	req = eap_msg_alloc(EAP_VENDOR_IETF, EAP_TYPE_PEAP, 1,
    213 			    EAP_CODE_REQUEST, id);
    214 	if (req == NULL) {
    215 		wpa_printf(MSG_ERROR, "EAP-PEAP: Failed to allocate memory for"
    216 			   " request");
    217 		eap_peap_state(data, FAILURE);
    218 		return NULL;
    219 	}
    220 
    221 	wpabuf_put_u8(req, EAP_TLS_FLAGS_START | data->peap_version);
    222 
    223 	eap_peap_state(data, PHASE1);
    224 
    225 	return req;
    226 }
    227 
    228 
    229 static struct wpabuf * eap_peap_build_phase2_req(struct eap_sm *sm,
    230 						 struct eap_peap_data *data,
    231 						 u8 id)
    232 {
    233 	struct wpabuf *buf, *encr_req, msgbuf;
    234 	const u8 *req;
    235 	size_t req_len;
    236 
    237 	if (data->phase2_method == NULL || data->phase2_priv == NULL) {
    238 		wpa_printf(MSG_DEBUG, "EAP-PEAP: Phase 2 method not ready");
    239 		return NULL;
    240 	}
    241 	buf = data->phase2_method->buildReq(sm, data->phase2_priv, id);
    242 	if (data->peap_version >= 2 && buf)
    243 		buf = eap_peapv2_tlv_eap_payload(buf);
    244 	if (buf == NULL)
    245 		return NULL;
    246 
    247 	req = wpabuf_head(buf);
    248 	req_len = wpabuf_len(buf);
    249 	wpa_hexdump_key(MSG_DEBUG, "EAP-PEAP: Encrypting Phase 2 data",
    250 			req, req_len);
    251 
    252 	if (data->peap_version == 0 &&
    253 	    data->phase2_method->method != EAP_TYPE_TLV) {
    254 		req += sizeof(struct eap_hdr);
    255 		req_len -= sizeof(struct eap_hdr);
    256 	}
    257 
    258 	wpabuf_set(&msgbuf, req, req_len);
    259 	encr_req = eap_server_tls_encrypt(sm, &data->ssl, &msgbuf);
    260 	wpabuf_free(buf);
    261 
    262 	return encr_req;
    263 }
    264 
    265 
    266 #ifdef EAP_SERVER_TNC
    267 static struct wpabuf * eap_peap_build_phase2_soh(struct eap_sm *sm,
    268 						 struct eap_peap_data *data,
    269 						 u8 id)
    270 {
    271 	struct wpabuf *buf1, *buf, *encr_req, msgbuf;
    272 	const u8 *req;
    273 	size_t req_len;
    274 
    275 	buf1 = tncs_build_soh_request();
    276 	if (buf1 == NULL)
    277 		return NULL;
    278 
    279 	buf = eap_msg_alloc(EAP_VENDOR_MICROSOFT, 0x21, wpabuf_len(buf1),
    280 			    EAP_CODE_REQUEST, id);
    281 	if (buf == NULL) {
    282 		wpabuf_free(buf1);
    283 		return NULL;
    284 	}
    285 	wpabuf_put_buf(buf, buf1);
    286 	wpabuf_free(buf1);
    287 
    288 	req = wpabuf_head(buf);
    289 	req_len = wpabuf_len(buf);
    290 
    291 	wpa_hexdump_key(MSG_DEBUG, "EAP-PEAP: Encrypting Phase 2 SOH data",
    292 			req, req_len);
    293 
    294 	req += sizeof(struct eap_hdr);
    295 	req_len -= sizeof(struct eap_hdr);
    296 	wpabuf_set(&msgbuf, req, req_len);
    297 
    298 	encr_req = eap_server_tls_encrypt(sm, &data->ssl, &msgbuf);
    299 	wpabuf_free(buf);
    300 
    301 	return encr_req;
    302 }
    303 #endif /* EAP_SERVER_TNC */
    304 
    305 
    306 static void eap_peap_get_isk(struct eap_peap_data *data,
    307 			     u8 *isk, size_t isk_len)
    308 {
    309 	size_t key_len;
    310 
    311 	os_memset(isk, 0, isk_len);
    312 	if (data->phase2_key == NULL)
    313 		return;
    314 
    315 	key_len = data->phase2_key_len;
    316 	if (key_len > isk_len)
    317 		key_len = isk_len;
    318 	os_memcpy(isk, data->phase2_key, key_len);
    319 }
    320 
    321 
    322 static int eap_peap_derive_cmk(struct eap_sm *sm, struct eap_peap_data *data)
    323 {
    324 	u8 *tk;
    325 	u8 isk[32], imck[60];
    326 
    327 	/*
    328 	 * Tunnel key (TK) is the first 60 octets of the key generated by
    329 	 * phase 1 of PEAP (based on TLS).
    330 	 */
    331 	tk = eap_server_tls_derive_key(sm, &data->ssl, "client EAP encryption",
    332 				       EAP_TLS_KEY_LEN);
    333 	if (tk == NULL)
    334 		return -1;
    335 	wpa_hexdump_key(MSG_DEBUG, "EAP-PEAP: TK", tk, 60);
    336 
    337 	eap_peap_get_isk(data, isk, sizeof(isk));
    338 	wpa_hexdump_key(MSG_DEBUG, "EAP-PEAP: ISK", isk, sizeof(isk));
    339 
    340 	/*
    341 	 * IPMK Seed = "Inner Methods Compound Keys" | ISK
    342 	 * TempKey = First 40 octets of TK
    343 	 * IPMK|CMK = PRF+(TempKey, IPMK Seed, 60)
    344 	 * (note: draft-josefsson-pppext-eap-tls-eap-10.txt includes a space
    345 	 * in the end of the label just before ISK; is that just a typo?)
    346 	 */
    347 	wpa_hexdump_key(MSG_DEBUG, "EAP-PEAP: TempKey", tk, 40);
    348 	if (peap_prfplus(data->peap_version, tk, 40,
    349 			 "Inner Methods Compound Keys",
    350 			 isk, sizeof(isk), imck, sizeof(imck)) < 0) {
    351 		os_free(tk);
    352 		return -1;
    353 	}
    354 	wpa_hexdump_key(MSG_DEBUG, "EAP-PEAP: IMCK (IPMKj)",
    355 			imck, sizeof(imck));
    356 
    357 	os_free(tk);
    358 
    359 	/* TODO: fast-connect: IPMK|CMK = TK */
    360 	os_memcpy(data->ipmk, imck, 40);
    361 	wpa_hexdump_key(MSG_DEBUG, "EAP-PEAP: IPMK (S-IPMKj)", data->ipmk, 40);
    362 	os_memcpy(data->cmk, imck + 40, 20);
    363 	wpa_hexdump_key(MSG_DEBUG, "EAP-PEAP: CMK (CMKj)", data->cmk, 20);
    364 
    365 	return 0;
    366 }
    367 
    368 
    369 static struct wpabuf * eap_peap_build_phase2_tlv(struct eap_sm *sm,
    370 						 struct eap_peap_data *data,
    371 						 u8 id)
    372 {
    373 	struct wpabuf *buf, *encr_req;
    374 	size_t mlen;
    375 
    376 	mlen = 6; /* Result TLV */
    377 	if (data->crypto_binding != NO_BINDING)
    378 		mlen += 60; /* Cryptobinding TLV */
    379 #ifdef EAP_SERVER_TNC
    380 	if (data->soh_response)
    381 		mlen += wpabuf_len(data->soh_response);
    382 #endif /* EAP_SERVER_TNC */
    383 
    384 	buf = eap_msg_alloc(EAP_VENDOR_IETF, EAP_TYPE_TLV, mlen,
    385 			    EAP_CODE_REQUEST, id);
    386 	if (buf == NULL)
    387 		return NULL;
    388 
    389 	wpabuf_put_u8(buf, 0x80); /* Mandatory */
    390 	wpabuf_put_u8(buf, EAP_TLV_RESULT_TLV);
    391 	/* Length */
    392 	wpabuf_put_be16(buf, 2);
    393 	/* Status */
    394 	wpabuf_put_be16(buf, data->tlv_request == TLV_REQ_SUCCESS ?
    395 			EAP_TLV_RESULT_SUCCESS : EAP_TLV_RESULT_FAILURE);
    396 
    397 	if (data->peap_version == 0 && data->tlv_request == TLV_REQ_SUCCESS &&
    398 	    data->crypto_binding != NO_BINDING) {
    399 		u8 *mac;
    400 		u8 eap_type = EAP_TYPE_PEAP;
    401 		const u8 *addr[2];
    402 		size_t len[2];
    403 		u16 tlv_type;
    404 
    405 #ifdef EAP_SERVER_TNC
    406 		if (data->soh_response) {
    407 			wpa_printf(MSG_DEBUG, "EAP-PEAP: Adding MS-SOH "
    408 				   "Response TLV");
    409 			wpabuf_put_buf(buf, data->soh_response);
    410 			wpabuf_free(data->soh_response);
    411 			data->soh_response = NULL;
    412 		}
    413 #endif /* EAP_SERVER_TNC */
    414 
    415 		if (eap_peap_derive_cmk(sm, data) < 0 ||
    416 		    random_get_bytes(data->binding_nonce, 32)) {
    417 			wpabuf_free(buf);
    418 			return NULL;
    419 		}
    420 
    421 		/* Compound_MAC: HMAC-SHA1-160(cryptobinding TLV | EAP type) */
    422 		addr[0] = wpabuf_put(buf, 0);
    423 		len[0] = 60;
    424 		addr[1] = &eap_type;
    425 		len[1] = 1;
    426 
    427 		tlv_type = EAP_TLV_CRYPTO_BINDING_TLV;
    428 		if (data->peap_version >= 2)
    429 			tlv_type |= EAP_TLV_TYPE_MANDATORY;
    430 		wpabuf_put_be16(buf, tlv_type);
    431 		wpabuf_put_be16(buf, 56);
    432 
    433 		wpabuf_put_u8(buf, 0); /* Reserved */
    434 		wpabuf_put_u8(buf, data->peap_version); /* Version */
    435 		wpabuf_put_u8(buf, data->recv_version); /* RecvVersion */
    436 		wpabuf_put_u8(buf, 0); /* SubType: 0 = Request, 1 = Response */
    437 		wpabuf_put_data(buf, data->binding_nonce, 32); /* Nonce */
    438 		mac = wpabuf_put(buf, 20); /* Compound_MAC */
    439 		wpa_hexdump(MSG_MSGDUMP, "EAP-PEAP: Compound_MAC CMK",
    440 			    data->cmk, 20);
    441 		wpa_hexdump(MSG_MSGDUMP, "EAP-PEAP: Compound_MAC data 1",
    442 			    addr[0], len[0]);
    443 		wpa_hexdump(MSG_MSGDUMP, "EAP-PEAP: Compound_MAC data 2",
    444 			    addr[1], len[1]);
    445 		hmac_sha1_vector(data->cmk, 20, 2, addr, len, mac);
    446 		wpa_hexdump(MSG_MSGDUMP, "EAP-PEAP: Compound_MAC",
    447 			    mac, SHA1_MAC_LEN);
    448 		data->crypto_binding_sent = 1;
    449 	}
    450 
    451 	wpa_hexdump_buf_key(MSG_DEBUG, "EAP-PEAP: Encrypting Phase 2 TLV data",
    452 			    buf);
    453 
    454 	encr_req = eap_server_tls_encrypt(sm, &data->ssl, buf);
    455 	wpabuf_free(buf);
    456 
    457 	return encr_req;
    458 }
    459 
    460 
    461 static struct wpabuf * eap_peap_build_phase2_term(struct eap_sm *sm,
    462 						  struct eap_peap_data *data,
    463 						  u8 id, int success)
    464 {
    465 	struct wpabuf *encr_req, msgbuf;
    466 	size_t req_len;
    467 	struct eap_hdr *hdr;
    468 
    469 	req_len = sizeof(*hdr);
    470 	hdr = os_zalloc(req_len);
    471 	if (hdr == NULL)
    472 		return NULL;
    473 
    474 	hdr->code = success ? EAP_CODE_SUCCESS : EAP_CODE_FAILURE;
    475 	hdr->identifier = id;
    476 	hdr->length = host_to_be16(req_len);
    477 
    478 	wpa_hexdump_key(MSG_DEBUG, "EAP-PEAP: Encrypting Phase 2 data",
    479 			(u8 *) hdr, req_len);
    480 
    481 	wpabuf_set(&msgbuf, hdr, req_len);
    482 	encr_req = eap_server_tls_encrypt(sm, &data->ssl, &msgbuf);
    483 	os_free(hdr);
    484 
    485 	return encr_req;
    486 }
    487 
    488 
    489 static struct wpabuf * eap_peap_buildReq(struct eap_sm *sm, void *priv, u8 id)
    490 {
    491 	struct eap_peap_data *data = priv;
    492 
    493 	if (data->ssl.state == FRAG_ACK) {
    494 		return eap_server_tls_build_ack(id, EAP_TYPE_PEAP,
    495 						data->peap_version);
    496 	}
    497 
    498 	if (data->ssl.state == WAIT_FRAG_ACK) {
    499 		return eap_server_tls_build_msg(&data->ssl, EAP_TYPE_PEAP,
    500 						data->peap_version, id);
    501 	}
    502 
    503 	switch (data->state) {
    504 	case START:
    505 		return eap_peap_build_start(sm, data, id);
    506 	case PHASE1:
    507 	case PHASE1_ID2:
    508 		if (data->peap_version < 2 &&
    509 		    tls_connection_established(sm->ssl_ctx, data->ssl.conn)) {
    510 			wpa_printf(MSG_DEBUG, "EAP-PEAP: Phase1 done, "
    511 				   "starting Phase2");
    512 			eap_peap_state(data, PHASE2_START);
    513 		}
    514 		break;
    515 	case PHASE2_ID:
    516 	case PHASE2_METHOD:
    517 		wpabuf_free(data->ssl.tls_out);
    518 		data->ssl.tls_out_pos = 0;
    519 		data->ssl.tls_out = eap_peap_build_phase2_req(sm, data, id);
    520 		break;
    521 #ifdef EAP_SERVER_TNC
    522 	case PHASE2_SOH:
    523 		wpabuf_free(data->ssl.tls_out);
    524 		data->ssl.tls_out_pos = 0;
    525 		data->ssl.tls_out = eap_peap_build_phase2_soh(sm, data, id);
    526 		break;
    527 #endif /* EAP_SERVER_TNC */
    528 	case PHASE2_TLV:
    529 		wpabuf_free(data->ssl.tls_out);
    530 		data->ssl.tls_out_pos = 0;
    531 		data->ssl.tls_out = eap_peap_build_phase2_tlv(sm, data, id);
    532 		break;
    533 	case SUCCESS_REQ:
    534 		wpabuf_free(data->ssl.tls_out);
    535 		data->ssl.tls_out_pos = 0;
    536 		data->ssl.tls_out = eap_peap_build_phase2_term(sm, data, id,
    537 							       1);
    538 		break;
    539 	case FAILURE_REQ:
    540 		wpabuf_free(data->ssl.tls_out);
    541 		data->ssl.tls_out_pos = 0;
    542 		data->ssl.tls_out = eap_peap_build_phase2_term(sm, data, id,
    543 							       0);
    544 		break;
    545 	default:
    546 		wpa_printf(MSG_DEBUG, "EAP-PEAP: %s - unexpected state %d",
    547 			   __func__, data->state);
    548 		return NULL;
    549 	}
    550 
    551 	return eap_server_tls_build_msg(&data->ssl, EAP_TYPE_PEAP,
    552 					data->peap_version, id);
    553 }
    554 
    555 
    556 static Boolean eap_peap_check(struct eap_sm *sm, void *priv,
    557 			      struct wpabuf *respData)
    558 {
    559 	const u8 *pos;
    560 	size_t len;
    561 
    562 	pos = eap_hdr_validate(EAP_VENDOR_IETF, EAP_TYPE_PEAP, respData, &len);
    563 	if (pos == NULL || len < 1) {
    564 		wpa_printf(MSG_INFO, "EAP-PEAP: Invalid frame");
    565 		return TRUE;
    566 	}
    567 
    568 	return FALSE;
    569 }
    570 
    571 
    572 static int eap_peap_phase2_init(struct eap_sm *sm, struct eap_peap_data *data,
    573 				EapType eap_type)
    574 {
    575 	if (data->phase2_priv && data->phase2_method) {
    576 		data->phase2_method->reset(sm, data->phase2_priv);
    577 		data->phase2_method = NULL;
    578 		data->phase2_priv = NULL;
    579 	}
    580 	data->phase2_method = eap_server_get_eap_method(EAP_VENDOR_IETF,
    581 							eap_type);
    582 	if (!data->phase2_method)
    583 		return -1;
    584 
    585 	sm->init_phase2 = 1;
    586 	data->phase2_priv = data->phase2_method->init(sm);
    587 	sm->init_phase2 = 0;
    588 	return 0;
    589 }
    590 
    591 
    592 static int eap_tlv_validate_cryptobinding(struct eap_sm *sm,
    593 					  struct eap_peap_data *data,
    594 					  const u8 *crypto_tlv,
    595 					  size_t crypto_tlv_len)
    596 {
    597 	u8 buf[61], mac[SHA1_MAC_LEN];
    598 	const u8 *pos;
    599 
    600 	if (crypto_tlv_len != 4 + 56) {
    601 		wpa_printf(MSG_DEBUG, "EAP-PEAP: Invalid cryptobinding TLV "
    602 			   "length %d", (int) crypto_tlv_len);
    603 		return -1;
    604 	}
    605 
    606 	pos = crypto_tlv;
    607 	pos += 4; /* TLV header */
    608 	if (pos[1] != data->peap_version) {
    609 		wpa_printf(MSG_DEBUG, "EAP-PEAP: Cryptobinding TLV Version "
    610 			   "mismatch (was %d; expected %d)",
    611 			   pos[1], data->peap_version);
    612 		return -1;
    613 	}
    614 
    615 	if (pos[3] != 1) {
    616 		wpa_printf(MSG_DEBUG, "EAP-PEAP: Unexpected Cryptobinding TLV "
    617 			   "SubType %d", pos[3]);
    618 		return -1;
    619 	}
    620 	pos += 4;
    621 	pos += 32; /* Nonce */
    622 
    623 	/* Compound_MAC: HMAC-SHA1-160(cryptobinding TLV | EAP type) */
    624 	os_memcpy(buf, crypto_tlv, 60);
    625 	os_memset(buf + 4 + 4 + 32, 0, 20); /* Compound_MAC */
    626 	buf[60] = EAP_TYPE_PEAP;
    627 	hmac_sha1(data->cmk, 20, buf, sizeof(buf), mac);
    628 
    629 	if (os_memcmp(mac, pos, SHA1_MAC_LEN) != 0) {
    630 		wpa_printf(MSG_DEBUG, "EAP-PEAP: Invalid Compound_MAC in "
    631 			   "cryptobinding TLV");
    632 		wpa_hexdump_key(MSG_DEBUG, "EAP-PEAP: CMK", data->cmk, 20);
    633 		wpa_hexdump(MSG_DEBUG, "EAP-PEAP: Cryptobinding seed data",
    634 			    buf, 61);
    635 		return -1;
    636 	}
    637 
    638 	wpa_printf(MSG_DEBUG, "EAP-PEAP: Valid cryptobinding TLV received");
    639 
    640 	return 0;
    641 }
    642 
    643 
    644 static void eap_peap_process_phase2_tlv(struct eap_sm *sm,
    645 					struct eap_peap_data *data,
    646 					struct wpabuf *in_data)
    647 {
    648 	const u8 *pos;
    649 	size_t left;
    650 	const u8 *result_tlv = NULL, *crypto_tlv = NULL;
    651 	size_t result_tlv_len = 0, crypto_tlv_len = 0;
    652 	int tlv_type, mandatory, tlv_len;
    653 
    654 	pos = eap_hdr_validate(EAP_VENDOR_IETF, EAP_TYPE_TLV, in_data, &left);
    655 	if (pos == NULL) {
    656 		wpa_printf(MSG_DEBUG, "EAP-PEAP: Invalid EAP-TLV header");
    657 		return;
    658 	}
    659 
    660 	/* Parse TLVs */
    661 	wpa_hexdump(MSG_DEBUG, "EAP-PEAP: Received TLVs", pos, left);
    662 	while (left >= 4) {
    663 		mandatory = !!(pos[0] & 0x80);
    664 		tlv_type = pos[0] & 0x3f;
    665 		tlv_type = (tlv_type << 8) | pos[1];
    666 		tlv_len = ((int) pos[2] << 8) | pos[3];
    667 		pos += 4;
    668 		left -= 4;
    669 		if ((size_t) tlv_len > left) {
    670 			wpa_printf(MSG_DEBUG, "EAP-PEAP: TLV underrun "
    671 				   "(tlv_len=%d left=%lu)", tlv_len,
    672 				   (unsigned long) left);
    673 			eap_peap_state(data, FAILURE);
    674 			return;
    675 		}
    676 		switch (tlv_type) {
    677 		case EAP_TLV_RESULT_TLV:
    678 			result_tlv = pos;
    679 			result_tlv_len = tlv_len;
    680 			break;
    681 		case EAP_TLV_CRYPTO_BINDING_TLV:
    682 			crypto_tlv = pos;
    683 			crypto_tlv_len = tlv_len;
    684 			break;
    685 		default:
    686 			wpa_printf(MSG_DEBUG, "EAP-PEAP: Unsupported TLV Type "
    687 				   "%d%s", tlv_type,
    688 				   mandatory ? " (mandatory)" : "");
    689 			if (mandatory) {
    690 				eap_peap_state(data, FAILURE);
    691 				return;
    692 			}
    693 			/* Ignore this TLV, but process other TLVs */
    694 			break;
    695 		}
    696 
    697 		pos += tlv_len;
    698 		left -= tlv_len;
    699 	}
    700 	if (left) {
    701 		wpa_printf(MSG_DEBUG, "EAP-PEAP: Last TLV too short in "
    702 			   "Request (left=%lu)", (unsigned long) left);
    703 		eap_peap_state(data, FAILURE);
    704 		return;
    705 	}
    706 
    707 	/* Process supported TLVs */
    708 	if (crypto_tlv && data->crypto_binding_sent) {
    709 		wpa_hexdump(MSG_DEBUG, "EAP-PEAP: Cryptobinding TLV",
    710 			    crypto_tlv, crypto_tlv_len);
    711 		if (eap_tlv_validate_cryptobinding(sm, data, crypto_tlv - 4,
    712 						   crypto_tlv_len + 4) < 0) {
    713 			eap_peap_state(data, FAILURE);
    714 			return;
    715 		}
    716 		data->crypto_binding_used = 1;
    717 	} else if (!crypto_tlv && data->crypto_binding_sent &&
    718 		   data->crypto_binding == REQUIRE_BINDING) {
    719 		wpa_printf(MSG_DEBUG, "EAP-PEAP: No cryptobinding TLV");
    720 		eap_peap_state(data, FAILURE);
    721 		return;
    722 	}
    723 
    724 	if (result_tlv) {
    725 		int status;
    726 		const char *requested;
    727 
    728 		wpa_hexdump(MSG_DEBUG, "EAP-PEAP: Result TLV",
    729 			    result_tlv, result_tlv_len);
    730 		if (result_tlv_len < 2) {
    731 			wpa_printf(MSG_INFO, "EAP-PEAP: Too short Result TLV "
    732 				   "(len=%lu)",
    733 				   (unsigned long) result_tlv_len);
    734 			eap_peap_state(data, FAILURE);
    735 			return;
    736 		}
    737 		requested = data->tlv_request == TLV_REQ_SUCCESS ? "Success" :
    738 			"Failure";
    739 		status = WPA_GET_BE16(result_tlv);
    740 		if (status == EAP_TLV_RESULT_SUCCESS) {
    741 			wpa_printf(MSG_INFO, "EAP-PEAP: TLV Result - Success "
    742 				   "- requested %s", requested);
    743 			if (data->tlv_request == TLV_REQ_SUCCESS)
    744 				eap_peap_state(data, SUCCESS);
    745 			else
    746 				eap_peap_state(data, FAILURE);
    747 
    748 		} else if (status == EAP_TLV_RESULT_FAILURE) {
    749 			wpa_printf(MSG_INFO, "EAP-PEAP: TLV Result - Failure "
    750 				   "- requested %s", requested);
    751 			eap_peap_state(data, FAILURE);
    752 		} else {
    753 			wpa_printf(MSG_INFO, "EAP-PEAP: Unknown TLV Result "
    754 				   "Status %d", status);
    755 			eap_peap_state(data, FAILURE);
    756 		}
    757 	}
    758 }
    759 
    760 
    761 #ifdef EAP_SERVER_TNC
    762 static void eap_peap_process_phase2_soh(struct eap_sm *sm,
    763 					struct eap_peap_data *data,
    764 					struct wpabuf *in_data)
    765 {
    766 	const u8 *pos, *vpos;
    767 	size_t left;
    768 	const u8 *soh_tlv = NULL;
    769 	size_t soh_tlv_len = 0;
    770 	int tlv_type, mandatory, tlv_len, vtlv_len;
    771 	u8 next_type;
    772 	u32 vendor_id;
    773 
    774 	pos = eap_hdr_validate(EAP_VENDOR_MICROSOFT, 0x21, in_data, &left);
    775 	if (pos == NULL) {
    776 		wpa_printf(MSG_DEBUG, "EAP-PEAP: Not a valid SoH EAP "
    777 			   "Extensions Method header - skip TNC");
    778 		goto auth_method;
    779 	}
    780 
    781 	/* Parse TLVs */
    782 	wpa_hexdump(MSG_DEBUG, "EAP-PEAP: Received TLVs (SoH)", pos, left);
    783 	while (left >= 4) {
    784 		mandatory = !!(pos[0] & 0x80);
    785 		tlv_type = pos[0] & 0x3f;
    786 		tlv_type = (tlv_type << 8) | pos[1];
    787 		tlv_len = ((int) pos[2] << 8) | pos[3];
    788 		pos += 4;
    789 		left -= 4;
    790 		if ((size_t) tlv_len > left) {
    791 			wpa_printf(MSG_DEBUG, "EAP-PEAP: TLV underrun "
    792 				   "(tlv_len=%d left=%lu)", tlv_len,
    793 				   (unsigned long) left);
    794 			eap_peap_state(data, FAILURE);
    795 			return;
    796 		}
    797 		switch (tlv_type) {
    798 		case EAP_TLV_VENDOR_SPECIFIC_TLV:
    799 			if (tlv_len < 4) {
    800 				wpa_printf(MSG_DEBUG, "EAP-PEAP: Too short "
    801 					   "vendor specific TLV (len=%d)",
    802 					   (int) tlv_len);
    803 				eap_peap_state(data, FAILURE);
    804 				return;
    805 			}
    806 
    807 			vendor_id = WPA_GET_BE32(pos);
    808 			if (vendor_id != EAP_VENDOR_MICROSOFT) {
    809 				if (mandatory) {
    810 					eap_peap_state(data, FAILURE);
    811 					return;
    812 				}
    813 				break;
    814 			}
    815 
    816 			vpos = pos + 4;
    817 			mandatory = !!(vpos[0] & 0x80);
    818 			tlv_type = vpos[0] & 0x3f;
    819 			tlv_type = (tlv_type << 8) | vpos[1];
    820 			vtlv_len = ((int) vpos[2] << 8) | vpos[3];
    821 			vpos += 4;
    822 			if (vpos + vtlv_len > pos + left) {
    823 				wpa_printf(MSG_DEBUG, "EAP-PEAP: Vendor TLV "
    824 					   "underrun");
    825 				eap_peap_state(data, FAILURE);
    826 				return;
    827 			}
    828 
    829 			if (tlv_type == 1) {
    830 				soh_tlv = vpos;
    831 				soh_tlv_len = vtlv_len;
    832 				break;
    833 			}
    834 
    835 			wpa_printf(MSG_DEBUG, "EAP-PEAP: Unsupported MS-TLV "
    836 				   "Type %d%s", tlv_type,
    837 				   mandatory ? " (mandatory)" : "");
    838 			if (mandatory) {
    839 				eap_peap_state(data, FAILURE);
    840 				return;
    841 			}
    842 			/* Ignore this TLV, but process other TLVs */
    843 			break;
    844 		default:
    845 			wpa_printf(MSG_DEBUG, "EAP-PEAP: Unsupported TLV Type "
    846 				   "%d%s", tlv_type,
    847 				   mandatory ? " (mandatory)" : "");
    848 			if (mandatory) {
    849 				eap_peap_state(data, FAILURE);
    850 				return;
    851 			}
    852 			/* Ignore this TLV, but process other TLVs */
    853 			break;
    854 		}
    855 
    856 		pos += tlv_len;
    857 		left -= tlv_len;
    858 	}
    859 	if (left) {
    860 		wpa_printf(MSG_DEBUG, "EAP-PEAP: Last TLV too short in "
    861 			   "Request (left=%lu)", (unsigned long) left);
    862 		eap_peap_state(data, FAILURE);
    863 		return;
    864 	}
    865 
    866 	/* Process supported TLVs */
    867 	if (soh_tlv) {
    868 		int failure = 0;
    869 		wpabuf_free(data->soh_response);
    870 		data->soh_response = tncs_process_soh(soh_tlv, soh_tlv_len,
    871 						      &failure);
    872 		if (failure) {
    873 			eap_peap_state(data, FAILURE);
    874 			return;
    875 		}
    876 	} else {
    877 		wpa_printf(MSG_DEBUG, "EAP-PEAP: No SoH TLV received");
    878 		eap_peap_state(data, FAILURE);
    879 		return;
    880 	}
    881 
    882 auth_method:
    883 	eap_peap_state(data, PHASE2_METHOD);
    884 	next_type = sm->user->methods[0].method;
    885 	sm->user_eap_method_index = 1;
    886 	wpa_printf(MSG_DEBUG, "EAP-PEAP: try EAP type %d", next_type);
    887 	eap_peap_phase2_init(sm, data, next_type);
    888 }
    889 #endif /* EAP_SERVER_TNC */
    890 
    891 
    892 static void eap_peap_process_phase2_response(struct eap_sm *sm,
    893 					     struct eap_peap_data *data,
    894 					     struct wpabuf *in_data)
    895 {
    896 	u8 next_type = EAP_TYPE_NONE;
    897 	const struct eap_hdr *hdr;
    898 	const u8 *pos;
    899 	size_t left;
    900 
    901 	if (data->state == PHASE2_TLV) {
    902 		eap_peap_process_phase2_tlv(sm, data, in_data);
    903 		return;
    904 	}
    905 
    906 #ifdef EAP_SERVER_TNC
    907 	if (data->state == PHASE2_SOH) {
    908 		eap_peap_process_phase2_soh(sm, data, in_data);
    909 		return;
    910 	}
    911 #endif /* EAP_SERVER_TNC */
    912 
    913 	if (data->phase2_priv == NULL) {
    914 		wpa_printf(MSG_DEBUG, "EAP-PEAP: %s - Phase2 not "
    915 			   "initialized?!", __func__);
    916 		return;
    917 	}
    918 
    919 	hdr = wpabuf_head(in_data);
    920 	pos = (const u8 *) (hdr + 1);
    921 
    922 	if (wpabuf_len(in_data) > sizeof(*hdr) && *pos == EAP_TYPE_NAK) {
    923 		left = wpabuf_len(in_data) - sizeof(*hdr);
    924 		wpa_hexdump(MSG_DEBUG, "EAP-PEAP: Phase2 type Nak'ed; "
    925 			    "allowed types", pos + 1, left - 1);
    926 		eap_sm_process_nak(sm, pos + 1, left - 1);
    927 		if (sm->user && sm->user_eap_method_index < EAP_MAX_METHODS &&
    928 		    sm->user->methods[sm->user_eap_method_index].method !=
    929 		    EAP_TYPE_NONE) {
    930 			next_type = sm->user->methods[
    931 				sm->user_eap_method_index++].method;
    932 			wpa_printf(MSG_DEBUG, "EAP-PEAP: try EAP type %d",
    933 				   next_type);
    934 		} else {
    935 			eap_peap_req_failure(sm, data);
    936 			next_type = EAP_TYPE_NONE;
    937 		}
    938 		eap_peap_phase2_init(sm, data, next_type);
    939 		return;
    940 	}
    941 
    942 	if (data->phase2_method->check(sm, data->phase2_priv, in_data)) {
    943 		wpa_printf(MSG_DEBUG, "EAP-PEAP: Phase2 check() asked to "
    944 			   "ignore the packet");
    945 		return;
    946 	}
    947 
    948 	data->phase2_method->process(sm, data->phase2_priv, in_data);
    949 
    950 	if (sm->method_pending == METHOD_PENDING_WAIT) {
    951 		wpa_printf(MSG_DEBUG, "EAP-PEAP: Phase2 method is in "
    952 			   "pending wait state - save decrypted response");
    953 		wpabuf_free(data->pending_phase2_resp);
    954 		data->pending_phase2_resp = wpabuf_dup(in_data);
    955 	}
    956 
    957 	if (!data->phase2_method->isDone(sm, data->phase2_priv))
    958 		return;
    959 
    960 	if (!data->phase2_method->isSuccess(sm, data->phase2_priv)) {
    961 		wpa_printf(MSG_DEBUG, "EAP-PEAP: Phase2 method failed");
    962 		eap_peap_req_failure(sm, data);
    963 		next_type = EAP_TYPE_NONE;
    964 		eap_peap_phase2_init(sm, data, next_type);
    965 		return;
    966 	}
    967 
    968 	os_free(data->phase2_key);
    969 	if (data->phase2_method->getKey) {
    970 		data->phase2_key = data->phase2_method->getKey(
    971 			sm, data->phase2_priv, &data->phase2_key_len);
    972 		if (data->phase2_key == NULL) {
    973 			wpa_printf(MSG_DEBUG, "EAP-PEAP: Phase2 getKey "
    974 				   "failed");
    975 			eap_peap_req_failure(sm, data);
    976 			eap_peap_phase2_init(sm, data, EAP_TYPE_NONE);
    977 			return;
    978 		}
    979 	}
    980 
    981 	switch (data->state) {
    982 	case PHASE1_ID2:
    983 	case PHASE2_ID:
    984 	case PHASE2_SOH:
    985 		if (eap_user_get(sm, sm->identity, sm->identity_len, 1) != 0) {
    986 			wpa_hexdump_ascii(MSG_DEBUG, "EAP_PEAP: Phase2 "
    987 					  "Identity not found in the user "
    988 					  "database",
    989 					  sm->identity, sm->identity_len);
    990 			eap_peap_req_failure(sm, data);
    991 			next_type = EAP_TYPE_NONE;
    992 			break;
    993 		}
    994 
    995 #ifdef EAP_SERVER_TNC
    996 		if (data->state != PHASE2_SOH && sm->tnc &&
    997 		    data->peap_version == 0) {
    998 			eap_peap_state(data, PHASE2_SOH);
    999 			wpa_printf(MSG_DEBUG, "EAP-PEAP: Try to initialize "
   1000 				   "TNC (NAP SOH)");
   1001 			next_type = EAP_TYPE_NONE;
   1002 			break;
   1003 		}
   1004 #endif /* EAP_SERVER_TNC */
   1005 
   1006 		eap_peap_state(data, PHASE2_METHOD);
   1007 		next_type = sm->user->methods[0].method;
   1008 		sm->user_eap_method_index = 1;
   1009 		wpa_printf(MSG_DEBUG, "EAP-PEAP: try EAP type %d", next_type);
   1010 		break;
   1011 	case PHASE2_METHOD:
   1012 		eap_peap_req_success(sm, data);
   1013 		next_type = EAP_TYPE_NONE;
   1014 		break;
   1015 	case FAILURE:
   1016 		break;
   1017 	default:
   1018 		wpa_printf(MSG_DEBUG, "EAP-PEAP: %s - unexpected state %d",
   1019 			   __func__, data->state);
   1020 		break;
   1021 	}
   1022 
   1023 	eap_peap_phase2_init(sm, data, next_type);
   1024 }
   1025 
   1026 
   1027 static void eap_peap_process_phase2(struct eap_sm *sm,
   1028 				    struct eap_peap_data *data,
   1029 				    const struct wpabuf *respData,
   1030 				    struct wpabuf *in_buf)
   1031 {
   1032 	struct wpabuf *in_decrypted;
   1033 	const struct eap_hdr *hdr;
   1034 	size_t len;
   1035 
   1036 	wpa_printf(MSG_DEBUG, "EAP-PEAP: received %lu bytes encrypted data for"
   1037 		   " Phase 2", (unsigned long) wpabuf_len(in_buf));
   1038 
   1039 	if (data->pending_phase2_resp) {
   1040 		wpa_printf(MSG_DEBUG, "EAP-PEAP: Pending Phase 2 response - "
   1041 			   "skip decryption and use old data");
   1042 		eap_peap_process_phase2_response(sm, data,
   1043 						 data->pending_phase2_resp);
   1044 		wpabuf_free(data->pending_phase2_resp);
   1045 		data->pending_phase2_resp = NULL;
   1046 		return;
   1047 	}
   1048 
   1049 	in_decrypted = tls_connection_decrypt(sm->ssl_ctx, data->ssl.conn,
   1050 					      in_buf);
   1051 	if (in_decrypted == NULL) {
   1052 		wpa_printf(MSG_INFO, "EAP-PEAP: Failed to decrypt Phase 2 "
   1053 			   "data");
   1054 		eap_peap_state(data, FAILURE);
   1055 		return;
   1056 	}
   1057 
   1058 	wpa_hexdump_buf_key(MSG_DEBUG, "EAP-PEAP: Decrypted Phase 2 EAP",
   1059 			    in_decrypted);
   1060 
   1061 	if (data->peap_version == 0 && data->state != PHASE2_TLV) {
   1062 		const struct eap_hdr *resp;
   1063 		struct eap_hdr *nhdr;
   1064 		struct wpabuf *nbuf =
   1065 			wpabuf_alloc(sizeof(struct eap_hdr) +
   1066 				     wpabuf_len(in_decrypted));
   1067 		if (nbuf == NULL) {
   1068 			wpabuf_free(in_decrypted);
   1069 			return;
   1070 		}
   1071 
   1072 		resp = wpabuf_head(respData);
   1073 		nhdr = wpabuf_put(nbuf, sizeof(*nhdr));
   1074 		nhdr->code = resp->code;
   1075 		nhdr->identifier = resp->identifier;
   1076 		nhdr->length = host_to_be16(sizeof(struct eap_hdr) +
   1077 					    wpabuf_len(in_decrypted));
   1078 		wpabuf_put_buf(nbuf, in_decrypted);
   1079 		wpabuf_free(in_decrypted);
   1080 
   1081 		in_decrypted = nbuf;
   1082 	} else if (data->peap_version >= 2) {
   1083 		struct eap_tlv_hdr *tlv;
   1084 		struct wpabuf *nmsg;
   1085 
   1086 		if (wpabuf_len(in_decrypted) < sizeof(*tlv) + sizeof(*hdr)) {
   1087 			wpa_printf(MSG_INFO, "EAP-PEAPv2: Too short Phase 2 "
   1088 				   "EAP TLV");
   1089 			wpabuf_free(in_decrypted);
   1090 			return;
   1091 		}
   1092 		tlv = wpabuf_mhead(in_decrypted);
   1093 		if ((be_to_host16(tlv->tlv_type) & EAP_TLV_TYPE_MASK) !=
   1094 		    EAP_TLV_EAP_PAYLOAD_TLV) {
   1095 			wpa_printf(MSG_INFO, "EAP-PEAPv2: Not an EAP TLV");
   1096 			wpabuf_free(in_decrypted);
   1097 			return;
   1098 		}
   1099 		if (sizeof(*tlv) + be_to_host16(tlv->length) >
   1100 		    wpabuf_len(in_decrypted)) {
   1101 			wpa_printf(MSG_INFO, "EAP-PEAPv2: Invalid EAP TLV "
   1102 				   "length");
   1103 			wpabuf_free(in_decrypted);
   1104 			return;
   1105 		}
   1106 		hdr = (struct eap_hdr *) (tlv + 1);
   1107 		if (be_to_host16(hdr->length) > be_to_host16(tlv->length)) {
   1108 			wpa_printf(MSG_INFO, "EAP-PEAPv2: No room for full "
   1109 				   "EAP packet in EAP TLV");
   1110 			wpabuf_free(in_decrypted);
   1111 			return;
   1112 		}
   1113 
   1114 		nmsg = wpabuf_alloc(be_to_host16(hdr->length));
   1115 		if (nmsg == NULL) {
   1116 			wpabuf_free(in_decrypted);
   1117 			return;
   1118 		}
   1119 
   1120 		wpabuf_put_data(nmsg, hdr, be_to_host16(hdr->length));
   1121 		wpabuf_free(in_decrypted);
   1122 		in_decrypted = nmsg;
   1123 	}
   1124 
   1125 	hdr = wpabuf_head(in_decrypted);
   1126 	if (wpabuf_len(in_decrypted) < (int) sizeof(*hdr)) {
   1127 		wpa_printf(MSG_INFO, "EAP-PEAP: Too short Phase 2 "
   1128 			   "EAP frame (len=%lu)",
   1129 			   (unsigned long) wpabuf_len(in_decrypted));
   1130 		wpabuf_free(in_decrypted);
   1131 		eap_peap_req_failure(sm, data);
   1132 		return;
   1133 	}
   1134 	len = be_to_host16(hdr->length);
   1135 	if (len > wpabuf_len(in_decrypted)) {
   1136 		wpa_printf(MSG_INFO, "EAP-PEAP: Length mismatch in "
   1137 			   "Phase 2 EAP frame (len=%lu hdr->length=%lu)",
   1138 			   (unsigned long) wpabuf_len(in_decrypted),
   1139 			   (unsigned long) len);
   1140 		wpabuf_free(in_decrypted);
   1141 		eap_peap_req_failure(sm, data);
   1142 		return;
   1143 	}
   1144 	wpa_printf(MSG_DEBUG, "EAP-PEAP: received Phase 2: code=%d "
   1145 		   "identifier=%d length=%lu", hdr->code, hdr->identifier,
   1146 		   (unsigned long) len);
   1147 	switch (hdr->code) {
   1148 	case EAP_CODE_RESPONSE:
   1149 		eap_peap_process_phase2_response(sm, data, in_decrypted);
   1150 		break;
   1151 	case EAP_CODE_SUCCESS:
   1152 		wpa_printf(MSG_DEBUG, "EAP-PEAP: Phase 2 Success");
   1153 		if (data->state == SUCCESS_REQ) {
   1154 			eap_peap_state(data, SUCCESS);
   1155 		}
   1156 		break;
   1157 	case EAP_CODE_FAILURE:
   1158 		wpa_printf(MSG_DEBUG, "EAP-PEAP: Phase 2 Failure");
   1159 		eap_peap_state(data, FAILURE);
   1160 		break;
   1161 	default:
   1162 		wpa_printf(MSG_INFO, "EAP-PEAP: Unexpected code=%d in "
   1163 			   "Phase 2 EAP header", hdr->code);
   1164 		break;
   1165 	}
   1166 
   1167 	wpabuf_free(in_decrypted);
   1168 }
   1169 
   1170 
   1171 static int eap_peapv2_start_phase2(struct eap_sm *sm,
   1172 				   struct eap_peap_data *data)
   1173 {
   1174 	struct wpabuf *buf, *buf2;
   1175 
   1176 	wpa_printf(MSG_DEBUG, "EAP-PEAPv2: Phase1 done, include first Phase2 "
   1177 		   "payload in the same message");
   1178 	eap_peap_state(data, PHASE1_ID2);
   1179 	if (eap_peap_phase2_init(sm, data, EAP_TYPE_IDENTITY))
   1180 		return -1;
   1181 
   1182 	/* TODO: which Id to use here? */
   1183 	buf = data->phase2_method->buildReq(sm, data->phase2_priv, 6);
   1184 	if (buf == NULL)
   1185 		return -1;
   1186 
   1187 	buf2 = eap_peapv2_tlv_eap_payload(buf);
   1188 	if (buf2 == NULL)
   1189 		return -1;
   1190 
   1191 	wpa_hexdump_buf(MSG_DEBUG, "EAP-PEAPv2: Identity Request", buf2);
   1192 
   1193 	buf = tls_connection_encrypt(sm->ssl_ctx, data->ssl.conn,
   1194 				     buf2);
   1195 	wpabuf_free(buf2);
   1196 
   1197 	if (buf == NULL) {
   1198 		wpa_printf(MSG_INFO, "EAP-PEAPv2: Failed to encrypt Phase 2 "
   1199 			   "data");
   1200 		return -1;
   1201 	}
   1202 
   1203 	wpa_hexdump_buf(MSG_DEBUG, "EAP-PEAPv2: Encrypted Identity Request",
   1204 			buf);
   1205 
   1206 	/* Append TLS data into the pending buffer after the Server Finished */
   1207 	if (wpabuf_resize(&data->ssl.tls_out, wpabuf_len(buf)) < 0) {
   1208 		wpabuf_free(buf);
   1209 		return -1;
   1210 	}
   1211 	wpabuf_put_buf(data->ssl.tls_out, buf);
   1212 	wpabuf_free(buf);
   1213 
   1214 	return 0;
   1215 }
   1216 
   1217 
   1218 static int eap_peap_process_version(struct eap_sm *sm, void *priv,
   1219 				    int peer_version)
   1220 {
   1221 	struct eap_peap_data *data = priv;
   1222 
   1223 	data->recv_version = peer_version;
   1224 	if (data->force_version >= 0 && peer_version != data->force_version) {
   1225 		wpa_printf(MSG_INFO, "EAP-PEAP: peer did not select the forced"
   1226 			   " version (forced=%d peer=%d) - reject",
   1227 			   data->force_version, peer_version);
   1228 		return -1;
   1229 	}
   1230 	if (peer_version < data->peap_version) {
   1231 		wpa_printf(MSG_DEBUG, "EAP-PEAP: peer ver=%d, own ver=%d; "
   1232 			   "use version %d",
   1233 			   peer_version, data->peap_version, peer_version);
   1234 		data->peap_version = peer_version;
   1235 	}
   1236 
   1237 	return 0;
   1238 }
   1239 
   1240 
   1241 static void eap_peap_process_msg(struct eap_sm *sm, void *priv,
   1242 				 const struct wpabuf *respData)
   1243 {
   1244 	struct eap_peap_data *data = priv;
   1245 
   1246 	switch (data->state) {
   1247 	case PHASE1:
   1248 		if (eap_server_tls_phase1(sm, &data->ssl) < 0) {
   1249 			eap_peap_state(data, FAILURE);
   1250 			break;
   1251 		}
   1252 
   1253 		if (data->peap_version >= 2 &&
   1254 		    tls_connection_established(sm->ssl_ctx, data->ssl.conn)) {
   1255 			if (eap_peapv2_start_phase2(sm, data)) {
   1256 				eap_peap_state(data, FAILURE);
   1257 				break;
   1258 			}
   1259 		}
   1260 		break;
   1261 	case PHASE2_START:
   1262 		eap_peap_state(data, PHASE2_ID);
   1263 		eap_peap_phase2_init(sm, data, EAP_TYPE_IDENTITY);
   1264 		break;
   1265 	case PHASE1_ID2:
   1266 	case PHASE2_ID:
   1267 	case PHASE2_METHOD:
   1268 	case PHASE2_SOH:
   1269 	case PHASE2_TLV:
   1270 		eap_peap_process_phase2(sm, data, respData, data->ssl.tls_in);
   1271 		break;
   1272 	case SUCCESS_REQ:
   1273 		eap_peap_state(data, SUCCESS);
   1274 		break;
   1275 	case FAILURE_REQ:
   1276 		eap_peap_state(data, FAILURE);
   1277 		break;
   1278 	default:
   1279 		wpa_printf(MSG_DEBUG, "EAP-PEAP: Unexpected state %d in %s",
   1280 			   data->state, __func__);
   1281 		break;
   1282 	}
   1283 }
   1284 
   1285 
   1286 static void eap_peap_process(struct eap_sm *sm, void *priv,
   1287 			     struct wpabuf *respData)
   1288 {
   1289 	struct eap_peap_data *data = priv;
   1290 	if (eap_server_tls_process(sm, &data->ssl, respData, data,
   1291 				   EAP_TYPE_PEAP, eap_peap_process_version,
   1292 				   eap_peap_process_msg) < 0)
   1293 		eap_peap_state(data, FAILURE);
   1294 }
   1295 
   1296 
   1297 static Boolean eap_peap_isDone(struct eap_sm *sm, void *priv)
   1298 {
   1299 	struct eap_peap_data *data = priv;
   1300 	return data->state == SUCCESS || data->state == FAILURE;
   1301 }
   1302 
   1303 
   1304 static u8 * eap_peap_getKey(struct eap_sm *sm, void *priv, size_t *len)
   1305 {
   1306 	struct eap_peap_data *data = priv;
   1307 	u8 *eapKeyData;
   1308 
   1309 	if (data->state != SUCCESS)
   1310 		return NULL;
   1311 
   1312 	if (data->crypto_binding_used) {
   1313 		u8 csk[128];
   1314 		/*
   1315 		 * Note: It looks like Microsoft implementation requires null
   1316 		 * termination for this label while the one used for deriving
   1317 		 * IPMK|CMK did not use null termination.
   1318 		 */
   1319 		if (peap_prfplus(data->peap_version, data->ipmk, 40,
   1320 				 "Session Key Generating Function",
   1321 				 (u8 *) "\00", 1, csk, sizeof(csk)) < 0)
   1322 			return NULL;
   1323 		wpa_hexdump_key(MSG_DEBUG, "EAP-PEAP: CSK", csk, sizeof(csk));
   1324 		eapKeyData = os_malloc(EAP_TLS_KEY_LEN);
   1325 		if (eapKeyData) {
   1326 			os_memcpy(eapKeyData, csk, EAP_TLS_KEY_LEN);
   1327 			*len = EAP_TLS_KEY_LEN;
   1328 			wpa_hexdump(MSG_DEBUG, "EAP-PEAP: Derived key",
   1329 				    eapKeyData, EAP_TLS_KEY_LEN);
   1330 		} else {
   1331 			wpa_printf(MSG_DEBUG, "EAP-PEAP: Failed to derive "
   1332 				   "key");
   1333 		}
   1334 
   1335 		return eapKeyData;
   1336 	}
   1337 
   1338 	/* TODO: PEAPv1 - different label in some cases */
   1339 	eapKeyData = eap_server_tls_derive_key(sm, &data->ssl,
   1340 					       "client EAP encryption",
   1341 					       EAP_TLS_KEY_LEN);
   1342 	if (eapKeyData) {
   1343 		*len = EAP_TLS_KEY_LEN;
   1344 		wpa_hexdump(MSG_DEBUG, "EAP-PEAP: Derived key",
   1345 			    eapKeyData, EAP_TLS_KEY_LEN);
   1346 	} else {
   1347 		wpa_printf(MSG_DEBUG, "EAP-PEAP: Failed to derive key");
   1348 	}
   1349 
   1350 	return eapKeyData;
   1351 }
   1352 
   1353 
   1354 static Boolean eap_peap_isSuccess(struct eap_sm *sm, void *priv)
   1355 {
   1356 	struct eap_peap_data *data = priv;
   1357 	return data->state == SUCCESS;
   1358 }
   1359 
   1360 
   1361 int eap_server_peap_register(void)
   1362 {
   1363 	struct eap_method *eap;
   1364 	int ret;
   1365 
   1366 	eap = eap_server_method_alloc(EAP_SERVER_METHOD_INTERFACE_VERSION,
   1367 				      EAP_VENDOR_IETF, EAP_TYPE_PEAP, "PEAP");
   1368 	if (eap == NULL)
   1369 		return -1;
   1370 
   1371 	eap->init = eap_peap_init;
   1372 	eap->reset = eap_peap_reset;
   1373 	eap->buildReq = eap_peap_buildReq;
   1374 	eap->check = eap_peap_check;
   1375 	eap->process = eap_peap_process;
   1376 	eap->isDone = eap_peap_isDone;
   1377 	eap->getKey = eap_peap_getKey;
   1378 	eap->isSuccess = eap_peap_isSuccess;
   1379 
   1380 	ret = eap_server_method_register(eap);
   1381 	if (ret)
   1382 		eap_server_method_free(eap);
   1383 	return ret;
   1384 }
   1385