Skip to content

Commit

Permalink
swtpm: Add support for recreate-svn-base-secret flags option
Browse files Browse the repository at this point in the history
Signed-off-by: Stefan Berger <[email protected]>
  • Loading branch information
stefanberger committed Oct 28, 2024
1 parent 395ada3 commit 94bb06a
Show file tree
Hide file tree
Showing 10 changed files with 57 additions and 20 deletions.
7 changes: 6 additions & 1 deletion man/man8/swtpm.pod
Original file line number Diff line number Diff line change
Expand Up @@ -297,7 +297,7 @@ The I<log> action is only available if libseccomp supports logging.
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][,disable-auto-shutdown]>
=item B<--flags [not-need-init][,startup-clear|startup-state|startup-deactivated|startup-none][,disable-auto-shutdown][,recreate-svn-base-secret]>

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
Expand All @@ -318,6 +318,11 @@ avoid increasing the dictionary attack (DA) lockout counter and ultimately
a DA lockout by the TPM 2 due to omission of sending a required TPM2_Shutdown()
before TPM 2 reset or swtpm process termination.

The I<recreate-svn-base-secrete> causes the SVN-limited hierarchy 'base secret'
to be recreated. The side effect of recreating this secret is that previous
firmware SVN secrets cannot be created anymore and objects (keys) associated
with the SVN-limited hierachy cannot be used anymore.

=item B<--print-capabilities> (since v0.2)

Print capabilities that were added to swtpm after version 0.1. The output
Expand Down
14 changes: 11 additions & 3 deletions src/swtpm/common.c
Original file line number Diff line number Diff line change
Expand Up @@ -259,6 +259,9 @@ static const OptionDesc flags_opt_desc[] = {
}, {
.name = "disable-auto-shutdown",
.type = OPT_TYPE_BOOLEAN,
}, {
.name = "recreate-svn-base-secret",
.type = OPT_TYPE_BOOLEAN,
},
END_OPTION_DESC
};
Expand Down Expand Up @@ -1301,7 +1304,8 @@ int handle_locality_options(const char *options, uint32_t *flags)
}

