Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1)

Side by Side Diff: src/platform/vboot_reference/utils/firmware_image_fw.c

Issue 1599001: VBoot Reference: Refactor Pass 1: Split {firmware|kernel}_image (Closed)
Patch Set: Created 10 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
(Empty)
1 /* Copyright (c) 2010 The Chromium OS Authors. All rights reserved.
2 * Use of this source code is governed by a BSD-style license that can be
3 * found in the LICENSE file.
4 *
5 * Functions for verifying a verified boot firmware image.
6 * (Firmware Portion)
7 */
8
9 #include "firmware_image_fw.h"
10
11 #include "padding.h"
12 #include "rollback_index.h"
13 #include "rsa_utility.h"
14 #include "sha_utility.h"
15 #include "utility.h"
16
17 /* Macro to determine the size of a field structure in the FirmwareImage
18 * structure. */
19 #define FIELD_LEN(field) (sizeof(((FirmwareImage*)0)->field))
20
21 char* kVerifyFirmwareErrors[VERIFY_FIRMWARE_MAX] = {
22 "Success.",
23 "Invalid Image.",
24 "Root Key Signature Failed.",
25 "Invalid Verification Algorithm.",
26 "Preamble Signature Failed.",
27 "Firmware Signature Failed.",
28 "Wrong Firmware Magic.",
29 "Invalid Firmware Header Checksum.",
30 "Firmware Signing Key Rollback.",
31 "Firmware Version Rollback."
32 };
33
34 int VerifyFirmwareHeader(const uint8_t* root_key_blob,
35 const uint8_t* header_blob,
36 int* algorithm,
37 int* header_len) {
38 int firmware_sign_key_len;
39 int root_key_len;
40 uint16_t hlen, algo;
41 uint8_t* header_checksum = NULL;
42
43 /* Base Offset for the header_checksum field. Actual offset is
44 * this + firmware_sign_key_len. */
45 int base_header_checksum_offset = (FIELD_LEN(header_len) +
46 FIELD_LEN(firmware_sign_algorithm) +
47 FIELD_LEN(firmware_key_version));
48
49
50 root_key_len = RSAProcessedKeySize(ROOT_SIGNATURE_ALGORITHM);
51 Memcpy(&hlen, header_blob, sizeof(hlen));
52 Memcpy(&algo,
53 header_blob + FIELD_LEN(firmware_sign_algorithm),
54 sizeof(algo));
55 if (algo >= kNumAlgorithms)
56 return VERIFY_FIRMWARE_INVALID_ALGORITHM;
57 *algorithm = (int) algo;
58 firmware_sign_key_len = RSAProcessedKeySize(*algorithm);
59
60 /* Verify that header len is correct. */
61 if (hlen != (base_header_checksum_offset +
62 firmware_sign_key_len +
63 FIELD_LEN(header_checksum)))
64 return VERIFY_FIRMWARE_INVALID_IMAGE;
65
66 *header_len = (int) hlen;
67
68 /* Verify if the hash of the header is correct. */
69 header_checksum = DigestBuf(header_blob,
70 *header_len - FIELD_LEN(header_checksum),
71 SHA512_DIGEST_ALGORITHM);
72 if (SafeMemcmp(header_checksum,
73 header_blob + (base_header_checksum_offset +
74 firmware_sign_key_len),
75 FIELD_LEN(header_checksum))) {
76 Free(header_checksum);
77 return VERIFY_FIRMWARE_WRONG_HEADER_CHECKSUM;
78 }
79 Free(header_checksum);
80
81 /* Root key signature on the firmware signing key is always checked
82 * irrespective of dev mode. */
83 if (!RSAVerifyBinary_f(root_key_blob, NULL, /* Key to use */
84 header_blob, /* Data to verify */
85 *header_len, /* Length of data */
86 header_blob + *header_len, /* Expected Signature */
87 ROOT_SIGNATURE_ALGORITHM))
88 return VERIFY_FIRMWARE_ROOT_SIGNATURE_FAILED;
89 return 0;
90 }
91
92 int VerifyFirmwarePreamble(RSAPublicKey* firmware_sign_key,
93 const uint8_t* preamble_blob,
94 int algorithm,
95 uint64_t* firmware_len) {
96 uint64_t len;
97 int preamble_len;
98 uint16_t firmware_version;
99
100 Memcpy(&firmware_version, preamble_blob, sizeof(firmware_version));
101
102 preamble_len = (FIELD_LEN(firmware_version) +
103 FIELD_LEN(firmware_len) +
104 FIELD_LEN(preamble));
105 if (!RSAVerifyBinary_f(NULL, firmware_sign_key, /* Key to use */
106 preamble_blob, /* Data to verify */
107 preamble_len, /* Length of data */
108 preamble_blob + preamble_len, /* Expected Signature */
109 algorithm))
110 return VERIFY_FIRMWARE_PREAMBLE_SIGNATURE_FAILED;
111
112 Memcpy(&len, preamble_blob + FIELD_LEN(firmware_version),
113 sizeof(len));
114 *firmware_len = len;
115 return 0;
116 }
117
118 int VerifyFirmwareData(RSAPublicKey* firmware_sign_key,
119 const uint8_t* preamble_start,
120 const uint8_t* firmware_data_start,
121 uint64_t firmware_len,
122 int algorithm) {
123 int signature_len = siglen_map[algorithm];
124 uint8_t* digest;
125 DigestContext ctx;
126
127 /* Since the firmware signature is over the preamble and the firmware data,
128 * which does not form a contiguous region of memory, we calculate the
129 * message digest ourselves. */
130 DigestInit(&ctx, algorithm);
131 DigestUpdate(&ctx, preamble_start,
132 (FIELD_LEN(firmware_version) +
133 FIELD_LEN(firmware_len) +
134 FIELD_LEN(preamble)));
135 DigestUpdate(&ctx, firmware_data_start + signature_len, firmware_len);
136 digest = DigestFinal(&ctx);
137 if (!RSAVerifyBinaryWithDigest_f(
138 NULL, firmware_sign_key, /* Key to use. */
139 digest, /* Digest of the data to verify. */
140 firmware_data_start, /* Expected Signature */
141 algorithm)) {
142 Free(digest);
143 return VERIFY_FIRMWARE_SIGNATURE_FAILED;
144 }
145 Free(digest);
146 return 0;
147 }
148
149 int VerifyFirmware(const uint8_t* root_key_blob,
150 const uint8_t* firmware_blob) {
151 int error_code = 0;
152 int algorithm; /* Signing key algorithm. */
153 RSAPublicKey* firmware_sign_key = NULL;
154 int firmware_sign_key_len, signature_len, header_len;
155 uint64_t firmware_len;
156 const uint8_t* header_ptr = NULL; /* Pointer to header. */
157 const uint8_t* firmware_sign_key_ptr = NULL; /* Pointer to signing key. */
158 const uint8_t* preamble_ptr = NULL; /* Pointer to preamble block. */
159 const uint8_t* firmware_ptr = NULL; /* Pointer to firmware signature/data. */
160
161 /* Note: All the offset calculations are based on struct FirmwareImage which
162 * is defined in include/firmware_image.h. */
163
164 /* Compare magic bytes. */
165 if (SafeMemcmp(firmware_blob, FIRMWARE_MAGIC, FIRMWARE_MAGIC_SIZE))
166 return VERIFY_FIRMWARE_WRONG_MAGIC;
167 header_ptr = firmware_blob + FIRMWARE_MAGIC_SIZE;
168
169 /* Only continue if header verification succeeds. */
170 if ((error_code = VerifyFirmwareHeader(root_key_blob, header_ptr,
171 &algorithm, &header_len)))
172 return error_code; /* AKA jump to revovery. */
173
174 /* Parse signing key into RSAPublicKey structure since it is required multiple
175 * times. */
176 firmware_sign_key_len = RSAProcessedKeySize(algorithm);
177 firmware_sign_key_ptr = header_ptr + (FIELD_LEN(header_len) +
178 FIELD_LEN(firmware_sign_algorithm) +
179 FIELD_LEN(firmware_key_version));
180 firmware_sign_key = RSAPublicKeyFromBuf(firmware_sign_key_ptr,
181 firmware_sign_key_len);
182 signature_len = siglen_map[algorithm];
183
184 /* Only continue if preamble verification succeeds. */
185 preamble_ptr = (header_ptr + header_len +
186 FIELD_LEN(firmware_key_signature));
187 if ((error_code = VerifyFirmwarePreamble(firmware_sign_key, preamble_ptr,
188 algorithm,
189 &firmware_len))) {
190 RSAPublicKeyFree(firmware_sign_key);
191 debug("Couldn't verify Firmware preamble.\n");
192 return error_code; /* AKA jump to recovery. */
193 }
194 /* Only continue if firmware data verification succeeds. */
195 firmware_ptr = (preamble_ptr +
196 (FIELD_LEN(firmware_version) + /* Skip the preamble. */
197 FIELD_LEN(firmware_len) +
198 FIELD_LEN(preamble)) +
199 signature_len);
200
201 if ((error_code = VerifyFirmwareData(firmware_sign_key, preamble_ptr,
202 firmware_ptr,
203 firmware_len,
204 algorithm))) {
205 RSAPublicKeyFree(firmware_sign_key);
206 debug("Couldn't verify Firmware data.\n");
207 return error_code; /* AKA jump to recovery. */
208 }
209
210 RSAPublicKeyFree(firmware_sign_key);
211 return 0; /* Success! */
212 }
213
214 uint32_t GetLogicalFirmwareVersion(uint8_t* firmware_blob) {
215 uint16_t firmware_key_version;
216 uint16_t firmware_version;
217 uint16_t firmware_sign_algorithm;
218 int firmware_sign_key_len;
219 Memcpy(&firmware_sign_algorithm,
220 firmware_blob + (FIELD_LEN(magic) + /* Offset to field. */
221 FIELD_LEN(header_len)),
222 sizeof(firmware_sign_algorithm));
223 Memcpy(&firmware_key_version,
224 firmware_blob + (FIELD_LEN(magic) + /* Offset to field. */
225 FIELD_LEN(header_len) +
226 FIELD_LEN(firmware_sign_algorithm)),
227 sizeof(firmware_key_version));
228 if (firmware_sign_algorithm >= kNumAlgorithms)
229 return 0;
230 firmware_sign_key_len = RSAProcessedKeySize(firmware_sign_algorithm);
231 Memcpy(&firmware_version,
232 firmware_blob + (FIELD_LEN(magic) + /* Offset to field. */
233 FIELD_LEN(header_len) +
234 FIELD_LEN(firmware_key_version) +
235 firmware_sign_key_len +
236 FIELD_LEN(header_checksum) +
237 FIELD_LEN(firmware_key_signature)),
238 sizeof(firmware_version));
239 return CombineUint16Pair(firmware_key_version, firmware_version);
240 }
241
242 int VerifyFirmwareDriver_f(uint8_t* root_key_blob,
243 uint8_t* firmwareA,
244 uint8_t* firmwareB) {
245 /* Contains the logical firmware version (32-bit) which is calculated as
246 * (firmware_key_version << 16 | firmware_version) where
247 * [firmware_key_version] [firmware_version] are both 16-bit.
248 */
249 uint32_t firmwareA_lversion, firmwareB_lversion;
250 uint8_t firmwareA_is_verified = 0; /* Whether firmwareA verify succeeded. */
251 uint32_t min_lversion; /* Minimum of firmware A and firmware lversion. */
252 uint32_t stored_lversion; /* Stored logical version in the TPM. */
253
254 /* Initialize the TPM since we'll be reading the rollback indices. */
255 SetupTPM();
256
257 /* We get the key versions by reading directly from the image blobs without
258 * any additional (expensive) sanity checking on the blob since it's faster to
259 * outright reject a firmware with an older firmware key version. A malformed
260 * or corrupted firmware blob will still fail when VerifyFirmware() is called
261 * on it.
262 */
263 firmwareA_lversion = GetLogicalFirmwareVersion(firmwareA);
264 firmwareB_lversion = GetLogicalFirmwareVersion(firmwareB);
265 min_lversion = Min(firmwareA_lversion, firmwareB_lversion);
266 stored_lversion = CombineUint16Pair(GetStoredVersion(FIRMWARE_KEY_VERSION),
267 GetStoredVersion(FIRMWARE_VERSION));
268 /* Always try FirmwareA first. */
269 if (VERIFY_FIRMWARE_SUCCESS == VerifyFirmware(root_key_blob, firmwareA))
270 firmwareA_is_verified = 1;
271 if (firmwareA_is_verified && (stored_lversion < firmwareA_lversion)) {
272 /* Stored version may need to be updated but only if FirmwareB
273 * is successfully verified and has a logical version greater than
274 * the stored logical version. */
275 if (stored_lversion < firmwareB_lversion) {
276 if (VERIFY_FIRMWARE_SUCCESS == VerifyFirmware(root_key_blob, firmwareB)) {
277 WriteStoredVersion(FIRMWARE_KEY_VERSION,
278 (uint16_t) (min_lversion >> 16));
279 WriteStoredVersion(FIRMWARE_VERSION,
280 (uint16_t) (min_lversion & 0x00FFFF));
281 stored_lversion = min_lversion; /* Update stored version as it's used
282 * later. */
283 }
284 }
285 }
286 /* Lock Firmware TPM rollback indices from further writes. */
287 /* TODO(gauravsh): Figure out if these can be combined into one
288 * 32-bit location since we seem to always use them together. This can help
289 * us minimize the number of NVRAM writes/locks (which are limited over flash
290 * memory lifetimes.
291 */
292 LockStoredVersion(FIRMWARE_KEY_VERSION);
293 LockStoredVersion(FIRMWARE_VERSION);
294
295 /* Determine which firmware (if any) to jump to.
296 *
297 * We always attempt to jump to FirmwareA first. If verification of FirmwareA
298 * fails, we try FirmwareB. In all cases, if the firmware successfully
299 * verified but is a rollback, we jump to recovery.
300 *
301 * Note: This means that if FirmwareA verified successfully and is a
302 * rollback, then no attempt is made to check FirmwareB. We still jump to
303 * recovery. FirmwareB is only used as a backup in case FirmwareA gets
304 * corrupted. Since newer firmware updates are always written to A,
305 * the case where firmware A is verified but a rollback should not occur in
306 * normal operation.
307 */
308 if (firmwareA_is_verified) {
309 if (stored_lversion <= firmwareA_lversion)
310 return BOOT_FIRMWARE_A_CONTINUE;
311 } else {
312 /* If FirmwareA was not valid, then we skipped over the
313 * check to update the rollback indices and a Verify of FirmwareB wasn't
314 * attempted.
315 * If FirmwareB is not a rollback, then we attempt to do the verification.
316 */
317 if (stored_lversion <= firmwareB_lversion &&
318 (VERIFY_FIRMWARE_SUCCESS == VerifyFirmware(root_key_blob, firmwareB)))
319 return BOOT_FIRMWARE_B_CONTINUE;
320 }
321 /* D'oh: No bootable firmware. */
322 return BOOT_FIRMWARE_RECOVERY_CONTINUE;
323 }
OLDNEW
« no previous file with comments | « src/platform/vboot_reference/utils/firmware_image.c ('k') | src/platform/vboot_reference/utils/kernel_image.c » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698