If necessary send a TPM2_Shutdown() command to libtpms before processing
CMD_INIT. However, this is only necessary for a TPM 2 and only if the
TPM2_Shutdown command has not been sent by the client (VM TPM driver) as
the last command as it should do under normal circumstances, for example
upon graceful VM shutdown.
This fixes a bug where abrupt VM resets may trigger the TPM 2's dictionary
attack lockout logic due to the TPM 2 not having received a TPM2_Shutdown
command before it was reset using CMD_INIT for example. An OS driver is
typically supposed to send a TPM2_Shutdown to the TPM 2 but an abrupt VM
reset prevents it.
There are 3 control commands where this needs to be done since they
call TPMLIB_Terminate():
- CMD_STOP:
This command is typically called before setting the state blobs of the
TPM or before configuring the buffer size [QEMU, test cases].
- CMD_INIT:
This command is called for resetting and initializing the TPM 2.
- CMD_SHUTDOWN:
This command is called for a graceful shutdown of the TPM 2.
There are no negative side effects to be expected if TPM2_Shutdown()
is sent before any of these. Also, since none of these are sent before
the state of the TPM is marshalled (for migration for example) migrated
state will not have a TPM2_Shutdown() applied to it (accidentally).
Edk2 sends a sequence of TPM2_Shutdown(SU_STATE) + TPM2_GetRandom()
before suspend-to-ram. Upon wake up a CMD_INIT is sent to the TPM to
reset it, which in this case now requires a TPM2_Shutdown(SU_STATE)
to be sent to the TPM 2 so that certain TPM 2 state is available
again upon resume. To avoid invaliding the SU_STATE, first send a
TPM2_Shutdown(SU_STATE) in *all cases* and only if this fails send a
TPM2_Shutdown(SU_CLEAR). This way the internal state is preserved and
the VM (or user) are expected to use TPM2_Startup(SU_CLEAR) when
staring up the TPM 2 and no previous state needs to be resumed.
Note: The VM's firmware is trusted to use SU_CLEAR under normal circum-
stances and SU_STATE upon resume. So it wouldn't restore the state if
it wasn't needed.
Note: The TPM 2 spec describes the command as follows:
"This command is used to prepare the TPM for a power cycle. The
shutdownType parameter indicates how the subsequent TPM2_Startup() will be
processed.[...]
This command saves TPM state but does not change the state other than the
internal indication that the context has been saved. The TPM shall
continue to accept commands. If a subsequent command changes TPM state
saved by this command, then the effect of this command is nullified. The
TPM MAY nullify this command for any subsequent command rather than check
whether the command changed state saved by this command. If this command
is nullified and if no TPM2_Shutdown() occurs before the next
TPM2_Startup(), then the next TPM2_Startup() shall be
TPM2_Startup(CLEAR)."
Buglink: https://bugzilla.redhat.com/show_bug.cgi?id=2087538
Signed-off-by: Stefan Berger <stefanb@linux.ibm.com>
Track the last command processed by the TPM so we can determine whether
we may need to send a TPM2_Shutdown() before reset of the TPM 2.
Introduce a variable lastCommand to help track the last command that
was sent to the TPM 2.
In relation to deciding whether a TPM2_Shutdown() needs to be sent, the
tracking of the last-sent command is merely an optimization since for
example a VM with EDK2 will send a TPM2_Shutdown() followed by a
TPM2_GetRandom() upon suspend-to-ram, thus indicating that the last
command was TPM2_GetRandom(). However, under most circumstances it helps
to avoid sending an additional TPM2_Shutdown() if the OS TPM driver sent
one already.
When the suspended VM resume swtpm gets a CMD_INIT that requires swtpm
to decide whether a TPM2_Shutdown() needs to be sent and per the last-sent
command it will then send a TPM2_Shutdown(SU_STATE) as in the abrupt
termination case.
Signed-off-by: Stefan Berger <stefanb@linux.ibm.com>
If seccomp-syscalls.h lags behind the syscall definition of __NR_xyz then
the __SNR_xyz #define is not available. Therefore, switch to check for
__SNR_xyz #define because they are available if __NR_xyz is available.
Signed-off-by: Stefan Berger <stefanb@linux.ibm.com>
Implement fips_mode_enabeld() to check whether FIPS is enabledand
use the new function to check for FIPS mode enablement before
trying to disable it.
Signed-off-by: Stefan Berger <stefanb@linux.ibm.com>
Rename disable_fips_mode() to fips_mode_disable() amd move into
tpmlib_start() after TPMLIB_MainInit(). Clean up the duplicate
prototype.
Signed-off-by: Stefan Berger <stefanb@linux.ibm.com>
The project wouldn't compile on my ubuntu 20.04.1 based system with the error message:
```
CC libswtpm_libtpms_la-seccomp_profile.lo
In file included from seccomp_profile.c:44:
seccomp_profile.c: In function ‘create_seccomp_profile’:
seccomp_profile.c:105:9: error: ‘__SNR_fs_mount’ undeclared (first use in this function)
105 | SCMP_SYS(fs_mount),
| ^~~~~~~~
seccomp_profile.c:105:9: note: each undeclared identifier is reported only once for each function it appears in
```
Additionally, there were some duplicates in the profile.
Signed-off-by: Hans Niklas Jacob <hnj@posteo.de>
Extend usage of the FILE_OPS_LOCK to prevent other threads from reading or
writing commands or doing ioctls while the current thread is reading a
response. This prevents a race condition where ptm_read_offset is set to 0
by a thread writing a new command to the device while the current thread
is reading a response from the device and needs this offset.
Resolves: https://github.com/stefanberger/swtpm/issues/725
Signed-off-by: Stefan Berger <stefanb@linux.ibm.com>
The swtpm man page also covers the CUSE TPM, so do not maintain the
swtpm_cuse man page anymore but replace it with a redirect to the swtpm
mane page instead.
Signed-off-by: Stefan Berger <stefanb@linux.ibm.com>
Restrict the opening of the CUSE device to one single file descriptor. We
can modify the CUSE TPM in this way since the kernel's /dev/tpm0 cannot be
opened multiple times, either, and the CUSE TPM should behave in the same
way.
Adjust test the partial reads case to only open CUSE device file once by
using a python program. Close the open file descriptor 100 before using
swtpm_ioctl to avoid failures.
Signed-off-by: Stefan Berger <stefanb@linux.ibm.com>
Move swtpm_open_cmddev call into swtpm_cmd_tx since the latter function is
always called in a subshell that previously inherited the file descriptor
opened by the test cases. Remove swtpm_cmd_tx from nearly all test cases
and also remove closing of file descriptor 100 via 'exec 100>&-' from test
cases since this is not necessary anymore.
Signed-off-by: Stefan Berger <stefanb@linux.ibm.com>
Revert the change from the previous patch that shows an error when
TPMLIB_ChooseTPMVersion fails but rather ignore the error as before.
If a TPM 2 is supported then tpm-2.0 capability verb will be shown
and if a TPM 1.2 is supported then tpm-1.2 will be shown, thus
allowing someone reading the JSON to determine what is supported.
Signed-off-by: Stefan Berger <stefanb@linux.ibm.com>
All callers to capabilities_print_json() call TPMLIB_ChooseTPMVersion
right before. Move it into the function now and check the return
code.
Signed-off-by: Stefan Berger <stefanb@linux.ibm.com>
Implement get_swtpm_capabilities() and call it from two existing functions
that now become a lot simpler.
Signed-off-by: Stefan Berger <stefanb@linux.ibm.com>
Commit 6559a902 implemented support for the startup-xyz flags for the CUSE
interface but the capability has not been advertised.
Adjust test cases to reflect the new verb being shown for
--print-capabilities.
Signed-off-by: Stefan Berger <stefanb@linux.ibm.com>
PCR Bank verification needs bash, so check for bash. While at it use the
autoconf shell construct macros over raw shell syntax which is slightly
more portable.
Examples:
./configure --enable-default-pcr-banks=sha256,sha920
checking which PCR banks to activate by default... configure: error: sha256,sha920 is an invalid list of PCR banks
./configure --enable-default-pcr-banks=sha256,sha512
checking which PCR banks to activate by default... sha256,sha512
./configure
checking which PCR banks to activate by default... sha256
Signed-off-by: William Roberts <william.c.roberts@intel.com>
Replace the hardcoded install path in src/selinux/swtpm.fc and
src/selinux/swtpmcuse.fc with @prefix@ and append .in to these files so
that they are generated when running configure.
Add the selinux policy input files with their suffix to the CLEANFILES
variable so they get cleaned up and 'make distcheck' works.
Resolves: https://github.com/stefanberger/swtpm/issues/711
Signed-off-by: Stefan Berger <stefanb@linux.ibm.com>
While libtpms does not provide any means to disable FIPS-disabled crypto
algorithms from being used, work around the issue by simply disabling the
FIPS mode of OpenSSL if it is enabled. If it cannot be disabled, exit
swtpm with a failure message that it cannot be disabled. If FIPS mode
was successfully disabled, print out a message as well.
Buglink: https://bugzilla.redhat.com/show_bug.cgi?id=2090219
Signed-off-by: Stefan Berger <stefanb@linux.ibm.com>
For being able to run tests with runtime-deactivated SHA-1 (in libtpms),
do not test with SHA-1 bank anymore.
Signed-off-by: Stefan Berger <stefanb@linux.ibm.com>
Do not use TPM2_ALG_SHA1 anymore as parameter to TPM2_IncrementalSelfTest()
so that this also works when SHA1 support in libtpms is runtime-disabled.
Signed-off-by: Stefan Berger <stefanb@linux.ibm.com>
Handle the case where an unknown blobtype is given and therefore
cannot be translated to a filename and blobname is NULL. Previously
this would have lead to an error when trying to read the file, now
we handle the failure case earlier.
Signed-off-by: Stefan Berger <stefanb@linux.ibm.com>
To avoid an overflowing expression cast '1' to uint64_t before shifting
it and assigning it to a uint64_t variable. In practice this kind of
overflow would never happen because there aren't that many available
PCR banks.
Signed-off-by: Stefan Berger <stefanb@linux.ibm.com>
Initialize the 'res' variable at the beginning of the function
even though this wouldn't be necessary in this case.
Signed-off-by: Stefan Berger <stefanb@linux.ibm.com>
Add a comment stating that failure to read the optsfile is not an
issue since the optsfile does not need to exist.
Signed-off-by: Stefan Berger <stefanb@linux.ibm.com>
Initialize pubek_len even though it isn't necessary to do so since
it will be initialized in the first function to which it is passed.
However, Coverity complains about pubek_len passed to print_as_hex()
not being initialized, even though this is not possible.
Signed-off-by: Stefan Berger <stefanb@linux.ibm.com>
Avoid a memory leaks if --tcp is provided multiple times by freeing
the previously allocated memory in the tcp_hostname variable.
Signed-off-by: Stefan Berger <stefanb@linux.ibm.com>
Close the file descriptor at the end of the main function.
To avoid closing random file descriptors initialize it with -1.
Signed-off-by: Stefan Berger <stefanb@linux.ibm.com>
Avoid memory leaks if one of the parameters --tcp, --tpm-device,
or --unix was passed multiple times by freeing the previously
parsed value.
Signed-off-by: Stefan Berger <stefanb@linux.ibm.com>
Avoid memory leaks if one of the parameters --modulus, --ecc-x,
or --ecc-y was passed multiple times by freeing the previously
parsed value.
Signed-off-by: Stefan Berger <stefanb@linux.ibm.com>
Commit 2d3deaef29 forgot to move the check for whether the lock file has
already been opened into the new function opening the lock file and there-
fore the lock file is now opened whenever swtpm gets a PTM_INIT. This fix
prevents the reopening of the lockfile if it has already been opened.
Otherwise many PTM_INIT's will lead to failure since no more files can
be opened.
Signed-off-by: Stefan Berger <stefanb@linux.ibm.com>
Remove support for TPM state files that didn't have the header
because they were created some time before v0.1.
Signed-off-by: Stefan Berger <stefanb@linux.ibm.com>
Use libtpms v0.6.6 and recreate the TPM 2 state file with header.
Start swtpm with the existing state files and have it rewrite the
volatiles state (swtpm_ioctl -v) and permanent state (tssnvdefine
+ tssnvundefine) files so that the header is on the files.
Signed-off-by: Stefan Berger <stefanb@linux.ibm.com>
Recreate TPM 2 state files that didn't have a header. Use latest
version of libtpms from the stable-0.6.0 branch to create the
state that more recent version have to be able to read.
Signed-off-by: Stefan Berger <stefanb@linux.ibm.com>
Recreate a TPM 1.2 state file with header.
The state of the TPM 1.2 must be initialized with Startup(ST_CLEAR)
and then saved so that the proper error code appears as a result
when running this test.
The PCR values was originally created by extending PCR 10 with
sha1("test"). This was recreated using this sequence:
s=$(echo -en test | sha1sum | cut -d " " -f1 | sed -n 's/\([a-f0-9]\{2\}\)/\\x\1/pg')
echo -en $s > input
tss1extend -ha 10 -if input
Signed-off-by: Stefan Berger <stefanb@linux.ibm.com>
Recreate TPM 1.2 state files with similar content but with the state
file header. The older versions of the state files were created before
the header was introduced in v0.1. The goal is to be able to get rid
of code supporting pre-v0.1 files that had no header.
The PCR values was originally created by extending PCR 10 with
sha1("test"). This was recreated using this sequence:
s=$(echo -en test | sha1sum | cut -d " " -f1 | sed -n 's/\([a-f0-9]\{2\}\)/\\x\1/pg')
echo -en $s > input
tss1extend -ha 10 -if input
Signed-off-by: Stefan Berger <stefanb@linux.ibm.com>
An apparmor profile was added for Debian-based distributions in order to
increase security. This blocks swtpm from accessing restricted and unnecessary
files, folders, and network interfaces. swtpm works as normal alongside libvirt
and its configurations, however users may run into issues when using swtpm on
its own when providing it with a restricted directory. The apparmor profile can
be modified to include additional permissions by creating and adding to the
file /etc/apparmor.d/local/usr.bin.swtpm.
Signed-off-by: Lena Voytek <lena.voytek@canonical.com>