summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNamyoon Woo <namyoon@google.com>2018-06-14 18:17:35 -0700
committerchrome-bot <chrome-bot@chromium.org>2018-06-21 01:05:47 -0700
commit47eb2d5fe7c7ff3bed6f5a33836ec19182d17941 (patch)
tree7c9b147c62cd0991129351221cc2431585a5e5d7
parent725b337a61b6250f72f392e7a6df330b7c7bcae6 (diff)
downloadchrome-ec-47eb2d5fe7c7ff3bed6f5a33836ec19182d17941.tar.gz
cr50: Disabling TPM or enabling TPM.
This patch introduces a new firmware status, TPM mode along with a new TPM vendor command VENDOR_CC_TPM_MODE. TPM mode indicates whether TPM is enabled or disabled. Initially, this value shall be TPM_MODE_ENABLED_TENTATIVE, which means TPM is enabled but can be changed. VENDOR_CC_TPM_MODE changes this value either as TPM_MODE_ENABLED or TPM_MODE_DISABLED. This is for one time use only until next TPM reset event. Once TPM is disabled, any subsequent TPM commands shall fail. TPM_MODE_TPM_MODE command may be issued with input size as zero, which would not change TPM mode value. Either with the valid input value or without any input value, it returns the current TPM mode value in uint8_t type. This adds 160 bytes in binary. BUG=b:77543596 BRANCH=cr50 TEST=manually (chroot) ./extra/usb_updater/gsctool -h Usage: gsctool [options] [<binary image>] Options: -m,--tpm_mode [enable|disable] Query or control tpm mode (dut) gsctool -a -i Board ID space: XXXXXXXX:XXXXXXXX:XXXXXXXX (chroot) ./extra/usb_updater/gsctool -m enable (dut) gsctool -a -i Board ID space: XXXXXXXX:XXXXXXXX:XXXXXXXX (chroot) gsctool -m enable Error 7 in enabling TPM. (dut) gsctool -a -i Board ID space: XXXXXXXX:XXXXXXXX:XXXXXXXX (dut) reboot (chroot) ./extra/usb_updater/gsctool -m disable (dut) gsctool -a -i Problems reading from TPM, got 10 bytes Error: Failed to send vendor command 25 (dut) tpm_version [ERROR:... TRUNKS_RC_WRITE_ERROR (dut) tpm-manager [INFO:tpm_manager_v2.cc(51)] Initializing TPM. [tpm_manager.TakeOwnershipReply] { status:STATUS_NOT_AVAILABLE } (dut) reboot (chroot) ./extra/usb_updater/gsctool -m TPM Mode: enabled (0) (dut) gsctool -a -i Board ID space: XXXXXXXX:XXXXXXXX:XXXXXXXX (dut) tpm_version TPM2.0 Version Info: ... (dut) tpm-manager [INFO:tpm_manager_v2.cc(51)] Initializing TPM. [INFO:tpm_manager_v2.cc(66)] TPM initialization successful (21 ms). Change-Id: I1453d1a8d03f13cc7fc203863cbc50bf84c9dd8c Signed-off-by: Namyoon Woo <namyoon@google.com> Reviewed-on: https://chromium-review.googlesource.com/1105614 Commit-Ready: Namyoon Woo <namyoon@chromium.org> Tested-by: Namyoon Woo <namyoon@chromium.org> Reviewed-by: Vadim Bendebury <vbendeb@chromium.org> Reviewed-by: Mary Ruthven <mruthven@chromium.org>
-rw-r--r--board/cr50/board.c6
-rw-r--r--board/cr50/build.mk1
-rw-r--r--board/cr50/tpm2/tpm_mode.c60
-rw-r--r--common/extension.c1
-rw-r--r--common/tpm_registers.c5
-rw-r--r--include/tpm_registers.h17
-rw-r--r--include/tpm_vendor_cmds.h11
7 files changed, 101 insertions, 0 deletions
diff --git a/board/cr50/board.c b/board/cr50/board.c
index ffd7b818cc..db7480b4e5 100644
--- a/board/cr50/board.c
+++ b/board/cr50/board.c
@@ -1289,6 +1289,7 @@ static int command_sysinfo(int argc, char **argv)
const struct SignedHeader *h;
int reset_count = GREG32(PMU, LONG_LIFE_SCRATCH0);
char rollback_str[15];
+ uint8_t tpm_mode;
ccprintf("Reset flags: 0x%08x (", system_get_reset_flags());
system_print_reset_flags();
@@ -1316,6 +1317,11 @@ static int command_sysinfo(int argc, char **argv)
system_get_rollback_bits(rollback_str, sizeof(rollback_str));
ccprintf("Rollback: %s\n", rollback_str);
+ tpm_mode = get_tpm_mode();
+ ccprintf("TPM MODE: %s (%d)\n",
+ (tpm_mode == TPM_MODE_DISABLED) ? "disabled" : "enabled",
+ tpm_mode);
+
return EC_SUCCESS;
}
DECLARE_SAFE_CONSOLE_COMMAND(sysinfo, command_sysinfo,
diff --git a/board/cr50/build.mk b/board/cr50/build.mk
index 58254ed8aa..83ffd04db6 100644
--- a/board/cr50/build.mk
+++ b/board/cr50/build.mk
@@ -52,6 +52,7 @@ board-y += tpm2/manufacture.o
board-y += tpm2/platform.o
board-y += tpm2/rsa.o
board-y += tpm2/stubs.o
+board-y += tpm2/tpm_mode.o
board-y += tpm2/tpm_state.o
board-y += tpm2/trng.o
board-y += tpm_nvmem_read.o
diff --git a/board/cr50/tpm2/tpm_mode.c b/board/cr50/tpm2/tpm_mode.c
new file mode 100644
index 0000000000..269e2feb5f
--- /dev/null
+++ b/board/cr50/tpm2/tpm_mode.c
@@ -0,0 +1,60 @@
+/*
+ * Copyright 2018 The Chromium OS Authors. All rights reserved.
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#include "config.h"
+#include "Global.h"
+#include "console.h"
+#include "extension.h"
+#include "hooks.h"
+#include "timer.h"
+#include "tpm_registers.h"
+#include "tpm_vendor_cmds.h"
+
+#define CPRINTS(format, args...) cprints(CC_EXTENSION, format, ## args)
+
+DECLARE_DEFERRED(tpm_stop);
+
+/*
+ * On TPM reset event, tpm_reset_now() in tpm_registers.c clears TPM2 BSS memory
+ * area. By placing s_tpm_mode in TPM2 BSS area, TPM mode value shall be
+ * "TPM_MODE_ENABLED_TENTATIVE" on every TPM reset events.
+ */
+static enum tpm_modes s_tpm_mode __attribute__((section(".bss.Tpm2_common")));
+
+static enum vendor_cmd_rc set_tpm_mode(struct vendor_cmd_params *p)
+{
+ uint8_t mode_val;
+ uint8_t *buffer;
+
+ p->out_size = 0;
+
+ if (p->in_size > sizeof(uint8_t))
+ return VENDOR_RC_NOT_ALLOWED;
+
+ buffer = (uint8_t *)p->buffer;
+ if (p->in_size == sizeof(uint8_t)) {
+ if (s_tpm_mode != TPM_MODE_ENABLED_TENTATIVE)
+ return VENDOR_RC_NOT_ALLOWED;
+ mode_val = buffer[0];
+ if (mode_val == TPM_MODE_DISABLED)
+ hook_call_deferred(&tpm_stop_data, 10 * MSEC);
+ else if (mode_val != TPM_MODE_ENABLED)
+ return VENDOR_RC_NOT_ALLOWED;
+ s_tpm_mode = mode_val;
+ }
+
+ p->out_size = sizeof(uint8_t);
+ buffer[0] = (uint8_t) s_tpm_mode;
+
+ return VENDOR_RC_SUCCESS;
+}
+DECLARE_VENDOR_COMMAND_P(VENDOR_CC_TPM_MODE, set_tpm_mode);
+
+enum tpm_modes get_tpm_mode(void)
+{
+ return s_tpm_mode;
+}
+
diff --git a/common/extension.c b/common/extension.c
index eaded0244f..a1f1d6920e 100644
--- a/common/extension.c
+++ b/common/extension.c
@@ -30,6 +30,7 @@ uint32_t extension_route_command(struct vendor_cmd_params *p)
case VENDOR_CC_IMMEDIATE_RESET:
case VENDOR_CC_INVALIDATE_INACTIVE_RW:
case VENDOR_CC_SET_BOARD_ID:
+ case VENDOR_CC_TPM_MODE:
#endif /* defined(CR50_DEV) */
case EXTENSION_POST_RESET: /* Always need to reset. */
case VENDOR_CC_CCD:
diff --git a/common/tpm_registers.c b/common/tpm_registers.c
index 215905efa9..30630f565d 100644
--- a/common/tpm_registers.c
+++ b/common/tpm_registers.c
@@ -895,6 +895,11 @@ int tpm_sync_reset(int wipe_first)
return wipe_result;
}
+void tpm_stop(void)
+{
+ if_stop();
+}
+
void tpm_task(void)
{
uint32_t evt = 0;
diff --git a/include/tpm_registers.h b/include/tpm_registers.h
index 0cbcdca39d..ed03959185 100644
--- a/include/tpm_registers.h
+++ b/include/tpm_registers.h
@@ -61,6 +61,11 @@ void tpm_reinstate_nvmem_commits(void);
int tpm_sync_reset(int wipe_first);
/*
+ * It shuts down the tpm interface, until next tpm reset event.
+ */
+void tpm_stop(void);
+
+/*
* This structure describes the header of all commands and responses sent and
* received over TPM FIFO.
*
@@ -105,4 +110,16 @@ void tpm_alt_extension(struct tpm_cmd_header *tpmh, size_t buffer_size);
#define TPM2_PCR_Read 0x0000017e
#define TPM2_Startup 0x00000144
+/* TPM mode */
+enum tpm_modes {
+ TPM_MODE_ENABLED_TENTATIVE = 0,
+ TPM_MODE_ENABLED = 1,
+ TPM_MODE_DISABLED = 2,
+};
+
+/*
+ * This function returns the current TPM_MODE value.
+ */
+enum tpm_modes get_tpm_mode(void);
+
#endif /* __CROS_EC_TPM_REGISTERS_H */
diff --git a/include/tpm_vendor_cmds.h b/include/tpm_vendor_cmds.h
index 2ecef80e57..16fa071a6b 100644
--- a/include/tpm_vendor_cmds.h
+++ b/include/tpm_vendor_cmds.h
@@ -69,6 +69,17 @@ enum vendor_cmd_cc {
* WPV subcommands.
*/
VENDOR_CC_WP = 39,
+ /*
+ * Either enable or disable TPM mode. This is allowed for one-time only
+ * until next TPM reset EVENT. In other words, once TPM mode is set,
+ * then it cannot be altered to the other mode value. The allowed input
+ * values are either TPM_MODE_ENABLED or TPM_MODE_DISABLED as defined
+ * in 'enum tpm_modes', tpm_registers.h.
+ * If the input size is zero, it won't change TPM_MODE.
+ * If either the input size is zero or the input value is valid,
+ * it will response with the current tpm_mode value in uint8_t format.
+ */
+ VENDOR_CC_TPM_MODE = 40,
LAST_VENDOR_COMMAND = 65535,
};