Patrick Georgi (pgeorgi(a)google.com) just uploaded a new patch set to gerrit, which you can find at https://review.coreboot.org/13577
-gerrit
commit c80665a73a8fa35d6dc1757b08835ade9313aacf
Author: Aaron Durbin <adurbin(a)chromium.org>
Date: Fri Jan 22 14:42:54 2016 -0600
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(a)chromium.org>
Original-Commit-Id: 9c78546b1d6298a4c397a587c564df6d9d097e75
Original-Change-Id: I86c96a4092deab2dfa51b3043b9dba16b6a4c201
Original-Signed-off-by: Aaron Durbin <adurbin(a)chromium.org>
Original-Reviewed-on: https://chromium-review.googlesource.com/323502
Original-Reviewed-by: Patrick Georgi <pgeorgi(a)chromium.org>
Original-Reviewed-by: Duncan Laurie <dlaurie(a)chromium.org>
---
src/ec/google/chromeec/Makefile.inc | 5 +++
src/ec/google/chromeec/vboot_storage.c | 62 ++++++++++++++++++++++++++++++++++
2 files changed, 67 insertions(+)
diff --git a/src/ec/google/chromeec/Makefile.inc b/src/ec/google/chromeec/Makefile.inc
index 59758ca..ad9de9e 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 0000000..f47c2f1
--- /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);
+}
Patrick Georgi (pgeorgi(a)google.com) just uploaded a new patch set to gerrit, which you can find at https://review.coreboot.org/13575
-gerrit
commit 68fa20b4782988754f51005695a24c8ce2636e3b
Author: Aaron Durbin <adurbin(a)chromium.org>
Date: Fri Jan 22 16:33:57 2016 -0600
chromeos/vboot: allow platform to hook into vboot_reboot()
Sometimes it's necessary for the platform to perform clean up
tasks prior to reboot when employing vboot. For example, x86 systems
that resume and do vboot verification may need to clear their
sleep control register prior to doing a cold reset so that the
next boot doesn't appear to be a resume. Allow that hook by
introducing vboot_platform_prepare_reboot().
BUG=chrome-os-partner:46049
BRANCH=glados
TEST=Ensure vboot_platform_prepare_reboot() called from vboot_reboot().
Change-Id: I622c9181d9fa3048204e3df3223d5dd4b458abca
Signed-off-by: Patrick Georgi <pgeorgi(a)chromium.org>
Original-Commit-Id: f31ffc40bde002dec398fd4dd9d2ee9d65df0d7b
Original-Change-Id: I97318cec34494a7fc4b1ecf2cb22715d20e730ff
Original-Signed-off-by: Aaron Durbin <adurbin(a)chromium.org>
Original-Reviewed-on: https://chromium-review.googlesource.com/323501
Original-Reviewed-by: Patrick Georgi <pgeorgi(a)chromium.org>
Original-Reviewed-by: Duncan Laurie <dlaurie(a)chromium.org>
---
src/vendorcode/google/chromeos/vboot_common.c | 5 +++++
src/vendorcode/google/chromeos/vboot_common.h | 3 +++
2 files changed, 8 insertions(+)
diff --git a/src/vendorcode/google/chromeos/vboot_common.c b/src/vendorcode/google/chromeos/vboot_common.c
index 448aad6..eef5417 100644
--- a/src/vendorcode/google/chromeos/vboot_common.c
+++ b/src/vendorcode/google/chromeos/vboot_common.c
@@ -92,10 +92,15 @@ int vboot_recovery_reason(void)
return sd->recovery_reason;
}
+void __attribute__((weak)) vboot_platform_prepare_reboot(void)
+{
+}
+
void vboot_reboot(void)
{
if (IS_ENABLED(CONFIG_CONSOLE_CBMEM_DUMP_TO_UART))
cbmem_dump_console();
+ vboot_platform_prepare_reboot();
hard_reset();
die("failed to reboot");
}
diff --git a/src/vendorcode/google/chromeos/vboot_common.h b/src/vendorcode/google/chromeos/vboot_common.h
index a658d62..250b0e5 100644
--- a/src/vendorcode/google/chromeos/vboot_common.h
+++ b/src/vendorcode/google/chromeos/vboot_common.h
@@ -64,6 +64,9 @@ int vboot_retrieve_hash(void *digest, size_t digest_size);
*/
int vboot_platform_is_resuming(void);
+/* Allow the platform to do any clean up work when vboot requests a reboot. */
+void vboot_platform_prepare_reboot(void);
+
/* Main logic for verified boot. verstage() is the stage entry point
* while the verstage_main() is just the core logic. */
void verstage_main(void);
Patrick Georgi (pgeorgi(a)google.com) just uploaded a new patch set to gerrit, which you can find at https://review.coreboot.org/13574
-gerrit
commit f0b61625818b2aa0469f913d5df3aaeff7ded7f0
Author: Aaron Durbin <adurbin(a)chromium.org>
Date: Fri Jan 22 15:26:04 2016 -0600
chromeos/vboot: provide support for x86 memory init verification
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. The reason is that any assets pulled out of the boot
media need to match how the platform previously booted. To do
that one needs obtain the hash digest of the chosen slot, and it
needs to be saved in a secure place on the normal boot path. On
resume one needs to retrieve the hash digest back to compare it
with the chosen slot. If they don't match resuming won't be
possible.
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.
CQ-DEPEND=CL:323460
Change-Id: I90ce26813b67f46913aa4026b42d9490a564bb6c
Signed-off-by: Patrick Georgi <pgeorgi(a)chromium.org>
Original-Commit-Id: 01a42c0ecfc6d60d1d2e5e36a86781d91d5c47a9
Original-Change-Id: I6c6bdce7e06712bc06cc620a3d7a6a6250c59c95
Original-Signed-off-by: Aaron Durbin <adurbin(a)chromium.org>
Original-Reviewed-on: https://chromium-review.googlesource.com/323500
Original-Reviewed-by: Patrick Georgi <pgeorgi(a)chromium.org>
Original-Reviewed-by: Duncan Laurie <dlaurie(a)chromium.org>
---
src/Kconfig | 9 +++
.../google/chromeos/vboot2/vboot_logic.c | 70 +++++++++++++++++++++-
src/vendorcode/google/chromeos/vboot_common.h | 18 ++++++
3 files changed, 96 insertions(+), 1 deletion(-)
diff --git a/src/Kconfig b/src/Kconfig
index 3f02843..feefc91 100644
--- a/src/Kconfig
+++ b/src/Kconfig
@@ -503,6 +503,15 @@ config HAVE_ACPI_RESUME
bool
default n
+config RESUME_PATH_SAME_AS_BOOT
+ bool
+ default y if ARCH_X86
+ depends on HAVE_ACPI_RESUME
+ help
+ This option indicates that when a system resumes it takes the
+ same path as a regular boot. e.g. an x86 system runs from the
+ reset vector at 0xfffffff0 on both resume and warm/cold boot.
+
config HAVE_HARD_RESET
bool
default n
diff --git a/src/vendorcode/google/chromeos/vboot2/vboot_logic.c b/src/vendorcode/google/chromeos/vboot2/vboot_logic.c
index b72de93..0d08d6a 100644
--- a/src/vendorcode/google/chromeos/vboot2/vboot_logic.c
+++ b/src/vendorcode/google/chromeos/vboot2/vboot_logic.c
@@ -26,6 +26,9 @@
#include "../chromeos.h"
#include "misc.h"
+/* The max hash size to expect is for SHA512. */
+#define VBOOT_MAX_HASH_SIZE VB2_SHA512_DIGEST_SIZE
+
#define TODO_BLOCK_SIZE 1024
static int is_slot_a(struct vb2_context *ctx)
@@ -111,15 +114,77 @@ int vb2ex_hwcrypto_digest_finalize(uint8_t *digest, uint32_t digest_size)
return VB2_ERROR_UNKNOWN;
}
+static int handle_digest_result(void *slot_hash, size_t slot_hash_sz)
+{
+ int is_resume;
+
+ /*
+ * Nothing to do since resuming on the platform doesn't require
+ * vboot verification again.
+ */
+ if (!IS_ENABLED(CONFIG_RESUME_PATH_SAME_AS_BOOT))
+ return 0;
+
+ /*
+ * Assume that if vboot doesn't start in bootblock verified
+ * RW memory init code is not employed. i.e. memory init code
+ * lives in RO CBFS.
+ */
+ if (!IS_ENABLED(CONFIG_VBOOT_STARTS_IN_BOOTBLOCK))
+ return 0;
+
+ is_resume = vboot_platform_is_resuming();
+
+ if (is_resume > 0) {
+ uint8_t saved_hash[VBOOT_MAX_HASH_SIZE];
+ const size_t saved_hash_sz = sizeof(saved_hash);
+
+ assert(slot_hash_sz == saved_hash_sz);
+
+ printk(BIOS_DEBUG, "Platform is resuming.\n");
+
+ if (vboot_retrieve_hash(saved_hash, saved_hash_sz)) {
+ printk(BIOS_ERR, "Couldn't retrieve saved hash.\n");
+ return -1;
+ }
+
+ if (memcmp(saved_hash, slot_hash, slot_hash_sz)) {
+ printk(BIOS_ERR, "Hash mismatch on resume.\n");
+ return -1;
+ }
+ } else if (is_resume < 0)
+ printk(BIOS_ERR, "Unable to determine if platform resuming.\n");
+
+ printk(BIOS_DEBUG, "Saving vboot hash.\n");
+
+ /* Always save the hash for the current boot. */
+ if (vboot_save_hash(slot_hash, slot_hash_sz)) {
+ printk(BIOS_ERR, "Error saving vboot hash.\n");
+ /* Though this is an error don't report it up since it could
+ * lead to a reboot loop. The consequence of this is that
+ * we will most likely fail resuming because of EC issues or
+ * the hash digest not matching. */
+ return 0;
+ }
+
+ return 0;
+}
+
static int hash_body(struct vb2_context *ctx, struct region_device *fw_main)
{
uint64_t load_ts;
uint32_t expected_size;
uint8_t block[TODO_BLOCK_SIZE];
+ uint8_t hash_digest[VBOOT_MAX_HASH_SIZE];
+ const size_t hash_digest_sz = sizeof(hash_digest);
size_t block_size = sizeof(block);
size_t offset;
int rv;
+ /* Clear the full digest so that any hash digests less than the
+ * max have trailing zeros. */
+ memset(hash_digest, 0, hash_digest_sz);
+
/*
* Since loading the firmware and calculating its hash is intertwined,
* we use this little trick to measure them separately and pretend it
@@ -160,12 +225,15 @@ static int hash_body(struct vb2_context *ctx, struct region_device *fw_main)
timestamp_add_now(TS_DONE_HASHING);
/* Check the result (with RSA signature verification) */
- rv = vb2api_check_hash(ctx);
+ rv = vb2api_check_hash_get_digest(ctx, hash_digest, hash_digest_sz);
if (rv)
return rv;
timestamp_add_now(TS_END_HASH_BODY);
+ if (handle_digest_result(hash_digest, hash_digest_sz))
+ return VB2_ERROR_UNKNOWN;
+
return VB2_SUCCESS;
}
diff --git a/src/vendorcode/google/chromeos/vboot_common.h b/src/vendorcode/google/chromeos/vboot_common.h
index fbffc29..a658d62 100644
--- a/src/vendorcode/google/chromeos/vboot_common.h
+++ b/src/vendorcode/google/chromeos/vboot_common.h
@@ -46,6 +46,24 @@ int vboot_recovery_reason(void);
void vboot_reboot(void);
+/*
+ * Save the provided hash digest to a secure location to check against in
+ * the resume path. Returns 0 on success, < 0 on error.
+ */
+int vboot_save_hash(void *digest, size_t digest_size);
+
+/*
+ * Retrieve the previously saved hash digest. Returns 0 on success,
+ * < 0 on error.
+ */
+int vboot_retrieve_hash(void *digest, size_t digest_size);
+
+/*
+ * Determine if the platform is resuming from suspend. Returns 0 when
+ * not resuming, > 0 if resuming, and < 0 on error.
+ */
+int vboot_platform_is_resuming(void);
+
/* Main logic for verified boot. verstage() is the stage entry point
* while the verstage_main() is just the core logic. */
void verstage_main(void);
the following patch was just integrated into master:
commit b09a5696a6292b14e5d6eaa00f6ed7f6c748368a
Author: Martin Roth <martinroth(a)google.com>
Date: Sun Jan 24 19:38:33 2016 -0700
build_system: Extend site-local
- Add a target at the end of the build that can be used to run additional
scripts or additional targets after coreboot.rom is built.
- Source a site-local Kconfig file to allow site-specific configuration.
This eliminates the need to add a hook for a script at the end of the
build because you can add one yourself in site-local.
Example site-local/Makefile.inc:
build_complete::
ifeq ($(CONFIG_SITE_LOCAL),y)
echo "Running additional steps in site-local"
# run some script here to make my build unreproducible.
endif
.phony: build_complete
Example site-local/Kconfig:
menu "site-local"
config SITE_LOCAL
bool "site-local enabled"
help
Enable my site-local configuration to do stuff.
endmenu
Change-Id: Id4d1e727c69b5cdb05e7d52731bbb1d1e201864a
Signed-off-by: Martin Roth <martinroth(a)google.com>
Reviewed-on: https://review.coreboot.org/13413
Reviewed-by: Patrick Georgi <pgeorgi(a)google.com>
Tested-by: build bot (Jenkins)
See https://review.coreboot.org/13413 for details.
-gerrit
Vladimir Serbinenko (phcoder(a)gmail.com) just uploaded a new patch set to gerrit, which you can find at https://review.coreboot.org/13570
-gerrit
commit d30bae730804ba21de721fa9fd544c5d25a26303
Author: Vladimir Serbinenko <phcoder(a)gmail.com>
Date: Wed Feb 3 11:55:08 2016 +0100
iasl: Disable warning 3144 when compiling with warnings as errors.
Warning 3144 is "assigned but not used variable". Yet often we need to read
registers to trigger some side effect and don't care about the actual value.
To implement this we dump result into variable we don't use afterwards.
Change-Id: Ic824c7b7c8469fd3c6cf673f50f54557fb363fbd
Signed-off-by: Vladimir Serbinenko <phcoder(a)gmail.com>
---
Makefile.inc | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/Makefile.inc b/Makefile.inc
index 175b08b..76a9b93 100644
--- a/Makefile.inc
+++ b/Makefile.inc
@@ -205,7 +205,7 @@ $(obj)/$(1).aml: $(src)/mainboard/$(MAINBOARDDIR)/$(1).asl $(obj)/config.h
@printf " IASL $$(subst $(top)/,,$$(@))\n"
$(CC_ramstage) -x assembler-with-cpp -E -MMD -MT $$(@) $$(CPPFLAGS_ramstage) -D__ACPI__ -P -include $(src)/include/kconfig.h -I$(obj) -I$(src) -I$(src)/include -I$(src)/arch/$(ARCHDIR-$(ARCH-ramstage-y))/include -I$(src)/mainboard/$(MAINBOARDDIR) $$< -o $$@
ifeq ($(CONFIG_IASL_WARNINGS_ARE_ERRORS),y)
- cd $$(dir $$@); $(IASL) -we -p $$(notdir $$@) $$(notdir $$@)
+ cd $$(dir $$@); $(IASL) -we -vw3144 -p $$(notdir $$@) $$(notdir $$@)
else
cd $$(dir $$@); $(IASL) -p $$(notdir $$@) $$(notdir $$@)
endif