summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJoel Kitching <kitching@google.com>2019-09-23 22:53:49 +0800
committerCommit Bot <commit-bot@chromium.org>2019-12-03 04:10:42 +0000
commit50b2d570b298ec4279f588cc22ef789867f03fb6 (patch)
tree4aa32c4b9b1ab87d3b71034bf66b23dc5719b074
parentd3095bf4def33da46320bd6b25b253850682dced (diff)
downloadvboot-50b2d570b298ec4279f588cc22ef789867f03fb6.tar.gz
vboot/secdata: rewrite rollback_index and centralize reads/writes
In current kernel verification code, secdata reads and writes are spread throughout the code. vboot2's design is to use vb2_context.secdata_* for storing the state of secdata spaces, and have the caller (depthcharge) read/save this field when necessary. Centralize secdata reads/writes into the functions of secdata_tpm.c, previously known as rollback_index.c. Functions which directly read/write to the TPM space are modified to use vb2_secdata_*_get and vb2_secdata_*_set. The secure spaces get read/flushed by functions in vboot_api_kernel.c. These calls and the underlying functions from secdata_tpm.c will eventually be relocated to depthcharge. Create a new external function vb2ex_commit_data, which commits any modified nvdata/secdata. Currently the depthcharge implementation of this function only writes nvdata, but once secdata TPM drivers have been migrated from vboot_reference to depthcharge, it will also commit these data spaces. This CL also removes the VbExNvStorageRead call from vb2_kernel_setup, and the data is instead read in depthcharge CL:1819379, right before calling VbSelectAndLoadKernel. As such, both the VbExNvStorageRead and VbExNvStorageWrite functions may be removed. Finally, create a vb2_secdata_kernel_lock function, which should be used right before attempting to leave vboot (by booting an OS or chainloading to another firmware). This should eventually be exposed as a vb2ex_ API function and relocated to depthcharge. BUG=b:124141368, chromium:972956, chromium:1006689 TEST=make clean && make runtests BRANCH=none Change-Id: Ifbfb21122af0bf85e22a6d3a0d48a1db7f7c25b7 Signed-off-by: Joel Kitching <kitching@google.com> Cq-Depend: chromium:1819380, chromium:1939168 Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/vboot_reference/+/1728298 Tested-by: Joel Kitching <kitching@chromium.org> Reviewed-by: Andrey Pronin <apronin@chromium.org> Reviewed-by: Julius Werner <jwerner@chromium.org> Commit-Queue: Joel Kitching <kitching@chromium.org> (cherry picked from commit adb418310d2e51e2f2a0f22607989fd3f66c4433) Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/vboot_reference/+/1947715 Reviewed-by: Shelley Chen <shchen@chromium.org> Commit-Queue: Shelley Chen <shchen@chromium.org> Tested-by: Shelley Chen <shchen@chromium.org>
-rw-r--r--Makefile20
-rw-r--r--firmware/2lib/2misc.c15
-rw-r--r--firmware/2lib/include/2api.h15
-rw-r--r--firmware/2lib/include/2misc.h14
-rw-r--r--firmware/2lib/include/2recovery_reasons.h3
-rw-r--r--firmware/2lib/include/2return_codes.h21
-rw-r--r--firmware/include/vboot_api.h15
-rw-r--r--firmware/include/vboot_test.h10
-rw-r--r--firmware/lib/include/load_kernel_fw.h4
-rw-r--r--firmware/lib/include/secdata_tpm.h168
-rw-r--r--firmware/lib/include/vboot_kernel.h28
-rw-r--r--firmware/lib/mocked_secdata_tpm.c26
-rw-r--r--firmware/lib/secdata_tpm.c263
-rw-r--r--firmware/lib/vboot_api_kernel.c205
-rw-r--r--firmware/lib/vboot_display.c4
-rw-r--r--firmware/lib/vboot_kernel.c19
-rw-r--r--firmware/lib/vboot_ui.c17
-rw-r--r--firmware/lib/vboot_ui_common.c5
-rw-r--r--firmware/lib/vboot_ui_menu.c17
-rw-r--r--firmware/stub/vboot_api_stub_init.c8
-rw-r--r--tests/secdata_tpm_tests.c584
-rw-r--r--tests/test_common.h2
-rw-r--r--tests/vboot_api_devmode_tests.c10
-rw-r--r--tests/vboot_api_kernel2_tests.c26
-rw-r--r--tests/vboot_api_kernel4_tests.c137
-rw-r--r--tests/vboot_detach_menu_tests.c25
-rw-r--r--tests/vboot_display_tests.c6
-rw-r--r--tests/vboot_kernel_tests.c21
28 files changed, 832 insertions, 856 deletions
diff --git a/Makefile b/Makefile
index b2e2fde5..0241e8f7 100644
--- a/Makefile
+++ b/Makefile
@@ -183,6 +183,11 @@ ifneq (${TPM2_MODE},)
CFLAGS += -DTPM2_MODE
endif
+# Some tests need to be disabled when using mocked_secdata_tpm.
+ifneq (${MOCK_TPM},)
+CFLAGS += -DMOCK_TPM
+endif
+
# enable all features during local compile (permits testing)
ifeq (${FIRMWARE_ARCH},)
DIAGNOSTIC_UI := 1
@@ -692,13 +697,16 @@ TEST_NAMES = \
tests/vboot_kernel_tests \
tests/verify_kernel
-ifeq (${TPM2_MODE}${MOCK_TPM},)
-# TODO(apronin): tests for TPM2 case?
+ifeq (${MOCK_TPM},)
# secdata_tpm_tests and tlcl_tests only work when MOCK_TPM is disabled
TEST_NAMES += \
- tests/secdata_tpm_tests \
+ tests/secdata_tpm_tests
+ifeq (${TPM2_MODE},)
+# TODO(apronin): tests for TPM2 case?
+TEST_NAMES += \
tests/tlcl_tests
endif
+endif
TEST_FUTIL_NAMES = \
tests/futility/binary_editor \
@@ -1258,12 +1266,14 @@ runtestscripts: test_setup genfuzztestcases
.PHONY: runmisctests
runmisctests: test_setup
-ifeq (${TPM2_MODE}${MOCK_TPM},)
-# TODO(apronin): tests for TPM2 case?
+ifeq (${MOCK_TPM},)
# secdata_tpm_tests and tlcl_tests only work when MOCK_TPM is disabled
${RUNTEST} ${BUILD_RUN}/tests/secdata_tpm_tests
+ifeq (${TPM2_MODE},)
+# TODO(apronin): tests for TPM2 case?
${RUNTEST} ${BUILD_RUN}/tests/tlcl_tests
endif
+endif
${RUNTEST} ${BUILD_RUN}/tests/utility_string_tests
${RUNTEST} ${BUILD_RUN}/tests/vboot_api_devmode_tests
${RUNTEST} ${BUILD_RUN}/tests/vboot_api_kernel2_tests
diff --git a/firmware/2lib/2misc.c b/firmware/2lib/2misc.c
index 92e930a8..86438b44 100644
--- a/firmware/2lib/2misc.c
+++ b/firmware/2lib/2misc.c
@@ -369,3 +369,18 @@ vb2_error_t vb2_select_fw_slot(struct vb2_context *ctx)
return VB2_SUCCESS;
}
+
+vb2_error_t vb2_enable_developer_mode(struct vb2_context *ctx)
+{
+ uint32_t flags;
+
+ VB2_DEBUG("Enabling developer mode...\n");
+
+ flags = vb2_secdata_firmware_get(ctx, VB2_SECDATA_FIRMWARE_FLAGS);
+ flags |= VB2_SECDATA_FIRMWARE_FLAG_DEV_MODE;
+ vb2_secdata_firmware_set(ctx, VB2_SECDATA_FIRMWARE_FLAGS, flags);
+
+ VB2_DEBUG("Mode change will take effect on next reboot\n");
+
+ return VB2_SUCCESS;
+}
diff --git a/firmware/2lib/include/2api.h b/firmware/2lib/include/2api.h
index 50ebc1bc..03df7e25 100644
--- a/firmware/2lib/include/2api.h
+++ b/firmware/2lib/include/2api.h
@@ -930,4 +930,19 @@ vb2_error_t vb2ex_auxfw_finalize(struct vb2_context *ctx);
*/
void vb2ex_abort(void);
+/**
+ * Commit any pending data to disk.
+ *
+ * Commit nvdata and secdata spaces if modified. Normally this should be
+ * performed after vboot has completed executing and control has been passed
+ * back to the caller. However, in certain kernel verification cases (e.g.
+ * right before attempting to boot an OS; from a UI screen which requires
+ * user-initiated shutdown; just prior to triggering battery cut-off), the
+ * caller may not get a chance to commit this data.
+ *
+ * @param ctx Vboot context
+ * @returns VB2_SUCCESS, or non-zero error code.
+ */
+vb2_error_t vb2ex_commit_data(struct vb2_context *ctx);
+
#endif /* VBOOT_REFERENCE_2API_H_ */
diff --git a/firmware/2lib/include/2misc.h b/firmware/2lib/include/2misc.h
index d9be9730..ac8311f2 100644
--- a/firmware/2lib/include/2misc.h
+++ b/firmware/2lib/include/2misc.h
@@ -163,4 +163,18 @@ vb2_error_t vb2_load_kernel_keyblock(struct vb2_context *ctx);
*/
vb2_error_t vb2_load_kernel_preamble(struct vb2_context *ctx);
+/**
+ * Utility function to enable developer mode.
+ *
+ * Enables the developer flag in vb2_context firmware secdata. Note that
+ * modified secdata must be saved for change to apply on reboot.
+ *
+ * NOTE: Doesn't update the LAST_BOOT_DEVELOPER secdata flag. That should be
+ * done on the next boot.
+ *
+ * @param ctx Vboot context
+ * @return VB2_SUCCESS, or error code on error.
+ */
+vb2_error_t vb2_enable_developer_mode(struct vb2_context *ctx);
+
#endif /* VBOOT_REFERENCE_2MISC_H_ */
diff --git a/firmware/2lib/include/2recovery_reasons.h b/firmware/2lib/include/2recovery_reasons.h
index d943563b..d76b142a 100644
--- a/firmware/2lib/include/2recovery_reasons.h
+++ b/firmware/2lib/include/2recovery_reasons.h
@@ -231,6 +231,9 @@ enum vb2_nv_recovery {
/* Alt FW Failed hash verification */
VB2_RECOVERY_ALTFW_HASH_FAILED = 0x61,
+ /* FWMP secure data initialization error */
+ VB2_RECOVERY_SECDATA_FWMP_INIT = 0x62,
+
/* Unspecified/unknown error in rewritable firmware */
VB2_RECOVERY_RW_UNSPECIFIED = 0x7f,
diff --git a/firmware/2lib/include/2return_codes.h b/firmware/2lib/include/2return_codes.h
index e6109485..0ab9e750 100644
--- a/firmware/2lib/include/2return_codes.h
+++ b/firmware/2lib/include/2return_codes.h
@@ -240,6 +240,27 @@ enum vb2_return_code {
/* Bad struct version in vb2_secdata_fwmp_check() */
VB2_ERROR_SECDATA_FWMP_VERSION,
+ /* Error reading secdata_firmware from storage backend */
+ VB2_ERROR_SECDATA_FIRMWARE_READ,
+
+ /* Error writing secdata_firmware to storage backend */
+ VB2_ERROR_SECDATA_FIRMWARE_WRITE,
+
+ /* Error locking secdata_firmware in storage backend */
+ VB2_ERROR_SECDATA_FIRMWARE_LOCK,
+
+ /* Error reading secdata_kernel from storage backend */
+ VB2_ERROR_SECDATA_KERNEL_READ,
+
+ /* Error writing secdata_kernel to storage backend */
+ VB2_ERROR_SECDATA_KERNEL_WRITE,
+
+ /* Error locking secdata_kernel in storage backend */
+ VB2_ERROR_SECDATA_KERNEL_LOCK,
+
+ /* Error reading secdata_fwmp from storage backend */
+ VB2_ERROR_SECDATA_FWMP_READ,
+
/**********************************************************************
* Common code errors
*/
diff --git a/firmware/include/vboot_api.h b/firmware/include/vboot_api.h
index 5481c379..455c3dcc 100644
--- a/firmware/include/vboot_api.h
+++ b/firmware/include/vboot_api.h
@@ -231,21 +231,6 @@ vb2_error_t VbExTpmGetRandom(uint8_t *buf, uint32_t length);
#endif /* CHROMEOS_ENVIRONMENT */
/*****************************************************************************/
-/* Non-volatile storage */
-
-#define VBNV_BLOCK_SIZE 16 /* Size of NV storage block in bytes */
-
-/**
- * Read the VBNV_BLOCK_SIZE-byte non-volatile storage into buf.
- */
-vb2_error_t VbExNvStorageRead(uint8_t *buf);
-
-/**
- * Write the VBNV_BLOCK_SIZE-byte non-volatile storage from buf.
- */
-vb2_error_t VbExNvStorageWrite(const uint8_t *buf);
-
-/*****************************************************************************/
/* Disk access (previously in boot_device.h) */
/* Flags for VbDisk APIs */
diff --git a/firmware/include/vboot_test.h b/firmware/include/vboot_test.h
index bdd1f378..a6ed8c09 100644
--- a/firmware/include/vboot_test.h
+++ b/firmware/include/vboot_test.h
@@ -26,10 +26,14 @@ vb2_error_t vb2_check_padding(const uint8_t *sig,
/****************************************************************************
* vboot_api_kernel.c */
-struct RollbackSpaceFwmp;
-struct RollbackSpaceFwmp *VbApiKernelGetFwmp(void);
-
struct LoadKernelParams;
struct LoadKernelParams *VbApiKernelGetParams(void);
+/****************************************************************************
+ * secdata_tpm.c */
+
+extern int secdata_kernel_locked;
+uint32_t tlcl_clear_and_reenable(void);
+uint32_t tlcl_safe_write(uint32_t index, const void *data, uint32_t length);
+
#endif /* VBOOT_REFERENCE_TEST_API_H_ */
diff --git a/firmware/lib/include/load_kernel_fw.h b/firmware/lib/include/load_kernel_fw.h
index b2841e17..9e4db8e6 100644
--- a/firmware/lib/include/load_kernel_fw.h
+++ b/firmware/lib/include/load_kernel_fw.h
@@ -19,8 +19,6 @@ struct vb2_context;
/* GPT is external */
#define BOOT_FLAG_EXTERNAL_GPT (0x04ULL)
-struct RollbackSpaceFwmp;
-
typedef struct LoadKernelParams {
/* Inputs to LoadKernel() */
/* Disk handle for current device */
@@ -37,8 +35,6 @@ typedef struct LoadKernelParams {
uint64_t kernel_buffer_size;
/* Boot flags */
uint64_t boot_flags;
- /* Firmware management parameters; may be NULL if not present. */
- const struct RollbackSpaceFwmp *fwmp;
/*
* Outputs from LoadKernel(); valid only if LoadKernel() returns
diff --git a/firmware/lib/include/secdata_tpm.h b/firmware/lib/include/secdata_tpm.h
index 6e31e71c..3cf1ae75 100644
--- a/firmware/lib/include/secdata_tpm.h
+++ b/firmware/lib/include/secdata_tpm.h
@@ -9,165 +9,25 @@
#ifndef VBOOT_REFERENCE_SECDATA_TPM_H_
#define VBOOT_REFERENCE_SECDATA_TPM_H_
-#include "2return_codes.h"
-#include "2sysincludes.h"
-#include "tss_constants.h"
+#include "2api.h"
/* TPM NVRAM location indices. */
-#define FIRMWARE_NV_INDEX 0x1007
-#define KERNEL_NV_INDEX 0x1008
-/* This is just an opaque space for backup purposes */
-#define BACKUP_NV_INDEX 0x1009
-#define BACKUP_NV_SIZE 16
-#define FWMP_NV_INDEX 0x100a
-#define FWMP_NV_MAX_SIZE 128
-#define REC_HASH_NV_INDEX 0x100b
-#define REC_HASH_NV_SIZE VB2_SHA256_DIGEST_SIZE
+#define FIRMWARE_NV_INDEX 0x1007
+#define KERNEL_NV_INDEX 0x1008
+/* BACKUP_NV_INDEX (size 16) used to live at 0x1009; now deprecated */
+#define FWMP_NV_INDEX 0x100a
+#define REC_HASH_NV_INDEX 0x100b
+#define REC_HASH_NV_SIZE VB2_SHA256_DIGEST_SIZE
/* Space to hold a temporary SHA256 digest of a public key for USB autoconfig;
* see crbug.com/845589. */
-#define OOBE_USB_AUTOCONFIG_KEY_DIGEST_NV_INDEX 0x100c
-#define OOBE_USB_AUTOCONFIG_KEY_DIGEST_NV_SIZE VB2_SHA256_DIGEST_SIZE
-
-/* Structure definitions for TPM spaces */
-
-/* Kernel space - KERNEL_NV_INDEX, locked with physical presence. */
-#define ROLLBACK_SPACE_KERNEL_VERSION 2
-#define ROLLBACK_SPACE_KERNEL_UID 0x4752574C /* 'GRWL' */
-
-typedef struct RollbackSpaceKernel {
- /* Struct version, for backwards compatibility */
- uint8_t struct_version;
- /* Unique ID to detect space redefinition */
- uint32_t uid;
- /* Kernel versions */
- uint32_t kernel_versions;
- /* Reserved for future expansion */
- uint8_t reserved[3];
- /* Checksum (v2 and later only) */
- uint8_t crc8;
-} __attribute__((packed)) RollbackSpaceKernel;
-
-/* Flags for firmware space */
-/*
- * Last boot was developer mode. TPM ownership is cleared when transitioning
- * to/from developer mode.
- */
-#define FLAG_LAST_BOOT_DEVELOPER 0x01
-/*
- * Some systems may not have a dedicated dev-mode switch, but enter and leave
- * dev-mode through some recovery-mode magic keypresses. For those systems, the
- * dev-mode "switch" state is in this bit (0=normal, 1=dev). To make it work, a
- * new flag is passed to VbInit(), indicating that the system lacks a physical
- * dev-mode switch. If a physical switch is present, this bit is ignored.
- */
-#define FLAG_VIRTUAL_DEV_MODE_ON 0x02
-
-/* Firmware space - FIRMWARE_NV_INDEX, locked with global lock. */
-#define ROLLBACK_SPACE_FIRMWARE_VERSION 2
-
-typedef struct RollbackSpaceFirmware {
- /* Struct version, for backwards compatibility */
- uint8_t struct_version;
- /* Flags (see FLAG_* above) */
- uint8_t flags;
- /* Firmware versions */
- uint32_t fw_versions;
- /* Reserved for future expansion */
- uint8_t reserved[3];
- /* Checksum (v2 and later only) */
- uint8_t crc8;
-} __attribute__((packed)) RollbackSpaceFirmware;
-
-#define FWMP_HASH_SIZE 32 /* Enough for SHA-256 */
-
-/* Firmware management parameters */
-struct RollbackSpaceFwmp {
- /* CRC-8 of fields following struct_size */
- uint8_t crc;
- /* Structure size in bytes */
- uint8_t struct_size;
- /* Structure version */
- uint8_t struct_version;
- /* Reserved; ignored by current reader */
- uint8_t reserved0;
- /* Flags; see enum fwmp_flags */
- uint32_t flags;
- /* Hash of developer kernel key */
- uint8_t dev_key_hash[FWMP_HASH_SIZE];
-} __attribute__((packed));
-
-#define ROLLBACK_SPACE_FWMP_VERSION 0x10 /* 1.0 */
-
-enum fwmp_flags {
- FWMP_DEV_DISABLE_BOOT = (1 << 0),
- FWMP_DEV_DISABLE_RECOVERY = (1 << 1),
- FWMP_DEV_ENABLE_USB = (1 << 2),
- FWMP_DEV_ENABLE_LEGACY = (1 << 3),
- FWMP_DEV_ENABLE_OFFICIAL_ONLY = (1 << 4),
- FWMP_DEV_USE_KEY_HASH = (1 << 5),
- /* CCD = case-closed debugging on cr50; flag implemented on cr50 */
- FWMP_DEV_DISABLE_CCD_UNLOCK = (1 << 6),
-};
+#define OOBE_USB_AUTOCONFIG_KEY_DIGEST_NV_INDEX 0x100c
+#define OOBE_USB_AUTOCONFIG_KEY_DIGEST_NV_SIZE VB2_SHA256_DIGEST_SIZE
/* All functions return TPM_SUCCESS (zero) if successful, non-zero if error */
-
-/*
- * These functions are callable from VbSelectAndLoadKernel(). They may use
- * global variables.
- */
-
-uint32_t ReadSpaceFirmware(RollbackSpaceFirmware *rsf);
-uint32_t WriteSpaceFirmware(RollbackSpaceFirmware *rsf);
-uint32_t ReadSpaceKernel(RollbackSpaceKernel *rsk);
-uint32_t WriteSpaceKernel(RollbackSpaceKernel *rsk);
-
-/**
- * Read stored kernel version.
- */
-uint32_t RollbackKernelRead(uint32_t *version);
-
-/**
- * Write stored kernel version.
- */
-uint32_t RollbackKernelWrite(uint32_t version);
-
-/**
- * Lock must be called. Internally, it's ignored in recovery mode.
- */
-uint32_t RollbackKernelLock(int recovery_mode);
-
-/**
- * Read and validate firmware management parameters.
- *
- * Absence of a FWMP is not an error; in this case, fwmp will be cleared.
- *
- * Returns non-zero if error.
- */
-uint32_t RollbackFwmpRead(struct RollbackSpaceFwmp *fwmp);
-
-/****************************************************************************/
-
-/*
- * The following functions are internal apis, listed here for use by unit tests
- * only.
- */
-
-/**
- * Issue a TPM_Clear and reenable/reactivate the TPM.
- */
-uint32_t TPMClearAndReenable(void);
-
-/**
- * Like TlclWrite(), but checks for write errors due to hitting the 64-write
- * limit and clears the TPM when that happens. This can only happen when the
- * TPM is unowned, so it is OK to clear it (and we really have no choice).
- * This is not expected to happen frequently, but it could happen.
- */
-uint32_t SafeWrite(uint32_t index, const void *data, uint32_t length);
-
-/**
- * Utility function to turn the virtual dev-mode flag on or off. 0=off, 1=on.
- */
-vb2_error_t SetVirtualDevMode(int val);
+uint32_t secdata_firmware_write(struct vb2_context *ctx);
+uint32_t secdata_kernel_read(struct vb2_context *ctx);
+uint32_t secdata_kernel_write(struct vb2_context *ctx);
+uint32_t secdata_kernel_lock(struct vb2_context *ctx);
+uint32_t secdata_fwmp_read(struct vb2_context *ctx);
#endif /* VBOOT_REFERENCE_SECDATA_TPM_H_ */
diff --git a/firmware/lib/include/vboot_kernel.h b/firmware/lib/include/vboot_kernel.h
index cf3c4bb3..28c6cc9a 100644
--- a/firmware/lib/include/vboot_kernel.h
+++ b/firmware/lib/include/vboot_kernel.h
@@ -80,22 +80,32 @@ vb2_error_t VbBootDeveloperMenu(struct vb2_context *ctx);
vb2_error_t VbBootRecoveryMenu(struct vb2_context *ctx);
/**
- * Return the current FWMP flags. Valid only inside VbSelectAndLoadKernel().
+ * Reinitialize global state. This should only need to be called by init tests.
*/
-uint32_t vb2_get_fwmp_flags(void);
+void vb2_init_ui(void);
/**
- * Commit NvStorage.
+ * Locks secdata_kernel.
*
- * This may be called by UI functions which need to save settings before they
- * sit in an infinite loop waiting for shutdown (this is, by a UI state which
- * will never return).
+ * Should be used right before attempting to leave vboot (by booting
+ * an OS or chainloading to another firmware).
+ *
+ * @param ctx Vboot context
+ * @returns VB2_SUCCESS, or non-zero error code.
*/
-void vb2_nv_commit(struct vb2_context *ctx);
+vb2_error_t vb2_secdata_kernel_lock(struct vb2_context *ctx);
/**
- * Reinitialize global state. This should only need to be called by init tests.
+ * Writes modified secdata spaces and nvdata.
+ *
+ * This is a temporary wrapper around vb2ex_commit_data, until secdata-writing
+ * functions are relocated into depthcharge.
+ *
+ * (See chromium:972956, chromium:1006689.)
+ *
+ * @param ctx Vboot context
+ * @returns VB2_SUCCESS, or non-zero error code.
*/
-void vb2_init_ui(void);
+vb2_error_t vb2_commit_data(struct vb2_context *ctx);
#endif /* VBOOT_REFERENCE_VBOOT_KERNEL_H_ */
diff --git a/firmware/lib/mocked_secdata_tpm.c b/firmware/lib/mocked_secdata_tpm.c
index dc9f16c6..373c4940 100644
--- a/firmware/lib/mocked_secdata_tpm.c
+++ b/firmware/lib/mocked_secdata_tpm.c
@@ -3,36 +3,42 @@
* found in the LICENSE file.
*
* Functions for querying, manipulating and locking secure data spaces
- * stored in the TPM NVRAM.
+ * stored in the TPM NVRAM (mock versions).
*/
+#include "2api.h"
+#include "2secdata.h"
#include "secdata_tpm.h"
#include "tss_constants.h"
-#include "utility.h"
-vb2_error_t SetVirtualDevMode(int val)
+int secdata_kernel_locked = 0;
+
+uint32_t secdata_firmware_write(struct vb2_context *ctx)
{
- return VB2_SUCCESS;
+ ctx->flags &= ~VB2_CONTEXT_SECDATA_FIRMWARE_CHANGED;
+ return TPM_SUCCESS;
}
-uint32_t RollbackKernelRead(uint32_t *version)
+uint32_t secdata_kernel_read(struct vb2_context *ctx)
{
- *version = 0;
+ vb2api_secdata_kernel_create(ctx);
return TPM_SUCCESS;
}
-uint32_t RollbackKernelWrite(uint32_t version)
+uint32_t secdata_kernel_write(struct vb2_context *ctx)
{
+ ctx->flags &= ~VB2_CONTEXT_SECDATA_KERNEL_CHANGED;
return TPM_SUCCESS;
}
-uint32_t RollbackKernelLock(int recovery_mode)
+uint32_t secdata_kernel_lock(struct vb2_context *ctx)
{
+ secdata_kernel_locked = 1;
return TPM_SUCCESS;
}
-uint32_t RollbackFwmpRead(struct RollbackSpaceFwmp *fwmp)
+uint32_t secdata_fwmp_read(struct vb2_context *ctx)
{
- memset(fwmp, 0, sizeof(*fwmp));
+ ctx->flags |= VB2_CONTEXT_NO_SECDATA_FWMP;
return TPM_SUCCESS;
}
diff --git a/firmware/lib/secdata_tpm.c b/firmware/lib/secdata_tpm.c
index 6b77ba55..b8f3522c 100644
--- a/firmware/lib/secdata_tpm.c
+++ b/firmware/lib/secdata_tpm.c
@@ -6,15 +6,12 @@
* stored in the TPM NVRAM.
*/
+#include "2api.h"
#include "2common.h"
-#include "2crc8.h"
-#include "2nvstorage.h"
-#include "2secdata.h"
-#include "2sysincludes.h"
#include "secdata_tpm.h"
#include "tlcl.h"
#include "tss_constants.h"
-#include "vboot_api.h"
+#include "vboot_test.h"
#define RETURN_ON_FAILURE(tpm_command) do { \
uint32_t result_; \
@@ -34,9 +31,15 @@
VB2_DEBUG_RAW("\n"); \
} while (0)
-uint32_t TPMClearAndReenable(void)
+/* Keeps track of whether the kernel space has already been locked or not. */
+int secdata_kernel_locked = 0;
+
+/**
+ * Issue a TPM_Clear and reenable/reactivate the TPM.
+ */
+uint32_t tlcl_clear_and_reenable(void)
{
- VB2_DEBUG("TPM: clear and re-enable\n");
+ VB2_DEBUG("TPM: clear_and_reenable\n");
RETURN_ON_FAILURE(TlclForceClear());
RETURN_ON_FAILURE(TlclSetEnable());
RETURN_ON_FAILURE(TlclSetDeactivated(0));
@@ -44,11 +47,17 @@ uint32_t TPMClearAndReenable(void)
return TPM_SUCCESS;
}
-uint32_t SafeWrite(uint32_t index, const void *data, uint32_t length)
+/**
+ * Like TlclWrite(), but checks for write errors due to hitting the 64-write
+ * limit and clears the TPM when that happens. This can only happen when the
+ * TPM is unowned, so it is OK to clear it (and we really have no choice).
+ * This is not expected to happen frequently, but it could happen.
+ */
+uint32_t tlcl_safe_write(uint32_t index, const void *data, uint32_t length)
{
uint32_t result = TlclWrite(index, data, length);
if (result == TPM_E_MAXNVWRITES) {
- RETURN_ON_FAILURE(TPMClearAndReenable());
+ RETURN_ON_FAILURE(tlcl_clear_and_reenable());
return TlclWrite(index, data, length);
} else {
return result;
@@ -56,73 +65,30 @@ uint32_t SafeWrite(uint32_t index, const void *data, uint32_t length)
}
/* Functions to read and write firmware and kernel spaces. */
-uint32_t ReadSpaceFirmware(RollbackSpaceFirmware *rsf)
-{
- uint32_t r;
- r = TlclRead(FIRMWARE_NV_INDEX, rsf, sizeof(RollbackSpaceFirmware));
- if (TPM_SUCCESS != r) {
- VB2_DEBUG("TPM: read secdata_firmware returned %#x\n", r);
- return r;
+uint32_t secdata_firmware_write(struct vb2_context *ctx)
+{
+ if (!(ctx->flags & VB2_CONTEXT_SECDATA_FIRMWARE_CHANGED)) {
+ VB2_DEBUG("TPM: secdata_firmware unchanged\n");
+ return TPM_SUCCESS;
}
- PRINT_BYTES("TPM: read secdata_firmware", rsf);
-
- if (rsf->struct_version < ROLLBACK_SPACE_FIRMWARE_VERSION)
- return TPM_E_STRUCT_VERSION;
- if (rsf->crc8 != vb2_crc8(rsf, offsetof(RollbackSpaceFirmware, crc8))) {
- VB2_DEBUG("TPM: bad secdata_firmware CRC\n");
- return TPM_E_CORRUPTED_STATE;
+ if (!(ctx->flags & VB2_CONTEXT_RECOVERY_MODE)) {
+ VB2_DEBUG("Error: secdata_firmware modified "
+ "in non-recovery mode?\n");
+ return TPM_E_AREA_LOCKED;
}
- return TPM_SUCCESS;
-}
-
-uint32_t WriteSpaceFirmware(RollbackSpaceFirmware *rsf)
-{
- uint32_t r;
-
- rsf->crc8 = vb2_crc8(rsf, offsetof(RollbackSpaceFirmware, crc8));
-
- PRINT_BYTES("TPM: write secdata", rsf);
- r = SafeWrite(FIRMWARE_NV_INDEX, rsf, sizeof(RollbackSpaceFirmware));
- if (TPM_SUCCESS != r) {
- VB2_DEBUG("TPM: write secdata_firmware failure\n");
- return r;
- }
+ PRINT_BYTES("TPM: write secdata_firmware", &ctx->secdata_firmware);
+ RETURN_ON_FAILURE(tlcl_safe_write(FIRMWARE_NV_INDEX,
+ ctx->secdata_firmware,
+ VB2_SECDATA_FIRMWARE_SIZE));
+ ctx->flags &= ~VB2_CONTEXT_SECDATA_FIRMWARE_CHANGED;
return TPM_SUCCESS;
}
-vb2_error_t SetVirtualDevMode(int val)
-{
- RollbackSpaceFirmware rsf;
-
- VB2_DEBUG("Enabling developer mode...\n");
-
- if (TPM_SUCCESS != ReadSpaceFirmware(&rsf))
- return VBERROR_TPM_FIRMWARE_SETUP;
-
- VB2_DEBUG("TPM: flags were 0x%02x\n", rsf.flags);
- if (val)
- rsf.flags |= FLAG_VIRTUAL_DEV_MODE_ON;
- else
- rsf.flags &= ~FLAG_VIRTUAL_DEV_MODE_ON;
- /*
- * NOTE: This doesn't update the FLAG_LAST_BOOT_DEVELOPER bit. That
- * will be done on the next boot.
- */
- VB2_DEBUG("TPM: flags are now 0x%02x\n", rsf.flags);
-
- if (TPM_SUCCESS != WriteSpaceFirmware(&rsf))
- return VBERROR_TPM_SET_BOOT_MODE_STATE;
-
- VB2_DEBUG("Mode change will take effect on next reboot\n");
-
- return VB2_SUCCESS;
-}
-
-uint32_t ReadSpaceKernel(RollbackSpaceKernel *rsk)
+uint32_t secdata_kernel_read(struct vb2_context *ctx)
{
#ifndef TPM2_MODE
/*
@@ -135,158 +101,89 @@ uint32_t ReadSpaceKernel(RollbackSpaceKernel *rsk)
uint32_t perms;
RETURN_ON_FAILURE(TlclGetPermissions(KERNEL_NV_INDEX, &perms));
-
- if (perms != TPM_NV_PER_PPWRITE)
+ if (perms != TPM_NV_PER_PPWRITE) {
+ VB2_DEBUG("TPM: invalid secdata_kernel permissions: %#x\n",
+ perms);
return TPM_E_CORRUPTED_STATE;
-#endif
-
- uint32_t r;
-
- r = TlclRead(KERNEL_NV_INDEX, rsk, sizeof(RollbackSpaceKernel));
- if (TPM_SUCCESS != r) {
- VB2_DEBUG("TPM: read secdata_kernel returned %#x\n", r);
- return r;
}
- PRINT_BYTES("TPM: read secdata_kernel", rsk);
+#endif
- if (rsk->struct_version < ROLLBACK_SPACE_FIRMWARE_VERSION)
- return TPM_E_STRUCT_VERSION;
+ RETURN_ON_FAILURE(TlclRead(KERNEL_NV_INDEX, ctx->secdata_kernel,
+ VB2_SECDATA_KERNEL_SIZE));
- if (rsk->uid != ROLLBACK_SPACE_KERNEL_UID)
- return TPM_E_CORRUPTED_STATE;
+ PRINT_BYTES("TPM: read secdata_kernel", &ctx->secdata_kernel);
- if (rsk->crc8 != vb2_crc8(rsk, offsetof(RollbackSpaceKernel, crc8))) {
- VB2_DEBUG("TPM: bad secdata_kernel CRC\n");
+ if (vb2api_secdata_kernel_check(ctx)) {
+ VB2_DEBUG("TPM: secdata_kernel invalid (corrupted?)\n");
return TPM_E_CORRUPTED_STATE;
}
return TPM_SUCCESS;
}
-uint32_t WriteSpaceKernel(RollbackSpaceKernel *rsk)
+uint32_t secdata_kernel_write(struct vb2_context *ctx)
{
- uint32_t r;
-
- rsk->crc8 = vb2_crc8(rsk, offsetof(RollbackSpaceKernel, crc8));
-
- PRINT_BYTES("TPM: write secdata_kernel", rsk);
- r = SafeWrite(KERNEL_NV_INDEX, rsk, sizeof(RollbackSpaceKernel));
- if (TPM_SUCCESS != r) {
- VB2_DEBUG("TPM: write secdata_kernel failure\n");
- return r;
+ if (!(ctx->flags & VB2_CONTEXT_SECDATA_KERNEL_CHANGED)) {
+ VB2_DEBUG("TPM: secdata_kernel unchanged\n");
+ return TPM_SUCCESS;
}
- return TPM_SUCCESS;
-}
+ PRINT_BYTES("TPM: write secdata_kernel", &ctx->secdata_kernel);
-uint32_t RollbackKernelRead(uint32_t* version)
-{
- RollbackSpaceKernel rsk;
- RETURN_ON_FAILURE(ReadSpaceKernel(&rsk));
- memcpy(version, &rsk.kernel_versions, sizeof(*version));
- VB2_DEBUG("TPM: RollbackKernelRead %#x\n", (int)*version);
- return TPM_SUCCESS;
-}
+ RETURN_ON_FAILURE(tlcl_safe_write(KERNEL_NV_INDEX, ctx->secdata_kernel,
+ VB2_SECDATA_KERNEL_SIZE));
-uint32_t RollbackKernelWrite(uint32_t version)
-{
- RollbackSpaceKernel rsk;
- uint32_t old_version;
- RETURN_ON_FAILURE(ReadSpaceKernel(&rsk));
- memcpy(&old_version, &rsk.kernel_versions, sizeof(old_version));
- VB2_DEBUG("TPM: RollbackKernelWrite %#x --> %#x\n",
- (int)old_version, (int)version);
- memcpy(&rsk.kernel_versions, &version, sizeof(version));
- return WriteSpaceKernel(&rsk);
+ ctx->flags &= ~VB2_CONTEXT_SECDATA_KERNEL_CHANGED;
+ return TPM_SUCCESS;
}
-uint32_t RollbackKernelLock(int recovery_mode)
+uint32_t secdata_kernel_lock(struct vb2_context *ctx)
{
- static int kernel_locked = 0;
- uint32_t r;
-
- if (recovery_mode || kernel_locked)
+ /* Skip if already locked */
+ if (secdata_kernel_locked) {
+ VB2_DEBUG("TPM: secdata_kernel already locked; skipping\n");
return TPM_SUCCESS;
+ }
- r = TlclLockPhysicalPresence();
- if (TPM_SUCCESS == r)
- kernel_locked = 1;
+ RETURN_ON_FAILURE(TlclLockPhysicalPresence());
- VB2_DEBUG("TPM: lock secdata_kernel returned %#x\n", r);
- return r;
+ VB2_DEBUG("TPM: secdata_kernel locked\n");
+ secdata_kernel_locked = 1;
+ return TPM_SUCCESS;
}
-uint32_t RollbackFwmpRead(struct RollbackSpaceFwmp *fwmp)
+uint32_t secdata_fwmp_read(struct vb2_context *ctx)
{
- union {
- /*
- * Use a union for buf and fwmp, rather than making fwmp a
- * pointer to a bare uint8_t[] buffer. This ensures fwmp will
- * be aligned if necesssary for the target platform.
- */
- uint8_t buf[FWMP_NV_MAX_SIZE];
- struct RollbackSpaceFwmp fwmp;
- } u;
+ vb2_error_t rv;
+ uint8_t size = VB2_SECDATA_FWMP_MIN_SIZE;
uint32_t r;
- /* Clear destination in case error or FWMP not present */
- memset(fwmp, 0, sizeof(*fwmp));
-
/* Try to read entire 1.0 struct */
- r = TlclRead(FWMP_NV_INDEX, u.buf, sizeof(u.fwmp));
+ r = TlclRead(FWMP_NV_INDEX, ctx->secdata_fwmp, size);
if (TPM_E_BADINDEX == r) {
- /* Missing space is not an error; use defaults */
- VB2_DEBUG("TPM: no FWMP space\n");
+ /* Missing space is not an error; tell vboot */
+ VB2_DEBUG("TPM: no secdata_fwmp space\n");
+ ctx->flags |= VB2_CONTEXT_NO_SECDATA_FWMP;
return TPM_SUCCESS;
} else if (TPM_SUCCESS != r) {
- VB2_DEBUG("TPM: read FWMP returned %#x\n", r);
+ VB2_DEBUG("TPM: read secdata_fwmp returned %#x\n", r);
return r;
}
- /*
- * Struct must be at least big enough for 1.0, but not bigger
- * than our buffer size.
- */
- if (u.fwmp.struct_size < sizeof(u.fwmp) ||
- u.fwmp.struct_size > sizeof(u.buf)) {
- VB2_DEBUG("TPM: FWMP size invalid: %#x\n", u.fwmp.struct_size);
- return TPM_E_STRUCT_SIZE;
- }
-
- /*
- * If space is bigger than we expect, re-read so we properly
- * compute the CRC.
- */
- if (u.fwmp.struct_size > sizeof(u.fwmp)) {
- r = TlclRead(FWMP_NV_INDEX, u.buf, u.fwmp.struct_size);
- if (TPM_SUCCESS != r) {
- VB2_DEBUG("TPM: re-read FWMP returned %#x\n", r);
- return r;
- }
- }
+ /* Re-read more data if necessary */
+ rv = vb2api_secdata_fwmp_check(ctx, &size);
+ if (rv == VB2_SUCCESS)
+ return VB2_SUCCESS;
- /* Verify CRC */
- if (u.fwmp.crc != vb2_crc8(u.buf + 2, u.fwmp.struct_size - 2)) {
- VB2_DEBUG("TPM: bad FWMP CRC\n");
- return TPM_E_CORRUPTED_STATE;
- }
+ if (rv == VB2_ERROR_SECDATA_FWMP_INCOMPLETE) {
+ RETURN_ON_FAILURE(TlclRead(FWMP_NV_INDEX, ctx->secdata_fwmp,
+ size));
- /* Verify major version is compatible */
- if ((u.fwmp.struct_version >> 4) !=
- (ROLLBACK_SPACE_FWMP_VERSION >> 4)) {
- VB2_DEBUG("TPM: FWMP major version incompatible\n");
- return TPM_E_STRUCT_VERSION;
+ /* Check one more time */
+ if (vb2api_secdata_fwmp_check(ctx, &size) == VB2_SUCCESS)
+ return VB2_SUCCESS;
}
- /*
- * Copy to destination. Note that if the space is bigger than
- * we expect (due to a minor version change), we only copy the
- * part of the FWMP that we know what to do with.
- *
- * If this were a 1.1+ reader and the source was a 1.0 struct,
- * we would need to take care of initializing the extra fields
- * added in 1.1+. But that's not an issue yet.
- */
- memcpy(fwmp, &u.fwmp, sizeof(*fwmp));
- return TPM_SUCCESS;
+ VB2_DEBUG("TPM: secdata_fwmp invalid (corrupted?)\n");
+ return TPM_E_CORRUPTED_STATE;
}
diff --git a/firmware/lib/vboot_api_kernel.c b/firmware/lib/vboot_api_kernel.c
index 5408c5a3..308a3275 100644
--- a/firmware/lib/vboot_api_kernel.c
+++ b/firmware/lib/vboot_api_kernel.c
@@ -22,36 +22,20 @@
#include "vboot_test.h"
/* Global variables */
-static struct RollbackSpaceFwmp fwmp;
static LoadKernelParams lkp;
#ifdef CHROMEOS_ENVIRONMENT
-/* Global variable accessors for unit tests */
-
-struct RollbackSpaceFwmp *VbApiKernelGetFwmp(void)
-{
- return &fwmp;
-}
-
+/* Global variable accessor for unit tests */
struct LoadKernelParams *VbApiKernelGetParams(void)
{
return &lkp;
}
-
#endif
-void vb2_nv_commit(struct vb2_context *ctx)
-{
- /* Exit if nothing has changed */
- if (!(ctx->flags & VB2_CONTEXT_NVDATA_CHANGED))
- return;
-
- ctx->flags &= ~VB2_CONTEXT_NVDATA_CHANGED;
- VbExNvStorageWrite(ctx->nvdata);
-}
-
static vb2_error_t handle_battery_cutoff(struct vb2_context *ctx)
{
+ vb2_error_t rv;
+
/*
* Check if we need to cut-off battery. This should be done after EC
* FW and Aux FW are updated, and before the kernel is started. This
@@ -61,8 +45,12 @@ static vb2_error_t handle_battery_cutoff(struct vb2_context *ctx)
if (vb2_nv_get(ctx, VB2_NV_BATTERY_CUTOFF_REQUEST)) {
VB2_DEBUG("Request to cut-off battery\n");
vb2_nv_set(ctx, VB2_NV_BATTERY_CUTOFF_REQUEST, 0);
+
/* May lose power immediately, so commit our update now. */
- vb2_nv_commit(ctx);
+ rv = vb2_commit_data(ctx);
+ if (rv)
+ return rv;
+
vb2ex_ec_battery_cutoff();
return VBERROR_SHUTDOWN_REQUESTED;
}
@@ -70,11 +58,6 @@ static vb2_error_t handle_battery_cutoff(struct vb2_context *ctx)
return VB2_SUCCESS;
}
-uint32_t vb2_get_fwmp_flags(void)
-{
- return fwmp.flags;
-}
-
vb2_error_t VbTryLoadKernel(struct vb2_context *ctx, uint32_t get_info_flags)
{
vb2_error_t rv = VBERROR_NO_DISK_FOUND;
@@ -82,7 +65,6 @@ vb2_error_t VbTryLoadKernel(struct vb2_context *ctx, uint32_t get_info_flags)
uint32_t disk_count = 0;
uint32_t i;
- lkp.fwmp = &fwmp;
lkp.disk_handle = NULL;
/* Find disks */
@@ -234,13 +216,8 @@ vb2_error_t VbBootNormal(struct vb2_context *ctx)
}
if (shared->kernel_version_tpm > shared->kernel_version_tpm_start) {
- uint32_t tpm_rv =
- RollbackKernelWrite(shared->kernel_version_tpm);
- if (tpm_rv) {
- VB2_DEBUG("Error writing kernel versions to TPM.\n");
- vb2api_fail(ctx, VB2_RECOVERY_RW_TPM_W_ERROR, tpm_rv);
- return VBERROR_TPM_WRITE_KERNEL;
- }
+ vb2_secdata_kernel_set(ctx, VB2_SECDATA_KERNEL_VERSIONS,
+ shared->kernel_version_tpm);
}
return rv;
@@ -251,6 +228,7 @@ static vb2_error_t vb2_kernel_setup(struct vb2_context *ctx,
VbSelectAndLoadKernelParams *kparams)
{
uint32_t tpm_rv;
+ vb2_error_t rv;
/* Translate vboot1 flags back to vboot2 */
if (shared->recovery_reason)
@@ -274,11 +252,9 @@ static vb2_error_t vb2_kernel_setup(struct vb2_context *ctx,
if (shared->flags & VBSD_NVDATA_V2)
ctx->flags |= VB2_CONTEXT_NVDATA_V2;
- VbExNvStorageRead(ctx->nvdata);
vb2_nv_init(ctx);
struct vb2_shared_data *sd = vb2_get_sd(ctx);
- struct vb2_gbb_header *gbb = vb2_get_gbb(ctx);
sd->recovery_reason = shared->recovery_reason;
/*
@@ -312,41 +288,53 @@ static vb2_error_t vb2_kernel_setup(struct vb2_context *ctx,
kparams->flags = 0;
memset(kparams->partition_guid, 0, sizeof(kparams->partition_guid));
- /* Read kernel version from the TPM. Ignore errors in recovery mode. */
- tpm_rv = RollbackKernelRead(&shared->kernel_version_tpm);
- if (tpm_rv) {
- VB2_DEBUG("Unable to get kernel versions from TPM\n");
- if (!(ctx->flags & VB2_CONTEXT_RECOVERY_MODE)) {
- vb2api_fail(ctx, VB2_RECOVERY_RW_TPM_R_ERROR, tpm_rv);
- return VBERROR_TPM_READ_KERNEL;
- }
+ /*
+ * Read secdata_kernel and secdata_fwmp spaces. No need to read
+ * secdata_firmware, since it was already read during firmware
+ * verification. Ignore errors in recovery mode.
+ */
+ tpm_rv = secdata_kernel_read(ctx);
+ if (tpm_rv && !(ctx->flags & VB2_CONTEXT_RECOVERY_MODE)) {
+ VB2_DEBUG("TPM: read secdata_kernel returned %#x\n", tpm_rv);
+ vb2api_fail(ctx, VB2_RECOVERY_RW_TPM_R_ERROR, tpm_rv);
+ return VB2_ERROR_SECDATA_KERNEL_READ;
}
-
- shared->kernel_version_tpm_start = shared->kernel_version_tpm;
-
- /* Read FWMP. Ignore errors in recovery mode. */
- if (gbb->flags & VB2_GBB_FLAG_DISABLE_FWMP) {
- memset(&fwmp, 0, sizeof(fwmp));
- return VB2_SUCCESS;
+ tpm_rv = secdata_fwmp_read(ctx);
+ if (tpm_rv && !(ctx->flags & VB2_CONTEXT_RECOVERY_MODE)) {
+ VB2_DEBUG("TPM: read secdata_fwmp returned %#x\n", tpm_rv);
+ vb2api_fail(ctx, VB2_RECOVERY_RW_TPM_R_ERROR, tpm_rv);
+ return VB2_ERROR_SECDATA_FWMP_READ;
}
- tpm_rv = RollbackFwmpRead(&fwmp);
- if (tpm_rv) {
- VB2_DEBUG("Unable to get FWMP from TPM\n");
- if (!(ctx->flags & VB2_CONTEXT_RECOVERY_MODE)) {
- vb2api_fail(ctx, VB2_RECOVERY_RW_TPM_R_ERROR, tpm_rv);
- return VBERROR_TPM_READ_FWMP;
- }
+ /*
+ * Init secdata_kernel and secdata_fwmp spaces. No need to init
+ * secdata_firmware, since it was already read during firmware
+ * verification. Ignore errors in recovery mode.
+ */
+ rv = vb2_secdata_kernel_init(ctx);
+ if (rv && !(ctx->flags & VB2_CONTEXT_RECOVERY_MODE)) {
+ VB2_DEBUG("TPM: init secdata_kernel returned %#x\n", rv);
+ vb2api_fail(ctx, VB2_RECOVERY_SECDATA_KERNEL_INIT, rv);
+ return rv;
}
+ rv = vb2_secdata_fwmp_init(ctx);
+ if (rv && !(ctx->flags & VB2_CONTEXT_RECOVERY_MODE)) {
+ VB2_DEBUG("TPM: init secdata_fwmp returned %#x\n", rv);
+ vb2api_fail(ctx, VB2_RECOVERY_SECDATA_FWMP_INIT, rv);
+ return rv;
+ }
+
+ /* Read kernel version from the TPM. */
+ shared->kernel_version_tpm =
+ vb2_secdata_kernel_get(ctx, VB2_SECDATA_KERNEL_VERSIONS);
+ shared->kernel_version_tpm_start = shared->kernel_version_tpm;
return VB2_SUCCESS;
}
-static vb2_error_t vb2_kernel_phase4(struct vb2_context *ctx,
- VbSelectAndLoadKernelParams *kparams)
+static void vb2_kernel_fill_kparams(struct vb2_context *ctx,
+ VbSelectAndLoadKernelParams *kparams)
{
- struct vb2_shared_data *sd = vb2_get_sd(ctx);
-
/* Save disk parameters */
kparams->disk_handle = lkp.disk_handle;
kparams->partition_number = lkp.partition_number;
@@ -357,30 +345,89 @@ static vb2_error_t vb2_kernel_phase4(struct vb2_context *ctx,
kparams->kernel_buffer_size = lkp.kernel_buffer_size;
memcpy(kparams->partition_guid, lkp.partition_guid,
sizeof(kparams->partition_guid));
+}
- /* Lock the kernel versions if not in recovery mode */
- if (!(ctx->flags & VB2_CONTEXT_RECOVERY_MODE)) {
- uint32_t tpm_rv = RollbackKernelLock(sd->recovery_reason);
- if (tpm_rv) {
- VB2_DEBUG("Error locking kernel versions.\n");
- vb2api_fail(ctx, VB2_RECOVERY_RW_TPM_L_ERROR, tpm_rv);
- return VBERROR_TPM_LOCK_KERNEL;
- }
+vb2_error_t vb2_secdata_kernel_lock(struct vb2_context *ctx)
+{
+ uint32_t tpm_rv;
+
+ /* Skip if in recovery mode. */
+ if (ctx->flags & VB2_CONTEXT_RECOVERY_MODE)
+ return VB2_SUCCESS;
+
+ tpm_rv = secdata_kernel_lock(ctx);
+ if (tpm_rv) {
+ VB2_DEBUG("TPM: lock secdata_kernel returned %#x\n", tpm_rv);
+ vb2api_fail(ctx, VB2_RECOVERY_RW_TPM_L_ERROR, tpm_rv);
+ return VB2_ERROR_SECDATA_KERNEL_LOCK;
}
return VB2_SUCCESS;
}
-static void vb2_kernel_cleanup(struct vb2_context *ctx)
+vb2_error_t vb2_commit_data(struct vb2_context *ctx)
{
- vb2_nv_commit(ctx);
+ vb2_error_t call_rv;
+ vb2_error_t rv = VB2_SUCCESS;
+ uint32_t tpm_rv;
+
+ /* Write secdata spaces. vboot never writes back to secdata_fwmp. */
+ tpm_rv = secdata_firmware_write(ctx);
+ if (tpm_rv && !(ctx->flags & VB2_CONTEXT_RECOVERY_MODE)) {
+ VB2_DEBUG("TPM: write secdata_firmware returned %#x\n", tpm_rv);
+ vb2api_fail(ctx, VB2_RECOVERY_RW_TPM_W_ERROR, tpm_rv);
+ rv = VB2_ERROR_SECDATA_FIRMWARE_WRITE;
+ }
+
+ tpm_rv = secdata_kernel_write(ctx);
+ if (tpm_rv && !(ctx->flags & VB2_CONTEXT_RECOVERY_MODE)) {
+ VB2_DEBUG("TPM: write secdata_kernel returned %#x\n", tpm_rv);
+ vb2api_fail(ctx, VB2_RECOVERY_RW_TPM_W_ERROR, tpm_rv);
+ if (rv == VB2_SUCCESS)
+ rv = VB2_ERROR_SECDATA_KERNEL_WRITE;
+ }
+
+ /* Always try to write nvdata, since it may have been changed by
+ setting a recovery reason above. */
+
+ /* TODO(chromium:972956, chromium:1006689): Currently only commits
+ nvdata, but should eventually also commit secdata. */
+ call_rv = vb2ex_commit_data(ctx);
+ switch (call_rv) {
+ case VB2_ERROR_NV_WRITE:
+ /* Don't bother with vb2api_fail since we can't write
+ nvdata anyways. */
+ if (ctx->flags & VB2_CONTEXT_RECOVERY_MODE) {
+ VB2_DEBUG("write nvdata failed\n");
+ if (rv == VB2_SUCCESS)
+ rv = call_rv;
+ } else {
+ /* Impossible to enter recovery mode */
+ VB2_DIE("write nvdata failed\n");
+ }
+ break;
+
+ case VB2_SUCCESS:
+ break;
+
+ default:
+ VB2_DEBUG("unknown commit error: %#x\n", call_rv);
+ if (!(ctx->flags & VB2_CONTEXT_RECOVERY_MODE) &&
+ rv == VB2_SUCCESS)
+ rv = call_rv;
+ break;
+ }
+
+ return rv;
}
vb2_error_t VbSelectAndLoadKernel(struct vb2_context *ctx,
VbSharedDataHeader *shared,
VbSelectAndLoadKernelParams *kparams)
{
- vb2_error_t rv = vb2_kernel_setup(ctx, shared, kparams);
+ vb2_error_t rv, call_rv;
+
+ rv = vb2_kernel_setup(ctx, shared, kparams);
if (rv)
goto VbSelectAndLoadKernel_exit;
@@ -441,10 +488,18 @@ vb2_error_t VbSelectAndLoadKernel(struct vb2_context *ctx,
VbSelectAndLoadKernel_exit:
- if (VB2_SUCCESS == rv)
- rv = vb2_kernel_phase4(ctx, kparams);
+ if (rv == VB2_SUCCESS)
+ vb2_kernel_fill_kparams(ctx, kparams);
+
+ /* Commit data, but retain any previous errors */
+ call_rv = vb2_commit_data(ctx);
+ if (rv == VB2_SUCCESS)
+ rv = call_rv;
- vb2_kernel_cleanup(ctx);
+ /* Lock secdata_kernel, but retain any previous errors */
+ call_rv = vb2_secdata_kernel_lock(ctx);
+ if (rv == VB2_SUCCESS)
+ rv = call_rv;
/* Pass through return value from boot path */
VB2_DEBUG("Returning %#x\n", rv);
diff --git a/firmware/lib/vboot_display.c b/firmware/lib/vboot_display.c
index d3daf658..0c62a86d 100644
--- a/firmware/lib/vboot_display.c
+++ b/firmware/lib/vboot_display.c
@@ -383,11 +383,11 @@ vb2_error_t VbCheckDisplayKey(struct vb2_context *ctx, uint32_t key,
/*
* Non-manual recovery mode is meant to be left via three-finger
* salute (into manual recovery mode). Need to commit nvdata
- * changes immediately.
+ * changes immediately. Ignore commit errors in recovery mode.
*/
if ((ctx->flags & VB2_CONTEXT_RECOVERY_MODE) &&
!vb2_allow_recovery(ctx))
- vb2_nv_commit(ctx);
+ vb2_commit_data(ctx);
/* Force redraw of current screen */
return VbDisplayScreen(ctx, disp_current_screen, 1, data);
diff --git a/firmware/lib/vboot_kernel.c b/firmware/lib/vboot_kernel.c
index 351044b3..1f1647cc 100644
--- a/firmware/lib/vboot_kernel.c
+++ b/firmware/lib/vboot_kernel.c
@@ -63,8 +63,8 @@ static int require_official_os(struct vb2_context *ctx,
return 1;
/* FWMP can require developer mode to use official OS */
- if (params->fwmp &&
- (params->fwmp->flags & FWMP_DEV_ENABLE_OFFICIAL_ONLY))
+ if (vb2_secdata_fwmp_get_flag(
+ ctx, VB2_SECDATA_FWMP_DEV_ENABLE_OFFICIAL_ONLY))
return 1;
/* Developer can request official OS via nvstorage */
@@ -210,7 +210,7 @@ static vb2_error_t vb2_verify_kernel_vblock(
/* If in developer mode and using key hash, check it */
if ((kBootDev == boot_mode) &&
- params->fwmp && (params->fwmp->flags & FWMP_DEV_USE_KEY_HASH)) {
+ vb2_secdata_fwmp_get_flag(ctx, VB2_SECDATA_FWMP_DEV_USE_KEY_HASH)) {
struct vb2_packed_key *key = &keyblock->data_key;
uint8_t *buf = ((uint8_t *)key) + key->key_offset;
uint32_t buflen = key->key_size;
@@ -219,15 +219,22 @@ static vb2_error_t vb2_verify_kernel_vblock(
VB2_DEBUG("Checking developer key hash.\n");
vb2_digest_buffer(buf, buflen, VB2_HASH_SHA256,
digest, sizeof(digest));
- if (0 != vb2_safe_memcmp(digest, params->fwmp->dev_key_hash,
+
+ uint8_t *fwmp_dev_key_hash =
+ vb2_secdata_fwmp_get_dev_key_hash(ctx);
+ if (fwmp_dev_key_hash == NULL) {
+ VB2_DEBUG("Couldn't retrieve developer key hash.\n");
+ return VB2_ERROR_VBLOCK_DEV_KEY_HASH;
+ }
+
+ if (0 != vb2_safe_memcmp(digest, fwmp_dev_key_hash,
VB2_SHA256_DIGEST_SIZE)) {
int i;
VB2_DEBUG("Wrong developer key hash.\n");
VB2_DEBUG("Want: ");
for (i = 0; i < VB2_SHA256_DIGEST_SIZE; i++)
- VB2_DEBUG("%02x",
- params->fwmp->dev_key_hash[i]);
+ VB2_DEBUG("%02x", fwmp_dev_key_hash[i]);
VB2_DEBUG("\nGot: ");
for (i = 0; i < VB2_SHA256_DIGEST_SIZE; i++)
VB2_DEBUG("%02x", digest[i]);
diff --git a/firmware/lib/vboot_ui.c b/firmware/lib/vboot_ui.c
index f7e82a99..306e22da 100644
--- a/firmware/lib/vboot_ui.c
+++ b/firmware/lib/vboot_ui.c
@@ -477,10 +477,10 @@ static vb2_error_t vb2_diagnostics_ui(struct vb2_context *ctx)
/*
* The following helps avoid use of the TPM after
* it's disabled (e.g., when vb2_run_altfw() calls
- * RollbackKernelLock() ).
+ * secdata_kernel_lock() ).
*/
- if (RollbackKernelLock(0)) {
+ if (secdata_kernel_lock(ctx)) {
VB2_DEBUG("Failed to lock TPM PP\n");
vb2api_fail(ctx, VB2_RECOVERY_TPM_DISABLE_FAILED, 0);
} else if (vb2ex_tpm_set_mode(VB2_TPM_MODE_DISABLED) !=
@@ -542,12 +542,11 @@ static vb2_error_t vb2_developer_ui(struct vb2_context *ctx)
}
/* Handle FWMP override */
- uint32_t fwmp_flags = vb2_get_fwmp_flags();
- if (fwmp_flags & FWMP_DEV_ENABLE_USB)
+ if (vb2_secdata_fwmp_get_flag(ctx, VB2_SECDATA_FWMP_DEV_ENABLE_USB))
allow_usb = 1;
- if (fwmp_flags & FWMP_DEV_ENABLE_LEGACY)
+ if (vb2_secdata_fwmp_get_flag(ctx, VB2_SECDATA_FWMP_DEV_ENABLE_LEGACY))
allow_legacy = 1;
- if (fwmp_flags & FWMP_DEV_DISABLE_BOOT) {
+ if (vb2_secdata_fwmp_get_flag(ctx, VB2_SECDATA_FWMP_DEV_DISABLE_BOOT)) {
if (gbb->flags & VB2_GBB_FLAG_FORCE_DEV_SWITCH_ON) {
VB2_DEBUG("FWMP_DEV_DISABLE_BOOT rejected by "
"FORCE_DEV_SWITCH_ON\n");
@@ -819,9 +818,9 @@ static vb2_error_t recovery_ui(struct vb2_context *ctx)
/*
* Non-manual recovery mode is meant to be left via three-finger
* salute (into manual recovery mode). Need to commit nvdata
- * changes immediately.
+ * changes immediately. Ignore commit errors in recovery mode.
*/
- vb2_nv_commit(ctx);
+ vb2_commit_data(ctx);
VbDisplayScreen(ctx, VB_SCREEN_OS_BROKEN, 0, NULL);
VB2_DEBUG("VbBootRecovery() waiting for manual recovery\n");
@@ -885,7 +884,7 @@ static vb2_error_t recovery_ui(struct vb2_context *ctx)
switch (VbUserConfirms(ctx, vbc_flags)) {
case 1:
VB2_DEBUG("Enabling dev-mode...\n");
- if (VB2_SUCCESS != SetVirtualDevMode(1))
+ if (VB2_SUCCESS != vb2_enable_developer_mode(ctx))
return VBERROR_TPM_SET_BOOT_MODE_STATE;
VB2_DEBUG("Reboot so it will take effect\n");
if (VbExGetSwitches
diff --git a/firmware/lib/vboot_ui_common.c b/firmware/lib/vboot_ui_common.c
index 1e956576..5f51f530 100644
--- a/firmware/lib/vboot_ui_common.c
+++ b/firmware/lib/vboot_ui_common.c
@@ -43,11 +43,12 @@ void vb2_error_notify(const char *print_msg,
void vb2_run_altfw(struct vb2_context *ctx, enum VbAltFwIndex_t altfw_num)
{
- if (RollbackKernelLock(0)) {
+ if (secdata_kernel_lock(ctx)) {
vb2_error_notify("Error locking kernel versions on legacy "
"boot.\n", NULL, VB_BEEP_FAILED);
} else {
- vb2_nv_commit(ctx);
+ /* TODO: Figure out what to do on commit error in altfw. */
+ vb2_commit_data(ctx);
VbExLegacy(altfw_num); /* will not return if found */
vb2_error_notify("Legacy boot failed. Missing BIOS?\n", NULL,
VB_BEEP_FAILED);
diff --git a/firmware/lib/vboot_ui_menu.c b/firmware/lib/vboot_ui_menu.c
index 89ac6323..bc3d882c 100644
--- a/firmware/lib/vboot_ui_menu.c
+++ b/firmware/lib/vboot_ui_menu.c
@@ -181,7 +181,7 @@ static vb2_error_t boot_usb_action(struct vb2_context *ctx)
if (!vb2_nv_get(ctx, VB2_NV_DEV_BOOT_USB) &&
!(vb2_get_gbb(ctx)->flags & VB2_GBB_FLAG_FORCE_DEV_BOOT_USB) &&
- !(vb2_get_fwmp_flags() & FWMP_DEV_ENABLE_USB)) {
+ !vb2_secdata_fwmp_get_flag(ctx, VB2_SECDATA_FWMP_DEV_ENABLE_USB)) {
vb2_flash_screen(ctx);
vb2_error_notify("WARNING: Booting from external media "
"(USB/SD) has not been enabled. Refer "
@@ -313,11 +313,11 @@ static vb2_error_t language_action(struct vb2_context *ctx)
/*
* Non-manual recovery mode is meant to be left via three-finger
* salute (into manual recovery mode). Need to commit nvdata
- * changes immediately.
+ * changes immediately. Ignore commit errors in recovery mode.
*/
if ((ctx->flags & VB2_CONTEXT_RECOVERY_MODE) &&
!vb2_allow_recovery(ctx))
- vb2_nv_commit(ctx);
+ vb2_commit_data(ctx);
/* Return to previous menu. */
switch (prev_menu) {
@@ -360,7 +360,7 @@ static vb2_error_t to_dev_action(struct vb2_context *ctx)
return VBERROR_KEEP_LOOPING;
VB2_DEBUG("Enabling dev-mode...\n");
- if (VB2_SUCCESS != SetVirtualDevMode(1))
+ if (VB2_SUCCESS != vb2_enable_developer_mode(ctx))
return VBERROR_TPM_SET_BOOT_MODE_STATE;
/* This was meant for headless devices, shouldn't really matter here. */
@@ -744,7 +744,7 @@ static vb2_error_t vb2_developer_menu(struct vb2_context *ctx)
/* Check if developer mode is disabled by FWMP */
disable_dev_boot = 0;
- if (vb2_get_fwmp_flags() & FWMP_DEV_DISABLE_BOOT) {
+ if (vb2_secdata_fwmp_get_flag(ctx, VB2_SECDATA_FWMP_DEV_DISABLE_BOOT)) {
if (gbb->flags & VB2_GBB_FLAG_FORCE_DEV_SWITCH_ON) {
VB2_DEBUG("FWMP_DEV_DISABLE_BOOT rejected by"
"FORCE_DEV_SWITCH_ON\n");
@@ -754,9 +754,10 @@ static vb2_error_t vb2_developer_menu(struct vb2_context *ctx)
VB2_DEBUG("dev_disable_boot is set.\n");
}
}
+
altfw_allowed = vb2_nv_get(ctx, VB2_NV_DEV_BOOT_LEGACY) ||
(gbb->flags & VB2_GBB_FLAG_FORCE_DEV_BOOT_LEGACY) ||
- (vb2_get_fwmp_flags() & FWMP_DEV_ENABLE_LEGACY);
+ vb2_secdata_fwmp_get_flag(ctx, VB2_SECDATA_FWMP_DEV_ENABLE_LEGACY);
/* Show appropriate initial menu */
if (disable_dev_boot)
@@ -849,7 +850,9 @@ static vb2_error_t broken_ui(struct vb2_context *ctx)
*/
VB2_DEBUG("saving recovery reason (%#x)\n", vbsd->recovery_reason);
vb2_nv_set(ctx, VB2_NV_RECOVERY_SUBCODE, vbsd->recovery_reason);
- vb2_nv_commit(ctx);
+
+ /* Ignore commit errors in recovery mode. */
+ vb2_commit_data(ctx);
enter_recovery_base_screen(ctx);
diff --git a/firmware/stub/vboot_api_stub_init.c b/firmware/stub/vboot_api_stub_init.c
index 7dc4c01c..d533325c 100644
--- a/firmware/stub/vboot_api_stub_init.c
+++ b/firmware/stub/vboot_api_stub_init.c
@@ -23,12 +23,8 @@ uint64_t VbExGetTimer(void)
return (uint64_t)tv.tv_sec * VB_USEC_PER_SEC + (uint64_t)tv.tv_usec;
}
-vb2_error_t VbExNvStorageRead(uint8_t *buf)
-{
- return VB2_SUCCESS;
-}
-
-vb2_error_t VbExNvStorageWrite(const uint8_t *buf)
+vb2_error_t vb2ex_commit_data(struct vb2_context *ctx)
{
+ ctx->flags &= ~VB2_CONTEXT_NVDATA_CHANGED;
return VB2_SUCCESS;
}
diff --git a/tests/secdata_tpm_tests.c b/tests/secdata_tpm_tests.c
index dd28e62a..32285ded 100644
--- a/tests/secdata_tpm_tests.c
+++ b/tests/secdata_tpm_tests.c
@@ -2,24 +2,16 @@
* Use of this source code is governed by a BSD-style license that can be
* found in the LICENSE file.
*
- * Tests for secdata_tpm functions
+ * Tests for TPM secure data space functions
*/
-#include <stdint.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-
-#include "2crc8.h"
+#include "2api.h"
+#include "2secdata.h"
#include "secdata_tpm.h"
#include "test_common.h"
#include "tlcl.h"
-
-_Static_assert(ROLLBACK_SPACE_FIRMWARE_VERSION > 0,
- "ROLLBACK_SPACE_FIRMWARE_VERSION must be greater than 0");
-
-_Static_assert(ROLLBACK_SPACE_KERNEL_VERSION > 0,
- "ROLLBACK_SPACE_KERNEL_VERSION must be greater than 0");
+#include "tss_constants.h"
+#include "vboot_test.h"
/*
* Buffer to hold accumulated list of calls to mocked Tlcl functions.
@@ -45,59 +37,85 @@ static char *mock_cnext = mock_calls;
static int mock_count = 0;
static int fail_at_count = 0;
static uint32_t fail_with_error = TPM_SUCCESS;
+static int mock_bad_crc = 0;
/* Params / backing store for mocked Tlcl functions. */
static TPM_PERMANENT_FLAGS mock_pflags;
-static RollbackSpaceFirmware mock_rsf;
-static RollbackSpaceKernel mock_rsk;
-
-static union {
- struct RollbackSpaceFwmp fwmp;
- uint8_t buf[FWMP_NV_MAX_SIZE];
-} mock_fwmp;
-
+static uint8_t mock_rsf[VB2_SECDATA_FIRMWARE_SIZE];
+static uint8_t mock_rsk[VB2_SECDATA_KERNEL_SIZE];
+static uint8_t mock_fwmp[VB2_SECDATA_FWMP_MAX_SIZE];
+static uint32_t mock_fwmp_real_size;
static uint32_t mock_permissions;
-/* Recalculate CRC of FWMP data */
-static void RecalcFwmpCrc(void)
-{
- mock_fwmp.fwmp.crc = vb2_crc8(mock_fwmp.buf + 2,
- mock_fwmp.fwmp.struct_size - 2);
-}
+static uint8_t workbuf[VB2_FIRMWARE_WORKBUF_RECOMMENDED_SIZE]
+ __attribute__ ((aligned (VB2_WORKBUF_ALIGN)));
+static struct vb2_context *ctx;
/* Reset the variables for the Tlcl mock functions. */
-static void ResetMocks(int fail_on_call, uint32_t fail_with_err)
+static void reset_common_data(int fail_on_call, uint32_t fail_with_err)
{
*mock_calls = 0;
mock_cnext = mock_calls;
mock_count = 0;
fail_at_count = fail_on_call;
fail_with_error = fail_with_err;
+ mock_bad_crc = 0;
memset(&mock_pflags, 0, sizeof(mock_pflags));
- memset(&mock_rsf, 0, sizeof(mock_rsf));
- mock_rsf.struct_version = ROLLBACK_SPACE_FIRMWARE_VERSION;
- mock_rsf.crc8 = vb2_crc8(&mock_rsf,
- offsetof(RollbackSpaceFirmware, crc8));
+ /* Use value other than 0 for memcmp() checks */
+ memset(&mock_rsf, 0xa6, sizeof(mock_rsf));
+ memset(&mock_rsk, 0xa7, sizeof(mock_rsk));
+ memset(&mock_fwmp, 0xa8, sizeof(mock_fwmp));
- memset(&mock_rsk, 0, sizeof(mock_rsk));
- mock_rsk.uid = ROLLBACK_SPACE_KERNEL_UID;
- mock_rsk.struct_version = ROLLBACK_SPACE_KERNEL_VERSION;
- mock_rsk.kernel_versions = 0x87654321;
- mock_rsk.crc8 = vb2_crc8(&mock_rsk,
- offsetof(RollbackSpaceKernel, crc8));
+ mock_fwmp_real_size = VB2_SECDATA_FWMP_MIN_SIZE;
+ /* Note: only used when TPM2_MODE is disabled. */
+#ifndef TPM2_MODE
mock_permissions = TPM_NV_PER_PPWRITE;
+#else
+ mock_permissions = 0;
+#endif
+
+ secdata_kernel_locked = 0;
+
+ TEST_SUCC(vb2api_init(workbuf, sizeof(workbuf), &ctx),
+ "vb2api_init failed");
+
+ ctx->flags |= VB2_CONTEXT_SECDATA_FIRMWARE_CHANGED;
+ ctx->flags |= VB2_CONTEXT_SECDATA_KERNEL_CHANGED;
+ ctx->flags |= VB2_CONTEXT_RECOVERY_MODE;
+}
+
+/* Mock functions */
+
+vb2_error_t vb2api_secdata_firmware_check(struct vb2_context *c)
+{
+ if (mock_bad_crc)
+ return VB2_ERROR_SECDATA_FIRMWARE_CRC;
+
+ return VB2_SUCCESS;
+}
- memset(mock_fwmp.buf, 0, sizeof(mock_fwmp.buf));
- mock_fwmp.fwmp.struct_size = sizeof(mock_fwmp.fwmp);
- mock_fwmp.fwmp.struct_version = ROLLBACK_SPACE_FWMP_VERSION;
- mock_fwmp.fwmp.flags = 0x1234;
- /* Put some data in the hash */
- mock_fwmp.fwmp.dev_key_hash[0] = 0xaa;
- mock_fwmp.fwmp.dev_key_hash[FWMP_HASH_SIZE - 1] = 0xbb;
- RecalcFwmpCrc();
+vb2_error_t vb2api_secdata_kernel_check(struct vb2_context *c)
+{
+ if (mock_bad_crc)
+ return VB2_ERROR_SECDATA_FIRMWARE_CRC;
+
+ return VB2_SUCCESS;
+}
+
+vb2_error_t vb2api_secdata_fwmp_check(struct vb2_context *c, uint8_t *size)
+{
+ if (*size < mock_fwmp_real_size) {
+ *size = mock_fwmp_real_size;
+ return VB2_ERROR_SECDATA_FWMP_INCOMPLETE;
+ }
+
+ if (mock_bad_crc)
+ return VB2_ERROR_SECDATA_FIRMWARE_CRC;
+
+ return VB2_SUCCESS;
}
/****************************************************************************/
@@ -212,26 +230,12 @@ uint32_t TlclAssertPhysicalPresence(void)
return (++mock_count == fail_at_count) ? fail_with_error : TPM_SUCCESS;
}
-uint32_t TlclFinalizePhysicalPresence(void)
-{
- mock_cnext += sprintf(mock_cnext, "TlclFinalizePhysicalPresence()\n");
- mock_pflags.physicalPresenceLifetimeLock = 1;
- return (++mock_count == fail_at_count) ? fail_with_error : TPM_SUCCESS;
-}
-
uint32_t TlclPhysicalPresenceCMDEnable(void)
{
mock_cnext += sprintf(mock_cnext, "TlclPhysicalPresenceCMDEnable()\n");
return (++mock_count == fail_at_count) ? fail_with_error : TPM_SUCCESS;
}
-uint32_t TlclSetNvLocked(void)
-{
- mock_cnext += sprintf(mock_cnext, "TlclSetNvLocked()\n");
- mock_pflags.nvLocked = 1;
- return (++mock_count == fail_at_count) ? fail_with_error : TPM_SUCCESS;
-}
-
uint32_t TlclSetGlobalLock(void)
{
mock_cnext += sprintf(mock_cnext, "TlclSetGlobalLock()\n");
@@ -244,6 +248,7 @@ uint32_t TlclLockPhysicalPresence(void)
return (++mock_count == fail_at_count) ? fail_with_error : TPM_SUCCESS;
}
+#ifndef TPM2_MODE
uint32_t TlclGetPermissions(uint32_t index, uint32_t* permissions)
{
mock_cnext += sprintf(mock_cnext, "TlclGetPermissions(%#x)\n", index);
@@ -251,297 +256,332 @@ uint32_t TlclGetPermissions(uint32_t index, uint32_t* permissions)
return (++mock_count == fail_at_count) ? fail_with_error : TPM_SUCCESS;
}
-/****************************************************************************/
-/* Tests for CRC errors */
-
-static void FirmwareSpaceTest(void)
+uint32_t TlclFinalizePhysicalPresence(void)
{
- RollbackSpaceFirmware rsf;
-
- /* Old version, valid CRC */
- ResetMocks(0, 0);
- mock_rsf.struct_version -= 1;
- mock_rsf.crc8 = vb2_crc8(&mock_rsf,
- offsetof(RollbackSpaceFirmware, crc8));
- TEST_EQ(ReadSpaceFirmware(&rsf), TPM_E_STRUCT_VERSION,
- "ReadSpaceFirmware(), old version");
- TEST_STR_EQ(mock_calls,
- "TlclRead(0x1007, 10)\n",
- "tlcl calls");
-
- /* Current version, bad CRC */
- ResetMocks(0, 0);
- mock_rsf.crc8 = 0;
- TEST_EQ(ReadSpaceFirmware(&rsf), TPM_E_CORRUPTED_STATE,
- "ReadSpaceFirmware(), bad CRC");
- TEST_STR_EQ(mock_calls,
- "TlclRead(0x1007, 10)\n",
- "tlcl calls");
-
- /* Current version, valid CRC */
- ResetMocks(0, 0);
- TEST_EQ(ReadSpaceFirmware(&rsf), 0,
- "ReadSpaceFirmware(), successful read");
- TEST_STR_EQ(mock_calls,
- "TlclRead(0x1007, 10)\n",
- "tlcl calls");
+ mock_cnext += sprintf(mock_cnext, "TlclFinalizePhysicalPresence()\n");
+ mock_pflags.physicalPresenceLifetimeLock = 1;
+ return (++mock_count == fail_at_count) ? fail_with_error : TPM_SUCCESS;
}
-static void KernelSpaceTest(void)
+uint32_t TlclSetNvLocked(void)
{
- RollbackSpaceKernel rsk;
-
- /* Current version, bad perms, valid CRC, valid UID */
- ResetMocks(0, 0);
- mock_permissions = 0;
- TEST_EQ(ReadSpaceKernel(&rsk), TPM_E_CORRUPTED_STATE,
- "ReadSpaceKernel(), bad permissions");
- TEST_STR_EQ(mock_calls,
- "TlclGetPermissions(0x1008)\n",
- "tlcl calls");
-
- /* Old version, good perms, valid CRC, valid UID */
- ResetMocks(0, 0);
- mock_rsk.struct_version -= 1;
- mock_rsk.crc8 = vb2_crc8(&mock_rsk,
- offsetof(RollbackSpaceKernel, crc8));
- TEST_EQ(ReadSpaceKernel(&rsk), TPM_E_STRUCT_VERSION,
- "ReadSpaceKernel(), old version");
- TEST_STR_EQ(mock_calls,
- "TlclGetPermissions(0x1008)\n"
- "TlclRead(0x1008, 13)\n",
- "tlcl calls");
-
- /* Current version, good perms, bad CRC, valid UID */
- ResetMocks(0, 0);
- mock_rsk.crc8 = 0;
- TEST_EQ(ReadSpaceKernel(&rsk), TPM_E_CORRUPTED_STATE,
- "ReadSpaceKernel(), bad CRC");
- TEST_STR_EQ(mock_calls,
- "TlclGetPermissions(0x1008)\n"
- "TlclRead(0x1008, 13)\n",
- "tlcl calls");
-
- /* Current version, good perms, valid CRC, bad UID */
- ResetMocks(0, 0);
- mock_rsk.uid = 0;
- mock_rsk.crc8 = vb2_crc8(&mock_rsk,
- offsetof(RollbackSpaceKernel, crc8));
- TEST_EQ(ReadSpaceKernel(&rsk), TPM_E_CORRUPTED_STATE,
- "ReadSpaceKernel(), bad UID");
- TEST_STR_EQ(mock_calls,
- "TlclGetPermissions(0x1008)\n"
- "TlclRead(0x1008, 13)\n",
- "tlcl calls");
-
- /* Current version, good perms, valid CRC, valid UID */
- ResetMocks(0, 0);
- TEST_EQ(ReadSpaceKernel(&rsk), 0,
- "ReadSpaceKernel(), successful read");
- TEST_STR_EQ(mock_calls,
- "TlclGetPermissions(0x1008)\n"
- "TlclRead(0x1008, 13)\n",
- "tlcl calls");
+ mock_cnext += sprintf(mock_cnext, "TlclSetNvLocked()\n");
+ mock_pflags.nvLocked = 1;
+ return (++mock_count == fail_at_count) ? fail_with_error : TPM_SUCCESS;
}
+#endif
/****************************************************************************/
/* Tests for misc helper functions */
-static void MiscTest(void)
+static void misc_tests(void)
{
uint8_t buf[8];
- ResetMocks(0, 0);
- TEST_EQ(TPMClearAndReenable(), 0, "TPMClearAndReenable()");
+ reset_common_data(0, 0);
+ TEST_EQ(tlcl_clear_and_reenable(), 0, "tlcl_clear_and_enable()");
TEST_STR_EQ(mock_calls,
"TlclForceClear()\n"
"TlclSetEnable()\n"
"TlclSetDeactivated(0)\n",
- "tlcl calls");
+ " tlcl calls");
- ResetMocks(0, 0);
- TEST_EQ(SafeWrite(0x123, buf, 8), 0, "SafeWrite()");
+ reset_common_data(0, 0);
+ TEST_EQ(tlcl_safe_write(0x123, buf, 8), 0, "tlcl_safe_write()");
TEST_STR_EQ(mock_calls,
"TlclWrite(0x123, 8)\n",
- "tlcl calls");
+ " tlcl calls");
- ResetMocks(1, TPM_E_BADINDEX);
- TEST_EQ(SafeWrite(0x123, buf, 8), TPM_E_BADINDEX, "SafeWrite() bad");
+ reset_common_data(1, TPM_E_BADINDEX);
+ TEST_EQ(tlcl_safe_write(0x123, buf, 8), TPM_E_BADINDEX,
+ "tlcl_safe_write() bad");
TEST_STR_EQ(mock_calls,
"TlclWrite(0x123, 8)\n",
- "tlcl calls");
+ " tlcl calls");
- ResetMocks(1, TPM_E_MAXNVWRITES);
- TEST_EQ(SafeWrite(0x123, buf, 8), 0, "SafeWrite() retry max writes");
+ reset_common_data(1, TPM_E_MAXNVWRITES);
+ TEST_EQ(tlcl_safe_write(0x123, buf, 8), 0,
+ "tlcl_safe_write() retry max writes");
TEST_STR_EQ(mock_calls,
"TlclWrite(0x123, 8)\n"
"TlclForceClear()\n"
"TlclSetEnable()\n"
"TlclSetDeactivated(0)\n"
"TlclWrite(0x123, 8)\n",
- "tlcl calls");
+ " tlcl calls");
}
/****************************************************************************/
-/* Tests for RollbackKernel() calls */
+/* Tests for firmware space functions */
-static void RollbackKernelTest(void)
+static void secdata_firmware_tests(void)
{
- uint32_t version = 0;
+ /* Write with no new changes */
+ reset_common_data(0, 0);
+ ctx->flags &= ~VB2_CONTEXT_SECDATA_FIRMWARE_CHANGED;
+ TEST_SUCC(secdata_firmware_write(ctx),
+ "secdata_firmware_write(), no changes, success");
+ TEST_STR_EQ(mock_calls,
+ "",
+ " tlcl calls");
- /* Normal read */
- ResetMocks(0, 0);
- TEST_EQ(RollbackKernelRead(&version), 0, "RollbackKernelRead()");
+ /* Write failure */
+ reset_common_data(1, TPM_E_IOERROR);
+ TEST_EQ(secdata_firmware_write(ctx), TPM_E_IOERROR,
+ "secdata_firmware_write(), failure");
TEST_STR_EQ(mock_calls,
- "TlclGetPermissions(0x1008)\n"
+ "TlclWrite(0x1007, 10)\n",
+ " tlcl calls");
+ TEST_NEQ(ctx->flags & VB2_CONTEXT_SECDATA_FIRMWARE_CHANGED, 0,
+ " should leave SECDATA_FIRMWARE_CHANGED context flag");
+
+ /* Write in normal mode */
+ reset_common_data(0, 0);
+ ctx->flags &= ~VB2_CONTEXT_RECOVERY_MODE;
+ TEST_EQ(secdata_firmware_write(ctx), TPM_E_AREA_LOCKED,
+ "secdata_firmware_write(), normal mode, failure");
+ TEST_STR_EQ(mock_calls,
+ "",
+ " tlcl calls");
+ TEST_NEQ(ctx->flags & VB2_CONTEXT_SECDATA_FIRMWARE_CHANGED, 0,
+ " should leave SECDATA_FIRMWARE_CHANGED context flag");
+
+ /* Write success and readback */
+ reset_common_data(0, 0);
+ memset(ctx->secdata_firmware, 0xaa, sizeof(ctx->secdata_firmware));
+ TEST_SUCC(secdata_firmware_write(ctx),
+ "secdata_firmware_write(), success");
+ TEST_STR_EQ(mock_calls,
+ "TlclWrite(0x1007, 10)\n",
+ " tlcl calls");
+ memset(ctx->secdata_firmware, 0xaa, sizeof(ctx->secdata_firmware));
+ TEST_EQ(memcmp(ctx->secdata_firmware, &mock_rsf,
+ sizeof(ctx->secdata_firmware)), 0,
+ " unchanged on readback");
+ TEST_EQ(ctx->flags & VB2_CONTEXT_SECDATA_FIRMWARE_CHANGED, 0,
+ " should reset SECDATA_FIRMWARE_CHANGED context flag");
+}
+
+/****************************************************************************/
+/* Tests for kernel space functions */
+
+static void secdata_kernel_tests(void)
+{
+ /* Not present is an error */
+ reset_common_data(1, TPM_E_BADINDEX);
+ TEST_EQ(secdata_kernel_read(ctx), TPM_E_BADINDEX,
+ "secdata_kernel_read(), not present");
+ TEST_STR_EQ(mock_calls,
+#ifndef TPM2_MODE
+ "TlclGetPermissions(0x1008)\n",
+#else
"TlclRead(0x1008, 13)\n",
- "tlcl calls");
- TEST_EQ(version, 0x87654321, "RollbackKernelRead() version");
+#endif
+ " tlcl calls");
- /* Read error */
- ResetMocks(1, TPM_E_IOERROR);
- TEST_EQ(RollbackKernelRead(&version), TPM_E_IOERROR,
- "RollbackKernelRead() error");
-
- /* Wrong permission or UID will return error */
- ResetMocks(0, 0);
- mock_rsk.uid = 0;
- mock_rsk.crc8 = vb2_crc8(&mock_rsk,
- offsetof(RollbackSpaceKernel, crc8));
- TEST_EQ(RollbackKernelRead(&version), TPM_E_CORRUPTED_STATE,
- "RollbackKernelRead() bad uid");
-
- ResetMocks(0, 0);
+#ifndef TPM2_MODE
+ /* Bad permissions */
+ reset_common_data(0, 0);
mock_permissions = 0;
- TEST_EQ(RollbackKernelRead(&version), TPM_E_CORRUPTED_STATE,
- "RollbackKernelRead() bad permissions");
-
- /* Test write */
- ResetMocks(0, 0);
- TEST_EQ(RollbackKernelWrite(0xBEAD4321), 0, "RollbackKernelWrite()");
- TEST_EQ(mock_rsk.kernel_versions, 0xBEAD4321,
- "RollbackKernelWrite() version");
+ TEST_EQ(secdata_kernel_read(ctx), TPM_E_CORRUPTED_STATE,
+ "secdata_kernel_read(), bad permissions");
+ TEST_STR_EQ(mock_calls,
+ "TlclGetPermissions(0x1008)\n",
+ " tlcl calls");
+#endif
+
+ /* Good permissions, read failure */
+#ifndef TPM2_MODE
+ int read_failure_on_call = 2;
+#else
+ int read_failure_on_call = 1;
+#endif
+ reset_common_data(read_failure_on_call, TPM_E_IOERROR);
+ TEST_EQ(secdata_kernel_read(ctx), TPM_E_IOERROR,
+ "secdata_kernel_read(), good permissions, failure");
TEST_STR_EQ(mock_calls,
+#ifndef TPM2_MODE
"TlclGetPermissions(0x1008)\n"
- "TlclRead(0x1008, 13)\n"
- "TlclWrite(0x1008, 13)\n",
- "tlcl calls");
+#endif
+ "TlclRead(0x1008, 13)\n",
+ " tlcl calls");
+
+ /* Good permissions, read success, bad CRC */
+ reset_common_data(0, 0);
+ mock_bad_crc = 1;
+ TEST_EQ(secdata_kernel_read(ctx), TPM_E_CORRUPTED_STATE,
+ "secdata_kernel_read(), read success, bad CRC");
+ TEST_STR_EQ(mock_calls,
+#ifndef TPM2_MODE
+ "TlclGetPermissions(0x1008)\n"
+#endif
+ "TlclRead(0x1008, 13)\n",
+ " tlcl calls");
- ResetMocks(1, TPM_E_IOERROR);
- TEST_EQ(RollbackKernelWrite(123), TPM_E_IOERROR,
- "RollbackKernelWrite() error");
+ /* Good permissions, read success */
+ reset_common_data(0, 0);
+ TEST_SUCC(secdata_kernel_read(ctx),
+ "secdata_kernel_read(), good permissions, success");
+ TEST_STR_EQ(mock_calls,
+#ifndef TPM2_MODE
+ "TlclGetPermissions(0x1008)\n"
+#endif
+ "TlclRead(0x1008, 13)\n",
+ " tlcl calls");
+ TEST_EQ(memcmp(ctx->secdata_kernel, &mock_rsk,
+ sizeof(ctx->secdata_kernel)), 0, " data");
+
+ /* Write with no new changes */
+ reset_common_data(0, 0);
+ ctx->flags &= ~VB2_CONTEXT_SECDATA_KERNEL_CHANGED;
+ TEST_SUCC(secdata_kernel_write(ctx),
+ "secdata_kernel_write(), no changes, success");
+ TEST_STR_EQ(mock_calls,
+ "",
+ " tlcl calls");
- /* Test lock (recovery off) */
- ResetMocks(1, TPM_E_IOERROR);
- TEST_EQ(RollbackKernelLock(0), TPM_E_IOERROR,
- "RollbackKernelLock() error");
+ /* Write failure */
+ reset_common_data(1, TPM_E_IOERROR);
+ TEST_EQ(secdata_kernel_write(ctx), TPM_E_IOERROR,
+ "secdata_kernel_write(), failure");
+ TEST_STR_EQ(mock_calls,
+ "TlclWrite(0x1008, 13)\n",
+ " tlcl calls");
+ TEST_NEQ(ctx->flags & VB2_CONTEXT_SECDATA_KERNEL_CHANGED, 0,
+ " should leave SECDATA_KERNEL_CHANGED context flag");
+
+ /* Write success and readback */
+ reset_common_data(0, 0);
+ memset(ctx->secdata_kernel, 0xaa, sizeof(ctx->secdata_kernel));
+ TEST_SUCC(secdata_kernel_write(ctx),
+ "secdata_kernel_write(), failure");
+ TEST_STR_EQ(mock_calls,
+ "TlclWrite(0x1008, 13)\n",
+ " tlcl calls");
+ memset(ctx->secdata_kernel, 0xaa, sizeof(ctx->secdata_kernel));
+ TEST_EQ(memcmp(ctx->secdata_kernel, &mock_rsk,
+ sizeof(ctx->secdata_kernel)), 0,
+ " unchanged on readback");
+ TEST_EQ(ctx->flags & VB2_CONTEXT_SECDATA_KERNEL_CHANGED, 0,
+ " should reset SECDATA_KERNEL_CHANGED context flag");
+
+ /* Lock in normal mode with failure */
+ reset_common_data(1, TPM_E_AREA_LOCKED);
+ TEST_EQ(secdata_kernel_lock(ctx), TPM_E_AREA_LOCKED,
+ "secdata_kernel_lock(), lock failure");
+ TEST_STR_EQ(mock_calls,
+ "TlclLockPhysicalPresence()\n",
+ " tlcl calls");
- /* Test lock with recovery on; shouldn't lock PP */
- ResetMocks(0, 0);
- TEST_EQ(RollbackKernelLock(1), 0, "RollbackKernelLock() in recovery");
- TEST_STR_EQ(mock_calls, "", "no tlcl calls");
+ /* Lock in normal mode */
+ reset_common_data(0, 0);
+ TEST_SUCC(secdata_kernel_lock(ctx),
+ "secdata_kernel_lock(), success (locked)");
+ TEST_STR_EQ(mock_calls,
+ "TlclLockPhysicalPresence()\n",
+ " tlcl calls");
- ResetMocks(0, 0);
- TEST_EQ(RollbackKernelLock(0), 0, "RollbackKernelLock()");
+ /* Lock after already locked (only one TlclLockPhysicalPresence). */
+ reset_common_data(0, 0);
+ TEST_SUCC(secdata_kernel_lock(ctx),
+ "secdata_kernel_lock(), lock first run");
+ TEST_SUCC(secdata_kernel_lock(ctx),
+ "secdata_kernel_lock(), already locked");
TEST_STR_EQ(mock_calls,
"TlclLockPhysicalPresence()\n",
- "tlcl calls");
+ " tlcl calls");
}
/****************************************************************************/
-/* Tests for RollbackFwmpRead() calls */
+/* Tests for fwmp space functions */
-static void RollbackFwmpTest(void)
+static void secdata_fwmp_tests(void)
{
- struct RollbackSpaceFwmp fwmp;
- struct RollbackSpaceFwmp fwmp_zero = {0};
+ /* Read failure */
+ reset_common_data(1, TPM_E_IOERROR);
+ TEST_EQ(secdata_fwmp_read(ctx), TPM_E_IOERROR,
+ "secdata_fwmp_read(), failure");
+ TEST_STR_EQ(mock_calls,
+ "TlclRead(0x100a, 40)\n",
+ " tlcl calls");
+ TEST_EQ(ctx->flags & VB2_CONTEXT_NO_SECDATA_FWMP, 0,
+ " should leave NO_SECDATA_FWMP context flag");
+
+ /* Normal read, bad CRC */
+ reset_common_data(0, 0);
+ mock_bad_crc = 1;
+ TEST_EQ(secdata_fwmp_read(ctx), TPM_E_CORRUPTED_STATE,
+ "secdata_fwmp_read(), success, bad CRC");
+ TEST_STR_EQ(mock_calls,
+ "TlclRead(0x100a, 40)\n",
+ " tlcl calls");
+ TEST_EQ(ctx->flags & VB2_CONTEXT_NO_SECDATA_FWMP, 0,
+ " should leave NO_SECDATA_FWMP context flag");
/* Normal read */
- ResetMocks(0, 0);
- TEST_EQ(RollbackFwmpRead(&fwmp), 0, "RollbackFwmpRead()");
+ reset_common_data(0, 0);
+ TEST_SUCC(secdata_fwmp_read(ctx),
+ "secdata_fwmp_read(), success");
TEST_STR_EQ(mock_calls,
"TlclRead(0x100a, 40)\n",
" tlcl calls");
- TEST_EQ(0, memcmp(&fwmp, &mock_fwmp, sizeof(fwmp)), " data");
+ TEST_EQ(memcmp(ctx->secdata_fwmp, &mock_fwmp,
+ mock_fwmp_real_size), 0, " data");
+ TEST_EQ(ctx->flags & VB2_CONTEXT_NO_SECDATA_FWMP, 0,
+ " should leave NO_SECDATA_FWMP context flag");
/* Read error */
- ResetMocks(1, TPM_E_IOERROR);
- TEST_EQ(RollbackFwmpRead(&fwmp), TPM_E_IOERROR,
- "RollbackFwmpRead() error");
+ reset_common_data(1, TPM_E_IOERROR);
+ TEST_EQ(secdata_fwmp_read(ctx), TPM_E_IOERROR,
+ "secdata_fwmp_read(), error");
TEST_STR_EQ(mock_calls,
"TlclRead(0x100a, 40)\n",
" tlcl calls");
- TEST_EQ(0, memcmp(&fwmp, &fwmp_zero, sizeof(fwmp)), " data clear");
+ TEST_EQ(ctx->flags & VB2_CONTEXT_NO_SECDATA_FWMP, 0,
+ " should leave NO_SECDATA_FWMP context flag");
- /* Not present isn't an error; just returns empty data */
- ResetMocks(1, TPM_E_BADINDEX);
- TEST_EQ(RollbackFwmpRead(&fwmp), 0, "RollbackFwmpRead() not present");
+ /* Not present isn't an error; just sets context flag */
+ reset_common_data(1, TPM_E_BADINDEX);
+ TEST_SUCC(secdata_fwmp_read(ctx), "secdata_fwmp_read(), not present");
TEST_STR_EQ(mock_calls,
"TlclRead(0x100a, 40)\n",
" tlcl calls");
- TEST_EQ(0, memcmp(&fwmp, &fwmp_zero, sizeof(fwmp)), " data clear");
-
- /* Struct size too small */
- ResetMocks(0, 0);
- mock_fwmp.fwmp.struct_size--;
- TEST_EQ(RollbackFwmpRead(&fwmp), TPM_E_STRUCT_SIZE,
- "RollbackFwmpRead() too small");
-
- /* Struct size too large with good CRC */
- ResetMocks(0, 0);
- mock_fwmp.fwmp.struct_size += 4;
- RecalcFwmpCrc();
- TEST_EQ(RollbackFwmpRead(&fwmp), 0, "RollbackFwmpRead() bigger");
+ TEST_NEQ(ctx->flags & VB2_CONTEXT_NO_SECDATA_FWMP, 0,
+ " should set NO_SECDATA_FWMP context flag");
+
+ /* Struct size too large, then bad CRC */
+ reset_common_data(0, 0);
+ mock_fwmp_real_size += 4;
+ mock_bad_crc = 1;
+ TEST_EQ(secdata_fwmp_read(ctx), TPM_E_CORRUPTED_STATE,
+ "secdata_fwmp_read(), bigger, bad CRC");
TEST_STR_EQ(mock_calls,
"TlclRead(0x100a, 40)\n"
"TlclRead(0x100a, 44)\n",
" tlcl calls");
- TEST_EQ(0, memcmp(&fwmp, &mock_fwmp, sizeof(fwmp)), " data");
-
- /* Bad CRC causes retry, then eventual failure */
- ResetMocks(0, 0);
- mock_fwmp.fwmp.crc++;
- TEST_EQ(RollbackFwmpRead(&fwmp), TPM_E_CORRUPTED_STATE,
- "RollbackFwmpRead() crc");
- TEST_STR_EQ(mock_calls,
- "TlclRead(0x100a, 40)\n",
- " tlcl calls");
+ TEST_EQ(ctx->flags & VB2_CONTEXT_NO_SECDATA_FWMP, 0,
+ " should leave NO_SECDATA_FWMP context flag");
- /* Struct size too large with bad CRC */
- ResetMocks(0, 0);
- mock_fwmp.fwmp.struct_size += 4;
- RecalcFwmpCrc();
- mock_fwmp.fwmp.crc++;
- TEST_EQ(RollbackFwmpRead(&fwmp), TPM_E_CORRUPTED_STATE,
- "RollbackFwmpRead() bigger crc");
+ /* Struct size too large */
+ reset_common_data(0, 0);
+ mock_fwmp_real_size += 4;
+ TEST_SUCC(secdata_fwmp_read(ctx), "secdata_fwmp_read(), bigger");
TEST_STR_EQ(mock_calls,
"TlclRead(0x100a, 40)\n"
"TlclRead(0x100a, 44)\n",
" tlcl calls");
- TEST_EQ(0, memcmp(&fwmp, &fwmp_zero, sizeof(fwmp)), " data");
-
- /* Minor version difference ok */
- ResetMocks(0, 0);
- mock_fwmp.fwmp.struct_version++;
- RecalcFwmpCrc();
- TEST_EQ(RollbackFwmpRead(&fwmp), 0, "RollbackFwmpRead() minor version");
- TEST_EQ(0, memcmp(&fwmp, &mock_fwmp, sizeof(fwmp)), " data");
-
- /* Major version difference not ok */
- ResetMocks(0, 0);
- mock_fwmp.fwmp.struct_version += 0x10;
- RecalcFwmpCrc();
- TEST_EQ(RollbackFwmpRead(&fwmp), TPM_E_STRUCT_VERSION,
- "RollbackFwmpRead() major version");
+ TEST_EQ(memcmp(ctx->secdata_fwmp, &mock_fwmp,
+ mock_fwmp_real_size), 0, " data");
+ TEST_EQ(ctx->flags & VB2_CONTEXT_NO_SECDATA_FWMP, 0,
+ " should leave NO_SECDATA_FWMP context flag");
}
int main(int argc, char* argv[])
{
- FirmwareSpaceTest();
- KernelSpaceTest();
- MiscTest();
- RollbackKernelTest();
- RollbackFwmpTest();
+ misc_tests();
+ secdata_firmware_tests();
+ secdata_kernel_tests();
+ secdata_fwmp_tests();
return gTestSuccess ? 0 : 255;
}
diff --git a/tests/test_common.h b/tests/test_common.h
index 17689b71..e0d8ef3b 100644
--- a/tests/test_common.h
+++ b/tests/test_common.h
@@ -109,7 +109,7 @@ int test_false(int result,
#result " == false", \
comment)
-/* Return 1 if result is 0 (VB_ERROR_SUCCESS / VB2_SUCCESS), else return 0.
+/* Return 1 if result is 0 (VB2_SUCCESS or other), else return 0.
* Also update the global gTestSuccess flag if test fails. */
int test_succ(int result,
const char *preamble, const char *desc, const char *comment);
diff --git a/tests/vboot_api_devmode_tests.c b/tests/vboot_api_devmode_tests.c
index 6cbcedec..36983d1f 100644
--- a/tests/vboot_api_devmode_tests.c
+++ b/tests/vboot_api_devmode_tests.c
@@ -122,6 +122,9 @@ static void ResetMocks(void)
sd = vb2_get_sd(ctx);
sd->vbsd = shared;
+ ctx->flags |= VB2_CONTEXT_NO_SECDATA_FWMP;
+ sd->status |= VB2_SD_STATUS_SECDATA_FWMP_INIT;
+
memset(&gbb, 0, sizeof(gbb));
memset(&shared_data, 0, sizeof(shared_data));
@@ -149,12 +152,7 @@ struct vb2_gbb_header *vb2_get_gbb(struct vb2_context *c)
return &gbb;
}
-vb2_error_t VbExNvStorageRead(uint8_t* buf)
-{
- return VB2_SUCCESS;
-}
-
-vb2_error_t VbExNvStorageWrite(const uint8_t* buf)
+vb2_error_t vb2_commit_data(struct vb2_context *c)
{
return VB2_SUCCESS;
}
diff --git a/tests/vboot_api_kernel2_tests.c b/tests/vboot_api_kernel2_tests.c
index 50ee0752..6d8946ee 100644
--- a/tests/vboot_api_kernel2_tests.c
+++ b/tests/vboot_api_kernel2_tests.c
@@ -9,6 +9,7 @@
#include "2misc.h"
#include "2nvstorage.h"
#include "2secdata.h"
+#include "2secdata_struct.h"
#include "host_common.h"
#include "load_kernel_fw.h"
#include "secdata_tpm.h"
@@ -30,6 +31,7 @@ static uint8_t workbuf[VB2_KERNEL_WORKBUF_RECOMMENDED_SIZE]
static struct vb2_context *ctx;
static struct vb2_shared_data *sd;
static struct vb2_gbb_header gbb;
+static struct vb2_secdata_fwmp *fwmp;
static int audio_looping_calls_left;
static uint32_t vbtlk_retval;
@@ -82,7 +84,6 @@ static void MockGpioAfter(uint32_t ticks, uint32_t gpio_flags)
static void ResetMocks(void)
{
vb2_init_ui();
- memset(VbApiKernelGetFwmp(), 0, sizeof(struct RollbackSpaceFwmp));
memset(&shared_data, 0, sizeof(shared_data));
VbSharedDataInit(shared, sizeof(shared_data));
@@ -97,6 +98,10 @@ static void ResetMocks(void)
sd->vbsd = shared;
sd->flags |= VB2_SD_FLAG_DISPLAY_AVAILABLE;
+ /* CRC will be invalid after here, but nobody's checking */
+ sd->status |= VB2_SD_STATUS_SECDATA_FWMP_INIT;
+ fwmp = (struct vb2_secdata_fwmp *)ctx->secdata_fwmp;
+
memset(&gbb, 0, sizeof(gbb));
audio_looping_calls_left = 30;
@@ -125,7 +130,8 @@ static void ResetMocks(void)
}
/* Mock functions */
-uint32_t RollbackKernelLock(int recovery_mode)
+
+uint32_t secdata_kernel_lock(struct vb2_context *c)
{
return TPM_SUCCESS;
}
@@ -252,9 +258,9 @@ vb2_error_t VbDisplayScreen(struct vb2_context *c, uint32_t screen, int force,
return VB2_SUCCESS;
}
-vb2_error_t SetVirtualDevMode(int val)
+vb2_error_t vb2_enable_developer_mode(struct vb2_context *c)
{
- virtdev_set = val;
+ virtdev_set = 1;
return virtdev_retval;
}
@@ -718,7 +724,7 @@ static void VbBootDevTest(void)
/* Enter altfw menu and select firmware 0 */
ResetMocks();
- VbApiKernelGetFwmp()->flags |= FWMP_DEV_ENABLE_LEGACY;
+ fwmp->flags |= VB2_SECDATA_FWMP_DEV_ENABLE_LEGACY;
mock_keypress[0] = VB_KEY_CTRL('L');
mock_keypress[1] = '0';
TEST_EQ(VbBootDeveloper(ctx), 1002,
@@ -750,7 +756,7 @@ static void VbBootDevTest(void)
TEST_EQ(altfw_num, key - '0', " check altfw_num");
ResetMocks();
- VbApiKernelGetFwmp()->flags |= FWMP_DEV_ENABLE_LEGACY;
+ fwmp->flags |= VB2_SECDATA_FWMP_DEV_ENABLE_LEGACY;
mock_keypress[0] = key;
TEST_EQ(VbBootDeveloper(ctx), 1002,
"Ctrl+L fwmp legacy");
@@ -779,7 +785,7 @@ static void VbBootDevTest(void)
/* Ctrl+U enabled via FWMP */
ResetMocks();
- VbApiKernelGetFwmp()->flags |= FWMP_DEV_ENABLE_USB;
+ fwmp->flags |= VB2_SECDATA_FWMP_DEV_ENABLE_USB;
mock_keypress[0] = VB_KEY_CTRL('U');
vbtlk_retval = VB2_SUCCESS - VB_DISK_FLAG_REMOVABLE;
TEST_EQ(VbBootDeveloper(ctx), 0, "Ctrl+U force USB");
@@ -984,7 +990,7 @@ static void VbBootDevTest(void)
/* If dev mode is disabled, goes to TONORM screen repeatedly */
ResetMocks();
- VbApiKernelGetFwmp()->flags |= FWMP_DEV_DISABLE_BOOT;
+ fwmp->flags |= VB2_SECDATA_FWMP_DEV_DISABLE_BOOT;
mock_keypress[0] = VB_KEY_ESC; /* Just causes TONORM again */
mock_keypress[1] = VB_KEY_ENTER;
TEST_EQ(VbBootDeveloper(ctx), VBERROR_REBOOT_REQUIRED,
@@ -1001,7 +1007,7 @@ static void VbBootDevTest(void)
/* Shutdown requested when dev disabled */
ResetMocks();
shared->flags = VBSD_BOOT_DEV_SWITCH_ON;
- VbApiKernelGetFwmp()->flags |= FWMP_DEV_DISABLE_BOOT;
+ fwmp->flags |= VB2_SECDATA_FWMP_DEV_DISABLE_BOOT;
MockGpioAfter(1, GPIO_SHUTDOWN);
TEST_EQ(VbBootDeveloper(ctx),
VBERROR_SHUTDOWN_REQUESTED,
@@ -1012,7 +1018,7 @@ static void VbBootDevTest(void)
/* Shutdown requested by keyboard when dev disabled */
ResetMocks();
shared->flags = VBSD_BOOT_DEV_SWITCH_ON;
- VbApiKernelGetFwmp()->flags |= FWMP_DEV_DISABLE_BOOT;
+ fwmp->flags |= VB2_SECDATA_FWMP_DEV_DISABLE_BOOT;
mock_keypress[0] = VB_BUTTON_POWER_SHORT_PRESS;
TEST_EQ(VbBootDeveloper(ctx),
VBERROR_SHUTDOWN_REQUESTED,
diff --git a/tests/vboot_api_kernel4_tests.c b/tests/vboot_api_kernel4_tests.c
index c168f82d..c0a10727 100644
--- a/tests/vboot_api_kernel4_tests.c
+++ b/tests/vboot_api_kernel4_tests.c
@@ -21,27 +21,31 @@
#include "vboot_common.h"
#include "vboot_kernel.h"
#include "vboot_struct.h"
+#include "vboot_test.h"
/* Mock data */
static uint8_t workbuf[VB2_KERNEL_WORKBUF_RECOMMENDED_SIZE]
__attribute__((aligned(VB2_WORKBUF_ALIGN)));
static struct vb2_context *ctx;
-static struct vb2_context ctx_nvram_backend;
static struct vb2_shared_data *sd;
static VbSelectAndLoadKernelParams kparams;
static uint8_t shared_data[VB_SHARED_DATA_MIN_SIZE];
static VbSharedDataHeader *shared = (VbSharedDataHeader *)shared_data;
static struct vb2_gbb_header gbb;
-static uint32_t rkr_version;
+static uint32_t kernel_version;
static uint32_t new_version;
-static struct RollbackSpaceFwmp rfr_fwmp;
-static int rkr_retval, rkw_retval, rkl_retval, rfr_retval;
+static uint8_t fwmp_buf[VB2_SECDATA_FWMP_MIN_SIZE];
+static uint32_t kernel_read_retval;
+static uint32_t kernel_write_retval;
+static uint32_t kernel_lock_retval;
+static uint32_t fwmp_read_retval;
static vb2_error_t vbboot_retval;
static uint32_t mock_switches[8];
static uint32_t mock_switches_count;
static int mock_switches_are_stuck;
+static int commit_data_called;
/* Reset mock data (for use before each test) */
static void ResetMocks(void)
@@ -57,26 +61,22 @@ static void ResetMocks(void)
"vb2api_init failed");
sd = vb2_get_sd(ctx);
sd->flags |= VB2_SD_FLAG_DISPLAY_AVAILABLE;
+ ctx->flags |= VB2_CONTEXT_NO_SECDATA_FWMP;
- /*
- * ctx_nvram_backend is only used as an NVRAM backend (see
- * VbExNvStorageRead and VbExNvStorageWrite), and with
- * vb2_set_nvdata and nv2_get_nvdata to manually read and tweak
- * contents. No other initialization is needed.
- */
- memset(&ctx_nvram_backend, 0, sizeof(ctx_nvram_backend));
- vb2_nv_init(&ctx_nvram_backend);
- vb2_nv_set(&ctx_nvram_backend, VB2_NV_KERNEL_MAX_ROLLFORWARD,
- 0xffffffff);
+ vb2_nv_init(ctx);
+ vb2_nv_set(ctx, VB2_NV_KERNEL_MAX_ROLLFORWARD, 0xffffffff);
+ commit_data_called = 0;
memset(&shared_data, 0, sizeof(shared_data));
VbSharedDataInit(shared, sizeof(shared_data));
- memset(&rfr_fwmp, 0, sizeof(rfr_fwmp));
- rfr_retval = TPM_SUCCESS;
+ memset(&fwmp_buf, 0, sizeof(fwmp_buf));
+ fwmp_read_retval = TPM_SUCCESS;
- rkr_version = new_version = 0x10002;
- rkr_retval = rkw_retval = rkl_retval = VB2_SUCCESS;
+ kernel_version = new_version = 0x10002;
+ kernel_read_retval = TPM_SUCCESS;
+ kernel_write_retval = TPM_SUCCESS;
+ kernel_lock_retval = TPM_SUCCESS;
vbboot_retval = VB2_SUCCESS;
memset(mock_switches, 0, sizeof(mock_switches));
@@ -86,41 +86,59 @@ static void ResetMocks(void)
/* Mock functions */
-vb2_error_t VbExNvStorageRead(uint8_t *buf)
+vb2_error_t vb2ex_commit_data(struct vb2_context *c)
{
- memcpy(buf, ctx_nvram_backend.nvdata,
- vb2_nv_get_size(&ctx_nvram_backend));
+ commit_data_called = 1;
return VB2_SUCCESS;
}
-vb2_error_t VbExNvStorageWrite(const uint8_t *buf)
+uint32_t secdata_firmware_write(struct vb2_context *c)
{
- memcpy(ctx_nvram_backend.nvdata, buf,
- vb2_nv_get_size(&ctx_nvram_backend));
- return VB2_SUCCESS;
+ return TPM_SUCCESS;
+}
+
+uint32_t secdata_kernel_read(struct vb2_context *c)
+{
+ return kernel_read_retval;
+}
+
+uint32_t secdata_kernel_write(struct vb2_context *c)
+{
+ return kernel_write_retval;
}
-uint32_t RollbackKernelRead(uint32_t *version)
+uint32_t secdata_kernel_lock(struct vb2_context *c)
{
- *version = rkr_version;
- return rkr_retval;
+ return kernel_lock_retval;
}
-uint32_t RollbackKernelWrite(uint32_t version)
+uint32_t secdata_fwmp_read(struct vb2_context *c)
{
- rkr_version = version;
- return rkw_retval;
+ memcpy(&c->secdata_fwmp, &fwmp_buf, sizeof(fwmp_buf));
+ return fwmp_read_retval;
}
-uint32_t RollbackKernelLock(int recovery_mode)
+vb2_error_t vb2_secdata_firmware_init(struct vb2_context *c)
{
- return rkl_retval;
+ return VB2_SUCCESS;
+}
+
+vb2_error_t vb2_secdata_kernel_init(struct vb2_context *c)
+{
+ return VB2_SUCCESS;
}
-uint32_t RollbackFwmpRead(struct RollbackSpaceFwmp *fwmp)
+uint32_t vb2_secdata_kernel_get(struct vb2_context *c,
+ enum vb2_secdata_kernel_param param)
{
- memcpy(fwmp, &rfr_fwmp, sizeof(*fwmp));
- return rfr_retval;
+ return kernel_version;
+}
+
+void vb2_secdata_kernel_set(struct vb2_context *c,
+ enum vb2_secdata_kernel_param param,
+ uint32_t value)
+{
+ kernel_version = value;
}
vb2_error_t VbTryLoadKernel(struct vb2_context *c, uint32_t get_info_flags)
@@ -164,8 +182,10 @@ vb2_error_t VbBootDiagnostic(struct vb2_context *c)
static void test_slk(vb2_error_t retval, int recovery_reason, const char *desc)
{
TEST_EQ(VbSelectAndLoadKernel(ctx, shared, &kparams), retval, desc);
- TEST_EQ(vb2_nv_get(&ctx_nvram_backend, VB2_NV_RECOVERY_REQUEST),
+ TEST_EQ(vb2_nv_get(ctx, VB2_NV_RECOVERY_REQUEST),
recovery_reason, " recovery reason");
+ if (recovery_reason)
+ TEST_TRUE(commit_data_called, " didn't commit nvdata");
}
uint32_t VbExGetSwitches(uint32_t request_mask)
@@ -189,7 +209,7 @@ static void VbSlkTest(void)
{
ResetMocks();
test_slk(0, 0, "Normal");
- TEST_EQ(rkr_version, 0x10002, " version");
+ TEST_EQ(kernel_version, 0x10002, " version");
/*
* If shared->flags doesn't ask for software sync, we won't notice
@@ -206,42 +226,43 @@ static void VbSlkTest(void)
/* Rollback kernel version */
ResetMocks();
- rkr_retval = 123;
- test_slk(VBERROR_TPM_READ_KERNEL,
+ kernel_read_retval = 123;
+ test_slk(VB2_ERROR_SECDATA_KERNEL_READ,
VB2_RECOVERY_RW_TPM_R_ERROR, "Read kernel rollback");
ResetMocks();
new_version = 0x20003;
test_slk(0, 0, "Roll forward");
- TEST_EQ(rkr_version, 0x20003, " version");
+ TEST_EQ(kernel_version, 0x20003, " version");
ResetMocks();
- vb2_nv_set(&ctx_nvram_backend, VB2_NV_FW_RESULT, VB2_FW_RESULT_TRYING);
+ vb2_nv_set(ctx, VB2_NV_FW_RESULT, VB2_FW_RESULT_TRYING);
new_version = 0x20003;
test_slk(0, 0, "Don't roll forward kernel when trying new FW");
- TEST_EQ(rkr_version, 0x10002, " version");
+ TEST_EQ(kernel_version, 0x10002, " version");
ResetMocks();
- vb2_nv_set(&ctx_nvram_backend, VB2_NV_KERNEL_MAX_ROLLFORWARD, 0x30005);
+ vb2_nv_set(ctx, VB2_NV_KERNEL_MAX_ROLLFORWARD, 0x30005);
new_version = 0x40006;
test_slk(0, 0, "Limit max roll forward");
- TEST_EQ(rkr_version, 0x30005, " version");
+ TEST_EQ(kernel_version, 0x30005, " version");
ResetMocks();
- vb2_nv_set(&ctx_nvram_backend, VB2_NV_KERNEL_MAX_ROLLFORWARD, 0x10001);
+ vb2_nv_set(ctx, VB2_NV_KERNEL_MAX_ROLLFORWARD, 0x10001);
new_version = 0x40006;
test_slk(0, 0, "Max roll forward can't rollback");
- TEST_EQ(rkr_version, 0x10002, " version");
+ TEST_EQ(kernel_version, 0x10002, " version");
+
ResetMocks();
new_version = 0x20003;
- rkw_retval = 123;
- test_slk(VBERROR_TPM_WRITE_KERNEL,
+ kernel_write_retval = 123;
+ test_slk(VB2_ERROR_SECDATA_KERNEL_WRITE,
VB2_RECOVERY_RW_TPM_W_ERROR, "Write kernel rollback");
ResetMocks();
- rkl_retval = 123;
- test_slk(VBERROR_TPM_LOCK_KERNEL,
+ kernel_lock_retval = 123;
+ test_slk(VB2_ERROR_SECDATA_KERNEL_LOCK,
VB2_RECOVERY_RW_TPM_L_ERROR, "Lock kernel rollback");
/* Boot normal */
@@ -253,12 +274,14 @@ static void VbSlkTest(void)
if (DIAGNOSTIC_UI) {
ResetMocks();
mock_switches[1] = VB_SWITCH_FLAG_PHYS_PRESENCE_PRESSED;
- vb2_nv_set(&ctx_nvram_backend, VB2_NV_DIAG_REQUEST, 1);
+ vb2_nv_set(ctx, VB2_NV_DIAG_REQUEST, 1);
vbboot_retval = -4;
test_slk(VB2_ERROR_MOCK, 0,
"Normal boot with diag");
- TEST_EQ(vb2_nv_get(&ctx_nvram_backend, VB2_NV_DIAG_REQUEST),
+ TEST_EQ(vb2_nv_get(ctx, VB2_NV_DIAG_REQUEST),
0, " diag not requested");
+ TEST_TRUE(commit_data_called,
+ " didn't commit nvdata");
}
/* Boot dev */
@@ -271,7 +294,7 @@ static void VbSlkTest(void)
shared->flags |= VBSD_BOOT_DEV_SWITCH_ON;
new_version = 0x20003;
test_slk(0, 0, "Dev doesn't roll forward");
- TEST_EQ(rkr_version, 0x10002, " version");
+ TEST_EQ(kernel_version, 0x10002, " version");
/* Boot recovery */
ResetMocks();
@@ -283,11 +306,13 @@ static void VbSlkTest(void)
shared->recovery_reason = 123;
new_version = 0x20003;
test_slk(0, 0, "Recovery doesn't roll forward");
- TEST_EQ(rkr_version, 0x10002, " version");
+ TEST_EQ(kernel_version, 0x10002, " version");
ResetMocks();
shared->recovery_reason = 123;
- rkr_retval = rkw_retval = rkl_retval = VB2_ERROR_MOCK;
+ kernel_read_retval = TPM_E_IOERROR;
+ kernel_write_retval = TPM_E_IOERROR;
+ kernel_lock_retval = TPM_E_IOERROR;
test_slk(0, 0, "Recovery ignore TPM errors");
ResetMocks();
diff --git a/tests/vboot_detach_menu_tests.c b/tests/vboot_detach_menu_tests.c
index f0440cfb..d85acbc6 100644
--- a/tests/vboot_detach_menu_tests.c
+++ b/tests/vboot_detach_menu_tests.c
@@ -9,6 +9,7 @@
#include "2misc.h"
#include "2nvstorage.h"
#include "2secdata.h"
+#include "2secdata_struct.h"
#include "host_common.h"
#include "load_kernel_fw.h"
#include "secdata_tpm.h"
@@ -32,6 +33,7 @@ static uint8_t workbuf[VB2_KERNEL_WORKBUF_RECOMMENDED_SIZE]
static struct vb2_context *ctx;
static struct vb2_shared_data *sd;
static struct vb2_gbb_header gbb;
+static struct vb2_secdata_fwmp *fwmp;
static int shutdown_request_calls_left;
static int audio_looping_calls_left;
@@ -61,8 +63,6 @@ static int vbexaltfwmask_called;
/* Reset mock data (for use before each test) */
static void ResetMocks(void)
{
- memset(VbApiKernelGetFwmp(), 0, sizeof(struct RollbackSpaceFwmp));
-
memset(&shared_data, 0, sizeof(shared_data));
VbSharedDataInit(shared, sizeof(shared_data));
shared->flags = VBSD_BOOT_FIRMWARE_VBOOT2;
@@ -76,6 +76,10 @@ static void ResetMocks(void)
sd = vb2_get_sd(ctx);
sd->vbsd = shared;
+ /* CRC will be invalid after here, but nobody's checking */
+ sd->status |= VB2_SD_STATUS_SECDATA_FWMP_INIT;
+ fwmp = (struct vb2_secdata_fwmp *)ctx->secdata_fwmp;
+
memset(&gbb, 0, sizeof(gbb));
/* In recovery we have 50 keyscans per disk scan, this must be high. */
@@ -124,7 +128,8 @@ static void ResetMocksForManualRecovery(void)
}
/* Mock functions */
-uint32_t RollbackKernelLock(int recovery_mode)
+
+uint32_t secdata_kernel_lock(struct vb2_context *c)
{
return TPM_SUCCESS;
}
@@ -252,9 +257,9 @@ vb2_error_t VbExBeep(uint32_t msec, uint32_t frequency)
return VB2_SUCCESS;
}
-vb2_error_t SetVirtualDevMode(int val)
+vb2_error_t vb2_enable_developer_mode(struct vb2_context *c)
{
- virtdev_set = val;
+ virtdev_set = 1;
return virtdev_retval;
}
@@ -665,7 +670,7 @@ static void VbBootDevTest(void)
/* Ctrl+L boots legacy if enabled by FWMP */
ResetMocksForDeveloper();
- VbApiKernelGetFwmp()->flags |= FWMP_DEV_ENABLE_LEGACY;
+ fwmp->flags |= VB2_SECDATA_FWMP_DEV_ENABLE_LEGACY;
mock_keypress[0] = VB_KEY_CTRL('L');
mock_keypress[1] = VB_BUTTON_POWER_SHORT_PRESS;
TEST_EQ(VbBootDeveloperMenu(ctx), vbtlk_retval_fixed,
@@ -755,7 +760,7 @@ static void VbBootDevTest(void)
/* Ctrl+U enabled via FWMP */
ResetMocksForDeveloper();
- VbApiKernelGetFwmp()->flags |= FWMP_DEV_ENABLE_USB;
+ fwmp->flags |= VB2_SECDATA_FWMP_DEV_ENABLE_USB;
mock_keypress[0] = VB_KEY_CTRL('U');
vbtlk_retval[0] = VB2_SUCCESS - VB_DISK_FLAG_REMOVABLE;
TEST_EQ(VbBootDeveloperMenu(ctx), VB2_SUCCESS, "Ctrl+U force USB");
@@ -1148,7 +1153,7 @@ static void VbBootDevTest(void)
/* If dev mode is disabled, goes to TONORM screen repeatedly */
ResetMocksForDeveloper();
- VbApiKernelGetFwmp()->flags |= FWMP_DEV_DISABLE_BOOT;
+ fwmp->flags |= VB2_SECDATA_FWMP_DEV_DISABLE_BOOT;
audio_looping_calls_left = 1; /* Confirm audio doesn't tick down. */
i = 0;
mock_keypress[i++] = VB_KEY_CTRL('D'); /* Just stays on TONORM and flashes */
@@ -1202,7 +1207,7 @@ static void VbBootDevTest(void)
/* Shutdown requested when dev disabled */
ResetMocksForDeveloper();
- VbApiKernelGetFwmp()->flags |= FWMP_DEV_DISABLE_BOOT;
+ fwmp->flags |= VB2_SECDATA_FWMP_DEV_DISABLE_BOOT;
shutdown_request_calls_left = 1;
TEST_EQ(VbBootDeveloperMenu(ctx), VBERROR_SHUTDOWN_REQUESTED,
"Shutdown requested when dev disabled");
@@ -1218,7 +1223,7 @@ static void VbBootDevTest(void)
/* Explicit Power Off when dev disabled */
ResetMocksForDeveloper();
- VbApiKernelGetFwmp()->flags |= FWMP_DEV_DISABLE_BOOT;
+ fwmp->flags |= VB2_SECDATA_FWMP_DEV_DISABLE_BOOT;
i = 0;
mock_keypress[i++] = VB_BUTTON_VOL_DOWN_SHORT_PRESS; // Power Off
mock_keypress[i++] = VB_BUTTON_POWER_SHORT_PRESS;
diff --git a/tests/vboot_display_tests.c b/tests/vboot_display_tests.c
index 58ccda07..7565a196 100644
--- a/tests/vboot_display_tests.c
+++ b/tests/vboot_display_tests.c
@@ -16,6 +16,7 @@
#include "2struct.h"
#include "2sysincludes.h"
#include "host_common.h"
+#include "secdata_tpm.h"
#include "test_common.h"
#include "vboot_common.h"
#include "vboot_display.h"
@@ -72,6 +73,11 @@ vb2_error_t VbExDisplayDebugInfo(const char *info_str, int full_info)
return VB2_SUCCESS;
}
+vb2_error_t vb2_commit_data(struct vb2_context *c)
+{
+ return VB2_SUCCESS;
+}
+
/* Test displaying debug info */
static void DebugInfoTest(void)
{
diff --git a/tests/vboot_kernel_tests.c b/tests/vboot_kernel_tests.c
index b43a2acd..86afcb8d 100644
--- a/tests/vboot_kernel_tests.c
+++ b/tests/vboot_kernel_tests.c
@@ -63,7 +63,7 @@ static VbSharedDataHeader *shared = (VbSharedDataHeader *)shared_data;
static LoadKernelParams lkp;
static struct vb2_keyblock kbh;
static VbKernelPreambleHeader kph;
-static struct RollbackSpaceFwmp fwmp;
+static struct vb2_secdata_fwmp *fwmp;
static uint8_t mock_disk[MOCK_SECTOR_SIZE * MOCK_SECTOR_COUNT];
static GptHeader *mock_gpt_primary =
(GptHeader*)&mock_disk[MOCK_SECTOR_SIZE * 1];
@@ -164,9 +164,6 @@ static void ResetMocks(void)
kph.bootloader_address = 0xbeadd008;
kph.bootloader_size = 0x1234;
- memset(&fwmp, 0, sizeof(fwmp));
- memcpy(fwmp.dev_key_hash, mock_digest, sizeof(fwmp.dev_key_hash));
-
memset(mock_parts, 0, sizeof(mock_parts));
mock_parts[0].start = 100;
mock_parts[0].size = 150; /* 75 KB */
@@ -181,6 +178,11 @@ static void ResetMocks(void)
struct vb2_shared_data *sd = vb2_get_sd(ctx);
sd->vbsd = shared;
+ /* CRC will be invalid after here, but nobody's checking */
+ sd->status |= VB2_SD_STATUS_SECDATA_FWMP_INIT;
+ fwmp = (struct vb2_secdata_fwmp *)ctx->secdata_fwmp;
+ memcpy(&fwmp->dev_key_hash, mock_digest, sizeof(fwmp->dev_key_hash));
+
// TODO: more workbuf fields - flags, secdata_firmware, secdata_kernel
}
@@ -670,8 +672,7 @@ static void LoadKernelTest(void)
ResetMocks();
ctx->flags |= VB2_CONTEXT_DEVELOPER_MODE;
- lkp.fwmp = &fwmp;
- fwmp.flags |= FWMP_DEV_ENABLE_OFFICIAL_ONLY;
+ fwmp->flags |= VB2_SECDATA_FWMP_DEV_ENABLE_OFFICIAL_ONLY;
keyblock_verify_fail = 1;
TestLoadKernel(VBERROR_INVALID_KERNEL_FOUND,
"Fail keyblock dev sig fwmp");
@@ -761,17 +762,15 @@ static void LoadKernelTest(void)
/* Check developer key hash - bad */
ResetMocks();
ctx->flags |= VB2_CONTEXT_DEVELOPER_MODE;
- lkp.fwmp = &fwmp;
- fwmp.flags |= FWMP_DEV_USE_KEY_HASH;
- fwmp.dev_key_hash[0]++;
+ fwmp->flags |= VB2_SECDATA_FWMP_DEV_USE_KEY_HASH;
+ fwmp->dev_key_hash[0]++;
TestLoadKernel(VBERROR_INVALID_KERNEL_FOUND,
"Fail keyblock dev fwmp hash");
/* Check developer key hash - good */
ResetMocks();
ctx->flags |= VB2_CONTEXT_DEVELOPER_MODE;
- lkp.fwmp = &fwmp;
- fwmp.flags |= FWMP_DEV_USE_KEY_HASH;
+ fwmp->flags |= VB2_SECDATA_FWMP_DEV_USE_KEY_HASH;
TestLoadKernel(0, "Good keyblock dev fwmp hash");
ResetMocks();