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

#include <zephyr/init.h>
#include <zephyr/kernel.h>
#include <string.h>
#include <zephyr/device.h>
#include <zephyr/drivers/i2c.h>
#include <zephyr/sys/__assert.h>
#include <zephyr/crypto/crypto.h>

#include "crypto_ataes132a_priv.h"

#define D10D24S 11
#define MAX_RETRIES 3
#define ATAES132A_AES_KEY_SIZE 16

/* ATAES132A can store up to 16 different crypto keys */
#define CRYPTO_MAX_SESSION 16

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

static struct ataes132a_driver_state ataes132a_state[CRYPTO_MAX_SESSION];

static void ataes132a_init_states(void)
{
	int i;

	for (i = 0; i < ATAES132A_AES_KEY_SIZE; i++) {
		ataes132a_state[i].in_use = false;
		ataes132a_state[i].key_id = i;
	}
}

static int ataes132a_send_command(const struct device *dev, uint8_t opcode,
				  uint8_t mode, uint8_t *params,
				  uint8_t nparams, uint8_t *response,
				  uint8_t *nresponse)
{
	int retry_count = 0;
	struct ataes132a_device_data *data = dev->data;
	const struct ataes132a_device_config *cfg = dev->config;
	uint8_t count;
	uint8_t status;
	uint8_t crc[2];
	int i, i2c_return;

	count = nparams + 5;
	if (count > 64) {
		LOG_ERR("command too large for command buffer");
		return -EDOM;
	}

	/* If there is a command in progress, idle wait until it is available.
	 * If there is concurrency protection around the driver, this should
	 * never happen.
	 */
	read_reg_i2c(data->i2c, cfg->i2c_addr, ATAES_STATUS_REG, &status);

	while (status & ATAES_STATUS_WIP) {
		k_busy_wait(D10D24S);
		read_reg_i2c(data->i2c, cfg->i2c_addr,
			     ATAES_STATUS_REG, &status);
	}

	data->command_buffer[0] = count;
	data->command_buffer[1] = opcode;
	data->command_buffer[2] = mode;
	for (i = 0; i < nparams; i++) {
		data->command_buffer[i + 3] = params[i];
	}

	/*Calculate command CRC*/
	ataes132a_atmel_crc(data->command_buffer, nparams + 3, crc);
	data->command_buffer[nparams + 3] = crc[0];
	data->command_buffer[nparams + 4] = crc[1];

	/*Reset i/O address start before sending a command*/
	write_reg_i2c(data->i2c, cfg->i2c_addr,
		      ATAES_COMMAND_ADDRR_RESET, 0x0);

	/*Send a command through the command buffer*/
	i2c_return = burst_write_i2c(data->i2c, cfg->i2c_addr,
				     ATAES_COMMAND_MEM_ADDR,
				     data->command_buffer, count);

	LOG_DBG("BURST WRITE RETURN: %d", i2c_return);

	/* Idle-waiting for the command completion*/
	do {
		k_busy_wait(D10D24S);
		read_reg_i2c(data->i2c, cfg->i2c_addr,
			     ATAES_STATUS_REG, &status);
	} while (status & ATAES_STATUS_WIP);

	if (status & ATAES_STATUS_CRC) {
		LOG_ERR("incorrect CRC command");
		return -EINVAL;
	}

	if (!(status & ATAES_STATUS_RDY)) {
		LOG_ERR("expected response is not in place");
		return -EINVAL;
	}

	/* Read the response */
	burst_read_i2c(data->i2c, cfg->i2c_addr,
		       ATAES_COMMAND_MEM_ADDR,
		       data->command_buffer, 64);

	count = data->command_buffer[0];

	/* Calculate and validate response CRC */
	ataes132a_atmel_crc(data->command_buffer, count - 2, crc);

	LOG_DBG("COMMAND CRC %x%x", data->command_buffer[count - 2],
		     data->command_buffer[count - 1]);
	LOG_DBG("CALCULATED CRC %x%x", crc[0], crc[1]);

	/* If CRC fails retry reading MAX RETRIES times */
	while (crc[0] != data->command_buffer[count - 2] ||
	       crc[1] != data->command_buffer[count - 1]) {
		if (retry_count > MAX_RETRIES - 1) {
			LOG_ERR("response crc validation rebase"
				    " max retries");
			return -EINVAL;
		}

		burst_read_i2c(data->i2c, cfg->i2c_addr,
			       ATAES_COMMAND_MEM_ADDR,
			       data->command_buffer, 64);

		count = data->command_buffer[0];

		ataes132a_atmel_crc(data->command_buffer, count -  2, crc);
		retry_count++;

		LOG_DBG("COMMAND RETRY %d", retry_count);
		LOG_DBG("COMMAND CRC %x%x",
			    data->command_buffer[count - 2],
			    data->command_buffer[count - 1]);
		LOG_DBG("CALCULATED CRC %x%x", crc[0], crc[1]);
		}

	if ((status & ATAES_STATUS_ERR) || data->command_buffer[1] != 0x00) {
		LOG_ERR("command execution error %x",
			    data->command_buffer[1]);
		return -EIO;
	}

	LOG_DBG("Read the response count: %d", count);

	for (i = 0; i < count - 3; i++) {
		response[i] = data->command_buffer[i + 1];
	}

	*nresponse = count - 3;

	return 0;
}

