/*
 * Copyright (c) 2017 Intel Corporation
 * Copyright (c) 2022 Nordic Semiconductor ASA
 *
 * SPDX-License-Identifier: Apache-2.0
 */

#include <string.h>
#include <stdbool.h>
#include <errno.h>
#include <zephyr/toolchain.h>
#include <zephyr/types.h>
#include <zephyr/sys/byteorder.h>
#include <zephyr/sys/util.h>

#include <tinycrypt/constants.h>
#include <tinycrypt/utils.h>
#include <tinycrypt/aes.h>
#include <tinycrypt/cmac_mode.h>
#include <tinycrypt/ccm_mode.h>
#include <tinycrypt/ecc.h>
#include <tinycrypt/ecc_dh.h>

#include <zephyr/bluetooth/mesh.h>
#include <zephyr/bluetooth/crypto.h>

#include "common/bt_str.h"

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

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

#define NET_MIC_LEN(pdu) (((pdu)[1] & 0x80) ? 8 : 4)
#define APP_MIC_LEN(aszmic) ((aszmic) ? 8 : 4)

struct bt_mesh_sg {
	const void *data;
	size_t len;
};

static int bt_mesh_aes_cmac(const uint8_t key[16], struct bt_mesh_sg *sg,
			size_t sg_len, uint8_t mac[16])
{
	struct tc_aes_key_sched_struct sched;
	struct tc_cmac_struct state;

	if (tc_cmac_setup(&state, key, &sched) == TC_CRYPTO_FAIL) {
		return -EIO;
	}

	for (; sg_len; sg_len--, sg++) {
		if (tc_cmac_update(&state, sg->data,
				   sg->len) == TC_CRYPTO_FAIL) {
			return -EIO;
		}
	}

	if (tc_cmac_final(mac, &state) == TC_CRYPTO_FAIL) {
		return -EIO;
	}

	return 0;
}

static int bt_mesh_aes_cmac_one(const uint8_t key[16], const void *m,
				size_t len, uint8_t mac[16])
{
	struct bt_mesh_sg sg = { m, len };

	return bt_mesh_aes_cmac(key, &sg, 1, mac);
}

int bt_mesh_s1(const char *m, uint8_t salt[16])
{
	const uint8_t zero[16] = { 0 };

	return bt_mesh_aes_cmac_one(zero, m, strlen(m), salt);
}

int bt_mesh_k1(const uint8_t *ikm, size_t ikm_len, const uint8_t salt[16],
	       const char *info, uint8_t okm[16])
{
	int err;

	err = bt_mesh_aes_cmac_one(salt, ikm, ikm_len, okm);
	if (err < 0) {
		return err;
	}

	return bt_mesh_aes_cmac_one(okm, info, strlen(info), okm);
}

int bt_mesh_k2(const uint8_t n[16], const uint8_t *p, size_t p_len,
	       uint8_t net_id[1], uint8_t enc_key[16], uint8_t priv_key[16])
{
	struct bt_mesh_sg sg[3];
	uint8_t salt[16];
	uint8_t out[16];
	uint8_t t[16];
	uint8_t pad;
	int err;

	LOG_DBG("n %s", bt_hex(n, 16));
	LOG_DBG("p %s", bt_hex(p, p_len));

	err = bt_mesh_s1("smk2", salt);
	if (err) {
		return err;
	}

	err = bt_mesh_aes_cmac_one(salt, n, 16, t);
	if (err) {
		return err;
	}

	pad = 0x01;

	sg[0].data = NULL;
	sg[0].len  = 0;
	sg[1].data = p;
	sg[1].len  = p_len;
	sg[2].data = &pad;
	sg[2].len  = sizeof(pad);

	err = bt_mesh_aes_cmac(t, sg, ARRAY_SIZE(sg), out);
	if (err) {
		return err;
	}

	net_id[0] = out[15] & 0x7f;

	sg[0].data = out;
	sg[0].len  = sizeof(out);
	pad = 0x02;

	err = bt_mesh_aes_cmac(t, sg, ARRAY_SIZE(sg), out);
	if (err) {
		return err;
	}

	memcpy(enc_key, out, 16);

	pad = 0x03;

	err = bt_mesh_aes_cmac(t, sg, ARRAY_SIZE(sg), out);
	if (err) {
		return err;
	}

	memcpy(priv_key, out, 16);

	LOG_DBG("NID 0x%02x enc_key %s", net_id[0], bt_hex(enc_key, 16));
	LOG_DBG("priv_key %s", bt_hex(priv_key, 16));

	return 0;
}

