/*
 * This file is part of the UWB stack for linux.
 *
 * Copyright (c) 2020-2022 Qorvo US, Inc.
 *
 * This software is provided under the GNU General Public License, version 2
 * (GPLv2), as well as under a Qorvo commercial license.
 *
 * You may choose to use this software under the terms of the GPLv2 License,
 * version 2 ("GPLv2"), as published by the Free Software Foundation. You should
 * have received a copy of the GPLv2 along with this program.  If not, see
 * <http://www.gnu.org/licenses/>.
 *
 * This program is distributed under the GPLv2 in the hope that it will be
 * useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GPLv2 for more
 * details.
 *
 * If you cannot meet the requirements of the GPLv2, you may not use this
 * software for any purpose without first obtaining a commercial license from
 * Qorvo. Please contact Qorvo to inquire about licensing terms.
 */

#ifdef __KERNEL__
#define pr_fmt(fmt) "%s:%s: " fmt, KBUILD_MODNAME, __func__
#endif

#include <linux/errno.h>
#include <linux/string.h>
#include <linux/kernel.h>
#include <linux/list.h>
#include <linux/module.h>
#include <linux/mutex.h>
#include <crypto/aes.h>

#include <asm/unaligned.h>

#include "fira_crypto.h"
#include <net/mcps802154_frame.h>
#include "mcps_crypto.h"

#ifdef CONFIG_FIRA_CRYPTO_HAVE_SE
#include "key_manager.h"
#endif

#ifdef __KERNEL__
static inline void *platform_malloc(size_t s) { return kmalloc(s, GFP_KERNEL); }
static inline void platform_free(void *p) { kfree(p); }
#else
#include "trace/define_trace_specific.h"
#define pr_info(...) print_trace(__VA_ARGS__)
#define pr_err(...) print_trace(__VA_ARGS__)
#include "platform_alloc.h"
#endif

#define FIRA_CRYPTO_KDF_LABEL_LEN	8
#define FIRA_CRYPTO_KDF_CONTEXT_LEN	16
#define FIRA_CRYPTO_KEY_STS_MASK	0x7FFFFFFF

#define FIRA_IE_VENDOR_OUI_LEN		3

#define FIRA_CRYPTO_AEAD_AUTHSIZE	8

/**
 * struct fira_crypto_aead - Context for payload encryption/decryption.
 */
struct fira_crypto_aead {
	/**
	 * @ctx: The context to be used during aead encryption & decryption.
	 */
	struct mcps_aes_ccm_star_128_ctx *ctx;
};

/**
 * struct fira_crypto - Context containing all crypto related
 * information.
 *
 * NOTE: It is regularly used by the FiRa region core to produce the STS
 * parameters for a given a session and to encrypt/decrypt frames.
 */
struct fira_crypto_base {
	/**
	 * @key_size: Size of the key used in the AES derivation.
	 */
	u8 key_size;

	/**
	 * @config_digest: Digest of the configuration, used as input for keys
	 * derivation.
	 */
	u8 config_digest[AES_BLOCK_SIZE];

	/**
	 * @data_protection_key: Derived from the session key, the label
	 * "DataPrtK" and the config_digest. The precise size is given by the
	 * key_size.
	 */
	u8 data_protection_key[FIRA_KEY_SIZE_MIN];

	/**
	 * @derived_authentication_iv: Derived from data_protection_key, the
	 * label "DerAuthI", the current value of crypto_sts_index, and the
	 * config_digest. Used to compute the STS parameters for a slot.
	 */
	u8 derived_authentication_iv[AES_BLOCK_SIZE];

	/**
	 * @derived_authentication_key: Derived from data_protection_key, the
	 * label "DerAuthK", the current value of crypto_sts_index and the
	 * config_digest. Used to compute the STS parameters for a slot.
	 */
	u8 derived_authentication_key[FIRA_KEY_SIZE_MIN];

	/**
	 * @derived_payload_key: Derived from data_protection_key, the label
	 * "DerPaylK", the current value of crypto_sts_index and the
	 * config_digest. Used to encrypt/decrypt message PIE.
	 */
	u8 derived_payload_key[FIRA_KEY_SIZE_MIN];

	/**
	 * @aead: AEAD Context for payload encryption/decryption.
	 */
	struct fira_crypto_aead aead;
};

struct fira_crypto {
	/**
	 * @phy_sts_index_init: Initial phy_sts_index deduced at context init.
	 */
	u32 phy_sts_index_init;
	/**
	 * @sts_config: The type of STS requested for this crypto.
	 */
	enum fira_sts_mode sts_config;

	/**
	 * @base: Common parameters between all types of crypto contexts.
	 */
	struct fira_crypto_base base;

	/******* Dynamic STS Only **************/

	/**
	 * @ecb_ctx: AES ECB context
	 */
	struct mcps_aes_ecb_128_ctx *ecb_ctx;

	/**
	 * @privacy_key: Derived from the session key, the label
	 * "PrivacyK" and the config_digest. Used to encrypt/decrypt message HIE.
	 */
	u8 privacy_key[FIRA_KEY_SIZE_MIN];

	/******* Static STS Only **************/
	/**
	 * @vupper64: The vupper 64 to use when static STS is used.
	 */
	u8 vupper64[FIRA_VUPPER64_SIZE];
};

static int fira_crypto_kdf(const u8 *input_key, unsigned int input_key_len,
			const char *label, const u8 *context, u8 *output_key,
			unsigned int output_key_len)
{
	u8 derivation_data[sizeof(u32) + FIRA_CRYPTO_KDF_LABEL_LEN +
		FIRA_CRYPTO_KDF_CONTEXT_LEN + sizeof(u32)];
	u8 *p;
	int r;

	if (input_key_len != AES_KEYSIZE_128) {
		pr_err("input_key_len != AES_KEYSIZE_128");
		return -EINVAL;
	}

	p = derivation_data;
	put_unaligned_be32(1, p);
	p += sizeof(u32);
	memcpy(p, label, FIRA_CRYPTO_KDF_LABEL_LEN);
	p += FIRA_CRYPTO_KDF_LABEL_LEN;
	memcpy(p, context, FIRA_CRYPTO_KDF_CONTEXT_LEN);
	p += FIRA_CRYPTO_KDF_CONTEXT_LEN;
	put_unaligned_be32(output_key_len * 8, p);

	r = mcps_crypto_cmac_aes_128_digest(input_key, derivation_data,
			sizeof(derivation_data), output_key);

	return r;
}

static int fira_crypto_aead_set_key(struct fira_crypto_aead *aead, const u8 *key)
{
	aead->ctx = mcps_crypto_aead_aes_ccm_star_128_create();

	return aead->ctx ? mcps_crypto_aead_aes_ccm_star_128_set(aead->ctx, key) : -ENOMEM;
}

static void fira_aead_fill_nonce(u8 *nonce, __le16 src_short_addr,
				 u32 crypto_sts_index)
{
	u8 *p;

	p = nonce;
	memset(p, 0, IEEE802154_EXTENDED_ADDR_LEN - IEEE802154_SHORT_ADDR_LEN);
	p += IEEE802154_EXTENDED_ADDR_LEN - IEEE802154_SHORT_ADDR_LEN;
	put_unaligned_be16(src_short_addr, p);
	p += IEEE802154_SHORT_ADDR_LEN;
	put_unaligned_be32(crypto_sts_index, p);
	p += sizeof(u32);
	*p++ = IEEE802154_SCF_SECLEVEL_ENC_MIC64;
}

static int fira_crypto_aead_encrypt(struct fira_crypto_aead *aead,
		struct sk_buff *skb, unsigned int header_len,
		__le16 src_short_addr, u32 crypto_sts_index)
{
	u8 nonce[MCPS_CRYPTO_AES_CCM_STAR_NONCE_LEN];
	u8 *header = skb->data;
	u8 *payload = skb->data + header_len;
	const int payload_len = skb->len - header_len;
	u8 *mac = skb->data + skb->len;
	int r;

	fira_aead_fill_nonce(nonce, src_short_addr, crypto_sts_index);

	skb->data[IEEE802154_FC_LEN + IEEE802154_SHORT_ADDR_LEN] =
		IEEE802154_SCF_SECLEVEL_ENC_MIC64 |
		IEEE802154_SCF_NO_FRAME_COUNTER;

	r = mcps_crypto_aead_aes_ccm_star_128_encrypt(
		aead->ctx, nonce, header, header_len, payload, payload_len, mac,
		FIRA_CRYPTO_AEAD_AUTHSIZE);

	if (!r)
		skb_put(skb, FIRA_CRYPTO_AEAD_AUTHSIZE);

	return r;
}

static int fira_crypto_aead_decrypt(struct fira_crypto_aead *aead,
		struct sk_buff *skb, unsigned int header_len,
		__le16 src_short_addr, u32 crypto_sts_index)
{
	u8 nonce[MCPS_CRYPTO_AES_CCM_STAR_NONCE_LEN];
	u8 *header;
	u8 *payload;
	unsigned int payload_len;
	u8 *mac;
	int r;

	header = skb->data - header_len;
	payload = skb->data;
	payload_len = skb->len;
	mac = skb->data + payload_len;

	fira_aead_fill_nonce(nonce, src_short_addr, crypto_sts_index);

	r = mcps_crypto_aead_aes_ccm_star_128_decrypt(
		aead->ctx, nonce, header, header_len, payload, payload_len, mac,
		FIRA_CRYPTO_AEAD_AUTHSIZE);

	if (!r) {
		header[IEEE802154_FC_LEN + IEEE802154_SHORT_ADDR_LEN] |=
			IEEE802154_SCF_NO_FRAME_COUNTER;
	}

	memzero_explicit(mac, FIRA_CRYPTO_AEAD_AUTHSIZE);

	return r;
}

static void fira_crypto_aead_destroy(struct fira_crypto_aead *aead)
{
	mcps_crypto_aead_aes_ccm_star_128_destroy(aead->ctx);
	aead->ctx = NULL;
}

static void remove_session(struct fira_crypto *session)
{
	fira_crypto_aead_destroy(&session->base.aead);
	mcps_crypto_aes_ecb_128_destroy(session->ecb_ctx);
	/* Wipe all derived keys */
	memzero_explicit(session, sizeof(*session));
	platform_free(session);
}

/*! ----------------------------------------------------------------------------------------------
 * @brief This function is used to initialise the FIRA crypto backend
 *
 * input parameters:
 * @param key_manager - key manager to use. Not used for the moment.
 *
 * output parameters
 *
 * return 0 if no error.
 */
int fira_crypto_init(void *key_manager)
{
#ifdef CONFIG_FIRA_CRYPTO_HAVE_SE
	/* Opens the UBWS - SE secure channel */
	return key_manager_init(NULL);
#else
	return 0;
#endif
}

/************************************** FIRA STS API FCTS ***************************************/

int fira_crypto_context_init(const struct fira_crypto_params *crypto_params,
		struct fira_crypto **crypto)
{
	int status = 0;
	struct fira_crypto *fira_crypto_ctx;
	u8 session_key[AES_KEYSIZE_128];

	fira_crypto_ctx = platform_malloc(sizeof(*fira_crypto_ctx));

	if (!fira_crypto_ctx)
		return -ENOMEM;

	memset(fira_crypto_ctx, 0, sizeof(*fira_crypto_ctx));

	/* Retrieve session key */
	switch (crypto_params->sts_config) {
	case FIRA_STS_MODE_STATIC:
		memcpy(session_key, "StaticTSStaticTS", AES_KEYSIZE_128);
		fira_crypto_ctx->base.key_size = AES_KEYSIZE_128;
		memcpy(fira_crypto_ctx->vupper64, crypto_params->vupper64, FIRA_VUPPER64_SIZE);
		break;

	case FIRA_STS_MODE_PROVISIONED:
	case FIRA_STS_MODE_PROVISIONED_INDIVIDUAL_KEY:
		if (crypto_params->key) {
			memcpy(session_key, crypto_params->key, crypto_params->key_len);
			fira_crypto_ctx->base.key_size = crypto_params->key_len;
		} else {
			/* Session key not set */
			pr_err("Session key not provisioned !\n");
			status = -1;
		}
		break;

	default:
		/* Bad value */
		pr_err("STS config unknown !\n");
		status = -1;
	}

	fira_crypto_ctx->sts_config = crypto_params->sts_config;

	if (!status) {
		/* Compute Config Digest */
		static const u8 zero_key[AES_KEYSIZE_128];

		status = mcps_crypto_cmac_aes_128_digest(zero_key,
				crypto_params->concat_params,
				crypto_params->concat_params_size,
				fira_crypto_ctx->base.config_digest);
		if (status)
			goto error_out;

		/* Compute secDataProtectionKey */
		status = fira_crypto_kdf(session_key,
				fira_crypto_ctx->base.key_size,
				"DataPrtK",
				fira_crypto_ctx->base.config_digest,
				fira_crypto_ctx->base.data_protection_key,
				FIRA_KEY_SIZE_MIN);
		if (status)
			goto error_out;

		if (crypto_params->sts_config == FIRA_STS_MODE_STATIC) {
			/* rotate keys only once for static_sts */
			status = fira_crypto_rotate_elements(
					fira_crypto_ctx,
					0);
		} else {

			/* Compute secPrivacy Key and setup AES ECB context */
			status = fira_crypto_kdf(
				session_key, fira_crypto_ctx->base.key_size,
				"PrivacyK", fira_crypto_ctx->base.config_digest,
				fira_crypto_ctx->privacy_key,
				FIRA_KEY_SIZE_MIN);
		}
		if (status)
			goto error_out;
	}

	/* Wipe session key */
	memzero_explicit(session_key, AES_KEYSIZE_128);

	*crypto = fira_crypto_ctx;

	return status;

error_out:
	/* Wipe session key */
	memzero_explicit(session_key, AES_KEYSIZE_128);
	*crypto = NULL;
	remove_session(fira_crypto_ctx);
	return status;
}

/**
 * fira_crypto_context_deinit() - De-initialize a crypto context.
 * @session_id: Pointer to the session id.
 */
void fira_crypto_context_deinit(struct fira_crypto *fira_crypto_ctx)
{
	if (fira_crypto_ctx) {
		/* Remove the context */
		remove_session(fira_crypto_ctx);
		fira_crypto_ctx = NULL;
	} else {
		/* The context doesn't exist */
		pr_err("Crypto context NULL\n");
	}
}

