Skip to content

Raspberry Pi Boot Modes and Security

Set of army boots next to a hard drive and a cloud
Different *boot* modes... (AI generated image)

This is just a quick post to highlight the possible boot modes on the Raspberry Pis, how these can be used in conjunction with network booting, and the key differences between the Pi 3 and 4B. I found this to all be quite confusing when I first looked at it, so hopefully this post will help it make a bit more sense.

Some of these principles can be applied to other computers, especially PXE boot. This post is, however, more geared towards the specifics encountered with the Raspberry Pi family of single-board computers.

SD Card

Traditionally, we boot Raspberry Pis with the SD card. This SD card contains the boot partition, which is where important parts of the bootloader are based, then the root partition, which contains the remainder of the filesystem, and most of the general use programs on the computer. The boot partition typically contains an initramfs, which is the initial kernel and subset of programs to run, which then in turn mount the root partition, with the remainder of programs and documents.

On the SD card, when we first flash the image, the boot partition will contain a set number of blocks, followed by the root partition, which will contain a set number of blocks too. The partition type used on the Pi is the master boot record, which then specifies the start and end blocks of both partitions.

When the Pi first boots into Raspberry Pi OS, the SD card partitions are resized by a service on the Pi called resize2fs_once. This ensures that the root partition will use the remainder of the SD card. I highlight this as it won't work on a netbooted image, as you cannot change the number of blocks allocated to an NFS-based filesystem.

PXE Booting

The second major form of booting that is common is network booting, otherwise known as PXE booting. This is where the Pi downloads an initial bootloader using the trivial file transfer protocol (TFTP), before running Linux using the /boot/cmdline.txt file. In this file, an NFS mount is specified for the root filesystem, in addition to an NFS mount for the boot partition. This type of booting allows us to use many recent Raspberry Pis without having to insert an SD card, and subsequently boot with storage on a central server. If you're interested in the specifics, I've written a guide with my findings so far, getting Pis to boot from the network with an OpenWRT router (which coincidentally also runs on a Pi).

PXE booting has been a standard since the 1990s, and as such has many shortcomings in today's zero-trust environments. Primarily, this is due to the lack of authentication and encryption in the TFTP and NFS protocols which are used. Neither of these protocols have been designed to operate in an open network, which may be susceptible to one of many attacks, including DHCP hijacking, DNS hijacking, or a malicious third party which can alter the contents of files on the NFS server.

So far, the only improvements that we have seen to NFS are through the use of Kerberos tickets, which can provide a way for a device to authenticate itself and encrypt traffic, or through TLS, but both of these methods are poorly documented.

HTTP Boot

A more modern replacement of the PXE boot system, implemented in the Raspberry Pi 4B onwards, is HTTP boot. This allows a device to obtain a network connection and request a specific file from a server anywhere on the public internet or local LAN, download this image, then verify it against a signature.

HTTP boot requires more configuration than PXE boot at the client side, as the EEPROM needs to be provisioned with the public key used for signing the bootloader, and optionally the hash of a root CA certificate. If this CA certificate exists, then the Pi will use HTTPS to download the ram disk image to boot the machine.

Secure Boot

HTTP boot already enforces secure boot as the firmware downloaded from the server has to be signed. Unfortunately, this is not configured for PXE booting and the Pi will happily boot any firmware from the network if the secure boot options are not enabled in the EEPROM. Secure boot ensures that the initial image that we run (the boot.img ramdisk) contains only code we trust. For development, the Raspberry Pi foundation burn in the development key to the OTP memory of the device.

This development key is meant to ensure that end users can test secure boot without the possibility of bricking the Pi, as we can always fall back to an image signed with the development key. Once we are ready to deploy our image, or ship our product containing a Pi (e.g., a CM4) out to the wider world, then we can revoke the development key and ensure that our device will only load firmware we specify.

Encryption

The Raspberry Pi 4B and 5 both have no form of trusted platform module embedded, which would typically store decryption keys for a bootloader in some secure enclave, accessible only on-die and then made inaccessible at boot. We can make use of an area of customer OTP memory on the EEPROM to write some random bytes, then use this as an encryption key.

When we load the bootloader using any of the above boot methods, we can then interact with the OTP memory through the kernel (specifically the GPU), then request access to this to decrypt further stages of the bootloader. We can also download the image for the initial kernel using HTTPS, but then we would need to configure some sort of access control on the server to ensure that the image we send to the Pi is actually being sent to the Pi.

Therefore, to achieve meaningful encryption, with keys resident on a single device, the initial bootloader we download should be as minimal as possible, and bootstrap another bootloader which is encrypted with the key burned into the OTP memory on the Pi.

Summary

Whilst it is not trivial to securely network boot the latest Raspberry Pi models, there are mechanisms in place to help do this, including the newer HTTP boot which seems to slowly be replacing the PXE boot, and some OTP memory which is infeasible to extract from the Pi once we force it to run a signed bootloader, as the burned in key is on die on the OTP memory.

Comments