/*
 * Copyright (c) 2017-2018 The Linux Foundation. All rights reserved.
 *
 * Permission to use, copy, modify, and/or distribute this software for
 * any purpose with or without fee is hereby granted, provided that the
 * above copyright notice and this permission notice appear in all
 * copies.
 *
 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
 * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
 * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
 * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
 * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
 * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
 * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
 * PERFORMANCE OF THIS SOFTWARE.
 */

#include "lim_process_fils.h"
#include <lim_send_messages.h>
#include <lim_types.h>
#include <lim_utils.h>
#include <lim_prop_exts_utils.h>
#include <lim_assoc_utils.h>
#include <lim_session.h>
#include <cds_ieee80211_defines.h>
#include <qdf_crypto.h>

#ifdef WLAN_FEATURE_FILS_SK

#ifdef WLAN_FILS_DEBUG
/**
 * lim_fils_data_dump()- dump fils data
 * @type: Data name
 * @data: pointer to data buffer
 * @len: data len
 *
 * Return: None
 */
static void lim_fils_data_dump(char *type, uint8_t *data, uint32_t len)
{

	QDF_TRACE(QDF_MODULE_ID_PE, QDF_TRACE_LEVEL_DEBUG,
		 ("%s : length %d"), type, len);
	qdf_trace_hex_dump(QDF_MODULE_ID_PE, QDF_TRACE_LEVEL_INFO, data, len);
}
#else
static void lim_fils_data_dump(char *type, uint8_t *data, uint32_t len)
{ }
#endif

/**
 * lim_get_crypto_digest_len()- Returns hash length based on crypto type
 * @type: Crypto type
 *
 * Return: hash length
 */
static int lim_get_crypto_digest_len(uint8_t *type)
{
	if (!strcmp(type, HMAC_SHA386_CRYPTO_TYPE))
		return SHA384_DIGEST_SIZE;
	else if (!strcmp(type, HMAC_SHA256_CRYPTO_TYPE))
		return SHA256_DIGEST_SIZE;
	return -EINVAL;
}

/**
 * lim_get_auth_tag_len()- This API returns auth tag len based on crypto suit
 * used to encrypt erp packet.
 * @crypto_suite: Crtpto suit
 *
 * Return: tag length
 */
static uint8_t lim_get_auth_tag_len(enum fils_erp_cryptosuite crypto_suite)
{
	switch (crypto_suite) {
	case HMAC_SHA256_64:
		return -EINVAL;
	case HMAC_SHA256_128:
		return FILS_SHA256_128_AUTH_TAG;
	case HMAC_SHA256_256:
		return FILS_SHA256_256_AUTH_TAG;
	default:
		return -EINVAL;
	}
}


/**
 * lim_get_crypto_type()- This API returns crypto type based on akm suite used
 * @akm: akm used for authentication
 *
 * Return: Crypto type
 */
static uint8_t *lim_get_crypto_type(uint8_t akm)
{
	switch (akm) {
	case eCSR_AUTH_TYPE_FILS_SHA384:
	case eCSR_AUTH_TYPE_FT_FILS_SHA384:
		return FILS_SHA384_CRYPTO_TYPE;
	case eCSR_AUTH_TYPE_FILS_SHA256:
	case eCSR_AUTH_TYPE_FT_FILS_SHA256:
	default:
		return FILS_SHA256_CRYPTO_TYPE;
	}
}

/**
 * lim_get_pmk_length()- This API returns pmk length based on akm used
 * @akm: akm used for authentication
 *
 * Return: PMK length
 */
static uint8_t lim_get_pmk_length(int akm_type)
{
	switch (akm_type) {
	case eCSR_AUTH_TYPE_FILS_SHA256:
	case eCSR_AUTH_TYPE_FT_FILS_SHA256:
		return FILS_SHA256_PKM_LEN;
	case eCSR_AUTH_TYPE_FILS_SHA384:
	case eCSR_AUTH_TYPE_FT_FILS_SHA384:
		return FILS_SHA384_PKM_LEN;
	default:
		return FILS_SHA256_PKM_LEN;
	}
}

/**
 * lim_get_kek_len()- This API returns kek length based on akm used
 * @akm: akm used for authentication
 *
 * Return: KEK length
 */
static uint8_t lim_get_kek_len(uint8_t akm)
{
	switch (akm) {
	case eCSR_AUTH_TYPE_FILS_SHA384:
	case eCSR_AUTH_TYPE_FT_FILS_SHA384:
		return FILS_SHA384_KEK_LEN;
	case eCSR_AUTH_TYPE_FILS_SHA256:
	case eCSR_AUTH_TYPE_FT_FILS_SHA256:
		return FILS_SHA256_KEK_LEN;
	default:
		return FILS_SHA256_KEK_LEN;
	}
}

/**
 * lim_get_tk_len()- This API returns tk length based on cypher used
 * @akm: cypher used
 *
 * Return: TK length
 */
static uint8_t lim_get_tk_len(int cypher_suite)
{
	switch (cypher_suite) {
	case eSIR_ED_TKIP:
		return TK_LEN_TKIP;
	case eSIR_ED_CCMP:
		return TK_LEN_CCMP;
	case eSIR_ED_AES_128_CMAC:
		return TK_LEN_AES_128_CMAC;
	default:
		return 0;
	}
}

/**
 * lim_get_ick_len()- This API returns ick length based on akm used
 * @akm: akm used for authentication
 *
 * Return: ICK length
 */
static int lim_get_ick_len(uint8_t akm)
{
	switch (akm) {
	case eCSR_AUTH_TYPE_FILS_SHA384:
	case eCSR_AUTH_TYPE_FT_FILS_SHA384:
		return FILS_SHA384_ICK_LEN;
	case eCSR_AUTH_TYPE_FILS_SHA256:
	case eCSR_AUTH_TYPE_FT_FILS_SHA256:
	default:
		return FILS_SHA256_ICK_LEN;
	}
}

/**
 * lim_get_key_from_prf()- This API returns key data using PRF-X as defined in
 * 11.6.1.7.2 ieee-80211-2012.
 * @type: crypto type needs to be used
 * @secret: key which needs to be used in crypto
 * @secret_len: key_len of secret
 * @label: PRF label
 * @optional_data: Data used for hash
 * @optional_data_len: data length
 * @key: key data output
 * @keylen: key data length
 *
 * Return: QDF_STATUS
 */
static QDF_STATUS lim_get_key_from_prf(uint8_t *type, uint8_t *secret,
		uint32_t secret_len, uint8_t *label, uint8_t *optional_data,
		uint32_t optional_data_len, uint8_t *key, uint32_t keylen)
{
	uint8_t count[2];
	uint8_t *addr[4];
	uint32_t len[4];
	uint16_t key_bit_length = keylen * 8;
	uint8_t key_length[2];
	uint32_t i = 0, remain_len;
	uint16_t interation;
	uint8_t crypto_digest_len = lim_get_crypto_digest_len(type);
	uint8_t tmp_hash[SHA384_DIGEST_SIZE] = {0};

	addr[0] = count;
	len[0] = sizeof(count);

	addr[1] = label;
	len[1] = strlen(label);

	addr[2] = optional_data;
	len[2] = optional_data_len;

	qdf_mem_copy(key_length, &key_bit_length, sizeof(key_bit_length));
	addr[3] = key_length;
	len[3] = sizeof(key_length);

	for (interation = 1; i < keylen; interation++) {
		remain_len = keylen - i;
		qdf_mem_copy(count, &interation, sizeof(interation));

		if (remain_len >= crypto_digest_len)
			remain_len = crypto_digest_len;

		if (qdf_get_hmac_hash(type, secret, secret_len, 4,
				addr, len, tmp_hash) < 0) {
			pe_err("qdf_get_hmac_hash failed");
			return QDF_STATUS_E_FAILURE;
		}
		qdf_mem_copy(&key[i], tmp_hash, remain_len);
		i += crypto_digest_len;
	}
	return QDF_STATUS_SUCCESS;
}

/**
 * lim_default_hmac_sha256_kdf()- This API calculates key data using default kdf
 * defined in RFC4306.
 * @secret: key which needs to be used in crypto
 * @secret_len: key_len of secret
 * @label: PRF label
 * @optional_data: Data used for hash
 * @optional_data_len: data length
 * @key: key data output
 * @keylen: key data length
 *
 * This API creates default KDF as defined in RFC4306
 * PRF+ (K,S) = T1 | T2 | T3 | T4 | ...
 * T1 = PRF (K, S | 0x01)
 * T2 = PRF (K, T1 | S | 0x02)
 * T3 = PRF (K, T2 | S | 0x03)
 * T4 = PRF (K, T3 | S | 0x04)
 *
 * for every iteration its creates 32 bit of hash
 *
 * Return: QDF_STATUS
 */
