summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNamyoon Woo <namyoon@google.com>2020-03-24 16:42:58 -0700
committerCommit Bot <commit-bot@chromium.org>2020-03-31 04:41:00 +0000
commite9f13a75eb3d05faa05e620a2e61dadebb20233f (patch)
tree72a9a9303fb73a7d2170aac5fe78da6a5768c43e
parentd674693d9b3f3a9ff0e3a0d00ebc35b75c4b3f43 (diff)
downloadchrome-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>
-rw-r--r--common/ec_comm.c24
-rw-r--r--common/ec_efs.c46
-rw-r--r--common/nvmem.c14
-rw-r--r--include/ec_comm.h2
-rw-r--r--include/nvmem.h8
5 files changed, 69 insertions, 25 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();
+}
diff --git a/include/ec_comm.h b/include/ec_comm.h
index c599868488..dd4d105d4a 100644
--- a/include/ec_comm.h
+++ b/include/ec_comm.h
@@ -42,7 +42,7 @@ void ec_efs_refresh(void);
/* print EC-EFS status */
void ec_efs_print_status(void);
/* corrupt ECRW hash */
-void ec_efs_corrupt_hash(void);
+enum ec_error_list ec_efs_corrupt_hash(void);
#ifdef BOARD_HOST
/* return the current boot mode. For test purpose only. */
diff --git a/include/nvmem.h b/include/nvmem.h
index f48c9cd9c4..00dc4b7879 100644
--- a/include/nvmem.h
+++ b/include/nvmem.h
@@ -212,6 +212,14 @@ void nvmem_clear_cache(void);
void nvmem_wipe_cache(void);
+/*
+ * Unlock nvmem mutex lock.
+ *
+ * @param init_act_partition: boolean to request to initialize active nvmem
+ * partition status or not.
+ */
+void nvmem_unlock_cache(int init_act_partition);
+
#ifdef __cplusplus
}
#endif