The secure platform, provided by Foundries.io is leveraged by several layers of signed binaries which are verified during boot time. Some layers use proprietary source code (such as the secure boot on some architectures) and other layers are part of well known open source projects (such as U-Boot and Linux Kernel).
This article details how to read the available log and artifacts from a booting machine, in order to detect the verification mechanism executed during a normal boot.
A common boot sequence starts with the execution of the content of a ROM software/firmware just after the power on. This ROM software/firmware then instructs the processor to jump to another software, the secondary program loader (SPL). Some architectures (i.e. i.MX family) support the verification of the SPL image during this jump which is performed by hardware (RoT).
For those cases, the boot sequence is as shown in the following diagram:
The hardware has the ways to verify the SPL binary, which has the information to verify the file
u-boot-itb has the information to load, execute and verify TF-A, OP-TEE and U-Boot proper.
The U-Boot proper then loads, executes and verifies the Linux Kernel image and any DTB file. The Linux Kernel modules (in tree and external drivers built as modules) are verified by kernel when they are loaded.
It is common that when an image is loaded and verified, a log prints the details for each boot phase.
Using the following UUU script, it is possible to check the HAB status of a board and double check if this is using secure boot or not.
uuu_version 1.2.39 SDP: boot -f SPL-mfgtool SDPV: delay 1000 SDPV: write -f u-boot-mfgtool.itb SDPV: jump FB: ucmd hab_status FB: DONE
The log of the board booting and the result of the command
hab_status from a closed
U-Boot 2020.04+fio+gcbb11e17ea (Aug 12 2021 - 23:27:31 +0000) CPU: i.MX6ULL rev1.1 900 MHz (running at 396 MHz) CPU: Commercial temperature grade (0C to 95C) at 48C Reset cause: POR Model: i.MX6 ULL 14x14 EVK Board Board: MX6ULL 14x14 EVK DRAM: 480 MiB WDT: Started with servicing (128s timeout) MMC: FSL_SDHC: 0, FSL_SDHC: 1 [*]-Video Link 0 (480 x 272)  [email protected], video In: serial Out: serial Err: serial flash target is MMC:1 Fastboot: Normal Boot from USB for uuu Secure boot enabled HAB Configuration: 0xcc, HAB State: 0x99 No HAB Events Found!
No HAB events are found because the booted image is signed with the same keys fused to the board. This board is closed.
With the instructions from Flash your Device. Paying attention to the boot log for the U-Boot we have:
U-Boot SPL 2020.04+fio+gcbb11e17ea (Aug 12 2021 - 23:27:31 +0000) Trying to boot from MMC1 SPL: Booting primary boot path: using 0x8a offset for next boot image sha256,rsa2048:ubootdev+ ## Checking hash(es) for Image optee ... sha256+ OK ## Checking hash(es) for Image uboot ... sha256+ OK ## Checking hash(es) for Image ubootfdt ... sha256+ OK ## Checking hash(es) for Image bootscr ... sha256+ OK
From this log, we note that
bootscr are being verified as the log shows
sha256+, the plus sign (
+) is printed when the verification processes succeed.
The key name is
ubootdev, as defined by variable
UBOOT_SIGN_KEYNAME in the
conf/local.conf from the LmP (Yocto Project).
For the Linux Kernel boot log, we note the DTB files are also using the
ubootdev key, and they are properly verified.
There are several other information for each image being verified and loaded.
## Copying 'fdt-imx6ull-14x14-evk.dtb' subimage from FIT image at 80800000 ... sha256,rsa2048:ubootdev+ sha256+ Loading part 253 ... OK Forcing secondary boot to 0 after reboot ## Loading kernel from FIT Image at 80800000 ... Using 'conf-imx6ull-14x14-evk.dtb' configuration Verifying Hash Integrity ... sha256,rsa2048:ubootdev+ OK Trying 'kernel-1' kernel subimage Description: Linux kernel Type: Kernel Image Compression: uncompressed Data Start: 0x80800110 Data Size: 7270504 Bytes = 6.9 MiB Architecture: ARM OS: Linux Load Address: 0x80008000 Entry Point: 0x80008000 Hash algo: sha256 Hash value: 56c254a00858b54d2f1278a68df49eb764ac284cd1a46198b1e8664e28dac185 Verifying Hash Integrity ... sha256+ OK ## Loading ramdisk from FIT Image at 80800000 ... Using 'conf-imx6ull-14x14-evk.dtb' configuration Verifying Hash Integrity ... sha256,rsa2048:ubootdev+ OK Trying 'ramdisk-1' ramdisk subimage Description: initramfs-ostree-lmp-image Type: RAMDisk Image Compression: uncompressed Data Start: 0x80f1b534 Data Size: 2922946 Bytes = 2.8 MiB Architecture: ARM OS: Linux Load Address: 0x84000000 Entry Point: unavailable Hash algo: sha256 Hash value: 834cf894b30100c4f49ae048e3749f189bff71094c50cd419bb2d7e7b5487ee6 Verifying Hash Integrity ... sha256+ OK Loading ramdisk from 0x80f1b534 to 0x84000000 ## Flattened Device Tree blob at 85800000 Booting using the fdt blob at 0x85800000 Loading Kernel Image Using Device Tree in place at 85800000, end 8580cfff
The key/certificate used to sign and verify the Linux Kernel modules are provided via LmP by the Yocto Project variable
MODSIGN_KEY_DIR. We can make sure the running linux has this feature enable by running the following commands to check the
[email protected]:~$ dmesg | grep -i 'x.*509' [ 2.927091] Asymmetric key parser 'x509' registered [ 4.571906] Loading compiled-in X.509 certificates [ 4.598640] Loaded X.509 cert 'Default insecure key from Factory II: 1b2327c0b75d0bc1e4914c8195bbf053629b8abb'
This article shows one example of boot sequence log and where to look to understand if the expected key/cert is being used and if the verification process is being successful.