int bt_mesh_k3(const uint8_t n[16], uint8_t out[8])
{
	uint8_t id64[] = { 'i', 'd', '6', '4', 0x01 };
	uint8_t tmp[16];
	uint8_t t[16];
	int err;

	err = bt_mesh_s1("smk3", tmp);
	if (err) {
		return err;
	}

	err = bt_mesh_aes_cmac_one(tmp, n, 16, t);
	if (err) {
		return err;
	}

	err = bt_mesh_aes_cmac_one(t, id64, sizeof(id64), tmp);
	if (err) {
		return err;
	}

	memcpy(out, tmp + 8, 8);

	return 0;
}

int bt_mesh_k4(const uint8_t n[16], uint8_t out[1])
{
	uint8_t id6[] = { 'i', 'd', '6', 0x01 };
	uint8_t tmp[16];
	uint8_t t[16];
	int err;

	err = bt_mesh_s1("smk4", tmp);
	if (err) {
		return err;
	}

	err = bt_mesh_aes_cmac_one(tmp, n, 16, t);
	if (err) {
		return err;
	}

	err = bt_mesh_aes_cmac_one(t, id6, sizeof(id6), tmp);
	if (err) {
		return err;
	}

	out[0] = tmp[15] & BIT_MASK(6);

	return 0;
}

int bt_mesh_id128(const uint8_t n[16], const char *s, uint8_t out[16])
{
	const char *id128 = "id128\x01";
	uint8_t salt[16];
	int err;

	err = bt_mesh_s1(s, salt);
	if (err) {
		return err;
	}

	return bt_mesh_k1(n, 16, salt, id128, out);
}

static void create_proxy_nonce(uint8_t nonce[13], const uint8_t *pdu,
			       uint32_t iv_index)
{
	/* Nonce Type */
	nonce[0] = 0x03;

	/* Pad */
	nonce[1] = 0x00;

	/* Sequence Number */
	nonce[2] = pdu[2];
	nonce[3] = pdu[3];
	nonce[4] = pdu[4];

	/* Source Address */
	nonce[5] = pdu[5];
	nonce[6] = pdu[6];

	/* Pad */
	nonce[7] = 0U;
	nonce[8] = 0U;

	/* IV Index */
	sys_put_be32(iv_index, &nonce[9]);
}

static void create_net_nonce(uint8_t nonce[13], const uint8_t *pdu,
			     uint32_t iv_index)
{
	/* Nonce Type */
	nonce[0] = 0x00;

	/* FRND + TTL */
	nonce[1] = pdu[1];

	/* Sequence Number */
	nonce[2] = pdu[2];
	nonce[3] = pdu[3];
	nonce[4] = pdu[4];

	/* Source Address */
	nonce[5] = pdu[5];
	nonce[6] = pdu[6];

	/* Pad */
	nonce[7] = 0U;
	nonce[8] = 0U;

	/* IV Index */
	sys_put_be32(iv_index, &nonce[9]);
}

int bt_mesh_net_obfuscate(uint8_t *pdu, uint32_t iv_index,
			  const uint8_t privacy_key[16])
{
	uint8_t priv_rand[16] = { 0x00, 0x00, 0x00, 0x00, 0x00, };
	uint8_t tmp[16];
	int err, i;

	LOG_DBG("IVIndex %u, PrivacyKey %s", iv_index, bt_hex(privacy_key, 16));

	sys_put_be32(iv_index, &priv_rand[5]);
	memcpy(&priv_rand[9], &pdu[7], 7);

	LOG_DBG("PrivacyRandom %s", bt_hex(priv_rand, 16));

	err = bt_encrypt_be(privacy_key, priv_rand, tmp);
	if (err) {
		return err;
	}

	for (i = 0; i < 6; i++) {
		pdu[1 + i] ^= tmp[i];
	}

	return 0;
}