static QDF_STATUS
lim_default_hmac_sha256_kdf(uint8_t *secret, uint32_t secret_len,
		uint8_t *label, uint8_t *optional_data,
		uint32_t optional_data_len, uint8_t *key, uint32_t keylen)
{
	uint8_t tmp_hash[SHA256_DIGEST_SIZE] = {0};
	uint8_t count = 1;
	uint8_t *addr[4];
	uint32_t len[4];
	uint32_t current_position = 0, remaining_data = SHA256_DIGEST_SIZE;

	addr[0] = tmp_hash;
	len[0] = SHA256_DIGEST_SIZE;
	addr[1] = label;
	len[1] = strlen(label) + 1;
	addr[2] = optional_data;
	len[2] = optional_data_len;
	addr[3] = &count;
	len[3] = 1;

	if (keylen == 0 ||
	   (keylen > (MAX_PRF_INTERATIONS_COUNT * SHA256_DIGEST_SIZE))) {
		pe_err("invalid key length %d", keylen);
		return QDF_STATUS_E_FAILURE;
	}

	/* Create T1 */
	if (qdf_get_hmac_hash(FILS_SHA256_CRYPTO_TYPE, secret, secret_len, 3,
			&addr[1], &len[1], tmp_hash) < 0) {
		pe_err("failed to get hmac hash");
		return QDF_STATUS_E_FAILURE;
	}

	/* Update hash from tmp_hash */
	qdf_mem_copy(key + current_position, tmp_hash, remaining_data);
	current_position += remaining_data;

	for (count = 2; current_position < keylen; count++) {
		remaining_data = keylen - current_position;
		if (remaining_data > SHA256_DIGEST_SIZE)
			remaining_data = SHA256_DIGEST_SIZE;

		/* Create T-n */
		if (qdf_get_hmac_hash(FILS_SHA256_CRYPTO_TYPE, secret,
				secret_len, 4, addr, len, tmp_hash) < 0) {
			pe_err("failed to get hmac hash");
			return QDF_STATUS_E_FAILURE;
		}
		/* Update hash from tmp_hash */
		qdf_mem_copy(key + current_position, tmp_hash, remaining_data);
		current_position += remaining_data;
	}
	return QDF_STATUS_SUCCESS;
}

/**
 * lim_process_fils_eap_tlv()- This API process eap tlv available in auth resp
 * and returns remaining length.
 * @pe_session: PE session
 * @wrapped_data: wrapped data
 * @data_len: length of tlv
 *
 * Return: remaining length
 */
static uint32_t lim_process_fils_eap_tlv(struct pe_session *pe_session,
				uint8_t *wrapped_data, uint32_t data_len)
{
	struct fils_eap_tlv *tlv;
	struct fils_auth_rsp_info *auth_info;
	uint8_t auth_tag_len;

	auth_info = &pe_session->fils_info->auth_info;
	/* Minimum */
	auth_tag_len = lim_get_auth_tag_len(HMAC_SHA256_128);

	while (data_len > (auth_tag_len + 1)) {
		tlv = (struct fils_eap_tlv *) wrapped_data;

		pe_debug("tlv type %x len %u total %u",
			tlv->type, tlv->length, data_len);

		if (tlv->length > (data_len - 2)) {
			pe_err("tlv len %d greater data_len %d",
				tlv->length, data_len);
			return 0;
		}

		switch (tlv->type) {
		case SIR_FILS_EAP_TLV_KEYNAME_NAI:
			auth_info->keyname = qdf_mem_malloc(tlv->length);
			if (!auth_info->keyname)
				return 0;

			qdf_mem_copy(auth_info->keyname,
				     tlv->data, tlv->length);
			auth_info->keylength = tlv->length;
			data_len -= (tlv->length + 2);
			wrapped_data += (tlv->length + 2);
			break;
		case SIR_FILS_EAP_TLV_R_RK_LIFETIME:
			/* TODO check this */
			auth_info->r_rk_lifetime = lim_get_u32(tlv->data);
			data_len -= (tlv->length + 2);
			wrapped_data += (tlv->length + 2);
			break;
		case SIR_FILS_EAP_TLV_R_MSK_LIFETIME:
			/* TODO check this */
			auth_info->r_msk_lifetime = lim_get_u32(tlv->data);
			data_len -= (tlv->length + 2);
			wrapped_data += (tlv->length + 2);
			break;
		case SIR_FILS_EAP_TLV_DOMAIN_NAME:
			auth_info->domain_name = qdf_mem_malloc(tlv->length);
			if (!auth_info->domain_name)
				return 0;

			qdf_mem_copy(auth_info->domain_name,
				     tlv->data, tlv->length);
			auth_info->domain_len = tlv->length;
			data_len -= (tlv->length + 2);
			wrapped_data += (tlv->length + 2);
			break;
			/* TODO process these now */
		case SIR_FILS_EAP_TLV_CRYPTO_LIST:
		case SIR_FILS_EAP_TLV_AUTH_INDICATION:
			data_len -= (tlv->length + 2);
			wrapped_data += (tlv->length + 2);
			break;
		default:
			pe_debug("Unknown type");
			return data_len;
		}
	}
	return data_len;
}

/**
 * lim_generate_key_data()- This API generates key data using prf
 * FILS-Key-Data = KDF-X(PMK, "FILS PTK Derivation", SPA||AA||SNonce||ANonce)
 * @fils_info: fils session info
 * @key_label: label used
 * @data: data buffer
 * @data_len: data buffer len
 * @key_data: hash data needs to be generated
 * @key_data_len: hash data len
 *
 * Return: QDF_STATUS
 */
static QDF_STATUS lim_generate_key_data(struct pe_fils_session *fils_info,
			uint8_t *key_label, uint8_t *data, uint32_t data_len,
			uint8_t *key_data, uint32_t key_data_len)
{
	QDF_STATUS status;

	if (!fils_info)
		return QDF_STATUS_E_FAILURE;

	status = lim_get_key_from_prf(lim_get_crypto_type(fils_info->akm),
			fils_info->fils_pmk,
			fils_info->fils_pmk_len,
			key_label, data, data_len, key_data, key_data_len);
	if (status != QDF_STATUS_SUCCESS)
		pe_err("failed to generate keydata");
	return status;
}

/**
 * lim_generate_ap_key_auth()- This API generates ap auth data which needs to be
 * verified in assoc response.
 * @pe_session: pe session pointer
 *
 * Return: None
 */
static void lim_generate_ap_key_auth(struct pe_session *pe_session)
{
	uint8_t *buf, *addr[1];
	uint32_t len;
	struct pe_fils_session *fils_info = pe_session->fils_info;
	uint8_t data[SIR_FILS_NONCE_LENGTH + SIR_FILS_NONCE_LENGTH
			+ QDF_MAC_ADDR_SIZE + QDF_MAC_ADDR_SIZE] = {0};

	if (!fils_info)
		return;

	len = SIR_FILS_NONCE_LENGTH + SIR_FILS_NONCE_LENGTH +
			QDF_MAC_ADDR_SIZE +  QDF_MAC_ADDR_SIZE;
	addr[0] = data;
	buf = data;
	qdf_mem_copy(buf, fils_info->auth_info.fils_nonce,
			SIR_FILS_NONCE_LENGTH);
	buf += SIR_FILS_NONCE_LENGTH;
	qdf_mem_copy(buf, fils_info->fils_nonce, SIR_FILS_NONCE_LENGTH);
	buf += SIR_FILS_NONCE_LENGTH;
	qdf_mem_copy(buf, pe_session->bssId, QDF_MAC_ADDR_SIZE);
	buf += QDF_MAC_ADDR_SIZE;
	qdf_mem_copy(buf, pe_session->selfMacAddr, QDF_MAC_ADDR_SIZE);
	buf += QDF_MAC_ADDR_SIZE;

	if (qdf_get_hmac_hash(lim_get_crypto_type(fils_info->akm),
				fils_info->ick, fils_info->ick_len, 1, &addr[0],
				&len, fils_info->ap_key_auth_data) < 0)
		pe_err("failed to generate PMK id");
	fils_info->ap_key_auth_len = lim_get_crypto_digest_len(
					lim_get_crypto_type(fils_info->akm));
	lim_fils_data_dump("AP Key Auth", fils_info->ap_key_auth_data,
		fils_info->ap_key_auth_len);
}

/**
 * lim_generate_key_auth()- This API generates sta auth data which needs to be
 * send to AP in assoc request, AP will generate the same the verify it.
 * @pe_session: pe session pointer
 *
 * Return: None
 */
