/*
 * hostapd / EAP-SAKE (RFC 4763) server
 * Copyright (c) 2006-2007, 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/random.h"
#include "eap_server/eap_i.h"
#include "eap_common/eap_sake_common.h"


struct eap_sake_data {
	enum { IDENTITY, CHALLENGE, CONFIRM, SUCCESS, FAILURE } state;
	u8 rand_s[EAP_SAKE_RAND_LEN];
	u8 rand_p[EAP_SAKE_RAND_LEN];
	struct {
		u8 auth[EAP_SAKE_TEK_AUTH_LEN];
		u8 cipher[EAP_SAKE_TEK_CIPHER_LEN];
	} tek;
	u8 msk[EAP_MSK_LEN];
	u8 emsk[EAP_EMSK_LEN];
	u8 session_id;
	u8 *peerid;
	size_t peerid_len;
	u8 *serverid;
	size_t serverid_len;
};


static const char * eap_sake_state_txt(int state)
{
	switch (state) {
	case IDENTITY:
		return "IDENTITY";
	case CHALLENGE:
		return "CHALLENGE";
	case CONFIRM:
		return "CONFIRM";
	case SUCCESS:
		return "SUCCESS";
	case FAILURE:
		return "FAILURE";
	default:
		return "?";
	}
}


static void eap_sake_state(struct eap_sake_data *data, int state)
{
	wpa_printf(MSG_DEBUG, "EAP-SAKE: %s -> %s",
		   eap_sake_state_txt(data->state),
		   eap_sake_state_txt(state));
	data->state = state;
}


static void * eap_sake_init(struct eap_sm *sm)
{
	struct eap_sake_data *data;

	data = os_zalloc(sizeof(*data));
	if (data == NULL)
		return NULL;
	data->state = CHALLENGE;

	if (os_get_random(&data->session_id, 1)) {
		wpa_printf(MSG_ERROR, "EAP-SAKE: Failed to get random data");
		os_free(data);
		return NULL;
	}
	wpa_printf(MSG_DEBUG, "EAP-SAKE: Initialized Session ID %d",
		   data->session_id);

	/* TODO: add support for configuring SERVERID */
	data->serverid = (u8 *) os_strdup("hostapd");
	if (data->serverid)
		data->serverid_len = os_strlen((char *) data->serverid);

	return data;
}


static void eap_sake_reset(struct eap_sm *sm, void *priv)
{
	struct eap_sake_data *data = priv;
	os_free(data->serverid);
	os_free(data->peerid);
	os_free(data);
}


static struct wpabuf * eap_sake_build_msg(struct eap_sake_data *data,
					  u8 id, size_t length, u8 subtype)
{
	struct eap_sake_hdr *sake;
	struct wpabuf *msg;
	size_t plen;

	plen = sizeof(struct eap_sake_hdr) + length;

	msg = eap_msg_alloc(EAP_VENDOR_IETF, EAP_TYPE_SAKE, plen,
			    EAP_CODE_REQUEST, id);
	if (msg == NULL) {
		wpa_printf(MSG_ERROR, "EAP-SAKE: Failed to allocate memory "
			   "request");
		return NULL;
	}

	sake = wpabuf_put(msg, sizeof(*sake));
	sake->version = EAP_SAKE_VERSION;
	sake->session_id = data->session_id;
	sake->subtype = subtype;

	return msg;
}


static struct wpabuf * eap_sake_build_identity(struct eap_sm *sm,
					       struct eap_sake_data *data,
					       u8 id)
{
	struct wpabuf *msg;
	size_t plen;

	wpa_printf(MSG_DEBUG, "EAP-SAKE: Request/Identity");

	plen = 4;
	if (data->serverid)
		plen += 2 + data->serverid_len;
	msg = eap_sake_build_msg(data, id, plen, EAP_SAKE_SUBTYPE_IDENTITY);
	if (msg == NULL) {
		data->state = FAILURE;
		return NULL;
	}

	wpa_printf(MSG_DEBUG, "EAP-SAKE: * AT_PERM_ID_REQ");
	eap_sake_add_attr(msg, EAP_SAKE_AT_PERM_ID_REQ, NULL, 2);

	if (data->serverid) {
		wpa_printf(MSG_DEBUG, "EAP-SAKE: * AT_SERVERID");
		eap_sake_add_attr(msg, EAP_SAKE_AT_SERVERID,
				  data->serverid, data->serverid_len);
	}

	return msg;
}


