docs(secure-boot): add a secure boot concept to the doc
This commit is contained in:
parent
db27468370
commit
e89a0c5195
|
|
@ -11,3 +11,4 @@ Belden CoreOS Boot Concepts
|
||||||
|
|
||||||
overview
|
overview
|
||||||
uboot
|
uboot
|
||||||
|
secure-boot
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,268 @@
|
||||||
|
*******************
|
||||||
|
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"];
|
||||||
|
|
||||||
|
}
|
||||||
Loading…
Reference in New Issue