Google's vboot utilities

Randall Spangler a609478d1a 2lib: add VB2_DEBUG_RAW() to print without function name %!s(int64=7) %!d(string=hai) anos
bdb 8df7ed1453 expand the BDB acronym in a few key places %!s(int64=8) %!d(string=hai) anos
cgpt 559a110f33 vboot: use malloc and free directly %!s(int64=8) %!d(string=hai) anos
firmware a609478d1a 2lib: add VB2_DEBUG_RAW() to print without function name %!s(int64=7) %!d(string=hai) anos
futility 2a84553d44 futility/cmd_validate_rec_mrc: Update futility to use new MRC struct %!s(int64=8) %!d(string=hai) anos
host a609478d1a 2lib: add VB2_DEBUG_RAW() to print without function name %!s(int64=7) %!d(string=hai) anos
scripts 62461d719f image_signing: support signing of OCI containers %!s(int64=7) %!d(string=hai) anos
tests 62461d719f image_signing: support signing of OCI containers %!s(int64=7) %!d(string=hai) anos
utility ad7a75531e firmware: Remove LoadKernelParams from APIs %!s(int64=7) %!d(string=hai) anos
.gitignore 6cda3966ec newbitmaps: Refine text layout & font settings. %!s(int64=12) %!d(string=hai) anos
Android.mk 2afa87360d vboot: Remove vboot1 init and select-firmware APIs %!s(int64=8) %!d(string=hai) anos
LICENSE 97a122817d Add LICENSE file %!s(int64=14) %!d(string=hai) anos
Makefile 71c6c033f9 firmware: Add developer menu support for detachables %!s(int64=7) %!d(string=hai) anos
PRESUBMIT.cfg d75eb7f77a presubmit: enable branch check %!s(int64=9) %!d(string=hai) anos
README efa8756c5e cleanup: DESTDIR refers to the install root, not the bin/ %!s(int64=10) %!d(string=hai) anos
WATCHLISTS d52030f340 vboot_reference: Fix Watchlists %!s(int64=14) %!d(string=hai) anos
emerge_test.sh 7de120208b Drop "depthcharge" and "unified_depthcharge" portage use symbols %!s(int64=8) %!d(string=hai) anos
inherit-review-settings-ok af5ae8e21b add inherit review settings for new repo %!s(int64=14) %!d(string=hai) anos
vboot_host.pc.in 07d9043da4 vboot_reference: Install vboot_host.pc file %!s(int64=9) %!d(string=hai) anos

README

This directory contains a reference implementation for Chrome OS
verified boot in firmware.

----------
Directory Structure
----------

The source is organized into distinct modules -

firmware/

Contains ONLY the code required by the BIOS to validate the secure boot
components. There shouldn't be any code in here that signs or generates
images. BIOS should require ONLY this directory to implement secure boot.
Refer to firmware/README for futher details.

cgpt/

Utility to read/write/modify GPT partitions. Similar to GNU parted or any
other GPT tool, but this has support for Chrome OS extensions.

host/

Miscellaneous functions needed by userland utilities.

futility/

The "firmware utility" tool, used to create, sign, and validate Chrome OS
images.

utility/

Random other utilities, not necesssarily related to verified boot as such.

tests/

User-land tests and benchmarks that test the reference implementation.
Please have a look at these if you'd like to understand how to use the
reference implementation.

build/

The output directory where the generated files will be placed, and where
tests are run.

scripts/

Tools and scripts used to generate and use new signing keypairs. These are
typically used only on a secure machine.


--------------------
Building and testing
--------------------

The suite can be built on the host or in the chroot environment.

Building on the host could fail if certain packages are not installed. If
there are host environment build problems due to missing .h files, try
researching what packages the files belong to and install the missing packages
before reporting a problem.


The commands are the more-or-less expected ones:

make
make runtests
make install [ DESTDIR=/usr/local ]



----------
Some useful utilities:
----------

futility vbutil_key Convert a public key into .vbpubk format
futility vbutil_keyblock Wrap a public key inside a signature and checksum
futility vbutil_firmware Create a .vblock with signature info for a
firmware image
futility vbutil_kernel Pack a kernel image, bootloader, and config into
a signed binary

dumpRSAPublicKey Dump RSA Public key (from a DER-encoded X509
certificate) in a format suitable for use by
RSAVerify* functions in crypto/.

verify_data.c Verify a given signature on a given file.



----------
Generating a signed firmware image:
----------

* Step 0: Build the tools, install them somewhere.

* Step 1: Generate RSA root and signing keys.

The root key is always 8192 bits.

$ openssl genrsa -F4 -out root_key.pem 8192

The signing key can be between 1024-8192 bits.

$ openssl genrsa -F4 -out signing_key.pem <1024|2048|4096|8192>

Note: The -F4 option must be specified to generate RSA keys with a public
exponent of 65535. RSA keys with 3 as a public exponent (the default)
won't work.

* Step 2: Generate pre-processed public versions of the above keys using
dumpRSAPublicKey. This utility expects an x509 certificate as
input, and emits an intermediate representation for further
processing.

$ openssl req -batch -new -x509 -key root_key.pem -out root_key.crt
$ openssl req -batch -new -x509 -key signing_key.pem -out signing_key.crt
$ dumpRSAPublicKey root_key.crt > root_key.keyb
$ dumpRSAPublicKey signing_key.crt > signing_key.keyb

************** TODO: STUFF PAST HERE IS OUT OF DATE ***************

At this point we have all the requisite keys needed to generate a signed
firmware image.

.pem RSA Public/Private Key Pair
.crt X509 Key Certificate
.keyb Pre-processed RSA Public Key


* Step 3: Use utility/firmware_utility to generate a signed firmare blob.

$ utility/firmware_utility --generate \
--root_key root_key.pem \
--firmware_sign_key signing_key.pem \
--firmware_sign_key_pub signing_key.keyb \
--firmware_sign_algorithm \
--firmware_key_version 1 \
--firmware_version 1 \
--in \
--out

Where is based on the signature algorithm to use for firmware
signining. The list of specifications can be output by running
'utility/firmware_utility' without any arguments.

Note: --firmware_key_version and --firmware_version are part of a signed
image and are used to prevent rollbacks to older version. For testing,
they can just be set to valid values.


* Step 4: Verify that this image verifies.

$ utility/firmware_utility --verify \
--in
--root_key_pub root_key.keyb
Verification SUCCESS.


Note: The verification functions expects a pointer to the
pre-processed public root key as input. For testing purposes,
root_key.keyb can be stored in RW part of the firmware. For the
final firmware, this will be a fixed public key which cannot be
changed and must be stored in RO firmware.

----------
Generating a signed kernel image:
----------

The steps for generating a signed kernel image are similar to that of
a firmware image. Since verification is chained - RO firmware verifies
RW firmware which verifies the kernel, only the keys change. An additional
kernel signing key must be generated. The firmware signing generated above
is the root key equivalent for signed kernel images.