/*
 * Copyright 2015 Freescale Semiconductor, Inc.
 *
 * SPDX-License-Identifier:	GPL-2.0+
 */

#include <common.h>
#include <fsl_validate.h>
#include <fsl_secboot_err.h>
#include <fsl_sfp.h>
#include <fsl_sec.h>
#include <command.h>
#include <malloc.h>
#include <dm/uclass.h>
#include <u-boot/rsa-mod-exp.h>
#include <hash.h>
#include <fsl_secboot_err.h>
#ifndef CONFIG_MPC85xx
#include <asm/arch/immap_ls102xa.h>
#endif

#define SHA256_BITS	256
#define SHA256_BYTES	(256/8)
#define SHA256_NIBBLES	(256/4)
#define NUM_HEX_CHARS	(sizeof(ulong) * 2)

/* This array contains DER value for SHA-256 */
static const u8 hash_identifier[] = { 0x30, 0x31, 0x30, 0x0d, 0x06, 0x09, 0x60,
		0x86, 0x48, 0x01, 0x65,	0x03, 0x04, 0x02, 0x01, 0x05, 0x00,
		0x04, 0x20
		};

static u8 hash_val[SHA256_BYTES];
static const u8 barker_code[ESBC_BARKER_LEN] = { 0x68, 0x39, 0x27, 0x81 };

void branch_to_self(void) __attribute__ ((noreturn));

/*
 * This function will put core in infinite loop.
 * This will be called when the ESBC can not proceed further due
 * to some unknown errors.
 */
void branch_to_self(void)
{
	printf("Core is in infinite loop due to errors.\n");
self:
	goto self;
}

#if defined(CONFIG_FSL_ISBC_KEY_EXT)
static u32 check_ie(struct fsl_secboot_img_priv *img)
{
	if (img->hdr.ie_flag)
		return 1;

	return 0;
}

/* This function returns the CSF Header Address of uboot
 * For MPC85xx based platforms, the LAW mapping for NOR
 * flash changes in uboot code. Hence the offset needs
 * to be calculated and added to the new NOR flash base
 * address
 */
#if defined(CONFIG_MPC85xx)
int get_csf_base_addr(ulong *csf_addr, ulong *flash_base_addr)
{
	struct ccsr_gur __iomem *gur = (void *)(CONFIG_SYS_MPC85xx_GUTS_ADDR);
	u32 csf_hdr_addr = in_be32(&gur->scratchrw[0]);
	u32 csf_flash_offset = csf_hdr_addr & ~(CONFIG_SYS_PBI_FLASH_BASE);
	ulong flash_addr, addr;
	int found = 0;
	int i = 0;

	for (i = 0; i < CONFIG_SYS_MAX_FLASH_BANKS; i++) {
		flash_addr = flash_info[i].start[0];
		addr = flash_info[i].start[0] + csf_flash_offset;
		if (memcmp((u8 *)addr, barker_code, ESBC_BARKER_LEN) == 0) {
			debug("Barker found on addr %lx\n", addr);
			found = 1;
			break;
		}
	}

	if (!found)
		return -1;

	*csf_addr = addr;
	*flash_base_addr = flash_addr;

	return 0;
}
#else
/* For platforms like LS1020, correct flash address is present in
 * the header. So the function reqturns flash base address as 0
 */
int get_csf_base_addr(ulong *csf_addr, ulong *flash_base_addr)
{
	struct ccsr_gur __iomem *gur = (void *)(CONFIG_SYS_FSL_GUTS_ADDR);
	u32 csf_hdr_addr = in_be32(&gur->scratchrw[0]);

	if (memcmp((u8 *)csf_hdr_addr, barker_code, ESBC_BARKER_LEN))
		return -1;

	*csf_addr = csf_hdr_addr;
	*flash_base_addr = 0;
	return 0;
}
#endif

