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 |