// SPDX-License-Identifier: GPL-2.0+
/*
 * Copyright (c) 2021 ASPEED Technology Inc.
 * Author: ChiaWei Wang <chiawei_wang@aspeedtech.com>
 */
#include <config.h>
#include <dm.h>
#include <log.h>
#include <malloc.h>
#include <watchdog.h>
#include <u-boot/hash.h>
#include <u-boot/crc.h>
#include <u-boot/md5.h>
#include <u-boot/sha1.h>
#include <u-boot/sha256.h>
#include <u-boot/sha512.h>

/* CRC16-CCITT */
static void hash_init_crc16_ccitt(void *ctx)
{
	*((uint16_t *)ctx) = 0;
}

static void hash_update_crc16_ccitt(void *ctx, const void *ibuf, uint32_t ilen)
{
	*((uint16_t *)ctx) = crc16_ccitt(*((uint16_t *)ctx), ibuf, ilen);
}

static void hash_finish_crc16_ccitt(void *ctx, void *obuf)
{
	*((uint16_t *)obuf) = *((uint16_t *)ctx);
}

/* CRC32 */
static void hash_init_crc32(void *ctx)
{
	*((uint32_t *)ctx) = 0;
}

static void hash_update_crc32(void *ctx, const void *ibuf, uint32_t ilen)
{
	*((uint32_t *)ctx) = crc32(*((uint32_t *)ctx), ibuf, ilen);
}

static void hash_finish_crc32(void *ctx, void *obuf)
{
	*((uint32_t *)obuf) = *((uint32_t *)ctx);
}

/* MD5 */
static void hash_init_md5(void *ctx)
{
	MD5Init((MD5Context *)ctx);
}

static void hash_update_md5(void *ctx, const void *ibuf, uint32_t ilen)
{
	MD5Update((MD5Context *)ctx, ibuf, ilen);
}

static void hash_finish_md5(void *ctx, void *obuf)
{
	MD5Final(obuf, (MD5Context *)ctx);
}

/* SHA1 */
static void hash_init_sha1(void *ctx)
{
	sha1_starts((sha1_context *)ctx);
}

static void hash_update_sha1(void *ctx, const void *ibuf, uint32_t ilen)
{
	sha1_update((sha1_context *)ctx, ibuf, ilen);
}

static void hash_finish_sha1(void *ctx, void *obuf)
{
	sha1_finish((sha1_context *)ctx, obuf);
}

/* SHA256 */
static void hash_init_sha256(void *ctx)
{
	sha256_starts((sha256_context *)ctx);
}

static void hash_update_sha256(void *ctx, const void *ibuf, uint32_t ilen)
{
	sha256_update((sha256_context *)ctx, ibuf, ilen);
}

static void hash_finish_sha256(void *ctx, void *obuf)
{
	sha256_finish((sha256_context *)ctx, obuf);
}

/* SHA384 */
static void hash_init_sha384(void *ctx)
{
	sha384_starts((sha512_context *)ctx);
}

static void hash_update_sha384(void *ctx, const void *ibuf, uint32_t ilen)
{
	sha384_update((sha512_context *)ctx, ibuf, ilen);
}

static void hash_finish_sha384(void *ctx, void *obuf)
{
	sha384_finish((sha512_context *)ctx, obuf);
}

/* SHA512 */
static void hash_init_sha512(void *ctx)
{
	sha512_starts((sha512_context *)ctx);
}

static void hash_update_sha512(void *ctx, const void *ibuf, uint32_t ilen)
{
	sha512_update((sha512_context *)ctx, ibuf, ilen);
}

static void hash_finish_sha512(void *ctx, void *obuf)
{
	sha512_finish((sha512_context *)ctx, obuf);
}

struct sw_hash_ctx {
	enum HASH_ALGO algo;
	uint8_t algo_ctx[];
};

struct sw_hash_impl {
	void (*init)(void *ctx);
	void (*update)(void *ctx, const void *ibuf, uint32_t ilen);
	void (*finish)(void *ctx, void *obuf);
	uint32_t ctx_alloc_sz;
};

static struct sw_hash_impl sw_hash_impl[HASH_ALGO_NUM] = {
	[HASH_ALGO_CRC16_CCITT] = {
		.init = hash_init_crc16_ccitt,
		.update = hash_update_crc16_ccitt,
		.finish = hash_finish_crc16_ccitt,
		.ctx_alloc_sz = sizeof(uint16_t),
	},

	[HASH_ALGO_CRC32] = {
		.init = hash_init_crc32,
		.update = hash_update_crc32,
		.finish = hash_finish_crc32,
		.ctx_alloc_sz = sizeof(uint32_t),
	},

