/*
 * EAP peer method: EAP-TEAP (RFC 7170)
 * Copyright (c) 2004-2019, Jouni Malinen <j@w1.fi>
 *
 * This software may be distributed under the terms of the BSD license.
 * See README for more details.
 */

#include "includes.h"

#include "common.h"
#include "crypto/tls.h"
#include "eap_common/eap_teap_common.h"
#include "eap_i.h"
#include "eap_tls_common.h"
#include "eap_config.h"
#include "eap_teap_pac.h"

#ifdef EAP_TEAP_DYNAMIC
#include "eap_teap_pac.c"
#endif /* EAP_TEAP_DYNAMIC */


static void eap_teap_deinit(struct eap_sm *sm, void *priv);


struct eap_teap_data {
	struct eap_ssl_data ssl;

	u8 teap_version; /* Negotiated version */
	u8 received_version; /* Version number received during negotiation */
	u16 tls_cs;

	const struct eap_method *phase2_method;
	void *phase2_priv;
	int phase2_success;
	int inner_method_done;
	int iresult_verified;
	int result_success_done;
	int on_tx_completion;

	struct eap_method_type phase2_type;
	struct eap_method_type *phase2_types;
	size_t num_phase2_types;
	int resuming; /* starting a resumed session */
#define EAP_TEAP_PROV_UNAUTH 1
#define EAP_TEAP_PROV_AUTH 2
	int provisioning_allowed; /* Allowed PAC provisioning modes */
	int provisioning; /* doing PAC provisioning (not the normal auth) */
	int anon_provisioning; /* doing anonymous (unauthenticated)
				* provisioning */
	int session_ticket_used;
	int test_outer_tlvs;

	u8 key_data[EAP_TEAP_KEY_LEN];
	u8 *session_id;
	size_t id_len;
	u8 emsk[EAP_EMSK_LEN];
	int success;

	struct eap_teap_pac *pac;
	struct eap_teap_pac *current_pac;
	size_t max_pac_list_len;
	int use_pac_binary_format;

	u8 simck_msk[EAP_TEAP_SIMCK_LEN];
	u8 simck_emsk[EAP_TEAP_SIMCK_LEN];
	int simck_idx;
	int cmk_emsk_available;

	struct wpabuf *pending_phase2_req;
	struct wpabuf *pending_resp;
	struct wpabuf *server_outer_tlvs;
	struct wpabuf *peer_outer_tlvs;
};


static int eap_teap_session_ticket_cb(void *ctx, const u8 *ticket, size_t len,
				      const u8 *client_random,
				      const u8 *server_random,
				      u8 *master_secret)
{
	struct eap_teap_data *data = ctx;

	wpa_printf(MSG_DEBUG, "EAP-TEAP: SessionTicket callback");

	if (!master_secret) {
		wpa_printf(MSG_DEBUG,
			   "EAP-TEAP: SessionTicket failed - fall back to full TLS handshake");
		data->session_ticket_used = 0;
		if (data->provisioning_allowed) {
			wpa_printf(MSG_DEBUG,
				   "EAP-TEAP: Try to provision a new PAC-Key");
			data->provisioning = 1;
			data->current_pac = NULL;
		}
		return 0;
	}

	wpa_hexdump(MSG_DEBUG, "EAP-TEAP: SessionTicket", ticket, len);

	if (!data->current_pac) {
		wpa_printf(MSG_DEBUG,
			   "EAP-TEAP: No PAC-Key available for using SessionTicket");
		data->session_ticket_used = 0;
		return 0;
	}

	/* EAP-TEAP uses PAC-Key as the TLS master_secret */
	os_memcpy(master_secret, data->current_pac->pac_key,
		  EAP_TEAP_PAC_KEY_LEN);

	data->session_ticket_used = 1;

	return 1;
}


static void eap_teap_parse_phase1(struct eap_teap_data *data,
				  const char *phase1)
{
	const char *pos;

	pos = os_strstr(phase1, "teap_provisioning=");
	if (pos) {
		data->provisioning_allowed = atoi(pos + 18);
		wpa_printf(MSG_DEBUG,
			   "EAP-TEAP: Automatic PAC provisioning mode: %d",
			   data->provisioning_allowed);
	}

	pos = os_strstr(phase1, "teap_max_pac_list_len=");
	if (pos) {
		data->max_pac_list_len = atoi(pos + 22);
		if (data->max_pac_list_len == 0)
			data->max_pac_list_len = 1;
		wpa_printf(MSG_DEBUG, "EAP-TEAP: Maximum PAC list length: %lu",
			   (unsigned long) data->max_pac_list_len);
	}

	if (os_strstr(phase1, "teap_pac_format=binary")) {
		data->use_pac_binary_format = 1;
		wpa_printf(MSG_DEBUG,
			   "EAP-TEAP: Using binary format for PAC list");
	}

#ifdef CONFIG_TESTING_OPTIONS
	if (os_strstr(phase1, "teap_test_outer_tlvs=1"))
		data->test_outer_tlvs = 1;
#endif /* CONFIG_TESTING_OPTIONS */
}


static void * eap_teap_init(struct eap_sm *sm)
{
	struct eap_teap_data *data;
	struct eap_peer_config *config = eap_get_config(sm);

	if (!config)
		return NULL;

	data = os_zalloc(sizeof(*data));
	if (!data)
		return NULL;
	data->teap_version = EAP_TEAP_VERSION;
	data->max_pac_list_len = 10;

	if (config->phase1)
		eap_teap_parse_phase1(data, config->phase1);

	if ((data->provisioning_allowed & EAP_TEAP_PROV_AUTH) &&
	    !config->cert.ca_cert && !config->cert.ca_path) {
		/* Prevent PAC provisioning without mutual authentication
		 * (either by validating server certificate or by suitable
		 * inner EAP method). */
		wpa_printf(MSG_INFO,
			   "EAP-TEAP: Disable authenticated provisioning due to no ca_cert/ca_path");
		data->provisioning_allowed &= ~EAP_TEAP_PROV_AUTH;
	}

	if (eap_peer_select_phase2_methods(config, "auth=",
					   &data->phase2_types,
					   &data->num_phase2_types, 0) < 0) {
		eap_teap_deinit(sm, data);
		return NULL;
	}

	data->phase2_type.vendor = EAP_VENDOR_IETF;
	data->phase2_type.method = EAP_TYPE_NONE;

	config->teap_anon_dh = !!(data->provisioning_allowed &
				  EAP_TEAP_PROV_UNAUTH);
	if (eap_peer_tls_ssl_init(sm, &data->ssl, config, EAP_TYPE_TEAP)) {
		wpa_printf(MSG_INFO, "EAP-TEAP: Failed to initialize SSL");
		eap_teap_deinit(sm, data);
		return NULL;
	}

	if (tls_connection_set_session_ticket_cb(sm->ssl_ctx, data->ssl.conn,
						 eap_teap_session_ticket_cb,
						 data) < 0) {
		wpa_printf(MSG_INFO,
			   "EAP-TEAP: Failed to set SessionTicket callback");
		eap_teap_deinit(sm, data);
		return NULL;
	}

	if (!config->pac_file) {
		wpa_printf(MSG_INFO, "EAP-TEAP: No PAC file configured");
		eap_teap_deinit(sm, data);
		return NULL;
	}

	if (data->use_pac_binary_format &&
	    eap_teap_load_pac_bin(sm, &data->pac, config->pac_file) < 0) {
		wpa_printf(MSG_INFO, "EAP-TEAP: Failed to load PAC file");
		eap_teap_deinit(sm, data);
		return NULL;
	}

	if (!data->use_pac_binary_format &&
	    eap_teap_load_pac(sm, &data->pac, config->pac_file) < 0) {
		wpa_printf(MSG_INFO, "EAP-TEAP: Failed to load PAC file");
		eap_teap_deinit(sm, data);
		return NULL;
	}
	eap_teap_pac_list_truncate(data->pac, data->max_pac_list_len);

	return data;
}


static void eap_teap_clear(struct eap_teap_data *data)
{
	forced_memzero(data->key_data, EAP_TEAP_KEY_LEN);
	forced_memzero(data->emsk, EAP_EMSK_LEN);
	os_free(data->session_id);
	data->session_id = NULL;
	wpabuf_free(data->pending_phase2_req);
	data->pending_phase2_req = NULL;
	wpabuf_free(data->pending_resp);
	data->pending_resp = NULL;
	wpabuf_free(data->server_outer_tlvs);
	data->server_outer_tlvs = NULL;
	wpabuf_free(data->peer_outer_tlvs);
	data->peer_outer_tlvs = NULL;
	forced_memzero(data->simck_msk, EAP_TEAP_SIMCK_LEN);
	forced_memzero(data->simck_emsk, EAP_TEAP_SIMCK_LEN);
}


static void eap_teap_deinit(struct eap_sm *sm, void *priv)
{
	struct eap_teap_data *data = priv;
	struct eap_teap_pac *pac, *prev;

	if (!data)
		return;
	if (data->phase2_priv && data->phase2_method)
		data->phase2_method->deinit(sm, data->phase2_priv);
	eap_teap_clear(data);
	os_free(data->phase2_types);
	eap_peer_tls_ssl_deinit(sm, &data->ssl);

	pac = data->pac;
	prev = NULL;
	while (pac) {
		prev = pac;
		pac = pac->next;
		eap_teap_free_pac(prev);
	}

	os_free(data);
}


static int eap_teap_derive_msk(struct eap_teap_data *data)
{
	/* FIX: RFC 7170 does not describe whether MSK or EMSK based S-IMCK[j]
	 * is used in this derivation */
	if (eap_teap_derive_eap_msk(data->tls_cs, data->simck_msk,
				    data->key_data) < 0 ||
	    eap_teap_derive_eap_emsk(data->tls_cs, data->simck_msk,
				     data->emsk) < 0)
		return -1;
	data->success = 1;
	return 0;
}


static int eap_teap_derive_key_auth(struct eap_sm *sm,
				    struct eap_teap_data *data)
{
	int res;

