/*
 * Copyright (c) 2023 Nordic Semiconductor ASA
 *
 * SPDX-License-Identifier: Apache-2.0
 */

#include <errno.h>

#include <zephyr/bluetooth/mesh.h>
#include <zephyr/sys/check.h>

#define LOG_LEVEL CONFIG_BT_MESH_CRYPTO_LOG_LEVEL
#include <zephyr/logging/log.h>
LOG_MODULE_REGISTER(bt_mesh_crypto_psa);

#include "mesh.h"
#include "crypto.h"
#include "prov.h"

/* Mesh requires to keep in persistent memory network keys (2 keys per subnetwork),
 * application keys (2 real keys per 1 configured) and device key + device key candidate.
 */
#if defined CONFIG_BT_MESH_CDB
#define BT_MESH_CDB_KEY_ID_RANGE_SIZE (2 * SUBNET_COUNT + \
		2 * APP_KEY_COUNT + NODE_COUNT)
#else
#define BT_MESH_CDB_KEY_ID_RANGE_SIZE  0
#endif
#define BT_MESH_KEY_ID_RANGE_SIZE (2 * CONFIG_BT_MESH_SUBNET_COUNT + \
		2 * CONFIG_BT_MESH_APP_KEY_COUNT + 2 + BT_MESH_CDB_KEY_ID_RANGE_SIZE)
#define BT_MESH_PSA_KEY_ID_USER_MIN (PSA_KEY_ID_USER_MIN + \
		CONFIG_BT_MESH_PSA_KEY_ID_USER_MIN_OFFSET)

BUILD_ASSERT(BT_MESH_PSA_KEY_ID_USER_MIN + BT_MESH_KEY_ID_RANGE_SIZE <= PSA_KEY_ID_USER_MAX,
	"BLE Mesh PSA key id range overlaps maximum allowed boundary.");

BUILD_ASSERT(PSA_MAC_LENGTH(PSA_KEY_TYPE_AES, 128, PSA_ALG_CMAC) == 16,
	"MAC length should be 16 bytes for 128-bits key for CMAC-AES");

BUILD_ASSERT(PSA_MAC_LENGTH(PSA_KEY_TYPE_HMAC, 256, PSA_ALG_HMAC(PSA_ALG_SHA_256)) == 32,
	"MAC length should be 32 bytes for 256-bits key for HMAC-SHA");

static struct {
	bool is_ready;
	psa_key_id_t priv_key_id;
	uint8_t public_key_be[PUB_KEY_SIZE + 1];
} dh_pair;

static ATOMIC_DEFINE(pst_keys, BT_MESH_KEY_ID_RANGE_SIZE);

int bt_mesh_crypto_init(void)
{
	if (psa_crypto_init() != PSA_SUCCESS) {
		return -EIO;
	}

	return 0;
}

int bt_mesh_encrypt(const struct bt_mesh_key *key, const uint8_t plaintext[16],
		    uint8_t enc_data[16])
{
	uint32_t output_len;
	psa_status_t status;
	int err = 0;

	status = psa_cipher_encrypt(key->key, PSA_ALG_ECB_NO_PADDING,
				    plaintext, 16,
				    enc_data, 16,
				    &output_len);

	if (status != PSA_SUCCESS || output_len != 16) {
		err = -EIO;
	}

	return err;
}

int bt_mesh_ccm_encrypt(const struct bt_mesh_key *key, uint8_t nonce[13],
			const uint8_t *plaintext, size_t len, const uint8_t *aad,
			size_t aad_len, uint8_t *enc_data, size_t mic_size)
{
	uint32_t output_len;
	psa_status_t status;
	int err = 0;
	psa_algorithm_t alg = PSA_ALG_AEAD_WITH_SHORTENED_TAG(PSA_ALG_CCM, mic_size);

	status = psa_aead_encrypt(key->key, alg,
				  nonce, 13,
				  aad, aad_len,
				  plaintext, len,
				  enc_data, len + mic_size,
				  &output_len);

	if (status != PSA_SUCCESS || output_len != len + mic_size) {
		err = -EIO;
	}

	return err;
}

