Skip to content

Commit

Permalink
Merge 9fca277 into 346b3d6
Browse files Browse the repository at this point in the history
  • Loading branch information
stefanberger committed Jan 31, 2023
2 parents 346b3d6 + 9fca277 commit 040bb75
Show file tree
Hide file tree
Showing 36 changed files with 1,548 additions and 48 deletions.
5 changes: 5 additions & 0 deletions .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -78,13 +78,15 @@ matrix:
CONFIG="--with-openssl --prefix=${PREFIX}"
CHECK="distcheck"
RUN_TEST="1"
LIBTPMS_GIT_CHECKOUT="origin/stefanberger/runtime_disable_algorithms.v3"
- dist: bionic
env: PREFIX="/usr"
CONFIG="--with-openssl --prefix=/usr --enable-test-coverage"
SUDO="sudo"
CHECK="check"
SWTPM_TEST_IBMTSS2="1"
SWTPM_TEST_STORE_VOLATILE="1"
LIBTPMS_GIT_CHECKOUT="origin/stefanberger/runtime_disable_algorithms.v3"
before_script:
- sudo apt-get -y install tss2
- sudo pip install cpp-coveralls
Expand All @@ -103,6 +105,7 @@ matrix:
CONFIG="--with-openssl --prefix=${PREFIX} --without-seccomp"
SUDO="sudo"
CHECK="check"
LIBTPMS_GIT_CHECKOUT="origin/stefanberger/runtime_disable_algorithms.v3"
- env: CFLAGS="-fsanitize=address -g -fno-omit-frame-pointer -fno-sanitize-recover"
LIBTPMS_CFLAGS="-fsanitize=address -g -fno-omit-frame-pointer -fno-sanitize-recover"
LIBTPMS_CONFIG="--disable-use-openssl-functions"
Expand All @@ -112,6 +115,7 @@ matrix:
CONFIG="--with-openssl --prefix=${PREFIX} --without-seccomp"
SUDO="sudo"
CHECK="check"
LIBTPMS_GIT_CHECKOUT="origin/stefanberger/runtime_disable_algorithms.v3"
- env: CFLAGS="-fsanitize=undefined -g -fno-omit-frame-pointer -fno-sanitize-recover"
LIBTPMS_CFLAGS="-fsanitize=undefined -g -fno-omit-frame-pointer -fno-sanitize-recover"
LIBS="-lubsan"
Expand All @@ -120,3 +124,4 @@ matrix:
CONFIG="--with-openssl --prefix=${PREFIX}"
SUDO="sudo"
CHECK="check"
LIBTPMS_GIT_CHECKOUT="origin/stefanberger/runtime_disable_algorithms.v3"
11 changes: 10 additions & 1 deletion configure.ac
Original file line number Diff line number Diff line change
Expand Up @@ -186,6 +186,14 @@ AC_CHECK_LIB(tpms,
TPMLIB_ChooseTPMVersion,[true],
AC_MSG_ERROR("libtpms 0.6 or later is required")
)
AC_CHECK_LIB(tpms,
[TPMLIB_SetProfile],
[AC_DEFINE_UNQUOTED([HAVE_LIBTPMS_SETPROFILE_API], 1,
[whether TPMLIB_SetProfile API is available])
libtpms_has_setprofile="yes"],
[libtpms_has_setprofile="no"]
)

AC_SUBST([LIBTPMS_LIBS])

