2 * Copyright (C) 2010-2015 Freescale Semiconductor, Inc.
4 * SPDX-License-Identifier: GPL-2.0+
9 #include <asm/system.h>
10 #include <asm/arch/clock.h>
11 #include <asm/arch/sys_proto.h>
12 #include <asm/arch/hab.h>
14 HAB_FUNC(entry, hab_status_t)
15 HAB_FUNC(exit, hab_status_t)
16 HAB_FUNC5(authenticate_image, void *, uint8_t, size_t, void **, size_t *, hab_loader_callback_f_t)
17 //HAB_FUNC1(run_dcd, hab_status_t, const uint8_t *)
18 HAB_FUNC2(run_csf, hab_status_t, const uint8_t *, uint8_t)
19 HAB_FUNC2(report_status, hab_status_t, hab_config_t *, hab_state_t *)
20 HAB_FUNC4(report_event, hab_status_t, hab_status_t, uint32_t, uint8_t *, size_t *)
21 HAB_FUNC3(check_target, hab_status_t, uint8_t, const void *, size_t)
22 HAB_FUNC3(assert, hab_status_t, uint8_t, const void *, size_t)
29 struct mx6_boot_data *boot_data;
35 struct mx6_boot_data {
42 #define ALIGN_SIZE 0x400
43 #define CSF_PAD_SIZE 0x2000
44 #define MX6DQ_PU_IROM_MMU_EN_VAR 0x009024a8
45 #define MX6DLS_PU_IROM_MMU_EN_VAR 0x00901dd0
46 #define MX6SL_PU_IROM_MMU_EN_VAR 0x00900a18
49 * +------------+ 0x0 (DDR_UIMAGE_START) -
51 * +------------+ 0x40 |
58 * . | > Stuff to be authenticated ----+
66 * +------------+ Align to ALIGN_SIZE | |
68 * +------------+ + IVT_SIZE - |
70 * | CSF DATA | <---------------------------------------------------------+
76 * +------------+ + CSF_PAD_SIZE
79 #define MAX_RECORD_BYTES (8*1024) /* 4 kbytes */
82 uint8_t tag; /* Tag */
83 uint8_t len[2]; /* Length */
84 uint8_t par; /* Version */
85 uint8_t contents[MAX_RECORD_BYTES];/* Record Data */
89 char *rsn_str[] = {"RSN = HAB_RSN_ANY (0x00)\n",
90 "RSN = HAB_ENG_FAIL (0x30)\n",
91 "RSN = HAB_INV_ADDRESS (0x22)\n",
92 "RSN = HAB_INV_ASSERTION (0x0C)\n",
93 "RSN = HAB_INV_CALL (0x28)\n",
94 "RSN = HAB_INV_CERTIFICATE (0x21)\n",
95 "RSN = HAB_INV_COMMAND (0x06)\n",
96 "RSN = HAB_INV_CSF (0x11)\n",
97 "RSN = HAB_INV_DCD (0x27)\n",
98 "RSN = HAB_INV_INDEX (0x0F)\n",
99 "RSN = HAB_INV_IVT (0x05)\n",
100 "RSN = HAB_INV_KEY (0x1D)\n",
101 "RSN = HAB_INV_RETURN (0x1E)\n",
102 "RSN = HAB_INV_SIGNATURE (0x18)\n",
103 "RSN = HAB_INV_SIZE (0x17)\n",
104 "RSN = HAB_MEM_FAIL (0x2E)\n",
105 "RSN = HAB_OVR_COUNT (0x2B)\n",
106 "RSN = HAB_OVR_STORAGE (0x2D)\n",
107 "RSN = HAB_UNS_ALGORITHM (0x12)\n",
108 "RSN = HAB_UNS_COMMAND (0x03)\n",
109 "RSN = HAB_UNS_ENGINE (0x0A)\n",
110 "RSN = HAB_UNS_ITEM (0x24)\n",
111 "RSN = HAB_UNS_KEY (0x1B)\n",
112 "RSN = HAB_UNS_PROTOCOL (0x14)\n",
113 "RSN = HAB_UNS_STATE (0x09)\n",
117 char *sts_str[] = {"STS = HAB_SUCCESS (0xF0)\n",
118 "STS = HAB_FAILURE (0x33)\n",
119 "STS = HAB_WARNING (0x69)\n",
123 char *eng_str[] = {"ENG = HAB_ENG_ANY (0x00)\n",
124 "ENG = HAB_ENG_SCC (0x03)\n",
125 "ENG = HAB_ENG_RTIC (0x05)\n",
126 "ENG = HAB_ENG_SAHARA (0x06)\n",
127 "ENG = HAB_ENG_CSU (0x0A)\n",
128 "ENG = HAB_ENG_SRTC (0x0C)\n",
129 "ENG = HAB_ENG_DCP (0x1B)\n",
130 "ENG = HAB_ENG_CAAM (0x1D)\n",
131 "ENG = HAB_ENG_SNVS (0x1E)\n",
132 "ENG = HAB_ENG_OCOTP (0x21)\n",
133 "ENG = HAB_ENG_DTCP (0x22)\n",
134 "ENG = HAB_ENG_ROM (0x36)\n",
135 "ENG = HAB_ENG_HDCP (0x24)\n",
136 "ENG = HAB_ENG_RTL (0x77)\n",
137 "ENG = HAB_ENG_SW (0xFF)\n",
141 char *ctx_str[] = {"CTX = HAB_CTX_ANY(0x00)\n",
142 "CTX = HAB_CTX_FAB (0xFF)\n",
143 "CTX = HAB_CTX_ENTRY (0xE1)\n",
144 "CTX = HAB_CTX_TARGET (0x33)\n",
145 "CTX = HAB_CTX_AUTHENTICATE (0x0A)\n",
146 "CTX = HAB_CTX_DCD (0xDD)\n",
147 "CTX = HAB_CTX_CSF (0xCF)\n",
148 "CTX = HAB_CTX_COMMAND (0xC0)\n",
149 "CTX = HAB_CTX_AUT_DAT (0xDB)\n",
150 "CTX = HAB_CTX_ASSERT (0xA0)\n",
151 "CTX = HAB_CTX_EXIT (0xEE)\n",
155 uint8_t hab_statuses[5] = {
163 uint8_t hab_reasons[26] = {
192 uint8_t hab_contexts[12] = {
197 HAB_CTX_AUTHENTICATE,
207 uint8_t hab_engines[16] = {
226 bool is_hab_enabled(void)
228 struct ocotp_regs *ocotp = (struct ocotp_regs *)OCOTP_BASE_ADDR;
229 struct fuse_bank *bank = &ocotp->bank[0];
230 struct fuse_bank0_regs *fuse =
231 (struct fuse_bank0_regs *)bank->fuse_regs;
232 uint32_t reg = readl(&fuse->cfg5);
233 static int first = 1;
236 debug("rvt_base=%p\n", hab_rvt_base());
237 debug("hab_rvt_entry=%p\n", hab_rvt_entry_p);
238 debug("hab_rvt_exit=%p\n", hab_rvt_exit_p);
239 debug("hab_rvt_check_target=%p\n", hab_rvt_check_target_p);
240 debug("hab_rvt_authenticate_image=%p\n", hab_rvt_authenticate_image_p);
241 debug("hab_rvt_report_event=%p\n", hab_rvt_report_event_p);
242 debug("hab_rvt_report_status=%p\n", hab_rvt_report_status_p);
243 debug("hab_rvt_assert=%p\n", hab_rvt_assert_p);
246 return (reg & 0x2) == 0x2;
249 static inline uint8_t get_idx(uint8_t *list, uint8_t tgt)
252 uint8_t element = list[idx];
253 while (element != -1) {
256 element = list[++idx];
261 void process_event_record(uint8_t *event_data, size_t bytes)
263 struct record *rec = (struct record *)event_data;
265 printf("\n\n%s", sts_str[get_idx(hab_statuses, rec->contents[0])]);
266 printf("%s", rsn_str[get_idx(hab_reasons, rec->contents[1])]);
267 printf("%s", ctx_str[get_idx(hab_contexts, rec->contents[2])]);
268 printf("%s", eng_str[get_idx(hab_engines, rec->contents[3])]);
271 void display_event(uint8_t *event_data, size_t bytes)
275 if (!(event_data && bytes > 0))
278 for (i = 0; i < bytes; i++) {
280 printf("\t0x%02x", event_data[i]);
281 else if ((i % 8) == 0)
282 printf("\n\t0x%02x", event_data[i]);
284 printf(" 0x%02x", event_data[i]);
287 process_event_record(event_data, bytes);
290 int get_hab_status(void)
292 static uint32_t last_hab_event __attribute__((section(".data")));
293 uint32_t index = last_hab_event; /* Loop index */
294 uint8_t event_data[128]; /* Event data buffer */
295 size_t bytes = sizeof(event_data); /* Event size in bytes */
296 enum hab_config config;
297 enum hab_state state;
300 if (is_hab_enabled())
301 puts("Secure boot enabled\n");
303 puts("Secure boot disabled\n");
305 /* Check HAB status */
306 config = state = 0; /* ROM code assumes short enums! */
307 ret = hab_rvt_report_status(&config, &state);
308 printf("HAB Configuration: 0x%02x, HAB State: 0x%02x\n",
310 if (ret != HAB_SUCCESS) {
311 /* Display HAB Error events */
312 while (hab_rvt_report_event(HAB_STS_ANY, index, event_data,
313 &bytes) == HAB_SUCCESS) {
315 printf("--------- HAB Event %d -----------------\n",
317 puts("event data:\n");
318 display_event(event_data, bytes);
320 bytes = sizeof(event_data);
323 ret = index - last_hab_event;
324 last_hab_event = index;
326 /* Display message if no HAB events are found */
327 puts("No HAB Events Found!\n");
333 static inline hab_status_t hab_init(void)
337 if (!is_hab_enabled()) {
338 puts("hab fuse not enabled\n");
342 hab_caam_clock_enable(1);
344 ret = hab_rvt_entry();
345 debug("hab_rvt_entry() returned %02x\n", ret);
346 if (ret != HAB_SUCCESS) {
347 printf("hab entry function failed: %02x\n", ret);
348 hab_caam_clock_enable(0);
354 static inline hab_status_t hab_exit(void)
358 ret = hab_rvt_exit();
359 if (ret != HAB_SUCCESS)
360 printf("hab exit function failed: %02x\n", ret);
362 hab_caam_clock_enable(0);
367 static hab_status_t hab_check_target(hab_target_t type, uint32_t addr, size_t len)
372 if (ret != HAB_SUCCESS)
375 ret = hab_rvt_check_target(type, (void *)addr, len);
376 if (ret != HAB_SUCCESS) {
377 printf("check_target(0x%08x, 0x%08x) failed: %d\n",
383 if (ret == HAB_SUCCESS && get_hab_status() > 0) {
389 static hab_status_t hab_assert(uint32_t type, uint32_t addr, size_t len)
394 if (ret != HAB_SUCCESS)
397 ret = hab_rvt_assert(type, (void *)addr, len);
398 if (ret != HAB_SUCCESS) {
399 printf("assert(0x%08x, 0x%08x) failed: %d\n",
405 if (ret == HAB_SUCCESS && get_hab_status() > 0) {
411 static int do_hab_status(cmd_tbl_t *cmdtp, int flag, int argc,
415 return CMD_RET_USAGE;
419 return CMD_RET_SUCCESS;
422 static int do_hab_check_target(cmd_tbl_t *cmdtp, int flag, int argc,
425 hab_target_t type = HAB_TGT_ANY;
430 return CMD_RET_USAGE;
432 addr = simple_strtoul(argv[1], NULL, 16);
433 len = simple_strtoul(argv[2], NULL, 16);
435 switch (argv[3][0]) {
438 type = HAB_TGT_PERIPHERAL;
442 type = HAB_TGT_MEMORY;
448 printf("Invalid type '%s'\n", argv[3]);
449 return CMD_RET_USAGE;
452 if (hab_check_target(type, addr, len) != HAB_SUCCESS)
453 return CMD_RET_FAILURE;
455 return CMD_RET_SUCCESS;
458 static int do_hab_assert(cmd_tbl_t *cmdtp, int flag, int argc,
466 return CMD_RET_USAGE;
468 addr = simple_strtoul(argv[1], NULL, 16);
469 len = simple_strtoul(argv[2], NULL, 16);
471 type = simple_strtoul(argv[3], NULL, 16);
474 if (hab_assert(type, addr, len) != HAB_SUCCESS)
475 return CMD_RET_FAILURE;
477 return CMD_RET_SUCCESS;
481 hab_status, CONFIG_SYS_MAXARGS, 1, do_hab_status,
482 "display HAB status",
487 hab_check_target, 4, 0, do_hab_check_target,
488 "verify an address range via HAB",
490 "\t\taddr -\taddress to verify\n"
491 "\t\tlen -\tlength of addr range to verify\n"
495 hab_assert, 4, 0, do_hab_assert,
496 "Test an assertion against the HAB audit log",
498 "\t\taddr -\taddress to verify\n"
499 "\t\tlen -\tlength of addr range to verify\n"