static void lim_generate_key_auth(struct pe_session *pe_session)
{
	uint8_t *buf, *addr[1];
	uint32_t len;
	struct pe_fils_session *fils_info = pe_session->fils_info;
	uint8_t data[SIR_FILS_NONCE_LENGTH + SIR_FILS_NONCE_LENGTH
			+ QDF_MAC_ADDR_SIZE + QDF_MAC_ADDR_SIZE] = {0};

	if (!fils_info)
		return;

	len = SIR_FILS_NONCE_LENGTH + SIR_FILS_NONCE_LENGTH +
			QDF_MAC_ADDR_SIZE +  QDF_MAC_ADDR_SIZE;

	addr[0] = data;
	buf = data;
	qdf_mem_copy(buf, fils_info->fils_nonce, SIR_FILS_NONCE_LENGTH);
	buf += SIR_FILS_NONCE_LENGTH;
	qdf_mem_copy(buf, fils_info->auth_info.fils_nonce,
			SIR_FILS_NONCE_LENGTH);
	buf += SIR_FILS_NONCE_LENGTH;
	qdf_mem_copy(buf, pe_session->selfMacAddr, QDF_MAC_ADDR_SIZE);
	buf += QDF_MAC_ADDR_SIZE;
	qdf_mem_copy(buf, pe_session->bssId, QDF_MAC_ADDR_SIZE);
	buf += QDF_MAC_ADDR_SIZE;

	if (qdf_get_hmac_hash(lim_get_crypto_type(fils_info->akm),
				fils_info->ick, fils_info->ick_len, 1,
				&addr[0], &len, fils_info->key_auth) < 0)
		pe_err("failed to generate key auth");
	fils_info->key_auth_len = lim_get_crypto_digest_len(
				lim_get_crypto_type(fils_info->akm));
	lim_fils_data_dump("STA Key Auth",
			fils_info->key_auth, fils_info->key_auth_len);
}

/**
 * lim_get_keys()- This API generates keys keydata which is generated after
 * parsing of auth response.
 * KCK = L(FILS-Key-Data, 0, KCK_bits)
 * KEK = L(FILS-Key-Data, KCK_bits, KEK_bits)
 * TK = L(FILS-Key-Data, KCK_bits + KEK_bits, TK_bits)
 * FILS-FT = L(FILS-Key-Data, KCK_bits + KEK_bits + TK_bits, FILS-FT_bits)
 * @pe_session: pe session pointer
 *
 * Return: None
 */
static void lim_get_keys(struct pe_session *pe_session)
{
	uint8_t key_label[] = PTK_KEY_LABEL;
	uint8_t *data;
	uint8_t data_len;
	struct pe_fils_session *fils_info = pe_session->fils_info;
	uint8_t key_data[MAX_ICK_LEN + MAX_KEK_LEN + MAX_TK_LEN] = {0};
	uint8_t key_data_len;
	uint8_t ick_len;
	uint8_t kek_len;
	uint8_t tk_len = lim_get_tk_len(pe_session->encryptType);
	uint8_t *buf;

	if (!fils_info)
		return;

	ick_len = lim_get_ick_len(fils_info->akm);
	kek_len = lim_get_kek_len(fils_info->akm);

	key_data_len = ick_len + kek_len + tk_len;

	data_len = 2 * SIR_FILS_NONCE_LENGTH + 2 * QDF_MAC_ADDR_SIZE;
	data = qdf_mem_malloc(data_len);
	if (!data)
		return;

	/* Update data */
	buf = data;
	qdf_mem_copy(buf, pe_session->selfMacAddr, QDF_MAC_ADDR_SIZE);
	buf += QDF_MAC_ADDR_SIZE;
	qdf_mem_copy(buf, pe_session->bssId, QDF_MAC_ADDR_SIZE);
	buf += QDF_MAC_ADDR_SIZE;
	qdf_mem_copy(buf, fils_info->fils_nonce, SIR_FILS_NONCE_LENGTH);
	buf += SIR_FILS_NONCE_LENGTH;
	qdf_mem_copy(buf, fils_info->auth_info.fils_nonce,
			SIR_FILS_NONCE_LENGTH);
	lim_generate_key_data(fils_info, key_label, data, data_len,
				key_data, key_data_len);
	buf = key_data;
	qdf_mem_copy(fils_info->ick, buf, ick_len);
	fils_info->ick_len = ick_len;
	buf += ick_len;
	qdf_mem_copy(fils_info->kek, buf, kek_len);
	fils_info->kek_len = kek_len;
	buf += kek_len;
	qdf_mem_copy(fils_info->tk, buf, tk_len);
	fils_info->tk_len = tk_len;
	qdf_mem_free(data);
}

/**
 * lim_generate_pmkid()- This API generates PMKID using hash of erp auth packet
 * parsing of auth response.
 * PMKID = Truncate-128(Hash(EAP-Initiate/Reauth))
 * @pe_session: pe session pointer
 *
 * Return: None
 */
static void lim_generate_pmkid(struct pe_session *pe_session)
{
	uint8_t hash[SHA384_DIGEST_SIZE];
	struct pe_fils_session *fils_info = pe_session->fils_info;

	if (!fils_info)
		return;

	qdf_get_hash(lim_get_crypto_type(fils_info->akm), 1,
		&fils_info->fils_erp_reauth_pkt,
		&fils_info->fils_erp_reauth_pkt_len, hash);
	qdf_mem_copy(fils_info->fils_pmkid, hash, PMKID_LEN);
	lim_fils_data_dump("PMKID", fils_info->fils_pmkid, PMKID_LEN);
}

/**
 * lim_generate_pmk()- This API generates PMK using hmac hash of rmsk data
 * anonce, snonce will be used as key for this
 * PMK = HMAC-Hash(SNonce || ANonce, rMSK [ || DHss ])
 * @pe_session: pe session pointer
 *
 * Return: None
 */
static void lim_generate_pmk(struct pe_session *pe_session)
{
	uint8_t nounce[2 * SIR_FILS_NONCE_LENGTH] = {0};
	uint8_t nounce_len = 2 * SIR_FILS_NONCE_LENGTH;
	uint8_t *addr[1];
	uint32_t len[1];
	struct pe_fils_session *fils_info = pe_session->fils_info;

	if (!fils_info)
		return;

	/* Snounce */
	qdf_mem_copy(nounce, pe_session->fils_info->fils_nonce,
			SIR_FILS_NONCE_LENGTH);
	/* anounce */
	qdf_mem_copy(nounce + SIR_FILS_NONCE_LENGTH,
			pe_session->fils_info->auth_info.fils_nonce,
			SIR_FILS_NONCE_LENGTH);
	fils_info->fils_pmk_len = lim_get_pmk_length(fils_info->akm);

	if (fils_info->fils_pmk)
		qdf_mem_free(fils_info->fils_pmk);

	fils_info->fils_pmk = qdf_mem_malloc(fils_info->fils_pmk_len);
	if (!fils_info->fils_pmk)
		return;

	addr[0] = fils_info->fils_rmsk;
	len[0] = fils_info->fils_rmsk_len;
	lim_fils_data_dump("Nonce", nounce, nounce_len);
	if (qdf_get_hmac_hash(lim_get_crypto_type(fils_info->akm), nounce,
				nounce_len, 1,
				&addr[0], &len[0], fils_info->fils_pmk) < 0)
		pe_err("failed to generate PMK");
}

/**
 * lim_generate_rmsk_data()- This API generates RMSK data using
 * default kdf as defined in RFC4306.
 * @pe_session: pe session pointer
 *
 * Return: None
 */
static void lim_generate_rmsk_data(struct pe_session *pe_session)
{
	uint8_t optional_data[4] = {0};
	uint8_t rmsk_label[] = RMSK_LABEL;
	struct pe_fils_session *fils_info = pe_session->fils_info;
	struct fils_auth_rsp_info *auth_info;

	if (!fils_info)
		return;

	auth_info = &(pe_session->fils_info->auth_info);
	fils_info->fils_rmsk_len = fils_info->fils_rrk_len;
	fils_info->fils_rmsk = qdf_mem_malloc(fils_info->fils_rrk_len);
	if (!fils_info->fils_rmsk)
		return;

	/*
	 * Sequence number sent in EAP-INIT packet,
	 * it should be in network byte order
	 */
	lim_copy_u16_be(&optional_data[0], fils_info->sequence_number);
	lim_copy_u16_be(&optional_data[2], fils_info->fils_rrk_len);
	lim_default_hmac_sha256_kdf(fils_info->fils_rrk,
			fils_info->fils_rrk_len, rmsk_label,
			optional_data, sizeof(optional_data),
			fils_info->fils_rmsk, fils_info->fils_rmsk_len);
}

/**
 * lim_process_auth_wrapped_data()- This API process wrapped data element
 * of auth response.
 * @pe_session: pe session pointer
 * @wrapped_data: wrapped data pointer
 * @data_len: wrapped data len
 *
 * Return: None
 */
