3.4.3. Authenticated Boot User Guide
3.4.3.1. Introduction
As we head into a new world of security requirements and regulations, secure boot is the first and most essential step. Secure boot is a process that ensures only authenticated software is selected and loaded, protecting systems from unauthorized or malicious code trying to load a unknown bootloader or OS on your device.
Secure boot is achieved by verifying digital signatures of each software layer involved during boot before executing that code. This requires that the design of hardware and software is prepared and developed with security in mind.
3.4.3.2. Learning
3.4.3.2.1. Root of Trust (RoT)
The Root of Trust is the foundation of authenticated boot. It is the first component in the system that is inherently trusted and is responsible for verifying all subsequent components in the boot process. The RoT is usually implemented in hardware, firmware, or a combination of both.
There are two main types of RoT:
Hardware Root of Trust: Typically embedded in a secure element (such as a Trusted Platform Module [TPM], Hardware Security Module [HSM], or Secure Boot ROM). It is immutable and performs the first-stage verification.
Firmware/Software Root of Trust: This is the first code that runs on the system, typically stored in Read-Only Memory (ROM) or write-protected storage.
3.4.3.2.2. Chain of Trust (CoT)
The Chain of Trust extends the RoT by ensuring that every stage of the boot process verifies the next stage before executing it. Each stage is cryptographically signed, and verification is performed using public key cryptography.
Process:
Boot ROM - Verifies the Primary Bootloader using a cryptographic signature.
Primary Bootloader - Verifies the Secondary Bootloader (U-Boot, GRUB, etc.) before executing it.
Secondary Bootloader - Verifies the Kernel before booting the operating system.
Kernel - Verifies the Initramfs and Root Filesystem using mechanisms like dm-verity or signatures.
Each step in the chain must be verified to maintain system integrity. If any stage fails verification, the system will refuse to boot or attempt recovery.
3.4.3.2.3. Device Mapper
Device Mapper (dm) is a Linux kernel subsystem that provides an abstraction layer for managing block devices. It enables advanced features like encryption (dm-crypt) and integrity verification (dm-verity) at the block device level.
3.4.3.2.3.1. dm-verity
dm-verity is a kernel feature designed to ensure that a block device remains read-only and has not been tampered with. It is commonly used in Android Verified Boot (AVB) and Linux-based secure boot systems.
The root filesystem is hashed block by block, creating a hash tree (Merkle tree). The root hash of the hash tree is signed by a trusted key. During boot, the kernel verifies the hash tree before mounting the root filesystem. If any block is modified, the hash verification will fail, preventing tampered data from being used.
While dm-verity guarantees data integrity, it does not promise confidentiality and works only on read-only filesystems.
3.4.3.2.3.2. dm-crypt
dm-crypt is a device-mapper target used for transparent disk encryption. It ensures data confidentiality by encrypting the entire partition or block device.
A user provides an encryption key (stored securely in a TPM or entered manually). dm-crypt encrypts each block before writing it to disk. When reading data, dm-crypt decrypts blocks on the fly. Only authorized users with the correct key can access the decrypted data.
Before encrypting a drive, it is recommended to perform a secure erase by overwriting the entire device with random data. This can be done by following this guide.
3.4.3.3. Setup
Note
A new Yocto layer is in the works to automate all of the below steps
The following steps describe how to build user-space tools and configuration on Yocto. Please use Processor SDK - Building the SDK with Yocto as reference.
Use the latest oe-config file. Build the default image and flash onto a 32GB+ SD card:
MACHINE=<machine> bitbake -k tisdk-default-imageFor this demo, the root filesystem is copied from the default rootfs into the encrypted partition on a 32GB+ SD card. Hence, the SD card needs to be partitioned accordingly. It is recommended to create 2 additional ext4 partitions bringing the total to 4 partitions:
Partition Label
/dev partition
Size
Comments
boot
/dev/mmcblk1p1
128MB
Default
root
/dev/mmcblk1p2
10GB
Default
crypt
/dev/mmcblk1p3
10GB
Same as root
verity
/dev/mmcblk1p4
1GB
10% of crypt
On the host machine, build the Linux Kernel with support for these configs:
CONFIG_BLK_DEV_DM=y CONFIG_DM_CRYPT=y CONFIG_DM_VERITY=y
These configs can be added using a separate .cfg file or the kernel can be edited using
MACHINE=<machine> bitbake -c menuconfig linux-ti-stagingEdit
sources/meta-arago/meta-arago-distro/recipes-core/images/tisdk-tiny-initramfs.bbto add dm-crypt and dm-verity support:PACKAGE_INSTALL += " cryptsetup lvm2 e2fsprogs-mke2fs"Build the initramfs image:
MACHINE=<machine> bitbake -k tisdk-tiny-initramfsExtract the initramfs .cpio file and add a
pass_keyfile# Extract command cpio -iv < <path to .cpio> # Create a random pass key tr -dc '[:alnum:]' </dev/urandom | head -c64 > <initramfs_root>/home/pass_key # Create cpio from initramfs folder cd <initramfs_root> find . | sort | cpio --reproducible -o -H newc -R root:root > ../<name>.cpio
Package the initramfs into the kernel by using the
menuconfigand build the kernel.General setup -> Initial RAM filesystem and RAM disk (initramfs/initrd) support -> Initramfs source file(s) /path/to/initramfs.cpio
Replace the
root/boot/Imagewith the updated Image and boot.Run the following commands in initramfs to setup the crypt and verity partitions
# Unmount encrypted partitions if already mounted umount /dev/mmcblk1p3 umount /dev/mmcblk1p4 # Create the mount paths mkdir /old_mnt mkdir /mnt # Mount default root mount /dev/mmcblk1p2 /old_mnt # Setup the encrypted partition # The default cipher at the time of writing this guide is aes-xts-plain64 # Hardware acceleration for dm-crypt is not tested cryptsetup luksFormat /dev/mmcblk1p3 --key-file=/home/pass_key --batch-mode cryptsetup luksOpen /dev/mmcblk1p3 crypt_root --key-file=/home/pass_key # Use following commands to verify the status of the LUKS device cryptsetup -v status crypt_root #Status Check cryptsetup luksDump /dev/mmcblk1p3 #Dump Headers # Format and copy rootfs inside encrypted partition mkfs.ext4 /dev/mapper/crypt_root # If command is successful you should see below output root@am62xx-evm:~# mkfs.ext4 /dev/mapper/crypt_root mkfs.ext4 /dev/mapper/crypt_root mke2fs 1.47.0 (5-Feb-2023) Creating filesystem with 2952704 4k blocks and 738192 inodes Filesystem UUID: 8cc1c02e-7b0a-4d57-82f0-f3a4c35e0f00 Superblock backups stored on blocks: 32768, 98304, 163840, 229376, 294912, 819200, 884736, 1605632, 2654208 Allocating group tables: done Writing inode tables: done Creating journal (16384 blocks): done Writing superblocks and filesystem accounting information: done # Mount the encrypted partition mount /dev/mapper/crypt_root /mnt cp -ar /old_mnt/. /mnt umount /mnt # Setup verity veritysetup format /dev/mapper/crypt_root /dev/mmcblk1p4 # Output will have a Root hash, copy that hash as it will be used in next step ... Root hash: 4392712ba01368efdf14b05c76f9e4df0d53664630b5d48632ed17a137f39076
Back on the host machine, add this init file at the root of the initramfs:
#!/bin/sh sleep 5 # For mmcblk1 to populate chown root:root /bin/mount.util-linux # Provide correct ownership # Mount dev, procfs and sysfs /bin/mount -t devtmpfs none /dev /bin/mount -t proc none /proc /bin/mount -t sysfs none /sys # Decrypt # If the cipher was previously changed, add --cipher aes-cbc-plain /sbin/cryptsetup luksOpen --key-file=/home/pass_key /dev/mmcblk1p3 crypt_root # Verify (use the root hash from the previous ``veritysetup format`` command) /sbin/veritysetup open /dev/mapper/crypt_root verity_root /dev/mmcblk1p4 4392712ba01368efdf14b05c76f9e4df0d53664630b5d48632ed17a137f39076 mount -o ro /dev/mapper/verity_root /mnt # Jump to secure root FS exec switch_root /mnt/ /sbin/init
and give it the appropriate permissions to run:
chmod +x initRepackage the initramfs into the kernel, build and replace the
root/boot/Imageand boot.
3.4.3.4. Next steps
This guide showcases the authenticated boot flow on TI devices and is not meant to be directly used in production. The demo utilizes a pass_key to secure the encrypted partition and is placed in the initramfs in a non-secure manner.