From 6d8e52a6e350e1dbf450d02fccdb2ac2b0c036e4 Mon Sep 17 00:00:00 2001 From: Raymond Mao Date: Mon, 27 Jan 2025 06:58:46 -0800 Subject: [PATCH] tpm: add TPM2_Shutdown command TPM2_shutdown command is sharing same structure and logics with TPM2_startup, thus this patch extends the existing startup APIs and cmd functions to support shutdown instead of created new ones. Signed-off-by: Raymond Mao Reviewed-by: Ilias Apalodimas Signed-off-by: Ilias Apalodimas --- cmd/tpm-v2.c | 14 +++++++++++--- include/tpm-v2.h | 3 ++- lib/tpm-v2.c | 9 +++++---- lib/tpm_api.c | 4 ++-- 4 files changed, 20 insertions(+), 10 deletions(-) diff --git a/cmd/tpm-v2.c b/cmd/tpm-v2.c index 8517833f861..a6d57ee7c49 100644 --- a/cmd/tpm-v2.c +++ b/cmd/tpm-v2.c @@ -18,11 +18,14 @@ static int do_tpm2_startup(struct cmd_tbl *cmdtp, int flag, int argc, enum tpm2_startup_types mode; struct udevice *dev; int ret; + bool bon = true; ret = get_tpm(&dev); if (ret) return ret; - if (argc != 2) + + /* argv[2] is optional to perform a TPM2_CC_SHUTDOWN */ + if (argc > 3 || (argc == 3 && strcasecmp("off", argv[2]))) return CMD_RET_USAGE; if (!strcasecmp("TPM2_SU_CLEAR", argv[1])) { @@ -34,7 +37,10 @@ static int do_tpm2_startup(struct cmd_tbl *cmdtp, int flag, int argc, return CMD_RET_FAILURE; } - return report_return_code(tpm2_startup(dev, mode)); + if (argv[2]) + bon = false; + + return report_return_code(tpm2_startup(dev, bon, mode)); } static int do_tpm2_self_test(struct cmd_tbl *cmdtp, int flag, int argc, @@ -420,11 +426,13 @@ U_BOOT_CMD(tpm2, CONFIG_SYS_MAXARGS, 1, do_tpm, "Issue a TPMv2.x command", " Initialize the software stack. Always the first command to issue.\n" " 'tpm startup' is the only acceptable command after a 'tpm init' has been\n" " issued\n" -"startup \n" +"startup []\n" " Issue a TPM2_Startup command.\n" " is one of:\n" " * TPM2_SU_CLEAR (reset state)\n" " * TPM2_SU_STATE (preserved state)\n" +" :\n" +" * off - To shutdown the TPM\n" "self_test \n" " Test the TPM capabilities.\n" " is one of:\n" diff --git a/include/tpm-v2.h b/include/tpm-v2.h index 65681464b37..f66a8e1bf41 100644 --- a/include/tpm-v2.h +++ b/include/tpm-v2.h @@ -230,6 +230,7 @@ enum tpm2_command_codes { TPM2_CC_PCR_READ = 0x017E, TPM2_CC_PCR_EXTEND = 0x0182, TPM2_CC_PCR_SETAUTHVAL = 0x0183, + TPM2_CC_SHUTDOWN = 0x0145, }; /** @@ -430,7 +431,7 @@ enum { * * Return: code of the operation */ -u32 tpm2_startup(struct udevice *dev, enum tpm2_startup_types mode); +u32 tpm2_startup(struct udevice *dev, bool onoff, enum tpm2_startup_types mode); /** * Issue a TPM2_SelfTest command. diff --git a/lib/tpm-v2.c b/lib/tpm-v2.c index bc750b7ca19..3946ac2dbb7 100644 --- a/lib/tpm-v2.c +++ b/lib/tpm-v2.c @@ -44,12 +44,13 @@ static int tpm2_update_active_banks(struct udevice *dev) return 0; } -u32 tpm2_startup(struct udevice *dev, enum tpm2_startup_types mode) +u32 tpm2_startup(struct udevice *dev, bool bon, enum tpm2_startup_types mode) { + int op = bon ? TPM2_CC_STARTUP : TPM2_CC_SHUTDOWN; const u8 command_v2[12] = { tpm_u16(TPM2_ST_NO_SESSIONS), tpm_u32(12), - tpm_u32(TPM2_CC_STARTUP), + tpm_u32(op), tpm_u16(mode), }; int ret; @@ -59,7 +60,7 @@ u32 tpm2_startup(struct udevice *dev, enum tpm2_startup_types mode) * but will return RC_INITIALIZE otherwise. */ ret = tpm_sendrecv_command(dev, command_v2, NULL, NULL); - if (ret && ret != TPM2_RC_INITIALIZE) + if ((ret && ret != TPM2_RC_INITIALIZE) || !bon) return ret; return tpm2_update_active_banks(dev); @@ -84,7 +85,7 @@ u32 tpm2_auto_start(struct udevice *dev) rc = tpm2_self_test(dev, TPMI_YES); if (rc == TPM2_RC_INITIALIZE) { - rc = tpm2_startup(dev, TPM2_SU_CLEAR); + rc = tpm2_startup(dev, true, TPM2_SU_CLEAR); if (rc) return rc; diff --git a/lib/tpm_api.c b/lib/tpm_api.c index 39a5121e302..576d601e5ff 100644 --- a/lib/tpm_api.c +++ b/lib/tpm_api.c @@ -28,7 +28,7 @@ u32 tpm_startup(struct udevice *dev, enum tpm_startup_type mode) case TPM_ST_DEACTIVATED: return -EINVAL; } - return tpm2_startup(dev, type); + return tpm2_startup(dev, true, type); } else { return -ENOSYS; } @@ -60,7 +60,7 @@ u32 tpm_resume(struct udevice *dev) if (tpm_is_v1(dev)) return tpm1_startup(dev, TPM_ST_STATE); else if (tpm_is_v2(dev)) - return tpm2_startup(dev, TPM2_SU_STATE); + return tpm2_startup(dev, true, TPM2_SU_STATE); else return -ENOSYS; }