// SPDX-License-Identifier: GPL-2.0+
/*
 * Copyright (c) 2012 The Chromium OS Authors.
 *
 * (C) Copyright 2011
 * Joe Hershberger, National Instruments, joe.hershberger@ni.com
 *
 * (C) Copyright 2000
 * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
 */

#ifndef USE_HOSTCC
#include <common.h>
#include <command.h>
#include <env.h>
#include <log.h>
#include <malloc.h>
#include <mapmem.h>
#include <hw_sha.h>
#include <asm/cache.h>
#include <asm/global_data.h>
#include <asm/io.h>
#include <linux/errno.h>
#include <u-boot/crc.h>
#else
#include "mkimage.h"
#include <time.h>
#endif /* !USE_HOSTCC*/

#include <hash.h>
#include <image.h>
#include <u-boot/crc.h>
#include <u-boot/sha1.h>
#include <u-boot/sha256.h>
#include <u-boot/sha512.h>
#include <u-boot/md5.h>

#if !defined(USE_HOSTCC) && defined(CONFIG_NEEDS_MANUAL_RELOC)
DECLARE_GLOBAL_DATA_PTR;
#endif

static void reloc_update(void);

#if defined(CONFIG_SHA1) && !defined(CONFIG_SHA_PROG_HW_ACCEL)
static int hash_init_sha1(struct hash_algo *algo, void **ctxp)
{
	sha1_context *ctx = malloc(sizeof(sha1_context));
	sha1_starts(ctx);
	*ctxp = ctx;
	return 0;
}

static int hash_update_sha1(struct hash_algo *algo, void *ctx, const void *buf,
			    unsigned int size, int is_last)
{
	sha1_update((sha1_context *)ctx, buf, size);
	return 0;
}

static int hash_finish_sha1(struct hash_algo *algo, void *ctx, void *dest_buf,
			    int size)
{
	if (size < algo->digest_size)
		return -1;

	sha1_finish((sha1_context *)ctx, dest_buf);
	free(ctx);
	return 0;
}
#endif

#if defined(CONFIG_SHA256) && !defined(CONFIG_SHA_PROG_HW_ACCEL)
static int hash_init_sha256(struct hash_algo *algo, void **ctxp)
{
	sha256_context *ctx = malloc(sizeof(sha256_context));
	sha256_starts(ctx);
	*ctxp = ctx;
	return 0;
}

static int hash_update_sha256(struct hash_algo *algo, void *ctx,
			      const void *buf, unsigned int size, int is_last)
{
	sha256_update((sha256_context *)ctx, buf, size);
	return 0;
}

static int hash_finish_sha256(struct hash_algo *algo, void *ctx, void
			      *dest_buf, int size)
{
	if (size < algo->digest_size)
		return -1;

	sha256_finish((sha256_context *)ctx, dest_buf);
	free(ctx);
	return 0;
}
#endif

#if defined(CONFIG_SHA384) && !defined(CONFIG_SHA_PROG_HW_ACCEL)
static int hash_init_sha384(struct hash_algo *algo, void **ctxp)
{
	sha512_context *ctx = malloc(sizeof(sha512_context));
	sha384_starts(ctx);
	*ctxp = ctx;
	return 0;
}

static int hash_update_sha384(struct hash_algo *algo, void *ctx,
			      const void *buf, unsigned int size, int is_last)
{
	sha384_update((sha512_context *)ctx, buf, size);
	return 0;
}

static int hash_finish_sha384(struct hash_algo *algo, void *ctx, void
			      *dest_buf, int size)
{
	if (size < algo->digest_size)
		return -1;

	sha384_finish((sha512_context *)ctx, dest_buf);
	free(ctx);
	return 0;
}
#endif

#if defined(CONFIG_SHA512) && !defined(CONFIG_SHA_PROG_HW_ACCEL)
static int hash_init_sha512(struct hash_algo *algo, void **ctxp)
{
	sha512_context *ctx = malloc(sizeof(sha512_context));
	sha512_starts(ctx);
	*ctxp = ctx;
	return 0;
}

