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

#include <common.h>
#include <dm.h>
#include <flash.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 <u-boot/rsa-mod-exp.h>
#include <hash.h>
#include <fsl_secboot_err.h>
#ifdef CONFIG_ARCH_LS1021A
#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)

#define CHECK_KEY_LEN(key_len)	(((key_len) == 2 * KEY_SIZE_BYTES / 4) || \
				 ((key_len) == 2 * KEY_SIZE_BYTES / 2) || \
				 ((key_len) == 2 * KEY_SIZE_BYTES))
#if defined(CONFIG_FSL_ISBC_KEY_EXT)
/* Global data structure */
static struct fsl_secboot_glb glb;
#endif

/* 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];

#ifdef CONFIG_ESBC_HDR_LS
/* New Barker Code for LS ESBC Header */
static const u8 barker_code[ESBC_BARKER_LEN] = { 0x12, 0x19, 0x20, 0x01 };
#else
static const u8 barker_code[ESBC_BARKER_LEN] = { 0x68, 0x39, 0x27, 0x81 };
#endif

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 & IE_FLAG_MASK)
		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(u32 *csf_addr, u32 *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);
	u32 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 %x\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(u32 *csf_addr, u32 *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 *)(uintptr_t)csf_hdr_addr,
		   barker_code, ESBC_BARKER_LEN))
		return -1;

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

#if defined(CONFIG_ESBC_HDR_LS)
static int get_ie_info_addr(uintptr_t *ie_addr)
{
	struct ccsr_gur __iomem *gur = (void *)(CONFIG_SYS_FSL_GUTS_ADDR);
	/* For LS-CH3, the address of IE Table is
	 * stated in Scratch13 and scratch14 of DCFG.
	 * Bootrom validates this table while validating uboot.
	 * DCFG is LE*/
	*ie_addr = in_le32(&gur->scratchrw[SCRATCH_IE_HIGH_ADR - 1]);
	*ie_addr = *ie_addr << 32;
	*ie_addr |= in_le32(&gur->scratchrw[SCRATCH_IE_LOW_ADR - 1]);
	return 0;
}
#else /* CONFIG_ESBC_HDR_LS */
static int get_ie_info_addr(uintptr_t *ie_addr)
{
	struct fsl_secboot_img_hdr *hdr;
	struct fsl_secboot_sg_table *sg_tbl;
	u32 flash_base_addr, csf_addr;

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

	hdr = (struct fsl_secboot_img_hdr *)(uintptr_t)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 *)
		 (((u32)hdr->psgtable & ~(CONFIG_SYS_PBI_FLASH_BASE)) +
		  flash_base_addr);
#else
	sg_tbl = (struct fsl_secboot_sg_table *)(uintptr_t)(csf_addr +
						 (u32)hdr->psgtable);
#endif

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

	debug("IE Table address is %lx\n", *ie_addr);
	return 0;
}
#endif /* CONFIG_ESBC_HDR_LS */
#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)
{
#ifdef CONFIG_ESBC_HDR_LS
	/* In LS, No SRK Flag as SRK is always present if IE not present*/
#if defined(CONFIG_FSL_ISBC_KEY_EXT)
	return !check_ie(img);
#endif
	return 1;
#else
	if (img->hdr.len_kr.srk_table_flag & SRK_FLAG)
		return 1;

	return 0;
#endif
}

/* 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 read validates srk_table key lengths.*/
static u32 read_validate_srk_tbl(struct fsl_secboot_img_priv *img)
{
	int i = 0;
	u32 ret, key_num, key_revoc_flag, size;
	struct fsl_secboot_img_hdr *hdr = &img->hdr;
	void *esbc = (u8 *)(uintptr_t)img->ehdrloc;

	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);

	for (i = 0; i < hdr->len_kr.num_srk; i++) {
		if (!CHECK_KEY_LEN(img->srk_tbl[i].key_len))
			return ERROR_ESBC_CLIENT_HEADER_INV_SRK_ENTRY_KEYLEN;
	}

	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);

	return 0;
}
#endif

