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

Side by Side Diff: vfirmware/firmware_image.c

Issue 2835006: Remove old firmware verification code (Closed) Base URL: ssh://gitrw.chromium.org/vboot_reference.git
Patch Set: Created 10 years, 6 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
« no previous file with comments | « vfirmware/Makefile ('k') | vfirmware/include/firmware_image.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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 generating and manipulating a verified boot firmware image.
6 */
7
8 #include "firmware_image.h"
9
10 #include <sys/types.h>
11 #include <sys/stat.h>
12 #include <fcntl.h>
13 #include <unistd.h>
14
15 #include "cryptolib.h"
16 #include "file_keys.h"
17 #include "signature_digest.h"
18 #include "stateful_util.h"
19
20 /* Macro to determine the size of a field structure in the FirmwareImage
21 * structure. */
22 #define FIELD_LEN(field) (sizeof(((FirmwareImage*)0)->field))
23
24 FirmwareImage* FirmwareImageNew(void) {
25 FirmwareImage* image = (FirmwareImage*) Malloc(sizeof(FirmwareImage));
26 if (image) {
27 image->firmware_sign_key = NULL;
28 image->kernel_subkey_sign_key = NULL;
29 image->preamble_signature = NULL;
30 image->firmware_signature = NULL;
31 image->firmware_data = NULL;
32 }
33 return image;
34 }
35
36 void FirmwareImageFree(FirmwareImage* image) {
37 if (image) {
38 Free(image->firmware_sign_key);
39 Free(image->kernel_subkey_sign_key);
40 Free(image->preamble_signature);
41 Free(image->firmware_signature);
42 Free(image->firmware_data);
43 Free(image);
44 }
45 }
46
47 FirmwareImage* ReadFirmwareImage(const char* input_file) {
48 uint64_t file_size;
49 int image_len = 0; /* Total size of the firmware image. */
50 int header_len = 0;
51 int firmware_sign_key_len;
52 int signature_len;
53 uint8_t* firmware_buf;
54 uint8_t header_checksum[FIELD_LEN(header_checksum)];
55 MemcpyState st;
56 FirmwareImage* image = FirmwareImageNew();
57
58 if (!image)
59 return NULL;
60
61 firmware_buf = BufferFromFile(input_file, &file_size);
62 image_len = file_size;
63
64 st.remaining_len = image_len;
65 st.remaining_buf = firmware_buf;
66 st.overrun = 0;
67
68 /* Read and compare magic bytes. */
69 StatefulMemcpy(&st, &image->magic, FIRMWARE_MAGIC_SIZE);
70 if (SafeMemcmp(image->magic, FIRMWARE_MAGIC, FIRMWARE_MAGIC_SIZE)) {
71 debug("Wrong Firmware Magic.\n");
72 Free(firmware_buf);
73 return NULL;
74 }
75 StatefulMemcpy(&st, &image->header_len, FIELD_LEN(header_len));
76 StatefulMemcpy(&st, &image->firmware_sign_algorithm,
77 FIELD_LEN(firmware_sign_algorithm));
78
79 /* Valid Algorithm? */
80 if (image->firmware_sign_algorithm >= kNumAlgorithms) {
81 Free(firmware_buf);
82 return NULL;
83 }
84
85 /* Compute size of pre-processed RSA public key and signature. */
86 firmware_sign_key_len = RSAProcessedKeySize(image->firmware_sign_algorithm);
87 signature_len = siglen_map[image->firmware_sign_algorithm];
88
89 /* Check whether the header length is correct. */
90 header_len = GetFirmwareHeaderLen(image);
91 if (header_len != image->header_len) {
92 debug("Header length mismatch. Got: %d Expected: %d\n",
93 image->header_len, header_len);
94 Free(firmware_buf);
95 return NULL;
96 }
97
98 /* Read pre-processed public half of the sign key. */
99 StatefulMemcpy(&st, &image->firmware_key_version,
100 FIELD_LEN(firmware_key_version));
101 image->firmware_sign_key = (uint8_t*) Malloc(firmware_sign_key_len);
102 StatefulMemcpy(&st, image->firmware_sign_key, firmware_sign_key_len);
103 StatefulMemcpy(&st, image->header_checksum, FIELD_LEN(header_checksum));
104
105 /* Check whether the header checksum matches. */
106 CalculateFirmwareHeaderChecksum(image, header_checksum);
107 if (SafeMemcmp(header_checksum, image->header_checksum,
108 FIELD_LEN(header_checksum))) {
109 debug("Invalid firmware header checksum!\n");
110 Free(firmware_buf);
111 return NULL;
112 }
113
114 /* Read key signature. */
115 StatefulMemcpy(&st, image->firmware_key_signature,
116 FIELD_LEN(firmware_key_signature));
117
118 /* Read the firmware preamble. */
119 StatefulMemcpy(&st,&image->firmware_version, FIELD_LEN(firmware_version));
120 StatefulMemcpy(&st, &image->firmware_len, FIELD_LEN(firmware_len));
121 StatefulMemcpy(&st, &image->kernel_subkey_sign_algorithm,
122 FIELD_LEN(kernel_subkey_sign_algorithm));
123 StatefulMemcpy(&st, image->kernel_subkey_sign_key,
124 RSAProcessedKeySize(image->kernel_subkey_sign_algorithm));
125 StatefulMemcpy(&st, image->preamble, FIELD_LEN(preamble));
126
127 /* Read firmware preamble signature. */
128 image->preamble_signature = (uint8_t*) Malloc(signature_len);
129 StatefulMemcpy(&st, image->preamble_signature, signature_len);
130
131 image->firmware_signature = (uint8_t*) Malloc(signature_len);
132 StatefulMemcpy(&st, image->firmware_signature, signature_len);
133
134 image->firmware_data = (uint8_t*) Malloc(image->firmware_len);
135 StatefulMemcpy(&st, image->firmware_data, image->firmware_len);
136
137 if(st.overrun || st.remaining_len != 0) { /* Overrun or underrun. */
138 Free(firmware_buf);
139 return NULL;
140 }
141
142 Free(firmware_buf);
143 return image;
144 }
145
146 int GetFirmwareHeaderLen(const FirmwareImage* image) {
147 return (FIELD_LEN(header_len) + FIELD_LEN(firmware_sign_algorithm) +
148 RSAProcessedKeySize(image->firmware_sign_algorithm) +
149 FIELD_LEN(firmware_key_version) + FIELD_LEN(header_checksum));
150 }
151
152 void CalculateFirmwareHeaderChecksum(const FirmwareImage* image,
153 uint8_t* header_checksum) {
154 uint8_t* checksum;
155 DigestContext ctx;
156 DigestInit(&ctx, SHA512_DIGEST_ALGORITHM);
157 DigestUpdate(&ctx, (uint8_t*) &image->header_len,
158 sizeof(image->header_len));
159 DigestUpdate(&ctx, (uint8_t*) &image->firmware_sign_algorithm,
160 sizeof(image->firmware_sign_algorithm));
161 DigestUpdate(&ctx, (uint8_t*) &image->firmware_key_version,
162 sizeof(image->firmware_key_version));
163 DigestUpdate(&ctx, image->firmware_sign_key,
164 RSAProcessedKeySize(image->firmware_sign_algorithm));
165 checksum = DigestFinal(&ctx);
166 Memcpy(header_checksum, checksum, FIELD_LEN(header_checksum));
167 Free(checksum);
168 return;
169 }
170
171
172 uint8_t* GetFirmwareHeaderBlob(const FirmwareImage* image) {
173 uint8_t* header_blob = NULL;
174 MemcpyState st;
175
176 header_blob = (uint8_t*) Malloc(GetFirmwareHeaderLen(image));
177 st.remaining_len = GetFirmwareHeaderLen(image);
178 st.remaining_buf = header_blob;
179 st.overrun = 0;
180
181 StatefulMemcpy_r(&st, &image->header_len, FIELD_LEN(header_len));
182 StatefulMemcpy_r(&st, &image->firmware_sign_algorithm, FIELD_LEN(header_len));
183 StatefulMemcpy_r(&st, &image->firmware_key_version,
184 FIELD_LEN(firmware_key_version));
185 StatefulMemcpy_r(&st, image->firmware_sign_key,
186 RSAProcessedKeySize(image->firmware_sign_algorithm));
187 StatefulMemcpy_r(&st, &image->header_checksum, FIELD_LEN(header_checksum));
188
189 if (st.overrun || st.remaining_len != 0) { /* Underrun or Overrun. */
190 Free(header_blob);
191 return NULL;
192 }
193 return header_blob;
194 }
195
196
197 uint8_t* GetFirmwarePreambleBlob(const FirmwareImage* image) {
198 uint8_t* preamble_blob = NULL;
199 MemcpyState st;
200 uint64_t preamble_len = GetFirmwarePreambleLen(
201 image->kernel_subkey_sign_algorithm);
202
203 preamble_blob = (uint8_t*) Malloc(preamble_len);
204 st.remaining_len = preamble_len;
205 st.remaining_buf = preamble_blob;
206 st.overrun = 0;
207
208 StatefulMemcpy_r(&st, &image->firmware_version, FIELD_LEN(firmware_version));
209 StatefulMemcpy_r(&st, &image->firmware_len, FIELD_LEN(firmware_len));
210 StatefulMemcpy_r(&st, &image->kernel_subkey_sign_algorithm,
211 FIELD_LEN(kernel_subkey_sign_algorithm));
212 StatefulMemcpy_r(&st, image->kernel_subkey_sign_key,
213 RSAProcessedKeySize(image->kernel_subkey_sign_algorithm));
214 StatefulMemcpy_r(&st, image->preamble, FIELD_LEN(preamble));
215
216 if (st.overrun || st.remaining_len != 0 ) { /* Underrun or Overrun. */
217 Free(preamble_blob);
218 return NULL;
219 }
220 return preamble_blob;
221 }
222
223
224 uint8_t* GetFirmwareBlob(const FirmwareImage* image, uint64_t* blob_len) {
225 int firmware_signature_len;
226 uint8_t* firmware_blob = NULL;
227 uint8_t* header_blob = NULL;
228 uint8_t* preamble_blob = NULL;
229 MemcpyState st;
230
231 if (!image)
232 return NULL;
233
234 firmware_signature_len = siglen_map[image->firmware_sign_algorithm];
235 *blob_len = (FIELD_LEN(magic) +
236 GetFirmwareHeaderLen(image) +
237 FIELD_LEN(firmware_key_signature) +
238 GetFirmwarePreambleLen(image->kernel_subkey_sign_algorithm) +
239 2 * firmware_signature_len +
240 image->firmware_len);
241 firmware_blob = (uint8_t*) Malloc(*blob_len);
242 st.remaining_len = *blob_len;
243 st.remaining_buf = firmware_blob;
244 st.overrun = 0;
245
246 header_blob = GetFirmwareHeaderBlob(image);
247 preamble_blob = GetFirmwarePreambleBlob(image);
248
249 StatefulMemcpy_r(&st, image->magic, FIELD_LEN(magic));
250 StatefulMemcpy_r(&st, header_blob, GetFirmwareHeaderLen(image));
251 StatefulMemcpy_r(&st, image->firmware_key_signature,
252 FIELD_LEN(firmware_key_signature));
253 StatefulMemcpy_r(&st, preamble_blob,
254 GetFirmwarePreambleLen(image->kernel_subkey_sign_algorithm));
255 StatefulMemcpy_r(&st, image->preamble_signature, firmware_signature_len);
256 StatefulMemcpy_r(&st, image->firmware_signature, firmware_signature_len);
257 StatefulMemcpy_r(&st, image->firmware_data, image->firmware_len);
258
259 Free(preamble_blob);
260 Free(header_blob);
261
262 if (st.overrun || st.remaining_len != 0) { /* Underrun or Overrun. */
263 Free(firmware_blob);
264 return NULL;
265 }
266 return firmware_blob;
267 }
268
269 int WriteFirmwareImage(const char* output_file,
270 const FirmwareImage* image,
271 int is_only_vblock,
272 int is_subkey_out) {
273 int fd;
274 int success = 1;
275 uint8_t* firmware_blob;
276 uint8_t* subkey_out_buf = NULL;
277 uint8_t* subkey_header = NULL;
278 uint64_t blob_len;
279
280 if (!image)
281 return 0;
282 if (-1 == (fd = creat(output_file, 0666))) {
283 debug("Couldn't open file for writing.\n");
284 return 0;
285 }
286 if (is_subkey_out) {
287 blob_len = GetFirmwareHeaderLen(image) +
288 siglen_map[ROOT_SIGNATURE_ALGORITHM];
289 subkey_out_buf = (uint8_t*) Malloc(blob_len);
290 subkey_header = GetFirmwareHeaderBlob(image);
291 Memcpy(subkey_out_buf, subkey_header, GetFirmwareHeaderLen(image));
292 Memcpy(subkey_out_buf + GetFirmwareHeaderLen(image),
293 image->firmware_key_signature,
294 siglen_map[ROOT_SIGNATURE_ALGORITHM]);
295 if (blob_len != write(fd, subkey_out_buf, blob_len)) {
296 debug("Couldn't write kernel subkey header to file: %s\n",
297 output_file);
298 success = 0;
299 }
300 Free(subkey_header);
301 Free(subkey_out_buf);
302 close(fd);
303 return success;
304 }
305
306 firmware_blob = GetFirmwareBlob(image, &blob_len);
307 if (!firmware_blob) {
308 debug("Couldn't create firmware blob from FirmwareImage.\n");
309 return 0;
310 }
311 if (!is_only_vblock) {
312 if (blob_len != write(fd, firmware_blob, blob_len)) {
313 debug("Couldn't write Firmware Image to file: %s\n", output_file);
314 success = 0;
315 }
316 } else {
317 /* Exclude the firmware_data. */
318 int vblock_len = blob_len - image->firmware_len;
319 if (vblock_len != write(fd, firmware_blob, vblock_len)) {
320 debug("Couldn't write Firmware Image verifcation block to file: %s\n",
321 output_file);
322 success = 0;
323 }
324 }
325 Free(firmware_blob);
326 close(fd);
327 return success;
328 }
329
330 void PrintFirmwareImage(const FirmwareImage* image) {
331 if (!image)
332 return;
333
334 /* Print header. */
335 debug("Header Length = %d\n"
336 "Firmware Signature Algorithm = %s\n"
337 "Firmware Key Version = %d\n\n",
338 image->header_len,
339 algo_strings[image->firmware_sign_algorithm],
340 image->firmware_key_version);
341 /* TODO(gauravsh): Output hash and key signature here? */
342 /* Print preamble. */
343 debug("Firmware Version = %d\n"
344 "Firmware Length = %" PRIu64 "\n\n",
345 image->firmware_version,
346 image->firmware_len);
347 /* Output key signature here? */
348 }
349
350 int VerifyFirmwareImage(const RSAPublicKey* root_key,
351 const FirmwareImage* image) {
352 RSAPublicKey* firmware_sign_key = NULL;
353 uint8_t* header_digest = NULL;
354 uint8_t* preamble_digest = NULL;
355 uint8_t* firmware_digest = NULL;
356 int firmware_sign_key_size;
357 int signature_size;
358 int error_code = 0;
359 DigestContext ctx;
360 DigestContext firmware_ctx;
361
362 if (!image)
363 return VERIFY_FIRMWARE_INVALID_IMAGE;
364
365 /* Verify root key signature on the sign key header if we
366 * are not in dev mode.
367 *
368 * TODO(gauravsh): Add additional sanity checks here for:
369 * 1) verifying the header length is correct.
370 * 2) header_checksum is correct.
371 */
372
373 /* Check key signature. */
374 DigestInit(&ctx, ROOT_SIGNATURE_ALGORITHM);
375 DigestUpdate(&ctx, (uint8_t*) &image->header_len,
376 FIELD_LEN(header_len));
377 DigestUpdate(&ctx, (uint8_t*) &image->firmware_sign_algorithm,
378 FIELD_LEN(firmware_sign_algorithm));
379 DigestUpdate(&ctx, (uint8_t*) &image->firmware_key_version,
380 FIELD_LEN(firmware_key_version));
381 DigestUpdate(&ctx, image->firmware_sign_key,
382 RSAProcessedKeySize(image->firmware_sign_algorithm));
383 DigestUpdate(&ctx, image->header_checksum,
384 FIELD_LEN(header_checksum));
385 header_digest = DigestFinal(&ctx);
386 if (!RSAVerify(root_key, image->firmware_key_signature,
387 FIELD_LEN(firmware_key_signature),
388 ROOT_SIGNATURE_ALGORITHM,
389 header_digest)) {
390 error_code = VERIFY_FIRMWARE_ROOT_SIGNATURE_FAILED;
391 goto verify_failure;
392 }
393
394 /* Get sign key to verify the rest of the firmware. */
395 firmware_sign_key_size = RSAProcessedKeySize(image->firmware_sign_algorithm);
396 firmware_sign_key = RSAPublicKeyFromBuf(image->firmware_sign_key,
397 firmware_sign_key_size);
398 signature_size = siglen_map[image->firmware_sign_algorithm];
399
400 if (image->firmware_sign_algorithm >= kNumAlgorithms)
401 return VERIFY_FIRMWARE_INVALID_ALGORITHM;
402
403 /* Verify firmware preamble signature. */
404 DigestInit(&ctx, image->firmware_sign_algorithm);
405 DigestUpdate(&ctx, (uint8_t*) &image->firmware_version,
406 FIELD_LEN(firmware_version));
407 DigestUpdate(&ctx, (uint8_t*) &image->firmware_len,
408 FIELD_LEN(firmware_len));
409 DigestUpdate(&ctx, (uint8_t*) &image->kernel_subkey_sign_algorithm,
410 FIELD_LEN(kernel_subkey_sign_algorithm));
411 DigestUpdate(&ctx, (uint8_t*) image->kernel_subkey_sign_key,
412 RSAProcessedKeySize(image->kernel_subkey_sign_algorithm));
413 DigestUpdate(&ctx, (uint8_t*) &image->preamble,
414 FIELD_LEN(preamble));
415 preamble_digest = DigestFinal(&ctx);
416 if (!RSAVerify(firmware_sign_key, image->preamble_signature,
417 signature_size, image->firmware_sign_algorithm,
418 preamble_digest)) {
419 error_code = VERIFY_FIRMWARE_PREAMBLE_SIGNATURE_FAILED;
420 goto verify_failure;
421 }
422
423 /* Verify firmware signature - firmware signature is on the contents
424 of firmware preamble + firmware_data. */
425 DigestInit(&firmware_ctx, image->firmware_sign_algorithm);
426 DigestUpdate(&firmware_ctx, (uint8_t*) &image->firmware_version,
427 FIELD_LEN(firmware_version));
428 DigestUpdate(&firmware_ctx, (uint8_t*) &image->firmware_len,
429 FIELD_LEN(firmware_len));
430 DigestUpdate(&firmware_ctx, (uint8_t*) &image->kernel_subkey_sign_algorithm,
431 FIELD_LEN(kernel_subkey_sign_algorithm));
432 DigestUpdate(&firmware_ctx, (uint8_t*) image->kernel_subkey_sign_key,
433 RSAProcessedKeySize(image->kernel_subkey_sign_algorithm));
434 DigestUpdate(&firmware_ctx, (uint8_t*) &image->preamble,
435 FIELD_LEN(preamble));
436 DigestUpdate(&firmware_ctx, image->firmware_data, image->firmware_len);
437 firmware_digest = DigestFinal(&firmware_ctx);
438 if (!RSAVerify(firmware_sign_key, image->firmware_signature,
439 signature_size, image->firmware_sign_algorithm,
440 firmware_digest)) {
441 error_code = VERIFY_FIRMWARE_SIGNATURE_FAILED;
442 goto verify_failure;
443 }
444
445 verify_failure:
446 RSAPublicKeyFree(firmware_sign_key);
447 Free(firmware_digest);
448 Free(preamble_digest);
449 Free(header_digest);
450 return error_code;
451 }
452
453 const char* VerifyFirmwareErrorString(int error) {
454 return kVerifyFirmwareErrors[error];
455 }
456
457 int AddFirmwareKeySignature(FirmwareImage* image, const char* root_key_file) {
458 uint8_t* header_blob = NULL;
459 uint8_t* signature;
460 if (!image || !root_key_file)
461 return 0;
462 header_blob = GetFirmwareHeaderBlob(image);
463 if (!header_blob)
464 return 0;
465 if (!(signature = SignatureBuf(header_blob,
466 GetFirmwareHeaderLen(image),
467 root_key_file,
468 ROOT_SIGNATURE_ALGORITHM))) {
469 Free(header_blob);
470 return 0;
471 }
472 Memcpy(image->firmware_key_signature, signature, RSA8192NUMBYTES);
473 Free(header_blob);
474 Free(signature);
475 return 1;
476 }
477
478 int AddFirmwareSignature(FirmwareImage* image, const char* signing_key_file) {
479 uint8_t* preamble_blob = NULL;
480 uint8_t* preamble_signature = NULL;
481 uint8_t* firmware_signature = NULL;
482 uint8_t* firmware_buf = NULL;
483 int signature_len = siglen_map[image->firmware_sign_algorithm];
484 uint64_t preamble_len = GetFirmwarePreambleLen(
485 image->kernel_subkey_sign_algorithm);
486
487 preamble_blob = GetFirmwarePreambleBlob(image);
488 if (!preamble_blob)
489 return 0;
490 if (!(preamble_signature = SignatureBuf(preamble_blob,
491 preamble_len,
492 signing_key_file,
493 image->firmware_sign_algorithm))) {
494 Free(preamble_blob);
495 return 0;
496 }
497 image->preamble_signature = (uint8_t*) Malloc(signature_len);
498 Memcpy(image->preamble_signature, preamble_signature, signature_len);
499 Free(preamble_signature);
500 /* Firmware signature must be calculated on preamble + firmware_data
501 * to avoid splicing attacks. */
502 firmware_buf = (uint8_t*) Malloc(preamble_len +
503 image->firmware_len);
504 Memcpy(firmware_buf, preamble_blob, preamble_len);
505 Memcpy(firmware_buf + preamble_len, image->firmware_data,
506 image->firmware_len);
507 if (!(firmware_signature = SignatureBuf(firmware_buf,
508 preamble_len +
509 image->firmware_len,
510 signing_key_file,
511 image->firmware_sign_algorithm))) {
512 Free(preamble_blob);
513 Free(firmware_buf);
514 return 0;
515 }
516 image->firmware_signature = (uint8_t*) Malloc(signature_len);
517 Memcpy(image->firmware_signature, firmware_signature, signature_len);
518 Free(firmware_signature);
519 Free(firmware_buf);
520 Free(preamble_blob);
521 return 1;
522 }
OLDNEW
« no previous file with comments | « vfirmware/Makefile ('k') | vfirmware/include/firmware_image.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698