static struct wpabuf * eap_sake_build_challenge(struct eap_sm *sm,
						struct eap_sake_data *data,
						u8 id)
{
	struct wpabuf *msg;
	size_t plen;

	wpa_printf(MSG_DEBUG, "EAP-SAKE: Request/Challenge");

	if (random_get_bytes(data->rand_s, EAP_SAKE_RAND_LEN)) {
		wpa_printf(MSG_ERROR, "EAP-SAKE: Failed to get random data");
		data->state = FAILURE;
		return NULL;
	}
	wpa_hexdump(MSG_MSGDUMP, "EAP-SAKE: RAND_S (server rand)",
		    data->rand_s, EAP_SAKE_RAND_LEN);

	plen = 2 + EAP_SAKE_RAND_LEN;
	if (data->serverid)
		plen += 2 + data->serverid_len;
	msg = eap_sake_build_msg(data, id, plen, EAP_SAKE_SUBTYPE_CHALLENGE);
	if (msg == NULL) {
		data->state = FAILURE;
		return NULL;
	}

	wpa_printf(MSG_DEBUG, "EAP-SAKE: * AT_RAND_S");
	eap_sake_add_attr(msg, EAP_SAKE_AT_RAND_S,
			  data->rand_s, EAP_SAKE_RAND_LEN);

	if (data->serverid) {
		wpa_printf(MSG_DEBUG, "EAP-SAKE: * AT_SERVERID");
		eap_sake_add_attr(msg, EAP_SAKE_AT_SERVERID,
				  data->serverid, data->serverid_len);
	}

	return msg;
}


static struct wpabuf * eap_sake_build_confirm(struct eap_sm *sm,
					      struct eap_sake_data *data,
					      u8 id)
{
	struct wpabuf *msg;
	u8 *mic;

	wpa_printf(MSG_DEBUG, "EAP-SAKE: Request/Confirm");

	msg = eap_sake_build_msg(data, id, 2 + EAP_SAKE_MIC_LEN,
				 EAP_SAKE_SUBTYPE_CONFIRM);
	if (msg == NULL) {
		data->state = FAILURE;
		return NULL;
	}

	wpa_printf(MSG_DEBUG, "EAP-SAKE: * AT_MIC_S");
	wpabuf_put_u8(msg, EAP_SAKE_AT_MIC_S);
	wpabuf_put_u8(msg, 2 + EAP_SAKE_MIC_LEN);
	mic = wpabuf_put(msg, EAP_SAKE_MIC_LEN);
	if (eap_sake_compute_mic(data->tek.auth, data->rand_s, data->rand_p,
				 data->serverid, data->serverid_len,
				 data->peerid, data->peerid_len, 0,
				 wpabuf_head(msg), wpabuf_len(msg), mic, mic))
	{
		wpa_printf(MSG_INFO, "EAP-SAKE: Failed to compute MIC");
		data->state = FAILURE;
		os_free(msg);
		return NULL;
	}

	return msg;
}


static struct wpabuf * eap_sake_buildReq(struct eap_sm *sm, void *priv, u8 id)
{
	struct eap_sake_data *data = priv;

	switch (data->state) {
	case IDENTITY:
		return eap_sake_build_identity(sm, data, id);
	case CHALLENGE:
		return eap_sake_build_challenge(sm, data, id);
	case CONFIRM:
		return eap_sake_build_confirm(sm, data, id);
	default:
		wpa_printf(MSG_DEBUG, "EAP-SAKE: Unknown state %d in buildReq",
			   data->state);
		break;
	}
	return NULL;
}


static Boolean eap_sake_check(struct eap_sm *sm, void *priv,
			      struct wpabuf *respData)
{
	struct eap_sake_data *data = priv;
	struct eap_sake_hdr *resp;
	size_t len;
	u8 version, session_id, subtype;
	const u8 *pos;

	pos = eap_hdr_validate(EAP_VENDOR_IETF, EAP_TYPE_SAKE, respData, &len);
	if (pos == NULL || len < sizeof(struct eap_sake_hdr)) {
		wpa_printf(MSG_INFO, "EAP-SAKE: Invalid frame");
		return TRUE;
	}

