int main(int argc, char** argv) { uint8_t disable, deactivated; int i; TlclLibInit(); TPM_CHECK(TlclStartupIfNeeded()); TPM_CHECK(TlclSelfTestFull()); TPM_CHECK(TlclAssertPhysicalPresence()); TPM_CHECK(TlclGetFlags(&disable, &deactivated, NULL)); printf("disable is %d, deactivated is %d\n", disable, deactivated); for (i = 0; i < 2; i++) { TPM_CHECK(TlclForceClear()); TPM_CHECK(TlclGetFlags(&disable, &deactivated, NULL)); printf("disable is %d, deactivated is %d\n", disable, deactivated); VbAssert(disable == 1 && deactivated == 1); TPM_CHECK(TlclSetEnable()); TPM_CHECK(TlclSetDeactivated(0)); TPM_CHECK(TlclGetFlags(&disable, &deactivated, NULL)); printf("disable is %d, deactivated is %d\n", disable, deactivated); VbAssert(disable == 0 && deactivated == 0); } printf("TEST SUCCEEDED\n"); return 0; }
VbError_t VbSelectFirmware(VbCommonParams *cparams, VbSelectFirmwareParams *fparams) { VbSharedDataHeader *shared = (VbSharedDataHeader *)cparams->shared_data_blob; VbNvContext vnc; VbError_t retval = VBERROR_UNKNOWN; /* Default to error */ int is_rec = (shared->recovery_reason ? 1 : 0); int is_dev = (shared->flags & VBSD_BOOT_DEV_SWITCH_ON ? 1 : 0); uint32_t tpm_status = 0; /* Start timer */ shared->timer_vb_select_firmware_enter = VbExGetTimer(); /* Load NV storage */ VbExNvStorageRead(vnc.raw); VbNvSetup(&vnc); if (is_rec) { /* * Recovery is requested; go straight to recovery without * checking the RW firmware. */ VBDEBUG(("VbSelectFirmware() detected recovery request\n")); /* Go directly to recovery mode */ fparams->selected_firmware = VB_SELECT_FIRMWARE_RECOVERY; } else { /* Chain to LoadFirmware() */ retval = LoadFirmware(cparams, fparams, &vnc); /* Exit if we failed to find an acceptable firmware */ if (VBERROR_SUCCESS != retval) goto VbSelectFirmware_exit; /* Translate the selected firmware path */ if (shared->flags & VBSD_LF_USE_RO_NORMAL) { /* Request the read-only normal/dev code path */ fparams->selected_firmware = VB_SELECT_FIRMWARE_READONLY; } else if (0 == shared->firmware_index) fparams->selected_firmware = VB_SELECT_FIRMWARE_A; else { fparams->selected_firmware = VB_SELECT_FIRMWARE_B; } /* Update TPM if necessary */ if (shared->fw_version_tpm_start < shared->fw_version_tpm) { tpm_status = RollbackFirmwareWrite(shared->fw_version_tpm); if (0 != tpm_status) { VBDEBUG(("Can't write FW version to TPM.\n")); VbNvSet(&vnc, VBNV_RECOVERY_REQUEST, VBNV_RECOVERY_RO_TPM_W_ERROR); retval = VBERROR_TPM_WRITE_FIRMWARE; goto VbSelectFirmware_exit; } } /* Lock firmware versions in TPM */ tpm_status = RollbackFirmwareLock(); if (0 != tpm_status) { VBDEBUG(("Unable to lock firmware version in TPM.\n")); VbNvSet(&vnc, VBNV_RECOVERY_REQUEST, VBNV_RECOVERY_RO_TPM_L_ERROR); retval = VBERROR_TPM_LOCK_FIRMWARE; goto VbSelectFirmware_exit; } } /* * At this point, we have a good idea of how we are going to * boot. Update the TPM with this state information. */ tpm_status = SetTPMBootModeState(is_dev, is_rec, shared->fw_keyblock_flags); if (0 != tpm_status) { VBDEBUG(("Can't update the TPM with boot mode information.\n")); if (!is_rec) { VbNvSet(&vnc, VBNV_RECOVERY_REQUEST, VBNV_RECOVERY_RO_TPM_U_ERROR); retval = VBERROR_TPM_SET_BOOT_MODE_STATE; goto VbSelectFirmware_exit; } } /* Success! */ retval = VBERROR_SUCCESS; VbSelectFirmware_exit: /* Save NV storage */ VbNvTeardown(&vnc); if (vnc.raw_changed) VbExNvStorageWrite(vnc.raw); /* Stop timer */ shared->timer_vb_select_firmware_exit = VbExGetTimer(); /* Should always have a known error code */ VbAssert(VBERROR_UNKNOWN != retval); return retval; }