/*
 * WPA Supplicant - PeerKey for Direct Link Setup (DLS)
 * Copyright (c) 2006-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"

#ifdef CONFIG_PEERKEY

#include "common.h"
#include "eloop.h"
#include "crypto/sha1.h"
#include "crypto/sha256.h"
#include "crypto/random.h"
#include "common/ieee802_11_defs.h"
#include "wpa.h"
#include "wpa_i.h"
#include "wpa_ie.h"
#include "peerkey.h"


static u8 * wpa_add_ie(u8 *pos, const u8 *ie, size_t ie_len)
{
	os_memcpy(pos, ie, ie_len);
	return pos + ie_len;
}


static u8 * wpa_add_kde(u8 *pos, u32 kde, const u8 *data, size_t data_len)
{
	*pos++ = WLAN_EID_VENDOR_SPECIFIC;
	*pos++ = RSN_SELECTOR_LEN + data_len;
	RSN_SELECTOR_PUT(pos, kde);
	pos += RSN_SELECTOR_LEN;
	os_memcpy(pos, data, data_len);
	pos += data_len;
	return pos;
}


static void wpa_supplicant_smk_timeout(void *eloop_ctx, void *timeout_ctx)
{
#if 0
	struct wpa_sm *sm = eloop_ctx;
	struct wpa_peerkey *peerkey = timeout_ctx;
#endif
	/* TODO: time out SMK and any STK that was generated using this SMK */
}


static void wpa_supplicant_peerkey_free(struct wpa_sm *sm,
					struct wpa_peerkey *peerkey)
{
	eloop_cancel_timeout(wpa_supplicant_smk_timeout, sm, peerkey);
	os_free(peerkey);
}


static int wpa_supplicant_send_smk_error(struct wpa_sm *sm, const u8 *dst,
					 const u8 *peer,
					 u16 mui, u16 error_type, int ver)
{
	size_t rlen;
	struct wpa_eapol_key *err;
	struct rsn_error_kde error;
	u8 *rbuf, *pos;
	size_t kde_len;
	u16 key_info;

	kde_len = 2 + RSN_SELECTOR_LEN + sizeof(error);
	if (peer)
		kde_len += 2 + RSN_SELECTOR_LEN + ETH_ALEN;

	rbuf = wpa_sm_alloc_eapol(sm, IEEE802_1X_TYPE_EAPOL_KEY,
				  NULL, sizeof(*err) + kde_len, &rlen,
				  (void *) &err);
	if (rbuf == NULL)
		return -1;

	err->type = EAPOL_KEY_TYPE_RSN;
	key_info = ver | WPA_KEY_INFO_SMK_MESSAGE | WPA_KEY_INFO_MIC |
		WPA_KEY_INFO_SECURE | WPA_KEY_INFO_ERROR |
		WPA_KEY_INFO_REQUEST;
	WPA_PUT_BE16(err->key_info, key_info);
	WPA_PUT_BE16(err->key_length, 0);
	os_memcpy(err->replay_counter, sm->request_counter,
		  WPA_REPLAY_COUNTER_LEN);
	inc_byte_array(sm->request_counter, WPA_REPLAY_COUNTER_LEN);

	WPA_PUT_BE16(err->key_data_length, (u16) kde_len);
	pos = (u8 *) (err + 1);

	if (peer) {
		/* Peer MAC Address KDE */
		pos = wpa_add_kde(pos, RSN_KEY_DATA_MAC_ADDR, peer, ETH_ALEN);
	}

	/* Error KDE */
	error.mui = host_to_be16(mui);
	error.error_type = host_to_be16(error_type);
	wpa_add_kde(pos, RSN_KEY_DATA_ERROR, (u8 *) &error, sizeof(error));

	if (peer) {
		wpa_printf(MSG_DEBUG, "RSN: Sending EAPOL-Key SMK Error (peer "
			   MACSTR " mui %d error_type %d)",
			   MAC2STR(peer), mui, error_type);
	} else {
		wpa_printf(MSG_DEBUG, "RSN: Sending EAPOL-Key SMK Error "
			   "(mui %d error_type %d)", mui, error_type);
	}

	wpa_eapol_key_send(sm, sm->ptk.kck, ver, dst, ETH_P_EAPOL,
			   rbuf, rlen, err->key_mic);

	return 0;
}


static int wpa_supplicant_send_smk_m3(struct wpa_sm *sm,
				      const unsigned char *src_addr,
				      const struct wpa_eapol_key *key,
				      int ver, struct wpa_peerkey *peerkey)
{
	size_t rlen;
	struct wpa_eapol_key *reply;
	u8 *rbuf, *pos;
	size_t kde_len;
	u16 key_info;

	/* KDEs: Peer RSN IE, Initiator MAC Address, Initiator Nonce */
	kde_len = peerkey->rsnie_p_len +
		2 + RSN_SELECTOR_LEN + ETH_ALEN +
		2 + RSN_SELECTOR_LEN + WPA_NONCE_LEN;

	rbuf = wpa_sm_alloc_eapol(sm, IEEE802_1X_TYPE_EAPOL_KEY,
				  NULL, sizeof(*reply) + kde_len, &rlen,
				  (void *) &reply);
	if (rbuf == NULL)
		return -1;

	reply->type = EAPOL_KEY_TYPE_RSN;
	key_info = ver | WPA_KEY_INFO_SMK_MESSAGE | WPA_KEY_INFO_MIC |
		WPA_KEY_INFO_SECURE;
	WPA_PUT_BE16(reply->key_info, key_info);
	WPA_PUT_BE16(reply->key_length, 0);
	os_memcpy(reply->replay_counter, key->replay_counter,
		  WPA_REPLAY_COUNTER_LEN);

	os_memcpy(reply->key_nonce, peerkey->pnonce, WPA_NONCE_LEN);

	WPA_PUT_BE16(reply->key_data_length, (u16) kde_len);
	pos = (u8 *) (reply + 1);

	/* Peer RSN IE */
	pos = wpa_add_ie(pos, peerkey->rsnie_p, peerkey->rsnie_p_len);

	/* Initiator MAC Address KDE */
	pos = wpa_add_kde(pos, RSN_KEY_DATA_MAC_ADDR, peerkey->addr, ETH_ALEN);

	/* Initiator Nonce */
	wpa_add_kde(pos, RSN_KEY_DATA_NONCE, peerkey->inonce, WPA_NONCE_LEN);

	wpa_printf(MSG_DEBUG, "RSN: Sending EAPOL-Key SMK M3");
	wpa_eapol_key_send(sm, sm->ptk.kck, ver, src_addr, ETH_P_EAPOL,
			   rbuf, rlen, reply->key_mic);

	return 0;
}