static int get_ie_info_addr(ulong *ie_addr)
{
	struct fsl_secboot_img_hdr *hdr;
	struct fsl_secboot_sg_table *sg_tbl;
	ulong flash_base_addr, csf_addr;

	if (get_csf_base_addr(&csf_addr, &flash_base_addr))
		return -1;

	hdr = (struct fsl_secboot_img_hdr *)csf_addr;

	/* For SoC's with Trust Architecture v1 with corenet bus
	 * the sg table field in CSF header has absolute address
	 * for sg table in memory. In other Trust Architecture,
	 * this field specifies the offset of sg table from the
	 * base address of CSF Header
	 */
#if defined(CONFIG_FSL_TRUST_ARCH_v1) && defined(CONFIG_FSL_CORENET)
	sg_tbl = (struct fsl_secboot_sg_table *)
		 (((ulong)hdr->psgtable & ~(CONFIG_SYS_PBI_FLASH_BASE)) +
		  flash_base_addr);
#else
	sg_tbl = (struct fsl_secboot_sg_table *)(csf_addr +
						 (ulong)hdr->psgtable);
#endif

	/* IE Key Table is the first entry in the SG Table */
#if defined(CONFIG_MPC85xx)
	*ie_addr = (sg_tbl->src_addr & ~(CONFIG_SYS_PBI_FLASH_BASE)) +
		   flash_base_addr;
#else
	*ie_addr = sg_tbl->src_addr;
#endif

	debug("IE Table address is %lx\n", *ie_addr);
	return 0;
}

#endif

#ifdef CONFIG_KEY_REVOCATION
/* This function checks srk_table_flag in header and set/reset srk_flag.*/
static u32 check_srk(struct fsl_secboot_img_priv *img)
{
	if (img->hdr.len_kr.srk_table_flag & SRK_FLAG)
		return 1;

	return 0;
}

/* This function returns ospr's key_revoc values.*/
static u32 get_key_revoc(void)
{
	struct ccsr_sfp_regs *sfp_regs = (void *)(CONFIG_SYS_SFP_ADDR);
	return (sfp_in32(&sfp_regs->ospr) & OSPR_KEY_REVOC_MASK) >>
		OSPR_KEY_REVOC_SHIFT;
}

/* This function checks if selected key is revoked or not.*/
static u32 is_key_revoked(u32 keynum, u32 rev_flag)
{
	if (keynum == UNREVOCABLE_KEY)
		return 0;

	if ((u32)(1 << (ALIGN_REVOC_KEY - keynum)) & rev_flag)
		return 1;

	return 0;
}

/* It validates srk_table key lengths.*/
static u32 validate_srk_tbl(struct srk_table *tbl, u32 num_entries)
{
	int i = 0;
	for (i = 0; i < num_entries; i++) {
		if (!((tbl[i].key_len == 2 * KEY_SIZE_BYTES/4) ||
		      (tbl[i].key_len == 2 * KEY_SIZE_BYTES/2) ||
		      (tbl[i].key_len == 2 * KEY_SIZE_BYTES)))
			return ERROR_ESBC_CLIENT_HEADER_INV_SRK_ENTRY_KEYLEN;
	}
	return 0;
}
#endif

/* This function return length of public key.*/
static inline u32 get_key_len(struct fsl_secboot_img_priv *img)
{
	return img->key_len;
}

/*
 * Handles the ESBC uboot client header verification failure.
 * This  function  handles all the errors which might occur in the
 * parsing and checking of ESBC uboot client header. It will also
 * set the error bits in the SEC_MON.
 */