AC_CHECK_LIB(c, clock_gettime, LIBRT_LIBS="", LIBRT_LIBS="-lrt")
Expand Down Expand Up @@ -626,7 +634,8 @@ printf "with_chardev : %5s (no = no chardev interface)\n" $with_chardev
printf "with_vtpm_proxy : %5s (no = no vtpm proxy support; Linux only)\n" $with_vtpm_proxy
printf "with_seccomp : %5s (no = no seccomp profile; Linux only)\n" $with_seccomp
printf "\n"
printf "active PCR banks : %s\n" $DEFAULT_PCR_BANKS
printf "active PCR banks : %s\n" $DEFAULT_PCR_BANKS
printf "TPM 2 profile support : %s\n" $libtpms_has_setprofile
echo
echo "Version to build : $PACKAGE_VERSION"
echo "Crypto library : $cryptolib"
Expand Down
79 changes: 78 additions & 1 deletion man/man8/swtpm.pod
Original file line number Diff line number Diff line change
Expand Up @@ -333,7 +333,8 @@ may contain the following:
"flags-opt-disable-auto-shutdown",
"rsa-keysize-1024",
"rsa-keysize-2048",
"rsa-keysize-3072"
"rsa-keysize-3072",
"cmdarg-profile"
],
"version": "0.7.0"
}
Expand Down Expand Up @@ -408,6 +409,12 @@ The I<--flags> option supports the I<disable-auto-shutdown> flag.
The TPM 2 supports the shown RSA key sizes. If none of the
rsa-keysize verbs is shown then only RSA 2048 bit keys are supported.

=item B<cmarg-profile> (since v0.8)

The option <--profile> is supported to set a profile for a TPM 2 using either
the option parameter I<name=> to select a profile by its name or I<profile=>
to provide a JSON-formatted profile.

=back

=item B<--print-states> (since v0.7)
Expand Down Expand Up @@ -451,6 +458,76 @@ from swtpm. To avoid releasing the lock too early the 'permanent'
and 'volatile' state blobs must be received before the 'savestate'
blob.

=item B<--profile name=E<lt>profile-nameE<gt>|profile=E<lt>json-profileE<gt>> (since v0.8)

This option allows to set a profile for a TPM 2 using either the option parameter
I<name=> to select a built-in profile by its name or I<profile=> to provide a
JSON-formatted profile that must provide the name of a built-in profile and may
also include a list of algorithms that restricts the algorithms that a TPM 2
enables.

The profile can only be set the very first time that a TPM 2 instance is
started and for as long as no state file exists. The profile cannot be changed
anymore afterwards and, if passed again using this option, will be silently
ignored.

Note that profiles may disable algorithms that are considered mandatory for
a TPM 2, such as RSA-PSS. However, FIPS-enforcement on the host disables
algorithms in the OpenSSL crypto library that the TPM 2 would normally
provide (RSA-PSS, Camellia, TDES, ...) and therefore they cannot be made
available by the TPM 2. Because of this it may be required that a profile be used
to avoid the TPM 2 entering failure mode upon self-testing. The effect of the
disablement of algoritms may be that certain programs and test suites requiring
them may not work correctly anymore. Therefore, profiles other than the default
profile have to be applied very carefully to avoid unnecessary application
failures where the only solution would be to not run them on a host that has
FIPS-enforcement enabled.

To see the list of algorithms that are supported and can be disabled one
may use the I<swtpm_ioctl> tool like this:

$ swtpm_ioctl --tcp :2322 --info 0x08 | jq
{
"RuntimeAlgorithms": {
"Implemented": "rsa,rsa-min-size=1024,tdes,tdes-min-size=128,sha1,hmac,aes,aes-min-size=128,mgf1,keyedhash,xor,sha256,sha384,sha512,null,rsassa,rsaes,rsapss,oaep,ecdsa,ecdh,ecdaa,sm2,ecschnorr,ecmqv,kdf1-sp800-56a,kdf2,kdf1-sp800-108,ecc,ecc-min-size=192,symcipher,camellia,camellia-min-size=128,cmac,ctr,ofb,cbc,cfb,ecb",
"CanBeDisabled": "tdes,sha1,sha512,rsassa,rsaes,rsapss,ecmqv,camellia,cmac,ctr,ofb,cbc,ecb",
"Enabled": "rsa,rsa-min-size=1024,tdes,tdes-min-size=128,sha1,hmac,aes,aes-min-size=128,mgf1,keyedhash,xor,sha256,sha384,sha512,null,rsassa,rsaes,rsapss,oaep,ecdsa,ecdh,ecdaa,sm2,ecschnorr,ecmqv,kdf1-sp800-56a,kdf2,kdf1-sp800-108,ecc,symcipher,camellia,camellia-min-size=128,cmac,ctr,ofb,cbc,cfb,ecb",
"Disabled": ""
}
}