static int wpa_supplicant_process_smk_m2(
	struct wpa_sm *sm, const unsigned char *src_addr,
	const struct wpa_eapol_key *key, size_t extra_len, int ver)
{
	struct wpa_peerkey *peerkey;
	struct wpa_eapol_ie_parse kde;
	struct wpa_ie_data ie;
	int cipher;
	struct rsn_ie_hdr *hdr;
	u8 *pos;

	wpa_printf(MSG_DEBUG, "RSN: Received SMK M2");

	if (!sm->peerkey_enabled || sm->proto != WPA_PROTO_RSN) {
		wpa_printf(MSG_INFO, "RSN: SMK handshake not allowed for "
			   "the current network");
		return -1;
	}

	if (wpa_supplicant_parse_ies((const u8 *) (key + 1), extra_len, &kde) <
	    0) {
		wpa_printf(MSG_INFO, "RSN: Failed to parse KDEs in SMK M2");
		return -1;
	}

	if (kde.rsn_ie == NULL || kde.mac_addr == NULL ||
	    kde.mac_addr_len < ETH_ALEN) {
		wpa_printf(MSG_INFO, "RSN: No RSN IE or MAC address KDE in "
			   "SMK M2");
		return -1;
	}

	wpa_printf(MSG_DEBUG, "RSN: SMK M2 - SMK initiator " MACSTR,
		   MAC2STR(kde.mac_addr));

	if (kde.rsn_ie_len > PEERKEY_MAX_IE_LEN) {
		wpa_printf(MSG_INFO, "RSN: Too long Initiator RSN IE in SMK "
			   "M2");
		return -1;
	}

	if (wpa_parse_wpa_ie_rsn(kde.rsn_ie, kde.rsn_ie_len, &ie) < 0) {
		wpa_printf(MSG_INFO, "RSN: Failed to parse RSN IE in SMK M2");
		return -1;
	}

	cipher = wpa_pick_pairwise_cipher(ie.pairwise_cipher &
					  sm->allowed_pairwise_cipher, 0);
	if (cipher < 0) {
		wpa_printf(MSG_INFO, "RSN: No acceptable cipher in SMK M2");
		wpa_supplicant_send_smk_error(sm, src_addr, kde.mac_addr,
					      STK_MUI_SMK, STK_ERR_CPHR_NS,
					      ver);
		return -1;
	}
	wpa_printf(MSG_DEBUG, "RSN: Using %s for PeerKey",
		   wpa_cipher_txt(cipher));

	/* TODO: find existing entry and if found, use that instead of adding
	 * a new one; how to handle the case where both ends initiate at the
	 * same time? */
	peerkey = os_zalloc(sizeof(*peerkey));
	if (peerkey == NULL)
		return -1;
	os_memcpy(peerkey->addr, kde.mac_addr, ETH_ALEN);
	os_memcpy(peerkey->inonce, key->key_nonce, WPA_NONCE_LEN);
	os_memcpy(peerkey->rsnie_i, kde.rsn_ie, kde.rsn_ie_len);
	peerkey->rsnie_i_len = kde.rsn_ie_len;
	peerkey->cipher = cipher;
#ifdef CONFIG_IEEE80211W
	if (ie.key_mgmt & (WPA_KEY_MGMT_IEEE8021X_SHA256 |
			   WPA_KEY_MGMT_PSK_SHA256))
		peerkey->use_sha256 = 1;
#endif /* CONFIG_IEEE80211W */

	if (random_get_bytes(peerkey->pnonce, WPA_NONCE_LEN)) {
		wpa_msg(sm->ctx->msg_ctx, MSG_WARNING,
			"WPA: Failed to get random data for PNonce");
		wpa_supplicant_peerkey_free(sm, peerkey);
		return -1;
	}

	hdr = (struct rsn_ie_hdr *) peerkey->rsnie_p;
	hdr->elem_id = WLAN_EID_RSN;
	WPA_PUT_LE16(hdr->version, RSN_VERSION);
	pos = (u8 *) (hdr + 1);
	/* Group Suite can be anything for SMK RSN IE; receiver will just
	 * ignore it. */
	RSN_SELECTOR_PUT(pos, RSN_CIPHER_SUITE_CCMP);
	pos += RSN_SELECTOR_LEN;
	/* Include only the selected cipher in pairwise cipher suite */
	WPA_PUT_LE16(pos, 1);
	pos += 2;
	RSN_SELECTOR_PUT(pos, wpa_cipher_to_suite(WPA_PROTO_RSN, cipher));
	pos += RSN_SELECTOR_LEN;

	hdr->len = (pos - peerkey->rsnie_p) - 2;
	peerkey->rsnie_p_len = pos - peerkey->rsnie_p;
	wpa_hexdump(MSG_DEBUG, "WPA: RSN IE for SMK handshake",
		    peerkey->rsnie_p, peerkey->rsnie_p_len);

	wpa_supplicant_send_smk_m3(sm, src_addr, key, ver, peerkey);

	peerkey->next = sm->peerkey;
	sm->peerkey = peerkey;

	return 0;
}


/**
 * rsn_smkid - Derive SMK identifier
 * @smk: Station master key (32 bytes)
 * @pnonce: Peer Nonce
 * @mac_p: Peer MAC address
 * @inonce: Initiator Nonce
 * @mac_i: Initiator MAC address
 * @use_sha256: Whether to use SHA256-based KDF
 *
 * 8.5.1.4 Station to station (STK) key hierarchy
 * SMKID = HMAC-SHA1-128(SMK, "SMK Name" || PNonce || MAC_P || INonce || MAC_I)
 */