static QDF_STATUS lim_process_auth_wrapped_data(struct pe_session *pe_session,
			uint8_t *wrapped_data, uint32_t data_len)
{
	uint8_t code;
	uint8_t identifier;
	uint16_t length;
	uint8_t type;
	unsigned long flags;
	struct pe_fils_session *fils_info;
	uint8_t hash[32] = {0}, crypto;
	uint32_t remaining_len = data_len, new_len;
	uint8_t *input_data[1];
	uint32_t input_len[1];
	uint8_t auth_tag_len;

	fils_info = pe_session->fils_info;
	input_data[0] = wrapped_data;
	input_len[0] = data_len;

	if (!fils_info)
		return QDF_STATUS_E_FAILURE;

	pe_debug("trying to process the wrappped data");

	code = *wrapped_data;
	wrapped_data++;
	remaining_len--;
	identifier = *wrapped_data;
	wrapped_data++;
	remaining_len--;

	length = lim_get_u16(wrapped_data);
	wrapped_data += sizeof(uint16_t);
	remaining_len -= sizeof(uint16_t);

	type = *wrapped_data; /* val should be 2 here */
	wrapped_data++;
	remaining_len--;

	flags = *wrapped_data;
	if (test_bit(7, &flags)) {
		pe_err("R bit is set in flag, error");
		return QDF_STATUS_E_FAILURE;
	}
	wrapped_data++;
	remaining_len--;

	fils_info->auth_info.sequence = lim_get_u16_be(wrapped_data);
	wrapped_data += sizeof(uint16_t);
	remaining_len -= sizeof(uint16_t);
	/* Validate Auth sequence number */
	if (fils_info->auth_info.sequence < fils_info->sequence_number) {
		pe_err("sequence EAP-finish:%d is less than EAP-init:%d",
			fils_info->auth_info.sequence,
			fils_info->sequence_number);
		return QDF_STATUS_E_FAILURE;
	}

	/* Parse attached TLVs */
	new_len = lim_process_fils_eap_tlv(pe_session,
				wrapped_data, remaining_len);

	wrapped_data += remaining_len - new_len;
	remaining_len = new_len;
	/* Remove cryptosuite */
	crypto = *wrapped_data;
	wrapped_data++;
	remaining_len--;

	auth_tag_len = lim_get_auth_tag_len(crypto);
	input_len[0] -= auth_tag_len;
	/* if we have auth tag remaining */
	if (remaining_len == auth_tag_len) {
		qdf_get_hmac_hash(FILS_SHA256_CRYPTO_TYPE,
				fils_info->fils_rik,
				fils_info->fils_rik_len,
				SINGLE_ELEMENT_HASH_CNT,
				input_data, input_len, hash);
	} else {
		pe_err("invalid remaining len %d",
			remaining_len);
	}
	if (qdf_mem_cmp(wrapped_data, hash, auth_tag_len)) {
		pe_err("integratity check failed for auth, crypto %d",
			crypto);
		return QDF_STATUS_E_FAILURE;
	}

	lim_generate_rmsk_data(pe_session);
	lim_generate_pmk(pe_session);
	lim_generate_pmkid(pe_session);
	return QDF_STATUS_SUCCESS;
}

/**
 * lim_is_valid_fils_auth_frame()- This API check whether auth frame is a
 * valid frame.
 * @mac_ctx: mac context
 * @pe_session: pe session pointer
 * @rx_auth_frm_body: pointer to autherntication frame
 *
 * Return: true if frame is valid or fils is disable, false otherwise
 */
bool lim_is_valid_fils_auth_frame(struct mac_context *mac_ctx,
		struct pe_session *pe_session,
		tSirMacAuthFrameBody *rx_auth_frm_body)
{
	if (!pe_session->fils_info)
		return true;

	if (pe_session->fils_info->is_fils_connection == false)
		return true;

	if (qdf_mem_cmp(rx_auth_frm_body->session,
				pe_session->fils_info->fils_session,
				SIR_FILS_SESSION_LENGTH)) {
		lim_fils_data_dump("Current FILS session",
				pe_session->fils_info->fils_session,
				SIR_FILS_SESSION_LENGTH);
		lim_fils_data_dump("FILS Session in pkt",
				rx_auth_frm_body->session,
				SIR_FILS_SESSION_LENGTH);
		return false;
	}
	qdf_mem_copy(pe_session->fils_info->auth_info.fils_nonce,
			rx_auth_frm_body->nonce, SIR_FILS_NONCE_LENGTH);
	pe_session->fils_info->auth_info.assoc_delay =
			rx_auth_frm_body->assoc_delay_info;
	return true;
}

QDF_STATUS lim_create_fils_rik(uint8_t *rrk, uint8_t rrk_len,
					uint8_t *rik, uint32_t *rik_len)
{
	uint8_t optional_data[SIR_FILS_OPTIONAL_DATA_LEN];
	uint8_t label[] = SIR_FILS_RIK_LABEL;

	if (!rrk || !rik) {
		pe_err("FILS rrk/rik NULL");
		return QDF_STATUS_E_FAILURE;
	}

	optional_data[0] = HMAC_SHA256_128;
	/* basic validation */
	if (rrk_len <= 0) {
		pe_err("invalid r_rk length %d", rrk_len);
		return QDF_STATUS_E_FAILURE;
	}
	lim_copy_u16_be(&optional_data[1], rrk_len);
	if (lim_default_hmac_sha256_kdf(rrk, rrk_len, label,
				optional_data, sizeof(optional_data),
				rik, rrk_len)
			!= QDF_STATUS_SUCCESS) {
		pe_err("failed to create rik");
		return QDF_STATUS_E_FAILURE;
	}
	*rik_len = rrk_len;

	return QDF_STATUS_SUCCESS;
}

/**
 * lim_create_fils_wrapper_data()- This API create warpped data which will be
 * sent in auth request.
 * @fils_info: fils session info
 *
 * Return: length of the created wrapped data
 */
static int lim_create_fils_wrapper_data(struct pe_fils_session *fils_info)
{
	uint8_t *buf;
	uint8_t auth_tag[FILS_AUTH_TAG_MAX_LENGTH] = {0};
	uint32_t length = 0;
	QDF_STATUS status;
	int buf_len;

	if (!fils_info)
		return 0;

	buf_len =
		/* code + identifier */
		sizeof(uint8_t) * 2 +
		/* length */
		sizeof(uint16_t) +
		/* type + flags */
		sizeof(uint8_t) * 2 +
		/* sequence */
		sizeof(uint16_t) +
		/* tlv : type, length, data */
		sizeof(uint8_t) * 2 + fils_info->keyname_nai_length +
		/* cryptosuite + auth_tag */
		sizeof(uint8_t) + lim_get_auth_tag_len(HMAC_SHA256_128);

	fils_info->fils_erp_reauth_pkt = qdf_mem_malloc(buf_len);
	if (!fils_info->fils_erp_reauth_pkt)
		return -EINVAL;

	buf = fils_info->fils_erp_reauth_pkt;
	*buf = 5;
	buf++;
	/* Identifier */
	*buf = 0;
	buf++;
	/* Length */
	lim_copy_u16_be(buf, buf_len);
	buf += sizeof(uint16_t);
	/* type */
	*buf = SIR_FILS_EAP_INIT_PACKET_TYPE;
	buf++;

	/**
	 *  flag
	 *  0 1 2  <-- 5 -->
	 * ----------------
	 * |R|B|L| Reserved|
	 * -----------------
	 */
	*buf = 0x20; /* l=1, b=0, r=0 */
	buf++;
	/* sequence */
	lim_copy_u16_be(buf, fils_info->sequence_number);
	buf += sizeof(uint16_t);

	/* tlv */
	/* Type */
	*buf = SIR_FILS_EAP_TLV_KEYNAME_NAI;
	buf++;
	/* NAI Length */
	*buf = fils_info->keyname_nai_length;
	buf++;
	/* NAI Data */
	qdf_mem_copy(buf, fils_info->keyname_nai_data,
			fils_info->keyname_nai_length);
	buf += fils_info->keyname_nai_length;

	/* cryptosuite */
	*buf = HMAC_SHA256_128;
	buf++;

	/*
	 * This should be moved to just after sending probe to save time
	 * lim_process_switch_channel_join_req ??
	 */
	fils_info->fils_rik = qdf_mem_malloc(fils_info->fils_rrk_len);
	if (!fils_info->fils_rik) {
		qdf_mem_free(fils_info->fils_erp_reauth_pkt);
		fils_info->fils_erp_reauth_pkt = NULL;
		return -EINVAL;
	}
	status = lim_create_fils_rik(fils_info->fils_rrk,
				     fils_info->fils_rrk_len,
				     fils_info->fils_rik,
				     &fils_info->fils_rik_len);
	if (QDF_IS_STATUS_ERROR(status)) {
		pe_err("RIK create fails");
		qdf_mem_free(fils_info->fils_erp_reauth_pkt);
		qdf_mem_free(fils_info->fils_rik);
		fils_info->fils_erp_reauth_pkt = NULL;
		fils_info->fils_rik = NULL;
		return -EINVAL;
	}

	fils_info->fils_erp_reauth_pkt_len = buf_len;
	length = fils_info->fils_erp_reauth_pkt_len -
			lim_get_auth_tag_len(HMAC_SHA256_128);
	qdf_get_hmac_hash(FILS_SHA256_CRYPTO_TYPE,
			fils_info->fils_rik, fils_info->fils_rik_len, 1,
			&fils_info->fils_erp_reauth_pkt, &length, auth_tag);

	lim_fils_data_dump("Auth tag", auth_tag,
			lim_get_auth_tag_len(HMAC_SHA256_128));
	lim_fils_data_dump("EAP init pkt", fils_info->fils_erp_reauth_pkt,
			fils_info->fils_erp_reauth_pkt_len);

	qdf_mem_copy(buf, auth_tag, lim_get_auth_tag_len(HMAC_SHA256_128));
	buf += lim_get_auth_tag_len(HMAC_SHA256_128);

	return buf_len;
}

