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 |