static void rsn_smkid(const u8 *smk, const u8 *pnonce, const u8 *mac_p,
		      const u8 *inonce, const u8 *mac_i, u8 *smkid,
		      int use_sha256)
{
	char *title = "SMK Name";
	const u8 *addr[5];
	const size_t len[5] = { 8, WPA_NONCE_LEN, ETH_ALEN, WPA_NONCE_LEN,
				ETH_ALEN };
	unsigned char hash[SHA256_MAC_LEN];

	addr[0] = (u8 *) title;
	addr[1] = pnonce;
	addr[2] = mac_p;
	addr[3] = inonce;
	addr[4] = mac_i;

#ifdef CONFIG_IEEE80211W
	if (use_sha256)
		hmac_sha256_vector(smk, PMK_LEN, 5, addr, len, hash);
	else
#endif /* CONFIG_IEEE80211W */
		hmac_sha1_vector(smk, PMK_LEN, 5, addr, len, hash);
	os_memcpy(smkid, hash, PMKID_LEN);
}


static void wpa_supplicant_send_stk_1_of_4(struct wpa_sm *sm,
					   struct wpa_peerkey *peerkey)
{
	size_t mlen;
	struct wpa_eapol_key *msg;
	u8 *mbuf;
	size_t kde_len;
	u16 key_info, ver;

	kde_len = 2 + RSN_SELECTOR_LEN + PMKID_LEN;

	mbuf = wpa_sm_alloc_eapol(sm, IEEE802_1X_TYPE_EAPOL_KEY, NULL,
				  sizeof(*msg) + kde_len, &mlen,
				  (void *) &msg);
	if (mbuf == NULL)
		return;

	msg->type = EAPOL_KEY_TYPE_RSN;

	if (peerkey->cipher != WPA_CIPHER_TKIP)
		ver = WPA_KEY_INFO_TYPE_HMAC_SHA1_AES;
	else
		ver = WPA_KEY_INFO_TYPE_HMAC_MD5_RC4;

	key_info = ver | WPA_KEY_INFO_KEY_TYPE | WPA_KEY_INFO_ACK;
	WPA_PUT_BE16(msg->key_info, key_info);

	if (peerkey->cipher != WPA_CIPHER_TKIP)
		WPA_PUT_BE16(msg->key_length, 16);
	else
		WPA_PUT_BE16(msg->key_length, 32);

	os_memcpy(msg->replay_counter, peerkey->replay_counter,
		  WPA_REPLAY_COUNTER_LEN);
	inc_byte_array(peerkey->replay_counter, WPA_REPLAY_COUNTER_LEN);

	WPA_PUT_BE16(msg->key_data_length, kde_len);
	wpa_add_kde((u8 *) (msg + 1), RSN_KEY_DATA_PMKID,
		    peerkey->smkid, PMKID_LEN);

	if (random_get_bytes(peerkey->inonce, WPA_NONCE_LEN)) {
		wpa_msg(sm->ctx->msg_ctx, MSG_WARNING,
			"RSN: Failed to get random data for INonce (STK)");
		os_free(mbuf);
		return;
	}
	wpa_hexdump(MSG_DEBUG, "RSN: INonce for STK 4-Way Handshake",
		    peerkey->inonce, WPA_NONCE_LEN);
	os_memcpy(msg->key_nonce, peerkey->inonce, WPA_NONCE_LEN);

	wpa_printf(MSG_DEBUG, "RSN: Sending EAPOL-Key STK 1/4 to " MACSTR,
		   MAC2STR(peerkey->addr));
	wpa_eapol_key_send(sm, NULL, ver, peerkey->addr, ETH_P_EAPOL,
			   mbuf, mlen, NULL);
}


static void wpa_supplicant_send_stk_3_of_4(struct wpa_sm *sm,
					   struct wpa_peerkey *peerkey)
{
	size_t mlen;
	struct wpa_eapol_key *msg;
	u8 *mbuf, *pos;
	size_t kde_len;
	u16 key_info, ver;
	be32 lifetime;

	kde_len = peerkey->rsnie_i_len +
		2 + RSN_SELECTOR_LEN + sizeof(lifetime);

	mbuf = wpa_sm_alloc_eapol(sm, IEEE802_1X_TYPE_EAPOL_KEY, NULL,
				  sizeof(*msg) + kde_len, &mlen,
				  (void *) &msg);
	if (mbuf == NULL)
		return;

	msg->type = EAPOL_KEY_TYPE_RSN;

	if (peerkey->cipher != WPA_CIPHER_TKIP)
		ver = WPA_KEY_INFO_TYPE_HMAC_SHA1_AES;
	else
		ver = WPA_KEY_INFO_TYPE_HMAC_MD5_RC4;

	key_info = ver | WPA_KEY_INFO_KEY_TYPE | WPA_KEY_INFO_ACK |
		WPA_KEY_INFO_MIC | WPA_KEY_INFO_SECURE;
	WPA_PUT_BE16(msg->key_info, key_info);

	if (peerkey->cipher != WPA_CIPHER_TKIP)
		WPA_PUT_BE16(msg->key_length, 16);
	else
		WPA_PUT_BE16(msg->key_length, 32);

	os_memcpy(msg->replay_counter, peerkey->replay_counter,
		  WPA_REPLAY_COUNTER_LEN);
	inc_byte_array(peerkey->replay_counter, WPA_REPLAY_COUNTER_LEN);

	WPA_PUT_BE16(msg->key_data_length, kde_len);
	pos = (u8 *) (msg + 1);
	pos = wpa_add_ie(pos, peerkey->rsnie_i, peerkey->rsnie_i_len);
	lifetime = host_to_be32(peerkey->lifetime);
	wpa_add_kde(pos, RSN_KEY_DATA_LIFETIME,
		    (u8 *) &lifetime, sizeof(lifetime));

	os_memcpy(msg->key_nonce, peerkey->inonce, WPA_NONCE_LEN);

	wpa_printf(MSG_DEBUG, "RSN: Sending EAPOL-Key STK 3/4 to " MACSTR,
		   MAC2STR(peerkey->addr));
	wpa_eapol_key_send(sm, peerkey->stk.kck, ver, peerkey->addr,
			   ETH_P_EAPOL, mbuf, mlen, msg->key_mic);
}


static int wpa_supplicant_process_smk_m4(struct wpa_peerkey *peerkey,
					 struct wpa_eapol_ie_parse *kde)
{
	wpa_printf(MSG_DEBUG, "RSN: Received SMK M4 (Initiator " MACSTR ")",
		   MAC2STR(kde->mac_addr));

	if (os_memcmp(kde->smk + PMK_LEN, peerkey->pnonce, WPA_NONCE_LEN) != 0)
	{
		wpa_printf(MSG_INFO, "RSN: PNonce in SMK KDE does not "
			   "match with the one used in SMK M3");
		return -1;
	}

