xref: /rk3399_rockchip-uboot/board/freescale/common/fsl_validate.c (revision 6ec9aef2cef311c57652e8d17b09eceac2cebb06)
147151e4bSgaurav rana /*
247151e4bSgaurav rana  * Copyright 2015 Freescale Semiconductor, Inc.
347151e4bSgaurav rana  *
447151e4bSgaurav rana  * SPDX-License-Identifier:	GPL-2.0+
547151e4bSgaurav rana  */
647151e4bSgaurav rana 
747151e4bSgaurav rana #include <common.h>
847151e4bSgaurav rana #include <fsl_validate.h>
947151e4bSgaurav rana #include <fsl_secboot_err.h>
1047151e4bSgaurav rana #include <fsl_sfp.h>
1147151e4bSgaurav rana #include <fsl_sec.h>
1247151e4bSgaurav rana #include <command.h>
1347151e4bSgaurav rana #include <malloc.h>
1447151e4bSgaurav rana #include <dm/uclass.h>
1547151e4bSgaurav rana #include <u-boot/rsa-mod-exp.h>
1647151e4bSgaurav rana #include <hash.h>
1747151e4bSgaurav rana #include <fsl_secboot_err.h>
1847151e4bSgaurav rana #ifndef CONFIG_MPC85xx
1947151e4bSgaurav rana #include <asm/arch/immap_ls102xa.h>
2047151e4bSgaurav rana #endif
2147151e4bSgaurav rana 
2247151e4bSgaurav rana #define SHA256_BITS	256
2347151e4bSgaurav rana #define SHA256_BYTES	(256/8)
2447151e4bSgaurav rana #define SHA256_NIBBLES	(256/4)
2547151e4bSgaurav rana #define NUM_HEX_CHARS	(sizeof(ulong) * 2)
2647151e4bSgaurav rana 
2747151e4bSgaurav rana /* This array contains DER value for SHA-256 */
2847151e4bSgaurav rana static const u8 hash_identifier[] = { 0x30, 0x31, 0x30, 0x0d, 0x06, 0x09, 0x60,
2947151e4bSgaurav rana 		0x86, 0x48, 0x01, 0x65,	0x03, 0x04, 0x02, 0x01, 0x05, 0x00,
3047151e4bSgaurav rana 		0x04, 0x20
3147151e4bSgaurav rana 		};
3247151e4bSgaurav rana 
3347151e4bSgaurav rana static u8 hash_val[SHA256_BYTES];
3447151e4bSgaurav rana static const u8 barker_code[ESBC_BARKER_LEN] = { 0x68, 0x39, 0x27, 0x81 };
3547151e4bSgaurav rana 
3647151e4bSgaurav rana void branch_to_self(void) __attribute__ ((noreturn));
3747151e4bSgaurav rana 
3847151e4bSgaurav rana /*
3947151e4bSgaurav rana  * This function will put core in infinite loop.
4047151e4bSgaurav rana  * This will be called when the ESBC can not proceed further due
4147151e4bSgaurav rana  * to some unknown errors.
4247151e4bSgaurav rana  */
4347151e4bSgaurav rana void branch_to_self(void)
4447151e4bSgaurav rana {
4547151e4bSgaurav rana 	printf("Core is in infinite loop due to errors.\n");
4647151e4bSgaurav rana self:
4747151e4bSgaurav rana 	goto self;
4847151e4bSgaurav rana }
4947151e4bSgaurav rana 
5047151e4bSgaurav rana #if defined(CONFIG_FSL_ISBC_KEY_EXT)
5147151e4bSgaurav rana static u32 check_ie(struct fsl_secboot_img_priv *img)
5247151e4bSgaurav rana {
5347151e4bSgaurav rana 	if (img->hdr.ie_flag)
5447151e4bSgaurav rana 		return 1;
5547151e4bSgaurav rana 
5647151e4bSgaurav rana 	return 0;
5747151e4bSgaurav rana }
5847151e4bSgaurav rana 
5947151e4bSgaurav rana /* This function returns the CSF Header Address of uboot
6047151e4bSgaurav rana  * For MPC85xx based platforms, the LAW mapping for NOR
6147151e4bSgaurav rana  * flash changes in uboot code. Hence the offset needs
6247151e4bSgaurav rana  * to be calculated and added to the new NOR flash base
6347151e4bSgaurav rana  * address
6447151e4bSgaurav rana  */
6547151e4bSgaurav rana #if defined(CONFIG_MPC85xx)
667bcb0eb2SAneesh Bansal int get_csf_base_addr(u32 *csf_addr, u32 *flash_base_addr)
6747151e4bSgaurav rana {
6847151e4bSgaurav rana 	struct ccsr_gur __iomem *gur = (void *)(CONFIG_SYS_MPC85xx_GUTS_ADDR);
6947151e4bSgaurav rana 	u32 csf_hdr_addr = in_be32(&gur->scratchrw[0]);
7047151e4bSgaurav rana 	u32 csf_flash_offset = csf_hdr_addr & ~(CONFIG_SYS_PBI_FLASH_BASE);
717bcb0eb2SAneesh Bansal 	u32 flash_addr, addr;
7247151e4bSgaurav rana 	int found = 0;
7347151e4bSgaurav rana 	int i = 0;
7447151e4bSgaurav rana 
7547151e4bSgaurav rana 	for (i = 0; i < CONFIG_SYS_MAX_FLASH_BANKS; i++) {
7647151e4bSgaurav rana 		flash_addr = flash_info[i].start[0];
7747151e4bSgaurav rana 		addr = flash_info[i].start[0] + csf_flash_offset;
7847151e4bSgaurav rana 		if (memcmp((u8 *)addr, barker_code, ESBC_BARKER_LEN) == 0) {
797bcb0eb2SAneesh Bansal 			debug("Barker found on addr %x\n", addr);
8047151e4bSgaurav rana 			found = 1;
8147151e4bSgaurav rana 			break;
8247151e4bSgaurav rana 		}
8347151e4bSgaurav rana 	}
8447151e4bSgaurav rana 
8547151e4bSgaurav rana 	if (!found)
8647151e4bSgaurav rana 		return -1;
8747151e4bSgaurav rana 
8847151e4bSgaurav rana 	*csf_addr = addr;
8947151e4bSgaurav rana 	*flash_base_addr = flash_addr;
9047151e4bSgaurav rana 
9147151e4bSgaurav rana 	return 0;
9247151e4bSgaurav rana }
9347151e4bSgaurav rana #else
9447151e4bSgaurav rana /* For platforms like LS1020, correct flash address is present in
9547151e4bSgaurav rana  * the header. So the function reqturns flash base address as 0
9647151e4bSgaurav rana  */
977bcb0eb2SAneesh Bansal int get_csf_base_addr(u32 *csf_addr, u32 *flash_base_addr)
9847151e4bSgaurav rana {
9947151e4bSgaurav rana 	struct ccsr_gur __iomem *gur = (void *)(CONFIG_SYS_FSL_GUTS_ADDR);
10047151e4bSgaurav rana 	u32 csf_hdr_addr = in_be32(&gur->scratchrw[0]);
10147151e4bSgaurav rana 
10247151e4bSgaurav rana 	if (memcmp((u8 *)csf_hdr_addr, barker_code, ESBC_BARKER_LEN))
10347151e4bSgaurav rana 		return -1;
10447151e4bSgaurav rana 
10547151e4bSgaurav rana 	*csf_addr = csf_hdr_addr;
10647151e4bSgaurav rana 	*flash_base_addr = 0;
10747151e4bSgaurav rana 	return 0;
10847151e4bSgaurav rana }
10947151e4bSgaurav rana #endif
11047151e4bSgaurav rana 
1117bcb0eb2SAneesh Bansal static int get_ie_info_addr(u32 *ie_addr)
11247151e4bSgaurav rana {
11347151e4bSgaurav rana 	struct fsl_secboot_img_hdr *hdr;
11447151e4bSgaurav rana 	struct fsl_secboot_sg_table *sg_tbl;
1157bcb0eb2SAneesh Bansal 	u32 flash_base_addr, csf_addr;
11647151e4bSgaurav rana 
11747151e4bSgaurav rana 	if (get_csf_base_addr(&csf_addr, &flash_base_addr))
11847151e4bSgaurav rana 		return -1;
11947151e4bSgaurav rana 
12047151e4bSgaurav rana 	hdr = (struct fsl_secboot_img_hdr *)csf_addr;
12147151e4bSgaurav rana 
12247151e4bSgaurav rana 	/* For SoC's with Trust Architecture v1 with corenet bus
12347151e4bSgaurav rana 	 * the sg table field in CSF header has absolute address
12447151e4bSgaurav rana 	 * for sg table in memory. In other Trust Architecture,
12547151e4bSgaurav rana 	 * this field specifies the offset of sg table from the
12647151e4bSgaurav rana 	 * base address of CSF Header
12747151e4bSgaurav rana 	 */
12847151e4bSgaurav rana #if defined(CONFIG_FSL_TRUST_ARCH_v1) && defined(CONFIG_FSL_CORENET)
12947151e4bSgaurav rana 	sg_tbl = (struct fsl_secboot_sg_table *)
1307bcb0eb2SAneesh Bansal 		 (((u32)hdr->psgtable & ~(CONFIG_SYS_PBI_FLASH_BASE)) +
13147151e4bSgaurav rana 		  flash_base_addr);
13247151e4bSgaurav rana #else
13347151e4bSgaurav rana 	sg_tbl = (struct fsl_secboot_sg_table *)(csf_addr +
1347bcb0eb2SAneesh Bansal 						 (u32)hdr->psgtable);
13547151e4bSgaurav rana #endif
13647151e4bSgaurav rana 
13747151e4bSgaurav rana 	/* IE Key Table is the first entry in the SG Table */
13847151e4bSgaurav rana #if defined(CONFIG_MPC85xx)
13947151e4bSgaurav rana 	*ie_addr = (sg_tbl->src_addr & ~(CONFIG_SYS_PBI_FLASH_BASE)) +
14047151e4bSgaurav rana 		   flash_base_addr;
14147151e4bSgaurav rana #else
14247151e4bSgaurav rana 	*ie_addr = sg_tbl->src_addr;
14347151e4bSgaurav rana #endif
14447151e4bSgaurav rana 
1457bcb0eb2SAneesh Bansal 	debug("IE Table address is %x\n", *ie_addr);
14647151e4bSgaurav rana 	return 0;
14747151e4bSgaurav rana }
14847151e4bSgaurav rana 
14947151e4bSgaurav rana #endif
15047151e4bSgaurav rana 
15147151e4bSgaurav rana #ifdef CONFIG_KEY_REVOCATION
15247151e4bSgaurav rana /* This function checks srk_table_flag in header and set/reset srk_flag.*/
15347151e4bSgaurav rana static u32 check_srk(struct fsl_secboot_img_priv *img)
15447151e4bSgaurav rana {
15547151e4bSgaurav rana 	if (img->hdr.len_kr.srk_table_flag & SRK_FLAG)
15647151e4bSgaurav rana 		return 1;
15747151e4bSgaurav rana 
15847151e4bSgaurav rana 	return 0;
15947151e4bSgaurav rana }
16047151e4bSgaurav rana 
16147151e4bSgaurav rana /* This function returns ospr's key_revoc values.*/
16247151e4bSgaurav rana static u32 get_key_revoc(void)
16347151e4bSgaurav rana {
16447151e4bSgaurav rana 	struct ccsr_sfp_regs *sfp_regs = (void *)(CONFIG_SYS_SFP_ADDR);
16547151e4bSgaurav rana 	return (sfp_in32(&sfp_regs->ospr) & OSPR_KEY_REVOC_MASK) >>
16647151e4bSgaurav rana 		OSPR_KEY_REVOC_SHIFT;
16747151e4bSgaurav rana }
16847151e4bSgaurav rana 
16947151e4bSgaurav rana /* This function checks if selected key is revoked or not.*/
17047151e4bSgaurav rana static u32 is_key_revoked(u32 keynum, u32 rev_flag)
17147151e4bSgaurav rana {
17247151e4bSgaurav rana 	if (keynum == UNREVOCABLE_KEY)
17347151e4bSgaurav rana 		return 0;
17447151e4bSgaurav rana 
17547151e4bSgaurav rana 	if ((u32)(1 << (ALIGN_REVOC_KEY - keynum)) & rev_flag)
17647151e4bSgaurav rana 		return 1;
17747151e4bSgaurav rana 
17847151e4bSgaurav rana 	return 0;
17947151e4bSgaurav rana }
18047151e4bSgaurav rana 
18147151e4bSgaurav rana /* It validates srk_table key lengths.*/
18247151e4bSgaurav rana static u32 validate_srk_tbl(struct srk_table *tbl, u32 num_entries)
18347151e4bSgaurav rana {
18447151e4bSgaurav rana 	int i = 0;
18547151e4bSgaurav rana 	for (i = 0; i < num_entries; i++) {
18647151e4bSgaurav rana 		if (!((tbl[i].key_len == 2 * KEY_SIZE_BYTES/4) ||
18747151e4bSgaurav rana 		      (tbl[i].key_len == 2 * KEY_SIZE_BYTES/2) ||
18847151e4bSgaurav rana 		      (tbl[i].key_len == 2 * KEY_SIZE_BYTES)))
18947151e4bSgaurav rana 			return ERROR_ESBC_CLIENT_HEADER_INV_SRK_ENTRY_KEYLEN;
19047151e4bSgaurav rana 	}
19147151e4bSgaurav rana 	return 0;
19247151e4bSgaurav rana }
19347151e4bSgaurav rana #endif
19447151e4bSgaurav rana 
19547151e4bSgaurav rana /* This function return length of public key.*/
19647151e4bSgaurav rana static inline u32 get_key_len(struct fsl_secboot_img_priv *img)
19747151e4bSgaurav rana {
19847151e4bSgaurav rana 	return img->key_len;
19947151e4bSgaurav rana }
20047151e4bSgaurav rana 
20147151e4bSgaurav rana /*
20247151e4bSgaurav rana  * Handles the ESBC uboot client header verification failure.
20347151e4bSgaurav rana  * This  function  handles all the errors which might occur in the
20447151e4bSgaurav rana  * parsing and checking of ESBC uboot client header. It will also
20547151e4bSgaurav rana  * set the error bits in the SEC_MON.
20647151e4bSgaurav rana  */
20747151e4bSgaurav rana static void fsl_secboot_header_verification_failure(void)
20847151e4bSgaurav rana {
20947151e4bSgaurav rana 	struct ccsr_sec_mon_regs *sec_mon_regs = (void *)
21047151e4bSgaurav rana 						(CONFIG_SYS_SEC_MON_ADDR);
21147151e4bSgaurav rana 	struct ccsr_sfp_regs *sfp_regs = (void *)(CONFIG_SYS_SFP_ADDR);
21247151e4bSgaurav rana 	u32 sts = sec_mon_in32(&sec_mon_regs->hp_stat);
21347151e4bSgaurav rana 
21447151e4bSgaurav rana 	/* 29th bit of OSPR is ITS */
21547151e4bSgaurav rana 	u32 its = sfp_in32(&sfp_regs->ospr) >> 2;
21647151e4bSgaurav rana 
21747151e4bSgaurav rana 	/*
21847151e4bSgaurav rana 	 * Read the SEC_MON status register
21947151e4bSgaurav rana 	 * Read SSM_ST field
22047151e4bSgaurav rana 	 */
22147151e4bSgaurav rana 	sts = sec_mon_in32(&sec_mon_regs->hp_stat);
22247151e4bSgaurav rana 	if ((sts & HPSR_SSM_ST_MASK) == HPSR_SSM_ST_TRUST) {
22347151e4bSgaurav rana 		if (its == 1)
22447151e4bSgaurav rana 			change_sec_mon_state(HPSR_SSM_ST_TRUST,
22547151e4bSgaurav rana 					     HPSR_SSM_ST_SOFT_FAIL);
22647151e4bSgaurav rana 		else
22747151e4bSgaurav rana 			change_sec_mon_state(HPSR_SSM_ST_TRUST,
22847151e4bSgaurav rana 					     HPSR_SSM_ST_NON_SECURE);
22947151e4bSgaurav rana 	}
23047151e4bSgaurav rana 
23147151e4bSgaurav rana 	printf("Generating reset request\n");
23247151e4bSgaurav rana 	do_reset(NULL, 0, 0, NULL);
23347151e4bSgaurav rana }
23447151e4bSgaurav rana 
23547151e4bSgaurav rana /*
23647151e4bSgaurav rana  * Handles the ESBC uboot client image verification failure.
23747151e4bSgaurav rana  * This  function  handles all the errors which might occur in the
23847151e4bSgaurav rana  * public key hash comparison and signature verification of
23947151e4bSgaurav rana  * ESBC uboot client image. It will also
24047151e4bSgaurav rana  * set the error bits in the SEC_MON.
24147151e4bSgaurav rana  */
24247151e4bSgaurav rana static void fsl_secboot_image_verification_failure(void)
24347151e4bSgaurav rana {
24447151e4bSgaurav rana 	struct ccsr_sec_mon_regs *sec_mon_regs = (void *)
24547151e4bSgaurav rana 						(CONFIG_SYS_SEC_MON_ADDR);
24647151e4bSgaurav rana 	struct ccsr_sfp_regs *sfp_regs = (void *)(CONFIG_SYS_SFP_ADDR);
24747151e4bSgaurav rana 	u32 sts = sec_mon_in32(&sec_mon_regs->hp_stat);
24847151e4bSgaurav rana 
249*6ec9aef2SAneesh Bansal 	u32 its = (sfp_in32(&sfp_regs->ospr) & ITS_MASK) >> ITS_BIT;
25047151e4bSgaurav rana 
25147151e4bSgaurav rana 	/*
25247151e4bSgaurav rana 	 * Read the SEC_MON status register
25347151e4bSgaurav rana 	 * Read SSM_ST field
25447151e4bSgaurav rana 	 */
25547151e4bSgaurav rana 	sts = sec_mon_in32(&sec_mon_regs->hp_stat);
25647151e4bSgaurav rana 	if ((sts & HPSR_SSM_ST_MASK) == HPSR_SSM_ST_TRUST) {
25747151e4bSgaurav rana 		if (its == 1) {
25847151e4bSgaurav rana 			change_sec_mon_state(HPSR_SSM_ST_TRUST,
25947151e4bSgaurav rana 					     HPSR_SSM_ST_SOFT_FAIL);
26047151e4bSgaurav rana 
26147151e4bSgaurav rana 			printf("Generating reset request\n");
26247151e4bSgaurav rana 			do_reset(NULL, 0, 0, NULL);
26347151e4bSgaurav rana 		} else {
26447151e4bSgaurav rana 			change_sec_mon_state(HPSR_SSM_ST_TRUST,
26547151e4bSgaurav rana 					     HPSR_SSM_ST_NON_SECURE);
26647151e4bSgaurav rana 		}
26747151e4bSgaurav rana 	}
26847151e4bSgaurav rana }
26947151e4bSgaurav rana 
27047151e4bSgaurav rana static void fsl_secboot_bootscript_parse_failure(void)
27147151e4bSgaurav rana {
27247151e4bSgaurav rana 	fsl_secboot_header_verification_failure();
27347151e4bSgaurav rana }
27447151e4bSgaurav rana 
27547151e4bSgaurav rana /*
27647151e4bSgaurav rana  * Handles the errors in esbc boot.
27747151e4bSgaurav rana  * This  function  handles all the errors which might occur in the
27847151e4bSgaurav rana  * esbc boot phase. It will call the appropriate api to log the
27947151e4bSgaurav rana  * errors and set the error bits in the SEC_MON.
28047151e4bSgaurav rana  */
28147151e4bSgaurav rana void fsl_secboot_handle_error(int error)
28247151e4bSgaurav rana {
28347151e4bSgaurav rana 	const struct fsl_secboot_errcode *e;
28447151e4bSgaurav rana 
28547151e4bSgaurav rana 	for (e = fsl_secboot_errcodes; e->errcode != ERROR_ESBC_CLIENT_MAX;
28647151e4bSgaurav rana 		e++) {
28747151e4bSgaurav rana 		if (e->errcode == error)
28847151e4bSgaurav rana 			printf("ERROR :: %x :: %s\n", error, e->name);
28947151e4bSgaurav rana 	}
29047151e4bSgaurav rana 
29147151e4bSgaurav rana 	switch (error) {
29247151e4bSgaurav rana 	case ERROR_ESBC_CLIENT_HEADER_BARKER:
29347151e4bSgaurav rana 	case ERROR_ESBC_CLIENT_HEADER_IMG_SIZE:
29447151e4bSgaurav rana 	case ERROR_ESBC_CLIENT_HEADER_KEY_LEN:
29547151e4bSgaurav rana 	case ERROR_ESBC_CLIENT_HEADER_SIG_LEN:
29647151e4bSgaurav rana 	case ERROR_ESBC_CLIENT_HEADER_KEY_LEN_NOT_TWICE_SIG_LEN:
29747151e4bSgaurav rana 	case ERROR_ESBC_CLIENT_HEADER_KEY_MOD_1:
29847151e4bSgaurav rana 	case ERROR_ESBC_CLIENT_HEADER_KEY_MOD_2:
29947151e4bSgaurav rana 	case ERROR_ESBC_CLIENT_HEADER_SIG_KEY_MOD:
30047151e4bSgaurav rana 	case ERROR_ESBC_CLIENT_HEADER_SG_ESBC_EP:
30147151e4bSgaurav rana 	case ERROR_ESBC_CLIENT_HEADER_SG_ENTIRES_BAD:
30247151e4bSgaurav rana #ifdef CONFIG_KEY_REVOCATION
30347151e4bSgaurav rana 	case ERROR_ESBC_CLIENT_HEADER_KEY_REVOKED:
30447151e4bSgaurav rana 	case ERROR_ESBC_CLIENT_HEADER_INVALID_SRK_NUM_ENTRY:
30547151e4bSgaurav rana 	case ERROR_ESBC_CLIENT_HEADER_INVALID_KEY_NUM:
30647151e4bSgaurav rana 	case ERROR_ESBC_CLIENT_HEADER_INV_SRK_ENTRY_KEYLEN:
30747151e4bSgaurav rana #endif
30847151e4bSgaurav rana #if defined(CONFIG_FSL_ISBC_KEY_EXT)
30947151e4bSgaurav rana 	/*@fallthrough@*/
31047151e4bSgaurav rana 	case ERROR_ESBC_CLIENT_HEADER_IE_KEY_REVOKED:
31147151e4bSgaurav rana 	case ERROR_ESBC_CLIENT_HEADER_INVALID_IE_NUM_ENTRY:
31247151e4bSgaurav rana 	case ERROR_ESBC_CLIENT_HEADER_INVALID_IE_KEY_NUM:
31347151e4bSgaurav rana 	case ERROR_ESBC_CLIENT_HEADER_INV_IE_ENTRY_KEYLEN:
31447151e4bSgaurav rana 	case ERROR_IE_TABLE_NOT_FOUND:
31547151e4bSgaurav rana #endif
31647151e4bSgaurav rana 		fsl_secboot_header_verification_failure();
31747151e4bSgaurav rana 		break;
31847151e4bSgaurav rana 	case ERROR_ESBC_SEC_RESET:
31947151e4bSgaurav rana 	case ERROR_ESBC_SEC_DEQ:
32047151e4bSgaurav rana 	case ERROR_ESBC_SEC_ENQ:
32147151e4bSgaurav rana 	case ERROR_ESBC_SEC_DEQ_TO:
32247151e4bSgaurav rana 	case ERROR_ESBC_SEC_JOBQ_STATUS:
32347151e4bSgaurav rana 	case ERROR_ESBC_CLIENT_HASH_COMPARE_KEY:
32447151e4bSgaurav rana 	case ERROR_ESBC_CLIENT_HASH_COMPARE_EM:
32547151e4bSgaurav rana 		fsl_secboot_image_verification_failure();
32647151e4bSgaurav rana 		break;
32747151e4bSgaurav rana 	case ERROR_ESBC_MISSING_BOOTM:
32847151e4bSgaurav rana 		fsl_secboot_bootscript_parse_failure();
32947151e4bSgaurav rana 		break;
33047151e4bSgaurav rana 	case ERROR_ESBC_WRONG_CMD:
33147151e4bSgaurav rana 	default:
33247151e4bSgaurav rana 		branch_to_self();
33347151e4bSgaurav rana 		break;
33447151e4bSgaurav rana 	}
33547151e4bSgaurav rana }
33647151e4bSgaurav rana 
33747151e4bSgaurav rana static void fsl_secblk_handle_error(int error)
33847151e4bSgaurav rana {
33947151e4bSgaurav rana 	switch (error) {
34047151e4bSgaurav rana 	case ERROR_ESBC_SEC_ENQ:
34147151e4bSgaurav rana 		fsl_secboot_handle_error(ERROR_ESBC_SEC_ENQ);
34247151e4bSgaurav rana 		break;
34347151e4bSgaurav rana 	case ERROR_ESBC_SEC_DEQ:
34447151e4bSgaurav rana 		fsl_secboot_handle_error(ERROR_ESBC_SEC_DEQ);
34547151e4bSgaurav rana 		break;
34647151e4bSgaurav rana 	case ERROR_ESBC_SEC_DEQ_TO:
34747151e4bSgaurav rana 		fsl_secboot_handle_error(ERROR_ESBC_SEC_DEQ_TO);
34847151e4bSgaurav rana 		break;
34947151e4bSgaurav rana 	default:
35047151e4bSgaurav rana 		printf("Job Queue Output status %x\n", error);
35147151e4bSgaurav rana 		fsl_secboot_handle_error(ERROR_ESBC_SEC_JOBQ_STATUS);
35247151e4bSgaurav rana 		break;
35347151e4bSgaurav rana 	}
35447151e4bSgaurav rana }
35547151e4bSgaurav rana 
35647151e4bSgaurav rana /*
35747151e4bSgaurav rana  * Calculate hash of key obtained via offset present in ESBC uboot
35847151e4bSgaurav rana  * client hdr. This function calculates the hash of key which is obtained
35947151e4bSgaurav rana  * through offset present in ESBC uboot client header.
36047151e4bSgaurav rana  */
36147151e4bSgaurav rana static int calc_img_key_hash(struct fsl_secboot_img_priv *img)
36247151e4bSgaurav rana {
36347151e4bSgaurav rana 	struct hash_algo *algo;
36447151e4bSgaurav rana 	void *ctx;
36547151e4bSgaurav rana 	int i, srk = 0;
36647151e4bSgaurav rana 	int ret = 0;
36747151e4bSgaurav rana 	const char *algo_name = "sha256";
36847151e4bSgaurav rana 
36947151e4bSgaurav rana 	/* Calculate hash of the esbc key */
37047151e4bSgaurav rana 	ret = hash_progressive_lookup_algo(algo_name, &algo);
37147151e4bSgaurav rana 	if (ret)
37247151e4bSgaurav rana 		return ret;
37347151e4bSgaurav rana 
37447151e4bSgaurav rana 	ret = algo->hash_init(algo, &ctx);
37547151e4bSgaurav rana 	if (ret)
37647151e4bSgaurav rana 		return ret;
37747151e4bSgaurav rana 
37847151e4bSgaurav rana 	/* Update hash for ESBC key */
37947151e4bSgaurav rana #ifdef CONFIG_KEY_REVOCATION
38047151e4bSgaurav rana 	if (check_srk(img)) {
38147151e4bSgaurav rana 		ret = algo->hash_update(algo, ctx,
38247151e4bSgaurav rana 			(u8 *)(img->ehdrloc + img->hdr.srk_tbl_off),
38347151e4bSgaurav rana 			img->hdr.len_kr.num_srk * sizeof(struct srk_table), 1);
38447151e4bSgaurav rana 		srk = 1;
38547151e4bSgaurav rana 	}
38647151e4bSgaurav rana #endif
38747151e4bSgaurav rana 	if (!srk)
38847151e4bSgaurav rana 		ret = algo->hash_update(algo, ctx,
38947151e4bSgaurav rana 			img->img_key, img->key_len, 1);
39047151e4bSgaurav rana 	if (ret)
39147151e4bSgaurav rana 		return ret;
39247151e4bSgaurav rana 
39347151e4bSgaurav rana 	/* Copy hash at destination buffer */
39447151e4bSgaurav rana 	ret = algo->hash_finish(algo, ctx, hash_val, algo->digest_size);
39547151e4bSgaurav rana 	if (ret)
39647151e4bSgaurav rana 		return ret;
39747151e4bSgaurav rana 
39847151e4bSgaurav rana 	for (i = 0; i < SHA256_BYTES; i++)
39947151e4bSgaurav rana 		img->img_key_hash[i] = hash_val[i];
40047151e4bSgaurav rana 
40147151e4bSgaurav rana 	return 0;
40247151e4bSgaurav rana }
40347151e4bSgaurav rana 
40447151e4bSgaurav rana /*
40547151e4bSgaurav rana  * Calculate hash of ESBC hdr and ESBC. This function calculates the
40647151e4bSgaurav rana  * single hash of ESBC header and ESBC image. If SG flag is on, all
40747151e4bSgaurav rana  * SG entries are also hashed alongwith the complete SG table.
40847151e4bSgaurav rana  */
40947151e4bSgaurav rana static int calc_esbchdr_esbc_hash(struct fsl_secboot_img_priv *img)
41047151e4bSgaurav rana {
41147151e4bSgaurav rana 	struct hash_algo *algo;
41247151e4bSgaurav rana 	void *ctx;
41347151e4bSgaurav rana 	int ret = 0;
41447151e4bSgaurav rana 	int key_hash = 0;
41547151e4bSgaurav rana 	const char *algo_name = "sha256";
41647151e4bSgaurav rana 
41747151e4bSgaurav rana 	/* Calculate the hash of the ESBC */
41847151e4bSgaurav rana 	ret = hash_progressive_lookup_algo(algo_name, &algo);
41947151e4bSgaurav rana 	if (ret)
42047151e4bSgaurav rana 		return ret;
42147151e4bSgaurav rana 
42247151e4bSgaurav rana 	ret = algo->hash_init(algo, &ctx);
42347151e4bSgaurav rana 	/* Copy hash at destination buffer */
42447151e4bSgaurav rana 	if (ret)
42547151e4bSgaurav rana 		return ret;
42647151e4bSgaurav rana 
42747151e4bSgaurav rana 	/* Update hash for CSF Header */
42847151e4bSgaurav rana 	ret = algo->hash_update(algo, ctx,
42947151e4bSgaurav rana 		(u8 *)&img->hdr, sizeof(struct fsl_secboot_img_hdr), 0);
43047151e4bSgaurav rana 	if (ret)
43147151e4bSgaurav rana 		return ret;
43247151e4bSgaurav rana 
43347151e4bSgaurav rana 	/* Update the hash with that of srk table if srk flag is 1
43447151e4bSgaurav rana 	 * If IE Table is selected, key is not added in the hash
43547151e4bSgaurav rana 	 * If neither srk table nor IE key table available, add key
43647151e4bSgaurav rana 	 * from header in the hash calculation
43747151e4bSgaurav rana 	 */
43847151e4bSgaurav rana #ifdef CONFIG_KEY_REVOCATION
43947151e4bSgaurav rana 	if (check_srk(img)) {
44047151e4bSgaurav rana 		ret = algo->hash_update(algo, ctx,
44147151e4bSgaurav rana 			(u8 *)(img->ehdrloc + img->hdr.srk_tbl_off),
44247151e4bSgaurav rana 			img->hdr.len_kr.num_srk * sizeof(struct srk_table), 0);
44347151e4bSgaurav rana 		key_hash = 1;
44447151e4bSgaurav rana 	}
44547151e4bSgaurav rana #endif
44647151e4bSgaurav rana #if defined(CONFIG_FSL_ISBC_KEY_EXT)
44747151e4bSgaurav rana 	if (!key_hash && check_ie(img))
44847151e4bSgaurav rana 		key_hash = 1;
44947151e4bSgaurav rana #endif
45047151e4bSgaurav rana 	if (!key_hash)
45147151e4bSgaurav rana 		ret = algo->hash_update(algo, ctx,
45247151e4bSgaurav rana 			img->img_key, img->hdr.key_len, 0);
45347151e4bSgaurav rana 	if (ret)
45447151e4bSgaurav rana 		return ret;
45547151e4bSgaurav rana 
45647151e4bSgaurav rana 	/* Update hash for actual Image */
45747151e4bSgaurav rana 	ret = algo->hash_update(algo, ctx,
45847151e4bSgaurav rana 			(u8 *)img->hdr.pimg, img->hdr.img_size, 1);
45947151e4bSgaurav rana 	if (ret)
46047151e4bSgaurav rana 		return ret;
46147151e4bSgaurav rana 
46247151e4bSgaurav rana 	/* Copy hash at destination buffer */
46347151e4bSgaurav rana 	ret = algo->hash_finish(algo, ctx, hash_val, algo->digest_size);
46447151e4bSgaurav rana 	if (ret)
46547151e4bSgaurav rana 		return ret;
46647151e4bSgaurav rana 
46747151e4bSgaurav rana 	return 0;
46847151e4bSgaurav rana }
46947151e4bSgaurav rana 
47047151e4bSgaurav rana /*
47147151e4bSgaurav rana  * Construct encoded hash EM' wrt PKCSv1.5. This function calculates the
47247151e4bSgaurav rana  * pointers for padding, DER value and hash. And finally, constructs EM'
47347151e4bSgaurav rana  * which includes hash of complete CSF header and ESBC image. If SG flag
47447151e4bSgaurav rana  * is on, hash of SG table and entries is also included.
47547151e4bSgaurav rana  */
47647151e4bSgaurav rana static void construct_img_encoded_hash_second(struct fsl_secboot_img_priv *img)
47747151e4bSgaurav rana {
47847151e4bSgaurav rana 	/*
47947151e4bSgaurav rana 	 * RSA PKCSv1.5 encoding format for encoded message is below
48047151e4bSgaurav rana 	 * EM = 0x0 || 0x1 || PS || 0x0 || DER || Hash
48147151e4bSgaurav rana 	 * PS is Padding String
48247151e4bSgaurav rana 	 * DER is DER value for SHA-256
48347151e4bSgaurav rana 	 * Hash is SHA-256 hash
48447151e4bSgaurav rana 	 * *********************************************************
48547151e4bSgaurav rana 	 * representative points to first byte of EM initially and is
48647151e4bSgaurav rana 	 * filled with 0x0
48747151e4bSgaurav rana 	 * representative is incremented by 1 and second byte is filled
48847151e4bSgaurav rana 	 * with 0x1
48947151e4bSgaurav rana 	 * padding points to third byte of EM
49047151e4bSgaurav rana 	 * digest points to full length of EM - 32 bytes
49147151e4bSgaurav rana 	 * hash_id (DER value) points to 19 bytes before pDigest
49247151e4bSgaurav rana 	 * separator is one byte which separates padding and DER
49347151e4bSgaurav rana 	 */
49447151e4bSgaurav rana 
49547151e4bSgaurav rana 	size_t len;
49647151e4bSgaurav rana 	u8 *representative;
49747151e4bSgaurav rana 	u8 *padding, *digest;
49847151e4bSgaurav rana 	u8 *hash_id, *separator;
49947151e4bSgaurav rana 	int i;
50047151e4bSgaurav rana 
50147151e4bSgaurav rana 	len = (get_key_len(img) / 2) - 1;
50247151e4bSgaurav rana 	representative = img->img_encoded_hash_second;
50347151e4bSgaurav rana 	representative[0] = 0;
50447151e4bSgaurav rana 	representative[1] = 1;  /* block type 1 */
50547151e4bSgaurav rana 
50647151e4bSgaurav rana 	padding = &representative[2];
50747151e4bSgaurav rana 	digest = &representative[1] + len - 32;
50847151e4bSgaurav rana 	hash_id = digest - sizeof(hash_identifier);
50947151e4bSgaurav rana 	separator = hash_id - 1;
51047151e4bSgaurav rana 
51147151e4bSgaurav rana 	/* fill padding area pointed by padding with 0xff */
51247151e4bSgaurav rana 	memset(padding, 0xff, separator - padding);
51347151e4bSgaurav rana 
51447151e4bSgaurav rana 	/* fill byte pointed by separator */
51547151e4bSgaurav rana 	*separator = 0;
51647151e4bSgaurav rana 
51747151e4bSgaurav rana 	/* fill SHA-256 DER value  pointed by HashId */
51847151e4bSgaurav rana 	memcpy(hash_id, hash_identifier, sizeof(hash_identifier));
51947151e4bSgaurav rana 
52047151e4bSgaurav rana 	/* fill hash pointed by Digest */
52147151e4bSgaurav rana 	for (i = 0; i < SHA256_BYTES; i++)
52247151e4bSgaurav rana 		digest[i] = hash_val[i];
52347151e4bSgaurav rana }
52447151e4bSgaurav rana 
52547151e4bSgaurav rana /*
52647151e4bSgaurav rana  * Reads and validates the ESBC client header.
52747151e4bSgaurav rana  * This function reads key and signature from the ESBC client header.
52847151e4bSgaurav rana  * If Scatter/Gather flag is on, lengths and offsets of images
52947151e4bSgaurav rana  * present as SG entries are also read. This function also checks
53047151e4bSgaurav rana  * whether the header is valid or not.
53147151e4bSgaurav rana  */
53247151e4bSgaurav rana static int read_validate_esbc_client_header(struct fsl_secboot_img_priv *img)
53347151e4bSgaurav rana {
53447151e4bSgaurav rana 	char buf[20];
53547151e4bSgaurav rana 	struct fsl_secboot_img_hdr *hdr = &img->hdr;
53647151e4bSgaurav rana 	void *esbc = (u8 *)img->ehdrloc;
53747151e4bSgaurav rana 	u8 *k, *s;
53847151e4bSgaurav rana #ifdef CONFIG_KEY_REVOCATION
53947151e4bSgaurav rana 	u32 ret;
54047151e4bSgaurav rana 	u32 key_num, key_revoc_flag, size;
54147151e4bSgaurav rana #endif
54247151e4bSgaurav rana #if defined(CONFIG_FSL_ISBC_KEY_EXT)
54347151e4bSgaurav rana 	struct ie_key_info *ie_info;
54447151e4bSgaurav rana 	u32 ie_num, ie_revoc_flag, ie_key_len;
54547151e4bSgaurav rana #endif
54647151e4bSgaurav rana 	int  key_found = 0;
54747151e4bSgaurav rana 
54847151e4bSgaurav rana 	/* check barker code */
54947151e4bSgaurav rana 	if (memcmp(hdr->barker, barker_code, ESBC_BARKER_LEN))
55047151e4bSgaurav rana 		return ERROR_ESBC_CLIENT_HEADER_BARKER;
55147151e4bSgaurav rana 
5527bcb0eb2SAneesh Bansal 	sprintf(buf, "%x", hdr->pimg);
55347151e4bSgaurav rana 	setenv("img_addr", buf);
55447151e4bSgaurav rana 
55547151e4bSgaurav rana 	if (!hdr->img_size)
55647151e4bSgaurav rana 		return ERROR_ESBC_CLIENT_HEADER_IMG_SIZE;
55747151e4bSgaurav rana 
55847151e4bSgaurav rana 	/* Key checking*/
55947151e4bSgaurav rana #ifdef CONFIG_KEY_REVOCATION
56047151e4bSgaurav rana 	if (check_srk(img)) {
56147151e4bSgaurav rana 		if ((hdr->len_kr.num_srk == 0) ||
56247151e4bSgaurav rana 		    (hdr->len_kr.num_srk > MAX_KEY_ENTRIES))
56347151e4bSgaurav rana 			return ERROR_ESBC_CLIENT_HEADER_INVALID_SRK_NUM_ENTRY;
56447151e4bSgaurav rana 
56547151e4bSgaurav rana 		key_num = hdr->len_kr.srk_sel;
56647151e4bSgaurav rana 		if (key_num == 0 || key_num > hdr->len_kr.num_srk)
56747151e4bSgaurav rana 			return ERROR_ESBC_CLIENT_HEADER_INVALID_KEY_NUM;
56847151e4bSgaurav rana 
56947151e4bSgaurav rana 		/* Get revoc key from sfp */
57047151e4bSgaurav rana 		key_revoc_flag = get_key_revoc();
57147151e4bSgaurav rana 		ret = is_key_revoked(key_num, key_revoc_flag);
57247151e4bSgaurav rana 		if (ret)
57347151e4bSgaurav rana 			return ERROR_ESBC_CLIENT_HEADER_KEY_REVOKED;
57447151e4bSgaurav rana 
57547151e4bSgaurav rana 		size = hdr->len_kr.num_srk * sizeof(struct srk_table);
57647151e4bSgaurav rana 
57747151e4bSgaurav rana 		memcpy(&img->srk_tbl, esbc + hdr->srk_tbl_off, size);
57847151e4bSgaurav rana 
57947151e4bSgaurav rana 		ret = validate_srk_tbl(img->srk_tbl, hdr->len_kr.num_srk);
58047151e4bSgaurav rana 
58147151e4bSgaurav rana 		if (ret != 0)
58247151e4bSgaurav rana 			return ret;
58347151e4bSgaurav rana 
58447151e4bSgaurav rana 		img->key_len = img->srk_tbl[key_num - 1].key_len;
58547151e4bSgaurav rana 
58647151e4bSgaurav rana 		memcpy(&img->img_key, &(img->srk_tbl[key_num - 1].pkey),
58747151e4bSgaurav rana 		       img->key_len);
58847151e4bSgaurav rana 
58947151e4bSgaurav rana 		key_found = 1;
59047151e4bSgaurav rana 	}
59147151e4bSgaurav rana #endif
59247151e4bSgaurav rana 
59347151e4bSgaurav rana #if defined(CONFIG_FSL_ISBC_KEY_EXT)
59447151e4bSgaurav rana 	if (!key_found && check_ie(img)) {
59547151e4bSgaurav rana 		if (get_ie_info_addr(&img->ie_addr))
59647151e4bSgaurav rana 			return ERROR_IE_TABLE_NOT_FOUND;
59747151e4bSgaurav rana 		ie_info = (struct ie_key_info *)img->ie_addr;
59847151e4bSgaurav rana 		if (ie_info->num_keys == 0 || ie_info->num_keys > 32)
59947151e4bSgaurav rana 			return ERROR_ESBC_CLIENT_HEADER_INVALID_IE_NUM_ENTRY;
60047151e4bSgaurav rana 
60147151e4bSgaurav rana 		ie_num = hdr->ie_key_sel;
60247151e4bSgaurav rana 		if (ie_num == 0 || ie_num > ie_info->num_keys)
60347151e4bSgaurav rana 			return ERROR_ESBC_CLIENT_HEADER_INVALID_IE_KEY_NUM;
60447151e4bSgaurav rana 
60547151e4bSgaurav rana 		ie_revoc_flag = ie_info->key_revok;
60647151e4bSgaurav rana 		if ((u32)(1 << (ie_num - 1)) & ie_revoc_flag)
60747151e4bSgaurav rana 			return ERROR_ESBC_CLIENT_HEADER_IE_KEY_REVOKED;
60847151e4bSgaurav rana 
60947151e4bSgaurav rana 		ie_key_len = ie_info->ie_key_tbl[ie_num - 1].key_len;
61047151e4bSgaurav rana 
61147151e4bSgaurav rana 		if (!((ie_key_len == 2 * KEY_SIZE_BYTES / 4) ||
61247151e4bSgaurav rana 		      (ie_key_len == 2 * KEY_SIZE_BYTES / 2) ||
61347151e4bSgaurav rana 		      (ie_key_len == 2 * KEY_SIZE_BYTES)))
61447151e4bSgaurav rana 			return ERROR_ESBC_CLIENT_HEADER_INV_IE_ENTRY_KEYLEN;
61547151e4bSgaurav rana 
61647151e4bSgaurav rana 		memcpy(&img->img_key, &(ie_info->ie_key_tbl[ie_num - 1].pkey),
61747151e4bSgaurav rana 		       ie_key_len);
61847151e4bSgaurav rana 
61947151e4bSgaurav rana 		img->key_len = ie_key_len;
62047151e4bSgaurav rana 		key_found = 1;
62147151e4bSgaurav rana 	}
62247151e4bSgaurav rana #endif
62347151e4bSgaurav rana 
62447151e4bSgaurav rana 	if (key_found == 0) {
62547151e4bSgaurav rana 		/* check key length */
62647151e4bSgaurav rana 		if (!((hdr->key_len == 2 * KEY_SIZE_BYTES / 4) ||
62747151e4bSgaurav rana 		      (hdr->key_len == 2 * KEY_SIZE_BYTES / 2) ||
62847151e4bSgaurav rana 		      (hdr->key_len == 2 * KEY_SIZE_BYTES)))
62947151e4bSgaurav rana 			return ERROR_ESBC_CLIENT_HEADER_KEY_LEN;
63047151e4bSgaurav rana 
63147151e4bSgaurav rana 		memcpy(&img->img_key, esbc + hdr->pkey, hdr->key_len);
63247151e4bSgaurav rana 
63347151e4bSgaurav rana 		img->key_len = hdr->key_len;
63447151e4bSgaurav rana 
63547151e4bSgaurav rana 		key_found = 1;
63647151e4bSgaurav rana 	}
63747151e4bSgaurav rana 
63847151e4bSgaurav rana 	/* check signaure */
63947151e4bSgaurav rana 	if (get_key_len(img) == 2 * hdr->sign_len) {
64047151e4bSgaurav rana 		/* check signature length */
64147151e4bSgaurav rana 		if (!((hdr->sign_len == KEY_SIZE_BYTES / 4) ||
64247151e4bSgaurav rana 		      (hdr->sign_len == KEY_SIZE_BYTES / 2) ||
64347151e4bSgaurav rana 		      (hdr->sign_len == KEY_SIZE_BYTES)))
64447151e4bSgaurav rana 			return ERROR_ESBC_CLIENT_HEADER_SIG_LEN;
64547151e4bSgaurav rana 	} else {
64647151e4bSgaurav rana 		return ERROR_ESBC_CLIENT_HEADER_KEY_LEN_NOT_TWICE_SIG_LEN;
64747151e4bSgaurav rana 	}
64847151e4bSgaurav rana 
64947151e4bSgaurav rana 	memcpy(&img->img_sign, esbc + hdr->psign, hdr->sign_len);
65047151e4bSgaurav rana 
65147151e4bSgaurav rana 	/* No SG support */
65247151e4bSgaurav rana 	if (hdr->sg_flag)
65347151e4bSgaurav rana 		return ERROR_ESBC_CLIENT_HEADER_SG;
65447151e4bSgaurav rana 
65547151e4bSgaurav rana 	/* modulus most significant bit should be set */
65647151e4bSgaurav rana 	k = (u8 *)&img->img_key;
65747151e4bSgaurav rana 
65847151e4bSgaurav rana 	if ((k[0] & 0x80) == 0)
65947151e4bSgaurav rana 		return ERROR_ESBC_CLIENT_HEADER_KEY_MOD_1;
66047151e4bSgaurav rana 
66147151e4bSgaurav rana 	/* modulus value should be odd */
66247151e4bSgaurav rana 	if ((k[get_key_len(img) / 2 - 1] & 0x1) == 0)
66347151e4bSgaurav rana 		return ERROR_ESBC_CLIENT_HEADER_KEY_MOD_2;
66447151e4bSgaurav rana 
66547151e4bSgaurav rana 	/* Check signature value < modulus value */
66647151e4bSgaurav rana 	s = (u8 *)&img->img_sign;
66747151e4bSgaurav rana 
66847151e4bSgaurav rana 	if (!(memcmp(s, k, hdr->sign_len) < 0))
66947151e4bSgaurav rana 		return ERROR_ESBC_CLIENT_HEADER_SIG_KEY_MOD;
67047151e4bSgaurav rana 
67147151e4bSgaurav rana 	return ESBC_VALID_HDR;
67247151e4bSgaurav rana }
67347151e4bSgaurav rana 
67447151e4bSgaurav rana static inline int str2longbe(const char *p, ulong *num)
67547151e4bSgaurav rana {
67647151e4bSgaurav rana 	char *endptr;
67747151e4bSgaurav rana 	ulong tmp;
67847151e4bSgaurav rana 
67947151e4bSgaurav rana 	if (!p) {
68047151e4bSgaurav rana 		return 0;
68147151e4bSgaurav rana 	} else {
68247151e4bSgaurav rana 		tmp = simple_strtoul(p, &endptr, 16);
68347151e4bSgaurav rana 		if (sizeof(ulong) == 4)
68447151e4bSgaurav rana 			*num = cpu_to_be32(tmp);
68547151e4bSgaurav rana 		else
68647151e4bSgaurav rana 			*num = cpu_to_be64(tmp);
68747151e4bSgaurav rana 	}
68847151e4bSgaurav rana 
68947151e4bSgaurav rana 	return *p != '\0' && *endptr == '\0';
69047151e4bSgaurav rana }
69147151e4bSgaurav rana 
69247151e4bSgaurav rana int fsl_secboot_validate(cmd_tbl_t *cmdtp, int flag, int argc,
69347151e4bSgaurav rana 		char * const argv[])
69447151e4bSgaurav rana {
69547151e4bSgaurav rana 	struct ccsr_sfp_regs *sfp_regs = (void *)(CONFIG_SYS_SFP_ADDR);
69647151e4bSgaurav rana 	ulong hash[SHA256_BYTES/sizeof(ulong)];
69747151e4bSgaurav rana 	char hash_str[NUM_HEX_CHARS + 1];
69847151e4bSgaurav rana 	ulong addr = simple_strtoul(argv[1], NULL, 16);
69947151e4bSgaurav rana 	struct fsl_secboot_img_priv *img;
70047151e4bSgaurav rana 	struct fsl_secboot_img_hdr *hdr;
70147151e4bSgaurav rana 	void *esbc;
70247151e4bSgaurav rana 	int ret, i, hash_cmd = 0;
70347151e4bSgaurav rana 	u32 srk_hash[8];
70447151e4bSgaurav rana 	uint32_t key_len;
70547151e4bSgaurav rana 	struct key_prop prop;
70647151e4bSgaurav rana #if !defined(USE_HOSTCC)
70747151e4bSgaurav rana 	struct udevice *mod_exp_dev;
70847151e4bSgaurav rana #endif
70947151e4bSgaurav rana 
71047151e4bSgaurav rana 	if (argc == 3) {
71147151e4bSgaurav rana 		char *cp = argv[2];
71247151e4bSgaurav rana 		int i = 0;
71347151e4bSgaurav rana 
71447151e4bSgaurav rana 		if (*cp == '0' && *(cp + 1) == 'x')
71547151e4bSgaurav rana 			cp += 2;
71647151e4bSgaurav rana 
71747151e4bSgaurav rana 		/* The input string expected is in hex, where
71847151e4bSgaurav rana 		 * each 4 bits would be represented by a hex
71947151e4bSgaurav rana 		 * sha256 hash is 256 bits long, which would mean
72047151e4bSgaurav rana 		 * num of characters = 256 / 4
72147151e4bSgaurav rana 		 */
72247151e4bSgaurav rana 		if (strlen(cp) != SHA256_NIBBLES) {
72347151e4bSgaurav rana 			printf("%s is not a 256 bits hex string as expected\n",
72447151e4bSgaurav rana 			       argv[2]);
72547151e4bSgaurav rana 			return -1;
72647151e4bSgaurav rana 		}
72747151e4bSgaurav rana 
72847151e4bSgaurav rana 		for (i = 0; i < sizeof(hash)/sizeof(ulong); i++) {
72947151e4bSgaurav rana 			strncpy(hash_str, cp + (i * NUM_HEX_CHARS),
73047151e4bSgaurav rana 				NUM_HEX_CHARS);
73147151e4bSgaurav rana 			hash_str[NUM_HEX_CHARS] = '\0';
73247151e4bSgaurav rana 			if (!str2longbe(hash_str, &hash[i])) {
73347151e4bSgaurav rana 				printf("%s is not a 256 bits hex string ",
73447151e4bSgaurav rana 				       argv[2]);
73547151e4bSgaurav rana 				return -1;
73647151e4bSgaurav rana 			}
73747151e4bSgaurav rana 		}
73847151e4bSgaurav rana 
73947151e4bSgaurav rana 		hash_cmd = 1;
74047151e4bSgaurav rana 	}
74147151e4bSgaurav rana 
74247151e4bSgaurav rana 	img = malloc(sizeof(struct fsl_secboot_img_priv));
74347151e4bSgaurav rana 
74447151e4bSgaurav rana 	if (!img)
74547151e4bSgaurav rana 		return -1;
74647151e4bSgaurav rana 
74747151e4bSgaurav rana 	memset(img, 0, sizeof(struct fsl_secboot_img_priv));
74847151e4bSgaurav rana 
74947151e4bSgaurav rana 	hdr = &img->hdr;
75047151e4bSgaurav rana 	img->ehdrloc = addr;
75147151e4bSgaurav rana 	esbc = (u8 *)img->ehdrloc;
75247151e4bSgaurav rana 
75347151e4bSgaurav rana 	memcpy(hdr, esbc, sizeof(struct fsl_secboot_img_hdr));
75447151e4bSgaurav rana 
75547151e4bSgaurav rana 	/* read and validate esbc header */
75647151e4bSgaurav rana 	ret = read_validate_esbc_client_header(img);
75747151e4bSgaurav rana 
75847151e4bSgaurav rana 	if (ret != ESBC_VALID_HDR) {
75947151e4bSgaurav rana 		fsl_secboot_handle_error(ret);
76047151e4bSgaurav rana 		goto exit;
76147151e4bSgaurav rana 	}
76247151e4bSgaurav rana 
76347151e4bSgaurav rana 	/* SRKH present in SFP */
76447151e4bSgaurav rana 	for (i = 0; i < NUM_SRKH_REGS; i++)
76547151e4bSgaurav rana 		srk_hash[i] = srk_in32(&sfp_regs->srk_hash[i]);
76647151e4bSgaurav rana 
76747151e4bSgaurav rana 	/*
76847151e4bSgaurav rana 	 * Calculate hash of key obtained via offset present in
76947151e4bSgaurav rana 	 * ESBC uboot client hdr
77047151e4bSgaurav rana 	 */
77147151e4bSgaurav rana 	ret = calc_img_key_hash(img);
77247151e4bSgaurav rana 	if (ret) {
77347151e4bSgaurav rana 		fsl_secblk_handle_error(ret);
77447151e4bSgaurav rana 		goto exit;
77547151e4bSgaurav rana 	}
77647151e4bSgaurav rana 
77747151e4bSgaurav rana 	/* Compare hash obtained above with SRK hash present in SFP */
77847151e4bSgaurav rana 	if (hash_cmd)
77947151e4bSgaurav rana 		ret = memcmp(&hash, &img->img_key_hash, SHA256_BYTES);
78047151e4bSgaurav rana 	else
78147151e4bSgaurav rana 		ret = memcmp(srk_hash, img->img_key_hash, SHA256_BYTES);
78247151e4bSgaurav rana 
78347151e4bSgaurav rana #if defined(CONFIG_FSL_ISBC_KEY_EXT)
78447151e4bSgaurav rana 	if (!hash_cmd && check_ie(img))
78547151e4bSgaurav rana 		ret = 0;
78647151e4bSgaurav rana #endif
78747151e4bSgaurav rana 
78847151e4bSgaurav rana 	if (ret != 0) {
78947151e4bSgaurav rana 		fsl_secboot_handle_error(ERROR_ESBC_CLIENT_HASH_COMPARE_KEY);
79047151e4bSgaurav rana 		goto exit;
79147151e4bSgaurav rana 	}
79247151e4bSgaurav rana 
79347151e4bSgaurav rana 	ret = calc_esbchdr_esbc_hash(img);
79447151e4bSgaurav rana 	if (ret) {
79547151e4bSgaurav rana 		fsl_secblk_handle_error(ret);
79647151e4bSgaurav rana 		goto exit;
79747151e4bSgaurav rana 	}
79847151e4bSgaurav rana 
79947151e4bSgaurav rana 	/* Construct encoded hash EM' wrt PKCSv1.5 */
80047151e4bSgaurav rana 	construct_img_encoded_hash_second(img);
80147151e4bSgaurav rana 
80247151e4bSgaurav rana 	/* Fill prop structure for public key */
80347151e4bSgaurav rana 	memset(&prop, 0, sizeof(struct key_prop));
80447151e4bSgaurav rana 	key_len = get_key_len(img) / 2;
80547151e4bSgaurav rana 	prop.modulus = img->img_key;
80647151e4bSgaurav rana 	prop.public_exponent = img->img_key + key_len;
80747151e4bSgaurav rana 	prop.num_bits = key_len * 8;
80847151e4bSgaurav rana 	prop.exp_len = key_len;
80947151e4bSgaurav rana 
81047151e4bSgaurav rana 	ret = uclass_get_device(UCLASS_MOD_EXP, 0, &mod_exp_dev);
81147151e4bSgaurav rana 	if (ret) {
81247151e4bSgaurav rana 		printf("RSA: Can't find Modular Exp implementation\n");
81347151e4bSgaurav rana 		return -EINVAL;
81447151e4bSgaurav rana 	}
81547151e4bSgaurav rana 
81647151e4bSgaurav rana 	ret = rsa_mod_exp(mod_exp_dev, img->img_sign, img->hdr.sign_len,
81747151e4bSgaurav rana 			  &prop, img->img_encoded_hash);
81847151e4bSgaurav rana 	if (ret) {
81947151e4bSgaurav rana 		fsl_secblk_handle_error(ret);
82047151e4bSgaurav rana 		goto exit;
82147151e4bSgaurav rana 	}
82247151e4bSgaurav rana 
82347151e4bSgaurav rana 	/*
82447151e4bSgaurav rana 	 * compare the encoded messages EM' and EM wrt RSA PKCSv1.5
82547151e4bSgaurav rana 	 * memcmp returns zero on success
82647151e4bSgaurav rana 	 * memcmp returns non-zero on failure
82747151e4bSgaurav rana 	 */
82847151e4bSgaurav rana 	ret = memcmp(&img->img_encoded_hash_second, &img->img_encoded_hash,
82947151e4bSgaurav rana 		img->hdr.sign_len);
83047151e4bSgaurav rana 
83147151e4bSgaurav rana 	if (ret) {
83247151e4bSgaurav rana 		fsl_secboot_handle_error(ERROR_ESBC_CLIENT_HASH_COMPARE_EM);
83347151e4bSgaurav rana 		goto exit;
83447151e4bSgaurav rana 	}
83547151e4bSgaurav rana 
83647151e4bSgaurav rana 	printf("esbc_validate command successful\n");
83747151e4bSgaurav rana 
83847151e4bSgaurav rana exit:
83947151e4bSgaurav rana 	return 0;
84047151e4bSgaurav rana }
841