/*
 * EAP-FAST server (RFC 4851)
 * Copyright (c) 2004-2008, 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/aes_wrap.h"
#include "crypto/sha1.h"
#include "crypto/tls.h"
#include "crypto/random.h"
#include "eap_common/eap_tlv_common.h"
#include "eap_common/eap_fast_common.h"
#include "eap_i.h"
#include "eap_tls_common.h"


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


/* Private PAC-Opaque TLV types */
#define PAC_OPAQUE_TYPE_PAD 0
#define PAC_OPAQUE_TYPE_KEY 1
#define PAC_OPAQUE_TYPE_LIFETIME 2
#define PAC_OPAQUE_TYPE_IDENTITY 3

struct eap_fast_data {
	struct eap_ssl_data ssl;
	enum {
		START, PHASE1, PHASE2_START, PHASE2_ID, PHASE2_METHOD,
		CRYPTO_BINDING, REQUEST_PAC, SUCCESS, FAILURE
	} state;

	int fast_version;
	const struct eap_method *phase2_method;
	void *phase2_priv;
	int force_version;
	int peer_version;

	u8 crypto_binding_nonce[32];
	int final_result;

	struct eap_fast_key_block_provisioning *key_block_p;

	u8 simck[EAP_FAST_SIMCK_LEN];
	u8 cmk[EAP_FAST_CMK_LEN];
	int simck_idx;

	u8 pac_opaque_encr[16];
	u8 *srv_id;
	size_t srv_id_len;
	char *srv_id_info;

	int anon_provisioning;
	int send_new_pac; /* server triggered re-keying of Tunnel PAC */
	struct wpabuf *pending_phase2_resp;
	u8 *identity; /* from PAC-Opaque */
	size_t identity_len;
	int eap_seq;
	int tnc_started;

	int pac_key_lifetime;
	int pac_key_refresh_time;
};


static int eap_fast_process_phase2_start(struct eap_sm *sm,
					 struct eap_fast_data *data);


static const char * eap_fast_state_txt(int state)
{
	switch (state) {
	case START:
		return "START";
	case PHASE1:
		return "PHASE1";
	case PHASE2_START:
		return "PHASE2_START";
	case PHASE2_ID:
		return "PHASE2_ID";
	case PHASE2_METHOD:
		return "PHASE2_METHOD";
	case CRYPTO_BINDING:
		return "CRYPTO_BINDING";
	case REQUEST_PAC:
		return "REQUEST_PAC";
	case SUCCESS:
		return "SUCCESS";
	case FAILURE:
		return "FAILURE";
	default:
		return "Unknown?!";
	}
}


static void eap_fast_state(struct eap_fast_data *data, int state)
{
	wpa_printf(MSG_DEBUG, "EAP-FAST: %s -> %s",
		   eap_fast_state_txt(data->state),
		   eap_fast_state_txt(state));
	data->state = state;
}


static EapType eap_fast_req_failure(struct eap_sm *sm,
				    struct eap_fast_data *data)
{
	/* TODO: send Result TLV(FAILURE) */
	eap_fast_state(data, FAILURE);
	return EAP_TYPE_NONE;
}


static int eap_fast_session_ticket_cb(void *ctx, const u8 *ticket, size_t len,
				      const u8 *client_random,
				      const u8 *server_random,
				      u8 *master_secret)
{
	struct eap_fast_data *data = ctx;
	const u8 *pac_opaque;
	size_t pac_opaque_len;
	u8 *buf, *pos, *end, *pac_key = NULL;
	os_time_t lifetime = 0;
	struct os_time now;
	u8 *identity = NULL;
	size_t identity_len = 0;

	wpa_printf(MSG_DEBUG, "EAP-FAST: SessionTicket callback");
	wpa_hexdump(MSG_DEBUG, "EAP-FAST: SessionTicket (PAC-Opaque)",
		    ticket, len);

	if (len < 4 || WPA_GET_BE16(ticket) != PAC_TYPE_PAC_OPAQUE) {
		wpa_printf(MSG_DEBUG, "EAP-FAST: Ignore invalid "
			   "SessionTicket");
		return 0;
	}

	pac_opaque_len = WPA_GET_BE16(ticket + 2);
	pac_opaque = ticket + 4;
	if (pac_opaque_len < 8 || pac_opaque_len % 8 ||
	    pac_opaque_len > len - 4) {
		wpa_printf(MSG_DEBUG, "EAP-FAST: Ignore invalid PAC-Opaque "
			   "(len=%lu left=%lu)",
			   (unsigned long) pac_opaque_len,
			   (unsigned long) len);
		return 0;
	}
	wpa_hexdump(MSG_DEBUG, "EAP-FAST: Received PAC-Opaque",
		    pac_opaque, pac_opaque_len);

	buf = os_malloc(pac_opaque_len - 8);
	if (buf == NULL) {
		wpa_printf(MSG_DEBUG, "EAP-FAST: Failed to allocate memory "
			   "for decrypting PAC-Opaque");
		return 0;
	}

	if (aes_unwrap(data->pac_opaque_encr, (pac_opaque_len - 8) / 8,
		       pac_opaque, buf) < 0) {
		wpa_printf(MSG_DEBUG, "EAP-FAST: Failed to decrypt "
			   "PAC-Opaque");
		os_free(buf);
		/*
		 * This may have been caused by server changing the PAC-Opaque
		 * encryption key, so just ignore this PAC-Opaque instead of
		 * failing the authentication completely. Provisioning can now
		 * be used to provision a new PAC.
		 */
		return 0;
	}

	end = buf + pac_opaque_len - 8;
	wpa_hexdump_key(MSG_DEBUG, "EAP-FAST: Decrypted PAC-Opaque",
			buf, end - buf);

	pos = buf;
	while (pos + 1 < end) {
		if (pos + 2 + pos[1] > end)
			break;

		switch (*pos) {
		case PAC_OPAQUE_TYPE_PAD:
			pos = end;
			break;
		case PAC_OPAQUE_TYPE_KEY:
			if (pos[1] != EAP_FAST_PAC_KEY_LEN) {
				wpa_printf(MSG_DEBUG, "EAP-FAST: Invalid "
					   "PAC-Key length %d", pos[1]);
				os_free(buf);
				return -1;
			}
			pac_key = pos + 2;
			wpa_hexdump_key(MSG_DEBUG, "EAP-FAST: PAC-Key from "
					"decrypted PAC-Opaque",
					pac_key, EAP_FAST_PAC_KEY_LEN);
			break;
		case PAC_OPAQUE_TYPE_LIFETIME:
			if (pos[1] != 4) {
				wpa_printf(MSG_DEBUG, "EAP-FAST: Invalid "
					   "PAC-Key lifetime length %d",
					   pos[1]);
				os_free(buf);
				return -1;
			}
			lifetime = WPA_GET_BE32(pos + 2);
			break;
		case PAC_OPAQUE_TYPE_IDENTITY:
			identity = pos + 2;
			identity_len = pos[1];
			break;
		}

		pos += 2 + pos[1];
	}

	if (pac_key == NULL) {
		wpa_printf(MSG_DEBUG, "EAP-FAST: No PAC-Key included in "
			   "PAC-Opaque");
		os_free(buf);
		return -1;
	}

	if (identity) {
		wpa_hexdump_ascii(MSG_DEBUG, "EAP-FAST: Identity from "
				  "PAC-Opaque", identity, identity_len);
		os_free(data->identity);
		data->identity = os_malloc(identity_len);
		if (data->identity) {
			os_memcpy(data->identity, identity, identity_len);
			data->identity_len = identity_len;
		}
	}

	if (os_get_time(&now) < 0 || lifetime <= 0 || now.sec > lifetime) {
		wpa_printf(MSG_DEBUG, "EAP-FAST: PAC-Key not valid anymore "
			   "(lifetime=%ld now=%ld)", lifetime, now.sec);
		data->send_new_pac = 2;
		/*
		 * Allow PAC to be used to allow a PAC update with some level
		 * of server authentication (i.e., do not fall back to full TLS
		 * handshake since we cannot be sure that the peer would be
		 * able to validate server certificate now). However, reject
		 * the authentication since the PAC was not valid anymore. Peer
		 * can connect again with the newly provisioned PAC after this.
		 */
	} else if (lifetime - now.sec < data->pac_key_refresh_time) {
		wpa_printf(MSG_DEBUG, "EAP-FAST: PAC-Key soft timeout; send "
			   "an update if authentication succeeds");
		data->send_new_pac = 1;
	}

	eap_fast_derive_master_secret(pac_key, server_random, client_random,
				      master_secret);

	os_free(buf);

	return 1;
}