	if (os_memcmp(kde->nonce, peerkey->inonce, WPA_NONCE_LEN) != 0) {
		wpa_printf(MSG_INFO, "RSN: INonce in SMK M4 did not "
			   "match with the one received in SMK M2");
		return -1;
	}

	return 0;
}


static int wpa_supplicant_process_smk_m5(struct wpa_sm *sm,
					 const unsigned char *src_addr,
					 const struct wpa_eapol_key *key,
					 int ver,
					 struct wpa_peerkey *peerkey,
					 struct wpa_eapol_ie_parse *kde)
{
	int cipher;
	struct wpa_ie_data ie;

	wpa_printf(MSG_DEBUG, "RSN: Received SMK M5 (Peer " MACSTR ")",
		   MAC2STR(kde->mac_addr));
	if (kde->rsn_ie == NULL || kde->rsn_ie_len > PEERKEY_MAX_IE_LEN ||
	    wpa_parse_wpa_ie_rsn(kde->rsn_ie, kde->rsn_ie_len, &ie) < 0) {
		wpa_printf(MSG_INFO, "RSN: No RSN IE in SMK M5");
		/* TODO: abort negotiation */
		return -1;
	}

	if (os_memcmp(key->key_nonce, peerkey->inonce, WPA_NONCE_LEN) != 0) {
		wpa_printf(MSG_INFO, "RSN: Key Nonce in SMK M5 does "
			   "not match with INonce used in SMK M1");
		return -1;
	}

	if (os_memcmp(kde->smk + PMK_LEN, peerkey->inonce, WPA_NONCE_LEN) != 0)
	{
		wpa_printf(MSG_INFO, "RSN: INonce in SMK KDE does not "
			   "match with the one used in SMK M1");
		return -1;
	}

	os_memcpy(peerkey->rsnie_p, kde->rsn_ie, kde->rsn_ie_len);
	peerkey->rsnie_p_len = kde->rsn_ie_len;
	os_memcpy(peerkey->pnonce, kde->nonce, WPA_NONCE_LEN);

	cipher = wpa_pick_pairwise_cipher(ie.pairwise_cipher &
					  sm->allowed_pairwise_cipher, 0);
	if (cipher < 0) {
		wpa_printf(MSG_INFO, "RSN: SMK Peer STA " MACSTR " selected "
			   "unacceptable cipher", MAC2STR(kde->mac_addr));
		wpa_supplicant_send_smk_error(sm, src_addr, kde->mac_addr,
					      STK_MUI_SMK, STK_ERR_CPHR_NS,
					      ver);
		/* TODO: abort negotiation */
		return -1;
	}
	wpa_printf(MSG_DEBUG, "RSN: Using %s for PeerKey",
		   wpa_cipher_txt(cipher));
	peerkey->cipher = cipher;

	return 0;
}


static int wpa_supplicant_process_smk_m45(
	struct wpa_sm *sm, const unsigned char *src_addr,
	const struct wpa_eapol_key *key, size_t extra_len, int ver)
{
	struct wpa_peerkey *peerkey;
	struct wpa_eapol_ie_parse kde;
	u32 lifetime;
	struct os_time now;

	if (!sm->peerkey_enabled || sm->proto != WPA_PROTO_RSN) {
		wpa_printf(MSG_DEBUG, "RSN: SMK handshake not allowed for "
			   "the current network");
		return -1;
	}

	if (wpa_supplicant_parse_ies((const u8 *) (key + 1), extra_len, &kde) <
	    0) {
		wpa_printf(MSG_INFO, "RSN: Failed to parse KDEs in SMK M4/M5");
		return -1;
	}

	if (kde.mac_addr == NULL || kde.mac_addr_len < ETH_ALEN ||
	    kde.nonce == NULL || kde.nonce_len < WPA_NONCE_LEN ||
	    kde.smk == NULL || kde.smk_len < PMK_LEN + WPA_NONCE_LEN ||
	    kde.lifetime == NULL || kde.lifetime_len < 4) {
		wpa_printf(MSG_INFO, "RSN: No MAC Address, Nonce, SMK, or "
			   "Lifetime KDE in SMK M4/M5");
		return -1;
	}

	for (peerkey = sm->peerkey; peerkey; peerkey = peerkey->next) {
		if (os_memcmp(peerkey->addr, kde.mac_addr, ETH_ALEN) == 0 &&
		    os_memcmp(peerkey->initiator ? peerkey->inonce :
			   peerkey->pnonce,
			   key->key_nonce, WPA_NONCE_LEN) == 0)
			break;
	}
	if (peerkey == NULL) {
		wpa_printf(MSG_INFO, "RSN: No matching SMK handshake found "
			   "for SMK M4/M5: peer " MACSTR,
			   MAC2STR(kde.mac_addr));
		return -1;
	}

	if (peerkey->initiator) {
		if (wpa_supplicant_process_smk_m5(sm, src_addr, key, ver,
						  peerkey, &kde) < 0)
			return -1;
	} else {
		if (wpa_supplicant_process_smk_m4(peerkey, &kde) < 0)
			return -1;
	}

	os_memcpy(peerkey->smk, kde.smk, PMK_LEN);
	peerkey->smk_complete = 1;
	wpa_hexdump_key(MSG_DEBUG, "RSN: SMK", peerkey->smk, PMK_LEN);
	lifetime = WPA_GET_BE32(kde.lifetime);
	wpa_printf(MSG_DEBUG, "RSN: SMK lifetime %u seconds", lifetime);
	if (lifetime > 1000000000)
		lifetime = 1000000000; /* avoid overflowing expiration time */
	peerkey->lifetime = lifetime;
	os_get_time(&now);
	peerkey->expiration = now.sec + lifetime;
	eloop_register_timeout(lifetime, 0, wpa_supplicant_smk_timeout,
			       sm, peerkey);

	if (peerkey->initiator) {
		rsn_smkid(peerkey->smk, peerkey->pnonce, peerkey->addr,
			  peerkey->inonce, sm->own_addr, peerkey->smkid,
			  peerkey->use_sha256);
		wpa_supplicant_send_stk_1_of_4(sm, peerkey);
	} else {
		rsn_smkid(peerkey->smk, peerkey->pnonce, sm->own_addr,
			  peerkey->inonce, peerkey->addr, peerkey->smkid,
			  peerkey->use_sha256);
	}
	wpa_hexdump(MSG_DEBUG, "RSN: SMKID", peerkey->smkid, PMKID_LEN);

	return 0;
}


