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 1519008: VBoot Reference: 18 Exabytes ought to be enough for everybody (Closed)
Patch Set: Use symbolic constants. 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
« 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 51 matching lines...) Expand 10 before | Expand all | Expand 10 after
62 KernelImage* image = KernelImageNew(); 62 KernelImage* image = KernelImageNew();
63 63
64 if (!image) 64 if (!image)
65 return NULL; 65 return NULL;
66 66
67 kernel_buf = BufferFromFile(input_file, &file_size); 67 kernel_buf = BufferFromFile(input_file, &file_size);
68 image_len = file_size; 68 image_len = file_size;
69 69
70 st.remaining_len = image_len; 70 st.remaining_len = image_len;
71 st.remaining_buf = kernel_buf; 71 st.remaining_buf = kernel_buf;
72 st.overrun = 0;
72 73
73 /* Read and compare magic bytes. */ 74 /* Read and compare magic bytes. */
74 StatefulMemcpy(&st, &image->magic, KERNEL_MAGIC_SIZE); 75 StatefulMemcpy(&st, &image->magic, KERNEL_MAGIC_SIZE);
75 76
76 if (SafeMemcmp(image->magic, KERNEL_MAGIC, KERNEL_MAGIC_SIZE)) { 77 if (SafeMemcmp(image->magic, KERNEL_MAGIC, KERNEL_MAGIC_SIZE)) {
77 fprintf(stderr, "Wrong Kernel Magic.\n"); 78 fprintf(stderr, "Wrong Kernel Magic.\n");
78 Free(kernel_buf); 79 Free(kernel_buf);
79 return NULL; 80 return NULL;
80 } 81 }
81 StatefulMemcpy(&st, &image->header_version, FIELD_LEN(header_version)); 82 StatefulMemcpy(&st, &image->header_version, FIELD_LEN(header_version));
(...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after
147 /* Read kernel config signature. */ 148 /* Read kernel config signature. */
148 image->config_signature = (uint8_t*) Malloc(kernel_signature_len); 149 image->config_signature = (uint8_t*) Malloc(kernel_signature_len);
149 StatefulMemcpy(&st, image->config_signature, kernel_signature_len); 150 StatefulMemcpy(&st, image->config_signature, kernel_signature_len);
150 151
151 image->kernel_signature = (uint8_t*) Malloc(kernel_signature_len); 152 image->kernel_signature = (uint8_t*) Malloc(kernel_signature_len);
152 StatefulMemcpy(&st, image->kernel_signature, kernel_signature_len); 153 StatefulMemcpy(&st, image->kernel_signature, kernel_signature_len);
153 154
154 image->kernel_data = (uint8_t*) Malloc(image->options.kernel_len); 155 image->kernel_data = (uint8_t*) Malloc(image->options.kernel_len);
155 StatefulMemcpy(&st, image->kernel_data, image->options.kernel_len); 156 StatefulMemcpy(&st, image->kernel_data, image->options.kernel_len);
156 157
157 if(st.remaining_len != 0) { /* Overrun or underrun. */ 158 if(st.overrun || st.remaining_len != 0) { /* Overrun or underrun. */
158 Free(kernel_buf); 159 Free(kernel_buf);
159 return NULL; 160 return NULL;
160 } 161 }
161 Free(kernel_buf); 162 Free(kernel_buf);
162 return image; 163 return image;
163 } 164 }
164 165
165 int GetKernelHeaderLen(const KernelImage* image) { 166 int GetKernelHeaderLen(const KernelImage* image) {
166 return (FIELD_LEN(header_version) + FIELD_LEN(header_len) + 167 return (FIELD_LEN(header_version) + FIELD_LEN(header_len) +
167 FIELD_LEN(firmware_sign_algorithm) + 168 FIELD_LEN(firmware_sign_algorithm) +
(...skipping 25 matching lines...) Expand all
193 return; 194 return;
194 } 195 }
195 196
196 uint8_t* GetKernelHeaderBlob(const KernelImage* image) { 197 uint8_t* GetKernelHeaderBlob(const KernelImage* image) {
197 uint8_t* header_blob = NULL; 198 uint8_t* header_blob = NULL;
198 MemcpyState st; 199 MemcpyState st;
199 200
200 header_blob = (uint8_t*) Malloc(GetKernelHeaderLen(image)); 201 header_blob = (uint8_t*) Malloc(GetKernelHeaderLen(image));
201 st.remaining_len = GetKernelHeaderLen(image); 202 st.remaining_len = GetKernelHeaderLen(image);
202 st.remaining_buf = header_blob; 203 st.remaining_buf = header_blob;
204 st.overrun = 0;
203 205
204 StatefulMemcpy_r(&st, &image->header_version, FIELD_LEN(header_version)); 206 StatefulMemcpy_r(&st, &image->header_version, FIELD_LEN(header_version));
205 StatefulMemcpy_r(&st, &image->header_len, FIELD_LEN(header_len)); 207 StatefulMemcpy_r(&st, &image->header_len, FIELD_LEN(header_len));
206 StatefulMemcpy_r(&st, &image->firmware_sign_algorithm, 208 StatefulMemcpy_r(&st, &image->firmware_sign_algorithm,
207 FIELD_LEN(firmware_sign_algorithm)); 209 FIELD_LEN(firmware_sign_algorithm));
208 StatefulMemcpy_r(&st, &image->kernel_sign_algorithm, 210 StatefulMemcpy_r(&st, &image->kernel_sign_algorithm,
209 FIELD_LEN(kernel_sign_algorithm)); 211 FIELD_LEN(kernel_sign_algorithm));
210 StatefulMemcpy_r(&st, &image->kernel_key_version, 212 StatefulMemcpy_r(&st, &image->kernel_key_version,
211 FIELD_LEN(kernel_key_version)); 213 FIELD_LEN(kernel_key_version));
212 StatefulMemcpy_r(&st, image->kernel_sign_key, 214 StatefulMemcpy_r(&st, image->kernel_sign_key,
213 RSAProcessedKeySize(image->kernel_sign_algorithm)); 215 RSAProcessedKeySize(image->kernel_sign_algorithm));
214 StatefulMemcpy_r(&st, &image->header_checksum, FIELD_LEN(header_checksum)); 216 StatefulMemcpy_r(&st, &image->header_checksum, FIELD_LEN(header_checksum));
215 217
216 if (st.remaining_len != 0) { /* Underrun or Overrun. */ 218 if (st.overrun || st.remaining_len != 0) { /* Underrun or Overrun. */
217 Free(header_blob); 219 Free(header_blob);
218 return NULL; 220 return NULL;
219 } 221 }
220 return header_blob; 222 return header_blob;
221 } 223 }
222 224
223 int GetKernelConfigLen() { 225 int GetKernelConfigLen() {
224 return (FIELD_LEN(kernel_version) + 226 return (FIELD_LEN(kernel_version) +
225 FIELD_LEN(options.version) + FIELD_LEN(options.cmd_line) + 227 FIELD_LEN(options.version) + FIELD_LEN(options.cmd_line) +
226 FIELD_LEN(options.kernel_len) + FIELD_LEN(options.kernel_load_addr) + 228 FIELD_LEN(options.kernel_len) + FIELD_LEN(options.kernel_load_addr) +
227 FIELD_LEN(options.kernel_entry_addr)); 229 FIELD_LEN(options.kernel_entry_addr));
228 } 230 }
229 231
230 uint8_t* GetKernelConfigBlob(const KernelImage* image) { 232 uint8_t* GetKernelConfigBlob(const KernelImage* image) {
231 uint8_t* config_blob = NULL; 233 uint8_t* config_blob = NULL;
232 MemcpyState st; 234 MemcpyState st;
233 235
234 config_blob = (uint8_t*) Malloc(GetKernelConfigLen()); 236 config_blob = (uint8_t*) Malloc(GetKernelConfigLen());
235 st.remaining_len = GetKernelConfigLen(); 237 st.remaining_len = GetKernelConfigLen();
236 st.remaining_buf = config_blob; 238 st.remaining_buf = config_blob;
239 st.overrun = 0;
237 240
238 StatefulMemcpy_r(&st, &image->kernel_version, FIELD_LEN(kernel_version)); 241 StatefulMemcpy_r(&st, &image->kernel_version, FIELD_LEN(kernel_version));
239 StatefulMemcpy_r(&st, image->options.version, FIELD_LEN(options.version)); 242 StatefulMemcpy_r(&st, image->options.version, FIELD_LEN(options.version));
240 StatefulMemcpy_r(&st, image->options.cmd_line, FIELD_LEN(options.cmd_line)); 243 StatefulMemcpy_r(&st, image->options.cmd_line, FIELD_LEN(options.cmd_line));
241 StatefulMemcpy_r(&st, &image->options.kernel_len, 244 StatefulMemcpy_r(&st, &image->options.kernel_len,
242 FIELD_LEN(options.kernel_len)); 245 FIELD_LEN(options.kernel_len));
243 StatefulMemcpy_r(&st, &image->options.kernel_load_addr, 246 StatefulMemcpy_r(&st, &image->options.kernel_load_addr,
244 FIELD_LEN(options.kernel_load_addr)); 247 FIELD_LEN(options.kernel_load_addr));
245 StatefulMemcpy_r(&st, &image->options.kernel_entry_addr, 248 StatefulMemcpy_r(&st, &image->options.kernel_entry_addr,
246 FIELD_LEN(options.kernel_entry_addr)); 249 FIELD_LEN(options.kernel_entry_addr));
247 if (st.remaining_len != 0) { /* Overrun or Underrun. */ 250 if (st.overrun || st.remaining_len != 0) { /* Overrun or Underrun. */
248 Free(config_blob); 251 Free(config_blob);
249 return NULL; 252 return NULL;
250 } 253 }
251 return config_blob; 254 return config_blob;
252 } 255 }
253 256
254 uint8_t* GetKernelBlob(const KernelImage* image, uint64_t* blob_len) { 257 uint8_t* GetKernelBlob(const KernelImage* image, uint64_t* blob_len) {
255 int kernel_key_signature_len; 258 int kernel_key_signature_len;
256 int kernel_signature_len; 259 int kernel_signature_len;
257 uint8_t* kernel_blob = NULL; 260 uint8_t* kernel_blob = NULL;
258 uint8_t* header_blob = NULL; 261 uint8_t* header_blob = NULL;
259 uint8_t* config_blob = NULL; 262 uint8_t* config_blob = NULL;
260 MemcpyState st; 263 MemcpyState st;
261 264
262 if (!image) 265 if (!image)
263 return NULL; 266 return NULL;
264 kernel_key_signature_len = siglen_map[image->firmware_sign_algorithm]; 267 kernel_key_signature_len = siglen_map[image->firmware_sign_algorithm];
265 kernel_signature_len = siglen_map[image->kernel_sign_algorithm]; 268 kernel_signature_len = siglen_map[image->kernel_sign_algorithm];
266 *blob_len = (FIELD_LEN(magic) + 269 *blob_len = (FIELD_LEN(magic) +
267 GetKernelHeaderLen(image) + 270 GetKernelHeaderLen(image) +
268 kernel_key_signature_len + 271 kernel_key_signature_len +
269 GetKernelConfigLen() + 272 GetKernelConfigLen() +
270 2 * kernel_signature_len + 273 2 * kernel_signature_len +
271 image->options.kernel_len); 274 image->options.kernel_len);
272 kernel_blob = (uint8_t*) Malloc(*blob_len); 275 kernel_blob = (uint8_t*) Malloc(*blob_len);
273 st.remaining_len = *blob_len; 276 st.remaining_len = *blob_len;
274 st.remaining_buf = kernel_blob; 277 st.remaining_buf = kernel_blob;
278 st.overrun = 0;
275 279
276 header_blob = GetKernelHeaderBlob(image); 280 header_blob = GetKernelHeaderBlob(image);
277 config_blob = GetKernelConfigBlob(image); 281 config_blob = GetKernelConfigBlob(image);
278 282
279 StatefulMemcpy_r(&st, image->magic, FIELD_LEN(magic)); 283 StatefulMemcpy_r(&st, image->magic, FIELD_LEN(magic));
280 StatefulMemcpy_r(&st, header_blob, GetKernelHeaderLen(image)); 284 StatefulMemcpy_r(&st, header_blob, GetKernelHeaderLen(image));
281 StatefulMemcpy_r(&st, image->kernel_key_signature, kernel_key_signature_len); 285 StatefulMemcpy_r(&st, image->kernel_key_signature, kernel_key_signature_len);
282 StatefulMemcpy_r(&st, config_blob, GetKernelConfigLen()); 286 StatefulMemcpy_r(&st, config_blob, GetKernelConfigLen());
283 StatefulMemcpy_r(&st, image->config_signature, kernel_signature_len); 287 StatefulMemcpy_r(&st, image->config_signature, kernel_signature_len);
284 StatefulMemcpy_r(&st, image->kernel_signature, kernel_signature_len); 288 StatefulMemcpy_r(&st, image->kernel_signature, kernel_signature_len);
285 StatefulMemcpy_r(&st, image->kernel_data, image->options.kernel_len); 289 StatefulMemcpy_r(&st, image->kernel_data, image->options.kernel_len);
286 290
287 Free(config_blob); 291 Free(config_blob);
288 Free(header_blob); 292 Free(header_blob);
289 293
290 if (st.remaining_len != 0) { /* Underrun or Overrun. */ 294 if (st.overrun || st.remaining_len != 0) { /* Underrun or Overrun. */
291 Free(kernel_blob); 295 Free(kernel_blob);
292 return NULL; 296 return NULL;
293 } 297 }
294 return kernel_blob; 298 return kernel_blob;
295 } 299 }
296 300
297 int WriteKernelImage(const char* input_file, 301 int WriteKernelImage(const char* input_file,
298 const KernelImage* image) { 302 const KernelImage* image) {
299 int fd; 303 int fd;
300 uint8_t* kernel_blob; 304 uint8_t* kernel_blob;
(...skipping 143 matching lines...) Expand 10 before | Expand all | Expand 10 after
444 header_blob + header_len, /* Expected Signature */ 448 header_blob + header_len, /* Expected Signature */
445 firmware_sign_algorithm)) 449 firmware_sign_algorithm))
446 return VERIFY_KERNEL_KEY_SIGNATURE_FAILED; 450 return VERIFY_KERNEL_KEY_SIGNATURE_FAILED;
447 } 451 }
448 return 0; 452 return 0;
449 } 453 }
450 454
451 int VerifyKernelConfig(RSAPublicKey* kernel_sign_key, 455 int VerifyKernelConfig(RSAPublicKey* kernel_sign_key,
452 const uint8_t* config_blob, 456 const uint8_t* config_blob,
453 int algorithm, 457 int algorithm,
454 int* kernel_len) { 458 uint64_t* kernel_len) {
455 uint32_t len, config_len; 459 uint64_t len;
456 config_len = GetKernelConfigLen(); 460 int config_len;
461 config_len = GetKernelConfigLen(NULL);
457 if (!RSAVerifyBinary_f(NULL, kernel_sign_key, /* Key to use */ 462 if (!RSAVerifyBinary_f(NULL, kernel_sign_key, /* Key to use */
458 config_blob, /* Data to verify */ 463 config_blob, /* Data to verify */
459 config_len, /* Length of data */ 464 config_len, /* Length of data */
460 config_blob + config_len, /* Expected Signature */ 465 config_blob + config_len, /* Expected Signature */
461 algorithm)) 466 algorithm))
462 return VERIFY_KERNEL_CONFIG_SIGNATURE_FAILED; 467 return VERIFY_KERNEL_CONFIG_SIGNATURE_FAILED;
463 468
464 Memcpy(&len, 469 Memcpy(&len,
465 config_blob + (FIELD_LEN(kernel_version) + FIELD_LEN(options.version) + 470 config_blob + (FIELD_LEN(kernel_version) + FIELD_LEN(options.version) +
466 FIELD_LEN(options.cmd_line)), 471 FIELD_LEN(options.cmd_line)),
467 sizeof(len)); 472 sizeof(len));
468 *kernel_len = (int) len; 473 *kernel_len = len;
469 return 0; 474 return 0;
470 } 475 }
471 476
472 int VerifyKernelData(RSAPublicKey* kernel_sign_key, 477 int VerifyKernelData(RSAPublicKey* kernel_sign_key,
473 const uint8_t* kernel_config_start, 478 const uint8_t* kernel_config_start,
474 const uint8_t* kernel_data_start, 479 const uint8_t* kernel_data_start,
475 int kernel_len, 480 uint64_t kernel_len,
476 int algorithm) { 481 int algorithm) {
477 int signature_len = siglen_map[algorithm]; 482 int signature_len = siglen_map[algorithm];
478 uint8_t* digest; 483 uint8_t* digest;
479 DigestContext ctx; 484 DigestContext ctx;
480 485
481 /* Since the kernel signature is computed over the kernel version, options 486 /* Since the kernel signature is computed over the kernel version, options
482 * and data, which does not form a contiguous region of memory, we calculate 487 * and data, which does not form a contiguous region of memory, we calculate
483 * the message digest ourselves. */ 488 * the message digest ourselves. */
484 DigestInit(&ctx, algorithm); 489 DigestInit(&ctx, algorithm);
485 DigestUpdate(&ctx, kernel_config_start, GetKernelConfigLen()); 490 DigestUpdate(&ctx, kernel_config_start, GetKernelConfigLen());
(...skipping 12 matching lines...) Expand all
498 } 503 }
499 504
500 int VerifyKernel(const uint8_t* firmware_key_blob, 505 int VerifyKernel(const uint8_t* firmware_key_blob,
501 const uint8_t* kernel_blob, 506 const uint8_t* kernel_blob,
502 const int dev_mode) { 507 const int dev_mode) {
503 int error_code; 508 int error_code;
504 int firmware_sign_algorithm; /* Firmware signing key algorithm. */ 509 int firmware_sign_algorithm; /* Firmware signing key algorithm. */
505 int kernel_sign_algorithm; /* Kernel Signing key algorithm. */ 510 int kernel_sign_algorithm; /* Kernel Signing key algorithm. */
506 RSAPublicKey* kernel_sign_key; 511 RSAPublicKey* kernel_sign_key;
507 int kernel_sign_key_len, kernel_key_signature_len, kernel_signature_len, 512 int kernel_sign_key_len, kernel_key_signature_len, kernel_signature_len,
508 header_len, kernel_len; 513 header_len;
514 uint64_t kernel_len;
509 const uint8_t* header_ptr; /* Pointer to header. */ 515 const uint8_t* header_ptr; /* Pointer to header. */
510 const uint8_t* kernel_sign_key_ptr; /* Pointer to signing key. */ 516 const uint8_t* kernel_sign_key_ptr; /* Pointer to signing key. */
511 const uint8_t* config_ptr; /* Pointer to kernel config block. */ 517 const uint8_t* config_ptr; /* Pointer to kernel config block. */
512 const uint8_t* kernel_ptr; /* Pointer to kernel signature/data. */ 518 const uint8_t* kernel_ptr; /* Pointer to kernel signature/data. */
513 519
514 /* Note: All the offset calculations are based on struct FirmwareImage which 520 /* Note: All the offset calculations are based on struct FirmwareImage which
515 * is defined in include/firmware_image.h. */ 521 * is defined in include/firmware_image.h. */
516 522
517 /* Compare magic bytes. */ 523 /* Compare magic bytes. */
518 if (SafeMemcmp(kernel_blob, KERNEL_MAGIC, KERNEL_MAGIC_SIZE)) 524 if (SafeMemcmp(kernel_blob, KERNEL_MAGIC, KERNEL_MAGIC_SIZE))
(...skipping 367 matching lines...) Expand 10 before | Expand all | Expand 10 after
886 /* Lock Kernel TPM rollback indices from further writes. 892 /* Lock Kernel TPM rollback indices from further writes.
887 * TODO(gauravsh): Figure out if these can be combined into one 893 * TODO(gauravsh): Figure out if these can be combined into one
888 * 32-bit location since we seem to always use them together. This can help 894 * 32-bit location since we seem to always use them together. This can help
889 * us minimize the number of NVRAM writes/locks (which are limited over flash 895 * us minimize the number of NVRAM writes/locks (which are limited over flash
890 * memory lifetimes. 896 * memory lifetimes.
891 */ 897 */
892 LockStoredVersion(KERNEL_KEY_VERSION); 898 LockStoredVersion(KERNEL_KEY_VERSION);
893 LockStoredVersion(KERNEL_VERSION); 899 LockStoredVersion(KERNEL_VERSION);
894 return kernel_to_boot; 900 return kernel_to_boot;
895 } 901 }
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