summaryrefslogtreecommitdiff
path: root/README
blob: 94d6b2ed45d0271ca482fdfeb3e1684883758b96 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
This directory contains a reference implementation for Chrome OS
verified boot in firmware.

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

include/ - Contains all the code headers. firmware_image.h and
kernel_image.h contains the structures that represent a verified boot
firmware and kernel image. Note that the

crypto/ - 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/ - Contains some utility functions and stub implementations for
certain wrapper functions used in the verification code. Some of these
(for example Free(), Malloc()) will need to be replaced with
appropriate firmware-land equivalent.

utils/ - This contains the implementation of kernel and firmware image
verification (see firmware_image.c and kernel_image.c) and some
utilities (e.g. firmware_utility - for generating verified boot
firmware images).

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.

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.
				 

---------- 
Here's what is required for a minimal verified boot implementation
----------

1) Crypto implementation from crypto/. The verified boot code should
use the wrappers from rsa_utility.h and sha_utility.h - RSAVerify_f()
and Digest*() functions.

2) Verified Firmware and Kernel image verification functions - only
functions that work on binary blobs (VerifyFirmware() and
VerifyKernel()) are required. The functions that work on Firmware and
Kernel images (e.g. VerifyFirmwareImage()) are only useful for
user-land utilities that manipulate signed firmware and kernel images.


---------- 
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
        utils/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
$ utils/dumpRSAPublicKey root_key.crt > root_key.keyb
$ utils/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 utils/firmware_utility to generate a signed firmare blob.

$ utils/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
'utils/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.

$ utils/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.