diff options
29 files changed, 3 insertions, 4166 deletions
@@ -46,9 +46,7 @@ VBSF_SRCS = \ firmware/lib/cryptolib/sha512.c \ firmware/lib/cryptolib/sha_utility.c \ firmware/lib/stateful_util.c \ - firmware/lib/vboot_api_firmware.c \ firmware/lib/vboot_common.c \ - firmware/lib/vboot_firmware.c \ firmware/lib/region-fw.c \ # Additional firmware library sources needed by VbSelectAndLoadKernel() call @@ -316,10 +316,8 @@ BDBLIB = ${BUILD}/bdb.a VBINIT_SRCS = \ firmware/lib/crc8.c \ firmware/lib/utility.c \ - firmware/lib/vboot_api_init.c \ firmware/lib/vboot_common_init.c \ firmware/lib/vboot_nvstorage.c \ - firmware/lib/vboot_nvstorage_rollback.c \ firmware/lib/region-init.c \ # Additional firmware library sources needed by VbSelectFirmware() call @@ -328,9 +326,7 @@ VBSF_SRCS = \ firmware/lib/cryptolib/rsa.c \ firmware/lib/cryptolib/rsa_utility.c \ firmware/lib/stateful_util.c \ - firmware/lib/vboot_api_firmware.c \ firmware/lib/vboot_common.c \ - firmware/lib/vboot_firmware.c \ firmware/lib/region-fw.c \ # Additional firmware library sources needed by VbSelectAndLoadKernel() call @@ -401,16 +397,10 @@ ifeq (${MOCK_TPM},) VBINIT_SRCS += \ firmware/lib/rollback_index.c \ ${TLCL_SRCS} - -VBSF_SRCS += \ - firmware/lib/tpm_bootmode.c else VBINIT_SRCS += \ firmware/lib/mocked_rollback_index.c \ firmware/lib/tpm_lite/mocked_tlcl.c - -VBSF_SRCS += \ - firmware/lib/mocked_tpm_bootmode.c endif ifeq (${FIRMWARE_ARCH},) @@ -737,12 +727,9 @@ TEST_NAMES = \ tests/rsa_verify_benchmark \ tests/sha_benchmark \ tests/stateful_util_tests \ - tests/tpm_bootmode_tests \ tests/utility_string_tests \ tests/utility_tests \ - tests/vboot_api_init_tests \ tests/vboot_api_devmode_tests \ - tests/vboot_api_firmware_tests \ tests/vboot_api_kernel_tests \ tests/vboot_api_kernel2_tests \ tests/vboot_api_kernel3_tests \ @@ -754,7 +741,6 @@ TEST_NAMES = \ tests/vboot_common2_tests \ tests/vboot_common3_tests \ tests/vboot_display_tests \ - tests/vboot_firmware_tests \ tests/vboot_kernel_tests \ tests/vboot_nvstorage_test \ tests/verify_kernel @@ -944,21 +930,12 @@ ${FWLIB21_OBJS}: INCLUDES += -Ifirmware/lib21/include ${BDBLIB_OBJS}: INCLUDES += -Ifirmware/bdb # Linktest ensures firmware lib doesn't rely on outside libraries -${BUILD}/firmware/linktest/main_vbinit: ${VBINIT_OBJS} -${BUILD}/firmware/linktest/main_vbinit: OBJS = ${VBINIT_OBJS} -TEST_OBJS += ${BUILD}/firmware/linktest/main_vbinit.o -${BUILD}/firmware/linktest/main_vbsf: ${FWLIB} -${BUILD}/firmware/linktest/main_vbsf: LIBS = ${FWLIB} -TEST_OBJS += ${BUILD}/firmware/linktest/main_vbsf.o ${BUILD}/firmware/linktest/main: ${FWLIB} ${BUILD}/firmware/linktest/main: LIBS = ${FWLIB} TEST_OBJS += ${BUILD}/firmware/linktest/main.o .PHONY: fwlinktest -fwlinktest: \ - ${BUILD}/firmware/linktest/main_vbinit \ - ${BUILD}/firmware/linktest/main_vbsf \ - ${BUILD}/firmware/linktest/main +fwlinktest: ${BUILD}/firmware/linktest/main .PHONY: fwlib fwlib: $(if ${FIRMWARE_ARCH},${FWLIB},fwlinktest) @@ -1456,12 +1433,9 @@ runmisctests: test_setup ${RUNTEST} ${BUILD_RUN}/tests/rsa_utility_tests ${RUNTEST} ${BUILD_RUN}/tests/stateful_util_tests ${RUNTEST} ${BUILD_RUN}/tests/tlcl_tests - ${RUNTEST} ${BUILD_RUN}/tests/tpm_bootmode_tests ${RUNTEST} ${BUILD_RUN}/tests/utility_string_tests ${RUNTEST} ${BUILD_RUN}/tests/utility_tests ${RUNTEST} ${BUILD_RUN}/tests/vboot_api_devmode_tests - ${RUNTEST} ${BUILD_RUN}/tests/vboot_api_firmware_tests - ${RUNTEST} ${BUILD_RUN}/tests/vboot_api_init_tests ${RUNTEST} ${BUILD_RUN}/tests/vboot_api_kernel_tests ${RUNTEST} ${BUILD_RUN}/tests/vboot_api_kernel2_tests ${RUNTEST} ${BUILD_RUN}/tests/vboot_api_kernel3_tests @@ -1473,7 +1447,6 @@ runmisctests: test_setup ${RUNTEST} ${BUILD_RUN}/tests/vboot_common2_tests ${TEST_KEYS} ${RUNTEST} ${BUILD_RUN}/tests/vboot_common3_tests ${TEST_KEYS} ${RUNTEST} ${BUILD_RUN}/tests/vboot_display_tests - ${RUNTEST} ${BUILD_RUN}/tests/vboot_firmware_tests ${RUNTEST} ${BUILD_RUN}/tests/vboot_kernel_tests ${RUNTEST} ${BUILD_RUN}/tests/vboot_nvstorage_test diff --git a/firmware/include/vboot_api.h b/firmware/include/vboot_api.h index 1a166344..75b20f38 100644 --- a/firmware/include/vboot_api.h +++ b/firmware/include/vboot_api.h @@ -365,36 +365,6 @@ typedef struct VbSelectAndLoadKernelParams { } VbSelectAndLoadKernelParams; /** - * Initialize the verified boot library. - * - * Returns VBERROR_SUCCESS if success, non-zero if error; on error, - * caller should reboot. - */ -VbError_t VbInit(VbCommonParams *cparams, VbInitParams *iparams); - -/** - * Select the main firmware. - * - * Returns VBERROR_SUCCESS if success, non-zero if error; on error, - * caller should reboot. - * - * NOTE: This is now called in all modes, including recovery. Previously, - * LoadFirmware() was not called in recovery mode, which meant that - * LoadKernel() needed to duplicate the TPM and VbSharedData initialization - * code. - */ -VbError_t VbSelectFirmware(VbCommonParams *cparams, - VbSelectFirmwareParams *fparams); - -/** - * Update the data hash for the current firmware image, extending it by [size] - * bytes stored in [*data]. This function must only be called inside - * VbExHashFirmwareBody(), which is in turn called by VbSelectFirmware(). - */ -void VbUpdateFirmwareBodyHash(VbCommonParams *cparams, - uint8_t *data, uint32_t size); - -/** * Select and loads the kernel. * * Returns VBERROR_SUCCESS if success, non-zero if error; on error, caller diff --git a/firmware/include/vboot_nvstorage.h b/firmware/include/vboot_nvstorage.h index ef78e47a..48f93d5a 100644 --- a/firmware/include/vboot_nvstorage.h +++ b/firmware/include/vboot_nvstorage.h @@ -348,26 +348,4 @@ int VbNvGet(VbNvContext *context, VbNvParam param, uint32_t *dest); */ int VbNvSet(VbNvContext *context, VbNvParam param, uint32_t value); -/** - * Attempt to restore some fields of a lost VbNvContext from a backup area. - * The rest of the fields are unchanged, so they'd need to be set to their - * appropriate defaults by calling VbNvSetup() first (which is usually how we - * know the fields have been lost). - * - * Returns 0 if success, non-zero if error. - * - * This may only be called between VbNvSetup() and VbNvTeardown(). - */ -int RestoreNvFromBackup(VbNvContext *vnc); - -/** - * Attempt to save some fields of the VbNvContext to a backup area. - * - * Returns 0 if success, non-zero if error. If it succeeds, it will clear the - * VBNV_BACKUP_NVRAM_REQUEST flag in the VbNvContext. - * - * This may only be called when the backup area is writable. - */ -int SaveNvToBackup(VbNvContext *vnc); - #endif /* VBOOT_REFERENCE_NVSTORAGE_H_ */ diff --git a/firmware/lib/include/load_firmware_fw.h b/firmware/lib/include/load_firmware_fw.h deleted file mode 100644 index 555cf6fd..00000000 --- a/firmware/lib/include/load_firmware_fw.h +++ /dev/null @@ -1,29 +0,0 @@ -/* Copyright (c) 2013 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. - * - * High-level firmware API for loading and verifying rewritable firmware. - * (Firmware Portion) - */ - -#ifndef VBOOT_REFERENCE_LOAD_FIRMWARE_FW_H_ -#define VBOOT_REFERENCE_LOAD_FIRMWARE_FW_H_ - -#include "vboot_api.h" -#include "vboot_nvstorage.h" -#include "vboot_struct.h" - -/** - * Load the rewritable firmware. - * - * Pass the common and firmware params from VbSelectFirmware(), and a - * VbNvContext. Caller is responsible for calling VbNvSetup() and - * VbNvTeardown() on the VbNvContext. - * - * Returns VBERROR_SUCCESS if successful. If unsuccessful, sets a recovery - * reason via VbNvStorage and returns an error code. - */ -int LoadFirmware(VbCommonParams *cparams, VbSelectFirmwareParams *fparams, - VbNvContext *vnc); - -#endif /* VBOOT_REFERENCE_LOAD_FIRMWARE_FW_H_ */ diff --git a/firmware/lib/include/rollback_index.h b/firmware/lib/include/rollback_index.h index 6cc9ee61..22a753a9 100644 --- a/firmware/lib/include/rollback_index.h +++ b/firmware/lib/include/rollback_index.h @@ -103,37 +103,6 @@ enum fwmp_flags { /* All functions return TPM_SUCCESS (zero) if successful, non-zero if error */ /* - * These functions are called from VbInit(). They cannot use global - * variables. - */ - -uint32_t RollbackS3Resume(void); - -/* - * These functions are callable from VbSelectFirmware(). They cannot use - * global variables. - */ - -/** - * This must be called. - */ -uint32_t RollbackFirmwareSetup(int is_hw_dev, - int disable_dev_request, - int clear_tpm_owner_request, - /* two outputs on success */ - int *is_virt_dev, uint32_t *tpm_version); - -/** - * Write may be called if the versions change. - */ -uint32_t RollbackFirmwareWrite(uint32_t version); - -/** - * Lock must be called. - */ -uint32_t RollbackFirmwareLock(void); - -/* * These functions are callable from VbSelectAndLoadKernel(). They may use * global variables. */ @@ -149,16 +118,6 @@ uint32_t RollbackKernelRead(uint32_t *version); uint32_t RollbackKernelWrite(uint32_t version); /** - * Read backup data. - */ -uint32_t RollbackBackupRead(uint8_t *raw); - -/** - * Write backup data. - */ -uint32_t RollbackBackupWrite(uint8_t *raw); - -/** * Lock must be called. Internally, it's ignored in recovery mode. */ uint32_t RollbackKernelLock(int recovery_mode); @@ -193,31 +152,6 @@ uint32_t TPMClearAndReenable(void); uint32_t SafeWrite(uint32_t index, const void *data, uint32_t length); /** - * Similarly to SafeWrite(), this ensures we don't fail a DefineSpace because - * we hit the TPM write limit. This is even less likely to happen than with - * writes because we only define spaces once at initialization, but we'd rather - * be paranoid about this. - */ -uint32_t SafeDefineSpace(uint32_t index, uint32_t perm, uint32_t size); - -/** - * Perform one-time initializations. - * - * Create the NVRAM spaces, and set their initial values as needed. Sets the - * nvLocked bit and ensures the physical presence command is enabled and - * locked. - */ -uint32_t OneTimeInitializeTPM(RollbackSpaceFirmware *rsf, - RollbackSpaceKernel *rsk); - -/** - * Start the TPM and establish the root of trust for the anti-rollback - * mechanism. - */ -uint32_t SetupTPM(int developer_mode, int disable_dev_request, - int clear_tpm_owner_request, RollbackSpaceFirmware *rsf); - -/** * Utility function to turn the virtual dev-mode flag on or off. 0=off, 1=on. */ uint32_t SetVirtualDevMode(int val); diff --git a/firmware/lib/include/tpm_bootmode.h b/firmware/lib/include/tpm_bootmode.h deleted file mode 100644 index 75509497..00000000 --- a/firmware/lib/include/tpm_bootmode.h +++ /dev/null @@ -1,29 +0,0 @@ -/* Copyright (c) 2013 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. - * - * Functions for updating the TPM state with the status of boot path. - */ - -#ifndef VBOOT_REFERENCE_TPM_BOOTMODE_H_ -#define VBOOT_REFERENCE_TPM_BOOTMODE_H_ - -#include "gbb_header.h" -#include "sysincludes.h" - -/** - * Update TPM PCR State with the boot path status. - * - * [developer_mode]: State of the developer switch. - * [recovery_mode]: State of the recovery mode. - * [fw_keyblock_flags]: Keyblock flags of the to-be-booted - * RW firmware keyblock. - * [gbb]: Pointer to GBB header from RO firmware. - * - * Returns: TPM_SUCCESS if the TPM extend operation succeeds. - */ -uint32_t SetTPMBootModeState(int developer_mode, int recovery_mode, - uint64_t fw_keyblock_flags, - GoogleBinaryBlockHeader *gbb); - -#endif /* VBOOT_REFERENCE_TPM_BOOTMODE_H_ */ diff --git a/firmware/lib/include/vboot_kernel.h b/firmware/lib/include/vboot_kernel.h index 2f1be5be..2c69f969 100644 --- a/firmware/lib/include/vboot_kernel.h +++ b/firmware/lib/include/vboot_kernel.h @@ -11,7 +11,6 @@ #include "cgptlib.h" #include "gpt_misc.h" -#include "load_firmware_fw.h" #include "load_kernel_fw.h" #include "vboot_api.h" diff --git a/firmware/lib/mocked_rollback_index.c b/firmware/lib/mocked_rollback_index.c index d20ca23a..bb253d15 100644 --- a/firmware/lib/mocked_rollback_index.c +++ b/firmware/lib/mocked_rollback_index.c @@ -18,71 +18,23 @@ uint32_t SetVirtualDevMode(int val) { return TPM_SUCCESS; } - uint32_t TPMClearAndReenable(void) { return TPM_SUCCESS; } - -uint32_t SetupTPM(int developer_mode, int disable_dev_request, - int clear_tpm_owner_request, RollbackSpaceFirmware* rsf) { - return TPM_SUCCESS; -} - - -uint32_t RollbackS3Resume(void) { - return TPM_SUCCESS; -} - - -uint32_t RollbackFirmwareSetup(int is_hw_dev, - int disable_dev_request, - int clear_tpm_owner_request, - int *is_virt_dev, uint32_t *version) { - *version = 0; - return TPM_SUCCESS; -} - - -uint32_t RollbackFirmwareWrite(uint32_t version) { - return TPM_SUCCESS; -} - - -uint32_t RollbackFirmwareLock(void) { - return TPM_SUCCESS; -} - - uint32_t RollbackKernelRead(uint32_t* version) { *version = 0; return TPM_SUCCESS; } - uint32_t RollbackKernelWrite(uint32_t version) { return TPM_SUCCESS; } - uint32_t RollbackKernelLock(int recovery_mode) { return TPM_SUCCESS; } -static uint8_t rollback_backup[BACKUP_NV_SIZE]; - -uint32_t RollbackBackupRead(uint8_t *raw) -{ - Memcpy(raw, rollback_backup, BACKUP_NV_SIZE); - return TPM_SUCCESS; -} - -uint32_t RollbackBackupWrite(uint8_t *raw) -{ - Memcpy(rollback_backup, raw, BACKUP_NV_SIZE); - return TPM_SUCCESS; -} - uint32_t RollbackFwmpRead(struct RollbackSpaceFwmp *fwmp) { Memset(fwmp, 0, sizeof(*fwmp)); diff --git a/firmware/lib/mocked_tpm_bootmode.c b/firmware/lib/mocked_tpm_bootmode.c deleted file mode 100644 index c1a02717..00000000 --- a/firmware/lib/mocked_tpm_bootmode.c +++ /dev/null @@ -1,69 +0,0 @@ -/* 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. - * - * Functions for updating the TPM state with the status of boot path. - */ - -#include "sysincludes.h" - -#include "tpm_bootmode.h" -#include "tss_constants.h" - -const char* kBootStateSHA1Digests[] = { - /* SHA1("\x00\x00\x00") */ - "\x29\xe2\xdc\xfb\xb1\x6f\x63\xbb\x02\x54\xdf\x75\x85\xa1\x5b\xb6" - "\xfb\x5e\x92\x7d", - - /* SHA1("\x00\x00\x01") */ - "\x25\x47\xcc\x73\x6e\x95\x1f\xa4\x91\x98\x53\xc4\x3a\xe8\x90\x86" - "\x1a\x3b\x32\x64", - - /* SHA1("\x00\x00\x02") */ - "\x1e\xf6\x24\x48\x2d\x62\x0e\x43\xe6\xd3\x4d\xa1\xaf\xe4\x62\x67" - "\xfc\x69\x5d\x9b", - - /* SHA1("\x00\x01\x00") */ - "\x62\x57\x18\x91\x21\x5b\x4e\xfc\x1c\xea\xb7\x44\xce\x59\xdd\x0b" - "\x66\xea\x6f\x73", - - /* SHA1("\x00\x01\x01") */ - "\xee\xe4\x47\xed\xc7\x9f\xea\x1c\xa7\xc7\xd3\x4e\x46\x32\x61\xcd" - "\xa4\xba\x33\x9e", - - /* SHA1("\x00\x01\x02") */ - "\x0c\x7a\x62\x3f\xd2\xbb\xc0\x5b\x06\x42\x3b\xe3\x59\xe4\x02\x1d" - "\x36\xe7\x21\xad", - - /* SHA1("\x01\x00\x00") */ - "\x95\x08\xe9\x05\x48\xb0\x44\x0a\x4a\x61\xe5\x74\x3b\x76\xc1\xe3" - "\x09\xb2\x3b\x7f", - - /* SHA1("\x01\x00\x01") */ - "\xc4\x2a\xc1\xc4\x6f\x1d\x4e\x21\x1c\x73\x5c\xc7\xdf\xad\x4f\xf8" - "\x39\x11\x10\xe9", - - /* SHA1("\x01\x00\x02") */ - "\xfa\x01\x0d\x26\x64\xcc\x5b\x3b\x82\xee\x48\x8f\xe2\xb9\xf5\x0f" - "\x49\x32\xeb\x8f", - - /* SHA1("\x01\x01\x00") */ - "\x47\xec\x8d\x98\x36\x64\x33\xdc\x00\x2e\x77\x21\xc9\xe3\x7d\x50" - "\x67\x54\x79\x37", - - /* SHA1("\x01\x01\x01") */ - "\x28\xd8\x6c\x56\xb3\xbf\x26\xd2\x36\x56\x9b\x8d\xc8\xc3\xf9\x1f" - "\x32\xf4\x7b\xc7", - - /* SHA1("\x01\x01\x02") */ - "\x12\xa3\x40\xd7\x89\x7f\xe7\x13\xfc\x8f\x02\xac\x53\x65\xb8\x6e" - "\xbf\x35\x31\x78", -}; - - -uint32_t SetTPMBootModeState(int developer_mode, int recovery_mode, - uint64_t fw_keyblock_flags, - GoogleBinaryBlockHeader *gbb) -{ - return TPM_SUCCESS; -} diff --git a/firmware/lib/rollback_index.c b/firmware/lib/rollback_index.c index 2431e98f..cf446d98 100644 --- a/firmware/lib/rollback_index.c +++ b/firmware/lib/rollback_index.c @@ -69,17 +69,6 @@ uint32_t SafeWrite(uint32_t index, const void *data, uint32_t length) } } -uint32_t SafeDefineSpace(uint32_t index, uint32_t perm, uint32_t size) -{ - uint32_t result = TlclDefineSpace(index, perm, size); - if (result == TPM_E_MAXNVWRITES) { - RETURN_ON_FAILURE(TPMClearAndReenable()); - return TlclDefineSpace(index, perm, size); - } else { - return result; - } -} - /* Functions to read and write firmware and kernel spaces. */ uint32_t ReadSpaceFirmware(RollbackSpaceFirmware *rsf) { @@ -167,7 +156,7 @@ uint32_t SetVirtualDevMode(int val) rsf.flags &= ~FLAG_VIRTUAL_DEV_MODE_ON; /* * NOTE: This doesn't update the FLAG_LAST_BOOT_DEVELOPER bit. That - * will be done by SetupTPM() on the next boot. + * will be done on the next boot. */ VBDEBUG(("TPM: flags are now 0x%02x\n", rsf.flags)); @@ -247,293 +236,9 @@ uint32_t WriteSpaceKernel(RollbackSpaceKernel *rsk) return TPM_E_CORRUPTED_STATE; } -#ifndef TPM2_MODE -uint32_t OneTimeInitializeTPM(RollbackSpaceFirmware *rsf, - RollbackSpaceKernel *rsk) -{ - static const RollbackSpaceFirmware rsf_init = { - .struct_version = ROLLBACK_SPACE_FIRMWARE_VERSION, - }; - static const RollbackSpaceKernel rsk_init = { - .struct_version = ROLLBACK_SPACE_KERNEL_VERSION, - .uid = ROLLBACK_SPACE_KERNEL_UID, - }; - TPM_PERMANENT_FLAGS pflags; - uint32_t result; - - VBDEBUG(("TPM: One-time initialization\n")); - - /* - * Do a full test. This only happens the first time the device is - * turned on in the factory, so performance is not an issue. This is - * almost certainly not necessary, but it gives us more confidence - * about some code paths below that are difficult to - * test---specifically the ones that set lifetime flags, and are only - * executed once per physical TPM. - */ - result = TlclSelfTestFull(); - if (result != TPM_SUCCESS) - return result; - - result = TlclGetPermanentFlags(&pflags); - if (result != TPM_SUCCESS) - return result; - - /* - * TPM may come from the factory without physical presence finalized. - * Fix if necessary. - */ - VBDEBUG(("TPM: physicalPresenceLifetimeLock=%d\n", - pflags.physicalPresenceLifetimeLock)); - if (!pflags.physicalPresenceLifetimeLock) { - VBDEBUG(("TPM: Finalizing physical presence\n")); - RETURN_ON_FAILURE(TlclFinalizePhysicalPresence()); - } - - /* - * The TPM will not enforce the NV authorization restrictions until the - * execution of a TPM_NV_DefineSpace with the handle of - * TPM_NV_INDEX_LOCK. Here we create that space if it doesn't already - * exist. */ - VBDEBUG(("TPM: nvLocked=%d\n", pflags.nvLocked)); - if (!pflags.nvLocked) { - VBDEBUG(("TPM: Enabling NV locking\n")); - RETURN_ON_FAILURE(TlclSetNvLocked()); - } - - /* Clear TPM owner, in case the TPM is already owned for some reason. */ - VBDEBUG(("TPM: Clearing owner\n")); - RETURN_ON_FAILURE(TPMClearAndReenable()); - - /* Initializes the firmware and kernel spaces */ - Memcpy(rsf, &rsf_init, sizeof(RollbackSpaceFirmware)); - Memcpy(rsk, &rsk_init, sizeof(RollbackSpaceKernel)); - - /* Define the backup space. No need to initialize it, though. */ - RETURN_ON_FAILURE(SafeDefineSpace( - BACKUP_NV_INDEX, TPM_NV_PER_PPWRITE, BACKUP_NV_SIZE)); - - /* Define and initialize the kernel space */ - RETURN_ON_FAILURE(SafeDefineSpace(KERNEL_NV_INDEX, TPM_NV_PER_PPWRITE, - sizeof(RollbackSpaceKernel))); - RETURN_ON_FAILURE(WriteSpaceKernel(rsk)); - - /* Do the firmware space last, so we retry if we don't get this far. */ - RETURN_ON_FAILURE(SafeDefineSpace( - FIRMWARE_NV_INDEX, - TPM_NV_PER_GLOBALLOCK | TPM_NV_PER_PPWRITE, - sizeof(RollbackSpaceFirmware))); - RETURN_ON_FAILURE(WriteSpaceFirmware(rsf)); - - return TPM_SUCCESS; -} -#endif - -/* - * SetupTPM starts the TPM and establishes the root of trust for the - * anti-rollback mechanism. SetupTPM can fail for three reasons. 1 A bug. 2 a - * TPM hardware failure. 3 An unexpected TPM state due to some attack. In - * general we cannot easily distinguish the kind of failure, so our strategy is - * to reboot in recovery mode in all cases. The recovery mode calls SetupTPM - * again, which executes (almost) the same sequence of operations. There is a - * good chance that, if recovery mode was entered because of a TPM failure, the - * failure will repeat itself. (In general this is impossible to guarantee - * because we have no way of creating the exact TPM initial state at the - * previous boot.) In recovery mode, we ignore the failure and continue, thus - * giving the recovery kernel a chance to fix things (that's why we don't set - * bGlobalLock). The choice is between a knowingly insecure device and a - * bricked device. - * - * As a side note, observe that we go through considerable hoops to avoid using - * the STCLEAR permissions for the index spaces. We do this to avoid writing - * to the TPM flashram at every reboot or wake-up, because of concerns about - * the durability of the NVRAM. - */ -uint32_t SetupTPM(int developer_mode, int disable_dev_request, - int clear_tpm_owner_request, RollbackSpaceFirmware* rsf) -{ - uint8_t in_flags; -#ifndef TPM2_MODE - uint8_t disable; - uint8_t deactivated; -#endif - uint32_t result; - uint32_t versions; - - RETURN_ON_FAILURE(TlclLibInit()); - -#ifdef TEGRA_SOFT_REBOOT_WORKAROUND - result = TlclStartup(); - if (result == TPM_E_INVALID_POSTINIT) { - /* - * Some prototype hardware doesn't reset the TPM on a CPU - * reset. We do a hard reset to get around this. - */ - VBDEBUG(("TPM: soft reset detected\n", result)); - return TPM_E_MUST_REBOOT; - } else if (result != TPM_SUCCESS) { - VBDEBUG(("TPM: TlclStartup returned %08x\n", result)); - return result; - } -#else - RETURN_ON_FAILURE(TlclStartup()); -#endif - - /* - * Some TPMs start the self test automatically at power on. In that case we - * don't need to call ContinueSelfTest. On some (other) TPMs, - * ContinueSelfTest may block. In that case, we definitely don't want to - * call it here. For TPMs in the intersection of these two sets, we're - * screwed. (In other words: TPMs that require manually starting the - * self-test AND block will have poor performance until we split - * TlclSendReceive() into Send() and Receive(), and have a state machine to - * control setup.) - * - * This comment is likely to become obsolete in the near future, so don't - * trust it. It may have not been updated. - */ -#ifdef TPM_MANUAL_SELFTEST -#ifdef TPM_BLOCKING_CONTINUESELFTEST -#warning "lousy TPM!" -#endif - RETURN_ON_FAILURE(TlclContinueSelfTest()); -#endif -#ifndef TPM2_MODE - result = TlclAssertPhysicalPresence(); - if (result != TPM_SUCCESS) { - /* - * It is possible that the TPM was delivered with the physical - * presence command disabled. This tries enabling it, then - * tries asserting PP again. - */ - RETURN_ON_FAILURE(TlclPhysicalPresenceCMDEnable()); - RETURN_ON_FAILURE(TlclAssertPhysicalPresence()); - } - - /* Check that the TPM is enabled and activated. */ - RETURN_ON_FAILURE(TlclGetFlags(&disable, &deactivated, NULL)); - if (disable || deactivated) { - VBDEBUG(("TPM: disabled (%d) or deactivated (%d). Fixing...\n", - disable, deactivated)); - RETURN_ON_FAILURE(TlclSetEnable()); - RETURN_ON_FAILURE(TlclSetDeactivated(0)); - VBDEBUG(("TPM: Must reboot to re-enable\n")); - return TPM_E_MUST_REBOOT; - } -#endif - - /* Read the firmware space. */ - result = ReadSpaceFirmware(rsf); -#ifndef TPM2_MODE - if (TPM_E_BADINDEX == result) { - RollbackSpaceKernel rsk; - - /* - * This is the first time we've run, and the TPM has not been - * initialized. Initialize it. - */ - VBDEBUG(("TPM: Not initialized yet.\n")); - RETURN_ON_FAILURE(OneTimeInitializeTPM(rsf, &rsk)); - } else -#endif - if (TPM_SUCCESS != result) { - VBDEBUG(("TPM: Firmware space in a bad state; giving up.\n")); - return TPM_E_CORRUPTED_STATE; - } - Memcpy(&versions, &rsf->fw_versions, sizeof(versions)); - VBDEBUG(("TPM: Firmware space sv%d f%x v%x\n", - rsf->struct_version, rsf->flags, versions)); - in_flags = rsf->flags; - - /* If we've been asked to clear the virtual dev-mode flag, do so now */ - if (disable_dev_request) { - rsf->flags &= ~FLAG_VIRTUAL_DEV_MODE_ON; - VBDEBUG(("TPM: Clearing virt dev-switch: f%x\n", rsf->flags)); - } - - /* - * The developer_mode value that's passed in is only set by a hardware - * dev-switch. We should OR it with the virtual switch, whether or not - * the virtual switch is used. If it's not used, it shouldn't change, - * so it doesn't matter. - */ - if (rsf->flags & FLAG_VIRTUAL_DEV_MODE_ON) - developer_mode = 1; - - /* - * Clear ownership if developer flag has toggled, or if an owner-clear - * has been requested. - */ - if ((developer_mode ? FLAG_LAST_BOOT_DEVELOPER : 0) != - (in_flags & FLAG_LAST_BOOT_DEVELOPER)) { - VBDEBUG(("TPM: Developer flag changed; clearing owner.\n")); - RETURN_ON_FAILURE(TPMClearAndReenable()); - } else if (clear_tpm_owner_request) { - VBDEBUG(("TPM: Clearing owner as specifically requested.\n")); - RETURN_ON_FAILURE(TPMClearAndReenable()); - } - - if (developer_mode) - rsf->flags |= FLAG_LAST_BOOT_DEVELOPER; - else - rsf->flags &= ~FLAG_LAST_BOOT_DEVELOPER; - - - /* If firmware space is dirty, flush it back to the TPM */ - if (rsf->flags != in_flags) { - VBDEBUG(("TPM: Updating firmware space.\n")); - RETURN_ON_FAILURE(WriteSpaceFirmware(rsf)); - } - - VBDEBUG(("TPM: SetupTPM() succeeded\n")); - return TPM_SUCCESS; -} - #ifdef DISABLE_ROLLBACK_TPM /* Dummy implementations which don't support TPM rollback protection */ -uint32_t RollbackS3Resume(void) -{ -#ifndef CHROMEOS_ENVIRONMENT - /* - * Initialize the TPM, but ignore return codes. In ChromeOS - * environment, don't even talk to the TPM. - */ - TlclLibInit(); - TlclResume(); -#endif - return TPM_SUCCESS; -} - -uint32_t RollbackFirmwareSetup(int is_hw_dev, - int disable_dev_request, - int clear_tpm_owner_request, - int *is_virt_dev, uint32_t *version) -{ -#ifndef CHROMEOS_ENVIRONMENT - /* - * Initialize the TPM, but ignores return codes. In ChromeOS - * environment, don't even talk to the TPM. - */ - TlclLibInit(); - TlclStartup(); - TlclContinueSelfTest(); -#endif - *is_virt_dev = 0; - *version = 0; - return TPM_SUCCESS; -} - -uint32_t RollbackFirmwareWrite(uint32_t version) -{ - return TPM_SUCCESS; -} - -uint32_t RollbackFirmwareLock(void) -{ - return TPM_SUCCESS; -} - uint32_t RollbackKernelRead(uint32_t* version) { *version = 0; @@ -545,16 +250,6 @@ uint32_t RollbackKernelWrite(uint32_t version) return TPM_SUCCESS; } -uint32_t RollbackBackupRead(uint8_t *raw) -{ - return TPM_SUCCESS; -} - -uint32_t RollbackBackupWrite(uint8_t *raw) -{ - return TPM_SUCCESS; -} - uint32_t RollbackKernelLock(int recovery_mode) { return TPM_SUCCESS; @@ -568,57 +263,6 @@ uint32_t RollbackFwmpRead(struct RollbackSpaceFwmp *fwmp) #else -uint32_t RollbackS3Resume(void) -{ - uint32_t result; - RETURN_ON_FAILURE(TlclLibInit()); - result = TlclResume(); - if (result == TPM_E_INVALID_POSTINIT) { - /* - * We're on a platform where the TPM maintains power in S3, so - * it's already initialized. - */ - return TPM_SUCCESS; - } - return result; -} - -uint32_t RollbackFirmwareSetup(int is_hw_dev, - int disable_dev_request, - int clear_tpm_owner_request, - int *is_virt_dev, uint32_t *version) -{ - RollbackSpaceFirmware rsf; - - /* Set version to 0 in case we fail */ - *version = 0; - - RETURN_ON_FAILURE(SetupTPM(is_hw_dev, disable_dev_request, - clear_tpm_owner_request, &rsf)); - Memcpy(version, &rsf.fw_versions, sizeof(*version)); - *is_virt_dev = (rsf.flags & FLAG_VIRTUAL_DEV_MODE_ON) ? 1 : 0; - VBDEBUG(("TPM: RollbackFirmwareSetup %x\n", (int)*version)); - return TPM_SUCCESS; -} - -uint32_t RollbackFirmwareWrite(uint32_t version) -{ - RollbackSpaceFirmware rsf; - uint32_t old_version; - - RETURN_ON_FAILURE(ReadSpaceFirmware(&rsf)); - Memcpy(&old_version, &rsf.fw_versions, sizeof(old_version)); - VBDEBUG(("TPM: RollbackFirmwareWrite %x --> %x\n", (int)old_version, - (int)version)); - Memcpy(&rsf.fw_versions, &version, sizeof(version)); - return WriteSpaceFirmware(&rsf); -} - -uint32_t RollbackFirmwareLock(void) -{ - return TlclSetGlobalLock(); -} - uint32_t RollbackKernelRead(uint32_t* version) { RollbackSpaceKernel rsk; @@ -664,29 +308,6 @@ uint32_t RollbackKernelWrite(uint32_t version) return WriteSpaceKernel(&rsk); } -/* - * We don't really care whether the TPM owner has been messing with this or - * not. We lock it along with the Kernel space just to avoid problems, but it's - * only useful in dev-mode and only when the battery has been drained - * completely. There aren't any security issues. It's just in the TPM because - * we don't have any other place to keep it. - */ -uint32_t RollbackBackupRead(uint8_t *raw) -{ - uint32_t r; - r = TlclRead(BACKUP_NV_INDEX, raw, BACKUP_NV_SIZE); - VBDEBUG(("TPM: %s returning 0x%x\n", __func__, r)); - return r; -} - -uint32_t RollbackBackupWrite(uint8_t *raw) -{ - uint32_t r; - r = TlclWrite(BACKUP_NV_INDEX, raw, BACKUP_NV_SIZE); - VBDEBUG(("TPM: %s returning 0x%x\n", __func__, r)); - return r; -} - uint32_t RollbackKernelLock(int recovery_mode) { static int kernel_locked = 0; diff --git a/firmware/lib/tpm_bootmode.c b/firmware/lib/tpm_bootmode.c deleted file mode 100644 index cae4b0b1..00000000 --- a/firmware/lib/tpm_bootmode.c +++ /dev/null @@ -1,169 +0,0 @@ -/* Copyright (c) 2013 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. - * - * Functions for updating the TPM state with the status of boot path. - */ - -#include "sysincludes.h" - -#include "tlcl.h" -#include "tpm_bootmode.h" -#include "utility.h" -#include "vboot_api.h" - -/* TPM PCRs to use for storing boot mode measurements. */ -#define BOOT_MODE_PCR 0 -#define HWID_DIGEST_PCR 1 - -/* - * Input digests for PCR extend. - * These are calculated as: - * SHA1("|Developer_Mode||Recovery_Mode||Keyblock_Mode|"). - * Developer_Mode can be 0 or 1. - * Recovery_Mode can be 0 or 1. - * Keyblock flags are defined in vboot_struct.h - * - * We map them to Keyblock_Mode as follows: - * ----------------------------------------- - * Keyblock Flags | Keyblock Mode - * ----------------------------------------- - * 6 (Dev-signed firmware) | 2 - * 7 Normal-signed firmware | 1 - * (anything else) | 0 - */ - -const char* kBootStateSHA1Digests[] = { - /* SHA1("\x00\x00\x00") */ - "\x29\xe2\xdc\xfb\xb1\x6f\x63\xbb\x02\x54\xdf\x75\x85\xa1\x5b\xb6" - "\xfb\x5e\x92\x7d", - - /* SHA1("\x00\x00\x01") */ - "\x25\x47\xcc\x73\x6e\x95\x1f\xa4\x91\x98\x53\xc4\x3a\xe8\x90\x86" - "\x1a\x3b\x32\x64", - - /* SHA1("\x00\x00\x02") */ - "\x1e\xf6\x24\x48\x2d\x62\x0e\x43\xe6\xd3\x4d\xa1\xaf\xe4\x62\x67" - "\xfc\x69\x5d\x9b", - - /* SHA1("\x00\x01\x00") */ - "\x62\x57\x18\x91\x21\x5b\x4e\xfc\x1c\xea\xb7\x44\xce\x59\xdd\x0b" - "\x66\xea\x6f\x73", - - /* SHA1("\x00\x01\x01") */ - "\xee\xe4\x47\xed\xc7\x9f\xea\x1c\xa7\xc7\xd3\x4e\x46\x32\x61\xcd" - "\xa4\xba\x33\x9e", - - /* SHA1("\x00\x01\x02") */ - "\x0c\x7a\x62\x3f\xd2\xbb\xc0\x5b\x06\x42\x3b\xe3\x59\xe4\x02\x1d" - "\x36\xe7\x21\xad", - - /* SHA1("\x01\x00\x00") */ - "\x95\x08\xe9\x05\x48\xb0\x44\x0a\x4a\x61\xe5\x74\x3b\x76\xc1\xe3" - "\x09\xb2\x3b\x7f", - - /* SHA1("\x01\x00\x01") */ - "\xc4\x2a\xc1\xc4\x6f\x1d\x4e\x21\x1c\x73\x5c\xc7\xdf\xad\x4f\xf8" - "\x39\x11\x10\xe9", - - /* SHA1("\x01\x00\x02") */ - "\xfa\x01\x0d\x26\x64\xcc\x5b\x3b\x82\xee\x48\x8f\xe2\xb9\xf5\x0f" - "\x49\x32\xeb\x8f", - - /* SHA1("\x01\x01\x00") */ - "\x47\xec\x8d\x98\x36\x64\x33\xdc\x00\x2e\x77\x21\xc9\xe3\x7d\x50" - "\x67\x54\x79\x37", - - /* SHA1("\x01\x01\x01") */ - "\x28\xd8\x6c\x56\xb3\xbf\x26\xd2\x36\x56\x9b\x8d\xc8\xc3\xf9\x1f" - "\x32\xf4\x7b\xc7", - - /* SHA1("\x01\x01\x02") */ - "\x12\xa3\x40\xd7\x89\x7f\xe7\x13\xfc\x8f\x02\xac\x53\x65\xb8\x6e" - "\xbf\x35\x31\x78", -}; - -#define MAX_BOOT_STATE_INDEX (sizeof(kBootStateSHA1Digests)/sizeof(char *)) - -/* - * Used for PCR extend when the passed-in boot state is invalid or if there is - * an internal error. - */ -const uint8_t kBootInvalidSHA1Digest[] = { - "\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff" - "\xff\xff\xff\xff" -}; - -/** - * Given the boot state, return the correct SHA1 digest index for TPMExtend - * in kBootStateSHA1Digests[]. - */ -static int GetBootStateIndex(int dev_mode, int rec_mode, - uint64_t keyblock_flags) -{ - int index = 0; - - /* - * Convert keyblock flags into keyblock mode which we use to index into - * kBootStateSHA1Digest[]. - */ - switch(keyblock_flags) { - case 6: - /* - * KEY_BLOCK_FLAG_RECOVERY_0 | KEY_BLOCK_FLAG_DEVELOPER_1 - * - * Developer firmware. */ - index = 2; - break; - case 7: - /* - * KEY_BLOCK_FLAG_RECOVERY_0 | KEY_BLOCK_FLAG_DEVELOPER_0 - * | KEY_BLOCK_FLAGS_DEVELOPER_1 - */ - index = 1; - break; - default: - /* Any other keyblock flags. */ - index = 0; - }; - - if (rec_mode) - index += 3; - if (dev_mode) - index += 6; - return index; -} - -uint32_t SetTPMBootModeState(int developer_mode, int recovery_mode, - uint64_t fw_keyblock_flags, - GoogleBinaryBlockHeader *gbb) -{ - uint32_t result0, result1 = 0; - const uint8_t *in_digest = NULL; - uint8_t out_digest[20]; /* For PCR extend output. */ - int digest_index = GetBootStateIndex(developer_mode, recovery_mode, - fw_keyblock_flags); - - if (digest_index >= 0 && digest_index < MAX_BOOT_STATE_INDEX) { - in_digest = (const uint8_t*) - kBootStateSHA1Digests[digest_index]; - } else { - /* Internal out of bounds error. */ - in_digest = kBootInvalidSHA1Digest; - } - - result0 = TlclExtend(BOOT_MODE_PCR, in_digest, out_digest); - VBDEBUG(("TPM: SetTPMBootModeState boot mode PCR%d result %d\n", - BOOT_MODE_PCR, result0)); - - /* Extend the HWID Digest into PCR1 (GBB v1.2 and later only) */ - if (gbb && gbb->minor_version >= 2) { - result1 = TlclExtend(HWID_DIGEST_PCR, gbb->hwid_digest, - out_digest); - VBDEBUG(("TPM: SetTPMBootModeState HWID PCR%d result %d\n", - HWID_DIGEST_PCR, result1)); - } - - /* The caller only looks for nonzero results, not error codes. */ - return result0 || result1; -} diff --git a/firmware/lib/vboot_api_firmware.c b/firmware/lib/vboot_api_firmware.c deleted file mode 100644 index c893d704..00000000 --- a/firmware/lib/vboot_api_firmware.c +++ /dev/null @@ -1,146 +0,0 @@ -/* Copyright (c) 2013 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. - * - * High-level firmware wrapper API - entry points for init, firmware selection - */ - -#include "sysincludes.h" - -#include "gbb_access.h" -#include "gbb_header.h" -#include "load_firmware_fw.h" -#include "rollback_index.h" -#include "tpm_bootmode.h" -#include "utility.h" -#include "vboot_api.h" -#include "vboot_common.h" -#include "vboot_nvstorage.h" - -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; - - cparams->gbb = NULL; - cparams->bmp = NULL; - - /* 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")); - - /* Best effort to read the GBB */ - cparams->gbb = VbExMalloc(sizeof(*cparams->gbb)); - retval = VbGbbReadHeader_static(cparams, cparams->gbb); - if (VBERROR_SUCCESS != retval) { - VBDEBUG(("Can't read GBB. Continuing anyway...\n")); - VbExFree(cparams->gbb); - cparams->gbb = NULL; - } - - /* Go directly to recovery mode */ - fparams->selected_firmware = VB_SELECT_FIRMWARE_RECOVERY; - } else { - cparams->gbb = VbExMalloc(sizeof(*cparams->gbb)); - retval = VbGbbReadHeader_static(cparams, cparams->gbb); - if (VBERROR_SUCCESS != retval) - goto VbSelectFirmware_exit; - - /* 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, - cparams->gbb); - 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: - - if (cparams->gbb) { - VbExFree(cparams->gbb); - cparams->gbb = NULL; - } - - /* 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; -} diff --git a/firmware/lib/vboot_api_init.c b/firmware/lib/vboot_api_init.c deleted file mode 100644 index 2657fb5d..00000000 --- a/firmware/lib/vboot_api_init.c +++ /dev/null @@ -1,378 +0,0 @@ -/* Copyright (c) 2013 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. - * - * High-level firmware wrapper API - entry points for init, firmware selection - */ - -#include "sysincludes.h" - -#include "region.h" -#include "gbb_access.h" -#include "gbb_header.h" -#include "load_firmware_fw.h" -#include "rollback_index.h" -#include "utility.h" -#include "vboot_api.h" -#include "vboot_common.h" -#include "vboot_nvstorage.h" - -VbError_t VbInit(VbCommonParams *cparams, VbInitParams *iparams) -{ - VbSharedDataHeader *shared = - (VbSharedDataHeader *)cparams->shared_data_blob; - GoogleBinaryBlockHeader gbb; - 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; - uint32_t require_official_os = 0; - uint32_t tpm_version = 0; - uint32_t tpm_status = 0; - int has_virt_dev_switch = 0; - int is_hw_dev = 0; - int is_virt_dev = 0; - uint32_t disable_dev_request = 0; - uint32_t clear_tpm_owner_request = 0; - int is_dev = 0; - uint32_t backup_requested = 0; - uint32_t backup_for_safety = 0; - int lost_nvram; - - /* Initialize output flags */ - iparams->out_flags = 0; - - retval = VbGbbReadHeader_static(cparams, &gbb); - if (retval) - return retval; - - VBDEBUG(("VbInit() input flags 0x%x gbb flags 0x%x\n", iparams->flags, - gbb.flags)); - - /* Set up NV storage */ - VbExNvStorageRead(vnc.raw); - VbNvSetup(&vnc); - lost_nvram = vnc.regenerate_crc; - - /* Initialize shared data structure */ - if (0 != VbSharedDataInit(shared, cparams->shared_data_size)) { - VBDEBUG(("Shared data init error\n")); - return VBERROR_INIT_SHARED_DATA; - } - - shared->timer_vb_init_enter = VbExGetTimer(); - - /* Copy some boot switch flags */ - /* TODO: in next refactor, just save in/out flags in VbSharedData */ - shared->flags = 0; - if (iparams->flags & VB_INIT_FLAG_REC_BUTTON_PRESSED) - shared->flags |= VBSD_BOOT_REC_SWITCH_ON; - if (iparams->flags & VB_INIT_FLAG_WP_ENABLED) - shared->flags |= VBSD_BOOT_FIRMWARE_WP_ENABLED; - if (iparams->flags & VB_INIT_FLAG_SW_WP_ENABLED) - shared->flags |= VBSD_BOOT_FIRMWARE_SW_WP_ENABLED; - if (iparams->flags & VB_INIT_FLAG_S3_RESUME) - shared->flags |= VBSD_BOOT_S3_RESUME; - if (iparams->flags & VB_INIT_FLAG_RO_NORMAL_SUPPORT) - shared->flags |= VBSD_BOOT_RO_NORMAL_SUPPORT; - if (iparams->flags & VB_INIT_FLAG_NOFAIL_BOOT) - shared->flags |= VBSD_NOFAIL_BOOT; - if (iparams->flags & VB_INIT_FLAG_EC_SOFTWARE_SYNC) - shared->flags |= VBSD_EC_SOFTWARE_SYNC; - if (iparams->flags & VB_INIT_FLAG_EC_SLOW_UPDATE) - shared->flags |= VBSD_EC_SLOW_UPDATE; - if (iparams->flags & VB_INIT_FLAG_VIRTUAL_REC_SWITCH) - shared->flags |= VBSD_BOOT_REC_SWITCH_VIRTUAL; - if (iparams->flags & VB_INIT_FLAG_OPROM_MATTERS) - shared->flags |= VBSD_OPROM_MATTERS; - if (iparams->flags & VB_INIT_FLAG_OPROM_LOADED) - shared->flags |= VBSD_OPROM_LOADED; - - is_s3_resume = (iparams->flags & VB_INIT_FLAG_S3_RESUME ? 1 : 0); - - /* Check if the OS is requesting a debug S3 reset */ - VbNvGet(&vnc, VBNV_DEBUG_RESET_MODE, &s3_debug_boot); - if (s3_debug_boot) { - if (is_s3_resume) { - VBDEBUG(("VbInit() requesting S3 debug boot\n")); - iparams->out_flags |= VB_INIT_OUT_S3_DEBUG_BOOT; - is_s3_resume = 0; /* Proceed as if normal boot */ - } - - /* - * Clear the request even if this is a normal boot, since we - * don't want the NEXT S3 resume to be a debug reset unless the - * OS asserts the request again. - */ - VbNvSet(&vnc, VBNV_DEBUG_RESET_MODE, 0); - } - - /* - * If this isn't a S3 resume, read the current recovery request, then - * clear it so we don't get stuck in recovery mode. - */ - if (!is_s3_resume) { - VbNvGet(&vnc, VBNV_RECOVERY_REQUEST, &recovery); - VBDEBUG(("VbInit sees recovery request = %d\n", recovery)); - if (VBNV_RECOVERY_NOT_REQUESTED != recovery) - 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) - recovery = VBNV_RECOVERY_RO_MANUAL; - - /* - * Copy current recovery reason to shared data. If we fail later on, it - * won't matter, since we'll just reboot. - */ - shared->recovery_reason = (uint8_t)recovery; - VBDEBUG(("VbInit now sets shared->recovery_reason = %d\n", recovery)); - - /* - * If this is a S3 resume, resume the TPM. - * - * FIXME: I think U-Boot won't ever ask us to do this. Can we remove - * it? - */ - 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 = VBERROR_TPM_S3_RESUME; - } - } else { - /* Should we pay attention to the TPM's virtual dev-switch? */ - if (iparams->flags & VB_INIT_FLAG_VIRTUAL_DEV_SWITCH) { - shared->flags |= VBSD_HONOR_VIRT_DEV_SWITCH; - has_virt_dev_switch = 1; - } - - /* - * We always believe the HW dev-switch, since there's one - * attached to servo which may be active even on systems - * without a physical switch. The EC may also implement a fake - * dev-switch for testing. - */ - if (iparams->flags & VB_INIT_FLAG_DEV_SWITCH_ON) - is_hw_dev = 1; - - /* We may be asked to clear the virtual dev-switch at boot. */ - VbNvGet(&vnc, VBNV_DISABLE_DEV_REQUEST, &disable_dev_request); - - /* Allow GBB flag to override dev switch */ - if (gbb.flags & GBB_FLAG_FORCE_DEV_SWITCH_ON) - is_hw_dev = 1; - - /* Have we been explicitly asked to clear the TPM owner? */ - VbNvGet(&vnc, VBNV_CLEAR_TPM_OWNER_REQUEST, - &clear_tpm_owner_request); - - /* - * Initialize the TPM. If the developer mode state has changed - * since the last boot, we need to clear TPM ownership. If the - * TPM space is initialized by this call, the virtual - * dev-switch will be disabled by default) - */ - VBDEBUG(("TPM: Call RollbackFirmwareSetup(r%d, d%d)\n", - recovery, is_hw_dev)); - tpm_status = RollbackFirmwareSetup(is_hw_dev, - disable_dev_request, - clear_tpm_owner_request, - /* two outputs on success */ - &is_virt_dev, &tpm_version); - - if (0 != tpm_status) { - VBDEBUG(("Unable to setup TPM and read " - "firmware version (0x%x)\n", tpm_status)); - - if (TPM_E_MUST_REBOOT == tpm_status) { - /* - * TPM wants to reboot into the same mode we're - * in now - */ - VBDEBUG(("TPM requires a reboot.\n")); - if (!recovery) { - /* - * Not recovery mode. Just reboot (not - * into recovery). - */ - retval = VBERROR_TPM_REBOOT_REQUIRED; - goto VbInit_exit; - } else if (VBNV_RECOVERY_RO_TPM_REBOOT != - shared->recovery_reason) { - /* - * In recovery mode now, and we haven't - * requested a TPM reboot yet, so - * request one. - */ - VbNvSet(&vnc, VBNV_RECOVERY_REQUEST, - VBNV_RECOVERY_RO_TPM_REBOOT); - retval = VBERROR_TPM_REBOOT_REQUIRED; - goto VbInit_exit; - } - } - - if (!recovery) { - VbNvSet(&vnc, VBNV_RECOVERY_REQUEST, - VBNV_RECOVERY_RO_TPM_S_ERROR); - VbNvSet(&vnc, VBNV_RECOVERY_SUBCODE, - tpm_status); - retval = VBERROR_TPM_FIRMWARE_SETUP; - goto VbInit_exit; - } - } - - /* TPM setup succeeded, or we're in recovery mode and ignoring - * errors. What did we learn? */ - shared->fw_version_tpm_start = tpm_version; - shared->fw_version_tpm = tpm_version; - if (is_hw_dev || (has_virt_dev_switch && is_virt_dev)) { - is_dev = 1; - shared->flags |= VBSD_BOOT_DEV_SWITCH_ON; - } - if (disable_dev_request && !is_virt_dev) - VbNvSet(&vnc, VBNV_DISABLE_DEV_REQUEST, 0); - if (clear_tpm_owner_request) { - VbNvSet(&vnc, VBNV_CLEAR_TPM_OWNER_REQUEST, 0); - VbNvSet(&vnc, VBNV_CLEAR_TPM_OWNER_DONE, 1); - } - } - - /* - * If the nvram state was lost, try to restore the bits we care about - * from the backup in the TPM. It's okay if we can't, though. - * Note: None of the bits that we back up should have been referenced - * before this point. Otherwise, they'll just be overwritten here. - * All the other bits will be unchanged from whatever has happened to - * them since VbNvSetup() reinitialized the VbNvContext. - */ - if (lost_nvram) - RestoreNvFromBackup(&vnc); - - /* Allow BIOS to load arbitrary option ROMs? */ - if (gbb.flags & GBB_FLAG_LOAD_OPTION_ROMS) - iparams->out_flags |= VB_INIT_OUT_ENABLE_OPROM; - - /* Factory may need to boot custom OSes when the dev-switch is on */ - if (is_dev && (gbb.flags & GBB_FLAG_ENABLE_ALTERNATE_OS)) - iparams->out_flags |= VB_INIT_OUT_ENABLE_ALTERNATE_OS; - - /* Set output flags */ - if (VBNV_RECOVERY_NOT_REQUESTED != recovery) { - /* Requesting recovery mode */ - iparams->out_flags |= (VB_INIT_OUT_ENABLE_RECOVERY | - VB_INIT_OUT_CLEAR_RAM | - VB_INIT_OUT_ENABLE_DISPLAY | - VB_INIT_OUT_ENABLE_USB_STORAGE); - } else if (is_dev) { - /* Developer switch is on, so need to support dev mode */ - iparams->out_flags |= (VB_INIT_OUT_ENABLE_DEVELOPER | - VB_INIT_OUT_CLEAR_RAM | - VB_INIT_OUT_ENABLE_DISPLAY | - VB_INIT_OUT_ENABLE_USB_STORAGE); - /* ... which may or may not include custom OSes */ - VbNvGet(&vnc, VBNV_DEV_BOOT_SIGNED_ONLY, &require_official_os); - if (!require_official_os) - iparams->out_flags |= VB_INIT_OUT_ENABLE_ALTERNATE_OS; - - /* - * Dev-mode needs the VGA option ROM to be loaded so it can - * display the scary boot screen. If we don't have it, we need - * to request it and reboot so it can be loaded. - */ - if ((iparams->flags & VB_INIT_FLAG_OPROM_MATTERS) && - !(iparams->flags & VB_INIT_FLAG_OPROM_LOADED)) { - VbNvSet(&vnc, VBNV_OPROM_NEEDED, 1); - /* - * If VbInit() is run before Option ROMs are run it - * can still respond to the VbNv flag and does not - * need to reboot here. - */ - if (!(iparams->flags & VB_INIT_FLAG_BEFORE_OPROM_LOAD)) - retval = VBERROR_VGA_OPROM_MISMATCH; - VBDEBUG(("VbInit() needs oprom, doesn't have it\n")); - } - - } else { - /* - * Normal mode, so disable dev_boot_* flags. This ensures they - * will be initially disabled if the user later transitions - * back into developer mode. - */ - VbNvSet(&vnc, VBNV_DEV_BOOT_USB, 0); - VbNvSet(&vnc, VBNV_DEV_BOOT_LEGACY, 0); - VbNvSet(&vnc, VBNV_DEV_BOOT_SIGNED_ONLY, 0); - VbNvSet(&vnc, VBNV_DEV_BOOT_FASTBOOT_FULL_CAP, 0); - VbNvSet(&vnc, VBNV_DEV_DEFAULT_BOOT, 0); - VbNvSet(&vnc, VBNV_FASTBOOT_UNLOCK_IN_FW, 0); - /* - * Back up any changes now, so these values can't be forgotten - * by draining the battery. We really only care about these - * three fields, but it's uncommon for any others to change so - * this is an easier test than checking each one. - */ - if (vnc.regenerate_crc) - backup_for_safety = 1; - - /* - * If we don't need the VGA option ROM but got it anyway, stop - * asking for it and reboot in case there's some vulnerability - * in using it. - */ - if ((iparams->flags & VB_INIT_FLAG_OPROM_MATTERS) && - (iparams->flags & VB_INIT_FLAG_OPROM_LOADED)) { - VbNvSet(&vnc, VBNV_OPROM_NEEDED, 0); - /* - * If VbInit() is run before Option ROMs are run it - * can still respond to the VbNv flag and does not - * need to reboot here. - */ - if (!(iparams->flags & VB_INIT_FLAG_BEFORE_OPROM_LOAD)) - retval = VBERROR_VGA_OPROM_MISMATCH; - VBDEBUG(("VbInit() has oprom, doesn't need it\n")); - } - } - -VbInit_exit: - /* - * If we successfully backup the NV storage, it will clear the - * VBNV_BACKUP_NVRAM_REQUEST field, so we want to do it before - * calling VbNvTeardown(). It's okay if we can't backup, though. - */ - VbNvGet(&vnc, VBNV_BACKUP_NVRAM_REQUEST, &backup_requested); - if (backup_requested || backup_for_safety) - SaveNvToBackup(&vnc); - - /* Tear down NV storage */ - VbNvTeardown(&vnc); - if (vnc.raw_changed) - VbExNvStorageWrite(vnc.raw); - - VBDEBUG(("VbInit() output flags 0x%x\n", iparams->out_flags)); - - shared->timer_vb_init_exit = VbExGetTimer(); - - VBDEBUG(("VbInit() returning 0x%x\n", retval)); - - return retval; -} diff --git a/firmware/lib/vboot_firmware.c b/firmware/lib/vboot_firmware.c deleted file mode 100644 index bfabfd48..00000000 --- a/firmware/lib/vboot_firmware.c +++ /dev/null @@ -1,368 +0,0 @@ -/* Copyright (c) 2013 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. - * - * High-level firmware API for loading and verifying rewritable firmware. - * (Firmware portion) - */ - -#include "sysincludes.h" -#include "2sysincludes.h" - -#include "2common.h" -#include "2sha.h" -#include "region.h" -#include "gbb_access.h" -#include "gbb_header.h" -#include "load_firmware_fw.h" -#include "utility.h" -#include "vboot_api.h" -#include "vboot_common.h" -#include "vboot_nvstorage.h" - -/* - * Static variables for UpdateFirmwareBodyHash(). It's less than optimal to - * have static variables in a library, but in UEFI the caller is deep inside a - * different firmware stack and doesn't have a good way to pass the params - * struct back to us. - */ -typedef struct VbLoadFirmwareInternal { - struct vb2_digest_context body_digest_context; - uint32_t body_size_accum; -} VbLoadFirmwareInternal; - -void VbUpdateFirmwareBodyHash(VbCommonParams *cparams, uint8_t *data, - uint32_t size) -{ - VbLoadFirmwareInternal *lfi = - (VbLoadFirmwareInternal*)cparams->vboot_context; - - vb2_digest_extend(&lfi->body_digest_context, data, size); - lfi->body_size_accum += size; -} - -int LoadFirmware(VbCommonParams *cparams, VbSelectFirmwareParams *fparams, - VbNvContext *vnc) -{ - VbSharedDataHeader *shared = - (VbSharedDataHeader *)cparams->shared_data_blob; - GoogleBinaryBlockHeader *gbb = cparams->gbb; - VbPublicKey *root_key = NULL; - VbLoadFirmwareInternal *lfi; - - uint32_t try_b_count; - uint32_t lowest_version = 0xFFFFFFFF; - int good_index = -1; - int is_dev; - int index; - int i; - - int retval = VBERROR_UNKNOWN; - int recovery = VBNV_RECOVERY_RO_UNSPECIFIED; - - /* Clear output params in case we fail */ - shared->firmware_index = 0xFF; - - VBDEBUG(("LoadFirmware started...\n")); - - /* Must have a root key from the GBB */ - retval = VbGbbReadRootKey(cparams, &root_key); - if (retval) { - VBDEBUG(("No GBB\n")); - retval = VBERROR_INVALID_GBB; - goto LoadFirmwareExit; - } - - /* Parse flags */ - is_dev = (shared->flags & VBSD_BOOT_DEV_SWITCH_ON ? 1 : 0); - if (is_dev) - shared->flags |= VBSD_LF_DEV_SWITCH_ON; - - /* Read try-b count and decrement if necessary */ - VbNvGet(vnc, VBNV_TRY_B_COUNT, &try_b_count); - if (0 != try_b_count) { - if (!(shared->flags & VBSD_NOFAIL_BOOT)) - VbNvSet(vnc, VBNV_TRY_B_COUNT, try_b_count - 1); - shared->flags |= VBSD_FWB_TRIED; - } - - /* Allocate our internal data */ - lfi = (VbLoadFirmwareInternal *) - VbExMalloc(sizeof(VbLoadFirmwareInternal)); - cparams->vboot_context = lfi; - - /* Loop over indices */ - for (i = 0; i < 2; i++) { - VbKeyBlockHeader *key_block; - uint32_t vblock_size; - VbFirmwarePreambleHeader *preamble; - RSAPublicKey *data_key; - uint64_t key_version; - uint32_t combined_version; - uint8_t *check_result; - - /* If try B count is non-zero try firmware B first */ - index = (try_b_count ? 1 - i : i); - if (0 == index) { - key_block = (VbKeyBlockHeader *) - fparams->verification_block_A; - vblock_size = fparams->verification_size_A; - check_result = &shared->check_fw_a_result; - } else { - key_block = (VbKeyBlockHeader *) - fparams->verification_block_B; - vblock_size = fparams->verification_size_B; - check_result = &shared->check_fw_b_result; - } - - /* - * Check the key block flags against the current boot mode. Do - * this before verifying the key block, since flags are faster - * to check than the RSA signature. - */ - if (!(key_block->key_block_flags & - (is_dev ? KEY_BLOCK_FLAG_DEVELOPER_1 : - KEY_BLOCK_FLAG_DEVELOPER_0))) { - VBDEBUG(("Developer flag mismatch.\n")); - *check_result = VBSD_LF_CHECK_DEV_MISMATCH; - continue; - } - - /* RW firmware never runs in recovery mode. */ - if (!(key_block->key_block_flags & KEY_BLOCK_FLAG_RECOVERY_0)) { - VBDEBUG(("Recovery flag mismatch.\n")); - *check_result = VBSD_LF_CHECK_REC_MISMATCH; - continue; - } - - /* Verify the key block */ - if ((0 != KeyBlockVerify(key_block, vblock_size, - root_key, 0))) { - VBDEBUG(("Key block verification failed.\n")); - *check_result = VBSD_LF_CHECK_VERIFY_KEYBLOCK; - continue; - } - - /* Check for rollback of key version. */ - key_version = key_block->data_key.key_version; - if (!(gbb->flags & GBB_FLAG_DISABLE_FW_ROLLBACK_CHECK)) { - if (key_version < (shared->fw_version_tpm >> 16)) { - VBDEBUG(("Key rollback detected.\n")); - *check_result = VBSD_LF_CHECK_KEY_ROLLBACK; - continue; - } - if (key_version > 0xFFFF) { - /* - * Key version is stored in 16 bits in the TPM, - * so key versions greater than 0xFFFF can't be - * stored properly. - */ - VBDEBUG(("Key version > 0xFFFF.\n")); - *check_result = VBSD_LF_CHECK_KEY_ROLLBACK; - continue; - } - } - - /* Get key for preamble/data verification from the key block. */ - data_key = PublicKeyToRSA(&key_block->data_key); - if (!data_key) { - VBDEBUG(("Unable to parse data key.\n")); - *check_result = VBSD_LF_CHECK_DATA_KEY_PARSE; - continue; - } - - /* Verify the preamble, which follows the key block. */ - preamble = (VbFirmwarePreambleHeader *) - ((uint8_t *)key_block + key_block->key_block_size); - if ((0 != VerifyFirmwarePreamble( - preamble, - vblock_size - key_block->key_block_size, - data_key))) { - VBDEBUG(("Preamble verfication failed.\n")); - *check_result = VBSD_LF_CHECK_VERIFY_PREAMBLE; - RSAPublicKeyFree(data_key); - continue; - } - - /* Check for rollback of firmware version. */ - combined_version = (uint32_t)((key_version << 16) | - (preamble->firmware_version & 0xFFFF)); - if (combined_version < shared->fw_version_tpm && - !(gbb->flags & GBB_FLAG_DISABLE_FW_ROLLBACK_CHECK)) { - VBDEBUG(("Firmware version rollback detected.\n")); - *check_result = VBSD_LF_CHECK_FW_ROLLBACK; - RSAPublicKeyFree(data_key); - continue; - } - - /* Header for this firmware is valid */ - *check_result = VBSD_LF_CHECK_HEADER_VALID; - - /* Check for lowest key version from a valid header. */ - if (lowest_version > combined_version) - lowest_version = combined_version; - - /* - * If we already have good firmware, no need to read another - * one; we only needed to look at the versions to check for - * rollback. - */ - if (-1 != good_index) { - RSAPublicKeyFree(data_key); - continue; - } - - /* Handle preamble flag for using the RO normal/dev code path */ - VBDEBUG(("Preamble flags %#x\n", VbGetFirmwarePreambleFlags(preamble))); - if (VbGetFirmwarePreambleFlags(preamble) & - VB_FIRMWARE_PREAMBLE_USE_RO_NORMAL) { - - /* Fail if calling firmware doesn't support RO normal */ - if (!(shared->flags & VBSD_BOOT_RO_NORMAL_SUPPORT)) { - VBDEBUG(("No RO normal support.\n")); - *check_result = VBSD_LF_CHECK_NO_RO_NORMAL; - RSAPublicKeyFree(data_key); - continue; - } - - /* Use the RO normal code path */ - shared->flags |= VBSD_LF_USE_RO_NORMAL; - - } else { - VbError_t rv; - - /* Read the firmware data */ - vb2_digest_init(&lfi->body_digest_context, - vb2_crypto_to_hash(data_key->algorithm)); - lfi->body_size_accum = 0; - rv = VbExHashFirmwareBody( - cparams, - (index ? VB_SELECT_FIRMWARE_B : - VB_SELECT_FIRMWARE_A)); - if (VBERROR_SUCCESS != rv) { - VBDEBUG(("VbExHashFirmwareBody() failed for " - "index %d\n", index)); - *check_result = VBSD_LF_CHECK_GET_FW_BODY; - RSAPublicKeyFree(data_key); - continue; - } - if (lfi->body_size_accum != - preamble->body_signature.data_size) { - VBDEBUG(("Hashed %d bytes but expected %d\n", - (int)lfi->body_size_accum, - (int)preamble->body_signature.data_size)); - *check_result = VBSD_LF_CHECK_HASH_WRONG_SIZE; - RSAPublicKeyFree(data_key); - continue; - } - - /* Verify firmware data */ - uint8_t body_digest[VB2_MAX_DIGEST_SIZE]; - vb2_digest_finalize(&lfi->body_digest_context, - body_digest, sizeof(body_digest)); - if (0 != VerifyDigest(body_digest, - &preamble->body_signature, - data_key)) { - VBDEBUG(("FW body verification failed.\n")); - *check_result = VBSD_LF_CHECK_VERIFY_BODY; - RSAPublicKeyFree(data_key); - continue; - } - } - - /* Done with the data key, so can free it now */ - RSAPublicKeyFree(data_key); - - /* If we're still here, the firmware is valid. */ - VBDEBUG(("Firmware %d is valid.\n", index)); - *check_result = VBSD_LF_CHECK_VALID; - if (-1 == good_index) { - /* Save the key we actually used */ - if (0 != VbSharedDataSetKernelKey( - shared, &preamble->kernel_subkey)) { - /* - * The firmware signature was good, but the - * public key was bigger that the caller can - * handle. - */ - VBDEBUG(("Unable to save kernel subkey.\n")); - continue; - } - - /* - * Save the good index, now that we're sure we can - * actually use this firmware. That's the one we'll - * boot. - */ - good_index = index; - shared->firmware_index = (uint8_t)index; - shared->fw_keyblock_flags = key_block->key_block_flags; - - /* - * If the good firmware's key version is the same as - * the tpm, then the TPM doesn't need updating; we can - * stop now. Otherwise, we'll check all the other - * headers to see if they contain a newer key. - */ - if (combined_version == shared->fw_version_tpm) - break; - } - } - - /* Free internal data */ - VbExFree(lfi); - cparams->vboot_context = NULL; - - /* Handle finding good firmware */ - if (good_index >= 0) { - - /* Save versions we found */ - shared->fw_version_lowest = lowest_version; - if (lowest_version > shared->fw_version_tpm) - shared->fw_version_tpm = lowest_version; - - /* Success */ - VBDEBUG(("Will boot firmware index %d\n", - (int)shared->firmware_index)); - retval = VBERROR_SUCCESS; - - } else { - uint8_t a = shared->check_fw_a_result; - uint8_t b = shared->check_fw_b_result; - uint8_t best_check; - - /* No good firmware, so go to recovery mode. */ - VBDEBUG(("Alas, no good firmware.\n")); - recovery = VBNV_RECOVERY_RO_INVALID_RW; - retval = VBERROR_LOAD_FIRMWARE; - - /* - * If the best check result fits in the range of recovery - * reasons, provide more detail on how far we got in - * validation. - */ - best_check = (a > b ? a : b) + - VBNV_RECOVERY_RO_INVALID_RW_CHECK_MIN; - if (best_check >= VBNV_RECOVERY_RO_INVALID_RW_CHECK_MIN && - best_check <= VBNV_RECOVERY_RO_INVALID_RW_CHECK_MAX) - recovery = best_check; - } - - LoadFirmwareExit: - VbExFree(root_key); - - /* Store recovery request, if any */ - VbNvSet(vnc, VBNV_RECOVERY_REQUEST, VBERROR_SUCCESS != retval ? - recovery : VBNV_RECOVERY_NOT_REQUESTED); - /* If the system does not support RO_NORMAL and LoadFirmware() - * encountered an error, update the shared recovery reason if - * recovery was not previously requested. */ - if (!(shared->flags & VBSD_BOOT_RO_NORMAL_SUPPORT) && - VBNV_RECOVERY_NOT_REQUESTED == shared->recovery_reason && - VBERROR_SUCCESS != retval) { - VBDEBUG(("RO normal but we got an error.\n")); - shared->recovery_reason = recovery; - } - - return retval; -} diff --git a/firmware/lib/vboot_nvstorage_rollback.c b/firmware/lib/vboot_nvstorage_rollback.c deleted file mode 100644 index a9132436..00000000 --- a/firmware/lib/vboot_nvstorage_rollback.c +++ /dev/null @@ -1,95 +0,0 @@ -/* Copyright (c) 2014 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. - */ - -/* Non-volatile storage routines. - */ -#include "sysincludes.h" - -#include "crc8.h" -#include "utility.h" -#include "vboot_common.h" -#include "vboot_nvstorage.h" -#include "rollback_index.h" - -/* These are the fields of the nvram that we want to back up. */ -static const VbNvParam backup_params[] = { - VBNV_KERNEL_FIELD, - VBNV_LOCALIZATION_INDEX, - VBNV_DEV_BOOT_USB, - VBNV_DEV_BOOT_LEGACY, - VBNV_DEV_BOOT_SIGNED_ONLY, - VBNV_DEV_BOOT_FASTBOOT_FULL_CAP, - VBNV_DEV_DEFAULT_BOOT, - VBNV_FASTBOOT_UNLOCK_IN_FW, -}; - -/* We can't back things up if there isn't enough storage. */ -BUILD_ASSERT(VBNV_BLOCK_SIZE <= BACKUP_NV_SIZE); - -int RestoreNvFromBackup(VbNvContext *vnc) -{ - VbNvContext bvnc; - uint32_t value; - int i; - - VBDEBUG(("TPM: %s()\n", __func__)); - - if (TPM_SUCCESS != RollbackBackupRead(bvnc.raw)) - return 1; - - VbNvSetup(&bvnc); - if (bvnc.regenerate_crc) { - VBDEBUG(("TPM: Oops, backup is no good.\n")); - return 1; - } - - for (i = 0; i < ARRAY_SIZE(backup_params); i++) { - VbNvGet(&bvnc, backup_params[i], &value); - VbNvSet(vnc, backup_params[i], value); - } - - /* VbNvTeardown(&bvnc); is not needed. We're done with it. */ - return 0; -} - -int SaveNvToBackup(VbNvContext *vnc) -{ - VbNvContext bvnc; - uint32_t value; - int i; - - VBDEBUG(("TPM: %s()\n", __func__)); - - /* Read it first. No point in writing the same data. */ - if (TPM_SUCCESS != RollbackBackupRead(bvnc.raw)) - return 1; - - VbNvSetup(&bvnc); - VBDEBUG(("TPM: existing backup is %s\n", - bvnc.regenerate_crc ? "bad" : "good")); - - for (i = 0; i < ARRAY_SIZE(backup_params); i++) { - VbNvGet(vnc, backup_params[i], &value); - VbNvSet(&bvnc, backup_params[i], value); - } - - VbNvTeardown(&bvnc); - - if (!bvnc.raw_changed) { - VBDEBUG(("TPM: Nothing's changed, not writing backup\n")); - /* Clear the request flag, since we're happy. */ - VbNvSet(vnc, VBNV_BACKUP_NVRAM_REQUEST, 0); - return 0; - } - - if (TPM_SUCCESS == RollbackBackupWrite(bvnc.raw)) { - /* Clear the request flag if we wrote successfully too */ - VbNvSet(vnc, VBNV_BACKUP_NVRAM_REQUEST, 0); - return 0; - } - - VBDEBUG(("TPM: Sorry, couldn't write backup.\n")); - return 1; -} diff --git a/firmware/linktest/main.c b/firmware/linktest/main.c index aec180e1..fad11101 100644 --- a/firmware/linktest/main.c +++ b/firmware/linktest/main.c @@ -6,11 +6,9 @@ #include "sysincludes.h" #include "cgptlib.h" -#include "load_firmware_fw.h" #include "load_kernel_fw.h" #include "rollback_index.h" #include "tlcl.h" -#include "tpm_bootmode.h" #include "vboot_common.h" #include "vboot_kernel.h" #include "vboot_nvstorage.h" @@ -23,24 +21,14 @@ int main(void) GptNextKernelEntry(0, 0, 0); GptUpdateKernelEntry(0, 0); - /* load_firmware_fw.h */ - LoadFirmware(0, 0, 0); - /* load_kernel_fw.h */ LoadKernel(0, 0); /* rollback_index.h */ - RollbackS3Resume(); - RollbackFirmwareSetup(0, 0, 0, 0, 0); - RollbackFirmwareWrite(0); - RollbackFirmwareLock(); RollbackKernelRead(0); RollbackKernelWrite(0); RollbackKernelLock(0); - /* tpm_bootmode.c */ - SetTPMBootModeState(0, 0, 0, 0); - /* tlcl.h */ TlclStartup(); TlclResume(); @@ -66,9 +54,6 @@ int main(void) #endif /* vboot_api.h - entry points INTO vboot_reference */ - VbInit(0, 0); - VbSelectFirmware(0, 0); - VbUpdateFirmwareBodyHash(0, 0, 0); VbSelectAndLoadKernel(0, 0); /* vboot_common.h */ diff --git a/firmware/linktest/main_vbinit.c b/firmware/linktest/main_vbinit.c deleted file mode 100644 index 0300c915..00000000 --- a/firmware/linktest/main_vbinit.c +++ /dev/null @@ -1,15 +0,0 @@ -/* Copyright (c) 2013 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. - */ - -#include "sysincludes.h" - -#include "vboot_api.h" - -int main(void) -{ - /* vboot_api.h - entry points INTO vboot_reference */ - VbInit(0, 0); - return 0; -} diff --git a/firmware/linktest/main_vbsf.c b/firmware/linktest/main_vbsf.c deleted file mode 100644 index db5c2660..00000000 --- a/firmware/linktest/main_vbsf.c +++ /dev/null @@ -1,16 +0,0 @@ -/* Copyright (c) 2013 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. - */ - -#include "sysincludes.h" - -#include "vboot_api.h" - -int main(void) -{ - /* vboot_api.h - entry points INTO vboot_reference */ - VbSelectFirmware(0, 0); - VbUpdateFirmwareBodyHash(0, 0, 0); - return 0; -} diff --git a/msc/README.txt b/msc/README.txt deleted file mode 100644 index f22bac03..00000000 --- a/msc/README.txt +++ /dev/null @@ -1,25 +0,0 @@ -This directory contains the Microsoft Visual C makefile for building vboot -reference code (and testing, eventually) in a 32 bit DOS window. - -Microsoft Visual C 2008 (or later) is the prerequisite for this to work. - -To build vboot_reference tree in the DOS window do the following: - -- untar or git clone the vboot_reference source tree - -- open a DOS window - -- run the MSVC provided script vcvars32.bat to create the command line build - environment. Script location is MSVC installation specific. For instance: - - c:\> \bios\devtls\MSVC9\Vc\bin\vcvars32.bat - -- define a directory where the nmake output should go into - - c:\> set MOD=z:\shared\tmp - -- start the make job as follows: - - c:\> nmake /f %path_to_vboot_reference_tree%\msc\nmakefile - -- observe the output generated in %MOD% diff --git a/msc/nmakefile b/msc/nmakefile deleted file mode 100644 index 9d78ad3f..00000000 --- a/msc/nmakefile +++ /dev/null @@ -1,58 +0,0 @@ -# Copyright (c) 2010 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. - -!IF "$(MOD)" == "" -!ERROR MOD (Make output dir) is not defined -!ENDIF - -O = $(MOD) -R = z:\shared\vboot_reference - -ALL_OBJS = $O\main.obj $O\stateful_util.obj $O\cgptlib_internal.obj \ - $O\cgptlib.obj $O\crc32.obj $O\vboot_common.obj $O\vboot_kernel.obj \ - $O\vboot_firmware.obj $O\rollback_index.obj $O\sha_utility.obj $O\rsa.obj \ - $O\rsa_utility.obj $O\padding.obj $O\sha2.obj $O\sha1.obj \ - $O\load_firmware_stub.obj $O\tlcl.obj $O\utility_stub.obj \ - $O\boot_device_stub.obj $O\crc32_test.obj $O\rollback_index_mock.obj \ - $O\test_common.obj $O\cgptlib_test.obj $O\rsa_padding_test.obj \ - $O\sha_tests.obj $O\vboot_common_tests.obj $O\vboot_common2_tests.obj \ - $O\vboot_common3_tests.obj - -CFLAGS = $(CFLAGS) /I $R\firmware\lib\include -CFLAGS = $(CFLAGS) /I $R\firmware\lib\cgptlib\include -CFLAGS = $(CFLAGS) /I $R\firmware\include -CFLAGS = $(CFLAGS) /I $R\firmware\stub\include -CFLAGS = $(CFLAGS) /I $R\firmware\lib\cryptolib\include -CFLAGS = $(CFLAGS) /I $R\host\include - -CFLAGS = $(CFLAGS) /W4 /WX /D TARGET_TEST_MODE - -COMPILE = $(CC) $(CFLAGS) /Fo$@ -c $< - -all: $(ALL_OBJS) - -{$R\firmware\linktest}.c{$O}.obj: - $(COMPILE) - -{$R\firmware\lib}.c{$O}.obj: - $(COMPILE) - -{$R\firmware\lib\cgptlib}.c{$O}.obj: - $(COMPILE) - -{$R\firmware\lib\cryptolib}.c{$O}.obj: - $(COMPILE) - -{$R\firmware\stub}.c{$O}.obj: - $(COMPILE) - -{$R\tests}.c{$O}.obj: - $(COMPILE) - -#{$R\cgpt}.c{$O}.obj: -#$R/firmware/lib/cgptlibc.$O.obj: -#$R/firmware/lib/cryptolibc.$O.obj: -#$R/firmware/stubc.$O.obj: -#$R/utilityc.$O.obj: -# $(CC) $(CFLAGS) -Fd$O\ -c $< diff --git a/tests/rollback_index2_tests.c b/tests/rollback_index2_tests.c index 9e9f5b94..b170a969 100644 --- a/tests/rollback_index2_tests.c +++ b/tests/rollback_index2_tests.c @@ -503,410 +503,6 @@ static void MiscTest(void) "TlclSetDeactivated(0)\n" "TlclWrite(0x123, 8)\n", "tlcl calls"); - - ResetMocks(0, 0); - TEST_EQ(SafeDefineSpace(0x123, 6, 8), 0, "SafeDefineSpace()"); - TEST_STR_EQ(mock_calls, - "TlclDefineSpace(0x123, 0x6, 8)\n", - "tlcl calls"); - - ResetMocks(1, TPM_E_BADINDEX); - TEST_EQ(SafeDefineSpace(0x123, 6, 8), TPM_E_BADINDEX, - "SafeDefineSpace() bad"); - TEST_STR_EQ(mock_calls, - "TlclDefineSpace(0x123, 0x6, 8)\n", - "tlcl calls"); - - ResetMocks(1, TPM_E_MAXNVWRITES); - TEST_EQ(SafeDefineSpace(0x123, 6, 8), 0, - "SafeDefineSpace() retry max writes"); - TEST_STR_EQ(mock_calls, - "TlclDefineSpace(0x123, 0x6, 8)\n" - "TlclForceClear()\n" - "TlclSetEnable()\n" - "TlclSetDeactivated(0)\n" - "TlclDefineSpace(0x123, 0x6, 8)\n", - "tlcl calls"); -} - -/****************************************************************************/ - -/* Tests for one-time initialization */ -static void OneTimeInitTest(void) -{ - RollbackSpaceFirmware rsf; - RollbackSpaceKernel rsk; - - /* Complete initialization */ - ResetMocks(0, 0); - TEST_EQ(OneTimeInitializeTPM(&rsf, &rsk), 0, "OneTimeInitializeTPM()"); - TEST_STR_EQ(mock_calls, - "TlclSelfTestFull()\n" - "TlclGetPermanentFlags()\n" - "TlclFinalizePhysicalPresence()\n" - "TlclSetNvLocked()\n" - "TlclForceClear()\n" - "TlclSetEnable()\n" - "TlclSetDeactivated(0)\n" - /* backup space */ - "TlclDefineSpace(0x1009, 0x1, 16)\n" - /* kernel space */ - "TlclDefineSpace(0x1008, 0x1, 13)\n" - "TlclWrite(0x1008, 13)\n" - "TlclRead(0x1008, 13)\n" - /* firmware space */ - "TlclDefineSpace(0x1007, 0x8001, 10)\n" - "TlclWrite(0x1007, 10)\n" - "TlclRead(0x1007, 10)\n", - "tlcl calls"); - TEST_EQ(mock_rsf.struct_version, ROLLBACK_SPACE_FIRMWARE_VERSION, - "rsf ver"); - TEST_EQ(mock_rsf.flags, 0, "rsf flags"); - TEST_EQ(mock_rsf.fw_versions, 0, "rsf fw_versions"); - TEST_EQ(mock_rsk.struct_version, ROLLBACK_SPACE_KERNEL_VERSION, - "rsk ver"); - TEST_EQ(mock_rsk.uid, ROLLBACK_SPACE_KERNEL_UID, "rsk uid"); - TEST_EQ(mock_rsk.kernel_versions, 0, "rsk kernel_versions"); - - /* Physical presence already initialized */ - ResetMocks(0, 0); - mock_pflags.physicalPresenceLifetimeLock = 1; - TEST_EQ(OneTimeInitializeTPM(&rsf, &rsk), 0, "OneTimeInitializeTPM()"); - TEST_STR_EQ(mock_calls, - "TlclSelfTestFull()\n" - "TlclGetPermanentFlags()\n" - "TlclSetNvLocked()\n" - "TlclForceClear()\n" - "TlclSetEnable()\n" - "TlclSetDeactivated(0)\n" - /* backup space */ - "TlclDefineSpace(0x1009, 0x1, 16)\n" - /* kernel space */ - "TlclDefineSpace(0x1008, 0x1, 13)\n" - "TlclWrite(0x1008, 13)\n" - "TlclRead(0x1008, 13)\n" - /* firmware space */ - "TlclDefineSpace(0x1007, 0x8001, 10)\n" - "TlclWrite(0x1007, 10)\n" - "TlclRead(0x1007, 10)\n", - "tlcl calls"); - - /* NV locking already initialized */ - ResetMocks(0, 0); - mock_pflags.nvLocked = 1; - TEST_EQ(OneTimeInitializeTPM(&rsf, &rsk), 0, "OneTimeInitializeTPM()"); - TEST_STR_EQ(mock_calls, - "TlclSelfTestFull()\n" - "TlclGetPermanentFlags()\n" - "TlclFinalizePhysicalPresence()\n" - "TlclForceClear()\n" - "TlclSetEnable()\n" - "TlclSetDeactivated(0)\n" - /* backup space */ - "TlclDefineSpace(0x1009, 0x1, 16)\n" - /* kernel space */ - "TlclDefineSpace(0x1008, 0x1, 13)\n" - "TlclWrite(0x1008, 13)\n" - "TlclRead(0x1008, 13)\n" - /* firmware space */ - "TlclDefineSpace(0x1007, 0x8001, 10)\n" - "TlclWrite(0x1007, 10)\n" - "TlclRead(0x1007, 10)\n", - "tlcl calls"); - - /* Self test error */ - ResetMocks(1, TPM_E_IOERROR); - TEST_EQ(OneTimeInitializeTPM(&rsf, &rsk), TPM_E_IOERROR, - "OneTimeInitializeTPM() selftest"); - TEST_STR_EQ(mock_calls, - "TlclSelfTestFull()\n", - "tlcl calls"); -} - -/****************************************************************************/ -/* Tests for TPM setup */ - -static void SetupTpmTest(void) -{ - RollbackSpaceFirmware rsf; - - /* Complete setup */ - ResetMocks(0, 0); - TEST_EQ(SetupTPM(0, 0, 0, &rsf), 0, "SetupTPM()"); - TEST_STR_EQ(mock_calls, - "TlclLibInit()\n" - "TlclStartup()\n" - "TlclAssertPhysicalPresence()\n" - "TlclGetPermanentFlags()\n" - "TlclRead(0x1007, 10)\n", - "tlcl calls"); - - /* If TPM is disabled or deactivated, must enable it */ - ResetMocks(0, 0); - mock_pflags.disable = 1; - TEST_EQ(SetupTPM(0, 0, 0, &rsf), TPM_E_MUST_REBOOT, - "SetupTPM() disabled"); - TEST_STR_EQ(mock_calls, - "TlclLibInit()\n" - "TlclStartup()\n" - "TlclAssertPhysicalPresence()\n" - "TlclGetPermanentFlags()\n" - "TlclSetEnable()\n" - "TlclSetDeactivated(0)\n", - "tlcl calls"); - - ResetMocks(0, 0); - mock_pflags.deactivated = 1; - TEST_EQ(SetupTPM(0, 0, 0, &rsf), TPM_E_MUST_REBOOT, - "SetupTPM() deactivated"); - TEST_STR_EQ(mock_calls, - "TlclLibInit()\n" - "TlclStartup()\n" - "TlclAssertPhysicalPresence()\n" - "TlclGetPermanentFlags()\n" - "TlclSetEnable()\n" - "TlclSetDeactivated(0)\n", - "tlcl calls"); - - /* If physical presence command isn't enabled, try to enable it */ - ResetMocks(3, TPM_E_IOERROR); - TEST_EQ(SetupTPM(0, 0, 0, &rsf), 0, "SetupTPM() pp cmd"); - TEST_STR_EQ(mock_calls, - "TlclLibInit()\n" - "TlclStartup()\n" - "TlclAssertPhysicalPresence()\n" - "TlclPhysicalPresenceCMDEnable()\n" - "TlclAssertPhysicalPresence()\n" - "TlclGetPermanentFlags()\n" - "TlclRead(0x1007, 10)\n", - "tlcl calls"); - - /* If firmware space is missing, do one-time init */ - ResetMocks(5, TPM_E_BADINDEX); - mock_pflags.physicalPresenceLifetimeLock = 1; - mock_pflags.nvLocked = 1; - TEST_EQ(SetupTPM(0, 0, 0, &rsf), 0, "SetupTPM() no firmware space"); - TEST_STR_EQ(mock_calls, - "TlclLibInit()\n" - "TlclStartup()\n" - "TlclAssertPhysicalPresence()\n" - "TlclGetPermanentFlags()\n" - "TlclRead(0x1007, 10)\n" - /* Calls from one-time init */ - "TlclSelfTestFull()\n" - "TlclGetPermanentFlags()\n" - "TlclForceClear()\n" - "TlclSetEnable()\n" - "TlclSetDeactivated(0)\n" - /* backup space */ - "TlclDefineSpace(0x1009, 0x1, 16)\n" - "TlclDefineSpace(0x1008, 0x1, 13)\n" - "TlclWrite(0x1008, 13)\n" - "TlclRead(0x1008, 13)\n" - "TlclDefineSpace(0x1007, 0x8001, 10)\n" - "TlclWrite(0x1007, 10)\n" - "TlclRead(0x1007, 10)\n", - "tlcl calls"); - - /* Other firmware space error is passed through */ - ResetMocks(5, TPM_E_IOERROR); - TEST_EQ(SetupTPM(0, 0, 0, &rsf), TPM_E_CORRUPTED_STATE, - "SetupTPM() bad firmware space"); - TEST_STR_EQ(mock_calls, - "TlclLibInit()\n" - "TlclStartup()\n" - "TlclAssertPhysicalPresence()\n" - "TlclGetPermanentFlags()\n" - "TlclRead(0x1007, 10)\n", - "tlcl calls"); - - /* If developer flag has toggled, clear ownership and write new flag */ - ResetMocks(0, 0); - TEST_EQ(SetupTPM(1, 0, 0, &rsf), 0, "SetupTPM() to dev"); - TEST_STR_EQ(mock_calls, - "TlclLibInit()\n" - "TlclStartup()\n" - "TlclAssertPhysicalPresence()\n" - "TlclGetPermanentFlags()\n" - "TlclRead(0x1007, 10)\n" - "TlclForceClear()\n" - "TlclSetEnable()\n" - "TlclSetDeactivated(0)\n" - "TlclWrite(0x1007, 10)\n" - "TlclRead(0x1007, 10)\n", - "tlcl calls"); - TEST_EQ(mock_rsf.flags, FLAG_LAST_BOOT_DEVELOPER, - "fw space flags to dev 1"); - - ResetMocks(0, 0); - mock_rsf.flags = FLAG_LAST_BOOT_DEVELOPER; - TEST_EQ(SetupTPM(0, 0, 0, &rsf), 0, "SetupTPM() from dev"); - TEST_STR_EQ(mock_calls, - "TlclLibInit()\n" - "TlclStartup()\n" - "TlclAssertPhysicalPresence()\n" - "TlclGetPermanentFlags()\n" - "TlclRead(0x1007, 10)\n" - "TlclForceClear()\n" - "TlclSetEnable()\n" - "TlclSetDeactivated(0)\n" - "TlclWrite(0x1007, 10)\n" - "TlclRead(0x1007, 10)\n", - "tlcl calls"); - TEST_EQ(mock_rsf.flags, 0, "fw space flags from dev 1"); - - /* If TPM clear request, clear ownership also */ - ResetMocks(0, 0); - TEST_EQ(SetupTPM(0, 0, 1, &rsf), 0, "SetupTPM() clear owner"); - TEST_STR_EQ(mock_calls, - "TlclLibInit()\n" - "TlclStartup()\n" - "TlclAssertPhysicalPresence()\n" - "TlclGetPermanentFlags()\n" - "TlclRead(0x1007, 10)\n" - "TlclForceClear()\n" - "TlclSetEnable()\n" - "TlclSetDeactivated(0)\n", - "tlcl calls"); - - /* Handle request to clear virtual dev switch */ - ResetMocks(0, 0); - mock_rsf.flags = FLAG_VIRTUAL_DEV_MODE_ON | FLAG_LAST_BOOT_DEVELOPER; - TEST_EQ(SetupTPM(0, 1, 0, &rsf), 0, "SetupTPM() clear virtual dev"); - TEST_EQ(mock_rsf.flags, 0, "Clear virtual dev"); - - /* If virtual dev switch is on, that should set last boot developer */ - ResetMocks(0, 0); - mock_rsf.flags = FLAG_VIRTUAL_DEV_MODE_ON; - SetupTPM(0, 0, 0, &rsf); - TEST_EQ(mock_rsf.flags, - FLAG_VIRTUAL_DEV_MODE_ON | FLAG_LAST_BOOT_DEVELOPER, - "virtual dev sets last boot"); - - /* - * Note: SetupTPM() recovery_mode parameter sets a global flag in - * rollback_index.c; this is tested along with RollbackKernelLock() - * below. - */ -} - -/****************************************************************************/ -/* Tests for RollbackFirmware() calls */ - -static void RollbackFirmwareTest(void) -{ - uint32_t version; - int dev_mode; - - /* Normal setup */ - ResetMocks(0, 0); - dev_mode = 0; - version = 123; - mock_rsf.fw_versions = 0x12345678; - TEST_EQ(RollbackFirmwareSetup(0, dev_mode, 0, &dev_mode, &version), - 0, "RollbackFirmwareSetup()"); - TEST_STR_EQ(mock_calls, - "TlclLibInit()\n" - "TlclStartup()\n" - "TlclAssertPhysicalPresence()\n" - "TlclGetPermanentFlags()\n" - "TlclRead(0x1007, 10)\n", - "tlcl calls"); - TEST_EQ(version, 0x12345678, "RollbackFirmwareSetup() version"); - - /* Error during setup should clear version */ - ResetMocks(1, TPM_E_IOERROR); - dev_mode = 0; - version = 123; - mock_rsf.fw_versions = 0x12345678; - TEST_EQ(RollbackFirmwareSetup(0, dev_mode, 0, &dev_mode, &version), - TPM_E_IOERROR, - "RollbackFirmwareSetup() error"); - TEST_STR_EQ(mock_calls, - "TlclLibInit()\n", - "tlcl calls"); - TEST_EQ(version, 0, "RollbackFirmwareSetup() version on error"); - - /* Developer mode flag gets passed properly */ - ResetMocks(0, 0); - dev_mode = 1; - TEST_EQ(RollbackFirmwareSetup(dev_mode, 0, 0, &dev_mode, &version), - 0, "RollbackFirmwareSetup() to dev"); - TEST_STR_EQ(mock_calls, - "TlclLibInit()\n" - "TlclStartup()\n" - "TlclAssertPhysicalPresence()\n" - "TlclGetPermanentFlags()\n" - "TlclRead(0x1007, 10)\n" - "TlclForceClear()\n" - "TlclSetEnable()\n" - "TlclSetDeactivated(0)\n" - "TlclWrite(0x1007, 10)\n" - "TlclRead(0x1007, 10)\n", - "tlcl calls"); - TEST_EQ(mock_rsf.flags, FLAG_LAST_BOOT_DEVELOPER, - "fw space flags to dev 2"); - - /* So does clear-TPM request */ - ResetMocks(0, 0); - dev_mode = 0; - TEST_EQ(RollbackFirmwareSetup(dev_mode, 0, 1, &dev_mode, &version), - 0, "RollbackFirmwareSetup() clear owner"); - TEST_STR_EQ(mock_calls, - "TlclLibInit()\n" - "TlclStartup()\n" - "TlclAssertPhysicalPresence()\n" - "TlclGetPermanentFlags()\n" - "TlclRead(0x1007, 10)\n" - "TlclForceClear()\n" - "TlclSetEnable()\n" - "TlclSetDeactivated(0)\n", - "tlcl calls"); - - /* Test write */ - ResetMocks(0, 0); - TEST_EQ(RollbackFirmwareWrite(0xBEAD1234), 0, - "RollbackFirmwareWrite()"); - TEST_EQ(mock_rsf.fw_versions, 0xBEAD1234, - "RollbackFirmwareWrite() version"); - TEST_STR_EQ(mock_calls, - "TlclRead(0x1007, 10)\n" - "TlclWrite(0x1007, 10)\n" - "TlclRead(0x1007, 10)\n", - "tlcl calls"); - - ResetMocks(1, TPM_E_IOERROR); - TEST_EQ(RollbackFirmwareWrite(123), TPM_E_IOERROR, - "RollbackFirmwareWrite() error"); - - /* Test setting virtual dev mode */ - ResetMocks(0, 0); - TEST_EQ(SetVirtualDevMode(1), 0, "SetVirtualDevMode(1)"); - TEST_EQ(mock_rsf.flags, FLAG_VIRTUAL_DEV_MODE_ON, "Virtual dev on"); - TEST_STR_EQ(mock_calls, - "TlclRead(0x1007, 10)\n" - "TlclWrite(0x1007, 10)\n" - "TlclRead(0x1007, 10)\n", - "tlcl calls"); - ResetMocks(0, 0); - TEST_EQ(SetVirtualDevMode(0), 0, "SetVirtualDevMode(0)"); - TEST_EQ(mock_rsf.flags, 0, "Virtual dev off"); - TEST_STR_EQ(mock_calls, - "TlclRead(0x1007, 10)\n" - "TlclWrite(0x1007, 10)\n" - "TlclRead(0x1007, 10)\n", - "tlcl calls"); - - /* Test lock */ - ResetMocks(0, 0); - TEST_EQ(RollbackFirmwareLock(), 0, "RollbackFirmwareLock()"); - TEST_STR_EQ(mock_calls, - "TlclSetGlobalLock()\n", - "tlcl calls"); - - ResetMocks(1, TPM_E_IOERROR); - TEST_EQ(RollbackFirmwareLock(), TPM_E_IOERROR, - "RollbackFirmwareLock() error"); } /****************************************************************************/ @@ -914,16 +510,8 @@ static void RollbackFirmwareTest(void) static void RollbackKernelTest(void) { - RollbackSpaceFirmware rsf; uint32_t version = 0; - /* - * RollbackKernel*() functions use a global flag inside - * rollback_index.c based on recovery mode, which is set by SetupTPM(). - * Clear the flag for the first set of tests. - */ - TEST_EQ(SetupTPM(0, 0, 0, &rsf), 0, "SetupTPM()"); - /* Normal read */ ResetMocks(0, 0); mock_rsk.uid = ROLLBACK_SPACE_KERNEL_UID; @@ -978,7 +566,6 @@ static void RollbackKernelTest(void) "RollbackKernelLock() error"); /* Test lock with recovery on; shouldn't lock PP */ - SetupTPM(0, 0, 0, &rsf); ResetMocks(0, 0); TEST_EQ(RollbackKernelLock(1), 0, "RollbackKernelLock() in recovery"); TEST_STR_EQ(mock_calls, "", "no tlcl calls"); @@ -991,27 +578,6 @@ static void RollbackKernelTest(void) } /****************************************************************************/ -/* Tests for RollbackS3Resume() */ -static void RollbackS3ResumeTest(void) -{ - ResetMocks(0, 0); - TEST_EQ(RollbackS3Resume(), 0, "RollbackS3Resume()"); - TEST_STR_EQ(mock_calls, - "TlclLibInit()\n" - "TlclResume()\n", - "tlcl calls"); - - /* Should ignore postinit error */ - ResetMocks(2, TPM_E_INVALID_POSTINIT); - TEST_EQ(RollbackS3Resume(), 0, "RollbackS3Resume() postinit"); - - /* Resume with other error */ - ResetMocks(2, TPM_E_IOERROR); - TEST_EQ(RollbackS3Resume(), TPM_E_IOERROR, - "RollbackS3Resume() other error"); -} - -/****************************************************************************/ /* Tests for RollbackFwmpRead() calls */ static void RollbackFwmpTest(void) @@ -1109,11 +675,7 @@ int main(int argc, char* argv[]) CrcTestFirmware(); CrcTestKernel(); MiscTest(); - OneTimeInitTest(); - SetupTpmTest(); - RollbackFirmwareTest(); RollbackKernelTest(); - RollbackS3ResumeTest(); RollbackFwmpTest(); return gTestSuccess ? 0 : 255; diff --git a/tests/rollback_index3_tests.c b/tests/rollback_index3_tests.c index e89ad0ce..46863fbd 100644 --- a/tests/rollback_index3_tests.c +++ b/tests/rollback_index3_tests.c @@ -17,22 +17,8 @@ int main(int argc, char* argv[]) { - int is_virt_dev; - uint32_t version; + uint32_t version = 1; - TEST_EQ(RollbackS3Resume(), 0, "RollbackS3Resume()"); - - is_virt_dev = 1; - version = 1; - TEST_EQ(RollbackFirmwareSetup(0, 0, 0, &is_virt_dev, &version), - 0, "RollbackFirmwareSetup()"); - TEST_EQ(is_virt_dev, 0, "rfs is_virt_dev"); - TEST_EQ(version, 0, "rfs version"); - - TEST_EQ(RollbackFirmwareWrite(0), 0, "RollbackFirmwareWrite()"); - TEST_EQ(RollbackFirmwareLock(), 0, "RollbackFirmwareLock()"); - - version = 1; TEST_EQ(RollbackKernelRead(&version), 0, "RollbackKernelRead()"); TEST_EQ(version, 0, "rkr version"); diff --git a/tests/tpm_bootmode_tests.c b/tests/tpm_bootmode_tests.c deleted file mode 100644 index 64171b56..00000000 --- a/tests/tpm_bootmode_tests.c +++ /dev/null @@ -1,152 +0,0 @@ -/* 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. - * - * Tests for tpm_bootmode functions - */ - -#include <stdint.h> -#include <stdio.h> -#include <stdlib.h> -#include <string.h> - -#define _STUB_IMPLEMENTATION_ /* So we can use memset() ourselves */ - -#include "test_common.h" -#include "utility.h" -#include "tpm_bootmode.h" - -extern const char* kBootStateSHA1Digests[]; - -/* Last in_digest passed to TlclExtend() for each PCR */ -static const uint8_t *last_in[20]; - -/* Return value to pass for TlclExtend() */ -static uint32_t extend_returns; - -/* How many calls to TlclExtend() should one SetTPMBootModeState() make? */ -static int expected_extend_count; -/* How many did we get? */ -static int actual_extend_count; - -static GoogleBinaryBlockHeader gbb_v1 = { - .major_version = GBB_MAJOR_VER, - .minor_version = 1, -}; - -static GoogleBinaryBlockHeader gbb_v2 = { - .major_version = GBB_MAJOR_VER, - .minor_version = 2, - .hwid_digest = {1, 2, 3, 4,}, -}; - -/* Mocked TlclExtend() function for testing */ -uint32_t TlclExtend(int pcr_num, const uint8_t *in_digest, - uint8_t *out_digest) -{ - /* Should be using correct pcr */ - TEST_EQ(pcr_num, actual_extend_count, "TlclExtend pcr_num"); - - last_in[actual_extend_count] = in_digest; - - actual_extend_count++; - return extend_returns; -} - - -/* Test setting TPM boot mode state */ -static void BootStateTest(void) -{ - int recdev; - int flags; - int index; - char what[128]; - - /* Test all permutations of developer and recovery mode */ - for (recdev = 0; recdev < 4; recdev++) { - /* Exhaustively test all permutations of key block flags - * currently defined in vboot_struct.h (KEY_BLOCK_FLAG_*) */ - for (flags = 0; flags < 16; flags++) { - index = recdev * 3; - if (6 == flags) - index += 2; - else if (7 == flags) - index += 1; - - /* Passing a null pointer for GBB */ - memset(last_in, 0, sizeof(last_in)); - actual_extend_count = 0; - expected_extend_count = 1; - TEST_EQ(SetTPMBootModeState(recdev & 2, recdev & 1, - flags, 0), 0, - "SetTPMBootModeState return (gbb0)"); - snprintf(what, sizeof(what), - "SetTPMBootModeState %d, 0x%x (gbb0)", - recdev, flags); - TEST_PTR_EQ(last_in[0], - kBootStateSHA1Digests[index], what); - TEST_EQ(expected_extend_count, actual_extend_count, - "Expected TlclExtend call count (gbb0)"); - snprintf(what, sizeof(what), - "SetTPMBootModeState %d, 0x%x (gbb0) PCR1", - recdev, flags); - TEST_PTR_EQ(last_in[1], NULL, what); - - /* GBB v1.1 - should be exactly the same */ - memset(last_in, 0, sizeof(last_in)); - actual_extend_count = 0; - expected_extend_count = 1; - TEST_EQ(SetTPMBootModeState(recdev & 2, recdev & 1, - flags, &gbb_v1), 0, - "SetTPMBootModeState return (gbb1)"); - snprintf(what, sizeof(what), - "SetTPMBootModeState %d, 0x%x (gbb1)", - recdev, flags); - TEST_PTR_EQ(last_in[0], - kBootStateSHA1Digests[index], what); - TEST_EQ(expected_extend_count, actual_extend_count, - "Expected TlclExtend call count (gbb1)"); - snprintf(what, sizeof(what), - "SetTPMBootModeState %d, 0x%x (gbb1) PCR1", - recdev, flags); - TEST_PTR_EQ(last_in[1], NULL, what); - - /* GBB v1.2 - should extend PCR1 with HWID digest */ - memset(last_in, 0, sizeof(last_in)); - actual_extend_count = 0; - expected_extend_count = 2; - TEST_EQ(SetTPMBootModeState(recdev & 2, recdev & 1, - flags, &gbb_v2), 0, - "SetTPMBootModeState return (gbb2)"); - snprintf(what, sizeof(what), - "SetTPMBootModeState %d, 0x%x (gbb2)", - recdev, flags); - TEST_PTR_EQ(last_in[0], - kBootStateSHA1Digests[index], what); - TEST_EQ(expected_extend_count, actual_extend_count, - "Expected TlclExtend call count (gbb2)"); - snprintf(what, sizeof(what), - "SetTPMBootModeState %d, 0x%x (gbb2) PCR1", - recdev, flags); - TEST_PTR_EQ(last_in[1], gbb_v2.hwid_digest, what); - } - } - - extend_returns = 1; - actual_extend_count = 0; - expected_extend_count = 1; - TEST_EQ(SetTPMBootModeState(0, 0, 0, 0), 1, - "SetTPMBootModeState error"); -} - -int main(int argc, char *argv[]) -{ - int error_code = 0; - - BootStateTest(); - - if (!gTestSuccess) - error_code = 255; - - return error_code; -} diff --git a/tests/vboot_api_firmware_tests.c b/tests/vboot_api_firmware_tests.c deleted file mode 100644 index 1b5c6361..00000000 --- a/tests/vboot_api_firmware_tests.c +++ /dev/null @@ -1,259 +0,0 @@ -/* 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. - * - * Tests for vboot_api_firmware - */ - -#include <stdint.h> -#include <stdio.h> -#include <stdlib.h> - -#include "gbb_header.h" -#include "host_common.h" -#include "rollback_index.h" -#include "test_common.h" -#include "vboot_common.h" -#include "vboot_nvstorage.h" -#include "vboot_struct.h" - -/* Flags for mock_*_got_flags variables */ -#define MOCK_DEV_FLAG 0x01 /* Developer parameter non-zero */ -#define MOCK_REC_FLAG 0x02 /* Recovery parameter non-zero */ - -/* Mock data */ -static VbCommonParams cparams; -static VbSelectFirmwareParams fparams; -static GoogleBinaryBlockHeader gbb; -static VbNvContext vnc; -static uint8_t shared_data[VB_SHARED_DATA_MIN_SIZE]; -static VbSharedDataHeader* shared = (VbSharedDataHeader*)shared_data; -static uint64_t mock_timer; -static int nv_write_called; -/* Mock TPM versions */ -static uint32_t mock_tpm_version; -static uint32_t mock_lf_tpm_version; /* TPM version set by LoadFirmware() */ -/* Variables for tracking params passed to mock functions */ -static uint32_t mock_stbms_got_flags; -static uint64_t mock_stbms_got_fw_flags; -static int mock_rfl_called; -/* Mock return values, so we can simulate errors */ -static VbError_t mock_rfw_retval; -static VbError_t mock_rfl_retval; -static VbError_t mock_lf_retval; -static VbError_t mock_stbms_retval; - -/* Reset mock data (for use before each test) */ -static void ResetMocks(void) { - Memset(&cparams, 0, sizeof(cparams)); - cparams.shared_data_size = sizeof(shared_data); - cparams.shared_data_blob = shared_data; - - Memset(&fparams, 0, sizeof(fparams)); - - Memset(&gbb, 0, sizeof(gbb)); - cparams.gbb_data = &gbb; - cparams.gbb_size = sizeof(gbb); - cparams.gbb = &gbb; - - Memset(&vnc, 0, sizeof(vnc)); - VbNvSetup(&vnc); - VbNvTeardown(&vnc); /* So CRC gets generated */ - - Memset(&shared_data, 0, sizeof(shared_data)); - VbSharedDataInit(shared, sizeof(shared_data)); - shared->fw_keyblock_flags = 0xABCDE0; - - mock_timer = 10; - nv_write_called = mock_rfl_called = 0; - - mock_stbms_got_flags = 0; - mock_stbms_got_fw_flags = 0; - - mock_tpm_version = mock_lf_tpm_version = 0x20004; - shared->fw_version_tpm_start = mock_tpm_version; - mock_rfw_retval = mock_rfl_retval = 0; - mock_lf_retval = mock_stbms_retval = 0; -} - -/****************************************************************************/ -/* Mocked verification functions */ - -VbError_t VbExNvStorageRead(uint8_t* buf) { - Memcpy(buf, vnc.raw, sizeof(vnc.raw)); - return VBERROR_SUCCESS; -} - -VbError_t VbExNvStorageWrite(const uint8_t* buf) { - nv_write_called = 1; - Memcpy(vnc.raw, buf, sizeof(vnc.raw)); - return VBERROR_SUCCESS; -} - -uint64_t VbExGetTimer(void) { - /* Exponential-ish rather than linear time, so that subtracting any - * two mock values will yield a unique result. */ - uint64_t new_timer = mock_timer * 2 + 1; - VbAssert(new_timer > mock_timer); /* Make sure we don't overflow */ - mock_timer = new_timer; - return mock_timer; -} - -uint32_t RollbackFirmwareWrite(uint32_t version) { - mock_tpm_version = version; - return mock_rfw_retval; -} - -uint32_t RollbackFirmwareLock(void) { - mock_rfl_called = 1; - return mock_rfl_retval; -} - -uint32_t SetTPMBootModeState(int developer_mode, int recovery_mode, - uint64_t fw_keyblock_flags, - GoogleBinaryBlockHeader *gbb) { - if (recovery_mode) - mock_stbms_got_flags |= MOCK_REC_FLAG; - if (developer_mode) - mock_stbms_got_flags |= MOCK_DEV_FLAG; - - mock_stbms_got_fw_flags = fw_keyblock_flags; - - return mock_stbms_retval; -} - -int LoadFirmware(VbCommonParams* cparams, VbSelectFirmwareParams* fparams, - VbNvContext* vnc) { - shared->fw_version_tpm = mock_lf_tpm_version; - return mock_lf_retval; -} - - -/****************************************************************************/ -/* Test VbSelectFirmware() and check expected return value and - * recovery reason */ -static void TestVbSf(VbError_t expected_retval, - uint8_t expected_recovery, const char* desc) { - uint32_t rr = 256; - - TEST_EQ(VbSelectFirmware(&cparams, &fparams), expected_retval, desc); - VbNvGet(&vnc, VBNV_RECOVERY_REQUEST, &rr); - TEST_EQ(rr, expected_recovery, " recovery request"); -} - -/****************************************************************************/ - -static void VbSelectFirmwareTest(void) { - /* Normal call */ - ResetMocks(); - TestVbSf(0, 0, "Normal call"); - TEST_EQ(shared->timer_vb_select_firmware_enter, 21, " time enter"); - TEST_EQ(shared->timer_vb_select_firmware_exit, 43, " time exit"); - TEST_EQ(nv_write_called, 0, " NV write not called since nothing changed"); - TEST_EQ(mock_stbms_got_flags, 0, " SetTPMBootModeState() flags"); - TEST_EQ(mock_stbms_got_fw_flags, 0xABCDE0, " fw keyblock flags"); - TEST_EQ(mock_rfl_called, 1, " RollbackFirmwareLock() called"); - - /* Developer mode call */ - ResetMocks(); - shared->flags |= VBSD_BOOT_DEV_SWITCH_ON; - TestVbSf(0, 0, "Developer mode"); - TEST_EQ(mock_stbms_got_flags, MOCK_DEV_FLAG, " SetTPMBootModeState() flags"); - TEST_EQ(mock_rfl_called, 1, " RollbackFirmwareLock() called"); - - /* Recovery mode doesn't call LoadFirmware(), - * RollbackFirmwareWrite(), or RollbackFirmwareLock(). */ - ResetMocks(); - shared->recovery_reason = VBNV_RECOVERY_US_TEST; - mock_lf_retval = VBERROR_UNKNOWN; - mock_rfw_retval = mock_rfl_retval = TPM_E_IOERROR; - TestVbSf(0, 0, "Recovery mode"); - TEST_EQ(fparams.selected_firmware, VB_SELECT_FIRMWARE_RECOVERY, - " select recovery"); - TEST_EQ(mock_stbms_got_flags, MOCK_REC_FLAG, " SetTPMBootModeState() flags"); - TEST_EQ(mock_rfl_called, 0, " RollbackFirmwareLock() not called"); - - /* Dev + recovery */ - ResetMocks(); - shared->recovery_reason = VBNV_RECOVERY_US_TEST; - shared->flags |= VBSD_BOOT_DEV_SWITCH_ON; - TestVbSf(0, 0, "Recovery+developer mode"); - TEST_EQ(fparams.selected_firmware, VB_SELECT_FIRMWARE_RECOVERY, - " select recovery"); - TEST_EQ(mock_stbms_got_flags, MOCK_DEV_FLAG|MOCK_REC_FLAG, - " SetTPMBootModeState() flags"); - TEST_EQ(mock_rfl_called, 0, " RollbackFirmwareLock() not called"); - - /* LoadFirmware() error code passed through */ - ResetMocks(); - mock_lf_retval = 0x12345; - TestVbSf(0x12345, 0, "LoadFirmware() error"); - - /* Select different firmware paths based on LoadFirmware() result */ - ResetMocks(); - shared->flags |= VBSD_LF_USE_RO_NORMAL; - TestVbSf(0, 0, "LoadFirmware() RO-normal"); - TEST_EQ(fparams.selected_firmware, VB_SELECT_FIRMWARE_READONLY, - " select RO normal"); - ResetMocks(); - shared->firmware_index = 0; - TestVbSf(0, 0, "LoadFirmware() A"); - TEST_EQ(fparams.selected_firmware, VB_SELECT_FIRMWARE_A, " select A"); - ResetMocks(); - shared->firmware_index = 1; - TestVbSf(0, 0, "LoadFirmware() B"); - TEST_EQ(fparams.selected_firmware, VB_SELECT_FIRMWARE_B, " select B"); - - /* Handle TPM version updates */ - ResetMocks(); - mock_lf_tpm_version = 0x30005; - TestVbSf(0, 0, "TPM version update"); - TEST_EQ(shared->fw_version_tpm_start, 0x20004, " TPM version start"); - TEST_EQ(shared->fw_version_tpm, 0x30005, " TPM version"); - TEST_EQ(mock_tpm_version, 0x30005, " TPM version written back"); - - /* Check error writing TPM version */ - ResetMocks(); - mock_lf_tpm_version = 0x30005; - mock_rfw_retval = TPM_E_IOERROR; - TestVbSf(VBERROR_TPM_WRITE_FIRMWARE, VBNV_RECOVERY_RO_TPM_W_ERROR, - "TPM version update failure"); - - /* If no change to TPM version, RollbackFirmwareWrite() not called */ - ResetMocks(); - mock_rfw_retval = TPM_E_IOERROR; - TestVbSf(0, 0, "LoadFirmware() TPM version not updated"); - TEST_EQ(shared->fw_version_tpm_start, 0x20004, " TPM version start"); - TEST_EQ(shared->fw_version_tpm, 0x20004, " TPM version"); - TEST_EQ(mock_tpm_version, 0x20004, " TPM version (not) written back"); - - /* Check errors from SetTPMBootModeState() */ - ResetMocks(); - mock_stbms_retval = TPM_E_IOERROR; - TestVbSf(VBERROR_TPM_SET_BOOT_MODE_STATE, VBNV_RECOVERY_RO_TPM_U_ERROR, - "TPM set boot mode state failure"); - ResetMocks(); - mock_stbms_retval = TPM_E_IOERROR; - shared->recovery_reason = VBNV_RECOVERY_US_TEST; - TestVbSf(0, 0, "TPM set boot mode state failure ignored in recovery"); - - /* Handle RollbackFirmwareLock() errors */ - ResetMocks(); - mock_rfl_retval = TPM_E_IOERROR; - TestVbSf(VBERROR_TPM_LOCK_FIRMWARE, VBNV_RECOVERY_RO_TPM_L_ERROR, - "TPM lock firmware failure"); -} - - -int main(int argc, char* argv[]) { - int error_code = 0; - - VbSelectFirmwareTest(); - - if (vboot_api_stub_check_memory()) - error_code = 255; - if (!gTestSuccess) - error_code = 255; - - return error_code; -} diff --git a/tests/vboot_api_init_tests.c b/tests/vboot_api_init_tests.c deleted file mode 100644 index 366873b6..00000000 --- a/tests/vboot_api_init_tests.c +++ /dev/null @@ -1,803 +0,0 @@ -/* Copyright (c) 2013 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. - * - * Tests for vboot_api_init - */ - -#include <stdint.h> -#include <stdio.h> -#include <stdlib.h> - -#include "gbb_header.h" -#include "host_common.h" -#include "rollback_index.h" -#include "test_common.h" -#include "vboot_common.h" -#include "vboot_nvstorage.h" -#include "vboot_struct.h" - -/* Mock data */ -static VbCommonParams cparams; -static VbInitParams iparams; -static VbNvContext vnc; -static uint8_t shared_data[VB_SHARED_DATA_MIN_SIZE]; -static VbSharedDataHeader *shared = (VbSharedDataHeader *)shared_data; -static uint64_t mock_timer; -static int rollback_s3_retval; -static int nv_write_called; -static GoogleBinaryBlockHeader gbb; -static int mock_virt_dev_sw; -static uint32_t mock_tpm_version; -static uint32_t mock_rfs_retval; -static int rfs_clear_tpm_request; -static int rfs_disable_dev_request; -static uint8_t backup_space[BACKUP_NV_SIZE]; -static int backup_write_called; -static int backup_read_called; - -/* Reset mock data (for use before each test) */ -static void ResetMocks(void) -{ - Memset(&cparams, 0, sizeof(cparams)); - cparams.shared_data_size = sizeof(shared_data); - cparams.shared_data_blob = shared_data; - cparams.gbb_data = &gbb; - cparams.gbb_size = sizeof(gbb); - - Memset(&gbb, 0, sizeof(gbb)); - gbb.major_version = GBB_MAJOR_VER; - gbb.minor_version = GBB_MINOR_VER; - gbb.flags = 0; - - Memset(&iparams, 0, sizeof(iparams)); - - Memset(&vnc, 0, sizeof(vnc)); - VbNvSetup(&vnc); - VbNvTeardown(&vnc); /* So CRC gets generated */ - - Memset(backup_space, 0, sizeof(backup_space)); - backup_write_called = 0; - backup_read_called = 0; - - Memset(&shared_data, 0, sizeof(shared_data)); - VbSharedDataInit(shared, sizeof(shared_data)); - - mock_timer = 10; - rollback_s3_retval = TPM_SUCCESS; - nv_write_called = 0; - - mock_virt_dev_sw = 0; - mock_tpm_version = 0x10001; - mock_rfs_retval = 0; - - rfs_clear_tpm_request = 0; - rfs_disable_dev_request = 0; -} - -/****************************************************************************/ -/* Mocked verification functions */ - -VbError_t VbExNvStorageRead(uint8_t *buf) -{ - Memcpy(buf, vnc.raw, sizeof(vnc.raw)); - return VBERROR_SUCCESS; -} - -VbError_t VbExNvStorageWrite(const uint8_t *buf) -{ - nv_write_called++; - Memcpy(vnc.raw, buf, sizeof(vnc.raw)); - return VBERROR_SUCCESS; -} - -uint32_t RollbackBackupRead(uint8_t *raw) -{ - backup_read_called++; - Memcpy(raw, backup_space, sizeof(backup_space)); - return TPM_SUCCESS; -} - -uint32_t RollbackBackupWrite(uint8_t *raw) -{ - backup_write_called++; - Memcpy(backup_space, raw, sizeof(backup_space)); - return TPM_SUCCESS; -} - -uint64_t VbExGetTimer(void) -{ - /* - * Exponential-ish rather than linear time, so that subtracting any - * two mock values will yield a unique result. - */ - uint64_t new_timer = mock_timer * 2 + 1; - VbAssert(new_timer > mock_timer); /* Make sure we don't overflow */ - mock_timer = new_timer; - return mock_timer; -} - -uint32_t RollbackS3Resume(void) -{ - return rollback_s3_retval; -} - -uint32_t RollbackFirmwareSetup(int is_hw_dev, - int disable_dev_request, - int clear_tpm_owner_request, - /* two outputs on success */ - int *is_virt_dev, uint32_t *version) -{ - rfs_clear_tpm_request = clear_tpm_owner_request; - rfs_disable_dev_request = disable_dev_request; - - *is_virt_dev = mock_virt_dev_sw; - *version = mock_tpm_version; - return mock_rfs_retval; -} - -/****************************************************************************/ -/* Test VbInit() and check expected return value and recovery reason */ - -static void TestVbInit(VbError_t expected_retval, - uint8_t expected_recovery, const char *desc) -{ - uint32_t rr = 256; - - TEST_EQ(VbInit(&cparams, &iparams), expected_retval, desc); - VbNvGet(&vnc, VBNV_RECOVERY_REQUEST, &rr); - TEST_EQ(rr, expected_recovery, " (recovery request)"); -} - -/****************************************************************************/ - -static void VbInitTest(void) -{ - uint32_t u; - - /* Test passing in too small a shared data area */ - ResetMocks(); - cparams.shared_data_size = VB_SHARED_DATA_MIN_SIZE - 1; - TestVbInit(VBERROR_INIT_SHARED_DATA, 0, "Shared data too small"); - - /* Normal call; dev=0 rec=0 */ - ResetMocks(); - TestVbInit(0, 0, "Normal call"); - TEST_EQ(shared->timer_vb_init_enter, 21, " time enter"); - TEST_EQ(shared->timer_vb_init_exit, 43, " time exit"); - TEST_EQ(shared->flags, 0, " shared flags"); - TEST_EQ(iparams.out_flags, 0, " out flags"); - TEST_EQ(nv_write_called, 0, - " NV write not called since nothing changed"); - - /* If NV data is trashed, we initialize it */ - ResetMocks(); - VbNvSet(&vnc, VBNV_RECOVERY_REQUEST, 123); - /* - * Note that we're not doing a VbNvTeardown(), so the CRC hasn't been - * regenerated yet. So VbInit() should ignore the corrupted recovery - * value and boot normally. - */ - TestVbInit(0, 0, "NV data trashed"); - TEST_EQ(nv_write_called, 1, " NV write called"); - - /* - * Test boot switch flags which are just passed through to shared - * flags, and don't have an effect on VbInit(). - */ - ResetMocks(); - iparams.flags = VB_INIT_FLAG_WP_ENABLED; - TestVbInit(0, 0, "Flags test WP"); - TEST_EQ(shared->flags, VBSD_BOOT_FIRMWARE_WP_ENABLED, - " shared flags"); - - ResetMocks(); - iparams.flags = VB_INIT_FLAG_SW_WP_ENABLED; - TestVbInit(0, 0, "Flags test SW WP"); - TEST_EQ(shared->flags, VBSD_BOOT_FIRMWARE_SW_WP_ENABLED, - " shared flags"); - - ResetMocks(); - iparams.flags = VB_INIT_FLAG_RO_NORMAL_SUPPORT; - TestVbInit(0, 0, " flags test RO normal"); - TEST_EQ(shared->flags, VBSD_BOOT_RO_NORMAL_SUPPORT, - " shared flags"); - - ResetMocks(); - iparams.flags = VB_INIT_FLAG_EC_SOFTWARE_SYNC; - TestVbInit(0, 0, " flags test EC software sync"); - TEST_EQ(shared->flags, VBSD_EC_SOFTWARE_SYNC, " shared flags"); - - ResetMocks(); - iparams.flags = VB_INIT_FLAG_EC_SLOW_UPDATE; - TestVbInit(0, 0, " flags test EC slow update"); - TEST_EQ(shared->flags, VBSD_EC_SLOW_UPDATE, " shared flags"); - - /* S3 resume */ - ResetMocks(); - iparams.flags = VB_INIT_FLAG_S3_RESUME; - VbNvSet(&vnc, VBNV_RECOVERY_REQUEST, 123); - VbNvTeardown(&vnc); - /* S3 resume doesn't clear the recovery request (or act on it) */ - TestVbInit(0, 123, "S3 resume"); - TEST_EQ(shared->flags, VBSD_BOOT_S3_RESUME, " shared flags S3"); - TEST_EQ(iparams.out_flags, 0, " out flags"); - TEST_EQ(shared->recovery_reason, 0, - " S3 doesn't look at recovery request"); - - /* S3 resume with TPM resume error */ - ResetMocks(); - iparams.flags = VB_INIT_FLAG_S3_RESUME; - rollback_s3_retval = 1; - /* S3 resume doesn't clear the recovery request (or act on it) */ - TestVbInit(VBERROR_TPM_S3_RESUME, 0, "S3 resume rollback error"); - - /* - * Normal boot doesn't care about TPM resume error because it doesn't - * call RollbackS3Resume(). - */ - ResetMocks(); - rollback_s3_retval = 1; - TestVbInit(0, 0, "Normal doesn't S3 resume"); - - /* S3 resume with debug reset */ - ResetMocks(); - iparams.flags = VB_INIT_FLAG_S3_RESUME; - VbNvSet(&vnc, VBNV_DEBUG_RESET_MODE, 1); - VbNvTeardown(&vnc); - TestVbInit(0, 0, "S3 debug reset"); - TEST_EQ(iparams.out_flags, VB_INIT_OUT_S3_DEBUG_BOOT, " out flags"); - VbNvGet(&vnc, VBNV_DEBUG_RESET_MODE, &u); - TEST_EQ(u, 0, " S3 clears nv debug reset mode"); - - /* Normal boot clears S3 debug reset mode; doesn't set output flag */ - ResetMocks(); - VbNvSet(&vnc, VBNV_DEBUG_RESET_MODE, 1); - VbNvTeardown(&vnc); - TestVbInit(0, 0, "Normal with debug reset mode"); - TEST_EQ(iparams.out_flags, 0, " out flags"); - VbNvGet(&vnc, VBNV_DEBUG_RESET_MODE, &u); - TEST_EQ(u, 0, " normal clears nv debug reset mode"); - - /* - * S3 resume with debug reset is a normal boot, so doesn't resume the - * TPM. - */ - ResetMocks(); - iparams.flags = VB_INIT_FLAG_S3_RESUME; - rollback_s3_retval = 1; - VbNvSet(&vnc, VBNV_DEBUG_RESET_MODE, 1); - VbNvTeardown(&vnc); - TestVbInit(0, 0, "S3 debug reset rollback error"); - - /* Developer mode */ - ResetMocks(); - iparams.flags = VB_INIT_FLAG_DEV_SWITCH_ON; - TestVbInit(0, 0, "Dev mode on"); - TEST_EQ(shared->recovery_reason, 0, " recovery reason"); - TEST_EQ(iparams.out_flags, - VB_INIT_OUT_CLEAR_RAM | - VB_INIT_OUT_ENABLE_DISPLAY | - VB_INIT_OUT_ENABLE_USB_STORAGE | - VB_INIT_OUT_ENABLE_DEVELOPER | - VB_INIT_OUT_ENABLE_ALTERNATE_OS, " out flags"); - TEST_EQ(shared->flags, VBSD_BOOT_DEV_SWITCH_ON, " shared flags"); - - /* Developer mode forced by GBB flag */ - ResetMocks(); - iparams.flags = 0; - gbb.flags = GBB_FLAG_FORCE_DEV_SWITCH_ON; - TestVbInit(0, 0, "Dev mode via GBB"); - TEST_EQ(shared->recovery_reason, 0, " recovery reason"); - TEST_EQ(iparams.out_flags, - VB_INIT_OUT_CLEAR_RAM | - VB_INIT_OUT_ENABLE_DISPLAY | - VB_INIT_OUT_ENABLE_USB_STORAGE | - VB_INIT_OUT_ENABLE_DEVELOPER | - VB_INIT_OUT_ENABLE_ALTERNATE_OS, " out flags"); - TEST_EQ(shared->flags, VBSD_BOOT_DEV_SWITCH_ON, " shared flags"); - - /* Developer mode when option ROM matters and isn't loaded */ - ResetMocks(); - iparams.flags = VB_INIT_FLAG_DEV_SWITCH_ON | - VB_INIT_FLAG_OPROM_MATTERS; - TestVbInit(VBERROR_VGA_OPROM_MISMATCH, 0, "Dev mode need oprom"); - VbNvGet(&vnc, VBNV_OPROM_NEEDED, &u); - TEST_EQ(u, 1, " oprom requested"); - - /* Developer mode when option ROM matters and is already loaded */ - ResetMocks(); - iparams.flags = VB_INIT_FLAG_DEV_SWITCH_ON | - VB_INIT_FLAG_OPROM_MATTERS | VB_INIT_FLAG_OPROM_LOADED; - TestVbInit(0, 0, "Dev mode has oprom"); - - /* Normal mode when option ROM matters and is loaded */ - ResetMocks(); - VbNvSet(&vnc, VBNV_OPROM_NEEDED, 1); - VbNvTeardown(&vnc); - iparams.flags = VB_INIT_FLAG_OPROM_MATTERS | VB_INIT_FLAG_OPROM_LOADED; - TestVbInit(VBERROR_VGA_OPROM_MISMATCH, 0, "Normal mode with oprom"); - VbNvGet(&vnc, VBNV_OPROM_NEEDED, &u); - TEST_EQ(u, 0, " oprom not requested"); - - /* Option ROMs can be forced by GBB flag */ - ResetMocks(); - gbb.flags = GBB_FLAG_LOAD_OPTION_ROMS; - TestVbInit(0, 0, "GBB load option ROMs"); - TEST_EQ(iparams.out_flags, VB_INIT_OUT_ENABLE_OPROM, " out flags"); - - /* If requiring signed only, don't enable alternate OS by default */ - ResetMocks(); - VbNvSet(&vnc, VBNV_DEV_BOOT_SIGNED_ONLY, 1); - VbNvTeardown(&vnc); - iparams.flags = VB_INIT_FLAG_DEV_SWITCH_ON; - TestVbInit(0, 0, "Dev signed only"); - TEST_EQ(iparams.out_flags, - VB_INIT_OUT_CLEAR_RAM | - VB_INIT_OUT_ENABLE_DISPLAY | - VB_INIT_OUT_ENABLE_USB_STORAGE | - VB_INIT_OUT_ENABLE_DEVELOPER, " out flags"); - - /* But that can be overridden by the GBB */ - ResetMocks(); - VbNvSet(&vnc, VBNV_DEV_BOOT_SIGNED_ONLY, 1); - VbNvTeardown(&vnc); - iparams.flags = VB_INIT_FLAG_DEV_SWITCH_ON; - gbb.flags = GBB_FLAG_ENABLE_ALTERNATE_OS; - TestVbInit(0, 0, "Force option ROMs via GBB"); - TEST_EQ(iparams.out_flags, - VB_INIT_OUT_CLEAR_RAM | - VB_INIT_OUT_ENABLE_DISPLAY | - VB_INIT_OUT_ENABLE_USB_STORAGE | - VB_INIT_OUT_ENABLE_DEVELOPER | - VB_INIT_OUT_ENABLE_ALTERNATE_OS, " out flags"); - - /* The GBB override is ignored in normal mode */ - ResetMocks(); - gbb.flags = GBB_FLAG_ENABLE_ALTERNATE_OS; - TestVbInit(0, 0, "Normal mode ignores forcing option ROMs via GBB"); - TEST_EQ(iparams.out_flags, 0, " out flags"); - - /* Recovery mode from NV storage */ - ResetMocks(); - VbNvSet(&vnc, VBNV_RECOVERY_REQUEST, 123); - VbNvTeardown(&vnc); - TestVbInit(0, 0, "Recovery mode - from nv"); - TEST_EQ(shared->recovery_reason, 123, " recovery reason"); - TEST_EQ(iparams.out_flags, - VB_INIT_OUT_ENABLE_RECOVERY | - VB_INIT_OUT_CLEAR_RAM | - VB_INIT_OUT_ENABLE_DISPLAY | - VB_INIT_OUT_ENABLE_USB_STORAGE, " out flags"); - TEST_EQ(shared->flags, 0, " shared flags"); - - /* Recovery mode from recovery button */ - ResetMocks(); - iparams.flags = VB_INIT_FLAG_REC_BUTTON_PRESSED; - TestVbInit(0, 0, "Recovery mode - button"); - TEST_EQ(shared->recovery_reason, VBNV_RECOVERY_RO_MANUAL, - " recovery reason"); - TEST_EQ(iparams.out_flags, - VB_INIT_OUT_ENABLE_RECOVERY | - VB_INIT_OUT_CLEAR_RAM | - VB_INIT_OUT_ENABLE_DISPLAY | - VB_INIT_OUT_ENABLE_USB_STORAGE, " out flags"); - TEST_EQ(shared->flags, VBSD_BOOT_REC_SWITCH_ON, " shared flags"); - - /* Recovery button reason supersedes NV reason */ - ResetMocks(); - iparams.flags = VB_INIT_FLAG_REC_BUTTON_PRESSED; - VbNvSet(&vnc, VBNV_RECOVERY_REQUEST, 123); - VbNvTeardown(&vnc); - TestVbInit(0, 0, "Recovery mode - button AND nv"); - TEST_EQ(shared->recovery_reason, VBNV_RECOVERY_RO_MANUAL, - " recovery reason"); - - /* Recovery mode from previous boot fail */ - ResetMocks(); - iparams.flags = VB_INIT_FLAG_PREVIOUS_BOOT_FAIL; - TestVbInit(0, 0, "Recovery mode - previous boot fail"); - TEST_EQ(shared->recovery_reason, VBNV_RECOVERY_RO_FIRMWARE, - " recovery reason"); - TEST_EQ(iparams.out_flags, - VB_INIT_OUT_ENABLE_RECOVERY | - VB_INIT_OUT_CLEAR_RAM | - VB_INIT_OUT_ENABLE_DISPLAY | - VB_INIT_OUT_ENABLE_USB_STORAGE, " out flags"); - TEST_EQ(shared->flags, 0, " shared flags"); - - /* Recovery mode from NV supersedes previous boot fail */ - ResetMocks(); - iparams.flags = VB_INIT_FLAG_PREVIOUS_BOOT_FAIL; - VbNvSet(&vnc, VBNV_RECOVERY_REQUEST, 123); - VbNvTeardown(&vnc); - TestVbInit(0, 0, "Recovery mode - previous boot fail AND nv"); - TEST_EQ(shared->recovery_reason, 123, " recovery reason"); - - /* Dev + recovery = recovery */ - ResetMocks(); - iparams.flags = VB_INIT_FLAG_REC_BUTTON_PRESSED | - VB_INIT_FLAG_DEV_SWITCH_ON; - TestVbInit(0, 0, "Recovery mode - button"); - TEST_EQ(shared->recovery_reason, VBNV_RECOVERY_RO_MANUAL, - " recovery reason"); - TEST_EQ(iparams.out_flags, - VB_INIT_OUT_ENABLE_RECOVERY | - VB_INIT_OUT_CLEAR_RAM | - VB_INIT_OUT_ENABLE_DISPLAY | - VB_INIT_OUT_ENABLE_USB_STORAGE, " out flags"); - TEST_EQ(shared->flags, - VBSD_BOOT_REC_SWITCH_ON | VBSD_BOOT_DEV_SWITCH_ON, - " shared flags"); -} - -static void VbInitTestTPM(void) -{ - uint32_t u; - - /* Rollback setup needs to reboot */ - ResetMocks(); - mock_rfs_retval = TPM_E_MUST_REBOOT; - TestVbInit(VBERROR_TPM_REBOOT_REQUIRED, 0, - "Rollback TPM reboot (rec=0)"); - ResetMocks(); - mock_rfs_retval = TPM_E_MUST_REBOOT; - iparams.flags = VB_INIT_FLAG_REC_BUTTON_PRESSED; - TestVbInit(VBERROR_TPM_REBOOT_REQUIRED, VBNV_RECOVERY_RO_TPM_REBOOT, - "Rollback TPM reboot, in recovery, first time"); - /* Ignore if we already tried rebooting */ - ResetMocks(); - mock_rfs_retval = TPM_E_MUST_REBOOT; - VbNvSet(&vnc, VBNV_RECOVERY_REQUEST, VBNV_RECOVERY_RO_TPM_REBOOT); - VbNvTeardown(&vnc); - TestVbInit(0, 0, "Rollback TPM reboot, in recovery, already retried"); - TEST_EQ(shared->fw_version_tpm, 0x10001, " shared fw_version_tpm"); - - /* Other rollback setup errors */ - ResetMocks(); - mock_rfs_retval = TPM_E_IOERROR; - mock_tpm_version = 0x20002; - TestVbInit(VBERROR_TPM_FIRMWARE_SETUP, VBNV_RECOVERY_RO_TPM_S_ERROR, - "Rollback TPM setup error - not in recovery"); - TEST_EQ(shared->fw_version_tpm, 0, " shared fw_version_tpm not set"); - ResetMocks(); - mock_rfs_retval = TPM_E_IOERROR; - VbNvSet(&vnc, VBNV_RECOVERY_REQUEST, VBNV_RECOVERY_US_TEST); - VbNvTeardown(&vnc); - TestVbInit(0, 0, "Rollback TPM setup error ignored in recovery"); - TEST_EQ(shared->fw_version_tpm, 0x10001, " shared fw_version_tpm"); - - /* Virtual developer switch, but not enabled. */ - ResetMocks(); - VbNvSet(&vnc, VBNV_DISABLE_DEV_REQUEST, 1); - VbNvTeardown(&vnc); - iparams.flags = VB_INIT_FLAG_VIRTUAL_DEV_SWITCH; - TestVbInit(0, 0, "TPM Dev mode off"); - TEST_EQ(shared->recovery_reason, 0, " recovery reason"); - TEST_EQ(iparams.out_flags, 0, " out flags"); - TEST_EQ(shared->flags, VBSD_HONOR_VIRT_DEV_SWITCH, " shared flags"); - VbNvGet(&vnc, VBNV_DISABLE_DEV_REQUEST, &u); - TEST_EQ(u, 0, " disable dev request"); - - /* Virtual developer switch, enabled. */ - ResetMocks(); - VbNvSet(&vnc, VBNV_DISABLE_DEV_REQUEST, 1); - VbNvTeardown(&vnc); - iparams.flags = VB_INIT_FLAG_VIRTUAL_DEV_SWITCH; - mock_virt_dev_sw = 1; - TestVbInit(0, 0, "TPM Dev mode on"); - TEST_EQ(shared->recovery_reason, 0, " recovery reason"); - TEST_EQ(iparams.out_flags, - VB_INIT_OUT_CLEAR_RAM | - VB_INIT_OUT_ENABLE_DISPLAY | - VB_INIT_OUT_ENABLE_USB_STORAGE | - VB_INIT_OUT_ENABLE_DEVELOPER | - VB_INIT_OUT_ENABLE_ALTERNATE_OS, " out flags"); - TEST_EQ(shared->flags, - VBSD_BOOT_DEV_SWITCH_ON | VBSD_HONOR_VIRT_DEV_SWITCH, - " shared flags"); - /* Disable-request doesn't get cleared because dev mode is still on */ - VbNvGet(&vnc, VBNV_DISABLE_DEV_REQUEST, &u); - TEST_EQ(u, 1, " disable dev request"); - /* Disable request was passed on to RollbackFirmwareSetup() */ - TEST_EQ(rfs_disable_dev_request, 1, " rfs disable dev"); - - /* Ignore virtual developer switch, even though enabled. */ - ResetMocks(); - mock_virt_dev_sw = 1; - TestVbInit(0, 0, "TPM Dev mode on but ignored"); - TEST_EQ(shared->recovery_reason, 0, " recovery reason"); - TEST_EQ(iparams.out_flags, 0, " out flags"); - TEST_EQ(shared->flags, 0, " shared flags"); - - /* HW dev switch on, no virtual developer switch */ - ResetMocks(); - iparams.flags = VB_INIT_FLAG_DEV_SWITCH_ON; - TestVbInit(0, 0, "HW Dev mode on"); - TEST_EQ(shared->recovery_reason, 0, " recovery reason"); - TEST_EQ(iparams.out_flags, - VB_INIT_OUT_CLEAR_RAM | - VB_INIT_OUT_ENABLE_DISPLAY | - VB_INIT_OUT_ENABLE_USB_STORAGE | - VB_INIT_OUT_ENABLE_DEVELOPER | - VB_INIT_OUT_ENABLE_ALTERNATE_OS, " out flags"); - TEST_EQ(shared->flags, VBSD_BOOT_DEV_SWITCH_ON, " shared flags"); - - /* Check TPM owner clear request */ - ResetMocks(); - VbNvSet(&vnc, VBNV_CLEAR_TPM_OWNER_REQUEST, 1); - VbNvTeardown(&vnc); - TestVbInit(0, 0, "TPM clear owner"); - VbNvGet(&vnc, VBNV_CLEAR_TPM_OWNER_REQUEST, &u); - TEST_EQ(u, 0, " tpm clear request"); - VbNvGet(&vnc, VBNV_CLEAR_TPM_OWNER_DONE, &u); - TEST_EQ(u, 1, " tpm clear request"); - TEST_EQ(rfs_clear_tpm_request, 1, "rfs tpm clear request"); -} - -static void VbInitTestBackup(void) -{ - VbNvContext tmp_vnc; - uint32_t u, nv_w, bu_r; - - ResetMocks(); - /* Normal mode call */ - TestVbInit(0, 0, "normal mode, no backup"); - TEST_EQ(shared->flags, 0, " shared flags"); - TEST_EQ(iparams.out_flags, 0, " out flags"); - TEST_EQ(nv_write_called, 0, - " NV write not called since nothing changed"); - - ResetMocks(); - /* Now set some params that should be backed up. */ - VbNvSet(&vnc, VBNV_KERNEL_FIELD, 0xaabbccdd); - VbNvSet(&vnc, VBNV_LOCALIZATION_INDEX, 0xa5); - VbNvSet(&vnc, VBNV_DEV_BOOT_USB, 1); - VbNvSet(&vnc, VBNV_DEV_BOOT_LEGACY, 1); - VbNvSet(&vnc, VBNV_DEV_BOOT_SIGNED_ONLY, 1); - VbNvSet(&vnc, VBNV_DEV_BOOT_FASTBOOT_FULL_CAP, 1); - VbNvSet(&vnc, VBNV_DEV_DEFAULT_BOOT, 1); - VbNvSet(&vnc, VBNV_FASTBOOT_UNLOCK_IN_FW, 1); - /* and some that don't */ - VbNvSet(&vnc, VBNV_OPROM_NEEDED, 1); - VbNvSet(&vnc, VBNV_TRY_B_COUNT, 3); - /* Make sure they're clean */ - VbNvTeardown(&vnc); - /* Normal mode call */ - TestVbInit(0, 0, "normal mode, some backup"); - TEST_EQ(shared->flags, 0, " shared flags"); - TEST_EQ(iparams.out_flags, 0, " out flags"); - TEST_EQ(nv_write_called, 1, - " Write NV because things have changed"); - /* Some fields should be unchanged */ - VbNvGet(&vnc, VBNV_KERNEL_FIELD, &u); - TEST_EQ(u, 0xaabbccdd, " NV kernel field"); - VbNvGet(&vnc, VBNV_LOCALIZATION_INDEX, &u); - TEST_EQ(u, 0xa5, " NV localization index"); - VbNvGet(&vnc, VBNV_OPROM_NEEDED, &u); - TEST_EQ(u, 1, " NV oprom_needed"); - VbNvGet(&vnc, VBNV_TRY_B_COUNT, &u); - TEST_EQ(u, 3, " NV try_b_count"); - /* But normal mode should have cleared the DEV_BOOT flags */ - VbNvGet(&vnc, VBNV_DEV_BOOT_USB, &u); - TEST_EQ(u, 0, " NV dev_boot_usb"); - VbNvGet(&vnc, VBNV_DEV_BOOT_LEGACY, &u); - TEST_EQ(u, 0, " NV dev_boot_legacy"); - VbNvGet(&vnc, VBNV_DEV_BOOT_SIGNED_ONLY, &u); - TEST_EQ(u, 0, " NV dev_boot_signed_only"); - VbNvGet(&vnc, VBNV_DEV_BOOT_FASTBOOT_FULL_CAP, &u); - TEST_EQ(u, 0, " NV dev_boot_fastboot_full_cap"); - VbNvGet(&vnc, VBNV_DEV_DEFAULT_BOOT, &u); - TEST_EQ(u, 0, " NV dev_default_boot"); - VbNvGet(&vnc, VBNV_FASTBOOT_UNLOCK_IN_FW, &u); - TEST_EQ(u, 0, " NV_fastboot_unlock_in_fw "); - /* So we should have written the backup */ - TEST_EQ(backup_write_called, 1, " Backup written once"); - /* And the backup should reflect the persisent flags. */ - Memset(&tmp_vnc, 0, sizeof(tmp_vnc)); - TEST_EQ(0, RestoreNvFromBackup(&tmp_vnc), "read from backup"); - VbNvGet(&tmp_vnc, VBNV_KERNEL_FIELD, &u); - TEST_EQ(u, 0xaabbccdd, " BU kernel field"); - VbNvGet(&tmp_vnc, VBNV_LOCALIZATION_INDEX, &u); - TEST_EQ(u, 0xa5, " BU localization index"); - VbNvGet(&tmp_vnc, VBNV_DEV_BOOT_USB, &u); - TEST_EQ(u, 0, " BU dev_boot_usb"); - VbNvGet(&tmp_vnc, VBNV_DEV_BOOT_LEGACY, &u); - TEST_EQ(u, 0, " BU dev_boot_legacy"); - VbNvGet(&tmp_vnc, VBNV_DEV_BOOT_SIGNED_ONLY, &u); - TEST_EQ(u, 0, " BU dev_boot_signed_only"); - VbNvGet(&tmp_vnc, VBNV_DEV_BOOT_FASTBOOT_FULL_CAP, &u); - TEST_EQ(u, 0, " BU dev_boot_fastboot_full_cap"); - VbNvGet(&tmp_vnc, VBNV_DEV_DEFAULT_BOOT, &u); - TEST_EQ(u, 0, " BU dev_default_boot"); - VbNvGet(&tmp_vnc, VBNV_FASTBOOT_UNLOCK_IN_FW, &u); - TEST_EQ(u, 0, " BU fastboot_unlock_in_fw"); - /* but not the others */ - VbNvGet(&tmp_vnc, VBNV_OPROM_NEEDED, &u); - TEST_EQ(u, 0, " BU oprom_needed"); - VbNvGet(&tmp_vnc, VBNV_TRY_B_COUNT, &u); - TEST_EQ(u, 0, " BU try_b_count"); - - /* - * If we change one of the non-backed-up NVRAM params and try - * again, we shouldn't need to backup again. - */ - VbNvSet(&vnc, VBNV_OPROM_NEEDED, 0); - VbNvSet(&vnc, VBNV_TRY_B_COUNT, 2); - /* Make sure they're clean */ - VbNvTeardown(&vnc); - /* Normal mode call */ - TestVbInit(0, 0, "normal mode, expect no backup"); - TEST_EQ(shared->flags, 0, " shared flags"); - TEST_EQ(iparams.out_flags, 0, " out flags"); - TEST_EQ(backup_write_called, 1, " Backup still only written once"); - - /* Now switch to dev-mode. */ - iparams.flags = VB_INIT_FLAG_DEV_SWITCH_ON; - TestVbInit(0, 0, "Dev mode on"); - TEST_EQ(shared->recovery_reason, 0, " recovery reason"); - TEST_EQ(iparams.out_flags, - VB_INIT_OUT_CLEAR_RAM | - VB_INIT_OUT_ENABLE_DISPLAY | - VB_INIT_OUT_ENABLE_USB_STORAGE | - VB_INIT_OUT_ENABLE_DEVELOPER | - VB_INIT_OUT_ENABLE_ALTERNATE_OS, " out flags"); - TEST_EQ(shared->flags, VBSD_BOOT_DEV_SWITCH_ON, " shared flags"); - TEST_EQ(backup_write_called, 1, " Still only one backup"); - - /* Now change some params that should be backed up. */ - VbNvSet(&vnc, VBNV_KERNEL_FIELD, 0xdeadbeef); - VbNvSet(&vnc, VBNV_LOCALIZATION_INDEX, 0x5a); - VbNvSet(&vnc, VBNV_DEV_BOOT_USB, 1); - VbNvSet(&vnc, VBNV_DEV_BOOT_LEGACY, 1); - VbNvSet(&vnc, VBNV_DEV_BOOT_SIGNED_ONLY, 1); - VbNvSet(&vnc, VBNV_DEV_BOOT_FASTBOOT_FULL_CAP, 1); - VbNvSet(&vnc, VBNV_DEV_DEFAULT_BOOT, 1); - VbNvSet(&vnc, VBNV_FASTBOOT_UNLOCK_IN_FW, 1); - /* and some that don't */ - VbNvSet(&vnc, VBNV_OPROM_NEEDED, 1); - VbNvSet(&vnc, VBNV_TRY_B_COUNT, 4); - /* Make sure they're clean */ - VbNvTeardown(&vnc); - TestVbInit(0, 0, "Dev mode on"); - TEST_EQ(shared->recovery_reason, 0, " recovery reason"); - TEST_EQ(iparams.out_flags, - VB_INIT_OUT_CLEAR_RAM | - VB_INIT_OUT_ENABLE_DISPLAY | - VB_INIT_OUT_ENABLE_USB_STORAGE | - VB_INIT_OUT_ENABLE_DEVELOPER, " out flags"); - TEST_EQ(shared->flags, VBSD_BOOT_DEV_SWITCH_ON, " shared flags"); - TEST_EQ(backup_write_called, 1, " Once more, one backup"); - - /* But if we explicitly request a backup, they'll get saved. */ - VbNvSet(&vnc, VBNV_BACKUP_NVRAM_REQUEST, 1); - VbNvTeardown(&vnc); - TestVbInit(0, 0, "Dev mode on"); - TEST_EQ(shared->recovery_reason, 0, " recovery reason"); - TEST_EQ(iparams.out_flags, - VB_INIT_OUT_CLEAR_RAM | - VB_INIT_OUT_ENABLE_DISPLAY | - VB_INIT_OUT_ENABLE_USB_STORAGE | - VB_INIT_OUT_ENABLE_DEVELOPER, " out flags"); - TEST_EQ(shared->flags, VBSD_BOOT_DEV_SWITCH_ON, " shared flags"); - TEST_EQ(backup_write_called, 2, " Two backups now"); - VbNvGet(&vnc, VBNV_BACKUP_NVRAM_REQUEST, &u); - TEST_EQ(u, 0, " backup_request cleared"); - /* Quick check that the non-backed-up stuff is still valid */ - VbNvGet(&vnc, VBNV_OPROM_NEEDED, &u); - TEST_EQ(u, 1, " NV oprom_needed"); - VbNvGet(&vnc, VBNV_TRY_B_COUNT, &u); - TEST_EQ(u, 4, " NV try_b_count"); - /* But only the stuff we care about was backed up */ - Memset(&tmp_vnc, 0, sizeof(tmp_vnc)); - TEST_EQ(0, RestoreNvFromBackup(&tmp_vnc), "read from backup"); - VbNvGet(&tmp_vnc, VBNV_KERNEL_FIELD, &u); - TEST_EQ(u, 0xdeadbeef, " BU kernel field"); - VbNvGet(&tmp_vnc, VBNV_LOCALIZATION_INDEX, &u); - TEST_EQ(u, 0x5a, " BU localization index"); - VbNvGet(&tmp_vnc, VBNV_DEV_BOOT_USB, &u); - TEST_EQ(u, 1, " BU dev_boot_usb"); - VbNvGet(&tmp_vnc, VBNV_DEV_BOOT_LEGACY, &u); - TEST_EQ(u, 1, " BU dev_boot_legacy"); - VbNvGet(&tmp_vnc, VBNV_DEV_BOOT_SIGNED_ONLY, &u); - TEST_EQ(u, 1, " BU dev_boot_signed_only"); - VbNvGet(&tmp_vnc, VBNV_DEV_BOOT_FASTBOOT_FULL_CAP, &u); - TEST_EQ(u, 1, " BU dev_boot_fastboot_full_cap"); - VbNvGet(&tmp_vnc, VBNV_DEV_DEFAULT_BOOT, &u); - TEST_EQ(u, 1, " BU dev_default_boot"); - VbNvGet(&tmp_vnc, VBNV_FASTBOOT_UNLOCK_IN_FW, &u); - TEST_EQ(u, 1, " BU fastboot_unlock_in_fw"); - /* but not the others */ - VbNvGet(&tmp_vnc, VBNV_OPROM_NEEDED, &u); - TEST_EQ(u, 0, " BU oprom_needed"); - VbNvGet(&tmp_vnc, VBNV_TRY_B_COUNT, &u); - TEST_EQ(u, 0, " BU try_b_count"); - - /* If we lose the NV storage, the backup bits will be restored */ - vnc.raw[0] = 0; - bu_r = backup_read_called; - nv_w = nv_write_called; - TestVbInit(0, 0, "Dev mode on"); - TEST_EQ(shared->recovery_reason, 0, " recovery reason"); - TEST_EQ(iparams.out_flags, - VB_INIT_OUT_CLEAR_RAM | - VB_INIT_OUT_ENABLE_DISPLAY | - VB_INIT_OUT_ENABLE_USB_STORAGE | - VB_INIT_OUT_ENABLE_DEVELOPER, " out flags"); - TEST_EQ(shared->flags, VBSD_BOOT_DEV_SWITCH_ON, " shared flags"); - TEST_EQ(backup_write_called, 2, " Still just two backups now"); - TEST_EQ(backup_read_called, bu_r + 1, " One more backup read"); - TEST_EQ(nv_write_called, nv_w + 1, " One more NV write"); - /* The non-backed-up stuff is reset to defaults */ - VbNvGet(&vnc, VBNV_OPROM_NEEDED, &u); - TEST_EQ(u, 0, " NV oprom_needed"); - VbNvGet(&vnc, VBNV_TRY_B_COUNT, &u); - TEST_EQ(u, 0, " NV try_b_count"); - /* And the backed up stuff is restored */ - VbNvGet(&vnc, VBNV_KERNEL_FIELD, &u); - TEST_EQ(u, 0xdeadbeef, " BU kernel field"); - VbNvGet(&vnc, VBNV_LOCALIZATION_INDEX, &u); - TEST_EQ(u, 0x5a, " BU localization index"); - VbNvGet(&vnc, VBNV_DEV_BOOT_USB, &u); - TEST_EQ(u, 1, " BU dev_boot_usb"); - VbNvGet(&vnc, VBNV_DEV_BOOT_LEGACY, &u); - TEST_EQ(u, 1, " BU dev_boot_legacy"); - VbNvGet(&vnc, VBNV_DEV_BOOT_SIGNED_ONLY, &u); - TEST_EQ(u, 1, " BU dev_boot_signed_only"); - VbNvGet(&vnc, VBNV_DEV_BOOT_FASTBOOT_FULL_CAP, &u); - TEST_EQ(u, 1, " BU dev_boot_fastboot_full_cap"); - VbNvGet(&tmp_vnc, VBNV_DEV_DEFAULT_BOOT, &u); - TEST_EQ(u, 1, " BU dev_default_boot"); - VbNvGet(&vnc, VBNV_FASTBOOT_UNLOCK_IN_FW, &u); - TEST_EQ(u, 1, " BU fastboot_unlock_in_fw"); - - /* - * But if we lose the NV storage and go back to normal mode at the same - * time, then the DEV_BOOT_* flags will be cleared. - */ - vnc.raw[0] = 0; - bu_r = backup_read_called; - nv_w = nv_write_called; - iparams.flags = 0; - TestVbInit(0, 0, "Back to normal mode"); - TEST_EQ(shared->recovery_reason, 0, " recovery reason"); - TEST_EQ(iparams.out_flags, 0, " out flags"); - TEST_EQ(shared->flags, 0, " shared flags"); - /* We read twice: once to restore, once for read-prior-to-write */ - TEST_EQ(backup_read_called, bu_r + 2, " Two more backup reads"); - TEST_EQ(backup_write_called, 3, " Backup write due clearing DEV_*"); - TEST_EQ(nv_write_called, nv_w + 1, " One more NV write"); - /* The non-backed-up stuff is reset to defaults */ - VbNvGet(&vnc, VBNV_OPROM_NEEDED, &u); - TEST_EQ(u, 0, " NV oprom_needed"); - VbNvGet(&vnc, VBNV_TRY_B_COUNT, &u); - TEST_EQ(u, 0, " NV try_b_count"); - /* And the backed up stuff is restored */ - VbNvGet(&vnc, VBNV_KERNEL_FIELD, &u); - TEST_EQ(u, 0xdeadbeef, " BU kernel field"); - VbNvGet(&vnc, VBNV_LOCALIZATION_INDEX, &u); - TEST_EQ(u, 0x5a, " BU localization index"); - /* But not the DEV_BOOT_* flags */ - VbNvGet(&vnc, VBNV_DEV_BOOT_USB, &u); - TEST_EQ(u, 0, " BU dev_boot_usb"); - VbNvGet(&vnc, VBNV_DEV_BOOT_LEGACY, &u); - TEST_EQ(u, 0, " BU dev_boot_legacy"); - VbNvGet(&vnc, VBNV_DEV_BOOT_SIGNED_ONLY, &u); - TEST_EQ(u, 0, " BU dev_boot_signed_only"); - VbNvGet(&vnc, VBNV_DEV_BOOT_FASTBOOT_FULL_CAP, &u); - TEST_EQ(u, 0, " BU dev_boot_fastboot_full_cap"); - VbNvGet(&vnc, VBNV_DEV_DEFAULT_BOOT, &u); - TEST_EQ(u, 0, " BU dev_default_boot"); - VbNvGet(&vnc, VBNV_FASTBOOT_UNLOCK_IN_FW, &u); - TEST_EQ(u, 0, " BU fastboot_unlock_in_fw"); -} - - -int main(int argc, char *argv[]) -{ - VbInitTest(); - VbInitTestTPM(); - VbInitTestBackup(); - - return gTestSuccess ? 0 : 255; -} diff --git a/tests/vboot_firmware_tests.c b/tests/vboot_firmware_tests.c deleted file mode 100644 index 97782951..00000000 --- a/tests/vboot_firmware_tests.c +++ /dev/null @@ -1,503 +0,0 @@ -/* Copyright (c) 2012 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. - * - * Tests for vboot_firmware library. - */ - -#include <stdint.h> -#include <stdio.h> -#include <stdlib.h> -#include <string.h> - -#include "2sysincludes.h" - -#include "2common.h" -#include "2sha.h" -#include "gbb_header.h" -#include "host_common.h" -#include "load_firmware_fw.h" -#include "test_common.h" -#include "vboot_common.h" -#include "vboot_nvstorage.h" -#include "vboot_struct.h" - -/* Mock data */ -static VbCommonParams cparams; -static VbSelectFirmwareParams fparams; -static VbKeyBlockHeader vblock[2]; -static VbFirmwarePreambleHeader mpreamble[2]; -static VbNvContext vnc; -static uint8_t shared_data[VB_SHARED_DATA_MIN_SIZE]; -static VbSharedDataHeader* shared = (VbSharedDataHeader*)shared_data; -static uint8_t gbb_data[sizeof(GoogleBinaryBlockHeader) + 2048]; -static GoogleBinaryBlockHeader* gbb = (GoogleBinaryBlockHeader*)gbb_data; -static RSAPublicKey data_key; -static uint32_t digest_size; -static uint8_t* digest_expect_ptr; -static int hash_fw_index; - -#define TEST_KEY_DATA \ - "Test contents for the root key this should be 64 chars long." - -/* Reset mock data (for use before each test) */ -static void ResetMocks(void) { - VbPublicKey *root_key; - uint8_t *root_key_data; - int i; - - Memset(&cparams, 0, sizeof(cparams)); - cparams.shared_data_blob = shared_data; - cparams.gbb_data = gbb_data; - cparams.gbb_size = sizeof(gbb_data); - cparams.gbb = gbb; - - Memset(&fparams, 0, sizeof(fparams)); - fparams.verification_block_A = vblock; - fparams.verification_size_A = sizeof(VbKeyBlockHeader); - fparams.verification_block_B = vblock + 1; - fparams.verification_size_B = sizeof(VbKeyBlockHeader); - - Memset(vblock, 0, sizeof(vblock)); - Memset(mpreamble, 0, sizeof(mpreamble)); - for (i = 0; i < 2; i++) { - /* Default verification blocks to working in all modes */ - vblock[i].key_block_flags = 0x0F; - vblock[i].data_key.key_version = 2; - /* Fix up offsets to preambles */ - vblock[i].key_block_size = - (uint8_t*)(mpreamble + i) - (uint8_t*)(vblock + i); - - mpreamble[i].header_version_minor = 1; /* Supports preamble flags */ - mpreamble[i].firmware_version = 4; - /* Point kernel subkey to some data following the key header */ - PublicKeyInit(&mpreamble[i].kernel_subkey, - (uint8_t*)&mpreamble[i].body_signature, 20); - mpreamble[i].kernel_subkey.algorithm = 7 + i; - mpreamble[i].body_signature.data_size = 20000 + 1000 * i; - } - - Memset(&vnc, 0, sizeof(vnc)); - VbNvSetup(&vnc); - - Memset(&shared_data, 0, sizeof(shared_data)); - VbSharedDataInit(shared, sizeof(shared_data)); - shared->fw_version_tpm = 0x00020004; - - Memset(&gbb_data, 0, sizeof(gbb_data)); - gbb->rootkey_offset = sizeof(GoogleBinaryBlockHeader); - root_key = (VbPublicKey *)(gbb_data + gbb->rootkey_offset); - root_key_data = (uint8_t *)(root_key + 1); - strcpy((char *)root_key_data, TEST_KEY_DATA); - PublicKeyInit(root_key, (uint8_t *)root_key_data, sizeof(TEST_KEY_DATA)); - - gbb->major_version = GBB_MAJOR_VER; - gbb->minor_version = GBB_MINOR_VER; - gbb->flags = 0; - - Memset(&data_key, 0, sizeof(data_key)); - - digest_size = 1234; - digest_expect_ptr = NULL; - hash_fw_index = -1; -} - -/****************************************************************************/ -/* Mocked verification functions */ - -int KeyBlockVerify(const VbKeyBlockHeader* block, uint64_t size, - const VbPublicKey *key, int hash_only) { - - TEST_EQ(hash_only, 0, " Don't verify firmware with hash"); - - /* - * We cannot check the address of key, since it will be allocated. We - * check the contents instead. - */ - TEST_STR_EQ((char *)GetPublicKeyDataC(key), TEST_KEY_DATA, - " Verify with root key"); - TEST_NEQ(block==vblock || block==vblock+1, 0, " Verify a valid key block"); - - /* Mock uses header_version_major to hold return value */ - return block->header_version_major; -} - -int VerifyFirmwarePreamble(const VbFirmwarePreambleHeader* preamble, - uint64_t size, const RSAPublicKey* key) { - TEST_PTR_EQ(key, &data_key, " Verify preamble data key"); - TEST_NEQ(preamble==mpreamble || preamble==mpreamble+1, 0, - " Verify a valid preamble"); - - /* Mock uses header_version_major to hold return value */ - return preamble->header_version_major; -} - -RSAPublicKey* PublicKeyToRSA(const VbPublicKey* key) { - /* Mock uses algorithm!0 to mean invalid key */ - if (key->algorithm) - return NULL; - /* Mock uses data key len to hold number of alloc'd keys */ - data_key.len++; - return &data_key; -} - -void RSAPublicKeyFree(RSAPublicKey* key) { - TEST_PTR_EQ(key, &data_key, " RSA data key"); - data_key.len--; -} - -int vb2_digest_init(struct vb2_digest_context *dc, - enum vb2_hash_algorithm hash_alg) -{ - digest_size = 0; - return VB2_SUCCESS; -} - -int vb2_digest_extend(struct vb2_digest_context *dc, - const uint8_t *buf, - uint32_t size) -{ - TEST_PTR_EQ(buf, digest_expect_ptr, " Digesting expected data"); - digest_size += size; - return VB2_SUCCESS; -} - -int vb2_digest_finalize(struct vb2_digest_context *dc, - uint8_t *digest, - uint32_t digest_size) -{ - return VB2_SUCCESS; -} - -VbError_t VbExHashFirmwareBody(VbCommonParams* cparams, - uint32_t firmware_index) { - if (VB_SELECT_FIRMWARE_A == firmware_index) - hash_fw_index = 0; - else if (VB_SELECT_FIRMWARE_B == firmware_index) - hash_fw_index = 1; - else - return VBERROR_INVALID_PARAMETER; - - digest_expect_ptr = (uint8_t*)(vblock + hash_fw_index) + 5; - VbUpdateFirmwareBodyHash( - cparams, digest_expect_ptr, - mpreamble[hash_fw_index].body_signature.data_size - 1024); - VbUpdateFirmwareBodyHash(cparams, digest_expect_ptr, 1024); - - /* If signature offset is 42, hash the wrong amount and return success */ - if (42 == mpreamble[hash_fw_index].body_signature.sig_offset) { - VbUpdateFirmwareBodyHash(cparams, digest_expect_ptr, 4); - return VBERROR_SUCCESS; - } - - /* Otherwise, mocked function uses body signature offset as returned value */ - return mpreamble[hash_fw_index].body_signature.sig_offset; -} - -int VerifyDigest(const uint8_t* digest, const VbSignature *sig, - const RSAPublicKey* key) { - TEST_PTR_EQ(key, &data_key, "Verifying using data key"); - TEST_PTR_EQ(sig, &mpreamble[hash_fw_index].body_signature, "Verifying sig"); - /* Mocked function uses sig size as return value for verifying digest */ - return sig->sig_size; -} - -/****************************************************************************/ -/* Test LoadFirmware() and check expected return value and recovery reason */ -static void TestLoadFirmware(VbError_t expected_retval, - uint8_t expected_recovery, const char* desc) { - uint32_t rr = 256; - - TEST_EQ(LoadFirmware(&cparams, &fparams, &vnc), expected_retval, desc); - VbNvGet(&vnc, VBNV_RECOVERY_REQUEST, &rr); - TEST_EQ(rr, expected_recovery, " recovery request"); - TEST_EQ(data_key.len, 0, " Data key free must be paired with alloc"); -} - -/****************************************************************************/ - -static void LoadFirmwareTest(void) { - uint32_t u; - - /* Require GBB */ - ResetMocks(); - cparams.gbb_data = NULL; - TestLoadFirmware(VBERROR_INVALID_GBB, VBNV_RECOVERY_RO_UNSPECIFIED, - "No GBB"); - - /* Key block flags must match */ - /* Normal boot */ - ResetMocks(); - vblock[0].key_block_flags = KEY_BLOCK_FLAG_DEVELOPER_1; - vblock[1].key_block_flags = - KEY_BLOCK_FLAG_DEVELOPER_0 | KEY_BLOCK_FLAG_RECOVERY_1; - TestLoadFirmware(VBERROR_LOAD_FIRMWARE, - (VBNV_RECOVERY_RO_INVALID_RW_CHECK_MIN + - VBSD_LF_CHECK_REC_MISMATCH), - "Flags mismatch dev=0"); - TEST_EQ(shared->flags & VBSD_LF_DEV_SWITCH_ON, 0, - "Dev flag in shared.flags dev=0"); - TEST_EQ(shared->check_fw_a_result, VBSD_LF_CHECK_DEV_MISMATCH, - "Key block flag mismatch for dev=0"); - TEST_EQ(shared->check_fw_b_result, VBSD_LF_CHECK_REC_MISMATCH, - "Key block flag mismatch for rec=0"); - /* Developer boot */ - ResetMocks(); - shared->flags |= VBSD_BOOT_DEV_SWITCH_ON; - vblock[0].key_block_flags = KEY_BLOCK_FLAG_DEVELOPER_0; - vblock[1].key_block_flags = - KEY_BLOCK_FLAG_DEVELOPER_1 | KEY_BLOCK_FLAG_RECOVERY_1; - TestLoadFirmware(VBERROR_LOAD_FIRMWARE, - (VBNV_RECOVERY_RO_INVALID_RW_CHECK_MIN + - VBSD_LF_CHECK_REC_MISMATCH), - "Flags mismatch dev=1"); - TEST_NEQ(shared->flags & VBSD_LF_DEV_SWITCH_ON, 0, - "Dev flag in shared.flags dev=1"); - TEST_EQ(shared->check_fw_a_result, VBSD_LF_CHECK_DEV_MISMATCH, - "Key block flag mismatch for dev=1"); - TEST_EQ(shared->check_fw_b_result, VBSD_LF_CHECK_REC_MISMATCH, - "Key block flag mismatch for rec=1"); - - /* Test key block verification with A and key version rollback with B */ - ResetMocks(); - vblock[0].header_version_major = 1; /* Simulate failure */ - vblock[1].data_key.key_version = 1; /* Simulate rollback */ - TestLoadFirmware(VBERROR_LOAD_FIRMWARE, - (VBNV_RECOVERY_RO_INVALID_RW_CHECK_MIN + - VBSD_LF_CHECK_KEY_ROLLBACK), - "Key block invalid / key version rollback"); - TEST_EQ(shared->check_fw_a_result, VBSD_LF_CHECK_VERIFY_KEYBLOCK, - "Key block invalid"); - TEST_EQ(shared->check_fw_b_result, VBSD_LF_CHECK_KEY_ROLLBACK, - "Key version rollback "); - TEST_EQ(shared->fw_version_lowest, 0, "Lowest valid version"); - TEST_EQ(shared->fw_version_tpm, 0x20004, "TPM version"); - - /* Test invalid key version with A and bad data key with B */ - ResetMocks(); - vblock[0].data_key.key_version = 0x10003; /* Version > 0xFFFF is invalid */ - vblock[1].data_key.algorithm = 1; /* Simulate invalid data key */ - TestLoadFirmware(VBERROR_LOAD_FIRMWARE, - (VBNV_RECOVERY_RO_INVALID_RW_CHECK_MIN + - VBSD_LF_CHECK_DATA_KEY_PARSE), - "Key version overflow / invalid data key"); - TEST_EQ(shared->check_fw_a_result, VBSD_LF_CHECK_KEY_ROLLBACK, - "Key version overflow"); - TEST_EQ(shared->check_fw_b_result, VBSD_LF_CHECK_DATA_KEY_PARSE, - "Data key invalid"); - - /* Test invalid key version with GBB bypass-rollback flag */ - ResetMocks(); - vblock[0].data_key.key_version = 1; /* Simulate rollback */ - gbb->flags = GBB_FLAG_DISABLE_FW_ROLLBACK_CHECK; - TestLoadFirmware(VBERROR_SUCCESS, 0, "Key version check + GBB override"); - TEST_EQ(shared->check_fw_a_result, VBSD_LF_CHECK_VALID, - "Key version rollback + GBB override"); - - /* Test invalid preamble with A */ - ResetMocks(); - mpreamble[0].header_version_major = 1; /* Simulate failure */ - vblock[1].key_block_flags = 0; /* Invalid */ - TestLoadFirmware(VBERROR_LOAD_FIRMWARE, - (VBNV_RECOVERY_RO_INVALID_RW_CHECK_MIN + - VBSD_LF_CHECK_VERIFY_PREAMBLE), - "Preamble invalid"); - TEST_EQ(shared->check_fw_a_result, VBSD_LF_CHECK_VERIFY_PREAMBLE, - "Preamble invalid A"); - - /* Test invalid firmware versions */ - ResetMocks(); - mpreamble[0].firmware_version = 3; /* Simulate rollback */ - mpreamble[1].firmware_version = 0x10001; /* Check overflow */ - TestLoadFirmware(VBERROR_LOAD_FIRMWARE, - (VBNV_RECOVERY_RO_INVALID_RW_CHECK_MIN + - VBSD_LF_CHECK_FW_ROLLBACK), - "Firmware version check"); - TEST_EQ(shared->check_fw_a_result, VBSD_LF_CHECK_FW_ROLLBACK, - "Firmware version rollback"); - TEST_EQ(shared->check_fw_b_result, VBSD_LF_CHECK_FW_ROLLBACK, - "Firmware version overflow"); - - /* Test invalid firmware versions with GBB bypass-rollback flag */ - ResetMocks(); - mpreamble[0].firmware_version = 3; /* Simulate rollback */ - mpreamble[1].firmware_version = 0x10001; /* Check overflow */ - gbb->flags = GBB_FLAG_DISABLE_FW_ROLLBACK_CHECK; - TestLoadFirmware(VBERROR_SUCCESS, 0, "Firmware version check + GBB bypass"); - TEST_EQ(shared->check_fw_a_result, VBSD_LF_CHECK_VALID, - "Firmware version rollback + GBB override"); - TEST_EQ(shared->check_fw_b_result, VBSD_LF_CHECK_HEADER_VALID, - "Firmware version overflow + GBB override"); - - /* Test RO normal with A */ - ResetMocks(); - mpreamble[0].flags = VB_FIRMWARE_PREAMBLE_USE_RO_NORMAL; - vblock[1].key_block_flags = 0; /* Invalid */ - TestLoadFirmware(VBERROR_LOAD_FIRMWARE, - (VBNV_RECOVERY_RO_INVALID_RW_CHECK_MIN + - VBSD_LF_CHECK_NO_RO_NORMAL), - "Preamble asked for RO normal but fw doesn't support it"); - TEST_EQ(shared->check_fw_a_result, VBSD_LF_CHECK_NO_RO_NORMAL, - "No RO normal A"); - - /* If RO normal is supported, don't need to verify the firmware body */ - ResetMocks(); - mpreamble[0].flags = VB_FIRMWARE_PREAMBLE_USE_RO_NORMAL; - /* Mock bad sig, to ensure we didn't use it */ - mpreamble[0].body_signature.sig_size = 1; - shared->flags |= VBSD_BOOT_RO_NORMAL_SUPPORT; - vblock[1].key_block_flags = 0; /* Invalid */ - TestLoadFirmware(VBERROR_SUCCESS, 0, "RO normal A"); - TEST_EQ(shared->check_fw_a_result, VBSD_LF_CHECK_VALID, "RO normal A valid"); - TEST_EQ(shared->firmware_index, 0, "Boot A shared index"); - TEST_EQ(shared->fw_keyblock_flags, vblock[0].key_block_flags, - "Copy key block flags"); - TEST_EQ(shared->kernel_subkey.algorithm, 7, "Copy kernel subkey"); - - /* If both A and B are valid and same version as TPM, A is selected - * and B isn't attempted. */ - ResetMocks(); - mpreamble[0].flags = VB_FIRMWARE_PREAMBLE_USE_RO_NORMAL; - mpreamble[1].flags = VB_FIRMWARE_PREAMBLE_USE_RO_NORMAL; - shared->flags |= VBSD_BOOT_RO_NORMAL_SUPPORT; - TestLoadFirmware(VBERROR_SUCCESS, 0, "Check A then B"); - TEST_EQ(shared->check_fw_a_result, VBSD_LF_CHECK_VALID, "RO normal A valid"); - TEST_EQ(shared->check_fw_b_result, 0, "RO normal B not checked "); - TEST_EQ(shared->firmware_index, 0, "Boot A"); - TEST_EQ(shared->flags & VBSD_FWB_TRIED, 0, "Didn't try firmware B"); - TEST_EQ(shared->kernel_subkey.algorithm, 7, "Copy kernel subkey"); - /* But if try B flag is set, B is selected and A not attempted */ - ResetMocks(); - mpreamble[0].flags = VB_FIRMWARE_PREAMBLE_USE_RO_NORMAL; - mpreamble[1].flags = VB_FIRMWARE_PREAMBLE_USE_RO_NORMAL; - shared->flags |= VBSD_BOOT_RO_NORMAL_SUPPORT; - VbNvSet(&vnc, VBNV_TRY_B_COUNT, 5); - TestLoadFirmware(VBERROR_SUCCESS, 0, "Check B then A"); - TEST_EQ(shared->check_fw_a_result, 0, "RO normal A not checked "); - TEST_EQ(shared->check_fw_b_result, VBSD_LF_CHECK_VALID, "RO normal B valid"); - TEST_EQ(shared->firmware_index, 1, "Boot B"); - TEST_NEQ(shared->flags & VBSD_FWB_TRIED, 0, "Tried firmware B"); - TEST_EQ(shared->kernel_subkey.algorithm, 8, "Copy kernel subkey"); - VbNvGet(&vnc, VBNV_TRY_B_COUNT, &u); - TEST_EQ(u, 4, "Used up a try"); - - /* There's a optimistic boot mode that doesn't consume tries. - * The behaviour should differ only in that the try count doesn't change. */ - /* Optimistic boot case 1: count == 0: Go for A */ - ResetMocks(); - mpreamble[0].flags = VB_FIRMWARE_PREAMBLE_USE_RO_NORMAL; - mpreamble[1].flags = VB_FIRMWARE_PREAMBLE_USE_RO_NORMAL; - shared->flags |= VBSD_BOOT_RO_NORMAL_SUPPORT; - shared->flags |= VBSD_NOFAIL_BOOT; - VbNvSet(&vnc, VBNV_TRY_B_COUNT, 0); - TestLoadFirmware(VBERROR_SUCCESS, 0, "Give up on B"); - TEST_EQ(shared->check_fw_a_result, VBSD_LF_CHECK_VALID, "RO normal A valid"); - TEST_EQ(shared->check_fw_b_result, 0, "RO normal B not checked"); - TEST_EQ(shared->firmware_index, 0, "Boot A"); - TEST_EQ(shared->flags & VBSD_FWB_TRIED, 0, "Didn't try firmware B"); - TEST_EQ(shared->kernel_subkey.algorithm, 7, "Copy kernel subkey"); - VbNvGet(&vnc, VBNV_TRY_B_COUNT, &u); - TEST_EQ(u, 0, "try count still zero"); - /* Optimistic boot case 2: count > 0: count unchanged, use B */ - ResetMocks(); - mpreamble[0].flags = VB_FIRMWARE_PREAMBLE_USE_RO_NORMAL; - mpreamble[1].flags = VB_FIRMWARE_PREAMBLE_USE_RO_NORMAL; - shared->flags |= VBSD_BOOT_RO_NORMAL_SUPPORT; - shared->flags |= VBSD_NOFAIL_BOOT; - VbNvSet(&vnc, VBNV_TRY_B_COUNT, 5); - TestLoadFirmware(VBERROR_SUCCESS, 0, "Check B then A"); - TEST_EQ(shared->check_fw_a_result, 0, "RO normal A not checked "); - TEST_EQ(shared->check_fw_b_result, VBSD_LF_CHECK_VALID, "RO normal B valid"); - TEST_EQ(shared->firmware_index, 1, "Boot B"); - TEST_NEQ(shared->flags & VBSD_FWB_TRIED, 0, "Tried firmware B"); - TEST_EQ(shared->kernel_subkey.algorithm, 8, "Copy kernel subkey"); - VbNvGet(&vnc, VBNV_TRY_B_COUNT, &u); - TEST_EQ(u, 5, "Not used up a try"); - - /* If both A and B are valid and grater version than TPM, A is - * selected and B preamble (but not body) is verified. */ - ResetMocks(); - mpreamble[0].flags = VB_FIRMWARE_PREAMBLE_USE_RO_NORMAL; - mpreamble[1].flags = 0; - mpreamble[0].firmware_version = 5; - mpreamble[1].firmware_version = 6; - shared->flags |= VBSD_BOOT_RO_NORMAL_SUPPORT; - TestLoadFirmware(VBERROR_SUCCESS, 0, "Check A then B advancing version"); - TEST_EQ(shared->check_fw_a_result, VBSD_LF_CHECK_VALID, "RO normal A valid"); - TEST_EQ(shared->check_fw_b_result, VBSD_LF_CHECK_HEADER_VALID, - "RO normal B header valid"); - TEST_EQ(shared->firmware_index, 0, "Boot A"); - TEST_EQ(shared->fw_keyblock_flags, vblock[0].key_block_flags, "Key block A"); - TEST_EQ(shared->kernel_subkey.algorithm, 7, "Copy kernel subkey"); - TEST_EQ(shared->fw_version_lowest, 0x20005, "Lowest valid version"); - TEST_EQ(shared->fw_version_tpm, 0x20005, "TPM version advanced"); - - /* Verify firmware data */ - ResetMocks(); - vblock[1].key_block_flags = 0; /* Invalid */ - TestLoadFirmware(VBERROR_SUCCESS, 0, "Verify firmware body"); - TEST_EQ(shared->check_fw_a_result, VBSD_LF_CHECK_VALID, - "Firmware body A valid"); - TEST_EQ(shared->firmware_index, 0, "Boot A shared index"); - TEST_EQ(hash_fw_index, 0, "Hash firmware data A"); - TEST_EQ(digest_size, mpreamble[0].body_signature.data_size, - "Verified all data expected"); - - /* Test error getting firmware body */ - ResetMocks(); - mpreamble[0].body_signature.sig_offset = VBERROR_UNKNOWN; - vblock[1].key_block_flags = 0; /* Invalid */ - TestLoadFirmware(VBERROR_LOAD_FIRMWARE, - (VBNV_RECOVERY_RO_INVALID_RW_CHECK_MIN + - VBSD_LF_CHECK_GET_FW_BODY), - "Error getting firmware body"); - TEST_EQ(shared->check_fw_a_result, VBSD_LF_CHECK_GET_FW_BODY, - "Firmware body A"); - - /* Test digesting the wrong amount */ - ResetMocks(); - mpreamble[0].body_signature.sig_offset = 42; /* Mock hashing wrong amount */ - vblock[1].key_block_flags = 0; /* Invalid */ - TestLoadFirmware(VBERROR_LOAD_FIRMWARE, - (VBNV_RECOVERY_RO_INVALID_RW_CHECK_MIN + - VBSD_LF_CHECK_HASH_WRONG_SIZE), - "Hash wrong size"); - TEST_EQ(shared->check_fw_a_result, VBSD_LF_CHECK_HASH_WRONG_SIZE, - "Firmware hash wrong size A"); - - /* Test bad signature */ - ResetMocks(); - mpreamble[0].body_signature.sig_size = 1; /* Mock bad sig */ - vblock[1].key_block_flags = 0; /* Invalid */ - TestLoadFirmware(VBERROR_LOAD_FIRMWARE, - (VBNV_RECOVERY_RO_INVALID_RW_CHECK_MIN + - VBSD_LF_CHECK_VERIFY_BODY), - "Bad signature"); - TEST_EQ(shared->check_fw_a_result, VBSD_LF_CHECK_VERIFY_BODY, - "Bad signature A"); - - /* Test unable to store kernel data key */ - ResetMocks(); - mpreamble[0].kernel_subkey.key_size = VB_SHARED_DATA_MIN_SIZE + 1; - vblock[1].key_block_flags = 0; /* Invalid */ - TestLoadFirmware(VBERROR_LOAD_FIRMWARE, - (VBNV_RECOVERY_RO_INVALID_RW_CHECK_MIN + - VBSD_LF_CHECK_VALID), - "Kernel key too big"); - TEST_EQ(shared->check_fw_a_result, VBSD_LF_CHECK_VALID, - "Kernel key too big"); -} - - -int main(int argc, char* argv[]) { - int error_code = 0; - - LoadFirmwareTest(); - - if (vboot_api_stub_check_memory()) - error_code = 255; - if (!gTestSuccess) - error_code = 255; - - return error_code; -} diff --git a/tests/vboot_region_tests.c b/tests/vboot_region_tests.c index 80d01a20..6dd6b624 100644 --- a/tests/vboot_region_tests.c +++ b/tests/vboot_region_tests.c @@ -115,12 +115,6 @@ static void ResetMocks(void) { /****************************************************************************/ /* Mocked verification functions */ -uint32_t SetTPMBootModeState(int developer_mode, int recovery_mode, - uint64_t fw_keyblock_flags - GoogleBinaryBlockHeader *gbb) { - return VBERROR_SUCCESS; -} - VbError_t VbExNvStorageRead(uint8_t* buf) { Memcpy(buf, vnc.raw, sizeof(vnc.raw)); return VBERROR_SUCCESS; diff --git a/utility/load_kernel_test.c b/utility/load_kernel_test.c index d8efd786..a2800bfa 100644 --- a/utility/load_kernel_test.c +++ b/utility/load_kernel_test.c @@ -16,7 +16,6 @@ #include "gbb_header.h" #include "host_common.h" -#include "load_firmware_fw.h" #include "load_kernel_fw.h" #include "rollback_index.h" #include "vboot_common.h" |