static int wpa_supplicant_process_smk_error(
	struct wpa_sm *sm, const unsigned char *src_addr,
	const struct wpa_eapol_key *key, size_t extra_len)
{
	struct wpa_eapol_ie_parse kde;
	struct rsn_error_kde error;
	u8 peer[ETH_ALEN];
	u16 error_type;

	wpa_printf(MSG_DEBUG, "RSN: Received SMK Error");

	if (!sm->peerkey_enabled || sm->proto != WPA_PROTO_RSN) {
		wpa_printf(MSG_DEBUG, "RSN: SMK handshake not allowed for "
			   "the current network");
		return -1;
	}

	if (wpa_supplicant_parse_ies((const u8 *) (key + 1), extra_len, &kde) <
	    0) {
		wpa_printf(MSG_INFO, "RSN: Failed to parse KDEs in SMK Error");
		return -1;
	}

	if (kde.error == NULL || kde.error_len < sizeof(error)) {
		wpa_printf(MSG_INFO, "RSN: No Error KDE in SMK Error");
		return -1;
	}

	if (kde.mac_addr && kde.mac_addr_len >= ETH_ALEN)
		os_memcpy(peer, kde.mac_addr, ETH_ALEN);
	else
		os_memset(peer, 0, ETH_ALEN);
	os_memcpy(&error, kde.error, sizeof(error));
	error_type = be_to_host16(error.error_type);
	wpa_msg(sm->ctx->msg_ctx, MSG_INFO,
		"RSN: SMK Error KDE received: MUI %d error_type %d peer "
		MACSTR,
		be_to_host16(error.mui), error_type,
		MAC2STR(peer));

	if (kde.mac_addr &&
	    (error_type == STK_ERR_STA_NR || error_type == STK_ERR_STA_NRSN ||
	     error_type == STK_ERR_CPHR_NS)) {
		struct wpa_peerkey *peerkey;

		for (peerkey = sm->peerkey; peerkey; peerkey = peerkey->next) {
			if (os_memcmp(peerkey->addr, kde.mac_addr, ETH_ALEN) ==
			    0)
				break;
		}
		if (peerkey == NULL) {
			wpa_printf(MSG_DEBUG, "RSN: No matching SMK handshake "
				   "found for SMK Error");
			return -1;
		}
		/* TODO: abort SMK/STK handshake and remove all related keys */
	}

	return 0;
}


static void wpa_supplicant_process_stk_1_of_4(struct wpa_sm *sm,
					      struct wpa_peerkey *peerkey,
					      const struct wpa_eapol_key *key,
					      u16 ver)
{
	struct wpa_eapol_ie_parse ie;
	const u8 *kde;
	size_t len, kde_buf_len;
	struct wpa_ptk *stk;
	u8 buf[8], *kde_buf, *pos;
	be32 lifetime;

	wpa_printf(MSG_DEBUG, "RSN: RX message 1 of STK 4-Way Handshake from "
		   MACSTR " (ver=%d)", MAC2STR(peerkey->addr), ver);

	os_memset(&ie, 0, sizeof(ie));

	/* RSN: msg 1/4 should contain SMKID for the selected SMK */
	kde = (const u8 *) (key + 1);
	len = WPA_GET_BE16(key->key_data_length);
	wpa_hexdump(MSG_DEBUG, "RSN: msg 1/4 key data", kde, len);
	if (wpa_supplicant_parse_ies(kde, len, &ie) < 0 || ie.pmkid == NULL) {
		wpa_printf(MSG_DEBUG, "RSN: No SMKID in STK 1/4");
		return;
	}
	if (os_memcmp(ie.pmkid, peerkey->smkid, PMKID_LEN) != 0) {
		wpa_hexdump(MSG_DEBUG, "RSN: Unknown SMKID in STK 1/4",
			    ie.pmkid, PMKID_LEN);
		return;
	}

	if (random_get_bytes(peerkey->pnonce, WPA_NONCE_LEN)) {
		wpa_msg(sm->ctx->msg_ctx, MSG_WARNING,
			"RSN: Failed to get random data for PNonce");
		return;
	}
	wpa_hexdump(MSG_DEBUG, "WPA: Renewed PNonce",
		    peerkey->pnonce, WPA_NONCE_LEN);

	/* Calculate STK which will be stored as a temporary STK until it has
	 * been verified when processing message 3/4. */
	stk = &peerkey->tstk;
	wpa_pmk_to_ptk(peerkey->smk, PMK_LEN, "Peer key expansion",
		       sm->own_addr, peerkey->addr,
		       peerkey->pnonce, key->key_nonce,
		       (u8 *) stk, sizeof(*stk),
		       peerkey->use_sha256);
	/* Supplicant: swap tx/rx Mic keys */
	os_memcpy(buf, stk->u.auth.tx_mic_key, 8);
	os_memcpy(stk->u.auth.tx_mic_key, stk->u.auth.rx_mic_key, 8);
	os_memcpy(stk->u.auth.rx_mic_key, buf, 8);
	peerkey->tstk_set = 1;

	kde_buf_len = peerkey->rsnie_p_len +
		2 + RSN_SELECTOR_LEN + sizeof(lifetime) +
		2 + RSN_SELECTOR_LEN + PMKID_LEN;
	kde_buf = os_malloc(kde_buf_len);
	if (kde_buf == NULL)
		return;
	pos = kde_buf;
	pos = wpa_add_ie(pos, peerkey->rsnie_p, peerkey->rsnie_p_len);
	lifetime = host_to_be32(peerkey->lifetime);
	pos = wpa_add_kde(pos, RSN_KEY_DATA_LIFETIME,
			  (u8 *) &lifetime, sizeof(lifetime));
	wpa_add_kde(pos, RSN_KEY_DATA_PMKID, peerkey->smkid, PMKID_LEN);

	if (wpa_supplicant_send_2_of_4(sm, peerkey->addr, key, ver,
				       peerkey->pnonce, kde_buf, kde_buf_len,
				       stk)) {
		os_free(kde_buf);
		return;
	}
	os_free(kde_buf);

	os_memcpy(peerkey->inonce, key->key_nonce, WPA_NONCE_LEN);
}