int bt_mesh_ccm_decrypt(const struct bt_mesh_key *key, uint8_t nonce[13],
			const uint8_t *enc_data, size_t len, const uint8_t *aad,
			size_t aad_len, uint8_t *plaintext, size_t mic_size)
{
	uint32_t output_len;
	psa_status_t status;
	int err = 0;
	psa_algorithm_t alg = PSA_ALG_AEAD_WITH_SHORTENED_TAG(PSA_ALG_CCM, mic_size);

	status = psa_aead_decrypt(key->key, alg,
				  nonce, 13,
				  aad, aad_len,
				  enc_data, len + mic_size,
				  plaintext, len,
				  &output_len);

	if (status != PSA_SUCCESS || output_len != len) {
		err = -EIO;
	}

	return err;
}

int bt_mesh_aes_cmac_mesh_key(const struct bt_mesh_key *key, struct bt_mesh_sg *sg,
			size_t sg_len, uint8_t mac[16])
{
	psa_mac_operation_t operation = PSA_MAC_OPERATION_INIT;
	psa_algorithm_t alg = PSA_ALG_CMAC;
	psa_status_t status;

	status = psa_mac_sign_setup(&operation, key->key, alg);
	if (status != PSA_SUCCESS) {
		return -EIO;
	}

	for (; sg_len; sg_len--, sg++) {
		status = psa_mac_update(&operation, sg->data, sg->len);
		if (status != PSA_SUCCESS) {
			psa_mac_abort(&operation);
			return -EIO;
		}
	}

	size_t mac_len;

	status = psa_mac_sign_finish(&operation, mac, 16, &mac_len);
	if (status != PSA_SUCCESS) {
		return -EIO;
	}

	if (mac_len != 16) {
		return -ERANGE;
	}

	return 0;
}

int bt_mesh_aes_cmac_raw_key(const uint8_t key[16], struct bt_mesh_sg *sg,
			size_t sg_len, uint8_t mac[16])
{
	struct bt_mesh_key key_id;
	int err;

	err = bt_mesh_key_import(BT_MESH_KEY_TYPE_CMAC, key, &key_id);
	if (err) {
		return err;
	}

	err = bt_mesh_aes_cmac_mesh_key(&key_id, sg, sg_len, mac);

	psa_destroy_key(key_id.key);

	return err;
}

int bt_mesh_sha256_hmac_raw_key(const uint8_t key[32], struct bt_mesh_sg *sg, size_t sg_len,
			uint8_t mac[32])
{
	psa_mac_operation_t operation = PSA_MAC_OPERATION_INIT;
	psa_algorithm_t alg = PSA_ALG_HMAC(PSA_ALG_SHA_256);

	psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
	psa_key_id_t key_id;

	psa_status_t status;
	int err = 0;

	/* Import a key */
	psa_set_key_usage_flags(&attributes, PSA_KEY_USAGE_SIGN_MESSAGE);
	psa_set_key_lifetime(&attributes, PSA_KEY_LIFETIME_VOLATILE);
	psa_set_key_algorithm(&attributes, PSA_ALG_HMAC(PSA_ALG_SHA_256));
	psa_set_key_type(&attributes, PSA_KEY_TYPE_HMAC);
	psa_set_key_bits(&attributes, 256);

	status = psa_import_key(&attributes, key, 32, &key_id);
	if (status != PSA_SUCCESS) {
		err = -EIO;
		goto end;
	}

	psa_reset_key_attributes(&attributes);

	status = psa_mac_sign_setup(&operation, key_id, alg);
	if (status != PSA_SUCCESS) {
		err = -EIO;
		goto end;
	}

	for (; sg_len; sg_len--, sg++) {
		status = psa_mac_update(&operation, sg->data, sg->len);
		if (status != PSA_SUCCESS) {
			psa_mac_abort(&operation);
			err = -EIO;
			goto end;
		}
	}

	size_t mac_len;

	status = psa_mac_sign_finish(&operation, mac, 32, &mac_len);
	if (status != PSA_SUCCESS) {
		err = -EIO;
		goto end;
	}

	if (mac_len != 32) {
		err = -ERANGE;
	}

end:
	/* Destroy the key */
	psa_destroy_key(key_id);

	return err;
}