static void fsl_secboot_header_verification_failure(void)
{
	struct ccsr_sec_mon_regs *sec_mon_regs = (void *)
						(CONFIG_SYS_SEC_MON_ADDR);
	struct ccsr_sfp_regs *sfp_regs = (void *)(CONFIG_SYS_SFP_ADDR);
	u32 sts = sec_mon_in32(&sec_mon_regs->hp_stat);

	/* 29th bit of OSPR is ITS */
	u32 its = sfp_in32(&sfp_regs->ospr) >> 2;

	/*
	 * Read the SEC_MON status register
	 * Read SSM_ST field
	 */
	sts = sec_mon_in32(&sec_mon_regs->hp_stat);
	if ((sts & HPSR_SSM_ST_MASK) == HPSR_SSM_ST_TRUST) {
		if (its == 1)
			change_sec_mon_state(HPSR_SSM_ST_TRUST,
					     HPSR_SSM_ST_SOFT_FAIL);
		else
			change_sec_mon_state(HPSR_SSM_ST_TRUST,
					     HPSR_SSM_ST_NON_SECURE);
	}

	printf("Generating reset request\n");
	do_reset(NULL, 0, 0, NULL);
}

/*
 * Handles the ESBC uboot client image verification failure.
 * This  function  handles all the errors which might occur in the
 * public key hash comparison and signature verification of
 * ESBC uboot client image. It will also
 * set the error bits in the SEC_MON.
 */
static void fsl_secboot_image_verification_failure(void)
{
	struct ccsr_sec_mon_regs *sec_mon_regs = (void *)
						(CONFIG_SYS_SEC_MON_ADDR);
	struct ccsr_sfp_regs *sfp_regs = (void *)(CONFIG_SYS_SFP_ADDR);
	u32 sts = sec_mon_in32(&sec_mon_regs->hp_stat);

	u32 its = sfp_in32(&sfp_regs->ospr) & ITS_MASK >> ITS_BIT;

	/*
	 * Read the SEC_MON status register
	 * Read SSM_ST field
	 */
	sts = sec_mon_in32(&sec_mon_regs->hp_stat);
	if ((sts & HPSR_SSM_ST_MASK) == HPSR_SSM_ST_TRUST) {
		if (its == 1) {
			change_sec_mon_state(HPSR_SSM_ST_TRUST,
					     HPSR_SSM_ST_SOFT_FAIL);

			printf("Generating reset request\n");
			do_reset(NULL, 0, 0, NULL);
		} else {
			change_sec_mon_state(HPSR_SSM_ST_TRUST,
					     HPSR_SSM_ST_NON_SECURE);
		}
	}
}

static void fsl_secboot_bootscript_parse_failure(void)
{
	fsl_secboot_header_verification_failure();
}

/*
 * Handles the errors in esbc boot.
 * This  function  handles all the errors which might occur in the
 * esbc boot phase. It will call the appropriate api to log the
 * errors and set the error bits in the SEC_MON.
 */
