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

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

Issue 874006: Add a command line string field to verified boot kernel config image. (Closed)
Patch Set: Created 10 years, 9 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/utils/firmware_image.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 */ 6 */
7 7
8 #include "kernel_image.h" 8 #include "kernel_image.h"
9 9
10 #include <fcntl.h> 10 #include <fcntl.h>
(...skipping 114 matching lines...) Expand 10 before | Expand all | Expand 10 after
125 StatefulMemcpy(&st, image->header_checksum, FIELD_LEN(header_checksum)); 125 StatefulMemcpy(&st, image->header_checksum, FIELD_LEN(header_checksum));
126 126
127 /* Read key signature. */ 127 /* Read key signature. */
128 image->kernel_key_signature = (uint8_t*) Malloc(kernel_key_signature_len); 128 image->kernel_key_signature = (uint8_t*) Malloc(kernel_key_signature_len);
129 StatefulMemcpy(&st, image->kernel_key_signature, 129 StatefulMemcpy(&st, image->kernel_key_signature,
130 kernel_key_signature_len); 130 kernel_key_signature_len);
131 131
132 /* Read the kernel config. */ 132 /* Read the kernel config. */
133 StatefulMemcpy(&st, &image->kernel_version, FIELD_LEN(kernel_version)); 133 StatefulMemcpy(&st, &image->kernel_version, FIELD_LEN(kernel_version));
134 StatefulMemcpy(&st, &image->options.version, FIELD_LEN(options.version)); 134 StatefulMemcpy(&st, &image->options.version, FIELD_LEN(options.version));
135 StatefulMemcpy(&st, &image->options.cmd_line, FIELD_LEN(options.cmd_line));
135 StatefulMemcpy(&st, &image->options.kernel_len, 136 StatefulMemcpy(&st, &image->options.kernel_len,
136 FIELD_LEN(options.kernel_len)); 137 FIELD_LEN(options.kernel_len));
137 StatefulMemcpy(&st, &image->options.kernel_load_addr, 138 StatefulMemcpy(&st, &image->options.kernel_load_addr,
138 FIELD_LEN(options.kernel_load_addr)); 139 FIELD_LEN(options.kernel_load_addr));
139 StatefulMemcpy(&st, &image->options.kernel_entry_addr, 140 StatefulMemcpy(&st, &image->options.kernel_entry_addr,
140 FIELD_LEN(options.kernel_entry_addr)); 141 FIELD_LEN(options.kernel_entry_addr));
141 142
142 /* Read kernel config signature. */ 143 /* Read kernel config signature. */
143 image->config_signature = (uint8_t*) Malloc(kernel_signature_len); 144 image->config_signature = (uint8_t*) Malloc(kernel_signature_len);
144 StatefulMemcpy(&st, image->config_signature, kernel_signature_len); 145 StatefulMemcpy(&st, image->config_signature, kernel_signature_len);
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after
186 StatefulMemcpy_r(&st, &image->header_checksum, FIELD_LEN(header_checksum)); 187 StatefulMemcpy_r(&st, &image->header_checksum, FIELD_LEN(header_checksum));
187 188
188 if (st.remaining_len != 0) { /* Underrun or Overrun. */ 189 if (st.remaining_len != 0) { /* Underrun or Overrun. */
189 Free(header_blob); 190 Free(header_blob);
190 return NULL; 191 return NULL;
191 } 192 }
192 return header_blob; 193 return header_blob;
193 } 194 }
194 195
195 int GetKernelConfigLen(const KernelImage* image) { 196 int GetKernelConfigLen(const KernelImage* image) {
196 return (FIELD_LEN(kernel_version) + FIELD_LEN(options.version) + 197 return (FIELD_LEN(kernel_version) +
198 FIELD_LEN(options.version) + FIELD_LEN(options.cmd_line) +
197 FIELD_LEN(options.kernel_len) + FIELD_LEN(options.kernel_load_addr) + 199 FIELD_LEN(options.kernel_len) + FIELD_LEN(options.kernel_load_addr) +
198 FIELD_LEN(options.kernel_entry_addr)); 200 FIELD_LEN(options.kernel_entry_addr));
199 } 201 }
200 202
201 uint8_t* GetKernelConfigBlob(const KernelImage* image) { 203 uint8_t* GetKernelConfigBlob(const KernelImage* image) {
202 uint8_t* config_blob = NULL; 204 uint8_t* config_blob = NULL;
203 MemcpyState st; 205 MemcpyState st;
204 206
205 config_blob = (uint8_t*) Malloc(GetKernelConfigLen(image)); 207 config_blob = (uint8_t*) Malloc(GetKernelConfigLen(image));
206 st.remaining_len = GetKernelConfigLen(image); 208 st.remaining_len = GetKernelConfigLen(image);
207 st.remaining_buf = config_blob; 209 st.remaining_buf = config_blob;
208 210
209 StatefulMemcpy_r(&st, &image->kernel_version, FIELD_LEN(kernel_version)); 211 StatefulMemcpy_r(&st, &image->kernel_version, FIELD_LEN(kernel_version));
210 StatefulMemcpy_r(&st, image->options.version, FIELD_LEN(options.version)); 212 StatefulMemcpy_r(&st, image->options.version, FIELD_LEN(options.version));
213 StatefulMemcpy_r(&st, image->options.cmd_line, FIELD_LEN(options.cmd_line));
211 StatefulMemcpy_r(&st, &image->options.kernel_len, 214 StatefulMemcpy_r(&st, &image->options.kernel_len,
212 FIELD_LEN(options.kernel_len)); 215 FIELD_LEN(options.kernel_len));
213 StatefulMemcpy_r(&st, &image->options.kernel_load_addr, 216 StatefulMemcpy_r(&st, &image->options.kernel_load_addr,
214 FIELD_LEN(options.kernel_load_addr)); 217 FIELD_LEN(options.kernel_load_addr));
215 StatefulMemcpy_r(&st, &image->options.kernel_entry_addr, 218 StatefulMemcpy_r(&st, &image->options.kernel_entry_addr,
216 FIELD_LEN(options.kernel_entry_addr)); 219 FIELD_LEN(options.kernel_entry_addr));
217 if (st.remaining_len != 0) { /* Overrun or Underrun. */ 220 if (st.remaining_len != 0) { /* Overrun or Underrun. */
218 Free(config_blob); 221 Free(config_blob);
219 return NULL; 222 return NULL;
220 } 223 }
(...skipping 86 matching lines...) Expand 10 before | Expand all | Expand 10 after
307 "Kernel Key Version = %d\n\n", 310 "Kernel Key Version = %d\n\n",
308 image->header_len, 311 image->header_len,
309 image->firmware_sign_algorithm, 312 image->firmware_sign_algorithm,
310 image->kernel_sign_algorithm, 313 image->kernel_sign_algorithm,
311 algo_strings[image->kernel_sign_algorithm], 314 algo_strings[image->kernel_sign_algorithm],
312 image->kernel_key_version); 315 image->kernel_key_version);
313 /* TODO(gauravsh): Output hash and key signature here? */ 316 /* TODO(gauravsh): Output hash and key signature here? */
314 /* Print preamble. */ 317 /* Print preamble. */
315 printf("Kernel Version = %d\n" 318 printf("Kernel Version = %d\n"
316 "Kernel Config Version = %d.%d\n" 319 "Kernel Config Version = %d.%d\n"
320 "Kernel Config command line = %s\n"
317 "kernel Length = %" PRId64 "\n" 321 "kernel Length = %" PRId64 "\n"
318 "Kernel Load Address = %" PRId64 "\n" 322 "Kernel Load Address = %" PRId64 "\n"
319 "Kernel Entry Address = %" PRId64 "\n\n", 323 "Kernel Entry Address = %" PRId64 "\n\n",
320 image->kernel_version, 324 image->kernel_version,
321 image->options.version[0], image->options.version[1], 325 image->options.version[0], image->options.version[1],
326 image->options.cmd_line,
322 image->options.kernel_len, 327 image->options.kernel_len,
323 image->options.kernel_load_addr, 328 image->options.kernel_load_addr,
324 image->options.kernel_entry_addr); 329 image->options.kernel_entry_addr);
325 /* TODO(gauravsh): Output kernel signature here? */ 330 /* TODO(gauravsh): Output kernel signature here? */
326 } 331 }
327 332
328 char* kVerifyKernelErrors[VERIFY_KERNEL_MAX] = { 333 char* kVerifyKernelErrors[VERIFY_KERNEL_MAX] = {
329 "Success.", 334 "Success.",
330 "Invalid Image.", 335 "Invalid Image.",
331 "Kernel Key Signature Failed.", 336 "Kernel Key Signature Failed.",
(...skipping 81 matching lines...) Expand 10 before | Expand all | Expand 10 after
413 return VERIFY_KERNEL_KEY_SIGNATURE_FAILED; 418 return VERIFY_KERNEL_KEY_SIGNATURE_FAILED;
414 } 419 }
415 return 0; 420 return 0;
416 } 421 }
417 422
418 int VerifyKernelConfig(RSAPublicKey* kernel_sign_key, 423 int VerifyKernelConfig(RSAPublicKey* kernel_sign_key,
419 const uint8_t* config_blob, 424 const uint8_t* config_blob,
420 int algorithm, 425 int algorithm,
421 int* kernel_len) { 426 int* kernel_len) {
422 uint32_t len, config_len; 427 uint32_t len, config_len;
423 config_len = (FIELD_LEN(kernel_version) + 428 config_len = GetKernelConfigLen(NULL);
424 FIELD_LEN(options.version)+
425 FIELD_LEN(options.kernel_len) +
426 FIELD_LEN(options.kernel_load_addr) +
427 FIELD_LEN(options.kernel_entry_addr));
428 if (!RSAVerifyBinary_f(NULL, kernel_sign_key, /* Key to use */ 429 if (!RSAVerifyBinary_f(NULL, kernel_sign_key, /* Key to use */
429 config_blob, /* Data to verify */ 430 config_blob, /* Data to verify */
430 config_len, /* Length of data */ 431 config_len, /* Length of data */
431 config_blob + config_len, /* Expected Signature */ 432 config_blob + config_len, /* Expected Signature */
432 algorithm)) 433 algorithm))
433 return VERIFY_KERNEL_CONFIG_SIGNATURE_FAILED; 434 return VERIFY_KERNEL_CONFIG_SIGNATURE_FAILED;
434 435
435 Memcpy(&len, config_blob + (FIELD_LEN(kernel_version)+ 436 Memcpy(&len,
436 FIELD_LEN(options.version)), 437 config_blob + (FIELD_LEN(kernel_version) + FIELD_LEN(options.version) +
438 FIELD_LEN(options.cmd_line)),
437 sizeof(len)); 439 sizeof(len));
438 *kernel_len = (int) len; 440 *kernel_len = (int) len;
439 return 0; 441 return 0;
440 } 442 }
441 443
442 int VerifyKernelData(RSAPublicKey* kernel_sign_key, 444 int VerifyKernelData(RSAPublicKey* kernel_sign_key,
443 const uint8_t* kernel_data_start, 445 const uint8_t* kernel_data_start,
444 int kernel_len, 446 int kernel_len,
445 int algorithm) { 447 int algorithm) {
446 int signature_len = siglen_map[algorithm]; 448 int signature_len = siglen_map[algorithm];
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after
499 /* Only continue if config verification succeeds. */ 501 /* Only continue if config verification succeeds. */
500 config_ptr = (header_ptr + header_len + kernel_key_signature_len); 502 config_ptr = (header_ptr + header_len + kernel_key_signature_len);
501 if ((error_code = VerifyKernelConfig(kernel_sign_key, config_ptr, 503 if ((error_code = VerifyKernelConfig(kernel_sign_key, config_ptr,
502 kernel_sign_algorithm, 504 kernel_sign_algorithm,
503 &kernel_len))) { 505 &kernel_len))) {
504 RSAPublicKeyFree(kernel_sign_key); 506 RSAPublicKeyFree(kernel_sign_key);
505 return error_code; /* AKA jump to recovery. */ 507 return error_code; /* AKA jump to recovery. */
506 } 508 }
507 /* Only continue if kernel data verification succeeds. */ 509 /* Only continue if kernel data verification succeeds. */
508 kernel_ptr = (config_ptr + 510 kernel_ptr = (config_ptr +
509 FIELD_LEN(kernel_version) + 511 GetKernelConfigLen(NULL) + /* Skip config block/signature. */
510 FIELD_LEN(options.version) +
511 FIELD_LEN(options.kernel_len) +
512 FIELD_LEN(options.kernel_entry_addr) +
513 FIELD_LEN(options.kernel_load_addr) +
514 kernel_signature_len); 512 kernel_signature_len);
515 513
516 if ((error_code = VerifyKernelData(kernel_sign_key, kernel_ptr, kernel_len, 514 if ((error_code = VerifyKernelData(kernel_sign_key, kernel_ptr, kernel_len,
517 kernel_sign_algorithm))) { 515 kernel_sign_algorithm))) {
518 RSAPublicKeyFree(kernel_sign_key); 516 RSAPublicKeyFree(kernel_sign_key);
519 return error_code; /* AKA jump to recovery. */ 517 return error_code; /* AKA jump to recovery. */
520 } 518 }
521 RSAPublicKeyFree(kernel_sign_key); 519 RSAPublicKeyFree(kernel_sign_key);
522 return 0; /* Success! */ 520 return 0; /* Success! */
523 } 521 }
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after
580 /* Get kernel signing key to verify the rest of the kernel. */ 578 /* Get kernel signing key to verify the rest of the kernel. */
581 kernel_sign_key_size = RSAProcessedKeySize(image->kernel_sign_algorithm); 579 kernel_sign_key_size = RSAProcessedKeySize(image->kernel_sign_algorithm);
582 kernel_sign_key = RSAPublicKeyFromBuf(image->kernel_sign_key, 580 kernel_sign_key = RSAPublicKeyFromBuf(image->kernel_sign_key,
583 kernel_sign_key_size); 581 kernel_sign_key_size);
584 kernel_signature_size = siglen_map[image->kernel_sign_algorithm]; 582 kernel_signature_size = siglen_map[image->kernel_sign_algorithm];
585 583
586 /* Verify kernel config signature. */ 584 /* Verify kernel config signature. */
587 DigestInit(&ctx, image->kernel_sign_algorithm); 585 DigestInit(&ctx, image->kernel_sign_algorithm);
588 DigestUpdate(&ctx, (uint8_t*) &image->kernel_version, 586 DigestUpdate(&ctx, (uint8_t*) &image->kernel_version,
589 FIELD_LEN(kernel_version)); 587 FIELD_LEN(kernel_version));
590 DigestUpdate(&ctx, (uint8_t*) &image->options.version, 588 DigestUpdate(&ctx, (uint8_t*) image->options.version,
591 FIELD_LEN(options.version)); 589 FIELD_LEN(options.version));
590 DigestUpdate(&ctx, (uint8_t*) image->options.cmd_line,
591 FIELD_LEN(options.cmd_line));
592 DigestUpdate(&ctx, (uint8_t*) &image->options.kernel_len, 592 DigestUpdate(&ctx, (uint8_t*) &image->options.kernel_len,
593 FIELD_LEN(options.kernel_len)); 593 FIELD_LEN(options.kernel_len));
594 DigestUpdate(&ctx, (uint8_t*) &image->options.kernel_load_addr, 594 DigestUpdate(&ctx, (uint8_t*) &image->options.kernel_load_addr,
595 FIELD_LEN(options.kernel_load_addr)); 595 FIELD_LEN(options.kernel_load_addr));
596 DigestUpdate(&ctx, (uint8_t*) &image->options.kernel_entry_addr, 596 DigestUpdate(&ctx, (uint8_t*) &image->options.kernel_entry_addr,
597 FIELD_LEN(options.kernel_entry_addr)); 597 FIELD_LEN(options.kernel_entry_addr));
598 config_digest = DigestFinal(&ctx); 598 config_digest = DigestFinal(&ctx);
599 if (!RSAVerify(kernel_sign_key, image->config_signature, 599 if (!RSAVerify(kernel_sign_key, image->config_signature,
600 kernel_signature_size, image->kernel_sign_algorithm, 600 kernel_signature_size, image->kernel_sign_algorithm,
601 config_digest)) { 601 config_digest)) {
(...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after
676 kernel_signing_key_file, 676 kernel_signing_key_file,
677 image->kernel_sign_algorithm))) { 677 image->kernel_sign_algorithm))) {
678 fprintf(stderr, "Could not compute signature on the kernel.\n"); 678 fprintf(stderr, "Could not compute signature on the kernel.\n");
679 return 0; 679 return 0;
680 } 680 }
681 image->kernel_signature = (uint8_t*) Malloc(signature_len); 681 image->kernel_signature = (uint8_t*) Malloc(signature_len);
682 Memcpy(image->kernel_signature, kernel_signature, signature_len); 682 Memcpy(image->kernel_signature, kernel_signature, signature_len);
683 Free(kernel_signature); 683 Free(kernel_signature);
684 return 1; 684 return 1;
685 } 685 }
OLDNEW
« no previous file with comments | « src/platform/vboot_reference/utils/firmware_image.c ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698