HABv4 with SPL and u-boot-dtb.img on i.MX6

Hello,
I'm trying to make secure boot work on i.MX6 SABRE with SPL and u-boot-dtb.img files and I'm not sure how to do it.
I'm using the U-Boot vanilla master branch (2024.04-rc2) with the following configuration:
# Remove some stuff to not exceed file size limit $ cat <<EOF >> configs/mx6sabresd_defconfig CONFIG_BOOTMETH_EFILOADER=n CONFIG_CMD_NET=n CONFIG_NET=n EOF
# Enable secure boot $ cat <<EOF >> configs/mx6sabresd_defconfig CONFIG_IMX_HAB=y CONFIG_SPL_LOAD_FIT_ADDRESS=0x18000000 EOF
$ make ARCH=arm O=build mx6sabresd_defconfig
$ make ARCH=arm O=build
I have no issue to generate a working SPL-signed file following doc/imx/habv4/guides/mx6_mx7_spl_secure_boot.txt instructions.
doc/imx/habv4/guides/mx6_mx7_spl_secure_boot.txt only gives instructions to sign u-boot-ivt.img but this file doesn't contain device trees listed in CONFIG_OF_LIST as u-boot-dtb.img does and I need them.
NXP AN4581 lists 2 possible formats to sign additional images:
- Image format:
------- +-----------------------------+ <-- *load_address ^ | | | | | | | Image data | Signed | | | Data | | | | +-----------------------------+ | | Padding Next Boundary | | +-----------------------------+ <-- *ivt v | Image Vector Table | ------- +-----------------------------+ <-- *csf | | | Command Sequence File (CSF) | | | +-----------------------------+ | Padding (optional) | +-----------------------------+
- FIT image format:
------- +-----------------------------+ ------- ^ | | ^ | | | | | | FDT FIT | | | | | | Signed data | | | | | +-----------------------------+ | | | Padding Next Boundary | | | +-----------------------------+ | v | Image Vector Table | | ------- +-----------------------------+ | FIT image | | | | Command Sequence File (CSF) | | | | | +-----------------------------+ | | Padding (optional) | | ------- +-----------------------------+ | ^ | | | Signed data | | U-Boot | | v | | v ------- +-----------------------------+ -------
And as u-boot-dtb.img is a FIT image, I probably have to use the FIT image format, right?
I manually craft the signed FIT image using doc/imx/habv4/csf_examples/mx8m/csf.sh as reference and everything looks fine:
U-Boot SPL 2024.04-rc2-00025-g9e00b6993f-dirty (Feb 19 2024 - 13:17:31 +0100) >>SPL: board_init_r() spl_init Trying to boot from MMC1 fit read offset 11400, size=12800, dst=18000000, count=12800 spl_load_simple_fit_fix_load: ivt: 18001000 offset: 1000 size: 3060 spl_load_simple_fit_fix_load: ivt self: 18001000 hab fuse not enabled
Authenticate image from DDR location 0x18000000...
ivt_offset = 0x1000, ivt addr = 0x18001000 ivt entry = 0x18000000, dcd = 0x00000000, csf = 0x18001020 Dumping IVT .. @............ ........ ....... Dumping CSF Header ..PC...........P ................ .......<........ ...............8
Calling authenticate_image in ROM ivt_offset = 0x1000 start = 0x18000000 bytes = 0x3060 firmware: 'firmware-1' External data: dst=17800000, offset=3060, size=86138 Image OS is U-Boot fdt: 'fdt-1' Can't get 'load' property from FIT 0x18000000, node: offset 464, name fdt-1 (FDT_ERR_NOTFOUND) External data: dst=17886140, offset=89198, size=ac00 Can't get 'entry' property from FIT 0x18000000, node: offset 464, name fdt-1 (FDT_ERR_NOTFOUND) loadables: 'firmware-1' no string for index 1 Jumping to U-Boot... SPL malloc() used 0x0 bytes (0 KB) image entry point: 0x
U-Boot 2024.04-rc2-00025-g9e00b6993f-dirty (Feb 19 2024 - 13:17:31 +0100)
CPU: Freescale i.MX6Q rev1.2 996 MHz (running at 792 MHz) CPU: Automotive temperature grade (-40C to 125C) at 35C Reset cause: POR Model: Freescale i.MX6 Quad SABRE Smart Device Board DRAM: 1 GiB Core: 94 devices, 23 uclasses, devicetree: separate WDT: Started watchdog@20c0000 with servicing every 1000ms (128s timeout) MMC: FSL_SDHC: 4, FSL_SDHC: 1, FSL_SDHC: 3 Loading Environment from MMC... *** Warning - bad CRC, using default environment
No panel detected: default to Hannstar-XGA Display: Hannstar-XGA (1024x768) In: serial Out: serial Err: serial SEC0: RNG instantiated Hit any key to stop autoboot: 0 => hab_status
Secure boot disabled
HAB Configuration: 0xf0, HAB State: 0x66 No HAB Events Found!
But as only the FDT part of the FIT image is checked through HAB, U-Boot and DTB are only protected by FIT image hashes, right?
Using fdtdump shows that crc32 is used as hash algorithm for FIT image which is a super weak one. I tried to pass another algo (sha256) using mkimage -o option but that doesn't work.
./tools/mkimage -f auto -A arm -T firmware -C none -O u-boot -a 0x17800000 -e 0x17800000 -p 0x0 -n "U-Boot 2024.04-rc2-00025-g9e00b6993f-dirty for mx6sabresd board" -E -b arch/arm/dts/imx6q-sabresd.dtb -b arch/arm/dts/imx6qp-sabresd.dtb -b arch/arm/dts/imx6dl-sabresd.dtb -d u-boot-nodtb.bin -o sha256 u-boot-dtb.img
Is there any way to change U-Boot FIT image hash?
I also try to use image format and force the HAB to verify the whole u-boot-dtb.img file by patching the FIT image size:
image_size=$(stat -tc %s u-boot-dtb.img) printf "00000004: %08x" "$image_size" | xxd -r - u-boot-dtb.img
SPL starts, authentication looks fine but the boot fails. Is there any chance to make it work or is it insane to try to use this format?
Regards,
Benjamin