	resp = (struct eap_sake_hdr *) pos;
	version = resp->version;
	session_id = resp->session_id;
	subtype = resp->subtype;

	if (version != EAP_SAKE_VERSION) {
		wpa_printf(MSG_INFO, "EAP-SAKE: Unknown version %d", version);
		return TRUE;
	}

	if (session_id != data->session_id) {
		wpa_printf(MSG_INFO, "EAP-SAKE: Session ID mismatch (%d,%d)",
			   session_id, data->session_id);
		return TRUE;
	}

	wpa_printf(MSG_DEBUG, "EAP-SAKE: Received frame: subtype=%d", subtype);

	if (data->state == IDENTITY && subtype == EAP_SAKE_SUBTYPE_IDENTITY)
		return FALSE;

	if (data->state == CHALLENGE && subtype == EAP_SAKE_SUBTYPE_CHALLENGE)
		return FALSE;

	if (data->state == CONFIRM && subtype == EAP_SAKE_SUBTYPE_CONFIRM)
		return FALSE;

	if (subtype == EAP_SAKE_SUBTYPE_AUTH_REJECT)
		return FALSE;

	wpa_printf(MSG_INFO, "EAP-SAKE: Unexpected subtype=%d in state=%d",
		   subtype, data->state);

	return TRUE;
}


static void eap_sake_process_identity(struct eap_sm *sm,
				      struct eap_sake_data *data,
				      const struct wpabuf *respData,
				      const u8 *payload, size_t payloadlen)
{
	if (data->state != IDENTITY)
		return;

	wpa_printf(MSG_DEBUG, "EAP-SAKE: Received Response/Identity");
	/* TODO: update identity and select new user data */
	eap_sake_state(data, CHALLENGE);
}


static void eap_sake_process_challenge(struct eap_sm *sm,
				       struct eap_sake_data *data,
				       const struct wpabuf *respData,
				       const u8 *payload, size_t payloadlen)
{
	struct eap_sake_parse_attr attr;
	u8 mic_p[EAP_SAKE_MIC_LEN];

	if (data->state != CHALLENGE)
		return;

	wpa_printf(MSG_DEBUG, "EAP-SAKE: Received Response/Challenge");

	if (eap_sake_parse_attributes(payload, payloadlen, &attr))
		return;

	if (!attr.rand_p || !attr.mic_p) {
		wpa_printf(MSG_INFO, "EAP-SAKE: Response/Challenge did not "
			   "include AT_RAND_P or AT_MIC_P");
		return;
	}

	os_memcpy(data->rand_p, attr.rand_p, EAP_SAKE_RAND_LEN);

	os_free(data->peerid);
	data->peerid = NULL;
	data->peerid_len = 0;
	if (attr.peerid) {
		data->peerid = os_malloc(attr.peerid_len);
		if (data->peerid == NULL)
			return;
		os_memcpy(data->peerid, attr.peerid, attr.peerid_len);
		data->peerid_len = attr.peerid_len;
	}

	if (sm->user == NULL || sm->user->password == NULL ||
	    sm->user->password_len != 2 * EAP_SAKE_ROOT_SECRET_LEN) {
		wpa_printf(MSG_INFO, "EAP-SAKE: Plaintext password with "
			   "%d-byte key not configured",
			   2 * EAP_SAKE_ROOT_SECRET_LEN);
		data->state = FAILURE;
		return;
	}
	eap_sake_derive_keys(sm->user->password,
			     sm->user->password + EAP_SAKE_ROOT_SECRET_LEN,
			     data->rand_s, data->rand_p,
			     (u8 *) &data->tek, data->msk, data->emsk);

	eap_sake_compute_mic(data->tek.auth, data->rand_s, data->rand_p,
			     data->serverid, data->serverid_len,
			     data->peerid, data->peerid_len, 1,
			     wpabuf_head(respData), wpabuf_len(respData),
			     attr.mic_p, mic_p);
	if (os_memcmp(attr.mic_p, mic_p, EAP_SAKE_MIC_LEN) != 0) {
		wpa_printf(MSG_INFO, "EAP-SAKE: Incorrect AT_MIC_P");
		eap_sake_state(data, FAILURE);
		return;
	}

	eap_sake_state(data, CONFIRM);
}