To see the list of available profiles one may use the I<swtpm_ioctl> tool like
this:

$ swtpm_ioctl --tcp :2322 --info 0x20 | jq
{
"AvailableProfiles": [
{
"name": "default",
"stateFormatLevel": 1
},
{
"name": "fips-2022",
"stateFormatLevel": 1,
"commands": "0x11f-0x122,0x124-0x12e,0x130-0x140,0x142-0x159,0x15b-0x15e,0x160-0x165,0x167-0x174,0x176-0x178,0x17a-0x193,0x197",
"algorithms": "rsa,rsa-min-size=2048,hmac,aes,aes-min-size=128,mgf1,keyedhash,xor,sha256,sha384,sha512,null,rsassa,rsaes,oaep,ecdsa,ecdh,ecdaa,sm2,ecschnorr,ecmqv,kdf1-sp800-56a,kdf2,kdf1-sp800-108,ecc,symcipher,cmac,ctr,ofb,cbc,cfb,ecb,ecc-min-size=256"
}
]
}


To see the current profile that a TPM 2 instance is running with one may use the
I<swtpm_ioctl> tool:

$ swtpm_ioctl --tcp :2322 --info 0x10 | jq
{
"ActiveProfile": {
"name": "default",
"stateFormatLevel": 1
}
}

=item B<-h|--help>

Display usage info.
Expand Down
25 changes: 25 additions & 0 deletions man/man8/swtpm_setup.pod
Original file line number Diff line number Diff line change
Expand Up @@ -193,6 +193,31 @@ size is used.
This option allows the reconfiguration of the active PCR banks of a
TPM 2 using the I<--pcr-banks> option.

=item B<--profile <json-profile>>

Configure a TPM 2 with the given profile. Example profiles look
like this:

{"name": "null"}

{"name": "default"}

{
"name":"default",
"algorithms":"rsa,rsa-min-size=1024,tdes-min-size=128,hmac,aes,\
aes-min-size=128,mgf1,keyedhash,xor,sha256,sha384,\
sha512,null,rsassa,rsaes,rsapss,oaep,ecdsa,ecdh,ecdaa,\
sm2,ecschnorr,ecmqv,kdf1-sp800-56a,kdf2,kdf1-sp800-108,\
ecc,ecc-min-size=192,symcipher,camellia,\
camellia-min-size=128,cmac,ctr,ofb,cbc,cfb,ecb"
}


The JSON profile must contain the 'name' field with a name of a profile
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<--print-capabilities> (since v0.2)

Print capabilities that were added to swtpm_setup after version 0.1.
Expand Down
2 changes: 2 additions & 0 deletions src/swtpm/Makefile.am
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,7 @@ libswtpm_libtpms_la_CFLAGS = \
$(CFLAGS) \
$(HARDENING_CFLAGS) \
$(GLIB_CFLAGS) \
$(JSON_GLIB_CFLAGS) \
$(LIBSECCOMP_CFLAGS)

libswtpm_libtpms_la_LDFLAGS = \
Expand All @@ -84,6 +85,7 @@ libswtpm_libtpms_la_LDFLAGS = \
libswtpm_libtpms_la_LIBADD = \
$(LIBTPMS_LIBS) \
$(GLIB_LIBS) \
$(JSON_GLIB_LIBS) \
$(LIBRT_LIBS) \
$(LIBSECCOMP_LIBS) \
$(LIBCRYPTO_LIBS)
Expand Down
98 changes: 96 additions & 2 deletions src/swtpm/capabilities.c
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,9 @@
#include <libtpms/tpm_library.h>
#include <libtpms/tpm_error.h>

#include <json-glib/json-glib.h>

#include "compiler_dependencies.h"
#include "capabilities.h"
#include "logging.h"
#include "swtpm_nvstore.h"
Expand Down Expand Up @@ -114,6 +117,73 @@ static int get_rsa_keysize_caps(char **keysizecaps)
goto cleanup;
}

#ifdef HAVE_LIBTPMS_SETPROFILE_API

