/*
 * EAP-IKEv2 peer (RFC 5106)
 * Copyright (c) 2007-2014, 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 "eap_i.h"
#include "eap_common/eap_ikev2_common.h"
#include "ikev2.h"


struct eap_ikev2_data {
	struct ikev2_responder_data ikev2;
	enum { WAIT_START, PROC_MSG, WAIT_FRAG_ACK, DONE, FAIL } state;
	struct wpabuf *in_buf;
	struct wpabuf *out_buf;
	size_t out_used;
	size_t fragment_size;
	int keys_ready;
	u8 keymat[EAP_MSK_LEN + EAP_EMSK_LEN];
	int keymat_ok;
};


static const char * eap_ikev2_state_txt(int state)
{
	switch (state) {
	case WAIT_START:
		return "WAIT_START";
	case PROC_MSG:
		return "PROC_MSG";
	case WAIT_FRAG_ACK:
		return "WAIT_FRAG_ACK";
	case DONE:
		return "DONE";
	case FAIL:
		return "FAIL";
	default:
		return "?";
	}
}


static void eap_ikev2_state(struct eap_ikev2_data *data, int state)
{
	wpa_printf(MSG_DEBUG, "EAP-IKEV2: %s -> %s",
		   eap_ikev2_state_txt(data->state),
		   eap_ikev2_state_txt(state));
	data->state = state;
}


static void * eap_ikev2_init(struct eap_sm *sm)
{
	struct eap_ikev2_data *data;
	const u8 *identity, *password;
	size_t identity_len, password_len;
	int fragment_size;

	identity = eap_get_config_identity(sm, &identity_len);
	if (identity == NULL) {
		wpa_printf(MSG_INFO, "EAP-IKEV2: No identity available");
		return NULL;
	}

	data = os_zalloc(sizeof(*data));
	if (data == NULL)
		return NULL;
	data->state = WAIT_START;
	fragment_size = eap_get_config_fragment_size(sm);
	if (fragment_size <= 0)
		data->fragment_size = IKEV2_FRAGMENT_SIZE;
	else
		data->fragment_size = fragment_size;
	data->ikev2.state = SA_INIT;
	data->ikev2.peer_auth = PEER_AUTH_SECRET;
	data->ikev2.key_pad = (u8 *) os_strdup("Key Pad for EAP-IKEv2");
	if (data->ikev2.key_pad == NULL)
		goto failed;
	data->ikev2.key_pad_len = 21;
	data->ikev2.IDr = os_memdup(identity, identity_len);
	if (data->ikev2.IDr == NULL)
		goto failed;
	data->ikev2.IDr_len = identity_len;

	password = eap_get_config_password(sm, &password_len);
	if (password) {
		data->ikev2.shared_secret = os_memdup(password, password_len);
		if (data->ikev2.shared_secret == NULL)
			goto failed;
		data->ikev2.shared_secret_len = password_len;
	}

	return data;

failed:
	ikev2_responder_deinit(&data->ikev2);
	os_free(data);
	return NULL;
}


static void eap_ikev2_deinit(struct eap_sm *sm, void *priv)
{
	struct eap_ikev2_data *data = priv;
	wpabuf_free(data->in_buf);
	wpabuf_free(data->out_buf);
	ikev2_responder_deinit(&data->ikev2);
	bin_clear_free(data, sizeof(*data));
}


static int eap_ikev2_peer_keymat(struct eap_ikev2_data *data)
{
	if (eap_ikev2_derive_keymat(
		    data->ikev2.proposal.prf, &data->ikev2.keys,
		    data->ikev2.i_nonce, data->ikev2.i_nonce_len,
		    data->ikev2.r_nonce, data->ikev2.r_nonce_len,
		    data->keymat) < 0) {
		wpa_printf(MSG_DEBUG, "EAP-IKEV2: Failed to "
			   "derive key material");
		return -1;
	}
	data->keymat_ok = 1;
	return 0;
}


static struct wpabuf * eap_ikev2_build_msg(struct eap_ikev2_data *data,
					   struct eap_method_ret *ret, u8 id)
{
	struct wpabuf *resp;
	u8 flags;
	size_t send_len, plen, icv_len = 0;

	ret->ignore = false;
	wpa_printf(MSG_DEBUG, "EAP-IKEV2: Generating Response");
	ret->allowNotifications = true;

	flags = 0;
	send_len = wpabuf_len(data->out_buf) - data->out_used;
	if (1 + send_len > data->fragment_size) {
		send_len = data->fragment_size - 1;
		flags |= IKEV2_FLAGS_MORE_FRAGMENTS;
		if (data->out_used == 0) {
			flags |= IKEV2_FLAGS_LENGTH_INCLUDED;
			send_len -= 4;
		}
	}

	plen = 1 + send_len;
	if (flags & IKEV2_FLAGS_LENGTH_INCLUDED)
		plen += 4;
	if (data->keys_ready) {
		const struct ikev2_integ_alg *integ;
		wpa_printf(MSG_DEBUG, "EAP-IKEV2: Add Integrity Checksum "
			   "Data");
		flags |= IKEV2_FLAGS_ICV_INCLUDED;
		integ = ikev2_get_integ(data->ikev2.proposal.integ);
		if (integ == NULL) {
			wpa_printf(MSG_DEBUG, "EAP-IKEV2: Unknown INTEG "
				   "transform / cannot generate ICV");
			return NULL;
		}
		icv_len = integ->hash_len;

		plen += icv_len;
	}
	resp = eap_msg_alloc(EAP_VENDOR_IETF, EAP_TYPE_IKEV2, plen,
			     EAP_CODE_RESPONSE, id);
	if (resp == NULL)
		return NULL;

	wpabuf_put_u8(resp, flags); /* Flags */
	if (flags & IKEV2_FLAGS_LENGTH_INCLUDED)
		wpabuf_put_be32(resp, wpabuf_len(data->out_buf));

	wpabuf_put_data(resp, wpabuf_head_u8(data->out_buf) + data->out_used,
			send_len);
	data->out_used += send_len;

	if (flags & IKEV2_FLAGS_ICV_INCLUDED) {
		const u8 *msg = wpabuf_head(resp);
		size_t len = wpabuf_len(resp);
		ikev2_integ_hash(data->ikev2.proposal.integ,
				 data->ikev2.keys.SK_ar,
				 data->ikev2.keys.SK_integ_len,
				 msg, len, wpabuf_put(resp, icv_len));
	}

	ret->methodState = METHOD_MAY_CONT;
	ret->decision = DECISION_FAIL;

	if (data->out_used == wpabuf_len(data->out_buf)) {
		wpa_printf(MSG_DEBUG, "EAP-IKEV2: Sending out %lu bytes "
			   "(message sent completely)",
			   (unsigned long) send_len);
		wpabuf_free(data->out_buf);
		data->out_buf = NULL;
		data->out_used = 0;
		switch (data->ikev2.state) {
		case SA_AUTH:
			/* SA_INIT was sent out, so message have to be
			 * integrity protected from now on. */
			data->keys_ready = 1;
			break;
		case IKEV2_DONE:
			ret->methodState = METHOD_DONE;
			if (data->state == FAIL)
				break;
			ret->decision = DECISION_COND_SUCC;
			wpa_printf(MSG_DEBUG, "EAP-IKEV2: Authentication "
				   "completed successfully");
			if (eap_ikev2_peer_keymat(data))
				break;
			eap_ikev2_state(data, DONE);
			break;
		case IKEV2_FAILED:
			wpa_printf(MSG_DEBUG, "EAP-IKEV2: Authentication "
				   "failed");
			ret->methodState = METHOD_DONE;
			ret->decision = DECISION_FAIL;
			break;
		default:
			break;
		}
	} else {
		wpa_printf(MSG_DEBUG, "EAP-IKEV2: Sending out %lu bytes "
			   "(%lu more to send)", (unsigned long) send_len,
			   (unsigned long) wpabuf_len(data->out_buf) -
			   data->out_used);
		eap_ikev2_state(data, WAIT_FRAG_ACK);
	}

	return resp;
}