/**
 * lim_add_fils_data_to_auth_frame()- This API add fils data to auth frame.
 * Following will be added in this.
 * RSNIE
 * SNonce
 * Session
 * Wrapped data
 * @session: PE session
 * @body: pointer to auth frame where data needs to be added
 *
 * Return: None
 */
void lim_add_fils_data_to_auth_frame(struct pe_session *session,
		uint8_t *body)
{
	struct pe_fils_session *fils_info;

	fils_info = session->fils_info;

	if (!fils_info)
		return;

	/* RSN IE */
	qdf_mem_copy(body, fils_info->rsn_ie, fils_info->rsn_ie_len);
	body += fils_info->rsn_ie_len;
	lim_fils_data_dump("FILS RSN", fils_info->rsn_ie,
			fils_info->rsn_ie_len);

	/* ***Nounce*** */
	/* Add element id */
	*body = SIR_MAX_ELEMENT_ID;
	body++;
	/* Add nounce length + 1 for ext element id */
	*body = SIR_FILS_NONCE_LENGTH + 1;
	body++;
	/* Add ext element */
	*body = SIR_FILS_NONCE_EXT_EID;
	body++;
	/* Add data */
	cds_rand_get_bytes(0, fils_info->fils_nonce, SIR_FILS_NONCE_LENGTH);
	qdf_mem_copy(body, fils_info->fils_nonce, SIR_FILS_NONCE_LENGTH);
	body = body + SIR_FILS_NONCE_LENGTH;
	/* Dump data */
	lim_fils_data_dump("fils anonce", fils_info->fils_nonce,
			SIR_FILS_NONCE_LENGTH);

	/*   *** Session ***  */
	/* Add element id */
	*body = SIR_MAX_ELEMENT_ID;
	body++;
	/* Add nounce length + 1 for ext element id */
	*body = SIR_FILS_SESSION_LENGTH + 1;
	body++;
	/* Add ext element */
	*body = SIR_FILS_SESSION_EXT_EID;
	body++;
	/* Add data */
	cds_rand_get_bytes(0, fils_info->fils_session, SIR_FILS_SESSION_LENGTH);
	qdf_mem_copy(body, fils_info->fils_session, SIR_FILS_SESSION_LENGTH);
	body = body + SIR_FILS_SESSION_LENGTH;
	/* dump data */
	lim_fils_data_dump("Fils Session",
		fils_info->fils_session, SIR_FILS_SESSION_LENGTH);

	/*  ERP Packet  */
	/* Add element id */
	*body = SIR_MAX_ELEMENT_ID;
	body++;
	/* Add packet length + 1 for ext element id */
	*body = fils_info->fils_erp_reauth_pkt_len + 1;
	body++;
	/* Add ext element */
	*body = SIR_FILS_WRAPPED_DATA_EXT_EID;
	body++;
	/* Copy data */
	qdf_mem_copy(body, fils_info->fils_erp_reauth_pkt,
			fils_info->fils_erp_reauth_pkt_len);
	lim_fils_data_dump("Fils ERP reauth Pkt",
			fils_info->fils_erp_reauth_pkt,
			fils_info->fils_erp_reauth_pkt_len);
	body = body + fils_info->fils_erp_reauth_pkt_len;
}

/**
 * lim_process_fils_auth_frame2()- This API process fils data from auth response
 * @mac_ctx: mac context
 * @session: PE session
 * @rx_auth_frm_body: pointer to auth frame
 *
 * Return: true if fils data needs to be processed else false
 */
bool lim_process_fils_auth_frame2(struct mac_context *mac_ctx,
		struct pe_session *pe_session,
		tSirMacAuthFrameBody *rx_auth_frm_body)
{
	int i;
	uint32_t ret;
	bool pmkid_found = false;
	tDot11fIERSN dot11f_ie_rsn = {0};

	if (!pe_session->fils_info)
		return false;

	if (rx_auth_frm_body->authAlgoNumber != SIR_FILS_SK_WITHOUT_PFS)
		return false;

	ret = dot11f_unpack_ie_rsn(mac_ctx, &rx_auth_frm_body->rsn_ie.info[0],
				rx_auth_frm_body->rsn_ie.length,
				&dot11f_ie_rsn, 0);
	if (!DOT11F_SUCCEEDED(ret)) {
		pe_err("unpack failed, ret: %d", ret);
		return false;
	}

	for (i = 0; i < dot11f_ie_rsn.pmkid_count; i++) {
		if (qdf_mem_cmp(dot11f_ie_rsn.pmkid[i],
		    pe_session->fils_info->fils_pmkid,
		    PMKID_LEN) == 0) {
			pmkid_found = true;
			pe_debug("pmkid match in rsn ie total_count %d",
				dot11f_ie_rsn.pmkid_count);
			break;
		}
	}
	if (!pmkid_found) {
		if (QDF_STATUS_SUCCESS !=
		    lim_process_auth_wrapped_data(pe_session,
			rx_auth_frm_body->wrapped_data,
			rx_auth_frm_body->wrapped_data_len))
			return false;
	}
	lim_get_keys(pe_session);
	lim_generate_key_auth(pe_session);
	lim_generate_ap_key_auth(pe_session);
	return true;
}

/**
 * lim_update_fils_config()- This API update fils session info to csr config
 * from join request.
 * @session: PE session
 * @sme_join_req: pointer to join request
 *
 * Return: None
 */
void lim_update_fils_config(struct pe_session *session,
		tpSirSmeJoinReq sme_join_req)
{
	struct pe_fils_session *csr_fils_info;
	struct cds_fils_connection_info *fils_config_info;

	fils_config_info = &sme_join_req->fils_con_info;
	csr_fils_info = session->fils_info;

	if (!csr_fils_info)
		return;

	if (fils_config_info->is_fils_connection == false)
		return;

	csr_fils_info->is_fils_connection =
		fils_config_info->is_fils_connection;
	csr_fils_info->keyname_nai_length =
		fils_config_info->key_nai_length;
	csr_fils_info->fils_rrk_len =
		fils_config_info->r_rk_length;
	csr_fils_info->akm = fils_config_info->akm_type;
	csr_fils_info->auth = fils_config_info->auth_type;
	csr_fils_info->sequence_number = fils_config_info->sequence_number;
	if (fils_config_info->key_nai_length > FILS_MAX_KEYNAME_NAI_LENGTH) {
		pe_err("Restricting the key_nai_length of  %d to max %d",
		       fils_config_info->key_nai_length,
		       FILS_MAX_KEYNAME_NAI_LENGTH);
		fils_config_info->key_nai_length = FILS_MAX_KEYNAME_NAI_LENGTH;
	}
	csr_fils_info->keyname_nai_data =
		qdf_mem_malloc(fils_config_info->key_nai_length);
	if (!csr_fils_info->keyname_nai_data)
		return;

	qdf_mem_copy(csr_fils_info->keyname_nai_data,
			fils_config_info->keyname_nai,
			fils_config_info->key_nai_length);
	csr_fils_info->fils_rrk =
		qdf_mem_malloc(fils_config_info->r_rk_length);
	if (!csr_fils_info->fils_rrk) {
		qdf_mem_free(csr_fils_info->keyname_nai_data);
		return;
	}

	if (fils_config_info->r_rk_length <= FILS_MAX_RRK_LENGTH)
		qdf_mem_copy(csr_fils_info->fils_rrk,
				fils_config_info->r_rk,
				fils_config_info->r_rk_length);

	qdf_mem_copy(csr_fils_info->fils_pmkid,
			fils_config_info->pmkid, PMKID_LEN);
	csr_fils_info->rsn_ie_len = sme_join_req->rsnIE.length;
	qdf_mem_copy(csr_fils_info->rsn_ie,
			sme_join_req->rsnIE.rsnIEdata,
			sme_join_req->rsnIE.length);

	csr_fils_info->fils_pmk_len = fils_config_info->pmk_len;
	if (fils_config_info->pmk_len) {
		csr_fils_info->fils_pmk =
			qdf_mem_malloc(fils_config_info->pmk_len);
		if (!csr_fils_info->fils_pmk) {
			qdf_mem_free(csr_fils_info->keyname_nai_data);
			qdf_mem_free(csr_fils_info->fils_rrk);
			return;
		}
		qdf_mem_copy(csr_fils_info->fils_pmk, fils_config_info->pmk,
			fils_config_info->pmk_len);
	}
	pe_debug("fils=%d nai-len=%d rrk_len=%d akm=%d auth=%d pmk_len=%d",
		fils_config_info->is_fils_connection,
		fils_config_info->key_nai_length,
		fils_config_info->r_rk_length,
		fils_config_info->akm_type,
		fils_config_info->auth_type,
		fils_config_info->pmk_len);
}

#define EXTENDED_IE_HEADER_LEN 3
/**
 * lim_create_fils_auth_data()- This API creates the fils auth data
 * which needs to be sent in auth req.
 * @mac_ctx: mac context
 * @auth_frame: pointer to auth frame
 * @session: PE session
 *
 * Return: length of fils data
 */
uint32_t lim_create_fils_auth_data(struct mac_context *mac_ctx,
		tpSirMacAuthFrameBody auth_frame,
		struct pe_session *session)
{
	uint32_t frame_len = 0;
	int32_t wrapped_data_len;

	if (!session->fils_info)
		return 0;

	/* These memory may already been allocated if auth retry */
	if (session->fils_info->fils_rik) {
		qdf_mem_free(session->fils_info->fils_rik);
		session->fils_info->fils_rik = NULL;
	}
	if  (session->fils_info->fils_erp_reauth_pkt) {
		qdf_mem_free(session->fils_info->fils_erp_reauth_pkt);
		session->fils_info->fils_erp_reauth_pkt = NULL;
	}
	if (auth_frame->authAlgoNumber == SIR_FILS_SK_WITHOUT_PFS) {
		frame_len += session->fils_info->rsn_ie_len;
		/* FILS nounce */
		frame_len += SIR_FILS_NONCE_LENGTH + EXTENDED_IE_HEADER_LEN;
		/* FILS Session */
		frame_len += SIR_FILS_SESSION_LENGTH + EXTENDED_IE_HEADER_LEN;
		/* Calculate data/length for FILS Wrapped Data */
		wrapped_data_len =
			lim_create_fils_wrapper_data(session->fils_info);
		if (wrapped_data_len < 0) {
			pe_err("failed to create warpped data");
			return 0;
		}
		frame_len += wrapped_data_len + EXTENDED_IE_HEADER_LEN;
	}
	return frame_len;
}

void populate_fils_connect_params(struct mac_context *mac_ctx,
				  struct pe_session *session,
				  tpSirSmeJoinRsp sme_join_rsp)
{
	struct fils_join_rsp_params *fils_join_rsp;
	struct pe_fils_session *fils_info = session->fils_info;

	if (!lim_is_fils_connection(session))
		return;

	if (!fils_info->fils_pmk_len ||
			!fils_info->tk_len || !fils_info->gtk_len ||
			!fils_info->fils_pmk || !fils_info->kek_len) {
		pe_err("Invalid FILS info pmk len %d kek len %d tk len %d gtk len %d",
			fils_info->fils_pmk_len,
			fils_info->kek_len,
			fils_info->tk_len,
			fils_info->gtk_len);
		return;
	}

	sme_join_rsp->fils_join_rsp = qdf_mem_malloc(sizeof(*fils_join_rsp));
	if (!sme_join_rsp->fils_join_rsp) {
		pe_delete_fils_info(session);
		return;
	}

	fils_join_rsp = sme_join_rsp->fils_join_rsp;
	fils_join_rsp->fils_pmk = qdf_mem_malloc(fils_info->fils_pmk_len);
	if (!fils_join_rsp->fils_pmk) {
		qdf_mem_free(fils_join_rsp);
		pe_delete_fils_info(session);
		return;
	}

	fils_join_rsp->fils_pmk_len = fils_info->fils_pmk_len;
	qdf_mem_copy(fils_join_rsp->fils_pmk, fils_info->fils_pmk,
			fils_info->fils_pmk_len);

	qdf_mem_copy(fils_join_rsp->fils_pmkid, fils_info->fils_pmkid,
			IEEE80211_PMKID_LEN);

	fils_join_rsp->kek_len = fils_info->kek_len;
	qdf_mem_copy(fils_join_rsp->kek, fils_info->kek, fils_info->kek_len);

	fils_join_rsp->tk_len = fils_info->tk_len;
	qdf_mem_copy(fils_join_rsp->tk, fils_info->tk, fils_info->tk_len);

	fils_join_rsp->gtk_len = fils_info->gtk_len;
	qdf_mem_copy(fils_join_rsp->gtk, fils_info->gtk, fils_info->gtk_len);

	cds_copy_hlp_info(&fils_info->dst_mac, &fils_info->src_mac,
			  fils_info->hlp_data_len, fils_info->hlp_data,
			  &fils_join_rsp->dst_mac, &fils_join_rsp->src_mac,
			  &fils_join_rsp->hlp_data_len,
			  fils_join_rsp->hlp_data);

	pe_debug("FILS connect params copied lim");
}

/**
 * lim_parse_kde_elements() - Parse Key Delivery Elements
 * @mac_ctx: mac context
 * @fils_info: FILS info
 * @kde_list: KDE list buffer
 * @kde_list_len: Length of @kde_list
 *
 * This API is used to parse the Key Delivery Elements from buffer
 * and populate them in PE FILS session struct i.e @fils_info
 *
 *             Key Delivery Element[KDE] format
 * +----------+--------+-----------+------------+----------+
 * | ID(0xDD) | length |  KDE OUI  |  data type |  IE data |
 * |----------|--------|-----------|------------|----------|
 * |  1 byte  | 1 byte |  3 bytes  |   1 byte   | variable |
 * +----------+--------+-----------+------------+----------+
 *
 * there can be multiple KDE present inside KDE list.
 * the IE data could be GTK, IGTK etc based on the data type
 *
 * Return: QDF_STATUS_SUCCESS if we parse GTK successfully,
 *         QDF_STATUS_E_FAILURE otherwise
 */
static QDF_STATUS lim_parse_kde_elements(struct mac_context *mac_ctx,
					 struct pe_fils_session *fils_info,
					 uint8_t *kde_list,
					 uint8_t kde_list_len)
{
	uint8_t rem_len = kde_list_len;
	uint8_t *temp_ie = kde_list;
	uint8_t elem_id, data_type, data_len, *ie_data = NULL, *current_ie;
	uint16_t elem_len;

	if (!kde_list_len || !kde_list) {
		pe_err("kde_list NULL or kde_list_len %d", kde_list_len);
		return QDF_STATUS_E_FAILURE;
	}

	while (rem_len >= 2) {
		current_ie = temp_ie;
		elem_id = *temp_ie++;
		elem_len = *temp_ie++;
		rem_len -= 2;

		if (rem_len < elem_len || elem_len > kde_list_len) {
			pe_err("Invalid elem_len %d rem_len %d list_len %d",
				elem_len, rem_len, kde_list_len);
			return QDF_STATUS_E_FAILURE;
		}

		if (elem_len < KDE_IE_DATA_OFFSET) {
			pe_err("Not enough len to parse elem_len %d",
				elem_len);
			return QDF_STATUS_E_FAILURE;
		}

		if (lim_check_if_vendor_oui_match(mac_ctx, KDE_OUI_TYPE,
				KDE_OUI_TYPE_SIZE, current_ie, elem_len)) {

			data_type = *(temp_ie + KDE_DATA_TYPE_OFFSET);
			ie_data = (temp_ie + KDE_IE_DATA_OFFSET);
			data_len = (elem_len - KDE_IE_DATA_OFFSET);

			switch (data_type) {
			case DATA_TYPE_GTK:
				if (data_len < GTK_OFFSET) {
					pe_err("Invalid KDE data_len %d",
						data_len);
					return QDF_STATUS_E_FAILURE;
				}
				qdf_mem_copy(fils_info->gtk, (ie_data +
					     GTK_OFFSET), (data_len -
					     GTK_OFFSET));
				fils_info->gtk_len = (data_len - GTK_OFFSET);
				break;

			case DATA_TYPE_IGTK:
				if (data_len < IGTK_OFFSET) {
					pe_err("Invalid KDE data_len %d",
						data_len);
					return QDF_STATUS_E_FAILURE;
				}
				fils_info->igtk_len = (data_len - IGTK_OFFSET);
				qdf_mem_copy(fils_info->igtk, (ie_data +
					     IGTK_OFFSET), (data_len -
					     IGTK_OFFSET));
				qdf_mem_copy(fils_info->ipn, (ie_data +
					     IPN_OFFSET), IPN_LEN);
			break;
			default:
				pe_err("Unknown KDE data type %x", data_type);
			break;
			}
		}

		temp_ie += elem_len;
		rem_len -= elem_len;
		ie_data = NULL;
	}

	/* Expecting GTK in KDE */
	if (!fils_info->gtk_len) {
		pe_err("GTK not found in KDE");
		return QDF_STATUS_E_FAILURE;
	}

	return QDF_STATUS_SUCCESS;
}

