Documentation: Convert vboot to markdown
Convert the HTML document to markdown and place it under security section. Change-Id: I212c6d0c977fd6772371ff6676478d48cc215d6e Signed-off-by: Patrick Rudolph <siro@das-labor.org> Reviewed-on: https://review.coreboot.org/c/coreboot/+/32610 Reviewed-by: Patrick Georgi <pgeorgi@google.com> Tested-by: build bot (Jenkins) <no-reply@coreboot.org>
This commit is contained in:
parent
62bc1cb88b
commit
fe80bf2fd1
|
@ -29,7 +29,6 @@
|
||||||
</li>
|
</li>
|
||||||
<li><a target="_blank" href="SoC/soc.html">SoC</a> support</li>
|
<li><a target="_blank" href="SoC/soc.html">SoC</a> support</li>
|
||||||
<li><a target="_blank" href="Board/board.html">Board</a> support</li>
|
<li><a target="_blank" href="Board/board.html">Board</a> support</li>
|
||||||
<li><a target="_blank" href="vboot.html">Verified Boot (vboot)</a> support</li>
|
|
||||||
</ul>
|
</ul>
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -1,402 +0,0 @@
|
||||||
<!DOCTYPE html>
|
|
||||||
<html>
|
|
||||||
<head>
|
|
||||||
<title>vboot - Verified Boot Support</title>
|
|
||||||
</head>
|
|
||||||
<body>
|
|
||||||
|
|
||||||
<h1>vboot - Verified Boot Support</h1>
|
|
||||||
|
|
||||||
<p>
|
|
||||||
Google's verified boot support consists of:
|
|
||||||
</p>
|
|
||||||
<ul>
|
|
||||||
<li>A root of trust</li>
|
|
||||||
<li>Special firmware layout</li>
|
|
||||||
<li>Firmware verification</li>
|
|
||||||
<li>Firmware measurements</li>
|
|
||||||
<li>A firmware update mechanism</li>
|
|
||||||
<li>Specific build flags</li>
|
|
||||||
<li>Signing the coreboot image</li>
|
|
||||||
</ul>
|
|
||||||
|
|
||||||
Google's vboot verifies the firmware and places measurements
|
|
||||||
within the TPM.
|
|
||||||
|
|
||||||
<hr>
|
|
||||||
<h2>Root of Trust</h2>
|
|
||||||
<p>
|
|
||||||
When using vboot, the root-of-trust is basically the read-only portion of the
|
|
||||||
SPI flash. The following items factor into the trust equation:
|
|
||||||
</p>
|
|
||||||
<ul>
|
|
||||||
<li>The GCC compiler must reliably translate the code into machine code
|
|
||||||
without inserting any additional code (virus, backdoor, etc.)
|
|
||||||
</li>
|
|
||||||
<li>The CPU must reliably execute the reset sequence and instructions as
|
|
||||||
documented by the CPU manufacturer.
|
|
||||||
</li>
|
|
||||||
<li>The SPI flash must provide only the code programmed into it to the CPU
|
|
||||||
without providing any alternative reset vector or code sequence.
|
|
||||||
</li>
|
|
||||||
<li>The SPI flash must honor the write-protect input and protect the
|
|
||||||
specified portion of the SPI flash from all erase and write accesses.
|
|
||||||
</li>
|
|
||||||
</ul>
|
|
||||||
|
|
||||||
<p>
|
|
||||||
The firmware is typically protected using the write-protect pin on the SPI
|
|
||||||
flash part and setting some of the write-protect bits in the status register
|
|
||||||
during manufacturing. The protected area is platform specific and for x86
|
|
||||||
platforms is typically 1/4th of the SPI flash
|
|
||||||
part size. Because this portion of the SPI flash is hardware write protected,
|
|
||||||
it is not possible to update this portion of the SPI flash in the field,
|
|
||||||
without altering the system to eliminate the ground connection to the SPI flash
|
|
||||||
write-protect pin. Without hardware modifications, this portion of the SPI
|
|
||||||
flash maintains the manufactured state during the system's lifetime.
|
|
||||||
</p>
|
|
||||||
|
|
||||||
<hr>
|
|
||||||
<h2>Firmware Layout</h2>
|
|
||||||
<p>
|
|
||||||
Several sections are added to the firmware layout to support vboot:
|
|
||||||
</p>
|
|
||||||
<ul>
|
|
||||||
<li>Read-only section</li>
|
|
||||||
<li>Google Binary Blob (GBB) area</li>
|
|
||||||
<li>Read/write section A</li>
|
|
||||||
<li>Read/write section B</li>
|
|
||||||
</ul>
|
|
||||||
<p>
|
|
||||||
The following sections describe the various portions of the flash layout.
|
|
||||||
</p>
|
|
||||||
|
|
||||||
<h3>Read-Only Section</h3>
|
|
||||||
<p>
|
|
||||||
The read-only section contains a coreboot file system (CBFS) that contains all
|
|
||||||
of the boot firmware necessary to perform recovery for the system. This
|
|
||||||
firmware is typically protected using the write-protect pin on the SPI flash
|
|
||||||
part and setting some of the write-protect bits in the status register during
|
|
||||||
manufacturing. The protected area is typically 1/4th of the SPI flash part
|
|
||||||
size and must cover the entire read-only section which consists of:
|
|
||||||
</p>
|
|
||||||
<ul>
|
|
||||||
<li>Vital Product Data (VPD) area</li>
|
|
||||||
<li>Firmware ID area</li>
|
|
||||||
<li>Google Binary Blob (GBB) area</li>
|
|
||||||
<li>coreboot file system containing read-only recovery firmware</li>
|
|
||||||
</ul>
|
|
||||||
|
|
||||||
<h3>Google Binary Blob (GBB) Area</h3>
|
|
||||||
<p>
|
|
||||||
The GBB area is part of the read-only section. This area contains a 4096 or
|
|
||||||
8192 bit public root RSA key that is used to verify the VBLOCK area to obtain
|
|
||||||
the firmware signing key.
|
|
||||||
</p>
|
|
||||||
|
|
||||||
<h3>Recovery Firmware</h3>
|
|
||||||
<p>
|
|
||||||
The recovery firmware is contained within a coreboot file system and consists
|
|
||||||
of:
|
|
||||||
</p>
|
|
||||||
<ul>
|
|
||||||
<li>reset vector</li>
|
|
||||||
<li>bootblock</li>
|
|
||||||
<li>verstage</li>
|
|
||||||
<li>romstage</li>
|
|
||||||
<li>postcar</li>
|
|
||||||
<li>ramstage</li>
|
|
||||||
<li>payload</li>
|
|
||||||
<li>flash map file</li>
|
|
||||||
<li>config file</li>
|
|
||||||
<li>processor specific files:
|
|
||||||
<ul>
|
|
||||||
<li>Microcode</li>
|
|
||||||
<li>fspm.bin</li>
|
|
||||||
<li>fsps.bin</li>
|
|
||||||
</ul>
|
|
||||||
</li>
|
|
||||||
</ul>
|
|
||||||
|
|
||||||
<p>
|
|
||||||
The recovery firmware is written during manufacturing and typically contains
|
|
||||||
code to write the storage device (eMMC device or hard disk). The recovery
|
|
||||||
image is usually contained on a socketed device such as a USB flash drive or
|
|
||||||
an SD card. Depending upon the payload firmware doing the recovery, it may
|
|
||||||
be possible for the user to interact with the system to specify the recovery
|
|
||||||
image path. Part of the recovery is also to write the A and B areas of the
|
|
||||||
SPI flash device to boot the system.
|
|
||||||
</p>
|
|
||||||
|
|
||||||
|
|
||||||
<h3>Read/Write Section</h3>
|
|
||||||
|
|
||||||
<p>
|
|
||||||
The read/write sections contain an area which contains the firmware signing
|
|
||||||
key and signature and an area containing a coreboot file system with a subset
|
|
||||||
of the firmware. The firmware files in FW_MAIN_A and FW_MAIN_B are:
|
|
||||||
</p>
|
|
||||||
<ul>
|
|
||||||
<li>romstage</li>
|
|
||||||
<li>postcar</li>
|
|
||||||
<li>ramstage</li>
|
|
||||||
<li>payload</li>
|
|
||||||
<li>config file</li>
|
|
||||||
<li>processor specific files:
|
|
||||||
<ul>
|
|
||||||
<li>Microcode</li>
|
|
||||||
<li>fspm.bin</li>
|
|
||||||
<li>fsps.bin</li>
|
|
||||||
</ul>
|
|
||||||
</li>
|
|
||||||
</ul>
|
|
||||||
|
|
||||||
<p>
|
|
||||||
The firmware subset enables most issues to be fixed in the field with firmware
|
|
||||||
updates. The firmware files handle memory and most of silicon initialization.
|
|
||||||
These files also produce the tables which get passed to the operating system.
|
|
||||||
</p>
|
|
||||||
|
|
||||||
<hr>
|
|
||||||
<h2>Firmware Updates</h2>
|
|
||||||
<p>
|
|
||||||
The read/write sections exist in one of three states:
|
|
||||||
</p>
|
|
||||||
<ul>
|
|
||||||
<li>Invalid</li>
|
|
||||||
<li>Ready to boot</li>
|
|
||||||
<li>Successfully booted</li>
|
|
||||||
</ul>
|
|
||||||
|
|
||||||
<table border="1">
|
|
||||||
<tr bgcolor="#ffc0c0">
|
|
||||||
<td>
|
|
||||||
Where is this state information written?
|
|
||||||
<br/>CMOS?
|
|
||||||
<br/>RW_NVRAM?
|
|
||||||
<br/>RW_FWID_*
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
</table>
|
|
||||||
|
|
||||||
<p>
|
|
||||||
Firmware updates are handled by the operating system by writing any read/write
|
|
||||||
section that is not in the "successfully booted" state. Upon the next reboot,
|
|
||||||
vboot determines the section to boot. If it finds one in the "ready to boot"
|
|
||||||
state then it attempts to boot using that section. If the boot fails then
|
|
||||||
vboot marks the section as invalid and attempts to fall back to a read/write
|
|
||||||
section in the "successfully booted" state. If vboot is not able to find a
|
|
||||||
section in the "successfully booted" state then vboot enters recovery mode.
|
|
||||||
</p>
|
|
||||||
|
|
||||||
<p>
|
|
||||||
Only the operating system is able to transition a section from the "ready to
|
|
||||||
boot" state to the "successfully booted" state. The transition is typically
|
|
||||||
done after the operating system has been running for a while indicating
|
|
||||||
that successful boot was possible and the operating system is stable.
|
|
||||||
</p>
|
|
||||||
|
|
||||||
<p>
|
|
||||||
Note that as long as the SPI write protection is in place then the system is
|
|
||||||
always recoverable. If the flash update fails then the system will continue
|
|
||||||
to boot using the previous read/write area. The same is true if coreboot
|
|
||||||
passes control to the payload or the operating system and then the boot fails.
|
|
||||||
In the worst case, the SPI flash gets totally corrupted in which case vboot
|
|
||||||
fails the signature checks and enters recovery mode. There are no times where
|
|
||||||
the SPI flash is exposed and the reset vector or part of the recovery firmware
|
|
||||||
gets corrupted.
|
|
||||||
</p>
|
|
||||||
|
|
||||||
<hr>
|
|
||||||
<h2>Build Flags</h2>
|
|
||||||
<p>
|
|
||||||
The following Kconfig values need to be selected to enable vboot:
|
|
||||||
</p>
|
|
||||||
<ul>
|
|
||||||
<li>COLLECT_TIMESTAMPS</li>
|
|
||||||
<li>VBOOT</li>
|
|
||||||
</ul>
|
|
||||||
|
|
||||||
<p>
|
|
||||||
The starting stage needs to be specified by selecting either
|
|
||||||
VBOOT_STARTS_IN_BOOTBLOCK or VBOOT_STARTS_IN_ROMSTAGE.
|
|
||||||
</p>
|
|
||||||
|
|
||||||
<p>
|
|
||||||
If vboot starts in bootblock then vboot may be built as a separate stage by
|
|
||||||
selecting VBOOT_SEPARATE_VERSTAGE. Additionally, if static RAM is too small
|
|
||||||
to fit both verstage and romstage then selecting VBOOT_RETURN_FROM_VERSTAGE
|
|
||||||
enables bootblock to reuse the RAM occupied by verstage for romstage.
|
|
||||||
</p>
|
|
||||||
|
|
||||||
<p>
|
|
||||||
Non-volatile flash is needed for vboot operation. This flash area may be in
|
|
||||||
CMOS, the EC, or in a read/write area of the SPI flash device. Select one of
|
|
||||||
the following:
|
|
||||||
</p>
|
|
||||||
<ul>
|
|
||||||
<li>VBOOT_VBNV_CMOS</li>
|
|
||||||
<li>VBOOT_VBNV_EC</li>
|
|
||||||
<li>VBOOT_VBNV_FLASH</li>
|
|
||||||
</ul>
|
|
||||||
<p>
|
|
||||||
More non-volatile storage features may be found in src/vboot/Kconfig.
|
|
||||||
</p>
|
|
||||||
|
|
||||||
<p>
|
|
||||||
A TPM is also required for vboot operation. TPMs are available in
|
|
||||||
drivers/i2c/tpm and drivers/pc80/tpm.
|
|
||||||
</p>
|
|
||||||
|
|
||||||
<p>
|
|
||||||
In addition to adding the coreboot files into the read-only region, enabling
|
|
||||||
vboot causes the build script to add the read/write files into coreboot file
|
|
||||||
systems in FW_MAIN_A and FW_MAIN_B.
|
|
||||||
</p>
|
|
||||||
|
|
||||||
<hr>
|
|
||||||
<h2>Signing the coreboot Image</h2>
|
|
||||||
<p>
|
|
||||||
The following command script is an example of how to sign the coreboot image file.
|
|
||||||
This script is used on the Intel Galileo board and creates the GBB area and
|
|
||||||
inserts it into the coreboot image. It also updates the VBLOCK areas with the
|
|
||||||
firmware signing key and the signature for the FW_MAIN firmware. More details
|
|
||||||
are available in 3rdparty/vboot/README.
|
|
||||||
</p>
|
|
||||||
|
|
||||||
<pre><code>#!/bin/sh
|
|
||||||
#
|
|
||||||
# The necessary tools were built and installed using the following commands:
|
|
||||||
#
|
|
||||||
# pushd 3rdparty/vboot
|
|
||||||
# make
|
|
||||||
# sudo make install
|
|
||||||
# popd
|
|
||||||
#
|
|
||||||
# The keys were made using the following command
|
|
||||||
#
|
|
||||||
# 3rdparty/vboot/scripts/keygeneration/create_new_keys.sh \
|
|
||||||
# --4k --4k-root --output $PWD/keys
|
|
||||||
#
|
|
||||||
#
|
|
||||||
# The "magic" numbers below are derived from the GBB section in
|
|
||||||
# src/mainboard/intel/galileo/vboot.fmd.
|
|
||||||
#
|
|
||||||
# GBB Header Size: 0x80
|
|
||||||
# GBB Offset: 0x611000, 4KiB block number: 1553 (0x611)
|
|
||||||
# GBB Length: 0x7f000, 4KiB blocks: 127 (0x7f)
|
|
||||||
# COREBOOT Offset: 0x690000, 4KiB block number: 1680 (0x690)
|
|
||||||
# COREBOOT Length: 0x170000, 4KiB blocks: 368 (0x170)
|
|
||||||
#
|
|
||||||
# 0x7f000 (GBB Length) = 0x80 + 0x100 + 0x1000 + 0x7ce80 + 0x1000
|
|
||||||
#
|
|
||||||
# Create the GBB area blob
|
|
||||||
# Parameters: hwid_size,rootkey_size,bmpfv_size,recoverykey_size
|
|
||||||
#
|
|
||||||
gbb_utility -c 0x100,0x1000,0x7ce80,0x1000 gbb.blob
|
|
||||||
|
|
||||||
#
|
|
||||||
# Copy from the start of the flash to the GBB region into the signed flash
|
|
||||||
# image.
|
|
||||||
#
|
|
||||||
# 1553 * 4096 = 0x611 * 0x1000 = 0x611000, size of area before GBB
|
|
||||||
#
|
|
||||||
dd conv=fdatasync ibs=4096 obs=4096 count=1553 \
|
|
||||||
if=build/coreboot.rom of=build/coreboot.signed.rom
|
|
||||||
|
|
||||||
#
|
|
||||||
# Append the empty GBB area to the coreboot.rom image.
|
|
||||||
#
|
|
||||||
# 1553 * 4096 = 0x611 * 0x1000 = 0x611000, offset to GBB
|
|
||||||
#
|
|
||||||
dd conv=fdatasync obs=4096 obs=4096 seek=1553 if=gbb.blob \
|
|
||||||
of=build/coreboot.signed.rom
|
|
||||||
|
|
||||||
#
|
|
||||||
# Append the rest of the read-only region into the signed flash image.
|
|
||||||
#
|
|
||||||
# 1680 * 4096 = 0x690 * 0x1000 = 0x690000, offset to COREBOOT area
|
|
||||||
# 368 * 4096 = 0x170 * 0x1000 = 0x170000, length of COREBOOT area
|
|
||||||
#
|
|
||||||
dd conv=fdatasync ibs=4096 obs=4096 skip=1680 seek=1680 count=368 \
|
|
||||||
if=build/coreboot.rom of=build/coreboot.signed.rom
|
|
||||||
|
|
||||||
#
|
|
||||||
# Insert the HWID and public root and recovery RSA keys into the GBB area.
|
|
||||||
#
|
|
||||||
gbb_utility \
|
|
||||||
--set --hwid='Galileo' \
|
|
||||||
-r $PWD/keys/recovery_key.vbpubk \
|
|
||||||
-k $PWD/keys/root_key.vbpubk \
|
|
||||||
build/coreboot.signed.rom
|
|
||||||
|
|
||||||
#
|
|
||||||
# Sign the read/write firmware areas with the private signing key and update
|
|
||||||
# the VBLOCK_A and VBLOCK_B regions.
|
|
||||||
#
|
|
||||||
3rdparty/vboot/scripts/image_signing/sign_firmware.sh \
|
|
||||||
build/coreboot.signed.rom \
|
|
||||||
$PWD/keys \
|
|
||||||
build/coreboot.signed.rom
|
|
||||||
</code></pre>
|
|
||||||
|
|
||||||
<hr>
|
|
||||||
<h2>Boot Flow</h2>
|
|
||||||
<p>
|
|
||||||
The reset vector exist in the read-only area and points to the bootblock entry
|
|
||||||
point. The only copy of the bootblock exists in the read-only area of the SPI
|
|
||||||
flash. Verstage may be part of the bootblock or a separate stage. If separate
|
|
||||||
then the bootblock loads verstage from the read-only area and transfers control
|
|
||||||
to it.
|
|
||||||
</p>
|
|
||||||
|
|
||||||
<p>
|
|
||||||
Upon first boot, verstage attempts to verify the read/write section A. It gets
|
|
||||||
the public root key from the GBB area and uses that to verify the VBLOCK area
|
|
||||||
in read-write section A. If the VBLOCK area is valid then it extracts the
|
|
||||||
firmware signing key (1024-8192 bits) and uses that to verify the FW_MAIN_A
|
|
||||||
area of read/write section A. If the verification is successful then verstage
|
|
||||||
instructs coreboot to use the coreboot file system in read/write section A for
|
|
||||||
the contents of the remaining boot firmware (romstage, postcar, ramstage and
|
|
||||||
the payload).
|
|
||||||
</p>
|
|
||||||
|
|
||||||
<p>
|
|
||||||
If verification fails for the read/write area and the other read/write area is
|
|
||||||
not valid vboot falls back to the read-only area to boot into system recovery.
|
|
||||||
</p>
|
|
||||||
|
|
||||||
<hr>
|
|
||||||
<h2>Chromebook Special Features</h2>
|
|
||||||
<p>
|
|
||||||
Google's Chromebooks have some special features:
|
|
||||||
</p>
|
|
||||||
<ul>
|
|
||||||
<li>Developer mode</li>
|
|
||||||
<li>Write-protect screw</li>
|
|
||||||
</ul>
|
|
||||||
|
|
||||||
<h3>Developer Mode</h3>
|
|
||||||
<p>
|
|
||||||
Developer mode allows the user to use coreboot to boot another operating system.
|
|
||||||
This may be a another (beta) version of Chrome OS, or another flavor of
|
|
||||||
GNU/Linux. Use of developer mode does not void the system warranty. Upon
|
|
||||||
entry into developer mode, all locally saved data on the system is lost.
|
|
||||||
This prevents someone from entering developer mode to subvert the system
|
|
||||||
security to access files on the local system or cloud.
|
|
||||||
</p>
|
|
||||||
|
|
||||||
<h3>Write Protect Screw</h3>
|
|
||||||
<p>
|
|
||||||
Chromebooks have a write-protect screw which provides the ground to the
|
|
||||||
write-protect pin of the SPI flash. Google specifically did this to allow
|
|
||||||
the manufacturing line and advanced developers to re-write the entire SPI flash
|
|
||||||
part. Once the screw is removed, any firmware may be placed on the device.
|
|
||||||
However, accessing this screw requires opening the case and voids the system
|
|
||||||
warranty!
|
|
||||||
</p>
|
|
||||||
|
|
||||||
<hr>
|
|
||||||
<p>Modified: 2 May 2017</p>
|
|
||||||
</body>
|
|
||||||
</html>
|
|
|
@ -4,4 +4,5 @@ This section describes documentation about the security architecture of coreboot
|
||||||
|
|
||||||
## Vendor
|
## Vendor
|
||||||
|
|
||||||
|
- [Verified Boot](vboot/index.md)
|
||||||
- [Measured Boot](vboot/measured_boot.md)
|
- [Measured Boot](vboot/measured_boot.md)
|
||||||
|
|
|
@ -0,0 +1,324 @@
|
||||||
|
# vboot - Verified Boot Support
|
||||||
|
|
||||||
|
Google's verified boot support consists of:
|
||||||
|
|
||||||
|
* A root of trust
|
||||||
|
* Special firmware layout
|
||||||
|
* Firmware verification
|
||||||
|
* Firmware measurements
|
||||||
|
* A firmware update mechanism
|
||||||
|
* Specific build flags
|
||||||
|
* Signing the coreboot image
|
||||||
|
|
||||||
|
Google's vboot verifies the firmware and places measurements within the TPM.
|
||||||
|
|
||||||
|
***
|
||||||
|
|
||||||
|
## Root of Trust
|
||||||
|
|
||||||
|
When using vboot, the root-of-trust is basically the read-only portion of the
|
||||||
|
SPI flash. The following items factor into the trust equation:
|
||||||
|
|
||||||
|
* The GCC compiler must reliably translate the code into machine code
|
||||||
|
without inserting any additional code (virus, backdoor, etc.)
|
||||||
|
* The CPU must reliably execute the reset sequence and instructions as
|
||||||
|
documented by the CPU manufacturer.
|
||||||
|
* The SPI flash must provide only the code programmed into it to the CPU
|
||||||
|
without providing any alternative reset vector or code sequence.
|
||||||
|
* The SPI flash must honor the write-protect input and protect the specified
|
||||||
|
portion of the SPI flash from all erase and write accesses.
|
||||||
|
|
||||||
|
The firmware is typically protected using the write-protect pin on the SPI
|
||||||
|
flash part and setting some of the write-protect bits in the status register
|
||||||
|
during manufacturing. The protected area is platform specific and for x86
|
||||||
|
platforms is typically 1/4th of the SPI flash part size.
|
||||||
|
Because this portion of the SPI flash is hardware write protected, it is not
|
||||||
|
possible to update this portion of the SPI flash in the field, without altering
|
||||||
|
the system to eliminate the ground connection to the SPI flash write-protect pin.
|
||||||
|
Without hardware modifications, this portion of the SPI flash maintains the
|
||||||
|
manufactured state during the system's lifetime.
|
||||||
|
|
||||||
|
***
|
||||||
|
|
||||||
|
## Firmware Layout
|
||||||
|
|
||||||
|
Several sections are added to the firmware layout to support vboot:
|
||||||
|
|
||||||
|
* Read-only section
|
||||||
|
* Google Binary Blob (GBB) area
|
||||||
|
* Read/write section A
|
||||||
|
* Read/write section B
|
||||||
|
|
||||||
|
The following sections describe the various portions of the flash layout.
|
||||||
|
|
||||||
|
### Read-Only Section
|
||||||
|
|
||||||
|
The read-only section contains a coreboot file system (CBFS) that contains all
|
||||||
|
of the boot firmware necessary to perform recovery for the system. This firmware
|
||||||
|
is typically protected using the write-protect pin on the SPI flash part and
|
||||||
|
setting some of the write-protect bits in the status register during
|
||||||
|
manufacturing.
|
||||||
|
The protected area is typically 1/4th of the SPI flash part size and must cover
|
||||||
|
the entire read-only section which consists of:
|
||||||
|
|
||||||
|
* Vital Product Data (VPD) area
|
||||||
|
* Firmware ID area
|
||||||
|
* Google Binary Blob (GBB) area
|
||||||
|
* coreboot file system containing read-only recovery firmware
|
||||||
|
|
||||||
|
### Google Binary Blob (GBB) Area
|
||||||
|
|
||||||
|
The GBB area is part of the read-only section. This area contains a 4096 or 8192
|
||||||
|
bit public root RSA key that is used to verify the *VBLOCK* area to obtain the
|
||||||
|
firmware signing key.
|
||||||
|
|
||||||
|
### Recovery Firmware
|
||||||
|
|
||||||
|
The recovery firmware is contained within a coreboot file system and consists of:
|
||||||
|
|
||||||
|
* reset vector
|
||||||
|
* bootblock
|
||||||
|
* verstage
|
||||||
|
* romstage
|
||||||
|
* postcar
|
||||||
|
* ramstage
|
||||||
|
* payload
|
||||||
|
* flash map file
|
||||||
|
* config file
|
||||||
|
* processor specific files:
|
||||||
|
* Microcode
|
||||||
|
* fspm.bin
|
||||||
|
* fsps.bin
|
||||||
|
|
||||||
|
The recovery firmware is written during manufacturing and typically contains
|
||||||
|
code to write the storage device (eMMC device or hard disk). The recovery image
|
||||||
|
is usually contained on a socketed device such as a USB flash drive or an
|
||||||
|
SD card. Depending upon the payload firmware doing the recovery, it may be
|
||||||
|
possible for the user to interact with the system to specify the recovery
|
||||||
|
image path. Part of the recovery is also to write the A and B areas of the SPI
|
||||||
|
flash device to boot the system.
|
||||||
|
|
||||||
|
### Read/Write Section
|
||||||
|
|
||||||
|
The read/write sections contain an area which contains the firmware signing
|
||||||
|
key and signature and an area containing a coreboot file system with a subset
|
||||||
|
of the firmware. The firmware files in *FW_MAIN_A* and *FW_MAIN_B* are:
|
||||||
|
|
||||||
|
* romstage
|
||||||
|
* postcar
|
||||||
|
* ramstage
|
||||||
|
* payload
|
||||||
|
* config file
|
||||||
|
* processor specific files:
|
||||||
|
* Microcode
|
||||||
|
* fspm.bin
|
||||||
|
* fsps.bin
|
||||||
|
|
||||||
|
The firmware subset enables most issues to be fixed in the field with firmware
|
||||||
|
updates. The firmware files handle memory and most of silicon initialization.
|
||||||
|
These files also produce the tables which get passed to the operating system.
|
||||||
|
|
||||||
|
***
|
||||||
|
|
||||||
|
## Firmware Updates
|
||||||
|
|
||||||
|
The read/write sections exist in one of three states:
|
||||||
|
|
||||||
|
* Invalid
|
||||||
|
* Ready to boot
|
||||||
|
* Successfully booted
|
||||||
|
|
||||||
|
|
||||||
|
Firmware updates are handled by the operating system by writing any read/write
|
||||||
|
section that is not in the "successfully booted" state. Upon the next reboot,
|
||||||
|
vboot determines the section to boot. If it finds one in the "ready to boot"
|
||||||
|
state then it attempts to boot using that section. If the boot fails then
|
||||||
|
vboot marks the section as invalid and attempts to fall back to a read/write
|
||||||
|
section in the "successfully booted" state. If vboot is not able to find a
|
||||||
|
section in the "successfully booted" state then vboot enters recovery mode.
|
||||||
|
|
||||||
|
Only the operating system is able to transition a section from the
|
||||||
|
"ready to boot" state to the "successfully booted" state.
|
||||||
|
The transition is typically done after the operating system has been running
|
||||||
|
for a while indicating that successful boot was possible and the operating
|
||||||
|
system is stable.
|
||||||
|
|
||||||
|
Note that as long as the SPI write protection is in place then the system
|
||||||
|
is always recoverable. If the flash update fails then the system will continue
|
||||||
|
to boot using the previous read/write area. The same is true if coreboot passes
|
||||||
|
control to the payload or the operating system and then the boot fails. In the
|
||||||
|
worst case, the SPI flash gets totally corrupted in which case vboot fails the
|
||||||
|
signature checks and enters recovery mode. There are no times where the SPI
|
||||||
|
flash is exposed and the reset vector or part of the recovery firmware gets
|
||||||
|
corrupted.
|
||||||
|
|
||||||
|
***
|
||||||
|
|
||||||
|
## Build Flags
|
||||||
|
|
||||||
|
The following *Kconfig* values need to be selected to enable vboot:
|
||||||
|
|
||||||
|
* COLLECT_TIMESTAMPS
|
||||||
|
* VBOOT
|
||||||
|
|
||||||
|
The starting stage needs to be specified by selecting either
|
||||||
|
VBOOT_STARTS_IN_BOOTBLOCK or VBOOT_STARTS_IN_ROMSTAGE.
|
||||||
|
|
||||||
|
If vboot starts in bootblock then vboot may be built as a separate stage by
|
||||||
|
selecting `VBOOT_SEPARATE_VERSTAGE`. Additionally, if static RAM is too small
|
||||||
|
to fit both verstage and romstage then selecting `VBOOT_RETURN_FROM_VERSTAGE`
|
||||||
|
enables bootblock to reuse the RAM occupied by verstage for romstage.
|
||||||
|
|
||||||
|
Non-volatile flash is needed for vboot operation. This flash area may be in
|
||||||
|
CMOS, the EC, or in a read/write area of the SPI flash device.
|
||||||
|
Select one of the following:
|
||||||
|
|
||||||
|
* `VBOOT_VBNV_CMOS`
|
||||||
|
* `VBOOT_VBNV_EC`
|
||||||
|
* `VBOOT_VBNV_FLASH`
|
||||||
|
|
||||||
|
More non-volatile storage features may be found in `security/vboot/Kconfig`.
|
||||||
|
|
||||||
|
A TPM is also required for vboot operation.
|
||||||
|
TPMs are available in `drivers/i2c/tpm` and `drivers/pc80/tpm`.
|
||||||
|
|
||||||
|
In addition to adding the coreboot files into the read-only region,
|
||||||
|
enabling vboot causes the build script to add the read/write files into
|
||||||
|
coreboot file systems in *FW_MAIN_A* and *FW_MAIN_B*.
|
||||||
|
|
||||||
|
***
|
||||||
|
|
||||||
|
## Signing the coreboot Image
|
||||||
|
|
||||||
|
The following command script is an example of how to sign the coreboot image
|
||||||
|
file. This script is used on the Intel Galileo board and creates the *GBB* area
|
||||||
|
and inserts it into the coreboot image. It also updates the *VBLOCK* areas with
|
||||||
|
the firmware signing key and the signature for the *FW_MAIN* firmware.
|
||||||
|
More details are available in `3rdparty/vboot/README`.
|
||||||
|
|
||||||
|
```bash
|
||||||
|
#!/bin/sh
|
||||||
|
#
|
||||||
|
# The necessary tools were built and installed using the following commands:
|
||||||
|
#
|
||||||
|
# pushd 3rdparty/vboot
|
||||||
|
# make
|
||||||
|
# sudo make install
|
||||||
|
# popd
|
||||||
|
#
|
||||||
|
# The keys were made using the following command
|
||||||
|
#
|
||||||
|
# 3rdparty/vboot/scripts/keygeneration/create_new_keys.sh \
|
||||||
|
# --4k --4k-root --output $PWD/keys
|
||||||
|
#
|
||||||
|
#
|
||||||
|
# The "magic" numbers below are derived from the GBB section in
|
||||||
|
# src/mainboard/intel/galileo/vboot.fmd.
|
||||||
|
#
|
||||||
|
# GBB Header Size: 0x80
|
||||||
|
# GBB Offset: 0x611000, 4KiB block number: 1553 (0x611)
|
||||||
|
# GBB Length: 0x7f000, 4KiB blocks: 127 (0x7f)
|
||||||
|
# COREBOOT Offset: 0x690000, 4KiB block number: 1680 (0x690)
|
||||||
|
# COREBOOT Length: 0x170000, 4KiB blocks: 368 (0x170)
|
||||||
|
#
|
||||||
|
# 0x7f000 (GBB Length) = 0x80 + 0x100 + 0x1000 + 0x7ce80 + 0x1000
|
||||||
|
#
|
||||||
|
# Create the GBB area blob
|
||||||
|
# Parameters: hwid_size,rootkey_size,bmpfv_size,recoverykey_size
|
||||||
|
#
|
||||||
|
gbb_utility -c 0x100,0x1000,0x7ce80,0x1000 gbb.blob
|
||||||
|
|
||||||
|
#
|
||||||
|
# Copy from the start of the flash to the GBB region into the signed flash
|
||||||
|
# image.
|
||||||
|
#
|
||||||
|
# 1553 * 4096 = 0x611 * 0x1000 = 0x611000, size of area before GBB
|
||||||
|
#
|
||||||
|
dd conv=fdatasync ibs=4096 obs=4096 count=1553 \
|
||||||
|
if=build/coreboot.rom of=build/coreboot.signed.rom
|
||||||
|
|
||||||
|
#
|
||||||
|
# Append the empty GBB area to the coreboot.rom image.
|
||||||
|
#
|
||||||
|
# 1553 * 4096 = 0x611 * 0x1000 = 0x611000, offset to GBB
|
||||||
|
#
|
||||||
|
dd conv=fdatasync obs=4096 obs=4096 seek=1553 if=gbb.blob \
|
||||||
|
of=build/coreboot.signed.rom
|
||||||
|
|
||||||
|
#
|
||||||
|
# Append the rest of the read-only region into the signed flash image.
|
||||||
|
#
|
||||||
|
# 1680 * 4096 = 0x690 * 0x1000 = 0x690000, offset to COREBOOT area
|
||||||
|
# 368 * 4096 = 0x170 * 0x1000 = 0x170000, length of COREBOOT area
|
||||||
|
#
|
||||||
|
dd conv=fdatasync ibs=4096 obs=4096 skip=1680 seek=1680 count=368 \
|
||||||
|
if=build/coreboot.rom of=build/coreboot.signed.rom
|
||||||
|
|
||||||
|
#
|
||||||
|
# Insert the HWID and public root and recovery RSA keys into the GBB area.
|
||||||
|
#
|
||||||
|
gbb_utility \
|
||||||
|
--set --hwid='Galileo' \
|
||||||
|
-r $PWD/keys/recovery_key.vbpubk \
|
||||||
|
-k $PWD/keys/root_key.vbpubk \
|
||||||
|
build/coreboot.signed.rom
|
||||||
|
|
||||||
|
#
|
||||||
|
# Sign the read/write firmware areas with the private signing key and update
|
||||||
|
# the VBLOCK_A and VBLOCK_B regions.
|
||||||
|
#
|
||||||
|
3rdparty/vboot/scripts/image_signing/sign_firmware.sh \
|
||||||
|
build/coreboot.signed.rom \
|
||||||
|
$PWD/keys \
|
||||||
|
build/coreboot.signed.rom
|
||||||
|
```
|
||||||
|
|
||||||
|
***
|
||||||
|
|
||||||
|
## Boot Flow
|
||||||
|
|
||||||
|
The reset vector exist in the read-only area and points to the bootblock
|
||||||
|
entry point. The only copy of the bootblock exists in the read-only area
|
||||||
|
of the SPI flash. Verstage may be part of the bootblock or a separate stage.
|
||||||
|
If separate then the bootblock loads verstage from the read-only area and
|
||||||
|
transfers control to it.
|
||||||
|
|
||||||
|
Upon first boot, verstage attempts to verify the read/write section A.
|
||||||
|
It gets the public root key from the GBB area and uses that to verify the
|
||||||
|
*VBLOCK* area in read-write section A. If the *VBLOCK* area is valid then it
|
||||||
|
extracts the firmware signing key (1024-8192 bits) and uses that to verify
|
||||||
|
the *FW_MAIN_A* area of read/write section A. If the verification is successful
|
||||||
|
then verstage instructs coreboot to use the coreboot file system in read/write
|
||||||
|
section A for the contents of the remaining boot firmware (romstage, postcar,
|
||||||
|
ramstage and the payload).
|
||||||
|
|
||||||
|
If verification fails for the read/write area and the other read/write area is
|
||||||
|
not valid vboot falls back to the read-only area to boot into system recovery.
|
||||||
|
|
||||||
|
***
|
||||||
|
|
||||||
|
## Chromebook Special Features
|
||||||
|
|
||||||
|
Google's Chromebooks have some special features:
|
||||||
|
|
||||||
|
* Developer mode
|
||||||
|
* Write-protect screw
|
||||||
|
|
||||||
|
### Developer Mode
|
||||||
|
|
||||||
|
Developer mode allows the user to use coreboot to boot another operating system.
|
||||||
|
This may be a another (beta) version of Chrome OS, or another flavor of
|
||||||
|
GNU/Linux. Use of developer mode does not void the system warranty. Upon entry
|
||||||
|
into developer mode, all locally saved data on the system is lost.
|
||||||
|
This prevents someone from entering developer mode to subvert the system
|
||||||
|
security to access files on the local system or cloud.
|
||||||
|
|
||||||
|
### Write Protect Screw
|
||||||
|
|
||||||
|
Chromebooks have a write-protect screw which provides the ground to the
|
||||||
|
write-protect pin of the SPI flash.
|
||||||
|
Google specifically did this to allow the manufacturing line and advanced
|
||||||
|
developers to re-write the entire SPI flash part. Once the screw is removed,
|
||||||
|
any firmware may be placed on the device.
|
||||||
|
However, accessing this screw requires opening the case and voids the
|
||||||
|
system warranty!
|
Loading…
Reference in New Issue