xref: /rk3399_rockchip-uboot/board/freescale/common/fsl_validate.c (revision 6629261ddd9d78c3cd8193b05c00a2a9bdc74796)
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>
189711f528SAneesh Bansal #ifdef CONFIG_LS102XA
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 
2794ba5e41SAneesh Bansal #define CHECK_KEY_LEN(key_len)	(((key_len) == 2 * KEY_SIZE_BYTES / 4) || \
2894ba5e41SAneesh Bansal 				 ((key_len) == 2 * KEY_SIZE_BYTES / 2) || \
2994ba5e41SAneesh Bansal 				 ((key_len) == 2 * KEY_SIZE_BYTES))
3094ba5e41SAneesh Bansal 
3147151e4bSgaurav rana /* This array contains DER value for SHA-256 */
3247151e4bSgaurav rana static const u8 hash_identifier[] = { 0x30, 0x31, 0x30, 0x0d, 0x06, 0x09, 0x60,
3347151e4bSgaurav rana 		0x86, 0x48, 0x01, 0x65,	0x03, 0x04, 0x02, 0x01, 0x05, 0x00,
3447151e4bSgaurav rana 		0x04, 0x20
3547151e4bSgaurav rana 		};
3647151e4bSgaurav rana 
3747151e4bSgaurav rana static u8 hash_val[SHA256_BYTES];
3847151e4bSgaurav rana static const u8 barker_code[ESBC_BARKER_LEN] = { 0x68, 0x39, 0x27, 0x81 };
3947151e4bSgaurav rana 
4047151e4bSgaurav rana void branch_to_self(void) __attribute__ ((noreturn));
4147151e4bSgaurav rana 
4247151e4bSgaurav rana /*
4347151e4bSgaurav rana  * This function will put core in infinite loop.
4447151e4bSgaurav rana  * This will be called when the ESBC can not proceed further due
4547151e4bSgaurav rana  * to some unknown errors.
4647151e4bSgaurav rana  */
4747151e4bSgaurav rana void branch_to_self(void)
4847151e4bSgaurav rana {
4947151e4bSgaurav rana 	printf("Core is in infinite loop due to errors.\n");
5047151e4bSgaurav rana self:
5147151e4bSgaurav rana 	goto self;
5247151e4bSgaurav rana }
5347151e4bSgaurav rana 
5447151e4bSgaurav rana #if defined(CONFIG_FSL_ISBC_KEY_EXT)
5547151e4bSgaurav rana static u32 check_ie(struct fsl_secboot_img_priv *img)
5647151e4bSgaurav rana {
5747151e4bSgaurav rana 	if (img->hdr.ie_flag)
5847151e4bSgaurav rana 		return 1;
5947151e4bSgaurav rana 
6047151e4bSgaurav rana 	return 0;
6147151e4bSgaurav rana }
6247151e4bSgaurav rana 
6347151e4bSgaurav rana /* This function returns the CSF Header Address of uboot
6447151e4bSgaurav rana  * For MPC85xx based platforms, the LAW mapping for NOR
6547151e4bSgaurav rana  * flash changes in uboot code. Hence the offset needs
6647151e4bSgaurav rana  * to be calculated and added to the new NOR flash base
6747151e4bSgaurav rana  * address
6847151e4bSgaurav rana  */
6947151e4bSgaurav rana #if defined(CONFIG_MPC85xx)
707bcb0eb2SAneesh Bansal int get_csf_base_addr(u32 *csf_addr, u32 *flash_base_addr)
7147151e4bSgaurav rana {
7247151e4bSgaurav rana 	struct ccsr_gur __iomem *gur = (void *)(CONFIG_SYS_MPC85xx_GUTS_ADDR);
7347151e4bSgaurav rana 	u32 csf_hdr_addr = in_be32(&gur->scratchrw[0]);
7447151e4bSgaurav rana 	u32 csf_flash_offset = csf_hdr_addr & ~(CONFIG_SYS_PBI_FLASH_BASE);
757bcb0eb2SAneesh Bansal 	u32 flash_addr, addr;
7647151e4bSgaurav rana 	int found = 0;
7747151e4bSgaurav rana 	int i = 0;
7847151e4bSgaurav rana 
7947151e4bSgaurav rana 	for (i = 0; i < CONFIG_SYS_MAX_FLASH_BANKS; i++) {
8047151e4bSgaurav rana 		flash_addr = flash_info[i].start[0];
8147151e4bSgaurav rana 		addr = flash_info[i].start[0] + csf_flash_offset;
8247151e4bSgaurav rana 		if (memcmp((u8 *)addr, barker_code, ESBC_BARKER_LEN) == 0) {
837bcb0eb2SAneesh Bansal 			debug("Barker found on addr %x\n", addr);
8447151e4bSgaurav rana 			found = 1;
8547151e4bSgaurav rana 			break;
8647151e4bSgaurav rana 		}
8747151e4bSgaurav rana 	}
8847151e4bSgaurav rana 
8947151e4bSgaurav rana 	if (!found)
9047151e4bSgaurav rana 		return -1;
9147151e4bSgaurav rana 
9247151e4bSgaurav rana 	*csf_addr = addr;
9347151e4bSgaurav rana 	*flash_base_addr = flash_addr;
9447151e4bSgaurav rana 
9547151e4bSgaurav rana 	return 0;
9647151e4bSgaurav rana }
9747151e4bSgaurav rana #else
9847151e4bSgaurav rana /* For platforms like LS1020, correct flash address is present in
9947151e4bSgaurav rana  * the header. So the function reqturns flash base address as 0
10047151e4bSgaurav rana  */
1017bcb0eb2SAneesh Bansal int get_csf_base_addr(u32 *csf_addr, u32 *flash_base_addr)
10247151e4bSgaurav rana {
10347151e4bSgaurav rana 	struct ccsr_gur __iomem *gur = (void *)(CONFIG_SYS_FSL_GUTS_ADDR);
10447151e4bSgaurav rana 	u32 csf_hdr_addr = in_be32(&gur->scratchrw[0]);
10547151e4bSgaurav rana 
1069711f528SAneesh Bansal 	if (memcmp((u8 *)(uintptr_t)csf_hdr_addr,
1079711f528SAneesh Bansal 		   barker_code, ESBC_BARKER_LEN))
10847151e4bSgaurav rana 		return -1;
10947151e4bSgaurav rana 
11047151e4bSgaurav rana 	*csf_addr = csf_hdr_addr;
11147151e4bSgaurav rana 	*flash_base_addr = 0;
11247151e4bSgaurav rana 	return 0;
11347151e4bSgaurav rana }
11447151e4bSgaurav rana #endif
11547151e4bSgaurav rana 
1167bcb0eb2SAneesh Bansal static int get_ie_info_addr(u32 *ie_addr)
11747151e4bSgaurav rana {
11847151e4bSgaurav rana 	struct fsl_secboot_img_hdr *hdr;
11947151e4bSgaurav rana 	struct fsl_secboot_sg_table *sg_tbl;
1207bcb0eb2SAneesh Bansal 	u32 flash_base_addr, csf_addr;
12147151e4bSgaurav rana 
12247151e4bSgaurav rana 	if (get_csf_base_addr(&csf_addr, &flash_base_addr))
12347151e4bSgaurav rana 		return -1;
12447151e4bSgaurav rana 
1259711f528SAneesh Bansal 	hdr = (struct fsl_secboot_img_hdr *)(uintptr_t)csf_addr;
12647151e4bSgaurav rana 
12747151e4bSgaurav rana 	/* For SoC's with Trust Architecture v1 with corenet bus
12847151e4bSgaurav rana 	 * the sg table field in CSF header has absolute address
12947151e4bSgaurav rana 	 * for sg table in memory. In other Trust Architecture,
13047151e4bSgaurav rana 	 * this field specifies the offset of sg table from the
13147151e4bSgaurav rana 	 * base address of CSF Header
13247151e4bSgaurav rana 	 */
13347151e4bSgaurav rana #if defined(CONFIG_FSL_TRUST_ARCH_v1) && defined(CONFIG_FSL_CORENET)
13447151e4bSgaurav rana 	sg_tbl = (struct fsl_secboot_sg_table *)
1357bcb0eb2SAneesh Bansal 		 (((u32)hdr->psgtable & ~(CONFIG_SYS_PBI_FLASH_BASE)) +
13647151e4bSgaurav rana 		  flash_base_addr);
13747151e4bSgaurav rana #else
1389711f528SAneesh Bansal 	sg_tbl = (struct fsl_secboot_sg_table *)(uintptr_t)(csf_addr +
1397bcb0eb2SAneesh Bansal 						 (u32)hdr->psgtable);
14047151e4bSgaurav rana #endif
14147151e4bSgaurav rana 
14247151e4bSgaurav rana 	/* IE Key Table is the first entry in the SG Table */
14347151e4bSgaurav rana #if defined(CONFIG_MPC85xx)
14447151e4bSgaurav rana 	*ie_addr = (sg_tbl->src_addr & ~(CONFIG_SYS_PBI_FLASH_BASE)) +
14547151e4bSgaurav rana 		   flash_base_addr;
14647151e4bSgaurav rana #else
14747151e4bSgaurav rana 	*ie_addr = sg_tbl->src_addr;
14847151e4bSgaurav rana #endif
14947151e4bSgaurav rana 
1507bcb0eb2SAneesh Bansal 	debug("IE Table address is %x\n", *ie_addr);
15147151e4bSgaurav rana 	return 0;
15247151e4bSgaurav rana }
15347151e4bSgaurav rana 
15447151e4bSgaurav rana #endif
15547151e4bSgaurav rana 
15647151e4bSgaurav rana #ifdef CONFIG_KEY_REVOCATION
15747151e4bSgaurav rana /* This function checks srk_table_flag in header and set/reset srk_flag.*/
15847151e4bSgaurav rana static u32 check_srk(struct fsl_secboot_img_priv *img)
15947151e4bSgaurav rana {
16047151e4bSgaurav rana 	if (img->hdr.len_kr.srk_table_flag & SRK_FLAG)
16147151e4bSgaurav rana 		return 1;
16247151e4bSgaurav rana 
16347151e4bSgaurav rana 	return 0;
16447151e4bSgaurav rana }
16547151e4bSgaurav rana 
16647151e4bSgaurav rana /* This function returns ospr's key_revoc values.*/
16747151e4bSgaurav rana static u32 get_key_revoc(void)
16847151e4bSgaurav rana {
16947151e4bSgaurav rana 	struct ccsr_sfp_regs *sfp_regs = (void *)(CONFIG_SYS_SFP_ADDR);
17047151e4bSgaurav rana 	return (sfp_in32(&sfp_regs->ospr) & OSPR_KEY_REVOC_MASK) >>
17147151e4bSgaurav rana 		OSPR_KEY_REVOC_SHIFT;
17247151e4bSgaurav rana }
17347151e4bSgaurav rana 
17447151e4bSgaurav rana /* This function checks if selected key is revoked or not.*/
17547151e4bSgaurav rana static u32 is_key_revoked(u32 keynum, u32 rev_flag)
17647151e4bSgaurav rana {
17747151e4bSgaurav rana 	if (keynum == UNREVOCABLE_KEY)
17847151e4bSgaurav rana 		return 0;
17947151e4bSgaurav rana 
18047151e4bSgaurav rana 	if ((u32)(1 << (ALIGN_REVOC_KEY - keynum)) & rev_flag)
18147151e4bSgaurav rana 		return 1;
18247151e4bSgaurav rana 
18347151e4bSgaurav rana 	return 0;
18447151e4bSgaurav rana }
18547151e4bSgaurav rana 
18694ba5e41SAneesh Bansal /* It read validates srk_table key lengths.*/
18794ba5e41SAneesh Bansal static u32 read_validate_srk_tbl(struct fsl_secboot_img_priv *img)
18847151e4bSgaurav rana {
18947151e4bSgaurav rana 	int i = 0;
19094ba5e41SAneesh Bansal 	u32 ret, key_num, key_revoc_flag, size;
19194ba5e41SAneesh Bansal 	struct fsl_secboot_img_hdr *hdr = &img->hdr;
19294ba5e41SAneesh Bansal 	void *esbc = (u8 *)(uintptr_t)img->ehdrloc;
19394ba5e41SAneesh Bansal 
19494ba5e41SAneesh Bansal 	if ((hdr->len_kr.num_srk == 0) ||
19594ba5e41SAneesh Bansal 	    (hdr->len_kr.num_srk > MAX_KEY_ENTRIES))
19694ba5e41SAneesh Bansal 		return ERROR_ESBC_CLIENT_HEADER_INVALID_SRK_NUM_ENTRY;
19794ba5e41SAneesh Bansal 
19894ba5e41SAneesh Bansal 	key_num = hdr->len_kr.srk_sel;
19994ba5e41SAneesh Bansal 	if (key_num == 0 || key_num > hdr->len_kr.num_srk)
20094ba5e41SAneesh Bansal 		return ERROR_ESBC_CLIENT_HEADER_INVALID_KEY_NUM;
20194ba5e41SAneesh Bansal 
20294ba5e41SAneesh Bansal 	/* Get revoc key from sfp */
20394ba5e41SAneesh Bansal 	key_revoc_flag = get_key_revoc();
20494ba5e41SAneesh Bansal 	ret = is_key_revoked(key_num, key_revoc_flag);
20594ba5e41SAneesh Bansal 	if (ret)
20694ba5e41SAneesh Bansal 		return ERROR_ESBC_CLIENT_HEADER_KEY_REVOKED;
20794ba5e41SAneesh Bansal 
20894ba5e41SAneesh Bansal 	size = hdr->len_kr.num_srk * sizeof(struct srk_table);
20994ba5e41SAneesh Bansal 
21094ba5e41SAneesh Bansal 	memcpy(&img->srk_tbl, esbc + hdr->srk_tbl_off, size);
21194ba5e41SAneesh Bansal 
21294ba5e41SAneesh Bansal 	for (i = 0; i < hdr->len_kr.num_srk; i++) {
21394ba5e41SAneesh Bansal 		if (!CHECK_KEY_LEN(img->srk_tbl[i].key_len))
21447151e4bSgaurav rana 			return ERROR_ESBC_CLIENT_HEADER_INV_SRK_ENTRY_KEYLEN;
21547151e4bSgaurav rana 	}
21694ba5e41SAneesh Bansal 
21794ba5e41SAneesh Bansal 	img->key_len = img->srk_tbl[key_num - 1].key_len;
21894ba5e41SAneesh Bansal 
21994ba5e41SAneesh Bansal 	memcpy(&img->img_key, &(img->srk_tbl[key_num - 1].pkey),
22094ba5e41SAneesh Bansal 	       img->key_len);
22194ba5e41SAneesh Bansal 
22247151e4bSgaurav rana 	return 0;
22347151e4bSgaurav rana }
22447151e4bSgaurav rana #endif
22547151e4bSgaurav rana 
22694ba5e41SAneesh Bansal static u32 read_validate_single_key(struct fsl_secboot_img_priv *img)
22794ba5e41SAneesh Bansal {
22894ba5e41SAneesh Bansal 	struct fsl_secboot_img_hdr *hdr = &img->hdr;
22994ba5e41SAneesh Bansal 	void *esbc = (u8 *)(uintptr_t)img->ehdrloc;
23094ba5e41SAneesh Bansal 
23194ba5e41SAneesh Bansal 	/* check key length */
23294ba5e41SAneesh Bansal 	if (!CHECK_KEY_LEN(hdr->key_len))
23394ba5e41SAneesh Bansal 		return ERROR_ESBC_CLIENT_HEADER_KEY_LEN;
23494ba5e41SAneesh Bansal 
23594ba5e41SAneesh Bansal 	memcpy(&img->img_key, esbc + hdr->pkey, hdr->key_len);
23694ba5e41SAneesh Bansal 
23794ba5e41SAneesh Bansal 	img->key_len = hdr->key_len;
23894ba5e41SAneesh Bansal 
23994ba5e41SAneesh Bansal 	return 0;
24094ba5e41SAneesh Bansal }
24194ba5e41SAneesh Bansal 
24294ba5e41SAneesh Bansal #if defined(CONFIG_FSL_ISBC_KEY_EXT)
24394ba5e41SAneesh Bansal static u32 read_validate_ie_tbl(struct fsl_secboot_img_priv *img)
24494ba5e41SAneesh Bansal {
24594ba5e41SAneesh Bansal 	struct fsl_secboot_img_hdr *hdr = &img->hdr;
24694ba5e41SAneesh Bansal 	u32 ie_key_len, ie_revoc_flag, ie_num;
24794ba5e41SAneesh Bansal 	struct ie_key_info *ie_info;
24894ba5e41SAneesh Bansal 
24994ba5e41SAneesh Bansal 	if (get_ie_info_addr(&img->ie_addr))
25094ba5e41SAneesh Bansal 		return ERROR_IE_TABLE_NOT_FOUND;
25194ba5e41SAneesh Bansal 	ie_info = (struct ie_key_info *)(uintptr_t)img->ie_addr;
25294ba5e41SAneesh Bansal 	if (ie_info->num_keys == 0 || ie_info->num_keys > 32)
25394ba5e41SAneesh Bansal 		return ERROR_ESBC_CLIENT_HEADER_INVALID_IE_NUM_ENTRY;
25494ba5e41SAneesh Bansal 
25594ba5e41SAneesh Bansal 	ie_num = hdr->ie_key_sel;
25694ba5e41SAneesh Bansal 	if (ie_num == 0 || ie_num > ie_info->num_keys)
25794ba5e41SAneesh Bansal 		return ERROR_ESBC_CLIENT_HEADER_INVALID_IE_KEY_NUM;
25894ba5e41SAneesh Bansal 
25994ba5e41SAneesh Bansal 	ie_revoc_flag = ie_info->key_revok;
26094ba5e41SAneesh Bansal 	if ((u32)(1 << (ie_num - 1)) & ie_revoc_flag)
26194ba5e41SAneesh Bansal 		return ERROR_ESBC_CLIENT_HEADER_IE_KEY_REVOKED;
26294ba5e41SAneesh Bansal 
26394ba5e41SAneesh Bansal 	ie_key_len = ie_info->ie_key_tbl[ie_num - 1].key_len;
26494ba5e41SAneesh Bansal 
26594ba5e41SAneesh Bansal 	if (!CHECK_KEY_LEN(ie_key_len))
26694ba5e41SAneesh Bansal 		return ERROR_ESBC_CLIENT_HEADER_INV_IE_ENTRY_KEYLEN;
26794ba5e41SAneesh Bansal 
26894ba5e41SAneesh Bansal 	memcpy(&img->img_key, &(ie_info->ie_key_tbl[ie_num - 1].pkey),
26994ba5e41SAneesh Bansal 	       ie_key_len);
27094ba5e41SAneesh Bansal 
27194ba5e41SAneesh Bansal 	img->key_len = ie_key_len;
27294ba5e41SAneesh Bansal 	return 0;
27394ba5e41SAneesh Bansal }
27494ba5e41SAneesh Bansal #endif
27594ba5e41SAneesh Bansal 
27694ba5e41SAneesh Bansal 
27747151e4bSgaurav rana /* This function return length of public key.*/
27847151e4bSgaurav rana static inline u32 get_key_len(struct fsl_secboot_img_priv *img)
27947151e4bSgaurav rana {
28047151e4bSgaurav rana 	return img->key_len;
28147151e4bSgaurav rana }
28247151e4bSgaurav rana 
28347151e4bSgaurav rana /*
28447151e4bSgaurav rana  * Handles the ESBC uboot client header verification failure.
28547151e4bSgaurav rana  * This  function  handles all the errors which might occur in the
28647151e4bSgaurav rana  * parsing and checking of ESBC uboot client header. It will also
28747151e4bSgaurav rana  * set the error bits in the SEC_MON.
28847151e4bSgaurav rana  */
28947151e4bSgaurav rana static void fsl_secboot_header_verification_failure(void)
29047151e4bSgaurav rana {
29147151e4bSgaurav rana 	struct ccsr_sec_mon_regs *sec_mon_regs = (void *)
29247151e4bSgaurav rana 						(CONFIG_SYS_SEC_MON_ADDR);
29347151e4bSgaurav rana 	struct ccsr_sfp_regs *sfp_regs = (void *)(CONFIG_SYS_SFP_ADDR);
29447151e4bSgaurav rana 	u32 sts = sec_mon_in32(&sec_mon_regs->hp_stat);
29547151e4bSgaurav rana 
29647151e4bSgaurav rana 	/* 29th bit of OSPR is ITS */
29747151e4bSgaurav rana 	u32 its = sfp_in32(&sfp_regs->ospr) >> 2;
29847151e4bSgaurav rana 
29947151e4bSgaurav rana 	/*
30047151e4bSgaurav rana 	 * Read the SEC_MON status register
30147151e4bSgaurav rana 	 * Read SSM_ST field
30247151e4bSgaurav rana 	 */
30347151e4bSgaurav rana 	sts = sec_mon_in32(&sec_mon_regs->hp_stat);
30447151e4bSgaurav rana 	if ((sts & HPSR_SSM_ST_MASK) == HPSR_SSM_ST_TRUST) {
30547151e4bSgaurav rana 		if (its == 1)
30647151e4bSgaurav rana 			change_sec_mon_state(HPSR_SSM_ST_TRUST,
30747151e4bSgaurav rana 					     HPSR_SSM_ST_SOFT_FAIL);
30847151e4bSgaurav rana 		else
30947151e4bSgaurav rana 			change_sec_mon_state(HPSR_SSM_ST_TRUST,
31047151e4bSgaurav rana 					     HPSR_SSM_ST_NON_SECURE);
31147151e4bSgaurav rana 	}
31247151e4bSgaurav rana 
31347151e4bSgaurav rana 	printf("Generating reset request\n");
31447151e4bSgaurav rana 	do_reset(NULL, 0, 0, NULL);
31547151e4bSgaurav rana }
31647151e4bSgaurav rana 
31747151e4bSgaurav rana /*
31847151e4bSgaurav rana  * Handles the ESBC uboot client image verification failure.
31947151e4bSgaurav rana  * This  function  handles all the errors which might occur in the
32047151e4bSgaurav rana  * public key hash comparison and signature verification of
32147151e4bSgaurav rana  * ESBC uboot client image. It will also
32247151e4bSgaurav rana  * set the error bits in the SEC_MON.
32347151e4bSgaurav rana  */
32447151e4bSgaurav rana static void fsl_secboot_image_verification_failure(void)
32547151e4bSgaurav rana {
32647151e4bSgaurav rana 	struct ccsr_sec_mon_regs *sec_mon_regs = (void *)
32747151e4bSgaurav rana 						(CONFIG_SYS_SEC_MON_ADDR);
32847151e4bSgaurav rana 	struct ccsr_sfp_regs *sfp_regs = (void *)(CONFIG_SYS_SFP_ADDR);
32947151e4bSgaurav rana 	u32 sts = sec_mon_in32(&sec_mon_regs->hp_stat);
33047151e4bSgaurav rana 
3316ec9aef2SAneesh Bansal 	u32 its = (sfp_in32(&sfp_regs->ospr) & ITS_MASK) >> ITS_BIT;
33247151e4bSgaurav rana 
33347151e4bSgaurav rana 	/*
33447151e4bSgaurav rana 	 * Read the SEC_MON status register
33547151e4bSgaurav rana 	 * Read SSM_ST field
33647151e4bSgaurav rana 	 */
33747151e4bSgaurav rana 	sts = sec_mon_in32(&sec_mon_regs->hp_stat);
33847151e4bSgaurav rana 	if ((sts & HPSR_SSM_ST_MASK) == HPSR_SSM_ST_TRUST) {
33947151e4bSgaurav rana 		if (its == 1) {
34047151e4bSgaurav rana 			change_sec_mon_state(HPSR_SSM_ST_TRUST,
34147151e4bSgaurav rana 					     HPSR_SSM_ST_SOFT_FAIL);
34247151e4bSgaurav rana 
34347151e4bSgaurav rana 			printf("Generating reset request\n");
34447151e4bSgaurav rana 			do_reset(NULL, 0, 0, NULL);
34547151e4bSgaurav rana 		} else {
34647151e4bSgaurav rana 			change_sec_mon_state(HPSR_SSM_ST_TRUST,
34747151e4bSgaurav rana 					     HPSR_SSM_ST_NON_SECURE);
34847151e4bSgaurav rana 		}
34947151e4bSgaurav rana 	}
35047151e4bSgaurav rana }
35147151e4bSgaurav rana 
35247151e4bSgaurav rana static void fsl_secboot_bootscript_parse_failure(void)
35347151e4bSgaurav rana {
35447151e4bSgaurav rana 	fsl_secboot_header_verification_failure();
35547151e4bSgaurav rana }
35647151e4bSgaurav rana 
35747151e4bSgaurav rana /*
35847151e4bSgaurav rana  * Handles the errors in esbc boot.
35947151e4bSgaurav rana  * This  function  handles all the errors which might occur in the
36047151e4bSgaurav rana  * esbc boot phase. It will call the appropriate api to log the
36147151e4bSgaurav rana  * errors and set the error bits in the SEC_MON.
36247151e4bSgaurav rana  */
36347151e4bSgaurav rana void fsl_secboot_handle_error(int error)
36447151e4bSgaurav rana {
36547151e4bSgaurav rana 	const struct fsl_secboot_errcode *e;
36647151e4bSgaurav rana 
36747151e4bSgaurav rana 	for (e = fsl_secboot_errcodes; e->errcode != ERROR_ESBC_CLIENT_MAX;
36847151e4bSgaurav rana 		e++) {
36947151e4bSgaurav rana 		if (e->errcode == error)
37047151e4bSgaurav rana 			printf("ERROR :: %x :: %s\n", error, e->name);
37147151e4bSgaurav rana 	}
37247151e4bSgaurav rana 
37347151e4bSgaurav rana 	switch (error) {
37447151e4bSgaurav rana 	case ERROR_ESBC_CLIENT_HEADER_BARKER:
37547151e4bSgaurav rana 	case ERROR_ESBC_CLIENT_HEADER_IMG_SIZE:
37647151e4bSgaurav rana 	case ERROR_ESBC_CLIENT_HEADER_KEY_LEN:
37747151e4bSgaurav rana 	case ERROR_ESBC_CLIENT_HEADER_SIG_LEN:
37847151e4bSgaurav rana 	case ERROR_ESBC_CLIENT_HEADER_KEY_LEN_NOT_TWICE_SIG_LEN:
37947151e4bSgaurav rana 	case ERROR_ESBC_CLIENT_HEADER_KEY_MOD_1:
38047151e4bSgaurav rana 	case ERROR_ESBC_CLIENT_HEADER_KEY_MOD_2:
38147151e4bSgaurav rana 	case ERROR_ESBC_CLIENT_HEADER_SIG_KEY_MOD:
38247151e4bSgaurav rana 	case ERROR_ESBC_CLIENT_HEADER_SG_ESBC_EP:
38347151e4bSgaurav rana 	case ERROR_ESBC_CLIENT_HEADER_SG_ENTIRES_BAD:
38447151e4bSgaurav rana #ifdef CONFIG_KEY_REVOCATION
38547151e4bSgaurav rana 	case ERROR_ESBC_CLIENT_HEADER_KEY_REVOKED:
38647151e4bSgaurav rana 	case ERROR_ESBC_CLIENT_HEADER_INVALID_SRK_NUM_ENTRY:
38747151e4bSgaurav rana 	case ERROR_ESBC_CLIENT_HEADER_INVALID_KEY_NUM:
38847151e4bSgaurav rana 	case ERROR_ESBC_CLIENT_HEADER_INV_SRK_ENTRY_KEYLEN:
38947151e4bSgaurav rana #endif
39047151e4bSgaurav rana #if defined(CONFIG_FSL_ISBC_KEY_EXT)
39147151e4bSgaurav rana 	/*@fallthrough@*/
39247151e4bSgaurav rana 	case ERROR_ESBC_CLIENT_HEADER_IE_KEY_REVOKED:
39347151e4bSgaurav rana 	case ERROR_ESBC_CLIENT_HEADER_INVALID_IE_NUM_ENTRY:
39447151e4bSgaurav rana 	case ERROR_ESBC_CLIENT_HEADER_INVALID_IE_KEY_NUM:
39547151e4bSgaurav rana 	case ERROR_ESBC_CLIENT_HEADER_INV_IE_ENTRY_KEYLEN:
39647151e4bSgaurav rana 	case ERROR_IE_TABLE_NOT_FOUND:
39747151e4bSgaurav rana #endif
39847151e4bSgaurav rana 		fsl_secboot_header_verification_failure();
39947151e4bSgaurav rana 		break;
40047151e4bSgaurav rana 	case ERROR_ESBC_SEC_RESET:
40147151e4bSgaurav rana 	case ERROR_ESBC_SEC_DEQ:
40247151e4bSgaurav rana 	case ERROR_ESBC_SEC_ENQ:
40347151e4bSgaurav rana 	case ERROR_ESBC_SEC_DEQ_TO:
40447151e4bSgaurav rana 	case ERROR_ESBC_SEC_JOBQ_STATUS:
40547151e4bSgaurav rana 	case ERROR_ESBC_CLIENT_HASH_COMPARE_KEY:
40647151e4bSgaurav rana 	case ERROR_ESBC_CLIENT_HASH_COMPARE_EM:
40747151e4bSgaurav rana 		fsl_secboot_image_verification_failure();
40847151e4bSgaurav rana 		break;
40947151e4bSgaurav rana 	case ERROR_ESBC_MISSING_BOOTM:
41047151e4bSgaurav rana 		fsl_secboot_bootscript_parse_failure();
41147151e4bSgaurav rana 		break;
41247151e4bSgaurav rana 	case ERROR_ESBC_WRONG_CMD:
41347151e4bSgaurav rana 	default:
41447151e4bSgaurav rana 		branch_to_self();
41547151e4bSgaurav rana 		break;
41647151e4bSgaurav rana 	}
41747151e4bSgaurav rana }
41847151e4bSgaurav rana 
41947151e4bSgaurav rana static void fsl_secblk_handle_error(int error)
42047151e4bSgaurav rana {
42147151e4bSgaurav rana 	switch (error) {
42247151e4bSgaurav rana 	case ERROR_ESBC_SEC_ENQ:
42347151e4bSgaurav rana 		fsl_secboot_handle_error(ERROR_ESBC_SEC_ENQ);
42447151e4bSgaurav rana 		break;
42547151e4bSgaurav rana 	case ERROR_ESBC_SEC_DEQ:
42647151e4bSgaurav rana 		fsl_secboot_handle_error(ERROR_ESBC_SEC_DEQ);
42747151e4bSgaurav rana 		break;
42847151e4bSgaurav rana 	case ERROR_ESBC_SEC_DEQ_TO:
42947151e4bSgaurav rana 		fsl_secboot_handle_error(ERROR_ESBC_SEC_DEQ_TO);
43047151e4bSgaurav rana 		break;
43147151e4bSgaurav rana 	default:
43247151e4bSgaurav rana 		printf("Job Queue Output status %x\n", error);
43347151e4bSgaurav rana 		fsl_secboot_handle_error(ERROR_ESBC_SEC_JOBQ_STATUS);
43447151e4bSgaurav rana 		break;
43547151e4bSgaurav rana 	}
43647151e4bSgaurav rana }
43747151e4bSgaurav rana 
43847151e4bSgaurav rana /*
43947151e4bSgaurav rana  * Calculate hash of key obtained via offset present in ESBC uboot
44047151e4bSgaurav rana  * client hdr. This function calculates the hash of key which is obtained
44147151e4bSgaurav rana  * through offset present in ESBC uboot client header.
44247151e4bSgaurav rana  */
44347151e4bSgaurav rana static int calc_img_key_hash(struct fsl_secboot_img_priv *img)
44447151e4bSgaurav rana {
44547151e4bSgaurav rana 	struct hash_algo *algo;
44647151e4bSgaurav rana 	void *ctx;
44747151e4bSgaurav rana 	int i, srk = 0;
44847151e4bSgaurav rana 	int ret = 0;
44947151e4bSgaurav rana 	const char *algo_name = "sha256";
45047151e4bSgaurav rana 
45147151e4bSgaurav rana 	/* Calculate hash of the esbc key */
45247151e4bSgaurav rana 	ret = hash_progressive_lookup_algo(algo_name, &algo);
45347151e4bSgaurav rana 	if (ret)
45447151e4bSgaurav rana 		return ret;
45547151e4bSgaurav rana 
45647151e4bSgaurav rana 	ret = algo->hash_init(algo, &ctx);
45747151e4bSgaurav rana 	if (ret)
45847151e4bSgaurav rana 		return ret;
45947151e4bSgaurav rana 
46047151e4bSgaurav rana 	/* Update hash for ESBC key */
46147151e4bSgaurav rana #ifdef CONFIG_KEY_REVOCATION
46247151e4bSgaurav rana 	if (check_srk(img)) {
46347151e4bSgaurav rana 		ret = algo->hash_update(algo, ctx,
4649711f528SAneesh Bansal 		      (u8 *)(uintptr_t)(img->ehdrloc + img->hdr.srk_tbl_off),
46547151e4bSgaurav rana 		      img->hdr.len_kr.num_srk * sizeof(struct srk_table), 1);
46647151e4bSgaurav rana 		srk = 1;
46747151e4bSgaurav rana 	}
46847151e4bSgaurav rana #endif
46947151e4bSgaurav rana 	if (!srk)
47047151e4bSgaurav rana 		ret = algo->hash_update(algo, ctx,
47147151e4bSgaurav rana 			img->img_key, img->key_len, 1);
47247151e4bSgaurav rana 	if (ret)
47347151e4bSgaurav rana 		return ret;
47447151e4bSgaurav rana 
47547151e4bSgaurav rana 	/* Copy hash at destination buffer */
47647151e4bSgaurav rana 	ret = algo->hash_finish(algo, ctx, hash_val, algo->digest_size);
47747151e4bSgaurav rana 	if (ret)
47847151e4bSgaurav rana 		return ret;
47947151e4bSgaurav rana 
48047151e4bSgaurav rana 	for (i = 0; i < SHA256_BYTES; i++)
48147151e4bSgaurav rana 		img->img_key_hash[i] = hash_val[i];
48247151e4bSgaurav rana 
48347151e4bSgaurav rana 	return 0;
48447151e4bSgaurav rana }
48547151e4bSgaurav rana 
48647151e4bSgaurav rana /*
48747151e4bSgaurav rana  * Calculate hash of ESBC hdr and ESBC. This function calculates the
48847151e4bSgaurav rana  * single hash of ESBC header and ESBC image. If SG flag is on, all
48947151e4bSgaurav rana  * SG entries are also hashed alongwith the complete SG table.
49047151e4bSgaurav rana  */
49147151e4bSgaurav rana static int calc_esbchdr_esbc_hash(struct fsl_secboot_img_priv *img)
49247151e4bSgaurav rana {
49347151e4bSgaurav rana 	struct hash_algo *algo;
49447151e4bSgaurav rana 	void *ctx;
49547151e4bSgaurav rana 	int ret = 0;
49647151e4bSgaurav rana 	int key_hash = 0;
49747151e4bSgaurav rana 	const char *algo_name = "sha256";
49847151e4bSgaurav rana 
49947151e4bSgaurav rana 	/* Calculate the hash of the ESBC */
50047151e4bSgaurav rana 	ret = hash_progressive_lookup_algo(algo_name, &algo);
50147151e4bSgaurav rana 	if (ret)
50247151e4bSgaurav rana 		return ret;
50347151e4bSgaurav rana 
50447151e4bSgaurav rana 	ret = algo->hash_init(algo, &ctx);
50547151e4bSgaurav rana 	/* Copy hash at destination buffer */
50647151e4bSgaurav rana 	if (ret)
50747151e4bSgaurav rana 		return ret;
50847151e4bSgaurav rana 
50947151e4bSgaurav rana 	/* Update hash for CSF Header */
51047151e4bSgaurav rana 	ret = algo->hash_update(algo, ctx,
51147151e4bSgaurav rana 		(u8 *)&img->hdr, sizeof(struct fsl_secboot_img_hdr), 0);
51247151e4bSgaurav rana 	if (ret)
51347151e4bSgaurav rana 		return ret;
51447151e4bSgaurav rana 
51547151e4bSgaurav rana 	/* Update the hash with that of srk table if srk flag is 1
51647151e4bSgaurav rana 	 * If IE Table is selected, key is not added in the hash
51747151e4bSgaurav rana 	 * If neither srk table nor IE key table available, add key
51847151e4bSgaurav rana 	 * from header in the hash calculation
51947151e4bSgaurav rana 	 */
52047151e4bSgaurav rana #ifdef CONFIG_KEY_REVOCATION
52147151e4bSgaurav rana 	if (check_srk(img)) {
52247151e4bSgaurav rana 		ret = algo->hash_update(algo, ctx,
5239711f528SAneesh Bansal 		      (u8 *)(uintptr_t)(img->ehdrloc + img->hdr.srk_tbl_off),
52447151e4bSgaurav rana 		      img->hdr.len_kr.num_srk * sizeof(struct srk_table), 0);
52547151e4bSgaurav rana 		key_hash = 1;
52647151e4bSgaurav rana 	}
52747151e4bSgaurav rana #endif
52847151e4bSgaurav rana #if defined(CONFIG_FSL_ISBC_KEY_EXT)
52947151e4bSgaurav rana 	if (!key_hash && check_ie(img))
53047151e4bSgaurav rana 		key_hash = 1;
53147151e4bSgaurav rana #endif
53247151e4bSgaurav rana 	if (!key_hash)
53347151e4bSgaurav rana 		ret = algo->hash_update(algo, ctx,
53447151e4bSgaurav rana 			img->img_key, img->hdr.key_len, 0);
53547151e4bSgaurav rana 	if (ret)
53647151e4bSgaurav rana 		return ret;
53747151e4bSgaurav rana 
53847151e4bSgaurav rana 	/* Update hash for actual Image */
5399711f528SAneesh Bansal #ifdef CONFIG_ESBC_ADDR_64BIT
54047151e4bSgaurav rana 	ret = algo->hash_update(algo, ctx,
5419711f528SAneesh Bansal 		(u8 *)(uintptr_t)img->hdr.pimg64, img->hdr.img_size, 1);
5429711f528SAneesh Bansal #else
5439711f528SAneesh Bansal 	ret = algo->hash_update(algo, ctx,
5449711f528SAneesh Bansal 		(u8 *)(uintptr_t)img->hdr.pimg, img->hdr.img_size, 1);
5459711f528SAneesh Bansal #endif
54647151e4bSgaurav rana 	if (ret)
54747151e4bSgaurav rana 		return ret;
54847151e4bSgaurav rana 
54947151e4bSgaurav rana 	/* Copy hash at destination buffer */
55047151e4bSgaurav rana 	ret = algo->hash_finish(algo, ctx, hash_val, algo->digest_size);
55147151e4bSgaurav rana 	if (ret)
55247151e4bSgaurav rana 		return ret;
55347151e4bSgaurav rana 
55447151e4bSgaurav rana 	return 0;
55547151e4bSgaurav rana }
55647151e4bSgaurav rana 
55747151e4bSgaurav rana /*
55847151e4bSgaurav rana  * Construct encoded hash EM' wrt PKCSv1.5. This function calculates the
55947151e4bSgaurav rana  * pointers for padding, DER value and hash. And finally, constructs EM'
56047151e4bSgaurav rana  * which includes hash of complete CSF header and ESBC image. If SG flag
56147151e4bSgaurav rana  * is on, hash of SG table and entries is also included.
56247151e4bSgaurav rana  */
56347151e4bSgaurav rana static void construct_img_encoded_hash_second(struct fsl_secboot_img_priv *img)
56447151e4bSgaurav rana {
56547151e4bSgaurav rana 	/*
56647151e4bSgaurav rana 	 * RSA PKCSv1.5 encoding format for encoded message is below
56747151e4bSgaurav rana 	 * EM = 0x0 || 0x1 || PS || 0x0 || DER || Hash
56847151e4bSgaurav rana 	 * PS is Padding String
56947151e4bSgaurav rana 	 * DER is DER value for SHA-256
57047151e4bSgaurav rana 	 * Hash is SHA-256 hash
57147151e4bSgaurav rana 	 * *********************************************************
57247151e4bSgaurav rana 	 * representative points to first byte of EM initially and is
57347151e4bSgaurav rana 	 * filled with 0x0
57447151e4bSgaurav rana 	 * representative is incremented by 1 and second byte is filled
57547151e4bSgaurav rana 	 * with 0x1
57647151e4bSgaurav rana 	 * padding points to third byte of EM
57747151e4bSgaurav rana 	 * digest points to full length of EM - 32 bytes
57847151e4bSgaurav rana 	 * hash_id (DER value) points to 19 bytes before pDigest
57947151e4bSgaurav rana 	 * separator is one byte which separates padding and DER
58047151e4bSgaurav rana 	 */
58147151e4bSgaurav rana 
58247151e4bSgaurav rana 	size_t len;
58347151e4bSgaurav rana 	u8 *representative;
58447151e4bSgaurav rana 	u8 *padding, *digest;
58547151e4bSgaurav rana 	u8 *hash_id, *separator;
58647151e4bSgaurav rana 	int i;
58747151e4bSgaurav rana 
58847151e4bSgaurav rana 	len = (get_key_len(img) / 2) - 1;
58947151e4bSgaurav rana 	representative = img->img_encoded_hash_second;
59047151e4bSgaurav rana 	representative[0] = 0;
59147151e4bSgaurav rana 	representative[1] = 1;  /* block type 1 */
59247151e4bSgaurav rana 
59347151e4bSgaurav rana 	padding = &representative[2];
59447151e4bSgaurav rana 	digest = &representative[1] + len - 32;
59547151e4bSgaurav rana 	hash_id = digest - sizeof(hash_identifier);
59647151e4bSgaurav rana 	separator = hash_id - 1;
59747151e4bSgaurav rana 
59847151e4bSgaurav rana 	/* fill padding area pointed by padding with 0xff */
59947151e4bSgaurav rana 	memset(padding, 0xff, separator - padding);
60047151e4bSgaurav rana 
60147151e4bSgaurav rana 	/* fill byte pointed by separator */
60247151e4bSgaurav rana 	*separator = 0;
60347151e4bSgaurav rana 
60447151e4bSgaurav rana 	/* fill SHA-256 DER value  pointed by HashId */
60547151e4bSgaurav rana 	memcpy(hash_id, hash_identifier, sizeof(hash_identifier));
60647151e4bSgaurav rana 
60747151e4bSgaurav rana 	/* fill hash pointed by Digest */
60847151e4bSgaurav rana 	for (i = 0; i < SHA256_BYTES; i++)
60947151e4bSgaurav rana 		digest[i] = hash_val[i];
61047151e4bSgaurav rana }
61147151e4bSgaurav rana 
61247151e4bSgaurav rana /*
61347151e4bSgaurav rana  * Reads and validates the ESBC client header.
61447151e4bSgaurav rana  * This function reads key and signature from the ESBC client header.
61547151e4bSgaurav rana  * If Scatter/Gather flag is on, lengths and offsets of images
61647151e4bSgaurav rana  * present as SG entries are also read. This function also checks
61747151e4bSgaurav rana  * whether the header is valid or not.
61847151e4bSgaurav rana  */
61947151e4bSgaurav rana static int read_validate_esbc_client_header(struct fsl_secboot_img_priv *img)
62047151e4bSgaurav rana {
62147151e4bSgaurav rana 	char buf[20];
62247151e4bSgaurav rana 	struct fsl_secboot_img_hdr *hdr = &img->hdr;
6239711f528SAneesh Bansal 	void *esbc = (u8 *)(uintptr_t)img->ehdrloc;
62447151e4bSgaurav rana 	u8 *k, *s;
62594ba5e41SAneesh Bansal 	u32 ret = 0;
62694ba5e41SAneesh Bansal 
62747151e4bSgaurav rana #ifdef CONFIG_KEY_REVOCATION
62847151e4bSgaurav rana #endif
62947151e4bSgaurav rana 	int  key_found = 0;
63047151e4bSgaurav rana 
63147151e4bSgaurav rana 	/* check barker code */
63247151e4bSgaurav rana 	if (memcmp(hdr->barker, barker_code, ESBC_BARKER_LEN))
63347151e4bSgaurav rana 		return ERROR_ESBC_CLIENT_HEADER_BARKER;
63447151e4bSgaurav rana 
6359711f528SAneesh Bansal #ifdef CONFIG_ESBC_ADDR_64BIT
6369711f528SAneesh Bansal 	sprintf(buf, "%llx", hdr->pimg64);
6379711f528SAneesh Bansal #else
6387bcb0eb2SAneesh Bansal 	sprintf(buf, "%x", hdr->pimg);
6399711f528SAneesh Bansal #endif
64047151e4bSgaurav rana 	setenv("img_addr", buf);
64147151e4bSgaurav rana 
64247151e4bSgaurav rana 	if (!hdr->img_size)
64347151e4bSgaurav rana 		return ERROR_ESBC_CLIENT_HEADER_IMG_SIZE;
64447151e4bSgaurav rana 
64547151e4bSgaurav rana 	/* Key checking*/
64647151e4bSgaurav rana #ifdef CONFIG_KEY_REVOCATION
64747151e4bSgaurav rana 	if (check_srk(img)) {
64894ba5e41SAneesh Bansal 		ret = read_validate_srk_tbl(img);
64947151e4bSgaurav rana 		if (ret != 0)
65047151e4bSgaurav rana 			return ret;
65147151e4bSgaurav rana 		key_found = 1;
65247151e4bSgaurav rana 	}
65347151e4bSgaurav rana #endif
65447151e4bSgaurav rana 
65547151e4bSgaurav rana #if defined(CONFIG_FSL_ISBC_KEY_EXT)
65647151e4bSgaurav rana 	if (!key_found && check_ie(img)) {
65794ba5e41SAneesh Bansal 		ret = read_validate_ie_tbl(img);
65894ba5e41SAneesh Bansal 		if (ret != 0)
65994ba5e41SAneesh Bansal 			return ret;
66047151e4bSgaurav rana 		key_found = 1;
66147151e4bSgaurav rana 	}
66247151e4bSgaurav rana #endif
66347151e4bSgaurav rana 
66447151e4bSgaurav rana 	if (key_found == 0) {
66594ba5e41SAneesh Bansal 		ret = read_validate_single_key(img);
66694ba5e41SAneesh Bansal 		if (ret != 0)
66794ba5e41SAneesh Bansal 			return ret;
66847151e4bSgaurav rana 		key_found = 1;
66947151e4bSgaurav rana 	}
67047151e4bSgaurav rana 
67147151e4bSgaurav rana 	/* check signaure */
67247151e4bSgaurav rana 	if (get_key_len(img) == 2 * hdr->sign_len) {
67347151e4bSgaurav rana 		/* check signature length */
67447151e4bSgaurav rana 		if (!((hdr->sign_len == KEY_SIZE_BYTES / 4) ||
67547151e4bSgaurav rana 		      (hdr->sign_len == KEY_SIZE_BYTES / 2) ||
67647151e4bSgaurav rana 		      (hdr->sign_len == KEY_SIZE_BYTES)))
67747151e4bSgaurav rana 			return ERROR_ESBC_CLIENT_HEADER_SIG_LEN;
67847151e4bSgaurav rana 	} else {
67947151e4bSgaurav rana 		return ERROR_ESBC_CLIENT_HEADER_KEY_LEN_NOT_TWICE_SIG_LEN;
68047151e4bSgaurav rana 	}
68147151e4bSgaurav rana 
68247151e4bSgaurav rana 	memcpy(&img->img_sign, esbc + hdr->psign, hdr->sign_len);
68347151e4bSgaurav rana 
68447151e4bSgaurav rana 	/* No SG support */
68547151e4bSgaurav rana 	if (hdr->sg_flag)
68647151e4bSgaurav rana 		return ERROR_ESBC_CLIENT_HEADER_SG;
68747151e4bSgaurav rana 
68847151e4bSgaurav rana 	/* modulus most significant bit should be set */
68947151e4bSgaurav rana 	k = (u8 *)&img->img_key;
69047151e4bSgaurav rana 
69147151e4bSgaurav rana 	if ((k[0] & 0x80) == 0)
69247151e4bSgaurav rana 		return ERROR_ESBC_CLIENT_HEADER_KEY_MOD_1;
69347151e4bSgaurav rana 
69447151e4bSgaurav rana 	/* modulus value should be odd */
69547151e4bSgaurav rana 	if ((k[get_key_len(img) / 2 - 1] & 0x1) == 0)
69647151e4bSgaurav rana 		return ERROR_ESBC_CLIENT_HEADER_KEY_MOD_2;
69747151e4bSgaurav rana 
69847151e4bSgaurav rana 	/* Check signature value < modulus value */
69947151e4bSgaurav rana 	s = (u8 *)&img->img_sign;
70047151e4bSgaurav rana 
70147151e4bSgaurav rana 	if (!(memcmp(s, k, hdr->sign_len) < 0))
70247151e4bSgaurav rana 		return ERROR_ESBC_CLIENT_HEADER_SIG_KEY_MOD;
70347151e4bSgaurav rana 
70447151e4bSgaurav rana 	return ESBC_VALID_HDR;
70547151e4bSgaurav rana }
70647151e4bSgaurav rana 
70747151e4bSgaurav rana static inline int str2longbe(const char *p, ulong *num)
70847151e4bSgaurav rana {
70947151e4bSgaurav rana 	char *endptr;
71047151e4bSgaurav rana 	ulong tmp;
71147151e4bSgaurav rana 
71247151e4bSgaurav rana 	if (!p) {
71347151e4bSgaurav rana 		return 0;
71447151e4bSgaurav rana 	} else {
71547151e4bSgaurav rana 		tmp = simple_strtoul(p, &endptr, 16);
71647151e4bSgaurav rana 		if (sizeof(ulong) == 4)
71747151e4bSgaurav rana 			*num = cpu_to_be32(tmp);
71847151e4bSgaurav rana 		else
71947151e4bSgaurav rana 			*num = cpu_to_be64(tmp);
72047151e4bSgaurav rana 	}
72147151e4bSgaurav rana 
72247151e4bSgaurav rana 	return *p != '\0' && *endptr == '\0';
72347151e4bSgaurav rana }
724*6629261dSAneesh Bansal /* Function to calculate the ESBC Image Hash
725*6629261dSAneesh Bansal  * and hash from Digital signature.
726*6629261dSAneesh Bansal  * The Two hash's are compared to yield the
727*6629261dSAneesh Bansal  * result of signature validation.
728*6629261dSAneesh Bansal  */
729*6629261dSAneesh Bansal static int calculate_cmp_img_sig(struct fsl_secboot_img_priv *img)
730*6629261dSAneesh Bansal {
731*6629261dSAneesh Bansal 	int ret;
732*6629261dSAneesh Bansal 	uint32_t key_len;
733*6629261dSAneesh Bansal 	struct key_prop prop;
734*6629261dSAneesh Bansal #if !defined(USE_HOSTCC)
735*6629261dSAneesh Bansal 	struct udevice *mod_exp_dev;
736*6629261dSAneesh Bansal #endif
737*6629261dSAneesh Bansal 	ret = calc_esbchdr_esbc_hash(img);
738*6629261dSAneesh Bansal 	if (ret)
739*6629261dSAneesh Bansal 		return ret;
740*6629261dSAneesh Bansal 
741*6629261dSAneesh Bansal 	/* Construct encoded hash EM' wrt PKCSv1.5 */
742*6629261dSAneesh Bansal 	construct_img_encoded_hash_second(img);
743*6629261dSAneesh Bansal 
744*6629261dSAneesh Bansal 	/* Fill prop structure for public key */
745*6629261dSAneesh Bansal 	memset(&prop, 0, sizeof(struct key_prop));
746*6629261dSAneesh Bansal 	key_len = get_key_len(img) / 2;
747*6629261dSAneesh Bansal 	prop.modulus = img->img_key;
748*6629261dSAneesh Bansal 	prop.public_exponent = img->img_key + key_len;
749*6629261dSAneesh Bansal 	prop.num_bits = key_len * 8;
750*6629261dSAneesh Bansal 	prop.exp_len = key_len;
751*6629261dSAneesh Bansal 
752*6629261dSAneesh Bansal 	ret = uclass_get_device(UCLASS_MOD_EXP, 0, &mod_exp_dev);
753*6629261dSAneesh Bansal 	if (ret) {
754*6629261dSAneesh Bansal 		printf("RSA: Can't find Modular Exp implementation\n");
755*6629261dSAneesh Bansal 		return -EINVAL;
756*6629261dSAneesh Bansal 	}
757*6629261dSAneesh Bansal 
758*6629261dSAneesh Bansal 	ret = rsa_mod_exp(mod_exp_dev, img->img_sign, img->hdr.sign_len,
759*6629261dSAneesh Bansal 			  &prop, img->img_encoded_hash);
760*6629261dSAneesh Bansal 	if (ret)
761*6629261dSAneesh Bansal 		return ret;
762*6629261dSAneesh Bansal 
763*6629261dSAneesh Bansal 	/*
764*6629261dSAneesh Bansal 	 * compare the encoded messages EM' and EM wrt RSA PKCSv1.5
765*6629261dSAneesh Bansal 	 * memcmp returns zero on success
766*6629261dSAneesh Bansal 	 * memcmp returns non-zero on failure
767*6629261dSAneesh Bansal 	 */
768*6629261dSAneesh Bansal 	ret = memcmp(&img->img_encoded_hash_second, &img->img_encoded_hash,
769*6629261dSAneesh Bansal 		img->hdr.sign_len);
770*6629261dSAneesh Bansal 
771*6629261dSAneesh Bansal 	if (ret)
772*6629261dSAneesh Bansal 		return ERROR_ESBC_CLIENT_HASH_COMPARE_EM;
773*6629261dSAneesh Bansal 
774*6629261dSAneesh Bansal 	return 0;
775*6629261dSAneesh Bansal }
77647151e4bSgaurav rana 
777bc71f926SAneesh Bansal int fsl_secboot_validate(ulong haddr, char *arg_hash_str)
77847151e4bSgaurav rana {
77947151e4bSgaurav rana 	struct ccsr_sfp_regs *sfp_regs = (void *)(CONFIG_SYS_SFP_ADDR);
78047151e4bSgaurav rana 	ulong hash[SHA256_BYTES/sizeof(ulong)];
78147151e4bSgaurav rana 	char hash_str[NUM_HEX_CHARS + 1];
78247151e4bSgaurav rana 	struct fsl_secboot_img_priv *img;
78347151e4bSgaurav rana 	struct fsl_secboot_img_hdr *hdr;
78447151e4bSgaurav rana 	void *esbc;
78547151e4bSgaurav rana 	int ret, i, hash_cmd = 0;
78647151e4bSgaurav rana 	u32 srk_hash[8];
78747151e4bSgaurav rana 
788bc71f926SAneesh Bansal 	if (arg_hash_str != NULL) {
789bc71f926SAneesh Bansal 		const char *cp = arg_hash_str;
79047151e4bSgaurav rana 		int i = 0;
79147151e4bSgaurav rana 
79247151e4bSgaurav rana 		if (*cp == '0' && *(cp + 1) == 'x')
79347151e4bSgaurav rana 			cp += 2;
79447151e4bSgaurav rana 
79547151e4bSgaurav rana 		/* The input string expected is in hex, where
79647151e4bSgaurav rana 		 * each 4 bits would be represented by a hex
79747151e4bSgaurav rana 		 * sha256 hash is 256 bits long, which would mean
79847151e4bSgaurav rana 		 * num of characters = 256 / 4
79947151e4bSgaurav rana 		 */
80047151e4bSgaurav rana 		if (strlen(cp) != SHA256_NIBBLES) {
80147151e4bSgaurav rana 			printf("%s is not a 256 bits hex string as expected\n",
802bc71f926SAneesh Bansal 			       arg_hash_str);
80347151e4bSgaurav rana 			return -1;
80447151e4bSgaurav rana 		}
80547151e4bSgaurav rana 
80647151e4bSgaurav rana 		for (i = 0; i < sizeof(hash)/sizeof(ulong); i++) {
80747151e4bSgaurav rana 			strncpy(hash_str, cp + (i * NUM_HEX_CHARS),
80847151e4bSgaurav rana 				NUM_HEX_CHARS);
80947151e4bSgaurav rana 			hash_str[NUM_HEX_CHARS] = '\0';
81047151e4bSgaurav rana 			if (!str2longbe(hash_str, &hash[i])) {
81147151e4bSgaurav rana 				printf("%s is not a 256 bits hex string ",
812bc71f926SAneesh Bansal 				       arg_hash_str);
81347151e4bSgaurav rana 				return -1;
81447151e4bSgaurav rana 			}
81547151e4bSgaurav rana 		}
81647151e4bSgaurav rana 
81747151e4bSgaurav rana 		hash_cmd = 1;
81847151e4bSgaurav rana 	}
81947151e4bSgaurav rana 
82047151e4bSgaurav rana 	img = malloc(sizeof(struct fsl_secboot_img_priv));
82147151e4bSgaurav rana 
82247151e4bSgaurav rana 	if (!img)
82347151e4bSgaurav rana 		return -1;
82447151e4bSgaurav rana 
82547151e4bSgaurav rana 	memset(img, 0, sizeof(struct fsl_secboot_img_priv));
82647151e4bSgaurav rana 
82747151e4bSgaurav rana 	hdr = &img->hdr;
828bc71f926SAneesh Bansal 	img->ehdrloc = haddr;
8299711f528SAneesh Bansal 	esbc = (u8 *)(uintptr_t)img->ehdrloc;
83047151e4bSgaurav rana 
83147151e4bSgaurav rana 	memcpy(hdr, esbc, sizeof(struct fsl_secboot_img_hdr));
83247151e4bSgaurav rana 
83347151e4bSgaurav rana 	/* read and validate esbc header */
83447151e4bSgaurav rana 	ret = read_validate_esbc_client_header(img);
83547151e4bSgaurav rana 
83647151e4bSgaurav rana 	if (ret != ESBC_VALID_HDR) {
83747151e4bSgaurav rana 		fsl_secboot_handle_error(ret);
83847151e4bSgaurav rana 		goto exit;
83947151e4bSgaurav rana 	}
84047151e4bSgaurav rana 
84147151e4bSgaurav rana 	/* SRKH present in SFP */
84247151e4bSgaurav rana 	for (i = 0; i < NUM_SRKH_REGS; i++)
84347151e4bSgaurav rana 		srk_hash[i] = srk_in32(&sfp_regs->srk_hash[i]);
84447151e4bSgaurav rana 
84547151e4bSgaurav rana 	/*
84647151e4bSgaurav rana 	 * Calculate hash of key obtained via offset present in
84747151e4bSgaurav rana 	 * ESBC uboot client hdr
84847151e4bSgaurav rana 	 */
84947151e4bSgaurav rana 	ret = calc_img_key_hash(img);
85047151e4bSgaurav rana 	if (ret) {
85147151e4bSgaurav rana 		fsl_secblk_handle_error(ret);
85247151e4bSgaurav rana 		goto exit;
85347151e4bSgaurav rana 	}
85447151e4bSgaurav rana 
85547151e4bSgaurav rana 	/* Compare hash obtained above with SRK hash present in SFP */
85647151e4bSgaurav rana 	if (hash_cmd)
85747151e4bSgaurav rana 		ret = memcmp(&hash, &img->img_key_hash, SHA256_BYTES);
85847151e4bSgaurav rana 	else
85947151e4bSgaurav rana 		ret = memcmp(srk_hash, img->img_key_hash, SHA256_BYTES);
86047151e4bSgaurav rana 
86147151e4bSgaurav rana #if defined(CONFIG_FSL_ISBC_KEY_EXT)
86247151e4bSgaurav rana 	if (!hash_cmd && check_ie(img))
86347151e4bSgaurav rana 		ret = 0;
86447151e4bSgaurav rana #endif
86547151e4bSgaurav rana 
86647151e4bSgaurav rana 	if (ret != 0) {
86747151e4bSgaurav rana 		fsl_secboot_handle_error(ERROR_ESBC_CLIENT_HASH_COMPARE_KEY);
86847151e4bSgaurav rana 		goto exit;
86947151e4bSgaurav rana 	}
87047151e4bSgaurav rana 
871*6629261dSAneesh Bansal 	ret = calculate_cmp_img_sig(img);
87247151e4bSgaurav rana 	if (ret) {
873*6629261dSAneesh Bansal 		fsl_secboot_handle_error(ret);
87447151e4bSgaurav rana 		goto exit;
87547151e4bSgaurav rana 	}
87647151e4bSgaurav rana 
87747151e4bSgaurav rana exit:
878bc71f926SAneesh Bansal 	return ret;
87947151e4bSgaurav rana }
880