Commit dd058bca4a30fff27bcd643575b2935c706d021b

Authored by Breno Lima
Committed by Ye Li
1 parent 5cc3fbe211

MLK-21174 mx7ulp: hab: Add hab_status command for HABv4 M4 boot

When booting in low power or dual boot modes the M4 binary is
authenticated by the M4 ROM code.

Add an option in hab_status command so users can retrieve M4 HAB
failure and warning events.

=> hab_status m4

   Secure boot disabled

   HAB Configuration: 0xf0, HAB State: 0x66
   No HAB Events Found!

Add command documentation in mx6_mx7_secure_boot.txt guide.

As HAB M4 API cannot be called from A7 core the code is parsing
the M4 HAB persistent memory region. The HAB persistent memory
stores HAB events, public keys and others HAB related information.

The HAB persistent memory region addresses and sizes can be found
in AN12263 "HABv4 RVT Guidelines and Recommendations".

Reviewed-by: Utkarsh Gupta <utkarsh.gupta@nxp.com>
Reviewed-by: Ye Li <ye.li@nxp.com>
Signed-off-by: Breno Lima <breno.lima@nxp.com>
(cherry picked from commit 0efff16579fabcf57acb9c8857afac8fb58de355)

Showing 3 changed files with 139 additions and 0 deletions Side-by-side Diff

arch/arm/include/asm/mach-imx/hab.h
... ... @@ -45,6 +45,15 @@
45 45 u8 par; /* Parameters field */
46 46 };
47 47  
  48 +/* Default event structure */
  49 +struct __packed evt_def {
  50 + struct hab_hdr hdr; /* Header */
  51 + uint32_t sts; /* Status */
  52 + uint32_t ctx; /* Default context */
  53 + uint8_t *data; /* Default data location */
  54 + size_t bytes; /* Size of default data */
  55 +};
  56 +
48 57 /* -------- start of HAB API updates ------------*/
49 58 /* The following are taken from HAB4 SIS */
50 59  
... ... @@ -216,6 +225,12 @@
216 225  
217 226 #define IVT_SIZE 0x20
218 227 #define CSF_PAD_SIZE 0x2000
  228 +
  229 +#define HAB_TAG_EVT 0xDB
  230 +#define HAB_TAG_EVT_DEF 0x0C
  231 +
  232 +#define HAB_MAJ_VER 0x40
  233 +#define HAB_MAJ_MASK 0xF0
219 234  
220 235 /* ----------- end of HAB API updates ------------*/
221 236  
arch/arm/mach-imx/hab.c
... ... @@ -23,6 +23,12 @@
23 23 (is_soc_type(MXC_SOC_MX7ULP) ? 0x80000000 : \
24 24 ((is_soc_type(MXC_SOC_MX7) || is_soc_type(MXC_SOC_IMX8M))? 0x2000000 : 0x2))
25 25  
  26 +#ifdef CONFIG_MX7ULP
  27 +#define HAB_M4_PERSISTENT_START ((soc_rev() >= CHIP_REV_2_0) ? 0x20008040 : \
  28 + 0x20008180)
  29 +#define HAB_M4_PERSISTENT_BYTES 0xB80
  30 +#endif
  31 +