static int hash_update_sha512(struct hash_algo *algo, void *ctx,
			      const void *buf, unsigned int size, int is_last)
{
	sha512_update((sha512_context *)ctx, buf, size);
	return 0;
}

static int hash_finish_sha512(struct hash_algo *algo, void *ctx, void
			      *dest_buf, int size)
{
	if (size < algo->digest_size)
		return -1;

	sha512_finish((sha512_context *)ctx, dest_buf);
	free(ctx);
	return 0;
}
#endif


static int hash_init_crc16_ccitt(struct hash_algo *algo, void **ctxp)
{
	uint16_t *ctx = malloc(sizeof(uint16_t));
	*ctx = 0;
	*ctxp = ctx;
	return 0;
}

static int hash_update_crc16_ccitt(struct hash_algo *algo, void *ctx,
				   const void *buf, unsigned int size,
				   int is_last)
{
	*((uint16_t *)ctx) = crc16_ccitt(*((uint16_t *)ctx), buf, size);
	return 0;
}

static int hash_finish_crc16_ccitt(struct hash_algo *algo, void *ctx,
				   void *dest_buf, int size)
{
	if (size < algo->digest_size)
		return -1;

	*((uint16_t *)dest_buf) = *((uint16_t *)ctx);
	free(ctx);
	return 0;
}

static int hash_init_crc32(struct hash_algo *algo, void **ctxp)
{
	uint32_t *ctx = malloc(sizeof(uint32_t));
	*ctx = 0;
	*ctxp = ctx;
	return 0;
}

static int hash_update_crc32(struct hash_algo *algo, void *ctx,
			     const void *buf, unsigned int size, int is_last)
{
	*((uint32_t *)ctx) = crc32(*((uint32_t *)ctx), buf, size);
	return 0;
}

static int hash_finish_crc32(struct hash_algo *algo, void *ctx, void *dest_buf,
			     int size)
{
	if (size < algo->digest_size)
		return -1;

	*((uint32_t *)dest_buf) = *((uint32_t *)ctx);
	free(ctx);
	return 0;
}

#ifdef USE_HOSTCC
# define I_WANT_MD5	1
#else
# define I_WANT_MD5	CONFIG_IS_ENABLED(MD5)
#endif
/*
 * These are the hash algorithms we support.  If we have hardware acceleration
 * is enable we will use that, otherwise a software version of the algorithm.
 * Note that algorithm names must be in lower case.
 */
