diff options
Diffstat (limited to 'drivers/hab')
-rw-r--r-- | drivers/hab/Makefile | 1 | ||||
-rw-r--r-- | drivers/hab/hab.c | 226 | ||||
-rw-r--r-- | drivers/hab/hab.h | 10 | ||||
-rw-r--r-- | drivers/hab/habv3.c | 19 | ||||
-rw-r--r-- | drivers/hab/habv4.c | 316 |
5 files changed, 377 insertions, 195 deletions
diff --git a/drivers/hab/Makefile b/drivers/hab/Makefile index b169a1346d..61ffa07e04 100644 --- a/drivers/hab/Makefile +++ b/drivers/hab/Makefile @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0-only obj-$(CONFIG_HABV4) += habv4.o obj-$(CONFIG_HABV3) += habv3.o obj-$(CONFIG_HAB) += hab.o diff --git a/drivers/hab/hab.c b/drivers/hab/hab.c index a346e01567..ed091058d8 100644 --- a/drivers/hab/hab.c +++ b/drivers/hab/hab.c @@ -1,27 +1,21 @@ -/* - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; version 2. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - */ +// SPDX-License-Identifier: GPL-2.0-only #define pr_fmt(fmt) "HAB: " fmt #include <common.h> #include <fcntl.h> #include <environment.h> #include <libfile.h> -#include <mach/generic.h> +#include <mach/imx/generic.h> #include <hab.h> -#include <regmap.h> +#include <linux/regmap.h> #include <fs.h> -#include <mach/iim.h> -#include <mach/imx25-fusemap.h> -#include <mach/ocotp.h> -#include <mach/imx6-fusemap.h> +#include <mach/imx/iim.h> +#include <mach/imx/imx25-fusemap.h> +#include <mach/imx/ocotp.h> +#include <mach/imx/imx6-fusemap.h> +#include <mach/imx/ele.h> + +#include "hab.h" bool imx_hab_srk_hash_valid(const void *buf) { @@ -103,7 +97,7 @@ static int imx_hab_permanent_write_enable_iim(int enable) return imx_iim_permanent_write(enable); } -static int imx_hab_lockdown_device_iim(void) +static int imx_hab_lockdown_device_iim(unsigned flags) { return imx_iim_write_field(IMX25_IIM_HAB_TYPE, 3); } @@ -159,7 +153,7 @@ static int imx_hab_permanent_write_enable_ocotp(int enable) return imx_ocotp_permanent_write(enable); } -static int imx_hab_lockdown_device_ocotp(void) +static int imx6_hab_lockdown_device_ocotp(unsigned flags) { int ret; @@ -170,7 +164,22 @@ static int imx_hab_lockdown_device_ocotp(void) return imx_ocotp_write_field(OCOTP_SEC_CONFIG_1, 1); } -static int imx_hab_device_locked_down_ocotp(void) +static int imx8m_hab_lockdown_device_ocotp(unsigned flags) +{ + int ret; + + ret = imx_ocotp_write_field(MX8M_OCOTP_SEC_CONFIG_1, 1); + if (ret < 0) + return ret; + + /* Only i.MX8MQ requires fusing of DIR_BT_DIS */ + if (!cpu_is_mx8mq()) + return ret; + + return imx_ocotp_write_field(MX8MQ_OCOTP_DIR_BT_DIS, 1); +} + +static int imx6_hab_device_locked_down_ocotp(void) { int ret; unsigned int v; @@ -182,13 +191,25 @@ static int imx_hab_device_locked_down_ocotp(void) return v; } +static int imx8m_hab_device_locked_down_ocotp(void) +{ + int ret; + unsigned int v; + + ret = imx_ocotp_read_field(MX8M_OCOTP_SEC_CONFIG_1, &v); + if (ret < 0) + return ret; + + return v; +} + struct imx_hab_ops { - int (*init)(void); int (*write_srk_hash)(const u8 *srk, unsigned flags); int (*read_srk_hash)(u8 *srk); int (*permanent_write_enable)(int enable); - int (*lockdown_device)(void); + int (*lockdown_device)(unsigned flags); int (*device_locked_down)(void); + int (*print_status)(void); }; static struct imx_hab_ops imx_hab_ops_iim = { @@ -197,39 +218,143 @@ static struct imx_hab_ops imx_hab_ops_iim = { .lockdown_device = imx_hab_lockdown_device_iim, .device_locked_down = imx_hab_device_locked_down_iim, .permanent_write_enable = imx_hab_permanent_write_enable_iim, + .print_status = imx25_hab_print_status, }; -static struct imx_hab_ops imx_hab_ops_ocotp = { +static struct imx_hab_ops imx6_hab_ops_ocotp = { .write_srk_hash = imx_hab_write_srk_hash_ocotp, .read_srk_hash = imx_hab_read_srk_hash_ocotp, - .lockdown_device = imx_hab_lockdown_device_ocotp, - .device_locked_down = imx_hab_device_locked_down_ocotp, + .lockdown_device = imx6_hab_lockdown_device_ocotp, + .device_locked_down = imx6_hab_device_locked_down_ocotp, .permanent_write_enable = imx_hab_permanent_write_enable_ocotp, + .print_status = imx6_hab_print_status, }; -static struct imx_hab_ops *imx_get_hab_ops(void) +static struct imx_hab_ops imx8m_hab_ops_ocotp = { + .write_srk_hash = imx_hab_write_srk_hash_ocotp, + .read_srk_hash = imx_hab_read_srk_hash_ocotp, + .lockdown_device = imx8m_hab_lockdown_device_ocotp, + .device_locked_down = imx8m_hab_device_locked_down_ocotp, + .permanent_write_enable = imx_hab_permanent_write_enable_ocotp, + .print_status = imx8m_hab_print_status, +}; + +static int imx_ahab_write_srk_hash(const u8 *__newsrk, unsigned flags) +{ + u32 *newsrk = (u32 *)__newsrk; + u32 resp; + int ret, i; + + if (!(flags & IMX_SRK_HASH_WRITE_PERMANENT)) { + pr_err("Cannot write fuses temporarily\n"); + return -EPERM; + } + + for (i = 0; i < 32 / sizeof(u32); i++) { + ret = ele_write_fuse(0x80 + i, newsrk[i], false, &resp); + if (ret) + pr_err("Writing fuse index 0x%02x failed with %d, response 0x%08x\n", + i, ret, resp); + } + + return 0; +} + +static int imx_ahab_read_srk_hash(u8 *__srk) +{ + u32 *srk = (u32 *)__srk; + u32 resp; + int ret, i; + + for (i = 0; i < SRK_HASH_SIZE / sizeof(uint32_t); i++) { + ret = ele_read_common_fuse(0x80 + i, &srk[i], &resp); + if (ret < 0) + return ret; + } + + return 0; +} + +static int imx_ahab_permanent_write_enable(int enable) +{ + return 0; +} + +static int imx_ahab_lockdown_device(unsigned flags) { - static struct imx_hab_ops *ops, *tmp; + unsigned int lc; int ret; + if (!(flags & IMX_SRK_HASH_WRITE_PERMANENT)) { + pr_err("Cannot write fuses temporarily\n"); + return -EPERM; + } + + lc = imx93_ahab_read_lifecycle(); + if (lc == ELE_LIFECYCLE_OEM_CLOSED) { + pr_info("already OEM closed\n"); + return 0; + } + + if (lc != ELE_LIFECYCLE_OEM_OPEN) { + pr_err("Current lifecycle is NOT OEM open, can't move to OEM closed\n"); + return -EPERM; + } + + ret = ele_forward_lifecycle(ELE_LIFECYCLE_OEM_CLOSED, NULL); + if (ret) { + printf("failed to forward lifecycle to OEM closed\n"); + return ret; + } + + printf("Change to OEM closed successfully\n"); + + return 0; +} + +static int imx_ahab_device_locked_down(void) +{ + return imx93_ahab_read_lifecycle() != ELE_LIFECYCLE_OEM_OPEN; +} + +static int imx_ahab_print_status(void) +{ + int ret; + + ret = ele_print_events(); + if (ret) + pr_err("Cannot read ELE events: %pe\n", ERR_PTR(ret)); + + return ret; +} + +static struct imx_hab_ops imx93_ahab_ops = { + .write_srk_hash = imx_ahab_write_srk_hash, + .read_srk_hash = imx_ahab_read_srk_hash, + .lockdown_device = imx_ahab_lockdown_device, + .device_locked_down = imx_ahab_device_locked_down, + .permanent_write_enable = imx_ahab_permanent_write_enable, + .print_status = imx_ahab_print_status, +}; + +static struct imx_hab_ops *imx_get_hab_ops(void) +{ + static struct imx_hab_ops *ops; + if (ops) return ops; - 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() || cpu_is_mx8mq())) - tmp = &imx_hab_ops_ocotp; + if (IS_ENABLED(CONFIG_HABV3) && cpu_is_mx25()) + ops = &imx_hab_ops_iim; + else if (IS_ENABLED(CONFIG_HABV4) && cpu_is_mx6()) + ops = &imx6_hab_ops_ocotp; + else if (IS_ENABLED(CONFIG_HABV4) && cpu_is_mx8m()) + ops = &imx8m_hab_ops_ocotp; + else if (IS_ENABLED(CONFIG_AHAB) && cpu_is_mx93()) + ops = &imx93_ahab_ops; else return NULL; - if (tmp->init) { - ret = tmp->init(); - if (ret) - return NULL; - } - - ops = tmp; - return ops; } @@ -327,7 +452,7 @@ int imx_hab_write_srk_hash_hex(const char *srkhash, unsigned flags) int imx_hab_lockdown_device(unsigned flags) { struct imx_hab_ops *ops = imx_get_hab_ops(); - u8 srk[SRK_HASH_SIZE]; + u8 srk[SRK_HASH_SIZE] = {}; int ret; ret = imx_hab_read_srk_hash(srk); @@ -348,7 +473,7 @@ int imx_hab_lockdown_device(unsigned flags) return ret; } - ret = ops->lockdown_device(); + ret = ops->lockdown_device(flags); if (flags & IMX_SRK_HASH_WRITE_PERMANENT) ops->permanent_write_enable(0); @@ -360,5 +485,26 @@ int imx_hab_device_locked_down(void) { struct imx_hab_ops *ops = imx_get_hab_ops(); + if (!ops) + return -ENOSYS; + return ops->device_locked_down(); } + +int imx_hab_print_status(void) +{ + struct imx_hab_ops *ops = imx_get_hab_ops(); + + if (!ops) + return -ENOSYS; + + return ops->print_status(); +} + +static int init_imx_hab_print_status(void) +{ + imx_hab_print_status(); + + return 0; +} +postmmu_initcall(init_imx_hab_print_status); diff --git a/drivers/hab/hab.h b/drivers/hab/hab.h new file mode 100644 index 0000000000..7be0e8386b --- /dev/null +++ b/drivers/hab/hab.h @@ -0,0 +1,10 @@ +// SPDX-License-Identifier: GPL-2.0-only + +#ifndef __DRIVER_HAB_HAB_H +#define __DRIVER_HAB_HAB_H + +int imx25_hab_print_status(void); +int imx6_hab_print_status(void); +int imx8m_hab_print_status(void); + +#endif /* __DRIVER_HAB_HAB_H */ diff --git a/drivers/hab/habv3.c b/drivers/hab/habv3.c index f3f94bc44c..e28e9998d7 100644 --- a/drivers/hab/habv3.c +++ b/drivers/hab/habv3.c @@ -1,20 +1,11 @@ -/* - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; version 2. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - */ +// SPDX-License-Identifier: GPL-2.0-only #define pr_fmt(fmt) "HABv3: " fmt #include <init.h> #include <common.h> #include <hab.h> #include <io.h> -#include <mach/generic.h> +#include <mach/imx/generic.h> struct hab_status { u8 value; @@ -78,11 +69,7 @@ static int imx_habv3_get_status(uint32_t status) return -EPERM; } -int imx25_hab_get_status(void) +int imx25_hab_print_status(void) { - if (!cpu_is_mx25()) - return 0; - return imx_habv3_get_status(readl(IOMEM(0x780018d4))); } -postmmu_initcall(imx25_hab_get_status); diff --git a/drivers/hab/habv4.c b/drivers/hab/habv4.c index f0a087d1a8..0f5618116e 100644 --- a/drivers/hab/habv4.c +++ b/drivers/hab/habv4.c @@ -1,19 +1,8 @@ +// SPDX-License-Identifier: GPL-2.0-or-later /* * Copyright (C) 2014, 2015 Marc Kleine-Budde <mkl@pengutronix.de> * Copyright (C) 2010 Freescale Semiconductor, Inc. * - * See file CREDITS for list of people who contributed to this - * project. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of - * the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. */ #define pr_fmt(fmt) "HABv4: " fmt @@ -22,13 +11,18 @@ #include <hab.h> #include <init.h> #include <types.h> +#include <mmu.h> +#include <dma.h> +#include <zero_page.h> +#include <linux/sizes.h> #include <linux/arm-smccc.h> #include <asm/cache.h> -#include <mach/generic.h> -#include <mach/imx8mq.h> +#include <mach/imx/generic.h> +#include <mach/imx/imx8mq.h> + +#include "hab.h" -#define HABV4_RVT_IMX28 0xffff8af8 #define HABV4_RVT_IMX6_OLD 0x00000094 #define HABV4_RVT_IMX6_NEW 0x00000098 #define HABV4_RVT_IMX6UL 0x00000100 @@ -76,18 +70,6 @@ enum hab_config { HAB_CONFIG_CLOSED = 0xcc, /* Secure IC */ }; -/* State definitions */ -enum hab_state { - HAB_STATE_INITIAL = 0x33, /* Initialising state (transitory) */ - HAB_STATE_CHECK = 0x55, /* Check state (non-secure) */ - HAB_STATE_NONSECURE = 0x66, /* Non-secure state */ - HAB_STATE_TRUSTED = 0x99, /* Trusted state */ - HAB_STATE_SECURE = 0xaa, /* Secure state */ - HAB_STATE_FAIL_SOFT = 0xcc, /* Soft fail state */ - HAB_STATE_FAIL_HARD = 0xff, /* Hard fail state (terminal) */ - HAB_STATE_NONE = 0xf0, /* No security state machine */ -}; - enum hab_reason { HAB_REASON_RSN_ANY = 0x00, /* Match any reason */ HAB_REASON_UNS_COMMAND = 0x03, /* Unsupported command */ @@ -164,33 +146,79 @@ struct hab_header { uint8_t par; } __packed; -typedef enum hab_status hab_loader_callback_fn(void **start, uint32_t *bytes, const void *boot_data); +typedef enum hab_status hab_loader_callback_fn(void **start, size_t *bytes, const void *boot_data); +typedef void hab_image_entry_fn(void); +/* + * This table is constructed from the NXP manual "High Assurance Boot + * Version 4 Application Programming Interface Reference Manual", + * section 4.5 ROM vector table. Revision 1.4 + */ struct habv4_rvt { struct hab_header header; enum hab_status (*entry)(void); enum hab_status (*exit)(void); - enum hab_status (*check_target)(enum hab_target target, const void *start, uint32_t bytes); - void *(*authenticate_image)(uint8_t cid, uint32_t ivt_offset, void **start, uint32_t *bytes, hab_loader_callback_fn *loader); - enum hab_status (*run_dcd)(const void *dcd); - enum hab_status (*run_csf)(const void *csf, uint8_t cid); + enum hab_status (*check_target)(enum hab_target target, const void *start, size_t bytes); + void *(*authenticate_image)(uint8_t cid, ptrdiff_t ivt_offset, void **start, size_t *bytes, hab_loader_callback_fn *loader); + enum hab_status (*run_dcd)(const uint8_t *dcd); + enum hab_status (*run_csf)(const uint8_t *csf, uint8_t cid, uint32_t srkmask); enum hab_status (*assert)(enum hab_assertion assertion, const void *data, uint32_t count); - enum hab_status (*report_event)(enum hab_status status, uint32_t index, void *event, uint32_t *bytes); - enum hab_status (*report_status)(enum hab_config *config, enum hab_state *state); + enum hab_status (*report_event)(enum hab_status status, uint32_t index, uint8_t *event, size_t *bytes); + enum hab_status (*report_status)(enum hab_config *config, enum habv4_state *state); void (*failsafe)(void); + hab_image_entry_fn* (* authenticate_image_no_dcd)(uint8_t cid, ptrdiff_t ivt_offset, void **start, size_t *bytes, hab_loader_callback_fn *loader); + uint32_t (*get_version)(void); + enum hab_status (*authenticate_container)(uint8_t cid, ptrdiff_t ivt_offset, void **start, size_t *bytes, hab_loader_callback_fn *loader, uint32_t srkmask, int skip_dcd); } __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 +#define FSL_SIP_HAB 0xC2000007 + +/* + * These values correspondent to the jump table found in the upstream + * TF-A version 2.10 `imx_hab_handler`, not all HAB rom functions are + * supported yet. + */ +enum hab_sip_cmd { + FSL_SIP_HAB_AUTHENTICATE = 0x00, + FSL_SIP_HAB_ENTRY = 0x01, + FSL_SIP_HAB_EXIT = 0x02, + FSL_SIP_HAB_REPORT_EVENT = 0x03, + FSL_SIP_HAB_REPORT_STATUS = 0x04, + FSL_SIP_HAB_FAILSAFE = 0x05, + FSL_SIP_HAB_CHECK_TARGET = 0x06, + FSL_SIP_HAB_GET_VERSION = 0x07, + FSL_SIP_HAB_AUTH_IMG_NO_DCD = 0x08, +}; + +static enum hab_status hab_sip_report_event(enum hab_status status, + uint32_t index, uint8_t *event, + size_t *bytes) +{ + struct arm_smccc_res res; + + v8_flush_dcache_range((unsigned long)bytes, + (unsigned long)bytes + sizeof(*bytes)); + + if (event) + v8_flush_dcache_range((unsigned long)event, + (unsigned long)event + *bytes); + + arm_smccc_smc(FSL_SIP_HAB, FSL_SIP_HAB_REPORT_EVENT, + (unsigned long)index, (unsigned long)event, + (unsigned long)bytes, 0, 0, 0, &res); + + v8_inv_dcache_range((unsigned long)bytes, + (unsigned long)bytes + sizeof(*bytes)); + + if (event) + v8_inv_dcache_range((unsigned long)event, + (unsigned long)event + *bytes); + + return (enum hab_status)res.a0; +} static enum hab_status hab_sip_report_status(enum hab_config *config, - enum hab_state *state) + enum habv4_state *state) { struct arm_smccc_res res; @@ -213,30 +241,62 @@ static enum hab_status hab_sip_report_status(enum hab_config *config, return (enum hab_status)res.a0; } +static uint32_t hab_sip_get_version(void) +{ + struct arm_smccc_res res; + + arm_smccc_smc(FSL_SIP_HAB, FSL_SIP_HAB_GET_VERSION, 0, 0, 0, 0, 0, 0, &res); + + return (uint32_t)res.a0; +} + +#define HABV4_EVENT_MAX_LEN 0x80 + +#define IMX8MQ_ROM_OCRAM_ADDRESS 0x9061C0 + static enum hab_status imx8m_read_sram_events(enum hab_status status, - uint32_t index, void *event, - uint32_t *bytes) + uint32_t index, uint8_t *event, + size_t *bytes) { struct hab_event_record *events[10]; int num_events = 0; - char *sram = (char *)0x9061c0; + u8 *sram; int i = 0; int internal_index = 0; - char *end = 0; + uint16_t ev_len; + u8 *end = 0; struct hab_event_record *search; + if (cpu_is_mx8mq()) + sram = (char *)IMX8MQ_ROM_OCRAM_ADDRESS; + else + return HAB_STATUS_FAILURE; + /* * 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. + * The max event length is just a sanity check. */ - end = sram + 0x1a0; + end = sram + 0x1a0; while (sram < end) { if (*sram == 0xdb) { search = (void *)sram; - sram = sram + be16_to_cpu(search->hdr.len); + ev_len = be16_to_cpu(search->hdr.len); + if (ev_len > HABV4_EVENT_MAX_LEN) + break; + + sram += ev_len; + if (sram > end) + break; + + if (num_events == ARRAY_SIZE(events)) { + pr_warn("Discarding excess event\n"); + continue; + } + events[num_events] = search; num_events++; } else { @@ -244,7 +304,7 @@ static enum hab_status imx8m_read_sram_events(enum hab_status status, } } while (i < num_events) { - if (events[i]->status == status) { + if (events[i]->status >= status) { if (internal_index == index) { *bytes = sizeof(struct hab_event_record) + be16_to_cpu(events[i]->hdr.len); @@ -260,9 +320,19 @@ static enum hab_status imx8m_read_sram_events(enum hab_status status, return HAB_STATUS_FAILURE; } +static enum hab_status imx8m_report_event(enum hab_status status, + uint32_t index, uint8_t *event, + size_t *bytes) +{ + if (cpu_is_mx8mq()) + return imx8m_read_sram_events(status, index, event, bytes); + else + return hab_sip_report_event(status, index, event, bytes); +} + struct habv4_rvt hab_smc_ops = { .header = { .tag = 0xdd }, - .report_event = imx8m_read_sram_events, + .report_event = imx8m_report_event, .report_status = hab_sip_report_status, }; @@ -298,7 +368,7 @@ static const char *habv4_get_config_str(enum hab_config config) return "<unknown>"; } -static const char *habv4_get_state_str(enum hab_state state) +static const char *habv4_get_state_str(enum habv4_state state) { switch (state) { case HAB_STATE_INITIAL: @@ -456,7 +526,7 @@ static void habv4_display_event_record(struct hab_event_record *record) pr_err("Engine: %s (0x%02x)\n", habv4_get_engine_str(record->engine), record->engine); } -static void habv4_display_event(uint8_t *data, uint32_t len) +static void habv4_display_event(uint8_t *data, size_t len) { unsigned int i; @@ -503,14 +573,44 @@ static bool is_known_rng_fail_event(const uint8_t *data, size_t len) return false; } +static uint8_t *hab_get_event(const struct habv4_rvt *rvt, int index, size_t *len) +{ + enum hab_status err; + uint8_t *buf; + + err = rvt->report_event(HAB_STATUS_ANY, index, NULL, len); + if (err != HAB_STATUS_SUCCESS) + return NULL; + + buf = dma_alloc(*len); + if (!buf) + return NULL; + + err = rvt->report_event(HAB_STATUS_ANY, index, buf, len); + if (err != HAB_STATUS_SUCCESS) { + pr_err("Unexpected HAB return code\n"); + free(buf); + return NULL; + } + + return buf; +} + +static int habv4_state = -EPROBE_DEFER; + +int habv4_get_state(void) +{ + return habv4_state; +} + static int habv4_get_status(const struct habv4_rvt *rvt) { - uint8_t data[256]; - uint32_t len; - uint32_t index = 0; + uint8_t *data; + size_t len; + int i; enum hab_status status; enum hab_config config = 0x0; - enum hab_state state = 0x0; + enum habv4_state state = 0x0; if (rvt->header.tag != HAB_TAG_RVT) { pr_err("ERROR - RVT not found!\n"); @@ -518,6 +618,8 @@ static int habv4_get_status(const struct habv4_rvt *rvt) } status = rvt->report_status(&config, &state); + habv4_state = state; + pr_info("Status: %s (0x%02x)\n", habv4_get_status_str(status), status); pr_info("Config: %s (0x%02x)\n", habv4_get_config_str(config), config); pr_info("State: %s (0x%02x)\n", habv4_get_state_str(state), state); @@ -527,56 +629,42 @@ static int habv4_get_status(const struct habv4_rvt *rvt) return 0; } - len = sizeof(data); - while (rvt->report_event(HAB_STATUS_WARNING, index, data, &len) == HAB_STATUS_SUCCESS) { + for (i = 0;; i++) { + data = hab_get_event(rvt, i, &len); + if (!data) + break; /* suppress RNG self-test fail events if they can be handled in software */ - if (IS_ENABLED(CONFIG_CRYPTO_DEV_FSL_CAAM_RNG_SELF_TEST) && - is_known_rng_fail_event(data, len)) { + if (is_known_rng_fail_event(data, len)) { pr_debug("RNG self-test failure detected, will run software self-test\n"); } else { - pr_err("-------- HAB warning Event %d --------\n", index); + pr_err("-------- HAB Event %d --------\n", i); pr_err("event data:\n"); habv4_display_event(data, len); } - len = sizeof(data); - index++; - } - - len = sizeof(data); - index = 0; - while (rvt->report_event(HAB_STATUS_FAILURE, index, data, &len) == HAB_STATUS_SUCCESS) { - pr_err("-------- HAB failure Event %d --------\n", index); - pr_err("event data:\n"); - - habv4_display_event(data, len); - len = sizeof(data); - index++; + free(data); } - /* Check reason for stopping */ - len = sizeof(data); - index = 0; - if (rvt->report_event(HAB_STATUS_ANY, index, NULL, &len) == HAB_STATUS_SUCCESS) - pr_err("ERROR: Recompile with larger event data buffer (at least %d bytes)\n\n", len); - return -EPERM; } -int imx6_hab_get_status(void) +static int imx6_hab_get_status(void) { const struct habv4_rvt *rvt; rvt = (void *)HABV4_RVT_IMX6_OLD; + OPTIMIZER_HIDE_VAR(rvt); if (rvt->header.tag == HAB_TAG_RVT) return habv4_get_status(rvt); rvt = (void *)HABV4_RVT_IMX6_NEW; + OPTIMIZER_HIDE_VAR(rvt); if (rvt->header.tag == HAB_TAG_RVT) return habv4_get_status(rvt); rvt = (void *)HABV4_RVT_IMX6UL; + OPTIMIZER_HIDE_VAR(rvt); if (rvt->header.tag == HAB_TAG_RVT) return habv4_get_status(rvt); @@ -585,73 +673,23 @@ int imx6_hab_get_status(void) return -EINVAL; } -static int imx8m_hab_get_status(void) -{ - return habv4_get_status(&hab_smc_ops); -} - -static int init_imx8m_hab_get_status(void) +int imx8m_hab_print_status(void) { - if (!cpu_is_mx8mq()) - /* can happen in multi-image builds and is not an error */ - return 0; + pr_info("ROM version: 0x%x\n", hab_sip_get_version()); - /* - * Nobody will check the return value if there were HAB errors, but the - * initcall will fail spectaculously with a strange error message. - */ - imx8m_hab_get_status(); + habv4_get_status(&hab_smc_ops); return 0; } -/* - * - * - * - */ -postmmu_initcall(init_imx8m_hab_get_status); - -static int init_imx6_hab_get_status(void) +int imx6_hab_print_status(void) { - if (!cpu_is_mx6()) - /* can happen in multi-image builds and is not an error */ - return 0; + remap_range(0x0, SZ_1M, MAP_CACHED); - /* - * Nobody will check the return value if there were HAB errors, but the - * initcall will fail spectaculously with a strange error message. - */ imx6_hab_get_status(); - return 0; -} - -/* - * Need to run before MMU setup because i.MX6 ROM code is mapped near 0x0, - * which will no longer be accessible when the MMU sets the zero page to - * faulting. - */ -postconsole_initcall(init_imx6_hab_get_status); - -int imx28_hab_get_status(void) -{ - const struct habv4_rvt *rvt = (void *)HABV4_RVT_IMX28; - - return habv4_get_status(rvt); -} - -static int init_imx28_hab_get_status(void) -{ - if (!cpu_is_mx28()) - /* can happen in multi-image builds and is not an error */ - return 0; - + zero_page_faulting(); + remap_range((void *)PAGE_SIZE, SZ_1M - PAGE_SIZE, MAP_UNCACHED); - /* nobody will check the return value if there were HAB errors, but the - * initcall will fail spectaculously with a strange error message. */ - imx28_hab_get_status(); return 0; } -/* i.MX28 ROM code can be run after MMU setup to make use of caching */ -postmmu_initcall(init_imx28_hab_get_status); |