/**
 * fira_crypto_rotate_elements() - Rotate the crypto elements contained in the
 * crypto context.
 *
 * NOTE: After calling this function, all active crypto elements will be the latest
 * rotated ones.
 *
 * @crypto: The context containing the elements to rotate.
 * @crypto_sts_index: The crypto STS index to use to rotate the elements.
 *
 * Return: 0 or error.
 */
int fira_crypto_rotate_elements(struct fira_crypto *fira_crypto_ctx,
				const u32 crypto_sts_index)
{
	int r = 0;
	u8 context[AES_BLOCK_SIZE];

	if (!fira_crypto_ctx)
		goto error_out;

	memcpy(context, fira_crypto_ctx->base.config_digest + sizeof(u32),
			AES_BLOCK_SIZE - sizeof(u32));
	put_unaligned_be32(crypto_sts_index, context + AES_BLOCK_SIZE -
			sizeof(u32));

	r = fira_crypto_kdf(fira_crypto_ctx->base.data_protection_key,
			fira_crypto_ctx->base.key_size,
			"DerAuthI", context,
			fira_crypto_ctx->base.derived_authentication_iv,
			fira_crypto_ctx->base.key_size);
	if (r)
		goto error_out;

	r = fira_crypto_kdf(fira_crypto_ctx->base.data_protection_key,
			fira_crypto_ctx->base.key_size,
			"DerAuthK", context,
			fira_crypto_ctx->base.derived_authentication_key,
			fira_crypto_ctx->base.key_size);
	if (r)
		goto error_out;

	r = fira_crypto_kdf(fira_crypto_ctx->base.data_protection_key,
			fira_crypto_ctx->base.key_size,
			"DerPaylK", context,
			fira_crypto_ctx->base.derived_payload_key,
			fira_crypto_ctx->base.key_size);
	if (r)
		goto error_out;

	if (fira_crypto_ctx->base.aead.ctx == NULL)
		r = fira_crypto_aead_set_key(&fira_crypto_ctx->base.aead,
				fira_crypto_ctx->base.derived_payload_key);

error_out:
	memzero_explicit(context, sizeof(context));
	return r;
}

u32 fira_crypto_get_phy_sts_index_init(const struct fira_crypto *crypto)
{
	if (!crypto)
		return -1;
	return crypto->phy_sts_index_init;
}

/**
 * fira_crypto_build_phy_sts_index_init() - Build the phy STS index init value
 * related to the given crypto context.
 *
 * @crypto: The context to use to compute the phy STS index init value.
 *
 * Return: 0 or error.
 */
int fira_crypto_build_phy_sts_index_init(struct fira_crypto *fira_crypto_ctx)
{
	int r = -1;
	u8 phy_sts_index_init_tmp[AES_KEYSIZE_128];

	if (!fira_crypto_ctx)
		goto error_out;

	r = fira_crypto_kdf(fira_crypto_ctx->base.data_protection_key,
			fira_crypto_ctx->base.key_size,
			"StsIndIn", fira_crypto_ctx->base.config_digest,
			phy_sts_index_init_tmp,
			fira_crypto_ctx->base.key_size);
	if (r)
		goto error_out;

	fira_crypto_ctx->phy_sts_index_init =
		get_unaligned_be32(phy_sts_index_init_tmp +
				fira_crypto_ctx->base.key_size - sizeof(u32)) &
				FIRA_CRYPTO_KEY_STS_MASK;
	return 0;

error_out:
	memzero_explicit(phy_sts_index_init_tmp,
			 sizeof(phy_sts_index_init_tmp));
	return r;

}

/**
 * fira_crypto_dynamic_get_sts_params() - Get STS parameters for a given slot
 * using a dynamic STS configuration.
 * @crypto: The context to use to get the STS parameters.
 * @crypto_sts_index: The crypto STS index related to the slot request slot.
 * @sts_v: Output buffer to store the STS V.
 * @sts_v_size: Size of the STS V buffer.
 * @sts_key: Output buffer to store the STS key.
 * @sts_key_size: Size of the STS key buffer.
 *
 * Return: 0 or error.
 */
int fira_crypto_get_sts_params(struct fira_crypto *fira_crypto_ctx,
		const u32 crypto_sts_index, u8 *sts_v, u32 sts_v_size,
		u8 *sts_key, u32 sts_key_size)
{
	u8 *vupper64 = NULL;
	u32 v_counter;
	u8 *sts_v_temp;

	if (!fira_crypto_ctx)
		return -1;

	if (fira_crypto_ctx->sts_config == FIRA_STS_MODE_STATIC)
		vupper64 = fira_crypto_ctx->vupper64;
	else
		vupper64 = fira_crypto_ctx->base.derived_authentication_iv;

	if (sts_v_size < AES_BLOCK_SIZE || sts_key_size < AES_KEYSIZE_128)
		return -EINVAL;

	sts_v_temp = sts_v;

	/* Concatenate the 128 bits of sts_v
	 * sts_v = vupper64 | crypto_sts_index | v_counter
	 */
	memcpy(sts_v_temp, vupper64, FIRA_VUPPER64_SIZE);
	sts_v_temp += FIRA_VUPPER64_SIZE;
	put_unaligned_be32(crypto_sts_index, sts_v_temp);
	sts_v_temp += sizeof(crypto_sts_index);
	v_counter = get_unaligned_be32(
			fira_crypto_ctx->base.derived_authentication_iv +
			AES_BLOCK_SIZE - sizeof(v_counter)) &
		FIRA_CRYPTO_KEY_STS_MASK;
	put_unaligned_be32(v_counter, sts_v_temp);

	memcpy(sts_key, fira_crypto_ctx->base.derived_authentication_key,
			fira_crypto_ctx->base.key_size);

	return 0;
}

/**
 * fira_crypto_encrypt_frame() - Encrypt a 802154 frame using a given context.
 *
 * NOTE: The src address is given as an argument as it is a part of the nonce needed
 * to encrypt the frame and it is not present in the 802154 frame.
 * The length of the header is given because only the payload is encrypted even if
 * the encryption algorithm needs the whole 802154 frame.
 * Encryption is done in-place.
 * When called this function shall increase the size of the skb of
 * FIRA_CRYPTO_AEAD_AUTHSIZE and set the correct bits in the 802154 frame SCF.
 *
 * @crypto: The context to use to encrypt the frame.
 * @skb: The buffer containing the whole frame, skb->data points to the start of
 * the 802154 frame header.
 * @header_len: The length of the 802154 frame header. Can be used to find the
 * position of the 802154 frame payload relative to skb->data.
 * @src_short_addr: The short source address attached to the frame.
 * @crypto_sts_index: The crypto STS index attached to the frame.
 *
 * Return: 0 or error.
 */
int fira_crypto_encrypt_frame(struct fira_crypto *fira_crypto_ctx, struct sk_buff *skb,
		int header_len, __le16 src_short_addr, u32 crypto_sts_index)
{
	if (!fira_crypto_ctx)
		return -1;

	return fira_crypto_aead_encrypt(&fira_crypto_ctx->base.aead, skb, header_len,
					src_short_addr, crypto_sts_index);
}

