summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAseda Aboagye <aaboagye@google.com>2017-02-13 10:57:26 -0800
committerchrome-bot <chrome-bot@chromium.org>2017-02-23 01:19:07 -0800
commitd7303404a59a296fad9085db23fa18fe97f0f5c3 (patch)
tree5b20b0f8f182f60519509c68a46f2e63e27c2433
parent3ce5e5d8b3ebdd9abf9d182082a81e29bd899d2b (diff)
downloadchrome-ec-d7303404a59a296fad9085db23fa18fe97f0f5c3.tar.gz
cr50: Make sure TPM wipe only clears TPM data.
Previously, wiping the TPM would wipe all of NvMem, however, it really should only clear the TPM's NvMem space. This commit adds a function to clear a given NvMem user's space and makes the TPM only clear its space. BUG=chrome-os-partner:61597 BRANCH=None TEST=Add code for using nvmem vars, create a test variable, add a user to snappy, unlock the console, verify that the user is no longer present on the system and the test nvmem var still exists. TEST=make -j buildall Change-Id: Ic98baa5166a1ef9ae76e910b1b9ab100300e947f Signed-off-by: Aseda Aboagye <aaboagye@google.com> Reviewed-on: https://chromium-review.googlesource.com/445803 Commit-Ready: Aseda Aboagye <aaboagye@chromium.org> Tested-by: Aseda Aboagye <aaboagye@chromium.org> Reviewed-by: Vadim Bendebury <vbendeb@chromium.org>
-rw-r--r--common/nvmem.c27
-rw-r--r--common/tpm_registers.c4
-rw-r--r--include/nvmem.h11
-rw-r--r--test/nvmem.c72
4 files changed, 70 insertions, 44 deletions
diff --git a/common/nvmem.c b/common/nvmem.c
index 7ffde9d977..cb4abc3287 100644
--- a/common/nvmem.c
+++ b/common/nvmem.c
@@ -358,34 +358,41 @@ static int nvmem_get_partition_off(int user, uint32_t offset,
return EC_SUCCESS;
}
-int nvmem_setup(void)
+int nvmem_erase_user_data(enum nvmem_users user)
{
int part;
int ret;
+ uint32_t user_offset, user_size;
- CPRINTS("Configuring NVMEM Flash Partition");
+ if (user >= NVMEM_NUM_USERS)
+ return EC_ERROR_INVAL;
- part = nvmem_act_partition;
- nvmem_act_partition = 0;
+ CPRINTS("Erasing NVMEM Flash Partition user: %d", user);
ret = EC_SUCCESS;
+ /* Find offset within cache. */
+ user_offset = nvmem_user_start_offset[user];
+ user_size = nvmem_user_sizes[user];
+
for (part = 0; part < NVMEM_NUM_PARTITIONS; part++) {
int rv;
- memset(nvmem_cache, 0xff, NVMEM_PARTITION_SIZE);
+ /* Lock the cache buffer. */
+ nvmem_lock_cache();
+ /* Erase the user's data. */
+ memset(nvmem_cache + user_offset, 0xFF, user_size);
+
/*
* Make sure the contents change between runs of
- * nvmem_save() so that both flash partitions are
+ * nvmem_save() so that all flash partitions are
* written with empty contents and different
* generation numbers.
*/
((struct nvmem_partition *)nvmem_cache)->tag.generation = part;
- /* Lock the cache buffer (unlocked by nvmem_save() */
- nvmem_lock_cache();
- rv = nvmem_save();
- /* Even if one partition saving failed, let's keep going. */
+ /* Make a best effort to clear each partition. */
+ rv = nvmem_save();
if (rv != EC_SUCCESS)
ret = rv;
}
diff --git a/common/tpm_registers.c b/common/tpm_registers.c
index c2728522ae..cac79c725d 100644
--- a/common/tpm_registers.c
+++ b/common/tpm_registers.c
@@ -727,8 +727,8 @@ static void tpm_reset_now(int wipe_first)
cprints(CC_TASK, "%s: force EC off", __func__);
assert_ec_rst();
- /* Now wipe nvmem */
- wipe_result = nvmem_setup();
+ /* Now wipe the TPM's nvmem */
+ wipe_result = nvmem_erase_user_data(NVMEM_TPM);
} else {
wipe_result = EC_SUCCESS;
}
diff --git a/include/nvmem.h b/include/nvmem.h
index 87de8b9cae..e9fae3d11d 100644
--- a/include/nvmem.h
+++ b/include/nvmem.h
@@ -174,14 +174,13 @@ int nvmem_move(uint32_t src_offset, uint32_t dest_offset, uint32_t size,
int nvmem_commit(void);
/*
- * Reinitialzse all NvMem partitions
+ * Clear out a user's data across all partitions.
*
- * This function should be called when NvMem needs to be wiped out.
- *
- * @return EC_SUCCESS if flash operations are successful.
- * EC_ERROR_UNKNOWN otherwise.
+ * @param user: The user who's data should be cleared.
+ * @return EC_SUCCESS if the user's data across all partitions was
+ * cleared. Error othrwise.
*/
-int nvmem_setup(void);
+int nvmem_erase_user_data(enum nvmem_users user);
/*
* Temporarily stopping NVMEM commits could be beneficial. One use case is
diff --git a/test/nvmem.c b/test/nvmem.c
index b70c4732f4..d09bf8752a 100644
--- a/test/nvmem.c
+++ b/test/nvmem.c
@@ -175,41 +175,61 @@ static int test_configured_nvmem(void)
return nvmem_init();
}
-/* Verify that nvmem_setup indeed reinitializes the entire NVMEM. */
-static int test_nvmem_setup(void)
+/* Verify that nvmem_erase_user_data only erases the given user's data. */
+static int test_nvmem_erase_user_data(void)
{
uint32_t write_value;
uint32_t read_value;
+ int i;
nvmem_init();
- write_value = 1;
-
- /* Make sure both partitions have data in them. */
- nvmem_write(0, sizeof(write_value), &write_value, NVMEM_USER_0);
- nvmem_commit();
- read_value = ~write_value;
- nvmem_read(0, sizeof(read_value), &read_value, NVMEM_USER_0);
- TEST_ASSERT(read_value == write_value);
+ /* Make sure all partitions have data in them. */
+ for (i = 0; i < NVMEM_NUM_PARTITIONS; i++) {
+ write_value = i;
+ nvmem_write(0, sizeof(write_value), &write_value, NVMEM_USER_0);
+ write_value = 2;
+ nvmem_write(0, sizeof(write_value), &write_value, NVMEM_USER_1);
+ write_value = 3;
+ nvmem_write(0, sizeof(write_value), &write_value, NVMEM_USER_2);
+ nvmem_commit();
+ }
- nvmem_write(0, sizeof(write_value), &write_value, NVMEM_USER_0);
- nvmem_commit();
+ /* Check that the writes took place. */
read_value = ~write_value;
nvmem_read(0, sizeof(read_value), &read_value, NVMEM_USER_0);
- TEST_ASSERT(read_value == write_value);
+ TEST_ASSERT(read_value == i-1);
+ nvmem_read(0, sizeof(read_value), &read_value, NVMEM_USER_1);
+ TEST_ASSERT(read_value == 2);
+ nvmem_read(0, sizeof(read_value), &read_value, NVMEM_USER_2);
+ TEST_ASSERT(read_value == 3);
- /* nvmem_setup() is supposed to erase both partitions. */
- nvmem_setup();
-
- nvmem_read(0, sizeof(read_value), &read_value, NVMEM_USER_0);
- TEST_ASSERT(read_value == 0xffffffff);
-
- /* Switch active partition. */
- nvmem_write(0, sizeof(write_value), &write_value, NVMEM_USER_0);
- nvmem_commit();
-
- nvmem_read(0, sizeof(read_value), &read_value, NVMEM_USER_0);
- TEST_ASSERT(read_value != 0xffffffff);
+ /*
+ * nvmem_erase_user_data() is supposed to erase the user's data across
+ * all partitions.
+ */
+ nvmem_erase_user_data(NVMEM_USER_0);
+
+ for (i = 0; i < NVMEM_NUM_PARTITIONS; i++) {
+ /* Make sure USER 0's data is (still) gone. */
+ nvmem_read(0, sizeof(read_value), &read_value, NVMEM_USER_0);
+ TEST_ASSERT(read_value == 0xffffffff);
+
+ /* Make sure the other users' data has been untouched. */
+ nvmem_read(0, sizeof(read_value), &read_value, NVMEM_USER_1);
+ TEST_ASSERT(read_value == 2);
+
+ /*
+ * The active partition changes when the contents of the cache
+ * changes. Therefore, in order to examine all the paritions,
+ * we'll keep modifying one of the user's data.
+ */
+ nvmem_read(0, sizeof(read_value), &read_value, NVMEM_USER_2);
+ TEST_ASSERT(read_value == (3+i));
+ write_value = 4 + i;
+ nvmem_write(0, sizeof(write_value), &write_value, NVMEM_USER_2);
+ nvmem_commit();
+ }
return EC_SUCCESS;
}
@@ -689,7 +709,7 @@ void run_test(void)
RUN_TEST(test_move);
RUN_TEST(test_is_different);
RUN_TEST(test_lock);
- RUN_TEST(test_nvmem_setup);
+ RUN_TEST(test_nvmem_erase_user_data);
RUN_TEST(test_nvmem_save);
test_print_result();
}