static int eap_ikev2_process_icv(struct eap_ikev2_data *data,
				 const struct wpabuf *reqData,
				 u8 flags, const u8 *pos, const u8 **end,
				 int frag_ack)
{
	if (flags & IKEV2_FLAGS_ICV_INCLUDED) {
		int icv_len = eap_ikev2_validate_icv(
			data->ikev2.proposal.integ, &data->ikev2.keys, 1,
			reqData, pos, *end);
		if (icv_len < 0)
			return -1;
		/* Hide Integrity Checksum Data from further processing */
		*end -= icv_len;
	} else if (data->keys_ready && !frag_ack) {
		wpa_printf(MSG_INFO, "EAP-IKEV2: The message should have "
			   "included integrity checksum");
		return -1;
	}

	return 0;
}


static int eap_ikev2_process_cont(struct eap_ikev2_data *data,
				  const u8 *buf, size_t len)
{
	/* Process continuation of a pending message */
	if (len > wpabuf_tailroom(data->in_buf)) {
		wpa_printf(MSG_DEBUG, "EAP-IKEV2: Fragment overflow");
		eap_ikev2_state(data, FAIL);
		return -1;
	}

	wpabuf_put_data(data->in_buf, buf, len);
	wpa_printf(MSG_DEBUG, "EAP-IKEV2: Received %lu bytes, waiting "
		   "for %lu bytes more", (unsigned long) len,
		   (unsigned long) wpabuf_tailroom(data->in_buf));

	return 0;
}