	/* RFC 7170, Section 5.1 */
	res = tls_connection_export_key(sm->ssl_ctx, data->ssl.conn,
					TEAP_TLS_EXPORTER_LABEL_SKS, NULL, 0,
					data->simck_msk, EAP_TEAP_SIMCK_LEN);
	if (res)
		return res;
	wpa_hexdump_key(MSG_DEBUG,
			"EAP-TEAP: session_key_seed (S-IMCK[0])",
			data->simck_msk, EAP_TEAP_SIMCK_LEN);
	os_memcpy(data->simck_emsk, data->simck_msk, EAP_TEAP_SIMCK_LEN);
	data->simck_idx = 0;
	return 0;
}


static int eap_teap_init_phase2_method(struct eap_sm *sm,
				       struct eap_teap_data *data)
{
	data->inner_method_done = 0;
	data->iresult_verified = 0;
	data->phase2_method =
		eap_peer_get_eap_method(data->phase2_type.vendor,
					data->phase2_type.method);
	if (!data->phase2_method)
		return -1;

	sm->init_phase2 = 1;
	data->phase2_priv = data->phase2_method->init(sm);
	sm->init_phase2 = 0;

	return data->phase2_priv == NULL ? -1 : 0;
}


static int eap_teap_select_phase2_method(struct eap_teap_data *data,
					 int vendor, enum eap_type type)
{
	size_t i;

	/* TODO: TNC with anonymous provisioning; need to require both
	 * completed inner EAP authentication (EAP-pwd or EAP-EKE) and TNC */

	if (data->anon_provisioning &&
	    !eap_teap_allowed_anon_prov_phase2_method(vendor, type)) {
		wpa_printf(MSG_INFO,
			   "EAP-TEAP: EAP type %u:%u not allowed during unauthenticated provisioning",
			   vendor, type);
		return -1;
	}

#ifdef EAP_TNC
	if (vendor == EAP_VENDOR_IETF && type == EAP_TYPE_TNC) {
		data->phase2_type.vendor = EAP_VENDOR_IETF;
		data->phase2_type.method = EAP_TYPE_TNC;
		wpa_printf(MSG_DEBUG,
			   "EAP-TEAP: Selected Phase 2 EAP vendor %d method %d for TNC",
			   data->phase2_type.vendor,
			   data->phase2_type.method);
		return 0;
	}
#endif /* EAP_TNC */

	for (i = 0; i < data->num_phase2_types; i++) {
		if (data->phase2_types[i].vendor != vendor ||
		    data->phase2_types[i].method != type)
			continue;

		data->phase2_type.vendor = data->phase2_types[i].vendor;
		data->phase2_type.method = data->phase2_types[i].method;
		wpa_printf(MSG_DEBUG,
			   "EAP-TEAP: Selected Phase 2 EAP vendor %d method %d",
			   data->phase2_type.vendor,
			   data->phase2_type.method);
		break;
	}

	if (vendor != data->phase2_type.vendor ||
	    type != data->phase2_type.method ||
	    (vendor == EAP_VENDOR_IETF && type == EAP_TYPE_NONE))
		return -1;

	return 0;
}


static void eap_teap_deinit_inner_eap(struct eap_sm *sm,
				      struct eap_teap_data *data)
{
	if (!data->phase2_priv || !data->phase2_method)
		return;

	wpa_printf(MSG_DEBUG,
		   "EAP-TEAP: Phase 2 EAP sequence - deinitialize previous method");
	data->phase2_method->deinit(sm, data->phase2_priv);
	data->phase2_method = NULL;
	data->phase2_priv = NULL;
	data->phase2_type.vendor = EAP_VENDOR_IETF;
	data->phase2_type.method = EAP_TYPE_NONE;
}


static int eap_teap_phase2_request(struct eap_sm *sm,
				   struct eap_teap_data *data,
				   struct eap_method_ret *ret,
				   struct eap_hdr *hdr,
				   struct wpabuf **resp)
{
	size_t len = be_to_host16(hdr->length);
	u8 *pos;
	struct eap_method_ret iret;
	struct eap_peer_config *config = eap_get_config(sm);
	struct wpabuf msg;
	int vendor = EAP_VENDOR_IETF;
	enum eap_type method;

	if (len <= sizeof(struct eap_hdr)) {
		wpa_printf(MSG_INFO,
			   "EAP-TEAP: too short Phase 2 request (len=%lu)",
			   (unsigned long) len);
		return -1;
	}
	pos = (u8 *) (hdr + 1);
	method = *pos;
	if (method == EAP_TYPE_EXPANDED) {
		if (len < sizeof(struct eap_hdr) + 8) {
			wpa_printf(MSG_INFO,
				   "EAP-TEAP: Too short Phase 2 request (expanded header) (len=%lu)",
				   (unsigned long) len);
			return -1;
		}
		vendor = WPA_GET_BE24(pos + 1);
		method = WPA_GET_BE32(pos + 4);
	}
	wpa_printf(MSG_DEBUG, "EAP-TEAP: Phase 2 Request: type=%u:%u",
		   vendor, method);
	if (vendor == EAP_VENDOR_IETF && method == EAP_TYPE_IDENTITY) {
		eap_teap_deinit_inner_eap(sm, data);
		*resp = eap_sm_buildIdentity(sm, hdr->identifier, 1);
		return 0;
	}

	if (data->phase2_priv && data->phase2_method &&
	    (vendor != data->phase2_type.vendor ||
	     method != data->phase2_type.method))
		eap_teap_deinit_inner_eap(sm, data);

	if (data->phase2_type.vendor == EAP_VENDOR_IETF &&
	    data->phase2_type.method == EAP_TYPE_NONE &&
	    eap_teap_select_phase2_method(data, vendor, method) < 0) {
		if (eap_peer_tls_phase2_nak(data->phase2_types,
					    data->num_phase2_types,
					    hdr, resp))
			return -1;
		return 0;
	}

	if ((!data->phase2_priv && eap_teap_init_phase2_method(sm, data) < 0) ||
	    !data->phase2_method) {
		wpa_printf(MSG_INFO,
			   "EAP-TEAP: Failed to initialize Phase 2 EAP method %u:%u",
			   vendor, method);
		ret->methodState = METHOD_DONE;
		ret->decision = DECISION_FAIL;
		return -1;
	}

	os_memset(&iret, 0, sizeof(iret));
	wpabuf_set(&msg, hdr, len);
	*resp = data->phase2_method->process(sm, data->phase2_priv, &iret,
					     &msg);
	if (iret.methodState == METHOD_DONE)
		data->inner_method_done = 1;
	if (!(*resp) ||
	    (iret.methodState == METHOD_DONE &&
	     iret.decision == DECISION_FAIL)) {
		/* Wait for protected indication of failure */
		ret->methodState = METHOD_MAY_CONT;
		ret->decision = DECISION_FAIL;
	} else if ((iret.methodState == METHOD_DONE ||
		    iret.methodState == METHOD_MAY_CONT) &&
		   (iret.decision == DECISION_UNCOND_SUCC ||
		    iret.decision == DECISION_COND_SUCC)) {
		data->phase2_success = 1;
	}

	if (!(*resp) && config &&
	    (config->pending_req_identity || config->pending_req_password ||
	     config->pending_req_otp || config->pending_req_new_password ||
	     config->pending_req_sim)) {
		wpabuf_free(data->pending_phase2_req);
		data->pending_phase2_req = wpabuf_alloc_copy(hdr, len);
	} else if (!(*resp))
		return -1;

	return 0;
}


static struct wpabuf * eap_teap_tlv_nak(int vendor_id, int tlv_type)
{
	struct wpabuf *buf;
	struct teap_tlv_nak *nak;

	wpa_printf(MSG_DEBUG,
		   "EAP-TEAP: Add NAK TLV (Vendor-Id %u NAK-Type %u)",
		   vendor_id, tlv_type);
	buf = wpabuf_alloc(sizeof(*nak));
	if (!buf)
		return NULL;
	nak = wpabuf_put(buf, sizeof(*nak));
	nak->tlv_type = host_to_be16(TEAP_TLV_MANDATORY | TEAP_TLV_NAK);
	nak->length = host_to_be16(6);
	nak->vendor_id = host_to_be32(vendor_id);
	nak->nak_type = host_to_be16(tlv_type);
	return buf;
}


static struct wpabuf * eap_teap_tlv_pac_ack(void)
{
	struct wpabuf *buf;
	struct teap_tlv_result *res;
	struct teap_tlv_pac_ack *ack;

	buf = wpabuf_alloc(sizeof(*res) + sizeof(*ack));
	if (!buf)
		return NULL;

	wpa_printf(MSG_DEBUG, "EAP-TEAP: Add PAC TLV (ack)");
	ack = wpabuf_put(buf, sizeof(*ack));
	ack->tlv_type = host_to_be16(TEAP_TLV_PAC | TEAP_TLV_MANDATORY);
	ack->length = host_to_be16(sizeof(*ack) - sizeof(struct teap_tlv_hdr));
	ack->pac_type = host_to_be16(PAC_TYPE_PAC_ACKNOWLEDGEMENT);
	ack->pac_len = host_to_be16(2);
	ack->result = host_to_be16(TEAP_STATUS_SUCCESS);

	return buf;
}


static struct wpabuf * eap_teap_add_identity_type(struct eap_sm *sm,
						  struct wpabuf *msg)
{
	struct wpabuf *tlv;

	tlv = eap_teap_tlv_identity_type(sm->use_machine_cred ?
					 TEAP_IDENTITY_TYPE_MACHINE :
					 TEAP_IDENTITY_TYPE_USER);
	return wpabuf_concat(msg, tlv);
}


static struct wpabuf * eap_teap_process_eap_payload_tlv(
	struct eap_sm *sm, struct eap_teap_data *data,
	struct eap_method_ret *ret,
	u8 *eap_payload_tlv, size_t eap_payload_tlv_len,
	enum teap_identity_types req_id_type)
{
	struct eap_hdr *hdr;
	struct wpabuf *resp = NULL;