On 2/20/24 04:50, Benjamin Lemouzy wrote:
Hello,
I'm trying to make secure boot work on i.MX6 SABRE with SPL and u-boot-dtb.img files and I'm not sure how to do it.
I'm using the U-Boot vanilla master branch (2024.04-rc2) with the following configuration:
# Remove some stuff to not exceed file size limit $ cat <<EOF >> configs/mx6sabresd_defconfig CONFIG_BOOTMETH_EFILOADER=n CONFIG_CMD_NET=n CONFIG_NET=n EOF # Enable secure boot $ cat <<EOF >> configs/mx6sabresd_defconfig CONFIG_IMX_HAB=y CONFIG_SPL_LOAD_FIT_ADDRESS=0x18000000 EOF $ make ARCH=arm O=build mx6sabresd_defconfig $ make ARCH=arm O=build
I have no issue to generate a working SPL-signed file following doc/imx/habv4/guides/mx6_mx7_spl_secure_boot.txt instructions.
doc/imx/habv4/guides/mx6_mx7_spl_secure_boot.txt only gives instructions to sign u-boot-ivt.img but this file doesn't contain device trees listed in CONFIG_OF_LIST as u-boot-dtb.img does and I need them.
NXP AN4581 lists 2 possible formats to sign additional images:
Image format:
------- +-----------------------------+ <-- *load_address ^ | | | | | | | Image data | Signed | | | Data | | | | +-----------------------------+ | | Padding Next Boundary | | +-----------------------------+ <-- *ivt v | Image Vector Table | ------- +-----------------------------+ <-- *csf | | | Command Sequence File (CSF) | | | +-----------------------------+ | Padding (optional) | +-----------------------------+
FIT image format:
------- +-----------------------------+ ------- ^ | | ^ | | | | | | FDT FIT | | | | | |
Signed data | | | | | +-----------------------------+ | | | Padding Next Boundary | | | +-----------------------------+ | v | Image Vector Table | | ------- +-----------------------------+ | FIT image | | | | Command Sequence File (CSF) | | | | | +-----------------------------+ | | Padding (optional) | | ------- +-----------------------------+ | ^ | | | Signed data | | U-Boot | | v | | v ------- +-----------------------------+ -------
And as u-boot-dtb.img is a FIT image, I probably have to use the FIT image format, right?
I manually craft the signed FIT image using doc/imx/habv4/csf_examples/mx8m/csf.sh as reference and everything looks fine:
U-Boot SPL 2024.04-rc2-00025-g9e00b6993f-dirty (Feb 19 2024 - 13:17:31 +0100) >>SPL: board_init_r() spl_init Trying to boot from MMC1 fit read offset 11400, size=12800, dst=18000000, count=12800 spl_load_simple_fit_fix_load: ivt: 18001000 offset: 1000 size: 3060 spl_load_simple_fit_fix_load: ivt self: 18001000 hab fuse not enabled Authenticate image from DDR location 0x18000000... ivt_offset = 0x1000, ivt addr = 0x18001000 ivt entry = 0x18000000, dcd = 0x00000000, csf = 0x18001020 Dumping IVT .. @............ ........ ....... Dumping CSF Header ..PC...........P ................ .......<........ ...............8 Calling authenticate_image in ROM ivt_offset = 0x1000 start = 0x18000000 bytes = 0x3060 firmware: 'firmware-1' External data: dst=17800000, offset=3060, size=86138 Image OS is U-Boot fdt: 'fdt-1' Can't get 'load' property from FIT 0x18000000, node: offset 464, name fdt-1 (FDT_ERR_NOTFOUND) External data: dst=17886140, offset=89198, size=ac00 Can't get 'entry' property from FIT 0x18000000, node: offset 464, name fdt-1 (FDT_ERR_NOTFOUND) loadables: 'firmware-1' no string for index 1 Jumping to U-Boot... SPL malloc() used 0x0 bytes (0 KB) image entry point: 0x U-Boot 2024.04-rc2-00025-g9e00b6993f-dirty (Feb 19 2024 - 13:17:31 +0100) CPU: Freescale i.MX6Q rev1.2 996 MHz (running at 792 MHz) CPU: Automotive temperature grade (-40C to 125C) at 35C Reset cause: POR Model: Freescale i.MX6 Quad SABRE Smart Device Board DRAM: 1 GiB Core: 94 devices, 23 uclasses, devicetree: separate WDT: Started watchdog@20c0000 with servicing every 1000ms (128s timeout) MMC: FSL_SDHC: 4, FSL_SDHC: 1, FSL_SDHC: 3 Loading Environment from MMC... *** Warning - bad CRC, using default environment No panel detected: default to Hannstar-XGA Display: Hannstar-XGA (1024x768) In: serial Out: serial Err: serial SEC0: RNG instantiated Hit any key to stop autoboot: 0 => hab_status Secure boot disabled HAB Configuration: 0xf0, HAB State: 0x66 No HAB Events Found!
But as only the FDT part of the FIT image is checked through HAB, U-Boot and DTB are only protected by FIT image hashes, right?
Using fdtdump shows that crc32 is used as hash algorithm for FIT image which is a super weak one. I tried to pass another algo (sha256) using mkimage -o option but that doesn't work.
./tools/mkimage -f auto -A arm -T firmware -C none -O u-boot -a 0x17800000 -e 0x17800000 -p 0x0 -n "U-Boot 2024.04-rc2-00025-g9e00b6993f-dirty for mx6sabresd board" -E -b arch/arm/dts/imx6q-sabresd.dtb -b arch/arm/dts/imx6qp-sabresd.dtb -b arch/arm/dts/imx6dl-sabresd.dtb -d u-boot-nodtb.bin -o sha256 u-boot-dtb.img
Is there any way to change U-Boot FIT image hash?
I believe these options are only used for signed FIT images (e.g. for verified boot [1]). Since you are using an external signing process, they have no effect. I suggest creating your FIT manually (e.g. -f u-boot.its instead of -f auto). You should be able to specify the hashes manually that way.
I also try to use image format and force the HAB to verify the whole u-boot-dtb.img file by patching the FIT image size:
image_size=$(stat -tc %s u-boot-dtb.img) printf "00000004: %08x" "$image_size" | xxd -r - u-boot-dtb.img
SPL starts, authentication looks fine but the boot fails. Is there any chance to make it work or is it insane to try to use this format?
I have always just used verified boot for U-Boot and the kernel, and only used vendor-specific stuff for SPL.
--Sean
[1] https://docs.u-boot.org/en/latest/usage/fit/verified-boot.html [2] https://docs.u-boot.org/en/latest/usage/fit/source_file_format.html
[Embedded World 2024, SECO SpA]https://www.messe-ticket.de/Nuernberg/embeddedworld2024/Register/ew24517689