static struct wpabuf * eap_ikev2_process_fragment(struct eap_ikev2_data *data,
						  struct eap_method_ret *ret,
						  u8 id, u8 flags,
						  u32 message_length,
						  const u8 *buf, size_t len)
{
	/* Process a fragment that is not the last one of the message */
	if (data->in_buf == NULL && !(flags & IKEV2_FLAGS_LENGTH_INCLUDED)) {
		wpa_printf(MSG_DEBUG, "EAP-IKEV2: No Message Length field in "
			   "a fragmented packet");
		ret->ignore = true;
		return NULL;
	}

	if (data->in_buf == NULL) {
		/* First fragment of the message */
		if (message_length > 50000) {
			/* Limit maximum memory allocation */
			wpa_printf(MSG_DEBUG,
				   "EAP-IKEV2: Ignore too long message");
			ret->ignore = true;
			return NULL;
		}
		data->in_buf = wpabuf_alloc(message_length);
		if (data->in_buf == NULL) {
			wpa_printf(MSG_DEBUG, "EAP-IKEV2: No memory for "
				   "message");
			ret->ignore = true;
			return NULL;
		}
		wpabuf_put_data(data->in_buf, buf, len);
		wpa_printf(MSG_DEBUG, "EAP-IKEV2: Received %lu bytes in first "
			   "fragment, waiting for %lu bytes more",
			   (unsigned long) len,
			   (unsigned long) wpabuf_tailroom(data->in_buf));
	}

	ret->ignore = false;
	return eap_ikev2_build_frag_ack(id, EAP_CODE_RESPONSE);
}


static struct wpabuf * eap_ikev2_process(struct eap_sm *sm, void *priv,
					 struct eap_method_ret *ret,
					 const struct wpabuf *reqData)
{
	struct eap_ikev2_data *data = priv;
	const u8 *start, *pos, *end;
	size_t len;
	u8 flags, id;
	u32 message_length = 0;
	struct wpabuf tmpbuf;

	pos = eap_hdr_validate(EAP_VENDOR_IETF, EAP_TYPE_IKEV2, reqData, &len);
	if (pos == NULL) {
		ret->ignore = true;
		return NULL;
	}

	id = eap_get_id(reqData);

	start = pos;
	end = start + len;

	if (len == 0)
		flags = 0; /* fragment ack */
	else
		flags = *pos++;

	if (eap_ikev2_process_icv(data, reqData, flags, pos, &end,
				  data->state == WAIT_FRAG_ACK && len == 0) < 0)
	{
		ret->ignore = true;
		return NULL;
	}

	if (flags & IKEV2_FLAGS_LENGTH_INCLUDED) {
		if (end - pos < 4) {
			wpa_printf(MSG_DEBUG, "EAP-IKEV2: Message underflow");
			ret->ignore = true;
			return NULL;
		}
		message_length = WPA_GET_BE32(pos);
		pos += 4;

		if (message_length < (u32) (end - pos)) {
			wpa_printf(MSG_DEBUG, "EAP-IKEV2: Invalid Message "
				   "Length (%d; %ld remaining in this msg)",
				   message_length, (long) (end - pos));
			ret->ignore = true;
			return NULL;
		}
	}

	wpa_printf(MSG_DEBUG, "EAP-IKEV2: Received packet: Flags 0x%x "
		   "Message Length %u", flags, message_length);

	if (data->state == WAIT_FRAG_ACK) {
		if (len != 0) {
			wpa_printf(MSG_DEBUG, "EAP-IKEV2: Unexpected payload "
				   "in WAIT_FRAG_ACK state");
			ret->ignore = true;
			return NULL;
		}
		wpa_printf(MSG_DEBUG, "EAP-IKEV2: Fragment acknowledged");
		eap_ikev2_state(data, PROC_MSG);
		return eap_ikev2_build_msg(data, ret, id);
	}

	if (data->in_buf && eap_ikev2_process_cont(data, pos, end - pos) < 0) {
		ret->ignore = true;
		return NULL;
	}

	if (flags & IKEV2_FLAGS_MORE_FRAGMENTS) {
		return eap_ikev2_process_fragment(data, ret, id, flags,
						  message_length, pos,
						  end - pos);
	}

	if (data->in_buf == NULL) {
		/* Wrap unfragmented messages as wpabuf without extra copy */
		wpabuf_set(&tmpbuf, pos, end - pos);
		data->in_buf = &tmpbuf;
	}

	if (ikev2_responder_process(&data->ikev2, data->in_buf) < 0) {
		if (data->in_buf == &tmpbuf)
			data->in_buf = NULL;
		eap_ikev2_state(data, FAIL);
		return NULL;
	}

	if (data->in_buf != &tmpbuf)
		wpabuf_free(data->in_buf);
	data->in_buf = NULL;

	if (data->out_buf == NULL) {
		data->out_buf = ikev2_responder_build(&data->ikev2);
		if (data->out_buf == NULL) {
			wpa_printf(MSG_DEBUG, "EAP-IKEV2: Failed to generate "
				   "IKEv2 message");
			return NULL;
		}
		data->out_used = 0;
	}

	eap_ikev2_state(data, PROC_MSG);
	return eap_ikev2_build_msg(data, ret, id);
}


