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

Side by Side Diff: src/platform/vboot_reference/vkernel/kernel_image.c

Issue 2292001: Make kernel signature a part of the kernel preamble. (Closed) Base URL: ssh://git@gitrw.chromium.org/chromiumos
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 | « src/platform/vboot_reference/vboot_firmware/linktest/main.c ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 /* Copyright (c) 2010 The Chromium OS Authors. All rights reserved. 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 2 * Use of this source code is governed by a BSD-style license that can be
3 * found in the LICENSE file. 3 * found in the LICENSE file.
4 * 4 *
5 * Functions for generating and manipulating a verified boot kernel image. 5 * Functions for generating and manipulating a verified boot kernel image.
6 * (Userland portion) 6 * (Userland portion)
7 */ 7 */
8 8
9 #include "kernel_image.h" 9 #include "kernel_image.h"
10 10
(...skipping 204 matching lines...) Expand 10 before | Expand all | Expand 10 after
215 Free(header_blob); 215 Free(header_blob);
216 return NULL; 216 return NULL;
217 } 217 }
218 return header_blob; 218 return header_blob;
219 } 219 }
220 220
221 uint8_t* GetKernelPreambleBlob(const KernelImage* image) { 221 uint8_t* GetKernelPreambleBlob(const KernelImage* image) {
222 uint8_t* preamble_blob = NULL; 222 uint8_t* preamble_blob = NULL;
223 MemcpyState st; 223 MemcpyState st;
224 224
225 preamble_blob = (uint8_t*) Malloc(GetKernelPreambleLen()); 225 preamble_blob = (uint8_t*) Malloc(
226 st.remaining_len = GetKernelPreambleLen(); 226 GetKernelPreambleLen(image->kernel_sign_algorithm));
227 st.remaining_len = GetKernelPreambleLen(image->kernel_sign_algorithm);
227 st.remaining_buf = preamble_blob; 228 st.remaining_buf = preamble_blob;
228 st.overrun = 0; 229 st.overrun = 0;
229 230
230 StatefulMemcpy_r(&st, &image->kernel_version, FIELD_LEN(kernel_version)); 231 StatefulMemcpy_r(&st, &image->kernel_version, FIELD_LEN(kernel_version));
231 StatefulMemcpy_r(&st, &image->kernel_len, FIELD_LEN(kernel_len)); 232 StatefulMemcpy_r(&st, &image->kernel_len, FIELD_LEN(kernel_len));
232 StatefulMemcpy_r(&st, &image->bootloader_offset, FIELD_LEN(bootloader_offset)) ; 233 StatefulMemcpy_r(&st, &image->bootloader_offset, FIELD_LEN(bootloader_offset)) ;
233 StatefulMemcpy_r(&st, &image->bootloader_size, FIELD_LEN(bootloader_size)); 234 StatefulMemcpy_r(&st, &image->bootloader_size, FIELD_LEN(bootloader_size));
234 StatefulMemcpy_r(&st, &image->padded_header_size, 235 StatefulMemcpy_r(&st, &image->padded_header_size,
235 FIELD_LEN(padded_header_size)); 236 FIELD_LEN(padded_header_size));
237 StatefulMemcpy_r(&st, image->kernel_signature,
238 siglen_map[image->kernel_sign_algorithm]);
236 239
237 if (st.overrun || st.remaining_len != 0) { /* Overrun or Underrun. */ 240 if (st.overrun || st.remaining_len != 0) { /* Overrun or Underrun. */
238 Free(preamble_blob); 241 Free(preamble_blob);
239 return NULL; 242 return NULL;
240 } 243 }
241 return preamble_blob; 244 return preamble_blob;
242 } 245 }
243 246
244 uint8_t* GetKernelBlob(const KernelImage* image, uint64_t* blob_len) { 247 uint8_t* GetKernelBlob(const KernelImage* image, uint64_t* blob_len) {
245 int kernel_key_signature_len; 248 int kernel_key_signature_len;
246 int kernel_signature_len; 249 int kernel_signature_len;
247 uint8_t* kernel_blob = NULL; 250 uint8_t* kernel_blob = NULL;
248 uint8_t* header_blob = NULL; 251 uint8_t* header_blob = NULL;
249 MemcpyState st; 252 MemcpyState st;
250 253
251 if (!image) 254 if (!image)
252 return NULL; 255 return NULL;
253 kernel_key_signature_len = siglen_map[image->firmware_sign_algorithm]; 256 kernel_key_signature_len = siglen_map[image->firmware_sign_algorithm];
254 kernel_signature_len = siglen_map[image->kernel_sign_algorithm]; 257 kernel_signature_len = siglen_map[image->kernel_sign_algorithm];
255 *blob_len = (FIELD_LEN(magic) + 258 *blob_len = (FIELD_LEN(magic) +
256 GetKernelHeaderLen(image) + 259 GetKernelHeaderLen(image) +
257 kernel_key_signature_len + 260 kernel_key_signature_len +
258 GetKernelPreambleLen() + 261 GetKernelPreambleLen(image->kernel_sign_algorithm) +
259 2 * kernel_signature_len + 262 kernel_signature_len +
260 image->kernel_len); 263 image->kernel_len);
261 kernel_blob = (uint8_t*) Malloc(*blob_len); 264 kernel_blob = (uint8_t*) Malloc(*blob_len);
262 st.remaining_len = *blob_len; 265 st.remaining_len = *blob_len;
263 st.remaining_buf = kernel_blob; 266 st.remaining_buf = kernel_blob;
264 st.overrun = 0; 267 st.overrun = 0;
265 268
266 header_blob = GetKernelHeaderBlob(image); 269 header_blob = GetKernelHeaderBlob(image);
267 270
268 StatefulMemcpy_r(&st, image->magic, FIELD_LEN(magic)); 271 StatefulMemcpy_r(&st, image->magic, FIELD_LEN(magic));
269 StatefulMemcpy_r(&st, header_blob, GetKernelHeaderLen(image)); 272 StatefulMemcpy_r(&st, header_blob, GetKernelHeaderLen(image));
270 StatefulMemcpy_r(&st, image->kernel_key_signature, kernel_key_signature_len); 273 StatefulMemcpy_r(&st, image->kernel_key_signature, kernel_key_signature_len);
271 /* Copy over kernel preamble blob (including signatures.) */ 274 /* Copy over kernel preamble blob (including signatures.) */
272 StatefulMemcpy_r(&st, &image->kernel_version, FIELD_LEN(kernel_version)); 275 StatefulMemcpy_r(&st, &image->kernel_version, FIELD_LEN(kernel_version));
273 StatefulMemcpy_r(&st, &image->kernel_len, FIELD_LEN(kernel_len)); 276 StatefulMemcpy_r(&st, &image->kernel_len, FIELD_LEN(kernel_len));
274 StatefulMemcpy_r(&st, &image->bootloader_offset, 277 StatefulMemcpy_r(&st, &image->bootloader_offset,
275 FIELD_LEN(bootloader_offset)); 278 FIELD_LEN(bootloader_offset));
276 StatefulMemcpy_r(&st, &image->bootloader_size, FIELD_LEN(bootloader_size)); 279 StatefulMemcpy_r(&st, &image->bootloader_size, FIELD_LEN(bootloader_size));
277 StatefulMemcpy_r(&st, &image->padded_header_size, 280 StatefulMemcpy_r(&st, &image->padded_header_size,
278 FIELD_LEN(padded_header_size)); 281 FIELD_LEN(padded_header_size));
282 StatefulMemcpy_r(&st, image->kernel_signature, kernel_signature_len);
279 StatefulMemcpy_r(&st, image->preamble_signature, kernel_signature_len); 283 StatefulMemcpy_r(&st, image->preamble_signature, kernel_signature_len);
280 StatefulMemcpy_r(&st, image->kernel_signature, kernel_signature_len);
281 StatefulMemcpy_r(&st, image->kernel_data, image->kernel_len); 284 StatefulMemcpy_r(&st, image->kernel_data, image->kernel_len);
282 285
283 Free(header_blob); 286 Free(header_blob);
284 287
285 if (st.overrun || st.remaining_len != 0) { /* Underrun or Overrun. */ 288 if (st.overrun || st.remaining_len != 0) { /* Underrun or Overrun. */
289 debug("GetKernelBlob() failed.\n");
286 Free(kernel_blob); 290 Free(kernel_blob);
287 return NULL; 291 return NULL;
288 } 292 }
289 return kernel_blob; 293 return kernel_blob;
290 } 294 }
291 295
292 int WriteKernelImage(const char* input_file, 296 int WriteKernelImage(const char* input_file,
293 const KernelImage* image, 297 const KernelImage* image,
294 int is_only_vblock) { 298 int is_only_vblock) {
295 int fd; 299 int fd;
(...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after
364 const KernelImage* image, 368 const KernelImage* image,
365 const int dev_mode) { 369 const int dev_mode) {
366 RSAPublicKey* kernel_sign_key = NULL; 370 RSAPublicKey* kernel_sign_key = NULL;
367 uint8_t* header_digest = NULL; 371 uint8_t* header_digest = NULL;
368 uint8_t* preamble_digest = NULL; 372 uint8_t* preamble_digest = NULL;
369 uint8_t* kernel_digest = NULL; 373 uint8_t* kernel_digest = NULL;
370 int kernel_sign_key_size; 374 int kernel_sign_key_size;
371 int kernel_signature_size; 375 int kernel_signature_size;
372 int error_code = 0; 376 int error_code = 0;
373 DigestContext ctx; 377 DigestContext ctx;
374 DigestContext kernel_ctx;
375 if (!image) 378 if (!image)
376 return VERIFY_KERNEL_INVALID_IMAGE; 379 return VERIFY_KERNEL_INVALID_IMAGE;
377 380
378 /* Verify kernel key signature on the key header if we 381 /* Verify kernel key signature on the key header if we
379 * are not in dev mode. 382 * are not in dev mode.
380 * 383 *
381 * TODO(gauravsh): Add additional sanity checks here for: 384 * TODO(gauravsh): Add additional sanity checks here for:
382 * 1) verifying the header length is correct. 385 * 1) verifying the header length is correct.
383 * 2) header_checksum is correct. 386 * 2) header_checksum is correct.
384 */ 387 */
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after
426 DigestUpdate(&ctx, (uint8_t*) &image->kernel_version, 429 DigestUpdate(&ctx, (uint8_t*) &image->kernel_version,
427 FIELD_LEN(kernel_version)); 430 FIELD_LEN(kernel_version));
428 DigestUpdate(&ctx, (uint8_t*) &image->kernel_len, 431 DigestUpdate(&ctx, (uint8_t*) &image->kernel_len,
429 FIELD_LEN(kernel_len)); 432 FIELD_LEN(kernel_len));
430 DigestUpdate(&ctx, (uint8_t*) &image->bootloader_offset, 433 DigestUpdate(&ctx, (uint8_t*) &image->bootloader_offset,
431 FIELD_LEN(bootloader_offset)); 434 FIELD_LEN(bootloader_offset));
432 DigestUpdate(&ctx, (uint8_t*) &image->bootloader_size, 435 DigestUpdate(&ctx, (uint8_t*) &image->bootloader_size,
433 FIELD_LEN(bootloader_size)); 436 FIELD_LEN(bootloader_size));
434 DigestUpdate(&ctx, (uint8_t*) &image->padded_header_size, 437 DigestUpdate(&ctx, (uint8_t*) &image->padded_header_size,
435 FIELD_LEN(padded_header_size)); 438 FIELD_LEN(padded_header_size));
439 DigestUpdate(&ctx, (uint8_t*) image->kernel_signature,
440 kernel_signature_size);
436 preamble_digest = DigestFinal(&ctx); 441 preamble_digest = DigestFinal(&ctx);
437 if (!RSAVerify(kernel_sign_key, image->preamble_signature, 442 if (!RSAVerify(kernel_sign_key, image->preamble_signature,
438 kernel_signature_size, image->kernel_sign_algorithm, 443 kernel_signature_size, image->kernel_sign_algorithm,
439 preamble_digest)) { 444 preamble_digest)) {
440 error_code = VERIFY_KERNEL_PREAMBLE_SIGNATURE_FAILED; 445 error_code = VERIFY_KERNEL_PREAMBLE_SIGNATURE_FAILED;
441 goto verify_failure; 446 goto verify_failure;
442 } 447 }
443 448
444 /* Verify kernel signature - kernel signature is computed on the contents 449 /* Verify kernel signature - kernel signature is computed on the contents
445 of kernel version + kernel options + kernel_data. */ 450 * of kernel_data.
446 DigestInit(&kernel_ctx, image->kernel_sign_algorithm); 451 * Association between the kernel_data and preamble is maintained by making
447 DigestUpdate(&kernel_ctx, (uint8_t*) &image->kernel_version, 452 * the kernel signature a part of the preamble and verifying it as part
448 FIELD_LEN(kernel_version)); 453 * of preamble signature checking. */
449 DigestUpdate(&kernel_ctx, (uint8_t*) &image->kernel_len, 454
450 FIELD_LEN(kernel_len)); 455 kernel_digest = DigestBuf(image->kernel_data,
451 DigestUpdate(&kernel_ctx, (uint8_t*) &image->bootloader_offset, 456 image->kernel_len,
452 FIELD_LEN(bootloader_offset)); 457 image->kernel_sign_algorithm);
453 DigestUpdate(&kernel_ctx, (uint8_t*) &image->bootloader_size,
454 FIELD_LEN(bootloader_size));
455 DigestUpdate(&kernel_ctx, (uint8_t*) &image->padded_header_size,
456 FIELD_LEN(padded_header_size));
457 DigestUpdate(&kernel_ctx, (uint8_t*) image->kernel_data,
458 image->kernel_len);
459 kernel_digest = DigestFinal(&kernel_ctx);
460 if (!RSAVerify(kernel_sign_key, image->kernel_signature, 458 if (!RSAVerify(kernel_sign_key, image->kernel_signature,
461 kernel_signature_size, image->kernel_sign_algorithm, 459 kernel_signature_size, image->kernel_sign_algorithm,
462 kernel_digest)) { 460 kernel_digest)) {
463 error_code = VERIFY_KERNEL_SIGNATURE_FAILED; 461 error_code = VERIFY_KERNEL_SIGNATURE_FAILED;
464 goto verify_failure; 462 goto verify_failure;
465 } 463 }
466 464
467 verify_failure: 465 verify_failure:
468 RSAPublicKeyFree(kernel_sign_key); 466 RSAPublicKeyFree(kernel_sign_key);
469 Free(kernel_digest); 467 Free(kernel_digest);
(...skipping 28 matching lines...) Expand all
498 Free(header_blob); 496 Free(header_blob);
499 return 1; 497 return 1;
500 } 498 }
501 499
502 int AddKernelSignature(KernelImage* image, 500 int AddKernelSignature(KernelImage* image,
503 const char* kernel_signing_key_file) { 501 const char* kernel_signing_key_file) {
504 uint8_t* preamble_blob = NULL; 502 uint8_t* preamble_blob = NULL;
505 uint8_t* preamble_signature = NULL; 503 uint8_t* preamble_signature = NULL;
506 uint8_t* kernel_signature = NULL; 504 uint8_t* kernel_signature = NULL;
507 uint8_t* kernel_buf; 505 uint8_t* kernel_buf;
508 int signature_len = siglen_map[image->kernel_sign_algorithm]; 506 int algorithm = image->kernel_sign_algorithm;
507 int signature_len = siglen_map[algorithm];
509 508
510 preamble_blob = GetKernelPreambleBlob(image); 509 /* Kernel signature must be calculated first as its used for computing the
511 if (!(preamble_signature = SignatureBuf(preamble_blob, 510 * preamble signature. */
512 GetKernelPreambleLen(), 511 kernel_buf = (uint8_t*) Malloc(image->kernel_len);
513 kernel_signing_key_file, 512 Memcpy(kernel_buf, image->kernel_data, image->kernel_len);
514 image->kernel_sign_algorithm))) {
515 debug("Could not compute signature on the kernel preamble.\n");
516 Free(preamble_blob);
517 return 0;
518 }
519
520 image->preamble_signature = (uint8_t*) Malloc(signature_len);
521 Memcpy(image->preamble_signature, preamble_signature, signature_len);
522 Free(preamble_signature);
523 /* Kernel signature muse be calculated on the kernel version, options and
524 * kernel data to avoid splicing attacks. */
525 kernel_buf = (uint8_t*) Malloc(GetKernelPreambleLen() +
526 image->kernel_len);
527 Memcpy(kernel_buf, preamble_blob, GetKernelPreambleLen());
528 Memcpy(kernel_buf + GetKernelPreambleLen(), image->kernel_data,
529 image->kernel_len);
530 if (!(kernel_signature = SignatureBuf(kernel_buf, 513 if (!(kernel_signature = SignatureBuf(kernel_buf,
531 GetKernelPreambleLen() +
532 image->kernel_len, 514 image->kernel_len,
533 kernel_signing_key_file, 515 kernel_signing_key_file,
534 image->kernel_sign_algorithm))) { 516 algorithm))) {
535 Free(preamble_blob); 517 Free(preamble_blob);
536 Free(kernel_buf); 518 Free(kernel_buf);
537 debug("Could not compute signature on the kernel.\n"); 519 debug("Could not compute signature on the kernel.\n");
538 return 0; 520 return 0;
539 } 521 }
540 image->kernel_signature = (uint8_t*) Malloc(signature_len); 522 image->kernel_signature = (uint8_t*) Malloc(signature_len);
541 Memcpy(image->kernel_signature, kernel_signature, signature_len); 523 Memcpy(image->kernel_signature, kernel_signature, signature_len);
524
525
526 preamble_blob = GetKernelPreambleBlob(image);
527 if (!(preamble_signature = SignatureBuf(preamble_blob,
528 GetKernelPreambleLen(algorithm),
529 kernel_signing_key_file,
530 algorithm))) {
531 debug("Could not compute signature on the kernel preamble.\n");
532 Free(preamble_blob);
533 return 0;
534 }
535 image->preamble_signature = (uint8_t*) Malloc(signature_len);
536 Memcpy(image->preamble_signature, preamble_signature, signature_len);
537
538 Free(preamble_signature);
539 Free(preamble_blob);
542 Free(kernel_signature); 540 Free(kernel_signature);
543 Free(kernel_buf); 541 Free(kernel_buf);
544 Free(preamble_blob);
545 return 1; 542 return 1;
546 } 543 }
547 544
548 void PrintKernelEntry(kernel_entry* entry) { 545 void PrintKernelEntry(kernel_entry* entry) {
549 debug("Boot Priority = %d\n", entry->boot_priority); 546 debug("Boot Priority = %d\n", entry->boot_priority);
550 debug("Boot Tries Remaining = %d\n", entry->boot_tries_remaining); 547 debug("Boot Tries Remaining = %d\n", entry->boot_tries_remaining);
551 debug("Boot Success Flag = %d\n", entry->boot_success_flag); 548 debug("Boot Success Flag = %d\n", entry->boot_success_flag);
552 } 549 }
OLDNEW
« no previous file with comments | « src/platform/vboot_reference/vboot_firmware/linktest/main.c ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698