Introduction
The #SecureBoot functionality of Arm processors effectively prevents unauthorized or maliciously modified firmware from running on devices. The Secure Boot system uses the keys burned into the processor to verify the Bootloader at startup, which in turn verifies the kernel FIT image, and the kernel continues to validate the rootfs’s integrity. This step-by-step verification process is known as the Chain of Trust. If users want to implement the boot functionality using traditional methods, they need to sequentially achieve each of the aforementioned steps. With the meta-toradex-security layer, this can be accomplished with just a few simple configurations.
Generating Keys
Secure Boot relies on matching key pairs to verify software. To enable Secure Boot, you need to burn the public key into the device’s OTP memory. This key must match the private key used to sign the verified firmware.
TI devices use three sets of key pairs to implement Secure Boot:
- • MEK (Manufacture Encryption Key): Provided by TI and permanently burned into the SoC, used to verify TI-signed software and cannot be changed.
- • SMPK (Secondary Manufacture Public Key): Created by the user and burned into the device, used to verify the signature of the user-generated bootloader.
- • BMPK (Backup Manufacture Public Key): An optional user-generated backup key. If the SMPK is lost or compromised, the system can be reconfigured to use the BMPK to verify the bootloader’s signature.
The SMPK and BMPK are used to sign the bootloader, so the generation and management of these keys must be handled with care and proper backups.
At the time of writing this article, key generation requires using OpenSSL version 1.1.1. Unless TI specifies otherwise in subsequent software versions, please use the <span>openssl version</span> command to check the current system’s OpenSSL version. If this version does not match, you can use the following commands to install it on a Linux system.
$ wget https://ftp.debian.org/debian/pool/main/o/openssl/
openssl_1.1.1w-0+deb11u1_amd64.deb
$ wget http://ftp.debian.org/debian/pool/main/o/openssl/
libssl1.1_1.1.1w-0+deb11u1_amd64.deb
$ sudo apt install ./libssl1.1_1.1.1w-0+deb11u1_amd64.deb
./openssl_1.1.1w-0+deb11u1_amd64.deb
Set environment variables. Since the subsequent TI MCU SDK and OPT Keywriter compilation will also require these keys, do not update the parameters of these variables.
$ export KEYS_DIR=~/keys/ti
$ export SMPK_NAME=custMpk
$ export BMPK_NAME=backMpk
Create the path for key generation.
$ mkdir -p "${KEYS_DIR}" && cd "${KEYS_DIR}"
Generate the SMPK key pair for the SSL certificate with RSA-4096.
$ openssl genrsa -F4 -out ${SMPK_NAME}.key 4096
$ cp ${SMPK_NAME}.key ${SMPK_NAME}.pem
$ openssl req -batch -new -x509 -key ${SMPK_NAME}.key -out ${SMPK_NAME}.crt
Generate the BMPK key pair for the SSL certificate with RSA-4096.
$ openssl genrsa -F4 -out ${BMPK_NAME}.key 4096
$ cp ${BMPK_NAME}.key ${BMPK_NAME}.pem
$ openssl req -batch -new -x509 -key ${BMPK_NAME}.key -out ${BMPK_NAME}.crt
Generate the ti-degenerate-key.
$ openssl genrsa -F4 -out ti-degenerate-key.pem 4096
Generate the AES-256 encryption key.
$ openssl rand -out aes256.key 32
$ openssl rand -out bmek.key 32
$ openssl rand -out smek.key 32
Remove write permissions for the keys and certificates.
$ chmod a-w *
Yocto Project Configuration
As in previous articles, you first need to set up the Yocto Project build environment. Here we will take the Verdin AM62 module based on the TI AM62 SoC as an example. Add the following two lines of configuration at the end of local.conf.
INHERIT += "tdx-signed"
TDX_K3_SECBOOT_TARGET_HSSE_DEVICE = "1"
When compiling the image, the keys used to sign the bootloader are by default searched for in the ${TOPDIR}/keys/ti location of the Yocto build directory. You can create a keys/ti directory in the Yocto build directory and copy all the files generated in ~/keys/ti over. The build directory will have the following folders.
tree -L 1
.
|-- buildhistory
|-- cache
|-- conf
|-- deploy
|-- keys
|-- tmp
`-- tmp-k3r5
<span>INHERIT</span> can use the <span>tdx-signed</span> and <span>tdxref-signed</span> parameters.
- • tdxref-signed: The generated image will enable Bootloader signature verification, U-Boot hardening, FIT image signature verification, and Rootfs signature verification.
- • tdx-signed: All features except for “Rootfs signature verification” are enabled. If dm-verity protection for the root filesystem is not required, this mode may be more suitable than tdxref-signed.
The keys used for signing the FIT image are located in the ${TOPDIR}/keys/ti/fit directory. It is also recommended to manage these keys properly.
tree keys -L 1
keys
|-- fit
`-- ti
<span>TDX_K3_SECBOOT_TARGET_HSSE_DEVICE</span> set to 0 allows the compiled image to run on AM62 modules without fuses. This is typically used for early development testing phases. When set to 1, the generated image can only run on fused AM62 modules. This image is used during the mass programming of the production process. For the sake of demonstrating the entire process, we will set it to 1 when compiling the image.
Then use the bitbake command to compile the image. The whole process is that simple.
bitbake tdx-reference-minimal-image
Compiling OTP Keywriter
The AM62 SoC uses the OTP Keywriter firmware to burn the keys used during Secure Boot into the processor’s registers. These registers are one-time programmable and irreversible, so please proceed with caution.
Compiling the OTP Keywriter requires the installation of the following software, and the OTP Keywriter needs to be requested from TI, which usually takes several working days. For specific download addresses, refer to this webpage. It is important to note that at the time of writing this article, compiling the OTP Keywriter requires using MCU Plus SDK version 9; version 10 of the OTP Keywriter cannot yet run on AM62. Please use the default installation path during installation, as using a different path may lead to compilation failures.
- • MCU Plus SDK
- • Code Composer Studio
- • SysConfig
- • OTP Keywriter
Navigate to the OTP Keywriter compilation directory.
$ cd ~/ti/mcu_plus_sdk_am62x_09_01_00_43/source/security/
sbl_keywriter/am62x-sk/r5fss0-0_nortos
Download and apply the following patch.
$ wget https://docs.toradex.com/private/116128-verdin-am62v1.2-vpp.patch
$ git apply 116128-verdin-am62v1.2-vpp.patch
Enter the ti-arm-clang directory to compile. Upon success, you should see the tiboot3.bin file.
$ cd ~/ti/mcu_plus_sdk_am62x_09_01_00_43/source/security/
sbl_keywriter/am62x-sk/r5fss0-0_nortos/ti-arm-clang
$ make -sj clean PROFILE=debug
$ make -sj PROFILE=debug
Running OTP Keywriter
The Verdin AM62 module can load the bootloader and run the OTP Keywriter to burn the key registers either through recovery mode or from eMMC. Recovery mode requires connecting the Verdin AM62 to a computer via the USB OTG interface and running the relevant commands on the computer. The bootloader can also be written to the eMMC boot partition using the Toradex Easy Installer, and upon powering on the module, it will load the bootloader from eMMC. The former is suitable for use during development, while the latter is more suitable for mass programming processes as it does not require a PC.
Loading Bootloader from Recovery Mode
Install dfu-util on the PC.
$ sudo apt install dfu-util
Then run:
$ sudo dfu-util -c 1 -i 0 -a bootloader -D tiboot3.bin
Upon successful execution, the Verdin AM62 will switch from HS-FS to HS-SE mode, enabling the Secure Boot functionality. On the next boot, the previously generated signed image will be loaded.
Loading Bootloader from eMMC
The #Verdin AM62’s eMMC has two boot partitions, mmcblk0boot0 and mmcblk0boot1. The tiboot3.bin bootloader containing the OTP Keywriter will first be burned into mmcblk0boot0. The regular bootloader tiboot3-am62x-hs-verdin.bin will be burned into the mmcblk0boot1 partition, which is included in the image generated by the Yocto Project. During the first boot, the bootloader on mmcblk0boot0 will be loaded to run the OTP Keywriter to complete the key register burning. At the same time, the eMMC EXTCSD register[179] will be configured to set mmcblk0boot1 as the default boot partition. This way, on the next boot, the regular bootloader on mmcblk0boot1 will be loaded, followed by U-boot.
The MCU SDK already has the MMC driver, so you only need to call <span>MMCSD_enableBootPartition()</span> in the OTP Keywriter code. Apply the following patch to the previous OTP Keywriter and recompile.
$ wget https://docs.toradex.com/117166-verdin-am62-fuse-switch-bootpart2.patch
$ git apply 117166-verdin-am62-fuse-switch-bootpart2.patch
Modify the image.json file in the signed image generated by the Yocto Project, changing the original <span>"name": "mmcblk0boot0"</span> to <span>"name": "mmcblk0boot1",</span> .
{
"name":"mmcblk0boot1",
"erase":true,
"content":{
"filesystem_type":"raw",
"rawfiles":[
{
"filename":"tiboot3-am62x-gp-verdin.bin",
"dd_options":"seek=0",
"product_ids": "0069"
In addition, add a new <span>"name": "mmcblk0boot0"</span> partition configuration, <span>"product_ids": "0074"</span> for the PID4 to be burned, and <span>"filename": "tiboot3.bin"</span> for the recompiled bootloader.
{
"name":"mmcblk0boot0",
"erase":true,
"content":{
"filesystem_type":"raw",
"rawfiles":[
{
"filename":"tiboot3.bin",
"dd_options":"seek=0",
"product_ids":"0074"
}
]
}
},
After burning is complete, the Verdin AM62 will switch from HS-FS to HS-SE mode during its first boot, enabling Secure Boot functionality. On the next boot, it will load the previously generated signed image from mmcblk0boot1. After the Linux system boots, you can delete the bootloader files on mmcblk0boot0.
Conclusion
With the help of meta-toradex-security, users can easily utilize the Secure Boot functionality of the module. More practical features from meta-toradex-security will be introduced in subsequent articles, so stay tuned.