void fsl_secboot_handle_error(int error)
{
	const struct fsl_secboot_errcode *e;

	for (e = fsl_secboot_errcodes; e->errcode != ERROR_ESBC_CLIENT_MAX;
		e++) {
		if (e->errcode == error)
			printf("ERROR :: %x :: %s\n", error, e->name);
	}

	switch (error) {
	case ERROR_ESBC_CLIENT_HEADER_BARKER:
	case ERROR_ESBC_CLIENT_HEADER_IMG_SIZE:
	case ERROR_ESBC_CLIENT_HEADER_KEY_LEN:
	case ERROR_ESBC_CLIENT_HEADER_SIG_LEN:
	case ERROR_ESBC_CLIENT_HEADER_KEY_LEN_NOT_TWICE_SIG_LEN:
	case ERROR_ESBC_CLIENT_HEADER_KEY_MOD_1:
	case ERROR_ESBC_CLIENT_HEADER_KEY_MOD_2:
	case ERROR_ESBC_CLIENT_HEADER_SIG_KEY_MOD:
	case ERROR_ESBC_CLIENT_HEADER_SG_ESBC_EP:
	case ERROR_ESBC_CLIENT_HEADER_SG_ENTIRES_BAD:
#ifdef CONFIG_KEY_REVOCATION
	case ERROR_ESBC_CLIENT_HEADER_KEY_REVOKED:
	case ERROR_ESBC_CLIENT_HEADER_INVALID_SRK_NUM_ENTRY:
	case ERROR_ESBC_CLIENT_HEADER_INVALID_KEY_NUM:
	case ERROR_ESBC_CLIENT_HEADER_INV_SRK_ENTRY_KEYLEN:
#endif
#if defined(CONFIG_FSL_ISBC_KEY_EXT)
	/*@fallthrough@*/
	case ERROR_ESBC_CLIENT_HEADER_IE_KEY_REVOKED:
	case ERROR_ESBC_CLIENT_HEADER_INVALID_IE_NUM_ENTRY:
	case ERROR_ESBC_CLIENT_HEADER_INVALID_IE_KEY_NUM:
	case ERROR_ESBC_CLIENT_HEADER_INV_IE_ENTRY_KEYLEN:
	case ERROR_IE_TABLE_NOT_FOUND:
#endif
		fsl_secboot_header_verification_failure();
		break;
	case ERROR_ESBC_SEC_RESET:
	case ERROR_ESBC_SEC_DEQ:
	case ERROR_ESBC_SEC_ENQ:
	case ERROR_ESBC_SEC_DEQ_TO:
	case ERROR_ESBC_SEC_JOBQ_STATUS:
	case ERROR_ESBC_CLIENT_HASH_COMPARE_KEY:
	case ERROR_ESBC_CLIENT_HASH_COMPARE_EM:
		fsl_secboot_image_verification_failure();
		break;
	case ERROR_ESBC_MISSING_BOOTM:
		fsl_secboot_bootscript_parse_failure();
		break;
	case ERROR_ESBC_WRONG_CMD:
	default:
		branch_to_self();
		break;
	}
}

static void fsl_secblk_handle_error(int error)
{
	switch (error) {
	case ERROR_ESBC_SEC_ENQ:
		fsl_secboot_handle_error(ERROR_ESBC_SEC_ENQ);
		break;
	case ERROR_ESBC_SEC_DEQ:
		fsl_secboot_handle_error(ERROR_ESBC_SEC_DEQ);
		break;
	case ERROR_ESBC_SEC_DEQ_TO:
		fsl_secboot_handle_error(ERROR_ESBC_SEC_DEQ_TO);
		break;
	default:
		printf("Job Queue Output status %x\n", error);
		fsl_secboot_handle_error(ERROR_ESBC_SEC_JOBQ_STATUS);
		break;
	}
}

/*
 * Calculate hash of key obtained via offset present in ESBC uboot
 * client hdr. This function calculates the hash of key which is obtained
 * through offset present in ESBC uboot client header.
 */
static int calc_img_key_hash(struct fsl_secboot_img_priv *img)
{
	struct hash_algo *algo;
	void *ctx;
	int i, srk = 0;
	int ret = 0;
	const char *algo_name = "sha256";

	/* Calculate hash of the esbc key */
	ret = hash_progressive_lookup_algo(algo_name, &algo);
	if (ret)
		return ret;

	ret = algo->hash_init(algo, &ctx);
	if (ret)
		return ret;

	/* Update hash for ESBC key */
#ifdef CONFIG_KEY_REVOCATION
	if (check_srk(img)) {
		ret = algo->hash_update(algo, ctx,
			(u8 *)(img->ehdrloc + img->hdr.srk_tbl_off),
			img->hdr.len_kr.num_srk * sizeof(struct srk_table), 1);
		srk = 1;
	}
#endif
	if (!srk)
		ret = algo->hash_update(algo, ctx,
			img->img_key, img->key_len, 1);
	if (ret)
		return ret;

	/* Copy hash at destination buffer */
	ret = algo->hash_finish(algo, ctx, hash_val, algo->digest_size);
	if (ret)
		return ret;

	for (i = 0; i < SHA256_BYTES; i++)
		img->img_key_hash[i] = hash_val[i];

	return 0;
}