static void eap_fast_derive_key_auth(struct eap_sm *sm,
				     struct eap_fast_data *data)
{
	u8 *sks;

	/* RFC 4851, Section 5.1:
	 * Extra key material after TLS key_block: session_key_seed[40]
	 */

	sks = eap_fast_derive_key(sm->ssl_ctx, data->ssl.conn, "key expansion",
				  EAP_FAST_SKS_LEN);
	if (sks == NULL) {
		wpa_printf(MSG_DEBUG, "EAP-FAST: Failed to derive "
			   "session_key_seed");
		return;
	}

	/*
	 * RFC 4851, Section 5.2:
	 * S-IMCK[0] = session_key_seed
	 */
	wpa_hexdump_key(MSG_DEBUG,
			"EAP-FAST: session_key_seed (SKS = S-IMCK[0])",
			sks, EAP_FAST_SKS_LEN);
	data->simck_idx = 0;
	os_memcpy(data->simck, sks, EAP_FAST_SIMCK_LEN);
	os_free(sks);
}


static void eap_fast_derive_key_provisioning(struct eap_sm *sm,
					     struct eap_fast_data *data)
{
	os_free(data->key_block_p);
	data->key_block_p = (struct eap_fast_key_block_provisioning *)
		eap_fast_derive_key(sm->ssl_ctx, data->ssl.conn,
				    "key expansion",
				    sizeof(*data->key_block_p));
	if (data->key_block_p == NULL) {
		wpa_printf(MSG_DEBUG, "EAP-FAST: Failed to derive key block");
		return;
	}
	/*
	 * RFC 4851, Section 5.2:
	 * S-IMCK[0] = session_key_seed
	 */
	wpa_hexdump_key(MSG_DEBUG,
			"EAP-FAST: session_key_seed (SKS = S-IMCK[0])",
			data->key_block_p->session_key_seed,
			sizeof(data->key_block_p->session_key_seed));
	data->simck_idx = 0;
	os_memcpy(data->simck, data->key_block_p->session_key_seed,
		  EAP_FAST_SIMCK_LEN);
	wpa_hexdump_key(MSG_DEBUG, "EAP-FAST: server_challenge",
			data->key_block_p->server_challenge,
			sizeof(data->key_block_p->server_challenge));
	wpa_hexdump_key(MSG_DEBUG, "EAP-FAST: client_challenge",
			data->key_block_p->client_challenge,
			sizeof(data->key_block_p->client_challenge));
}


static int eap_fast_get_phase2_key(struct eap_sm *sm,
				   struct eap_fast_data *data,
				   u8 *isk, size_t isk_len)
{
	u8 *key;
	size_t key_len;

	os_memset(isk, 0, isk_len);

	if (data->phase2_method == NULL || data->phase2_priv == NULL) {
		wpa_printf(MSG_DEBUG, "EAP-FAST: Phase 2 method not "
			   "available");
		return -1;
	}

	if (data->phase2_method->getKey == NULL)
		return 0;

	if ((key = data->phase2_method->getKey(sm, data->phase2_priv,
					       &key_len)) == NULL) {
		wpa_printf(MSG_DEBUG, "EAP-FAST: Could not get key material "
			   "from Phase 2");
		return -1;
	}

	if (key_len > isk_len)
		key_len = isk_len;
	if (key_len == 32 &&
	    data->phase2_method->vendor == EAP_VENDOR_IETF &&
	    data->phase2_method->method == EAP_TYPE_MSCHAPV2) {
		/*
		 * EAP-FAST uses reverse order for MS-MPPE keys when deriving
		 * MSK from EAP-MSCHAPv2. Swap the keys here to get the correct
		 * ISK for EAP-FAST cryptobinding.
		 */
		os_memcpy(isk, key + 16, 16);
		os_memcpy(isk + 16, key, 16);
	} else
		os_memcpy(isk, key, key_len);
	os_free(key);

	return 0;
}


static int eap_fast_update_icmk(struct eap_sm *sm, struct eap_fast_data *data)
{
	u8 isk[32], imck[60];

	wpa_printf(MSG_DEBUG, "EAP-FAST: Deriving ICMK[%d] (S-IMCK and CMK)",
		   data->simck_idx + 1);

	/*
	 * RFC 4851, Section 5.2:
	 * IMCK[j] = T-PRF(S-IMCK[j-1], "Inner Methods Compound Keys",
	 *                 MSK[j], 60)
	 * S-IMCK[j] = first 40 octets of IMCK[j]
	 * CMK[j] = last 20 octets of IMCK[j]
	 */

	if (eap_fast_get_phase2_key(sm, data, isk, sizeof(isk)) < 0)
		return -1;
	wpa_hexdump_key(MSG_MSGDUMP, "EAP-FAST: ISK[j]", isk, sizeof(isk));
	sha1_t_prf(data->simck, EAP_FAST_SIMCK_LEN,
		   "Inner Methods Compound Keys",
		   isk, sizeof(isk), imck, sizeof(imck));
	data->simck_idx++;
	os_memcpy(data->simck, imck, EAP_FAST_SIMCK_LEN);
	wpa_hexdump_key(MSG_MSGDUMP, "EAP-FAST: S-IMCK[j]",
			data->simck, EAP_FAST_SIMCK_LEN);
	os_memcpy(data->cmk, imck + EAP_FAST_SIMCK_LEN, EAP_FAST_CMK_LEN);
	wpa_hexdump_key(MSG_MSGDUMP, "EAP-FAST: CMK[j]",
			data->cmk, EAP_FAST_CMK_LEN);

	return 0;
}


