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

#include <errno.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 <tinycrypt/hmac.h>

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

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

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

static struct {
	bool is_ready;
	uint8_t private_key_be[PRIV_KEY_SIZE];
	uint8_t public_key_be[PUB_KEY_SIZE];
} key;

int bt_mesh_encrypt(const uint8_t key[16], const uint8_t plaintext[16], uint8_t enc_data[16])
{
	return bt_encrypt_be(key, plaintext, enc_data);
}

int bt_mesh_ccm_encrypt(const uint8_t key[16], 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)
{
	return bt_ccm_encrypt(key, nonce, plaintext, len, aad, aad_len, enc_data, mic_size);
}

int bt_mesh_ccm_decrypt(const uint8_t key[16], 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)
{
	return bt_ccm_decrypt(key, nonce, enc_data, len, aad, aad_len, plaintext, mic_size);
}

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;
}

int bt_mesh_sha256_hmac(const uint8_t key[32], struct bt_mesh_sg *sg, size_t sg_len,
			uint8_t mac[32])
{
	struct tc_hmac_state_struct h;

	if (tc_hmac_set_key(&h, key, 32) == TC_CRYPTO_FAIL) {
		return -EIO;
	}

	if (tc_hmac_init(&h) == TC_CRYPTO_FAIL) {
		return -EIO;
	}

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

	if (tc_hmac_final(mac, 32, &h) == TC_CRYPTO_FAIL) {
		return -EIO;
	}

	return 0;
}

int bt_mesh_pub_key_gen(void)
{
	int rc = uECC_make_key(key.public_key_be, key.private_key_be, &curve_secp256r1);

	if (rc == TC_CRYPTO_FAIL) {
		key.is_ready = false;
		LOG_ERR("Failed to create public/private pair");
		return -EIO;
	}

	key.is_ready = true;

	return 0;
}

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

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 ? priv_key : key.private_key_be, dhkey,
				      &curve_secp256r1) != TC_CRYPTO_SUCCESS) {
		LOG_ERR("DHKey generation failed");
		return -EIO;
	}

	return 0;
}

__weak int default_CSPRNG(uint8_t *dst, unsigned int len)
{
	return !bt_rand(dst, len);
}

int bt_mesh_crypto_init(void)
{
	return 0;
}