	if (eap_payload_tlv_len < sizeof(*hdr)) {
		wpa_printf(MSG_DEBUG,
			   "EAP-TEAP: too short EAP Payload TLV (len=%lu)",
			   (unsigned long) eap_payload_tlv_len);
		return NULL;
	}

	hdr = (struct eap_hdr *) eap_payload_tlv;
	if (be_to_host16(hdr->length) > eap_payload_tlv_len) {
		wpa_printf(MSG_DEBUG,
			   "EAP-TEAP: EAP packet overflow in EAP Payload TLV");
		return NULL;
	}

	if (hdr->code != EAP_CODE_REQUEST) {
		wpa_printf(MSG_INFO,
			   "EAP-TEAP: Unexpected code=%d in Phase 2 EAP header",
			   hdr->code);
		return NULL;
	}

	if (eap_teap_phase2_request(sm, data, ret, hdr, &resp)) {
		wpa_printf(MSG_INFO,
			   "EAP-TEAP: Phase 2 Request processing failed");
		return NULL;
	}

	resp = eap_teap_tlv_eap_payload(resp);
	if (req_id_type)
		resp = eap_teap_add_identity_type(sm, resp);

	return resp;
}


static struct wpabuf * eap_teap_process_basic_auth_req(
	struct eap_sm *sm, struct eap_teap_data *data,
	u8 *basic_auth_req, size_t basic_auth_req_len,
	enum teap_identity_types req_id_type)
{
	const u8 *identity, *password;
	size_t identity_len, password_len, plen;
	struct wpabuf *resp;

	wpa_hexdump_ascii(MSG_DEBUG, "EAP-TEAP: Basic-Password-Auth-Req prompt",
			  basic_auth_req, basic_auth_req_len);
	/* TODO: send over control interface */

	identity = eap_get_config_identity(sm, &identity_len);
	password = eap_get_config_password(sm, &password_len);
	if (!identity || !password ||
	    identity_len > 255 || password_len > 255) {
		wpa_printf(MSG_DEBUG,
			   "EAP-TEAP: No username/password suitable for Basic-Password-Auth");
		return eap_teap_tlv_nak(0, TEAP_TLV_BASIC_PASSWORD_AUTH_REQ);
	}

	plen = 1 + identity_len + 1 + password_len;
	resp = wpabuf_alloc(sizeof(struct teap_tlv_hdr) + plen);
	if (!resp)
		return NULL;
	eap_teap_put_tlv_hdr(resp, TEAP_TLV_BASIC_PASSWORD_AUTH_RESP, plen);
	wpabuf_put_u8(resp, identity_len);
	wpabuf_put_data(resp, identity, identity_len);
	wpabuf_put_u8(resp, password_len);
	wpabuf_put_data(resp, password, password_len);
	wpa_hexdump_buf_key(MSG_DEBUG, "EAP-TEAP: Basic-Password-Auth-Resp",
			    resp);
	if (req_id_type)
		resp = eap_teap_add_identity_type(sm, resp);

	/* Assume this succeeds so that Result TLV(Success) from the server can
	 * be used to terminate TEAP. */
	data->phase2_success = 1;

	return resp;
}


static int
eap_teap_validate_crypto_binding(struct eap_teap_data *data,
				 const struct teap_tlv_crypto_binding *cb)
{
	u8 flags, subtype;

	subtype = cb->subtype & 0x0f;
	flags = cb->subtype >> 4;

	wpa_printf(MSG_DEBUG,
		   "EAP-TEAP: Crypto-Binding TLV: Version %u Received Version %u Flags %u Sub-Type %u",
		   cb->version, cb->received_version, flags, subtype);
	wpa_hexdump(MSG_MSGDUMP, "EAP-TEAP: Nonce",
		    cb->nonce, sizeof(cb->nonce));
	wpa_hexdump(MSG_MSGDUMP, "EAP-TEAP: EMSK Compound MAC",
		    cb->emsk_compound_mac, sizeof(cb->emsk_compound_mac));
	wpa_hexdump(MSG_MSGDUMP, "EAP-TEAP: MSK Compound MAC",
		    cb->msk_compound_mac, sizeof(cb->msk_compound_mac));

	if (cb->version != EAP_TEAP_VERSION ||
	    cb->received_version != data->received_version ||
	    subtype != TEAP_CRYPTO_BINDING_SUBTYPE_REQUEST ||
	    flags < 1 || flags > 3) {
		wpa_printf(MSG_INFO,
			   "EAP-TEAP: Invalid Version/Flags/Sub-Type in Crypto-Binding TLV: Version %u Received Version %u Flags %u Sub-Type %u",
			   cb->version, cb->received_version, flags, subtype);
		return -1;
	}

	if (cb->nonce[EAP_TEAP_NONCE_LEN - 1] & 0x01) {
		wpa_printf(MSG_INFO,
			   "EAP-TEAP: Invalid Crypto-Binding TLV Nonce in request");
		return -1;
	}

	return 0;
}


static int eap_teap_write_crypto_binding(
	struct eap_teap_data *data,
	struct teap_tlv_crypto_binding *rbind,
	const struct teap_tlv_crypto_binding *cb,
	const u8 *cmk_msk, const u8 *cmk_emsk)
{
	u8 subtype, flags;

	rbind->tlv_type = host_to_be16(TEAP_TLV_MANDATORY |
				       TEAP_TLV_CRYPTO_BINDING);
	rbind->length = host_to_be16(sizeof(*rbind) -
				     sizeof(struct teap_tlv_hdr));
	rbind->version = EAP_TEAP_VERSION;
	rbind->received_version = data->received_version;
	/* FIX: RFC 7170 is not clear on which Flags value to use when
	 * Crypto-Binding TLV is used with Basic-Password-Auth */
	flags = cmk_emsk ? TEAP_CRYPTO_BINDING_EMSK_AND_MSK_CMAC :
		TEAP_CRYPTO_BINDING_MSK_CMAC;
	subtype = TEAP_CRYPTO_BINDING_SUBTYPE_RESPONSE;
	rbind->subtype = (flags << 4) | subtype;
	os_memcpy(rbind->nonce, cb->nonce, sizeof(cb->nonce));
	inc_byte_array(rbind->nonce, sizeof(rbind->nonce));
	os_memset(rbind->emsk_compound_mac, 0, EAP_TEAP_COMPOUND_MAC_LEN);
	os_memset(rbind->msk_compound_mac, 0, EAP_TEAP_COMPOUND_MAC_LEN);

	if (eap_teap_compound_mac(data->tls_cs, rbind, data->server_outer_tlvs,
				  data->peer_outer_tlvs, cmk_msk,
				  rbind->msk_compound_mac) < 0)
		return -1;
	if (cmk_emsk &&
	    eap_teap_compound_mac(data->tls_cs, rbind, data->server_outer_tlvs,
				  data->peer_outer_tlvs, cmk_emsk,
				  rbind->emsk_compound_mac) < 0)
		return -1;

	wpa_printf(MSG_DEBUG,
		   "EAP-TEAP: Reply Crypto-Binding TLV: Version %u Received Version %u Flags %u SubType %u",
		   rbind->version, rbind->received_version, flags, subtype);
	wpa_hexdump(MSG_MSGDUMP, "EAP-TEAP: Nonce",
		    rbind->nonce, sizeof(rbind->nonce));
	wpa_hexdump(MSG_MSGDUMP, "EAP-TEAP: EMSK Compound MAC",
		    rbind->emsk_compound_mac, sizeof(rbind->emsk_compound_mac));
	wpa_hexdump(MSG_MSGDUMP, "EAP-TEAP: MSK Compound MAC",
		    rbind->msk_compound_mac, sizeof(rbind->msk_compound_mac));

	return 0;
}


static int eap_teap_get_cmk(struct eap_sm *sm, struct eap_teap_data *data,
			    u8 *cmk_msk, u8 *cmk_emsk)
{
	u8 *msk = NULL, *emsk = NULL;
	size_t msk_len = 0, emsk_len = 0;
	int res;

	wpa_printf(MSG_DEBUG,
		   "EAP-TEAP: Determining CMK[%d] for Compound MAC calculation",
		   data->simck_idx + 1);

	if (!data->phase2_method)
		return eap_teap_derive_cmk_basic_pw_auth(data->tls_cs,
							 data->simck_msk,
							 cmk_msk);

	if (!data->phase2_method || !data->phase2_priv) {
		wpa_printf(MSG_INFO, "EAP-TEAP: Phase 2 method not available");
		return -1;
	}

	if (data->phase2_method->isKeyAvailable &&
	    !data->phase2_method->isKeyAvailable(sm, data->phase2_priv)) {
		wpa_printf(MSG_INFO,
			   "EAP-TEAP: Phase 2 key material not available");
		return -1;
	}

	if (data->phase2_method->isKeyAvailable &&
	    data->phase2_method->getKey) {
		msk = data->phase2_method->getKey(sm, data->phase2_priv,
						  &msk_len);
		if (!msk) {
			wpa_printf(MSG_INFO,
				   "EAP-TEAP: Could not fetch Phase 2 MSK");
			return -1;
		}
	}

	if (data->phase2_method->isKeyAvailable &&
	    data->phase2_method->get_emsk) {
		emsk = data->phase2_method->get_emsk(sm, data->phase2_priv,
						     &emsk_len);
	}

	res = eap_teap_derive_imck(data->tls_cs,
				   data->simck_msk, data->simck_emsk,
				   msk, msk_len, emsk, emsk_len,
				   data->simck_msk, cmk_msk,
				   data->simck_emsk, cmk_emsk);
	bin_clear_free(msk, msk_len);
	bin_clear_free(emsk, emsk_len);
	if (res == 0) {
		data->simck_idx++;
		if (emsk)
			data->cmk_emsk_available = 1;
	}
	return res;
}