int ataes132a_init(const struct device *dev)
{
	struct ataes132a_device_data *ataes132a = dev->data;
	const struct ataes132a_device_config *cfg = dev->config;
	uint32_t i2c_cfg;

	LOG_DBG("ATAES132A INIT");

	ataes132a->i2c = device_get_binding((char *)cfg->i2c_port);
	if (!ataes132a->i2c) {
		LOG_DBG("ATAE132A master controller not found!");
		return -EINVAL;
	}

	i2c_cfg = I2C_MODE_CONTROLLER | I2C_SPEED_SET(ATAES132A_BUS_SPEED);

	i2c_configure(ataes132a->i2c, i2c_cfg);

	k_sem_init(&ataes132a->device_sem, 1, K_SEM_MAX_LIMIT);

	ataes132a_init_states();

	return 0;
}

int ataes132a_aes_ccm_decrypt(const struct device *dev,
			      uint8_t key_id,
			      struct ataes132a_mac_mode *mac_mode,
			      struct ataes132a_mac_packet *mac_packet,
			      struct cipher_aead_pkt *aead_op,
			      uint8_t *nonce_buf)
{
	uint8_t command_mode = 0x0;
	struct ataes132a_device_data *data = dev->data;
	uint8_t out_len;
	uint8_t in_buf_len;
	uint8_t return_code;
	uint8_t expected_out_len;
	uint8_t param_buffer[52];

	if (!aead_op) {
		LOG_ERR("Parameter cannot be null");
		return -EINVAL;
	}

	if (!aead_op->pkt) {
		LOG_ERR("Parameter cannot be null");
		return -EINVAL;
	}

	in_buf_len = aead_op->pkt->in_len;
	expected_out_len = aead_op->pkt->out_len;

	/*The KeyConfig[EKeyID].ExternalCrypto bit must be 1b.*/
	if (!(ataes132a_state[key_id].key_config & ATAES_KEYCONFIG_EXTERNAL)) {
		LOG_ERR("key %x external mode disabled", key_id);
		return -EINVAL;
	}

	if (in_buf_len != 16U && in_buf_len != 32U) {
		LOG_ERR("ccm mode only accepts input blocks of 16"
			    " and 32 bytes");
		return -EINVAL;
	}

	if (expected_out_len > 32) {
		LOG_ERR("ccm mode cannot generate more than"
			    " 32 output bytes");
		return -EINVAL;
	}

	/* If KeyConfig[key_id].AuthKey is set, then prior authentication
	 * is required
	 */
	if (!(ataes132a_state[key_id].key_config & ATAES_KEYCONFIG_AUTHKEY)) {
		LOG_DBG("keep in mind key %x will require"
			    " previous authentication", key_id);
	}

	if (!aead_op->pkt->in_buf || !aead_op->pkt->out_buf) {
		return 0;
	}

	/* If the KeyConfig[EKeyID].RandomNonce bit is set
	 * the current nonce register content will be used.
	 * If there is an invalid random nonce or if there
	 * is no nonce synchronization between device
	 * the decrypt operation will fail accordingly.
	 */
	if (ataes132a_state[key_id].key_config & ATAES_KEYCONFIG_RAND_NONCE) {
		LOG_DBG("key %x requires random nonce,"
			    " nonce_buf will be ignored", key_id);

		LOG_DBG("current nonce register will be used");

	}

	k_sem_take(&data->device_sem, K_FOREVER);

	/* If the KeyConfig[EKeyID].RandomNonce bit is not set
	 * then the nonce send as parameter will be loaded into
	 * the nonce register.
	 */
	if (!(ataes132a_state[key_id].key_config & ATAES_KEYCONFIG_RAND_NONCE)
	    && nonce_buf) {
		param_buffer[0] = 0x0;
		param_buffer[1] = 0x0;
		param_buffer[2] = 0x0;
		param_buffer[3] = 0x0;
		memcpy(param_buffer + 4,  nonce_buf, 12);

		return_code = ataes132a_send_command(dev, ATAES_NONCE_OP,
						     0x0, param_buffer, 16,
						     param_buffer, &out_len);

		if (return_code != 0U) {
			LOG_ERR("nonce command ended with code %d",
				    return_code);
			k_sem_give(&data->device_sem);
			return -EINVAL;
		}

		if (param_buffer[0] != 0U) {
			LOG_ERR("nonce command failed with error"
				    " code %d", param_buffer[0]);
			k_sem_give(&data->device_sem);
			return -EIO;
		}
	}

	/* If the KeyConfig[EKeyID].RandomNonce bit is not set
	 * and the nonce send as parameter is a null value,
	 * the command will use the current nonce register value.
	 */
	if (!(ataes132a_state[key_id].key_config & ATAES_KEYCONFIG_RAND_NONCE)
	    && !nonce_buf) {
		LOG_DBG("current nonce register will be used");
	}

	/* Client decryption mode requires a MAC packet to specify the
	 * encryption key id and the MAC count of the encryption device
	 * to synchronize MAC generation
	 */
	if (mac_packet) {
		param_buffer[0] = mac_packet->encryption_key_id;
		param_buffer[2] = mac_packet->encryption_mac_count;
	} else {
		param_buffer[0] = 0x0;
		param_buffer[2] = 0x0;
		LOG_DBG("normal decryption mode"
			    " ignores mac_packet parameter");
	}

	/* Client decryption mode requires a MAC packet to specify
	 * if MAC counter, serial number and small zone number are
	 * included in MAC generation.
	 */
	if (mac_mode) {
		if (mac_mode->include_counter) {
			LOG_DBG("including usage counter in the MAC: "
				    "decrypt and encrypt dev must be the same");
			command_mode = command_mode | ATAES_MAC_MODE_COUNTER;
		}

		if (mac_mode->include_serial) {
			LOG_DBG("including serial number in the MAC: "
				    "decrypt and encrypt dev must be the same");
			command_mode = command_mode | ATAES_MAC_MODE_SERIAL;
		}

		if (mac_mode->include_smallzone) {
			LOG_DBG("including small zone in the MAC: "
				    "decrypt and encrypt dev share the "
				    "first four bytes of their small zone");
			command_mode = command_mode | ATAES_MAC_MODE_SMALLZONE;
		}
	}

	param_buffer[1] = key_id;
	param_buffer[3] = expected_out_len;
	if (aead_op->tag) {
		memcpy(param_buffer + 4,  aead_op->tag, 16);
	}
	memcpy(param_buffer + 20, aead_op->pkt->in_buf, in_buf_len);

	return_code = ataes132a_send_command(dev, ATAES_DECRYPT_OP,
					     command_mode, param_buffer,
					     in_buf_len + 4, param_buffer,
					     &out_len);

	if (return_code != 0U) {
		LOG_ERR("decrypt command ended with code %d", return_code);
		k_sem_give(&data->device_sem);
		return -EINVAL;
	}

	if (out_len < 2 || out_len > 33) {
		LOG_ERR("decrypt command response has invalid"
			    " size %d", out_len);
		k_sem_give(&data->device_sem);
		return -EINVAL;
	}

	if (param_buffer[0] != 0U) {
		LOG_ERR("legacy command failed with error"
			    " code %d", param_buffer[0]);
		k_sem_give(&data->device_sem);
		return -param_buffer[0];
	}

	if (expected_out_len != out_len - 1) {
		LOG_ERR("decrypted output data size %d and expected data"
			    " size %d  are different", out_len - 1,
			    expected_out_len);
		k_sem_give(&data->device_sem);
		return -EINVAL;
	}

	memcpy(aead_op->pkt->out_buf, param_buffer + 1, out_len - 1);

	k_sem_give(&data->device_sem);

	return 0;
}

