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