/**
 * fira_crypto_decrypt_frame() - Decrypt a 802154 frame using a given context.
 *
 * NOTE: The src address is given as an argument as it is a part of the nonce needed
 * to decrypt the frame and it is not present in the 802154 frame.
 * The length of the header is given because only the payload is encrypted even if
 * the encryption algorithm needs the whole 802154 frame.
 * Decryption is done in-place.
 * When called, this function shall reduce the
 * size of the skb of FIRA_CRYPTO_AEAD_AUTHSIZE and verify the correct bits in the
 * 802154 frame SCF.
 *
 * @crypto: The crypto to use to decrypt the frame.
 * @skb: The buffer containing the whole frame, skb->data points to the start of
 * the 802154 frame payload.
 * @header_len: The length of the 802154 frame header. Can be used to find the
 * start of the 802154 frame payload relative to skb->data.
 * @src_short_addr: The short source address attached to the frame.
 * @crypto_sts_index: The crypto STS index attached to the frame.
 *
 * Return: 0 or error.
 */
int fira_crypto_decrypt_frame(struct fira_crypto *fira_crypto_ctx, struct sk_buff *skb,
		int header_len, __le16 src_short_addr, u32 crypto_sts_index)
{
	if (!fira_crypto_ctx)
		return -1;

	return fira_crypto_aead_decrypt(&fira_crypto_ctx->base.aead, skb, header_len,
					src_short_addr, crypto_sts_index);
}

/**
 * fira_crypto_encrypt_hie() - Encrypt the HIE in a FiRa 802154 frame.
 * @crypto: The context to use to get the STS parameters.
 * @skb: Buffer containing the frame to encrypt.
 * @hie_offset: Offset to the start of the HIE (relating to skb->data) to encrypt.
 * @hie_len: Length of the HIE to encrypt.
 *
 * Return: 0 or error.
 */
int fira_crypto_encrypt_hie(struct fira_crypto *fira_crypto_ctx, struct sk_buff *skb,
		int hie_offset, int hie_len)
{
	int rc;

	if (!fira_crypto_ctx)
		return -1;

	if (fira_crypto_ctx->sts_config == FIRA_STS_MODE_STATIC)
		return 0;

	fira_crypto_ctx->ecb_ctx = mcps_crypto_aes_ecb_128_create();
	if (!fira_crypto_ctx->ecb_ctx ||
		mcps_crypto_aes_ecb_128_set_encrypt(
			fira_crypto_ctx->ecb_ctx,
			fira_crypto_ctx->privacy_key))
		return -1;

	rc = mcps_crypto_aes_ecb_128_encrypt(fira_crypto_ctx->ecb_ctx,
			(const uint8_t *)(skb->data + hie_offset +
				IEEE802154_IE_HEADER_LEN +
				FIRA_IE_VENDOR_OUI_LEN),
			(unsigned int)hie_len - IEEE802154_IE_HEADER_LEN -
				FIRA_IE_VENDOR_OUI_LEN,
			(uint8_t *)(skb->data + hie_offset +
				IEEE802154_IE_HEADER_LEN +
				FIRA_IE_VENDOR_OUI_LEN));

	mcps_crypto_aes_ecb_128_destroy(fira_crypto_ctx->ecb_ctx);
	fira_crypto_ctx->ecb_ctx = NULL;

	return rc;
}

/**
 * fira_crypto_decrypt_hie() - Decrypt the HIE in a FiRa 802154 frame.
 * @crypto: The context to use to get the STS parameters.
 * @skb: Buffer containing the frame to decrypt.
 * @hie_offset: Offset to the start of the HIE (relative to skb->data) to decrypt.
 * @hie_len: Length of the HIE to decrypt.
 *
 * Return: 0 or error.
 */
int fira_crypto_decrypt_hie(struct fira_crypto *fira_crypto_ctx, struct sk_buff *skb,
		int hie_offset, int hie_len)
{
	int rc;

	if (!fira_crypto_ctx)
		return -1;

	if (fira_crypto_ctx->sts_config == FIRA_STS_MODE_STATIC)
		return 0;

	fira_crypto_ctx->ecb_ctx = mcps_crypto_aes_ecb_128_create();
	if (!fira_crypto_ctx->ecb_ctx ||
			mcps_crypto_aes_ecb_128_set_decrypt(
				fira_crypto_ctx->ecb_ctx,
				fira_crypto_ctx->privacy_key))
		return -1;

	rc = mcps_crypto_aes_ecb_128_encrypt(fira_crypto_ctx->ecb_ctx,
			(const uint8_t *)(skb->data + hie_offset),
			(unsigned int)hie_len,
			(uint8_t *)(skb->data + hie_offset));

	mcps_crypto_aes_ecb_128_destroy(fira_crypto_ctx->ecb_ctx);
	fira_crypto_ctx->ecb_ctx = NULL;

	return rc;
}

/**
 * fira_crypto_get_capabilities() - Get capabilities of the platform used.
 *
 * Return:
 *    bit 0 : FIRA_STS_MODE_STATIC supported
 *    bit 1 : FIRA_STS_MODE_DYNAMIC supported
 *    bit 2 : FIRA_STS_MODE_DYNAMIC_INDIVIDUAL_KEY supported
 *    bit 3 : FIRA_STS_MODE_PROVISIONED supported
 *    bit 4 : FIRA_STS_MODE_PROVISIONED_INDIVIDUAL_KEY supported
 *    other : not used
 */
u32 fira_crypto_get_capabilities(void)
{
	u32 status = 0;

	status += STS_CAP(STATIC);
	status += STS_CAP(PROVISIONED);
	status += STS_CAP(PROVISIONED_INDIVIDUAL_KEY);

#ifdef CONFIG_FIRA_CRYPTO_HAVE_SE
	status += STS_CAP(DYNAMIC);
#endif

	return status;
}

int fira_crypto_prepare_decrypt(struct fira_crypto *crypto, struct sk_buff *skb)
{
	u8 scf;
	u8 *p;

	p = skb->data - (IEEE802154_FC_LEN + IEEE802154_SHORT_ADDR_LEN +
			 IEEE802154_SCF_LEN);
	scf = p[IEEE802154_FC_LEN + IEEE802154_SHORT_ADDR_LEN];
	if (!(scf == (IEEE802154_SCF_SECLEVEL_ENC_MIC64 |
		      IEEE802154_SCF_NO_FRAME_COUNTER)) ||
	    (skb->len < FIRA_CRYPTO_AEAD_AUTHSIZE))
		return -EBADMSG;
	skb_trim(skb, skb->len - FIRA_CRYPTO_AEAD_AUTHSIZE);

	return 0;
}

static bool compare_bufs(const void *a, size_t alen, const void *b, size_t blen)
{
	if (alen != blen || memcmp(a, b, alen) != 0) {
#ifdef __KERNEL__
		print_hex_dump(KERN_ERR, "a: ", DUMP_PREFIX_OFFSET, 16, 1, a,
				alen, false);
		print_hex_dump(KERN_ERR, "b: ", DUMP_PREFIX_OFFSET, 16, 1, b,
				blen, false);
#endif
		return false;
	}

	return true;
}

/**
 * fira_crypto_test_static()
 * Run the FIRA CONSORTIUM UWB MAC TECHNICAL REQUIREMENTS
 * version 1.3.0 test vectors for Static STS
 *
 * NOTE: This APis used for unit tests only.
 *
 * Return: 0 if ok
 */
