summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAaron Durbin <adurbin@chromium.org>2016-01-22 14:42:54 -0600
committerPatrick Georgi <pgeorgi@google.com>2016-02-04 17:34:58 +0100
commit49b2383ddb14f479cd2a5d1e01b1378810e8108e (patch)
tree7be063a24b7fa0a32d84c05e2a95507c70089a22
parentf55e7ddbd6635c89f9da020a3874d6722c32626c (diff)
google/chromeec: implement vboot_(save|retrieve)_hash API
For x86 systems which resume through the reset vector one needs to ensure the the RW slot taken at resume time matches the one at boot time. To that end, allow Chrome OS EC to supply the plumbing to vboot for storing and retrieving the RW slots' hash digest using the vstore backend. BUG=chrome-os-partner:46049 BRANCH=glados TEST=Suspended and resumed on chell. Also, tested with an EC build which returns a bad hash to ensure that is properly caught. Change-Id: Ib056f7e6b3386447ed1ff95c740ef5b4544f9049 Signed-off-by: Patrick Georgi <pgeorgi@chromium.org> Original-Commit-Id: 9c78546b1d6298a4c397a587c564df6d9d097e75 Original-Change-Id: I86c96a4092deab2dfa51b3043b9dba16b6a4c201 Original-Signed-off-by: Aaron Durbin <adurbin@chromium.org> Original-Reviewed-on: https://chromium-review.googlesource.com/323502 Original-Reviewed-by: Patrick Georgi <pgeorgi@chromium.org> Original-Reviewed-by: Duncan Laurie <dlaurie@chromium.org> Reviewed-on: https://review.coreboot.org/13577 Tested-by: build bot (Jenkins) Reviewed-by: Stefan Reinauer <stefan.reinauer@coreboot.org>
-rw-r--r--src/ec/google/chromeec/Makefile.inc5
-rw-r--r--src/ec/google/chromeec/vboot_storage.c62
2 files changed, 67 insertions, 0 deletions
diff --git a/src/ec/google/chromeec/Makefile.inc b/src/ec/google/chromeec/Makefile.inc
index 59758ca87c..ad9de9e2a5 100644
--- a/src/ec/google/chromeec/Makefile.inc
+++ b/src/ec/google/chromeec/Makefile.inc
@@ -21,4 +21,9 @@ verstage-$(CONFIG_EC_GOOGLE_CHROMEEC_LPC) += ec_lpc.c
verstage-$(CONFIG_EC_GOOGLE_CHROMEEC_MEC) += ec_mec.c
verstage-$(CONFIG_EC_GOOGLE_CHROMEEC_SPI) += ec_spi.c
+ramstage-$(CONFIG_VBOOT_VERIFY_FIRMWARE) += vboot_storage.c
+smm-$(CONFIG_VBOOT_VERIFY_FIRMWARE) += vboot_storage.c
+romstage-$(CONFIG_VBOOT_VERIFY_FIRMWARE) += vboot_storage.c
+verstage-$(CONFIG_VBOOT_VERIFY_FIRMWARE) += vboot_storage.c
+
endif
diff --git a/src/ec/google/chromeec/vboot_storage.c b/src/ec/google/chromeec/vboot_storage.c
new file mode 100644
index 0000000000..f47c2f14e9
--- /dev/null
+++ b/src/ec/google/chromeec/vboot_storage.c
@@ -0,0 +1,62 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright 2016 Google Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+#include <assert.h>
+#include <console/console.h>
+#include <ec/google/chromeec/ec.h>
+#include <vendorcode/google/chromeos/chromeos.h>
+
+#define VBOOT_HASH_VSLOT 0
+#define VBOOT_HASH_VSLOT_MASK (1 << (VBOOT_HASH_VSLOT))
+
+int vboot_save_hash(void *digest, size_t digest_size)
+{
+ const int slot = VBOOT_HASH_VSLOT;
+ uint32_t lock_status;
+ int num_slots;
+
+ /* Ensure the digests being saved match the EC's slot size. */
+ assert(digest_size == EC_VSTORE_SLOT_SIZE);
+
+ if (google_chromeec_vstore_write(slot, digest, digest_size))
+ return -1;
+
+ /* Assert the slot is locked on successful write. */
+ num_slots = google_chromeec_vstore_info(&lock_status);
+
+ /* Normalize to be 0 based. If num_slots returned 0 then it'll be -1. */
+ num_slots--;
+
+ if (num_slots < slot) {
+ printk(BIOS_ERR, "Not enough vstore slots for vboot hash: %d\n",
+ num_slots + 1);
+ return -1;
+ }
+
+ if ((lock_status & VBOOT_HASH_VSLOT_MASK) == 0) {
+ printk(BIOS_ERR, "Vstore slot not locked after write.\n");
+ return -1;
+ }
+
+ return 0;
+}
+
+int vboot_retrieve_hash(void *digest, size_t digest_size)
+{
+ /* Ensure the digests being saved match the EC's slot size. */
+ assert(digest_size == EC_VSTORE_SLOT_SIZE);
+
+ return google_chromeec_vstore_read(VBOOT_HASH_VSLOT, digest);
+}