static void wpa_supplicant_update_smk_lifetime(struct wpa_sm *sm,
					       struct wpa_peerkey *peerkey,
					       struct wpa_eapol_ie_parse *kde)
{
	u32 lifetime;
	struct os_time now;

	if (kde->lifetime == NULL || kde->lifetime_len < sizeof(lifetime))
		return;

	lifetime = WPA_GET_BE32(kde->lifetime);

	if (lifetime >= peerkey->lifetime) {
		wpa_printf(MSG_DEBUG, "RSN: Peer used SMK lifetime %u seconds "
			   "which is larger than or equal to own value %u "
			   "seconds - ignored", lifetime, peerkey->lifetime);
		return;
	}

	wpa_printf(MSG_DEBUG, "RSN: Peer used shorter SMK lifetime %u seconds "
		   "(own was %u seconds) - updated",
		   lifetime, peerkey->lifetime);
	peerkey->lifetime = lifetime;

	os_get_time(&now);
	peerkey->expiration = now.sec + lifetime;
	eloop_cancel_timeout(wpa_supplicant_smk_timeout, sm, peerkey);
	eloop_register_timeout(lifetime, 0, wpa_supplicant_smk_timeout,
			       sm, peerkey);
}


static void wpa_supplicant_process_stk_2_of_4(struct wpa_sm *sm,
					      struct wpa_peerkey *peerkey,
					      const struct wpa_eapol_key *key,
					      u16 ver)
{
	struct wpa_eapol_ie_parse kde;
	const u8 *keydata;
	size_t len;

	wpa_printf(MSG_DEBUG, "RSN: RX message 2 of STK 4-Way Handshake from "
		   MACSTR " (ver=%d)", MAC2STR(peerkey->addr), ver);

	os_memset(&kde, 0, sizeof(kde));

	/* RSN: msg 2/4 should contain SMKID for the selected SMK and RSN IE
	 * from the peer. It may also include Lifetime KDE. */
	keydata = (const u8 *) (key + 1);
	len = WPA_GET_BE16(key->key_data_length);
	wpa_hexdump(MSG_DEBUG, "RSN: msg 2/4 key data", keydata, len);
	if (wpa_supplicant_parse_ies(keydata, len, &kde) < 0 ||
	    kde.pmkid == NULL || kde.rsn_ie == NULL) {
		wpa_printf(MSG_DEBUG, "RSN: No SMKID or RSN IE in STK 2/4");
		return;
	}

	if (os_memcmp(kde.pmkid, peerkey->smkid, PMKID_LEN) != 0) {
		wpa_hexdump(MSG_DEBUG, "RSN: Unknown SMKID in STK 2/4",
			    kde.pmkid, PMKID_LEN);
		return;
	}

	if (kde.rsn_ie_len != peerkey->rsnie_p_len ||
	    os_memcmp(kde.rsn_ie, peerkey->rsnie_p, kde.rsn_ie_len) != 0) {
		wpa_printf(MSG_INFO, "RSN: Peer RSN IE in SMK and STK "
			   "handshakes did not match");
		wpa_hexdump(MSG_DEBUG, "RSN: Peer RSN IE in SMK handshake",
			    peerkey->rsnie_p, peerkey->rsnie_p_len);
		wpa_hexdump(MSG_DEBUG, "RSN: Peer RSN IE in STK handshake",
			    kde.rsn_ie, kde.rsn_ie_len);
		return;
	}

	wpa_supplicant_update_smk_lifetime(sm, peerkey, &kde);

	wpa_supplicant_send_stk_3_of_4(sm, peerkey);
	os_memcpy(peerkey->pnonce, key->key_nonce, WPA_NONCE_LEN);
}


static void wpa_supplicant_process_stk_3_of_4(struct wpa_sm *sm,
					      struct wpa_peerkey *peerkey,
					      const struct wpa_eapol_key *key,
					      u16 ver)
{
	struct wpa_eapol_ie_parse kde;
	const u8 *keydata;
	size_t len, key_len;
	const u8 *_key;
	u8 key_buf[32], rsc[6];

	wpa_printf(MSG_DEBUG, "RSN: RX message 3 of STK 4-Way Handshake from "
		   MACSTR " (ver=%d)", MAC2STR(peerkey->addr), ver);

	os_memset(&kde, 0, sizeof(kde));

	/* RSN: msg 3/4 should contain Initiator RSN IE. It may also include
	 * Lifetime KDE. */
	keydata = (const u8 *) (key + 1);
	len = WPA_GET_BE16(key->key_data_length);
	wpa_hexdump(MSG_DEBUG, "RSN: msg 3/4 key data", keydata, len);
	if (wpa_supplicant_parse_ies(keydata, len, &kde) < 0) {
		wpa_printf(MSG_DEBUG, "RSN: Failed to parse key data in "
			   "STK 3/4");
		return;
	}

	if (kde.rsn_ie_len != peerkey->rsnie_i_len ||
	    os_memcmp(kde.rsn_ie, peerkey->rsnie_i, kde.rsn_ie_len) != 0) {
		wpa_printf(MSG_INFO, "RSN: Initiator RSN IE in SMK and STK "
			   "handshakes did not match");
		wpa_hexdump(MSG_DEBUG, "RSN: Initiator RSN IE in SMK "
			    "handshake",
			    peerkey->rsnie_i, peerkey->rsnie_i_len);
		wpa_hexdump(MSG_DEBUG, "RSN: Initiator RSN IE in STK "
			    "handshake",
			    kde.rsn_ie, kde.rsn_ie_len);
		return;
	}

	if (os_memcmp(peerkey->inonce, key->key_nonce, WPA_NONCE_LEN) != 0) {
		wpa_printf(MSG_WARNING, "RSN: INonce from message 1 of STK "
			   "4-Way Handshake differs from 3 of STK 4-Way "
			   "Handshake - drop packet (src=" MACSTR ")",
			   MAC2STR(peerkey->addr));
		return;
	}

	wpa_supplicant_update_smk_lifetime(sm, peerkey, &kde);

	if (wpa_supplicant_send_4_of_4(sm, peerkey->addr, key, ver,
				       WPA_GET_BE16(key->key_info),
				       NULL, 0, &peerkey->stk))
		return;

	_key = (u8 *) peerkey->stk.tk1;
	if (peerkey->cipher == WPA_CIPHER_TKIP) {
		/* Swap Tx/Rx keys for Michael MIC */
		os_memcpy(key_buf, _key, 16);
		os_memcpy(key_buf + 16, peerkey->stk.u.auth.rx_mic_key, 8);
		os_memcpy(key_buf + 24, peerkey->stk.u.auth.tx_mic_key, 8);
		_key = key_buf;
		key_len = 32;
	} else
		key_len = 16;

	os_memset(rsc, 0, 6);
	if (wpa_sm_set_key(sm, peerkey->cipher, peerkey->addr, 0, 1,
			   rsc, sizeof(rsc), _key, key_len) < 0) {
		wpa_printf(MSG_WARNING, "RSN: Failed to set STK to the "
			   "driver.");
		return;
	}
}