#ifndef CONFIG_ESBC_HDR_LS
static u32 read_validate_single_key(struct fsl_secboot_img_priv *img)
{
	struct fsl_secboot_img_hdr *hdr = &img->hdr;
	void *esbc = (u8 *)(uintptr_t)img->ehdrloc;

	/* check key length */
	if (!CHECK_KEY_LEN(hdr->key_len))
		return ERROR_ESBC_CLIENT_HEADER_KEY_LEN;

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

	img->key_len = hdr->key_len;

	return 0;
}
#endif /* CONFIG_ESBC_HDR_LS */

#if defined(CONFIG_FSL_ISBC_KEY_EXT)

static void install_ie_tbl(uintptr_t ie_tbl_addr,
		struct fsl_secboot_img_priv *img)
{
	/* Copy IE tbl to Global Data */
	memcpy(&glb.ie_tbl, (u8 *)ie_tbl_addr, sizeof(struct ie_key_info));
	img->ie_addr = (uintptr_t)&glb.ie_tbl;
	glb.ie_addr = img->ie_addr;
}

static u32 read_validate_ie_tbl(struct fsl_secboot_img_priv *img)
{
	struct fsl_secboot_img_hdr *hdr = &img->hdr;
	u32 ie_key_len, ie_revoc_flag, ie_num;
	struct ie_key_info *ie_info;

	if (!img->ie_addr) {
		if (get_ie_info_addr(&img->ie_addr))
			return ERROR_IE_TABLE_NOT_FOUND;
		else
			install_ie_tbl(img->ie_addr, img);
		}

	ie_info = (struct ie_key_info *)(uintptr_t)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 (!CHECK_KEY_LEN(ie_key_len))
		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;
	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_sfp_regs *sfp_regs = (void *)(CONFIG_SYS_SFP_ADDR);

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

	if (its == 1)
		set_sec_mon_state(HPSR_SSM_ST_SOFT_FAIL);
	else
		set_sec_mon_state(HPSR_SSM_ST_NON_SECURE);

	printf("Generating reset request\n");
	do_reset(NULL, 0, 0, NULL);
	/* If reset doesn't coocur, halt execution */
	do_esbc_halt(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_sfp_regs *sfp_regs = (void *)(CONFIG_SYS_SFP_ADDR);

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

	if (its == 1) {
		set_sec_mon_state(HPSR_SSM_ST_SOFT_FAIL);

		printf("Generating reset request\n");
		do_reset(NULL, 0, 0, NULL);
		/* If reset doesn't coocur, halt execution */
		do_esbc_halt(NULL, 0, 0, NULL);

	} else {
		set_sec_mon_state(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)
{
#ifndef CONFIG_SPL_BUILD
	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);
	}
#else
	printf("ERROR :: %x\n", error);
#endif

	/* If Boot Mode is secure, transition the SNVS state and issue
	 * reset based on type of failure and ITS setting.
	 * If Boot mode is non-secure, return from this function.
	 */
	if (fsl_check_boot_mode_secure() == 0)
		return;

	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:
	case ERROR_KEY_TABLE_NOT_FOUND:
#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 *)(uintptr_t)(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 *)(uintptr_t)(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
#ifndef CONFIG_ESBC_HDR_LS
/* No single key support in LS ESBC header */
	if (!key_hash) {
		ret = algo->hash_update(algo, ctx,
			img->img_key, img->hdr.key_len, 0);
		key_hash = 1;
	}
#endif
	if (ret)
		return ret;
	if (!key_hash)
		return ERROR_KEY_TABLE_NOT_FOUND;

	/* Update hash for actual Image */
	ret = algo->hash_update(algo, ctx,
		(u8 *)(*(img->img_addr_ptr)), img->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)
{
	struct fsl_secboot_img_hdr *hdr = &img->hdr;
	void *esbc = (u8 *)(uintptr_t)img->ehdrloc;
	u8 *k, *s;
	u32 ret = 0;

	int  key_found = 0;

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

	/* If Image Address is not passed as argument to function,
	 * then Address and Size must be read from the Header.
	 */
	if (*(img->img_addr_ptr) == 0) {
	#ifdef CONFIG_ESBC_ADDR_64BIT
		*(img->img_addr_ptr) = hdr->pimg64;
	#else
		*(img->img_addr_ptr) = hdr->pimg;
	#endif
	}

	if (!hdr->img_size)
		return ERROR_ESBC_CLIENT_HEADER_IMG_SIZE;

	img->img_size = hdr->img_size;

	/* Key checking*/
#ifdef CONFIG_KEY_REVOCATION
	if (check_srk(img)) {
		ret = read_validate_srk_tbl(img);
		if (ret != 0)
			return ret;
		key_found = 1;
	}
#endif

#if defined(CONFIG_FSL_ISBC_KEY_EXT)
	if (!key_found && check_ie(img)) {
		ret = read_validate_ie_tbl(img);
		if (ret != 0)
			return ret;
		key_found = 1;
	}
#endif
#ifndef CONFIG_ESBC_HDR_LS
/* Single Key Feature not available in LS ESBC Header */
	if (key_found == 0) {
		ret = read_validate_single_key(img);
		if (ret != 0)
			return ret;
		key_found = 1;
	}
#endif
	if (!key_found)
		return ERROR_KEY_TABLE_NOT_FOUND;

	/* 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 in LS-CH3 */
#ifndef CONFIG_ESBC_HDR_LS
	/* No SG support */
	if (hdr->sg_flag)
		return ERROR_ESBC_CLIENT_HEADER_SG;
#endif

	/* 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';
}
/* Function to calculate the ESBC Image Hash
 * and hash from Digital signature.
 * The Two hash's are compared to yield the
 * result of signature validation.
 */
static int calculate_cmp_img_sig(struct fsl_secboot_img_priv *img)
{
	int ret;
	uint32_t key_len;
	struct key_prop prop;
#if !defined(USE_HOSTCC)
	struct udevice *mod_exp_dev;
#endif
	ret = calc_esbchdr_esbc_hash(img);
	if (ret)
		return ret;

	/* 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)
		return ret;

	/*
	 * 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)
		return ERROR_ESBC_CLIENT_HASH_COMPARE_EM;

	return 0;
}
/* Function to initialize img priv and global data structure
 */
static int secboot_init(struct fsl_secboot_img_priv **img_ptr)
{
	*img_ptr = malloc(sizeof(struct fsl_secboot_img_priv));

	struct fsl_secboot_img_priv *img = *img_ptr;

	if (!img)
		return -ENOMEM;
	memset(img, 0, sizeof(struct fsl_secboot_img_priv));

#if defined(CONFIG_FSL_ISBC_KEY_EXT)
	if (glb.ie_addr)
		img->ie_addr = glb.ie_addr;
#endif
	return 0;
}


/* haddr - Address of the header of image to be validated.
 * arg_hash_str - Option hash string. If provided, this
 * overrides the key hash in the SFP fuses.
 * img_addr_ptr - Optional pointer to address of image to be validated.
 * If non zero addr, this overrides the addr of image in header,
 * otherwise updated to image addr in header.
 * Acts as both input and output of function.
 * This pointer shouldn't be NULL.
 */
int fsl_secboot_validate(uintptr_t haddr, char *arg_hash_str,
			uintptr_t *img_addr_ptr)
{
	struct ccsr_sfp_regs *sfp_regs = (void *)(CONFIG_SYS_SFP_ADDR);
	ulong hash[SHA256_BYTES/sizeof(ulong)];
	char hash_str[NUM_HEX_CHARS + 1];
	struct fsl_secboot_img_priv *img;
	struct fsl_secboot_img_hdr *hdr;
	void *esbc;
	int ret, i, hash_cmd = 0;
	u32 srk_hash[8];

	if (arg_hash_str != NULL) {
		const char *cp = arg_hash_str;
		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",
			       arg_hash_str);
			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 ",
				       arg_hash_str);
				return -1;
			}
		}

		hash_cmd = 1;
	}

	ret = secboot_init(&img);
	if (ret)
		goto exit;

	/* Update the information in Private Struct */
	hdr = &img->hdr;
	img->ehdrloc = haddr;
	img->img_addr_ptr = img_addr_ptr;
	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 = calculate_cmp_img_sig(img);
	if (ret) {
		fsl_secboot_handle_error(ret);
		goto exit;
	}

exit:
	/* Free Img as it was malloc'ed*/
	free(img);
	return ret;
}
