| 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 |
| crypto/. |
| |
| 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 |
| utility/dumpRSAPublicKey |
| |
| # 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. |