int ataes132a_aes_ccm_encrypt(const struct device *dev,
			      uint8_t key_id,
			      struct ataes132a_mac_mode *mac_mode,
			      struct cipher_aead_pkt *aead_op,
			      uint8_t *nonce_buf,
			      uint8_t *mac_count)
{
	uint8_t command_mode = 0x0;
	struct ataes132a_device_data *data = dev->data;
	uint8_t buf_len;
	uint8_t out_len;
	uint8_t return_code;
	uint8_t param_buffer[40];

	if (!aead_op) {
		LOG_ERR("Parameter cannot be null");
		return -EINVAL;
	}

	if (!aead_op->pkt) {
		LOG_ERR("Parameter cannot be null");
		return -EINVAL;
	}

	buf_len = aead_op->pkt->in_len;

	/*The KeyConfig[EKeyID].ExternalCrypto bit must be 1b.*/
	if (!(ataes132a_state[key_id].key_config & ATAES_KEYCONFIG_EXTERNAL)) {
		LOG_ERR("key %x external mode disabled", key_id);
		return -EINVAL;
	}

	if (buf_len > 32) {
		LOG_ERR("only up to 32 bytes accepted for ccm mode");
			return -EINVAL;
	}

	/* If KeyConfig[key_id].AuthKey is set, then prior authentication
	 * is required
	 */
	if (!(ataes132a_state[key_id].key_config & ATAES_KEYCONFIG_AUTHKEY)) {
		LOG_DBG("keep in mind key %x will require"
			    " previous authentication", key_id);
	}

	if (!aead_op->pkt->in_buf || !aead_op->pkt->out_buf) {
		return 0;
	}

	/* If the KeyConfig[EKeyID].RandomNonce bit is set
	 * the current nonce register content will be used.
	 * If there is an invalid random nonce or if there
	 * is no nonce synchronization between device
	 * the decrypt operation will fail accordingly.
	 */
	if (ataes132a_state[key_id].key_config & ATAES_KEYCONFIG_RAND_NONCE) {
		LOG_DBG("key %x requires random nonce,"
			    " nonce_buf will be ignored", key_id);

		LOG_DBG("current nonce register will be used");

	}

	k_sem_take(&data->device_sem, K_FOREVER);

	/* If the KeyConfig[EKeyID].RandomNonce bit is not set
	 * then the nonce send as parameter will be loaded into
	 * the nonce register.
	 */
	if (!(ataes132a_state[key_id].key_config & ATAES_KEYCONFIG_RAND_NONCE)
	    && nonce_buf) {
		param_buffer[0] = 0x0;
		param_buffer[1] = 0x0;
		param_buffer[2] = 0x0;
		param_buffer[3] = 0x0;
		memcpy(param_buffer + 4,  nonce_buf, 12);

		return_code = ataes132a_send_command(dev, ATAES_NONCE_OP,
						     0x0, param_buffer, 16,
						     param_buffer, &out_len);

		if (return_code != 0U) {
			LOG_ERR("nonce command ended with code %d",
				    return_code);
			k_sem_give(&data->device_sem);
			return -EINVAL;
		}

		if (param_buffer[0] != 0U) {
			LOG_ERR("nonce command failed with error"
				    " code %d", param_buffer[0]);
			k_sem_give(&data->device_sem);
			return -EIO;
		}
	}
	/* If the KeyConfig[EKeyID].RandomNonce bit is not set
	 * and the nonce send as parameter is a null value,
	 * the command will use the current nonce register value.
	 */
	if (!(ataes132a_state[key_id].key_config & ATAES_KEYCONFIG_RAND_NONCE)
	    && !nonce_buf) {
		LOG_DBG("current nonce register will be used");
	}

	/* MAC packet to specify if MAC counter, serial number and small zone
	 * number are included in MAC generation.
	 */
	if (mac_mode) {
		if (mac_mode->include_counter) {
			LOG_DBG("including usage counter in the MAC: "
				    "decrypt and encrypt dev must be the same");
			command_mode = command_mode | ATAES_MAC_MODE_COUNTER;
		}

		if (mac_mode->include_serial) {
			LOG_DBG("including serial number in the MAC: "
				    "decrypt and encrypt dev must be the same");
			command_mode = command_mode | ATAES_MAC_MODE_SERIAL;
		}

		if (mac_mode->include_smallzone) {
			LOG_DBG("including small zone in the MAC: "
				    "decrypt and encrypt dev share the "
				    "first four bytes of their small zone");
			command_mode = command_mode | ATAES_MAC_MODE_SMALLZONE;
		}
	}

	param_buffer[0] = key_id;
	param_buffer[1] = buf_len;
	memcpy(param_buffer + 2, aead_op->pkt->in_buf, buf_len);

	return_code = ataes132a_send_command(dev, ATAES_ENCRYPT_OP,
					     command_mode, param_buffer,
					     buf_len + 2, param_buffer,
					     &out_len);

	if (return_code != 0U) {
		LOG_ERR("encrypt command ended with code %d", return_code);
		k_sem_give(&data->device_sem);
		return -EINVAL;
	}

	if (out_len < 33 || out_len > 49) {
		LOG_ERR("encrypt command response has invalid"
			    " size %d", out_len);
		k_sem_give(&data->device_sem);
		return -EINVAL;
	}

	if (param_buffer[0] != 0U) {
		LOG_ERR("encrypt command failed with error"
			    " code %d", param_buffer[0]);
		k_sem_give(&data->device_sem);
		return -EIO;
	}

	if (aead_op->tag) {
		memcpy(aead_op->tag, param_buffer + 1, 16);
	}
	memcpy(aead_op->pkt->out_buf, param_buffer + 17, out_len - 17U);

	if (mac_mode) {
		if (mac_mode->include_counter) {
			param_buffer[0] = 0x0;
			param_buffer[1] = 0x0;
			param_buffer[2] = 0x0;
			param_buffer[3] = 0x0;
			ataes132a_send_command(dev, ATAES_INFO_OP, 0x0,
					       param_buffer,	4,
					       param_buffer, &out_len);
			if (param_buffer[0] != 0U) {
				LOG_ERR("info command failed with error"
					    " code %d", param_buffer[0]);
				k_sem_give(&data->device_sem);
				return -EIO;
			}
			if (mac_count) {
				*mac_count = param_buffer[2];
			}
		}
	}

	k_sem_give(&data->device_sem);

	return 0;
}

