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