static void eap_sake_process_confirm(struct eap_sm *sm,
				     struct eap_sake_data *data,
				     const struct wpabuf *respData,
				     const u8 *payload, size_t payloadlen)
{
	struct eap_sake_parse_attr attr;
	u8 mic_p[EAP_SAKE_MIC_LEN];

	if (data->state != CONFIRM)
		return;

	wpa_printf(MSG_DEBUG, "EAP-SAKE: Received Response/Confirm");

	if (eap_sake_parse_attributes(payload, payloadlen, &attr))
		return;

	if (!attr.mic_p) {
		wpa_printf(MSG_INFO, "EAP-SAKE: Response/Confirm did not "
			   "include AT_MIC_P");
		return;
	}

	eap_sake_compute_mic(data->tek.auth, data->rand_s, data->rand_p,
			     data->serverid, data->serverid_len,
			     data->peerid, data->peerid_len, 1,
			     wpabuf_head(respData), wpabuf_len(respData),
			     attr.mic_p, mic_p);
	if (os_memcmp(attr.mic_p, mic_p, EAP_SAKE_MIC_LEN) != 0) {
		wpa_printf(MSG_INFO, "EAP-SAKE: Incorrect AT_MIC_P");
		eap_sake_state(data, FAILURE);
	} else
		eap_sake_state(data, SUCCESS);
}


static void eap_sake_process_auth_reject(struct eap_sm *sm,
					 struct eap_sake_data *data,
					 const struct wpabuf *respData,
					 const u8 *payload, size_t payloadlen)
{
	wpa_printf(MSG_DEBUG, "EAP-SAKE: Received Response/Auth-Reject");
	eap_sake_state(data, FAILURE);
}


static void eap_sake_process(struct eap_sm *sm, void *priv,
			     struct wpabuf *respData)
{
	struct eap_sake_data *data = priv;
	struct eap_sake_hdr *resp;
	u8 subtype;
	size_t len;
	const u8 *pos, *end;

	pos = eap_hdr_validate(EAP_VENDOR_IETF, EAP_TYPE_SAKE, respData, &len);
	if (pos == NULL || len < sizeof(struct eap_sake_hdr))
		return;

	resp = (struct eap_sake_hdr *) pos;
	end = pos + len;
	subtype = resp->subtype;
	pos = (u8 *) (resp + 1);

	wpa_hexdump(MSG_DEBUG, "EAP-SAKE: Received attributes",
		    pos, end - pos);

	switch (subtype) {
	case EAP_SAKE_SUBTYPE_IDENTITY:
		eap_sake_process_identity(sm, data, respData, pos, end - pos);
		break;
	case EAP_SAKE_SUBTYPE_CHALLENGE:
		eap_sake_process_challenge(sm, data, respData, pos, end - pos);
		break;
	case EAP_SAKE_SUBTYPE_CONFIRM:
		eap_sake_process_confirm(sm, data, respData, pos, end - pos);
		break;
	case EAP_SAKE_SUBTYPE_AUTH_REJECT:
		eap_sake_process_auth_reject(sm, data, respData, pos,
					     end - pos);
		break;
	}
}


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


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

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

	key = os_malloc(EAP_MSK_LEN);
	if (key == NULL)
		return NULL;
	os_memcpy(key, data->msk, EAP_MSK_LEN);
	*len = EAP_MSK_LEN;

	return key;
}


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

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

	key = os_malloc(EAP_EMSK_LEN);
	if (key == NULL)
		return NULL;
	os_memcpy(key, data->emsk, EAP_EMSK_LEN);
	*len = EAP_EMSK_LEN;

	return key;
}


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


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

	eap = eap_server_method_alloc(EAP_SERVER_METHOD_INTERFACE_VERSION,
				      EAP_VENDOR_IETF, EAP_TYPE_SAKE, "SAKE");
	if (eap == NULL)
		return -1;

	eap->init = eap_sake_init;
	eap->reset = eap_sake_reset;
	eap->buildReq = eap_sake_buildReq;
	eap->check = eap_sake_check;
	eap->process = eap_sake_process;
	eap->isDone = eap_sake_isDone;
	eap->getKey = eap_sake_getKey;
	eap->isSuccess = eap_sake_isSuccess;
	eap->get_emsk = eap_sake_get_emsk;

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