AnsweredAssumed Answered

Validating uImage signature using HAB

Question asked by Jose Diaz de Grenu de Pedro on Jun 8, 2016
Latest reply on Jun 10, 2016 by Jose Diaz de Grenu de Pedro


Hi, I am reading the document i.MX 6 Linux High Assurance Boot (HAB) User's Guide, Rev. L3.0.35_1.1.0, 01/2013 which mentions how to use the HAB on the i.MX6 to validate uImages.

I have been trying the feature with some success. Some notes:

  • I am using a signed and encrypted U-Boot.
  • I have tested this on both closed and opened devices
  • I have slightly modified the code U-Boot code in the hab_authenticate_image function (hab.c) to add more debug, and to skip the check about whether the device is closed.

 

These are my results:

  • If I try to use a default uImage, the hab_authenticate_image fails, and the target does not boot. This works as expected
  • If a use a signed uImage, the behaviour is strange (to my understanding) because:
    • HAB events *are* generated
    • The verifications of the uImage passes succesfully, and the target boots.

 

This behaviour I find confusing:

  • What do this HAB events exactly mean?
  • Why is the uImage authentication by the HAB passing if HAB events are generated?

 

This is the complete output:

 

U-Boot dub-2015.04-r4+gef02d8ca6e65 (Jun 08 2016 - 10:49:38)

 

 

CPU:   Freescale i.MX6Q rev1.5 1200 MHz (running at 792 MHz)

CPU:   Extended Commercial temperature grade (-20C to 105C) at 44C

Reset cause: POR

I2C:   ready

DRAM:  1 GiB

MMC:   FSL_SDHC: 0 (eMMC), FSL_SDHC: 1

In:    serial

Out:   serial

Err:   serial

Boot device: MMC4

PMIC:  DA9063, Device: 0x61, Variant: 0x50, Customer: 0x00, Config: 0x56

Net:   FEC [PRIME]

Normal Boot

Hit any key to stop autoboot:  0

reading boot.scr

2042 bytes read in 19 ms (104.5 KiB/s)

## Executing script at 12000000

reading uImage

5001248 bytes read in 155 ms (30.8 MiB/s)

reading uImage-imx6q-ccimx6sbc-wb.dtb

45292 bytes read in 22 ms (2 MiB/s)

 

 

Authenticate image from DDR location 0x12000000...

hab_rvt_entry success

 

 

ivt_offset = 0x4c3000, ivt addr = 0x124c3000

Dumping IVT

124c3000: 402000d1 12001000 00000000 00000000    .. @............

124c3010: 00000000 124c3000 124c3020 00000000    .....0L. 0L.....

Dumping CSF Header

124c3020: 405000d4 000c00be 00001703 50000000    ..P@...........P

124c3030: 020c00be 01000009 90040000 000c00ca    ................

124c3040: 0000c501 e4070000 000c00be 02000009    ................

124c3050: e8090000 001400ca 0000c502 3c0d0000    ...............<

--- Status before ---

 

 

Secure boot disabled

 

 

HAB Configuration: 0xf0, HAB State: 0x66

No HAB Events Found!

 

 

--- ------------- ----

 

 

Calling authenticate_image in ROM

        ivt_offset = 0x4c3000

        start = 0x12000000

        bytes = 0x4c5020

load_addr: 301993984

hab_rvt_exit() success

--- status after ---

 

 

Secure boot disabled

 

 

HAB Configuration: 0xf0, HAB State: 0x66

--------- HAB Event 1 -----------------

event data:

        0xdb 0x00 0x14 0x41 0x33 0x0f 0xc0 0x00

        0xbe 0x00 0x0c 0x00 0x03 0x17 0x00 0x00

        0x00 0x00 0x00 0x50

 

 

--------- HAB Event 2 -----------------

event data:

        0xdb 0x00 0x14 0x41 0x33 0x0c 0xa0 0x00

        0x00 0x00 0x00 0x00 0x12 0x4c 0x30 0x00

        0x00 0x00 0x00 0x20

 

 

--------- HAB Event 3 -----------------