static void wpa_supplicant_process_stk_4_of_4(struct wpa_sm *sm,
					      struct wpa_peerkey *peerkey,
					      const struct wpa_eapol_key *key,
					      u16 ver)
{
	u8 rsc[6];

	wpa_printf(MSG_DEBUG, "RSN: RX message 4 of STK 4-Way Handshake from "
		   MACSTR " (ver=%d)", MAC2STR(peerkey->addr), ver);

	os_memset(rsc, 0, 6);
	if (wpa_sm_set_key(sm, peerkey->cipher, peerkey->addr, 0, 1,
			   rsc, sizeof(rsc), (u8 *) peerkey->stk.tk1,
			   peerkey->cipher == WPA_CIPHER_TKIP ? 32 : 16) < 0) {
		wpa_printf(MSG_WARNING, "RSN: Failed to set STK to the "
			   "driver.");
		return;
	}
}


/**
 * peerkey_verify_eapol_key_mic - Verify PeerKey MIC
 * @sm: Pointer to WPA state machine data from wpa_sm_init()
 * @peerkey: Pointer to the PeerKey data for the peer
 * @key: Pointer to the EAPOL-Key frame header
 * @ver: Version bits from EAPOL-Key Key Info
 * @buf: Pointer to the beginning of EAPOL-Key frame
 * @len: Length of the EAPOL-Key frame
 * Returns: 0 on success, -1 on failure
 */
int peerkey_verify_eapol_key_mic(struct wpa_sm *sm,
				 struct wpa_peerkey *peerkey,
				 struct wpa_eapol_key *key, u16 ver,
				 const u8 *buf, size_t len)
{
	u8 mic[16];
	int ok = 0;

	if (peerkey->initiator && !peerkey->stk_set) {
		wpa_pmk_to_ptk(peerkey->smk, PMK_LEN, "Peer key expansion",
			       sm->own_addr, peerkey->addr,
			       peerkey->inonce, key->key_nonce,
			       (u8 *) &peerkey->stk, sizeof(peerkey->stk),
			       peerkey->use_sha256);
		peerkey->stk_set = 1;
	}

	os_memcpy(mic, key->key_mic, 16);
	if (peerkey->tstk_set) {
		os_memset(key->key_mic, 0, 16);
		wpa_eapol_key_mic(peerkey->tstk.kck, ver, buf, len,
				  key->key_mic);
		if (os_memcmp(mic, key->key_mic, 16) != 0) {
			wpa_printf(MSG_WARNING, "RSN: Invalid EAPOL-Key MIC "
				   "when using TSTK - ignoring TSTK");
		} else {
			ok = 1;
			peerkey->tstk_set = 0;
			peerkey->stk_set = 1;
			os_memcpy(&peerkey->stk, &peerkey->tstk,
				  sizeof(peerkey->stk));
		}
	}

	if (!ok && peerkey->stk_set) {
		os_memset(key->key_mic, 0, 16);
		wpa_eapol_key_mic(peerkey->stk.kck, ver, buf, len,
				  key->key_mic);
		if (os_memcmp(mic, key->key_mic, 16) != 0) {
			wpa_printf(MSG_WARNING, "RSN: Invalid EAPOL-Key MIC "
				   "- dropping packet");
			return -1;
		}
		ok = 1;
	}

	if (!ok) {
		wpa_printf(MSG_WARNING, "RSN: Could not verify EAPOL-Key MIC "
			   "- dropping packet");
		return -1;
	}

	os_memcpy(peerkey->replay_counter, key->replay_counter,
		  WPA_REPLAY_COUNTER_LEN);
	peerkey->replay_counter_set = 1;
	return 0;
}


/**
 * wpa_sm_stkstart - Send EAPOL-Key Request for STK handshake (STK M1)
 * @sm: Pointer to WPA state machine data from wpa_sm_init()
 * @peer: MAC address of the peer STA
 * Returns: 0 on success, or -1 on failure
 *
 * Send an EAPOL-Key Request to the current authenticator to start STK
 * handshake with the peer.
 */