static int fira_crypto_test_static(void)
{
	/* Static STS */
	static const u8 config[] = {
		0x02, 0x00, 0x00, 0x09, 0x07, 0xd0, 0x00, 0x03,
		0x0a, 0x02, 0x00, 0x01, 0x03, 0x01, 0x23, 0x45,
		0x67
	};
	static const u8 vUpp[] = {0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07};
	static const struct fira_crypto_params param = {
		.session_id = 0x01234567,
		.sts_config = FIRA_STS_MODE_STATIC,
		.concat_params = config,
		.concat_params_size = sizeof(config),
		.vupper64 = vUpp
	};
	static const u8 configDigest[] = {
		0xa0, 0x43, 0x90, 0xcf, 0x8a, 0x33, 0xf6, 0xeb,
		0x7e, 0x2f, 0xc3, 0x78, 0x87, 0xb6, 0xb2, 0xa3
	};
	static const u8 secDataProtectionKey[] = {
		0xf3, 0x21, 0x6c, 0x87, 0xd0, 0xc6, 0x93, 0x2e,
		0x39, 0x57, 0xb4, 0x81, 0xfa, 0xb8, 0xb2, 0x09
	};
	static const u8 derived_authentication_iv[] = {
		0x8b, 0x54, 0x37, 0x6e, 0x7c, 0xd7, 0xa5, 0xd6,
		0x6b, 0xd1, 0x20, 0x00, 0x97, 0x27, 0x41, 0x19
	};
	static const u8 derived_authentication_key[] = {
		0xdd, 0x98, 0x97, 0xf2, 0xb8, 0x5c, 0x9d, 0xc8,
		0xa7, 0xde, 0xc0, 0x1c, 0xca, 0x5b, 0x61, 0xdb
	};
	static const u8 derived_payload_key[] = {
		0xa5, 0x5f, 0xab, 0x83, 0xb6, 0x20, 0xf9, 0xf6,
		0xa4, 0x7c, 0xdb, 0x72, 0x91, 0x7c, 0x73, 0x8a
	};
	static const u8 sts_v_ref[] = {
		0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
		0x00, 0x00, 0x00, 0x00, 0x17, 0x27, 0x41, 0x19
	};
	/* build the RCM Frame */
	/* build the header */
	static const u8 RCM[] = {
		0x49, 0x2b, 0xa2, 0xaa, 0x26, 0x13, 0x00, 0xff,
		0x18, 0x5a, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08,
		0x08, 0x08, 0x67, 0x45, 0x23, 0x01, 0x78, 0xbe,
		0x9b, 0x0b, 0x00, 0x3f, 0x1b, 0x90, 0xff, 0x18,
		0x5a, 0x03, 0x05, 0x00, 0x00, 0x03, 0x42, 0x55,
		0x01, 0x04, 0x44, 0x55, 0x03, 0x07, 0x42, 0x55,
		0x05, 0x09, 0x42, 0x55, 0x09, 0x0a, 0x44, 0x55,
		0x0b
	};
	static const u8 RCMRef[] = {
		0x49, 0x2b, 0xa2, 0xaa, 0x26, 0x13, 0x00, 0xff,
		0x18, 0x5a, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08,
		0x08, 0x08, 0x67, 0x45, 0x23, 0x01, 0x78, 0xbe,
		0x9b, 0x0b, 0x00, 0x3f, 0xcb, 0xa4, 0xfd, 0x37,
		0xd1, 0x99, 0x44, 0x88, 0x7c, 0x2b, 0xec, 0x2e,
		0x1a, 0x99, 0x8e, 0x80, 0x61, 0x7c, 0x44, 0xb5,
		0xe8, 0xe3, 0xf3, 0x35, 0x3a, 0xb9, 0xf2, 0x29,
		0x1b, 0x80, 0x4b, 0xba, 0xe1, 0xa9, 0x2a, 0x20,
		0x28
	};
	static const u8 Header[] = {
		0x49, 0x2b, 0xa2, 0xaa, 0x26, 0x13, 0x00, 0xff,
		0x18, 0x5a, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08,
		0x08, 0x08, 0x67, 0x45, 0x23, 0x01, 0x78, 0xbe,
		0x9b, 0x0b
	};
	static const u8 HeaderRef[] = {
		0x49, 0x2b, 0xa2, 0xaa, 0x26, 0x13, 0x00, 0xff,
		0x18, 0x5a, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08,
		0x08, 0x08, 0x67, 0x45, 0x23, 0x01, 0x78, 0xbe,
		0x9b, 0x0b
	};
	/* Decrypt Frame */
	static const u8 RCM_Rcv_Ref[] = {
		0x49, 0x2b, 0xa2, 0xaa, 0x26, 0x13, 0x00, 0xff,
		0x18, 0x5a, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08,
		0x08, 0x08, 0x67, 0x45, 0x23, 0x01, 0x78, 0xbe,
		0x9b, 0x0b, 0x00, 0x3f, 0x1b, 0x90, 0xff, 0x18,
		0x5a, 0x03, 0x05, 0x00, 0x00, 0x03, 0x42, 0x55,
		0x01, 0x04, 0x44, 0x55, 0x03, 0x07, 0x42, 0x55,
		0x05, 0x09, 0x42, 0x55, 0x09, 0x0a, 0x44, 0x55,
		0x0b
	};
	static const u8 Frame_Rcv[] = {
		0x49, 0x2b, 0xa2, 0xaa, 0x26, 0x13, 0x00, 0xff,
		0x18, 0x5a, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08,
		0x08, 0x08, 0x67, 0x45, 0x23, 0x01, 0x78, 0xbe,
		0x9b, 0x0b, 0x00, 0x3f, 0xcb, 0xa4, 0xfd, 0x37,
		0xd1, 0x99, 0x44, 0x88, 0x7c, 0x2b, 0xec, 0x2e,
		0x1a, 0x99, 0x8e, 0x80, 0x61, 0x7c, 0x44, 0xb5,
		0xe8, 0xe3, 0xf3, 0x35, 0x3a, 0xb9, 0xf2, 0x29,
		0x1b, 0x80, 0x4b, 0xba, 0xe1, 0xa9, 0x2a, 0x20,
		0x28
	};
	static const u8 Header_Rcv[] = {
		0x49, 0x2b, 0xa2, 0xaa, 0x26, 0x13, 0x00, 0xff,
		0x18, 0x5a, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08,
		0x08, 0x08, 0x67, 0x45, 0x23, 0x01, 0x78, 0xbe,
		0x9b, 0x0b
	};
	static const u8 HeaderRef_Rcv[] = {
		0x49, 0x2b, 0xa2, 0xaa, 0x26, 0x13, 0x00, 0xff,
		0x18, 0x5a, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08,
		0x08, 0x08, 0x67, 0x45, 0x23, 0x01, 0x78, 0xbe,
		0x9b, 0x0b
	};
	int err = -1, r;
	struct fira_crypto *fira_crypto_ctx;
	const u32 crypto_sts_index = 0;
	u8 sts_v[16];
	u8 sts_key[16];
	struct sk_buff *skb = NULL;

	r = fira_crypto_context_init(&param, &fira_crypto_ctx);
	if (r != 0 || !fira_crypto_ctx) {
		pr_err("fira_crypto_context_init fail: %d\n", r);
		goto end;
	}

	if (!compare_bufs(configDigest, sizeof(configDigest),
				fira_crypto_ctx->base.config_digest,
				sizeof(fira_crypto_ctx->base.config_digest))) {
		pr_err("compare configDigest fail\n");
		goto end;
	}

	if (!compare_bufs(secDataProtectionKey, sizeof(secDataProtectionKey),
				fira_crypto_ctx->base.data_protection_key,
				sizeof(fira_crypto_ctx->base.data_protection_key))) {
		pr_err("compare secDataProtectionKey fail\n");
		goto end;
	}

	if (!compare_bufs(derived_authentication_iv,
				sizeof(derived_authentication_iv),
				fira_crypto_ctx->base.derived_authentication_iv,
				sizeof(fira_crypto_ctx->base.derived_authentication_iv))) {
		pr_err("compare derived_authentication_iv fail\n");
		goto end;
	}

	if (!compare_bufs(derived_authentication_key,
				sizeof(derived_authentication_key),
				fira_crypto_ctx->base.derived_authentication_key,
				sizeof(fira_crypto_ctx->base.derived_authentication_key))) {
		pr_err("compare derived_authentication_key fail\n");
		goto end;
	}

	if (!compare_bufs(derived_payload_key, sizeof(derived_payload_key),
				fira_crypto_ctx->base.derived_payload_key,
				sizeof(fira_crypto_ctx->base.derived_payload_key))) {
		pr_err("compare derived_payload_key fail\n");
		goto end;
	}

	r = fira_crypto_build_phy_sts_index_init(fira_crypto_ctx);
	if (r != 0) {
		pr_err("fira_crypto_build_phy_sts_index_init fail: %d\n", r);
		goto end;
	}
	if (fira_crypto_ctx->phy_sts_index_init != 0x0b9bbe78) {
		pr_err("phy_sts_index_init fail\n");
		goto end;
	}

	r = fira_crypto_get_sts_params(fira_crypto_ctx, crypto_sts_index, sts_v,
				sizeof(sts_v), sts_key, sizeof(sts_key));
	if (r != 0) {
		pr_err("fira_crypto_get_sts_params fail: %d\n", r);
		goto end;
	}
	if (!compare_bufs(derived_authentication_key,
				sizeof(derived_authentication_key),
				sts_key, sizeof(sts_key))) {
		pr_err("compare sts_key fail\n");
		goto end;
	}

	if (!compare_bufs(sts_v_ref, sizeof(sts_v_ref), sts_v, sizeof(sts_v))) {
		pr_err("compare sts_v fail\n");
		goto end;
	}

	skb = alloc_skb(128, GFP_KERNEL);
	if (!skb) {
		pr_err("cannot allocate skb\n");
		goto end;
	}

	skb_put_data(skb, Header, sizeof(Header));

	/* Encrypt Header first (NOP in Static STS) */
	r = fira_crypto_encrypt_hie(fira_crypto_ctx, skb, 5, 21);
	if (r != 0) {
		pr_err("fira_crypto_encrypt_hie fail: %d\n", r);
		goto end;
	}
	if (!compare_bufs(HeaderRef, sizeof(HeaderRef), skb->data, skb->len)) {
		pr_err("fira_crypto_encrypt_hie compare HeaderRef fail\n");
		goto end;
	}

	kfree_skb(skb);

	skb = alloc_skb(128, GFP_KERNEL);
	if (!skb) {
		pr_err("cannot allocate skb\n");
		goto end;
	}

	skb_put_data(skb, RCM, sizeof(RCM));

	r = fira_crypto_encrypt_frame(fira_crypto_ctx, skb, 28, 0xaaa1, 0);
	if (r != 0) {
		pr_err("fira_crypto_encrypt_frame fail: %d\n", r);
		goto end;
	}

	if (!compare_bufs(RCMRef, sizeof(RCMRef), skb->data, skb->len)) {
		pr_err("fira_crypto_encrypt_frame compare RCMRef fail\n");
		goto end;
	}

	kfree_skb(skb);

	skb = alloc_skb(128, GFP_KERNEL);
	if (!skb) {
		pr_err("cannot allocate skb\n");
		goto end;
	}

	skb_put_data(skb, Frame_Rcv, sizeof(Frame_Rcv));
	skb_pull(skb, 28); /* skip header */

	skb_trim(skb, skb->len - FIRA_CRYPTO_AEAD_AUTHSIZE);
	r = fira_crypto_decrypt_frame(fira_crypto_ctx, skb, 28, 0xaaa1, 0);
	if (r != 0) {
		pr_err("fira_crypto_decrypt_frame fail: %d\n", r);
		goto end;
	}

	skb_push(skb, 28); /* restore header */

	if (!compare_bufs(RCM_Rcv_Ref, sizeof(RCM_Rcv_Ref), skb->data, skb->len)) {
		pr_err("fira_crypto_decrypt_frame compare RCM_Rcv_Ref fail\n");
		goto end;
	}

	kfree_skb(skb);

	skb = alloc_skb(128, GFP_KERNEL);
	if (!skb) {
		pr_err("cannot allocate skb\n");
		goto end;
	}

	skb_put_data(skb, Header_Rcv, sizeof(Header_Rcv));

	/* Decrypt header (NOP in Static STS) */
	r = fira_crypto_decrypt_hie(fira_crypto_ctx, skb, 10, 16);
	if (r != 0) {
		pr_err("fira_crypto_decrypt_hie fail: %d\n", r);
		goto end;
	}
	if (!compare_bufs(HeaderRef_Rcv, sizeof(HeaderRef_Rcv), skb->data,
				skb->len)) {
		pr_err("fira_crypto_decrypt_hie compare HeaderRef_Rcv fail\n");
		goto end;
	}

	err = 0;

	pr_info("Static STS tests success\n");

end:
	if (skb)
		kfree_skb(skb);
	if (fira_crypto_ctx)
		fira_crypto_context_deinit(fira_crypto_ctx);

	return err;
}

