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

/**
 * @file Shim layer for mbedTLS, crypto API compliant.
 */


#include <kernel.h>
#include <init.h>
#include <errno.h>
#include <crypto/crypto.h>

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

#include <mbedtls/ccm.h>
#ifdef CONFIG_MBEDTLS_CIPHER_GCM_ENABLED
#include <mbedtls/gcm.h>
#endif
#include <mbedtls/aes.h>

#include <mbedtls/sha256.h>
#include <mbedtls/sha512.h>

#define MTLS_SUPPORT (CAP_RAW_KEY | CAP_SEPARATE_IO_BUFS | CAP_SYNC_OPS | \
		      CAP_NO_IV_PREFIX)

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

struct mtls_shim_session {
	union {
		mbedtls_ccm_context mtls_ccm;
#ifdef CONFIG_MBEDTLS_CIPHER_GCM_ENABLED
		mbedtls_gcm_context mtls_gcm;
#endif
		mbedtls_aes_context mtls_aes;
		mbedtls_sha256_context mtls_sha256;
		mbedtls_sha512_context mtls_sha512;
	};
	bool in_use;
	union {
		enum cipher_mode mode;
		enum hash_algo algo;
	};
};

#define CRYPTO_MAX_SESSION CONFIG_CRYPTO_MBEDTLS_SHIM_MAX_SESSION

struct mtls_shim_session mtls_sessions[CRYPTO_MAX_SESSION];

#if defined(MBEDTLS_MEMORY_BUFFER_ALLOC_C)
#include "mbedtls/memory_buffer_alloc.h"
#else
#error "You need to define MBEDTLS_MEMORY_BUFFER_ALLOC_C"
#endif /* MBEDTLS_MEMORY_BUFFER_ALLOC_C */