static void * eap_fast_init(struct eap_sm *sm)
{
	struct eap_fast_data *data;
	u8 ciphers[5] = {
		TLS_CIPHER_ANON_DH_AES128_SHA,
		TLS_CIPHER_AES128_SHA,
		TLS_CIPHER_RSA_DHE_AES128_SHA,
		TLS_CIPHER_RC4_SHA,
		TLS_CIPHER_NONE
	};

	data = os_zalloc(sizeof(*data));
	if (data == NULL)
		return NULL;
	data->fast_version = EAP_FAST_VERSION;
	data->force_version = -1;
	if (sm->user && sm->user->force_version >= 0) {
		data->force_version = sm->user->force_version;
		wpa_printf(MSG_DEBUG, "EAP-FAST: forcing version %d",
			   data->force_version);
		data->fast_version = data->force_version;
	}
	data->state = START;

	if (eap_server_tls_ssl_init(sm, &data->ssl, 0)) {
		wpa_printf(MSG_INFO, "EAP-FAST: Failed to initialize SSL.");
		eap_fast_reset(sm, data);
		return NULL;
	}

	if (tls_connection_set_cipher_list(sm->ssl_ctx, data->ssl.conn,
					   ciphers) < 0) {
		wpa_printf(MSG_INFO, "EAP-FAST: Failed to set TLS cipher "
			   "suites");
		eap_fast_reset(sm, data);
		return NULL;
	}

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

	if (sm->pac_opaque_encr_key == NULL) {
		wpa_printf(MSG_INFO, "EAP-FAST: No PAC-Opaque encryption key "
			   "configured");
		eap_fast_reset(sm, data);
		return NULL;
	}
	os_memcpy(data->pac_opaque_encr, sm->pac_opaque_encr_key,
		  sizeof(data->pac_opaque_encr));

	if (sm->eap_fast_a_id == NULL) {
		wpa_printf(MSG_INFO, "EAP-FAST: No A-ID configured");
		eap_fast_reset(sm, data);
		return NULL;
	}
	data->srv_id = os_malloc(sm->eap_fast_a_id_len);
	if (data->srv_id == NULL) {
		eap_fast_reset(sm, data);
		return NULL;
	}
	os_memcpy(data->srv_id, sm->eap_fast_a_id, sm->eap_fast_a_id_len);
	data->srv_id_len = sm->eap_fast_a_id_len;

	if (sm->eap_fast_a_id_info == NULL) {
		wpa_printf(MSG_INFO, "EAP-FAST: No A-ID-Info configured");
		eap_fast_reset(sm, data);
		return NULL;
	}
	data->srv_id_info = os_strdup(sm->eap_fast_a_id_info);
	if (data->srv_id_info == NULL) {
		eap_fast_reset(sm, data);
		return NULL;
	}

	/* PAC-Key lifetime in seconds (hard limit) */
	data->pac_key_lifetime = sm->pac_key_lifetime;

	/*
	 * PAC-Key refresh time in seconds (soft limit on remaining hard
	 * limit). The server will generate a new PAC-Key when this number of
	 * seconds (or fewer) of the lifetime remains.
	 */
	data->pac_key_refresh_time = sm->pac_key_refresh_time;

	return data;
}


static void eap_fast_reset(struct eap_sm *sm, void *priv)
{
	struct eap_fast_data *data = priv;
	if (data == NULL)
		return;
	if (data->phase2_priv && data->phase2_method)
		data->phase2_method->reset(sm, data->phase2_priv);
	eap_server_tls_ssl_deinit(sm, &data->ssl);
	os_free(data->srv_id);
	os_free(data->srv_id_info);
	os_free(data->key_block_p);
	wpabuf_free(data->pending_phase2_resp);
	os_free(data->identity);
	os_free(data);
}


static struct wpabuf * eap_fast_build_start(struct eap_sm *sm,
					    struct eap_fast_data *data, u8 id)
{
	struct wpabuf *req;

	req = eap_msg_alloc(EAP_VENDOR_IETF, EAP_TYPE_FAST,
			    1 + sizeof(struct pac_tlv_hdr) + data->srv_id_len,
			    EAP_CODE_REQUEST, id);
	if (req == NULL) {
		wpa_printf(MSG_ERROR, "EAP-FAST: Failed to allocate memory for"
			   " request");
		eap_fast_state(data, FAILURE);
		return NULL;
	}

	wpabuf_put_u8(req, EAP_TLS_FLAGS_START | data->fast_version);

	/* RFC 4851, 4.1.1. Authority ID Data */
	eap_fast_put_tlv(req, PAC_TYPE_A_ID, data->srv_id, data->srv_id_len);

	eap_fast_state(data, PHASE1);

	return req;
}


static int eap_fast_phase1_done(struct eap_sm *sm, struct eap_fast_data *data)
{
	char cipher[64];

	wpa_printf(MSG_DEBUG, "EAP-FAST: Phase1 done, starting Phase2");

	if (tls_get_cipher(sm->ssl_ctx, data->ssl.conn, cipher, sizeof(cipher))
	    < 0) {
		wpa_printf(MSG_DEBUG, "EAP-FAST: Failed to get cipher "
			   "information");
		eap_fast_state(data, FAILURE);
		return -1;
	}
	data->anon_provisioning = os_strstr(cipher, "ADH") != NULL;
		    
	if (data->anon_provisioning) {
		wpa_printf(MSG_DEBUG, "EAP-FAST: Anonymous provisioning");
		eap_fast_derive_key_provisioning(sm, data);
	} else
		eap_fast_derive_key_auth(sm, data);

	eap_fast_state(data, PHASE2_START);

	return 0;
}


static struct wpabuf * eap_fast_build_phase2_req(struct eap_sm *sm,
						 struct eap_fast_data *data,
						 u8 id)
{
	struct wpabuf *req;

	if (data->phase2_priv == NULL) {
		wpa_printf(MSG_DEBUG, "EAP-FAST: Phase 2 method not "
			   "initialized");
		return NULL;
	}
	req = data->phase2_method->buildReq(sm, data->phase2_priv, id);
	if (req == NULL)
		return NULL;

	wpa_hexdump_buf_key(MSG_MSGDUMP, "EAP-FAST: Phase 2 EAP-Request", req);
	return eap_fast_tlv_eap_payload(req);
}


static struct wpabuf * eap_fast_build_crypto_binding(
	struct eap_sm *sm, struct eap_fast_data *data)
{
	struct wpabuf *buf;
	struct eap_tlv_result_tlv *result;
	struct eap_tlv_crypto_binding_tlv *binding;

	buf = wpabuf_alloc(2 * sizeof(*result) + sizeof(*binding));
	if (buf == NULL)
		return NULL;

	if (data->send_new_pac || data->anon_provisioning ||
	    data->phase2_method)
		data->final_result = 0;
	else
		data->final_result = 1;

	if (!data->final_result || data->eap_seq > 1) {
		/* Intermediate-Result */
		wpa_printf(MSG_DEBUG, "EAP-FAST: Add Intermediate-Result TLV "
			   "(status=SUCCESS)");
		result = wpabuf_put(buf, sizeof(*result));
		result->tlv_type = host_to_be16(
			EAP_TLV_TYPE_MANDATORY |
			EAP_TLV_INTERMEDIATE_RESULT_TLV);
		result->length = host_to_be16(2);
		result->status = host_to_be16(EAP_TLV_RESULT_SUCCESS);
	}

