summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndrey Pronin <apronin@google.com>2022-01-26 12:47:14 -0800
committerCommit Bot <commit-bot@chromium.org>2022-02-16 09:32:06 +0000
commit43fa560eb5c519f1a5afabe1fb2374943fe88013 (patch)
treeaf638f5b29453da0b9f1bfc477799cc8d1bf0959
parent76eba574138371ca7dfc5bb47133d032113770ee (diff)
downloadchrome-ec-stabilize-14526.84.B-cr50_stab.tar.gz
This CL in case of unorderly TPM reset that doesn't also reset GSC preserves RAM-backed values of orderly nv indices. BUG=b:201101365 TEST=1) create an orderly counter 2) increment it 3) trigger EC reset 4) verify that the counter value was preserved Cq-Depend: chromium:3417937 Change-Id: I799183ad06584055d025c2acf5f83ff2ded32d39 Signed-off-by: Andrey Pronin <apronin@chromium.org> Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/ec/+/3418122 Reviewed-by: Vadim Bendebury <vbendeb@chromium.org> Commit-Queue: Mary Ruthven <mruthven@chromium.org>
-rw-r--r--board/cr50/tpm_nvmem_ops.c12
-rw-r--r--board/cr50/tpm_nvmem_ops.h6
-rw-r--r--common/tpm_registers.c28
3 files changed, 42 insertions, 4 deletions
diff --git a/board/cr50/tpm_nvmem_ops.c b/board/cr50/tpm_nvmem_ops.c
index ba295c7f4f..76f740c0ee 100644
--- a/board/cr50/tpm_nvmem_ops.c
+++ b/board/cr50/tpm_nvmem_ops.c
@@ -108,3 +108,15 @@ size_t read_tpm_nvmem_size(uint16_t obj_index)
return size;
}
+
+BUILD_ASSERT(TPM_ORDERLY_STATE_SIZE >= RAM_INDEX_SPACE);
+
+void tpm_orderly_state_capture(char copy[TPM_ORDERLY_STATE_SIZE])
+{
+ NvStateCapture(copy);
+}
+
+void tpm_orderly_state_restore(const char copy[TPM_ORDERLY_STATE_SIZE])
+{
+ NvStateRestore(copy);
+}
diff --git a/board/cr50/tpm_nvmem_ops.h b/board/cr50/tpm_nvmem_ops.h
index ef1c5a07fc..da8036b16f 100644
--- a/board/cr50/tpm_nvmem_ops.h
+++ b/board/cr50/tpm_nvmem_ops.h
@@ -7,6 +7,8 @@
#ifndef __EC_BOARD_CR50_TPM_NVMEM_OPS_H
#define __EC_BOARD_CR50_TPM_NVMEM_OPS_H
+#define TPM_ORDERLY_STATE_SIZE 512
+
enum tpm_read_rv {
TPM_READ_SUCCESS,
TPM_READ_NOT_FOUND,
@@ -46,4 +48,8 @@ enum tpm_write_rv write_tpm_nvmem_hidden(uint16_t object_index,
/* return size of hidden nvmem object, 0 if not found */
size_t read_tpm_nvmem_size(uint16_t obj_index);
+void tpm_orderly_state_capture(char copy[TPM_ORDERLY_STATE_SIZE]);
+
+void tpm_orderly_state_restore(const char copy[TPM_ORDERLY_STATE_SIZE]);
+
#endif /* ! __EC_BOARD_CR50_TPM_NVMEM_OPS_H */
diff --git a/common/tpm_registers.c b/common/tpm_registers.c
index d0ae42e904..429e895283 100644
--- a/common/tpm_registers.c
+++ b/common/tpm_registers.c
@@ -21,6 +21,7 @@
#include "system_chip.h"
#include "task.h"
#include "tpm_manufacture.h"
+#include "tpm_nvmem_ops.h"
#include "tpm_registers.h"
#include "util.h"
#include "watchdog.h"
@@ -850,8 +851,21 @@ void tpm_reinstate_nvmem_commits(void)
task_set_event(TASK_ID_TPM, TPM_EVENT_COMMIT, 0);
}
-static void tpm_reset_now(int wipe_first)
+/*
+ * Reset TPM stack state.
+ * Called at boot, when AP resets (TPM_RESET_EVENT) and when a TPM data wipe
+ * is requested.
+ *
+ * Parameters:
+ * wipe_first - wipe TPM nvmem as a part of reset.
+ * can_preserve_orderly - preserve orderly nvmem spaces over a possibly
+ * unorderly shutdown (unless wipe_first is requested). This is a GSC
+ * specific modification to TPM behavior.
+ */
+static void tpm_reset_now(int wipe_first, int can_preserve_orderly)
{
+ char orderly_state_copy[TPM_ORDERLY_STATE_SIZE];
+
if_stop();
/* This is more related to TPM task activity than TPM transactions */
@@ -874,6 +888,9 @@ static void tpm_reset_now(int wipe_first)
*/
nvmem_enable_commits();
+ if (can_preserve_orderly && !wipe_first)
+ tpm_orderly_state_capture(orderly_state_copy);
+
/*
* Clear the TPM library's zero-init data. Note that the linker script
* includes this file's .bss in the same section, so it will be cleared
@@ -889,6 +906,9 @@ static void tpm_reset_now(int wipe_first)
/* Re-initialize our registers */
tpm_init();
+ if (can_preserve_orderly && !wipe_first)
+ tpm_orderly_state_restore(orderly_state_copy);
+
if (waiting_for_reset != TASK_ID_INVALID) {
/* Wake the waiting task, if any */
task_set_event(waiting_for_reset, TPM_EVENT_RESET, 0);
@@ -908,7 +928,7 @@ static void tpm_reset_now(int wipe_first)
int tpm_sync_reset(int wipe_first)
{
- tpm_reset_now(wipe_first);
+ tpm_reset_now(wipe_first, 1);
return wipe_result;
}
@@ -957,7 +977,7 @@ void tpm_task(void *u)
__func__, __LINE__, evt);
}
- tpm_reset_now(0);
+ tpm_reset_now(0, 0);
while (1) {
uint8_t *response = NULL;
unsigned response_size;
@@ -971,7 +991,7 @@ void tpm_task(void *u)
evt = task_wait_event(-1);
if (evt & TPM_EVENT_RESET) {
- tpm_reset_now(wipe_requested);
+ tpm_reset_now(wipe_requested, 1);
if (evt & TPM_EVENT_ALT_EXTENSION) {
/*
* Need to tell the waiting task that