mirror of
https://github.com/Telecominfraproject/OpenCellular.git
synced 2026-01-10 17:41:54 +00:00
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>
This commit is contained in:
committed by
chrome-bot
parent
3ce5e5d8b3
commit
d7303404a5
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
66
test/nvmem.c
66
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 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();
|
||||
}
|
||||
|
||||
/* Make sure both partitions have data in them. */
|
||||
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_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);
|
||||
/*
|
||||
* nvmem_erase_user_data() is supposed to erase the user's data across
|
||||
* all partitions.
|
||||
*/
|
||||
nvmem_erase_user_data(NVMEM_USER_0);
|
||||
|
||||
/* nvmem_setup() is supposed to erase both partitions. */
|
||||
nvmem_setup();
|
||||
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);
|
||||
|
||||
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);
|
||||
|
||||
/* 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);
|
||||
/*
|
||||
* 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();
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user