summaryrefslogtreecommitdiff
path: root/include
diff options
context:
space:
mode:
authorDaisuke Nojiri <dnojiri@chromium.org>2019-10-21 10:07:48 -0700
committerCommit Bot <commit-bot@chromium.org>2020-02-09 08:31:43 +0000
commit37151225f4d791204a75173eec64ebfdaf2cbdec (patch)
treea9680e1fd0897c1ea6e0461055760c42944fdee7 /include
parenta4f7c8ef7c0b9b3206f67299414c2cbd2a5fe84a (diff)
downloadchrome-ec-37151225f4d791204a75173eec64ebfdaf2cbdec.tar.gz
EFS2: Implement Early Firmware Selection ver.2
EFS v1 allowed Chromeboxes to verify RW without AP. EFS v2 will bring the benefts to Chromebooks, which are: - Reduce RO dependency and presence. Allow more code to be updated in the fields. - Remove jumptag and workarounds needed for late sysjump. Major imporvements over v1 are: - No A/B slot required. - No signature in RW or public key in RO. - Rollback-attack protection. - Verifies only RW being used instead of whole RW section. For battery-equipped devices, additional benefts are: - Immediate boot on drained battery. - Support recovery mode regardless of battery condition. - Faster charge in S5/G3. EC-Cr50 communication is based on the shared UART (go/ec-cr50-comm). EFS2 is documented in go/ec-efs2. Signed-off-by: Daisuke Nojiri <dnojiri@chromium.org> BUG=chromium:1045217,chromium:141143112 BRANCH=none TEST=Boot Helios in NORMAL/NO_BOOT/NO_BOOT_RECOVERY/RECOVERY mode. TEST=Wake up EC from hibernate. TEST=Make EC assert PACKET_MODE to wake up Cr50 from deepsleep. Change-Id: I98a4fe1ecc59d106810a75daec3c424f953ff880 Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/ec/+/2015357 Reviewed-by: Daisuke Nojiri <dnojiri@chromium.org> Commit-Queue: Daisuke Nojiri <dnojiri@chromium.org> Tested-by: Daisuke Nojiri <dnojiri@chromium.org> Auto-Submit: Daisuke Nojiri <dnojiri@chromium.org>
Diffstat (limited to 'include')
-rw-r--r--include/config.h8
-rw-r--r--include/vboot.h116
-rw-r--r--include/vboot_hash.h17
3 files changed, 140 insertions, 1 deletions
diff --git a/include/config.h b/include/config.h
index fcd8978840..591235ec43 100644
--- a/include/config.h
+++ b/include/config.h
@@ -4335,8 +4335,14 @@
/*****************************************************************************/
-/* Support early firmware selection */
+/*
+ * Support early firmware selection
+ *
+ * EFS1 is being deprecated. EFS2 is faster, doesn't need two slots, and
+ * supports rollback protection.
+ */
#undef CONFIG_VBOOT_EFS
+#undef CONFIG_VBOOT_EFS2
/* Offset of RW-A image in writable storage when using EFS. */
#undef CONFIG_RW_A_STORAGE_OFF
diff --git a/include/vboot.h b/include/vboot.h
index 776cc16441..771aeda599 100644
--- a/include/vboot.h
+++ b/include/vboot.h
@@ -3,9 +3,15 @@
* found in the LICENSE file.
*/
+#ifndef __CROS_EC_INCLUDE_VBOOT_H
+#define __CROS_EC_INCLUDE_VBOOT_H
+
#include "common.h"
#include "vb21_struct.h"
#include "rsa.h"
+#include "sha256.h"
+#include "stdbool.h"
+#include "timer.h"
/**
* Validate key contents.
@@ -66,3 +72,113 @@ void vboot_main(void);
* @return 1: need PD communication. 0: PD communication is not needed.
*/
int vboot_need_pd_comm(void);
+
+/**
+ * Callback for boards to notify users of vboot error when no display is
+ * available.
+ *
+ * Typically this happens when a Chromebox is booting on a Type-C adapter and
+ * EFS failed.
+ */
+__override_proto void show_critical_error(void);
+
+/**
+ * Callback for boards to notify the user of power shortage.
+ */
+__override_proto void show_power_shortage(void);
+
+/**
+ * Interrupt handler for packet mode entry.
+ *
+ * @param signal GPIO id for packet mode interrupt pin.
+ */
+void packet_mode_interrupt(enum gpio_signal signal);
+
+/* Maximum number of times EC retries packet transmission before giving up. */
+#define CR50_COMM_MAX_RETRY 5
+
+/* EC's timeout for packet transmission to Cr50. */
+#define CR50_COMM_TIMEOUT (50 * MSEC)
+
+/* Preamble character repeated before the packet header starts. */
+#define CR50_COMM_PREAMBLE 0xec
+
+/* Magic characters used to identify ec-cr50-comm packets */
+#define CR50_PACKET_MAGIC 0x4345 /* 'EC' in little endian */
+
+/* version of struct cr50_comm_request */
+#define CR50_COMM_PACKET_VERSION (0 << 4 | 0 << 0) /* 0.0 */
+
+/**
+ * EC-Cr50 data frame looks like the following:
+ *
+ * [preamble][header][payload]
+ *
+ * preamble: 0xec ...
+ * header: struct cr50_comm_request
+ * payload: data[]
+ */
+struct cr50_comm_request {
+ /* Header */
+ uint16_t magic; /* CR50_PACKET_MAGIC */
+ uint8_t struct_version; /* version of this struct msb:lsb=major:minor */
+ uint8_t crc; /* checksum computed from all bytes after crc */
+ uint16_t type; /* CR50_CMD_* */
+ uint8_t size; /* Payload size. Be easy on Cr50 buffer. */
+ /* Payload */
+ uint8_t data[];
+} __packed;
+
+struct cr50_comm_response {
+ uint16_t error;
+} __packed;
+
+#define CR50_COMM_MAX_REQUEST_SIZE (sizeof(struct cr50_comm_request) \
+ + UINT8_MAX)
+#define CR50_UART_RX_BUFFER_SIZE 32 /* TODO: Get from Cr50 header */
+
+/* commands */
+enum cr50_comm_cmd {
+ CR50_COMM_CMD_HELLO = 0x0000,
+ CR50_COMM_CMD_SET_BOOT_MODE = 0x0001,
+ CR50_COMM_CMD_VERIFY_HASH = 0x0002,
+ CR50_COMM_CMD_LIMIT = 0xffff,
+} __packed;
+BUILD_ASSERT(sizeof(enum cr50_comm_cmd) == sizeof(uint16_t));
+
+#define CR50_COMM_ERR_PREFIX 0xec
+
+/* return code */
+enum cr50_comm_err {
+ CR50_COMM_SUCCESS = 0xec00,
+ CR50_COMM_ERR_UNKNOWN = 0xec01,
+ CR50_COMM_ERR_MAGIC = 0xec02,
+ CR50_COMM_ERR_CRC = 0xec03,
+ CR50_COMM_ERR_SIZE = 0xec04,
+ CR50_COMM_ERR_TIMEOUT = 0xec05, /* Generated by EC */
+ CR50_COMM_ERR_BAD_PAYLOAD = 0xec06,
+ CR50_COMM_ERR_UNDEFINED_CMD = 0xec07,
+ CR50_COMM_ERR_STRUCT_VERSION = 0xec08,
+} __packed;
+BUILD_ASSERT(sizeof(enum cr50_comm_err) == sizeof(uint16_t));
+
+/*
+ * BIT(1) : NO_BOOT flag
+ * BIT(0) : RECOVERY flag
+ */
+enum boot_mode {
+ BOOT_MODE_NORMAL = 0x00,
+ BOOT_MODE_NO_BOOT = 0x01,
+} __packed;
+BUILD_ASSERT(sizeof(enum boot_mode) == sizeof(uint8_t));
+
+/**
+ * Indicate PD is allowed (in RO) by vboot or not.
+ *
+ * Overridden by each EFS implementation (EFS1 and EFS2) not by boards.
+ *
+ * @return true - allowed. false - disallowed.
+ */
+__override_proto bool vboot_allow_usb_pd(void);
+
+#endif /* __CROS_EC_INCLUDE_VBOOT_H */
diff --git a/include/vboot_hash.h b/include/vboot_hash.h
index 3d66a7c56d..126872393e 100644
--- a/include/vboot_hash.h
+++ b/include/vboot_hash.h
@@ -11,6 +11,23 @@
#include "common.h"
/**
+ * Get hash of RW image.
+ *
+ * Your task will be blocked until hash computation is done. Hashing can be
+ * aborted only due to internal errors (e.g. read error) but not external
+ * causes.
+ *
+ * This is expected to be called before tasks are initialized. If it's called
+ * after tasks are started, it may starve lower priority tasks.
+ *
+ * See chromium:1047870 for some optimization.
+ *
+ * @param dst (OUT) Address where computed hash is stored.
+ * @return enum ec_error_list.
+ */
+int vboot_get_rw_hash(const uint8_t **dst);
+
+/**
* Invalidate the hash if the hashed data overlaps the specified region.
*
* @param offset Region start offset in flash