int ataes132a_aes_ecb_block(const struct device *dev,
			    uint8_t key_id,
			    struct cipher_pkt *pkt)
{
	struct ataes132a_device_data *data = dev->data;
	uint8_t buf_len;
	uint8_t out_len;
	uint8_t return_code;
	uint8_t param_buffer[19];

	if (!pkt) {
		LOG_ERR("Parameter cannot be null");
		return -EINVAL;
	}

	buf_len = pkt->in_len;
	if (buf_len > 16) {
		LOG_ERR("input block cannot be above 16 bytes");
		return -EINVAL;
	}

	/* AES ECB can only be executed if the ChipConfig.LegacyE configuration
	 * is set to 1 and if KeyConfig[key_id].LegacyOK is set to 1.
	 */
	if (!(ataes132a_state[key_id].chip_config & ATAES_CHIPCONFIG_LEGACYE)) {
		LOG_ERR("legacy mode disabled");
		return -EINVAL;
	}

	if (!(ataes132a_state[key_id].key_config & ATAES_KEYCONFIG_LEGACYOK)) {
		LOG_ERR("key %x legacy mode disabled", key_id);
		return -EINVAL;
	}

	LOG_DBG("Chip config: %x", ataes132a_state[key_id].chip_config);
	LOG_DBG("Key ID: %d", key_id);
	LOG_DBG("Key config: %x", ataes132a_state[key_id].key_config);