static int eap_teap_session_id(struct eap_teap_data *data)
{
	const size_t max_id_len = 100;
	int res;

	os_free(data->session_id);
	data->session_id = os_malloc(max_id_len);
	if (!data->session_id)
		return -1;

	data->session_id[0] = EAP_TYPE_TEAP;
	res = tls_get_tls_unique(data->ssl.conn, data->session_id + 1,
				 max_id_len - 1);
	if (res < 0) {
		os_free(data->session_id);
		data->session_id = NULL;
		wpa_printf(MSG_ERROR, "EAP-TEAP: Failed to derive Session-Id");
		return -1;
	}

	data->id_len = 1 + res;
	wpa_hexdump(MSG_DEBUG, "EAP-TEAP: Derived Session-Id",
		    data->session_id, data->id_len);
	return 0;
}


static struct wpabuf * eap_teap_process_crypto_binding(
	struct eap_sm *sm, struct eap_teap_data *data,
	struct eap_method_ret *ret,
	const struct teap_tlv_crypto_binding *cb, size_t bind_len)
{
	struct wpabuf *resp;
	u8 *pos;
	u8 cmk_msk[EAP_TEAP_CMK_LEN];
	u8 cmk_emsk[EAP_TEAP_CMK_LEN];
	const u8 *cmk_emsk_ptr = NULL;
	int res;
	size_t len;
	u8 flags;

	if (eap_teap_validate_crypto_binding(data, cb) < 0 ||
	    eap_teap_get_cmk(sm, data, cmk_msk, cmk_emsk) < 0)
		return NULL;

	/* Validate received MSK/EMSK Compound MAC */
	flags = cb->subtype >> 4;

	if (flags == TEAP_CRYPTO_BINDING_MSK_CMAC ||
	    flags == TEAP_CRYPTO_BINDING_EMSK_AND_MSK_CMAC) {
		u8 msk_compound_mac[EAP_TEAP_COMPOUND_MAC_LEN];

		if (eap_teap_compound_mac(data->tls_cs, cb,
					  data->server_outer_tlvs,
					  data->peer_outer_tlvs, cmk_msk,
					  msk_compound_mac) < 0)
			return NULL;
		res = os_memcmp_const(msk_compound_mac, cb->msk_compound_mac,
				      EAP_TEAP_COMPOUND_MAC_LEN);
		wpa_hexdump(MSG_MSGDUMP, "EAP-TEAP: Received MSK Compound MAC",
			    cb->msk_compound_mac, EAP_TEAP_COMPOUND_MAC_LEN);
		wpa_hexdump(MSG_MSGDUMP,
			    "EAP-TEAP: Calculated MSK Compound MAC",
			    msk_compound_mac, EAP_TEAP_COMPOUND_MAC_LEN);
		if (res != 0) {
			wpa_printf(MSG_INFO,
				   "EAP-TEAP: MSK Compound MAC did not match");
			return NULL;
		}
	}

	if ((flags == TEAP_CRYPTO_BINDING_EMSK_CMAC ||
	     flags == TEAP_CRYPTO_BINDING_EMSK_AND_MSK_CMAC) &&
	    data->cmk_emsk_available) {
		u8 emsk_compound_mac[EAP_TEAP_COMPOUND_MAC_LEN];

		if (eap_teap_compound_mac(data->tls_cs, cb,
					  data->server_outer_tlvs,
					  data->peer_outer_tlvs, cmk_emsk,
					  emsk_compound_mac) < 0)
			return NULL;
		res = os_memcmp_const(emsk_compound_mac, cb->emsk_compound_mac,
				      EAP_TEAP_COMPOUND_MAC_LEN);
		wpa_hexdump(MSG_MSGDUMP, "EAP-TEAP: Received EMSK Compound MAC",
			    cb->emsk_compound_mac, EAP_TEAP_COMPOUND_MAC_LEN);
		wpa_hexdump(MSG_MSGDUMP,
			    "EAP-TEAP: Calculated EMSK Compound MAC",
			    emsk_compound_mac, EAP_TEAP_COMPOUND_MAC_LEN);
		if (res != 0) {
			wpa_printf(MSG_INFO,
				   "EAP-TEAP: EMSK Compound MAC did not match");
			return NULL;
		}

		cmk_emsk_ptr = cmk_emsk;
	}

	if (flags == TEAP_CRYPTO_BINDING_EMSK_CMAC &&
	    !data->cmk_emsk_available) {
		wpa_printf(MSG_INFO,
			   "EAP-TEAP: Server included only EMSK Compound MAC, but no locally generated inner EAP EMSK to validate this");
		return NULL;
	}

	/*
	 * Compound MAC was valid, so authentication succeeded. Reply with
	 * crypto binding to allow server to complete authentication.
	 */

	len = sizeof(struct teap_tlv_crypto_binding);
	resp = wpabuf_alloc(len);
	if (!resp)
		return NULL;

	if (data->phase2_success && eap_teap_derive_msk(data) < 0) {
		wpa_printf(MSG_INFO, "EAP-TEAP: Failed to generate MSK");
		ret->methodState = METHOD_DONE;
		ret->decision = DECISION_FAIL;
		data->phase2_success = 0;
		wpabuf_free(resp);
		return NULL;
	}

	if (data->phase2_success && eap_teap_session_id(data) < 0) {
		wpabuf_free(resp);
		return NULL;
	}

	pos = wpabuf_put(resp, sizeof(struct teap_tlv_crypto_binding));
	if (eap_teap_write_crypto_binding(
		    data, (struct teap_tlv_crypto_binding *) pos,
		    cb, cmk_msk, cmk_emsk_ptr) < 0) {
		wpabuf_free(resp);
		return NULL;
	}

	return resp;
}


static void eap_teap_parse_pac_tlv(struct eap_teap_pac *entry, int type,
				   u8 *pos, size_t len, int *pac_key_found)
{
	switch (type & 0x7fff) {
	case PAC_TYPE_PAC_KEY:
		wpa_hexdump_key(MSG_DEBUG, "EAP-TEAP: PAC-Key", pos, len);
		if (len != EAP_TEAP_PAC_KEY_LEN) {
			wpa_printf(MSG_DEBUG,
				   "EAP-TEAP: Invalid PAC-Key length %lu",
				   (unsigned long) len);
			break;
		}
		*pac_key_found = 1;
		os_memcpy(entry->pac_key, pos, len);
		break;
	case PAC_TYPE_PAC_OPAQUE:
		wpa_hexdump(MSG_DEBUG, "EAP-TEAP: PAC-Opaque", pos, len);
		entry->pac_opaque = pos;
		entry->pac_opaque_len = len;
		break;
	case PAC_TYPE_PAC_INFO:
		wpa_hexdump(MSG_DEBUG, "EAP-TEAP: PAC-Info", pos, len);
		entry->pac_info = pos;
		entry->pac_info_len = len;
		break;
	default:
		wpa_printf(MSG_DEBUG, "EAP-TEAP: Ignored unknown PAC type %d",
			   type);
		break;
	}
}


static int eap_teap_process_pac_tlv(struct eap_teap_pac *entry,
				    u8 *pac, size_t pac_len)
{
	struct pac_attr_hdr *hdr;
	u8 *pos;
	size_t left, len;
	int type, pac_key_found = 0;

	pos = pac;
	left = pac_len;

	while (left > sizeof(*hdr)) {
		hdr = (struct pac_attr_hdr *) pos;
		type = be_to_host16(hdr->type);
		len = be_to_host16(hdr->len);
		pos += sizeof(*hdr);
		left -= sizeof(*hdr);
		if (len > left) {
			wpa_printf(MSG_DEBUG,
				   "EAP-TEAP: PAC TLV overrun (type=%d len=%lu left=%lu)",
				   type, (unsigned long) len,
				   (unsigned long) left);
			return -1;
		}

		eap_teap_parse_pac_tlv(entry, type, pos, len, &pac_key_found);

		pos += len;
		left -= len;
	}

	if (!pac_key_found || !entry->pac_opaque || !entry->pac_info) {
		wpa_printf(MSG_DEBUG,
			   "EAP-TEAP: PAC TLV does not include all the required fields");
		return -1;
	}

	return 0;
}


static int eap_teap_parse_pac_info(struct eap_teap_pac *entry, int type,
				   u8 *pos, size_t len)
{
	u16 pac_type;
	u32 lifetime;
	struct os_time now;

	switch (type & 0x7fff) {
	case PAC_TYPE_CRED_LIFETIME:
		if (len != 4) {
			wpa_hexdump(MSG_DEBUG,
				    "EAP-TEAP: PAC-Info - Invalid CRED_LIFETIME length - ignored",
				    pos, len);
			return 0;
		}

		/*
		 * This is not currently saved separately in PAC files since
		 * the server can automatically initiate PAC update when
		 * needed. Anyway, the information is available from PAC-Info
		 * dump if it is needed for something in the future.
		 */
		lifetime = WPA_GET_BE32(pos);
		os_get_time(&now);
		wpa_printf(MSG_DEBUG,
			   "EAP-TEAP: PAC-Info - CRED_LIFETIME %d (%d days)",
			   lifetime, (lifetime - (u32) now.sec) / 86400);
		break;
	case PAC_TYPE_A_ID:
		wpa_hexdump_ascii(MSG_DEBUG, "EAP-TEAP: PAC-Info - A-ID",
				  pos, len);
		entry->a_id = pos;
		entry->a_id_len = len;
		break;
	case PAC_TYPE_I_ID:
		wpa_hexdump_ascii(MSG_DEBUG, "EAP-TEAP: PAC-Info - I-ID",
				  pos, len);
		entry->i_id = pos;
		entry->i_id_len = len;
		break;
	case PAC_TYPE_A_ID_INFO:
		wpa_hexdump_ascii(MSG_DEBUG, "EAP-TEAP: PAC-Info - A-ID-Info",
				  pos, len);
		entry->a_id_info = pos;
		entry->a_id_info_len = len;
		break;
	case PAC_TYPE_PAC_TYPE:
		/* RFC 7170, Section 4.2.12.6 - PAC-Type TLV */
		if (len != 2) {
			wpa_printf(MSG_INFO,
				   "EAP-TEAP: Invalid PAC-Type length %lu (expected 2)",
				   (unsigned long) len);
			wpa_hexdump_ascii(MSG_DEBUG,
					  "EAP-TEAP: PAC-Info - PAC-Type",
					  pos, len);
			return -1;
		}
		pac_type = WPA_GET_BE16(pos);
		if (pac_type != PAC_TYPE_TUNNEL_PAC) {
			wpa_printf(MSG_INFO,
				   "EAP-TEAP: Unsupported PAC Type %d",
				   pac_type);
			return -1;
		}

		wpa_printf(MSG_DEBUG, "EAP-TEAP: PAC-Info - PAC-Type %d",
			   pac_type);
		entry->pac_type = pac_type;
		break;
	default:
		wpa_printf(MSG_DEBUG,
			   "EAP-TEAP: Ignored unknown PAC-Info type %d", type);
		break;
	}

	return 0;
}


