diff options
-rw-r--r-- | firmware/include/vboot_api.h | 14 | ||||
-rw-r--r-- | firmware/include/vboot_nvstorage.h | 3 | ||||
-rw-r--r-- | firmware/include/vboot_struct.h | 19 | ||||
-rw-r--r-- | firmware/lib/vboot_api_firmware.c | 7 | ||||
-rw-r--r-- | firmware/lib/vboot_api_init.c | 47 | ||||
-rw-r--r-- | firmware/lib/vboot_api_kernel.c | 65 | ||||
-rw-r--r-- | firmware/lib/vboot_firmware.c | 5 | ||||
-rw-r--r-- | firmware/lib/vboot_kernel.c | 180 | ||||
-rw-r--r-- | firmware/linktest/main.c | 3 | ||||
-rw-r--r-- | host/lib/crossystem.c | 12 |
10 files changed, 175 insertions, 180 deletions
diff --git a/firmware/include/vboot_api.h b/firmware/include/vboot_api.h index c9eeb33d..48859e06 100644 --- a/firmware/include/vboot_api.h +++ b/firmware/include/vboot_api.h @@ -95,7 +95,11 @@ typedef struct VbCommonParams { #define VB_INIT_FLAG_WP_ENABLED 0x00000004 /* This is a S3 resume, not a normal boot. */ #define VB_INIT_FLAG_S3_RESUME 0x00000008 - +/* Previous boot attempt failed for reasons external to verified boot (RAM + * init failure, SSD missing, etc.). */ +/* TODO: add a field to VbInitParams which holds a reason code, and report + * that via VbSharedData. */ +#define VB_INIT_FLAG_PREVIOUS_BOOT_FAIL 0x00000010 /* Output flags for VbInitParams.out_flags. Used to indicate * potential boot paths and configuration to the calling firmware @@ -210,14 +214,6 @@ void VbUpdateFirmwareBodyHash(VbCommonParams* cparams, VbError_t VbSelectAndLoadKernel(VbCommonParams* cparams, VbSelectAndLoadKernelParams* kparams); -/* S3 resume handler. This only needs to be called if the hardware - * does not maintain power to the TPM when in S3 (suspend-to-RAM). - * - * Returns VBERROR_SUCCESS if success, non-zero if error; on error, - * caller should reboot. */ -VbError_t VbS3Resume(void); - - /*****************************************************************************/ /* Debug output (from utility.h) */ diff --git a/firmware/include/vboot_nvstorage.h b/firmware/include/vboot_nvstorage.h index 02f81a70..046dd75d 100644 --- a/firmware/include/vboot_nvstorage.h +++ b/firmware/include/vboot_nvstorage.h @@ -86,6 +86,9 @@ typedef enum VbNvParam { * vboot_struct.h. */ #define VBNV_RECOVERY_RO_INVALID_RW_CHECK_MIN 0x10 #define VBNV_RECOVERY_RO_INVALID_RW_CHECK_MAX 0x1F +/* Firmware boot failure outside of verified boot (RAM init, missing SSD, + * etc.). */ +#define VBNV_RECOVERY_RO_FIRMWARE 0x20 /* Unspecified/unknown error in read-only firmware */ #define VBNV_RECOVERY_RO_UNSPECIFIED 0x3F /* User manually requested recovery by pressing a key at developer diff --git a/firmware/include/vboot_struct.h b/firmware/include/vboot_struct.h index e9336dfe..0271979c 100644 --- a/firmware/include/vboot_struct.h +++ b/firmware/include/vboot_struct.h @@ -280,14 +280,17 @@ typedef struct VbSharedDataHeader { uint64_t kernel_subkey_data_size; /* Size of kernel subkey data */ /* Timer values from VbExGetTimer(). Unused values are set to 0. - * If a function is called mutiple times, these are the times from - * the most recent call. See crosbug.com/17018. */ - uint64_t timer_load_firmware_start_enter; /* VbInit() - enter */ - uint64_t timer_load_firmware_start_exit; /* VbInit() - exit */ - uint64_t timer_load_firmware_enter; /* LoadFirmware() - enter */ - uint64_t timer_load_firmware_exit; /* LoadFirmware() - exit */ - uint64_t timer_load_kernel_enter; /* LoadKernel() - enter */ - uint64_t timer_load_kernel_exit; /* LoadKernel() - exit */ + * Note that these are now the enter/exit times for the wrapper API entry + * points; see crosbug.com/17018. */ + /* VbInit() enter/exit */ + uint64_t timer_vb_init_enter; + uint64_t timer_vb_init_exit; + /* VbSelectFirmware() enter/exit */ + uint64_t timer_vb_select_firmware_enter; + uint64_t timer_vb_select_firmware_exit; + /* VbSelectAndLoadKernel() enter/exit */ + uint64_t timer_vb_select_and_load_kernel_enter; + uint64_t timer_vb_select_and_load_kernel_exit; /* Information stored in TPM, as retrieved by firmware */ uint32_t fw_version_tpm; /* Current firmware version in TPM */ diff --git a/firmware/lib/vboot_api_firmware.c b/firmware/lib/vboot_api_firmware.c index b4c14811..e4e4af02 100644 --- a/firmware/lib/vboot_api_firmware.c +++ b/firmware/lib/vboot_api_firmware.c @@ -20,11 +20,15 @@ VbError_t VbSelectFirmware(VbCommonParams* cparams, VbNvContext vnc; int rv; + /* Start timer */ + shared->timer_vb_select_firmware_enter = VbExGetTimer(); + /* If recovery is requested, go straight to recovery without checking the * RW firmware. */ if (VBNV_RECOVERY_NOT_REQUESTED != shared->recovery_reason) { VBDEBUG(("VbSelectFirmware() detected recovery request, reason=%d.\n", (int)shared->recovery_reason)); + shared->timer_vb_select_firmware_exit = VbExGetTimer(); fparams->selected_firmware = VB_SELECT_FIRMWARE_RECOVERY; return VBERROR_SUCCESS; } @@ -66,6 +70,9 @@ VbError_t VbSelectFirmware(VbCommonParams* cparams, /* Copy amount of used shared data back to the wrapper API struct */ cparams->shared_data_size = (uint32_t)p.shared_data_size; + /* Stop timer */ + shared->timer_vb_select_firmware_exit = VbExGetTimer(); + /* Translate return codes */ if (LOAD_FIRMWARE_SUCCESS == rv) { /* Found good firmware in either A or B */ diff --git a/firmware/lib/vboot_api_init.c b/firmware/lib/vboot_api_init.c index 8bccfe53..890b5768 100644 --- a/firmware/lib/vboot_api_init.c +++ b/firmware/lib/vboot_api_init.c @@ -17,6 +17,7 @@ VbError_t VbInit(VbCommonParams* cparams, VbInitParams* iparams) { VbSharedDataHeader* shared = (VbSharedDataHeader*)cparams->shared_data_blob; VbNvContext vnc; + VbError_t retval = VBERROR_SUCCESS; uint32_t recovery = VBNV_RECOVERY_NOT_REQUESTED; int is_s3_resume = 0; uint32_t s3_debug_boot = 0; @@ -36,7 +37,7 @@ VbError_t VbInit(VbCommonParams* cparams, VbInitParams* iparams) { return 1; } - shared->timer_load_firmware_start_enter = VbExGetTimer(); + shared->timer_vb_init_enter = VbExGetTimer(); /* Copy boot switch flags */ shared->flags = 0; @@ -74,6 +75,15 @@ VbError_t VbInit(VbCommonParams* cparams, VbInitParams* iparams) { VbNvSet(&vnc, VBNV_RECOVERY_REQUEST, VBNV_RECOVERY_NOT_REQUESTED); } + /* If the previous boot failed in the firmware somewhere outside of verified + * boot, and recovery is not requested for our own reasons, request recovery + * mode. This gives the calling firmware a way to request recovery if it + * finds something terribly wrong. */ + if (VBNV_RECOVERY_NOT_REQUESTED == recovery && + iparams->flags & VB_INIT_FLAG_PREVIOUS_BOOT_FAIL) { + recovery = VBNV_RECOVERY_RO_FIRMWARE; + } + /* If recovery button is pressed, override recovery reason. Note that we * do this in the S3 resume path also. */ if (iparams->flags & VB_INIT_FLAG_REC_BUTTON_PRESSED) @@ -97,11 +107,15 @@ VbError_t VbInit(VbCommonParams* cparams, VbInitParams* iparams) { /* Copy current recovery reason to shared data */ shared->recovery_reason = (uint8_t)recovery; - /* Clear the recovery request, so we won't get stuck in recovery mode */ - VbNvSet(&vnc, VBNV_RECOVERY_REQUEST, VBNV_RECOVERY_NOT_REQUESTED); - - // TODO: Handle S3 resume path ourselves, if VB_INIT_FLAG_S3_RESUME - // (I believe we can do this now...) + /* If this is a S3 resume, resume the TPM */ + if (is_s3_resume) { + if (TPM_SUCCESS != RollbackS3Resume()) { + /* If we can't resume, just do a full reboot. No need to go to recovery + * mode here, since if the TPM is really broken we'll catch it on the + * next boot. */ + retval = 1; + } + } /* Tear down NV storage */ VbNvTeardown(&vnc); @@ -110,24 +124,7 @@ VbError_t VbInit(VbCommonParams* cparams, VbInitParams* iparams) { VBDEBUG(("VbInit() output flags 0x%x\n", iparams->out_flags)); - shared->timer_load_firmware_start_exit = VbExGetTimer(); - - return VBERROR_SUCCESS; -} - - -VbError_t VbS3Resume(void) { + shared->timer_vb_init_exit = VbExGetTimer(); - /* TODO: handle test errors (requires passing in VbNvContext) */ - - /* Resume the TPM */ - uint32_t status = RollbackS3Resume(); - - /* If we can't resume, just do a full reboot. No need to go to recovery - * mode here, since if the TPM is really broken we'll catch it on the - * next boot. */ - if (status == TPM_SUCCESS) - return VBERROR_SUCCESS; - else - return 1; + return retval; } diff --git a/firmware/lib/vboot_api_kernel.c b/firmware/lib/vboot_api_kernel.c index 1afac378..738c4769 100644 --- a/firmware/lib/vboot_api_kernel.c +++ b/firmware/lib/vboot_api_kernel.c @@ -219,24 +219,67 @@ static VbError_t VbDisplayScreen(VbCommonParams* cparams, uint32_t screen, return VbExDisplayScreen(screen); } +#define DEBUG_INFO_SIZE 512 static VbError_t VbCheckDisplayKey(VbCommonParams* cparams, uint32_t key) { + VbSharedDataHeader* shared = (VbSharedDataHeader*)cparams->shared_data_blob; + GoogleBinaryBlockHeader* gbb = (GoogleBinaryBlockHeader*)cparams->gbb_data; if ('\t' == key) { /* Tab = display debug info */ + char buf[DEBUG_INFO_SIZE] = ""; + uint32_t used = 0; + uint32_t i; /* Redisplay the current screen, to overwrite any previous debug output */ VbDisplayScreen(cparams, disp_current_screen, 1); - /* TODO: add real data: - * - HWID - * - Current recovery request - * - Boot flags + /* Add hardware ID */ + used += Strncat(buf + used, "HWID: ", DEBUG_INFO_SIZE - used); + if (0 == gbb->hwid_size || + gbb->hwid_offset > cparams->gbb_size || + gbb->hwid_offset + gbb->hwid_size > cparams->gbb_size) { + VBDEBUG(("VbCheckDisplayKey(): invalid hwid offset/size\n")); + used += Strncat(buf + used, "(INVALID)", DEBUG_INFO_SIZE - used); + } else { + used += Strncat(buf + used, (char*)((uint8_t*)gbb + gbb->hwid_offset), + DEBUG_INFO_SIZE - used); + } + + /* Add recovery request */ + used += Strncat(buf + used, "\nrecovery_request: 0x", + DEBUG_INFO_SIZE - used); + used += Uint64ToString(buf + used, DEBUG_INFO_SIZE - used, + shared->recovery_reason, 16, 2); + + /* Add VbSharedData flags */ + used += Strncat(buf + used, "\nVbSD.flags: 0x", DEBUG_INFO_SIZE - used); + used += Uint64ToString(buf + used, DEBUG_INFO_SIZE - used, + shared->flags, 16, 8); + + /* Add raw contents of VbNvStorage */ + used += Strncat(buf + used, "\nVbNv.raw:", DEBUG_INFO_SIZE - used); + for (i = 0; i < VBNV_BLOCK_SIZE; i++) { + used += Strncat(buf + used, " ", DEBUG_INFO_SIZE - used); + used += Uint64ToString(buf + used, DEBUG_INFO_SIZE - used, + vnc.raw[i], 16, 2); + } + + used += Strncat(buf + used, "\n", DEBUG_INFO_SIZE - used); + + /* TODO: add more interesting data: + * - TPM firmware and kernel versions. In the current code, they're + * only filled into VbSharedData by LoadFirmware() and LoadKernel(), and + * since neither of those is called in the recovery path this isn't + * feasible yet. + * - SHA1 of kernel subkey (assuming we always set it in VbSelectFirmware, + * even in recovery mode, where we just copy it from the root key) * - Information on current disks - * - Anything else interesting from cparams and/or nvram - * - * TODO: Add a VbExSnprintf() function for this? */ - return VbExDisplayDebugInfo("Testing 1 2 3\nTesting 4 5 6\n"); + * - Anything else interesting from VbNvStorage */ + + buf[DEBUG_INFO_SIZE - 1] = '\0'; + VBDEBUG(("VbCheckDisplayKey() wants to show '%s'\n", buf)); + return VbExDisplayDebugInfo(buf); } else if (VB_KEY_LEFT == key || VB_KEY_RIGHT == key) { /* Arrow keys = change localization */ @@ -505,6 +548,9 @@ VbError_t VbSelectAndLoadKernel(VbCommonParams* cparams, VBDEBUG(("VbSelectAndLoadKernel() start\n")); + /* Start timer */ + shared->timer_vb_select_and_load_kernel_enter = VbExGetTimer(); + VbExNvStorageRead(vnc.raw); vnc.raw_changed = 0; @@ -563,6 +609,9 @@ VbError_t VbSelectAndLoadKernel(VbCommonParams* cparams, if (vnc.raw_changed) VbExNvStorageWrite(vnc.raw); + /* Stop timer */ + shared->timer_vb_select_and_load_kernel_exit = VbExGetTimer(); + VBDEBUG(("VbSelectAndLoadKernel() returning %d\n", (int)retval)); /* Pass through return value from boot path */ diff --git a/firmware/lib/vboot_firmware.c b/firmware/lib/vboot_firmware.c index 1022ad9d..1e989a4d 100644 --- a/firmware/lib/vboot_firmware.c +++ b/firmware/lib/vboot_firmware.c @@ -64,9 +64,6 @@ int LoadFirmware(LoadFirmwareParams* params) { /* Setup NV storage */ VbNvSetup(vnc); - /* Start timer */ - shared->timer_load_firmware_enter = VbExGetTimer(); - /* Handle test errors */ VbNvGet(vnc, VBNV_TEST_ERROR_FUNC, &test_err); if (VBNV_TEST_ERROR_LOAD_FIRMWARE == test_err) { @@ -378,8 +375,6 @@ LoadFirmwareExit: recovery : VBNV_RECOVERY_NOT_REQUESTED); VbNvTeardown(vnc); - shared->timer_load_firmware_exit = VbExGetTimer(); - /* Note that we don't reduce params->shared_data_size to shared->data_used, * since we want to leave space for LoadKernel() to add to the shared data * buffer. */ diff --git a/firmware/lib/vboot_kernel.c b/firmware/lib/vboot_kernel.c index 26c91210..97d32d34 100644 --- a/firmware/lib/vboot_kernel.c +++ b/firmware/lib/vboot_kernel.c @@ -145,7 +145,6 @@ int LoadKernel(LoadKernelParams* params) { int retval = LOAD_KERNEL_RECOVERY; int recovery = VBNV_RECOVERY_RO_UNSPECIFIED; - uint64_t timer_enter = VbExGetTimer(); /* Setup NV storage */ VbNvSetup(vnc); @@ -178,38 +177,23 @@ int LoadKernel(LoadKernelParams* params) { dev_switch = 0; /* Always do a fully verified boot */ } - if (kBootRecovery == boot_mode) { - /* Initialize the shared data structure, since LoadFirmware() didn't do it - * for us. */ - if (0 != VbSharedDataInit(shared, params->shared_data_size)) { - /* Error initializing the shared data, but we can keep going. We just - * can't use the shared data. */ - VBDEBUG(("Shared data init error\n")); - params->shared_data_size = 0; - shared = NULL; - } - } - - if (shared) { - /* Set up tracking for this call. This wraps around if called many times, - * so we need to initialize the call entry each time. */ - shcall = shared->lk_calls + (shared->lk_call_count - & (VBSD_MAX_KERNEL_CALLS - 1)); - Memset(shcall, 0, sizeof(VbSharedDataKernelCall)); - shcall->boot_flags = (uint32_t)params->boot_flags; - shcall->boot_mode = boot_mode; - shcall->sector_size = (uint32_t)params->bytes_per_lba; - shcall->sector_count = params->ending_lba + 1; - shared->lk_call_count++; - } + /* Set up tracking for this call. This wraps around if called many times, + * so we need to initialize the call entry each time. */ + shcall = shared->lk_calls + (shared->lk_call_count + & (VBSD_MAX_KERNEL_CALLS - 1)); + Memset(shcall, 0, sizeof(VbSharedDataKernelCall)); + shcall->boot_flags = (uint32_t)params->boot_flags; + shcall->boot_mode = boot_mode; + shcall->sector_size = (uint32_t)params->bytes_per_lba; + shcall->sector_count = params->ending_lba + 1; + shared->lk_call_count++; /* Handle test errors */ VbNvGet(vnc, VBNV_TEST_ERROR_FUNC, &test_err); if (VBNV_TEST_ERROR_LOAD_KERNEL == test_err) { /* Get error code */ VbNvGet(vnc, VBNV_TEST_ERROR_NUM, &test_err); - if (shcall) - shcall->test_error_num = (uint8_t)test_err; + shcall->test_error_num = (uint8_t)test_err; /* Clear test params so we don't repeat the error */ VbNvSet(vnc, VBNV_TEST_ERROR_FUNC, 0); VbNvSet(vnc, VBNV_TEST_ERROR_NUM, 0); @@ -237,11 +221,10 @@ int LoadKernel(LoadKernelParams* params) { } if (kBootDev == boot_mode && !dev_switch) { - /* Dev firmware should be signed such that it never boots with the dev - * switch is off; so something is terribly wrong. */ + /* Dev firmware should be signed such that it never boots with the dev + * switch is off; so something is terribly wrong. */ VBDEBUG(("LoadKernel() called with dev firmware but dev switch off\n")); - if (shcall) - shcall->check_result = VBSD_LKC_CHECK_DEV_SWITCH_MISMATCH; + shcall->check_result = VBSD_LKC_CHECK_DEV_SWITCH_MISMATCH; recovery = VBNV_RECOVERY_RW_DEV_MISMATCH; goto LoadKernelExit; } @@ -253,17 +236,14 @@ int LoadKernel(LoadKernelParams* params) { /* Let the TPM know if we're in recovery mode */ if (0 != RollbackKernelRecovery(dev_switch)) { VBDEBUG(("Error setting up TPM for recovery kernel\n")); - if (shcall) - shcall->flags |= VBSD_LK_FLAG_REC_TPM_INIT_ERROR; + shcall->flags |= VBSD_LK_FLAG_REC_TPM_INIT_ERROR; /* Ignore return code, since we need to boot recovery mode to * fix the TPM. */ } /* Read the key indices from the TPM; ignore any errors */ - if (shared) { - RollbackFirmwareRead(&shared->fw_version_tpm); - RollbackKernelRead(&shared->kernel_version_tpm); - } + RollbackFirmwareRead(&shared->fw_version_tpm); + RollbackKernelRead(&shared->kernel_version_tpm); } else { /* Use the kernel subkey passed from LoadFirmware(). */ kernel_subkey = &shared->kernel_subkey; @@ -279,8 +259,7 @@ int LoadKernel(LoadKernelParams* params) { recovery = VBNV_RECOVERY_RW_TPM_ERROR; goto LoadKernelExit; } - if (shared) - shared->kernel_version_tpm = tpm_version; + shared->kernel_version_tpm = tpm_version; } do { @@ -289,16 +268,14 @@ int LoadKernel(LoadKernelParams* params) { gpt.drive_sectors = params->ending_lba + 1; if (0 != AllocAndReadGptData(params->disk_handle, &gpt)) { VBDEBUG(("Unable to read GPT data\n")); - if (shcall) - shcall->check_result = VBSD_LKC_CHECK_GPT_READ_ERROR; + shcall->check_result = VBSD_LKC_CHECK_GPT_READ_ERROR; break; } /* Initialize GPT library */ if (GPT_SUCCESS != GptInit(&gpt)) { VBDEBUG(("Error parsing GPT\n")); - if (shcall) - shcall->check_result = VBSD_LKC_CHECK_GPT_PARSE_ERROR; + shcall->check_result = VBSD_LKC_CHECK_GPT_PARSE_ERROR; break; } @@ -323,19 +300,17 @@ int LoadKernel(LoadKernelParams* params) { VBDEBUG(("Found kernel entry at %" PRIu64 " size %" PRIu64 "\n", part_start, part_size)); - if (shcall) { - /* Set up tracking for this partition. This wraps around if called - * many times, so initialize the partition entry each time. */ - shpart = shcall->parts + (shcall->kernel_parts_found - & (VBSD_MAX_KERNEL_PARTS - 1)); - Memset(shpart, 0, sizeof(VbSharedDataKernelPart)); - shpart->sector_start = part_start; - shpart->sector_count = part_size; - /* TODO: GPT partitions start at 1, but cgptlib starts them at 0. - * Adjust here, until cgptlib is fixed. */ - shpart->gpt_index = (uint8_t)(gpt.current_kernel + 1); - shcall->kernel_parts_found++; - } + /* Set up tracking for this partition. This wraps around if called + * many times, so initialize the partition entry each time. */ + shpart = shcall->parts + (shcall->kernel_parts_found + & (VBSD_MAX_KERNEL_PARTS - 1)); + Memset(shpart, 0, sizeof(VbSharedDataKernelPart)); + shpart->sector_start = part_start; + shpart->sector_count = part_size; + /* TODO: GPT partitions start at 1, but cgptlib starts them at 0. + * Adjust here, until cgptlib is fixed. */ + shpart->gpt_index = (uint8_t)(gpt.current_kernel + 1); + shcall->kernel_parts_found++; /* Found at least one kernel partition. */ found_partitions++; @@ -343,16 +318,14 @@ int LoadKernel(LoadKernelParams* params) { /* Read the first part of the kernel partition. */ if (part_size < kbuf_sectors) { VBDEBUG(("Partition too small to hold kernel.\n")); - if (shpart) - shpart->check_result = VBSD_LKP_CHECK_TOO_SMALL; + shpart->check_result = VBSD_LKP_CHECK_TOO_SMALL; goto bad_kernel; } if (0 != VbExDiskRead(params->disk_handle, part_start, kbuf_sectors, kbuf)) { VBDEBUG(("Unable to read start of partition.\n")); - if (shpart) - shpart->check_result = VBSD_LKP_CHECK_READ_START; + shpart->check_result = VBSD_LKP_CHECK_READ_START; goto bad_kernel; } @@ -360,8 +333,7 @@ int LoadKernel(LoadKernelParams* params) { key_block = (VbKeyBlockHeader*)kbuf; if (0 != KeyBlockVerify(key_block, KBUF_SIZE, kernel_subkey, 0)) { VBDEBUG(("Verifying key block signature failed.\n")); - if (shpart) - shpart->check_result = VBSD_LKP_CHECK_KEY_BLOCK_SIG; + shpart->check_result = VBSD_LKP_CHECK_KEY_BLOCK_SIG; key_block_valid = 0; @@ -373,8 +345,7 @@ int LoadKernel(LoadKernelParams* params) { * block is valid. */ if (0 != KeyBlockVerify(key_block, KBUF_SIZE, kernel_subkey, 1)) { VBDEBUG(("Verifying key block hash failed.\n")); - if (shpart) - shpart->check_result = VBSD_LKP_CHECK_KEY_BLOCK_HASH; + shpart->check_result = VBSD_LKP_CHECK_KEY_BLOCK_HASH; goto bad_kernel; } } @@ -384,16 +355,14 @@ int LoadKernel(LoadKernelParams* params) { (dev_switch ? KEY_BLOCK_FLAG_DEVELOPER_1 : KEY_BLOCK_FLAG_DEVELOPER_0))) { VBDEBUG(("Key block developer flag mismatch.\n")); - if (shpart) - shpart->check_result = VBSD_LKP_CHECK_DEV_MISMATCH; + shpart->check_result = VBSD_LKP_CHECK_DEV_MISMATCH; key_block_valid = 0; } if (!(key_block->key_block_flags & (rec_switch ? KEY_BLOCK_FLAG_RECOVERY_1 : KEY_BLOCK_FLAG_RECOVERY_0))) { VBDEBUG(("Key block recovery flag mismatch.\n")); - if (shpart) - shpart->check_result = VBSD_LKP_CHECK_REC_MISMATCH; + shpart->check_result = VBSD_LKP_CHECK_REC_MISMATCH; key_block_valid = 0; } @@ -402,8 +371,7 @@ int LoadKernel(LoadKernelParams* params) { if (kBootRecovery != boot_mode) { if (key_version < (tpm_version >> 16)) { VBDEBUG(("Key version too old.\n")); - if (shpart) - shpart->check_result = VBSD_LKP_CHECK_KEY_ROLLBACK; + shpart->check_result = VBSD_LKP_CHECK_KEY_ROLLBACK; key_block_valid = 0; } } @@ -418,8 +386,7 @@ int LoadKernel(LoadKernelParams* params) { data_key = PublicKeyToRSA(&key_block->data_key); if (!data_key) { VBDEBUG(("Data key bad.\n")); - if (shpart) - shpart->check_result = VBSD_LKP_CHECK_DATA_KEY_PARSE; + shpart->check_result = VBSD_LKP_CHECK_DATA_KEY_PARSE; goto bad_kernel; } @@ -429,8 +396,7 @@ int LoadKernel(LoadKernelParams* params) { KBUF_SIZE - key_block->key_block_size, data_key))) { VBDEBUG(("Preamble verification failed.\n")); - if (shpart) - shpart->check_result = VBSD_LKP_CHECK_VERIFY_PREAMBLE; + shpart->check_result = VBSD_LKP_CHECK_VERIFY_PREAMBLE; goto bad_kernel; } @@ -438,13 +404,11 @@ int LoadKernel(LoadKernelParams* params) { * rollback of the kernel version. */ combined_version = ((key_version << 16) | (preamble->kernel_version & 0xFFFF)); - if (shpart) - shpart->combined_version = (uint32_t)combined_version; + shpart->combined_version = (uint32_t)combined_version; if (key_block_valid && kBootRecovery != boot_mode) { if (combined_version < tpm_version) { VBDEBUG(("Kernel version too low.\n")); - if (shpart) - shpart->check_result = VBSD_LKP_CHECK_KERNEL_ROLLBACK; + shpart->check_result = VBSD_LKP_CHECK_KERNEL_ROLLBACK; /* If we're not in developer mode, kernel version must be valid. */ if (kBootDev != boot_mode) goto bad_kernel; @@ -452,8 +416,7 @@ int LoadKernel(LoadKernelParams* params) { } VBDEBUG(("Kernel preamble is good.\n")); - if (shpart) - shpart->check_result = VBSD_LKP_CHECK_PREAMBLE_VALID; + shpart->check_result = VBSD_LKP_CHECK_PREAMBLE_VALID; /* Check for lowest version from a valid header. */ if (key_block_valid && lowest_version > combined_version) @@ -473,8 +436,7 @@ int LoadKernel(LoadKernelParams* params) { if ((preamble->body_load_address != (size_t)params->kernel_buffer) && !(params->boot_flags & BOOT_FLAG_SKIP_ADDR_CHECK)) { VBDEBUG(("Wrong body load address.\n")); - if (shpart) - shpart->check_result = VBSD_LKP_CHECK_BODY_ADDRESS; + shpart->check_result = VBSD_LKP_CHECK_BODY_ADDRESS; goto bad_kernel; } @@ -482,8 +444,7 @@ int LoadKernel(LoadKernelParams* params) { body_offset = key_block->key_block_size + preamble->preamble_size; if (0 != body_offset % blba) { VBDEBUG(("Kernel body not at multiple of sector size.\n")); - if (shpart) - shpart->check_result = VBSD_LKP_CHECK_BODY_OFFSET; + shpart->check_result = VBSD_LKP_CHECK_BODY_OFFSET; goto bad_kernel; } body_offset_sectors = body_offset / blba; @@ -492,16 +453,14 @@ int LoadKernel(LoadKernelParams* params) { body_sectors = (preamble->body_signature.data_size + blba - 1) / blba; if (body_sectors * blba > params->kernel_buffer_size) { VBDEBUG(("Kernel body doesn't fit in memory.\n")); - if (shpart) - shpart->check_result = VBSD_LKP_CHECK_BODY_EXCEEDS_MEM; + shpart->check_result = VBSD_LKP_CHECK_BODY_EXCEEDS_MEM; goto bad_kernel; } /* Verify kernel body fits in the partition */ if (body_offset_sectors + body_sectors > part_size) { VBDEBUG(("Kernel body doesn't fit in partition.\n")); - if (shpart) - shpart->check_result = VBSD_LKP_CHECK_BODY_EXCEEDS_PART; + shpart->check_result = VBSD_LKP_CHECK_BODY_EXCEEDS_PART; goto bad_kernel; } @@ -512,8 +471,7 @@ int LoadKernel(LoadKernelParams* params) { body_sectors, params->kernel_buffer)) { VBDEBUG(("Unable to read kernel data.\n")); VBPERFEND("VB_RKD"); - if (shpart) - shpart->check_result = VBSD_LKP_CHECK_READ_DATA; + shpart->check_result = VBSD_LKP_CHECK_READ_DATA; goto bad_kernel; } VBPERFEND("VB_RKD"); @@ -523,8 +481,7 @@ int LoadKernel(LoadKernelParams* params) { params->kernel_buffer_size, &preamble->body_signature, data_key)) { VBDEBUG(("Kernel data verification failed.\n")); - if (shpart) - shpart->check_result = VBSD_LKP_CHECK_VERIFY_DATA; + shpart->check_result = VBSD_LKP_CHECK_VERIFY_DATA; goto bad_kernel; } @@ -535,11 +492,9 @@ int LoadKernel(LoadKernelParams* params) { /* If we're still here, the kernel is valid. */ /* Save the first good partition we find; that's the one we'll boot */ VBDEBUG(("Partition is good.\n")); - if (shpart) { - shpart->check_result = VBSD_LKP_CHECK_KERNEL_GOOD; - if (key_block_valid) - shpart->flags |= VBSD_LKP_FLAG_KEY_BLOCK_VALID; - } + shpart->check_result = VBSD_LKP_CHECK_KERNEL_GOOD; + if (key_block_valid) + shpart->flags |= VBSD_LKP_FLAG_KEY_BLOCK_VALID; good_partition_key_block_valid = key_block_valid; /* TODO: GPT partitions start at 1, but cgptlib starts them at 0. @@ -597,8 +552,7 @@ int LoadKernel(LoadKernelParams* params) { /* Handle finding a good partition */ if (good_partition >= 0) { VBDEBUG(("Good_partition >= 0\n")); - if (shcall) - shcall->check_result = VBSD_LKC_CHECK_GOOD_PARTITION; + shcall->check_result = VBSD_LKC_CHECK_GOOD_PARTITION; /* See if we need to update the TPM */ if ((kBootNormal == boot_mode) && @@ -619,8 +573,7 @@ int LoadKernel(LoadKernelParams* params) { recovery = VBNV_RECOVERY_RW_TPM_ERROR; goto LoadKernelExit; } - if (shared) - shared->kernel_version_tpm = (uint32_t)lowest_version; + shared->kernel_version_tpm = (uint32_t)lowest_version; } } @@ -641,10 +594,9 @@ int LoadKernel(LoadKernelParams* params) { /* Success! */ retval = LOAD_KERNEL_SUCCESS; } else { - if (shcall) - shcall->check_result = (found_partitions > 0 - ? VBSD_LKC_CHECK_INVALID_PARTITIONS - : VBSD_LKC_CHECK_NO_PARTITIONS); + shcall->check_result = (found_partitions > 0 + ? VBSD_LKC_CHECK_INVALID_PARTITIONS + : VBSD_LKC_CHECK_NO_PARTITIONS); /* TODO: differentiate between finding an invalid kernel * (found_partitions>0) and not finding one at all. Right now we @@ -659,20 +611,14 @@ LoadKernelExit: recovery : VBNV_RECOVERY_NOT_REQUESTED); VbNvTeardown(vnc); - if (shared) { - if (shcall) - shcall->return_code = (uint8_t)retval; + shcall->return_code = (uint8_t)retval; - /* Save whether the good partition's key block was fully verified */ - if (good_partition_key_block_valid) - shared->flags |= VBSD_KERNEL_KEY_VERIFIED; + /* Save whether the good partition's key block was fully verified */ + if (good_partition_key_block_valid) + shared->flags |= VBSD_KERNEL_KEY_VERIFIED; - /* Save timer values */ - shared->timer_load_kernel_enter = timer_enter; - shared->timer_load_kernel_exit = VbExGetTimer(); - /* Store how much shared data we used, if any */ - params->shared_data_size = shared->data_used; - } + /* Store how much shared data we used, if any */ + params->shared_data_size = shared->data_used; return retval; } diff --git a/firmware/linktest/main.c b/firmware/linktest/main.c index 49500b71..4aae27d9 100644 --- a/firmware/linktest/main.c +++ b/firmware/linktest/main.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2010 The Chromium OS Authors. All rights reserved. +/* Copyright (c) 2011 The Chromium OS Authors. All rights reserved. * Use of this source code is governed by a BSD-style license that can be * found in the LICENSE file. */ @@ -65,7 +65,6 @@ int main(void) TlclGetPermissions(0, 0); /* vboot_api.h - entry points INTO vboot_reference */ - VbS3Resume(); VbInit(0, 0); VbSelectFirmware(0, 0); VbUpdateFirmwareBodyHash(0, 0, 0); diff --git a/host/lib/crossystem.c b/host/lib/crossystem.c index 72f2c666..88afde25 100644 --- a/host/lib/crossystem.c +++ b/host/lib/crossystem.c @@ -277,12 +277,12 @@ char* GetVdatString(char* dest, int size, VdatStringField field) "LFS=%" PRIu64 ",%" PRIu64 " LF=%" PRIu64 ",%" PRIu64 " LK=%" PRIu64 ",%" PRIu64, - sh->timer_load_firmware_start_enter, - sh->timer_load_firmware_start_exit, - sh->timer_load_firmware_enter, - sh->timer_load_firmware_exit, - sh->timer_load_kernel_enter, - sh->timer_load_kernel_exit); + sh->timer_vb_init_enter, + sh->timer_vb_init_exit, + sh->timer_vb_select_firmware_enter, + sh->timer_vb_select_firmware_exit, + sh->timer_vb_select_and_load_kernel_enter, + sh->timer_vb_select_and_load_kernel_exit); break; case VDAT_STRING_LOAD_FIRMWARE_DEBUG: |