269 lines
14 KiB
ReStructuredText
269 lines
14 KiB
ReStructuredText
*******************
|
||
Secure Boot Concept
|
||
*******************
|
||
|
||
Currently CoreOS provide a Proof Of Concept of some of the secure boot element that we want to
|
||
implement a full secure-boot solution based on UEFI secure boot.
|
||
|
||
The current proof of concept is structured as follows:
|
||
|
||
Hardware Requirements
|
||
=====================
|
||
|
||
- The device must have an `eMMC`.
|
||
- The architecture of the device must be either `ARM32` or `AARCH64`.
|
||
|
||
|
||
eMMC Embedded MultiMediaCard
|
||
============================
|
||
|
||
eMMC, or Embedded MultiMediaCard, represents a prevalent storage format in devices such as
|
||
smartphones, tablets, and other embedded systems. It encapsulates NAND flash memory and a dedicated
|
||
controller within one package. This structure not only eases integration for device manufacturers
|
||
but also ensures a compact, efficient storage medium.
|
||
|
||
Within eMMC's architecture, distinct hardware partitions cater to diverse operational demands:
|
||
|
||
.. graphviz::
|
||
|
||
digraph emmcStructure {
|
||
rankdir=TB;
|
||
node [shape=box, style=filled, fillcolor="#e6f2ff"];
|
||
edge [color="#0099cc", fontsize=12];
|
||
|
||
compound=true;
|
||
|
||
subgraph cluster_eMMC {
|
||
label="eMMC";
|
||
color="#0099cc";
|
||
|
||
Boot0 [label="Boot0"];
|
||
Boot1 [label="Boot1"];
|
||
RPMB [label="RPMB"];
|
||
|
||
subgraph cluster_User {
|
||
label="User";
|
||
color="#00cc99";
|
||
GPT [label="GPT Table"];
|
||
|
||
subgraph cluster_GPT {
|
||
label="Software Partitions (GPT)";
|
||
color="#99e6e6";
|
||
|
||
SoftwarePartition1 [label="Partition 1"];
|
||
SoftwarePartition2 [label="Partition 2"];
|
||
SoftwarePartitionN [label="Partition N"];
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
|
||
#. **Boot0 and Boot1**: The boot partitions cater to device start-up requirements, typically hosting
|
||
the firmware. Boot0 predominantly initiates the boot-up, while Boot1 stands as a secondary guard
|
||
or backup, ensuring booting is resilient and failsafe.
|
||
|
||
#. **RPMB (Replay Protected Memory Block)**: As a secure partition, RPMB shelters data against
|
||
potential tampering. It's tailored for sensitive information storage, such as cryptographic keys.
|
||
Its design counters data replays or rollbacks, fortifying against particular attack types.
|
||
|
||
#. **User**: The primary storage domain, the User partition accommodates the OS, applications,
|
||
and user-centric data. It's reminiscent of the primary storage drive in larger computing devices.
|
||
Importantly, the User partition has a layered structure. Using the GPT (GUID Partition Table), it
|
||
is further divided into multiple software partitions, which can house diverse datasets or file
|
||
systems.
|
||
|
||
The boot concept of CoreOS rely on the presence of an eMMC to implement the following feature:
|
||
|
||
- Storage of two copy of the firmware with a way to switch from a copy to another using the eMMC
|
||
boot0 and boot1 hardware partition
|
||
- Storage of keys used by the UEFI Secure Key specification inside the secure RPMB hardware
|
||
partition.
|
||
- Storage of the bootloader, kernel and rootfs inside the user hardware partition using multiple
|
||
software partition in the GPT format.
|
||
|
||
Firmware
|
||
========
|
||
|
||
The firmware of the device should implement a subset of the UEFI specification as defined in the
|
||
ARM Base Boot Requirements (EBBR) and should implement the optional UEFI Secure Boot part of the
|
||
EBBR specifications.
|
||
|
||
This is done in CoreOS by levering the built-in EBBR and UEFI Secure Boot present into the u-boot
|
||
project.
|
||
|
||
The hardware should verify the validity of the firmware using a hardware specific way. Then the
|
||
generic secure boot concept explained here can be used to valide all the following component of
|
||
CoreOS.
|
||
|
||
UEFI Key used by UEFI Secure Boot
|
||
=================================
|
||
|
||
|
||
- **PK (Platform Key)**: This top-tier key shoulders the responsibility of KEK verification and its
|
||
potential revocation. PK holders have the exclusive privilege to configure the KEK and the `db`
|
||
database. It's the gatekeeper ensuring only authorized software can touch the firmware or
|
||
bootloader.
|
||
|
||
- **KEK (Key Exchange Key)**: As a medium for data exchange, the KEK is pivotal for signing the `db`
|
||
and `dbx` databases.
|
||
|
||
- **db (Allowed Database)**: This is the white list. It houses the keys or hashes of permitted
|
||
firmware and OS loaders. Execution is only granted to software with a signature that resonates
|
||
with the keys/hashes in this database.
|
||
|
||
- **dbx (Forbidden Database)**: The black sheep are here. Housing keys or hashes of known
|
||
unauthorized software, it ensures any associated software is prohibited from executing.
|
||
|
||
Currently all theses public keys are built-in into u-boot at build time and are read only. In the
|
||
future we will use the OP-TEE support into u-boot to use OP-TEE to manage the keys.
|
||
|
||
OP-TEE and RPMB as key manager
|
||
==============================
|
||
|
||
OP-TEE, or Open Portable Trusted Execution Environment, is an open-source implementation of the
|
||
Trusted Execution Environment (TEE) designed for ARM-powered platforms. In essence, a TEE is a
|
||
secure enclave that provides a separated, isolated environment where specific applications and their
|
||
data can run independently from the regular operating system, ensuring they are protected against
|
||
potential tampering or unauthorized access.
|
||
|
||
OP-TEE guarantees confidentiality, integrity, and authenticity for critical applications by
|
||
executing them in this secure space. It offers a wide range of security features, including secure
|
||
storage of cryptographic keys, secure boot, and hardware-backed crypto operations.
|
||
|
||
In the context of UEFI secure boot, OP-TEE becomes instrumental. UEFI's secure boot mechanism
|
||
ensures that only trusted, signed firmware, OS loaders, and OS kernels are executed during the boot
|
||
process. To enforce this level of trust, UEFI relies on a set of cryptographic keys, including PK
|
||
(Platform Key), KEK (Key Exchange Key), and db/dbx (allowed and forbidden signature databases).
|
||
Safeguarding these keys is paramount to maintain the security and integrity of the boot process.
|
||
|
||
By leveraging OP-TEE, these UEFI secure boot keys can be securely stored in the RPMB (Replay
|
||
Protected Memory Block) partition of the eMMC. The RPMB is a write-protected, secure area of the
|
||
eMMC designed to hold sensitive data and protect it against tampering and replay attacks.
|
||
Since OP-TEE manages secure access to the RPMB partition, it ensures that the UEFI secure boot keys
|
||
are not only safely stored but are also accessible only by authorized firmware components.
|
||
|
||
eMMC User Partition
|
||
===================
|
||
|
||
The user partition of the eMMC must be structured using the GPT (GUID Partition Table) format.
|
||
|
||
Within the GPT-formatted user partition, specific partitions should be established for efficient
|
||
booting and system operation:
|
||
|
||
1. **EFI**: This is the Essential Firmware Interface partition. It holds the `efibootguard`
|
||
os-loader binary, responsible for the boot sequence's initial steps and the kernel's selection
|
||
based on its configuration. This binary is signed with a key present in the `dbx` database
|
||
|
||
2. **EBG0 - Efibootguard Config 0**: This partition houses the `efibootguard` configuration for the
|
||
first kernel option. Alongside the configuration file, it also contains a Unified Kernel Image
|
||
(UKI), a bundled package comprising the Linux kernel, device trees, and associated boot
|
||
components. The UKI is signed with a key present in the `dbx` database
|
||
|
||
3. **EBG1 - Efibootguard Config 1**: Similar to EBG0, this partition carries the `efibootguard`
|
||
configuration for the second kernel option. It too holds a Unified Kernel Image tailored for this
|
||
alternate boot choice.
|
||
|
||
4. **rootfs0**: This partition stores the CoreOS root filesystem designed to complement and operate
|
||
with the kernel embedded in the EBG0 partition. It provides the essential system files and
|
||
structures required for the operating system's functioning when the kernel from EBG0 is booted.
|
||
Integrety of this rootfs is assured by storing an hash of the rootfs inside the UKI image.
|
||
|
||
5. **rootfs1**: Analogous to `rootfs0`, this partition houses the CoreOS root filesystem tailored
|
||
for the kernel within the EBG1 partition. It ensures that, should the system boot from the kernel
|
||
in EBG1, the appropriate file structures and system components are readily available.
|
||
|
||
EFIBootGuard Configuration
|
||
==========================
|
||
|
||
Efibootguard, as a part of its design, employs a configuration system to determine the appropriate
|
||
kernel and associated resources to boot from. This configuration is stored in distinct partitions,
|
||
EBG0 and EBG1, each holding its configuration file.
|
||
|
||
The configuration file itself comprises several fields, but most crucially, it contains a revision
|
||
field. This field is a numerical identifier indicating the version or update level of the contained
|
||
kernel and resources. When the system initiates its boot sequence, Efibootguard assesses the
|
||
revision values in both the EBG0 and EBG1 configuration files.
|
||
|
||
The selection process is straightforward yet robust: Efibootguard chooses the partition with the
|
||
higher revision value. By doing so, it inherently opts for the most recent or updated kernel version
|
||
available. However, this system also supports failover mechanisms. In case the kernel in the
|
||
partition with the higher revision encounters issues during boot, Efibootguard can revert to the
|
||
other partition, ensuring resilience and continuity in system operations.
|
||
|
||
Moreover, the choice isn't rigidly fixed. When the system undergoes updates, the configuration files
|
||
can be rewritten, and the revision values adjusted, allowing for dynamic and flexible booting in
|
||
line with system evolutions and updates. In essence, Efibootguard, with its configuration-based
|
||
approach, ensures a blend of up-to-date system booting and built-in fail-safes for dependable
|
||
operation.
|
||
|
||
Unified Kernel Image
|
||
====================
|
||
|
||
After having choosen the right configuration file, Efibootguard takes on the responsibility of
|
||
launching the Unified Kernel Image (UKI) linked with the active configuration. This image bundle
|
||
together essential boot components like the Linux kernel, device trees, and the kernel command
|
||
line. The secure initiation of this image is paramount, and Efibootguard ensures this by leveraging
|
||
UEFI's start_image system call.
|
||
|
||
The UEFI start_image system call verifies the image's signature against the Secure Boot keys
|
||
(PK, KEK, db, and potentially dbx). If the signature matches, indicating that the image is trusted
|
||
and hasn't been tampered with, the image is permitted to execute. If not, the booting halts,
|
||
preventing any unauthorized or potentially malicious code from running.
|
||
|
||
Once the UKI has been securely initiated, it undertakes multiple tasks. It first extracts the
|
||
necessary components from the bundled package, identifying and utilizing the appropriate device
|
||
trees based on `compatible` node, by matching with the `compatible` node of the `device-tree` that
|
||
is built into the firmware. These device trees inform the system about the hardware configuration,
|
||
ensuring the kernel interacts correctly with the system's components.
|
||
|
||
The UKI os-launcher also has CoreOS specialized patches, enabling dynamic rootfs switching without
|
||
requiring an initramfs by changing the `root=` part of the kernel command line at run time to
|
||
point to the right rootfs partition.
|
||
|
||
RootFS and dm-verity
|
||
====================
|
||
|
||
dm-verity is a Linux kernel feature designed to provide transparent integrity checking of block
|
||
devices, particularly for read-only file systems. Rooted in cryptographic principles, dm-verity
|
||
employs a hash-based approach to ensure and validate the integrity of the root filesystem (rootfs).
|
||
|
||
The way dm-verity operates is by building a Merkle tree, a structure where each leaf node contains a
|
||
hash of a block of the underlying data, while each non-leaf node is a hash of its children. The
|
||
topmost node, the root of the Merkle tree, provides a cumulative hash representing the entirety of
|
||
the data. This top hash, known as the root hash, serves as a concise, cryptographic representation
|
||
of the entire filesystem's state.
|
||
|
||
When integrating dm-verity with the Unified Kernel Image (UKI), an additional layer of security is
|
||
established. By embedding the root hash into the signed UKI, any tampering or modification in the
|
||
rootfs can be swiftly detected. When the system boots, the UKI, being signed, ensures that the
|
||
embedded root hash is legitimate and untampered. As the OS accesses the rootfs, dm-verity
|
||
recalculates the hash values in real-time and compares them to the values in the original Merkle
|
||
tree, referenced by the embedded root hash.
|
||
|
||
If any discrepancies are found – that is, if the recalculated hash doesn't match the stored value –
|
||
it indicates potential tampering, and the OS can halt access or take appropriate measures.
|
||
|
||
.. graphviz::
|
||
|
||
digraph SecureBootFlow {
|
||
rankdir=TB;
|
||
|
||
node [shape=box, style=filled, fillcolor="#e6f2ff"];
|
||
edge [color="#0099cc", fontsize=12];
|
||
|
||
Hardware [label="Hardware\n(ARM32/AARCH64 with eMMC)"];
|
||
Firmware [label="u-boot Firmware\n(UEFI EBRR subset)"];
|
||
eMMCConfig [label="eMMC Configuration\n(GPT with EFI partition)"];
|
||
EFIBootGuard [label="EFIBootGuard\n(A/B Kernel Switching)"];
|
||
UnifiedKernel [label="Unified Kernel Image\n(Kernel, cmd line, DTB)"];
|
||
KernelAndRootFS [label="Kernel & RootFS\n(dm-verity validation)"];
|
||
|
||
Hardware -> Firmware [label="Flashed with u-boot\n+ Built-in keys"];
|
||
Firmware -> eMMCConfig [label="eMMC boot"];
|
||
eMMCConfig -> EFIBootGuard [label="Boots from EFI partition"];
|
||
EFIBootGuard -> UnifiedKernel [label="Selects kernel A/B"];
|
||
UnifiedKernel -> KernelAndRootFS [label="Kernel boot\n+ RootFS verification"];
|
||
|
||
}
|