* [PATCH 00/13] HAB for i.MX8MQ
@ 2019-06-26 4:58 Rouven Czerwinski
2019-06-26 4:58 ` [PATCH 01/13] hab: implement interface " Rouven Czerwinski
` (12 more replies)
0 siblings, 13 replies; 21+ messages in thread
From: Rouven Czerwinski @ 2019-06-26 4:58 UTC (permalink / raw)
To: barebox; +Cc: Rouven Czerwinski
This patch series adds HAB support for i.MX8MQ.
This was tested on the NXP i.MX8MQ EVK. Other i.MX8MQ boards should
still be supported but will require a lowlevel.c rework similar to this
done for the i.MX8MQ.
The first part adds the necessary HAB interfaces for i.MX8MQ. Than the
ability to read and copy the piggydata to the correct location in DRAM
is added. Next imx-image is adjusted to support signing of the i.MX8MQ
images. The fourth part is the addition of sha256 to the PBL. This is
necessary since only the PBL is authenticated using HAB, the main
barebox binary is than authenticated to a sha256sum built into the PBL.
Finally the EVK board files are adjusted to the changes.
Kind Regards,
Rouven Czerwinski
Rouven Czerwinski (13):
hab: implement interface for i.MX8MQ
mach-imx: enable HAB on i.MX8MQ
arm: lib: add CSF section between PBL and piggy
esdhc-pbl: extract header parsing from image start
esdhc-pbl: add piggy load function
sections: fix macro for barebox_pbl_size
scripts: imx: support signing for i.MX8MQ
images: always build sha256sum into pbl
pbl: add sha256 and piggy verification to PBL
arm: uncompress: verify sha256 if enabled
mach-imx: add gencsf header for i.MX8MQ
mach-imx: hab: select piggy verification for i.MX8
boards: nxp-mx8-evk: rework to different boot flow
arch/arm/boards/nxp-imx8mq-evk/flash-header-imx8mq-evk.imxcfg | 1 +-
arch/arm/boards/nxp-imx8mq-evk/lowlevel.c | 78 ++---
arch/arm/cpu/uncompress.c | 18 +-
arch/arm/lib/pbl.lds.S | 17 +-
arch/arm/mach-imx/Kconfig | 5 +-
arch/arm/mach-imx/include/mach/habv4-imx8-gencsf.h | 59 ++++-
arch/arm/mach-imx/include/mach/imx-header.h | 2 +-
arch/arm/mach-imx/include/mach/xload.h | 5 +-
arch/arm/mach-imx/xload-common.c | 6 +-
crypto/Makefile | 2 +-
crypto/sha2.c | 11 +-
drivers/hab/hab.c | 2 +-
drivers/hab/habv4.c | 112 +++++++-
drivers/mci/imx-esdhc-pbl.c | 90 +++++-
images/Makefile | 22 +-
images/sha_sum.S | 6 +-
include/asm-generic/sections.h | 4 +-
include/crypto/pbl-sha.h | 12 +-
include/pbl.h | 2 +-
pbl/Kconfig | 9 +-
pbl/decomp.c | 40 +++-
scripts/Makefile.lib | 3 +-
scripts/imx/imx-image.c | 68 +++-
scripts/imx/imx.c | 15 +-
24 files changed, 511 insertions(+), 78 deletions(-)
create mode 100644 arch/arm/mach-imx/include/mach/habv4-imx8-gencsf.h
create mode 100644 images/sha_sum.S
create mode 100644 include/crypto/pbl-sha.h
base-commit: a34fd3272a88101483f74a608b07db4312a64015
--
git-series 0.9.1
_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox
^ permalink raw reply [flat|nested] 21+ messages in thread
* [PATCH 01/13] hab: implement interface for i.MX8MQ
2019-06-26 4:58 [PATCH 00/13] HAB for i.MX8MQ Rouven Czerwinski
@ 2019-06-26 4:58 ` Rouven Czerwinski
2019-06-26 7:31 ` Sascha Hauer
2019-06-26 4:58 ` [PATCH 02/13] mach-imx: enable HAB on i.MX8MQ Rouven Czerwinski
` (11 subsequent siblings)
12 siblings, 1 reply; 21+ messages in thread
From: Rouven Czerwinski @ 2019-06-26 4:58 UTC (permalink / raw)
To: barebox; +Cc: Rouven Czerwinski
The HAB interface for i.MX8MQ only implements the retrieval of status
and events. The SoC status is retrieved using the TF-A SIP API found in
the downstream imx TF-A. After calling into the TF-A the passed data
structures need to be invalidated, since otherwise the cached zero value
is used.
Currently the TF-A report event call only supports FAILURE events.
Testing the TF-A with other event types resulted in a freeze in the
bootrom code, which was not investigated further.
We instead walk the memory containing the events and retrieve the events
ourselves. They are exposed using the same API.
Signed-off-by: Rouven Czerwinski <r.czerwinski@pengutronix.de>
---
drivers/hab/hab.c | 2 +-
drivers/hab/habv4.c | 112 +++++++++++++++++++++++++++++++++++++++++++++-
2 files changed, 113 insertions(+), 1 deletion(-)
diff --git a/drivers/hab/hab.c b/drivers/hab/hab.c
index 03bb65e..a346e01 100644
--- a/drivers/hab/hab.c
+++ b/drivers/hab/hab.c
@@ -217,7 +217,7 @@ static struct imx_hab_ops *imx_get_hab_ops(void)
if (IS_ENABLED(CONFIG_HABV3) && (cpu_is_mx25() || cpu_is_mx35()))
tmp = &imx_hab_ops_iim;
- else if (IS_ENABLED(CONFIG_HABV4) && cpu_is_mx6())
+ else if (IS_ENABLED(CONFIG_HABV4) && (cpu_is_mx6() || cpu_is_mx8mq()))
tmp = &imx_hab_ops_ocotp;
else
return NULL;
diff --git a/drivers/hab/habv4.c b/drivers/hab/habv4.c
index 496fbe3..36e249a 100644
--- a/drivers/hab/habv4.c
+++ b/drivers/hab/habv4.c
@@ -22,8 +22,11 @@
#include <hab.h>
#include <init.h>
#include <types.h>
+#include <linux/arm-smccc.h>
+#include <asm/cache.h>
#include <mach/generic.h>
+#include <mach/imx8mq.h>
#define HABV4_RVT_IMX28 0xffff8af8
#define HABV4_RVT_IMX6_OLD 0x00000094
@@ -177,6 +180,85 @@ struct habv4_rvt {
void (*failsafe)(void);
} __packed;
+#define FSL_SIP_HAB 0xC2000007
+#define FSL_SIP_HAB_AUTHENTICATE 0x00
+#define FSL_SIP_HAB_ENTRY 0x01
+#define FSL_SIP_HAB_EXIT 0x02
+#define FSL_SIP_HAB_REPORT_EVENT 0x03
+#define FSL_SIP_HAB_REPORT_STATUS 0x04
+#define FSL_SIP_HAB_FAILSAFE 0x05
+#define FSL_SIP_HAB_CHECK_TARGET 0x06
+
+static enum hab_status hab_sip_report_status(enum hab_config *config,
+ enum hab_state *state)
+{
+ struct arm_smccc_res res;
+
+ arm_smccc_smc(FSL_SIP_HAB, FSL_SIP_HAB_REPORT_STATUS,
+ (unsigned long) config,
+ (unsigned long) state, 0, 0, 0, 0, &res);
+ if (state)
+ v8_inv_dcache_range((unsigned long) state,
+ (unsigned long)state + sizeof(*config));
+ if (config)
+ v8_inv_dcache_range((unsigned long) config,
+ (unsigned long)config + sizeof(*state));
+ return (enum hab_status)res.a0;
+}
+
+static enum hab_status imx8_read_sram_events(enum hab_status status,
+ uint32_t index, void *event,
+ uint32_t *bytes)
+{
+ struct hab_event_record *events[10];
+ int num_events = 0;
+ char *sram = (char *)0x9061c0;
+ int i = 0;
+ int internal_index = 0;
+ char *end = 0;
+ struct hab_event_record *search;
+
+ /*
+ * AN12263 HABv4 Guidelines and Recommendations
+ * recommends the address and size, however errors are usually contained
+ * within the first bytes. Scan only the first few bytes to rule out
+ * lots of false positives.
+ */
+ end = sram + 0x1a0;
+
+ while (sram < end) {
+ if (*sram == 0xdb) {
+ search = (void *)sram;
+ sram = sram + be16_to_cpu(search->hdr.len);
+ events[num_events] = search;
+ num_events++;
+ } else {
+ sram++;
+ }
+ }
+ while (i < num_events) {
+ if (events[i]->status == status) {
+ if (internal_index == index) {
+ *bytes = sizeof(struct hab_event_record) +
+ be16_to_cpu(events[i]->hdr.len);
+ if (event)
+ memcpy(event, events[i], *bytes);
+ return HAB_STATUS_SUCCESS;
+ } else {
+ internal_index++;
+ }
+ }
+ i++;
+ }
+ return HAB_STATUS_FAILURE;
+}
+
+struct habv4_rvt hab_smc_ops = {
+ .header = { .tag = 0xdd },
+ .report_event = imx8_read_sram_events,
+ .report_status = hab_sip_report_status,
+};
+
static const char *habv4_get_status_str(enum hab_status status)
{
switch (status) {
@@ -507,6 +589,36 @@ int imx6_hab_get_status(void)
return -EINVAL;
}
+static int imx8_hab_get_status(void)
+{
+ return habv4_get_status(&hab_smc_ops);
+}
+
+static int init_imx8_hab_get_status(void)
+{
+ int ret = 0;
+
+ if (cpu_is_mx8mq())
+ ret = imx8_hab_get_status();
+ else
+ return 0;
+
+ /*
+ * Nobody will check the return value if there were HAB errors, but the
+ * initcall will fail spectaculously with a strange error message.
+ */
+ if (ret == -EPERM)
+ return 0;
+ return ret;
+}
+
+/*
+ *
+ *
+ *
+ */
+postmmu_initcall(init_imx8_hab_get_status);
+
static int init_imx6_hab_get_status(void)
{
int ret = 0;
--
git-series 0.9.1
_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox
^ permalink raw reply [flat|nested] 21+ messages in thread
* [PATCH 02/13] mach-imx: enable HAB on i.MX8MQ
2019-06-26 4:58 [PATCH 00/13] HAB for i.MX8MQ Rouven Czerwinski
2019-06-26 4:58 ` [PATCH 01/13] hab: implement interface " Rouven Czerwinski
@ 2019-06-26 4:58 ` Rouven Czerwinski
2019-06-26 4:58 ` [PATCH 03/13] arm: lib: add CSF section between PBL and piggy Rouven Czerwinski
` (10 subsequent siblings)
12 siblings, 0 replies; 21+ messages in thread
From: Rouven Czerwinski @ 2019-06-26 4:58 UTC (permalink / raw)
To: barebox; +Cc: Rouven Czerwinski
Enable HAB for i.MX8MQ. Since the status and report functions are now
implemented, we can safely enable HABV4 for i.MX8MQ.
Signed-off-by: Rouven Czerwinski <r.czerwinski@pengutronix.de>
---
arch/arm/mach-imx/Kconfig | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/arch/arm/mach-imx/Kconfig b/arch/arm/mach-imx/Kconfig
index 71d37ce..3cb8820 100644
--- a/arch/arm/mach-imx/Kconfig
+++ b/arch/arm/mach-imx/Kconfig
@@ -784,10 +784,10 @@ config HABV4
select HAB
select NVMEM
select IMX_OCOTP
- depends on ARCH_IMX6
+ depends on ARCH_IMX6 || ARCH_IMX8MQ
depends on OFDEVICE
help
- High Assurance Boot, as found on i.MX28/i.MX6.
+ High Assurance Boot, as found on i.MX28/i.MX6/i.MX8MQ.
config HAB_CERTS_ENV
depends on HAB
--
git-series 0.9.1
_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox
^ permalink raw reply [flat|nested] 21+ messages in thread
* [PATCH 03/13] arm: lib: add CSF section between PBL and piggy
2019-06-26 4:58 [PATCH 00/13] HAB for i.MX8MQ Rouven Czerwinski
2019-06-26 4:58 ` [PATCH 01/13] hab: implement interface " Rouven Czerwinski
2019-06-26 4:58 ` [PATCH 02/13] mach-imx: enable HAB on i.MX8MQ Rouven Czerwinski
@ 2019-06-26 4:58 ` Rouven Czerwinski
2019-06-26 4:58 ` [PATCH 04/13] esdhc-pbl: extract header parsing from image start Rouven Czerwinski
` (9 subsequent siblings)
12 siblings, 0 replies; 21+ messages in thread
From: Rouven Czerwinski @ 2019-06-26 4:58 UTC (permalink / raw)
To: barebox; +Cc: Rouven Czerwinski
Signing on i.MX8MQ is done by signing only the PBL, since the DRAM is
not available on early start and the SRAM is not big enough to contain
the whole image. Reserve a CSF area between PBL and the piggydata, to
ensure that the CSF area can be loaded into SRAM.
Signed-off-by: Rouven Czerwinski <r.czerwinski@pengutronix.de>
---
arch/arm/lib/pbl.lds.S | 10 ++++++++++
1 file changed, 10 insertions(+)
diff --git a/arch/arm/lib/pbl.lds.S b/arch/arm/lib/pbl.lds.S
index 300671b..d2f5ab2 100644
--- a/arch/arm/lib/pbl.lds.S
+++ b/arch/arm/lib/pbl.lds.S
@@ -90,6 +90,16 @@ SECTIONS
pbl_memory_size = . - BASE;
+#if defined(CONFIG_CPU_64) && defined(CONFIG_HABV4)
+ . = ALIGN(0x1000);
+ __csf_start = .;
+ .hab_csf : {
+ BYTE(0x5a);
+ . += + 0x1fff;
+ } = 0x5a
+ __csf_end = .;
+#endif /* CONFIG_CPU_64 && CONFIG_HABV4 */
+
. = ALIGN(4);
__piggydata_start = .;
.piggydata : {
--
git-series 0.9.1
_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox
^ permalink raw reply [flat|nested] 21+ messages in thread
* [PATCH 04/13] esdhc-pbl: extract header parsing from image start
2019-06-26 4:58 [PATCH 00/13] HAB for i.MX8MQ Rouven Czerwinski
` (2 preceding siblings ...)
2019-06-26 4:58 ` [PATCH 03/13] arm: lib: add CSF section between PBL and piggy Rouven Czerwinski
@ 2019-06-26 4:58 ` Rouven Czerwinski
2019-06-26 4:58 ` [PATCH 05/13] esdhc-pbl: add piggy load function Rouven Czerwinski
` (8 subsequent siblings)
12 siblings, 0 replies; 21+ messages in thread
From: Rouven Czerwinski @ 2019-06-26 4:58 UTC (permalink / raw)
To: barebox; +Cc: Rouven Czerwinski
Extract the header parsing code from esdc_start_image. The header
parsing function will be used by the piggy loading code added in the
next commit.
Signed-off-by: Rouven Czerwinski <r.czerwinski@pengutronix.de>
---
drivers/mci/imx-esdhc-pbl.c | 44 +++++++++++++++++++++++++-------------
1 file changed, 30 insertions(+), 14 deletions(-)
diff --git a/drivers/mci/imx-esdhc-pbl.c b/drivers/mci/imx-esdhc-pbl.c
index 0251757..35faf6d 100644
--- a/drivers/mci/imx-esdhc-pbl.c
+++ b/drivers/mci/imx-esdhc-pbl.c
@@ -243,27 +243,22 @@ static int esdhc_read_blocks(struct esdhc *esdhc, void *dst, size_t len)
}
#ifdef CONFIG_ARCH_IMX
-static int
-esdhc_start_image(struct esdhc *esdhc, ptrdiff_t address, ptrdiff_t entry, u32 offset)
+static int esdhc_search_header(struct esdhc *esdhc,
+ struct imx_flash_header_v2 **header_pointer,
+ void *buffer, u32 *offset)
{
-
- void *buf = (void *)address;
- struct imx_flash_header_v2 *hdr;
- int ret, len;
- void __noreturn (*bb)(void);
- unsigned int ofs;
+ int ret;
int i, header_count = 1;
-
- len = imx_image_size();
- len = ALIGN(len, SECTOR_SIZE);
+ void *buf = buffer;
+ struct imx_flash_header_v2 *hdr;
for (i = 0; i < header_count; i++) {
ret = esdhc_read_blocks(esdhc, buf,
- offset + SZ_1K + SECTOR_SIZE);
+ *offset + SZ_1K + SECTOR_SIZE);
if (ret)
return ret;
- hdr = buf + offset + SZ_1K;
+ hdr = buf + *offset + SZ_1K;
if (!is_imx_flash_header_v2(hdr)) {
pr_debug("IVT header not found on SD card. "
@@ -286,10 +281,31 @@ esdhc_start_image(struct esdhc *esdhc, ptrdiff_t address, ptrdiff_t entry, u32 o
* this time skipping anything HDMI firmware
* related.
*/
- offset += hdr->boot_data.size + hdr->header.length;
+ *offset += hdr->boot_data.size + hdr->header.length;
header_count++;
}
}
+ *header_pointer = hdr;
+ return 0;
+}
+
+static int
+esdhc_start_image(struct esdhc *esdhc, ptrdiff_t address, ptrdiff_t entry,
+ u32 offset)
+{
+
+ void *buf = (void *)address;
+ struct imx_flash_header_v2 *hdr = NULL;
+ int ret, len;
+ void __noreturn (*bb)(void);
+ unsigned int ofs;
+
+ len = imx_image_size();
+ len = ALIGN(len, SECTOR_SIZE);
+
+ ret = esdhc_search_header(esdhc, &hdr, buf, &offset);
+ if (ret)
+ return ret;
pr_debug("Check ok, loading image\n");
--
git-series 0.9.1
_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox
^ permalink raw reply [flat|nested] 21+ messages in thread
* [PATCH 05/13] esdhc-pbl: add piggy load function
2019-06-26 4:58 [PATCH 00/13] HAB for i.MX8MQ Rouven Czerwinski
` (3 preceding siblings ...)
2019-06-26 4:58 ` [PATCH 04/13] esdhc-pbl: extract header parsing from image start Rouven Czerwinski
@ 2019-06-26 4:58 ` Rouven Czerwinski
2019-06-26 4:58 ` [PATCH 06/13] sections: fix macro for barebox_pbl_size Rouven Czerwinski
` (7 subsequent siblings)
12 siblings, 0 replies; 21+ messages in thread
From: Rouven Czerwinski @ 2019-06-26 4:58 UTC (permalink / raw)
To: barebox; +Cc: Rouven Czerwinski
Add a function to load and copy the piggy data to the correct offset
expected by barebox in the RAM. This way the PBL can later verify the
piggydata before uncompressing and loading the main barebox.
Signed-off-by: Rouven Czerwinski <r.czerwinski@pengutronix.de>
---
arch/arm/mach-imx/include/mach/xload.h | 5 +++-
arch/arm/mach-imx/xload-common.c | 6 ++++-
drivers/mci/imx-esdhc-pbl.c | 46 +++++++++++++++++++++++++++-
3 files changed, 57 insertions(+)
diff --git a/arch/arm/mach-imx/include/mach/xload.h b/arch/arm/mach-imx/include/mach/xload.h
index 8f141bc..a605e76 100644
--- a/arch/arm/mach-imx/include/mach/xload.h
+++ b/arch/arm/mach-imx/include/mach/xload.h
@@ -6,7 +6,12 @@ int imx6_spi_load_image(int instance, unsigned int flash_offset, void *buf, int
int imx6_spi_start_image(int instance);
int imx6_esdhc_start_image(int instance);
int imx8_esdhc_start_image(int instance);
+int imx8_esdhc_load_piggy(int instance);
int imx_image_size(void);
+int piggydata_size(void);
+
+extern unsigned char input_data[];
+extern unsigned char input_data_end[];
#endif /* __MACH_XLOAD_H */
diff --git a/arch/arm/mach-imx/xload-common.c b/arch/arm/mach-imx/xload-common.c
index c5727eb..bd64052 100644
--- a/arch/arm/mach-imx/xload-common.c
+++ b/arch/arm/mach-imx/xload-common.c
@@ -8,3 +8,9 @@ int imx_image_size(void)
/* i.MX header is 4k */
return barebox_image_size + SZ_4K;
}
+
+int piggydata_size(void)
+{
+ return input_data_end - input_data;
+}
+
diff --git a/drivers/mci/imx-esdhc-pbl.c b/drivers/mci/imx-esdhc-pbl.c
index 35faf6d..75593e8 100644
--- a/drivers/mci/imx-esdhc-pbl.c
+++ b/drivers/mci/imx-esdhc-pbl.c
@@ -423,6 +423,52 @@ int imx8_esdhc_start_image(int instance)
return esdhc_start_image(&esdhc, MX8MQ_DDR_CSD1_BASE_ADDR,
MX8MQ_ATF_BL33_BASE_ADDR, SZ_32K);
}
+
+int imx8_esdhc_load_piggy(int instance)
+{
+ void *buf = (void *)MX8MQ_ATF_BL33_BASE_ADDR;
+ struct imx_flash_header_v2 *hdr = NULL;
+ void *bb = 0;
+ struct esdhc esdhc;
+ int ret, len;
+ int offset = SZ_32K;
+
+
+ switch (instance) {
+ case 0:
+ esdhc.regs = IOMEM(MX8MQ_USDHC1_BASE_ADDR);
+ break;
+ case 1:
+ esdhc.regs = IOMEM(MX8MQ_USDHC2_BASE_ADDR);
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ esdhc.is_be = 0;
+ esdhc.is_mx6 = 1;
+
+ ret = esdhc_search_header(&esdhc, &hdr, buf, &offset);
+ if (ret)
+ return ret;
+
+ len = offset + hdr->boot_data.size + piggydata_size();
+ len = ALIGN(len, SECTOR_SIZE);
+
+ ret = esdhc_read_blocks(&esdhc, buf, len);
+
+ /*
+ * Calculate location of the piggydata at the offset loaded into RAM
+ */
+ buf = buf + offset + hdr->boot_data.size;
+ /*
+ * Barebox expects the piggydata right behind the PBL in the beginning
+ * of RAM.
+ */
+ bb = (void *) MX8MQ_DDR_CSD1_BASE_ADDR + barebox_pbl_size;
+ memcpy(bb, buf, piggydata_size());
+ return ret;
+}
#endif
#ifdef CONFIG_ARCH_LS1046
--
git-series 0.9.1
_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox
^ permalink raw reply [flat|nested] 21+ messages in thread
* [PATCH 06/13] sections: fix macro for barebox_pbl_size
2019-06-26 4:58 [PATCH 00/13] HAB for i.MX8MQ Rouven Czerwinski
` (4 preceding siblings ...)
2019-06-26 4:58 ` [PATCH 05/13] esdhc-pbl: add piggy load function Rouven Czerwinski
@ 2019-06-26 4:58 ` Rouven Czerwinski
2019-06-26 4:58 ` [PATCH 07/13] scripts: imx: support signing for i.MX8MQ Rouven Czerwinski
` (6 subsequent siblings)
12 siblings, 0 replies; 21+ messages in thread
From: Rouven Czerwinski @ 2019-06-26 4:58 UTC (permalink / raw)
To: barebox; +Cc: Rouven Czerwinski
On ARM64 this did not contain the expected barebox_pbl size. Rework this
to be a substraction between __piggydata_start and __image_start, which
should cover the whole PBL.
Signed-off-by: Rouven Czerwinski <r.czerwinski@pengutronix.de>
---
include/asm-generic/sections.h | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/include/asm-generic/sections.h b/include/asm-generic/sections.h
index 0eb18f6..f584cad 100644
--- a/include/asm-generic/sections.h
+++ b/include/asm-generic/sections.h
@@ -8,12 +8,12 @@ extern char __bare_init_start[], __bare_init_end[];
extern char _end[];
extern char __image_start[];
extern char __image_end[];
+extern char __piggydata_start[];
extern void *_barebox_image_size;
extern void *_barebox_bare_init_size;
extern void *_barebox_pbl_size;
#define barebox_image_size (__image_end - __image_start)
#define barebox_bare_init_size (unsigned int)&_barebox_bare_init_size
-#define barebox_pbl_size (unsigned int)&_barebox_pbl_size
-
+#define barebox_pbl_size (__piggydata_start - __image_start)
#endif /* _ASM_GENERIC_SECTIONS_H_ */
--
git-series 0.9.1
_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox
^ permalink raw reply [flat|nested] 21+ messages in thread
* [PATCH 07/13] scripts: imx: support signing for i.MX8MQ
2019-06-26 4:58 [PATCH 00/13] HAB for i.MX8MQ Rouven Czerwinski
` (5 preceding siblings ...)
2019-06-26 4:58 ` [PATCH 06/13] sections: fix macro for barebox_pbl_size Rouven Czerwinski
@ 2019-06-26 4:58 ` Rouven Czerwinski
2019-06-26 7:51 ` Sascha Hauer
2019-06-26 4:58 ` [PATCH 08/13] images: always build sha256sum into pbl Rouven Czerwinski
` (5 subsequent siblings)
12 siblings, 1 reply; 21+ messages in thread
From: Rouven Czerwinski @ 2019-06-26 4:58 UTC (permalink / raw)
To: barebox; +Cc: Rouven Czerwinski
Implement signing of the PBL for i.MX8MQ.
The imagesize is also modified to i.MX8MQ to only contain the PBL.
This obsoletes the max_load_size, which is kept for other boards
currently using it.
Signed-off-by: Rouven Czerwinski <r.czerwinski@pengutronix.de>
---
| 2 +-
scripts/Makefile.lib | 3 +-
scripts/imx/imx-image.c | 68 ++++++++++++++++++----
scripts/imx/imx.c | 15 ++++-
4 files changed, 74 insertions(+), 14 deletions(-)
--git a/arch/arm/mach-imx/include/mach/imx-header.h b/arch/arm/mach-imx/include/mach/imx-header.h
index 50584bb..dc8e2ee 100644
--- a/arch/arm/mach-imx/include/mach/imx-header.h
+++ b/arch/arm/mach-imx/include/mach/imx-header.h
@@ -98,6 +98,7 @@ struct config_data {
uint32_t image_size;
uint32_t max_load_size;
uint32_t load_size;
+ uint32_t pbl_code_size;
char *outfile;
char *srkfile;
int header_version;
@@ -111,6 +112,7 @@ struct config_data {
int (*nop)(const struct config_data *data);
int csf_space;
char *csf;
+ int sign_image;
char *signed_hdmi_firmware_file;
int encrypt_image;
size_t dek_size;
diff --git a/scripts/Makefile.lib b/scripts/Makefile.lib
index 95eaf52..1c8a0a9 100644
--- a/scripts/Makefile.lib
+++ b/scripts/Makefile.lib
@@ -498,7 +498,8 @@ imximg-tmp = $(subst $(comma),_,$(dot-target).imxcfg.tmp)
quiet_cmd_imx_image = IMX-IMG $@
cmd_imx_image = $(CPP) $(imxcfg_cpp_flags) -o $(imximg-tmp) $(2) ; \
- $(objtree)/scripts/imx/imx-image -o $@ -b -c $(imximg-tmp) $(3) -f $<
+ $(objtree)/scripts/imx/imx-image -o $@ -b -c $(imximg-tmp) $(3) \
+ -p $($(patsubst $(obj)/%.pblb,PBL_MEMORY_SIZE_%,$<)) -f $<
quiet_cmd_kwb_image = KWB $@
cmd_kwb_image = scripts/kwbimage -p $< $(OPTS_$(@F)) -o $@
diff --git a/scripts/imx/imx-image.c b/scripts/imx/imx-image.c
index a7f1421..7169bf7 100644
--- a/scripts/imx/imx-image.c
+++ b/scripts/imx/imx-image.c
@@ -315,6 +315,17 @@ static size_t add_header_v2(const struct config_data *data, void *buf)
uint32_t loadaddr = data->image_load_addr;
uint32_t imagesize = data->load_size;
+ if (data->cpu_type == IMX_CPU_IMX8MQ) {
+ /*
+ * If singing is enabled on IMX8MQ, the linker script reserves a
+ * CSF_LEN aligned section directly after the PBL,
+ * only load and sign this area of the data.
+ */
+ imagesize = roundup(data->pbl_code_size + HEADER_LEN, 0x4);
+ if (data->csf)
+ imagesize = roundup(imagesize, 0x1000);
+ }
+
buf += offset;
hdr = buf;
@@ -333,14 +344,22 @@ static size_t add_header_v2(const struct config_data *data, void *buf)
hdr->self = loadaddr + offset;
hdr->boot_data.start = loadaddr;
- if (data->max_load_size && imagesize > data->max_load_size)
+ if (!data->csf && data->max_load_size
+ && imagesize > data->max_load_size)
hdr->boot_data.size = data->max_load_size;
else
hdr->boot_data.size = imagesize;
- if (data->csf) {
+ if (data->sign_image) {
hdr->csf = loadaddr + imagesize;
hdr->boot_data.size += CSF_LEN;
+ } else if (data->cpu_type == IMX_CPU_IMX8MQ && data->csf) {
+ /*
+ * For i.MX8 the CSF space is added via the linker script, so
+ * the CSF length needs to be added if HABV4 is enabled but
+ * signing is not.
+ */
+ hdr->boot_data.size += CSF_LEN;
}
hdr->dcd_header.tag = TAG_DCD_HEADER;
@@ -546,6 +565,7 @@ static int hab_sign(struct config_data *data)
char *cst;
void *buf;
size_t csf_space = CSF_LEN;
+ unsigned int offset = 0;
cst = getenv("CST");
if (!cst)
@@ -620,6 +640,9 @@ static int hab_sign(struct config_data *data)
return -errno;
}
+ printf("--- CSF START ---\n");
+ printf("%s\n", data->csf);
+ printf("--- CSF END ---\n");
fwrite(data->csf, 1, strlen(data->csf) + 1, f);
pclose(f);
@@ -672,13 +695,36 @@ static int hab_sign(struct config_data *data)
return -errno;
}
- outfd = open(data->outfile, O_WRONLY | O_APPEND);
+ /*
+ * For i.MX8, write into the reserved CSF section
+ */
+ if (data->cpu_type == IMX_CPU_IMX8MQ)
+ outfd = open(data->outfile, O_WRONLY);
+ else
+ outfd = open(data->outfile, O_WRONLY | O_APPEND);
+
if (outfd < 0) {
fprintf(stderr, "Cannot open %s for writing: %s\n", data->outfile,
strerror(errno));
exit(1);
}
+ if (data->cpu_type == IMX_CPU_IMX8MQ) {
+ /*
+ * For i.MX8 insert the CSF data into the reserved CSF area
+ * right behind the PBL
+ */
+ offset = roundup(data->header_gap + data->pbl_code_size +
+ HEADER_LEN, 0x1000);
+ if (data->signed_hdmi_firmware_file)
+ offset += PLUGIN_HDMI_SIZE;
+
+ if (lseek(outfd, offset, SEEK_SET) < 0) {
+ perror("lseek");
+ exit(1);
+ }
+ }
+
ret = xwrite(outfd, buf, csf_space);
if (ret < 0) {
fprintf(stderr, "write failed: %s\n", strerror(errno));
@@ -743,7 +789,6 @@ int main(int argc, char *argv[])
int outfd;
int dcd_only = 0;
int now = 0;
- int sign_image = 0;
int i, header_copies;
int add_barebox_header;
uint32_t barebox_image_size = 0;
@@ -760,7 +805,7 @@ int main(int argc, char *argv[])
prgname = argv[0];
- while ((opt = getopt(argc, argv, "c:hf:o:bduse")) != -1) {
+ while ((opt = getopt(argc, argv, "c:hf:o:p:bduse")) != -1) {
switch (opt) {
case 'c':
configfile = optarg;
@@ -771,6 +816,9 @@ int main(int argc, char *argv[])
case 'o':
data.outfile = optarg;
break;
+ case 'p':
+ data.pbl_code_size = strtoul(optarg, NULL, 0);
+ break;
case 'b':
add_barebox_header = 1;
break;
@@ -778,7 +826,7 @@ int main(int argc, char *argv[])
dcd_only = 1;
break;
case 's':
- sign_image = 1;
+ data.sign_image = 1;
break;
case 'u':
create_usb_image = 1;
@@ -832,14 +880,12 @@ int main(int argc, char *argv[])
if (ret)
exit(1);
- if (data.max_load_size && (sign_image || data.encrypt_image)) {
+ if (data.max_load_size && (data.encrypt_image || data.csf)
+ && data.cpu_type != IMX_CPU_IMX8MQ) {
fprintf(stderr, "Specifying max_load_size is incompatible with HAB signing/encrypting\n");
exit(1);
}
- if (!sign_image)
- data.csf = NULL;
-
if (create_usb_image && !data.csf) {
fprintf(stderr, "Warning: the -u option only has effect with signed images\n");
create_usb_image = 0;
@@ -987,7 +1033,7 @@ int main(int argc, char *argv[])
exit(1);
}
- if (data.csf) {
+ if (data.csf && data.sign_image) {
ret = hab_sign(&data);
if (ret)
exit(1);
diff --git a/scripts/imx/imx.c b/scripts/imx/imx.c
index f37f151..e245194 100644
--- a/scripts/imx/imx.c
+++ b/scripts/imx/imx.c
@@ -338,6 +338,7 @@ static int do_hab_blocks(struct config_data *data, int argc, char *argv[])
char *str;
int ret;
uint32_t signed_size = data->load_size;
+ uint32_t offset = 0;
if (!data->csf)
return -EINVAL;
@@ -354,9 +355,19 @@ static int do_hab_blocks(struct config_data *data, int argc, char *argv[])
if (data->encrypt_image)
signed_size = ENCRYPT_OFFSET;
+ /*
+ * Ensure we only sign the PBL for i.MX8MQ
+ */
+ if (data->pbl_code_size && data->cpu_type == IMX_CPU_IMX8MQ) {
+ offset = data->header_gap;
+ signed_size = roundup(data->pbl_code_size + HEADER_LEN, 0x1000);
+ if (data->signed_hdmi_firmware_file)
+ offset += PLUGIN_HDMI_SIZE;
+ }
+
if (!strcmp(type, "full")) {
- ret = asprintf(&str, "Blocks = 0x%08x 0 %d \"%s\"\n",
- data->image_load_addr, signed_size,
+ ret = asprintf(&str, "Blocks = 0x%08x 0x%08x 0x%08x \"%s\"\n",
+ data->image_load_addr, offset, signed_size,
data->outfile);
} else if (!strcmp(type, "from-dcdofs")) {
ret = asprintf(&str, "Blocks = 0x%08x 0x%x %d \"%s\"\n",
--
git-series 0.9.1
_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox
^ permalink raw reply [flat|nested] 21+ messages in thread
* [PATCH 08/13] images: always build sha256sum into pbl
2019-06-26 4:58 [PATCH 00/13] HAB for i.MX8MQ Rouven Czerwinski
` (6 preceding siblings ...)
2019-06-26 4:58 ` [PATCH 07/13] scripts: imx: support signing for i.MX8MQ Rouven Czerwinski
@ 2019-06-26 4:58 ` Rouven Czerwinski
2019-06-26 4:58 ` [PATCH 09/13] pbl: add sha256 and piggy verification to PBL Rouven Czerwinski
` (4 subsequent siblings)
12 siblings, 0 replies; 21+ messages in thread
From: Rouven Czerwinski @ 2019-06-26 4:58 UTC (permalink / raw)
To: barebox; +Cc: Rouven Czerwinski
Create a sha256sum of the compressed barebox image and always add it to
the PBL. We also add a custom linker section for ARM, to retrieve the
sha256sum for piggydata verification.
Signed-off-by: Rouven Czerwinski <r.czerwinski@pengutronix.de>
---
arch/arm/lib/pbl.lds.S | 7 +++++++
images/Makefile | 22 +++++++++++++++++++---
images/sha_sum.S | 6 ++++++
3 files changed, 32 insertions(+), 3 deletions(-)
create mode 100644 images/sha_sum.S
diff --git a/arch/arm/lib/pbl.lds.S b/arch/arm/lib/pbl.lds.S
index d2f5ab2..01ed384 100644
--- a/arch/arm/lib/pbl.lds.S
+++ b/arch/arm/lib/pbl.lds.S
@@ -68,6 +68,13 @@ SECTIONS
. = ALIGN(4);
.data : { *(.data*) }
+ . = ALIGN(4);
+ __shasum_start = .;
+ .shasum : {
+ KEEP(*(.shasum))
+ }
+ __shasum_end = .;
+
.rel_dyn_start : { *(.__rel_dyn_start) }
#ifdef CONFIG_CPU_32
.rel.dyn : { *(.rel*) }
diff --git a/images/Makefile b/images/Makefile
index e525e0d..9f23895 100644
--- a/images/Makefile
+++ b/images/Makefile
@@ -57,11 +57,12 @@ quiet_cmd_elf__ ?= LD $@
cmd_elf__ ?= $(LD) $(LDFLAGS_barebox) --gc-sections \
-e $(2) -Map $@.map $(LDFLAGS_$(@F)) -o $@ \
-T $(pbl-lds) \
- --start-group $(barebox-pbl-common) $(obj)/piggy.o --end-group
+ --start-group $(barebox-pbl-common) $(obj)/piggy.o \
+ $(obj)/sha_sum.o --end-group
PBL_CPPFLAGS += -fdata-sections -ffunction-sections
-$(obj)/%.pbl: $(pbl-lds) $(barebox-pbl-common) $(obj)/piggy.o FORCE
+$(obj)/%.pbl: $(pbl-lds) $(barebox-pbl-common) $(obj)/piggy.o $(obj)/sha_sum.o FORCE
$(call if_changed,elf__,$(*F))
$(obj)/%.pblb: $(obj)/%.pbl FORCE
@@ -111,6 +112,21 @@ suffix_$(CONFIG_IMAGE_COMPRESSION_NONE) = comp_copy
$(obj)/piggy.o: $(obj)/barebox.z FORCE
+$(obj)/sha_sum.o: $(obj)/barebox.sha.bin FORCE
+
+quiet_cmd_sha256bin ?= SHA-BIN $@
+ cmd_sha256bin ?= printf "$(shell awk '{printf $$1}' < $(obj)/barebox.sum | sed -e 's/../\\x&/g' )" > $@
+
+quiet_cmd_sha256sum ?= SHA $@
+ cmd_sha256sum ?= sha256sum $(obj)/barebox.z > $@
+
+$(obj)/barebox.sha.bin: $(obj)/barebox.sum FORCE
+ $(call if_changed,sha256bin)
+
+$(obj)/barebox.sum: $(obj)/barebox.z FORCE
+ $(call if_changed,sha256sum)
+
+
# barebox.z - compressed barebox binary
# ----------------------------------------------------------------
$(obj)/barebox.z: $(obj)/../barebox.bin FORCE
@@ -152,7 +168,7 @@ ifneq ($(pblx-y)$(pblx-),)
$(error pblx- has been removed. Please use pblb- instead.)
endif
-targets += $(image-y) pbl.lds barebox.x barebox.z piggy.o
+targets += $(image-y) pbl.lds barebox.x barebox.z piggy.o sha_sum.o barebox.sha.bin barebox.sum
targets += $(patsubst %,%.pblb,$(pblb-y))
targets += $(patsubst %,%.pbl,$(pblb-y))
targets += $(patsubst %,%.s,$(pblb-y))
diff --git a/images/sha_sum.S b/images/sha_sum.S
new file mode 100644
index 0000000..1f9bd80
--- /dev/null
+++ b/images/sha_sum.S
@@ -0,0 +1,6 @@
+ .section .shasum,"a"
+ .globl sha_sum
+sha_sum:
+ .incbin "images/barebox.sha.bin"
+ .globl sha_sum_end
+sha_sum_end:
--
git-series 0.9.1
_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox
^ permalink raw reply [flat|nested] 21+ messages in thread
* [PATCH 09/13] pbl: add sha256 and piggy verification to PBL
2019-06-26 4:58 [PATCH 00/13] HAB for i.MX8MQ Rouven Czerwinski
` (7 preceding siblings ...)
2019-06-26 4:58 ` [PATCH 08/13] images: always build sha256sum into pbl Rouven Czerwinski
@ 2019-06-26 4:58 ` Rouven Czerwinski
2019-06-26 4:58 ` [PATCH 10/13] arm: uncompress: verify sha256 if enabled Rouven Czerwinski
` (3 subsequent siblings)
12 siblings, 0 replies; 21+ messages in thread
From: Rouven Czerwinski @ 2019-06-26 4:58 UTC (permalink / raw)
To: barebox; +Cc: Rouven Czerwinski
Extract the necessary functions from sha256 into a PBL headder and add a
verification function to the PBL. The function will be called before the
individual architectures decompress functions is run.
Signed-off-by: Rouven Czerwinski <r.czerwinski@pengutronix.de>
---
crypto/Makefile | 2 ++
crypto/sha2.c | 11 +++++++----
include/crypto/pbl-sha.h | 12 ++++++++++++
include/pbl.h | 2 ++
pbl/Kconfig | 9 +++++++++
pbl/decomp.c | 40 ++++++++++++++++++++++++++++++++++++++++
6 files changed, 72 insertions(+), 4 deletions(-)
create mode 100644 include/crypto/pbl-sha.h
diff --git a/crypto/Makefile b/crypto/Makefile
index 3402f57..d6fb74a 100644
--- a/crypto/Makefile
+++ b/crypto/Makefile
@@ -8,6 +8,8 @@ obj-$(CONFIG_DIGEST_MD5_GENERIC) += md5.o
obj-$(CONFIG_DIGEST_SHA1_GENERIC) += sha1.o
obj-$(CONFIG_DIGEST_SHA224_GENERIC) += sha2.o
obj-$(CONFIG_DIGEST_SHA256_GENERIC) += sha2.o
+pbl-$(CONFIG_PBL_VERIFY_PIGGY) += sha2.o
+pbl-$(CONFIG_PBL_VERIFY_PIGGY) += digest.o
obj-$(CONFIG_DIGEST_SHA384_GENERIC) += sha4.o
obj-$(CONFIG_DIGEST_SHA512_GENERIC) += sha4.o
diff --git a/crypto/sha2.c b/crypto/sha2.c
index c62ddb8..3947a09 100644
--- a/crypto/sha2.c
+++ b/crypto/sha2.c
@@ -27,6 +27,7 @@
#include <crypto/sha.h>
#include <crypto/internal.h>
+#include <crypto/pbl-sha.h>
static inline u32 Ch(u32 x, u32 y, u32 z)
{
@@ -232,7 +233,7 @@ static int sha224_init(struct digest *desc)
return 0;
}
-static int sha256_init(struct digest *desc)
+int sha256_init(struct digest *desc)
{
struct sha256_state *sctx = digest_ctx(desc);
sctx->state[0] = SHA256_H0;
@@ -248,7 +249,7 @@ static int sha256_init(struct digest *desc)
return 0;
}
-static int sha256_update(struct digest *desc, const void *data,
+int sha256_update(struct digest *desc, const void *data,
unsigned long len)
{
struct sha256_state *sctx = digest_ctx(desc);
@@ -280,7 +281,7 @@ static int sha256_update(struct digest *desc, const void *data,
return 0;
}
-static int sha256_final(struct digest *desc, u8 *out)
+int sha256_final(struct digest *desc, u8 *out)
{
struct sha256_state *sctx = digest_ctx(desc);
__be32 *dst = (__be32 *)out;
@@ -348,7 +349,7 @@ static int sha224_digest_register(void)
}
device_initcall(sha224_digest_register);
-static struct digest_algo m256 = {
+struct digest_algo m256 = {
.base = {
.name = "sha256",
.driver_name = "sha256-generic",
@@ -365,6 +366,7 @@ static struct digest_algo m256 = {
.ctx_length = sizeof(struct sha256_state),
};
+#ifndef __PBL__
static int sha256_digest_register(void)
{
if (!IS_ENABLED(CONFIG_SHA256))
@@ -373,3 +375,4 @@ static int sha256_digest_register(void)
return digest_algo_register(&m256);
}
coredevice_initcall(sha256_digest_register);
+#endif /* __PBL__ */
diff --git a/include/crypto/pbl-sha.h b/include/crypto/pbl-sha.h
new file mode 100644
index 0000000..8ecbfad
--- /dev/null
+++ b/include/crypto/pbl-sha.h
@@ -0,0 +1,12 @@
+#ifndef __PBL_SHA_H_
+
+#define __PBL_SHA_H_
+
+#include <digest.h>
+#include <types.h>
+
+int sha256_init(struct digest *desc);
+int sha256_update(struct digest *desc, const void *data, unsigned long len);
+int sha256_final(struct digest *desc, u8 *out);
+
+#endif /* __PBL-SHA_H_ */
diff --git a/include/pbl.h b/include/pbl.h
index 787bd82..302d3c1 100644
--- a/include/pbl.h
+++ b/include/pbl.h
@@ -11,6 +11,8 @@ extern unsigned long free_mem_ptr;
extern unsigned long free_mem_end_ptr;
void pbl_barebox_uncompress(void *dest, void *compressed_start, unsigned int len);
+int pbl_barebox_verify(void *compressed_start, unsigned int len, void* hash,
+ unsigned int hash_len);
#ifdef __PBL__
#define IN_PBL 1
diff --git a/pbl/Kconfig b/pbl/Kconfig
index f2250dd..38f1003 100644
--- a/pbl/Kconfig
+++ b/pbl/Kconfig
@@ -44,6 +44,15 @@ config PBL_RELOCATABLE
This option only inflluences the PBL image. See RELOCATABLE to also make
the real image relocatable.
+config PBL_VERIFY_PIGGY
+ depends on ARM
+ bool "Verify piggydata"
+ help
+ Use a PBL builtin sha256sum to verify the piggydata before decompression.
+ WARNING: your board will not boot if a mismatch is detected, enable DEBUG_LL
+ to see the builtin and calculated hash.
+ This effectively locks a given PBL to the matching main barebox.
+
config IMAGE_COMPRESSION
bool
depends on HAVE_IMAGE_COMPRESSION
diff --git a/pbl/decomp.c b/pbl/decomp.c
index c8014c4..ed74956 100644
--- a/pbl/decomp.c
+++ b/pbl/decomp.c
@@ -6,7 +6,12 @@
*/
#include <common.h>
+#include <crypto/sha.h>
+#include <crypto/pbl-sha.h>
+#include <digest.h>
+#include <asm/sections.h>
#include <pbl.h>
+#include <debug_ll.h>
#define STATIC static
@@ -50,3 +55,38 @@ void pbl_barebox_uncompress(void *dest, void *compressed_start, unsigned int len
NULL, NULL,
dest, NULL, errorfn);
}
+
+int pbl_barebox_verify(void *compressed_start, unsigned int len, void* hash,
+ unsigned int hash_len)
+{
+ struct sha256_state sha_state = { 0 };
+ struct digest d = { .ctx = &sha_state };
+ char computed_hash[SHA256_DIGEST_SIZE];
+ int i;
+ char *char_hash = hash;
+
+ if (hash_len != SHA256_DIGEST_SIZE)
+ return -1;
+
+ sha256_init(&d);
+ sha256_update(&d, compressed_start, len);
+ sha256_final(&d, computed_hash);
+ if (IS_ENABLED(CONFIG_DEBUG_LL)) {
+ putc_ll('C');
+ putc_ll('H');
+ putc_ll('\n');
+ for (i = 0; i < SHA256_DIGEST_SIZE; i++) {
+ puthex_ll(computed_hash[i]);
+ putc_ll('\n');
+ }
+ putc_ll('I');
+ putc_ll('H');
+ putc_ll('\n');
+ for (i = 0; i < SHA256_DIGEST_SIZE; i++) {
+ puthex_ll(char_hash[i]);
+ putc_ll('\n');
+ }
+ }
+
+ return memcmp(hash, computed_hash, SHA256_DIGEST_SIZE);
+}
--
git-series 0.9.1
_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox
^ permalink raw reply [flat|nested] 21+ messages in thread
* [PATCH 10/13] arm: uncompress: verify sha256 if enabled
2019-06-26 4:58 [PATCH 00/13] HAB for i.MX8MQ Rouven Czerwinski
` (8 preceding siblings ...)
2019-06-26 4:58 ` [PATCH 09/13] pbl: add sha256 and piggy verification to PBL Rouven Czerwinski
@ 2019-06-26 4:58 ` Rouven Czerwinski
2019-06-26 7:52 ` Sascha Hauer
2019-06-26 4:58 ` [PATCH 11/13] mach-imx: add gencsf header for i.MX8MQ Rouven Czerwinski
` (2 subsequent siblings)
12 siblings, 1 reply; 21+ messages in thread
From: Rouven Czerwinski @ 2019-06-26 4:58 UTC (permalink / raw)
To: barebox; +Cc: Rouven Czerwinski
Add piggydata verification before the ARM uncompress function.
This calculates the sha256sum of the compressed barebox binary and only
continues if the builtin sha256sum matches the calculated sha256sum.
Signed-off-by: Rouven Czerwinski <r.czerwinski@pengutronix.de>
---
arch/arm/cpu/uncompress.c | 18 +++++++++++++++++-
1 file changed, 17 insertions(+), 1 deletion(-)
diff --git a/arch/arm/cpu/uncompress.c b/arch/arm/cpu/uncompress.c
index e527165..ce5f2c1 100644
--- a/arch/arm/cpu/uncompress.c
+++ b/arch/arm/cpu/uncompress.c
@@ -42,14 +42,18 @@ unsigned long free_mem_end_ptr;
extern unsigned char input_data[];
extern unsigned char input_data_end[];
+extern unsigned char sha_sum[];
+extern unsigned char sha_sum_end[];
+
void __noreturn barebox_multi_pbl_start(unsigned long membase,
unsigned long memsize, void *boarddata)
{
- uint32_t pg_len, uncompressed_len;
+ uint32_t pg_len, uncompressed_len, pbl_hash_len;
void __noreturn (*barebox)(unsigned long, unsigned long, void *);
unsigned long endmem = membase + memsize;
unsigned long barebox_base;
void *pg_start, *pg_end;
+ void *pbl_hash_start, *pbl_hash_end;
unsigned long pc = get_pc();
pg_start = input_data + global_variable_offset();
@@ -92,6 +96,18 @@ void __noreturn barebox_multi_pbl_start(unsigned long membase,
pr_debug("uncompressing barebox binary at 0x%p (size 0x%08x) to 0x%08lx (uncompressed size: 0x%08x)\n",
pg_start, pg_len, barebox_base, uncompressed_len);
+ if (IS_ENABLED(CONFIG_PBL_VERIFY_PIGGY)) {
+ pbl_hash_start = sha_sum + global_variable_offset();
+ pbl_hash_end = sha_sum_end + global_variable_offset();
+ pbl_hash_len = pbl_hash_end - pbl_hash_start;
+ if (pbl_barebox_verify(pg_start, pg_len, pbl_hash_start,
+ pbl_hash_len) != 0) {
+ putc_ll('!');
+ pr_err("hash mismatch, refusing to decompress");
+ panic("hash mismatch, refusing to decompress");
+ }
+ }
+
pbl_barebox_uncompress((void*)barebox_base, pg_start, pg_len);
arm_early_mmu_cache_flush();
--
git-series 0.9.1
_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox
^ permalink raw reply [flat|nested] 21+ messages in thread
* [PATCH 11/13] mach-imx: add gencsf header for i.MX8MQ
2019-06-26 4:58 [PATCH 00/13] HAB for i.MX8MQ Rouven Czerwinski
` (9 preceding siblings ...)
2019-06-26 4:58 ` [PATCH 10/13] arm: uncompress: verify sha256 if enabled Rouven Czerwinski
@ 2019-06-26 4:58 ` Rouven Czerwinski
2019-06-26 4:58 ` [PATCH 12/13] mach-imx: hab: select piggy verification for i.MX8 Rouven Czerwinski
2019-06-26 4:58 ` [PATCH 13/13] boards: nxp-mx8-evk: rework to different boot flow Rouven Czerwinski
12 siblings, 0 replies; 21+ messages in thread
From: Rouven Czerwinski @ 2019-06-26 4:58 UTC (permalink / raw)
To: barebox; +Cc: Rouven Czerwinski
Add the required gencsf header for i.MX8MQ.
Signed-off-by: Rouven Czerwinski <r.czerwinski@pengutronix.de>
---
arch/arm/mach-imx/include/mach/habv4-imx8-gencsf.h | 59 +++++++++++++++-
1 file changed, 59 insertions(+)
create mode 100644 arch/arm/mach-imx/include/mach/habv4-imx8-gencsf.h
diff --git a/arch/arm/mach-imx/include/mach/habv4-imx8-gencsf.h b/arch/arm/mach-imx/include/mach/habv4-imx8-gencsf.h
new file mode 100644
index 0000000..34039ee
--- /dev/null
+++ b/arch/arm/mach-imx/include/mach/habv4-imx8-gencsf.h
@@ -0,0 +1,59 @@
+/*
+ * This snippet can be included from a i.MX flash header configuration
+ * file for generating signed images. The necessary keys/certificates
+ * are expected in these config variables:
+ *
+ * CONFIG_HABV4_TABLE_BIN
+ * CONFIG_HABV4_CSF_CRT_PEM
+ * CONFIG_HABV4_IMG_CRT_PEM
+ */
+#if defined(CONFIG_HABV4) && defined(CONFIG_CPU_64)
+hab [Header]
+hab Version = 4.3
+hab Hash Algorithm = sha256
+hab Engine Configuration = 0
+hab Certificate Format = X509
+hab Signature Format = CMS
+hab Engine = CAAM
+
+hab [Install SRK]
+hab File = CONFIG_HABV4_TABLE_BIN
+hab # SRK index within SRK-Table 0..3
+hab Source index = 0
+
+hab [Install CSFK]
+/* target key index in keystore 1 */
+hab File = CONFIG_HABV4_CSF_CRT_PEM
+
+hab [Authenticate CSF]
+
+hab [Unlock]
+hab Engine = CAAM
+hab Features = RNG
+
+hab [Install Key]
+/* verification key index in key store (0, 2...4) */
+hab Verification index = 0
+/* target key index in key store (2...4) */
+hab Target index = 2
+hab File = CONFIG_HABV4_IMG_CRT_PEM
+
+hab [Authenticate Data]
+/* verification key index in key store (2...4) */
+hab Verification index = 2
+
+hab_blocks
+
+hab_encrypt [Install Secret Key]
+hab_encrypt Verification index = 0
+hab_encrypt Target index = 0
+hab_encrypt_key
+hab_encrypt_key_length 256
+hab_encrypt_blob_address
+
+hab_encrypt [Decrypt Data]
+hab_encrypt Verification index = 0
+hab_encrypt Mac Bytes = 16
+
+hab_encrypt_blocks
+#endif
--
git-series 0.9.1
_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox
^ permalink raw reply [flat|nested] 21+ messages in thread
* [PATCH 12/13] mach-imx: hab: select piggy verification for i.MX8
2019-06-26 4:58 [PATCH 00/13] HAB for i.MX8MQ Rouven Czerwinski
` (10 preceding siblings ...)
2019-06-26 4:58 ` [PATCH 11/13] mach-imx: add gencsf header for i.MX8MQ Rouven Czerwinski
@ 2019-06-26 4:58 ` Rouven Czerwinski
2019-06-26 4:58 ` [PATCH 13/13] boards: nxp-mx8-evk: rework to different boot flow Rouven Czerwinski
12 siblings, 0 replies; 21+ messages in thread
From: Rouven Czerwinski @ 2019-06-26 4:58 UTC (permalink / raw)
To: barebox; +Cc: Rouven Czerwinski
Always select the piggy verification if HAB is enabled on i.MX8,
otherwise the signed PBL might load untrusted piggydata.
Signed-off-by: Rouven Czerwinski <r.czerwinski@pengutronix.de>
---
arch/arm/mach-imx/Kconfig | 1 +
1 file changed, 1 insertion(+)
diff --git a/arch/arm/mach-imx/Kconfig b/arch/arm/mach-imx/Kconfig
index 3cb8820..7a7684f 100644
--- a/arch/arm/mach-imx/Kconfig
+++ b/arch/arm/mach-imx/Kconfig
@@ -786,6 +786,7 @@ config HABV4
select IMX_OCOTP
depends on ARCH_IMX6 || ARCH_IMX8MQ
depends on OFDEVICE
+ select PBL_VERIFY_PIGGY if ARCH_IMX8MQ
help
High Assurance Boot, as found on i.MX28/i.MX6/i.MX8MQ.
--
git-series 0.9.1
_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox
^ permalink raw reply [flat|nested] 21+ messages in thread
* [PATCH 13/13] boards: nxp-mx8-evk: rework to different boot flow
2019-06-26 4:58 [PATCH 00/13] HAB for i.MX8MQ Rouven Czerwinski
` (11 preceding siblings ...)
2019-06-26 4:58 ` [PATCH 12/13] mach-imx: hab: select piggy verification for i.MX8 Rouven Czerwinski
@ 2019-06-26 4:58 ` Rouven Czerwinski
12 siblings, 0 replies; 21+ messages in thread
From: Rouven Czerwinski @ 2019-06-26 4:58 UTC (permalink / raw)
To: barebox; +Cc: Rouven Czerwinski
Rework the evk boot flow to use the new piggydata load function and
install a trampoline for the TF-A setup. This allows the PBL boot
process to stay in SRAM up until the verification of the piggydata is
done and main barebox can be loaded
Signed-off-by: Rouven Czerwinski <r.czerwinski@pengutronix.de>
---
| 1 +-
arch/arm/boards/nxp-imx8mq-evk/lowlevel.c | 78 +++----
2 files changed, 42 insertions(+), 37 deletions(-)
--git a/arch/arm/boards/nxp-imx8mq-evk/flash-header-imx8mq-evk.imxcfg b/arch/arm/boards/nxp-imx8mq-evk/flash-header-imx8mq-evk.imxcfg
index aff8321..11463fe 100644
--- a/arch/arm/boards/nxp-imx8mq-evk/flash-header-imx8mq-evk.imxcfg
+++ b/arch/arm/boards/nxp-imx8mq-evk/flash-header-imx8mq-evk.imxcfg
@@ -3,3 +3,4 @@ soc imx8mq
loadaddr 0x007E1000
max_load_size 0x3F000
dcdofs 0x400
+#include <mach/habv4-imx8-gencsf.h>
diff --git a/arch/arm/boards/nxp-imx8mq-evk/lowlevel.c b/arch/arm/boards/nxp-imx8mq-evk/lowlevel.c
index 6451e5d..67dc876 100644
--- a/arch/arm/boards/nxp-imx8mq-evk/lowlevel.c
+++ b/arch/arm/boards/nxp-imx8mq-evk/lowlevel.c
@@ -53,18 +53,21 @@ static void setup_uart(void)
static void nxp_imx8mq_evk_sram_setup(void)
{
- enum bootsource src = BOOTSOURCE_UNKNOWN;
- int instance = BOOTSOURCE_INSTANCE_UNKNOWN;
- int ret = -ENOTSUPP;
-
ddr_init();
+}
- imx8_get_boot_source(&src, &instance);
-
- if (src == BOOTSOURCE_MMC)
- ret = imx8_esdhc_start_image(instance);
-
- BUG_ON(ret);
+static void nxp_imx8mq_evk_install_tfa_trampoline(void)
+{
+ /*
+ * Create a trampoline which is places in DRAM and calls back into the
+ * PBL entry function found in the TCRAM. Register x0 is set to 1 to
+ * indicate that DRAM setup was already run.
+ */
+ int trampoline[4] = {0xd2840013, /* mov x19, #0x2000 */
+ 0xf2a00fd3, /* movk x19, #0x7e, lsl #16 */
+ 0xd2800020, /* mov x0, #0x1 */
+ 0xd61f0260};/* br x19 */
+ memcpy((void *)MX8MQ_ATF_BL33_BASE_ADDR, &trampoline, 16);
}
/*
@@ -75,50 +78,51 @@ static void nxp_imx8mq_evk_sram_setup(void)
* 1. MaskROM uploads PBL into OCRAM and that's where this function is
* executed for the first time
*
- * 2. DDR is initialized and full i.MX image is loaded to the
- * beginning of RAM
+ * 2. DDR is initialized and the TF-A trampoline is installed in the
+ * DRAM.
*
- * 3. start_nxp_imx8mq_evk, now in RAM, is executed again
+ * 3. TF-A is executed and exits into the trampoline in RAM, which enters the
+ * PBL for the second time. DRAM setup done is indicated by a one in register
+ * x0 by the trampoline
*
- * 4. BL31 blob is uploaded to OCRAM and the control is transfer to it
+ * 4. The piggydata is loaded from the SD card and copied to the expected
+ * location in the DRAM.
*
- * 5. BL31 exits EL3 into EL2 at address MX8MQ_ATF_BL33_BASE_ADDR,
- * executing start_nxp_imx8mq_evk() the third time
- *
- * 6. Standard barebox boot flow continues
+ * 5. Standard barebox boot flow continues
*/
ENTRY_FUNCTION(start_nxp_imx8mq_evk, r0, r1, r2)
{
+ enum bootsource src = BOOTSOURCE_UNKNOWN;
+ int instance = BOOTSOURCE_INSTANCE_UNKNOWN;
+ int ret = -ENOTSUPP;
+ const u8 *bl31;
+ size_t bl31_size;
+
imx8mq_cpu_lowlevel_init();
if (IS_ENABLED(CONFIG_DEBUG_LL))
setup_uart();
- if (get_pc() < MX8MQ_DDR_CSD1_BASE_ADDR) {
- /*
- * We assume that we were just loaded by MaskROM into
- * SRAM if we are not running from DDR. We also assume
- * that means DDR needs to be initialized for the
- * first time.
- */
- nxp_imx8mq_evk_sram_setup();
- }
/*
- * Straight from the power-on we are at EL3, so the following
- * code _will_ load and jump to ATF.
- *
- * However when we are re-executed upon exit from ATF's
- * initialization routine, it is EL2 which means we'll skip
- * loadting ATF blob again
+ * if register r0 does not contain 1, we are running for the first time
+ * and need to initialize the DRAM, install the trampoline and run TF-A
+ * (BL31).
+ * Otherwise the 1 indicates that the DRAM setup and trampoline are
+ * already installed and TF-A has been run. In this case we can skip
*/
- if (current_el() == 3) {
- const u8 *bl31;
- size_t bl31_size;
-
+ if (r0 != 1) {
+ nxp_imx8mq_evk_sram_setup();
+ nxp_imx8mq_evk_install_tfa_trampoline();
get_builtin_firmware(imx8mq_bl31_bin, &bl31, &bl31_size);
imx8mq_atf_load_bl31(bl31, bl31_size);
}
+ imx8_get_boot_source(&src, &instance);
+
+ if (src == BOOTSOURCE_MMC)
+ ret = imx8_esdhc_load_piggy(instance);
+ else
+ BUG_ON(ret);
/*
* Standard entry we hit once we initialized both DDR and ATF
*/
--
git-series 0.9.1
_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox
^ permalink raw reply [flat|nested] 21+ messages in thread
* Re: [PATCH 01/13] hab: implement interface for i.MX8MQ
2019-06-26 4:58 ` [PATCH 01/13] hab: implement interface " Rouven Czerwinski
@ 2019-06-26 7:31 ` Sascha Hauer
2019-06-26 10:26 ` Roland Hieber
0 siblings, 1 reply; 21+ messages in thread
From: Sascha Hauer @ 2019-06-26 7:31 UTC (permalink / raw)
To: Rouven Czerwinski; +Cc: barebox
On Wed, Jun 26, 2019 at 06:58:42AM +0200, Rouven Czerwinski wrote:
> The HAB interface for i.MX8MQ only implements the retrieval of status
> and events. The SoC status is retrieved using the TF-A SIP API found in
> the downstream imx TF-A. After calling into the TF-A the passed data
> structures need to be invalidated, since otherwise the cached zero value
> is used.
> Currently the TF-A report event call only supports FAILURE events.
> Testing the TF-A with other event types resulted in a freeze in the
> bootrom code, which was not investigated further.
> We instead walk the memory containing the events and retrieve the events
> ourselves. They are exposed using the same API.
>
> Signed-off-by: Rouven Czerwinski <r.czerwinski@pengutronix.de>
> ---
> +{
> + return habv4_get_status(&hab_smc_ops);
> +}
> +
> +static int init_imx8_hab_get_status(void)
> +{
> + int ret = 0;
> +
> + if (cpu_is_mx8mq())
> + ret = imx8_hab_get_status();
> + else
> + return 0;
> +
> + /*
> + * Nobody will check the return value if there were HAB errors, but the
> + * initcall will fail spectaculously with a strange error message.
> + */
> + if (ret == -EPERM)
> + return 0;
Maybe just ignore the return value of imx8_hab_get_status() completely
and just add a comment that this is called for error printing only here?
Sascha
--
Pengutronix e.K. | |
Industrial Linux Solutions | http://www.pengutronix.de/ |
Peiner Str. 6-8, 31137 Hildesheim, Germany | Phone: +49-5121-206917-0 |
Amtsgericht Hildesheim, HRA 2686 | Fax: +49-5121-206917-5555 |
_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox
^ permalink raw reply [flat|nested] 21+ messages in thread
* Re: [PATCH 07/13] scripts: imx: support signing for i.MX8MQ
2019-06-26 4:58 ` [PATCH 07/13] scripts: imx: support signing for i.MX8MQ Rouven Czerwinski
@ 2019-06-26 7:51 ` Sascha Hauer
2019-07-02 5:47 ` Rouven Czerwinski
0 siblings, 1 reply; 21+ messages in thread
From: Sascha Hauer @ 2019-06-26 7:51 UTC (permalink / raw)
To: Rouven Czerwinski; +Cc: barebox
On Wed, Jun 26, 2019 at 06:58:48AM +0200, Rouven Czerwinski wrote:
> quiet_cmd_kwb_image = KWB $@
> cmd_kwb_image = scripts/kwbimage -p $< $(OPTS_$(@F)) -o $@
> diff --git a/scripts/imx/imx-image.c b/scripts/imx/imx-image.c
> index a7f1421..7169bf7 100644
> --- a/scripts/imx/imx-image.c
> +++ b/scripts/imx/imx-image.c
> @@ -315,6 +315,17 @@ static size_t add_header_v2(const struct config_data *data, void *buf)
> uint32_t loadaddr = data->image_load_addr;
> uint32_t imagesize = data->load_size;
>
> + if (data->cpu_type == IMX_CPU_IMX8MQ) {
> + /*
> + * If singing is enabled on IMX8MQ, the linker script reserves a
Make sure singing is not enabled without a speaker connected ;)
> + * CSF_LEN aligned section directly after the PBL,
> + * only load and sign this area of the data.
> + */
> + imagesize = roundup(data->pbl_code_size + HEADER_LEN, 0x4);
> + if (data->csf)
> + imagesize = roundup(imagesize, 0x1000);
> + }
> +
> buf += offset;
> hdr = buf;
>
> @@ -333,14 +344,22 @@ static size_t add_header_v2(const struct config_data *data, void *buf)
> hdr->self = loadaddr + offset;
>
> hdr->boot_data.start = loadaddr;
> - if (data->max_load_size && imagesize > data->max_load_size)
> + if (!data->csf && data->max_load_size
> + && imagesize > data->max_load_size)
> hdr->boot_data.size = data->max_load_size;
> else
> hdr->boot_data.size = imagesize;
>
> - if (data->csf) {
> + if (data->sign_image) {
> hdr->csf = loadaddr + imagesize;
> hdr->boot_data.size += CSF_LEN;
> + } else if (data->cpu_type == IMX_CPU_IMX8MQ && data->csf) {
> + /*
> + * For i.MX8 the CSF space is added via the linker script, so
> + * the CSF length needs to be added if HABV4 is enabled but
> + * signing is not.
> + */
> + hdr->boot_data.size += CSF_LEN;
> }
>
> hdr->dcd_header.tag = TAG_DCD_HEADER;
> @@ -546,6 +565,7 @@ static int hab_sign(struct config_data *data)
> char *cst;
> void *buf;
> size_t csf_space = CSF_LEN;
> + unsigned int offset = 0;
>
> cst = getenv("CST");
> if (!cst)
> @@ -620,6 +640,9 @@ static int hab_sign(struct config_data *data)
> return -errno;
> }
>
> + printf("--- CSF START ---\n");
> + printf("%s\n", data->csf);
> + printf("--- CSF END ---\n");
> fwrite(data->csf, 1, strlen(data->csf) + 1, f);
>
> pclose(f);
> @@ -672,13 +695,36 @@ static int hab_sign(struct config_data *data)
> return -errno;
> }
>
> - outfd = open(data->outfile, O_WRONLY | O_APPEND);
> + /*
> + * For i.MX8, write into the reserved CSF section
> + */
> + if (data->cpu_type == IMX_CPU_IMX8MQ)
> + outfd = open(data->outfile, O_WRONLY);
> + else
> + outfd = open(data->outfile, O_WRONLY | O_APPEND);
> +
> if (outfd < 0) {
> fprintf(stderr, "Cannot open %s for writing: %s\n", data->outfile,
> strerror(errno));
> exit(1);
> }
>
> + if (data->cpu_type == IMX_CPU_IMX8MQ) {
> + /*
> + * For i.MX8 insert the CSF data into the reserved CSF area
> + * right behind the PBL
> + */
> + offset = roundup(data->header_gap + data->pbl_code_size +
> + HEADER_LEN, 0x1000);
> + if (data->signed_hdmi_firmware_file)
> + offset += PLUGIN_HDMI_SIZE;
> +
> + if (lseek(outfd, offset, SEEK_SET) < 0) {
> + perror("lseek");
> + exit(1);
> + }
> + }
> +
> ret = xwrite(outfd, buf, csf_space);
> if (ret < 0) {
> fprintf(stderr, "write failed: %s\n", strerror(errno));
> @@ -743,7 +789,6 @@ int main(int argc, char *argv[])
> int outfd;
> int dcd_only = 0;
> int now = 0;
> - int sign_image = 0;
> int i, header_copies;
> int add_barebox_header;
> uint32_t barebox_image_size = 0;
> @@ -760,7 +805,7 @@ int main(int argc, char *argv[])
>
> prgname = argv[0];
>
> - while ((opt = getopt(argc, argv, "c:hf:o:bduse")) != -1) {
> + while ((opt = getopt(argc, argv, "c:hf:o:p:bduse")) != -1) {
I'm missing the hunk for the usage() function ;)
> switch (opt) {
> case 'c':
> configfile = optarg;
> @@ -771,6 +816,9 @@ int main(int argc, char *argv[])
> case 'o':
> data.outfile = optarg;
> break;
> + case 'p':
> + data.pbl_code_size = strtoul(optarg, NULL, 0);
> + break;
> case 'b':
> add_barebox_header = 1;
> break;
> @@ -778,7 +826,7 @@ int main(int argc, char *argv[])
> dcd_only = 1;
> break;
> case 's':
> - sign_image = 1;
> + data.sign_image = 1;
Storing sign_image in struct config_data could be an extra patch to make
this one a bit smaller.
> break;
> case 'u':
> create_usb_image = 1;
> @@ -832,14 +880,12 @@ int main(int argc, char *argv[])
> if (ret)
> exit(1);
>
> - if (data.max_load_size && (sign_image || data.encrypt_image)) {
> + if (data.max_load_size && (data.encrypt_image || data.csf)
> + && data.cpu_type != IMX_CPU_IMX8MQ) {
> fprintf(stderr, "Specifying max_load_size is incompatible with HAB signing/encrypting\n");
> exit(1);
> }
>
> - if (!sign_image)
> - data.csf = NULL;
Why is this no longer necessary with this patch? Was it unnecessary
before aswell? Then this might be worth an extra patch.
Sascha
--
Pengutronix e.K. | |
Industrial Linux Solutions | http://www.pengutronix.de/ |
Peiner Str. 6-8, 31137 Hildesheim, Germany | Phone: +49-5121-206917-0 |
Amtsgericht Hildesheim, HRA 2686 | Fax: +49-5121-206917-5555 |
_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox
^ permalink raw reply [flat|nested] 21+ messages in thread
* Re: [PATCH 10/13] arm: uncompress: verify sha256 if enabled
2019-06-26 4:58 ` [PATCH 10/13] arm: uncompress: verify sha256 if enabled Rouven Czerwinski
@ 2019-06-26 7:52 ` Sascha Hauer
2019-07-01 6:19 ` Rouven Czerwinski
0 siblings, 1 reply; 21+ messages in thread
From: Sascha Hauer @ 2019-06-26 7:52 UTC (permalink / raw)
To: Rouven Czerwinski; +Cc: barebox
On Wed, Jun 26, 2019 at 06:58:51AM +0200, Rouven Czerwinski wrote:
> Add piggydata verification before the ARM uncompress function.
> This calculates the sha256sum of the compressed barebox binary and only
> continues if the builtin sha256sum matches the calculated sha256sum.
>
> Signed-off-by: Rouven Czerwinski <r.czerwinski@pengutronix.de>
> ---
> arch/arm/cpu/uncompress.c | 18 +++++++++++++++++-
> 1 file changed, 17 insertions(+), 1 deletion(-)
>
> diff --git a/arch/arm/cpu/uncompress.c b/arch/arm/cpu/uncompress.c
> index e527165..ce5f2c1 100644
> --- a/arch/arm/cpu/uncompress.c
> +++ b/arch/arm/cpu/uncompress.c
> @@ -42,14 +42,18 @@ unsigned long free_mem_end_ptr;
> extern unsigned char input_data[];
> extern unsigned char input_data_end[];
>
> +extern unsigned char sha_sum[];
> +extern unsigned char sha_sum_end[];
> +
> void __noreturn barebox_multi_pbl_start(unsigned long membase,
> unsigned long memsize, void *boarddata)
> {
> - uint32_t pg_len, uncompressed_len;
> + uint32_t pg_len, uncompressed_len, pbl_hash_len;
> void __noreturn (*barebox)(unsigned long, unsigned long, void *);
> unsigned long endmem = membase + memsize;
> unsigned long barebox_base;
> void *pg_start, *pg_end;
> + void *pbl_hash_start, *pbl_hash_end;
> unsigned long pc = get_pc();
>
> pg_start = input_data + global_variable_offset();
> @@ -92,6 +96,18 @@ void __noreturn barebox_multi_pbl_start(unsigned long membase,
> pr_debug("uncompressing barebox binary at 0x%p (size 0x%08x) to 0x%08lx (uncompressed size: 0x%08x)\n",
> pg_start, pg_len, barebox_base, uncompressed_len);
>
> + if (IS_ENABLED(CONFIG_PBL_VERIFY_PIGGY)) {
> + pbl_hash_start = sha_sum + global_variable_offset();
> + pbl_hash_end = sha_sum_end + global_variable_offset();
> + pbl_hash_len = pbl_hash_end - pbl_hash_start;
> + if (pbl_barebox_verify(pg_start, pg_len, pbl_hash_start,
> + pbl_hash_len) != 0) {
> + putc_ll('!');
> + pr_err("hash mismatch, refusing to decompress");
> + panic("hash mismatch, refusing to decompress");
Isn't printing the string in panic() enough?
Sascha
--
Pengutronix e.K. | |
Industrial Linux Solutions | http://www.pengutronix.de/ |
Peiner Str. 6-8, 31137 Hildesheim, Germany | Phone: +49-5121-206917-0 |
Amtsgericht Hildesheim, HRA 2686 | Fax: +49-5121-206917-5555 |
_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox
^ permalink raw reply [flat|nested] 21+ messages in thread
* Re: [PATCH 01/13] hab: implement interface for i.MX8MQ
2019-06-26 7:31 ` Sascha Hauer
@ 2019-06-26 10:26 ` Roland Hieber
0 siblings, 0 replies; 21+ messages in thread
From: Roland Hieber @ 2019-06-26 10:26 UTC (permalink / raw)
To: Sascha Hauer; +Cc: barebox, Rouven Czerwinski
On Wed, Jun 26, 2019 at 09:31:14AM +0200, Sascha Hauer wrote:
> On Wed, Jun 26, 2019 at 06:58:42AM +0200, Rouven Czerwinski wrote:
> > The HAB interface for i.MX8MQ only implements the retrieval of status
> > and events. The SoC status is retrieved using the TF-A SIP API found in
> > the downstream imx TF-A. After calling into the TF-A the passed data
> > structures need to be invalidated, since otherwise the cached zero value
> > is used.
> > Currently the TF-A report event call only supports FAILURE events.
> > Testing the TF-A with other event types resulted in a freeze in the
> > bootrom code, which was not investigated further.
> > We instead walk the memory containing the events and retrieve the events
> > ourselves. They are exposed using the same API.
> >
> > Signed-off-by: Rouven Czerwinski <r.czerwinski@pengutronix.de>
> > ---
> > +{
> > + return habv4_get_status(&hab_smc_ops);
> > +}
> > +
> > +static int init_imx8_hab_get_status(void)
> > +{
> > + int ret = 0;
> > +
> > + if (cpu_is_mx8mq())
> > + ret = imx8_hab_get_status();
> > + else
> > + return 0;
> > +
> > + /*
> > + * Nobody will check the return value if there were HAB errors, but the
> > + * initcall will fail spectaculously with a strange error message.
> > + */
> > + if (ret == -EPERM)
> > + return 0;
>
> Maybe just ignore the return value of imx8_hab_get_status() completely
> and just add a comment that this is called for error printing only here?
This was probably copied from the i.MX6 HAB implementation, feel free to
change it there too.
- Roland
--
Roland Hieber | r.hieber@pengutronix.de |
Pengutronix e.K. | https://www.pengutronix.de/ |
Peiner Str. 6-8, 31137 Hildesheim | Phone: +49-5121-206917-5086 |
Amtsgericht Hildesheim, HRA 2686 | Fax: +49-5121-206917-5555 |
_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox
^ permalink raw reply [flat|nested] 21+ messages in thread
* Re: [PATCH 10/13] arm: uncompress: verify sha256 if enabled
2019-06-26 7:52 ` Sascha Hauer
@ 2019-07-01 6:19 ` Rouven Czerwinski
2019-07-01 6:45 ` Sascha Hauer
0 siblings, 1 reply; 21+ messages in thread
From: Rouven Czerwinski @ 2019-07-01 6:19 UTC (permalink / raw)
To: Sascha Hauer; +Cc: barebox
On Wed, 2019-06-26 at 09:52 +0200, Sascha Hauer wrote:
> On Wed, Jun 26, 2019 at 06:58:51AM +0200, Rouven Czerwinski wrote:
> > Add piggydata verification before the ARM uncompress function.
> > This calculates the sha256sum of the compressed barebox binary and
> > only
> > continues if the builtin sha256sum matches the calculated
> > sha256sum.
> >
> > Signed-off-by: Rouven Czerwinski <r.czerwinski@pengutronix.de>
> > ---
> > arch/arm/cpu/uncompress.c | 18 +++++++++++++++++-
> > 1 file changed, 17 insertions(+), 1 deletion(-)
> >
> > diff --git a/arch/arm/cpu/uncompress.c b/arch/arm/cpu/uncompress.c
> > index e527165..ce5f2c1 100644
> > --- a/arch/arm/cpu/uncompress.c
> > +++ b/arch/arm/cpu/uncompress.c
> > @@ -42,14 +42,18 @@ unsigned long free_mem_end_ptr;
> > extern unsigned char input_data[];
> > extern unsigned char input_data_end[];
> >
> > +extern unsigned char sha_sum[];
> > +extern unsigned char sha_sum_end[];
> > +
> > void __noreturn barebox_multi_pbl_start(unsigned long membase,
> > unsigned long memsize, void *boarddata)
> > {
> > - uint32_t pg_len, uncompressed_len;
> > + uint32_t pg_len, uncompressed_len, pbl_hash_len;
> > void __noreturn (*barebox)(unsigned long, unsigned long, void
> > *);
> > unsigned long endmem = membase + memsize;
> > unsigned long barebox_base;
> > void *pg_start, *pg_end;
> > + void *pbl_hash_start, *pbl_hash_end;
> > unsigned long pc = get_pc();
> >
> > pg_start = input_data + global_variable_offset();
> > @@ -92,6 +96,18 @@ void __noreturn barebox_multi_pbl_start(unsigned
> > long membase,
> > pr_debug("uncompressing barebox binary at 0x%p (size 0x%08x) to
> > 0x%08lx (uncompressed size: 0x%08x)\n",
> > pg_start, pg_len, barebox_base,
> > uncompressed_len);
> >
> > + if (IS_ENABLED(CONFIG_PBL_VERIFY_PIGGY)) {
> > + pbl_hash_start = sha_sum + global_variable_offset();
> > + pbl_hash_end = sha_sum_end + global_variable_offset();
> > + pbl_hash_len = pbl_hash_end - pbl_hash_start;
> > + if (pbl_barebox_verify(pg_start, pg_len,
> > pbl_hash_start,
> > + pbl_hash_len) != 0) {
> > + putc_ll('!');
> > + pr_err("hash mismatch, refusing to
> > decompress");
> > + panic("hash mismatch, refusing to decompress");
>
> Isn't printing the string in panic() enough?
Unfortunately not, pbl/misc.c defines panic as:
void __noreturn panic(const char *fmt, ...)
{
while(1);
}
Rouven Czerwinski
--
Pengutronix e.K. | |
Industrial Linux Solutions | https://www.pengutronix.de/ |
Peiner Str. 6-8, 31137 Hildesheim, Germany | Phone: +49-5121-206917-0 |
Amtsgericht Hildesheim, HRA 2686 | Fax: +49-5121-206917-5555 |
_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox
^ permalink raw reply [flat|nested] 21+ messages in thread
* Re: [PATCH 10/13] arm: uncompress: verify sha256 if enabled
2019-07-01 6:19 ` Rouven Czerwinski
@ 2019-07-01 6:45 ` Sascha Hauer
0 siblings, 0 replies; 21+ messages in thread
From: Sascha Hauer @ 2019-07-01 6:45 UTC (permalink / raw)
To: Rouven Czerwinski; +Cc: barebox
On Mon, Jul 01, 2019 at 08:19:13AM +0200, Rouven Czerwinski wrote:
> On Wed, 2019-06-26 at 09:52 +0200, Sascha Hauer wrote:
> > On Wed, Jun 26, 2019 at 06:58:51AM +0200, Rouven Czerwinski wrote:
> > > Add piggydata verification before the ARM uncompress function.
> > > This calculates the sha256sum of the compressed barebox binary and
> > > only
> > > continues if the builtin sha256sum matches the calculated
> > > sha256sum.
> > >
> > > Signed-off-by: Rouven Czerwinski <r.czerwinski@pengutronix.de>
> > > ---
> > > arch/arm/cpu/uncompress.c | 18 +++++++++++++++++-
> > > 1 file changed, 17 insertions(+), 1 deletion(-)
> > >
> > > diff --git a/arch/arm/cpu/uncompress.c b/arch/arm/cpu/uncompress.c
> > > index e527165..ce5f2c1 100644
> > > --- a/arch/arm/cpu/uncompress.c
> > > +++ b/arch/arm/cpu/uncompress.c
> > > @@ -42,14 +42,18 @@ unsigned long free_mem_end_ptr;
> > > extern unsigned char input_data[];
> > > extern unsigned char input_data_end[];
> > >
> > > +extern unsigned char sha_sum[];
> > > +extern unsigned char sha_sum_end[];
> > > +
> > > void __noreturn barebox_multi_pbl_start(unsigned long membase,
> > > unsigned long memsize, void *boarddata)
> > > {
> > > - uint32_t pg_len, uncompressed_len;
> > > + uint32_t pg_len, uncompressed_len, pbl_hash_len;
> > > void __noreturn (*barebox)(unsigned long, unsigned long, void
> > > *);
> > > unsigned long endmem = membase + memsize;
> > > unsigned long barebox_base;
> > > void *pg_start, *pg_end;
> > > + void *pbl_hash_start, *pbl_hash_end;
> > > unsigned long pc = get_pc();
> > >
> > > pg_start = input_data + global_variable_offset();
> > > @@ -92,6 +96,18 @@ void __noreturn barebox_multi_pbl_start(unsigned
> > > long membase,
> > > pr_debug("uncompressing barebox binary at 0x%p (size 0x%08x) to
> > > 0x%08lx (uncompressed size: 0x%08x)\n",
> > > pg_start, pg_len, barebox_base,
> > > uncompressed_len);
> > >
> > > + if (IS_ENABLED(CONFIG_PBL_VERIFY_PIGGY)) {
> > > + pbl_hash_start = sha_sum + global_variable_offset();
> > > + pbl_hash_end = sha_sum_end + global_variable_offset();
> > > + pbl_hash_len = pbl_hash_end - pbl_hash_start;
> > > + if (pbl_barebox_verify(pg_start, pg_len,
> > > pbl_hash_start,
> > > + pbl_hash_len) != 0) {
> > > + putc_ll('!');
> > > + pr_err("hash mismatch, refusing to
> > > decompress");
> > > + panic("hash mismatch, refusing to decompress");
> >
> > Isn't printing the string in panic() enough?
>
> Unfortunately not, pbl/misc.c defines panic as:
>
> void __noreturn panic(const char *fmt, ...)
> {
> while(1);
> }
Then maybe we should add the printf here. We have static inline wrappers
for printf when the cosnole is disabled in the PBL.
Sascha
--
Pengutronix e.K. | |
Industrial Linux Solutions | http://www.pengutronix.de/ |
Peiner Str. 6-8, 31137 Hildesheim, Germany | Phone: +49-5121-206917-0 |
Amtsgericht Hildesheim, HRA 2686 | Fax: +49-5121-206917-5555 |
_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox
^ permalink raw reply [flat|nested] 21+ messages in thread
* Re: [PATCH 07/13] scripts: imx: support signing for i.MX8MQ
2019-06-26 7:51 ` Sascha Hauer
@ 2019-07-02 5:47 ` Rouven Czerwinski
0 siblings, 0 replies; 21+ messages in thread
From: Rouven Czerwinski @ 2019-07-02 5:47 UTC (permalink / raw)
To: Sascha Hauer; +Cc: barebox
On Wed, 2019-06-26 at 09:51 +0200, Sascha Hauer wrote:
> On Wed, Jun 26, 2019 at 06:58:48AM +0200, Rouven Czerwinski wrote:
> > quiet_cmd_kwb_image = KWB $@
> > cmd_kwb_image = scripts/kwbimage -p $< $(OPTS_$(@F)) -o $@
> > diff --git a/scripts/imx/imx-image.c b/scripts/imx/imx-image.c
> > index a7f1421..7169bf7 100644
> > --- a/scripts/imx/imx-image.c
> > +++ b/scripts/imx/imx-image.c
> > @@ -315,6 +315,17 @@ static size_t add_header_v2(const struct
> > config_data *data, void *buf)
> > uint32_t loadaddr = data->image_load_addr;
> > uint32_t imagesize = data->load_size;
> >
> > + if (data->cpu_type == IMX_CPU_IMX8MQ) {
> > + /*
> > + * If singing is enabled on IMX8MQ, the linker script
> > reserves a
>
> Make sure singing is not enabled without a speaker connected ;)
>
> > + * CSF_LEN aligned section directly after the PBL,
> > + * only load and sign this area of the data.
> > + */
> > + imagesize = roundup(data->pbl_code_size + HEADER_LEN,
> > 0x4);
> > + if (data->csf)
> > + imagesize = roundup(imagesize, 0x1000);
> > + }
> > +
> > buf += offset;
> > hdr = buf;
> >
> > @@ -333,14 +344,22 @@ static size_t add_header_v2(const struct
> > config_data *data, void *buf)
> > hdr->self = loadaddr + offset;
> >
> > hdr->boot_data.start = loadaddr;
> > - if (data->max_load_size && imagesize > data->max_load_size)
> > + if (!data->csf && data->max_load_size
> > + && imagesize > data->max_load_size)
> > hdr->boot_data.size = data->max_load_size;
> > else
> > hdr->boot_data.size = imagesize;
> >
> > - if (data->csf) {
> > + if (data->sign_image) {
> > hdr->csf = loadaddr + imagesize;
> > hdr->boot_data.size += CSF_LEN;
> > + } else if (data->cpu_type == IMX_CPU_IMX8MQ && data->csf) {
> > + /*
> > + * For i.MX8 the CSF space is added via the linker
> > script, so
> > + * the CSF length needs to be added if HABV4 is enabled
> > but
> > + * signing is not.
> > + */
> > + hdr->boot_data.size += CSF_LEN;
> > }
> >
> > hdr->dcd_header.tag = TAG_DCD_HEADER;
> > @@ -546,6 +565,7 @@ static int hab_sign(struct config_data *data)
> > char *cst;
> > void *buf;
> > size_t csf_space = CSF_LEN;
> > + unsigned int offset = 0;
> >
> > cst = getenv("CST");
> > if (!cst)
> > @@ -620,6 +640,9 @@ static int hab_sign(struct config_data *data)
> > return -errno;
> > }
> >
> > + printf("--- CSF START ---\n");
> > + printf("%s\n", data->csf);
> > + printf("--- CSF END ---\n");
> > fwrite(data->csf, 1, strlen(data->csf) + 1, f);
> >
> > pclose(f);
> > @@ -672,13 +695,36 @@ static int hab_sign(struct config_data *data)
> > return -errno;
> > }
> >
> > - outfd = open(data->outfile, O_WRONLY | O_APPEND);
> > + /*
> > + * For i.MX8, write into the reserved CSF section
> > + */
> > + if (data->cpu_type == IMX_CPU_IMX8MQ)
> > + outfd = open(data->outfile, O_WRONLY);
> > + else
> > + outfd = open(data->outfile, O_WRONLY | O_APPEND);
> > +
> > if (outfd < 0) {
> > fprintf(stderr, "Cannot open %s for writing: %s\n",
> > data->outfile,
> > strerror(errno));
> > exit(1);
> > }
> >
> > + if (data->cpu_type == IMX_CPU_IMX8MQ) {
> > + /*
> > + * For i.MX8 insert the CSF data into the reserved CSF
> > area
> > + * right behind the PBL
> > + */
> > + offset = roundup(data->header_gap + data->pbl_code_size
> > +
> > + HEADER_LEN, 0x1000);
> > + if (data->signed_hdmi_firmware_file)
> > + offset += PLUGIN_HDMI_SIZE;
> > +
> > + if (lseek(outfd, offset, SEEK_SET) < 0) {
> > + perror("lseek");
> > + exit(1);
> > + }
> > + }
> > +
> > ret = xwrite(outfd, buf, csf_space);
> > if (ret < 0) {
> > fprintf(stderr, "write failed: %s\n", strerror(errno));
> > @@ -743,7 +789,6 @@ int main(int argc, char *argv[])
> > int outfd;
> > int dcd_only = 0;
> > int now = 0;
> > - int sign_image = 0;
> > int i, header_copies;
> > int add_barebox_header;
> > uint32_t barebox_image_size = 0;
> > @@ -760,7 +805,7 @@ int main(int argc, char *argv[])
> >
> > prgname = argv[0];
> >
> > - while ((opt = getopt(argc, argv, "c:hf:o:bduse")) != -1) {
> > + while ((opt = getopt(argc, argv, "c:hf:o:p:bduse")) != -1) {
>
> I'm missing the hunk for the usage() function ;)
>
> > switch (opt) {
> > case 'c':
> > configfile = optarg;
> > @@ -771,6 +816,9 @@ int main(int argc, char *argv[])
> > case 'o':
> > data.outfile = optarg;
> > break;
> > + case 'p':
> > + data.pbl_code_size = strtoul(optarg, NULL, 0);
> > + break;
> > case 'b':
> > add_barebox_header = 1;
> > break;
> > @@ -778,7 +826,7 @@ int main(int argc, char *argv[])
> > dcd_only = 1;
> > break;
> > case 's':
> > - sign_image = 1;
> > + data.sign_image = 1;
>
> Storing sign_image in struct config_data could be an extra patch to
> make
> this one a bit smaller.
>
> > break;
> > case 'u':
> > create_usb_image = 1;
> > @@ -832,14 +880,12 @@ int main(int argc, char *argv[])
> > if (ret)
> > exit(1);
> >
> > - if (data.max_load_size && (sign_image || data.encrypt_image)) {
> > + if (data.max_load_size && (data.encrypt_image || data.csf)
> > + && data.cpu_type != IMX_CPU_IMX8MQ) {
> > fprintf(stderr, "Specifying max_load_size is
> > incompatible with HAB signing/encrypting\n");
> > exit(1);
> > }
> >
> > - if (!sign_image)
> > - data.csf = NULL;
>
> Why is this no longer necessary with this patch? Was it unnecessary
> before aswell? Then this might be worth an extra patch.
No. I'm now using data->csf and data->sign_image to distinguish the
case where HABv4 is enabled, but signing is not. Since the CSF space is
always added if HABv4 is enabled, imx-image needs to correctly set
boot_data.size, otherwise the piggy_data can't be correctly located
later.
I'll split this out and put the information into the commit message.
Greetings,
Rouven Czerwinski
--
Pengutronix e.K. | |
Industrial Linux Solutions | https://www.pengutronix.de/ |
Peiner Str. 6-8, 31137 Hildesheim, Germany | Phone: +49-5121-206917-0 |
Amtsgericht Hildesheim, HRA 2686 | Fax: +49-5121-206917-5555 |
_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox
^ permalink raw reply [flat|nested] 21+ messages in thread
end of thread, other threads:[~2019-07-02 5:47 UTC | newest]
Thread overview: 21+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2019-06-26 4:58 [PATCH 00/13] HAB for i.MX8MQ Rouven Czerwinski
2019-06-26 4:58 ` [PATCH 01/13] hab: implement interface " Rouven Czerwinski
2019-06-26 7:31 ` Sascha Hauer
2019-06-26 10:26 ` Roland Hieber
2019-06-26 4:58 ` [PATCH 02/13] mach-imx: enable HAB on i.MX8MQ Rouven Czerwinski
2019-06-26 4:58 ` [PATCH 03/13] arm: lib: add CSF section between PBL and piggy Rouven Czerwinski
2019-06-26 4:58 ` [PATCH 04/13] esdhc-pbl: extract header parsing from image start Rouven Czerwinski
2019-06-26 4:58 ` [PATCH 05/13] esdhc-pbl: add piggy load function Rouven Czerwinski
2019-06-26 4:58 ` [PATCH 06/13] sections: fix macro for barebox_pbl_size Rouven Czerwinski
2019-06-26 4:58 ` [PATCH 07/13] scripts: imx: support signing for i.MX8MQ Rouven Czerwinski
2019-06-26 7:51 ` Sascha Hauer
2019-07-02 5:47 ` Rouven Czerwinski
2019-06-26 4:58 ` [PATCH 08/13] images: always build sha256sum into pbl Rouven Czerwinski
2019-06-26 4:58 ` [PATCH 09/13] pbl: add sha256 and piggy verification to PBL Rouven Czerwinski
2019-06-26 4:58 ` [PATCH 10/13] arm: uncompress: verify sha256 if enabled Rouven Czerwinski
2019-06-26 7:52 ` Sascha Hauer
2019-07-01 6:19 ` Rouven Czerwinski
2019-07-01 6:45 ` Sascha Hauer
2019-06-26 4:58 ` [PATCH 11/13] mach-imx: add gencsf header for i.MX8MQ Rouven Czerwinski
2019-06-26 4:58 ` [PATCH 12/13] mach-imx: hab: select piggy verification for i.MX8 Rouven Czerwinski
2019-06-26 4:58 ` [PATCH 13/13] boards: nxp-mx8-evk: rework to different boot flow Rouven Czerwinski
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox