/*
 * Copyright (c) 2020 Bose Corporation
 * Copyright (c) 2021-2022 Nordic Semiconductor ASA
 *
 * SPDX-License-Identifier: Apache-2.0
 *
 * The static functions in this file operate on Big Endian (BE) as the
 * underlying encryption library is BE as well. Furthermore, the sample data
 * in the CSIS spec is also provided as BE, and logging values as BE will make
 * it easier to compare.
 */
#include "csip_crypto.h"
#include <zephyr/bluetooth/crypto.h>
#include <tinycrypt/constants.h>
#include <tinycrypt/utils.h>
#include <tinycrypt/aes.h>
#include <tinycrypt/cmac_mode.h>
#include <tinycrypt/ccm_mode.h>
#include <zephyr/sys/byteorder.h>

#include "common/bt_str.h"

#include <zephyr/logging/log.h>

LOG_MODULE_REGISTER(bt_csip_crypto, CONFIG_BT_CSIP_SET_MEMBER_CRYPTO_LOG_LEVEL);

#define BT_CSIP_CRYPTO_PADDING_SIZE 13
#define BT_CSIP_R_SIZE              3 /* r is 24 bit / 3 octet */
#define BT_CSIP_R_MASK              BIT_MASK(24) /* r is 24 bit / 3 octet */

static int aes_cmac(const uint8_t key[BT_CSIP_CRYPTO_KEY_SIZE],
		    const uint8_t *in, size_t in_len, uint8_t *out)
{
	struct tc_aes_key_sched_struct sched;
	struct tc_cmac_struct state;

	/* TODO: Copy of the aes_cmac from smp.c: Can we merge them? */

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

	if (tc_cmac_update(&state, in, in_len) == TC_CRYPTO_FAIL) {
		return -EIO;
	}

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

	return 0;
}

static void xor_128(const uint8_t a[16], const uint8_t b[16], uint8_t out[16])
{
	size_t len = 16;
	/* TODO: Identical to the xor_128 from smp.c: Move to util */

	while (len--) {
		*out++ = *a++ ^ *b++;
	}
}

int bt_csip_sih(const uint8_t sirk[BT_CSIP_SET_SIRK_SIZE], uint32_t r,
		uint32_t *out)
{
	uint8_t res[16]; /* need to store 128 bit */
	int err;
	uint8_t sirk_tmp[BT_CSIP_SET_SIRK_SIZE];

	if ((r & BIT(23)) || ((r & BIT(22)) == 0)) {
		LOG_DBG("Invalid r %0x06x", (uint32_t)(r & BT_CSIP_R_MASK));
	}

	LOG_DBG("SIRK %s", bt_hex(sirk, BT_CSIP_SET_SIRK_SIZE));
	LOG_DBG("r 0x%06x", r);

	/* r' = padding || r */
	(void)memset(res, 0, BT_CSIP_CRYPTO_PADDING_SIZE);
	sys_put_be24(r, res + BT_CSIP_CRYPTO_PADDING_SIZE);

	LOG_DBG("BE: r' %s", bt_hex(res, sizeof(res)));

	if (IS_ENABLED(CONFIG_LITTLE_ENDIAN)) {
		/* Swap to Big Endian (BE) */
		sys_memcpy_swap(sirk_tmp, sirk, BT_CSIP_SET_SIRK_SIZE);
	} else {
		(void)memcpy(sirk_tmp, sirk, BT_CSIP_SET_SIRK_SIZE);
	}

	err = bt_encrypt_be(sirk_tmp, res, res);

	if (err != 0) {
		return err;
	}

	/* The output of the function sih is:
	 *      sih(k, r) = e(k, r') mod 2^24
	 * The output of the security function e is then truncated to 24 bits
	 * by taking the least significant 24 bits of the output of e as the
	 * result of sih.
	 */

	LOG_DBG("BE: res %s", bt_hex(res, sizeof(res)));

	/* Result is the lowest 3 bytes */
	*out = sys_get_be24(res + 13);

	LOG_DBG("sih 0x%06x", *out);

	return 0;
}

/**
 * @brief k1 derivation function
 *
 * The key derivation function k1 is used to derive a key. The derived key is
 * used to encrypt and decrypt the value of the Set Identity Resolving Key
 * characteristic.
 *
 * @param n      n is 0 or more bytes.
 * @param n_size Number of bytes in @p n.
 * @param salt   A 16-byte salt.
 * @param p      p is 0 or more bytes.
 * @param p_size Number of bytes in @p p.
 * @param out    A 16-byte output buffer.
 * @return int 0 on success, any other value indicates a failure.
 */