bool lim_verify_fils_params_assoc_rsp(struct mac_context *mac_ctx,
				      struct pe_session *session_entry,
				      tpSirAssocRsp assoc_rsp,
				      tLimMlmAssocCnf *assoc_cnf)
{
	struct pe_fils_session *fils_info = session_entry->fils_info;
	tDot11fIEfils_session fils_session = assoc_rsp->fils_session;
	tDot11fIEfils_key_confirmation fils_key_auth = assoc_rsp->fils_key_auth;
	tDot11fIEfils_kde fils_kde = assoc_rsp->fils_kde;
	QDF_STATUS status;

	if (!lim_is_fils_connection(session_entry))
		return true;

	if (!fils_info) {
		pe_err("FILS Info not present");
		goto verify_fils_params_fails;
	}

	if (!assoc_rsp->fils_session.present) {
		pe_err("FILS IE not present");
		goto verify_fils_params_fails;
	}

	/* Compare FILS session */
	if (qdf_mem_cmp(fils_info->fils_session,
			fils_session.session, DOT11F_IE_FILS_SESSION_MAX_LEN)) {
		pe_err("FILS session mismatch");
		goto verify_fils_params_fails;
	}

	/* Compare FILS key auth */
	if ((fils_key_auth.num_key_auth != fils_info->key_auth_len) ||
		qdf_mem_cmp(fils_info->ap_key_auth_data, fils_key_auth.key_auth,
					 fils_info->ap_key_auth_len)) {
		lim_fils_data_dump("session keyauth",
				   fils_info->ap_key_auth_data,
				   fils_info->ap_key_auth_len);
		lim_fils_data_dump("Pkt keyauth",
				   fils_key_auth.key_auth,
				   fils_key_auth.num_key_auth);
		goto verify_fils_params_fails;
	}

	/* Verify the Key Delivery Element presence */
	if (!fils_kde.num_kde_list) {
		pe_err("FILS KDE list absent");
		goto verify_fils_params_fails;
	}

	/* Derive KDE elements */
	status = lim_parse_kde_elements(mac_ctx, fils_info, fils_kde.kde_list,
					fils_kde.num_kde_list);
	if (!QDF_IS_STATUS_SUCCESS(status)) {
		pe_err("KDE parsing fails");
		goto verify_fils_params_fails;
	}
	return true;

verify_fils_params_fails:
	assoc_cnf->resultCode = eSIR_SME_ASSOC_REFUSED;
	assoc_cnf->protStatusCode = eSIR_MAC_UNSPEC_FAILURE_STATUS;
	return false;
}

/**
 * find_ie_data_after_fils_session_ie() - Find IE pointer after FILS Session IE
 * @mac_ctx: MAC context
 * @buf: IE buffer
 * @buf_len: Length of @buf
 * @ie: Pointer to update the found IE pointer after FILS session IE
 * @ie_len: length of the IE data after FILS session IE
 *
 * This API is used to find the IE data ptr and length after FILS session IE
 *
 * Return: QDF_STATUS_SUCCESS if found, else QDF_STATUS_E_FAILURE
 */
static QDF_STATUS find_ie_data_after_fils_session_ie(struct mac_context *mac_ctx,
						     uint8_t *buf,
						     uint32_t buf_len,
						     uint8_t **ie,
						     uint32_t *ie_len)
{
	uint32_t left = buf_len;
	uint8_t *ptr = buf;
	uint8_t elem_id, elem_len;

	if (NULL == buf || 0 == buf_len)
		return QDF_STATUS_E_FAILURE;

	while (left >= 2) {
		elem_id = ptr[0];
		elem_len = ptr[1];
		left -= 2;
		if (elem_len > left)
			return QDF_STATUS_E_FAILURE;

		if (elem_id == SIR_MAC_REQUEST_EID_MAX &&
			ptr[2] == SIR_FILS_SESSION_EXT_EID) {
			(*ie) = ((&ptr[1]) + ptr[1] + 1);
			(*ie_len) = (left - elem_len);
			return QDF_STATUS_SUCCESS;
		}
		left -= elem_len;
		ptr += (elem_len + 2);
	}
	return QDF_STATUS_E_FAILURE;
}

/**
 * fils_aead_encrypt() - API to do FILS AEAD encryption
 *
 * @kek: Pointer to KEK
 * @kek_len: KEK length
 * @own_mac: Pointer to own MAC address
 * @bssid: Bssid
 * @snonce: Supplicant Nonce
 * @anonce: Authenticator Nonce
 * @data: Pointer to data after MAC header
 * @data_len: length of @data
 * @plain_text: Pointer to data after FILS Session IE
 * @plain_text_len: length of @plain_text
 * @out: Pointer to the encrypted data
 *
 * length of AEAD encryption @out is @plain_text_len + AES_BLOCK_SIZE[16 bytes]
 *
 * Return: zero on success, error otherwise
 */
static int fils_aead_encrypt(const uint8_t *kek, unsigned int kek_len,
			     const uint8_t *own_mac, const uint8_t *bssid,
			     const uint8_t *snonce, const uint8_t *anonce,
			     const uint8_t *data, size_t data_len,
			     uint8_t *plain_text, size_t plain_text_len,
			     uint8_t *out)
{
	uint8_t v[AES_BLOCK_SIZE];
	const uint8_t *aad[6];
	size_t aad_len[6];
	uint8_t *buf;
	int ret;

	/* SIV Encrypt/Decrypt takes input key of length 256, 384 or 512 bits */
	if (kek_len != 32 && kek_len != 48 && kek_len != 64) {
		QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_ERROR,
			  FL("Invalid key length: %u"), kek_len);
		return -EINVAL;
	}

	if (own_mac == NULL || bssid == NULL || snonce == NULL ||
	    anonce == NULL || data_len == 0 || plain_text_len == 0 ||
	    out == NULL) {
		QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_ERROR,
			  FL("Error missing params mac:%pK bssid:%pK snonce:%pK anonce:%pK data_len:%zu plain_text_len:%zu out:%pK"),
			  own_mac, bssid, snonce, anonce, data_len,
			  plain_text_len, out);
		return -EINVAL;
	}

	if (plain_text == out) {
		buf = qdf_mem_malloc(plain_text_len);
		if (!buf)
			return -ENOMEM;
		qdf_mem_copy(buf, plain_text, plain_text_len);
	} else {
		buf = plain_text;
	}

	aad[0] = own_mac;
	aad_len[0] = QDF_MAC_ADDR_SIZE;
	aad[1] = bssid;
	aad_len[1] = QDF_MAC_ADDR_SIZE;
	aad[2] = snonce;
	aad_len[2] = SIR_FILS_NONCE_LENGTH;
	aad[3] = anonce;
	aad_len[3] = SIR_FILS_NONCE_LENGTH;
	aad[4] = data;
	aad_len[4] = data_len;
	/* Plain text, P, is Sn in AES-SIV */
	aad[5] = buf;
	aad_len[5] = plain_text_len;

	/* AES-SIV S2V */
	/* K1 = leftmost(K, len(K)/2) */
	ret = qdf_aes_s2v(kek, kek_len/2, aad, aad_len, 6, v);
	if (ret)
		goto error;

	/* out = SIV || C (Synthetic Initialization Vector || Ciphered text) */
	qdf_mem_copy(out, v, AES_BLOCK_SIZE);

	/* AES-SIV CTR */
	/* K2 = rightmost(K, len(K)/2) */
	/* Clear 31st and 63rd bits in counter synthetic iv */
	v[12] &= 0x7F;
	v[8] &= 0x7F;

	ret = qdf_aes_ctr(kek + kek_len/2, kek_len/2, v, buf, plain_text_len,
		      out + AES_BLOCK_SIZE, true);

error:
	if (plain_text == out)
		qdf_mem_free(buf);
	return ret;
}

