diff options
author | Aaron Durbin <adurbin@chromium.org> | 2016-01-22 14:42:54 -0600 |
---|---|---|
committer | Patrick Georgi <pgeorgi@google.com> | 2016-02-04 17:34:58 +0100 |
commit | 49b2383ddb14f479cd2a5d1e01b1378810e8108e (patch) | |
tree | 7be063a24b7fa0a32d84c05e2a95507c70089a22 /src/ec | |
parent | f55e7ddbd6635c89f9da020a3874d6722c32626c (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>
Diffstat (limited to 'src/ec')
-rw-r--r-- | src/ec/google/chromeec/Makefile.inc | 5 | ||||
-rw-r--r-- | src/ec/google/chromeec/vboot_storage.c | 62 |
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); +} |