/*
 * Copyright (c) 2020 Nordic Semiconductor ASA
 *
 * SPDX-License-Identifier: Apache-2.0
 */

#include <string.h>
#include <crypto/crypto.h>
#include <logging/log.h>
#include <hal/nrf_ecb.h>

#define DT_DRV_COMPAT nordic_nrf_ecb

#define ECB_AES_KEY_SIZE   16
#define ECB_AES_BLOCK_SIZE 16

LOG_MODULE_REGISTER(crypto_nrf_ecb, CONFIG_CRYPTO_LOG_LEVEL);

struct ecb_data {
	uint8_t key[ECB_AES_KEY_SIZE];
	uint8_t cleartext[ECB_AES_BLOCK_SIZE];
	uint8_t ciphertext[ECB_AES_BLOCK_SIZE];
};

struct nrf_ecb_drv_state {
	struct ecb_data data;
	bool in_use;
};

static struct nrf_ecb_drv_state drv_state;

static int do_ecb_encrypt(struct cipher_ctx *ctx, struct cipher_pkt *pkt)
{
	ARG_UNUSED(ctx);

	if (pkt->in_len != ECB_AES_BLOCK_SIZE) {
		LOG_ERR("only 16-byte blocks are supported");
		return -EINVAL;
	}
	if (pkt->out_buf_max < pkt->in_len) {
		LOG_ERR("output buffer too small");
		return -EINVAL;
	}

	if (pkt->in_buf != drv_state.data.cleartext) {
		memcpy(drv_state.data.cleartext, pkt->in_buf,
		       ECB_AES_BLOCK_SIZE);
	}

	nrf_ecb_event_clear(NRF_ECB, NRF_ECB_EVENT_ENDECB);
	nrf_ecb_event_clear(NRF_ECB, NRF_ECB_EVENT_ERRORECB);
	nrf_ecb_task_trigger(NRF_ECB, NRF_ECB_TASK_STARTECB);
	while (!(nrf_ecb_event_check(NRF_ECB, NRF_ECB_EVENT_ENDECB) ||
		 nrf_ecb_event_check(NRF_ECB, NRF_ECB_EVENT_ERRORECB))) {
	}
	if (nrf_ecb_event_check(NRF_ECB, NRF_ECB_EVENT_ERRORECB)) {
		LOG_ERR("ECB operation error");
		return -EIO;
	}
	if (pkt->out_buf != drv_state.data.ciphertext) {
		memcpy(pkt->out_buf, drv_state.data.ciphertext,
		       ECB_AES_BLOCK_SIZE);
	}
	pkt->out_len = pkt->in_len;
	return 0;
}

static int nrf_ecb_driver_init(const struct device *dev)
{
	ARG_UNUSED(dev);

	nrf_ecb_data_pointer_set(NRF_ECB, &drv_state.data);
	drv_state.in_use = false;
	return 0;
}

static int nrf_ecb_query_caps(const struct device *dev)
{
	ARG_UNUSED(dev);

	return (CAP_RAW_KEY | CAP_SEPARATE_IO_BUFS | CAP_SYNC_OPS);
}

static int nrf_ecb_session_setup(const struct device *dev,
				 struct cipher_ctx *ctx,
				 enum cipher_algo algo, enum cipher_mode mode,
				 enum cipher_op op_type)
{
	ARG_UNUSED(dev);

	if ((algo != CRYPTO_CIPHER_ALGO_AES) ||
	    !(ctx->flags & CAP_SYNC_OPS) ||
	    (ctx->keylen != ECB_AES_KEY_SIZE) ||
	    (op_type != CRYPTO_CIPHER_OP_ENCRYPT) ||
	    (mode != CRYPTO_CIPHER_MODE_ECB)) {
		LOG_ERR("This driver only supports 128-bit AES ECB encryption"
			" in synchronous mode");
		return -EINVAL;
	}

	if (ctx->key.bit_stream == NULL) {
		LOG_ERR("No key provided");
		return -EINVAL;
	}

	if (drv_state.in_use) {
		LOG_ERR("Peripheral in use");
		return -EBUSY;
	}

	drv_state.in_use = true;

	ctx->ops.block_crypt_hndlr = do_ecb_encrypt;
	ctx->ops.cipher_mode = mode;

	if (ctx->key.bit_stream != drv_state.data.key) {
		memcpy(drv_state.data.key, ctx->key.bit_stream,
		       ECB_AES_KEY_SIZE);
	}

	return 0;
}

static int nrf_ecb_session_free(const struct device *dev,
				struct cipher_ctx *sessn)
{
	ARG_UNUSED(dev);
	ARG_UNUSED(sessn);

	drv_state.in_use = false;

	return 0;
}

static const struct crypto_driver_api crypto_enc_funcs = {
	.cipher_begin_session = nrf_ecb_session_setup,
	.cipher_free_session = nrf_ecb_session_free,
	.cipher_async_callback_set = NULL,
	.query_hw_caps = nrf_ecb_query_caps,
};

DEVICE_DT_INST_DEFINE(0, nrf_ecb_driver_init, NULL,
		      NULL, NULL,
		      POST_KERNEL, CONFIG_CRYPTO_INIT_PRIORITY,
		      &crypto_enc_funcs);