	if (data->final_result) {
		/* Result TLV */
		wpa_printf(MSG_DEBUG, "EAP-FAST: Add Result TLV "
			   "(status=SUCCESS)");
		result = wpabuf_put(buf, sizeof(*result));
		result->tlv_type = host_to_be16(EAP_TLV_TYPE_MANDATORY |
						EAP_TLV_RESULT_TLV);
		result->length = host_to_be16(2);
		result->status = host_to_be16(EAP_TLV_RESULT_SUCCESS);
	}

	/* Crypto-Binding TLV */
	binding = wpabuf_put(buf, sizeof(*binding));
	binding->tlv_type = host_to_be16(EAP_TLV_TYPE_MANDATORY |
					 EAP_TLV_CRYPTO_BINDING_TLV);
	binding->length = host_to_be16(sizeof(*binding) -
				       sizeof(struct eap_tlv_hdr));
	binding->version = EAP_FAST_VERSION;
	binding->received_version = data->peer_version;
	binding->subtype = EAP_TLV_CRYPTO_BINDING_SUBTYPE_REQUEST;
	if (random_get_bytes(binding->nonce, sizeof(binding->nonce)) < 0) {
		wpabuf_free(buf);
		return NULL;
	}

	/*
	 * RFC 4851, Section 4.2.8:
	 * The nonce in a request MUST have its least significant bit set to 0.
	 */
	binding->nonce[sizeof(binding->nonce) - 1] &= ~0x01;

	os_memcpy(data->crypto_binding_nonce, binding->nonce,
		  sizeof(binding->nonce));

	/*
	 * RFC 4851, Section 5.3:
	 * CMK = CMK[j]
	 * Compound-MAC = HMAC-SHA1( CMK, Crypto-Binding TLV )
	 */

	hmac_sha1(data->cmk, EAP_FAST_CMK_LEN,
		  (u8 *) binding, sizeof(*binding),
		  binding->compound_mac);

	wpa_printf(MSG_DEBUG, "EAP-FAST: Add Crypto-Binding TLV: Version %d "
		   "Received Version %d SubType %d",
		   binding->version, binding->received_version,
		   binding->subtype);
	wpa_hexdump(MSG_MSGDUMP, "EAP-FAST: NONCE",
		    binding->nonce, sizeof(binding->nonce));
	wpa_hexdump(MSG_MSGDUMP, "EAP-FAST: Compound MAC",
		    binding->compound_mac, sizeof(binding->compound_mac));

	return buf;
}


static struct wpabuf * eap_fast_build_pac(struct eap_sm *sm,
					  struct eap_fast_data *data)
{
	u8 pac_key[EAP_FAST_PAC_KEY_LEN];
	u8 *pac_buf, *pac_opaque;
	struct wpabuf *buf;
	u8 *pos;
	size_t buf_len, srv_id_info_len, pac_len;
	struct eap_tlv_hdr *pac_tlv;
	struct pac_tlv_hdr *pac_info;
	struct eap_tlv_result_tlv *result;
	struct os_time now;

	if (random_get_bytes(pac_key, EAP_FAST_PAC_KEY_LEN) < 0 ||
	    os_get_time(&now) < 0)
		return NULL;
	wpa_hexdump_key(MSG_DEBUG, "EAP-FAST: Generated PAC-Key",
			pac_key, EAP_FAST_PAC_KEY_LEN);

	pac_len = (2 + EAP_FAST_PAC_KEY_LEN) + (2 + 4) +
		(2 + sm->identity_len) + 8;
	pac_buf = os_malloc(pac_len);
	if (pac_buf == NULL)
		return NULL;

	srv_id_info_len = os_strlen(data->srv_id_info);

	pos = pac_buf;
	*pos++ = PAC_OPAQUE_TYPE_KEY;
	*pos++ = EAP_FAST_PAC_KEY_LEN;
	os_memcpy(pos, pac_key, EAP_FAST_PAC_KEY_LEN);
	pos += EAP_FAST_PAC_KEY_LEN;

	*pos++ = PAC_OPAQUE_TYPE_LIFETIME;
	*pos++ = 4;
	WPA_PUT_BE32(pos, now.sec + data->pac_key_lifetime);
	pos += 4;

	if (sm->identity) {
		*pos++ = PAC_OPAQUE_TYPE_IDENTITY;
		*pos++ = sm->identity_len;
		os_memcpy(pos, sm->identity, sm->identity_len);
		pos += sm->identity_len;
	}

	pac_len = pos - pac_buf;
	while (pac_len % 8) {
		*pos++ = PAC_OPAQUE_TYPE_PAD;
		pac_len++;
	}

	pac_opaque = os_malloc(pac_len + 8);
	if (pac_opaque == NULL) {
		os_free(pac_buf);
		return NULL;
	}
	if (aes_wrap(data->pac_opaque_encr, pac_len / 8, pac_buf,
		     pac_opaque) < 0) {
		os_free(pac_buf);
		os_free(pac_opaque);
		return NULL;
	}
	os_free(pac_buf);

	pac_len += 8;
	wpa_hexdump(MSG_DEBUG, "EAP-FAST: PAC-Opaque",
		    pac_opaque, pac_len);

	buf_len = sizeof(*pac_tlv) +
		sizeof(struct pac_tlv_hdr) + EAP_FAST_PAC_KEY_LEN +
		sizeof(struct pac_tlv_hdr) + pac_len +
		data->srv_id_len + srv_id_info_len + 100 + sizeof(*result);
	buf = wpabuf_alloc(buf_len);
	if (buf == NULL) {
		os_free(pac_opaque);
		return NULL;
	}

	/* Result TLV */
	wpa_printf(MSG_DEBUG, "EAP-FAST: Add Result TLV (status=SUCCESS)");
	result = wpabuf_put(buf, sizeof(*result));
	WPA_PUT_BE16((u8 *) &result->tlv_type,
		     EAP_TLV_TYPE_MANDATORY | EAP_TLV_RESULT_TLV);
	WPA_PUT_BE16((u8 *) &result->length, 2);
	WPA_PUT_BE16((u8 *) &result->status, EAP_TLV_RESULT_SUCCESS);

	/* PAC TLV */
	wpa_printf(MSG_DEBUG, "EAP-FAST: Add PAC TLV");
	pac_tlv = wpabuf_put(buf, sizeof(*pac_tlv));
	pac_tlv->tlv_type = host_to_be16(EAP_TLV_TYPE_MANDATORY |
					 EAP_TLV_PAC_TLV);

	/* PAC-Key */
	eap_fast_put_tlv(buf, PAC_TYPE_PAC_KEY, pac_key, EAP_FAST_PAC_KEY_LEN);

	/* PAC-Opaque */
	eap_fast_put_tlv(buf, PAC_TYPE_PAC_OPAQUE, pac_opaque, pac_len);
	os_free(pac_opaque);

	/* PAC-Info */
	pac_info = wpabuf_put(buf, sizeof(*pac_info));
	pac_info->type = host_to_be16(PAC_TYPE_PAC_INFO);

	/* PAC-Lifetime (inside PAC-Info) */
	eap_fast_put_tlv_hdr(buf, PAC_TYPE_CRED_LIFETIME, 4);
	wpabuf_put_be32(buf, now.sec + data->pac_key_lifetime);

	/* A-ID (inside PAC-Info) */
	eap_fast_put_tlv(buf, PAC_TYPE_A_ID, data->srv_id, data->srv_id_len);
	
	/* Note: headers may be misaligned after A-ID */