static bool eap_ikev2_isKeyAvailable(struct eap_sm *sm, void *priv)
{
	struct eap_ikev2_data *data = priv;
	return data->state == DONE && data->keymat_ok;
}


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

	if (data->state != DONE || !data->keymat_ok)
		return NULL;

	key = os_malloc(EAP_MSK_LEN);
	if (key) {
		os_memcpy(key, data->keymat, EAP_MSK_LEN);
		*len = EAP_MSK_LEN;
	}

	return key;
}


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

	if (data->state != DONE || !data->keymat_ok)
		return NULL;

	key = os_malloc(EAP_EMSK_LEN);
	if (key) {
		os_memcpy(key, data->keymat + EAP_MSK_LEN, EAP_EMSK_LEN);
		*len = EAP_EMSK_LEN;
	}

	return key;
}


static u8 * eap_ikev2_get_session_id(struct eap_sm *sm, void *priv, size_t *len)
{
	struct eap_ikev2_data *data = priv;
	u8 *sid;
	size_t sid_len;
	size_t offset;

	if (data->state != DONE || !data->keymat_ok)
		return NULL;

	sid_len = 1 + data->ikev2.i_nonce_len + data->ikev2.r_nonce_len;
	sid = os_malloc(sid_len);
	if (sid) {
		offset = 0;
		sid[offset] = EAP_TYPE_IKEV2;
		offset++;
		os_memcpy(sid + offset, data->ikev2.i_nonce,
			  data->ikev2.i_nonce_len);
		offset += data->ikev2.i_nonce_len;
		os_memcpy(sid + offset, data->ikev2.r_nonce,
			  data->ikev2.r_nonce_len);
		*len = sid_len;
		wpa_hexdump(MSG_DEBUG, "EAP-IKEV2: Derived Session-Id",
			    sid, sid_len);
	}

	return sid;
}


int eap_peer_ikev2_register(void)
{
	struct eap_method *eap;

	eap = eap_peer_method_alloc(EAP_PEER_METHOD_INTERFACE_VERSION,
				    EAP_VENDOR_IETF, EAP_TYPE_IKEV2,
				    "IKEV2");
	if (eap == NULL)
		return -1;

	eap->init = eap_ikev2_init;
	eap->deinit = eap_ikev2_deinit;
	eap->process = eap_ikev2_process;
	eap->isKeyAvailable = eap_ikev2_isKeyAvailable;
	eap->getKey = eap_ikev2_getKey;
	eap->get_emsk = eap_ikev2_get_emsk;
	eap->getSessionId = eap_ikev2_get_session_id;

	return eap_peer_method_register(eap);
}
