| 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 116 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 127 int is_dev = ((BOOT_FLAG_DEVELOPER & params->boot_flags) && | 127 int is_dev = ((BOOT_FLAG_DEVELOPER & params->boot_flags) && |
| 128 !(BOOT_FLAG_RECOVERY & params->boot_flags)); | 128 !(BOOT_FLAG_RECOVERY & params->boot_flags)); |
| 129 int is_normal = (!(BOOT_FLAG_DEVELOPER & params->boot_flags) && | 129 int is_normal = (!(BOOT_FLAG_DEVELOPER & params->boot_flags) && |
| 130 !(BOOT_FLAG_RECOVERY & params->boot_flags)); | 130 !(BOOT_FLAG_RECOVERY & params->boot_flags)); |
| 131 | 131 |
| 132 /* Clear output params in case we fail */ | 132 /* Clear output params in case we fail */ |
| 133 params->partition_number = 0; | 133 params->partition_number = 0; |
| 134 params->bootloader_address = 0; | 134 params->bootloader_address = 0; |
| 135 params->bootloader_size = 0; | 135 params->bootloader_size = 0; |
| 136 | 136 |
| 137 /* Set up TPM; required in all modes */ | 137 /* Let the TPM know if we're in recovery mode */ |
| 138 if (0 != SetupTPM( | 138 if (BOOT_FLAG_RECOVERY & params->boot_flags) { |
| 139 ((BOOT_FLAG_RECOVERY & params->boot_flags) ? | 139 if (0 != RollbackKernelRecovery(BOOT_FLAG_DEVELOPER & params->boot_flags |
| 140 RO_RECOVERY_MODE : RW_NORMAL_MODE), | 140 ? 1 : 0)) { |
| 141 ((BOOT_FLAG_DEVELOPER & params->boot_flags) ? 1 : 0))) { | 141 debug("Error setting up TPM for recovery kernel\n"); |
| 142 debug("Error setting up TPM\n"); | 142 return LOAD_KERNEL_RECOVERY; |
| 143 return LOAD_KERNEL_RECOVERY; | 143 } |
| 144 } | 144 } |
| 145 | 145 |
| 146 if (is_normal) { | 146 if (is_normal) { |
| 147 /* Read current kernel key index from TPM. Assumes TPM is already | 147 /* Read current kernel key index from TPM. Assumes TPM is already |
| 148 * initialized. */ | 148 * initialized. */ |
| 149 if (0 != GetStoredVersions(KERNEL_VERSIONS, | 149 if (0 != RollbackKernelRead(&tpm_key_version, &tpm_kernel_version)) { |
| 150 &tpm_key_version, | 150 debug("Unable to get kernel versions from TPM\n"); |
| 151 &tpm_kernel_version)) { | |
| 152 debug("Unable to get stored version from TPM\n"); | |
| 153 return LOAD_KERNEL_RECOVERY; | 151 return LOAD_KERNEL_RECOVERY; |
| 154 } | 152 } |
| 155 } else if (is_dev) { | 153 } else if (is_dev) { |
| 156 /* In developer mode, we ignore the kernel subkey, and just use | 154 /* In developer mode, we ignore the kernel subkey, and just use |
| 157 * the SHA-512 hash to verify the key block. */ | 155 * the SHA-512 hash to verify the key block. */ |
| 158 kernel_subkey = NULL; | 156 kernel_subkey = NULL; |
| 159 } | 157 } |
| 160 | 158 |
| 161 do { | 159 do { |
| 162 /* Read GPT data */ | 160 /* Read GPT data */ |
| (...skipping 198 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 361 /* We only update the TPM in normal boot mode. In developer | 359 /* We only update the TPM in normal boot mode. In developer |
| 362 * mode, the kernel is self-signed by the developer, so we can't | 360 * mode, the kernel is self-signed by the developer, so we can't |
| 363 * trust the key version and wouldn't want to roll the TPM | 361 * trust the key version and wouldn't want to roll the TPM |
| 364 * forward. In recovery mode, the TPM stays PP-unlocked, so | 362 * forward. In recovery mode, the TPM stays PP-unlocked, so |
| 365 * anything we write gets blown away by the firmware when we go | 363 * anything we write gets blown away by the firmware when we go |
| 366 * back to normal mode. */ | 364 * back to normal mode. */ |
| 367 debug("Boot_flags = is_normal\n"); | 365 debug("Boot_flags = is_normal\n"); |
| 368 if ((lowest_key_version > tpm_key_version) || | 366 if ((lowest_key_version > tpm_key_version) || |
| 369 (lowest_key_version == tpm_key_version && | 367 (lowest_key_version == tpm_key_version && |
| 370 lowest_kernel_version > tpm_kernel_version)) { | 368 lowest_kernel_version > tpm_kernel_version)) { |
| 371 if (0 != WriteStoredVersions(KERNEL_VERSIONS, | 369 if (0 != RollbackKernelWrite((uint16_t)lowest_key_version, |
| 372 (uint16_t)lowest_key_version, | 370 (uint16_t)lowest_kernel_version)) { |
| 373 (uint16_t)lowest_kernel_version)) | 371 debug("Error writing kernel versions to TPM.\n"); |
| 374 return LOAD_KERNEL_RECOVERY; | 372 return LOAD_KERNEL_RECOVERY; |
| 373 } |
| 375 } | 374 } |
| 376 } | 375 } |
| 377 | 376 |
| 378 if (!(BOOT_FLAG_RECOVERY & params->boot_flags)) { | 377 /* Lock the kernel versions, since we're about to boot the kernel */ |
| 379 /* We can lock the TPM now, since we've decided which kernel we | 378 if (0 != RollbackKernelLock()) { |
| 380 * like. If we don't find a good kernel, we leave the TPM | 379 debug("Error locking kernel versions.\n"); |
| 381 * unlocked so we can try again on the next boot device. If no | 380 return LOAD_KERNEL_RECOVERY; |
| 382 * kernels are good, we'll reboot to recovery mode, so it's ok to | |
| 383 * leave the TPM unlocked in that case too. | |
| 384 * | |
| 385 * If we're already in recovery mode, we need to leave PP unlocked, | |
| 386 * so don't lock the kernel versions. */ | |
| 387 debug("Lock kernel versions\n"); | |
| 388 if (0 != LockKernelVersionsByLockingPP()) | |
| 389 return LOAD_KERNEL_RECOVERY; | |
| 390 } | 381 } |
| 391 | 382 |
| 392 /* Success! */ | 383 /* Success! */ |
| 393 return LOAD_KERNEL_SUCCESS; | 384 return LOAD_KERNEL_SUCCESS; |
| 394 } | 385 } |
| 395 | 386 |
| 396 // Handle error cases | 387 // Handle error cases |
| 397 if (found_partitions) | 388 if (found_partitions) |
| 398 return LOAD_KERNEL_INVALID; | 389 return LOAD_KERNEL_INVALID; |
| 399 else | 390 else |
| 400 return LOAD_KERNEL_NOT_FOUND; | 391 return LOAD_KERNEL_NOT_FOUND; |
| 401 } | 392 } |
| OLD | NEW |