Validating uImage signature using HAB

cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

Validating uImage signature using HAB

Jump to solution
2,509 Views
jdepedro
Contributor IV


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 :smileyhappy:

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 :smileyhappy:

--- 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;

}

1 Solution
1,530 Views
jdepedro
Contributor IV

The previous error was generated because I was using different key indexes for validation of the U-Boot image and the uImage. Using the same key index solved the error.

View solution in original post

5 Replies
1,530 Views
jdepedro
Contributor IV

After debugging the problem, I have found that the following code behaves differently:

                        load_addr = (uint32_t)hab_rvt_authenticate_image(

                                        HAB_CID_UBOOT,

                                        ivt_offset, (void **)&start,

                                        (size_t *)&bytes, NULL);

That returns 0 in closed devices, but != 0 on open devices, using the same U-Boot Image and the same uImage. That is the root cause of the differences.

This is a consistent behaviour, because in open devices allows the device to boot.

I still don't understand the following HAB event, could you help me interpret it?

--------- 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

STS = HAB_FAILURE (0x33)

RSN = HAB_INV_INDEX (0x0F)

CTX = HAB_CTX_COMMAND (0xC0)

ENG = HAB_ENG_ANY (0x00)

0 Kudos
1,531 Views
jdepedro
Contributor IV

The previous error was generated because I was using different key indexes for validation of the U-Boot image and the uImage. Using the same key index solved the error.

1,530 Views
Yuri
NXP Employee
NXP Employee

Hello,

   please use Appendix A (Interpreting HAB Event Data from Report_Event() API)

of the “HAB4_API.pdf” in the CST package to get more information about HAB events.

  The fact that system boots in any case may mean, that the i.MX6 is not really “closed”.

Have a great day,
Yuri

-----------------------------------------------------------------------------------------------------------------------
Note: If this post answers your question, please click the Correct Answer button. Thank you!
-----------------------------------------------------------------------------------------------------------------------

0 Kudos
1,530 Views
jdepedro
Contributor IV

Hi Yuri,

thanks for your answer!

Please notice that I am using a properly signed and encrypted U-Boot which does boot a closed device. (The output on the first image shows that the device is in open mode because I tried with both open and closed devices).

The strange behaviour is in the uImage (not the U-Boot image) validation.

I will debug the HAB events to get more information. By the way, I have noticed in posts from other NXP employess a nice formatted HAB interpretation which I think is done by some kind of script. Could you share that script, or any way to automatically interpret HAB events?

Thanks a lot.

0 Kudos
1,530 Views
jdepedro
Contributor IV

Never mind, I just found [U-Boot] [PATCH] iMX: adding parsing to hab_status command  !

I will try to debug the HAB events and will update this post, thanks.

0 Kudos