/*
 * Calculate hash of ESBC hdr and ESBC. This function calculates the
 * single hash of ESBC header and ESBC image. If SG flag is on, all
 * SG entries are also hashed alongwith the complete SG table.
 */
static int calc_esbchdr_esbc_hash(struct fsl_secboot_img_priv *img)
{
	struct hash_algo *algo;
	void *ctx;
	int ret = 0;
	int key_hash = 0;
	const char *algo_name = "sha256";

	/* Calculate the hash of the ESBC */
	ret = hash_progressive_lookup_algo(algo_name, &algo);
	if (ret)
		return ret;

	ret = algo->hash_init(algo, &ctx);
	/* Copy hash at destination buffer */
	if (ret)
		return ret;

	/* Update hash for CSF Header */
	ret = algo->hash_update(algo, ctx,
		(u8 *)&img->hdr, sizeof(struct fsl_secboot_img_hdr), 0);
	if (ret)
		return ret;

	/* Update the hash with that of srk table if srk flag is 1
	 * If IE Table is selected, key is not added in the hash
	 * If neither srk table nor IE key table available, add key
	 * from header in the hash calculation
	 */
#ifdef CONFIG_KEY_REVOCATION
	if (check_srk(img)) {
		ret = algo->hash_update(algo, ctx,
			(u8 *)(img->ehdrloc + img->hdr.srk_tbl_off),
			img->hdr.len_kr.num_srk * sizeof(struct srk_table), 0);
		key_hash = 1;
	}
#endif
#if defined(CONFIG_FSL_ISBC_KEY_EXT)
	if (!key_hash && check_ie(img))
		key_hash = 1;
#endif
	if (!key_hash)
		ret = algo->hash_update(algo, ctx,
			img->img_key, img->hdr.key_len, 0);
	if (ret)
		return ret;

	/* Update hash for actual Image */
	ret = algo->hash_update(algo, ctx,
			(u8 *)img->hdr.pimg, img->hdr.img_size, 1);
	if (ret)
		return ret;

	/* Copy hash at destination buffer */
	ret = algo->hash_finish(algo, ctx, hash_val, algo->digest_size);
	if (ret)
		return ret;

	return 0;
}

/*
 * Construct encoded hash EM' wrt PKCSv1.5. This function calculates the
 * pointers for padding, DER value and hash. And finally, constructs EM'
 * which includes hash of complete CSF header and ESBC image. If SG flag
 * is on, hash of SG table and entries is also included.
 */
static void construct_img_encoded_hash_second(struct fsl_secboot_img_priv *img)
{
	/*
	 * RSA PKCSv1.5 encoding format for encoded message is below
	 * EM = 0x0 || 0x1 || PS || 0x0 || DER || Hash
	 * PS is Padding String
	 * DER is DER value for SHA-256
	 * Hash is SHA-256 hash
	 * *********************************************************
	 * representative points to first byte of EM initially and is
	 * filled with 0x0
	 * representative is incremented by 1 and second byte is filled
	 * with 0x1
	 * padding points to third byte of EM
	 * digest points to full length of EM - 32 bytes
	 * hash_id (DER value) points to 19 bytes before pDigest
	 * separator is one byte which separates padding and DER
	 */

	size_t len;
	u8 *representative;
	u8 *padding, *digest;
	u8 *hash_id, *separator;
	int i;

	len = (get_key_len(img) / 2) - 1;
	representative = img->img_encoded_hash_second;
	representative[0] = 0;
	representative[1] = 1;  /* block type 1 */

	padding = &representative[2];
	digest = &representative[1] + len - 32;
	hash_id = digest - sizeof(hash_identifier);
	separator = hash_id - 1;

	/* fill padding area pointed by padding with 0xff */
	memset(padding, 0xff, separator - padding);

	/* fill byte pointed by separator */
	*separator = 0;

	/* fill SHA-256 DER value  pointed by HashId */
	memcpy(hash_id, hash_identifier, sizeof(hash_identifier));

	/* fill hash pointed by Digest */
	for (i = 0; i < SHA256_BYTES; i++)
		digest[i] = hash_val[i];
}