static struct hash_algo hash_algo[] = {
#if I_WANT_MD5
	{
		.name		= "md5",
		.digest_size	= MD5_SUM_LEN,
		.chunk_size	= CHUNKSZ_MD5,
		.hash_func_ws	= md5_wd,
	},
#endif
#ifdef CONFIG_SHA1
	{
		.name 		= "sha1",
		.digest_size	= SHA1_SUM_LEN,
		.chunk_size	= CHUNKSZ_SHA1,
#ifdef CONFIG_SHA_HW_ACCEL
		.hash_func_ws	= hw_sha1,
#else
		.hash_func_ws	= sha1_csum_wd,
#endif
#ifdef CONFIG_SHA_PROG_HW_ACCEL
		.hash_init	= hw_sha_init,
		.hash_update	= hw_sha_update,
		.hash_finish	= hw_sha_finish,
#else
		.hash_init	= hash_init_sha1,
		.hash_update	= hash_update_sha1,
		.hash_finish	= hash_finish_sha1,
#endif
	},
#endif
#ifdef CONFIG_SHA256
	{
		.name		= "sha256",
		.digest_size	= SHA256_SUM_LEN,
		.chunk_size	= CHUNKSZ_SHA256,
#ifdef CONFIG_SHA_HW_ACCEL
		.hash_func_ws	= hw_sha256,
#else
		.hash_func_ws	= sha256_csum_wd,
#endif
#ifdef CONFIG_SHA_PROG_HW_ACCEL
		.hash_init	= hw_sha_init,
		.hash_update	= hw_sha_update,
		.hash_finish	= hw_sha_finish,
#else
		.hash_init	= hash_init_sha256,
		.hash_update	= hash_update_sha256,
		.hash_finish	= hash_finish_sha256,
#endif
	},
#endif
#ifdef CONFIG_SHA384
	{
		.name		= "sha384",
		.digest_size	= SHA384_SUM_LEN,
		.chunk_size	= CHUNKSZ_SHA384,
#ifdef CONFIG_SHA512_HW_ACCEL
		.hash_func_ws	= hw_sha384,
#else
		.hash_func_ws	= sha384_csum_wd,
#endif
#if defined(CONFIG_SHA512_HW_ACCEL) && defined(CONFIG_SHA_PROG_HW_ACCEL)
		.hash_init	= hw_sha_init,
		.hash_update	= hw_sha_update,
		.hash_finish	= hw_sha_finish,
#else
		.hash_init	= hash_init_sha384,
		.hash_update	= hash_update_sha384,
		.hash_finish	= hash_finish_sha384,
#endif
	},
#endif
#ifdef CONFIG_SHA512
	{
		.name		= "sha512",
		.digest_size	= SHA512_SUM_LEN,
		.chunk_size	= CHUNKSZ_SHA512,
#ifdef CONFIG_SHA512_HW_ACCEL
		.hash_func_ws	= hw_sha512,
#else
		.hash_func_ws	= sha512_csum_wd,
#endif
#if defined(CONFIG_SHA512_HW_ACCEL) && defined(CONFIG_SHA_PROG_HW_ACCEL)
		.hash_init	= hw_sha_init,
		.hash_update	= hw_sha_update,
		.hash_finish	= hw_sha_finish,
#else
		.hash_init	= hash_init_sha512,
		.hash_update	= hash_update_sha512,
		.hash_finish	= hash_finish_sha512,
#endif
	},
#endif
	{
		.name		= "crc16-ccitt",
		.digest_size	= 2,
		.chunk_size	= CHUNKSZ,
		.hash_func_ws	= crc16_ccitt_wd_buf,
		.hash_init	= hash_init_crc16_ccitt,
		.hash_update	= hash_update_crc16_ccitt,
		.hash_finish	= hash_finish_crc16_ccitt,
	},
	{
		.name		= "crc32",
		.digest_size	= 4,
		.chunk_size	= CHUNKSZ_CRC32,
		.hash_func_ws	= crc32_wd_buf,
		.hash_init	= hash_init_crc32,
		.hash_update	= hash_update_crc32,
		.hash_finish	= hash_finish_crc32,
	},
};

/* Try to minimize code size for boards that don't want much hashing */
#if defined(CONFIG_SHA256) || defined(CONFIG_CMD_SHA1SUM) || \
	defined(CONFIG_CRC32_VERIFY) || defined(CONFIG_CMD_HASH) || \
	defined(CONFIG_SHA384) || defined(CONFIG_SHA512)
#define multi_hash()	1
#else
#define multi_hash()	0
#endif

static void reloc_update(void)
{
#if !defined(USE_HOSTCC) && defined(CONFIG_NEEDS_MANUAL_RELOC)
	int i;
	static bool done;

	if (!done) {
		done = true;
		for (i = 0; i < ARRAY_SIZE(hash_algo); i++) {
			hash_algo[i].name += gd->reloc_off;
			hash_algo[i].hash_func_ws += gd->reloc_off;
			hash_algo[i].hash_init += gd->reloc_off;
			hash_algo[i].hash_update += gd->reloc_off;
			hash_algo[i].hash_finish += gd->reloc_off;
		}
	}
#endif
}

int hash_lookup_algo(const char *algo_name, struct hash_algo **algop)
{
	int i;

	reloc_update();

	for (i = 0; i < ARRAY_SIZE(hash_algo); i++) {
		if (!strcmp(algo_name, hash_algo[i].name)) {
			*algop = &hash_algo[i];
			return 0;
		}
	}

	debug("Unknown hash algorithm '%s'\n", algo_name);
	return -EPROTONOSUPPORT;
}

int hash_progressive_lookup_algo(const char *algo_name,
				 struct hash_algo **algop)
{
	int i;

	reloc_update();

