| OLD | NEW |
| 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 loading a kernel from disk. | 5 * Functions for loading a kernel from disk. |
| 6 * (Firmware portion) | 6 * (Firmware portion) |
| 7 */ | 7 */ |
| 8 | 8 |
| 9 #include "load_kernel_fw.h" | 9 #include "load_kernel_fw.h" |
| 10 | 10 |
| 11 #include "boot_device.h" | 11 #include "boot_device.h" |
| 12 #include "cgptlib.h" | 12 #include "cgptlib.h" |
| 13 #include "kernel_image_fw.h" | 13 #include "kernel_image_fw.h" |
| 14 #include "rollback_index.h" | 14 #include "rollback_index.h" |
| 15 #include "utility.h" | 15 #include "utility.h" |
| 16 | 16 |
| 17 #define GPT_ENTRIES_SIZE 16384 /* Bytes to read for GPT entries */ | 17 #define GPT_ENTRIES_SIZE 16384 /* Bytes to read for GPT entries */ |
| 18 | 18 |
| 19 #ifdef PRINT_DEBUG_INFO |
| 19 // TODO: for testing | 20 // TODO: for testing |
| 20 #include <stdio.h> | 21 #include <stdio.h> |
| 21 #include <inttypes.h> /* For PRIu64 macro */ | 22 #include <inttypes.h> /* For PRIu64 macro */ |
| 22 #include "cgptlib_internal.h" | 23 #endif |
| 23 | 24 |
| 24 /* TODO: Remove this terrible hack which fakes partition attributes | 25 /* TODO: Remove this terrible hack which fakes partition attributes |
| 25 * for the kernel partitions so that GptNextKernelEntry() won't | 26 * for the kernel partitions so that GptNextKernelEntry() won't |
| 26 * choke. */ | 27 * choke. */ |
| 28 #include "cgptlib_internal.h" |
| 27 void FakePartitionAttributes(GptData* gpt) { | 29 void FakePartitionAttributes(GptData* gpt) { |
| 30 GptHeader* h = (GptHeader*)gpt->primary_header; |
| 28 GptEntry* entries = (GptEntry*)gpt->primary_entries; | 31 GptEntry* entries = (GptEntry*)gpt->primary_entries; |
| 29 GptEntry* e; | 32 GptEntry* e; |
| 30 int i; | 33 int i; |
| 31 printf("Hacking partition attributes...\n"); | |
| 32 | 34 |
| 33 for (i = 0, e = entries; i < 12; i++, e++) { | 35 for (i = 0, e = entries; i < h->number_of_entries; i++, e++) { |
| 36 if (!IsKernelEntry(e)) |
| 37 continue; |
| 38 |
| 39 #ifdef PRINT_DEBUG_INFO |
| 34 | 40 |
| 35 printf("%2d %08x %04x %04x %02x %02x %02x %02x %02x %02x %02x %02x", | 41 printf("%2d %08x %04x %04x %02x %02x %02x %02x %02x %02x %02x %02x", |
| 36 i, | 42 i, |
| 37 e->type.u.Uuid.time_low, | 43 e->type.u.Uuid.time_low, |
| 38 e->type.u.Uuid.time_mid, | 44 e->type.u.Uuid.time_mid, |
| 39 e->type.u.Uuid.time_high_and_version, | 45 e->type.u.Uuid.time_high_and_version, |
| 40 e->type.u.Uuid.clock_seq_high_and_reserved, | 46 e->type.u.Uuid.clock_seq_high_and_reserved, |
| 41 e->type.u.Uuid.clock_seq_low, | 47 e->type.u.Uuid.clock_seq_low, |
| 42 e->type.u.Uuid.node[0], | 48 e->type.u.Uuid.node[0], |
| 43 e->type.u.Uuid.node[1], | 49 e->type.u.Uuid.node[1], |
| 44 e->type.u.Uuid.node[2], | 50 e->type.u.Uuid.node[2], |
| 45 e->type.u.Uuid.node[3], | 51 e->type.u.Uuid.node[3], |
| 46 e->type.u.Uuid.node[4], | 52 e->type.u.Uuid.node[4], |
| 47 e->type.u.Uuid.node[5] | 53 e->type.u.Uuid.node[5] |
| 48 ); | 54 ); |
| 49 printf(" %8" PRIu64 " %8" PRIu64"\n", e->starting_lba, | 55 printf(" %8" PRIu64 " %8" PRIu64"\n", e->starting_lba, |
| 50 e->ending_lba - e->starting_lba + 1); | 56 e->ending_lba - e->starting_lba + 1); |
| 51 if (!IsKernelEntry(e)) | |
| 52 continue; | |
| 53 printf("Hacking attributes for kernel partition %d\n", i); | 57 printf("Hacking attributes for kernel partition %d\n", i); |
| 58 #endif |
| 59 |
| 54 SetEntryPriority(e, 2); | 60 SetEntryPriority(e, 2); |
| 55 SetEntrySuccessful(e, 1); | 61 SetEntrySuccessful(e, 1); |
| 56 } | 62 } |
| 57 } | 63 } |
| 58 | 64 |
| 59 | 65 |
| 60 int AllocAndReadGptData(GptData *gptdata) { | 66 int AllocAndReadGptData(GptData *gptdata) { |
| 61 /* Allocates and reads GPT data from the drive. The sector_bytes and | 67 /* Allocates and reads GPT data from the drive. The sector_bytes and |
| 62 * drive_sectors fields should be filled on input. The primary and | 68 * drive_sectors fields should be filled on input. The primary and |
| 63 * secondary header and entries are filled on output. | 69 * secondary header and entries are filled on output. |
| (...skipping 139 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 203 if (VERIFY_KERNEL_SUCCESS != VerifyKernelHeader( | 209 if (VERIFY_KERNEL_SUCCESS != VerifyKernelHeader( |
| 204 params->header_sign_key_blob, | 210 params->header_sign_key_blob, |
| 205 kbuf, | 211 kbuf, |
| 206 KBUF_SIZE, | 212 KBUF_SIZE, |
| 207 (BOOT_MODE_DEVELOPER == params->boot_mode ? 1 : 0), | 213 (BOOT_MODE_DEVELOPER == params->boot_mode ? 1 : 0), |
| 208 kim, | 214 kim, |
| 209 &kernel_sign_key)) { | 215 &kernel_sign_key)) { |
| 210 continue; | 216 continue; |
| 211 } | 217 } |
| 212 | 218 |
| 219 #ifdef PRINT_DEBUG_INFO |
| 213 printf("Kernel header:\n"); | 220 printf("Kernel header:\n"); |
| 214 printf("header version: %d\n", kim->header_version); | 221 printf("header version: %d\n", kim->header_version); |
| 215 printf("header len: %d\n", kim->header_len); | 222 printf("header len: %d\n", kim->header_len); |
| 216 printf("firmware sign alg: %d\n", kim->firmware_sign_algorithm); | 223 printf("firmware sign alg: %d\n", kim->firmware_sign_algorithm); |
| 217 printf("kernel sign alg: %d\n", kim->kernel_sign_algorithm); | 224 printf("kernel sign alg: %d\n", kim->kernel_sign_algorithm); |
| 218 printf("kernel key version: %d\n", kim->kernel_key_version); | 225 printf("kernel key version: %d\n", kim->kernel_key_version); |
| 219 printf("kernel version: %d\n", kim->kernel_version); | 226 printf("kernel version: %d\n", kim->kernel_version); |
| 220 printf("kernel len: %" PRIu64 "\n", kim->kernel_len); | 227 printf("kernel len: %" PRIu64 "\n", kim->kernel_len); |
| 221 printf("bootloader addr: %" PRIu64 "\n", kim->bootloader_offset); | 228 printf("bootloader addr: %" PRIu64 "\n", kim->bootloader_offset); |
| 222 printf("bootloader size: %" PRIu64 "\n", kim->bootloader_size); | 229 printf("bootloader size: %" PRIu64 "\n", kim->bootloader_size); |
| 223 printf("padded header size: %" PRIu64 "\n", kim->padded_header_size); | 230 printf("padded header size: %" PRIu64 "\n", kim->padded_header_size); |
| 231 #endif |
| 224 | 232 |
| 225 /* Check for rollback of key version */ | 233 /* Check for rollback of key version */ |
| 226 if (kim->kernel_key_version < tpm_kernel_key_version) { | 234 if (kim->kernel_key_version < tpm_kernel_key_version) { |
| 227 RSAPublicKeyFree(kernel_sign_key); | 235 RSAPublicKeyFree(kernel_sign_key); |
| 228 continue; | 236 continue; |
| 229 } | 237 } |
| 230 | 238 |
| 231 /* Check for rollback of kernel version */ | 239 /* Check for rollback of kernel version */ |
| 232 if (kim->kernel_key_version == tpm_kernel_key_version && | 240 if (kim->kernel_key_version == tpm_kernel_key_version && |
| 233 kim->kernel_version < tpm_kernel_version) { | 241 kim->kernel_version < tpm_kernel_version) { |
| (...skipping 97 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 331 | 339 |
| 332 // Handle error cases | 340 // Handle error cases |
| 333 if (found_partition) | 341 if (found_partition) |
| 334 return LOAD_KERNEL_INVALID; | 342 return LOAD_KERNEL_INVALID; |
| 335 else | 343 else |
| 336 return LOAD_KERNEL_NOT_FOUND; | 344 return LOAD_KERNEL_NOT_FOUND; |
| 337 /* TODO: no error code for "internal error", but what would the firmware do | 345 /* TODO: no error code for "internal error", but what would the firmware do |
| 338 * with that anyway? So in the do-while(0) code above, the firmware just | 346 * with that anyway? So in the do-while(0) code above, the firmware just |
| 339 * does 'break' to indicate an internal error... */ | 347 * does 'break' to indicate an internal error... */ |
| 340 } | 348 } |
| OLD | NEW |