#define MTLS_GET_CTX(c, m) \
	(&((struct mtls_shim_session *)c->drv_sessn_state)->mtls_ ## m)

#define MTLS_GET_ALGO(c) \
	(((struct mtls_shim_session *)c->drv_sessn_state)->algo)

int mtls_ecb_encrypt(struct cipher_ctx *ctx, struct cipher_pkt *pkt)
{
	int ret;
	mbedtls_aes_context *ecb_ctx = MTLS_GET_CTX(ctx, aes);

	/* For security reasons, ECB mode should not be used to encrypt
	 * more than one block. Use CBC mode instead.
	 */
	if (pkt->in_len > 16) {
		LOG_ERR("Cannot encrypt more than 1 block");
		return -EINVAL;
	}

	ret = mbedtls_aes_crypt_ecb(ecb_ctx, MBEDTLS_AES_ENCRYPT,
				    pkt->in_buf, pkt->out_buf);
	if (ret) {
		LOG_ERR("Could not encrypt (%d)", ret);
		return -EINVAL;
	}

	pkt->out_len = 16;

	return 0;
}

int mtls_ecb_decrypt(struct cipher_ctx *ctx, struct cipher_pkt *pkt)
{
	int ret;
	mbedtls_aes_context *ecb_ctx = MTLS_GET_CTX(ctx, aes);

	/* For security reasons, ECB mode should not be used to decrypt
	 * more than one block. Use CBC mode instead.
	 */
	if (pkt->in_len > 16) {
		LOG_ERR("Cannot decrypt more than 1 block");
		return -EINVAL;
	}

	ret = mbedtls_aes_crypt_ecb(ecb_ctx, MBEDTLS_AES_DECRYPT,
				    pkt->in_buf, pkt->out_buf);
	if (ret) {
		LOG_ERR("Could not encrypt (%d)", ret);
		return -EINVAL;
	}

	pkt->out_len = 16;

	return 0;
}

int mtls_cbc_encrypt(struct cipher_ctx *ctx, struct cipher_pkt *pkt, uint8_t *iv)
{
	int ret, iv_bytes;
	uint8_t *p_iv, iv_loc[16];
	mbedtls_aes_context *cbc_ctx = MTLS_GET_CTX(ctx, aes);

	if ((ctx->flags & CAP_NO_IV_PREFIX) == 0U) {
		/* Prefix IV to ciphertext, which is default behavior of Zephyr
		 * crypto API, unless CAP_NO_IV_PREFIX is requested.
		 */
		iv_bytes = 16;
		memcpy(pkt->out_buf, iv, 16);
		p_iv = iv;
	} else {
		iv_bytes = 0;
		memcpy(iv_loc, iv, 16);
		p_iv = iv_loc;
	}

	ret = mbedtls_aes_crypt_cbc(cbc_ctx, MBEDTLS_AES_ENCRYPT, pkt->in_len,
				    p_iv, pkt->in_buf, pkt->out_buf + iv_bytes);
	if (ret) {
		LOG_ERR("Could not encrypt (%d)", ret);
		return -EINVAL;
	}

	pkt->out_len = pkt->in_len + iv_bytes;

	return 0;
}

int mtls_cbc_decrypt(struct cipher_ctx *ctx, struct cipher_pkt *pkt, uint8_t *iv)
{
	int ret, iv_bytes;
	uint8_t *p_iv, iv_loc[16];
	mbedtls_aes_context *cbc_ctx = MTLS_GET_CTX(ctx, aes);

	if ((ctx->flags & CAP_NO_IV_PREFIX) == 0U) {
		iv_bytes = 16;
		p_iv = iv;
	} else {
		iv_bytes = 0;
		memcpy(iv_loc, iv, 16);
		p_iv = iv_loc;
	}

	ret = mbedtls_aes_crypt_cbc(cbc_ctx, MBEDTLS_AES_DECRYPT, pkt->in_len,
				    p_iv, pkt->in_buf + iv_bytes, pkt->out_buf);
	if (ret) {
		LOG_ERR("Could not encrypt (%d)", ret);
		return -EINVAL;
	}

	pkt->out_len = pkt->in_len - iv_bytes;

	return 0;
}

static int mtls_ccm_encrypt_auth(struct cipher_ctx *ctx,
				 struct cipher_aead_pkt *apkt,
				 uint8_t *nonce)
{
	mbedtls_ccm_context *mtls_ctx = MTLS_GET_CTX(ctx, ccm);
	int ret;

	ret = mbedtls_ccm_encrypt_and_tag(mtls_ctx, apkt->pkt->in_len, nonce,
					  ctx->mode_params.ccm_info.nonce_len,
					  apkt->ad, apkt->ad_len,
					  apkt->pkt->in_buf,
					  apkt->pkt->out_buf, apkt->tag,
					  ctx->mode_params.ccm_info.tag_len);
	if (ret) {
		LOG_ERR("Could not encrypt/auth (%d)", ret);

		/*ToDo: try to return relevant code depending on ret? */
		return -EINVAL;
	}

	/* This is equivalent to what the TinyCrypt shim does in
	 * do_ccm_encrypt_mac().
	 */
	apkt->pkt->out_len = apkt->pkt->in_len;
	apkt->pkt->out_len += ctx->mode_params.ccm_info.tag_len;

	return 0;
}

static int mtls_ccm_decrypt_auth(struct cipher_ctx *ctx,
				 struct cipher_aead_pkt *apkt,
				 uint8_t *nonce)
{
	mbedtls_ccm_context *mtls_ctx = MTLS_GET_CTX(ctx, ccm);
	int ret;

	ret = mbedtls_ccm_auth_decrypt(mtls_ctx, apkt->pkt->in_len, nonce,
				       ctx->mode_params.ccm_info.nonce_len,
				       apkt->ad, apkt->ad_len,
				       apkt->pkt->in_buf,
				       apkt->pkt->out_buf, apkt->tag,
				       ctx->mode_params.ccm_info.tag_len);
	if (ret) {
		if (ret == MBEDTLS_ERR_CCM_AUTH_FAILED) {
			LOG_ERR("Message authentication failed");
			return -EFAULT;
		}

		LOG_ERR("Could not decrypt/auth (%d)", ret);

		/*ToDo: try to return relevant code depending on ret? */
		return -EINVAL;
	}

	apkt->pkt->out_len = apkt->pkt->in_len;
	apkt->pkt->out_len += ctx->mode_params.ccm_info.tag_len;

	return 0;
}

#ifdef CONFIG_MBEDTLS_CIPHER_GCM_ENABLED
static int mtls_gcm_encrypt_auth(struct cipher_ctx *ctx,
				 struct cipher_aead_pkt *apkt,
				 uint8_t *nonce)
{
	mbedtls_gcm_context *mtls_ctx = MTLS_GET_CTX(ctx, gcm);
	int ret;

	ret = mbedtls_gcm_crypt_and_tag(mtls_ctx, MBEDTLS_GCM_ENCRYPT,
					  apkt->pkt->in_len, nonce,
					  ctx->mode_params.gcm_info.nonce_len,
					  apkt->ad, apkt->ad_len,
					  apkt->pkt->in_buf,
					  apkt->pkt->out_buf,
					  ctx->mode_params.gcm_info.tag_len,
					  apkt->tag);
	if (ret) {
		LOG_ERR("Could not encrypt/auth (%d)", ret);

		return -EINVAL;
	}

	/* This is equivalent to what is done in mtls_ccm_encrypt_auth(). */
	apkt->pkt->out_len = apkt->pkt->in_len;
	apkt->pkt->out_len += ctx->mode_params.gcm_info.tag_len;

	return 0;
}

static int mtls_gcm_decrypt_auth(struct cipher_ctx *ctx,
				 struct cipher_aead_pkt *apkt,
				 uint8_t *nonce)
{
	mbedtls_gcm_context *mtls_ctx = MTLS_GET_CTX(ctx, gcm);
	int ret;

	ret = mbedtls_gcm_auth_decrypt(mtls_ctx, apkt->pkt->in_len, nonce,
				       ctx->mode_params.gcm_info.nonce_len,
				       apkt->ad, apkt->ad_len,
				       apkt->tag,
				       ctx->mode_params.gcm_info.tag_len,
				       apkt->pkt->in_buf,
				       apkt->pkt->out_buf);
	if (ret) {
		if (ret == MBEDTLS_ERR_GCM_AUTH_FAILED) {
			LOG_ERR("Message authentication failed");
			return -EFAULT;
		}

		LOG_ERR("Could not decrypt/auth (%d)", ret);
		return -EINVAL;
	}

	apkt->pkt->out_len = apkt->pkt->in_len;
	apkt->pkt->out_len += ctx->mode_params.gcm_info.tag_len;

	return 0;
}
#endif /* CONFIG_MBEDTLS_CIPHER_GCM_ENABLED */

static int mtls_get_unused_session_index(void)
{
	int i;

	for (i = 0; i < CRYPTO_MAX_SESSION; i++) {
		if (!mtls_sessions[i].in_use) {
			mtls_sessions[i].in_use = true;
			return i;
		}
	}

	return -1;
}

static int mtls_session_setup(const struct device *dev,
			      struct cipher_ctx *ctx,
			      enum cipher_algo algo, enum cipher_mode mode,
			      enum cipher_op op_type)
{
	mbedtls_aes_context *aes_ctx;
	mbedtls_ccm_context *ccm_ctx;
#ifdef CONFIG_MBEDTLS_CIPHER_GCM_ENABLED
	mbedtls_gcm_context *gcm_ctx;
#endif
	int ctx_idx;
	int ret;

	if (ctx->flags & ~(MTLS_SUPPORT)) {
		LOG_ERR("Unsupported flag");
		return -EINVAL;
	}

	if (algo != CRYPTO_CIPHER_ALGO_AES) {
		LOG_ERR("Unsupported algo");
		return -EINVAL;
	}

	if (mode != CRYPTO_CIPHER_MODE_CCM &&
	    mode != CRYPTO_CIPHER_MODE_CBC &&
#ifdef CONFIG_MBEDTLS_CIPHER_GCM_ENABLED
	    mode != CRYPTO_CIPHER_MODE_GCM &&
#endif
	    mode != CRYPTO_CIPHER_MODE_ECB) {
		LOG_ERR("Unsupported mode");
		return -EINVAL;
	}

	if (ctx->keylen != 16U) {
		LOG_ERR("%u key size is not supported", ctx->keylen);
		return -EINVAL;
	}

	ctx_idx = mtls_get_unused_session_index();
	if (ctx_idx < 0) {
		LOG_ERR("No free session for now");
		return -ENOSPC;
	}


	switch (mode) {
	case CRYPTO_CIPHER_MODE_ECB:
		aes_ctx = &mtls_sessions[ctx_idx].mtls_aes;
		mbedtls_aes_init(aes_ctx);
		if (op_type == CRYPTO_CIPHER_OP_ENCRYPT) {
			ret = mbedtls_aes_setkey_enc(aes_ctx,
					ctx->key.bit_stream, ctx->keylen * 8U);
			ctx->ops.block_crypt_hndlr = mtls_ecb_encrypt;
		} else {
			ret = mbedtls_aes_setkey_dec(aes_ctx,
					ctx->key.bit_stream, ctx->keylen * 8U);
			ctx->ops.block_crypt_hndlr = mtls_ecb_decrypt;
		}
		if (ret) {
			LOG_ERR("AES_ECB: failed at setkey (%d)", ret);
			ctx->ops.block_crypt_hndlr = NULL;
			mtls_sessions[ctx_idx].in_use = false;
			return -EINVAL;
		}
		break;
	case CRYPTO_CIPHER_MODE_CBC:
		aes_ctx = &mtls_sessions[ctx_idx].mtls_aes;
		mbedtls_aes_init(aes_ctx);
		if (op_type == CRYPTO_CIPHER_OP_ENCRYPT) {
			ret = mbedtls_aes_setkey_enc(aes_ctx,
					ctx->key.bit_stream, ctx->keylen * 8U);
			ctx->ops.cbc_crypt_hndlr = mtls_cbc_encrypt;
		} else {
			ret = mbedtls_aes_setkey_dec(aes_ctx,
					ctx->key.bit_stream, ctx->keylen * 8U);
			ctx->ops.cbc_crypt_hndlr = mtls_cbc_decrypt;
		}
		if (ret) {
			LOG_ERR("AES_CBC: failed at setkey (%d)", ret);
			ctx->ops.cbc_crypt_hndlr = NULL;
			mtls_sessions[ctx_idx].in_use = false;
			return -EINVAL;
		}
		break;
	case CRYPTO_CIPHER_MODE_CCM:
		ccm_ctx = &mtls_sessions[ctx_idx].mtls_ccm;
		mbedtls_ccm_init(ccm_ctx);
		ret = mbedtls_ccm_setkey(ccm_ctx, MBEDTLS_CIPHER_ID_AES,
					 ctx->key.bit_stream, ctx->keylen * 8U);
		if (ret) {
			LOG_ERR("AES_CCM: failed at setkey (%d)", ret);
			mtls_sessions[ctx_idx].in_use = false;

			return -EINVAL;
		}
		if (op_type == CRYPTO_CIPHER_OP_ENCRYPT) {
			ctx->ops.ccm_crypt_hndlr = mtls_ccm_encrypt_auth;
		} else {
			ctx->ops.ccm_crypt_hndlr = mtls_ccm_decrypt_auth;
		}
		break;
#ifdef CONFIG_MBEDTLS_CIPHER_GCM_ENABLED
	case CRYPTO_CIPHER_MODE_GCM:
		gcm_ctx = &mtls_sessions[ctx_idx].mtls_gcm;
		mbedtls_gcm_init(gcm_ctx);
		ret = mbedtls_gcm_setkey(gcm_ctx, MBEDTLS_CIPHER_ID_AES,
					 ctx->key.bit_stream, ctx->keylen * 8U);
		if (ret) {
			LOG_ERR("AES_GCM: failed at setkey (%d)", ret);
			mtls_sessions[ctx_idx].in_use = false;

			return -EINVAL;
		}
		if (op_type == CRYPTO_CIPHER_OP_ENCRYPT) {
			ctx->ops.gcm_crypt_hndlr = mtls_gcm_encrypt_auth;
		} else {
			ctx->ops.gcm_crypt_hndlr = mtls_gcm_decrypt_auth;
		}
		break;
#endif /* CONFIG_MBEDTLS_CIPHER_GCM_ENABLED */
	default:
		LOG_ERR("Unhandled mode");
		mtls_sessions[ctx_idx].in_use = false;
		return -EINVAL;
	}

	mtls_sessions[ctx_idx].mode = mode;
	ctx->drv_sessn_state = &mtls_sessions[ctx_idx];

	return ret;
}

static int mtls_session_free(const struct device *dev, struct cipher_ctx *ctx)
{
	struct mtls_shim_session *mtls_session =
		(struct mtls_shim_session *)ctx->drv_sessn_state;

	if (mtls_session->mode == CRYPTO_CIPHER_MODE_CCM) {
		mbedtls_ccm_free(&mtls_session->mtls_ccm);
#ifdef CONFIG_MBEDTLS_CIPHER_GCM_ENABLED
	} else if (mtls_session->mode == CRYPTO_CIPHER_MODE_GCM) {
		mbedtls_gcm_free(&mtls_session->mtls_gcm);
#endif
	} else {
		mbedtls_aes_free(&mtls_session->mtls_aes);
	}
	mtls_session->in_use = false;

	return 0;
}

static int mtls_sha256_compute(struct hash_ctx *ctx, struct hash_pkt *pkt,
			       bool finish)
{
	int ret;
	mbedtls_sha256_context *sha256_ctx = MTLS_GET_CTX(ctx, sha256);


	if (!ctx->started) {
		ret = mbedtls_sha256_starts(sha256_ctx,
					    MTLS_GET_ALGO(ctx) == CRYPTO_HASH_ALGO_SHA224);
		if (ret != 0) {
			LOG_ERR("Could not compute the hash");
			return -EINVAL;
		}
		ctx->started = true;
	}

	ret = mbedtls_sha256_update(sha256_ctx, pkt->in_buf, pkt->in_len);
	if (ret != 0) {
		LOG_ERR("Could not update the hash");
		ctx->started = false;
		return -EINVAL;
	}

	if (finish) {
		ctx->started = false;
		ret = mbedtls_sha256_finish(sha256_ctx, pkt->out_buf);
		if (ret != 0) {
			LOG_ERR("Could not compute the hash");
			return -EINVAL;
		}
	}

	return 0;
}

static int mtls_sha512_compute(struct hash_ctx *ctx, struct hash_pkt *pkt,
			       bool finish)
{
	int ret;
	mbedtls_sha512_context *sha512_ctx = MTLS_GET_CTX(ctx, sha512);

	if (!ctx->started) {
		ret = mbedtls_sha512_starts(sha512_ctx,
					    MTLS_GET_ALGO(ctx) == CRYPTO_HASH_ALGO_SHA384);
		if (ret != 0) {
			LOG_ERR("Could not compute the hash");
			return -EINVAL;
		}
		ctx->started = true;
	}

	ret = mbedtls_sha512_update(sha512_ctx, pkt->in_buf, pkt->in_len);
	if (ret != 0) {
		LOG_ERR("Could not update the hash");
		ctx->started = false;
		return -EINVAL;
	}

	if (finish) {
		ctx->started = false;
		ret = mbedtls_sha512_finish(sha512_ctx, pkt->out_buf);
		if (ret != 0) {
			LOG_ERR("Could not compute the hash");
			return -EINVAL;
		}
	}

	return 0;
}

static int mtls_hash_session_setup(const struct device *dev,
				   struct hash_ctx *ctx,
				   enum hash_algo algo)
{
	int ctx_idx;

	if (ctx->flags & ~(MTLS_SUPPORT)) {
		LOG_ERR("Unsupported flag");
		return -EINVAL;
	}

	if ((algo != CRYPTO_HASH_ALGO_SHA224) &&
	    (algo != CRYPTO_HASH_ALGO_SHA256) &&
	    (algo != CRYPTO_HASH_ALGO_SHA384) &&
	    (algo != CRYPTO_HASH_ALGO_SHA512)) {
		LOG_ERR("Unsupported algo: %d", algo);
		return -EINVAL;
	}

	ctx_idx = mtls_get_unused_session_index();
	if (ctx_idx < 0) {
		LOG_ERR("No free session for now");
		return -ENOSPC;
	}

	mtls_sessions[ctx_idx].algo = algo;
	ctx->drv_sessn_state = &mtls_sessions[ctx_idx];
	ctx->started = false;

	if ((algo == CRYPTO_HASH_ALGO_SHA224) ||
	    (algo == CRYPTO_HASH_ALGO_SHA256)) {
		mbedtls_sha256_context *sha256_ctx =
			&mtls_sessions[ctx_idx].mtls_sha256;
		mbedtls_sha256_init(sha256_ctx);
		ctx->hash_hndlr = mtls_sha256_compute;
	} else {
		mbedtls_sha512_context *sha512_ctx =
			&mtls_sessions[ctx_idx].mtls_sha512;
		mbedtls_sha512_init(sha512_ctx);
		ctx->hash_hndlr = mtls_sha512_compute;
	}

	return 0;
}

static int mtls_hash_session_free(const struct device *dev, struct hash_ctx *ctx)
{
	struct mtls_shim_session *mtls_session =
		(struct mtls_shim_session *)ctx->drv_sessn_state;

	if (mtls_session->algo == CRYPTO_HASH_ALGO_SHA256) {
		mbedtls_sha256_free(&mtls_session->mtls_sha256);
	} else {
		mbedtls_sha512_free(&mtls_session->mtls_sha512);
	}
	mtls_session->in_use = false;

	return 0;
}


static int mtls_query_caps(const struct device *dev)
{
	return MTLS_SUPPORT;
}

static int mtls_shim_init(const struct device *dev)
{
	return 0;
}

static struct crypto_driver_api mtls_crypto_funcs = {
	.cipher_begin_session = mtls_session_setup,
	.cipher_free_session = mtls_session_free,
	.cipher_async_callback_set = NULL,
	.hash_begin_session = mtls_hash_session_setup,
	.hash_free_session = mtls_hash_session_free,
	.query_hw_caps = mtls_query_caps,
};

DEVICE_DEFINE(crypto_mtls, CONFIG_CRYPTO_MBEDTLS_SHIM_DRV_NAME,
		    &mtls_shim_init, NULL, NULL, NULL,
		    POST_KERNEL, CONFIG_CRYPTO_INIT_PRIORITY,
		    (void *)&mtls_crypto_funcs);