static int eap_teap_process_pac_info(struct eap_teap_pac *entry)
{
	struct pac_attr_hdr *hdr;
	u8 *pos;
	size_t left, len;
	int type;

	/* RFC 7170, Section 4.2.12.4 */

	/* PAC-Type defaults to Tunnel PAC (Type 1) */
	entry->pac_type = PAC_TYPE_TUNNEL_PAC;

	pos = entry->pac_info;
	left = entry->pac_info_len;
	while (left > sizeof(*hdr)) {
		hdr = (struct pac_attr_hdr *) pos;
		type = be_to_host16(hdr->type);
		len = be_to_host16(hdr->len);
		pos += sizeof(*hdr);
		left -= sizeof(*hdr);
		if (len > left) {
			wpa_printf(MSG_DEBUG,
				   "EAP-TEAP: PAC-Info overrun (type=%d len=%lu left=%lu)",
				   type, (unsigned long) len,
				   (unsigned long) left);
			return -1;
		}

		if (eap_teap_parse_pac_info(entry, type, pos, len) < 0)
			return -1;

		pos += len;
		left -= len;
	}

	if (!entry->a_id || !entry->a_id_info) {
		wpa_printf(MSG_DEBUG,
			   "EAP-TEAP: PAC-Info does not include all the required fields");
		return -1;
	}

	return 0;
}


static struct wpabuf * eap_teap_process_pac(struct eap_sm *sm,
					    struct eap_teap_data *data,
					    struct eap_method_ret *ret,
					    u8 *pac, size_t pac_len)
{
	struct eap_peer_config *config = eap_get_config(sm);
	struct eap_teap_pac entry;

	os_memset(&entry, 0, sizeof(entry));
	if (eap_teap_process_pac_tlv(&entry, pac, pac_len) ||
	    eap_teap_process_pac_info(&entry))
		return NULL;

	eap_teap_add_pac(&data->pac, &data->current_pac, &entry);
	eap_teap_pac_list_truncate(data->pac, data->max_pac_list_len);
	if (data->use_pac_binary_format)
		eap_teap_save_pac_bin(sm, data->pac, config->pac_file);
	else
		eap_teap_save_pac(sm, data->pac, config->pac_file);

	wpa_printf(MSG_DEBUG,
		   "EAP-TEAP: Send PAC-Acknowledgement - %s initiated provisioning completed successfully",
		   data->provisioning ? "peer" : "server");
	return eap_teap_tlv_pac_ack();
}


static int eap_teap_parse_decrypted(struct wpabuf *decrypted,
				    struct eap_teap_tlv_parse *tlv,
				    struct wpabuf **resp)
{
	u16 tlv_type;
	int mandatory, res;
	size_t len;
	u8 *pos, *end;

	os_memset(tlv, 0, sizeof(*tlv));

	/* Parse TLVs from the decrypted Phase 2 data */
	pos = wpabuf_mhead(decrypted);
	end = pos + wpabuf_len(decrypted);
	while (end - pos >= 4) {
		mandatory = pos[0] & 0x80;
		tlv_type = WPA_GET_BE16(pos) & 0x3fff;
		pos += 2;
		len = WPA_GET_BE16(pos);
		pos += 2;
		if (len > (size_t) (end - pos)) {
			wpa_printf(MSG_INFO, "EAP-TEAP: TLV overflow");
			return -1;
		}
		wpa_printf(MSG_DEBUG,
			   "EAP-TEAP: Received Phase 2: TLV type %u (%s) length %u%s",
			   tlv_type, eap_teap_tlv_type_str(tlv_type),
			   (unsigned int) len,
			   mandatory ? " (mandatory)" : "");

		res = eap_teap_parse_tlv(tlv, tlv_type, pos, len);
		if (res == -2)
			break;
		if (res < 0) {
			if (mandatory) {
				wpa_printf(MSG_DEBUG,
					   "EAP-TEAP: NAK unknown mandatory TLV type %u",
					   tlv_type);
				*resp = eap_teap_tlv_nak(0, tlv_type);
				break;
			}

			wpa_printf(MSG_DEBUG,
				   "EAP-TEAP: Ignore unknown optional TLV type %u",
				   tlv_type);
		}

		pos += len;
	}

	return 0;
}


static struct wpabuf * eap_teap_pac_request(void)
{
	struct wpabuf *req;
	struct teap_tlv_request_action *act;
	struct teap_tlv_hdr *pac;
	struct teap_attr_pac_type *type;

	req = wpabuf_alloc(sizeof(*act) + sizeof(*pac) + sizeof(*type));
	if (!req)
		return NULL;

	wpa_printf(MSG_DEBUG, "EAP-TEAP: Add Request Action TLV (Process TLV)");
	act = wpabuf_put(req, sizeof(*act));
	act->tlv_type = host_to_be16(TEAP_TLV_REQUEST_ACTION);
	act->length = host_to_be16(2);
	act->status = TEAP_STATUS_SUCCESS;
	act->action = TEAP_REQUEST_ACTION_PROCESS_TLV;

	wpa_printf(MSG_DEBUG, "EAP-TEAP: Add PAC TLV (PAC-Type = Tunnel)");
	pac = wpabuf_put(req, sizeof(*pac));
	pac->tlv_type = host_to_be16(TEAP_TLV_PAC);
	pac->length = host_to_be16(sizeof(*type));

	type = wpabuf_put(req, sizeof(*type));
	type->type = host_to_be16(PAC_TYPE_PAC_TYPE);
	type->length = host_to_be16(2);
	type->pac_type = host_to_be16(PAC_TYPE_TUNNEL_PAC);

	return req;
}


static int eap_teap_process_decrypted(struct eap_sm *sm,
				      struct eap_teap_data *data,
				      struct eap_method_ret *ret,
				      u8 identifier,
				      struct wpabuf *decrypted,
				      struct wpabuf **out_data)
{
	struct wpabuf *resp = NULL, *tmp;
	struct eap_teap_tlv_parse tlv;
	int failed = 0;
	enum teap_error_codes error = 0;
	int iresult_added = 0;

	if (eap_teap_parse_decrypted(decrypted, &tlv, &resp) < 0) {
		/* Parsing failed - no response available */
		return 0;
	}

	if (resp) {
		/* Parsing rejected the message - send out an error response */
		goto send_resp;
	}

	if (tlv.result == TEAP_STATUS_FAILURE) {
		/* Server indicated failure - respond similarly per
		 * RFC 7170, 3.6.3. This authentication exchange cannot succeed
		 * and will be terminated with a cleartext EAP Failure. */
		wpa_printf(MSG_DEBUG,
			   "EAP-TEAP: Server rejected authentication");
		resp = eap_teap_tlv_result(TEAP_STATUS_FAILURE, 0);
		ret->methodState = METHOD_DONE;
		ret->decision = DECISION_FAIL;
		goto send_resp;
	}

	if (tlv.iresult == TEAP_STATUS_SUCCESS && !tlv.crypto_binding) {
		/* Intermediate-Result TLV indicating success, but no
		 * Crypto-Binding TLV */
		wpa_printf(MSG_DEBUG,
			   "EAP-TEAP: Intermediate-Result TLV indicating success, but no Crypto-Binding TLV");
		failed = 1;
		error = TEAP_ERROR_TUNNEL_COMPROMISE_ERROR;
		goto done;
	}

	if (!data->iresult_verified && !data->result_success_done &&
	    tlv.result == TEAP_STATUS_SUCCESS && !tlv.crypto_binding) {
		/* Result TLV indicating success, but no Crypto-Binding TLV */
		wpa_printf(MSG_DEBUG,
			   "EAP-TEAP: Result TLV indicating success, but no Crypto-Binding TLV");
		failed = 1;
		error = TEAP_ERROR_TUNNEL_COMPROMISE_ERROR;
		goto done;
	}

	if (tlv.iresult != TEAP_STATUS_SUCCESS &&
	    tlv.iresult != TEAP_STATUS_FAILURE &&
	    data->inner_method_done) {
		wpa_printf(MSG_DEBUG,
			   "EAP-TEAP: Inner EAP method exchange completed, but no Intermediate-Result TLV included");
		failed = 1;
		error = TEAP_ERROR_TUNNEL_COMPROMISE_ERROR;
		goto done;
	}

	if (tlv.identity_type == TEAP_IDENTITY_TYPE_MACHINE) {
		struct eap_peer_config *config = eap_get_config(sm);

		sm->use_machine_cred = config && config->machine_identity &&
			config->machine_identity_len;
	} else if (tlv.identity_type) {
		sm->use_machine_cred = 0;
	}
	if (tlv.identity_type) {
		struct eap_peer_config *config = eap_get_config(sm);

		os_free(data->phase2_types);
		data->phase2_types = NULL;
		data->num_phase2_types = 0;
		if (config &&
		    eap_peer_select_phase2_methods(config, "auth=",
						   &data->phase2_types,
						   &data->num_phase2_types,
						   sm->use_machine_cred) < 0) {
			wpa_printf(MSG_INFO,
				   "EAP-TEAP: Failed to update Phase 2 EAP types");
			failed = 1;
			goto done;
		}
	}