/**
 * fira_crypto_test_provisioned()
 * Run the FIRA CONSORTIUM UWB MAC TECHNICAL REQUIREMENTS
 * version 1.3.0 test vectors for Dynamic STS (Provisioned STS is ran instead of
 * pure dynamic)
 *
 * NOTE: This APis used for unit tests only.
 *
 * Return: 0 if ok
 */
static int fira_crypto_test_provisioned(void)
{
	/* Provisioned STS (equivalent to D-STS) */
	static const u8 config_P_STS[] = {
		0x02, 0x01, 0x00, 0x09, 0x07, 0xD0, 0x00, 0x03,
		0x0a, 0x02, 0x00, 0x01, 0x03, 0x01, 0x23, 0x45,
		0x67
	};
	static const u8 sessionKey[] = {
		0x44, 0x79, 0x6e, 0x61, 0x6d, 0x69, 0x63, 0x53,
		0x54, 0x53, 0x4e, 0x6f, 0x52, 0x6f, 0x74, 0x30
	};
	static const struct fira_crypto_params param_p_sts = {
		.session_id = 0x01234567,
		.sts_config = FIRA_STS_MODE_PROVISIONED,
		.concat_params = config_P_STS,
		.concat_params_size = sizeof(config_P_STS),
		.key = sessionKey,
		.key_len = sizeof(sessionKey)
	};
	static const u8 configDigest_p_sts[] = {
		0x08, 0x93, 0x66, 0xba, 0xfb, 0x3b, 0x24, 0xbf,
		0xd2, 0x93, 0x33, 0x77, 0x61, 0xb8, 0x8f, 0xc3
	};
	static const u8 secDataPrivacyKey_p_sts[] = {
		0x3a, 0x4b, 0xab, 0x18, 0x74, 0x4a, 0xee, 0x93,
		0x86, 0x50, 0xf1, 0xa0, 0x3f, 0x58, 0x5a, 0x49
	};
	static const u8 secDataProtectionKey_p_sts[] = {
		0x67, 0xf7, 0x02, 0x7e, 0xa6, 0x2d, 0x84, 0xa5,
		0xe1, 0xa8, 0xd7, 0xb8, 0xb8, 0xac, 0xae, 0xaf
	};
	static const u8 derived_authentication_iv_p_sts[] = {
		0xfa, 0x32, 0x6f, 0xed, 0x87, 0xd2, 0xef, 0x7e,
		0xb6, 0x80, 0xb2, 0xd6, 0xd1, 0x19, 0xa9, 0xb8
	};
	static const u8 derived_authentication_key_p_sts[] = {
		0x91, 0xa2, 0xde, 0x58, 0xff, 0x3b, 0x5e, 0x85,
		0x15, 0x33, 0x58, 0xd6, 0x15, 0x64, 0x64, 0xff
	};
	static const u8 derived_payload_key_p_sts[] = {
		0x97, 0xe4, 0xab, 0x69, 0x61, 0x77, 0xbb, 0x39,
		0x92, 0x77, 0xb8, 0x35, 0x9f, 0xa5, 0x5d, 0x19
	};
	static const u8 sts_v_ref_p_sts[] = {
		0xfa, 0x32, 0x6f, 0xed, 0x87, 0xd2, 0xef, 0x7e,
		0x04, 0x1f, 0x3b, 0xa0, 0x51, 0x19, 0xa9, 0xb8
	};
	/* build the RCM Frame */
	static const u8 RCM_p_sts[] = {
		0x49, 0x2b, 0xa2, 0xaa, 0x26, 0x13, 0x00, 0xff,
		0x18, 0x5a, 0x84, 0x6c, 0xa4, 0x3c, 0x52, 0xfb,
		0xb0, 0x2b, 0x56, 0xa9, 0x87, 0x9d, 0xb0, 0x4e,
		0x4e, 0x03, 0x00, 0x3f, 0x1b, 0x90, 0xff, 0x18,
		0x5a, 0x03, 0x05, 0x00, 0x00, 0x03, 0x42, 0x55,
		0x01, 0x04, 0x44, 0x55, 0x03, 0x07, 0x42, 0x55,
		0x05, 0x09, 0x42, 0x55, 0x09, 0x0a, 0x44, 0x55,
		0x0b
	};
	static const u8 RCMRef_p_sts[] = {
		0x49, 0x2b, 0xa2, 0xaa, 0x26, 0x13, 0x00, 0xff,
		0x18, 0x5a, 0x84, 0x6c, 0xa4, 0x3c, 0x52, 0xfb,
		0xb0, 0x2b, 0x56, 0xa9, 0x87, 0x9d, 0xb0, 0x4e,
		0x4e, 0x03, 0x00, 0x3f, 0x82, 0x76, 0xe0, 0x44,
		0xf3, 0x78, 0xab, 0xbe, 0xd2, 0x39, 0x86, 0x7e,
		0xd2, 0xfe, 0x5c, 0x9d, 0xcd, 0x13, 0x1d, 0x1f,
		0x63, 0x38, 0xf1, 0xf7,	0x9d, 0xb1, 0x84, 0x71,
		0x72, 0x7a, 0x10, 0xfc, 0x80, 0x04, 0x7e, 0xdb,
		0x0f
	};
	static const u8 Header_p_sts[] = {
		0x49, 0x2b, 0xa2, 0xaa, 0x26, 0x13, 0x00, 0xff,
		0x18, 0x5a, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08,
		0x08, 0x08, 0x67, 0x45, 0x23, 0x01, 0xa0, 0x3b,
		0x1f, 0x04
	};
	static const u8 HeaderRef_p_sts[] = {
		0x49, 0x2b, 0xa2, 0xaa, 0x26, 0x13, 0x00, 0xff,
		0x18, 0x5a, 0x84, 0x6c, 0xa4, 0x3c, 0x52, 0xfb,
		0xb0, 0x2b, 0x56, 0xa9, 0x87, 0x9d, 0xb0, 0x4e,
		0x4e, 0x03
	};
	/* Decrypt Frame */
	static const u8 Header_RCM_p_sts_Rcv[] = {
		0x49, 0x2b, 0xa2, 0xaa, 0x26, 0x13, 0x00, 0xff,
		0x18, 0x5a, 0x84, 0x6c, 0xa4, 0x3c, 0x52, 0xfb,
		0xb0, 0x2b, 0x56, 0xa9, 0x87, 0x9d, 0xb0, 0x4e,
		0x4e, 0x03, 0x00, 0x3f, 0x82, 0x76, 0xe0, 0x44,
		0xf3, 0x78, 0xab, 0xbe, 0xd2, 0x39, 0x86, 0x7e,
		0xd2, 0xfe, 0x5c, 0x9d, 0xcd, 0x13, 0x1d, 0x1f,
		0x63, 0x38, 0xf1, 0xf7, 0x9d, 0xb1, 0x84, 0x71,
		0x72, 0x7a, 0x10, 0xfc, 0x80, 0x04, 0x7e, 0xdb,
		0x0f
	};
	static const u8 RCMRef_p_sts_Rcv[] = {
		0x49, 0x2b, 0xa2, 0xaa, 0x26, 0x13, 0x00, 0xff,
		0x18, 0x5a, 0x84, 0x6c, 0xa4, 0x3c, 0x52, 0xfb,
		0xb0, 0x2b, 0x56, 0xa9, 0x87, 0x9d, 0xb0, 0x4e,
		0x4e, 0x03, 0x00, 0x3f, 0x1b, 0x90, 0xff, 0x18,
		0x5a, 0x03, 0x05, 0x00, 0x00, 0x03, 0x42, 0x55,
		0x01, 0x04, 0x44, 0x55, 0x03, 0x07, 0x42, 0x55,
		0x05, 0x09, 0x42, 0x55, 0x09, 0x0a, 0x44, 0x55,
		0x0b
	};
	static const u8 Header_p_sts_Rcv[] = {
		0x49, 0x2b, 0xa2, 0xaa, 0x26, 0x13, 0x00, 0xff,
		0x18, 0x5a, 0x84, 0x6c, 0xa4, 0x3c, 0x52, 0xfb,
		0xb0, 0x2b, 0x56, 0xa9, 0x87, 0x9d, 0xb0, 0x4e,
		0x4e, 0x03
	};
	static const u8 HeaderRef_p_sts_Rcv[] = {
		0x49, 0x2b, 0xa2, 0xaa, 0x26, 0x13, 0x00, 0xff,
		0x18, 0x5a, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08,
		0x08, 0x08, 0x67, 0x45, 0x23, 0x01, 0xa0, 0x3b,
		0x1f, 0x04
	};
	int err = -1, r;
	struct fira_crypto *fira_crypto_ctx;
	u32 crypto_sts_index_p_sts = 0;
	u8 sts_v[16];
	u8 sts_key[16];
	struct sk_buff *skb = NULL;

	r = fira_crypto_context_init(&param_p_sts, &fira_crypto_ctx);
	if (r != 0 || !fira_crypto_ctx) {
		pr_err("fira_crypto_context_init fail: %d\n", r);
		goto end;
	}

	if (!compare_bufs(configDigest_p_sts, sizeof(configDigest_p_sts),
				fira_crypto_ctx->base.config_digest,
				sizeof(fira_crypto_ctx->base.config_digest))) {
		pr_err("compare configDigest_p_sts fail\n");
		goto end;
	}

	if (!compare_bufs(secDataPrivacyKey_p_sts,
				sizeof(secDataPrivacyKey_p_sts),
				fira_crypto_ctx->privacy_key,
				sizeof(fira_crypto_ctx->privacy_key))) {
		pr_err("compare secDataPrivacyKey_p_sts fail\n");
		goto end;
	}

	if (!compare_bufs(secDataProtectionKey_p_sts,
				sizeof(secDataProtectionKey_p_sts),
				fira_crypto_ctx->base.data_protection_key,
				sizeof(fira_crypto_ctx->base.data_protection_key))) {
		pr_err("compare secDataProtectionKey fail\n");
		goto end;
	}

	r = fira_crypto_build_phy_sts_index_init(fira_crypto_ctx);
	if (r != 0) {
		pr_err("fira_crypto_build_phy_sts_index_init fail: %d\n", r);
		goto end;
	}
	if (fira_crypto_ctx->phy_sts_index_init != 0x041f3ba0) {
		pr_err("phy_sts_index_init fail\n");
		goto end;
	}

	r = fira_crypto_rotate_elements(fira_crypto_ctx,
					fira_crypto_ctx->phy_sts_index_init);

	if (r != 0) {
		pr_err("fira_crypto_rotate_elements fail: %d\n", r);
		goto end;
	}

	if (!compare_bufs(derived_authentication_iv_p_sts,
				sizeof(derived_authentication_iv_p_sts),
				fira_crypto_ctx->base.derived_authentication_iv,
				sizeof(fira_crypto_ctx->base.derived_authentication_iv))) {
		pr_err("compare derived_authentication_iv_p_sts fail\n");
		goto end;
	}

	if (!compare_bufs(derived_authentication_key_p_sts,
				sizeof(derived_authentication_key_p_sts),
				fira_crypto_ctx->base.derived_authentication_key,
				sizeof(fira_crypto_ctx->base.derived_authentication_key))) {
		pr_err("compare derived_authentication_key_p_sts fail\n");
		goto end;
	}

	if (!compare_bufs(derived_payload_key_p_sts,
				sizeof(derived_payload_key_p_sts),
				fira_crypto_ctx->base.derived_payload_key,
				sizeof(fira_crypto_ctx->base.derived_payload_key))) {
		pr_err("compare derived_payload_key fail\n");
		goto end;
	}

	/* Return STS parameters slot 0 */
	crypto_sts_index_p_sts = 0x041f3ba0;
	r = fira_crypto_get_sts_params(fira_crypto_ctx, crypto_sts_index_p_sts, sts_v,
				sizeof(sts_v), sts_key, sizeof(sts_key));
	if (r != 0) {
		pr_err("fira_crypto_get_sts_params fail: %d\n", r);
		goto end;
	}
	if (!compare_bufs(derived_authentication_key_p_sts,
				sizeof(derived_authentication_key_p_sts),
				sts_key, sizeof(sts_key))) {
		pr_err("compare sts_key Fail\n");
		goto end;
	}
	if (!compare_bufs(sts_v_ref_p_sts, sizeof(sts_v_ref_p_sts), sts_v,
				sizeof(sts_v))) {
		pr_err("compare sts_v_ref_p_sts Fail\n");
		goto end;
	}

	skb = alloc_skb(128, GFP_KERNEL);
	if (!skb) {
		pr_err("cannot allocate skb\n");
		goto end;
	}

	skb_put_data(skb, Header_p_sts, sizeof(Header_p_sts));

	/* Encrypt Header first */
	r = fira_crypto_encrypt_hie(fira_crypto_ctx, skb, 5, 16);
	if (r != 0) {
		pr_err("fira_crypto_encrypt_hie fail: %d\n", r);
		goto end;
	}
	if (!compare_bufs(HeaderRef_p_sts, sizeof(HeaderRef_p_sts), skb->data,
				skb->len)) {
		pr_err("compare HeaderRef_p_sts fail\n");
		goto end;
	}

	kfree_skb(skb);

	skb = alloc_skb(128, GFP_KERNEL);
	if (!skb) {
		pr_err("cannot allocate skb\n");
		goto end;
	}

	skb_put_data(skb, RCM_p_sts, sizeof(RCM_p_sts));

	r = fira_crypto_encrypt_frame(fira_crypto_ctx, skb, 28, 0xaaa1, 0x041f3ba0);

	if (r != 0) {
		pr_err("fira_crypto_encrypt_frame fail: %d\n", r);
		goto end;
	}
	if (!compare_bufs(RCMRef_p_sts, sizeof(RCMRef_p_sts), skb->data,
				skb->len)) {
		pr_err("compare RCMRef_p_sts fail\n");
		goto end;
	}

	kfree_skb(skb);

	skb = alloc_skb(128, GFP_KERNEL);
	if (!skb) {
		pr_err("cannot allocate skb\n");
		goto end;
	}

	skb_put_data(skb, Header_RCM_p_sts_Rcv, sizeof(Header_RCM_p_sts_Rcv));
	skb_pull(skb, 28); /* skip header */

	skb_trim(skb, skb->len - FIRA_CRYPTO_AEAD_AUTHSIZE);
	r = fira_crypto_decrypt_frame(fira_crypto_ctx, skb, 28, 0xaaa1, 0x041f3ba0);
	if (r != 0) {
		pr_err("fira_crypto_decrypt_frame fail: %d\n", r);
		goto end;
	}

	skb_push(skb, 28); /* restore header */

	if (!compare_bufs(RCMRef_p_sts_Rcv, sizeof(RCMRef_p_sts_Rcv), skb->data,
				skb->len)) {
		pr_err("compare RCMRef_p_sts_Rcv fail\n");
		goto end;
	}

	kfree_skb(skb);

	skb = alloc_skb(128, GFP_KERNEL);
	if (!skb) {
		pr_err("cannot allocate skb\n");
		goto end;
	}

	skb_put_data(skb, Header_p_sts_Rcv, sizeof(Header_p_sts_Rcv));

	/* Decrypt header */
	r = fira_crypto_decrypt_hie(fira_crypto_ctx, skb, 10, 16);
	if (r != 0) {
		pr_err("fira_crypto_decrypt_hie fail: %d\n", r);
		goto end;
	}
	if (!compare_bufs(HeaderRef_p_sts_Rcv, sizeof(HeaderRef_p_sts_Rcv),
				skb->data, skb->len)) {
		pr_err("compare HeaderRef_p_sts_Rcv fail\n");
		goto end;
	}

	err = 0;

	pr_info("Provisioned STS tests success\n");

end:
	if (skb)
		kfree_skb(skb);
	if (fira_crypto_ctx)
		fira_crypto_context_deinit(fira_crypto_ctx);

	return err;
}

/**
 * fira_crypto_test() - Run the FIRA CONSORTIUM UWB MAC TECHNICAL REQUIREMENTS
 * version 1.3.0 test vectors for Static STS and Dynamic STS (Provisioned STS is
 * ran instead of pure dynnamic)
 *
 *
 * NOTE: This APis used for unit tests only.
 *
 * Return: 0 if ok,
 */
int fira_crypto_test(void)
{
	int r = 0;

	r = fira_crypto_test_static() || r;
	r = fira_crypto_test_provisioned() || r;

	return r ? -1 : 0;
}