26 32 static int ivt_header_error(const char *err_str, struct ivt_header *ivt_hdr)
27 33 {
28 34 printf("%s magic=0x%x length=0x%02x version=0x%x\n", err_str,
29 35  
30 36  
... ... @@ -469,15 +475,99 @@
469 475 return 0;
470 476 }
471 477  
  478 +#ifdef CONFIG_MX7ULP
  479 +
  480 +static int get_record_len(struct record *rec)
  481 +{
  482 + return (size_t)((rec->len[0] << 8) + (rec->len[1]));
  483 +}
  484 +
  485 +static int get_hab_status_m4(void)
  486 +{
  487 + unsigned int index = 0;
  488 + uint8_t event_data[128];
  489 + size_t record_len, offset = 0;
  490 + enum hab_config config = 0;
  491 + enum hab_state state = 0;
  492 +
  493 + if (imx_hab_is_enabled())
  494 + puts("\nSecure boot enabled\n");
  495 + else
  496 + puts("\nSecure boot disabled\n");
  497 +
  498 + /*
  499 + * HAB in both A7 and M4 gather the security state
  500 + * and configuration of the chip from
  501 + * shared SNVS module
  502 + */
  503 + hab_rvt_report_status(&config, &state);
  504 + printf("\nHAB Configuration: 0x%02x, HAB State: 0x%02x\n",
  505 + config, state);
  506 +
  507 + struct record *rec = (struct record *)(HAB_M4_PERSISTENT_START);
  508 +
  509 + record_len = get_record_len(rec);
  510 +
  511 + /* Check if HAB persistent memory is valid */
  512 + if (rec->tag != HAB_TAG_EVT_DEF ||
  513 + record_len != sizeof(struct evt_def) ||
  514 + (rec->par & HAB_MAJ_MASK) != HAB_MAJ_VER) {
  515 + puts("\nERROR: Invalid HAB persistent memory\n");
  516 + return 1;
  517 + }
  518 +
  519 + /* Parse events in HAB M4 persistent memory region */
  520 + while (offset < HAB_M4_PERSISTENT_BYTES) {
  521 + rec = (struct record *)(HAB_M4_PERSISTENT_START + offset);
  522 +
  523 + record_len = get_record_len(rec);
  524 +
  525 + if (rec->tag == HAB_TAG_EVT) {
  526 + memcpy(&event_data, rec, record_len);
  527 + puts("\n");
  528 + printf("--------- HAB Event %d -----------------\n",
  529 + index + 1);
  530 + puts("event data:\n");
  531 + display_event(event_data, record_len);
  532 + puts("\n");
  533 + index++;
  534 + }
  535 +
  536 + offset += record_len;
  537 +
  538 + /* Ensure all records start on a word boundary */
  539 + if ((offset % 4) != 0)
  540 + offset = offset + (4 - (offset % 4));
  541 + }
  542 +
  543 + if (!index)
  544 + puts("No HAB Events Found!\n\n");
  545 +
  546 + return 0;
  547 +}
  548 +#endif
  549 +
472 550 static int do_hab_status(cmd_tbl_t *cmdtp, int flag, int argc,
473 551 char * const argv[])
474 552 {
  553 +#ifdef CONFIG_MX7ULP
  554 + if ((argc > 2)) {
  555 + cmd_usage(cmdtp);
  556 + return 1;
  557 + }
  558 +
  559 + if (strcmp("m4", argv[1]) == 0)
  560 + get_hab_status_m4();
  561 + else
  562 + get_hab_status();
  563 +#else
475 564 if ((argc != 1)) {
476 565 cmd_usage(cmdtp);
477 566 return 1;
478 567 }
479 568  
480 569 get_hab_status();
  570 +#endif
481 571  
482 572 return 0;
483 573 }
484 574  
485 575  
... ... @@ -517,11 +607,20 @@
517 607 return 0;
518 608 }
519 609  
  610 +#ifdef CONFIG_MX7ULP
520 611 U_BOOT_CMD(
  612 + hab_status, CONFIG_SYS_MAXARGS, 2, do_hab_status,
  613 + "display HAB status and events",
  614 + "hab_status - A7 HAB event and status\n"
  615 + "hab_status m4 - M4 HAB event and status"
  616 + );
  617 +#else
  618 +U_BOOT_CMD(
521 619 hab_status, CONFIG_SYS_MAXARGS, 1, do_hab_status,
522 620 "display HAB status",
523 621 ""
524 622 );
  623 +#endif
525 624  
526 625 U_BOOT_CMD(
527 626 hab_auth_img, 4, 0, do_authenticate_image,
doc/imx/habv4/guides/mx6_mx7_secure_boot.txt
... ... @@ -230,6 +230,30 @@
230 230 HAB Configuration: 0xf0, HAB State: 0x66
231 231 No HAB Events Found!
232 232  
  233 +1.6.1 Verifying HAB events in i.MX7ULP
  234 +---------------------------------------
  235 +
  236 +When booting i.MX7ULP in low power or dual boot modes the M4 binary is
  237 +authenticated by an independent HAB in M4 ROM code using a
  238 +different SRK key set.
  239 +
  240 +The U-Boot provides a M4 option in hab_status command so users can retrieve
  241 +M4 HAB failure and warning events.
  242 +
  243 +- Verify HAB M4 events:
  244 +
  245 + => hab_status m4
  246 +
  247 + Secure boot disabled
  248 +
  249 + HAB Configuration: 0xf0, HAB State: 0x66
  250 + No HAB Events Found!
  251 +
  252 +As HAB M4 API cannot be called from A7 core the command is parsing the M4 HAB
  253 +persistent memory region, M4 software should not modify this reserved region.
  254 +
  255 +Details about HAB persistent memory region can be found in AN12263[2].
  256 +
233 257 1.7 Closing the device
234 258 -----------------------
235 259  
... ... @@ -417,4 +441,5 @@
417 441 References:
418 442 [1] AN4581: "Secure Boot on i.MX 50, i.MX 53, i.MX 6 and i.MX 7 Series using
419 443 HABv4" - Rev 2.
  444 +[2] AN12263: "HABv4 RVT Guidelines and Recommendations" - Rev 0.