	if (tlv.basic_auth_req) {
		tmp = eap_teap_process_basic_auth_req(sm, data,
						      tlv.basic_auth_req,
						      tlv.basic_auth_req_len,
						      tlv.identity_type);
		if (!tmp)
			failed = 1;
		resp = wpabuf_concat(resp, tmp);
	} else if (tlv.eap_payload_tlv) {
		tmp = eap_teap_process_eap_payload_tlv(sm, data, ret,
						       tlv.eap_payload_tlv,
						       tlv.eap_payload_tlv_len,
						       tlv.identity_type);
		if (!tmp)
			failed = 1;
		resp = wpabuf_concat(resp, tmp);

		if (tlv.iresult == TEAP_STATUS_SUCCESS ||
		    tlv.iresult == TEAP_STATUS_FAILURE) {
			tmp = eap_teap_tlv_result(failed ?
						  TEAP_STATUS_FAILURE :
						  TEAP_STATUS_SUCCESS, 1);
			resp = wpabuf_concat(resp, tmp);
			if (tlv.iresult == TEAP_STATUS_FAILURE)
				failed = 1;
			iresult_added = 1;
		}
	}

	if (tlv.crypto_binding) {
		if (tlv.iresult != TEAP_STATUS_SUCCESS &&
		    tlv.result != TEAP_STATUS_SUCCESS) {
			wpa_printf(MSG_DEBUG,
				   "EAP-TEAP: Unexpected Crypto-Binding TLV without Result TLV or Intermediate-Result TLV indicating success");
			failed = 1;
			error = TEAP_ERROR_UNEXPECTED_TLVS_EXCHANGED;
			goto done;
		}

		tmp = eap_teap_process_crypto_binding(sm, data, ret,
						      tlv.crypto_binding,
						      tlv.crypto_binding_len);
		if (!tmp) {
			failed = 1;
			error = TEAP_ERROR_TUNNEL_COMPROMISE_ERROR;
		} else {
			resp = wpabuf_concat(resp, tmp);
			if (tlv.result == TEAP_STATUS_SUCCESS && !failed)
				data->result_success_done = 1;
			if (tlv.iresult == TEAP_STATUS_SUCCESS && !failed) {
				data->inner_method_done = 0;
				data->iresult_verified = 1;
			}
		}
	}

	if (data->result_success_done && data->session_ticket_used &&
	    eap_teap_derive_msk(data) == 0) {
		/* Assume the server might accept authentication without going
		 * through inner authentication. */
		wpa_printf(MSG_DEBUG,
			   "EAP-TEAP: PAC used - server may decide to skip inner authentication");
		ret->methodState = METHOD_MAY_CONT;
		ret->decision = DECISION_COND_SUCC;
	} else if (data->result_success_done &&
		   tls_connection_get_own_cert_used(data->ssl.conn) &&
		   eap_teap_derive_msk(data) == 0) {
		/* Assume the server might accept authentication without going
		 * through inner authentication. */
		wpa_printf(MSG_DEBUG,
			   "EAP-TEAP: Client certificate used - server may decide to skip inner authentication");
		ret->methodState = METHOD_MAY_CONT;
		ret->decision = DECISION_COND_SUCC;
	}

	if (tlv.pac) {
		if (tlv.result == TEAP_STATUS_SUCCESS) {
			tmp = eap_teap_process_pac(sm, data, ret,
						   tlv.pac, tlv.pac_len);
			resp = wpabuf_concat(resp, tmp);
		} else {
			wpa_printf(MSG_DEBUG,
				   "EAP-TEAP: PAC TLV without Result TLV acknowledging success");
			failed = 1;
			error = TEAP_ERROR_UNEXPECTED_TLVS_EXCHANGED;
		}
	}

	if (!data->current_pac && data->provisioning && !failed && !tlv.pac &&
	    tlv.crypto_binding &&
	    (!data->anon_provisioning ||
	     (data->phase2_success && data->phase2_method &&
	      data->phase2_method->vendor == 0 &&
	      eap_teap_allowed_anon_prov_cipher_suite(data->tls_cs) &&
	      eap_teap_allowed_anon_prov_phase2_method(
		      data->phase2_method->vendor,
		      data->phase2_method->method))) &&
	    (tlv.iresult == TEAP_STATUS_SUCCESS ||
	     tlv.result == TEAP_STATUS_SUCCESS)) {
		/*
		 * Need to request Tunnel PAC when using authenticated
		 * provisioning.
		 */
		wpa_printf(MSG_DEBUG, "EAP-TEAP: Request Tunnel PAC");
		tmp = eap_teap_pac_request();
		resp = wpabuf_concat(resp, tmp);
	}

done:
	if (failed) {
		tmp = eap_teap_tlv_result(TEAP_STATUS_FAILURE, 0);
		resp = wpabuf_concat(tmp, resp);

		if (error != 0) {
			tmp = eap_teap_tlv_error(error);
			resp = wpabuf_concat(tmp, resp);
		}

		ret->methodState = METHOD_DONE;
		ret->decision = DECISION_FAIL;
	} else if (tlv.result == TEAP_STATUS_SUCCESS) {
		tmp = eap_teap_tlv_result(TEAP_STATUS_SUCCESS, 0);
		resp = wpabuf_concat(tmp, resp);
	}
	if ((tlv.iresult == TEAP_STATUS_SUCCESS ||
	     tlv.iresult == TEAP_STATUS_FAILURE) && !iresult_added) {
		tmp = eap_teap_tlv_result((!failed && data->phase2_success) ?
					  TEAP_STATUS_SUCCESS :
					  TEAP_STATUS_FAILURE, 1);
		resp = wpabuf_concat(tmp, resp);
	}

	if (resp && tlv.result == TEAP_STATUS_SUCCESS && !failed &&
	    (tlv.crypto_binding || data->iresult_verified) &&
	    data->phase2_success) {
		/* Successfully completed Phase 2 */
		wpa_printf(MSG_DEBUG,
			   "EAP-TEAP: Authentication completed successfully");
		ret->methodState = METHOD_MAY_CONT;
		data->on_tx_completion = data->provisioning ?
			METHOD_MAY_CONT : METHOD_DONE;
		ret->decision = DECISION_UNCOND_SUCC;
	}

	if (!resp) {
		wpa_printf(MSG_DEBUG,
			   "EAP-TEAP: No recognized TLVs - send empty response packet");
		resp = wpabuf_alloc(1);
	}

send_resp:
	if (!resp)
		return 0;

	wpa_hexdump_buf(MSG_DEBUG, "EAP-TEAP: Encrypting Phase 2 data", resp);
	if (eap_peer_tls_encrypt(sm, &data->ssl, EAP_TYPE_TEAP,
				 data->teap_version, identifier,
				 resp, out_data)) {
		wpa_printf(MSG_INFO,
			   "EAP-TEAP: Failed to encrypt a Phase 2 frame");
	}
	wpabuf_free(resp);

	return 0;
}


static int eap_teap_decrypt(struct eap_sm *sm, struct eap_teap_data *data,
			    struct eap_method_ret *ret, u8 identifier,
			    const struct wpabuf *in_data,
			    struct wpabuf **out_data)
{
	struct wpabuf *in_decrypted;
	int res;

	wpa_printf(MSG_DEBUG,
		   "EAP-TEAP: Received %lu bytes encrypted data for Phase 2",
		   (unsigned long) wpabuf_len(in_data));

	if (data->pending_phase2_req) {
		wpa_printf(MSG_DEBUG,
			   "EAP-TEAP: Pending Phase 2 request - skip decryption and use old data");
		/* Clear TLS reassembly state. */
		eap_peer_tls_reset_input(&data->ssl);

		in_decrypted = data->pending_phase2_req;
		data->pending_phase2_req = NULL;
		goto continue_req;
	}

	if (wpabuf_len(in_data) == 0) {
		/* Received TLS ACK - requesting more fragments */
		res = eap_peer_tls_encrypt(sm, &data->ssl, EAP_TYPE_TEAP,
					   data->teap_version,
					   identifier, NULL, out_data);
		if (res == 0 && !data->ssl.tls_out &&
		    data->on_tx_completion) {
			wpa_printf(MSG_DEBUG,
				   "EAP-TEAP: Mark authentication completed at full TX of fragments");
			ret->methodState = data->on_tx_completion;
			data->on_tx_completion = 0;
			ret->decision = DECISION_UNCOND_SUCC;
		}
		return res;
	}

	res = eap_peer_tls_decrypt(sm, &data->ssl, in_data, &in_decrypted);
	if (res)
		return res;

continue_req:
	wpa_hexdump_buf(MSG_MSGDUMP, "EAP-TEAP: Decrypted Phase 2 TLV(s)",
			in_decrypted);

	if (wpabuf_len(in_decrypted) < 4) {
		wpa_printf(MSG_INFO,
			   "EAP-TEAP: Too short Phase 2 TLV frame (len=%lu)",
			   (unsigned long) wpabuf_len(in_decrypted));
		wpabuf_free(in_decrypted);
		return -1;
	}

	res = eap_teap_process_decrypted(sm, data, ret, identifier,
					 in_decrypted, out_data);

	wpabuf_free(in_decrypted);

	return res;
}


static void eap_teap_select_pac(struct eap_teap_data *data,
				const u8 *a_id, size_t a_id_len)
{
	if (!a_id)
		return;
	data->current_pac = eap_teap_get_pac(data->pac, a_id, a_id_len,
					     PAC_TYPE_TUNNEL_PAC);
	if (data->current_pac) {
		wpa_printf(MSG_DEBUG,
			   "EAP-TEAP: PAC found for this A-ID (PAC-Type %d)",
			   data->current_pac->pac_type);
		wpa_hexdump_ascii(MSG_MSGDUMP, "EAP-TEAP: A-ID-Info",
				  data->current_pac->a_id_info,
				  data->current_pac->a_id_info_len);
	}
}


static int eap_teap_use_pac_opaque(struct eap_sm *sm,
				   struct eap_teap_data *data,
				   struct eap_teap_pac *pac)
{
	u8 *tlv;
	size_t tlv_len, olen;
	struct teap_tlv_hdr *ehdr;