	/* If KeyConfig[key_id].AuthKey is set, then prior authentication
	 * is required
	 */
	if (!(ataes132a_state[key_id].key_config & ATAES_KEYCONFIG_AUTHKEY)) {
		LOG_DBG("keep in mind key %x will require"
			    " previous authentication", key_id);
	}

	if (!pkt->in_buf || !pkt->out_buf) {
		return 0;
	}

	k_sem_take(&data->device_sem, K_FOREVER);

	param_buffer[0] = 0x0;
	param_buffer[1] = key_id;
	param_buffer[2] = 0x0;
	memcpy(param_buffer + 3, pkt->in_buf, buf_len);
	(void)memset(param_buffer + 3 + buf_len, 0x0, 16 - buf_len);

	return_code = ataes132a_send_command(dev, ATAES_LEGACY_OP, 0x00,
					     param_buffer, buf_len + 3,
					     param_buffer, &out_len);

	if (return_code != 0U) {
		LOG_ERR("legacy command ended with code %d", return_code);
		k_sem_give(&data->device_sem);
		return -EINVAL;
	}

	if (out_len != 17U) {
		LOG_ERR("legacy command response has invalid"
			    " size %d", out_len);
		k_sem_give(&data->device_sem);
		return -EINVAL;
	}
	if (param_buffer[0] != 0U) {
		LOG_ERR("legacy command failed with error"
			    " code %d", param_buffer[0]);
		k_sem_give(&data->device_sem);
		return -EIO;
	}