	for (i = 0; i < ARRAY_SIZE(hash_algo); i++) {
		if (!strcmp(algo_name, hash_algo[i].name)) {
			if (hash_algo[i].hash_init) {
				*algop = &hash_algo[i];
				return 0;
			}
		}
	}

	debug("Unknown hash algorithm '%s'\n", algo_name);
	return -EPROTONOSUPPORT;
}

#ifndef USE_HOSTCC
int hash_parse_string(const char *algo_name, const char *str, uint8_t *result)
{
	struct hash_algo *algo;
	int ret;
	int i;

	ret = hash_lookup_algo(algo_name, &algo);
	if (ret)
		return ret;

	for (i = 0; i < algo->digest_size; i++) {
		char chr[3];

		strlcpy(chr, &str[i * 2], 3);
		result[i] = hextoul(chr, NULL);
	}

	return 0;
}

int hash_block(const char *algo_name, const void *data, unsigned int len,
	       uint8_t *output, int *output_size)
{
	struct hash_algo *algo;
	int ret;

	ret = hash_lookup_algo(algo_name, &algo);
	if (ret)
		return ret;

	if (output_size && *output_size < algo->digest_size) {
		debug("Output buffer size %d too small (need %d bytes)",
		      *output_size, algo->digest_size);
		return -ENOSPC;
	}
	if (output_size)
		*output_size = algo->digest_size;
	algo->hash_func_ws(data, len, output, algo->chunk_size);

	return 0;
}

#if defined(CONFIG_CMD_HASH) || defined(CONFIG_CMD_SHA1SUM) || defined(CONFIG_CMD_CRC32)
/**
 * store_result: Store the resulting sum to an address or variable
 *
 * @algo:		Hash algorithm being used
 * @sum:		Hash digest (algo->digest_size bytes)
 * @dest:		Destination, interpreted as a hex address if it starts
 *			with * (or allow_env_vars is 0) or otherwise as an
 *			environment variable.
 * @allow_env_vars:	non-zero to permit storing the result to an
 *			variable environment
 */
static void store_result(struct hash_algo *algo, const uint8_t *sum,
			 const char *dest, int allow_env_vars)
{
	unsigned int i;
	int env_var = 0;

	/*
	 * If environment variables are allowed, then we assume that 'dest'
	 * is an environment variable, unless it starts with *, in which
	 * case we assume it is an address. If not allowed, it is always an
	 * address. This is to support the crc32 command.
	 */
	if (allow_env_vars) {
		if (*dest == '*')
			dest++;
		else
			env_var = 1;
	}

	if (env_var) {
		char str_output[HASH_MAX_DIGEST_SIZE * 2 + 1];
		char *str_ptr = str_output;

		for (i = 0; i < algo->digest_size; i++) {
			sprintf(str_ptr, "%02x", sum[i]);
			str_ptr += 2;
		}
		*str_ptr = '\0';
		env_set(dest, str_output);
	} else {
		ulong addr;
		void *buf;

		addr = hextoul(dest, NULL);
		buf = map_sysmem(addr, algo->digest_size);
		memcpy(buf, sum, algo->digest_size);
		unmap_sysmem(buf);
	}
}

/**
 * parse_verify_sum: Parse a hash verification parameter
 *
 * @algo:		Hash algorithm being used
 * @verify_str:		Argument to parse. If it starts with * then it is
 *			interpreted as a hex address containing the hash.
 *			If the length is exactly the right number of hex digits
 *			for the digest size, then we assume it is a hex digest.
 *			Otherwise we assume it is an environment variable, and
 *			look up its value (it must contain a hex digest).
 * @vsum:		Returns binary digest value (algo->digest_size bytes)
 * @allow_env_vars:	non-zero to permit storing the result to an environment
 *			variable. If 0 then verify_str is assumed to be an
 *			address, and the * prefix is not expected.
 * @return 0 if ok, non-zero on error
 */
