diff options
author | Namyoon Woo <namyoon@chromium.org> | 2019-12-06 13:40:18 -0800 |
---|---|---|
committer | Commit Bot <commit-bot@chromium.org> | 2020-02-22 01:46:37 +0000 |
commit | c5322ba116003017deab926f5d1e9bdd16f649b8 (patch) | |
tree | 029288582014d5a5d8be0ca87643e0e1fe707328 /board | |
parent | cfc689dcb00f3b81e857c8fbd21e4599443ceeff (diff) | |
download | chrome-ec-c5322ba116003017deab926f5d1e9bdd16f649b8.tar.gz |
read EC Firmware hash from kernel secdata during board init
Cr50 reads EC Firmware hash from kernel secdata. This data shall be
used for EC-EFS (Early Firmware Selection) procedure.
BUG=chromium:1020578, b:148489182
BRANCH=cr50
TEST=none
Change-Id: Id8942b5b49dd5b0412d198a12ee0bf87fd59d47f
Signed-off-by: Namyoon Woo <namyoon@chromium.org>
Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/ec/+/1956159
Reviewed-by: Vadim Bendebury <vbendeb@chromium.org>
Diffstat (limited to 'board')
-rw-r--r-- | board/cr50/ec_comm.h | 4 | ||||
-rw-r--r-- | board/cr50/ec_efs.c | 61 | ||||
-rw-r--r-- | board/cr50/tpm2/NVMem.c | 9 |
3 files changed, 73 insertions, 1 deletions
diff --git a/board/cr50/ec_comm.h b/board/cr50/ec_comm.h index 9e84a715e1..bec2deb57b 100644 --- a/board/cr50/ec_comm.h +++ b/board/cr50/ec_comm.h @@ -36,4 +36,8 @@ void ec_efs_reset(void); uint16_t ec_efs_set_boot_mode(const char *data, const uint8_t size); /* Verify the given hash data against the EC-FW hash from kernel secdata */ uint16_t ec_efs_verify_hash(const char *hash_data, const uint8_t size); + +/* Re-load EC Hash code from TPM Kernel Secdata */ +void ec_efs_refresh(void); + #endif /* __CROS_EC_COMM_H */ diff --git a/board/cr50/ec_efs.c b/board/cr50/ec_efs.c index da5a31f019..677fb7d7f9 100644 --- a/board/cr50/ec_efs.c +++ b/board/cr50/ec_efs.c @@ -7,10 +7,13 @@ #include "common.h" #include "console.h" #include "ec_comm.h" +#include "crc8.h" #include "ec_commands.h" #include "hooks.h" #include "registers.h" #include "system.h" +#include "tpm_nvmem.h" +#include "tpm_nvmem_ops.h" #include "vboot.h" #ifdef CR50_DEV @@ -48,6 +51,44 @@ static void set_boot_mode_(uint8_t mode_val) GREG32(PMU, PWRDN_SCRATCH20) |= mode_val; } +static int load_ec_hash_(uint8_t * const ec_hash) +{ + struct vb2_secdata_kernel secdata; + const uint8_t secdata_size = sizeof(struct vb2_secdata_kernel); + uint8_t size_to_crc; + uint8_t struct_size; + uint8_t crc; + + if (read_tpm_nvmem(KERNEL_NV_INDEX, secdata_size, + (void *)&secdata) != tpm_read_success) + return EC_ERROR_VBOOT_DATA_UNDERSIZED; + + /* + * Check struct version. CRC offset may be different with old struct + * version + */ + if (secdata.struct_version < VB2_SECDATA_KERNEL_STRUCT_VERSION_MIN) + return EC_ERROR_VBOOT_DATA_INCOMPATIBLE; + + /* Check struct size. */ + struct_size = secdata.struct_size; + if (struct_size != secdata_size) + return EC_ERROR_VBOOT_DATA; + + /* Check CRC */ + size_to_crc = struct_size - + offsetof(struct vb2_secdata_kernel, crc8) - + sizeof(secdata.crc8); + crc = crc8((uint8_t *)&secdata.reserved0, size_to_crc); + if (crc != secdata.crc8) + return EC_ERROR_CRC; + + /* Read hash and copy to hash */ + memcpy(ec_hash, secdata.ec_hash, sizeof(secdata.ec_hash)); + + return EC_SUCCESS; +} + /* * Initialize EC-EFS context. */ @@ -66,7 +107,11 @@ static void ec_efs_init_(void) else ec_efs_reset(); - /* TODO(crbug/1020578): Read Hash from Kernel NV Index */ + /* Read an EC hash in kernel secdata (TPM kernel NV index). */ + if (ec_efs_ctx.hash_is_loaded) + return; + + ec_efs_refresh(); } DECLARE_HOOK(HOOK_INIT, ec_efs_init_, HOOK_PRIO_DEFAULT); @@ -74,3 +119,17 @@ void ec_efs_reset(void) { set_boot_mode_(EC_EFS_BOOT_MODE_NORMAL); } + +void ec_efs_refresh(void) +{ + int rv; + + rv = load_ec_hash_(ec_efs_ctx.hash); + if (rv == EC_SUCCESS) { + ec_efs_ctx.hash_is_loaded = 1; + } else { + ec_efs_ctx.hash_is_loaded = 0; + cprints(CC_SYSTEM, "load_ec_hash error: 0x%x\n", rv); + } + ec_efs_ctx.secdata_error_code = rv; +} diff --git a/board/cr50/tpm2/NVMem.c b/board/cr50/tpm2/NVMem.c index e1a14b4536..052165d5b6 100644 --- a/board/cr50/tpm2/NVMem.c +++ b/board/cr50/tpm2/NVMem.c @@ -14,9 +14,12 @@ #include "Platform.h" #include "PlatformData.h" +#include "TPM_Types.h" #include "TpmError.h" #include "assert.h" +#include "ec_comm.h" #include "nvmem.h" +#include "tpm_nvmem.h" /* Local state */ static struct { @@ -188,3 +191,9 @@ void _plat__ClearNvAvail(void) local_state.s_NvIsAvailable = FALSE; return; } + +void _plat__NvInformIndexDataChanged(unsigned int handle) +{ + if (handle == (HR_NV_INDEX + KERNEL_NV_INDEX)) + ec_efs_refresh(); +} |