static int parse_flags_options(const char *options, bool *need_init_cmd,
uint16_t *startupType, bool *disable_auto_shutdown)
uint16_t *startupType, bool *disable_auto_shutdown,
bool *recreate_svn_base_secret)
{
OptionValues *ovs = NULL;
char *error = NULL;
Expand Down Expand Up @@ -1329,6 +1333,9 @@ static int parse_flags_options(const char *options, bool *need_init_cmd,
if (*startupType != _TPM_ST_NONE)
*need_init_cmd = false;

if (option_get_bool(ovs, "recreate-svn-base-secret", false))
*recreate_svn_base_secret = true;

option_values_free(ovs);

return 0;
Expand All @@ -1349,13 +1356,14 @@ static int parse_flags_options(const char *options, bool *need_init_cmd,
* Returns 0 on success, -1 on failure.
*/
int handle_flags_options(const char *options, bool *need_init_cmd,
uint16_t *startupType, bool *disable_auto_shutdown)
uint16_t *startupType, bool *disable_auto_shutdown,
bool *recreate_svn_base_secret)
{
if (!options)
return 0;

if (parse_flags_options(options, need_init_cmd, startupType,
disable_auto_shutdown) < 0)
disable_auto_shutdown, recreate_svn_base_secret) < 0)
return -1;

return 0;
Expand Down
3 changes: 2 additions & 1 deletion src/swtpm/common.h
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,8 @@ struct server;
int handle_server_options(const char *options, struct server **s);
int handle_locality_options(const char *options, uint32_t *flags);
int handle_flags_options(const char *options, bool *need_init_cmd,
uint16_t *startupType, bool *disable_auto_shutdown);
uint16_t *startupType, bool *disable_auto_shutdown,
bool *recreate_base_secret);
#ifdef WITH_SECCOMP
int handle_seccomp_options(const char *options, unsigned int *seccomp_action);
#else
Expand Down
2 changes: 1 addition & 1 deletion src/swtpm/ctrlchannel.c
Original file line number Diff line number Diff line change
Expand Up @@ -577,7 +577,7 @@ int ctrlchannel_process_fd(int fd,

res = tpmlib_start(be32toh(init_p->u.req.init_flags),
mlp->tpmversion, mlp->storage_locked,
mlp->json_profile);
mlp->json_profile, &mlp->recreate_svn_base_secret);
if (res) {
logprintf(STDERR_FILENO,
"Error: Could not initialize the TPM\n");
Expand Down
20 changes: 14 additions & 6 deletions src/swtpm/cuse_tpm.c
Original file line number Diff line number Diff line change
Expand Up @@ -125,6 +125,9 @@ static bool g_storage_locked;
/* whether to release the lock on outgoing migration */
static bool g_release_lock_outgoing;

/* whether to recreate the SVN base secret of a TPM 2 */
static bool g_recreate_svn_base_secret;

/* how many times to retry locking; use for fallback after releasing
the lock on outgoing migration. */
static unsigned int g_locking_retries;
Expand Down Expand Up @@ -255,12 +258,13 @@ static void usage(FILE *file, const char *prgname, const char *iface)
" mode allows a user to set the file mode bits of the state\n"
" files; the default mode is 0640;\n"
" lock enables file-locking by the storage backend;\n"
"--flags [not-need-init][,startup-clear|startup-state|startup-deactivated|startup-none][,disable-auto-shutdown]\n"
"--flags [not-need-init][,startup-clear|startup-state|startup-deactivated|startup-none][,disable-auto-shutdown][,recreate-svn-base-secret]\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"
" recreate-svn-base-secret recreates the SVN base secret;\n"
"-r|--runas <user> : after creating the CUSE device, change to the given\n"
" user\n"
"-R|--chroot <path> : chroot to the given directory at startup\n"
Expand Down Expand Up @@ -515,7 +519,8 @@ static void worker_thread(gpointer data, gpointer user_data SWTPM_ATTR_UNUSED)
* @res: the result from starting the TPM
*/
static int tpm_start(uint32_t flags, TPMLIB_TPMVersion l_tpmversion,
const char *json_profile, TPM_RESULT *res)
const char *json_profile, TPM_RESULT *res,
bool *recreate_svn_base_secret)
{
DIR *dir;
const char *uri = tpmstate_get_backend_uri();
Expand Down Expand Up @@ -556,7 +561,8 @@ static int tpm_start(uint32_t flags, TPMLIB_TPMVersion l_tpmversion,

g_storage_locked = !g_incoming_migration;

*res = tpmlib_start(flags, l_tpmversion, g_storage_locked, json_profile);
*res = tpmlib_start(flags, l_tpmversion, g_storage_locked, json_profile,
recreate_svn_base_secret);
if (*res != TPM_SUCCESS)
goto error_del_pool;

Expand Down Expand Up @@ -1191,7 +1197,7 @@ static void ptm_ioctl(fuse_req_t req, int cmd, void *arg,

tpm_running = false;
if (tpm_start(init_p->u.req.init_flags, tpmversion,
g_json_profile, &res) < 0) {
g_json_profile, &res, &g_recreate_svn_base_secret) < 0) {
logprintf(STDERR_FILENO,
"Error: Could not initialize the TPM.\n");
} else {
Expand Down Expand Up @@ -1868,7 +1874,8 @@ int swtpm_cuse_main(int argc, char **argv, const char *prgname, const char *ifac
handle_seccomp_options(param.seccompdata, &param.seccomp_action) < 0 ||
handle_locality_options(param.localitydata, &locality_flags) < 0 ||
handle_flags_options(param.flagsdata, &need_init_cmd,
&param.startupType, &g_disable_auto_shutdown) < 0 ||
&param.startupType, &g_disable_auto_shutdown,
&g_recreate_svn_base_secret) < 0 ||
handle_migration_options(param.migrationdata, &g_incoming_migration,
&g_release_lock_outgoing) < 0 ||
handle_profile_options(param.profiledata, &g_json_profile) < 0) {
Expand Down Expand Up @@ -1919,7 +1926,8 @@ int swtpm_cuse_main(int argc, char **argv, const char *prgname, const char *ifac
g_mutex_lock(FILE_OPS_LOCK);

if (!need_init_cmd || (infoflags && tpmstate_get_backend_uri())) {
if (tpm_start(0, tpmversion, g_json_profile, &res) < 0) {
if (tpm_start(0, tpmversion, g_json_profile, &res,
&g_recreate_svn_base_secret) < 0) {
ret = -1;
goto err_unlock;
}
Expand Down
2 changes: 2 additions & 0 deletions src/swtpm/mainloop.h
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,8 @@ struct mainLoopParams {
bool storage_locked;
/* whether to release the lock on outgoing migration */
bool release_lock_outgoing;
/* whether to recreate the SVN base secret of the TPM 2 */
bool recreate_svn_base_secret;
/* how many times to retry locking; use for fallback after releasing
the lock on outgoing migration. */
unsigned int locking_retries;
Expand Down
9 changes: 6 additions & 3 deletions src/swtpm/swtpm.c
Original file line number Diff line number Diff line change
Expand Up @@ -172,12 +172,13 @@ static void usage(FILE *file, const char *prgname, const char *iface)
" 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][,disable-auto-shutdown]\n"
"--flags [not-need-init][,startup-clear|startup-state|startup-deactivated|startup-none][,disable-auto-shutdown][,recreate-svn-base-secret]\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"
" recreate-svn-base-secret recreates the SVN base secret;\n"
"-r|--runas <user>: change to the given user\n"
"-R|--chroot <path>\n"
" : chroot to the given directory at startup\n"
Expand Down Expand Up @@ -241,6 +242,7 @@ int swtpm_main(int argc, char **argv, const char *prgname, const char *iface)
.disable_auto_shutdown = false,
.incoming_migration = false,
.storage_locked = false,
.recreate_svn_base_secret = false,
};
g_autofree gchar *jsoninfo = NULL;
struct server *server = NULL;
Expand Down Expand Up @@ -542,7 +544,8 @@ int swtpm_main(int argc, char **argv, const char *prgname, const char *iface)
handle_tpmstate_options(tpmstatedata) < 0 ||
handle_seccomp_options(seccompdata, &seccomp_action) < 0 ||
handle_flags_options(flagsdata, &need_init_cmd,
&mlp.startupType, &mlp.disable_auto_shutdown) < 0 ||
&mlp.startupType, &mlp.disable_auto_shutdown,
&mlp.recreate_svn_base_secret) < 0 ||
handle_migration_options(migrationdata, &mlp.incoming_migration,
&mlp.release_lock_outgoing) < 0 ||
handle_profile_options(profiledata, &mlp.json_profile) < 0) {
Expand Down Expand Up @@ -585,7 +588,7 @@ int swtpm_main(int argc, char **argv, const char *prgname, const char *iface)
mlp.storage_locked = !mlp.incoming_migration;

if ((rc = tpmlib_start(0, mlp.tpmversion, mlp.storage_locked,
mlp.json_profile)))
mlp.json_profile, &mlp.recreate_svn_base_secret)))
goto error_no_tpm;
tpm_running = true;
SWTPM_G_FREE(mlp.json_profile);
Expand Down
9 changes: 6 additions & 3 deletions src/swtpm/swtpm_chardev.c
Original file line number Diff line number Diff line change
Expand Up @@ -194,14 +194,15 @@ static void usage(FILE *file, const char *prgname, const char *iface)
"--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][,disable-auto-shutdown]\n"
"--flags [not-need-init][,startup-clear|startup-state|startup-deactivated|startup-none][,disable-auto-shutdown][,recreate-svn-base-secret]\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"
" recreate-svn-base-secret recreates the SVN base secret;\n"
"--tpm2 : choose TPM2 functionality\n"
#ifdef WITH_SECCOMP
# ifndef SCMP_ACT_LOG
Expand Down Expand Up @@ -299,6 +300,7 @@ int swtpm_chardev_main(int argc, char **argv, const char *prgname, const char *i
.disable_auto_shutdown = false,
.incoming_migration = false,
.storage_locked = false,
.recreate_svn_base_secret = false,
};
g_autofree gchar *jsoninfo = NULL;
unsigned long val;
Expand Down Expand Up @@ -606,7 +608,8 @@ int swtpm_chardev_main(int argc, char **argv, const char *prgname, const char *i
handle_tpmstate_options(tpmstatedata) < 0 ||
handle_seccomp_options(seccompdata, &seccomp_action) < 0 ||
handle_flags_options(flagsdata, &need_init_cmd,
&mlp.startupType, &mlp.disable_auto_shutdown) < 0 ||
&mlp.startupType, &mlp.disable_auto_shutdown,
&mlp.recreate_svn_base_secret) < 0 ||
handle_migration_options(migrationdata, &mlp.incoming_migration,
&mlp.release_lock_outgoing) < 0 ||
handle_profile_options(profiledata, &mlp.json_profile) < 0) {
Expand Down Expand Up @@ -635,7 +638,7 @@ int swtpm_chardev_main(int argc, char **argv, const char *prgname, const char *i
mlp.storage_locked = !mlp.incoming_migration;

if ((rc = tpmlib_start(0, mlp.tpmversion, mlp.storage_locked,
mlp.json_profile)))
mlp.json_profile, &mlp.recreate_svn_base_secret)))
goto error_no_tpm;
tpm_running = true;
SWTPM_G_FREE(mlp.json_profile);
Expand Down
8 changes: 7 additions & 1 deletion src/swtpm/tpmlib.c
Original file line number Diff line number Diff line change
Expand Up @@ -274,7 +274,8 @@ static int tpmlib_maybe_configure_openssl(TPMLIB_TPMVersion tpmversion)
}