static int k1(const uint8_t *n, size_t n_size,
	      const uint8_t salt[BT_CSIP_CRYPTO_SALT_SIZE],
	      const uint8_t *p, size_t p_size, uint8_t out[16])
{
	/* TODO: This is basically a duplicate of bt_mesh_k1 - Perhaps they can
	 * be merged
	 */
	uint8_t t[16];
	int err;

	/*
	 * T = AES_CMAC_SALT(N)
	 *
	 * k1(N, SALT, P) = AES-CMAC_T(P)
	 */

	LOG_DBG("BE: n %s", bt_hex(n, n_size));
	LOG_DBG("BE: salt %s", bt_hex(salt, BT_CSIP_CRYPTO_SALT_SIZE));
	LOG_DBG("BE: p %s", bt_hex(p, p_size));

	err = aes_cmac(salt, n, n_size, t);

	LOG_DBG("BE: t %s", bt_hex(t, sizeof(t)));

	if (err) {
		return err;
	}

	err = aes_cmac(t, p, p_size, out);

	LOG_DBG("BE: out %s", bt_hex(out, 16));

	return err;
}

/**
 * @brief s1 SALT generation function
 *
 * @param m      A non-zero length octet array or ASCII encoded string
 * @param m_size Size of @p m.
 * @param out    16-byte output buffer.
 * @return int 0 on success, any other value indicates a failure.
 */
static int s1(const uint8_t *m, size_t m_size,
	      uint8_t out[BT_CSIP_CRYPTO_SALT_SIZE])
{
	uint8_t zero[16];
	int err;

	/*
	 * s1(M) = AES-CMAC_zero(M)
	 */

	LOG_DBG("BE: m %s", bt_hex(m, m_size));

	memset(zero, 0, sizeof(zero));

	err = aes_cmac(zero, m, m_size, out);

	LOG_DBG("BE: out %s", bt_hex(out, 16));

	return err;
}

int bt_csip_sef(const uint8_t k[BT_CSIP_CRYPTO_KEY_SIZE],
		const uint8_t sirk[BT_CSIP_SET_SIRK_SIZE],
		uint8_t out_sirk[BT_CSIP_SET_SIRK_SIZE])
{
	const uint8_t m[] = {'S', 'I', 'R', 'K', 'e', 'n', 'c'};
	const uint8_t p[] = {'c', 's', 'i', 's'};
	uint8_t s1_out[BT_CSIP_CRYPTO_SALT_SIZE];
	uint8_t k1_out[BT_CSIP_CRYPTO_KEY_SIZE];
	uint8_t k1_tmp[BT_CSIP_CRYPTO_KEY_SIZE];
	int err;

	/*
	 * sef(K, SIRK) = k1(K, s1("SIRKenc"), "csis") ^ SIRK
	 */

	LOG_DBG("SIRK %s", bt_hex(sirk, BT_CSIP_SET_SIRK_SIZE));

	if (IS_ENABLED(CONFIG_LITTLE_ENDIAN)) {
		/* Swap because aes_cmac is big endian
		 * and we are little endian
		 */
		sys_memcpy_swap(k1_tmp, k, sizeof(k1_tmp));
	} else {
		(void)memcpy(k1_tmp, k, sizeof(k1_tmp));
	}
	LOG_DBG("BE: k %s", bt_hex(k1_tmp, sizeof(k1_tmp)));

	err = s1(m, sizeof(m), s1_out);
	if (err) {
		return err;
	}

	LOG_DBG("BE: s1 result %s", bt_hex(s1_out, sizeof(s1_out)));

	err = k1(k1_tmp, sizeof(k1_tmp), s1_out, p, sizeof(p), k1_out);
	if (err) {
		return err;
	}

	LOG_DBG("BE: k1 result %s", bt_hex(k1_out, sizeof(k1_out)));

	if (IS_ENABLED(CONFIG_LITTLE_ENDIAN)) {
		/* Swap result back to little endian */
		sys_mem_swap(k1_out, sizeof(k1_out));
	}

	xor_128(k1_out, sirk, out_sirk);
	LOG_DBG("out %s", bt_hex(out_sirk, BT_CSIP_SET_SIRK_SIZE));

	return 0;
}

int bt_csip_sdf(const uint8_t k[BT_CSIP_CRYPTO_KEY_SIZE],
		const uint8_t enc_sirk[BT_CSIP_SET_SIRK_SIZE],
		uint8_t out_sirk[BT_CSIP_SET_SIRK_SIZE])
{
	/* SIRK encryption is currently symmetric, which means that we can
	 * simply apply the sef function to decrypt it.
	 */

	/*
	 * sdf(K, EncSIRK) = k1(K, s1("SIRKenc"), "csis") ^ EncSIRK
	 */

	LOG_DBG("Running SDF as SEF");
	return bt_csip_sef(k, enc_sirk, out_sirk);
}
