tpm: add TPM2_Shutdown command
authorRaymond Mao <raymond.mao@linaro.org>
Mon, 27 Jan 2025 14:58:46 +0000 (06:58 -0800)
committerIlias Apalodimas <ilias.apalodimas@linaro.org>
Tue, 28 Jan 2025 06:58:41 +0000 (08:58 +0200)
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 <raymond.mao@linaro.org>
Reviewed-by: Ilias Apalodimas <ilias.apalodimas@linaro.org>
Signed-off-by: Ilias Apalodimas <ilias.apalodimas@linaro.org>
cmd/tpm-v2.c
include/tpm-v2.h
lib/tpm-v2.c
lib/tpm_api.c

index 8517833..a6d57ee 100644 (file)
@@ -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 <mode>\n"
+"startup <mode> [<op>]\n"
 "    Issue a TPM2_Startup command.\n"
 "    <mode> is one of:\n"
 "        * TPM2_SU_CLEAR (reset state)\n"
 "        * TPM2_SU_STATE (preserved state)\n"
+"    <op>:\n"
+"        * off - To shutdown the TPM\n"
 "self_test <type>\n"
 "    Test the TPM capabilities.\n"
 "    <type> is one of:\n"
index 6568146..f66a8e1 100644 (file)
@@ -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.
index bc750b7..3946ac2 100644 (file)
@@ -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;
 
index 39a5121..576d601 100644 (file)
@@ -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;
 }