Skip to content

Commit

Permalink
swtpm_setup: Implement --profile-remove-fips-disabled option
Browse files Browse the repository at this point in the history
Implement the --profile-remove-fips-disabled option that is used to tell
swtpm to remove algorithms that are disabled by FIPS mode on the host.
Internally, this option passes the remove-fips-disabled option parameter
with the --profile option to swtpm.

Add a test cases passing this option and check that the resulting profiles
have key sizes adjusted and relevant attributes set.

Signed-off-by: Stefan Berger <stefanb@linux.ibm.com>
  • Loading branch information
stefanberger committed Sep 16, 2024
1 parent 9744a77 commit 3643de1
Show file tree
Hide file tree
Showing 7 changed files with 83 additions and 14 deletions.
22 changes: 21 additions & 1 deletion man/man8/swtpm_setup.pod
Original file line number Diff line number Diff line change
Expand Up @@ -218,6 +218,21 @@ supported by libtpms. The profile may contain an algorithms field with a
list of algorithms to enable. Unknown fields in the JSON profile will be
ignored.

=item B<--profile-remove-disabled check|fips-host>

When this option is passed then swtpm will remove algorithms from the given
profile that OpenSSL cannot use when FIPS mode is enabled on the host. If
the I<check> parameter is given then algorithms are tested before they are
removed while the I<fips-host> parameter forces the removal of all potentially
disabled algorithms without testing them.

This option only works if the 'custom' profile is given by passing
I<--profile '{"Name":"custom"}'> for example.

This option passes the I<remove-disable> option parameter as part of the
I<--profile> option to swtpm. For further information see the man page for
I<swtpm>.

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

Print capabilities that were added to swtpm_setup after version 0.1.
Expand All @@ -236,7 +251,8 @@ The output may contain the following:
"cmdarg-reconfigure-pcr-banks",
"tpm2-rsa-keysize-2048",
"tpm2-rsa-keysize-3072",
"cmdarg-profile"
"cmdarg-profile",
"cmdarg-profile-remove-disabled"
],
"version": "0.7.0"
}
Expand Down Expand Up @@ -291,6 +307,10 @@ TPM 2 setup is supported (libtpms is compiled with TPM 2 support).

The I<--profile> option is supported.

=item B<cmdarg-profile-remove-disabled> (since v0.10)

The I<--profile-remove-disabled> option is supported.

=back

=item B<--write-ek-cert-files <directory>> (since v0.7)
Expand Down
21 changes: 16 additions & 5 deletions src/swtpm_setup/swtpm.c
Original file line number Diff line number Diff line change
Expand Up @@ -120,7 +120,14 @@ static int swtpm_start(struct swtpm *self)
}

