| 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 "vboot_kernel.h" | 9 #include "vboot_kernel.h" |
| 10 | 10 |
| (...skipping 129 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 140 return LOAD_KERNEL_RECOVERY; | 140 return LOAD_KERNEL_RECOVERY; |
| 141 } | 141 } |
| 142 } else if (is_dev) { | 142 } else if (is_dev) { |
| 143 /* In developer mode, we ignore the kernel subkey, and just use | 143 /* In developer mode, we ignore the kernel subkey, and just use |
| 144 * the SHA-512 hash to verify the key block. */ | 144 * the SHA-512 hash to verify the key block. */ |
| 145 kernel_subkey = NULL; | 145 kernel_subkey = NULL; |
| 146 } | 146 } |
| 147 | 147 |
| 148 do { | 148 do { |
| 149 /* Read GPT data */ | 149 /* Read GPT data */ |
| 150 gpt.sector_bytes = blba; | 150 gpt.sector_bytes = (uint32_t)blba; |
| 151 gpt.drive_sectors = params->ending_lba + 1; | 151 gpt.drive_sectors = params->ending_lba + 1; |
| 152 if (0 != AllocAndReadGptData(&gpt)) { | 152 if (0 != AllocAndReadGptData(&gpt)) { |
| 153 debug("Unable to read GPT data\n"); | 153 debug("Unable to read GPT data\n"); |
| 154 break; | 154 break; |
| 155 } | 155 } |
| 156 | 156 |
| 157 /* Initialize GPT library */ | 157 /* Initialize GPT library */ |
| 158 if (GPT_SUCCESS != GptInit(&gpt)) { | 158 if (GPT_SUCCESS != GptInit(&gpt)) { |
| 159 debug("Error parsing GPT\n"); | 159 debug("Error parsing GPT\n"); |
| 160 break; | 160 break; |
| (...skipping 138 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 299 RSAPublicKeyFree(data_key); | 299 RSAPublicKeyFree(data_key); |
| 300 continue; | 300 continue; |
| 301 } | 301 } |
| 302 | 302 |
| 303 /* Done with the kernel signing key, so can free it now */ | 303 /* Done with the kernel signing key, so can free it now */ |
| 304 RSAPublicKeyFree(data_key); | 304 RSAPublicKeyFree(data_key); |
| 305 | 305 |
| 306 /* If we're still here, the kernel is valid. */ | 306 /* If we're still here, the kernel is valid. */ |
| 307 /* Save the first good partition we find; that's the one we'll boot */ | 307 /* Save the first good partition we find; that's the one we'll boot */ |
| 308 debug("Partiton is good.\n"); | 308 debug("Partiton is good.\n"); |
| 309 good_partition = gpt.current_kernel; | 309 /* TODO: GPT partitions start at 1, but cgptlib starts them at 0. |
| 310 * Adjust here, until cgptlib is fixed. */ |
| 311 good_partition = gpt.current_kernel + 1; |
| 310 params->partition_number = gpt.current_kernel; | 312 params->partition_number = gpt.current_kernel; |
| 311 params->bootloader_address = preamble->bootloader_address; | 313 params->bootloader_address = preamble->bootloader_address; |
| 312 params->bootloader_size = preamble->bootloader_size; | 314 params->bootloader_size = preamble->bootloader_size; |
| 313 /* If we're in developer or recovery mode, there's no rollback | 315 /* If we're in developer or recovery mode, there's no rollback |
| 314 * protection, so we can stop at the first valid kernel. */ | 316 * protection, so we can stop at the first valid kernel. */ |
| 315 if (!is_normal) | 317 if (!is_normal) { |
| 318 debug("Boot_flags = !is_normal\n"); |
| 316 break; | 319 break; |
| 320 } |
| 317 | 321 |
| 318 /* Otherwise, we're in normal boot mode, so we do care about the | 322 /* Otherwise, we're in normal boot mode, so we do care about the |
| 319 * key index in the TPM. If the good partition's key version is | 323 * key index in the TPM. If the good partition's key version is |
| 320 * the same as the tpm, then the TPM doesn't need updating; we | 324 * the same as the tpm, then the TPM doesn't need updating; we |
| 321 * can stop now. Otherwise, we'll check all the other headers | 325 * can stop now. Otherwise, we'll check all the other headers |
| 322 * to see if they contain a newer key. */ | 326 * to see if they contain a newer key. */ |
| 323 if (key_version == tpm_key_version && | 327 if (key_version == tpm_key_version && |
| 324 preamble->kernel_version == tpm_kernel_version) | 328 preamble->kernel_version == tpm_kernel_version) { |
| 329 debug("Same key version\n"); |
| 325 break; | 330 break; |
| 331 } |
| 326 } /* while(GptNextKernelEntry) */ | 332 } /* while(GptNextKernelEntry) */ |
| 327 } while(0); | 333 } while(0); |
| 328 | 334 |
| 329 /* Free kernel buffer */ | 335 /* Free kernel buffer */ |
| 330 if (kbuf) | 336 if (kbuf) |
| 331 Free(kbuf); | 337 Free(kbuf); |
| 332 | 338 |
| 333 /* Write and free GPT data */ | 339 /* Write and free GPT data */ |
| 334 WriteAndFreeGptData(&gpt); | 340 WriteAndFreeGptData(&gpt); |
| 335 | 341 |
| 336 /* Handle finding a good partition */ | 342 /* Handle finding a good partition */ |
| 337 if (good_partition >= 0) { | 343 if (good_partition >= 0) { |
| 344 debug("Good_partition >= 0\n"); |
| 338 | 345 |
| 339 /* See if we need to update the TPM */ | 346 /* See if we need to update the TPM */ |
| 340 if (is_normal) { | 347 if (is_normal) { |
| 341 /* We only update the TPM in normal boot mode. In developer | 348 /* We only update the TPM in normal boot mode. In developer |
| 342 * mode, the kernel is self-signed by the developer, so we can't | 349 * mode, the kernel is self-signed by the developer, so we can't |
| 343 * trust the key version and wouldn't want to roll the TPM | 350 * trust the key version and wouldn't want to roll the TPM |
| 344 * forward. In recovery mode, the TPM stays PP-unlocked, so | 351 * forward. In recovery mode, the TPM stays PP-unlocked, so |
| 345 * anything we write gets blown away by the firmware when we go | 352 * anything we write gets blown away by the firmware when we go |
| 346 * back to normal mode. */ | 353 * back to normal mode. */ |
| 354 debug("Boot_flags = is_normal\n"); |
| 347 if ((lowest_key_version > tpm_key_version) || | 355 if ((lowest_key_version > tpm_key_version) || |
| 348 (lowest_key_version == tpm_key_version && | 356 (lowest_key_version == tpm_key_version && |
| 349 lowest_kernel_version > tpm_kernel_version)) { | 357 lowest_kernel_version > tpm_kernel_version)) { |
| 350 if (0 != WriteStoredVersions(KERNEL_VERSIONS, | 358 if (0 != WriteStoredVersions(KERNEL_VERSIONS, |
| 351 lowest_key_version, | 359 (uint16_t)lowest_key_version, |
| 352 lowest_kernel_version)) | 360 (uint16_t)lowest_kernel_version)) |
| 353 return LOAD_KERNEL_RECOVERY; | 361 return LOAD_KERNEL_RECOVERY; |
| 354 } | 362 } |
| 355 } | 363 } |
| 356 | 364 |
| 357 if (!(BOOT_FLAG_RECOVERY & params->boot_flags)) { | 365 if (!(BOOT_FLAG_RECOVERY & params->boot_flags)) { |
| 358 /* We can lock the TPM now, since we've decided which kernel we | 366 /* We can lock the TPM now, since we've decided which kernel we |
| 359 * like. If we don't find a good kernel, we leave the TPM | 367 * like. If we don't find a good kernel, we leave the TPM |
| 360 * unlocked so we can try again on the next boot device. If no | 368 * unlocked so we can try again on the next boot device. If no |
| 361 * kernels are good, we'll reboot to recovery mode, so it's ok to | 369 * kernels are good, we'll reboot to recovery mode, so it's ok to |
| 362 * leave the TPM unlocked in that case too. | 370 * leave the TPM unlocked in that case too. |
| 363 * | 371 * |
| 364 * If we're already in recovery mode, we need to leave PP unlocked, | 372 * If we're already in recovery mode, we need to leave PP unlocked, |
| 365 * so don't lock the kernel versions. */ | 373 * so don't lock the kernel versions. */ |
| 374 debug("Lock kernel versions\n"); |
| 366 if (0 != LockKernelVersionsByLockingPP()) | 375 if (0 != LockKernelVersionsByLockingPP()) |
| 367 return LOAD_KERNEL_RECOVERY; | 376 return LOAD_KERNEL_RECOVERY; |
| 368 } | 377 } |
| 369 | 378 |
| 370 /* Success! */ | 379 /* Success! */ |
| 371 return LOAD_KERNEL_SUCCESS; | 380 return LOAD_KERNEL_SUCCESS; |
| 372 } | 381 } |
| 373 | 382 |
| 374 // Handle error cases | 383 // Handle error cases |
| 375 if (found_partitions) | 384 if (found_partitions) |
| 376 return LOAD_KERNEL_INVALID; | 385 return LOAD_KERNEL_INVALID; |
| 377 else | 386 else |
| 378 return LOAD_KERNEL_NOT_FOUND; | 387 return LOAD_KERNEL_NOT_FOUND; |
| 379 } | 388 } |
| OLD | NEW |