static int parse_verify_sum(struct hash_algo *algo, char *verify_str,
			    uint8_t *vsum, int allow_env_vars)
{
	int env_var = 0;

	/* See comment above in store_result() */
	if (allow_env_vars) {
		if (*verify_str == '*')
			verify_str++;
		else
			env_var = 1;
	}

	if (!env_var) {
		ulong addr;
		void *buf;

		addr = hextoul(verify_str, NULL);
		buf = map_sysmem(addr, algo->digest_size);
		memcpy(vsum, buf, algo->digest_size);
	} else {
		char *vsum_str;
		int digits = algo->digest_size * 2;

		/*
		 * As with the original code from sha1sum.c, we assume that a
		 * string which matches the digest size exactly is a hex
		 * string and not an environment variable.
		 */
		if (strlen(verify_str) == digits)
			vsum_str = verify_str;
		else {
			vsum_str = env_get(verify_str);
			if (vsum_str == NULL || strlen(vsum_str) != digits) {
				printf("Expected %d hex digits in env var\n",
				       digits);
				return 1;
			}
		}

		hash_parse_string(algo->name, vsum_str, vsum);
	}
	return 0;
}

static void hash_show(struct hash_algo *algo, ulong addr, ulong len, uint8_t *output)
{
	int i;

	printf("%s for %08lx ... %08lx ==> ", algo->name, addr, addr + len - 1);
	for (i = 0; i < algo->digest_size; i++)
		printf("%02x", output[i]);
}

int hash_command(const char *algo_name, int flags, struct cmd_tbl *cmdtp,
		 int flag, int argc, char *const argv[])
{
	ulong addr, len;

	if ((argc < 2) || ((flags & HASH_FLAG_VERIFY) && (argc < 3)))
		return CMD_RET_USAGE;

	addr = hextoul(*argv++, NULL);
	len = hextoul(*argv++, NULL);

	if (multi_hash()) {
		struct hash_algo *algo;
		u8 *output;
		uint8_t vsum[HASH_MAX_DIGEST_SIZE];
		void *buf;

		if (hash_lookup_algo(algo_name, &algo)) {
			printf("Unknown hash algorithm '%s'\n", algo_name);
			return CMD_RET_USAGE;
		}
		argc -= 2;

		if (algo->digest_size > HASH_MAX_DIGEST_SIZE) {
			puts("HASH_MAX_DIGEST_SIZE exceeded\n");
			return 1;
		}

		output = memalign(ARCH_DMA_MINALIGN,
				  sizeof(uint32_t) * HASH_MAX_DIGEST_SIZE);

		buf = map_sysmem(addr, len);
		algo->hash_func_ws(buf, len, output, algo->chunk_size);
		unmap_sysmem(buf);

		/* Try to avoid code bloat when verify is not needed */
#if defined(CONFIG_CRC32_VERIFY) || defined(CONFIG_SHA1SUM_VERIFY) || \
	defined(CONFIG_HASH_VERIFY)
		if (flags & HASH_FLAG_VERIFY) {
#else
		if (0) {
#endif
			if (parse_verify_sum(algo, *argv, vsum,
					flags & HASH_FLAG_ENV)) {
				printf("ERROR: %s does not contain a valid "
					"%s sum\n", *argv, algo->name);
				return 1;
			}
			if (memcmp(output, vsum, algo->digest_size) != 0) {
				int i;

				hash_show(algo, addr, len, output);
				printf(" != ");
				for (i = 0; i < algo->digest_size; i++)
					printf("%02x", vsum[i]);
				puts(" ** ERROR **\n");
				return 1;
			}
		} else {
			hash_show(algo, addr, len, output);
			printf("\n");

			if (argc) {
				store_result(algo, output, *argv,
					flags & HASH_FLAG_ENV);
			}
		unmap_sysmem(output);

		}

	/* Horrible code size hack for boards that just want crc32 */
	} else {
		ulong crc;
		ulong *ptr;

		crc = crc32_wd(0, (const uchar *)addr, len, CHUNKSZ_CRC32);

		printf("CRC32 for %08lx ... %08lx ==> %08lx\n",
				addr, addr + len - 1, crc);

		if (argc >= 3) {
			ptr = (ulong *)hextoul(argv[0], NULL);
			*ptr = crc;
		}
	}

	return 0;
}
#endif /* CONFIG_CMD_HASH || CONFIG_CMD_SHA1SUM || CONFIG_CMD_CRC32) */
#endif /* !USE_HOSTCC */