int bt_mesh_net_encrypt(const uint8_t key[16], struct net_buf_simple *buf,
			uint32_t iv_index, bool proxy)
{
	uint8_t mic_len = NET_MIC_LEN(buf->data);
	uint8_t nonce[13];
	int err;

	LOG_DBG("IVIndex %u EncKey %s mic_len %u", iv_index, bt_hex(key, 16), mic_len);
	LOG_DBG("PDU (len %u) %s", buf->len, bt_hex(buf->data, buf->len));

	if (IS_ENABLED(CONFIG_BT_MESH_PROXY) && proxy) {
		create_proxy_nonce(nonce, buf->data, iv_index);
	} else {
		create_net_nonce(nonce, buf->data, iv_index);
	}

	LOG_DBG("Nonce %s", bt_hex(nonce, 13));

	err = bt_ccm_encrypt(key, nonce, &buf->data[7], buf->len - 7, NULL, 0,
			     &buf->data[7], mic_len);
	if (!err) {
		net_buf_simple_add(buf, mic_len);
	}

	return err;
}

int bt_mesh_net_decrypt(const uint8_t key[16], struct net_buf_simple *buf,
			uint32_t iv_index, bool proxy)
{
	uint8_t mic_len = NET_MIC_LEN(buf->data);
	uint8_t nonce[13];

	LOG_DBG("PDU (%u bytes) %s", buf->len, bt_hex(buf->data, buf->len));
	LOG_DBG("iv_index %u, key %s mic_len %u", iv_index, bt_hex(key, 16), mic_len);

	if (IS_ENABLED(CONFIG_BT_MESH_PROXY) && proxy) {
		create_proxy_nonce(nonce, buf->data, iv_index);
	} else {
		create_net_nonce(nonce, buf->data, iv_index);
	}

	LOG_DBG("Nonce %s", bt_hex(nonce, 13));

	buf->len -= mic_len;

	return bt_ccm_decrypt(key, nonce, &buf->data[7], buf->len - 7, NULL, 0,
			      &buf->data[7], mic_len);
}

static void create_app_nonce(uint8_t nonce[13],
			     const struct bt_mesh_app_crypto_ctx *ctx)
{
	if (ctx->dev_key) {
		nonce[0] = 0x02;
	} else {
		nonce[0] = 0x01;
	}

	sys_put_be32((ctx->seq_num | ((uint32_t)ctx->aszmic << 31)), &nonce[1]);

	sys_put_be16(ctx->src, &nonce[5]);
	sys_put_be16(ctx->dst, &nonce[7]);

	sys_put_be32(ctx->iv_index, &nonce[9]);
}

int bt_mesh_app_encrypt(const uint8_t key[16],
			const struct bt_mesh_app_crypto_ctx *ctx,
			struct net_buf_simple *buf)
{
	uint8_t nonce[13];
	int err;

	LOG_DBG("AppKey %s", bt_hex(key, 16));
	LOG_DBG("dev_key %u src 0x%04x dst 0x%04x", ctx->dev_key, ctx->src, ctx->dst);
	LOG_DBG("seq_num 0x%08x iv_index 0x%08x", ctx->seq_num, ctx->iv_index);
	LOG_DBG("Clear: %s", bt_hex(buf->data, buf->len));

	create_app_nonce(nonce, ctx);

	LOG_DBG("Nonce  %s", bt_hex(nonce, 13));

	err = bt_ccm_encrypt(key, nonce, buf->data, buf->len, ctx->ad,
			     ctx->ad ? 16 : 0, buf->data,
			     APP_MIC_LEN(ctx->aszmic));
	if (!err) {
		net_buf_simple_add(buf, APP_MIC_LEN(ctx->aszmic));
		LOG_DBG("Encr: %s", bt_hex(buf->data, buf->len));
	}

	return err;
}

int bt_mesh_app_decrypt(const uint8_t key[16],
			const struct bt_mesh_app_crypto_ctx *ctx,
			struct net_buf_simple *buf, struct net_buf_simple *out)
{
	uint8_t nonce[13];
	int err;

	LOG_DBG("EncData (len %u) %s", buf->len, bt_hex(buf->data, buf->len));

	create_app_nonce(nonce, ctx);

	LOG_DBG("AppKey %s", bt_hex(key, 16));
	LOG_DBG("Nonce  %s", bt_hex(nonce, 13));

	err = bt_ccm_decrypt(key, nonce, buf->data, buf->len, ctx->ad,
			     ctx->ad ? 16 : 0, out->data,
			     APP_MIC_LEN(ctx->aszmic));
	if (!err) {
		net_buf_simple_add(out, buf->len);
	}