int wpa_sm_stkstart(struct wpa_sm *sm, const u8 *peer)
{
	size_t rlen, kde_len;
	struct wpa_eapol_key *req;
	int key_info, ver;
	u8 bssid[ETH_ALEN], *rbuf, *pos, *count_pos;
	u16 count;
	struct rsn_ie_hdr *hdr;
	struct wpa_peerkey *peerkey;
	struct wpa_ie_data ie;

	if (sm->proto != WPA_PROTO_RSN || !sm->ptk_set || !sm->peerkey_enabled)
		return -1;

	if (sm->ap_rsn_ie &&
	    wpa_parse_wpa_ie_rsn(sm->ap_rsn_ie, sm->ap_rsn_ie_len, &ie) == 0 &&
	    !(ie.capabilities & WPA_CAPABILITY_PEERKEY_ENABLED)) {
		wpa_printf(MSG_DEBUG, "RSN: Current AP does not support STK");
		return -1;
	}

	if (sm->pairwise_cipher != WPA_CIPHER_TKIP)
		ver = WPA_KEY_INFO_TYPE_HMAC_SHA1_AES;
	else
		ver = WPA_KEY_INFO_TYPE_HMAC_MD5_RC4;

	if (wpa_sm_get_bssid(sm, bssid) < 0) {
		wpa_printf(MSG_WARNING, "Failed to read BSSID for EAPOL-Key "
			   "SMK M1");
		return -1;
	}

	/* TODO: find existing entry and if found, use that instead of adding
	 * a new one */
	peerkey = os_zalloc(sizeof(*peerkey));
	if (peerkey == NULL)
		return -1;
	peerkey->initiator = 1;
	os_memcpy(peerkey->addr, peer, ETH_ALEN);
#ifdef CONFIG_IEEE80211W
	if (wpa_key_mgmt_sha256(sm->key_mgmt))
		peerkey->use_sha256 = 1;
#endif /* CONFIG_IEEE80211W */

	/* SMK M1:
	 * EAPOL-Key(S=1, M=1, A=0, I=0, K=0, SM=1, KeyRSC=0, Nonce=INonce,
	 *           MIC=MIC, DataKDs=(RSNIE_I, MAC_P KDE))
	 */

	hdr = (struct rsn_ie_hdr *) peerkey->rsnie_i;
	hdr->elem_id = WLAN_EID_RSN;
	WPA_PUT_LE16(hdr->version, RSN_VERSION);
	pos = (u8 *) (hdr + 1);
	/* Group Suite can be anything for SMK RSN IE; receiver will just
	 * ignore it. */
	RSN_SELECTOR_PUT(pos, RSN_CIPHER_SUITE_CCMP);
	pos += RSN_SELECTOR_LEN;
	count_pos = pos;
	pos += 2;

	count = rsn_cipher_put_suites(pos, sm->allowed_pairwise_cipher);
	pos += count * RSN_SELECTOR_LEN;
	WPA_PUT_LE16(count_pos, count);

	hdr->len = (pos - peerkey->rsnie_i) - 2;
	peerkey->rsnie_i_len = pos - peerkey->rsnie_i;
	wpa_hexdump(MSG_DEBUG, "WPA: RSN IE for SMK handshake",
		    peerkey->rsnie_i, peerkey->rsnie_i_len);

	kde_len = peerkey->rsnie_i_len + 2 + RSN_SELECTOR_LEN + ETH_ALEN;

	rbuf = wpa_sm_alloc_eapol(sm, IEEE802_1X_TYPE_EAPOL_KEY, NULL,
				  sizeof(*req) + kde_len, &rlen,
				  (void *) &req);
	if (rbuf == NULL) {
		wpa_supplicant_peerkey_free(sm, peerkey);
		return -1;
	}

	req->type = EAPOL_KEY_TYPE_RSN;
	key_info = WPA_KEY_INFO_SMK_MESSAGE | WPA_KEY_INFO_MIC |
		WPA_KEY_INFO_SECURE | WPA_KEY_INFO_REQUEST | ver;
	WPA_PUT_BE16(req->key_info, key_info);
	WPA_PUT_BE16(req->key_length, 0);
	os_memcpy(req->replay_counter, sm->request_counter,
		  WPA_REPLAY_COUNTER_LEN);
	inc_byte_array(sm->request_counter, WPA_REPLAY_COUNTER_LEN);

	if (random_get_bytes(peerkey->inonce, WPA_NONCE_LEN)) {
		wpa_msg(sm->ctx->msg_ctx, MSG_WARNING,
			"WPA: Failed to get random data for INonce");
		os_free(rbuf);
		wpa_supplicant_peerkey_free(sm, peerkey);
		return -1;
	}
	os_memcpy(req->key_nonce, peerkey->inonce, WPA_NONCE_LEN);
	wpa_hexdump(MSG_DEBUG, "WPA: INonce for SMK handshake",
		    req->key_nonce, WPA_NONCE_LEN);

	WPA_PUT_BE16(req->key_data_length, (u16) kde_len);
	pos = (u8 *) (req + 1);

	/* Initiator RSN IE */
	pos = wpa_add_ie(pos, peerkey->rsnie_i, peerkey->rsnie_i_len);
	/* Peer MAC address KDE */
	wpa_add_kde(pos, RSN_KEY_DATA_MAC_ADDR, peer, ETH_ALEN);

	wpa_printf(MSG_INFO, "RSN: Sending EAPOL-Key SMK M1 Request (peer "
		   MACSTR ")", MAC2STR(peer));
	wpa_eapol_key_send(sm, sm->ptk.kck, ver, bssid, ETH_P_EAPOL,
			   rbuf, rlen, req->key_mic);

	peerkey->next = sm->peerkey;
	sm->peerkey = peerkey;

	return 0;
}


/**
 * peerkey_deinit - Free PeerKey values
 * @sm: Pointer to WPA state machine data from wpa_sm_init()
 */
void peerkey_deinit(struct wpa_sm *sm)
{
	struct wpa_peerkey *prev, *peerkey = sm->peerkey;
	while (peerkey) {
		prev = peerkey;
		peerkey = peerkey->next;
		os_free(prev);
	}
	sm->peerkey = NULL;
}


void peerkey_rx_eapol_4way(struct wpa_sm *sm, struct wpa_peerkey *peerkey,
			   struct wpa_eapol_key *key, u16 key_info, u16 ver)
{
	if ((key_info & (WPA_KEY_INFO_MIC | WPA_KEY_INFO_ACK)) ==
	    (WPA_KEY_INFO_MIC | WPA_KEY_INFO_ACK)) {
		/* 3/4 STK 4-Way Handshake */
		wpa_supplicant_process_stk_3_of_4(sm, peerkey, key, ver);
	} else if (key_info & WPA_KEY_INFO_ACK) {
		/* 1/4 STK 4-Way Handshake */
		wpa_supplicant_process_stk_1_of_4(sm, peerkey, key, ver);
	} else if (key_info & WPA_KEY_INFO_SECURE) {
		/* 4/4 STK 4-Way Handshake */
		wpa_supplicant_process_stk_4_of_4(sm, peerkey, key, ver);
	} else {
		/* 2/4 STK 4-Way Handshake */
		wpa_supplicant_process_stk_2_of_4(sm, peerkey, key, ver);
	}
}


void peerkey_rx_eapol_smk(struct wpa_sm *sm, const u8 *src_addr,
			  struct wpa_eapol_key *key, size_t extra_len,
			  u16 key_info, u16 ver)
{
	if (key_info & WPA_KEY_INFO_ERROR) {
		/* SMK Error */
		wpa_supplicant_process_smk_error(sm, src_addr, key, extra_len);
	} else if (key_info & WPA_KEY_INFO_ACK) {
		/* SMK M2 */
		wpa_supplicant_process_smk_m2(sm, src_addr, key, extra_len,
					      ver);
	} else {
		/* SMK M4 or M5 */
		wpa_supplicant_process_smk_m45(sm, src_addr, key, extra_len,
					       ver);
	}
}

#endif /* CONFIG_PEERKEY */
