/*
 * Copyright (c) 2020 Siddharth Chandrasekaran <siddharth@embedjournal.com>
 *
 * SPDX-License-Identifier: Apache-2.0
 */

#include <ctype.h>

#include <zephyr/device.h>
#include <zephyr/sys/crc.h>
#include <zephyr/logging/log.h>

#ifdef CONFIG_OSDP_SC_ENABLED
#include <zephyr/crypto/crypto.h>
#include <zephyr/random/rand32.h>
#endif

#include "osdp_common.h"

LOG_MODULE_DECLARE(osdp, CONFIG_OSDP_LOG_LEVEL);

void osdp_dump(const char *head, uint8_t *buf, int len)
{
	LOG_HEXDUMP_DBG(buf, len, head);
}

uint16_t osdp_compute_crc16(const uint8_t *buf, size_t len)
{
	return crc16_itu_t(0x1D0F, buf, len);
}

int64_t osdp_millis_now(void)
{
	return (int64_t) k_uptime_get();
}

int64_t osdp_millis_since(int64_t last)
{
	int64_t tmp = last;

	return (int64_t) k_uptime_delta(&tmp);
}

#ifdef CONFIG_OSDP_SC_ENABLED

void osdp_encrypt(uint8_t *key, uint8_t *iv, uint8_t *data, int len)
{
	const struct device *dev;
	struct cipher_ctx ctx = {
		.keylen = 16,
		.key.bit_stream = key,
		.flags = CAP_NO_IV_PREFIX
	};
	struct cipher_pkt encrypt = {
		.in_buf = data,
		.in_len = len,
		.out_buf = data,
		.out_len = len
	};

	dev = device_get_binding(CONFIG_OSDP_CRYPTO_DRV_NAME);
	if (dev == NULL) {
		LOG_ERR("Failed to get crypto dev binding!");
		return;
	}

	if (iv != NULL) {
		if (cipher_begin_session(dev, &ctx,
					 CRYPTO_CIPHER_ALGO_AES,
					 CRYPTO_CIPHER_MODE_CBC,
					 CRYPTO_CIPHER_OP_ENCRYPT)) {
			LOG_ERR("Failed at cipher_begin_session");
			return;
		}
		if (cipher_cbc_op(&ctx, &encrypt, iv)) {
			LOG_ERR("CBC ENCRYPT - Failed");
		}
	} else {
		if (cipher_begin_session(dev, &ctx,
					 CRYPTO_CIPHER_ALGO_AES,
					 CRYPTO_CIPHER_MODE_ECB,
					 CRYPTO_CIPHER_OP_ENCRYPT)) {
			LOG_ERR("Failed at cipher_begin_session");
			return;
		}
		if (cipher_block_op(&ctx, &encrypt)) {
			LOG_ERR("ECB ENCRYPT - Failed");
		}
	}
	cipher_free_session(dev, &ctx);
}

void osdp_decrypt(uint8_t *key, uint8_t *iv, uint8_t *data, int len)
{
	const struct device *dev;
	struct cipher_ctx ctx = {
		.keylen = 16,
		.key.bit_stream = key,
		.flags = CAP_NO_IV_PREFIX
	};
	struct cipher_pkt decrypt = {
		.in_buf = data,
		.in_len = len,
		.out_buf = data,
		.out_len = len
	};

	dev = device_get_binding(CONFIG_OSDP_CRYPTO_DRV_NAME);
	if (dev == NULL) {
		LOG_ERR("Failed to get crypto dev binding!");
		return;
	}

	if (iv != NULL) {
		if (cipher_begin_session(dev, &ctx,
					 CRYPTO_CIPHER_ALGO_AES,
					 CRYPTO_CIPHER_MODE_CBC,
					 CRYPTO_CIPHER_OP_DECRYPT)) {
			LOG_ERR("Failed at cipher_begin_session");
			return;
		}
		if (cipher_cbc_op(&ctx, &decrypt, iv)) {
			LOG_ERR("CBC DECRYPT - Failed");
		}
	} else {
		if (cipher_begin_session(dev, &ctx,
					 CRYPTO_CIPHER_ALGO_AES,
					 CRYPTO_CIPHER_MODE_ECB,
					 CRYPTO_CIPHER_OP_DECRYPT)) {
			LOG_ERR("Failed at cipher_begin_session");
			return;
		}
		if (cipher_block_op(&ctx, &decrypt)) {
			LOG_ERR("ECB DECRYPT - Failed");
		}
	}
	cipher_free_session(dev, &ctx);
}

void osdp_fill_random(uint8_t *buf, int len)
{
	sys_csrand_get(buf, len);
}

uint32_t osdp_get_sc_status_mask(void)
{
	int i;
	uint32_t mask = 0;
	struct osdp_pd *pd;
	struct osdp *ctx = osdp_get_ctx();

	for (i = 0; i < NUM_PD(ctx); i++) {
		pd = osdp_to_pd(ctx, i);
		if (ISSET_FLAG(pd, PD_FLAG_SC_ACTIVE)) {
			mask |= 1 << i;
		}
	}
	return mask;
}

#endif /* CONFIG_OSDP_SC_ENABLED */
