blob: c2df44bf3fe1b19330a77ec83259a7c63a45daed [file] [log] [blame]
This directory contains a reference implementation for Chrome OS
verified boot in firmware.
Directory Structure
The source is organized into distinct modules -
cryptolib/ - Contains the implementation for the crypto library. This
includes implementations for SHA1, SHA256, SHA512, and RSA signature
verification (for PKCS #1 v1.5 signatures).
common/ - Utility functions and stub implementations for wrapper
functions used in the verification code. These stub implementations
will need to be replaced with appropriate firmware equivalents.
misclibs/ - Miscellaneous functions used by userland utilities.
utility/ - Utilities for generating and verifying signed
firmware and kernel images, as well as arbitrary blobs.
vfirmware/ and vkernel/ - The main firmware and kernel image
verification modules. It has functions for verifying and manipulating
signed firmware and kernel images. The main files of interest are:
vfirmware/firmware_image_fw.c (verification Functions used in Firmware)
vfirmware/firmware_image.c (functions for userland tools)
vkernel/kernel_image_fw.c (verification functions used in Firmware)
vkernel/kernel_image.c (functions for userland tools)
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.
Some useful utilities:
firmware_utility.c To generate verified boot firmware images.
kernel_utility.c To generate verified boot kernel images.
dumpRSAPublicKey.c Dump RSA Public key (from a DER-encoded X509
certificate) in a format suitable for
use by RSAVerify* functions in
verify_data.c Verify a given signature on a given file.
What is required for a minimal verified boot implementation
1) cryptolib/ - as a separate module since it will be used by others
parts of the verified boot process.
2) common/ - this contains the interface for dealing with memory allocation
and interacting with the TPM. The stubs will need to be replaced with their
firmware-level equivalents.
3) Verified Firmware and Kernel image verification - This is the core
of the verified boot implementation. They are implemented under vfirmware
and vkernel (for firmware and kernel image verification respectively).
firmware_image_fw.c and kernel_image_fw.c : Contain verification logic
used in the firmware. Needed.
firmware_image.c and kernel_image.c : High level functions used by userland
tools. NOT needed in the firmware.
cryptolib/, common/, vfirmware/firmware_image_fw.c are part of the RO firmware.
vkernel/kernel_image_fw.c is part of the RW firmware (it verifies the OS kernel).
Generating a signed firmware image:
* Step 1: Generate RSA root and signing keys.
# Root key is always 8192 bits.
$ openssl genrsa -F4 -out root_key.pem 8192
# 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 expects an x509 certificate as input.
$ 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
$ utility/dumpRSAPublicKey root_key.crt > root_key.keyb
$ utility/dumpRSAPublicKey signing_key.crt > signing_key.keyb
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 <algoid> \
--firmware_key_version 1 \
--firmware_version 1 \
--in <firmware blob file> \
--out <output file>
Where <algoid> is based on the signature algorithm to use for firmware
signining. The list of <algoid> 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 valid values.
* Step 4: Verify that this image verifies.
$ utility/firmware_utility --verify \
--in <signed firmware image>
--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.