On Tue, 20 Feb 2024 11:29:53 -0500 Sean Anderson sean.anderson@seco.com wrote:
On 2/20/24 04:50, Benjamin Lemouzy wrote:
Using fdtdump shows that crc32 is used as hash algorithm for FIT image which is a super weak one. I tried to pass another algo (sha256) using mkimage -o option but that doesn't work.
./tools/mkimage -f auto -A arm -T firmware -C none -O u-boot -a 0x17800000 -e 0x17800000 -p 0x0 -n "U-Boot 2024.04-rc2-00025-g9e00b6993f-dirty for mx6sabresd board" -E -b arch/arm/dts/imx6q-sabresd.dtb -b arch/arm/dts/imx6qp-sabresd.dtb -b arch/arm/dts/imx6dl-sabresd.dtb -d u-boot-nodtb.bin -o sha256 u-boot-dtb.img
Is there any way to change U-Boot FIT image hash?
I believe these options are only used for signed FIT images (e.g. for verified boot [1]). Since you are using an external signing process, they have no effect. I suggest creating your FIT manually (e.g. -f u-boot.its instead of -f auto). You should be able to specify the hashes manually that way.
Using "fdtdump -s u-boot-dtb.img" output as reference to create a u-boot.its file, I now have a u-boot.itb file with sha256 hashes.
I also try to use image format and force the HAB to verify the whole u-boot-dtb.img file by patching the FIT image size:
image_size=$(stat -tc %s u-boot-dtb.img) printf "00000004: %08x" "$image_size" | xxd -r - u-boot-dtb.img
SPL starts, authentication looks fine but the boot fails. Is there any chance to make it work or is it insane to try to use this format?
I have always just used verified boot for U-Boot and the kernel, and only used vendor-specific stuff for SPL.
That indeed a good idea but CONFIG_SPL_FIT_SIGNATURE and CONFIG_SPL_DM (as dependency) take a lot of space and SPL overflows i.MX6 OCRAM.
I finally succeed to make U-Boot check with HAB work using the new u-boot.itb image with the following signature format:
------- +-----------------------------+ <-- *load_address ^ | | | | | | | Image data | Signed | | | Data | | | | +-----------------------------+ | | Padding Next Boundary | | +-----------------------------+ <-- *ivt v | Image Vector Table | ------- +-----------------------------+ <-- *csf | | | Command Sequence File (CSF) | | | +-----------------------------+ | Padding (optional) | +-----------------------------+
I don't really understand what u-boot-dtb.img file is but it doesn't work with U-Boot CONFIG_IMX_HAB.
Thanks for help!
Benjamin
participants (2)
-
Benjamin Lemouzy
-
Sean Anderson