--- /dev/null
+/*
+ * Copyright (C) 2010-2014 Freescale Semiconductor, Inc.
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+
+#include <common.h>
+#include <errno.h>
+#include <asm/io.h>
+#include <asm/system.h>
+#include <asm/arch/clock.h>
+#include <asm/arch/sys_proto.h>
+#include <asm/arch/hab.h>
+
+HAB_FUNC(entry, hab_status_t)
+HAB_FUNC(exit, hab_status_t)
+HAB_FUNC5(authenticate_image, void *, uint8_t, size_t, void **, size_t *, hab_loader_callback_f_t)
+HAB_FUNC2(report_status, hab_status_t, hab_config_t *, hab_state_t *)
+HAB_FUNC4(report_event, hab_status_t, hab_status_t, uint32_t, uint8_t *, size_t *)
+HAB_FUNC3(check_target, hab_status_t, uint8_t, const void *, size_t)
+HAB_FUNC3(assert, hab_status_t, uint8_t, const void *, size_t)
+
+struct mx53_ivt {
+ u32 header;
+ u32 app_start_addr;
+ u32 rsrvd1;
+ void *dcd_ptr;
+ struct mx53_boot_data *boot_data;
+ void *self;
+ void *csf;
+ u32 rsrvd2;
+};
+
+struct mx53_boot_data {
+ void *start;
+ u32 length;
+ u32 plugin;
+};
+
+#define IVT_SIZE 0x20
+#define ALIGN_SIZE 0x400
+#define CSF_PAD_SIZE 0x2000
+
+/*
+ * +------------+ 0x0 (DDR_UIMAGE_START) -
+ * | Header | |
+ * +------------+ 0x40 |
+ * | | |
+ * | | |
+ * | | |
+ * | | |
+ * | Image Data | |
+ * . | |
+ * . | > Stuff to be authenticated ----+
+ * . | | |
+ * | | | |
+ * | | | |
+ * +------------+ | |
+ * | | | |
+ * | Fill Data | | |
+ * | | | |
+ * +------------+ Align to ALIGN_SIZE | |
+ * | IVT | | |
+ * +------------+ + IVT_SIZE - |
+ * | | |
+ * | CSF DATA | <---------------------------------------------------------+
+ * | |
+ * +------------+
+ * | |
+ * | Fill Data |
+ * | |
+ * +------------+ + CSF_PAD_SIZE
+ */
+
+static inline int read_fuse(unsigned bank, unsigned row)
+{
+ struct iim_regs *iim_regs = (void *)IMX_IIM_BASE;
+ u32 *fuses;
+
+ if (bank > ARRAY_SIZE(iim_regs->bank))
+ return -EINVAL;
+ fuses = iim_regs->bank[bank].fuse_regs;
+
+ debug("Reading fuse bank %u row %u @ %p\n", bank, row, &fuses[row]);
+ return readl(&fuses[row]);
+}
+
+static bool is_hab_enabled(void)
+{
+#ifdef DEBUG
+ static int first = 1;
+
+ if (first) {
+ debug("rvt_base=%p\n", hab_rvt_base());
+ debug("hab_rvt_entry=%p\n", hab_rvt_entry_p);
+ debug("hab_rvt_exit=%p\n", hab_rvt_exit_p);
+ debug("hab_rvt_check_target=%p\n", hab_rvt_check_target_p);
+ debug("hab_rvt_authenticate_image=%p\n", hab_rvt_authenticate_image_p);
+ debug("hab_rvt_report_event=%p\n", hab_rvt_report_event_p);
+ debug("hab_rvt_report_status=%p\n", hab_rvt_report_status_p);
+ debug("hab_rvt_assert=%p\n", hab_rvt_assert_p);
+ first = 0;
+ }
+#endif
+ return read_fuse(0, 4) & (1 << 1);
+}
+
+static void mx53_hab_display_event(uint8_t *event_data, size_t bytes)
+{
+ uint32_t i;
+
+ if (!(event_data && bytes > 0))
+ return;
+
+ for (i = 0; i < bytes; i++) {
+ if (i == 0)
+ printf("\t0x%02x", event_data[i]);
+ else if ((i % 8) == 0)
+ printf("\n\t0x%02x", event_data[i]);
+ else
+ printf(" 0x%02x", event_data[i]);
+ }
+}
+
+static inline void mx53_hab_pr_fuse_val(unsigned bank, unsigned row)
+{
+ printf(" %02x", read_fuse(bank, row));
+}
+
+static inline void mx53_hab_dump_srk_hash(void)
+{
+ int i;
+
+ printf("SRK hash:\n\t");
+ mx53_hab_pr_fuse_val(1, 1);
+ for (i = 1; i <= 31; i++) {
+ if (i % 8 == 0)
+ printf("\n\t");
+ mx53_hab_pr_fuse_val(3, i);
+ }
+ printf("\n");
+}
+
+int get_hab_status(void)
+{
+ static uint32_t last_hab_event __attribute__((section(".data")));
+ uint32_t index = last_hab_event; /* Loop index */
+ uint8_t event_data[128]; /* Event data buffer */
+ size_t bytes = sizeof(event_data); /* Event size in bytes */
+ enum hab_config config;
+ enum hab_state state;
+ int ret;
+ int hab_debug = getenv_yesno("hab_debug") == 1;
+
+ if (hab_debug) {
+ if (is_hab_enabled()) {
+ printf("Secure boot enabled\n\t");
+ } else {
+ printf("Secure boot disabled\n");
+ }
+ mx53_hab_dump_srk_hash();
+ }
+
+ /* Check HAB status */
+ config = state = 0; /* ROM code assumes short enums! */
+ ret = hab_rvt_report_status(&config, &state);
+ if (hab_debug || ret != HAB_SUCCESS)
+ printf("HAB Configuration: 0x%02x, HAB State: 0x%02x\n",
+ config, state);
+ if (ret != HAB_SUCCESS) {
+ /* Display HAB Error events */
+ while (hab_rvt_report_event(HAB_STS_ANY, index, event_data,
+ &bytes) == HAB_SUCCESS) {
+ puts("\n");
+ printf("--------- HAB Event %d -----------------\n",
+ index + 1);
+ puts("event data:\n");
+ mx53_hab_display_event(event_data, bytes);
+ puts("\n");
+ bytes = sizeof(event_data);
+ index++;
+ }
+ ret = index - last_hab_event;
+ last_hab_event = index;
+ } else {
+ /* Display message if no HAB events are found */
+ if (hab_debug)
+ puts("No HAB Events Found!\n");
+ ret = 0;
+ }
+ return ret;
+}
+
+static inline hab_status_t hab_init(void)
+{
+ hab_status_t ret;
+
+ ret = hab_rvt_entry();
+ debug("hab_rvt_entry() returned %02x\n", ret);
+ if (ret != HAB_SUCCESS) {
+ printf("hab entry function failed: %02x\n", ret);
+ }
+
+ return ret;
+}
+
+static inline hab_status_t hab_exit(void)
+{
+ hab_status_t ret;
+
+ ret = hab_rvt_exit();
+ if (ret != HAB_SUCCESS)
+ printf("hab exit function failed: %02x\n", ret);
+
+ return ret;
+}
+
+static hab_status_t hab_check_target(hab_target_t type, uint32_t addr, size_t len)
+{
+ hab_status_t ret;
+
+ ret = hab_init();
+ if (ret != HAB_SUCCESS)
+ return ret;
+
+ ret = hab_rvt_check_target(type, (void *)addr, len);
+ if (ret != HAB_SUCCESS) {
+ printf("check_target(0x%08x, 0x%08x) failed: %d\n",
+ addr, len, ret);
+ return ret;
+ }
+ ret = hab_exit();
+
+ if (ret == HAB_SUCCESS && get_hab_status() > 0) {
+ return HAB_FAILURE;
+ }
+ return ret;
+}
+
+static hab_status_t hab_assert(uint32_t type, uint32_t addr, size_t len)
+{
+ hab_status_t ret;
+
+ ret = hab_init();
+ if (ret != HAB_SUCCESS)
+ return ret;
+
+ ret = hab_rvt_assert(type, (void *)addr, len);
+ if (ret != HAB_SUCCESS) {
+ printf("assert(0x%08x, 0x%08x) failed: %d\n",
+ addr, len, ret);
+ return ret;
+ }
+ ret = hab_exit();
+
+ if (ret == HAB_SUCCESS && get_hab_status() > 0) {
+ return HAB_FAILURE;
+ }
+ return ret;
+}
+
+static int do_hab_status(cmd_tbl_t *cmdtp, int flag, int argc,
+ char *const argv[])
+{
+ if (argc != 1)
+ return CMD_RET_USAGE;
+
+ get_hab_status();
+
+ return CMD_RET_SUCCESS;
+}
+
+static int do_hab_check_target(cmd_tbl_t *cmdtp, int flag, int argc,
+ char *const argv[])
+{
+ hab_target_t type = HAB_TGT_MEMORY;
+ uint32_t addr;
+ size_t len;
+
+ if (argc < 3)
+ return CMD_RET_USAGE;
+
+ addr = simple_strtoul(argv[1], NULL, 16);
+ len = simple_strtoul(argv[2], NULL, 16);
+ if (argc > 3) {
+ switch (argv[3][0]) {
+ case 'p':
+ case 'P':
+ type = HAB_TGT_PERIPHERAL;
+ break;
+ case 'm':
+ case 'M':
+ type = HAB_TGT_MEMORY;
+ break;
+ default:
+ printf("Invalid type '%s'\n", argv[3]);
+ return CMD_RET_USAGE;
+ }
+ }
+ if (hab_check_target(type, addr, len) != HAB_SUCCESS)
+ return CMD_RET_FAILURE;
+
+ return CMD_RET_SUCCESS;
+}
+
+static int do_hab_assert(cmd_tbl_t *cmdtp, int flag, int argc,
+ char *const argv[])
+{
+ uint32_t type = 0;
+ uint32_t addr;
+ size_t len;
+
+ if (argc < 3)
+ return CMD_RET_USAGE;
+
+ addr = simple_strtoul(argv[1], NULL, 16);
+ len = simple_strtoul(argv[2], NULL, 16);
+ if (argc > 3) {
+ type = simple_strtoul(argv[3], NULL, 16);
+ }
+
+ if (hab_assert(type, addr, len) != HAB_SUCCESS)
+ return CMD_RET_FAILURE;
+
+ return CMD_RET_SUCCESS;
+}
+
+U_BOOT_CMD(
+ hab_status, CONFIG_SYS_MAXARGS, 1, do_hab_status,
+ "display HAB status",
+ ""
+ );
+
+U_BOOT_CMD(
+ hab_check_target, 4, 0, do_hab_check_target,
+ "verify an address range via HAB",
+ "addr len [type]\n"
+ "\t\taddr -\taddress to verify\n"
+ "\t\tlen -\tlength of addr range to verify\n"
+ );
+
+U_BOOT_CMD(
+ hab_assert, 4, 0, do_hab_assert,
+ "Test an assertion against the HAB audit log",
+ "addr len [type]\n"
+ "\t\taddr -\taddress to verify\n"
+ "\t\tlen -\tlength of addr range to verify\n"
+ );
--- /dev/null
+/*
+ * Copyright (C) 2012 Freescale Semiconductor, Inc. All Rights Reserved.
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ *
+*/
+
+#ifndef __ARCH_MX5_HAB_H
+#define __ARCH_MX5_HAB_H
+
+#ifdef CONFIG_SECURE_BOOT
+
+#include <linux/types.h>
+
+int get_hab_status(void);
+
+/* -------- start of HAB API updates ------------*/
+/* The following are taken from HAB4 SIS */
+
+/* Status definitions */
+typedef enum hab_status {
+ HAB_STS_ANY = 0x00,
+ HAB_FAILURE = 0x33,
+ HAB_WARNING = 0x69,
+ HAB_SUCCESS = 0xf0
+} hab_status_t;
+
+/* Security Configuration definitions */
+typedef enum hab_config {
+ HAB_CFG_RETURN = 0x33, /**< Field Return IC */
+ HAB_CFG_OPEN = 0xf0, /**< Non-secure IC */
+ HAB_CFG_CLOSED = 0xcc /**< Secure IC */
+} hab_config_t;
+
+/* State definitions */
+typedef 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 */
+ HAB_STATE_MAX
+} hab_state_t;
+
+typedef enum hab_target {
+ HAB_TGT_MEMORY = 0x0f, /* Check memory white list */
+ HAB_TGT_PERIPHERAL = 0xf0, /* Check peripheral white list*/
+} hab_target_t;
+
+enum HAB_FUNC_OFFSETS {
+ HAB_RVT_HEADER,
+ HAB_RVT_ENTRY,
+ HAB_RVT_EXIT,
+ HAB_RVT_CHECK_TARGET,
+ HAB_RVT_AUTHENTICATE_IMAGE,
+ HAB_RVT_RUN_DCD,
+ HAB_RVT_RUN_CSF,
+ HAB_RVT_ASSERT,
+ HAB_RVT_REPORT_EVENT,
+ HAB_RVT_REPORT_STATUS,
+ HAB_RVT_FAILSAFE,
+};
+
+/* Function prototype description */
+typedef hab_status_t hab_rvt_entry_t(void);
+
+typedef hab_status_t hab_rvt_exit_t(void);
+
+typedef hab_status_t hab_rvt_check_target_t(hab_target_t, const void *,
+ size_t);
+
+typedef hab_status_t hab_loader_callback_f_t(void**, size_t*, const void*);
+typedef void *hab_rvt_authenticate_image_t(uint8_t, ptrdiff_t,
+ void **, size_t *, hab_loader_callback_f_t);
+
+typedef hab_status_t hab_rvt_assert_t(uint32_t, const void *,
+ size_t);
+
+typedef hab_status_t hab_rvt_report_event_t(hab_status_t, uint32_t,
+ uint8_t* , size_t*);
+
+typedef hab_status_t hab_rvt_report_status_t(enum hab_config *,
+ enum hab_state *);
+
+typedef void hapi_clock_init_t(void);
+
+#define HAB_RVT_BASE 0x00000094
+
+static inline void **hab_rvt_base(void)
+{
+ uint32_t *base = (void *)0x94;
+
+ if ((*base & 0xff0000ff) != cpu_to_be32(0xdd000040)) {
+ printf("Invalid RVT @ %p\n", base);
+ hang();
+ }
+ return (void **)base;
+}
+
+#define HAB_CID_ROM 0 /**< ROM Caller ID */
+#define HAB_CID_UBOOT 1 /**< UBOOT Caller ID*/
+/* ----------- end of HAB API updates ------------*/
+
+#define hab_rvt_entry_p \
+ ((hab_rvt_entry_t *)hab_rvt_base()[HAB_RVT_ENTRY])
+
+#define hab_rvt_exit_p \
+ ((hab_rvt_exit_t *)hab_rvt_base()[HAB_RVT_EXIT])
+
+#define hab_rvt_check_target_p \
+ ((hab_rvt_check_target_t*)hab_rvt_base()[HAB_RVT_CHECK_TARGET])
+
+#define hab_rvt_authenticate_image_p \
+ ((hab_rvt_authenticate_image_t *)hab_rvt_base()[HAB_RVT_AUTHENTICATE_IMAGE])
+
+#define hab_rvt_assert_p \
+ ((hab_rvt_assert_t*)hab_rvt_base()[HAB_RVT_ASSERT])
+
+#define hab_rvt_report_event_p \
+ ((hab_rvt_report_event_t*)hab_rvt_base()[HAB_RVT_REPORT_EVENT])
+
+#define hab_rvt_report_status_p \
+ ((hab_rvt_report_status_t*)hab_rvt_base()[HAB_RVT_REPORT_STATUS])
+
+#define HAB_FUNC(n, rt) \
+static inline rt hab_rvt_##n(void) \
+{ \
+ if (hab_rvt_base() == NULL) \
+ return (rt)-1; \
+ return hab_rvt_##n##_p(); \
+} \
+
+#define HAB_FUNC2(n, rt, t1, t2) \
+static inline rt hab_rvt_##n(t1 p1, t2 p2) \
+{ \
+ if (hab_rvt_base() == NULL) \
+ return (rt)-1; \
+ return hab_rvt_##n##_p(p1, p2); \
+}
+
+#define HAB_FUNC3(n, rt, t1, t2, t3) \
+static inline rt hab_rvt_##n(t1 p1, t2 p2, t3 p3) \
+{ \
+ if (hab_rvt_base() == NULL) \
+ return (rt)-1; \
+ return hab_rvt_##n##_p(p1, p2, p3); \
+}
+
+#define HAB_FUNC4(n, rt, t1, t2, t3, t4) \
+static inline rt hab_rvt_##n(t1 p1, t2 p2, t3 p3, t4 p4) \
+{ \
+ if (hab_rvt_base() == NULL) \
+ return (rt)-1; \
+ return hab_rvt_##n##_p(p1, p2, p3, p4); \
+}
+
+#define HAB_FUNC5(n, rt, t1, t2, t3, t4, t5) \
+static inline rt hab_rvt_##n(t1 p1, t2 p2, t3 p3, t4 p4, t5 p5) \
+{ \
+ if (hab_rvt_base() == NULL) \
+ return (rt)-1; \
+ return hab_rvt_##n##_p(p1, p2, p3, p4, p5); \
+}
+
+#else /* CONFIG_SECURE_BOOT */
+
+static inline int get_hab_status(void)
+{
+ return 0;
+}
+
+#endif /* CONFIG_SECURE_BOOT */
+#endif /* __ARCH_MX5_HAB_H */