summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--common/build.mk1
-rw-r--r--common/host_command.c3
-rw-r--r--common/vstore.c127
-rw-r--r--include/config.h6
-rw-r--r--include/ec_commands.h46
5 files changed, 183 insertions, 0 deletions
diff --git a/common/build.mk b/common/build.mk
index 01b0868917..311cf3508b 100644
--- a/common/build.mk
+++ b/common/build.mk
@@ -86,6 +86,7 @@ common-$(CONFIG_USB_POWER_DELIVERY)+=usb_pd_protocol.o usb_pd_policy.o
common-$(CONFIG_USB_PD_LOGGING)+=pd_log.o
common-$(CONFIG_USB_PD_TCPC)+=usb_pd_tcpc.o
common-$(CONFIG_VBOOT_HASH)+=sha256.o vboot_hash.o
+common-$(CONFIG_VSTORE)+=vstore.o
common-$(CONFIG_WIRELESS)+=wireless.o
common-$(HAS_TASK_BLOB)+=blob.o
common-$(HAS_TASK_CHIPSET)+=chipset.o
diff --git a/common/host_command.c b/common/host_command.c
index 40b4efd4af..0dae3bf036 100644
--- a/common/host_command.c
+++ b/common/host_command.c
@@ -751,6 +751,9 @@ static int host_command_get_features(struct host_cmd_handler_args *args)
#ifdef CONFIG_ACCEL_FIFO
| EC_FEATURE_MASK_0(EC_FEATURE_MOTION_SENSE_FIFO)
#endif
+#ifdef CONFIG_VSTORE
+ | EC_FEATURE_MASK_0(EC_FEATURE_VSTORE)
+#endif
;
return EC_RES_SUCCESS;
}
diff --git a/common/vstore.c b/common/vstore.c
new file mode 100644
index 0000000000..a2d81ba9a5
--- /dev/null
+++ b/common/vstore.c
@@ -0,0 +1,127 @@
+/* Copyright 2015 The Chromium OS Authors. All rights reserved.
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+/*
+ * Temporary secure storage commands for use by the host for verified boot
+ * related activities such as storing the hash of verified firmware for use
+ * in suspend/resume.
+ *
+ * There are a configurable number of vstore slots, with all slots having
+ * the same size of EC_VSTORE_SLOT_SIZE (64 bytes).
+ *
+ * Slots can be written once per AP power-on and will then be locked and
+ * cannot be written again until it is cleared in the CHIPSET_SHUTDOWN
+ * or CHIPSET_RESET hooks.
+ */
+
+#include "common.h"
+#include "hooks.h"
+#include "host_command.h"
+#include "system.h"
+#include "util.h"
+
+#define VSTORE_SYSJUMP_TAG 0x5653 /* "VS" */
+#define VSTORE_HOOK_VERSION 1
+
+struct vstore_slot {
+ uint8_t locked;
+ uint8_t data[EC_VSTORE_SLOT_SIZE];
+};
+
+static struct vstore_slot vstore_slots[CONFIG_VSTORE_SLOT_COUNT];
+static const int vstore_size =
+ sizeof(struct vstore_slot) * CONFIG_VSTORE_SLOT_COUNT;
+BUILD_ASSERT(ARRAY_SIZE(vstore_slots) <= EC_VSTORE_SLOT_MAX);
+
+/*
+ * vstore_info - Get slot count and mask of locked slots.
+ */
+static int vstore_info(struct host_cmd_handler_args *args)
+{
+ struct ec_response_vstore_info *r = args->response;
+ int i;
+
+ r->slot_count = CONFIG_VSTORE_SLOT_COUNT;
+ r->slot_locked = 0;
+ for (i = 0; i < CONFIG_VSTORE_SLOT_COUNT; i++)
+ if (vstore_slots[i].locked)
+ r->slot_locked |= 1 << i;
+
+ args->response_size = sizeof(*r);
+
+ return EC_RES_SUCCESS;
+}
+DECLARE_HOST_COMMAND(EC_CMD_VSTORE_INFO, vstore_info, EC_VER_MASK(0));
+
+/*
+ * vstore_read - Read slot from temporary secure storage.
+ *
+ * Response is EC_VSTORE_SLOT_SIZE bytes of data.
+ */
+static int vstore_read(struct host_cmd_handler_args *args)
+{
+ const struct ec_params_vstore_read *p = args->params;
+ struct ec_response_vstore_read *r = args->response;
+
+ if (p->slot >= CONFIG_VSTORE_SLOT_COUNT)
+ return EC_RES_INVALID_PARAM;
+
+ memcpy(r->data, vstore_slots[p->slot].data, EC_VSTORE_SLOT_SIZE);
+
+ args->response_size = sizeof(*r);
+
+ return EC_RES_SUCCESS;
+}
+DECLARE_HOST_COMMAND(EC_CMD_VSTORE_READ, vstore_read, EC_VER_MASK(0));
+
+/*
+ * vstore_write - Write temporary secure storage slot and lock it.
+ */
+static int vstore_write(struct host_cmd_handler_args *args)
+{
+ const struct ec_params_vstore_write *p = args->params;
+ struct vstore_slot *slot;
+
+ if (p->slot >= CONFIG_VSTORE_SLOT_COUNT)
+ return EC_RES_INVALID_PARAM;
+ slot = &vstore_slots[p->slot];
+
+ if (slot->locked)
+ return EC_RES_ACCESS_DENIED;
+ slot->locked = 1;
+ memcpy(slot->data, p->data, EC_VSTORE_SLOT_SIZE);
+
+ return EC_RES_SUCCESS;
+}
+DECLARE_HOST_COMMAND(EC_CMD_VSTORE_WRITE, vstore_write, EC_VER_MASK(0));
+
+static void vstore_clear_lock(void)
+{
+ int i;
+
+ for (i = 0; i < CONFIG_VSTORE_SLOT_COUNT; i++)
+ vstore_slots[i].locked = 0;
+}
+DECLARE_HOOK(HOOK_CHIPSET_RESET, vstore_clear_lock, HOOK_PRIO_DEFAULT);
+
+static void vstore_preserve_state(void)
+{
+ system_add_jump_tag(VSTORE_SYSJUMP_TAG, VSTORE_HOOK_VERSION,
+ vstore_size, vstore_slots);
+}
+DECLARE_HOOK(HOOK_SYSJUMP, vstore_preserve_state, HOOK_PRIO_DEFAULT);
+
+static void vstore_init(void)
+{
+ const struct vstore_slot *prev;
+ int version, size;
+
+ prev = (const struct vstore_slot *)system_get_jump_tag(
+ VSTORE_SYSJUMP_TAG, &version, &size);
+
+ if (prev && version == VSTORE_HOOK_VERSION && size == vstore_size)
+ memcpy(vstore_slots, prev, vstore_size);
+}
+DECLARE_HOOK(HOOK_INIT, vstore_init, HOOK_PRIO_DEFAULT);
diff --git a/include/config.h b/include/config.h
index fba68c1c0e..b98f940f61 100644
--- a/include/config.h
+++ b/include/config.h
@@ -1983,6 +1983,12 @@
/* Support computing hash of code for verified boot */
#undef CONFIG_VBOOT_HASH
+/* Support for secure temporary storage for verified boot */
+#undef CONFIG_VSTORE
+
+/* Number of supported slots for secure temporary storage */
+#undef CONFIG_VSTORE_SLOT_COUNT
+
/*****************************************************************************/
/* Watchdog config */
diff --git a/include/ec_commands.h b/include/ec_commands.h
index 7901745e9e..9434a5df45 100644
--- a/include/ec_commands.h
+++ b/include/ec_commands.h
@@ -942,6 +942,8 @@ enum ec_feature_code {
EC_FEATURE_USB_MUX = 23,
/* Motion Sensor code has an internal software FIFO */
EC_FEATURE_MOTION_SENSE_FIFO = 24,
+ /* Support temporary secure vstore */
+ EC_FEATURE_VSTORE = 25,
};
#define EC_FEATURE_MASK_0(event_code) (1UL << (event_code % 32))
@@ -2123,6 +2125,50 @@ struct ec_response_port80_last_boot {
} __packed;
/*****************************************************************************/
+/* Temporary secure storage for host verified boot use */
+
+/* Number of bytes in a vstore slot */
+#define EC_VSTORE_SLOT_SIZE 64
+
+/* Maximum number of vstore slots */
+#define EC_VSTORE_SLOT_MAX 32
+
+/* Get persistent storage info */
+#define EC_CMD_VSTORE_INFO 0x49
+
+struct ec_response_vstore_info {
+ /* Indicates which slots are locked */
+ uint32_t slot_locked;
+ /* Total number of slots available */
+ uint8_t slot_count;
+} __packed;
+
+/*
+ * Read temporary secure storage
+ *
+ * Response is EC_VSTORE_SLOT_SIZE bytes of data.
+ */
+#define EC_CMD_VSTORE_READ 0x4a
+
+struct ec_params_vstore_read {
+ uint8_t slot; /* Slot to read from */
+} __packed;
+
+struct ec_response_vstore_read {
+ uint8_t data[EC_VSTORE_SLOT_SIZE];
+} __packed;
+
+/*
+ * Write temporary secure storage and lock it.
+ */
+#define EC_CMD_VSTORE_WRITE 0x4b
+
+struct ec_params_vstore_write {
+ uint8_t slot; /* Slot to write to */
+ uint8_t data[EC_VSTORE_SLOT_SIZE];
+} __packed;
+
+/*****************************************************************************/
/* Thermal engine commands. Note that there are two implementations. We'll
* reuse the command number, but the data and behavior is incompatible.
* Version 0 is what originally shipped on Link.