static int get_profiles(gchar **profiles)
{
char *info_data = TPMLIB_GetInfo(32 /*TPMLIB_INFO_AVAILABLE_PROFILES*/);
JsonParser *jp = NULL;
JsonReader *jr = NULL;
g_autoptr(GError) error = NULL;
JsonNode *root;
gint i, num;
int ret = 0;
GString *gstr = g_string_new(NULL);

jp = json_parser_new();

if (!json_parser_load_from_data(jp, info_data, -1, &error)) {
logprintf(STDERR_FILENO,
"Could not parse JSON data: %s\n", error->message);
goto error;
}

root = json_parser_get_root(jp);
jr = json_reader_new(root);

if (!json_reader_read_member(jr, "AvailableProfiles")) {
logprintf(STDERR_FILENO,
"Missing 'AvailableProfiles' field: %s\n",
info_data);
goto error_unref_jr;
}

num = json_reader_count_elements(jr);
for (i = 0; i < num; i++) {
if (!json_reader_read_element(jr, i) ||
!json_reader_read_member(jr, "name")) {
logprintf(STDERR_FILENO,
"Failed to traverse JSON list.\n");
goto error_unref_jr;
}
g_string_append_printf(gstr, "%s\"%s\"",
i > 0 ? ", " : " ",
json_reader_get_string_value(jr));
json_reader_end_element(jr);
json_reader_end_element(jr);
}


error_unref_jr:
g_object_unref(jr);

error:
g_object_unref(jp);
*profiles = g_string_free(gstr, false);
free(info_data);

return ret;
}

#else

static int get_profiles(gchar **profiles SWTPM_ATTR_UNUSED)
{
return 0;
}

#endif

int capabilities_print_json(bool cusetpm, TPMLIB_TPMVersion tpmversion)
{
char *string = NULL;
Expand All @@ -129,6 +199,13 @@ int capabilities_print_json(bool cusetpm, TPMLIB_TPMVersion tpmversion)
char *keysizecaps = NULL;
const char *nvram_backend_dir = "\"nvram-backend-dir\", ";
const char *nvram_backend_file = "\"nvram-backend-file\"";
#ifdef HAVE_LIBTPMS_SETPROFILE_API
const char *cmdarg_profile = "\"cmdarg-profile\"";
#else
const char *cmdarg_profile = NULL;
#endif
g_autofree gchar *profiles = NULL;
bool comma1;

/* ignore errors */
TPMLIB_ChooseTPMVersion(tpmversion);
Expand All @@ -137,17 +214,28 @@ int capabilities_print_json(bool cusetpm, TPMLIB_TPMVersion tpmversion)
if (ret < 0)
goto cleanup;

if (tpmversion == TPMLIB_TPM_VERSION_2) {
ret = get_profiles(&profiles);
if (ret < 0)
goto cleanup;
}

if (TPMLIB_ChooseTPMVersion(TPMLIB_TPM_VERSION_1_2) == TPM_SUCCESS)
with_tpm1 = "\"tpm-1.2\", ";
if (TPMLIB_ChooseTPMVersion(TPMLIB_TPM_VERSION_2) == TPM_SUCCESS)
with_tpm2 = "\"tpm-2.0\", ";

comma1 = cmdarg_profile || profiles;

n = asprintf(&string,
"{ "
"\"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%s%s%s%s%s%s%s%s%s"
" ], "
#ifdef HAVE_LIBTPMS_SETPROFILE_API
"\"profiles\": [%s ], "
#endif
"\"version\": \"" VERSION "\" "
"}",
with_tpm1,
Expand All @@ -164,7 +252,13 @@ int capabilities_print_json(bool cusetpm, TPMLIB_TPMVersion tpmversion)
true ? "\"cmdarg-migration\", " : "",
nvram_backend_dir,
nvram_backend_file,
keysizecaps ? keysizecaps : ""
keysizecaps ? keysizecaps : "",
comma1 ? ", " : "",
cmdarg_profile ? cmdarg_profile : ""
#ifdef HAVE_LIBTPMS_SETPROFILE_API
,
profiles ? profiles : ""
#endif
);

if (n < 0) {
Expand Down
Loading

0 comments on commit 040bb75

Please sign in to comment.