	return err;
}

/* reversed, 8-bit, poly=0x07 */
static const uint8_t crc_table[256] = {
	0x00, 0x91, 0xe3, 0x72, 0x07, 0x96, 0xe4, 0x75,
	0x0e, 0x9f, 0xed, 0x7c, 0x09, 0x98, 0xea, 0x7b,
	0x1c, 0x8d, 0xff, 0x6e, 0x1b, 0x8a, 0xf8, 0x69,
	0x12, 0x83, 0xf1, 0x60, 0x15, 0x84, 0xf6, 0x67,

	0x38, 0xa9, 0xdb, 0x4a, 0x3f, 0xae, 0xdc, 0x4d,
	0x36, 0xa7, 0xd5, 0x44, 0x31, 0xa0, 0xd2, 0x43,
	0x24, 0xb5, 0xc7, 0x56, 0x23, 0xb2, 0xc0, 0x51,
	0x2a, 0xbb, 0xc9, 0x58, 0x2d, 0xbc, 0xce, 0x5f,

	0x70, 0xe1, 0x93, 0x02, 0x77, 0xe6, 0x94, 0x05,
	0x7e, 0xef, 0x9d, 0x0c, 0x79, 0xe8, 0x9a, 0x0b,
	0x6c, 0xfd, 0x8f, 0x1e, 0x6b, 0xfa, 0x88, 0x19,
	0x62, 0xf3, 0x81, 0x10, 0x65, 0xf4, 0x86, 0x17,

	0x48, 0xd9, 0xab, 0x3a, 0x4f, 0xde, 0xac, 0x3d,
	0x46, 0xd7, 0xa5, 0x34, 0x41, 0xd0, 0xa2, 0x33,
	0x54, 0xc5, 0xb7, 0x26, 0x53, 0xc2, 0xb0, 0x21,
	0x5a, 0xcb, 0xb9, 0x28, 0x5d, 0xcc, 0xbe, 0x2f,

	0xe0, 0x71, 0x03, 0x92, 0xe7, 0x76, 0x04, 0x95,
	0xee, 0x7f, 0x0d, 0x9c, 0xe9, 0x78, 0x0a, 0x9b,
	0xfc, 0x6d, 0x1f, 0x8e, 0xfb, 0x6a, 0x18, 0x89,
	0xf2, 0x63, 0x11, 0x80, 0xf5, 0x64, 0x16, 0x87,

	0xd8, 0x49, 0x3b, 0xaa, 0xdf, 0x4e, 0x3c, 0xad,
	0xd6, 0x47, 0x35, 0xa4, 0xd1, 0x40, 0x32, 0xa3,
	0xc4, 0x55, 0x27, 0xb6, 0xc3, 0x52, 0x20, 0xb1,
	0xca, 0x5b, 0x29, 0xb8, 0xcd, 0x5c, 0x2e, 0xbf,

	0x90, 0x01, 0x73, 0xe2, 0x97, 0x06, 0x74, 0xe5,
	0x9e, 0x0f, 0x7d, 0xec, 0x99, 0x08, 0x7a, 0xeb,
	0x8c, 0x1d, 0x6f, 0xfe, 0x8b, 0x1a, 0x68, 0xf9,
	0x82, 0x13, 0x61, 0xf0, 0x85, 0x14, 0x66, 0xf7,

	0xa8, 0x39, 0x4b, 0xda, 0xaf, 0x3e, 0x4c, 0xdd,
	0xa6, 0x37, 0x45, 0xd4, 0xa1, 0x30, 0x42, 0xd3,
	0xb4, 0x25, 0x57, 0xc6, 0xb3, 0x22, 0x50, 0xc1,
	0xba, 0x2b, 0x59, 0xc8, 0xbd, 0x2c, 0x5e, 0xcf
};

uint8_t bt_mesh_fcs_calc(const uint8_t *data, uint8_t data_len)
{
	uint8_t fcs = 0xff;

	while (data_len--) {
		fcs = crc_table[fcs ^ *data++];
	}

	LOG_DBG("fcs 0x%02x", 0xff - fcs);

	return 0xff - fcs;
}

bool bt_mesh_fcs_check(struct net_buf_simple *buf, uint8_t received_fcs)
{
	const uint8_t *data = buf->data;
	uint16_t data_len = buf->len;
	uint8_t fcs = 0xff;

	while (data_len--) {
		fcs = crc_table[fcs ^ *data++];
	}

	return crc_table[fcs ^ received_fcs] == 0xcf;
}