	wpa_printf(MSG_DEBUG, "EAP-TEAP: Add PAC-Opaque TLS extension");
	olen = pac->pac_opaque_len;
	tlv_len = sizeof(*ehdr) + olen;
	tlv = os_malloc(tlv_len);
	if (tlv) {
		ehdr = (struct teap_tlv_hdr *) tlv;
		ehdr->tlv_type = host_to_be16(PAC_TYPE_PAC_OPAQUE);
		ehdr->length = host_to_be16(olen);
		os_memcpy(ehdr + 1, pac->pac_opaque, olen);
	}
	if (!tlv ||
	    tls_connection_client_hello_ext(sm->ssl_ctx, data->ssl.conn,
					    TLS_EXT_PAC_OPAQUE,
					    tlv, tlv_len) < 0) {
		wpa_printf(MSG_DEBUG,
			   "EAP-TEAP: Failed to add PAC-Opaque TLS extension");
		os_free(tlv);
		return -1;
	}
	os_free(tlv);

	return 0;
}


static int eap_teap_clear_pac_opaque_ext(struct eap_sm *sm,
					 struct eap_teap_data *data)
{
	if (tls_connection_client_hello_ext(sm->ssl_ctx, data->ssl.conn,
					    TLS_EXT_PAC_OPAQUE, NULL, 0) < 0) {
		wpa_printf(MSG_DEBUG,
			   "EAP-TEAP: Failed to remove PAC-Opaque TLS extension");
		return -1;
	}
	return 0;
}


static int eap_teap_process_start(struct eap_sm *sm,
				  struct eap_teap_data *data, u8 flags,
				  const u8 *pos, size_t left)
{
	const u8 *a_id = NULL;
	size_t a_id_len = 0;

	/* TODO: Support (mostly theoretical) case of TEAP/Start request being
	 * fragmented */

	/* EAP-TEAP version negotiation (RFC 7170, Section 3.2) */
	data->received_version = flags & EAP_TLS_VERSION_MASK;
	wpa_printf(MSG_DEBUG, "EAP-TEAP: Start (server ver=%u, own ver=%u)",
		   data->received_version, data->teap_version);
	if (data->received_version < 1) {
		/* Version 1 was the first defined version, so reject 0 */
		wpa_printf(MSG_INFO,
			   "EAP-TEAP: Server used unknown TEAP version %u",
			   data->received_version);
		return -1;
	}
	if (data->received_version < data->teap_version)
		data->teap_version = data->received_version;
	wpa_printf(MSG_DEBUG, "EAP-TEAP: Using TEAP version %d",
		   data->teap_version);
	wpa_hexdump(MSG_MSGDUMP, "EAP-TEAP: Start message payload", pos, left);

	/* Parse Authority-ID TLV from Outer TLVs, if present */
	if (flags & EAP_TEAP_FLAGS_OUTER_TLV_LEN) {
		const u8 *outer_pos, *outer_end;
		u32 outer_tlv_len;

		if (left < 4) {
			wpa_printf(MSG_INFO,
				   "EAP-TEAP: Not enough room for the Outer TLV Length field");
			return -1;
		}

		outer_tlv_len = WPA_GET_BE32(pos);
		pos += 4;
		left -= 4;

		if (outer_tlv_len > left) {
			wpa_printf(MSG_INFO,
				   "EAP-TEAP: Truncated Outer TLVs field (Outer TLV Length: %u; remaining buffer: %u)",
				   outer_tlv_len, (unsigned int) left);
			return -1;
		}

		outer_pos = pos + left - outer_tlv_len;
		outer_end = outer_pos + outer_tlv_len;
		wpa_hexdump(MSG_MSGDUMP, "EAP-TEAP: Start message Outer TLVs",
			    outer_pos, outer_tlv_len);
		wpabuf_free(data->server_outer_tlvs);
		data->server_outer_tlvs = wpabuf_alloc_copy(outer_pos,
							    outer_tlv_len);
		if (!data->server_outer_tlvs)
			return -1;
		left -= outer_tlv_len;
		if (left > 0) {
			wpa_hexdump(MSG_INFO,
				    "EAP-TEAP: Unexpected TLS Data in Start message",
				    pos, left);
			return -1;
		}

		while (outer_pos < outer_end) {
			u16 tlv_type, tlv_len;

			if (outer_end - outer_pos < 4) {
				wpa_printf(MSG_INFO,
					   "EAP-TEAP: Truncated Outer TLV header");
				return -1;
			}
			tlv_type = WPA_GET_BE16(outer_pos);
			outer_pos += 2;
			tlv_len = WPA_GET_BE16(outer_pos);
			outer_pos += 2;
			/* Outer TLVs are required to be optional, so no need to
			 * check the M flag */
			tlv_type &= TEAP_TLV_TYPE_MASK;
			wpa_printf(MSG_DEBUG,
				   "EAP-TEAP: Outer TLV: Type=%u Length=%u",
				   tlv_type, tlv_len);
			if (outer_end - outer_pos < tlv_len) {
				wpa_printf(MSG_INFO,
					   "EAP-TEAP: Truncated Outer TLV (Type %u)",
					   tlv_type);
				return -1;
			}
			if (tlv_type == TEAP_TLV_AUTHORITY_ID) {
				wpa_hexdump(MSG_DEBUG, "EAP-TEAP: Authority-ID",
					    outer_pos, tlv_len);
				if (a_id) {
					wpa_printf(MSG_INFO,
						   "EAP-TEAP: Multiple Authority-ID TLVs in TEAP/Start");
					return -1;
				}
				a_id = outer_pos;
				a_id_len = tlv_len;
			} else {
				wpa_printf(MSG_DEBUG,
					   "EAP-TEAP: Ignore unknown Outer TLV (Type %u)",
					   tlv_type);
			}
			outer_pos += tlv_len;
		}
	} else if (left > 0) {
		wpa_hexdump(MSG_INFO,
			    "EAP-TEAP: Unexpected TLS Data in Start message",
			    pos, left);
		return -1;
	}

	eap_teap_select_pac(data, a_id, a_id_len);

	if (data->resuming && data->current_pac) {
		wpa_printf(MSG_DEBUG,
			   "EAP-TEAP: Trying to resume session - do not add PAC-Opaque to TLS ClientHello");
		if (eap_teap_clear_pac_opaque_ext(sm, data) < 0)
			return -1;
	} else if (data->current_pac) {
		/*
		 * PAC found for the A-ID and we are not resuming an old
		 * session, so add PAC-Opaque extension to ClientHello.
		 */
		if (eap_teap_use_pac_opaque(sm, data, data->current_pac) < 0)
			return -1;
	} else if (data->provisioning_allowed) {
		wpa_printf(MSG_DEBUG,
			   "EAP-TEAP: No PAC found - starting provisioning");
		if (eap_teap_clear_pac_opaque_ext(sm, data) < 0)
			return -1;
		data->provisioning = 1;
	}

	return 0;
}


#ifdef CONFIG_TESTING_OPTIONS
static struct wpabuf * eap_teap_add_dummy_outer_tlvs(struct eap_teap_data *data,
						     struct wpabuf *resp)
{
	struct wpabuf *resp2;
	u16 len;
	const u8 *pos;
	u8 flags;

	wpabuf_free(data->peer_outer_tlvs);
	data->peer_outer_tlvs = wpabuf_alloc(4 + 4);
	if (!data->peer_outer_tlvs) {
		wpabuf_free(resp);
		return NULL;
	}

	/* Outer TLVs (dummy Vendor-Specific TLV for testing) */
	wpabuf_put_be16(data->peer_outer_tlvs, TEAP_TLV_VENDOR_SPECIFIC);
	wpabuf_put_be16(data->peer_outer_tlvs, 4);
	wpabuf_put_be32(data->peer_outer_tlvs, EAP_VENDOR_HOSTAP);
	wpa_hexdump_buf(MSG_DEBUG, "EAP-TEAP: TESTING - Add dummy Outer TLVs",
			data->peer_outer_tlvs);

	wpa_hexdump_buf(MSG_DEBUG,
			"EAP-TEAP: TEAP/Start response before modification",
			resp);
	resp2 = wpabuf_alloc(wpabuf_len(resp) + 4 +
			     wpabuf_len(data->peer_outer_tlvs));
	if (!resp2) {
		wpabuf_free(resp);
		return NULL;
	}

	pos = wpabuf_head(resp);
	wpabuf_put_u8(resp2, *pos++); /* Code */
	wpabuf_put_u8(resp2, *pos++); /* Identifier */
	len = WPA_GET_BE16(pos);
	pos += 2;
	wpabuf_put_be16(resp2, len + 4 + wpabuf_len(data->peer_outer_tlvs));
	wpabuf_put_u8(resp2, *pos++); /* Type */
	/* Flags | Ver (with Outer TLV length included flag set to 1) */
	flags = *pos++;
	if (flags & (EAP_TEAP_FLAGS_OUTER_TLV_LEN |
		     EAP_TLS_FLAGS_LENGTH_INCLUDED)) {
		wpa_printf(MSG_INFO,
			   "EAP-TEAP: Cannot add Outer TLVs for testing");
		wpabuf_free(resp);
		wpabuf_free(resp2);
		return NULL;
	}
	flags |= EAP_TEAP_FLAGS_OUTER_TLV_LEN;
	wpabuf_put_u8(resp2, flags);
	/* Outer TLV Length */
	wpabuf_put_be32(resp2, wpabuf_len(data->peer_outer_tlvs));
	/* TLS Data */
	wpabuf_put_data(resp2, pos, wpabuf_len(resp) - 6);
	wpabuf_put_buf(resp2, data->peer_outer_tlvs); /* Outer TLVs */

	wpabuf_free(resp);
	wpa_hexdump_buf(MSG_DEBUG,
			"EAP-TEAP: TEAP/Start response after modification",
			resp2);
	return resp2;
}
#endif /* CONFIG_TESTING_OPTIONS */


