/**
 * @file hci_ecc.c
 * HCI ECC emulation
 */

/*
 * Copyright (c) 2016 Intel Corporation
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include <zephyr.h>
#include <atomic.h>
#include <microkernel/task.h>
#include <misc/byteorder.h>
#include <tinycrypt/utils.h>
#include <tinycrypt/ecc.h>
#include <tinycrypt/ecc_dh.h>
#include <bluetooth/log.h>
#include <bluetooth/hci.h>
#include <bluetooth/driver.h>
#include "hci_core.h"

#if !defined(CONFIG_BLUETOOTH_DEBUG_HCI_CORE)
#undef BT_DBG
#define BT_DBG(fmt, ...)
#endif

/* based on Core Specification 4.2 Vol 3. Part H 2.3.5.6.1 */
static const uint32_t debug_private_key[8] = {
	0xcd3c1abd, 0x5899b8a6, 0xeb40b799, 0x4aff607b, 0xd2103f50, 0x74c9b3e3,
	0xa3c55f38, 0x3f49f6d4
};

static struct nano_fifo ecc_queue;
static int (*drv_send)(struct net_buf *buf);
static uint32_t private_key[8];

static void send_cmd_status(uint16_t opcode, uint8_t status)
{
	struct bt_hci_evt_cmd_status *evt;
	struct bt_hci_evt_hdr *hdr;
	struct net_buf *buf;

	BT_DBG("opcode %x status %x", opcode, status);

	buf = bt_buf_get_evt();
	if (!buf) {
		BT_ERR("No available event buffers!");
		return;
	}

	hdr = net_buf_add(buf, sizeof(*hdr));
	hdr->evt = BT_HCI_EVT_CMD_STATUS;
	hdr->len = sizeof(*evt);

	evt = net_buf_add(buf, sizeof(*evt));
	evt->ncmd = 1;
	evt->opcode = sys_cpu_to_le16(opcode);
	evt->status = status;

	bt_recv(buf);
}

static void emulate_le_p256_public_key_cmd(struct net_buf *buf)
{
	struct bt_hci_evt_le_p256_public_key_complete *evt;
	struct bt_hci_evt_le_meta_event *meta;
	struct bt_hci_evt_hdr *hdr;
	EccPoint pkey;

	BT_DBG();

	net_buf_unref(buf);

	send_cmd_status(BT_HCI_OP_LE_P256_PUBLIC_KEY, 0);

	buf = bt_buf_get_evt();
	if (!buf) {
		BT_ERR("No available event buffers!");
		return;
	}

	hdr = net_buf_add(buf, sizeof(*hdr));
	hdr->evt = BT_HCI_EVT_LE_META_EVENT;
	hdr->len = sizeof(*meta) + sizeof(*evt);

	meta = net_buf_add(buf, sizeof(*meta));
	meta->subevent = BT_HCI_EVT_LE_P256_PUBLIC_KEY_COMPLETE;

	evt = net_buf_add(buf, sizeof(*evt));
	evt->status = 0;

	do {
		uint32_t random[8];

		if (bt_rand((uint8_t *)random, sizeof(random))) {
			BT_ERR("Failed to get random bytes for ECC keys");
			evt->status = 0x1f; /* unspecified error */
			break;
		}

		if (ecc_make_key(&pkey, private_key, random) == TC_FAIL) {
			BT_ERR("Failed to create ECC public/private pair");
			evt->status = 0x1f; /* unspecified error */
			break;
		}

	/* make sure generated key isn't debug key */
	} while (memcmp(private_key, debug_private_key, 32) == 0);

	if (!evt->status) {
		memcpy(evt->key, pkey.x, 32);
		memcpy(&evt->key[32], pkey.y, 32);
	} else {
		memset(evt->key, 0, sizeof(evt->key));
	}

	bt_recv(buf);
}

