The purpose of secure boot is to ensure that only payloads which have been verified are executed as the system boots. This document describes the process by which OpenTitan aims to ensure this property holds, as well as the services that the secure boot chain provides to software, such as attestation and firmware upgrade support.
ROM
: Metal mask ROM, sometimes known as Boot ROM.ROM_EXT
: ROM Extension. Stored in flash and signed by the Silicon Creator.BL0
: Bootloader. Signed by the Silicon Owner.Kernel
: Signed by the Silicon Owner.The boot process flows as follows:
ROM_EXT
Slot.ROM_EXT
Slot, the ROM code performs the following:ROM_EXT
image from the active slot.ROM_EXT
manifest for the active slot.ROM_EXT
Slot fails to boot, look up the boot failure policy from the ownership blob and act upon it.ROM_EXT
stage.ROM_EXT
reads the Boot Info page to determine which BL0/Kernel image it should be booting.ROM_EXT
computes the digest of the Silicon Owner image, and compares it with the digest present in the manifest.ROM_EXT
verifies the digest signature from the manifest with Silicon Owner key stored in the Boot Info page.ROM_EXT
and silicon owner boot slot was used.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.
The OpenTitan Secure Boot implementation uses two mechanisms to attempt to prevent glitching attacks from moving the program counter ahead into user-controllable code without validation: the first being [OpenTitan Secure Boot HW Support][secure-boot-hw-support]. This mechanism ensures that execution cannot leave the ROM stage without going through a hardened comparator path that ensures the active ROM_EXT
has been verified. The second isolation mechanism is the PMP. By default, the PMP is configured with a single region that covers flash and only grants read access to the core. Each stage must explicitly add a new region that allows execution in the region that it has verified. The PMP configuration is documented here: [Secure Boot PMP][secure-boot-pmp].
The first mechanism ensures that we can enter ROM_EXT
with an extremely high level of confidence in the code there, and the second ensures that the barrier to execution for each successive stage remains high.
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][ownership-transfer]'s [Unlock Flow][ot-unlock-flow], relinquish ownership of the device.TRANSFER_OWNERSHIP
: Initiate processing of an ownership transfer blob.REFRESH_ATTESTATION
: See [Attestation][attestation]. Causes the ROM_EXT
to regenerate the attestation chain as per the [attestation command][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 Mask ROM. 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.[attestation]: {{< relref “/doc/security/specs/attestation” >}} [attestation-command]: {{< relref “/doc/security/specs/attestation” >}}#attestation-command [identities-keys]: {{< relref “/doc/security/specs/identities_and_root_keys” >}} [key-manager]: {{< relref “/hw/ip/keymgr/doc” >}} [ot-flash]: # [ot-unlock-flow]: # [ownership-transfer]: {{< relref “/doc/security/specs/ownership_transfer” >}} [rv-isa-priv]: https://riscv.org/technical/specifications/ [secure-boot-hw-support]: # [secure-boot-pmp]: #