diff options
author | Namyoon Woo <namyoon@google.com> | 2020-03-24 16:42:58 -0700 |
---|---|---|
committer | Commit Bot <commit-bot@chromium.org> | 2020-03-31 04:41:00 +0000 |
commit | e9f13a75eb3d05faa05e620a2e61dadebb20233f (patch) | |
tree | 72a9a9303fb73a7d2170aac5fe78da6a5768c43e /common | |
parent | d674693d9b3f3a9ff0e3a0d00ebc35b75c4b3f43 (diff) | |
download | chrome-ec-e9f13a75eb3d05faa05e620a2e61dadebb20233f.tar.gz |
Modify ec_comm command to corrupt NVMEM copy of kernel secdata
'ec_comm corrupt' used to corrupt a copy of EC-RW hash in ec_efs.c for
test purpose. This patch makes it corrupt the copy stored in the TPM
NVMEM cache first, and then read it into the cache in ec_efs.c.
'corrupt' option is available for regular image as well onl if CCD is
opened.
'reload' option is obsolete.
BUG=b:150650877
TEST=checked the behavior in the sequence below:
0. program regular image
cr50> ec_comm corrupt
CCD is not opened
Access Denied
Usage: ec_comm [corrupt]
1. open ccd.
2. Checked the original hash code.
cr50> ec_comm
...
ec_hash_sec_data : /* original hash code, Hm. */
3. Corrupt the hash code.
cr50> ec_comm corrupt
...
ec_hash_sec_data : /* corrupted hash code, Hc. */
4. Reboot EC.
ec> reboot ap-off
5. Check the boot mode is NO_BOOT mode.
chroot$ gsctool --getbootmode
...
Boot mode = 0x01: NO_BOOT
6. Turn on AP by tapping the power button.
Check AP rewrites the secdata, and Cr50 reloads it.
cr50> ec_comm
...
ec_hash_sec_data : /* original hash code, Hm. */
Signed-off-by: Namyoon Woo <namyoon@google.com>
Change-Id: Id34239911da204e1eacd285fa601a9b5db03c4ee
Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/ec/+/2119130
Reviewed-by: Daisuke Nojiri <dnojiri@chromium.org>
Reviewed-by: Mary Ruthven <mruthven@chromium.org>
Commit-Queue: Namyoon Woo <namyoon@chromium.org>
Tested-by: Namyoon Woo <namyoon@chromium.org>
Diffstat (limited to 'common')
-rw-r--r-- | common/ec_comm.c | 24 | ||||
-rw-r--r-- | common/ec_efs.c | 46 | ||||
-rw-r--r-- | common/nvmem.c | 14 |
3 files changed, 60 insertions, 24 deletions
diff --git a/common/ec_comm.c b/common/ec_comm.c index eaf26b4509..18ea225ef9 100644 --- a/common/ec_comm.c +++ b/common/ec_comm.c @@ -323,20 +323,18 @@ static int command_ec_comm(int argc, char **argv) } if (argc > 1) { -#ifdef CR50_RELAXED - if (!strcasecmp(argv[1], "corrupt")) - ec_efs_corrupt_hash(); - else if (!strcasecmp(argv[1], "reload")) - ec_efs_refresh(); - else + if (!strcasecmp(argv[1], "corrupt")) { + int result = ec_efs_corrupt_hash(); + + if (result != EC_SUCCESS) + return result; + } else { return EC_ERROR_PARAM1; + } /* * let's keep processing so that we can see how the context * values are changed. */ -#else - return EC_ERROR_PARAM_COUNT; -#endif } /* @@ -361,12 +359,6 @@ static int command_ec_comm(int argc, char **argv) return EC_SUCCESS; } DECLARE_SAFE_CONSOLE_COMMAND(ec_comm, command_ec_comm, -#ifdef CR50_RELAXED - "[corrupt|reload]", - "Dump EC-CR50-comm status, or corrupt ECRW hash," - "or reload it" -#else - NULL, + "[corrupt]", "Dump EC-CR50-comm status" -#endif ); diff --git a/common/ec_efs.c b/common/ec_efs.c index fabc549ec8..d7bc881872 100644 --- a/common/ec_efs.c +++ b/common/ec_efs.c @@ -7,10 +7,16 @@ #include "common.h" #include "console.h" #include "ec_comm.h" +#include "ccd_config.h" #include "crc8.h" #include "ec_commands.h" #include "extension.h" #include "hooks.h" +#ifndef BOARD_HOST +#include "Global.h" +#include "NV_fp.h" +#include "nvmem.h" +#endif #include "registers.h" #include "system.h" #include "tpm_nvmem.h" @@ -288,15 +294,47 @@ void ec_efs_print_status(void) #endif } -#ifdef CR50_RELAXED -void ec_efs_corrupt_hash(void) +enum ec_error_list ec_efs_corrupt_hash(void) { +#ifndef BOARD_HOST + struct vb2_secdata_kernel secdata; + const uint8_t secdata_size = sizeof(struct vb2_secdata_kernel); + TPM_HANDLE object_handle; + NV_INDEX nvIndex; + uint8_t size_to_crc; int i; + /* Check CCD is opened */ + if (ccd_get_state() != CCD_STATE_OPENED) { + ccprintf("CCD is not opened\n"); + return EC_ERROR_ACCESS_DENIED; + } + + /* Read the kernel secdata */ + if (read_tpm_nvmem(KERNEL_NV_INDEX, secdata_size, + (void *)&secdata) != TPM_READ_SUCCESS) + return EC_ERROR_VBOOT_DATA_UNDERSIZED; + + /* Modify hash */ for (i = 0; i < SHA256_DIGEST_SIZE; i++) - ec_efs_ctx.hash[i] = ~ec_efs_ctx.hash[i] + 0x01; -} + secdata.ec_hash[i] = ~ec_efs_ctx.hash[i] + 0x01; + + size_to_crc = secdata_size - + offsetof(struct vb2_secdata_kernel, crc8) - + sizeof(secdata.crc8); + secdata.crc8 = crc8((uint8_t *)&secdata.reserved0, size_to_crc); + + /* Corrupt KERNEL_NV_INDEX in nvmem cache. */ + object_handle = HR_NV_INDEX + KERNEL_NV_INDEX; + NvGetIndexInfo(object_handle, &nvIndex); + NvWriteIndexData(object_handle, &nvIndex, 0, secdata_size, &secdata); + nvmem_unlock_cache(1); + + /* Reload the corrupted ECRW-hash from kernel secdata. */ + ec_efs_refresh(); #endif + return EC_SUCCESS; +} #ifdef BOARD_HOST uint8_t ec_efs_get_boot_mode(void) diff --git a/common/nvmem.c b/common/nvmem.c index 42fc0ba161..92e097077a 100644 --- a/common/nvmem.c +++ b/common/nvmem.c @@ -106,11 +106,8 @@ static int nvmem_save(void) rv = new_nvmem_save(); - if (rv == EC_SUCCESS) - nvmem_act_partition = NVMEM_NOT_INITIALIZED; + nvmem_unlock_cache(rv == EC_SUCCESS); - nvmem_mutex.write_in_progress = 0; - nvmem_release_cache(); return rv; } @@ -507,3 +504,12 @@ void nvmem_clear_cache(void) nvmem_save(); } + +void nvmem_unlock_cache(int init_act_partition) +{ + if (init_act_partition) + nvmem_act_partition = NVMEM_NOT_INITIALIZED; + + nvmem_mutex.write_in_progress = 0; + nvmem_release_cache(); +} |