if (self->json_profile != NULL) {
json_profile = g_strdup_printf("profile=%s", self->json_profile);
json_profile = g_strdup_printf("profile=%s%s%s",
self->json_profile,
self->profile_remove_disabled_param != NULL
? ",remove-disabled="
: "",
self->profile_remove_disabled_param != NULL
? self->profile_remove_disabled_param
: "");
argv = concat_arrays(argv, (gchar*[]){"--profile", json_profile, NULL}, TRUE);
logit(self->logfile, "Apply profile: %s\n", self->json_profile);
}
Expand Down Expand Up @@ -2016,7 +2023,8 @@ static void swtpm_init(struct swtpm *swtpm,
gchar **swtpm_exec_l, const gchar *state_path,
const gchar *keyopts, const gchar *logfile,
int *fds_to_pass, size_t n_fds_to_pass,
gboolean is_tpm2, const gchar *json_profile)
gboolean is_tpm2, const gchar *json_profile,
const gchar *profile_remove_disabled_param)
{
swtpm->cops = &swtpm_cops;
swtpm->swtpm_exec_l = swtpm_exec_l;
Expand All @@ -2027,6 +2035,7 @@ static void swtpm_init(struct swtpm *swtpm,
swtpm->n_fds_to_pass = n_fds_to_pass;
swtpm->is_tpm2 = is_tpm2;
swtpm->json_profile = json_profile;
swtpm->profile_remove_disabled_param = profile_remove_disabled_param;

swtpm->pid = -1;
swtpm->ctrl_fds[0] = swtpm->ctrl_fds[1] = -1;
Expand All @@ -2040,7 +2049,7 @@ struct swtpm12 *swtpm12_new(gchar **swtpm_exec_l, const gchar *state_path,
struct swtpm12 *swtpm12 = g_malloc0(sizeof(struct swtpm12));

swtpm_init(&swtpm12->swtpm, swtpm_exec_l, state_path, keyopts, logfile,
fds_to_pass, n_fds_to_pass, FALSE, NULL);
fds_to_pass, n_fds_to_pass, FALSE, NULL, NULL);
swtpm12->ops = &swtpm_tpm12_ops;

return swtpm12;
Expand All @@ -2049,12 +2058,14 @@ struct swtpm12 *swtpm12_new(gchar **swtpm_exec_l, const gchar *state_path,
struct swtpm2 *swtpm2_new(gchar **swtpm_exec_l, const gchar *state_path,
const gchar *keyopts, const gchar *logfile,
int *fds_to_pass, size_t n_fds_to_pass,
const gchar *json_profile)
const gchar *json_profile,
const gchar *profile_remove_disabled_param)
{
struct swtpm2 *swtpm2 = g_malloc0(sizeof(struct swtpm2));

swtpm_init(&swtpm2->swtpm, swtpm_exec_l, state_path, keyopts, logfile,
fds_to_pass, n_fds_to_pass, TRUE, json_profile);
fds_to_pass, n_fds_to_pass, TRUE, json_profile,
profile_remove_disabled_param);
swtpm2->ops = &swtpm_tpm2_ops;

return swtpm2;
Expand Down
4 changes: 3 additions & 1 deletion src/swtpm_setup/swtpm.h
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,7 @@ struct swtpm {
size_t n_fds_to_pass;
gboolean is_tpm2;
const char *json_profile;
const char *profile_remove_disabled_param;

GPid pid;
int ctrl_fds[2];
Expand All @@ -92,7 +93,8 @@ struct swtpm12 *swtpm12_new(gchar **swtpm_prg_l, const gchar *tpm_state_path,
struct swtpm2 *swtpm2_new(gchar **swtpm_prg_l, const gchar *tpm_state_path,
const gchar *swtpm_keyopts, const gchar *logfile,
int *fds_to_pass, size_t n_fds_to_pass,
const gchar *profile_rules);
const gchar *profile_rules,
const gchar *profile_remove_disabled_param);

void swtpm_free(struct swtpm *);

Expand Down
29 changes: 25 additions & 4 deletions src/swtpm_setup/swtpm_setup.c
Original file line number Diff line number Diff line change
Expand Up @@ -559,14 +559,16 @@ static int init_tpm2(unsigned long flags, gchar **swtpm_prg_l, const gchar *conf
const gchar *tpm2_state_path, const gchar *vmid, const gchar *pcr_banks,
const gchar *swtpm_keyopt, int *fds_to_pass, size_t n_fds_to_pass,
unsigned int rsa_keysize, const gchar *certsdir,
const gchar *user_certsdir, const gchar *json_profile)
const gchar *user_certsdir, const gchar *json_profile,
const gchar *profile_remove_disabled_param)
{
struct swtpm2 *swtpm2;
struct swtpm *swtpm;
int ret;

swtpm2 = swtpm2_new(swtpm_prg_l, tpm2_state_path, swtpm_keyopt, gl_LOGFILE,
fds_to_pass, n_fds_to_pass, json_profile);
fds_to_pass, n_fds_to_pass, json_profile,
profile_remove_disabled_param);
if (swtpm2 == NULL)
return 1;
swtpm = &swtpm2->swtpm;
Expand Down Expand Up @@ -992,6 +994,12 @@ static void usage(const char *prgname, const char *default_config_file)
"--profile <json-profile>\n"
" : Configure swtpm with the given profile.\n"
"\n"
"--profile-remove-disabled check|fips-host\n"
" : Instruct swtpm to remove algorithms that may be disabled by\n"
" FIPS mode on the host from 'custom' profile.\n"
" check: algorithms are tested.\n"
" fips-host: no testing.\n"
"\n"
"--version : Display version and exit\n"
"\n"
"--help,-h : Display this help screen\n\n",
Expand Down Expand Up @@ -1167,7 +1175,7 @@ static int print_capabilities(char **swtpm_prg_l, gboolean swtpm_has_tpm12,
", \"cmdarg-write-ek-cert-files\", \"cmdarg-create-config-files\""
", \"cmdarg-reconfigure-pcr-banks\""
"%s"
", \"cmdarg-profile\""
", \"cmdarg-profile\", \"cmdarg-profile-remove-disabled\""
""
" ], "
"\"profiles\": [%s], "
Expand Down Expand Up @@ -1297,6 +1305,7 @@ int main(int argc, char *argv[])
{"print-capabilities", no_argument, NULL, 'y'},
{"reconfigure", no_argument, NULL, 'R'},
{"profile", required_argument, NULL, 'I'},
{"profile-remove-disabled", required_argument, NULL, 'j'},
{"help", no_argument, NULL, 'h'},
{NULL, 0, NULL, 0}
};
Expand Down Expand Up @@ -1326,6 +1335,7 @@ int main(int argc, char *argv[])
g_autofree gchar *certsdir = NULL;
g_autofree gchar *user_certsdir = NULL;
g_autofree gchar *json_profile = NULL;
g_autofree gchar *profile_remove_disabled_param = NULL;
gchar *tmp;
gchar **swtpm_prg_l = NULL;
gchar **tmp_l = NULL;
Expand Down Expand Up @@ -1515,6 +1525,17 @@ int main(int argc, char *argv[])
g_free(json_profile);
json_profile = g_strdup(optarg);
break;
case 'j': /* --profile-remove-disabled */
if (strcmp(optarg, "fips-host") != 0 &&
strcmp(optarg, "check") != 0) {
fprintf(stderr,
"Unsupported parameter for --profile-remove-disabled: %s\n",
optarg);
goto error;
}
g_free(profile_remove_disabled_param);
profile_remove_disabled_param = g_strdup(optarg);
break;
case '?':
case 'h': /* --help */
usage(argv[0], config_file);
Expand Down Expand Up @@ -1798,7 +1819,7 @@ int main(int argc, char *argv[])
} else {
ret = init_tpm2(flags, swtpm_prg_l, config_file, tpm_state_path, vmid, pcr_banks,
swtpm_keyopt, fds_to_pass, n_fds_to_pass, rsa_keysize, certsdir,
user_certsdir, json_profile);
user_certsdir, json_profile, profile_remove_disabled_param);
}

