/*
 * Copyright (c) 2019, NXP
 *
 * SPDX-License-Identifier: Apache-2.0
 */

#include <init.h>
#include <device.h>
#include <drivers/entropy.h>
#include <kernel.h>
#include <string.h>

#if defined(CONFIG_MBEDTLS)
#if !defined(CONFIG_MBEDTLS_CFG_FILE)
#include "mbedtls/config.h"
#else
#include CONFIG_MBEDTLS_CFG_FILE
#endif /* CONFIG_MBEDTLS_CFG_FILE */
#include <mbedtls/ctr_drbg.h>

#elif defined(CONFIG_TINYCRYPT)

#include <tinycrypt/ctr_prng.h>
#include <tinycrypt/aes.h>
#include <tinycrypt/constants.h>

#endif /* CONFIG_MBEDTLS */

static K_SEM_DEFINE(state_sem, 1, 1);

/*
 * entropy_dev is initialized at runtime to allow first time initialization
 * of the ctr_drbg engine.
 */
static const struct device *entropy_dev;
static const unsigned char drbg_seed[] = CONFIG_CS_CTR_DRBG_PERSONALIZATION;
static bool ctr_initialised;

#if defined(CONFIG_MBEDTLS)

static mbedtls_ctr_drbg_context ctr_ctx;

static int ctr_drbg_entropy_func(void *ctx, unsigned char *buf, size_t len)
{
	return entropy_get_entropy(entropy_dev, (void *)buf, len);
}

#elif defined(CONFIG_TINYCRYPT)

static TCCtrPrng_t ctr_ctx;

#endif /* CONFIG_MBEDTLS */


static int ctr_drbg_initialize(void)
{
	int ret;

	entropy_dev = DEVICE_DT_GET(DT_CHOSEN(zephyr_entropy));

	if (!device_is_ready(entropy_dev)) {
		__ASSERT(0, "Entropy device %s not ready", entropy_dev->name);
		return -ENODEV;
	}

#if defined(CONFIG_MBEDTLS)

	mbedtls_ctr_drbg_init(&ctr_ctx);

	ret = mbedtls_ctr_drbg_seed(&ctr_ctx,
				    ctr_drbg_entropy_func,
				    NULL,
				    drbg_seed,
				    sizeof(drbg_seed));

	if (ret != 0) {
		mbedtls_ctr_drbg_free(&ctr_ctx);
		return -EIO;
	}

#elif defined(CONFIG_TINYCRYPT)

	uint8_t entropy[TC_AES_KEY_SIZE + TC_AES_BLOCK_SIZE];

	ret = entropy_get_entropy(entropy_dev, (void *)&entropy,
				  sizeof(entropy));
	if (ret != 0) {
		return -EIO;
	}

	ret = tc_ctr_prng_init(&ctr_ctx,
			       (uint8_t *)&entropy,
			       sizeof(entropy),
			       (uint8_t *)drbg_seed,
			       sizeof(drbg_seed));

	if (ret == TC_CRYPTO_FAIL) {
		return -EIO;
	}

#endif
	ctr_initialised = true;
	return 0;
}


int z_impl_sys_csrand_get(void *dst, uint32_t outlen)
{
	int ret;
	unsigned int key = irq_lock();

	if (unlikely(!ctr_initialised)) {
		ret = ctr_drbg_initialize();
		if (ret != 0) {
			ret = -EIO;
			goto end;
		}
	}

#if defined(CONFIG_MBEDTLS)

	ret = mbedtls_ctr_drbg_random(&ctr_ctx, (unsigned char *)dst, outlen);

#elif defined(CONFIG_TINYCRYPT)

	uint8_t entropy[TC_AES_KEY_SIZE + TC_AES_BLOCK_SIZE];

	ret = tc_ctr_prng_generate(&ctr_ctx, 0, 0, (uint8_t *)dst, outlen);

	if (ret == TC_CRYPTO_SUCCESS) {
		ret = 0;
	} else if (ret == TC_CTR_PRNG_RESEED_REQ) {

		ret = entropy_get_entropy(entropy_dev,
				    (void *)&entropy, sizeof(entropy));
		if (ret != 0) {
			ret = -EIO;
			goto end;
		}

		ret = tc_ctr_prng_reseed(&ctr_ctx,
					entropy,
					sizeof(entropy),
					drbg_seed,
					sizeof(drbg_seed));

		ret = tc_ctr_prng_generate(&ctr_ctx, 0, 0,
					   (uint8_t *)dst, outlen);

		ret = (ret == TC_CRYPTO_SUCCESS) ? 0 : -EIO;
	} else {
		ret = -EIO;
	}
#endif
end:
	irq_unlock(key);

	return ret;
}
