From 98d9aa4013d9ad4df199297e79d955f55bd6eead Mon Sep 17 00:00:00 2001 From: Gong Qianyu Date: Thu, 31 Dec 2015 18:29:02 +0800 Subject: freescale/qixis: Add support for booting from SD/QSPI 1.Use "qixis_reset sd" to boot from SD 2.Use "qixis_reset sd_qspi" to boot from SD with QSPI support 3.Use "qixis_reset qspi" to boot from QSPI flash On some SoCs such as LS1021A and LS1043A, IFC and QSPI could be pin-multiplexed. So the switches are different between SD boot with IFC support and SD boot with QSPI support. The default booting from SD is with IFC support. Once QSPI is enabled(IFC disabled), only use I2C to access QIXIS. Signed-off-by: Gong Qianyu Reviewed-by: York Sun --- board/freescale/common/qixis.c | 36 ++++++++++++++++++++++++++++++++++++ 1 file changed, 36 insertions(+) (limited to 'board/freescale/common') diff --git a/board/freescale/common/qixis.c b/board/freescale/common/qixis.c index 9f6b0e7..113295f 100644 --- a/board/freescale/common/qixis.c +++ b/board/freescale/common/qixis.c @@ -216,6 +216,39 @@ int qixis_reset_cmd(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) #else printf("Not implemented\n"); #endif + } else if (strcmp(argv[1], "sd") == 0) { +#ifdef QIXIS_LBMAP_SD + QIXIS_WRITE(rst_ctl, 0x30); + QIXIS_WRITE(rcfg_ctl, 0); + set_lbmap(QIXIS_LBMAP_SD); + set_rcw_src(QIXIS_RCW_SRC_SD); + QIXIS_WRITE(rcfg_ctl, 0x20); + QIXIS_WRITE(rcfg_ctl, 0x21); +#else + printf("Not implemented\n"); +#endif + } else if (strcmp(argv[1], "sd_qspi") == 0) { +#ifdef QIXIS_LBMAP_SD_QSPI + QIXIS_WRITE(rst_ctl, 0x30); + QIXIS_WRITE(rcfg_ctl, 0); + set_lbmap(QIXIS_LBMAP_SD_QSPI); + set_rcw_src(QIXIS_RCW_SRC_SD); + qixis_write_i2c(offsetof(struct qixis, rcfg_ctl), 0x20); + qixis_write_i2c(offsetof(struct qixis, rcfg_ctl), 0x21); +#else + printf("Not implemented\n"); +#endif + } else if (strcmp(argv[1], "qspi") == 0) { +#ifdef QIXIS_LBMAP_QSPI + QIXIS_WRITE(rst_ctl, 0x30); + QIXIS_WRITE(rcfg_ctl, 0); + set_lbmap(QIXIS_LBMAP_QSPI); + set_rcw_src(QIXIS_RCW_SRC_QSPI); + qixis_write_i2c(offsetof(struct qixis, rcfg_ctl), 0x20); + qixis_write_i2c(offsetof(struct qixis, rcfg_ctl), 0x21); +#else + printf("Not implemented\n"); +#endif } else if (strcmp(argv[1], "watchdog") == 0) { static char *period[9] = {"2s", "4s", "8s", "16s", "32s", "1min", "2min", "4min", "8min"}; @@ -255,6 +288,9 @@ U_BOOT_CMD( "- hard reset to default bank\n" "qixis_reset altbank - reset to alternate bank\n" "qixis_reset nand - reset to nand\n" + "qixis_reset sd - reset to sd\n" + "qixis_reset sd_qspi - reset to sd with qspi support\n" + "qixis_reset qspi - reset to qspi\n" "qixis watchdog - set the watchdog period\n" " period: 1s 2s 4s 8s 16s 32s 1min 2min 4min 8min\n" "qixis_reset dump - display the QIXIS registers\n" -- cgit v1.1 From bc71f926e35be8af1a9491ea0332871881c7eda5 Mon Sep 17 00:00:00 2001 From: Aneesh Bansal Date: Tue, 8 Dec 2015 14:14:12 +0530 Subject: SECURE BOOT: change prototype of fsl_secboot_validate function The prototype and defination of function fsl_secboot_validate has been changed to support calling this function from another function within u-boot. Only two aruments needed: 1) header address - Mandatory 2) SHA256 string - optional Signed-off-by: Saksham Jain Signed-off-by: Aneesh Bansal Acked-by: Ruchika Gupta Reviewed-by: York Sun --- board/freescale/common/cmd_esbc_validate.c | 17 ++++++++++++++++- board/freescale/common/fsl_validate.c | 18 +++++++----------- 2 files changed, 23 insertions(+), 12 deletions(-) (limited to 'board/freescale/common') diff --git a/board/freescale/common/cmd_esbc_validate.c b/board/freescale/common/cmd_esbc_validate.c index 8bbe85b..ae6a9af 100644 --- a/board/freescale/common/cmd_esbc_validate.c +++ b/board/freescale/common/cmd_esbc_validate.c @@ -21,10 +21,25 @@ loop: static int do_esbc_validate(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) { + char *hash_str = NULL; + ulong haddr; + int ret; + if (argc < 2) return cmd_usage(cmdtp); + else if (argc > 2) + /* Second arg - Optional - Hash Str*/ + hash_str = argv[2]; + + /* First argument - header address -32/64bit */ + haddr = simple_strtoul(argv[1], NULL, 16); - return fsl_secboot_validate(cmdtp, flag, argc, argv); + ret = fsl_secboot_validate(haddr, hash_str); + if (ret) + return 1; + + printf("esbc_validate command successful\n"); + return 0; } /***************************************************/ diff --git a/board/freescale/common/fsl_validate.c b/board/freescale/common/fsl_validate.c index b510c71..282ce53 100644 --- a/board/freescale/common/fsl_validate.c +++ b/board/freescale/common/fsl_validate.c @@ -699,13 +699,11 @@ static inline int str2longbe(const char *p, ulong *num) return *p != '\0' && *endptr == '\0'; } -int fsl_secboot_validate(cmd_tbl_t *cmdtp, int flag, int argc, - char * const argv[]) +int fsl_secboot_validate(ulong haddr, char *arg_hash_str) { struct ccsr_sfp_regs *sfp_regs = (void *)(CONFIG_SYS_SFP_ADDR); ulong hash[SHA256_BYTES/sizeof(ulong)]; char hash_str[NUM_HEX_CHARS + 1]; - ulong addr = simple_strtoul(argv[1], NULL, 16); struct fsl_secboot_img_priv *img; struct fsl_secboot_img_hdr *hdr; void *esbc; @@ -717,8 +715,8 @@ int fsl_secboot_validate(cmd_tbl_t *cmdtp, int flag, int argc, struct udevice *mod_exp_dev; #endif - if (argc == 3) { - char *cp = argv[2]; + if (arg_hash_str != NULL) { + const char *cp = arg_hash_str; int i = 0; if (*cp == '0' && *(cp + 1) == 'x') @@ -731,7 +729,7 @@ int fsl_secboot_validate(cmd_tbl_t *cmdtp, int flag, int argc, */ if (strlen(cp) != SHA256_NIBBLES) { printf("%s is not a 256 bits hex string as expected\n", - argv[2]); + arg_hash_str); return -1; } @@ -741,7 +739,7 @@ int fsl_secboot_validate(cmd_tbl_t *cmdtp, int flag, int argc, hash_str[NUM_HEX_CHARS] = '\0'; if (!str2longbe(hash_str, &hash[i])) { printf("%s is not a 256 bits hex string ", - argv[2]); + arg_hash_str); return -1; } } @@ -757,7 +755,7 @@ int fsl_secboot_validate(cmd_tbl_t *cmdtp, int flag, int argc, memset(img, 0, sizeof(struct fsl_secboot_img_priv)); hdr = &img->hdr; - img->ehdrloc = addr; + img->ehdrloc = haddr; esbc = (u8 *)(uintptr_t)img->ehdrloc; memcpy(hdr, esbc, sizeof(struct fsl_secboot_img_hdr)); @@ -843,8 +841,6 @@ int fsl_secboot_validate(cmd_tbl_t *cmdtp, int flag, int argc, goto exit; } - printf("esbc_validate command successful\n"); - exit: - return 0; + return ret; } -- cgit v1.1 From 94ba5e41402719ab8a58bf55b925867e50abcb35 Mon Sep 17 00:00:00 2001 From: Aneesh Bansal Date: Tue, 8 Dec 2015 14:14:13 +0530 Subject: SECURE BOOT: separate functions for reading keys Separate functions are created for reading and checking the sanity of Public keys: - read_validate_single_key - read_validate_ie_tbl - read_validate_srk_table Signed-off-by: Saksham Jain Signed-off-by: Aneesh Bansal Acked-by: Ruchika Gupta Reviewed-by: York Sun --- board/freescale/common/fsl_validate.c | 169 +++++++++++++++++++--------------- 1 file changed, 96 insertions(+), 73 deletions(-) (limited to 'board/freescale/common') diff --git a/board/freescale/common/fsl_validate.c b/board/freescale/common/fsl_validate.c index 282ce53..ef7a5ae 100644 --- a/board/freescale/common/fsl_validate.c +++ b/board/freescale/common/fsl_validate.c @@ -24,6 +24,10 @@ #define SHA256_NIBBLES (256/4) #define NUM_HEX_CHARS (sizeof(ulong) * 2) +#define CHECK_KEY_LEN(key_len) (((key_len) == 2 * KEY_SIZE_BYTES / 4) || \ + ((key_len) == 2 * KEY_SIZE_BYTES / 2) || \ + ((key_len) == 2 * KEY_SIZE_BYTES)) + /* This array contains DER value for SHA-256 */ static const u8 hash_identifier[] = { 0x30, 0x31, 0x30, 0x0d, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x01, 0x05, 0x00, @@ -179,20 +183,97 @@ static u32 is_key_revoked(u32 keynum, u32 rev_flag) return 0; } -/* It validates srk_table key lengths.*/ -static u32 validate_srk_tbl(struct srk_table *tbl, u32 num_entries) +/* It read validates srk_table key lengths.*/ +static u32 read_validate_srk_tbl(struct fsl_secboot_img_priv *img) { int i = 0; - for (i = 0; i < num_entries; i++) { - if (!((tbl[i].key_len == 2 * KEY_SIZE_BYTES/4) || - (tbl[i].key_len == 2 * KEY_SIZE_BYTES/2) || - (tbl[i].key_len == 2 * KEY_SIZE_BYTES))) + u32 ret, key_num, key_revoc_flag, size; + struct fsl_secboot_img_hdr *hdr = &img->hdr; + void *esbc = (u8 *)(uintptr_t)img->ehdrloc; + + if ((hdr->len_kr.num_srk == 0) || + (hdr->len_kr.num_srk > MAX_KEY_ENTRIES)) + return ERROR_ESBC_CLIENT_HEADER_INVALID_SRK_NUM_ENTRY; + + key_num = hdr->len_kr.srk_sel; + if (key_num == 0 || key_num > hdr->len_kr.num_srk) + return ERROR_ESBC_CLIENT_HEADER_INVALID_KEY_NUM; + + /* Get revoc key from sfp */ + key_revoc_flag = get_key_revoc(); + ret = is_key_revoked(key_num, key_revoc_flag); + if (ret) + return ERROR_ESBC_CLIENT_HEADER_KEY_REVOKED; + + size = hdr->len_kr.num_srk * sizeof(struct srk_table); + + memcpy(&img->srk_tbl, esbc + hdr->srk_tbl_off, size); + + for (i = 0; i < hdr->len_kr.num_srk; i++) { + if (!CHECK_KEY_LEN(img->srk_tbl[i].key_len)) return ERROR_ESBC_CLIENT_HEADER_INV_SRK_ENTRY_KEYLEN; } + + img->key_len = img->srk_tbl[key_num - 1].key_len; + + memcpy(&img->img_key, &(img->srk_tbl[key_num - 1].pkey), + img->key_len); + return 0; } #endif +static u32 read_validate_single_key(struct fsl_secboot_img_priv *img) +{ + struct fsl_secboot_img_hdr *hdr = &img->hdr; + void *esbc = (u8 *)(uintptr_t)img->ehdrloc; + + /* check key length */ + if (!CHECK_KEY_LEN(hdr->key_len)) + return ERROR_ESBC_CLIENT_HEADER_KEY_LEN; + + memcpy(&img->img_key, esbc + hdr->pkey, hdr->key_len); + + img->key_len = hdr->key_len; + + return 0; +} + +#if defined(CONFIG_FSL_ISBC_KEY_EXT) +static u32 read_validate_ie_tbl(struct fsl_secboot_img_priv *img) +{ + struct fsl_secboot_img_hdr *hdr = &img->hdr; + u32 ie_key_len, ie_revoc_flag, ie_num; + struct ie_key_info *ie_info; + + if (get_ie_info_addr(&img->ie_addr)) + return ERROR_IE_TABLE_NOT_FOUND; + ie_info = (struct ie_key_info *)(uintptr_t)img->ie_addr; + if (ie_info->num_keys == 0 || ie_info->num_keys > 32) + return ERROR_ESBC_CLIENT_HEADER_INVALID_IE_NUM_ENTRY; + + ie_num = hdr->ie_key_sel; + if (ie_num == 0 || ie_num > ie_info->num_keys) + return ERROR_ESBC_CLIENT_HEADER_INVALID_IE_KEY_NUM; + + ie_revoc_flag = ie_info->key_revok; + if ((u32)(1 << (ie_num - 1)) & ie_revoc_flag) + return ERROR_ESBC_CLIENT_HEADER_IE_KEY_REVOKED; + + ie_key_len = ie_info->ie_key_tbl[ie_num - 1].key_len; + + if (!CHECK_KEY_LEN(ie_key_len)) + return ERROR_ESBC_CLIENT_HEADER_INV_IE_ENTRY_KEYLEN; + + memcpy(&img->img_key, &(ie_info->ie_key_tbl[ie_num - 1].pkey), + ie_key_len); + + img->key_len = ie_key_len; + return 0; +} +#endif + + /* This function return length of public key.*/ static inline u32 get_key_len(struct fsl_secboot_img_priv *img) { @@ -541,13 +622,9 @@ static int read_validate_esbc_client_header(struct fsl_secboot_img_priv *img) struct fsl_secboot_img_hdr *hdr = &img->hdr; void *esbc = (u8 *)(uintptr_t)img->ehdrloc; u8 *k, *s; + u32 ret = 0; + #ifdef CONFIG_KEY_REVOCATION - u32 ret; - u32 key_num, key_revoc_flag, size; -#endif -#if defined(CONFIG_FSL_ISBC_KEY_EXT) - struct ie_key_info *ie_info; - u32 ie_num, ie_revoc_flag, ie_key_len; #endif int key_found = 0; @@ -568,80 +645,26 @@ static int read_validate_esbc_client_header(struct fsl_secboot_img_priv *img) /* Key checking*/ #ifdef CONFIG_KEY_REVOCATION if (check_srk(img)) { - if ((hdr->len_kr.num_srk == 0) || - (hdr->len_kr.num_srk > MAX_KEY_ENTRIES)) - return ERROR_ESBC_CLIENT_HEADER_INVALID_SRK_NUM_ENTRY; - - key_num = hdr->len_kr.srk_sel; - if (key_num == 0 || key_num > hdr->len_kr.num_srk) - return ERROR_ESBC_CLIENT_HEADER_INVALID_KEY_NUM; - - /* Get revoc key from sfp */ - key_revoc_flag = get_key_revoc(); - ret = is_key_revoked(key_num, key_revoc_flag); - if (ret) - return ERROR_ESBC_CLIENT_HEADER_KEY_REVOKED; - - size = hdr->len_kr.num_srk * sizeof(struct srk_table); - - memcpy(&img->srk_tbl, esbc + hdr->srk_tbl_off, size); - - ret = validate_srk_tbl(img->srk_tbl, hdr->len_kr.num_srk); - + ret = read_validate_srk_tbl(img); if (ret != 0) return ret; - - img->key_len = img->srk_tbl[key_num - 1].key_len; - - memcpy(&img->img_key, &(img->srk_tbl[key_num - 1].pkey), - img->key_len); - key_found = 1; } #endif #if defined(CONFIG_FSL_ISBC_KEY_EXT) if (!key_found && check_ie(img)) { - if (get_ie_info_addr(&img->ie_addr)) - return ERROR_IE_TABLE_NOT_FOUND; - ie_info = (struct ie_key_info *)(uintptr_t)img->ie_addr; - if (ie_info->num_keys == 0 || ie_info->num_keys > 32) - return ERROR_ESBC_CLIENT_HEADER_INVALID_IE_NUM_ENTRY; - - ie_num = hdr->ie_key_sel; - if (ie_num == 0 || ie_num > ie_info->num_keys) - return ERROR_ESBC_CLIENT_HEADER_INVALID_IE_KEY_NUM; - - ie_revoc_flag = ie_info->key_revok; - if ((u32)(1 << (ie_num - 1)) & ie_revoc_flag) - return ERROR_ESBC_CLIENT_HEADER_IE_KEY_REVOKED; - - ie_key_len = ie_info->ie_key_tbl[ie_num - 1].key_len; - - if (!((ie_key_len == 2 * KEY_SIZE_BYTES / 4) || - (ie_key_len == 2 * KEY_SIZE_BYTES / 2) || - (ie_key_len == 2 * KEY_SIZE_BYTES))) - return ERROR_ESBC_CLIENT_HEADER_INV_IE_ENTRY_KEYLEN; - - memcpy(&img->img_key, &(ie_info->ie_key_tbl[ie_num - 1].pkey), - ie_key_len); - - img->key_len = ie_key_len; + ret = read_validate_ie_tbl(img); + if (ret != 0) + return ret; key_found = 1; } #endif if (key_found == 0) { - /* check key length */ - if (!((hdr->key_len == 2 * KEY_SIZE_BYTES / 4) || - (hdr->key_len == 2 * KEY_SIZE_BYTES / 2) || - (hdr->key_len == 2 * KEY_SIZE_BYTES))) - return ERROR_ESBC_CLIENT_HEADER_KEY_LEN; - - memcpy(&img->img_key, esbc + hdr->pkey, hdr->key_len); - - img->key_len = hdr->key_len; - + ret = read_validate_single_key(img); + if (ret != 0) + return ret; key_found = 1; } -- cgit v1.1 From 6629261ddd9d78c3cd8193b05c00a2a9bdc74796 Mon Sep 17 00:00:00 2001 From: Aneesh Bansal Date: Tue, 8 Dec 2015 14:14:14 +0530 Subject: SECURE BOOT: separate function created for signature The code for image hash calculation, hash calculation from RSA signature and comparison of hashes has been mobed to a separate function. Signed-off-by: Saksham Jain Signed-off-by: Aneesh Bansal Acked-by: Ruchika Gupta Reviewed-by: York Sun --- board/freescale/common/fsl_validate.c | 98 +++++++++++++++++++---------------- 1 file changed, 54 insertions(+), 44 deletions(-) (limited to 'board/freescale/common') diff --git a/board/freescale/common/fsl_validate.c b/board/freescale/common/fsl_validate.c index ef7a5ae..08a2f79 100644 --- a/board/freescale/common/fsl_validate.c +++ b/board/freescale/common/fsl_validate.c @@ -721,6 +721,58 @@ static inline int str2longbe(const char *p, ulong *num) return *p != '\0' && *endptr == '\0'; } +/* Function to calculate the ESBC Image Hash + * and hash from Digital signature. + * The Two hash's are compared to yield the + * result of signature validation. + */ +static int calculate_cmp_img_sig(struct fsl_secboot_img_priv *img) +{ + int ret; + uint32_t key_len; + struct key_prop prop; +#if !defined(USE_HOSTCC) + struct udevice *mod_exp_dev; +#endif + ret = calc_esbchdr_esbc_hash(img); + if (ret) + return ret; + + /* Construct encoded hash EM' wrt PKCSv1.5 */ + construct_img_encoded_hash_second(img); + + /* Fill prop structure for public key */ + memset(&prop, 0, sizeof(struct key_prop)); + key_len = get_key_len(img) / 2; + prop.modulus = img->img_key; + prop.public_exponent = img->img_key + key_len; + prop.num_bits = key_len * 8; + prop.exp_len = key_len; + + ret = uclass_get_device(UCLASS_MOD_EXP, 0, &mod_exp_dev); + if (ret) { + printf("RSA: Can't find Modular Exp implementation\n"); + return -EINVAL; + } + + ret = rsa_mod_exp(mod_exp_dev, img->img_sign, img->hdr.sign_len, + &prop, img->img_encoded_hash); + if (ret) + return ret; + + /* + * compare the encoded messages EM' and EM wrt RSA PKCSv1.5 + * memcmp returns zero on success + * memcmp returns non-zero on failure + */ + ret = memcmp(&img->img_encoded_hash_second, &img->img_encoded_hash, + img->hdr.sign_len); + + if (ret) + return ERROR_ESBC_CLIENT_HASH_COMPARE_EM; + + return 0; +} int fsl_secboot_validate(ulong haddr, char *arg_hash_str) { @@ -732,11 +784,6 @@ int fsl_secboot_validate(ulong haddr, char *arg_hash_str) void *esbc; int ret, i, hash_cmd = 0; u32 srk_hash[8]; - uint32_t key_len; - struct key_prop prop; -#if !defined(USE_HOSTCC) - struct udevice *mod_exp_dev; -#endif if (arg_hash_str != NULL) { const char *cp = arg_hash_str; @@ -821,46 +868,9 @@ int fsl_secboot_validate(ulong haddr, char *arg_hash_str) goto exit; } - ret = calc_esbchdr_esbc_hash(img); - if (ret) { - fsl_secblk_handle_error(ret); - goto exit; - } - - /* Construct encoded hash EM' wrt PKCSv1.5 */ - construct_img_encoded_hash_second(img); - - /* Fill prop structure for public key */ - memset(&prop, 0, sizeof(struct key_prop)); - key_len = get_key_len(img) / 2; - prop.modulus = img->img_key; - prop.public_exponent = img->img_key + key_len; - prop.num_bits = key_len * 8; - prop.exp_len = key_len; - - ret = uclass_get_device(UCLASS_MOD_EXP, 0, &mod_exp_dev); - if (ret) { - printf("RSA: Can't find Modular Exp implementation\n"); - return -EINVAL; - } - - ret = rsa_mod_exp(mod_exp_dev, img->img_sign, img->hdr.sign_len, - &prop, img->img_encoded_hash); - if (ret) { - fsl_secblk_handle_error(ret); - goto exit; - } - - /* - * compare the encoded messages EM' and EM wrt RSA PKCSv1.5 - * memcmp returns zero on success - * memcmp returns non-zero on failure - */ - ret = memcmp(&img->img_encoded_hash_second, &img->img_encoded_hash, - img->hdr.sign_len); - + ret = calculate_cmp_img_sig(img); if (ret) { - fsl_secboot_handle_error(ERROR_ESBC_CLIENT_HASH_COMPARE_EM); + fsl_secboot_handle_error(ret); goto exit; } -- cgit v1.1 From b055a0fd867b11e40944b3414026d37ea00e0840 Mon Sep 17 00:00:00 2001 From: Aneesh Bansal Date: Tue, 8 Dec 2015 14:14:15 +0530 Subject: SECURE BOOT: support for validation of dynamic image Some images to be validated are relocated to a dynamic address at run time. So, these addresses cannot be known befor hand while signing the images and creating the header offline. So, support is required to pass the image address to the validate function as an argument. If an address is provided to the function, the address field in Header is not read and is treated as a reserved field. Signed-off-by: Saksham Jain Signed-off-by: Aneesh Bansal Acked-by: Ruchika Gupta Reviewed-by: York Sun --- board/freescale/common/cmd_esbc_validate.c | 10 ++++++--- board/freescale/common/fsl_validate.c | 33 ++++++++++++++++++------------ 2 files changed, 27 insertions(+), 16 deletions(-) (limited to 'board/freescale/common') diff --git a/board/freescale/common/cmd_esbc_validate.c b/board/freescale/common/cmd_esbc_validate.c index ae6a9af..ca7c737 100644 --- a/board/freescale/common/cmd_esbc_validate.c +++ b/board/freescale/common/cmd_esbc_validate.c @@ -22,7 +22,7 @@ static int do_esbc_validate(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) { char *hash_str = NULL; - ulong haddr; + uintptr_t haddr; int ret; if (argc < 2) @@ -32,9 +32,13 @@ static int do_esbc_validate(cmd_tbl_t *cmdtp, int flag, int argc, hash_str = argv[2]; /* First argument - header address -32/64bit */ - haddr = simple_strtoul(argv[1], NULL, 16); + haddr = (uintptr_t)simple_strtoul(argv[1], NULL, 16); - ret = fsl_secboot_validate(haddr, hash_str); + /* With esbc_validate command, Image address must be + * part of header. So, the function is called + * by passing this argument as 0. + */ + ret = fsl_secboot_validate(haddr, hash_str, 0); if (ret) return 1; diff --git a/board/freescale/common/fsl_validate.c b/board/freescale/common/fsl_validate.c index 08a2f79..de40081 100644 --- a/board/freescale/common/fsl_validate.c +++ b/board/freescale/common/fsl_validate.c @@ -536,13 +536,8 @@ static int calc_esbchdr_esbc_hash(struct fsl_secboot_img_priv *img) return ret; /* Update hash for actual Image */ -#ifdef CONFIG_ESBC_ADDR_64BIT ret = algo->hash_update(algo, ctx, - (u8 *)(uintptr_t)img->hdr.pimg64, img->hdr.img_size, 1); -#else - ret = algo->hash_update(algo, ctx, - (u8 *)(uintptr_t)img->hdr.pimg, img->hdr.img_size, 1); -#endif + (u8 *)img->img_addr, img->img_size, 1); if (ret) return ret; @@ -632,16 +627,25 @@ static int read_validate_esbc_client_header(struct fsl_secboot_img_priv *img) if (memcmp(hdr->barker, barker_code, ESBC_BARKER_LEN)) return ERROR_ESBC_CLIENT_HEADER_BARKER; -#ifdef CONFIG_ESBC_ADDR_64BIT - sprintf(buf, "%llx", hdr->pimg64); -#else - sprintf(buf, "%x", hdr->pimg); -#endif + /* If Image Address is not passed as argument to function, + * then Address and Size must be read from the Header. + */ + if (img->img_addr == 0) { + #ifdef CONFIG_ESBC_ADDR_64BIT + img->img_addr = hdr->pimg64; + #else + img->img_addr = hdr->pimg; + #endif + } + + sprintf(buf, "%lx", img->img_addr); setenv("img_addr", buf); if (!hdr->img_size) return ERROR_ESBC_CLIENT_HEADER_IMG_SIZE; + img->img_size = hdr->img_size; + /* Key checking*/ #ifdef CONFIG_KEY_REVOCATION if (check_srk(img)) { @@ -774,7 +778,8 @@ static int calculate_cmp_img_sig(struct fsl_secboot_img_priv *img) return 0; } -int fsl_secboot_validate(ulong haddr, char *arg_hash_str) +int fsl_secboot_validate(uintptr_t haddr, char *arg_hash_str, + uintptr_t img_addr) { struct ccsr_sfp_regs *sfp_regs = (void *)(CONFIG_SYS_SFP_ADDR); ulong hash[SHA256_BYTES/sizeof(ulong)]; @@ -824,9 +829,11 @@ int fsl_secboot_validate(ulong haddr, char *arg_hash_str) memset(img, 0, sizeof(struct fsl_secboot_img_priv)); + /* Update the information in Private Struct */ hdr = &img->hdr; img->ehdrloc = haddr; - esbc = (u8 *)(uintptr_t)img->ehdrloc; + img->img_addr = img_addr; + esbc = (u8 *)img->ehdrloc; memcpy(hdr, esbc, sizeof(struct fsl_secboot_img_hdr)); -- cgit v1.1 From 0a6b2714adfffce6a1497bd2ed6cbf4f7b4b0236 Mon Sep 17 00:00:00 2001 From: Aneesh Bansal Date: Fri, 22 Jan 2016 16:37:25 +0530 Subject: secure_boot: create function to determine boot mode A function is created to detrmine if the boot mode is secure or non-secure for differnt SoC's. Signed-off-by: Aneesh Bansal Acked-by: Ruchika Gupta Reviewed-by: York Sun --- board/freescale/common/fsl_chain_of_trust.c | 53 +++++++++++++++++++++++++++++ 1 file changed, 53 insertions(+) create mode 100644 board/freescale/common/fsl_chain_of_trust.c (limited to 'board/freescale/common') diff --git a/board/freescale/common/fsl_chain_of_trust.c b/board/freescale/common/fsl_chain_of_trust.c new file mode 100644 index 0000000..ff67bd7 --- /dev/null +++ b/board/freescale/common/fsl_chain_of_trust.c @@ -0,0 +1,53 @@ +/* + * Copyright 2015 Freescale Semiconductor, Inc. + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include +#include +#include + +#ifdef CONFIG_LS102XA +#include +#endif + +#if defined(CONFIG_MPC85xx) +#define CONFIG_DCFG_ADDR CONFIG_SYS_MPC85xx_GUTS_ADDR +#else +#define CONFIG_DCFG_ADDR CONFIG_SYS_FSL_GUTS_ADDR +#endif + +#ifdef CONFIG_SYS_FSL_CCSR_GUR_LE +#define gur_in32(a) in_le32(a) +#else +#define gur_in32(a) in_be32(a) +#endif + +/* Check the Boot Mode. If Secure, return 1 else return 0 */ +int fsl_check_boot_mode_secure(void) +{ + uint32_t val; + struct ccsr_sfp_regs *sfp_regs = (void *)(CONFIG_SYS_SFP_ADDR); + struct ccsr_gur __iomem *gur = (void *)(CONFIG_DCFG_ADDR); + + val = sfp_in32(&sfp_regs->ospr) & ITS_MASK; + if (val == ITS_MASK) + return 1; + +#if defined(CONFIG_FSL_CORENET) || !defined(CONFIG_MPC85xx) + /* For PBL based platforms check the SB_EN bit in RCWSR */ + val = gur_in32(&gur->rcwsr[RCW_SB_EN_REG_INDEX - 1]) & RCW_SB_EN_MASK; + if (val == RCW_SB_EN_MASK) + return 1; +#endif + +#if defined(CONFIG_MPC85xx) && !defined(CONFIG_FSL_CORENET) + /* For Non-PBL Platforms, check the Device Status register 2*/ + val = gur_in32(&gur->pordevsr2) & MPC85xx_PORDEVSR2_SBC_MASK; + if (val != MPC85xx_PORDEVSR2_SBC_MASK) + return 1; + +#endif + return 0; +} -- cgit v1.1 From d041288586b05164c84794a5956ddc5fb8939115 Mon Sep 17 00:00:00 2001 From: Aneesh Bansal Date: Fri, 22 Jan 2016 16:37:26 +0530 Subject: secure_boot: enable chain of trust for ARM platforms Chain of Trust is enabled for ARM platforms (LS1021 and LS1043). In board_late_init(), fsl_setenv_chain_of_trust() is called which will perform the following: - If boot mode is non-secure, return (No Change) - If boot mode is secure, set the following environmet variables: bootdelay = 0 (To disable Boot Prompt) bootcmd = CONFIG_CHAIN_BOOT_CMD (Validate and execute Boot script) Signed-off-by: Aneesh Bansal Acked-by: Ruchika Gupta Reviewed-by: York Sun --- board/freescale/common/Makefile | 1 + board/freescale/common/fsl_chain_of_trust.c | 17 +++++++++++++++++ 2 files changed, 18 insertions(+) (limited to 'board/freescale/common') diff --git a/board/freescale/common/Makefile b/board/freescale/common/Makefile index 51d2814..be114ce 100644 --- a/board/freescale/common/Makefile +++ b/board/freescale/common/Makefile @@ -76,5 +76,6 @@ obj-$(CONFIG_LAYERSCAPE_NS_ACCESS) += ns_access.o ifdef CONFIG_SECURE_BOOT obj-$(CONFIG_CMD_ESBC_VALIDATE) += fsl_validate.o cmd_esbc_validate.o endif +obj-$(CONFIG_CHAIN_OF_TRUST) += fsl_chain_of_trust.o endif diff --git a/board/freescale/common/fsl_chain_of_trust.c b/board/freescale/common/fsl_chain_of_trust.c index ff67bd7..ecfcc82 100644 --- a/board/freescale/common/fsl_chain_of_trust.c +++ b/board/freescale/common/fsl_chain_of_trust.c @@ -51,3 +51,20 @@ int fsl_check_boot_mode_secure(void) #endif return 0; } + +int fsl_setenv_chain_of_trust(void) +{ + /* Check Boot Mode + * If Boot Mode is Non-Secure, no changes are required + */ + if (fsl_check_boot_mode_secure() == 0) + return 0; + + /* If Boot mode is Secure, set the environment variables + * bootdelay = 0 (To disable Boot Prompt) + * bootcmd = CONFIG_CHAIN_BOOT_CMD (Validate and execute Boot script) + */ + setenv("bootdelay", "0"); + setenv("bootcmd", CONFIG_CHAIN_BOOT_CMD); + return 0; +} -- cgit v1.1 From 856b284617eea5688ccf5f4655f8d70ac5ae5fbb Mon Sep 17 00:00:00 2001 From: Aneesh Bansal Date: Fri, 22 Jan 2016 16:37:28 +0530 Subject: secure_boot: change error handler for esbc_validate In case of error while executing esbc_validate command, SNVS transition and issue of reset is required only for secure-boot. If boot mode is non-secure, this is not required. Similarly, esbc_halt command which puts the core in Spin Loop is applicable only for Secure Boot. Signed-off-by: Aneesh Bansal Acked-by: Ruchika Gupta Reviewed-by: York Sun --- board/freescale/common/cmd_esbc_validate.c | 7 ++++++- board/freescale/common/fsl_validate.c | 7 +++++++ 2 files changed, 13 insertions(+), 1 deletion(-) (limited to 'board/freescale/common') diff --git a/board/freescale/common/cmd_esbc_validate.c b/board/freescale/common/cmd_esbc_validate.c index ca7c737..dfa3e21 100644 --- a/board/freescale/common/cmd_esbc_validate.c +++ b/board/freescale/common/cmd_esbc_validate.c @@ -11,6 +11,11 @@ static int do_esbc_halt(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) { + if (fsl_check_boot_mode_secure() == 0) { + printf("Boot Mode is Non-Secure. Not entering spin loop.\n"); + return 0; + } + printf("Core is entering spin loop.\n"); loop: goto loop; @@ -64,6 +69,6 @@ U_BOOT_CMD( U_BOOT_CMD( esbc_halt, 1, 0, do_esbc_halt, - "Put the core in spin loop ", + "Put the core in spin loop (Secure Boot Only)", "" ); diff --git a/board/freescale/common/fsl_validate.c b/board/freescale/common/fsl_validate.c index de40081..8fd6dd6 100644 --- a/board/freescale/common/fsl_validate.c +++ b/board/freescale/common/fsl_validate.c @@ -370,6 +370,13 @@ void fsl_secboot_handle_error(int error) printf("ERROR :: %x :: %s\n", error, e->name); } + /* If Boot Mode is secure, transition the SNVS state and issue + * reset based on type of failure and ITS setting. + * If Boot mode is non-secure, return from this function. + */ + if (fsl_check_boot_mode_secure() == 0) + return; + switch (error) { case ERROR_ESBC_CLIENT_HEADER_BARKER: case ERROR_ESBC_CLIENT_HEADER_IMG_SIZE: -- cgit v1.1