	if (sm->identity) {
		eap_fast_put_tlv(buf, PAC_TYPE_I_ID, sm->identity,
				 sm->identity_len);
	}

	/* A-ID-Info (inside PAC-Info) */
	eap_fast_put_tlv(buf, PAC_TYPE_A_ID_INFO, data->srv_id_info,
			 srv_id_info_len);

	/* PAC-Type (inside PAC-Info) */
	eap_fast_put_tlv_hdr(buf, PAC_TYPE_PAC_TYPE, 2);
	wpabuf_put_be16(buf, PAC_TYPE_TUNNEL_PAC);

	/* Update PAC-Info and PAC TLV Length fields */
	pos = wpabuf_put(buf, 0);
	pac_info->len = host_to_be16(pos - (u8 *) (pac_info + 1));
	pac_tlv->length = host_to_be16(pos - (u8 *) (pac_tlv + 1));

	return buf;
}


static int eap_fast_encrypt_phase2(struct eap_sm *sm,
				   struct eap_fast_data *data,
				   struct wpabuf *plain, int piggyback)
{
	struct wpabuf *encr;

	wpa_hexdump_buf_key(MSG_DEBUG, "EAP-FAST: Encrypting Phase 2 TLVs",
			    plain);
	encr = eap_server_tls_encrypt(sm, &data->ssl, plain);
	wpabuf_free(plain);

	if (data->ssl.tls_out && piggyback) {
		wpa_printf(MSG_DEBUG, "EAP-FAST: Piggyback Phase 2 data "
			   "(len=%d) with last Phase 1 Message (len=%d "
			   "used=%d)",
			   (int) wpabuf_len(encr),
			   (int) wpabuf_len(data->ssl.tls_out),
			   (int) data->ssl.tls_out_pos);
		if (wpabuf_resize(&data->ssl.tls_out, wpabuf_len(encr)) < 0) {
			wpa_printf(MSG_WARNING, "EAP-FAST: Failed to resize "
				   "output buffer");
			wpabuf_free(encr);
			return -1;
		}
		wpabuf_put_buf(data->ssl.tls_out, encr);
		wpabuf_free(encr);
	} else {
		wpabuf_free(data->ssl.tls_out);
		data->ssl.tls_out_pos = 0;
		data->ssl.tls_out = encr;
	}

	return 0;
}


static struct wpabuf * eap_fast_buildReq(struct eap_sm *sm, void *priv, u8 id)
{
	struct eap_fast_data *data = priv;
	struct wpabuf *req = NULL;
	int piggyback = 0;

	if (data->ssl.state == FRAG_ACK) {
		return eap_server_tls_build_ack(id, EAP_TYPE_FAST,
						data->fast_version);
	}

	if (data->ssl.state == WAIT_FRAG_ACK) {
		return eap_server_tls_build_msg(&data->ssl, EAP_TYPE_FAST,
						data->fast_version, id);
	}

	switch (data->state) {
	case START:
		return eap_fast_build_start(sm, data, id);
	case PHASE1:
		if (tls_connection_established(sm->ssl_ctx, data->ssl.conn)) {
			if (eap_fast_phase1_done(sm, data) < 0)
				return NULL;
			if (data->state == PHASE2_START) {
				/*
				 * Try to generate Phase 2 data to piggyback
				 * with the end of Phase 1 to avoid extra
				 * roundtrip.
				 */
				wpa_printf(MSG_DEBUG, "EAP-FAST: Try to start "
					   "Phase 2");
				if (eap_fast_process_phase2_start(sm, data))
					break;
				req = eap_fast_build_phase2_req(sm, data, id);
				piggyback = 1;
			}
		}
		break;
	case PHASE2_ID:
	case PHASE2_METHOD:
		req = eap_fast_build_phase2_req(sm, data, id);
		break;
	case CRYPTO_BINDING:
		req = eap_fast_build_crypto_binding(sm, data);
		if (data->phase2_method) {
			/*
			 * Include the start of the next EAP method in the
			 * sequence in the same message with Crypto-Binding to
			 * save a round-trip.
			 */
			struct wpabuf *eap;
			eap = eap_fast_build_phase2_req(sm, data, id);
			req = wpabuf_concat(req, eap);
			eap_fast_state(data, PHASE2_METHOD);
		}
		break;
	case REQUEST_PAC:
		req = eap_fast_build_pac(sm, data);
		break;
	default:
		wpa_printf(MSG_DEBUG, "EAP-FAST: %s - unexpected state %d",
			   __func__, data->state);
		return NULL;
	}

	if (req &&
	    eap_fast_encrypt_phase2(sm, data, req, piggyback) < 0)
		return NULL;

	return eap_server_tls_build_msg(&data->ssl, EAP_TYPE_FAST,
					data->fast_version, id);
}


static Boolean eap_fast_check(struct eap_sm *sm, void *priv,
			      struct wpabuf *respData)
{
	const u8 *pos;
	size_t len;

	pos = eap_hdr_validate(EAP_VENDOR_IETF, EAP_TYPE_FAST, respData, &len);
	if (pos == NULL || len < 1) {
		wpa_printf(MSG_INFO, "EAP-FAST: Invalid frame");
		return TRUE;
	}

	return FALSE;
}