event data:

        0xdb 0x00 0x14 0x41 0x33 0x0c 0xa0 0x00

        0x00 0x00 0x00 0x00 0x12 0x00 0x10 0x00

        0x00 0x00 0x00 0x04

--- ------------ ---

## Booting kernel from Legacy Image at 12000000 ...

   Image Name:   Linux-3.14.0+

   Image Type:   ARM Linux Kernel Image (uncompressed)

   Data Size:    4991888 Bytes = 4.8 MiB

   Load Address: 10800000

   Entry Point:  10800000

   Verifying Checksum ... OK

## Flattened Device Tree blob at 18000000

   Booting using the fdt blob at 0x18000000

   Loading Kernel Image ... OK

   Using Device Tree in place at 18000000, end 1800e0eb

1.2G chip, increase VDDARM_IN/VDDSOC_IN

 

 

Starting kernel ...

 

 

 

 

 

 

 

 

These are the changes to the code:

 

 

diff --git a/arch/arm/cpu/armv7/mx6/hab.c b/arch/arm/cpu/armv7/mx6/hab.c

index f58e688b78b8..f7980816e45e 100644

--- a/arch/arm/cpu/armv7/mx6/hab.c

+++ b/arch/arm/cpu/armv7/mx6/hab.c

@@ -136,20 +136,20 @@ uint32_t authenticate_image(uint32_t ddr_start, uint32_t image_size)

        hab_rvt_entry = hab_rvt_entry_p;

        hab_rvt_exit = hab_rvt_exit_p;

 

-       if (is_hab_enabled()) {

                printf("\nAuthenticate image from DDR location 0x%x...\n",

                       ddr_start);

 

                hab_caam_clock_enable(1);

 

                if (hab_rvt_entry() == HAB_SUCCESS) {

+                       printf("hab_rvt_entry success :)\n");

                        /* If not already aligned, Align to ALIGN_SIZE */

                        ivt_offset = (image_size + ALIGN_SIZE - 1) &

                                        ~(ALIGN_SIZE - 1);

 

                        start = ddr_start;

                        bytes = ivt_offset + IVT_SIZE + CSF_PAD_SIZE;

-#ifdef DEBUG

+                      

                        printf("\nivt_offset = 0x%x, ivt addr = 0x%x\n",

                               ivt_offset, ddr_start + ivt_offset);

                        puts("Dumping IVT\n");

@@ -162,13 +162,14 @@ uint32_t authenticate_image(uint32_t ddr_start, uint32_t image_size)

                                     (void *)(ddr_start + ivt_offset+IVT_SIZE),

                                     4, 0x10, 0);

 

+                       puts(" --- Status before ---\n");

                        get_hab_status();

+                       puts(" --- ------------- ----\n");

 

                        puts("\nCalling authenticate_image in ROM\n");

                        printf("\tivt_offset = 0x%x\n", ivt_offset);

                        printf("\tstart = 0x%08lx\n", start);

                        printf("\tbytes = 0x%x\n", bytes);

-#endif

                        /*

                         * If the MMU is enabled, we have to notify the ROM

                         * code, or it won't flush the caches when needed.

@@ -203,9 +204,12 @@ uint32_t authenticate_image(uint32_t ddr_start, uint32_t image_size)

                                        HAB_CID_UBOOT,

                                        ivt_offset, (void **)&start,

                                        (size_t *)&bytes, NULL);

+                       printf("load_addr: %d\n", load_addr);

                        if (hab_rvt_exit() != HAB_SUCCESS) {

                                puts("hab exit function fail\n");

                                load_addr = 0;

+                       } else {

+                               puts("hab_rvt_exit() success :)\n");

                        }

                } else {

                        puts("hab entry function fail\n");

@@ -213,15 +217,12 @@ uint32_t authenticate_image(uint32_t ddr_start, uint32_t image_size)

 

                hab_caam_clock_enable(0);

 

+               puts(" --- status after ---\n");

                get_hab_status();

-       } else {

-               puts("hab fuse not enabled\n");

-       }

-

-       if ((!is_hab_enabled()) || (load_addr != 0))

-               result = 1;

+               puts(" --- ------------ ---\n");

 

-       return result;

+       if (load_addr == 0) return 0;

+       return 1;

}

Outcomes