static void emulate_le_generate_dhkey(struct net_buf *buf)
{
	struct bt_hci_evt_le_generate_dhkey_complete *evt;
	struct bt_hci_cp_le_generate_dhkey *cmd;
	struct bt_hci_evt_le_meta_event *meta;
	struct bt_hci_evt_hdr *hdr;
	EccPoint pk;

	cmd = (void *)buf->data  + sizeof(struct bt_hci_cmd_hdr);

	/* TODO verify cmd parameters? */
	send_cmd_status(BT_HCI_OP_LE_GENERATE_DHKEY, 0);

	memcpy(pk.x, cmd->key, 32);
	memcpy(pk.y, &cmd->key[32], 32);

	net_buf_unref(buf);

	buf = bt_buf_get_evt();
	if (!buf) {
		BT_ERR("No available event buffers!");
		return;
	}

	hdr = net_buf_add(buf, sizeof(*hdr));
	hdr->evt = BT_HCI_EVT_LE_META_EVENT;
	hdr->len = sizeof(*meta) + sizeof(*evt);

	meta = net_buf_add(buf, sizeof(*meta));
	meta->subevent = BT_HCI_EVT_LE_GENERATE_DHKEY_COMPLETE;

	evt = net_buf_add(buf, sizeof(*evt));
	evt->status = 0;

	if (ecc_valid_public_key(&pk) < 0) {
		evt->status = 0x1f; /* unspecified error */
		memset(evt->dhkey, 0, sizeof(evt->dhkey));
		bt_recv(buf);
		return;
	}

	if (ecdh_shared_secret((uint32_t *)evt->dhkey, &pk, private_key)
	    == TC_FAIL) {
		evt->status = 0x1f; /* unspecified error */
		memset(evt->dhkey, 0, sizeof(evt->dhkey));
	}

	bt_recv(buf);
}

static void ecc_task(void)
{
	nano_fifo_init(&ecc_queue);

	while (true) {
		struct net_buf *buf;

		buf = nano_task_fifo_get(&ecc_queue, TICKS_UNLIMITED);

		switch (bt_hci_get_cmd_opcode(buf)) {
		case BT_HCI_OP_LE_P256_PUBLIC_KEY:
			emulate_le_p256_public_key_cmd(buf);
			break;
		case BT_HCI_OP_LE_GENERATE_DHKEY:
			emulate_le_generate_dhkey(buf);
			break;
		default:
			BT_ERR("Unhandled command for ECC task (opcode %x)",
			       bt_hci_get_cmd_opcode(buf));
			net_buf_unref(buf);
			break;
		}
	}
}

/* TODO measure required stack size, 1024 is not enough */
DEFINE_TASK(ECC_TASKID, 10, ecc_task, 2048, EXE);

static void clear_ecc_events(struct net_buf *buf)
{
	struct bt_hci_cp_le_set_event_mask *cmd;

	cmd = (void *)buf->data  + sizeof(struct bt_hci_cmd_hdr);

	/*
	 * don't enable controller ECC events as those will be generated from
	 * emulation code
	 */
	cmd->events[0] &= ~0x80; /* LE Read Local P-256 PKey Compl */
	cmd->events[1] &= ~0x01; /* LE Generate DHKey Compl Event */
}

static int ecc_send(struct net_buf *buf)
{
	if (bt_buf_get_type(buf) == BT_BUF_CMD) {
		switch (bt_hci_get_cmd_opcode(buf)) {
		case BT_HCI_OP_LE_P256_PUBLIC_KEY:
		case BT_HCI_OP_LE_GENERATE_DHKEY:
			nano_fifo_put(&ecc_queue, buf);
			return 0;
		case BT_HCI_OP_LE_SET_EVENT_MASK:
			clear_ecc_events(buf);
			break;
		default:
			break;
		}
	}

	return drv_send(buf);
}

void bt_hci_ecc_init(void)
{
	/* set wrapper for driver send function */
	drv_send = bt_dev.drv->send;
	bt_dev.drv->send = ecc_send;
}