TPM_RESULT tpmlib_start(uint32_t flags, TPMLIB_TPMVersion tpmversion,
bool lock_nvram, const char *json_profile)
bool lock_nvram, const char *json_profile,
bool *recreate_svn_base_secret)
{
TPM_RESULT res;

Expand Down Expand Up @@ -319,6 +320,11 @@ TPM_RESULT tpmlib_start(uint32_t flags, TPMLIB_TPMVersion tpmversion,
}
}

if (*recreate_svn_base_secret) {
TPMLIB_RecreateSvnBaseSecret();
*recreate_svn_base_secret = false;
}

if (tpmlib_maybe_configure_openssl(tpmversion)) {
res = TPM_FAIL;
goto error_terminate;
Expand Down
3 changes: 2 additions & 1 deletion src/swtpm/tpmlib.h
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,8 @@ enum TPMLIB_StateType tpmlib_blobtype_to_statetype(uint32_t blobtype);
TPM_RESULT tpmlib_register_callbacks(struct libtpms_callbacks *cbs);
TPM_RESULT tpmlib_choose_tpm_version(TPMLIB_TPMVersion tpmversion);
TPM_RESULT tpmlib_start(uint32_t flags, TPMLIB_TPMVersion tpmversion,
bool lock_nvram, const char *profile);
bool lock_nvram, const char *profile,
bool *recreate_svn_base_secret);
int tpmlib_get_tpm_property(enum TPMLIB_TPMProperty prop);
uint32_t tpmlib_get_cmd_ordinal(const unsigned char *request, size_t req_len);
bool tpmlib_is_request_cancelable(TPMLIB_TPMVersion tpmversion,
Expand Down

0 comments on commit 94bb06a

Please sign in to comment.