/*
 * Reads and validates the ESBC client header.
 * This function reads key and signature from the ESBC client header.
 * If Scatter/Gather flag is on, lengths and offsets of images
 * present as SG entries are also read. This function also checks
 * whether the header is valid or not.
 */
static int read_validate_esbc_client_header(struct fsl_secboot_img_priv *img)
{
	char buf[20];
	struct fsl_secboot_img_hdr *hdr = &img->hdr;
	void *esbc = (u8 *)img->ehdrloc;
	u8 *k, *s;
#ifdef CONFIG_KEY_REVOCATION
	u32 ret;
	u32 key_num, key_revoc_flag, size;
#endif
#if defined(CONFIG_FSL_ISBC_KEY_EXT)
	struct ie_key_info *ie_info;
	u32 ie_num, ie_revoc_flag, ie_key_len;
#endif
	int  key_found = 0;

	/* check barker code */
	if (memcmp(hdr->barker, barker_code, ESBC_BARKER_LEN))
		return ERROR_ESBC_CLIENT_HEADER_BARKER;

	sprintf(buf, "%p", hdr->pimg);
	setenv("img_addr", buf);

	if (!hdr->img_size)
		return ERROR_ESBC_CLIENT_HEADER_IMG_SIZE;

	/* Key checking*/
#ifdef CONFIG_KEY_REVOCATION
	if (check_srk(img)) {
		if ((hdr->len_kr.num_srk == 0) ||
		    (hdr->len_kr.num_srk > MAX_KEY_ENTRIES))
			return ERROR_ESBC_CLIENT_HEADER_INVALID_SRK_NUM_ENTRY;

		key_num = hdr->len_kr.srk_sel;
		if (key_num == 0 || key_num > hdr->len_kr.num_srk)
			return ERROR_ESBC_CLIENT_HEADER_INVALID_KEY_NUM;

		/* Get revoc key from sfp */
		key_revoc_flag = get_key_revoc();
		ret = is_key_revoked(key_num, key_revoc_flag);
		if (ret)
			return ERROR_ESBC_CLIENT_HEADER_KEY_REVOKED;

		size = hdr->len_kr.num_srk * sizeof(struct srk_table);

		memcpy(&img->srk_tbl, esbc + hdr->srk_tbl_off, size);

		ret = validate_srk_tbl(img->srk_tbl, hdr->len_kr.num_srk);

		if (ret != 0)
			return ret;

		img->key_len = img->srk_tbl[key_num - 1].key_len;

		memcpy(&img->img_key, &(img->srk_tbl[key_num - 1].pkey),
		       img->key_len);

		key_found = 1;
	}
#endif

#if defined(CONFIG_FSL_ISBC_KEY_EXT)
	if (!key_found && check_ie(img)) {
		if (get_ie_info_addr(&img->ie_addr))
			return ERROR_IE_TABLE_NOT_FOUND;
		ie_info = (struct ie_key_info *)img->ie_addr;
		if (ie_info->num_keys == 0 || ie_info->num_keys > 32)
			return ERROR_ESBC_CLIENT_HEADER_INVALID_IE_NUM_ENTRY;

		ie_num = hdr->ie_key_sel;
		if (ie_num == 0 || ie_num > ie_info->num_keys)
			return ERROR_ESBC_CLIENT_HEADER_INVALID_IE_KEY_NUM;

		ie_revoc_flag = ie_info->key_revok;
		if ((u32)(1 << (ie_num - 1)) & ie_revoc_flag)
			return ERROR_ESBC_CLIENT_HEADER_IE_KEY_REVOKED;

		ie_key_len = ie_info->ie_key_tbl[ie_num - 1].key_len;

		if (!((ie_key_len == 2 * KEY_SIZE_BYTES / 4) ||
		      (ie_key_len == 2 * KEY_SIZE_BYTES / 2) ||
		      (ie_key_len == 2 * KEY_SIZE_BYTES)))
			return ERROR_ESBC_CLIENT_HEADER_INV_IE_ENTRY_KEYLEN;

		memcpy(&img->img_key, &(ie_info->ie_key_tbl[ie_num - 1].pkey),
		       ie_key_len);

		img->key_len = ie_key_len;
		key_found = 1;
	}
#endif

	if (key_found == 0) {
		/* check key length */
		if (!((hdr->key_len == 2 * KEY_SIZE_BYTES / 4) ||
		      (hdr->key_len == 2 * KEY_SIZE_BYTES / 2) ||
		      (hdr->key_len == 2 * KEY_SIZE_BYTES)))
			return ERROR_ESBC_CLIENT_HEADER_KEY_LEN;

		memcpy(&img->img_key, esbc + hdr->pkey, hdr->key_len);

		img->key_len = hdr->key_len;

		key_found = 1;
	}

	/* check signaure */
	if (get_key_len(img) == 2 * hdr->sign_len) {
		/* check signature length */
		if (!((hdr->sign_len == KEY_SIZE_BYTES / 4) ||
		      (hdr->sign_len == KEY_SIZE_BYTES / 2) ||
		      (hdr->sign_len == KEY_SIZE_BYTES)))
			return ERROR_ESBC_CLIENT_HEADER_SIG_LEN;
	} else {
		return ERROR_ESBC_CLIENT_HEADER_KEY_LEN_NOT_TWICE_SIG_LEN;
	}

	memcpy(&img->img_sign, esbc + hdr->psign, hdr->sign_len);

	/* No SG support */
	if (hdr->sg_flag)
		return ERROR_ESBC_CLIENT_HEADER_SG;

	/* modulus most significant bit should be set */
	k = (u8 *)&img->img_key;

	if ((k[0] & 0x80) == 0)
		return ERROR_ESBC_CLIENT_HEADER_KEY_MOD_1;

	/* modulus value should be odd */
	if ((k[get_key_len(img) / 2 - 1] & 0x1) == 0)
		return ERROR_ESBC_CLIENT_HEADER_KEY_MOD_2;

	/* Check signature value < modulus value */
	s = (u8 *)&img->img_sign;

	if (!(memcmp(s, k, hdr->sign_len) < 0))
		return ERROR_ESBC_CLIENT_HEADER_SIG_KEY_MOD;

	return ESBC_VALID_HDR;
}