	[HASH_ALGO_MD5] = {
		.init = hash_init_md5,
		.update = hash_update_md5,
		.finish = hash_finish_md5,
		.ctx_alloc_sz = sizeof(MD5Context),
	},

	[HASH_ALGO_SHA1] = {
		.init = hash_init_sha1,
		.update = hash_update_sha1,
		.finish = hash_finish_sha1,
		.ctx_alloc_sz = sizeof(sha1_context),
	},

	[HASH_ALGO_SHA256] = {
		.init = hash_init_sha256,
		.update = hash_update_sha256,
		.finish = hash_finish_sha256,
		.ctx_alloc_sz = sizeof(sha256_context),
	},

	[HASH_ALGO_SHA384] = {
		.init = hash_init_sha384,
		.update = hash_update_sha384,
		.finish = hash_finish_sha384,
		.ctx_alloc_sz = sizeof(sha512_context),
	},

	[HASH_ALGO_SHA512] = {
		.init = hash_init_sha512,
		.update = hash_update_sha512,
		.finish = hash_finish_sha512,
		.ctx_alloc_sz = sizeof(sha512_context),
	},
};

static int sw_hash_init(struct udevice *dev, enum HASH_ALGO algo, void **ctxp)
{
	struct sw_hash_ctx *hash_ctx;
	struct sw_hash_impl *hash_impl = &sw_hash_impl[algo];

	hash_ctx = malloc(sizeof(hash_ctx->algo) + hash_impl->ctx_alloc_sz);
	if (!hash_ctx)
		return -ENOMEM;

	hash_ctx->algo = algo;

	hash_impl->init(hash_ctx->algo_ctx);

	*ctxp = hash_ctx;

	return 0;
}

static int sw_hash_update(struct udevice *dev, void *ctx, const void *ibuf, uint32_t ilen)
{
	struct sw_hash_ctx *hash_ctx = ctx;
	struct sw_hash_impl *hash_impl = &sw_hash_impl[hash_ctx->algo];

	hash_impl->update(hash_ctx->algo_ctx, ibuf, ilen);

	return 0;
}

static int sw_hash_finish(struct udevice *dev, void *ctx, void *obuf)
{
	struct sw_hash_ctx *hash_ctx = ctx;
	struct sw_hash_impl *hash_impl = &sw_hash_impl[hash_ctx->algo];

	hash_impl->finish(hash_ctx->algo_ctx, obuf);

	free(ctx);

	return 0;
}

static int sw_hash_digest_wd(struct udevice *dev, enum HASH_ALGO algo,
			     const void *ibuf, const uint32_t ilen,
			     void *obuf, uint32_t chunk_sz)
{
	int rc;
	void *ctx;
	const void *cur, *end;
	uint32_t chunk;

	rc = sw_hash_init(dev, algo, &ctx);
	if (rc)
		return rc;

	if (IS_ENABLED(CONFIG_HW_WATCHDOG) || CONFIG_IS_ENABLED(WATCHDOG)) {
		cur = ibuf;
		end = ibuf + ilen;

		while (cur < end) {
			chunk = end - cur;
			if (chunk > chunk_sz)
				chunk = chunk_sz;

			rc = sw_hash_update(dev, ctx, cur, chunk);
			if (rc)
				return rc;

			cur += chunk;
			schedule();
		}
	} else {
		rc = sw_hash_update(dev, ctx, ibuf, ilen);
		if (rc)
			return rc;
	}

	rc = sw_hash_finish(dev, ctx, obuf);
	if (rc)
		return rc;

	return 0;
}

static int sw_hash_digest(struct udevice *dev, enum HASH_ALGO algo,
			  const void *ibuf, const uint32_t ilen,
			  void *obuf)
{
	/* re-use the watchdog version with input length as the chunk_sz */
	return sw_hash_digest_wd(dev, algo, ibuf, ilen, obuf, ilen);
}

static const struct hash_ops hash_ops_sw = {
	.hash_init = sw_hash_init,
	.hash_update = sw_hash_update,
	.hash_finish = sw_hash_finish,
	.hash_digest_wd = sw_hash_digest_wd,
	.hash_digest = sw_hash_digest,
};

U_BOOT_DRIVER(hash_sw) = {
	.name = "hash_sw",
	.id = UCLASS_HASH,
	.ops = &hash_ops_sw,
	.flags = DM_FLAG_PRE_RELOC,
};

U_BOOT_DRVINFO(hash_sw) = {
	.name = "hash_sw",
};
