xref: /rk3399_rockchip-uboot/board/freescale/common/fsl_validate.c (revision 47151e4bcc10d87247e0a4809e6761b4477aa80b)
1*47151e4bSgaurav rana /*
2*47151e4bSgaurav rana  * Copyright 2015 Freescale Semiconductor, Inc.
3*47151e4bSgaurav rana  *
4*47151e4bSgaurav rana  * SPDX-License-Identifier:	GPL-2.0+
5*47151e4bSgaurav rana  */
6*47151e4bSgaurav rana 
7*47151e4bSgaurav rana #include <common.h>
8*47151e4bSgaurav rana #include <fsl_validate.h>
9*47151e4bSgaurav rana #include <fsl_secboot_err.h>
10*47151e4bSgaurav rana #include <fsl_sfp.h>
11*47151e4bSgaurav rana #include <fsl_sec.h>
12*47151e4bSgaurav rana #include <command.h>
13*47151e4bSgaurav rana #include <malloc.h>
14*47151e4bSgaurav rana #include <dm/uclass.h>
15*47151e4bSgaurav rana #include <u-boot/rsa-mod-exp.h>
16*47151e4bSgaurav rana #include <hash.h>
17*47151e4bSgaurav rana #include <fsl_secboot_err.h>
18*47151e4bSgaurav rana #ifndef CONFIG_MPC85xx
19*47151e4bSgaurav rana #include <asm/arch/immap_ls102xa.h>
20*47151e4bSgaurav rana #endif
21*47151e4bSgaurav rana 
22*47151e4bSgaurav rana #define SHA256_BITS	256
23*47151e4bSgaurav rana #define SHA256_BYTES	(256/8)
24*47151e4bSgaurav rana #define SHA256_NIBBLES	(256/4)
25*47151e4bSgaurav rana #define NUM_HEX_CHARS	(sizeof(ulong) * 2)
26*47151e4bSgaurav rana 
27*47151e4bSgaurav rana /* This array contains DER value for SHA-256 */
28*47151e4bSgaurav rana static const u8 hash_identifier[] = { 0x30, 0x31, 0x30, 0x0d, 0x06, 0x09, 0x60,
29*47151e4bSgaurav rana 		0x86, 0x48, 0x01, 0x65,	0x03, 0x04, 0x02, 0x01, 0x05, 0x00,
30*47151e4bSgaurav rana 		0x04, 0x20
31*47151e4bSgaurav rana 		};
32*47151e4bSgaurav rana 
33*47151e4bSgaurav rana static u8 hash_val[SHA256_BYTES];
34*47151e4bSgaurav rana static const u8 barker_code[ESBC_BARKER_LEN] = { 0x68, 0x39, 0x27, 0x81 };
35*47151e4bSgaurav rana 
36*47151e4bSgaurav rana void branch_to_self(void) __attribute__ ((noreturn));
37*47151e4bSgaurav rana 
38*47151e4bSgaurav rana /*
39*47151e4bSgaurav rana  * This function will put core in infinite loop.
40*47151e4bSgaurav rana  * This will be called when the ESBC can not proceed further due
41*47151e4bSgaurav rana  * to some unknown errors.
42*47151e4bSgaurav rana  */
43*47151e4bSgaurav rana void branch_to_self(void)
44*47151e4bSgaurav rana {
45*47151e4bSgaurav rana 	printf("Core is in infinite loop due to errors.\n");
46*47151e4bSgaurav rana self:
47*47151e4bSgaurav rana 	goto self;
48*47151e4bSgaurav rana }
49*47151e4bSgaurav rana 
50*47151e4bSgaurav rana #if defined(CONFIG_FSL_ISBC_KEY_EXT)
51*47151e4bSgaurav rana static u32 check_ie(struct fsl_secboot_img_priv *img)
52*47151e4bSgaurav rana {
53*47151e4bSgaurav rana 	if (img->hdr.ie_flag)
54*47151e4bSgaurav rana 		return 1;
55*47151e4bSgaurav rana 
56*47151e4bSgaurav rana 	return 0;
57*47151e4bSgaurav rana }
58*47151e4bSgaurav rana 
59*47151e4bSgaurav rana /* This function returns the CSF Header Address of uboot
60*47151e4bSgaurav rana  * For MPC85xx based platforms, the LAW mapping for NOR
61*47151e4bSgaurav rana  * flash changes in uboot code. Hence the offset needs
62*47151e4bSgaurav rana  * to be calculated and added to the new NOR flash base
63*47151e4bSgaurav rana  * address
64*47151e4bSgaurav rana  */
65*47151e4bSgaurav rana #if defined(CONFIG_MPC85xx)
66*47151e4bSgaurav rana int get_csf_base_addr(ulong *csf_addr, ulong *flash_base_addr)
67*47151e4bSgaurav rana {
68*47151e4bSgaurav rana 	struct ccsr_gur __iomem *gur = (void *)(CONFIG_SYS_MPC85xx_GUTS_ADDR);
69*47151e4bSgaurav rana 	u32 csf_hdr_addr = in_be32(&gur->scratchrw[0]);
70*47151e4bSgaurav rana 	u32 csf_flash_offset = csf_hdr_addr & ~(CONFIG_SYS_PBI_FLASH_BASE);
71*47151e4bSgaurav rana 	ulong flash_addr, addr;
72*47151e4bSgaurav rana 	int found = 0;
73*47151e4bSgaurav rana 	int i = 0;
74*47151e4bSgaurav rana 
75*47151e4bSgaurav rana 	for (i = 0; i < CONFIG_SYS_MAX_FLASH_BANKS; i++) {
76*47151e4bSgaurav rana 		flash_addr = flash_info[i].start[0];
77*47151e4bSgaurav rana 		addr = flash_info[i].start[0] + csf_flash_offset;
78*47151e4bSgaurav rana 		if (memcmp((u8 *)addr, barker_code, ESBC_BARKER_LEN) == 0) {
79*47151e4bSgaurav rana 			debug("Barker found on addr %lx\n", addr);
80*47151e4bSgaurav rana 			found = 1;
81*47151e4bSgaurav rana 			break;
82*47151e4bSgaurav rana 		}
83*47151e4bSgaurav rana 	}
84*47151e4bSgaurav rana 
85*47151e4bSgaurav rana 	if (!found)
86*47151e4bSgaurav rana 		return -1;
87*47151e4bSgaurav rana 
88*47151e4bSgaurav rana 	*csf_addr = addr;
89*47151e4bSgaurav rana 	*flash_base_addr = flash_addr;
90*47151e4bSgaurav rana 
91*47151e4bSgaurav rana 	return 0;
92*47151e4bSgaurav rana }
93*47151e4bSgaurav rana #else
94*47151e4bSgaurav rana /* For platforms like LS1020, correct flash address is present in
95*47151e4bSgaurav rana  * the header. So the function reqturns flash base address as 0
96*47151e4bSgaurav rana  */
97*47151e4bSgaurav rana int get_csf_base_addr(ulong *csf_addr, ulong *flash_base_addr)
98*47151e4bSgaurav rana {
99*47151e4bSgaurav rana 	struct ccsr_gur __iomem *gur = (void *)(CONFIG_SYS_FSL_GUTS_ADDR);
100*47151e4bSgaurav rana 	u32 csf_hdr_addr = in_be32(&gur->scratchrw[0]);
101*47151e4bSgaurav rana 
102*47151e4bSgaurav rana 	if (memcmp((u8 *)csf_hdr_addr, barker_code, ESBC_BARKER_LEN))
103*47151e4bSgaurav rana 		return -1;
104*47151e4bSgaurav rana 
105*47151e4bSgaurav rana 	*csf_addr = csf_hdr_addr;
106*47151e4bSgaurav rana 	*flash_base_addr = 0;
107*47151e4bSgaurav rana 	return 0;
108*47151e4bSgaurav rana }
109*47151e4bSgaurav rana #endif
110*47151e4bSgaurav rana 
111*47151e4bSgaurav rana static int get_ie_info_addr(ulong *ie_addr)
112*47151e4bSgaurav rana {
113*47151e4bSgaurav rana 	struct fsl_secboot_img_hdr *hdr;
114*47151e4bSgaurav rana 	struct fsl_secboot_sg_table *sg_tbl;
115*47151e4bSgaurav rana 	ulong flash_base_addr, csf_addr;
116*47151e4bSgaurav rana 
117*47151e4bSgaurav rana 	if (get_csf_base_addr(&csf_addr, &flash_base_addr))
118*47151e4bSgaurav rana 		return -1;
119*47151e4bSgaurav rana 
120*47151e4bSgaurav rana 	hdr = (struct fsl_secboot_img_hdr *)csf_addr;
121*47151e4bSgaurav rana 
122*47151e4bSgaurav rana 	/* For SoC's with Trust Architecture v1 with corenet bus
123*47151e4bSgaurav rana 	 * the sg table field in CSF header has absolute address
124*47151e4bSgaurav rana 	 * for sg table in memory. In other Trust Architecture,
125*47151e4bSgaurav rana 	 * this field specifies the offset of sg table from the
126*47151e4bSgaurav rana 	 * base address of CSF Header
127*47151e4bSgaurav rana 	 */
128*47151e4bSgaurav rana #if defined(CONFIG_FSL_TRUST_ARCH_v1) && defined(CONFIG_FSL_CORENET)
129*47151e4bSgaurav rana 	sg_tbl = (struct fsl_secboot_sg_table *)
130*47151e4bSgaurav rana 		 (((ulong)hdr->psgtable & ~(CONFIG_SYS_PBI_FLASH_BASE)) +
131*47151e4bSgaurav rana 		  flash_base_addr);
132*47151e4bSgaurav rana #else
133*47151e4bSgaurav rana 	sg_tbl = (struct fsl_secboot_sg_table *)(csf_addr +
134*47151e4bSgaurav rana 						 (ulong)hdr->psgtable);
135*47151e4bSgaurav rana #endif
136*47151e4bSgaurav rana 
137*47151e4bSgaurav rana 	/* IE Key Table is the first entry in the SG Table */
138*47151e4bSgaurav rana #if defined(CONFIG_MPC85xx)
139*47151e4bSgaurav rana 	*ie_addr = (sg_tbl->src_addr & ~(CONFIG_SYS_PBI_FLASH_BASE)) +
140*47151e4bSgaurav rana 		   flash_base_addr;
141*47151e4bSgaurav rana #else
142*47151e4bSgaurav rana 	*ie_addr = sg_tbl->src_addr;
143*47151e4bSgaurav rana #endif
144*47151e4bSgaurav rana 
145*47151e4bSgaurav rana 	debug("IE Table address is %lx\n", *ie_addr);
146*47151e4bSgaurav rana 	return 0;
147*47151e4bSgaurav rana }
148*47151e4bSgaurav rana 
149*47151e4bSgaurav rana #endif
150*47151e4bSgaurav rana 
151*47151e4bSgaurav rana #ifdef CONFIG_KEY_REVOCATION
152*47151e4bSgaurav rana /* This function checks srk_table_flag in header and set/reset srk_flag.*/
153*47151e4bSgaurav rana static u32 check_srk(struct fsl_secboot_img_priv *img)
154*47151e4bSgaurav rana {
155*47151e4bSgaurav rana 	if (img->hdr.len_kr.srk_table_flag & SRK_FLAG)
156*47151e4bSgaurav rana 		return 1;
157*47151e4bSgaurav rana 
158*47151e4bSgaurav rana 	return 0;
159*47151e4bSgaurav rana }
160*47151e4bSgaurav rana 
161*47151e4bSgaurav rana /* This function returns ospr's key_revoc values.*/
162*47151e4bSgaurav rana static u32 get_key_revoc(void)
163*47151e4bSgaurav rana {
164*47151e4bSgaurav rana 	struct ccsr_sfp_regs *sfp_regs = (void *)(CONFIG_SYS_SFP_ADDR);
165*47151e4bSgaurav rana 	return (sfp_in32(&sfp_regs->ospr) & OSPR_KEY_REVOC_MASK) >>
166*47151e4bSgaurav rana 		OSPR_KEY_REVOC_SHIFT;
167*47151e4bSgaurav rana }
168*47151e4bSgaurav rana 
169*47151e4bSgaurav rana /* This function checks if selected key is revoked or not.*/
170*47151e4bSgaurav rana static u32 is_key_revoked(u32 keynum, u32 rev_flag)
171*47151e4bSgaurav rana {
172*47151e4bSgaurav rana 	if (keynum == UNREVOCABLE_KEY)
173*47151e4bSgaurav rana 		return 0;
174*47151e4bSgaurav rana 
175*47151e4bSgaurav rana 	if ((u32)(1 << (ALIGN_REVOC_KEY - keynum)) & rev_flag)
176*47151e4bSgaurav rana 		return 1;
177*47151e4bSgaurav rana 
178*47151e4bSgaurav rana 	return 0;
179*47151e4bSgaurav rana }
180*47151e4bSgaurav rana 
181*47151e4bSgaurav rana /* It validates srk_table key lengths.*/
182*47151e4bSgaurav rana static u32 validate_srk_tbl(struct srk_table *tbl, u32 num_entries)
183*47151e4bSgaurav rana {
184*47151e4bSgaurav rana 	int i = 0;
185*47151e4bSgaurav rana 	for (i = 0; i < num_entries; i++) {
186*47151e4bSgaurav rana 		if (!((tbl[i].key_len == 2 * KEY_SIZE_BYTES/4) ||
187*47151e4bSgaurav rana 		      (tbl[i].key_len == 2 * KEY_SIZE_BYTES/2) ||
188*47151e4bSgaurav rana 		      (tbl[i].key_len == 2 * KEY_SIZE_BYTES)))
189*47151e4bSgaurav rana 			return ERROR_ESBC_CLIENT_HEADER_INV_SRK_ENTRY_KEYLEN;
190*47151e4bSgaurav rana 	}
191*47151e4bSgaurav rana 	return 0;
192*47151e4bSgaurav rana }
193*47151e4bSgaurav rana #endif
194*47151e4bSgaurav rana 
195*47151e4bSgaurav rana /* This function return length of public key.*/
196*47151e4bSgaurav rana static inline u32 get_key_len(struct fsl_secboot_img_priv *img)
197*47151e4bSgaurav rana {
198*47151e4bSgaurav rana 	return img->key_len;
199*47151e4bSgaurav rana }
200*47151e4bSgaurav rana 
201*47151e4bSgaurav rana /*
202*47151e4bSgaurav rana  * Handles the ESBC uboot client header verification failure.
203*47151e4bSgaurav rana  * This  function  handles all the errors which might occur in the
204*47151e4bSgaurav rana  * parsing and checking of ESBC uboot client header. It will also
205*47151e4bSgaurav rana  * set the error bits in the SEC_MON.
206*47151e4bSgaurav rana  */
207*47151e4bSgaurav rana static void fsl_secboot_header_verification_failure(void)
208*47151e4bSgaurav rana {
209*47151e4bSgaurav rana 	struct ccsr_sec_mon_regs *sec_mon_regs = (void *)
210*47151e4bSgaurav rana 						(CONFIG_SYS_SEC_MON_ADDR);
211*47151e4bSgaurav rana 	struct ccsr_sfp_regs *sfp_regs = (void *)(CONFIG_SYS_SFP_ADDR);
212*47151e4bSgaurav rana 	u32 sts = sec_mon_in32(&sec_mon_regs->hp_stat);
213*47151e4bSgaurav rana 
214*47151e4bSgaurav rana 	/* 29th bit of OSPR is ITS */
215*47151e4bSgaurav rana 	u32 its = sfp_in32(&sfp_regs->ospr) >> 2;
216*47151e4bSgaurav rana 
217*47151e4bSgaurav rana 	/*
218*47151e4bSgaurav rana 	 * Read the SEC_MON status register
219*47151e4bSgaurav rana 	 * Read SSM_ST field
220*47151e4bSgaurav rana 	 */
221*47151e4bSgaurav rana 	sts = sec_mon_in32(&sec_mon_regs->hp_stat);
222*47151e4bSgaurav rana 	if ((sts & HPSR_SSM_ST_MASK) == HPSR_SSM_ST_TRUST) {
223*47151e4bSgaurav rana 		if (its == 1)
224*47151e4bSgaurav rana 			change_sec_mon_state(HPSR_SSM_ST_TRUST,
225*47151e4bSgaurav rana 					     HPSR_SSM_ST_SOFT_FAIL);
226*47151e4bSgaurav rana 		else
227*47151e4bSgaurav rana 			change_sec_mon_state(HPSR_SSM_ST_TRUST,
228*47151e4bSgaurav rana 					     HPSR_SSM_ST_NON_SECURE);
229*47151e4bSgaurav rana 	}
230*47151e4bSgaurav rana 
231*47151e4bSgaurav rana 	printf("Generating reset request\n");
232*47151e4bSgaurav rana 	do_reset(NULL, 0, 0, NULL);
233*47151e4bSgaurav rana }
234*47151e4bSgaurav rana 
235*47151e4bSgaurav rana /*
236*47151e4bSgaurav rana  * Handles the ESBC uboot client image verification failure.
237*47151e4bSgaurav rana  * This  function  handles all the errors which might occur in the
238*47151e4bSgaurav rana  * public key hash comparison and signature verification of
239*47151e4bSgaurav rana  * ESBC uboot client image. It will also
240*47151e4bSgaurav rana  * set the error bits in the SEC_MON.
241*47151e4bSgaurav rana  */
242*47151e4bSgaurav rana static void fsl_secboot_image_verification_failure(void)
243*47151e4bSgaurav rana {
244*47151e4bSgaurav rana 	struct ccsr_sec_mon_regs *sec_mon_regs = (void *)
245*47151e4bSgaurav rana 						(CONFIG_SYS_SEC_MON_ADDR);
246*47151e4bSgaurav rana 	struct ccsr_sfp_regs *sfp_regs = (void *)(CONFIG_SYS_SFP_ADDR);
247*47151e4bSgaurav rana 	u32 sts = sec_mon_in32(&sec_mon_regs->hp_stat);
248*47151e4bSgaurav rana 
249*47151e4bSgaurav rana 	u32 its = sfp_in32(&sfp_regs->ospr) & ITS_MASK >> ITS_BIT;
250*47151e4bSgaurav rana 
251*47151e4bSgaurav rana 	/*
252*47151e4bSgaurav rana 	 * Read the SEC_MON status register
253*47151e4bSgaurav rana 	 * Read SSM_ST field
254*47151e4bSgaurav rana 	 */
255*47151e4bSgaurav rana 	sts = sec_mon_in32(&sec_mon_regs->hp_stat);
256*47151e4bSgaurav rana 	if ((sts & HPSR_SSM_ST_MASK) == HPSR_SSM_ST_TRUST) {
257*47151e4bSgaurav rana 		if (its == 1) {
258*47151e4bSgaurav rana 			change_sec_mon_state(HPSR_SSM_ST_TRUST,
259*47151e4bSgaurav rana 					     HPSR_SSM_ST_SOFT_FAIL);
260*47151e4bSgaurav rana 
261*47151e4bSgaurav rana 			printf("Generating reset request\n");
262*47151e4bSgaurav rana 			do_reset(NULL, 0, 0, NULL);
263*47151e4bSgaurav rana 		} else {
264*47151e4bSgaurav rana 			change_sec_mon_state(HPSR_SSM_ST_TRUST,
265*47151e4bSgaurav rana 					     HPSR_SSM_ST_NON_SECURE);
266*47151e4bSgaurav rana 		}
267*47151e4bSgaurav rana 	}
268*47151e4bSgaurav rana }
269*47151e4bSgaurav rana 
270*47151e4bSgaurav rana static void fsl_secboot_bootscript_parse_failure(void)
271*47151e4bSgaurav rana {
272*47151e4bSgaurav rana 	fsl_secboot_header_verification_failure();
273*47151e4bSgaurav rana }
274*47151e4bSgaurav rana 
275*47151e4bSgaurav rana /*
276*47151e4bSgaurav rana  * Handles the errors in esbc boot.
277*47151e4bSgaurav rana  * This  function  handles all the errors which might occur in the
278*47151e4bSgaurav rana  * esbc boot phase. It will call the appropriate api to log the
279*47151e4bSgaurav rana  * errors and set the error bits in the SEC_MON.
280*47151e4bSgaurav rana  */
281*47151e4bSgaurav rana void fsl_secboot_handle_error(int error)
282*47151e4bSgaurav rana {
283*47151e4bSgaurav rana 	const struct fsl_secboot_errcode *e;
284*47151e4bSgaurav rana 
285*47151e4bSgaurav rana 	for (e = fsl_secboot_errcodes; e->errcode != ERROR_ESBC_CLIENT_MAX;
286*47151e4bSgaurav rana 		e++) {
287*47151e4bSgaurav rana 		if (e->errcode == error)
288*47151e4bSgaurav rana 			printf("ERROR :: %x :: %s\n", error, e->name);
289*47151e4bSgaurav rana 	}
290*47151e4bSgaurav rana 
291*47151e4bSgaurav rana 	switch (error) {
292*47151e4bSgaurav rana 	case ERROR_ESBC_CLIENT_HEADER_BARKER:
293*47151e4bSgaurav rana 	case ERROR_ESBC_CLIENT_HEADER_IMG_SIZE:
294*47151e4bSgaurav rana 	case ERROR_ESBC_CLIENT_HEADER_KEY_LEN:
295*47151e4bSgaurav rana 	case ERROR_ESBC_CLIENT_HEADER_SIG_LEN:
296*47151e4bSgaurav rana 	case ERROR_ESBC_CLIENT_HEADER_KEY_LEN_NOT_TWICE_SIG_LEN:
297*47151e4bSgaurav rana 	case ERROR_ESBC_CLIENT_HEADER_KEY_MOD_1:
298*47151e4bSgaurav rana 	case ERROR_ESBC_CLIENT_HEADER_KEY_MOD_2:
299*47151e4bSgaurav rana 	case ERROR_ESBC_CLIENT_HEADER_SIG_KEY_MOD:
300*47151e4bSgaurav rana 	case ERROR_ESBC_CLIENT_HEADER_SG_ESBC_EP:
301*47151e4bSgaurav rana 	case ERROR_ESBC_CLIENT_HEADER_SG_ENTIRES_BAD:
302*47151e4bSgaurav rana #ifdef CONFIG_KEY_REVOCATION
303*47151e4bSgaurav rana 	case ERROR_ESBC_CLIENT_HEADER_KEY_REVOKED:
304*47151e4bSgaurav rana 	case ERROR_ESBC_CLIENT_HEADER_INVALID_SRK_NUM_ENTRY:
305*47151e4bSgaurav rana 	case ERROR_ESBC_CLIENT_HEADER_INVALID_KEY_NUM:
306*47151e4bSgaurav rana 	case ERROR_ESBC_CLIENT_HEADER_INV_SRK_ENTRY_KEYLEN:
307*47151e4bSgaurav rana #endif
308*47151e4bSgaurav rana #if defined(CONFIG_FSL_ISBC_KEY_EXT)
309*47151e4bSgaurav rana 	/*@fallthrough@*/
310*47151e4bSgaurav rana 	case ERROR_ESBC_CLIENT_HEADER_IE_KEY_REVOKED:
311*47151e4bSgaurav rana 	case ERROR_ESBC_CLIENT_HEADER_INVALID_IE_NUM_ENTRY:
312*47151e4bSgaurav rana 	case ERROR_ESBC_CLIENT_HEADER_INVALID_IE_KEY_NUM:
313*47151e4bSgaurav rana 	case ERROR_ESBC_CLIENT_HEADER_INV_IE_ENTRY_KEYLEN:
314*47151e4bSgaurav rana 	case ERROR_IE_TABLE_NOT_FOUND:
315*47151e4bSgaurav rana #endif
316*47151e4bSgaurav rana 		fsl_secboot_header_verification_failure();
317*47151e4bSgaurav rana 		break;
318*47151e4bSgaurav rana 	case ERROR_ESBC_SEC_RESET:
319*47151e4bSgaurav rana 	case ERROR_ESBC_SEC_DEQ:
320*47151e4bSgaurav rana 	case ERROR_ESBC_SEC_ENQ:
321*47151e4bSgaurav rana 	case ERROR_ESBC_SEC_DEQ_TO:
322*47151e4bSgaurav rana 	case ERROR_ESBC_SEC_JOBQ_STATUS:
323*47151e4bSgaurav rana 	case ERROR_ESBC_CLIENT_HASH_COMPARE_KEY:
324*47151e4bSgaurav rana 	case ERROR_ESBC_CLIENT_HASH_COMPARE_EM:
325*47151e4bSgaurav rana 		fsl_secboot_image_verification_failure();
326*47151e4bSgaurav rana 		break;
327*47151e4bSgaurav rana 	case ERROR_ESBC_MISSING_BOOTM:
328*47151e4bSgaurav rana 		fsl_secboot_bootscript_parse_failure();
329*47151e4bSgaurav rana 		break;
330*47151e4bSgaurav rana 	case ERROR_ESBC_WRONG_CMD:
331*47151e4bSgaurav rana 	default:
332*47151e4bSgaurav rana 		branch_to_self();
333*47151e4bSgaurav rana 		break;
334*47151e4bSgaurav rana 	}
335*47151e4bSgaurav rana }
336*47151e4bSgaurav rana 
337*47151e4bSgaurav rana static void fsl_secblk_handle_error(int error)
338*47151e4bSgaurav rana {
339*47151e4bSgaurav rana 	switch (error) {
340*47151e4bSgaurav rana 	case ERROR_ESBC_SEC_ENQ:
341*47151e4bSgaurav rana 		fsl_secboot_handle_error(ERROR_ESBC_SEC_ENQ);
342*47151e4bSgaurav rana 		break;
343*47151e4bSgaurav rana 	case ERROR_ESBC_SEC_DEQ:
344*47151e4bSgaurav rana 		fsl_secboot_handle_error(ERROR_ESBC_SEC_DEQ);
345*47151e4bSgaurav rana 		break;
346*47151e4bSgaurav rana 	case ERROR_ESBC_SEC_DEQ_TO:
347*47151e4bSgaurav rana 		fsl_secboot_handle_error(ERROR_ESBC_SEC_DEQ_TO);
348*47151e4bSgaurav rana 		break;
349*47151e4bSgaurav rana 	default:
350*47151e4bSgaurav rana 		printf("Job Queue Output status %x\n", error);
351*47151e4bSgaurav rana 		fsl_secboot_handle_error(ERROR_ESBC_SEC_JOBQ_STATUS);
352*47151e4bSgaurav rana 		break;
353*47151e4bSgaurav rana 	}
354*47151e4bSgaurav rana }
355*47151e4bSgaurav rana 
356*47151e4bSgaurav rana /*
357*47151e4bSgaurav rana  * Calculate hash of key obtained via offset present in ESBC uboot
358*47151e4bSgaurav rana  * client hdr. This function calculates the hash of key which is obtained
359*47151e4bSgaurav rana  * through offset present in ESBC uboot client header.
360*47151e4bSgaurav rana  */
361*47151e4bSgaurav rana static int calc_img_key_hash(struct fsl_secboot_img_priv *img)
362*47151e4bSgaurav rana {
363*47151e4bSgaurav rana 	struct hash_algo *algo;
364*47151e4bSgaurav rana 	void *ctx;
365*47151e4bSgaurav rana 	int i, srk = 0;
366*47151e4bSgaurav rana 	int ret = 0;
367*47151e4bSgaurav rana 	const char *algo_name = "sha256";
368*47151e4bSgaurav rana 
369*47151e4bSgaurav rana 	/* Calculate hash of the esbc key */
370*47151e4bSgaurav rana 	ret = hash_progressive_lookup_algo(algo_name, &algo);
371*47151e4bSgaurav rana 	if (ret)
372*47151e4bSgaurav rana 		return ret;
373*47151e4bSgaurav rana 
374*47151e4bSgaurav rana 	ret = algo->hash_init(algo, &ctx);
375*47151e4bSgaurav rana 	if (ret)
376*47151e4bSgaurav rana 		return ret;
377*47151e4bSgaurav rana 
378*47151e4bSgaurav rana 	/* Update hash for ESBC key */
379*47151e4bSgaurav rana #ifdef CONFIG_KEY_REVOCATION
380*47151e4bSgaurav rana 	if (check_srk(img)) {
381*47151e4bSgaurav rana 		ret = algo->hash_update(algo, ctx,
382*47151e4bSgaurav rana 			(u8 *)(img->ehdrloc + img->hdr.srk_tbl_off),
383*47151e4bSgaurav rana 			img->hdr.len_kr.num_srk * sizeof(struct srk_table), 1);
384*47151e4bSgaurav rana 		srk = 1;
385*47151e4bSgaurav rana 	}
386*47151e4bSgaurav rana #endif
387*47151e4bSgaurav rana 	if (!srk)
388*47151e4bSgaurav rana 		ret = algo->hash_update(algo, ctx,
389*47151e4bSgaurav rana 			img->img_key, img->key_len, 1);
390*47151e4bSgaurav rana 	if (ret)
391*47151e4bSgaurav rana 		return ret;
392*47151e4bSgaurav rana 
393*47151e4bSgaurav rana 	/* Copy hash at destination buffer */
394*47151e4bSgaurav rana 	ret = algo->hash_finish(algo, ctx, hash_val, algo->digest_size);
395*47151e4bSgaurav rana 	if (ret)
396*47151e4bSgaurav rana 		return ret;
397*47151e4bSgaurav rana 
398*47151e4bSgaurav rana 	for (i = 0; i < SHA256_BYTES; i++)
399*47151e4bSgaurav rana 		img->img_key_hash[i] = hash_val[i];
400*47151e4bSgaurav rana 
401*47151e4bSgaurav rana 	return 0;
402*47151e4bSgaurav rana }
403*47151e4bSgaurav rana 
404*47151e4bSgaurav rana /*
405*47151e4bSgaurav rana  * Calculate hash of ESBC hdr and ESBC. This function calculates the
406*47151e4bSgaurav rana  * single hash of ESBC header and ESBC image. If SG flag is on, all
407*47151e4bSgaurav rana  * SG entries are also hashed alongwith the complete SG table.
408*47151e4bSgaurav rana  */
409*47151e4bSgaurav rana static int calc_esbchdr_esbc_hash(struct fsl_secboot_img_priv *img)
410*47151e4bSgaurav rana {
411*47151e4bSgaurav rana 	struct hash_algo *algo;
412*47151e4bSgaurav rana 	void *ctx;
413*47151e4bSgaurav rana 	int ret = 0;
414*47151e4bSgaurav rana 	int key_hash = 0;
415*47151e4bSgaurav rana 	const char *algo_name = "sha256";
416*47151e4bSgaurav rana 
417*47151e4bSgaurav rana 	/* Calculate the hash of the ESBC */
418*47151e4bSgaurav rana 	ret = hash_progressive_lookup_algo(algo_name, &algo);
419*47151e4bSgaurav rana 	if (ret)
420*47151e4bSgaurav rana 		return ret;
421*47151e4bSgaurav rana 
422*47151e4bSgaurav rana 	ret = algo->hash_init(algo, &ctx);
423*47151e4bSgaurav rana 	/* Copy hash at destination buffer */
424*47151e4bSgaurav rana 	if (ret)
425*47151e4bSgaurav rana 		return ret;
426*47151e4bSgaurav rana 
427*47151e4bSgaurav rana 	/* Update hash for CSF Header */
428*47151e4bSgaurav rana 	ret = algo->hash_update(algo, ctx,
429*47151e4bSgaurav rana 		(u8 *)&img->hdr, sizeof(struct fsl_secboot_img_hdr), 0);
430*47151e4bSgaurav rana 	if (ret)
431*47151e4bSgaurav rana 		return ret;
432*47151e4bSgaurav rana 
433*47151e4bSgaurav rana 	/* Update the hash with that of srk table if srk flag is 1
434*47151e4bSgaurav rana 	 * If IE Table is selected, key is not added in the hash
435*47151e4bSgaurav rana 	 * If neither srk table nor IE key table available, add key
436*47151e4bSgaurav rana 	 * from header in the hash calculation
437*47151e4bSgaurav rana 	 */
438*47151e4bSgaurav rana #ifdef CONFIG_KEY_REVOCATION
439*47151e4bSgaurav rana 	if (check_srk(img)) {
440*47151e4bSgaurav rana 		ret = algo->hash_update(algo, ctx,
441*47151e4bSgaurav rana 			(u8 *)(img->ehdrloc + img->hdr.srk_tbl_off),
442*47151e4bSgaurav rana 			img->hdr.len_kr.num_srk * sizeof(struct srk_table), 0);
443*47151e4bSgaurav rana 		key_hash = 1;
444*47151e4bSgaurav rana 	}
445*47151e4bSgaurav rana #endif
446*47151e4bSgaurav rana #if defined(CONFIG_FSL_ISBC_KEY_EXT)
447*47151e4bSgaurav rana 	if (!key_hash && check_ie(img))
448*47151e4bSgaurav rana 		key_hash = 1;
449*47151e4bSgaurav rana #endif
450*47151e4bSgaurav rana 	if (!key_hash)
451*47151e4bSgaurav rana 		ret = algo->hash_update(algo, ctx,
452*47151e4bSgaurav rana 			img->img_key, img->hdr.key_len, 0);
453*47151e4bSgaurav rana 	if (ret)
454*47151e4bSgaurav rana 		return ret;
455*47151e4bSgaurav rana 
456*47151e4bSgaurav rana 	/* Update hash for actual Image */
457*47151e4bSgaurav rana 	ret = algo->hash_update(algo, ctx,
458*47151e4bSgaurav rana 			(u8 *)img->hdr.pimg, img->hdr.img_size, 1);
459*47151e4bSgaurav rana 	if (ret)
460*47151e4bSgaurav rana 		return ret;
461*47151e4bSgaurav rana 
462*47151e4bSgaurav rana 	/* Copy hash at destination buffer */
463*47151e4bSgaurav rana 	ret = algo->hash_finish(algo, ctx, hash_val, algo->digest_size);
464*47151e4bSgaurav rana 	if (ret)
465*47151e4bSgaurav rana 		return ret;
466*47151e4bSgaurav rana 
467*47151e4bSgaurav rana 	return 0;
468*47151e4bSgaurav rana }
469*47151e4bSgaurav rana 
470*47151e4bSgaurav rana /*
471*47151e4bSgaurav rana  * Construct encoded hash EM' wrt PKCSv1.5. This function calculates the
472*47151e4bSgaurav rana  * pointers for padding, DER value and hash. And finally, constructs EM'
473*47151e4bSgaurav rana  * which includes hash of complete CSF header and ESBC image. If SG flag
474*47151e4bSgaurav rana  * is on, hash of SG table and entries is also included.
475*47151e4bSgaurav rana  */
476*47151e4bSgaurav rana static void construct_img_encoded_hash_second(struct fsl_secboot_img_priv *img)
477*47151e4bSgaurav rana {
478*47151e4bSgaurav rana 	/*
479*47151e4bSgaurav rana 	 * RSA PKCSv1.5 encoding format for encoded message is below
480*47151e4bSgaurav rana 	 * EM = 0x0 || 0x1 || PS || 0x0 || DER || Hash
481*47151e4bSgaurav rana 	 * PS is Padding String
482*47151e4bSgaurav rana 	 * DER is DER value for SHA-256
483*47151e4bSgaurav rana 	 * Hash is SHA-256 hash
484*47151e4bSgaurav rana 	 * *********************************************************
485*47151e4bSgaurav rana 	 * representative points to first byte of EM initially and is
486*47151e4bSgaurav rana 	 * filled with 0x0
487*47151e4bSgaurav rana 	 * representative is incremented by 1 and second byte is filled
488*47151e4bSgaurav rana 	 * with 0x1
489*47151e4bSgaurav rana 	 * padding points to third byte of EM
490*47151e4bSgaurav rana 	 * digest points to full length of EM - 32 bytes
491*47151e4bSgaurav rana 	 * hash_id (DER value) points to 19 bytes before pDigest
492*47151e4bSgaurav rana 	 * separator is one byte which separates padding and DER
493*47151e4bSgaurav rana 	 */
494*47151e4bSgaurav rana 
495*47151e4bSgaurav rana 	size_t len;
496*47151e4bSgaurav rana 	u8 *representative;
497*47151e4bSgaurav rana 	u8 *padding, *digest;
498*47151e4bSgaurav rana 	u8 *hash_id, *separator;
499*47151e4bSgaurav rana 	int i;
500*47151e4bSgaurav rana 
501*47151e4bSgaurav rana 	len = (get_key_len(img) / 2) - 1;
502*47151e4bSgaurav rana 	representative = img->img_encoded_hash_second;
503*47151e4bSgaurav rana 	representative[0] = 0;
504*47151e4bSgaurav rana 	representative[1] = 1;  /* block type 1 */
505*47151e4bSgaurav rana 
506*47151e4bSgaurav rana 	padding = &representative[2];
507*47151e4bSgaurav rana 	digest = &representative[1] + len - 32;
508*47151e4bSgaurav rana 	hash_id = digest - sizeof(hash_identifier);
509*47151e4bSgaurav rana 	separator = hash_id - 1;
510*47151e4bSgaurav rana 
511*47151e4bSgaurav rana 	/* fill padding area pointed by padding with 0xff */
512*47151e4bSgaurav rana 	memset(padding, 0xff, separator - padding);
513*47151e4bSgaurav rana 
514*47151e4bSgaurav rana 	/* fill byte pointed by separator */
515*47151e4bSgaurav rana 	*separator = 0;
516*47151e4bSgaurav rana 
517*47151e4bSgaurav rana 	/* fill SHA-256 DER value  pointed by HashId */
518*47151e4bSgaurav rana 	memcpy(hash_id, hash_identifier, sizeof(hash_identifier));
519*47151e4bSgaurav rana 
520*47151e4bSgaurav rana 	/* fill hash pointed by Digest */
521*47151e4bSgaurav rana 	for (i = 0; i < SHA256_BYTES; i++)
522*47151e4bSgaurav rana 		digest[i] = hash_val[i];
523*47151e4bSgaurav rana }
524*47151e4bSgaurav rana 
525*47151e4bSgaurav rana /*
526*47151e4bSgaurav rana  * Reads and validates the ESBC client header.
527*47151e4bSgaurav rana  * This function reads key and signature from the ESBC client header.
528*47151e4bSgaurav rana  * If Scatter/Gather flag is on, lengths and offsets of images
529*47151e4bSgaurav rana  * present as SG entries are also read. This function also checks
530*47151e4bSgaurav rana  * whether the header is valid or not.
531*47151e4bSgaurav rana  */
532*47151e4bSgaurav rana static int read_validate_esbc_client_header(struct fsl_secboot_img_priv *img)
533*47151e4bSgaurav rana {
534*47151e4bSgaurav rana 	char buf[20];
535*47151e4bSgaurav rana 	struct fsl_secboot_img_hdr *hdr = &img->hdr;
536*47151e4bSgaurav rana 	void *esbc = (u8 *)img->ehdrloc;
537*47151e4bSgaurav rana 	u8 *k, *s;
538*47151e4bSgaurav rana #ifdef CONFIG_KEY_REVOCATION
539*47151e4bSgaurav rana 	u32 ret;
540*47151e4bSgaurav rana 	u32 key_num, key_revoc_flag, size;
541*47151e4bSgaurav rana #endif
542*47151e4bSgaurav rana #if defined(CONFIG_FSL_ISBC_KEY_EXT)
543*47151e4bSgaurav rana 	struct ie_key_info *ie_info;
544*47151e4bSgaurav rana 	u32 ie_num, ie_revoc_flag, ie_key_len;
545*47151e4bSgaurav rana #endif
546*47151e4bSgaurav rana 	int  key_found = 0;
547*47151e4bSgaurav rana 
548*47151e4bSgaurav rana 	/* check barker code */
549*47151e4bSgaurav rana 	if (memcmp(hdr->barker, barker_code, ESBC_BARKER_LEN))
550*47151e4bSgaurav rana 		return ERROR_ESBC_CLIENT_HEADER_BARKER;
551*47151e4bSgaurav rana 
552*47151e4bSgaurav rana 	sprintf(buf, "%p", hdr->pimg);
553*47151e4bSgaurav rana 	setenv("img_addr", buf);
554*47151e4bSgaurav rana 
555*47151e4bSgaurav rana 	if (!hdr->img_size)
556*47151e4bSgaurav rana 		return ERROR_ESBC_CLIENT_HEADER_IMG_SIZE;
557*47151e4bSgaurav rana 
558*47151e4bSgaurav rana 	/* Key checking*/
559*47151e4bSgaurav rana #ifdef CONFIG_KEY_REVOCATION
560*47151e4bSgaurav rana 	if (check_srk(img)) {
561*47151e4bSgaurav rana 		if ((hdr->len_kr.num_srk == 0) ||
562*47151e4bSgaurav rana 		    (hdr->len_kr.num_srk > MAX_KEY_ENTRIES))
563*47151e4bSgaurav rana 			return ERROR_ESBC_CLIENT_HEADER_INVALID_SRK_NUM_ENTRY;
564*47151e4bSgaurav rana 
565*47151e4bSgaurav rana 		key_num = hdr->len_kr.srk_sel;
566*47151e4bSgaurav rana 		if (key_num == 0 || key_num > hdr->len_kr.num_srk)
567*47151e4bSgaurav rana 			return ERROR_ESBC_CLIENT_HEADER_INVALID_KEY_NUM;
568*47151e4bSgaurav rana 
569*47151e4bSgaurav rana 		/* Get revoc key from sfp */
570*47151e4bSgaurav rana 		key_revoc_flag = get_key_revoc();
571*47151e4bSgaurav rana 		ret = is_key_revoked(key_num, key_revoc_flag);
572*47151e4bSgaurav rana 		if (ret)
573*47151e4bSgaurav rana 			return ERROR_ESBC_CLIENT_HEADER_KEY_REVOKED;
574*47151e4bSgaurav rana 
575*47151e4bSgaurav rana 		size = hdr->len_kr.num_srk * sizeof(struct srk_table);
576*47151e4bSgaurav rana 
577*47151e4bSgaurav rana 		memcpy(&img->srk_tbl, esbc + hdr->srk_tbl_off, size);
578*47151e4bSgaurav rana 
579*47151e4bSgaurav rana 		ret = validate_srk_tbl(img->srk_tbl, hdr->len_kr.num_srk);
580*47151e4bSgaurav rana 
581*47151e4bSgaurav rana 		if (ret != 0)
582*47151e4bSgaurav rana 			return ret;
583*47151e4bSgaurav rana 
584*47151e4bSgaurav rana 		img->key_len = img->srk_tbl[key_num - 1].key_len;
585*47151e4bSgaurav rana 
586*47151e4bSgaurav rana 		memcpy(&img->img_key, &(img->srk_tbl[key_num - 1].pkey),
587*47151e4bSgaurav rana 		       img->key_len);
588*47151e4bSgaurav rana 
589*47151e4bSgaurav rana 		key_found = 1;
590*47151e4bSgaurav rana 	}
591*47151e4bSgaurav rana #endif
592*47151e4bSgaurav rana 
593*47151e4bSgaurav rana #if defined(CONFIG_FSL_ISBC_KEY_EXT)
594*47151e4bSgaurav rana 	if (!key_found && check_ie(img)) {
595*47151e4bSgaurav rana 		if (get_ie_info_addr(&img->ie_addr))
596*47151e4bSgaurav rana 			return ERROR_IE_TABLE_NOT_FOUND;
597*47151e4bSgaurav rana 		ie_info = (struct ie_key_info *)img->ie_addr;
598*47151e4bSgaurav rana 		if (ie_info->num_keys == 0 || ie_info->num_keys > 32)
599*47151e4bSgaurav rana 			return ERROR_ESBC_CLIENT_HEADER_INVALID_IE_NUM_ENTRY;
600*47151e4bSgaurav rana 
601*47151e4bSgaurav rana 		ie_num = hdr->ie_key_sel;
602*47151e4bSgaurav rana 		if (ie_num == 0 || ie_num > ie_info->num_keys)
603*47151e4bSgaurav rana 			return ERROR_ESBC_CLIENT_HEADER_INVALID_IE_KEY_NUM;
604*47151e4bSgaurav rana 
605*47151e4bSgaurav rana 		ie_revoc_flag = ie_info->key_revok;
606*47151e4bSgaurav rana 		if ((u32)(1 << (ie_num - 1)) & ie_revoc_flag)
607*47151e4bSgaurav rana 			return ERROR_ESBC_CLIENT_HEADER_IE_KEY_REVOKED;
608*47151e4bSgaurav rana 
609*47151e4bSgaurav rana 		ie_key_len = ie_info->ie_key_tbl[ie_num - 1].key_len;
610*47151e4bSgaurav rana 
611*47151e4bSgaurav rana 		if (!((ie_key_len == 2 * KEY_SIZE_BYTES / 4) ||
612*47151e4bSgaurav rana 		      (ie_key_len == 2 * KEY_SIZE_BYTES / 2) ||
613*47151e4bSgaurav rana 		      (ie_key_len == 2 * KEY_SIZE_BYTES)))
614*47151e4bSgaurav rana 			return ERROR_ESBC_CLIENT_HEADER_INV_IE_ENTRY_KEYLEN;
615*47151e4bSgaurav rana 
616*47151e4bSgaurav rana 		memcpy(&img->img_key, &(ie_info->ie_key_tbl[ie_num - 1].pkey),
617*47151e4bSgaurav rana 		       ie_key_len);
618*47151e4bSgaurav rana 
619*47151e4bSgaurav rana 		img->key_len = ie_key_len;
620*47151e4bSgaurav rana 		key_found = 1;
621*47151e4bSgaurav rana 	}
622*47151e4bSgaurav rana #endif
623*47151e4bSgaurav rana 
624*47151e4bSgaurav rana 	if (key_found == 0) {
625*47151e4bSgaurav rana 		/* check key length */
626*47151e4bSgaurav rana 		if (!((hdr->key_len == 2 * KEY_SIZE_BYTES / 4) ||
627*47151e4bSgaurav rana 		      (hdr->key_len == 2 * KEY_SIZE_BYTES / 2) ||
628*47151e4bSgaurav rana 		      (hdr->key_len == 2 * KEY_SIZE_BYTES)))
629*47151e4bSgaurav rana 			return ERROR_ESBC_CLIENT_HEADER_KEY_LEN;
630*47151e4bSgaurav rana 
631*47151e4bSgaurav rana 		memcpy(&img->img_key, esbc + hdr->pkey, hdr->key_len);
632*47151e4bSgaurav rana 
633*47151e4bSgaurav rana 		img->key_len = hdr->key_len;
634*47151e4bSgaurav rana 
635*47151e4bSgaurav rana 		key_found = 1;
636*47151e4bSgaurav rana 	}
637*47151e4bSgaurav rana 
638*47151e4bSgaurav rana 	/* check signaure */
639*47151e4bSgaurav rana 	if (get_key_len(img) == 2 * hdr->sign_len) {
640*47151e4bSgaurav rana 		/* check signature length */
641*47151e4bSgaurav rana 		if (!((hdr->sign_len == KEY_SIZE_BYTES / 4) ||
642*47151e4bSgaurav rana 		      (hdr->sign_len == KEY_SIZE_BYTES / 2) ||
643*47151e4bSgaurav rana 		      (hdr->sign_len == KEY_SIZE_BYTES)))
644*47151e4bSgaurav rana 			return ERROR_ESBC_CLIENT_HEADER_SIG_LEN;
645*47151e4bSgaurav rana 	} else {
646*47151e4bSgaurav rana 		return ERROR_ESBC_CLIENT_HEADER_KEY_LEN_NOT_TWICE_SIG_LEN;
647*47151e4bSgaurav rana 	}
648*47151e4bSgaurav rana 
649*47151e4bSgaurav rana 	memcpy(&img->img_sign, esbc + hdr->psign, hdr->sign_len);
650*47151e4bSgaurav rana 
651*47151e4bSgaurav rana 	/* No SG support */
652*47151e4bSgaurav rana 	if (hdr->sg_flag)
653*47151e4bSgaurav rana 		return ERROR_ESBC_CLIENT_HEADER_SG;
654*47151e4bSgaurav rana 
655*47151e4bSgaurav rana 	/* modulus most significant bit should be set */
656*47151e4bSgaurav rana 	k = (u8 *)&img->img_key;
657*47151e4bSgaurav rana 
658*47151e4bSgaurav rana 	if ((k[0] & 0x80) == 0)
659*47151e4bSgaurav rana 		return ERROR_ESBC_CLIENT_HEADER_KEY_MOD_1;
660*47151e4bSgaurav rana 
661*47151e4bSgaurav rana 	/* modulus value should be odd */
662*47151e4bSgaurav rana 	if ((k[get_key_len(img) / 2 - 1] & 0x1) == 0)
663*47151e4bSgaurav rana 		return ERROR_ESBC_CLIENT_HEADER_KEY_MOD_2;
664*47151e4bSgaurav rana 
665*47151e4bSgaurav rana 	/* Check signature value < modulus value */
666*47151e4bSgaurav rana 	s = (u8 *)&img->img_sign;
667*47151e4bSgaurav rana 
668*47151e4bSgaurav rana 	if (!(memcmp(s, k, hdr->sign_len) < 0))
669*47151e4bSgaurav rana 		return ERROR_ESBC_CLIENT_HEADER_SIG_KEY_MOD;
670*47151e4bSgaurav rana 
671*47151e4bSgaurav rana 	return ESBC_VALID_HDR;
672*47151e4bSgaurav rana }
673*47151e4bSgaurav rana 
674*47151e4bSgaurav rana static inline int str2longbe(const char *p, ulong *num)
675*47151e4bSgaurav rana {
676*47151e4bSgaurav rana 	char *endptr;
677*47151e4bSgaurav rana 	ulong tmp;
678*47151e4bSgaurav rana 
679*47151e4bSgaurav rana 	if (!p) {
680*47151e4bSgaurav rana 		return 0;
681*47151e4bSgaurav rana 	} else {
682*47151e4bSgaurav rana 		tmp = simple_strtoul(p, &endptr, 16);
683*47151e4bSgaurav rana 		if (sizeof(ulong) == 4)
684*47151e4bSgaurav rana 			*num = cpu_to_be32(tmp);
685*47151e4bSgaurav rana 		else
686*47151e4bSgaurav rana 			*num = cpu_to_be64(tmp);
687*47151e4bSgaurav rana 	}
688*47151e4bSgaurav rana 
689*47151e4bSgaurav rana 	return *p != '\0' && *endptr == '\0';
690*47151e4bSgaurav rana }
691*47151e4bSgaurav rana 
692*47151e4bSgaurav rana int fsl_secboot_validate(cmd_tbl_t *cmdtp, int flag, int argc,
693*47151e4bSgaurav rana 		char * const argv[])
694*47151e4bSgaurav rana {
695*47151e4bSgaurav rana 	struct ccsr_sfp_regs *sfp_regs = (void *)(CONFIG_SYS_SFP_ADDR);
696*47151e4bSgaurav rana 	ulong hash[SHA256_BYTES/sizeof(ulong)];
697*47151e4bSgaurav rana 	char hash_str[NUM_HEX_CHARS + 1];
698*47151e4bSgaurav rana 	ulong addr = simple_strtoul(argv[1], NULL, 16);
699*47151e4bSgaurav rana 	struct fsl_secboot_img_priv *img;
700*47151e4bSgaurav rana 	struct fsl_secboot_img_hdr *hdr;
701*47151e4bSgaurav rana 	void *esbc;
702*47151e4bSgaurav rana 	int ret, i, hash_cmd = 0;
703*47151e4bSgaurav rana 	u32 srk_hash[8];
704*47151e4bSgaurav rana 	uint32_t key_len;
705*47151e4bSgaurav rana 	struct key_prop prop;
706*47151e4bSgaurav rana #if !defined(USE_HOSTCC)
707*47151e4bSgaurav rana 	struct udevice *mod_exp_dev;
708*47151e4bSgaurav rana #endif
709*47151e4bSgaurav rana 
710*47151e4bSgaurav rana 	if (argc == 3) {
711*47151e4bSgaurav rana 		char *cp = argv[2];
712*47151e4bSgaurav rana 		int i = 0;
713*47151e4bSgaurav rana 
714*47151e4bSgaurav rana 		if (*cp == '0' && *(cp + 1) == 'x')
715*47151e4bSgaurav rana 			cp += 2;
716*47151e4bSgaurav rana 
717*47151e4bSgaurav rana 		/* The input string expected is in hex, where
718*47151e4bSgaurav rana 		 * each 4 bits would be represented by a hex
719*47151e4bSgaurav rana 		 * sha256 hash is 256 bits long, which would mean
720*47151e4bSgaurav rana 		 * num of characters = 256 / 4
721*47151e4bSgaurav rana 		 */
722*47151e4bSgaurav rana 		if (strlen(cp) != SHA256_NIBBLES) {
723*47151e4bSgaurav rana 			printf("%s is not a 256 bits hex string as expected\n",
724*47151e4bSgaurav rana 			       argv[2]);
725*47151e4bSgaurav rana 			return -1;
726*47151e4bSgaurav rana 		}
727*47151e4bSgaurav rana 
728*47151e4bSgaurav rana 		for (i = 0; i < sizeof(hash)/sizeof(ulong); i++) {
729*47151e4bSgaurav rana 			strncpy(hash_str, cp + (i * NUM_HEX_CHARS),
730*47151e4bSgaurav rana 				NUM_HEX_CHARS);
731*47151e4bSgaurav rana 			hash_str[NUM_HEX_CHARS] = '\0';
732*47151e4bSgaurav rana 			if (!str2longbe(hash_str, &hash[i])) {
733*47151e4bSgaurav rana 				printf("%s is not a 256 bits hex string ",
734*47151e4bSgaurav rana 				       argv[2]);
735*47151e4bSgaurav rana 				return -1;
736*47151e4bSgaurav rana 			}
737*47151e4bSgaurav rana 		}
738*47151e4bSgaurav rana 
739*47151e4bSgaurav rana 		hash_cmd = 1;
740*47151e4bSgaurav rana 	}
741*47151e4bSgaurav rana 
742*47151e4bSgaurav rana 	img = malloc(sizeof(struct fsl_secboot_img_priv));
743*47151e4bSgaurav rana 
744*47151e4bSgaurav rana 	if (!img)
745*47151e4bSgaurav rana 		return -1;
746*47151e4bSgaurav rana 
747*47151e4bSgaurav rana 	memset(img, 0, sizeof(struct fsl_secboot_img_priv));
748*47151e4bSgaurav rana 
749*47151e4bSgaurav rana 	hdr = &img->hdr;
750*47151e4bSgaurav rana 	img->ehdrloc = addr;
751*47151e4bSgaurav rana 	esbc = (u8 *)img->ehdrloc;
752*47151e4bSgaurav rana 
753*47151e4bSgaurav rana 	memcpy(hdr, esbc, sizeof(struct fsl_secboot_img_hdr));
754*47151e4bSgaurav rana 
755*47151e4bSgaurav rana 	/* read and validate esbc header */
756*47151e4bSgaurav rana 	ret = read_validate_esbc_client_header(img);
757*47151e4bSgaurav rana 
758*47151e4bSgaurav rana 	if (ret != ESBC_VALID_HDR) {
759*47151e4bSgaurav rana 		fsl_secboot_handle_error(ret);
760*47151e4bSgaurav rana 		goto exit;
761*47151e4bSgaurav rana 	}
762*47151e4bSgaurav rana 
763*47151e4bSgaurav rana 	/* SRKH present in SFP */
764*47151e4bSgaurav rana 	for (i = 0; i < NUM_SRKH_REGS; i++)
765*47151e4bSgaurav rana 		srk_hash[i] = srk_in32(&sfp_regs->srk_hash[i]);
766*47151e4bSgaurav rana 
767*47151e4bSgaurav rana 	/*
768*47151e4bSgaurav rana 	 * Calculate hash of key obtained via offset present in
769*47151e4bSgaurav rana 	 * ESBC uboot client hdr
770*47151e4bSgaurav rana 	 */
771*47151e4bSgaurav rana 	ret = calc_img_key_hash(img);
772*47151e4bSgaurav rana 	if (ret) {
773*47151e4bSgaurav rana 		fsl_secblk_handle_error(ret);
774*47151e4bSgaurav rana 		goto exit;
775*47151e4bSgaurav rana 	}
776*47151e4bSgaurav rana 
777*47151e4bSgaurav rana 	/* Compare hash obtained above with SRK hash present in SFP */
778*47151e4bSgaurav rana 	if (hash_cmd)
779*47151e4bSgaurav rana 		ret = memcmp(&hash, &img->img_key_hash, SHA256_BYTES);
780*47151e4bSgaurav rana 	else
781*47151e4bSgaurav rana 		ret = memcmp(srk_hash, img->img_key_hash, SHA256_BYTES);
782*47151e4bSgaurav rana 
783*47151e4bSgaurav rana #if defined(CONFIG_FSL_ISBC_KEY_EXT)
784*47151e4bSgaurav rana 	if (!hash_cmd && check_ie(img))
785*47151e4bSgaurav rana 		ret = 0;
786*47151e4bSgaurav rana #endif
787*47151e4bSgaurav rana 
788*47151e4bSgaurav rana 	if (ret != 0) {
789*47151e4bSgaurav rana 		fsl_secboot_handle_error(ERROR_ESBC_CLIENT_HASH_COMPARE_KEY);
790*47151e4bSgaurav rana 		goto exit;
791*47151e4bSgaurav rana 	}
792*47151e4bSgaurav rana 
793*47151e4bSgaurav rana 	ret = calc_esbchdr_esbc_hash(img);
794*47151e4bSgaurav rana 	if (ret) {
795*47151e4bSgaurav rana 		fsl_secblk_handle_error(ret);
796*47151e4bSgaurav rana 		goto exit;
797*47151e4bSgaurav rana 	}
798*47151e4bSgaurav rana 
799*47151e4bSgaurav rana 	/* Construct encoded hash EM' wrt PKCSv1.5 */
800*47151e4bSgaurav rana 	construct_img_encoded_hash_second(img);
801*47151e4bSgaurav rana 
802*47151e4bSgaurav rana 	/* Fill prop structure for public key */
803*47151e4bSgaurav rana 	memset(&prop, 0, sizeof(struct key_prop));
804*47151e4bSgaurav rana 	key_len = get_key_len(img) / 2;
805*47151e4bSgaurav rana 	prop.modulus = img->img_key;
806*47151e4bSgaurav rana 	prop.public_exponent = img->img_key + key_len;
807*47151e4bSgaurav rana 	prop.num_bits = key_len * 8;
808*47151e4bSgaurav rana 	prop.exp_len = key_len;
809*47151e4bSgaurav rana 
810*47151e4bSgaurav rana 	ret = uclass_get_device(UCLASS_MOD_EXP, 0, &mod_exp_dev);
811*47151e4bSgaurav rana 	if (ret) {
812*47151e4bSgaurav rana 		printf("RSA: Can't find Modular Exp implementation\n");
813*47151e4bSgaurav rana 		return -EINVAL;
814*47151e4bSgaurav rana 	}
815*47151e4bSgaurav rana 
816*47151e4bSgaurav rana 	ret = rsa_mod_exp(mod_exp_dev, img->img_sign, img->hdr.sign_len,
817*47151e4bSgaurav rana 			  &prop, img->img_encoded_hash);
818*47151e4bSgaurav rana 	if (ret) {
819*47151e4bSgaurav rana 		fsl_secblk_handle_error(ret);
820*47151e4bSgaurav rana 		goto exit;
821*47151e4bSgaurav rana 	}
822*47151e4bSgaurav rana 
823*47151e4bSgaurav rana 	/*
824*47151e4bSgaurav rana 	 * compare the encoded messages EM' and EM wrt RSA PKCSv1.5
825*47151e4bSgaurav rana 	 * memcmp returns zero on success
826*47151e4bSgaurav rana 	 * memcmp returns non-zero on failure
827*47151e4bSgaurav rana 	 */
828*47151e4bSgaurav rana 	ret = memcmp(&img->img_encoded_hash_second, &img->img_encoded_hash,
829*47151e4bSgaurav rana 		img->hdr.sign_len);
830*47151e4bSgaurav rana 
831*47151e4bSgaurav rana 	if (ret) {
832*47151e4bSgaurav rana 		fsl_secboot_handle_error(ERROR_ESBC_CLIENT_HASH_COMPARE_EM);
833*47151e4bSgaurav rana 		goto exit;
834*47151e4bSgaurav rana 	}
835*47151e4bSgaurav rana 
836*47151e4bSgaurav rana 	printf("esbc_validate command successful\n");
837*47151e4bSgaurav rana 
838*47151e4bSgaurav rana exit:
839*47151e4bSgaurav rana 	return 0;
840*47151e4bSgaurav rana }
841