int bt_mesh_pub_key_gen(void)
{
	psa_key_attributes_t key_attributes = PSA_KEY_ATTRIBUTES_INIT;
	psa_status_t status;
	int err = 0;
	size_t key_len;

	psa_destroy_key(dh_pair.priv_key_id);
	dh_pair.is_ready = false;

	/* Crypto settings for ECDH using the SHA256 hashing algorithm,
	 * the secp256r1 curve
	 */
	psa_set_key_usage_flags(&key_attributes, PSA_KEY_USAGE_DERIVE);
	psa_set_key_lifetime(&key_attributes, PSA_KEY_LIFETIME_VOLATILE);
	psa_set_key_algorithm(&key_attributes, PSA_ALG_ECDH);
	psa_set_key_type(&key_attributes, PSA_KEY_TYPE_ECC_KEY_PAIR(PSA_ECC_FAMILY_SECP_R1));
	psa_set_key_bits(&key_attributes, 256);

	/* Generate a key pair */
	status = psa_generate_key(&key_attributes, &dh_pair.priv_key_id);
	if (status != PSA_SUCCESS) {
		err = -EIO;
		goto end;
	}

	status = psa_export_public_key(dh_pair.priv_key_id, dh_pair.public_key_be,
				sizeof(dh_pair.public_key_be), &key_len);
	if (status != PSA_SUCCESS) {
		err = -EIO;
		goto end;
	}

	if (key_len != PUB_KEY_SIZE + 1) {
		err = -ERANGE;
		goto end;
	}

	dh_pair.is_ready = true;

end:
	psa_reset_key_attributes(&key_attributes);

	return err;
}

const uint8_t *bt_mesh_pub_key_get(void)
{
	return dh_pair.is_ready ? dh_pair.public_key_be + 1 : NULL;
}

BUILD_ASSERT(PSA_RAW_KEY_AGREEMENT_OUTPUT_SIZE(
	PSA_KEY_TYPE_ECC_KEY_PAIR(PSA_ECC_FAMILY_SECP_R1), 256) == DH_KEY_SIZE,
	"Diffie-Hellman shared secret size should be the same in PSA and BLE Mesh");

BUILD_ASSERT(PSA_KEY_EXPORT_ECC_PUBLIC_KEY_MAX_SIZE(256) == PUB_KEY_SIZE + 1,
	"Exported PSA public key should be 1 byte larger than BLE Mesh public key");

int bt_mesh_dhkey_gen(const uint8_t *pub_key, const uint8_t *priv_key, uint8_t *dhkey)
{
	int err = 0;
	psa_key_id_t priv_key_id  = PSA_KEY_ID_NULL;
	uint8_t public_key_repr[PUB_KEY_SIZE + 1];
	psa_status_t status;
	size_t dh_key_len;

	if (priv_key) {
		psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;

		/* Import a custom private key */
		psa_set_key_usage_flags(&attributes, PSA_KEY_USAGE_DERIVE);
		psa_set_key_lifetime(&attributes, PSA_KEY_LIFETIME_VOLATILE);
		psa_set_key_algorithm(&attributes, PSA_ALG_ECDH);
		psa_set_key_type(&attributes, PSA_KEY_TYPE_ECC_KEY_PAIR(PSA_ECC_FAMILY_SECP_R1));
		psa_set_key_bits(&attributes, 256);

		status = psa_import_key(&attributes, priv_key, PRIV_KEY_SIZE, &priv_key_id);
		if (status != PSA_SUCCESS) {
			err = -EIO;
			goto end;
		}

		psa_reset_key_attributes(&attributes);
	} else {
		priv_key_id = dh_pair.priv_key_id;
	}

	/* For elliptic curve key pairs for Weierstrass curve families (PSA_ECC_FAMILY_SECP_R1)
	 *  the representations of public key is:
	 *  - The byte 0x04;
	 *  - x_P as a ceiling(m/8)-byte string, big-endian;
	 *  - y_P as a ceiling(m/8)-byte string, big-endian.
	 */
	public_key_repr[0] = 0x04;
	memcpy(public_key_repr + 1, pub_key, PUB_KEY_SIZE);

	/* Calculate the secret */
	status = psa_raw_key_agreement(PSA_ALG_ECDH, priv_key_id, public_key_repr,
			PUB_KEY_SIZE + 1, dhkey, DH_KEY_SIZE, &dh_key_len);
	if (status != PSA_SUCCESS) {
		err = -EIO;
		goto end;
	}

	if (dh_key_len != DH_KEY_SIZE) {
		err = -ERANGE;
	}

end:

	if (priv_key) {
		psa_destroy_key(priv_key_id);
	}

	return err;
}

