2 * Copyright (C) 2010-2015 Freescale Semiconductor, Inc.
4 * SPDX-License-Identifier: GPL-2.0+
10 #include <asm/system.h>
11 #include <asm/arch/clock.h>
12 #include <asm/arch/sys_proto.h>
13 #include <asm/arch/hab.h>
15 HAB_FUNC(entry, enum hab_status)
16 HAB_FUNC(exit, enum hab_status)
17 HAB_FUNC5(authenticate_image, void *, uint8_t, size_t, void **, size_t *, hab_loader_callback_f_t)
18 //HAB_FUNC1(run_dcd, enum hab_status, const uint8_t *)
19 HAB_FUNC2(run_csf, enum hab_status, const uint8_t *, uint8_t)
20 HAB_FUNC2(report_status, enum hab_status, enum hab_config *, enum hab_state *)
21 HAB_FUNC4(report_event, enum hab_status, enum hab_status, uint32_t, uint8_t *, size_t *)
22 HAB_FUNC3(check_target, enum hab_status, uint8_t, const void *, size_t)
23 HAB_FUNC3(assert, enum hab_status, uint8_t, const void *, size_t)
25 #define MAX_RECORD_BYTES (8 * 1024)
28 uint8_t tag; /* Tag */
29 uint8_t len[2]; /* Length */
30 uint8_t par; /* Version */
31 uint8_t contents[MAX_RECORD_BYTES];/* Record Data */
36 "RSN = HAB_RSN_ANY (0x00)\n",
37 "RSN = HAB_ENG_FAIL (0x30)\n",
38 "RSN = HAB_INV_ADDRESS (0x22)\n",
39 "RSN = HAB_INV_ASSERTION (0x0C)\n",
40 "RSN = HAB_INV_CALL (0x28)\n",
41 "RSN = HAB_INV_CERTIFICATE (0x21)\n",
42 "RSN = HAB_INV_COMMAND (0x06)\n",
43 "RSN = HAB_INV_CSF (0x11)\n",
44 "RSN = HAB_INV_DCD (0x27)\n",
45 "RSN = HAB_INV_INDEX (0x0F)\n",
46 "RSN = HAB_INV_IVT (0x05)\n",
47 "RSN = HAB_INV_KEY (0x1D)\n",
48 "RSN = HAB_INV_RETURN (0x1E)\n",
49 "RSN = HAB_INV_SIGNATURE (0x18)\n",
50 "RSN = HAB_INV_SIZE (0x17)\n",
51 "RSN = HAB_MEM_FAIL (0x2E)\n",
52 "RSN = HAB_OVR_COUNT (0x2B)\n",
53 "RSN = HAB_OVR_STORAGE (0x2D)\n",
54 "RSN = HAB_UNS_ALGORITHM (0x12)\n",
55 "RSN = HAB_UNS_COMMAND (0x03)\n",
56 "RSN = HAB_UNS_ENGINE (0x0A)\n",
57 "RSN = HAB_UNS_ITEM (0x24)\n",
58 "RSN = HAB_UNS_KEY (0x1B)\n",
59 "RSN = HAB_UNS_PROTOCOL (0x14)\n",
60 "RSN = HAB_UNS_STATE (0x09)\n",
65 "STS = HAB_STS_ANY (0x00)\n",
66 "STS = HAB_FAILURE (0x33)\n",
67 "STS = HAB_WARNING (0x69)\n",
68 "STS = HAB_SUCCESS (0xF0)\n",
73 "ENG = HAB_ENG_ANY (0x00)\n",
74 "ENG = HAB_ENG_SCC (0x03)\n",
75 "ENG = HAB_ENG_RTIC (0x05)\n",
76 "ENG = HAB_ENG_SAHARA (0x06)\n",
77 "ENG = HAB_ENG_CSU (0x0A)\n",
78 "ENG = HAB_ENG_SRTC (0x0C)\n",
79 "ENG = HAB_ENG_DCP (0x1B)\n",
80 "ENG = HAB_ENG_CAAM (0x1D)\n",
81 "ENG = HAB_ENG_SNVS (0x1E)\n",
82 "ENG = HAB_ENG_OCOTP (0x21)\n",
83 "ENG = HAB_ENG_DTCP (0x22)\n",
84 "ENG = HAB_ENG_ROM (0x36)\n",
85 "ENG = HAB_ENG_HDCP (0x24)\n",
86 "ENG = HAB_ENG_RTL (0x77)\n",
87 "ENG = HAB_ENG_SW (0xFF)\n",
92 "CTX = HAB_CTX_ANY(0x00)\n",
93 "CTX = HAB_CTX_FAB (0xFF)\n",
94 "CTX = HAB_CTX_ENTRY (0xE1)\n",
95 "CTX = HAB_CTX_TARGET (0x33)\n",
96 "CTX = HAB_CTX_AUTHENTICATE (0x0A)\n",
97 "CTX = HAB_CTX_DCD (0xDD)\n",
98 "CTX = HAB_CTX_CSF (0xCF)\n",
99 "CTX = HAB_CTX_COMMAND (0xC0)\n",
100 "CTX = HAB_CTX_AUT_DAT (0xDB)\n",
101 "CTX = HAB_CTX_ASSERT (0xA0)\n",
102 "CTX = HAB_CTX_EXIT (0xEE)\n",
106 uint8_t hab_statuses[ARRAY_SIZE(sts_str)] = {
114 uint8_t hab_reasons[ARRAY_SIZE(rsn_str)] = {
143 uint8_t hab_contexts[ARRAY_SIZE(ctx_str)] = {
148 HAB_CTX_AUTHENTICATE,
158 uint8_t hab_engines[ARRAY_SIZE(eng_str)] = {
177 bool is_hab_enabled(void)
180 static int first = 1;
182 if (fuse_read(0, 6, ®)) {
183 printf("Failed to read SECURE_BOOT fuse\n");
188 debug("rvt_base=%p\n", hab_rvt_base());
189 debug("hab_rvt_entry=%p\n", hab_rvt_entry_p);
190 debug("hab_rvt_exit=%p\n", hab_rvt_exit_p);
191 debug("hab_rvt_check_target=%p\n", hab_rvt_check_target_p);
192 debug("hab_rvt_authenticate_image=%p\n", hab_rvt_authenticate_image_p);
193 debug("hab_rvt_report_event=%p\n", hab_rvt_report_event_p);
194 debug("hab_rvt_report_status=%p\n", hab_rvt_report_status_p);
195 debug("hab_rvt_assert=%p\n", hab_rvt_assert_p);
198 return (reg & 0x2) == 0x2;
201 static inline uint8_t get_idx(uint8_t *list, uint8_t tgt)
204 uint8_t element = list[idx];
205 while (element != -1) {
208 element = list[++idx];
213 void process_event_record(uint8_t *event_data, size_t bytes)
215 struct record *rec = (struct record *)event_data;
217 printf("\n\n%s", sts_str[get_idx(hab_statuses, rec->contents[0])]);
218 printf("%s", rsn_str[get_idx(hab_reasons, rec->contents[1])]);
219 printf("%s", ctx_str[get_idx(hab_contexts, rec->contents[2])]);
220 printf("%s", eng_str[get_idx(hab_engines, rec->contents[3])]);
223 void display_event(uint8_t *event_data, size_t bytes)
227 if (!(event_data && bytes > 0))
230 for (i = 0; i < bytes; i++) {
232 printf("\t0x%02x", event_data[i]);
233 else if ((i % 8) == 0)
234 printf("\n\t0x%02x", event_data[i]);
236 printf(" 0x%02x", event_data[i]);
239 process_event_record(event_data, bytes);
242 int get_hab_status(void)
244 static uint32_t last_hab_event __attribute__((section(".data")));
245 uint32_t index = last_hab_event; /* Loop index */
246 uint8_t event_data[128]; /* Event data buffer */
247 size_t bytes = sizeof(event_data); /* Event size in bytes */
248 enum hab_config config;
249 enum hab_state state;
252 if (is_hab_enabled())
253 puts("Secure boot enabled\n");
255 puts("Secure boot disabled\n");
257 /* Check HAB status */
259 config = state = 0; /* ROM code assumes short enums! */
260 ret = hab_rvt_report_status(&config, &state);
262 printf("HAB Configuration: 0x%02x, HAB State: 0x%02x\n",
264 if (ret != HAB_SUCCESS) {
265 /* Display HAB Error events */
266 while (hab_rvt_report_event(HAB_STS_ANY, index, event_data,
267 &bytes) == HAB_SUCCESS) {
269 printf("--------- HAB Event %d -----------------\n",
271 puts("event data:\n");
272 display_event(event_data, bytes);
274 bytes = sizeof(event_data);
277 ret = index - last_hab_event;
278 last_hab_event = index;
280 /* Display message if no HAB events are found */
281 puts("No HAB Events Found!\n");
287 static inline enum hab_status hab_init(void)
292 if (!is_hab_enabled()) {
293 puts("hab fuse not enabled\n");
297 hab_caam_clock_enable(1);
299 ret = hab_rvt_entry();
300 debug("hab_rvt_entry() returned %02x\n", ret);
301 if (ret != HAB_SUCCESS) {
302 printf("hab entry function failed: %02x\n", ret);
303 hab_caam_clock_enable(0);
309 static inline enum hab_status hab_exit(void)
313 ret = hab_rvt_exit();
314 if (ret != HAB_SUCCESS)
315 printf("hab exit function failed: %02x\n", ret);
317 hab_caam_clock_enable(0);
323 static enum hab_status hab_check_target(enum hab_target type, uint32_t addr, size_t len)
328 if (ret != HAB_SUCCESS)
331 ret = hab_rvt_check_target(type, (void *)addr, len);
332 if (ret != HAB_SUCCESS) {
333 printf("check_target(0x%08x, 0x%08x) failed: %d\n",
339 if (ret == HAB_SUCCESS && get_hab_status() > 0) {
345 static enum hab_status hab_assert(uint32_t type, uint32_t addr, size_t len)
350 if (ret != HAB_SUCCESS)
353 ret = hab_rvt_assert(type, (void *)addr, len);
354 if (ret != HAB_SUCCESS) {
355 printf("assert(0x%08x, 0x%08x) failed: %d\n",
361 if (ret == HAB_SUCCESS && get_hab_status() > 0) {
367 static int do_hab_status(cmd_tbl_t *cmdtp, int flag, int argc,
371 return CMD_RET_USAGE;
375 return CMD_RET_SUCCESS;
378 static int do_hab_check_target(cmd_tbl_t *cmdtp, int flag, int argc,
381 enum hab_target type = HAB_TGT_ANY;
386 return CMD_RET_USAGE;
388 addr = simple_strtoul(argv[1], NULL, 16);
389 len = simple_strtoul(argv[2], NULL, 16);
391 switch (argv[3][0]) {
394 type = HAB_TGT_PERIPHERAL;
398 type = HAB_TGT_MEMORY;
404 printf("Invalid type '%s'\n", argv[3]);
405 return CMD_RET_USAGE;
408 if (hab_check_target(type, addr, len) != HAB_SUCCESS)
409 return CMD_RET_FAILURE;
411 return CMD_RET_SUCCESS;
414 static int do_hab_assert(cmd_tbl_t *cmdtp, int flag, int argc,
422 return CMD_RET_USAGE;
424 addr = simple_strtoul(argv[1], NULL, 16);
425 len = simple_strtoul(argv[2], NULL, 16);
427 type = simple_strtoul(argv[3], NULL, 16);
430 if (hab_assert(type, addr, len) != HAB_SUCCESS)
431 return CMD_RET_FAILURE;
433 return CMD_RET_SUCCESS;
437 hab_status, CONFIG_SYS_MAXARGS, 1, do_hab_status,
438 "display HAB status",
443 hab_check_target, 4, 0, do_hab_check_target,
444 "verify an address range via HAB",
446 "\t\taddr -\taddress to verify\n"
447 "\t\tlen -\tlength of addr range to verify\n"
451 hab_assert, 4, 0, do_hab_assert,
452 "Test an assertion against the HAB audit log",
454 "\t\taddr -\taddress to verify\n"
455 "\t\tlen -\tlength of addr range to verify\n"