Secure boot is a mechanism for verifying the integrity of the kernel image and other files required during boot by storing them in a signed ramdisk image. These files include the GPU firmware (start.elf etc), kernel, initrd, Device Tree and overlays. Secure boot does not depend on a particular OS, nor does it provide services to the OS after startup. However, since secure boot will only load trusted kernel and initrd images, the kernel/initrd can safely verify or mount an an encrypted file system e.g. by using a TPM.
N.B. The memory for the secure ramdisk is reclaimed as soon as the CPU is started.
This example includes a simple buildroot image for Compute Module 4 in order to demonstrate secure boot on a simple but functional OS.
The example does NOT modify the OTP or make other permanent changes to the system; the code signing can be disabled by reflashing the default bootloader EEPROM.
This tutorial does not cover how to create the boot.img
file or permanently
require secure boot in OTP. Please see the top level README and
secure-boot-recovery/README guides for
more information.
- A Raspberry Pi Compute Module 4
- Micro USB cable for
rpiboot
connection - USB serial cable (for debug logs)
- Linux or Cygwin (Windows 10)
- OpenSSL
- Python3
- Python
cryptodomex
python3 -m pip install pycryptodomex
# or
pip install pycryptodomex
Before starting it's advisable to create a fresh clone of the usbboot
repo
to ensure that there are no stale configuration files.
git clone https://github.com/raspberrypi/usbboot secure-boot
cd secure-boot
make
See the top-level README for build instructions.
Prepare the Compute Module for rpiboot
mode:
- Set the
nRPIBOOT
jumper which is labelled `Fit jumper to disable eMMC Boot' on the Compute Module 4 IO board. - Connect the micro USB cable to the
USB slave
port on the CM4 IO board. - Power cycle the CM4 IO board.
- Connect the USB serial adapter to GPIO 14/15 on the 40-pin header.
Enable rpiboot
mode and flash the latest EEPROM image:
./rpiboot -d recovery
Enable rpiboot
mode and load the OS via rpiboot
without enabling code-signing:
./rpiboot -d secure-boot-example
The OS should load and show activity on the boot UART and HDMI console.
Secure boot requires a 2048 bit RSA private key. You can either use a pre-existing
key or generate an specific key for this example. The KEY_FILE
environment variable
used in the following instructions must contain the absolute path to the RSA private key in
PEM format.
openssl genrsa 2048 > private.pem
export KEY_FILE=$(pwd)/private.pem
In a production environment it's essential that this key file is stored privately and securely.
Enable rpiboot
mode and flash the bootloader EEPROM with updated setting enables code signing.
The boot.conf
file sets the SIGNED_BOOT
property 1
which instructs the bootloader to only
load files (firmware, kernel, overlays etc) from boot.img
instead of the normal boot partition and verify the boot.img
signature boot.sig
using the public key in the EEPROM.
The update-pieeprom.sh
generates the signed pieeprom.bin
image.
cd secure-boot-recovery
# Generate the signed EEPROM image.
../tools/update-pieeprom.sh -k "${KEY_FILE}"
cd ..
./rpiboot -d secure-boot-recovery
At this stage OTP has not been modified and the signed image requirement can be reverted by flashing a default, unsigned image.
However, once the OTP secure-boot flags are set then SIGNED_BOOT
is permenantely enabled and cannot be overriden via the EEPROM config.
cd secure-boot-example
../tools/rpi-eeprom-digest -i boot.img -o boot.sig -k "${KEY_FILE}"
cd ..
Enable rpiboot
mode and run the example OS as before. However, if the
boot.sig
signature does not match boot.img
, the bootloader will refuse to
load the OS.
./rpiboot -d secure-boot-example
This example OS image is minimal Linux ramdisk image. Login as root
with the empty password.
Now that SIGNED_BOOT
is enabled the bootloader will only load images signed with private key generated earlier.
To boot the Compute Module in mass storage mode a signed version of this code must be generated.
This signed image should not be made available for download because it gives access to the EMMC as a block device.
Sign the mass storage drivers in the secure-boot-msd
directory. Please see the top level README for a description of the different usbboot
firmware drivers.
cd secure-boot-msd
../tools/rpi-eeprom-digest -i boot.img -o boot.sig -k "${KEY_FILE}"
cd ..
A new mass storage device should now be visible on the host OS. On Linux check dmesg
for something like '/dev/sda'.
./rpiboot -d secure-boot-msd
The bootloader can load a ramdisk boot.img
from any of the bootable modes defined by the BOOT_ORDER EEPROM config setting.
For example:
- Boot the CM4 in MSD mode as explained in the previous step.
- Copy the
boot.img
andboot.sig
files from thesecure-boot-example
stage to the mass storage drive: No other files are required. - Remove the
nRPIBOOT
jumper. - Power cycle the CM4 IO board.
- The system should now boot into the OS.
N.B. The example image is currently the same as the mass storage-gadget
, so the EMMC/SD will appear as block devices on the host PC if the micro USB cable is still connected.