static inline int str2longbe(const char *p, ulong *num)
{
	char *endptr;
	ulong tmp;

	if (!p) {
		return 0;
	} else {
		tmp = simple_strtoul(p, &endptr, 16);
		if (sizeof(ulong) == 4)
			*num = cpu_to_be32(tmp);
		else
			*num = cpu_to_be64(tmp);
	}

	return *p != '\0' && *endptr == '\0';
}

int fsl_secboot_validate(cmd_tbl_t *cmdtp, int flag, int argc,
		char * const argv[])
{
	struct ccsr_sfp_regs *sfp_regs = (void *)(CONFIG_SYS_SFP_ADDR);
	ulong hash[SHA256_BYTES/sizeof(ulong)];
	char hash_str[NUM_HEX_CHARS + 1];
	ulong addr = simple_strtoul(argv[1], NULL, 16);
	struct fsl_secboot_img_priv *img;
	struct fsl_secboot_img_hdr *hdr;
	void *esbc;
	int ret, i, hash_cmd = 0;
	u32 srk_hash[8];
	uint32_t key_len;
	struct key_prop prop;
#if !defined(USE_HOSTCC)
	struct udevice *mod_exp_dev;
#endif

	if (argc == 3) {
		char *cp = argv[2];
		int i = 0;

		if (*cp == '0' && *(cp + 1) == 'x')
			cp += 2;

		/* The input string expected is in hex, where
		 * each 4 bits would be represented by a hex
		 * sha256 hash is 256 bits long, which would mean
		 * num of characters = 256 / 4
		 */
		if (strlen(cp) != SHA256_NIBBLES) {
			printf("%s is not a 256 bits hex string as expected\n",
			       argv[2]);
			return -1;
		}

		for (i = 0; i < sizeof(hash)/sizeof(ulong); i++) {
			strncpy(hash_str, cp + (i * NUM_HEX_CHARS),
				NUM_HEX_CHARS);
			hash_str[NUM_HEX_CHARS] = '\0';
			if (!str2longbe(hash_str, &hash[i])) {
				printf("%s is not a 256 bits hex string ",
				       argv[2]);
				return -1;
			}
		}

		hash_cmd = 1;
	}

	img = malloc(sizeof(struct fsl_secboot_img_priv));

	if (!img)
		return -1;

	memset(img, 0, sizeof(struct fsl_secboot_img_priv));

	hdr = &img->hdr;
	img->ehdrloc = addr;
	esbc = (u8 *)img->ehdrloc;

	memcpy(hdr, esbc, sizeof(struct fsl_secboot_img_hdr));

	/* read and validate esbc header */
	ret = read_validate_esbc_client_header(img);

	if (ret != ESBC_VALID_HDR) {
		fsl_secboot_handle_error(ret);
		goto exit;
	}

	/* SRKH present in SFP */
	for (i = 0; i < NUM_SRKH_REGS; i++)
		srk_hash[i] = srk_in32(&sfp_regs->srk_hash[i]);

	/*
	 * Calculate hash of key obtained via offset present in
	 * ESBC uboot client hdr
	 */
	ret = calc_img_key_hash(img);
	if (ret) {
		fsl_secblk_handle_error(ret);
		goto exit;
	}

	/* Compare hash obtained above with SRK hash present in SFP */
	if (hash_cmd)
		ret = memcmp(&hash, &img->img_key_hash, SHA256_BYTES);
	else
		ret = memcmp(srk_hash, img->img_key_hash, SHA256_BYTES);

#if defined(CONFIG_FSL_ISBC_KEY_EXT)
	if (!hash_cmd && check_ie(img))
		ret = 0;
#endif

	if (ret != 0) {
		fsl_secboot_handle_error(ERROR_ESBC_CLIENT_HASH_COMPARE_KEY);
		goto exit;
	}

	ret = calc_esbchdr_esbc_hash(img);
	if (ret) {
		fsl_secblk_handle_error(ret);
		goto exit;
	}

	/* Construct encoded hash EM' wrt PKCSv1.5 */
	construct_img_encoded_hash_second(img);

	/* Fill prop structure for public key */
	memset(&prop, 0, sizeof(struct key_prop));
	key_len = get_key_len(img) / 2;
	prop.modulus = img->img_key;
	prop.public_exponent = img->img_key + key_len;
	prop.num_bits = key_len * 8;
	prop.exp_len = key_len;

	ret = uclass_get_device(UCLASS_MOD_EXP, 0, &mod_exp_dev);
	if (ret) {
		printf("RSA: Can't find Modular Exp implementation\n");
		return -EINVAL;
	}

	ret = rsa_mod_exp(mod_exp_dev, img->img_sign, img->hdr.sign_len,
			  &prop, img->img_encoded_hash);
	if (ret) {
		fsl_secblk_handle_error(ret);
		goto exit;
	}

	/*
	 * compare the encoded messages EM' and EM wrt RSA PKCSv1.5
	 * memcmp returns zero on success
	 * memcmp returns non-zero on failure
	 */
	ret = memcmp(&img->img_encoded_hash_second, &img->img_encoded_hash,
		img->hdr.sign_len);

	if (ret) {
		fsl_secboot_handle_error(ERROR_ESBC_CLIENT_HASH_COMPARE_EM);
		goto exit;
	}

	printf("esbc_validate command successful\n");

exit:
	return 0;
}