QDF_STATUS aead_encrypt_assoc_req(struct mac_context *mac_ctx,
				  struct pe_session *pe_session,
				  uint8_t *frm, uint32_t *frm_len)
{
	uint8_t *plain_text = NULL, *data;
	uint32_t plain_text_len = 0, data_len;
	QDF_STATUS status;
	struct pe_fils_session *fils_info = pe_session->fils_info;

	/*
	 * data is the packet data after MAC header till
	 * FILS session IE(inclusive)
	 */
	data = frm + sizeof(tSirMacMgmtHdr);

	/*
	 * plain_text is the packet data after FILS session IE
	 * which needs to be encrypted. Get plain_text ptr and
	 * plain_text_len values using find_ptr_aft_fils_session_ie()
	 */
	status = find_ie_data_after_fils_session_ie(mac_ctx, data +
					      FIXED_PARAM_OFFSET_ASSOC_REQ,
					      (*frm_len -
					      FIXED_PARAM_OFFSET_ASSOC_REQ),
					      &plain_text, &plain_text_len);
	if (QDF_IS_STATUS_ERROR(status)) {
		pe_err("Could not find FILS session IE");
		return QDF_STATUS_E_FAILURE;
	}
	data_len = ((*frm_len) - plain_text_len);

	lim_fils_data_dump("Plain text: ", plain_text, plain_text_len);

	/* Overwrite the AEAD encrypted output @ plain_text */
	if (fils_aead_encrypt(fils_info->kek, fils_info->kek_len,
			      pe_session->selfMacAddr, pe_session->bssId,
			      fils_info->fils_nonce,
			      fils_info->auth_info.fils_nonce,
			      data, data_len, plain_text, plain_text_len,
			      plain_text)) {
		pe_err("AEAD Encryption fails!");
		return QDF_STATUS_E_FAILURE;
	}

	/*
	 * AEAD encrypted output(cipher_text) will have length equals to
	 * plain_text_len + AES_BLOCK_SIZE(AEAD encryption header info).
	 * Add this to frm_len
	 */
	(*frm_len) += (AES_BLOCK_SIZE);

	return QDF_STATUS_SUCCESS;
}

/**
 * fils_aead_decrypt() - API to do AEAD decryption
 *
 * @kek: Pointer to KEK
 * @kek_len: KEK length
 * @own_mac: Pointer to own MAC address
 * @bssid: Bssid
 * @snonce: Supplicant Nonce
 * @anonce: Authenticator Nonce
 * @data: Pointer to data after MAC header
 * @data_len: length of @data
 * @plain_text: Pointer to data after FILS Session IE
 * @plain_text_len: length of @plain_text
 * @out: Pointer to the encrypted data
 *
 * Return: zero on success, error otherwise
 */
static int fils_aead_decrypt(const uint8_t *kek, unsigned int kek_len,
			     const uint8_t *own_mac, const uint8_t *bssid,
			     const uint8_t *snonce, const uint8_t *anonce,
			     const uint8_t *data, size_t data_len,
			     uint8_t *ciphered_text, size_t ciphered_text_len,
			     uint8_t *plain_text)
{
	const uint8_t *aad[6];
	size_t aad_len[6];
	uint8_t *buf;
	size_t buf_len;
	uint8_t v[AES_BLOCK_SIZE];
	uint8_t siv[AES_BLOCK_SIZE];
	int ret;

	/* SIV Encrypt/Decrypt takes input key of length 256, 384 or 512 bits */
	if (kek_len != 32 && kek_len != 48 && kek_len != 64) {
		QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_ERROR,
			  FL("Invalid key length: %u"), kek_len);
		return -EINVAL;
	}

	if (own_mac == NULL || bssid == NULL || snonce == NULL ||
	    anonce == NULL || data_len == 0 || ciphered_text_len == 0 ||
	    plain_text == NULL) {
		QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_ERROR,
			  FL("Error missing params mac:%pK bssid:%pK snonce:%pK anonce:%pK data_len:%zu ciphered_text_len:%zu plain_text:%pK"),
			  own_mac, bssid, snonce, anonce, data_len,
			  ciphered_text_len, plain_text);
		return -EINVAL;
	}

	qdf_mem_copy(v, ciphered_text, AES_BLOCK_SIZE);
	qdf_mem_copy(siv, ciphered_text, AES_BLOCK_SIZE);
	v[12] &= 0x7F;
	v[8] &= 0x7F;

	buf_len = ciphered_text_len - AES_BLOCK_SIZE;
	if (ciphered_text == plain_text) {
		/* in place decryption */
		buf = qdf_mem_malloc(buf_len);
		if (!buf)
			return -ENOMEM;
		qdf_mem_copy(buf, ciphered_text + AES_BLOCK_SIZE, buf_len);
	} else {
		buf = ciphered_text + AES_BLOCK_SIZE;
	}

	/* AES-SIV CTR */
	/* K2 = rightmost(K, len(K)/2) */
	ret = qdf_aes_ctr(kek + kek_len/2, kek_len/2, v, buf, buf_len,
			  plain_text, false);
	if (ret)
		goto error;

	aad[0] = bssid;
	aad_len[0] = QDF_MAC_ADDR_SIZE;
	aad[1] = own_mac;
	aad_len[1] = QDF_MAC_ADDR_SIZE;
	aad[2] = anonce;
	aad_len[2] = SIR_FILS_NONCE_LENGTH;
	aad[3] = snonce;
	aad_len[3] = SIR_FILS_NONCE_LENGTH;
	aad[4] = data;
	aad_len[4] = data_len;
	aad[5] = plain_text;
	aad_len[5] = buf_len;

	/* AES-SIV S2V */
	/* K1 = leftmost(K, len(K)/2) */
	ret = qdf_aes_s2v(kek, kek_len/2, aad, aad_len, 6, v);
	if (ret)
		goto error;

	/* compare the iv generated against the one sent by AP */
	if (memcmp(v, siv, AES_BLOCK_SIZE) != 0) {
		QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_ERROR,
			  FL("siv not same as frame siv"));
		ret = -EINVAL;
	}

error:
	if (ciphered_text == plain_text)
		qdf_mem_free(buf);
	return ret;
}

QDF_STATUS aead_decrypt_assoc_rsp(struct mac_context *mac_ctx,
				  struct pe_session *session,
				  tDot11fAssocResponse *ar,
				  uint8_t *p_frame, uint32_t *n_frame)
{
	QDF_STATUS status;
	uint32_t data_len, fils_ies_len;
	uint8_t *fils_ies;
	struct pe_fils_session *fils_info = session->fils_info;

	status = find_ie_data_after_fils_session_ie(mac_ctx, p_frame +
					      FIXED_PARAM_OFFSET_ASSOC_RSP,
					      ((*n_frame) -
					      FIXED_PARAM_OFFSET_ASSOC_RSP),
					      &fils_ies, &fils_ies_len);
	if (!QDF_IS_STATUS_SUCCESS(status)) {
		pe_err("FILS session IE not present");
		return status;
	}

	data_len = (*n_frame) - fils_ies_len;

	if (fils_aead_decrypt(fils_info->kek, fils_info->kek_len,
			      session->selfMacAddr, session->bssId,
			      fils_info->fils_nonce,
			      fils_info->auth_info.fils_nonce,
			      p_frame, data_len,
			      fils_ies, fils_ies_len, fils_ies)){
		pe_err("AEAD decryption fails");
		return QDF_STATUS_E_FAILURE;
	}

	/* Dump the output of AEAD decrypt */
	lim_fils_data_dump("Plain text: ", fils_ies,
			   fils_ies_len - AES_BLOCK_SIZE);

	(*n_frame) -= AES_BLOCK_SIZE;
	return status;
}

void lim_update_fils_rik(struct pe_session *pe_session,
			 tSirRoamOffloadScanReq *req_buffer)
{
	struct pe_fils_session *pe_fils_info = pe_session->fils_info;
	struct roam_fils_params *roam_fils_params =
		&req_buffer->roam_fils_params;

	/*
	 * If it is first connection, LIM session entries will not be
	 * set with FILS. However in RSO, CSR filled the RRK, realm
	 * info and is_fils_connection to true in req_buffer, RIK
	 * can be created with RRK and send all the FILS info to fw
	 */
	if ((!lim_is_fils_connection(pe_session) ||
	     !pe_fils_info) && (req_buffer->is_fils_connection)) {
		if (roam_fils_params->rrk_length > FILS_MAX_RRK_LENGTH) {
			pe_debug("FILS rrk len(%d) max (%d)",
				 roam_fils_params->rrk_length,
				 FILS_MAX_RRK_LENGTH);
			return;
		}

		lim_create_fils_rik(roam_fils_params->rrk,
				    roam_fils_params->rrk_length,
				    roam_fils_params->rik,
				    &roam_fils_params->rik_length);
		pe_debug("Fils created rik len %d",
					roam_fils_params->rik_length);
		return;
	}

	if (!pe_fils_info) {
		pe_debug("No FILS info available in the session");
		return;
	}
	if ((pe_fils_info->fils_rik_len > FILS_MAX_RIK_LENGTH) ||
	    !pe_fils_info->fils_rik) {
		pe_err("Fils rik len(%d) max %d", pe_fils_info->fils_rik_len,
				FILS_MAX_RIK_LENGTH);
		return;
	}

	roam_fils_params->rik_length = pe_fils_info->fils_rik_len;
	qdf_mem_copy(roam_fils_params->rik, pe_fils_info->fils_rik,
			roam_fils_params->rik_length);
	pe_debug("fils rik len %d", roam_fils_params->rik_length);
}
#endif
