swtpm: Introduce disable-auto-shutdown flag for --flags option
Introduce disable-auto-shutdown flag for the --flags option to disable
the sending of TPM2_Shutdown() if swtpm determines that it needs to send
this command to a TPM 2 before device reset or swtpm program termination.
Signed-off-by: Stefan Berger <stefanb@linux.ibm.com>
diff --git a/man/man8/swtpm.pod b/man/man8/swtpm.pod
index 605ed8d..f67a3e2 100644
--- a/man/man8/swtpm.pod
+++ b/man/man8/swtpm.pod
@@ -277,7 +277,7 @@
This option is only available on Linux and only if swtpm was compiled with
libseccomp support.
-=item B<--flags [not-need-init] [,startup-clear|startup-state|startup-deactivated|startup-none]>
+=item B<--flags [not-need-init][,startup-clear|startup-state|startup-deactivated|startup-none][,disable-auto-shutdown]>
The I<not-need-init> flag enables the TPM to accept TPM commands right after
start without requiring an INIT to be sent to it through the command channel
@@ -291,6 +291,13 @@
If I<--vtpm-proxy> is used, I<startup-clear> is automatically chosen but
this can be changed with this option.
+The I<disable-auto-shutdown> flag prevents swtpm from automatically sending a
+TPM2_Shutdown() before the reset of a TPM 2 or before the swtpm process
+is terminated. When this flag is not provide swtpm will send this command to
+avoid increasing the dictionary attack (DA) lockout counter and ulimately
+a DA lockout by the TPM 2 due to omission of sending a required TPM2_Shutdown()
+before TPM 2 reset or swtpm process termination.
+
=item B<--print-capabilities> (since v0.2)
Print capabilities that were added to swtpm after version 0.1. The output
@@ -309,6 +316,7 @@
"nvram-backend-file",
"tpm-send-command-header",
"flags-opt-startup",
+ "flags-opt-disable-auto-shutdown",
"rsa-keysize-1024",
"rsa-keysize-2048",
"rsa-keysize-3072"
@@ -369,6 +377,10 @@
The I<--flags> option supports the I<startup-...> options.
+=item B<flags-opt-disable-auto-shutdown> (since v0.8)
+
+The I<--flags> option supports the I<disable-auto-shutdown> flag.
+
=item B<rsa-keysize-2048> (since v0.4)
The TPM 2 supports the shown RSA key sizes. If none of the
diff --git a/src/swtpm/capabilities.c b/src/swtpm/capabilities.c
index dfcac83..c81c79b 100644
--- a/src/swtpm/capabilities.c
+++ b/src/swtpm/capabilities.c
@@ -146,7 +146,7 @@
"{ "
"\"type\": \"swtpm\", "
"\"features\": [ "
- "%s%s%s%s%s%s%s%s%s%s%s"
+ "%s%s%s%s%s%s%s%s%s%s%s%s"
" ], "
"\"version\": \"" VERSION "\" "
"}",
@@ -154,6 +154,7 @@
with_tpm2,
!cusetpm ? "\"tpm-send-command-header\", ": "",
true ? "\"flags-opt-startup\", " : "",
+ true ? "\"flags-opt-disable-auto-shutdown\", ": "",
cmdarg_seccomp,
true ? "\"cmdarg-key-fd\", " : "",
true ? "\"cmdarg-pwd-fd\", " : "",
diff --git a/src/swtpm/common.c b/src/swtpm/common.c
index 06408c6..b4e5803 100644
--- a/src/swtpm/common.c
+++ b/src/swtpm/common.c
@@ -246,6 +246,9 @@
}, {
.name = "startup-deactivated",
.type = OPT_TYPE_BOOLEAN,
+ }, {
+ .name = "disable-auto-shutdown",
+ .type = OPT_TYPE_BOOLEAN,
},
END_OPTION_DESC
};
@@ -1234,7 +1237,7 @@
}
static int parse_flags_options(char *options, bool *need_init_cmd,
- uint16_t *startupType)
+ uint16_t *startupType, bool *disable_auto_shutdown)
{
OptionValues *ovs = NULL;
char *error = NULL;
@@ -1247,6 +1250,8 @@
if (option_get_bool(ovs, "not-need-init", false))
*need_init_cmd = false;
+ if (option_get_bool(ovs, "disable-auto-shutdown", false))
+ *disable_auto_shutdown = true;
if (option_get_bool(ovs, "startup-clear", false))
*startupType = TPM_ST_CLEAR;
@@ -1280,12 +1285,13 @@
* Returns 0 on success, -1 on failure.
*/
int handle_flags_options(char *options, bool *need_init_cmd,
- uint16_t *startupType)
+ uint16_t *startupType, bool *disable_auto_shutdown)
{
if (!options)
return 0;
- if (parse_flags_options(options, need_init_cmd, startupType) < 0)
+ if (parse_flags_options(options, need_init_cmd, startupType,
+ disable_auto_shutdown) < 0)
return -1;
return 0;
diff --git a/src/swtpm/common.h b/src/swtpm/common.h
index f284028..1df3163 100644
--- a/src/swtpm/common.h
+++ b/src/swtpm/common.h
@@ -54,7 +54,7 @@
int handle_server_options(char *options, struct server **s);
int handle_locality_options(char *options, uint32_t *flags);
int handle_flags_options(char *options, bool *need_init_cmd,
- uint16_t *startupType);
+ uint16_t *startupType, bool *disable_auto_shutdown);
#ifdef WITH_SECCOMP
int handle_seccomp_options(char *options, unsigned int *seccomp_action);
#else
diff --git a/src/swtpm/ctrlchannel.c b/src/swtpm/ctrlchannel.c
index babd150..2713b2c 100644
--- a/src/swtpm/ctrlchannel.c
+++ b/src/swtpm/ctrlchannel.c
@@ -554,7 +554,7 @@
if (n != (ssize_t)sizeof(ptm_init)) /* r/w */
goto err_bad_input;
- if (*tpm_running)
+ if (*tpm_running && !mlp->disable_auto_shutdown)
tpmlib_maybe_send_tpm2_shutdown(mlp->tpmversion,
&mlp->lastCommand);
@@ -580,7 +580,7 @@
if (n != 0) /* wo */
goto err_bad_input;
- if (*tpm_running)
+ if (*tpm_running && !mlp->disable_auto_shutdown)
tpmlib_maybe_send_tpm2_shutdown(mlp->tpmversion,
&mlp->lastCommand);
@@ -596,7 +596,7 @@
if (n != 0) /* wo */
goto err_bad_input;
- if (*tpm_running)
+ if (*tpm_running && !mlp->disable_auto_shutdown)
tpmlib_maybe_send_tpm2_shutdown(mlp->tpmversion,
&mlp->lastCommand);
diff --git a/src/swtpm/cuse_tpm.c b/src/swtpm/cuse_tpm.c
index 61bd9a3..a011b44 100644
--- a/src/swtpm/cuse_tpm.c
+++ b/src/swtpm/cuse_tpm.c
@@ -113,6 +113,9 @@
/* last command sent to the TPM */
static uint32_t g_lastCommand = TPM_ORDINAL_NONE;
+/* TPM2_Shutdown() will NOT be sent by swtpm */
+static bool g_disable_auto_shutdown = false;
+
#if GLIB_MAJOR_VERSION >= 2
# if GLIB_MINOR_VERSION >= 32
@@ -229,10 +232,12 @@
" instead of dir option;\n"
" mode allows a user to set the file mode bits of the state\n"
" files; the default mode is 0640;\n"
-"--flags [not-need-init][,startup-clear|startup-state|startup-deactivated|startup-none]\n"
+"--flags [not-need-init][,startup-clear|startup-state|startup-deactivated|startup-none][,disable-auto-shutdown]\n"
" : not-need-init: commands can be sent without needing to\n"
" send an INIT via control channel;\n"
" startup-...: send Startup command with this type;\n"
+" disable-auto-shutdown disables automatic sending of\n"
+" TPM2_Shutdown before TPM 2 reset or swtpm termination;\n"
"-r|--runas <user> : after creating the CUSE device, change to the given\n"
" user\n"
"--tpm2 : choose TPM2 functionality\n"
@@ -1091,7 +1096,7 @@
worker_thread_end();
- if (tpm_running)
+ if (tpm_running && !g_disable_auto_shutdown)
tpmlib_maybe_send_tpm2_shutdown(tpmversion,
&g_lastCommand);
@@ -1112,7 +1117,7 @@
case PTM_STOP:
worker_thread_end();
- if (tpm_running)
+ if (tpm_running && !g_disable_auto_shutdown)
tpmlib_maybe_send_tpm2_shutdown(tpmversion, &g_lastCommand);
res = TPM_SUCCESS;
@@ -1130,7 +1135,7 @@
case PTM_SHUTDOWN:
worker_thread_end();
- if (tpm_running)
+ if (tpm_running && !g_disable_auto_shutdown)
tpmlib_maybe_send_tpm2_shutdown(tpmversion, &g_lastCommand);
res = TPM_SUCCESS;
@@ -1705,7 +1710,7 @@
handle_seccomp_options(param.seccompdata, ¶m.seccomp_action) < 0 ||
handle_locality_options(param.localitydata, &locality_flags) < 0 ||
handle_flags_options(param.flagsdata, &need_init_cmd,
- ¶m.startupType) < 0) {
+ ¶m.startupType, &g_disable_auto_shutdown) < 0) {
ret = -3;
goto exit;
}
diff --git a/src/swtpm/mainloop.h b/src/swtpm/mainloop.h
index 8feed1e..a1705a0 100644
--- a/src/swtpm/mainloop.h
+++ b/src/swtpm/mainloop.h
@@ -61,6 +61,7 @@
TPMLIB_TPMVersion tpmversion;
uint16_t startupType; /* use TPM 1.2 types */
uint32_t lastCommand; /* last Command sent to TPM */
+ bool disable_auto_shutdown; /* TPM2_Shutdown() will NOT be sent by swtpm */
};
int mainLoop(struct mainLoopParams *mlp,
diff --git a/src/swtpm/swtpm.c b/src/swtpm/swtpm.c
index c2c255b..94c8c09 100644
--- a/src/swtpm/swtpm.c
+++ b/src/swtpm/swtpm.c
@@ -168,10 +168,12 @@
" mode allows a user to set the file mode bits of the socket; the\n"
" value must be given in octal number format;\n"
" uid and gid set the ownership of the Unixio socket's file;\n"
- "--flags [not-need-init][,startup-clear|startup-state|startup-deactivated|startup-none]\n"
+ "--flags [not-need-init][,startup-clear|startup-state|startup-deactivated|startup-none][,disable-auto-shutdown]\n"
" : not-need-init: commands can be sent without needing to\n"
" send an INIT via control channel;\n"
" startup-...: send Startup command with this type;\n"
+ " disable-auto-shutdown disables automatic sending of\n"
+ " TPM2_Shutdown before TPM 2 reset or swtpm termination;\n"
"-r|--runas <user>: change to the given user\n"
"--tpm2 : choose TPM2 functionality\n"
#ifdef WITH_SECCOMP
@@ -216,6 +218,7 @@
.tpmversion = TPMLIB_TPM_VERSION_1_2,
.startupType = _TPM_ST_NONE,
.lastCommand = TPM_ORDINAL_NONE,
+ .disable_auto_shutdown = false,
};
struct server *server = NULL;
unsigned long val;
@@ -469,7 +472,7 @@
handle_tpmstate_options(tpmstatedata) < 0 ||
handle_seccomp_options(seccompdata, &seccomp_action) < 0 ||
handle_flags_options(flagsdata, &need_init_cmd,
- &mlp.startupType) < 0) {
+ &mlp.startupType, &mlp.disable_auto_shutdown) < 0) {
goto exit_failure;
}
diff --git a/src/swtpm/swtpm_chardev.c b/src/swtpm/swtpm_chardev.c
index a1d6c8d..8767d90 100644
--- a/src/swtpm/swtpm_chardev.c
+++ b/src/swtpm/swtpm_chardev.c
@@ -189,12 +189,14 @@
"--locality [reject-locality-4][,allow-set-locality]\n"
" : reject-locality-4: reject any command in locality 4\n"
" allow-set-locality: accept SetLocality command\n"
- "--flags [not-need-init][,startup-clear|startup-state|startup-deactivated|startup-none]\n"
+ "--flags [not-need-init][,startup-clear|startup-state|startup-deactivated|startup-none][,disable-auto-shutdown]\n"
" : not-need-init: commands can be sent without needing to\n"
" send an INIT via control channel; not needed when using\n"
" --vtpm-proxy\n"
" startup-...: send Startup command with this type;\n"
" when --vtpm-proxy is used, startup-clear is used\n"
+ " disable-auto-shutdown disables automatic sending of\n"
+ " TPM2_Shutdown before TPM 2 reset or swtpm termination;\n"
"--tpm2 : choose TPM2 functionality\n"
#ifdef WITH_SECCOMP
# ifndef SCMP_ACT_LOG
@@ -275,6 +277,7 @@
.tpmversion = TPMLIB_TPM_VERSION_1_2,
.startupType = _TPM_ST_NONE,
.lastCommand = TPM_ORDINAL_NONE,
+ .disable_auto_shutdown = false,
};
unsigned long val;
char *end_ptr;
@@ -532,7 +535,7 @@
handle_tpmstate_options(tpmstatedata) < 0 ||
handle_seccomp_options(seccompdata, &seccomp_action) < 0 ||
handle_flags_options(flagsdata, &need_init_cmd,
- &mlp.startupType) < 0) {
+ &mlp.startupType, &mlp.disable_auto_shutdown) < 0) {
goto exit_failure;
}
diff --git a/tests/_test_print_capabilities b/tests/_test_print_capabilities
index 92073e3..87b0fd5 100755
--- a/tests/_test_print_capabilities
+++ b/tests/_test_print_capabilities
@@ -25,7 +25,7 @@
noncuse='"tpm-send-command-header", '
fi
-exp='\{ "type": "swtpm", "features": \[ "tpm-1.2",( "tpm-2.0",)? '${noncuse}'"flags-opt-startup", '${seccomp}'"cmdarg-key-fd", "cmdarg-pwd-fd", "cmdarg-print-states", "nvram-backend-dir", "nvram-backend-file" \], "version": "[^"]*" \}'
+exp='\{ "type": "swtpm", "features": \[ "tpm-1.2",( "tpm-2.0",)? '${noncuse}'"flags-opt-startup", "flags-opt-disable-auto-shutdown", '${seccomp}'"cmdarg-key-fd", "cmdarg-pwd-fd", "cmdarg-print-states", "nvram-backend-dir", "nvram-backend-file" \], "version": "[^"]*" \}'
if ! [[ ${msg} =~ ${exp} ]]; then
echo "Unexpected response from ${SWTPM_IFACE} TPM to --print-capabilities:"
echo "Actual : ${msg}"
diff --git a/tests/_test_tpm2_print_capabilities b/tests/_test_tpm2_print_capabilities
index 2e54587..35f77e6 100755
--- a/tests/_test_tpm2_print_capabilities
+++ b/tests/_test_tpm2_print_capabilities
@@ -26,7 +26,7 @@
fi
# The rsa key size reporting is variable, so use a regex
-exp='\{ "type": "swtpm", "features": \[( "tpm-1.2",)? "tpm-2.0", '${noncuse}'"flags-opt-startup", '${seccomp}'"cmdarg-key-fd", "cmdarg-pwd-fd", "cmdarg-print-states", "nvram-backend-dir", "nvram-backend-file"(, "rsa-keysize-1024")?(, "rsa-keysize-2048")?(, "rsa-keysize-3072")? \], "version": "[^"]*" \}'
+exp='\{ "type": "swtpm", "features": \[( "tpm-1.2",)? "tpm-2.0", '${noncuse}'"flags-opt-startup", "flags-opt-disable-auto-shutdown", '${seccomp}'"cmdarg-key-fd", "cmdarg-pwd-fd", "cmdarg-print-states", "nvram-backend-dir", "nvram-backend-file"(, "rsa-keysize-1024")?(, "rsa-keysize-2048")?(, "rsa-keysize-3072")? \], "version": "[^"]*" \}'
if ! [[ ${msg} =~ ${exp} ]]; then
echo "Unexpected response from ${SWTPM_IFACE} TPM to --print-capabilities:"
echo "Actual : ${msg}"