The following overview gives a brief, high-level explanation of OpenTitan‘s secure boot process. The basic guarantee of secure boot is that *no unauthorized code will be executed before the boot process reaches the device owner’s code*. All executed code must be cryptographically signed by either the owner of the OpenTitan device or the (trusted) entity that originally set up the device at manufacturing time (the “Silicon Creator”).
Additionally, the secure boot procedure restricts certain stages to the Silicon Creator, so that even the current device owner can't change them. Therefore, if the device changes owners, the new owner only has to trust the Silicon Creator, not the previous owner(s).
The diagram below summarizes the specific steps involved in the secure boot process:
The first stage of secure boot is called “ROM”. ROM is a region of read-only memory that cannot be updated at all after an OpenTitan device is manufactured. For that reason, the ROM is kept as simple as possible; it does some minimal setup, authenticates the next stage (ROM_EXT
), and jumps there.
The ROM contains non-updateable public keys, which it uses to authenticate the ROM_EXT
signature. These public keys correspond to what OpenTitan calls the “Silicon Creator”: the entity who was initially involved in the manufacturing of the device. It's important to distinguish between the unchanging Silicon Creator and the changeable “Silicon Owner”, the entity that owns the device at a given time.
On startup, hardware settings use a feature called “enhanced Physical Memory Protection” (ePMP) to ensure that only the ROM code itself is executable. For details about how the ROM configures ePMP, see Memory Protection Module. Flash and MMIO memory regions are unlocked for read/write (for signature verification and configuring peripherals) but are not executable at this stage.
On boot, the ROM code does the following:
ROM_EXT
, which includes the start and end address of ROM_EXT
code, a cryptographic signature, a public key modulus, and “selector bits” for hardware information.ROM_EXT
implementations; the ROM will first try the one with the newest security version. If the signature verification for that slot fails, the ROM will attempt to boot from the other slot.ROM_EXT
image can restrict their signature to only certain devices/states.ROM_EXT
start and end address given in the manifest.ROM_EXT
region is executable, and jump to the start of ROM_EXT
.ROM_EXT
The ROM_EXT
(“ROM extension”) stage is another region of read-only memory that is controlled by the Silicon Creator. However, unlike the ROM, it can be updated after the device is manufactured, as long as the new version is signed by the Silicon Creator.
Like the ROM, the ROM_EXT
must check the signature of the next boot stage (this time against the Silicon Owner‘s keys, rather than the Silicon Creator’s). In addition, the ROM_EXT
initializes Silicon Creator and then Silicon Owner keys using the key manager and performs “boot services”, which are a small set of specific operations that require access to the Silicon Creator’s keys (for instance, providing an attestation of device state or transferring the device to a new owner). These services must happen during boot and not afterwards, because after boot we don't have access to the Silicon Creator keys.
The general procedure for the ROM_EXT
looks something like this:
ROM_EXT
manifest described in the ROM procedure).ROM_EXT
.ROM_EXT
implementations.ROM_EXT
. It will differ between devices and between ROM_EXT
images.Once the code has jumped into the Silicon Owner code at BL0, secure boot in its simplest form is complete. The Silicon Owner may choose to extend the secure boot process with multiple boot stages of their own; this will differ between device owners, while the stages described here are guaranteed by the Silicon Creator and will be shared by all OpenTitan implementations. If any signature verification in the above process fails, or there is any kind of unexpected error, the device will fail to boot.
The Silicon Creator has multiple public keys. This redundancy partially protects against the scenario in which one of the keys is compromised; any OpenTitan devices produced after the key is known to be compromised can mark the compromised key invalid, without requiring a full new ROM implementation. Devices produced before the key is known to be compromised are not protected by this strategy.
Additionally, each key is restricted to one of three “roles”, which determine in which device states the key can be used. The roles are:
DEV
lifecycle state)TEST_UNLOCK
lifecycle state)PROD
or PROD_END
lifecycle states)If the key indicated in the manifest has a role that doesn't match the lifecycle state of the device, the boot fails. All of these keys are 3072-bit RSA public keys with exponent e=65537 (the “F4 exponent”).
ROM
and ROM_EXT
boot stages.ROM_EXT
.The Silicon Creator and the Silicon Owner may be the same individual or group, but are not necessarily so. The Silicon Owner can change during the lifetime of the device, but the Silicon Creator cannot.
ROM
: Metal ROM, sometimes known as ROM or Boot ROM.ROM_EXT
: ROM Extension. Stored in flash and signed by the Silicon Creator.BL0
: Bootloader. Signed by the Silicon Owner.Kernel
: Post-bootloader code. Signed by the Silicon Owner.In order to provide a flexible boot mechanism the Boot Info page will store a structure called the Boot Policy. The boot policy dictates the boot flow, including storing boot attempts and successes for a given ROM_EXT
, allowing the ROM code to decide when to mark a ROM_EXT
good or bad. The boot policy also contains directions to ROM_EXT
about which slot it loads silicon owner code from. TODO(gdk): Expand on policy.
Memory on OpenTitan can be considered as split into three separate regions: ROM, Flash Info, and addressable flash. The addressable flash is further divided into two equally-sized regions called Flash Bank 0 and Flash Bank 1. The beginning addresses for Flash Bank 0 and Flash Bank 1 are the only fixed points of reference that the system is opinionated about, as they correspond to the beginning of each physical flash bank. It is expected that a Silicon Owner might arbitrarily reserve space at the end of each flash bank to use as additional storage.
Boot Services refers to the functionality stored inside of ROM
/ROM_EXT
that can be controlled via specific messages passed between from Silicon Owner code in retention SRAM. Since ROM/ROM_EXT
is responsible for the boot process and is the only software on the device which can manipulate identities belonging to the Silicon Owner, these services are required to perform actions such as attestation of device identity and firmware update.
Boot services are invoked by placing a request structure at the beginning of retention SRAM and resetting the system with the cause BOOT_SERVICE_REQUEST
.
UNLOCK_OWNERSHIP
: As per Ownership Transfer's Unlock Flow, relinquish ownership of the device.TRANSFER_OWNERSHIP
: Initiate processing of an ownership transfer blob.REFRESH_ATTESTATION
: See Attestation. Causes the ROM_EXT
to regenerate the attestation chain as per the attestation command section.UPDATE_FIRMWARE
: Instructs the active ROM_EXT
to begin the firmware update process. This process allows for attempting to boot from a new ROM_EXT
or silicon owner code with a programmable attempt count that must be satisfied before committing to the new code. This is done by updating the boot policy block. When a kernel wishes to update the other slot in the device it writes the firmware there and then issues an UPDATE_FIRMWARE
command to instruct the next boot of ROM_EXT
to attempt to load from that slot.This document does not prescribe an exact data structure for the ROM_EXT
manifest as seen by the ROM. For that information, see the manifest format page. However, these are the requirements that the manifest format is required to support:
ROM_EXT
slot.ROM_EXT
slot.ROM_EXT
. This version field is used as part of the measurements for key derivations, and can be used as a constraint for the boot policy.ROM_EXT
to determine if this version is bootable or is considered a rollback.ROM_EXT
slot.