if (ret == 0) {
Expand Down
3 changes: 2 additions & 1 deletion tests/_test_print_capabilities
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,8 @@ exp='\{ "type": "swtpm_setup", '\
'"features": \[ "tpm-1.2",( "tpm-2.0",)? "cmdarg-keyfile-fd", "cmdarg-pwdfile-fd", '\
'"tpm12-not-need-root", "cmdarg-write-ek-cert-files", "cmdarg-create-config-files", '\
'"cmdarg-reconfigure-pcr-banks"'\
'(, "tpm2-rsa-keysize-2048")?(, "tpm2-rsa-keysize-3072")?(, "cmdarg-profile")? \],'\
'(, "tpm2-rsa-keysize-2048")?(, "tpm2-rsa-keysize-3072")?, "cmdarg-profile", '\
'"cmdarg-profile-remove-disabled" \],'\
'( "profiles": \[ [^]]*\],)? '\
'"version": "[^"]*" \}'
if ! [[ ${msg} =~ ${exp} ]]; then
Expand Down
4 changes: 2 additions & 2 deletions tests/_test_tpm2_print_capabilities
Original file line number Diff line number Diff line change
Expand Up @@ -53,8 +53,8 @@ fi
exp='\{ "type": "swtpm_setup", '\
'"features": \[( "tpm-1.2",)? "tpm-2.0", "cmdarg-keyfile-fd", "cmdarg-pwdfile-fd", '\
'"tpm12-not-need-root", "cmdarg-write-ek-cert-files", "cmdarg-create-config-files", '\
'"cmdarg-reconfigure-pcr-banks"(, "tpm2-rsa-keysize-2048")?(, "tpm2-rsa-keysize-3072")?'\
'(, "cmdarg-profile")? \],'\
'"cmdarg-reconfigure-pcr-banks"(, "tpm2-rsa-keysize-2048")?(, "tpm2-rsa-keysize-3072")?, '\
'"cmdarg-profile", "cmdarg-profile-remove-disabled" \],'\
'( "profiles": \[ [^]]*\],)? '\
'"version": "[^"]*" \}'
if ! [[ ${msg} =~ ${exp} ]]; then
Expand Down
14 changes: 14 additions & 0 deletions tests/test_tpm2_swtpm_setup_profile
Original file line number Diff line number Diff line change
Expand Up @@ -281,6 +281,20 @@ test_swtpm_setup_profile \

echo "Test with custom profile and 'sha1' disabled algorithms passed"

# Check that swtpm adjusts key sizes and sets 'Attributes' when
# '--profile-remove-disabled fips-host' is passed
profile="{\"Name\":\"custom\",\"Description\":\"Test\"} --profile-remove-disabled fips-host"
exp_response="\{\"ActiveProfile\":\{\"Name\":\"custom\",.*,\"Algorithms\":\".*,rsa-min-size=2048,.*,ecc-min-size=224,.*\",\"Attributes\":\"no-sha1-signing,no-sha1-verification,no-unpadded-encryption\",\"Description\":\"Test\"\}\}"
test_swtpm_setup_profile "${workdir}" "${profile}" "${exp_response}" "" "" "" "0"

profile="{\"Name\":\"custom\",\"Attributes\":\"no-sha1-signing\",\"Description\":\"Test\"} --profile-remove-disabled fips-host"
test_swtpm_setup_profile "${workdir}" "${profile}" "${exp_response}" "" "" "" "0"

profile="{\"Name\":\"custom\",\"Attributes\":\"fips-host\",\"Description\":\"Test\"} --profile-remove-disabled fips-host"
exp_response="\{\"ActiveProfile\":\{\"Name\":\"custom\",.*,\"Algorithms\":\".*,rsa-min-size=2048,.*,ecc-min-size=224,.*\",\"Attributes\":\"fips-host\",\"Description\":\"Test\"\}\}"
test_swtpm_setup_profile "${workdir}" "${profile}" "${exp_response}" "" "" "" "0"

echo "Tests with custom profile and --profile-remove-disabled option passed"

# Copy TPM 2 state written by libtpms v0.9 and have the TPM read and re-write the state.
# The size of the state file must not change since we don't want the profile to be
Expand Down

0 comments on commit 3643de1

Please sign in to comment.