	memcpy(pkt->out_buf, param_buffer + 1, 16);

	k_sem_give(&data->device_sem);

	return 0;
}

static int do_ccm_encrypt_mac(struct cipher_ctx *ctx,
			      struct cipher_aead_pkt *aead_op, uint8_t *nonce)
{
	const struct device *dev = ctx->device;
	struct ataes132a_driver_state *state = ctx->drv_sessn_state;
	struct ataes132a_mac_mode mac_mode;
	uint8_t key_id;

	key_id = state->key_id;

	__ASSERT_NO_MSG(*(uint8_t *)ctx->key.handle == key_id);

	/* Removing all this salt from the MAC reduces the protection
	 * but allows any other crypto implementations to authorize
	 * the message.
	 */
	mac_mode.include_counter = false;
	mac_mode.include_serial = false;
	mac_mode.include_smallzone = false;

	if (aead_op->pkt->in_len <= 16 &&
	    aead_op->pkt->out_buf_max < 16) {
		LOG_ERR("Not enough space available in out buffer.");
		return -EINVAL;
	}

	if (aead_op->pkt->in_len > 16 &&
	    aead_op->pkt->out_buf_max < 32) {
		LOG_ERR("Not enough space available in out buffer.");
		return -EINVAL;
	}

	if (aead_op->pkt->in_len <= 16) {
		aead_op->pkt->out_len = 16;
	} else  if (aead_op->pkt->in_len > 16) {
		aead_op->pkt->out_len = 32;
	}

