swtpm/src
Stefan Berger 9b3add22ac swtpm: If necessary send TPM2_Shutdown() before TPMLIB_Terminate()
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>
2022-08-18 09:50:16 -04:00
..
selinux selinux: Replace hardcoded install path with @prefix@ 2022-06-28 07:55:20 -04:00
swtpm swtpm: If necessary send TPM2_Shutdown() before TPMLIB_Terminate() 2022-08-18 09:50:16 -04:00
swtpm_bios swtpm_bios: Use TPM2_ALG_SHA256 as parameter to TPM2_IncrementalSelfTest 2022-06-13 21:46:56 -04:00
swtpm_cert swtpm_cert: Test for NULL pointer returned by malloc 2022-05-25 18:54:58 -04:00
swtpm_ioctl swtpm_ioctl: Only close file descriptor if >= 0 (Coverity) 2022-08-16 09:00:42 -04:00
swtpm_localca swtpm_localca: Add comment that failure to read optsfile is not an issue 2022-05-25 18:54:58 -04:00
swtpm_setup swtpm_setup: Add missing newline to help screen 2022-08-10 20:38:59 -04:00
utils swtpm: Move ARRAY_LEN and min #define's to swtpm_utils.h 2021-10-07 14:27:10 -04:00
Makefile.am Move swtpm_localca sources from samples/ to src/ 2021-07-25 08:52:13 -04:00