int bt_mesh_virtual_addr(const uint8_t virtual_label[16], uint16_t *addr)
{
	uint8_t salt[16];
	uint8_t tmp[16];
	int err;

	err = bt_mesh_s1("vtad", salt);
	if (err) {
		return err;
	}

	err = bt_mesh_aes_cmac_one(salt, virtual_label, 16, tmp);
	if (err) {
		return err;
	}

	*addr = (sys_get_be16(&tmp[14]) & 0x3fff) | 0x8000;

	return 0;
}

int bt_mesh_prov_salt(const uint8_t conf_salt[16], const uint8_t prov_rand[16],
		      const uint8_t dev_rand[16], uint8_t prov_salt[16])
{
	const uint8_t prov_salt_key[16] = { 0 };
	struct bt_mesh_sg sg[] = {
		{ conf_salt, 16 },
		{ prov_rand, 16 },
		{ dev_rand, 16 },
	};

	return bt_mesh_aes_cmac(prov_salt_key, sg, ARRAY_SIZE(sg), prov_salt);
}

int bt_mesh_prov_conf_salt(const uint8_t conf_inputs[145], uint8_t salt[16])
{
	const uint8_t conf_salt_key[16] = { 0 };

	return bt_mesh_aes_cmac_one(conf_salt_key, conf_inputs, 145, salt);
}

int bt_mesh_prov_conf_key(const uint8_t dhkey[32], const uint8_t conf_salt[16],
			  uint8_t conf_key[16])
{
	return bt_mesh_k1(dhkey, 32, conf_salt, "prck", conf_key);
}

int bt_mesh_prov_conf(const uint8_t conf_key[16], const uint8_t rand[16],
		      const uint8_t auth[16], uint8_t conf[16])
{
	struct bt_mesh_sg sg[] = { { rand, 16 }, { auth, 16 } };

	LOG_DBG("ConfirmationKey %s", bt_hex(conf_key, 16));
	LOG_DBG("RandomDevice %s", bt_hex(rand, 16));
	LOG_DBG("AuthValue %s", bt_hex(auth, 16));

	return bt_mesh_aes_cmac(conf_key, sg, ARRAY_SIZE(sg), conf);
}

int bt_mesh_prov_decrypt(const uint8_t key[16], uint8_t nonce[13],
			 const uint8_t data[25 + 8], uint8_t out[25])
{
	return bt_ccm_decrypt(key, nonce, data, 25, NULL, 0, out, 8);
}

int bt_mesh_prov_encrypt(const uint8_t key[16], uint8_t nonce[13],
			 const uint8_t data[25], uint8_t out[25 + 8])
{
	return bt_ccm_encrypt(key, nonce, data, 25, NULL, 0, out, 8);
}

int bt_mesh_beacon_auth(const uint8_t beacon_key[16], uint8_t flags,
			const uint8_t net_id[8], uint32_t iv_index,
			uint8_t auth[8])
{
	uint8_t msg[13], tmp[16];
	int err;

	LOG_DBG("BeaconKey %s", bt_hex(beacon_key, 16));
	LOG_DBG("NetId %s", bt_hex(net_id, 8));
	LOG_DBG("IV Index 0x%08x", iv_index);

	msg[0] = flags;
	memcpy(&msg[1], net_id, 8);
	sys_put_be32(iv_index, &msg[9]);

	LOG_DBG("BeaconMsg %s", bt_hex(msg, sizeof(msg)));

	err = bt_mesh_aes_cmac_one(beacon_key, msg, sizeof(msg), tmp);
	if (!err) {
		memcpy(auth, tmp, 8);
	}

	return err;
}

int bt_mesh_dhkey_gen(const uint8_t *pub_key, const uint8_t *priv_key, uint8_t *dhkey)
{
	if (uECC_valid_public_key(pub_key, &curve_secp256r1)) {
		LOG_ERR("Public key is not valid");
		return -EIO;
	} else if (uECC_shared_secret(pub_key, priv_key, dhkey,
				&curve_secp256r1) != TC_CRYPTO_SUCCESS) {
		LOG_ERR("DHKey generation failed");
		return -EIO;
	}

	return 0;
}