static struct wpabuf * eap_teap_process(struct eap_sm *sm, void *priv,
					struct eap_method_ret *ret,
					const struct wpabuf *reqData)
{
	const struct eap_hdr *req;
	size_t left;
	int res;
	u8 flags, id;
	struct wpabuf *resp;
	const u8 *pos;
	struct eap_teap_data *data = priv;
	struct wpabuf msg;

	pos = eap_peer_tls_process_init(sm, &data->ssl, EAP_TYPE_TEAP, ret,
					reqData, &left, &flags);
	if (!pos)
		return NULL;

	req = wpabuf_head(reqData);
	id = req->identifier;

	if (flags & EAP_TLS_FLAGS_START) {
		if (eap_teap_process_start(sm, data, flags, pos, left) < 0)
			return NULL;

		/* Outer TLVs are not used in further packet processing and
		 * there cannot be TLS Data in this TEAP/Start message, so
		 * enforce that by ignoring whatever data might remain in the
		 * buffer. */
		left = 0;
	} else if (flags & EAP_TEAP_FLAGS_OUTER_TLV_LEN) {
		/* TODO: RFC 7170, Section 4.3.1 indicates that the unexpected
		 * Outer TLVs MUST be ignored instead of ignoring the full
		 * message. */
		wpa_printf(MSG_INFO,
			   "EAP-TEAP: Outer TLVs present in non-Start message -> ignore message");
		return NULL;
	}

	wpabuf_set(&msg, pos, left);

	resp = NULL;
	if (tls_connection_established(sm->ssl_ctx, data->ssl.conn) &&
	    !data->resuming) {
		/* Process tunneled (encrypted) phase 2 data. */
		res = eap_teap_decrypt(sm, data, ret, id, &msg, &resp);
		if (res < 0) {
			ret->methodState = METHOD_DONE;
			ret->decision = DECISION_FAIL;
			/*
			 * Ack possible Alert that may have caused failure in
			 * decryption.
			 */
			res = 1;
		}
	} else {
		if (sm->waiting_ext_cert_check && data->pending_resp) {
			struct eap_peer_config *config = eap_get_config(sm);

			if (config->pending_ext_cert_check ==
			    EXT_CERT_CHECK_GOOD) {
				wpa_printf(MSG_DEBUG,
					   "EAP-TEAP: External certificate check succeeded - continue handshake");
				resp = data->pending_resp;
				data->pending_resp = NULL;
				sm->waiting_ext_cert_check = 0;
				return resp;
			}

			if (config->pending_ext_cert_check ==
			    EXT_CERT_CHECK_BAD) {
				wpa_printf(MSG_DEBUG,
					   "EAP-TEAP: External certificate check failed - force authentication failure");
				ret->methodState = METHOD_DONE;
				ret->decision = DECISION_FAIL;
				sm->waiting_ext_cert_check = 0;
				return NULL;
			}

			wpa_printf(MSG_DEBUG,
				   "EAP-TEAP: Continuing to wait external server certificate validation");
			return NULL;
		}

		/* Continue processing TLS handshake (phase 1). */
		res = eap_peer_tls_process_helper(sm, &data->ssl,
						  EAP_TYPE_TEAP,
						  data->teap_version, id, &msg,
						  &resp);
		if (res < 0) {
			wpa_printf(MSG_DEBUG,
				   "EAP-TEAP: TLS processing failed");
			ret->methodState = METHOD_DONE;
			ret->decision = DECISION_FAIL;
			return resp;
		}

		if (sm->waiting_ext_cert_check) {
			wpa_printf(MSG_DEBUG,
				   "EAP-TEAP: Waiting external server certificate validation");
			wpabuf_free(data->pending_resp);
			data->pending_resp = resp;
			return NULL;
		}

		if (tls_connection_established(sm->ssl_ctx, data->ssl.conn)) {
			char cipher[80];

			wpa_printf(MSG_DEBUG,
				   "EAP-TEAP: TLS done, proceed to Phase 2");
			data->tls_cs =
				tls_connection_get_cipher_suite(data->ssl.conn);
			wpa_printf(MSG_DEBUG,
				   "EAP-TEAP: TLS cipher suite 0x%04x",
				   data->tls_cs);

			if (data->provisioning &&
			    (!(data->provisioning_allowed &
			       EAP_TEAP_PROV_AUTH) ||
			     tls_get_cipher(sm->ssl_ctx, data->ssl.conn,
					    cipher, sizeof(cipher)) < 0 ||
			     os_strstr(cipher, "ADH-") ||
			     os_strstr(cipher, "anon"))) {
				wpa_printf(MSG_DEBUG,
					   "EAP-TEAP: Using anonymous (unauthenticated) provisioning");
				data->anon_provisioning = 1;
			} else {
				data->anon_provisioning = 0;
			}
			data->resuming = 0;
			if (eap_teap_derive_key_auth(sm, data) < 0) {
				wpa_printf(MSG_DEBUG,
					   "EAP-TEAP: Could not derive keys");
				ret->methodState = METHOD_DONE;
				ret->decision = DECISION_FAIL;
				wpabuf_free(resp);
				return NULL;
			}
		}

		if (res == 2) {
			/*
			 * Application data included in the handshake message.
			 */
			wpabuf_free(data->pending_phase2_req);
			data->pending_phase2_req = resp;
			resp = NULL;
			res = eap_teap_decrypt(sm, data, ret, id, &msg, &resp);
		}
	}

	if (res == 1) {
		wpabuf_free(resp);
		return eap_peer_tls_build_ack(id, EAP_TYPE_TEAP,
					      data->teap_version);
	}

#ifdef CONFIG_TESTING_OPTIONS
	if (data->test_outer_tlvs && res == 0 && resp &&
	    (flags & EAP_TLS_FLAGS_START) && wpabuf_len(resp) >= 6)
		resp = eap_teap_add_dummy_outer_tlvs(data, resp);
#endif /* CONFIG_TESTING_OPTIONS */

	return resp;
}


#if 0 /* TODO */
static bool eap_teap_has_reauth_data(struct eap_sm *sm, void *priv)
{
	struct eap_teap_data *data = priv;

	return tls_connection_established(sm->ssl_ctx, data->ssl.conn);
}


static void eap_teap_deinit_for_reauth(struct eap_sm *sm, void *priv)
{
	struct eap_teap_data *data = priv;

	if (data->phase2_priv && data->phase2_method &&
	    data->phase2_method->deinit_for_reauth)
		data->phase2_method->deinit_for_reauth(sm, data->phase2_priv);
	eap_teap_clear(data);
}


static void * eap_teap_init_for_reauth(struct eap_sm *sm, void *priv)
{
	struct eap_teap_data *data = priv;

	if (eap_peer_tls_reauth_init(sm, &data->ssl)) {
		eap_teap_deinit(sm, data);
		return NULL;
	}
	if (data->phase2_priv && data->phase2_method &&
	    data->phase2_method->init_for_reauth)
		data->phase2_method->init_for_reauth(sm, data->phase2_priv);
	data->phase2_success = 0;
	data->inner_method_done = 0;
	data->result_success_done = 0;
	data->iresult_verified = 0;
	data->done_on_tx_completion = 0;
	data->resuming = 1;
	data->provisioning = 0;
	data->anon_provisioning = 0;
	data->simck_idx = 0;
	return priv;
}
#endif


static int eap_teap_get_status(struct eap_sm *sm, void *priv, char *buf,
			       size_t buflen, int verbose)
{
	struct eap_teap_data *data = priv;
	int len, ret;

	len = eap_peer_tls_status(sm, &data->ssl, buf, buflen, verbose);
	if (data->phase2_method) {
		ret = os_snprintf(buf + len, buflen - len,
				  "EAP-TEAP Phase 2 method=%s\n",
				  data->phase2_method->name);
		if (os_snprintf_error(buflen - len, ret))
			return len;
		len += ret;
	}
	return len;
}


static bool eap_teap_isKeyAvailable(struct eap_sm *sm, void *priv)
{
	struct eap_teap_data *data = priv;

	return data->success;
}


static u8 * eap_teap_getKey(struct eap_sm *sm, void *priv, size_t *len)
{
	struct eap_teap_data *data = priv;
	u8 *key;

	if (!data->success)
		return NULL;

	key = os_memdup(data->key_data, EAP_TEAP_KEY_LEN);
	if (!key)
		return NULL;

	*len = EAP_TEAP_KEY_LEN;

	return key;
}


static u8 * eap_teap_get_session_id(struct eap_sm *sm, void *priv, size_t *len)
{
	struct eap_teap_data *data = priv;
	u8 *id;

	if (!data->success || !data->session_id)
		return NULL;

	id = os_memdup(data->session_id, data->id_len);
	if (!id)
		return NULL;

	*len = data->id_len;

	return id;
}


static u8 * eap_teap_get_emsk(struct eap_sm *sm, void *priv, size_t *len)
{
	struct eap_teap_data *data = priv;
	u8 *key;

	if (!data->success)
		return NULL;

	key = os_memdup(data->emsk, EAP_EMSK_LEN);
	if (!key)
		return NULL;

	*len = EAP_EMSK_LEN;

	return key;
}


int eap_peer_teap_register(void)
{
	struct eap_method *eap;

	eap = eap_peer_method_alloc(EAP_PEER_METHOD_INTERFACE_VERSION,
				    EAP_VENDOR_IETF, EAP_TYPE_TEAP, "TEAP");
	if (!eap)
		return -1;

	eap->init = eap_teap_init;
	eap->deinit = eap_teap_deinit;
	eap->process = eap_teap_process;
	eap->isKeyAvailable = eap_teap_isKeyAvailable;
	eap->getKey = eap_teap_getKey;
	eap->getSessionId = eap_teap_get_session_id;
	eap->get_status = eap_teap_get_status;
#if 0 /* TODO */
	eap->has_reauth_data = eap_teap_has_reauth_data;
	eap->deinit_for_reauth = eap_teap_deinit_for_reauth;
	eap->init_for_reauth = eap_teap_init_for_reauth;
#endif
	eap->get_emsk = eap_teap_get_emsk;

	return eap_peer_method_register(eap);
}
