The secure Linux 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 Linux log and artifacts from a booting machine, in order to detect the verification mechanism executed during a normal boot.
A common Linux 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.
Following the Linux boot logs
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)  lcdif@21c8000, 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.
SPL loads TF-A, OP-TEE and U-Boot proper
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 Linux microPlatform (Yocto Project).
Linux Kernel image and DTBs
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 pieces of 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
Linux Kernel Modules
The key/certificate used to sign and verify the Linux Kernel modules are provided via Linux microPlatform by the Yocto Project variable
MODSIGN_KEY_DIR. We can make sure the running linux has this feature enabled by running the following commands to check the
fio@imx6ullevk-sec:~$ 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'
Linux Boot Log Summary
We explored just one example of a secure Linux boot sequence log in Foundries.io Linux microPlatform FoundriesFactory and where to look to understand if the expected boot log key/cert is being used and how to ensure proper verification using those keys and certificates.
For more information on secure Linux boot logs and keys see our related article below.