__weak psa_key_id_t bt_mesh_user_keyid_alloc(void)
{
	for (int i = 0; i < BT_MESH_KEY_ID_RANGE_SIZE; i++) {
		if (!atomic_test_bit(pst_keys, i)) {
			atomic_set_bit(pst_keys, i);
			return BT_MESH_PSA_KEY_ID_USER_MIN + i;
		}
	}

	return PSA_KEY_ID_NULL;
}

__weak int bt_mesh_user_keyid_free(psa_key_id_t key_id)
{
	if (IN_RANGE(key_id, BT_MESH_PSA_KEY_ID_USER_MIN,
			BT_MESH_PSA_KEY_ID_USER_MIN + BT_MESH_KEY_ID_RANGE_SIZE - 1)) {
		atomic_clear_bit(pst_keys, key_id - BT_MESH_PSA_KEY_ID_USER_MIN);
		return 0;
	}

	return -EIO;
}

__weak void bt_mesh_user_keyid_assign(psa_key_id_t key_id)
{
	if (IN_RANGE(key_id, BT_MESH_PSA_KEY_ID_USER_MIN,
				BT_MESH_PSA_KEY_ID_USER_MIN + BT_MESH_KEY_ID_RANGE_SIZE - 1)) {
		atomic_set_bit(pst_keys, key_id - BT_MESH_PSA_KEY_ID_USER_MIN);
	}
}