static int eap_fast_phase2_init(struct eap_sm *sm, struct eap_fast_data *data,
				EapType eap_type)
{
	if (data->phase2_priv && data->phase2_method) {
		data->phase2_method->reset(sm, data->phase2_priv);
		data->phase2_method = NULL;
		data->phase2_priv = NULL;
	}
	data->phase2_method = eap_server_get_eap_method(EAP_VENDOR_IETF,
							eap_type);
	if (!data->phase2_method)
		return -1;

	if (data->key_block_p) {
		sm->auth_challenge = data->key_block_p->server_challenge;
		sm->peer_challenge = data->key_block_p->client_challenge;
	}
	sm->init_phase2 = 1;
	data->phase2_priv = data->phase2_method->init(sm);
	sm->init_phase2 = 0;
	sm->auth_challenge = NULL;
	sm->peer_challenge = NULL;

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


static void eap_fast_process_phase2_response(struct eap_sm *sm,
					     struct eap_fast_data *data,
					     u8 *in_data, size_t in_len)
{
	u8 next_type = EAP_TYPE_NONE;
	struct eap_hdr *hdr;
	u8 *pos;
	size_t left;
	struct wpabuf buf;
	const struct eap_method *m = data->phase2_method;
	void *priv = data->phase2_priv;

	if (priv == NULL) {
		wpa_printf(MSG_DEBUG, "EAP-FAST: %s - Phase2 not "
			   "initialized?!", __func__);
		return;
	}

	hdr = (struct eap_hdr *) in_data;
	pos = (u8 *) (hdr + 1);

	if (in_len > sizeof(*hdr) && *pos == EAP_TYPE_NAK) {
		left = in_len - sizeof(*hdr);
		wpa_hexdump(MSG_DEBUG, "EAP-FAST: Phase2 type Nak'ed; "
			    "allowed types", pos + 1, left - 1);
#ifdef EAP_SERVER_TNC
		if (m && m->vendor == EAP_VENDOR_IETF &&
		    m->method == EAP_TYPE_TNC) {
			wpa_printf(MSG_DEBUG, "EAP-FAST: Peer Nak'ed required "
				   "TNC negotiation");
			next_type = eap_fast_req_failure(sm, data);
			eap_fast_phase2_init(sm, data, next_type);
			return;
		}
#endif /* EAP_SERVER_TNC */
		eap_sm_process_nak(sm, pos + 1, left - 1);
		if (sm->user && sm->user_eap_method_index < EAP_MAX_METHODS &&
		    sm->user->methods[sm->user_eap_method_index].method !=
		    EAP_TYPE_NONE) {
			next_type = sm->user->methods[
				sm->user_eap_method_index++].method;
			wpa_printf(MSG_DEBUG, "EAP-FAST: try EAP type %d",
				   next_type);
		} else {
			next_type = eap_fast_req_failure(sm, data);
		}
		eap_fast_phase2_init(sm, data, next_type);
		return;
	}

	wpabuf_set(&buf, in_data, in_len);

	if (m->check(sm, priv, &buf)) {
		wpa_printf(MSG_DEBUG, "EAP-FAST: Phase2 check() asked to "
			   "ignore the packet");
		next_type = eap_fast_req_failure(sm, data);
		return;
	}

	m->process(sm, priv, &buf);

	if (!m->isDone(sm, priv))
		return;

	if (!m->isSuccess(sm, priv)) {
		wpa_printf(MSG_DEBUG, "EAP-FAST: Phase2 method failed");
		next_type = eap_fast_req_failure(sm, data);
		eap_fast_phase2_init(sm, data, next_type);
		return;
	}

	switch (data->state) {
	case PHASE2_ID:
		if (eap_user_get(sm, sm->identity, sm->identity_len, 1) != 0) {
			wpa_hexdump_ascii(MSG_DEBUG, "EAP-FAST: Phase2 "
					  "Identity not found in the user "
					  "database",
					  sm->identity, sm->identity_len);
			next_type = eap_fast_req_failure(sm, data);
			break;
		}

		eap_fast_state(data, PHASE2_METHOD);
		if (data->anon_provisioning) {
			/*
			 * Only EAP-MSCHAPv2 is allowed for anonymous
			 * provisioning.
			 */
			next_type = EAP_TYPE_MSCHAPV2;
			sm->user_eap_method_index = 0;
		} else {
			next_type = sm->user->methods[0].method;
			sm->user_eap_method_index = 1;
		}
		wpa_printf(MSG_DEBUG, "EAP-FAST: try EAP type %d", next_type);
		break;
	case PHASE2_METHOD:
	case CRYPTO_BINDING:
		eap_fast_update_icmk(sm, data);
		eap_fast_state(data, CRYPTO_BINDING);
		data->eap_seq++;
		next_type = EAP_TYPE_NONE;
#ifdef EAP_SERVER_TNC
		if (sm->tnc && !data->tnc_started) {
			wpa_printf(MSG_DEBUG, "EAP-FAST: Initialize TNC");
			next_type = EAP_TYPE_TNC;
			data->tnc_started = 1;
		}
#endif /* EAP_SERVER_TNC */
		break;
	case FAILURE:
		break;
	default:
		wpa_printf(MSG_DEBUG, "EAP-FAST: %s - unexpected state %d",
			   __func__, data->state);
		break;
	}

	eap_fast_phase2_init(sm, data, next_type);
}


static void eap_fast_process_phase2_eap(struct eap_sm *sm,
					struct eap_fast_data *data,
					u8 *in_data, size_t in_len)
{
	struct eap_hdr *hdr;
	size_t len;

	hdr = (struct eap_hdr *) in_data;
	if (in_len < (int) sizeof(*hdr)) {
		wpa_printf(MSG_INFO, "EAP-FAST: Too short Phase 2 "
			   "EAP frame (len=%lu)", (unsigned long) in_len);
		eap_fast_req_failure(sm, data);
		return;
	}
	len = be_to_host16(hdr->length);
	if (len > in_len) {
		wpa_printf(MSG_INFO, "EAP-FAST: Length mismatch in "
			   "Phase 2 EAP frame (len=%lu hdr->length=%lu)",
			   (unsigned long) in_len, (unsigned long) len);
		eap_fast_req_failure(sm, data);
		return;
	}
	wpa_printf(MSG_DEBUG, "EAP-FAST: Received Phase 2: code=%d "
		   "identifier=%d length=%lu", hdr->code, hdr->identifier,
		   (unsigned long) len);
	switch (hdr->code) {
	case EAP_CODE_RESPONSE:
		eap_fast_process_phase2_response(sm, data, (u8 *) hdr, len);
		break;
	default:
		wpa_printf(MSG_INFO, "EAP-FAST: Unexpected code=%d in "
			   "Phase 2 EAP header", hdr->code);
		break;
	}
}


static int eap_fast_parse_tlvs(struct wpabuf *data,
			       struct eap_fast_tlv_parse *tlv)
{
	int mandatory, tlv_type, len, res;
	u8 *pos, *end;

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

	pos = wpabuf_mhead(data);
	end = pos + wpabuf_len(data);
	while (pos + 4 < end) {
		mandatory = pos[0] & 0x80;
		tlv_type = WPA_GET_BE16(pos) & 0x3fff;
		pos += 2;
		len = WPA_GET_BE16(pos);
		pos += 2;
		if (pos + len > end) {
			wpa_printf(MSG_INFO, "EAP-FAST: TLV overflow");
			return -1;
		}
		wpa_printf(MSG_DEBUG, "EAP-FAST: Received Phase 2: "
			   "TLV type %d length %d%s",
			   tlv_type, len, mandatory ? " (mandatory)" : "");

		res = eap_fast_parse_tlv(tlv, tlv_type, pos, len);
		if (res == -2)
			break;
		if (res < 0) {
			if (mandatory) {
				wpa_printf(MSG_DEBUG, "EAP-FAST: Nak unknown "
					   "mandatory TLV type %d", tlv_type);
				/* TODO: generate Nak TLV */
				break;
			} else {
				wpa_printf(MSG_DEBUG, "EAP-FAST: Ignored "
					   "unknown optional TLV type %d",
					   tlv_type);
			}
		}

		pos += len;
	}

	return 0;
}


static int eap_fast_validate_crypto_binding(
	struct eap_fast_data *data, struct eap_tlv_crypto_binding_tlv *b,
	size_t bind_len)
{
	u8 cmac[SHA1_MAC_LEN];

	wpa_printf(MSG_DEBUG, "EAP-FAST: Reply Crypto-Binding TLV: "
		   "Version %d Received Version %d SubType %d",
		   b->version, b->received_version, b->subtype);
	wpa_hexdump(MSG_MSGDUMP, "EAP-FAST: NONCE",
		    b->nonce, sizeof(b->nonce));
	wpa_hexdump(MSG_MSGDUMP, "EAP-FAST: Compound MAC",
		    b->compound_mac, sizeof(b->compound_mac));

	if (b->version != EAP_FAST_VERSION ||
	    b->received_version != EAP_FAST_VERSION) {
		wpa_printf(MSG_DEBUG, "EAP-FAST: Unexpected version "
			   "in Crypto-Binding: version %d "
			   "received_version %d", b->version,
			   b->received_version);
		return -1;
	}

	if (b->subtype != EAP_TLV_CRYPTO_BINDING_SUBTYPE_RESPONSE) {
		wpa_printf(MSG_DEBUG, "EAP-FAST: Unexpected subtype in "
			   "Crypto-Binding: %d", b->subtype);
		return -1;
	}

	if (os_memcmp(data->crypto_binding_nonce, b->nonce, 31) != 0 ||
	    (data->crypto_binding_nonce[31] | 1) != b->nonce[31]) {
		wpa_printf(MSG_DEBUG, "EAP-FAST: Invalid nonce in "
			   "Crypto-Binding");
		return -1;
	}

	os_memcpy(cmac, b->compound_mac, sizeof(cmac));
	os_memset(b->compound_mac, 0, sizeof(cmac));
	wpa_hexdump(MSG_MSGDUMP, "EAP-FAST: Crypto-Binding TLV for "
		    "Compound MAC calculation",
		    (u8 *) b, bind_len);
	hmac_sha1(data->cmk, EAP_FAST_CMK_LEN, (u8 *) b, bind_len,
		  b->compound_mac);
	if (os_memcmp(cmac, b->compound_mac, sizeof(cmac)) != 0) {
		wpa_hexdump(MSG_MSGDUMP,
			    "EAP-FAST: Calculated Compound MAC",
			    b->compound_mac, sizeof(cmac));
		wpa_printf(MSG_INFO, "EAP-FAST: Compound MAC did not "
			   "match");
		return -1;
	}

	return 0;
}


static int eap_fast_pac_type(u8 *pac, size_t len, u16 type)
{
	struct eap_tlv_pac_type_tlv *tlv;

	if (pac == NULL || len != sizeof(*tlv))
		return 0;

	tlv = (struct eap_tlv_pac_type_tlv *) pac;

	return be_to_host16(tlv->tlv_type) == PAC_TYPE_PAC_TYPE &&
		be_to_host16(tlv->length) == 2 &&
		be_to_host16(tlv->pac_type) == type;
}


static void eap_fast_process_phase2_tlvs(struct eap_sm *sm,
					 struct eap_fast_data *data,
					 struct wpabuf *in_data)
{
	struct eap_fast_tlv_parse tlv;
	int check_crypto_binding = data->state == CRYPTO_BINDING;

	if (eap_fast_parse_tlvs(in_data, &tlv) < 0) {
		wpa_printf(MSG_DEBUG, "EAP-FAST: Failed to parse received "
			   "Phase 2 TLVs");
		return;
	}

	if (tlv.result == EAP_TLV_RESULT_FAILURE) {
		wpa_printf(MSG_DEBUG, "EAP-FAST: Result TLV indicated "
			   "failure");
		eap_fast_state(data, FAILURE);
		return;
	}

	if (data->state == REQUEST_PAC) {
		u16 type, len, res;
		if (tlv.pac == NULL || tlv.pac_len < 6) {
			wpa_printf(MSG_DEBUG, "EAP-FAST: No PAC "
				   "Acknowledgement received");
			eap_fast_state(data, FAILURE);
			return;
		}

		type = WPA_GET_BE16(tlv.pac);
		len = WPA_GET_BE16(tlv.pac + 2);
		res = WPA_GET_BE16(tlv.pac + 4);

		if (type != PAC_TYPE_PAC_ACKNOWLEDGEMENT || len != 2 ||
		    res != EAP_TLV_RESULT_SUCCESS) {
			wpa_printf(MSG_DEBUG, "EAP-FAST: PAC TLV did not "
				   "contain acknowledgement");
			eap_fast_state(data, FAILURE);
			return;
		}

		wpa_printf(MSG_DEBUG, "EAP-FAST: PAC-Acknowledgement received "
			   "- PAC provisioning succeeded");
		eap_fast_state(data, (data->anon_provisioning ||
				      data->send_new_pac == 2) ?
			       FAILURE : SUCCESS);
		return;
	}

	if (check_crypto_binding) {
		if (tlv.crypto_binding == NULL) {
			wpa_printf(MSG_DEBUG, "EAP-FAST: No Crypto-Binding "
				   "TLV received");
			eap_fast_state(data, FAILURE);
			return;
		}

		if (data->final_result &&
		    tlv.result != EAP_TLV_RESULT_SUCCESS) {
			wpa_printf(MSG_DEBUG, "EAP-FAST: Crypto-Binding TLV "
				   "without Success Result");
			eap_fast_state(data, FAILURE);
			return;
		}

		if (!data->final_result &&
		    tlv.iresult != EAP_TLV_RESULT_SUCCESS) {
			wpa_printf(MSG_DEBUG, "EAP-FAST: Crypto-Binding TLV "
				   "without intermediate Success Result");
			eap_fast_state(data, FAILURE);
			return;
		}

		if (eap_fast_validate_crypto_binding(data, tlv.crypto_binding,
						     tlv.crypto_binding_len)) {
			eap_fast_state(data, FAILURE);
			return;
		}

		wpa_printf(MSG_DEBUG, "EAP-FAST: Valid Crypto-Binding TLV "
			   "received");
		if (data->final_result) {
			wpa_printf(MSG_DEBUG, "EAP-FAST: Authentication "
				   "completed successfully");
		}

		if (data->anon_provisioning &&
		    sm->eap_fast_prov != ANON_PROV &&
		    sm->eap_fast_prov != BOTH_PROV) {
			wpa_printf(MSG_DEBUG, "EAP-FAST: Client is trying to "
				   "use unauthenticated provisioning which is "
				   "disabled");
			eap_fast_state(data, FAILURE);
			return;
		}

		if (sm->eap_fast_prov != AUTH_PROV &&
		    sm->eap_fast_prov != BOTH_PROV &&
		    tlv.request_action == EAP_TLV_ACTION_PROCESS_TLV &&
		    eap_fast_pac_type(tlv.pac, tlv.pac_len,
				      PAC_TYPE_TUNNEL_PAC)) {
			wpa_printf(MSG_DEBUG, "EAP-FAST: Client is trying to "
				   "use authenticated provisioning which is "
				   "disabled");
			eap_fast_state(data, FAILURE);
			return;
		}

		if (data->anon_provisioning ||
		    (tlv.request_action == EAP_TLV_ACTION_PROCESS_TLV &&
		     eap_fast_pac_type(tlv.pac, tlv.pac_len,
				       PAC_TYPE_TUNNEL_PAC))) {
			wpa_printf(MSG_DEBUG, "EAP-FAST: Requested a new "
				   "Tunnel PAC");
			eap_fast_state(data, REQUEST_PAC);
		} else if (data->send_new_pac) {
			wpa_printf(MSG_DEBUG, "EAP-FAST: Server triggered "
				   "re-keying of Tunnel PAC");
			eap_fast_state(data, REQUEST_PAC);
		} else if (data->final_result)
			eap_fast_state(data, SUCCESS);
	}

	if (tlv.eap_payload_tlv) {
		eap_fast_process_phase2_eap(sm, data, tlv.eap_payload_tlv,
					    tlv.eap_payload_tlv_len);
	}
}


static void eap_fast_process_phase2(struct eap_sm *sm,
				    struct eap_fast_data *data,
				    struct wpabuf *in_buf)
{
	struct wpabuf *in_decrypted;

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

	if (data->pending_phase2_resp) {
		wpa_printf(MSG_DEBUG, "EAP-PEAP: Pending Phase 2 response - "
			   "skip decryption and use old data");
		eap_fast_process_phase2_tlvs(sm, data,
					     data->pending_phase2_resp);
		wpabuf_free(data->pending_phase2_resp);
		data->pending_phase2_resp = NULL;
		return;
	}

	in_decrypted = tls_connection_decrypt(sm->ssl_ctx, data->ssl.conn,
					      in_buf);
	if (in_decrypted == NULL) {
		wpa_printf(MSG_INFO, "EAP-FAST: Failed to decrypt Phase 2 "
			   "data");
		eap_fast_state(data, FAILURE);
		return;
	}

	wpa_hexdump_buf_key(MSG_DEBUG, "EAP-FAST: Decrypted Phase 2 TLVs",
			    in_decrypted);

	eap_fast_process_phase2_tlvs(sm, data, in_decrypted);

	if (sm->method_pending == METHOD_PENDING_WAIT) {
		wpa_printf(MSG_DEBUG, "EAP-FAST: Phase2 method is in "
			   "pending wait state - save decrypted response");
		wpabuf_free(data->pending_phase2_resp);
		data->pending_phase2_resp = in_decrypted;
		return;
	}

	wpabuf_free(in_decrypted);
}


static int eap_fast_process_version(struct eap_sm *sm, void *priv,
				    int peer_version)
{
	struct eap_fast_data *data = priv;

	data->peer_version = peer_version;

	if (data->force_version >= 0 && peer_version != data->force_version) {
		wpa_printf(MSG_INFO, "EAP-FAST: peer did not select the forced"
			   " version (forced=%d peer=%d) - reject",
			   data->force_version, peer_version);
		return -1;
	}

	if (peer_version < data->fast_version) {
		wpa_printf(MSG_DEBUG, "EAP-FAST: peer ver=%d, own ver=%d; "
			   "use version %d",
			   peer_version, data->fast_version, peer_version);
		data->fast_version = peer_version;
	}

	return 0;
}


static int eap_fast_process_phase1(struct eap_sm *sm,
				   struct eap_fast_data *data)
{
	if (eap_server_tls_phase1(sm, &data->ssl) < 0) {
		wpa_printf(MSG_INFO, "EAP-FAST: TLS processing failed");
		eap_fast_state(data, FAILURE);
		return -1;
	}

	if (!tls_connection_established(sm->ssl_ctx, data->ssl.conn) ||
	    wpabuf_len(data->ssl.tls_out) > 0)
		return 1;

	/*
	 * Phase 1 was completed with the received message (e.g., when using
	 * abbreviated handshake), so Phase 2 can be started immediately
	 * without having to send through an empty message to the peer.
	 */

	return eap_fast_phase1_done(sm, data);
}


static int eap_fast_process_phase2_start(struct eap_sm *sm,
					 struct eap_fast_data *data)
{
	u8 next_type;

	if (data->identity) {
		os_free(sm->identity);
		sm->identity = data->identity;
		data->identity = NULL;
		sm->identity_len = data->identity_len;
		data->identity_len = 0;
		sm->require_identity_match = 1;
		if (eap_user_get(sm, sm->identity, sm->identity_len, 1) != 0) {
			wpa_hexdump_ascii(MSG_DEBUG, "EAP-FAST: "
					  "Phase2 Identity not found "
					  "in the user database",
					  sm->identity, sm->identity_len);
			next_type = eap_fast_req_failure(sm, data);
		} else {
			wpa_printf(MSG_DEBUG, "EAP-FAST: Identity already "
				   "known - skip Phase 2 Identity Request");
			next_type = sm->user->methods[0].method;
			sm->user_eap_method_index = 1;
		}

		eap_fast_state(data, PHASE2_METHOD);
	} else {
		eap_fast_state(data, PHASE2_ID);
		next_type = EAP_TYPE_IDENTITY;
	}

	return eap_fast_phase2_init(sm, data, next_type);
}


static void eap_fast_process_msg(struct eap_sm *sm, void *priv,
				 const struct wpabuf *respData)
{
	struct eap_fast_data *data = priv;

	switch (data->state) {
	case PHASE1:
		if (eap_fast_process_phase1(sm, data))
			break;

		/* fall through to PHASE2_START */
	case PHASE2_START:
		eap_fast_process_phase2_start(sm, data);
		break;
	case PHASE2_ID:
	case PHASE2_METHOD:
	case CRYPTO_BINDING:
	case REQUEST_PAC:
		eap_fast_process_phase2(sm, data, data->ssl.tls_in);
		break;
	default:
		wpa_printf(MSG_DEBUG, "EAP-FAST: Unexpected state %d in %s",
			   data->state, __func__);
		break;
	}
}


static void eap_fast_process(struct eap_sm *sm, void *priv,
			     struct wpabuf *respData)
{
	struct eap_fast_data *data = priv;
	if (eap_server_tls_process(sm, &data->ssl, respData, data,
				   EAP_TYPE_FAST, eap_fast_process_version,
				   eap_fast_process_msg) < 0)
		eap_fast_state(data, FAILURE);
}


static Boolean eap_fast_isDone(struct eap_sm *sm, void *priv)
{
	struct eap_fast_data *data = priv;
	return data->state == SUCCESS || data->state == FAILURE;
}


static u8 * eap_fast_getKey(struct eap_sm *sm, void *priv, size_t *len)
{
	struct eap_fast_data *data = priv;
	u8 *eapKeyData;

	if (data->state != SUCCESS)
		return NULL;

	eapKeyData = os_malloc(EAP_FAST_KEY_LEN);
	if (eapKeyData == NULL)
		return NULL;

	eap_fast_derive_eap_msk(data->simck, eapKeyData);
	*len = EAP_FAST_KEY_LEN;

	return eapKeyData;
}


static u8 * eap_fast_get_emsk(struct eap_sm *sm, void *priv, size_t *len)
{
	struct eap_fast_data *data = priv;
	u8 *eapKeyData;

	if (data->state != SUCCESS)
		return NULL;

	eapKeyData = os_malloc(EAP_EMSK_LEN);
	if (eapKeyData == NULL)
		return NULL;

	eap_fast_derive_eap_emsk(data->simck, eapKeyData);
	*len = EAP_EMSK_LEN;

	return eapKeyData;
}


static Boolean eap_fast_isSuccess(struct eap_sm *sm, void *priv)
{
	struct eap_fast_data *data = priv;
	return data->state == SUCCESS;
}


int eap_server_fast_register(void)
{
	struct eap_method *eap;
	int ret;

	eap = eap_server_method_alloc(EAP_SERVER_METHOD_INTERFACE_VERSION,
				      EAP_VENDOR_IETF, EAP_TYPE_FAST, "FAST");
	if (eap == NULL)
		return -1;

	eap->init = eap_fast_init;
	eap->reset = eap_fast_reset;
	eap->buildReq = eap_fast_buildReq;
	eap->check = eap_fast_check;
	eap->process = eap_fast_process;
	eap->isDone = eap_fast_isDone;
	eap->getKey = eap_fast_getKey;
	eap->get_emsk = eap_fast_get_emsk;
	eap->isSuccess = eap_fast_isSuccess;

	ret = eap_server_method_register(eap);
	if (ret)
		eap_server_method_free(eap);
	return ret;
}