	if (aead_op->ad != NULL || aead_op->ad_len != 0U) {
		LOG_ERR("Associated data is not supported.");
		return -EINVAL;
	}

	ataes132a_aes_ccm_encrypt(dev, key_id, &mac_mode,
				  aead_op, nonce, NULL);

	return 0;
}

static int do_ccm_decrypt_auth(struct cipher_ctx *ctx,
			       struct cipher_aead_pkt *aead_op, uint8_t *nonce)
{
	const struct device *dev = ctx->device;
	struct ataes132a_driver_state *state = ctx->drv_sessn_state;
	struct ataes132a_mac_mode mac_mode;
	uint8_t key_id;

	key_id = state->key_id;

	__ASSERT_NO_MSG(*(uint8_t *)ctx->key.handle == key_id);

	/* Removing all this salt from the MAC reduces the protection
	 * but allows any other crypto implementations to authorize
	 * the message.
	 */
	mac_mode.include_counter = false;
	mac_mode.include_serial = false;
	mac_mode.include_smallzone = false;

	if (aead_op->pkt->in_len <= 16 &&
	    aead_op->pkt->out_buf_max < 16) {
		LOG_ERR("Not enough space available in out buffer.");
		return -EINVAL;
	}

	if (aead_op->pkt->in_len > 16 &&
	    aead_op->pkt->out_buf_max < 32) {
		LOG_ERR("Not enough space available in out buffer.");
		return -EINVAL;
	}

	aead_op->pkt->ctx = ctx;

	if (aead_op->ad != NULL || aead_op->ad_len != 0U) {
		LOG_ERR("Associated data is not supported.");
		return -EINVAL;
	}

	/* Normal Decryption Mode will only decrypt host generated packets */
	ataes132a_aes_ccm_decrypt(dev, key_id, &mac_mode,
				  NULL, aead_op, nonce);

	return 0;
}

static int do_block(struct cipher_ctx *ctx, struct cipher_pkt *pkt)
{
	const struct device *dev = ctx->device;
	struct ataes132a_driver_state *state = ctx->drv_sessn_state;
	uint8_t key_id;

	key_id = state->key_id;

	__ASSERT_NO_MSG(*(uint8_t *)ctx->key.handle == key_id);

	if (pkt->out_buf_max < 16) {
		LOG_ERR("Not enough space available in out buffer.");
		return -EINVAL;
	}

	pkt->out_len = 16;

	return ataes132a_aes_ecb_block(dev, key_id, pkt);
}

static int ataes132a_session_free(const struct device *dev,
				  struct cipher_ctx *session)
{
	struct ataes132a_driver_state *state = session->drv_sessn_state;

	ARG_UNUSED(dev);

	state->in_use = false;

	return 0;
}

static int ataes132a_session_setup(const struct device *dev,
				   struct cipher_ctx *ctx,
				   enum cipher_algo algo, enum cipher_mode mode,
				   enum cipher_op op_type)
{
	uint8_t key_id = *((uint8_t *)ctx->key.handle);
	struct ataes132a_device_data *data = dev->data;
	const struct ataes132a_device_config *cfg = dev->config;
	uint8_t config;