int bt_mesh_key_import(enum bt_mesh_key_type type, const uint8_t in[16], struct bt_mesh_key *out)
{
	psa_key_attributes_t key_attributes = PSA_KEY_ATTRIBUTES_INIT;
	psa_status_t status;
	psa_key_id_t key_id = PSA_KEY_ID_NULL;
	int err = 0;

	switch (type) {
	case BT_MESH_KEY_TYPE_ECB:
		psa_set_key_lifetime(&key_attributes, PSA_KEY_LIFETIME_VOLATILE);
		psa_set_key_usage_flags(&key_attributes,
			PSA_KEY_USAGE_ENCRYPT | PSA_KEY_USAGE_DECRYPT);
		psa_set_key_algorithm(&key_attributes, PSA_ALG_ECB_NO_PADDING);
		break;
	case BT_MESH_KEY_TYPE_CCM:
		psa_set_key_lifetime(&key_attributes, PSA_KEY_LIFETIME_VOLATILE);
		psa_set_key_usage_flags(&key_attributes,
			PSA_KEY_USAGE_ENCRYPT | PSA_KEY_USAGE_DECRYPT);
		psa_set_key_algorithm(&key_attributes,
			PSA_ALG_AEAD_WITH_AT_LEAST_THIS_LENGTH_TAG(PSA_ALG_CCM, 4));
		break;
	case BT_MESH_KEY_TYPE_CMAC:
		psa_set_key_lifetime(&key_attributes, PSA_KEY_LIFETIME_VOLATILE);
		psa_set_key_usage_flags(&key_attributes, PSA_KEY_USAGE_SIGN_MESSAGE);
		psa_set_key_algorithm(&key_attributes, PSA_ALG_CMAC);
		break;
	case BT_MESH_KEY_TYPE_NET:
		if (IS_ENABLED(CONFIG_BT_SETTINGS)) {
			key_id = bt_mesh_user_keyid_alloc();

			if (key_id == PSA_KEY_ID_NULL) {
				return -ENOMEM;
			}

			psa_set_key_lifetime(&key_attributes, PSA_KEY_LIFETIME_PERSISTENT);
			psa_set_key_id(&key_attributes, key_id);
		} else {
			psa_set_key_lifetime(&key_attributes, PSA_KEY_LIFETIME_VOLATILE);
		}
		psa_set_key_usage_flags(&key_attributes, PSA_KEY_USAGE_EXPORT);
		break;
	case BT_MESH_KEY_TYPE_APP:
	case BT_MESH_KEY_TYPE_DEV:
		if (IS_ENABLED(CONFIG_BT_SETTINGS)) {
			key_id = bt_mesh_user_keyid_alloc();

			if (key_id == PSA_KEY_ID_NULL) {
				return -ENOMEM;
			}

			psa_set_key_lifetime(&key_attributes, PSA_KEY_LIFETIME_PERSISTENT);
			psa_set_key_id(&key_attributes, key_id);
		} else {
			psa_set_key_lifetime(&key_attributes, PSA_KEY_LIFETIME_VOLATILE);
		}
		psa_set_key_usage_flags(&key_attributes,
			PSA_KEY_USAGE_ENCRYPT | PSA_KEY_USAGE_DECRYPT | PSA_KEY_USAGE_EXPORT);
		psa_set_key_algorithm(&key_attributes,
			PSA_ALG_AEAD_WITH_AT_LEAST_THIS_LENGTH_TAG(PSA_ALG_CCM, 4));
		break;
	default:
		return -EIO;
	}

	psa_set_key_type(&key_attributes, PSA_KEY_TYPE_AES);
	psa_set_key_bits(&key_attributes, 128);

	status = psa_import_key(&key_attributes, in, 16, &out->key);
	err = status == PSA_SUCCESS ? 0 :
		status == PSA_ERROR_ALREADY_EXISTS ? -EALREADY : -EIO;

	if (err && key_id != PSA_KEY_ID_NULL) {
		bt_mesh_user_keyid_free(key_id);
	}

	psa_reset_key_attributes(&key_attributes);

	return err;
}

int bt_mesh_key_export(uint8_t out[16], const struct bt_mesh_key *in)
{
	size_t data_length;

	if (psa_export_key(in->key, out, 16, &data_length) != PSA_SUCCESS) {
		return -EIO;
	}

	if (data_length != 16) {
		return -EIO;
	}

	return 0;
}

void bt_mesh_key_assign(struct bt_mesh_key *dst, const struct bt_mesh_key *src)
{
	memcpy(dst, src, sizeof(struct bt_mesh_key));
	if (IS_ENABLED(CONFIG_BT_SETTINGS)) {
		bt_mesh_user_keyid_assign(dst->key);
	}
}

int bt_mesh_key_destroy(const struct bt_mesh_key *key)
{
	if (psa_destroy_key(key->key) != PSA_SUCCESS) {
		return -EIO;
	}

	if (IS_ENABLED(CONFIG_BT_SETTINGS)) {
		return bt_mesh_user_keyid_free(key->key);
	}

	return 0;
}

int bt_mesh_key_compare(const uint8_t raw_key[16], const struct bt_mesh_key *key)
{
	uint8_t out[16];
	int err;

	err = bt_mesh_key_export(out, key);
	if (err) {
		return err;
	}

	return memcmp(out, raw_key, 16);
}

__weak int bt_rand(void *buf, size_t len)
{
	CHECKIF(buf == NULL || len == 0) {
		return -EINVAL;
	}

	return psa_generate_random(buf, len) == PSA_SUCCESS ? 0 : -EIO;
}
