Exemplo n.º 1
0
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;
}