	if (ataes132a_state[key_id].in_use) {
		LOG_ERR("Session in progress");
		return -EINVAL;
	}
	if (mode == CRYPTO_CIPHER_MODE_CCM &&
	    ctx->mode_params.ccm_info.tag_len != 16U) {
		LOG_ERR("ATAES132A support 16 byte tag only.");
		return -EINVAL;
	}
	if (mode == CRYPTO_CIPHER_MODE_CCM &&
	    ctx->mode_params.ccm_info.nonce_len != 12U) {
		LOG_ERR("ATAES132A support 12 byte nonce only.");
		return -EINVAL;
	}

	ataes132a_state[key_id].in_use = true;
	read_reg_i2c(data->i2c, cfg->i2c_addr,
		     ATAES_KEYCFG_REG(key_id),
		     &config);
	ataes132a_state[key_id].key_config = config;
	read_reg_i2c(data->i2c, cfg->i2c_addr,
		     ATAES_CHIPCONFIG_REG,
		     &config);
	ataes132a_state[key_id].chip_config = config;

	ctx->drv_sessn_state = &ataes132a_state[key_id];
	ctx->device = dev;

	if (algo != CRYPTO_CIPHER_ALGO_AES) {
		LOG_ERR("ATAES132A unsupported algorithm");
		return -EINVAL;
	}

	/*ATAES132A support I2C polling only*/
	if (!(ctx->flags & CAP_SYNC_OPS)) {
		LOG_ERR("Async not supported by this driver");
		return -EINVAL;
	}

	if (ctx->keylen != ATAES132A_AES_KEY_SIZE) {
		LOG_ERR("ATAES132A unsupported key size");
		return -EINVAL;
	}

	if (op_type == CRYPTO_CIPHER_OP_ENCRYPT) {
		switch (mode) {
		case CRYPTO_CIPHER_MODE_ECB:
			ctx->ops.block_crypt_hndlr = do_block;
			break;
		case CRYPTO_CIPHER_MODE_CCM:
			ctx->ops.ccm_crypt_hndlr = do_ccm_encrypt_mac;
			break;
		default:
			LOG_ERR("ATAES132A unsupported mode");
			return -EINVAL;
		}
	} else {
		switch (mode) {
		case CRYPTO_CIPHER_MODE_ECB:
			ctx->ops.block_crypt_hndlr = do_block;
			break;
		case CRYPTO_CIPHER_MODE_CCM:
			ctx->ops.ccm_crypt_hndlr = do_ccm_decrypt_auth;
			break;
		default:
			LOG_ERR("ATAES132A unsupported mode");
			return -EINVAL;
		}
	}

	ctx->ops.cipher_mode = mode;

	return 0;
}

static int ataes132a_query_caps(const struct device *dev)
{
	return (CAP_OPAQUE_KEY_HNDL | CAP_SEPARATE_IO_BUFS |
		CAP_SYNC_OPS | CAP_AUTONONCE);
}

const struct ataes132a_device_config ataes132a_config = {
	.i2c_port = CONFIG_CRYPTO_ATAES132A_I2C_PORT_NAME,
	.i2c_addr = CONFIG_CRYPTO_ATAES132A_I2C_ADDR,
	.i2c_speed = ATAES132A_BUS_SPEED,
};

static struct crypto_driver_api crypto_enc_funcs = {
	.cipher_begin_session = ataes132a_session_setup,
	.cipher_free_session = ataes132a_session_free,
	.cipher_async_callback_set = NULL,
	.query_hw_caps = ataes132a_query_caps,
};

struct ataes132a_device_data ataes132a_data;

DEVICE_DEFINE(ataes132a, CONFIG_CRYPTO_ATAES132A_DRV_NAME, ataes132a_init,
		NULL, &ataes132a_data, &ataes132a_config,
		POST_KERNEL, CONFIG_CRYPTO_INIT_PRIORITY,
		(void *)&crypto_enc_funcs);
