/**
 * @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 <misc/nano_work.h>
#include <tinycrypt/constants.h>
#include <tinycrypt/utils.h>
#include <tinycrypt/ecc.h>
#include <tinycrypt/ecc_dh.h>
#include <bluetooth/bluetooth.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(BT_HCI_EVT_CMD_STATUS);
	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;
	int rc;

	BT_DBG();

	net_buf_unref(buf);

	send_cmd_status(BT_HCI_OP_LE_P256_PUBLIC_KEY, 0);

	buf = bt_buf_get_evt(BT_HCI_EVT_LE_META_EVENT);
	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;
		}

		rc = ecc_make_key(&pkey, private_key, random);
		if (rc == TC_CRYPTO_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(BT_HCI_EVT_LE_META_EVENT);
	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_CRYPTO_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:
			net_buf_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;
}
