Avoid this type of complaint from static analyzer:
src/swtpm/tpmlib.c:392:37: note: Result of 'malloc' is converted to a
pointer of type 'unsigned char', which is incompatible with sizeof
operand type 'struct tpm_resp_header'
Signed-off-by: Stefan Berger <stefanb@linux.ibm.com>
OSSL_PARAM_construct_utf8_string takes a char * as parameter.
The OpenSSL code base casts constant strings to char *, so we can do this
also.
Signed-off-by: Stefan Berger <stefanb@linux.ibm.com>
serverdata will be assiged a const char * later on, therefore make it a
const char *. This can then also be passed into options_parse.
Signed-off-by: Stefan Berger <stefanb@linux.ibm.com>
Some function pass a const char * into the options parse function.
Therefore, convert it to accept a const char * now.
Signed-off-by: Stefan Berger <stefanb@linux.ibm.com>
Extend the list of SWTPM_INFO flags with recently added flags for
TPMLIB_GetInfo. Use the CMD_GET_INFO control channel command to get
the currently active profile for a TPM 2 from swtpm and display it in
the log unless it is reconfigured.
Signed-off-by: Stefan Berger <stefanb@linux.ibm.com>
Ignore the remove-disabled parameter on non-'custom' profile identified
by return value '1'. Switch to negative return values in the called function.
Extend a test case to ensure that the --profile-remove-disabled option
on swtpm_setup, which is passed through to swtpm, has no effect on 'null'
and 'default-v1' profiles.
Signed-off-by: Stefan Berger <stefanb@linux.ibm.com>
Very old OpenSSL versions (e.g., 1.1.0i) are using /dev/urandom to get
entropy while newer ones are using the getrandom syscall that does not
need the device file. In some environments access to the created
/dev/urandom device file may not work (EACCESS; chroot test case) and
then OpenSSL will start failing operations that depend on good entropy.
Therefore, check the status of the random number generator after chroot.
Signed-off-by: Stefan Berger <stefanb@linux.ibm.com>
HMAC+sha1 may be restricted next, so test for it but do not support
forced removal of support for it.
Signed-off-by: Stefan Berger <stefanb@linux.ibm.com>
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>
Implement a function that checks whether a crypto algorithm identified by
TPM algorithm identifiers is disabled.
Signed-off-by: Stefan Berger <stefanb@linux.ibm.com>
strv_remove: Remove matches from a 2nd array in a 1st array
strv_dedup: Remove duplicates in an array
strv_extend: Append elements of a 2nd array to a 1st array
Signed-off-by: Stefan Berger <stefanb@linux.ibm.com>
Convert check_rsaes to check_rsa_encryption that can also be used for
testing of unpadded RSA encryption.
Signed-off-by: Stefan Berger <stefanb@linux.ibm.com>
Do not ignore the padding parameter passed to swtpm_rsasign but use
it as parameter to the OpenSSL function.
Change "rsapss" to "tsassa" in one case where it was wrong.
Also rename swtpm_rsasign to swtpm_rsa_sign.
Signed-off-by: Stefan Berger <stefanb@linux.ibm.com>
Commit 96fe5afa forgot to add cmdarg-print-profiles to the list of
capabilities. Also fix typo in the man page and sort shown output
to match application output.
Fixes: 96fe5afa ("swtpm: Add support for --print-profiles option")
Signed-off-by: Stefan Berger <stefanb@linux.ibm.com>
To avoid setting the environment variable OPENSSL_ENABLE_SHA1_SIGNATURES
check whether SHA1 signature support is disabled in the TPM 2 profile.
It is disabled if either 'fips-host' or the pair 'no-sha1-signing' and
'no-sha1-verification' are found among the enabled attributes.
Signed-off-by: Stefan Berger <stefanb@linux.ibm.com>
Use TPMLIB_WasManufactured to check whether a profile was applied since a
new instance was created. If a profile was given and no new TPM 2 instance
was created then display an error message and exit with an error code.
This avoids silently ignoring a provided profile that was not applied
since the TPM 2 instance already existed.
Make sure that a profile is only applied once by swtpm by clearing the
json_profile once TPMLIB_MainInit succeeded.
Signed-off-by: Stefan Berger <stefanb@linux.ibm.com>
Get the list of enabled 'RuntimeAlgorithms' from libtpms and determine
whether any of these enabled algorithms is disabled in OpenSSL due to FIPS
mode. If FIPS mode on the host is enabled then disabled FIPS mode in
OpenSSL so that the TPM 2 can function properly.
The following algorithms are disabled when OpenSSL is in FIPS mode:
- camellia
- rsaes
- tdes
- ECC keys <224 bits
- RSA keys <2048 bits
Per openssl-ciphers man page it should be possible to disable the following
algorithms use by cipher-suites:
- AES128, AES256, AES
- CAMELLIA128, CAMELLIA256, CAMELLIA
- 3DES
- SHA1, SHA, SHA256, SHA384
- CBC
Note: It's not clear at what API level these are disabled. I have not been able
to use !SHA256 to disabled SHA256.
Also test whether signatures with SHA1 are working and enable them by setting
OPENSSL_ENABLE_SHA1_SIGNATURES=1.
The following output is expected for RHEL 9.x and CentOS 9 but does not
appear on Fedora 40 since there sha1 signatures are not (yet) disabled.
> swtpm socket \
--tpmstate dir=/tmp/myvtpm \
--ctrl type=tcp,port=2322 \
--server type=tcp,port=2321,disconnect \
--flags not-need-init,startup-clear \
--log level=0 \
--tpm2 \
--profile name=null
Warning: Profile-enabled algorithms contain disabled 'RSA-1024-sign(SHA1, pkcs1-pss)'
Warning: Setting OPENSSL_ENABLE_SHA1_SIGNATURES=1
Signed-off-by: Stefan Berger <stefanb@linux.ibm.com>
Check whether the bufferSize parameter is too small and an underflow of the
expression bufferSize - offset could theoretically occur. However, in
practice this will never happen since the caller will always provide a
bufferSize of around 4kb.
Signed-off-by: Stefan Berger <stefanb@linux.ibm.com>
Since 'comma1' will always be true combine it with cmdarg_profile into one
string formatting parameter following the same formatting as further above.
Signed-off-by: Stefan Berger <stefanb@linux.ibm.com>
If the user did not provide the profile on the command line read the
default profile from the swtpm_setup.conf configuration file.
Signed-off-by: Stefan Berger <stefanb@linux.ibm.com>
Add support for --print-profiles option to print all profiles supported
by libtpms.
Usage:
swtpm socket --tpm2 --print-profiles | jq
Signed-off-by: Stefan Berger <stefanb@linux.ibm.com>
Print a list of names of profiles implemented by libtpms as part of the
capabilities JSON. The profiles map will only be visible if libtpms v0.10
with the TPMLIB_SetProfile() API is used.
swtpm_setup --print-capabilities --tpm2 | jq
{
"type": "swtpm_setup",
"features": [
[...]
],
"profiles": [
"default-v1",
"null",
"custom"
],
"version": "0.10.0"
}
Signed-off-by: Stefan Berger <stefanb@linux.ibm.com>
Print a list of names of profiles implemented by libtpms as part of the
capabilities JSON. The profiles map will only be visible if libtpms v0.10
with the TPMLIB_SetProfile() API is used.
swtpm socket --print-capabilities --tpm2| jq
{
"type": "swtpm",
"features": [
[...]
],
"profiles": {
"names": [
"default-v1",
"null",
"custom"
],
...
},
"version": "0.10.0"
}
Signed-off-by: Stefan Berger <stefanb@linux.ibm.com>
Display the new capability verb 'cmdarg-profile' indicating that the
--profile option with the name= and profile= parameters is supported.
Signed-off-by: Stefan Berger <stefanb@linux.ibm.com>
Add support for the --profile option for a TPM 2. The 'name=' parameter
allows a user to select a specific profile available in libtpms. The
'profile=' parameter allows a user to pass a JSON profile that must
contain a name field with a profile known to libtpms. It may contain
an algorithm field that has a comma-separated list of verbs with the
names of algorithms that the TPM 2 is supposed to provide.
The --profile option only has an effect the first time a TPM 2 is started
since afterwards whenever the state of the TPM 2 is read, the profile
found in the state is being used.
Signed-off-by: Stefan Berger <stefanb@linux.ibm.com>
Allow passing a JSON map as part of an option value in the format of
--foo name={...},... Prior to this patch this would not have worked since
the option values were broken apart around commas, which a map may also
contain. Now, if a '{' is following the '=', the value is attempted to be
parsed as a JSON map and the end of the map is searched considering
possibly embedded maps.
Signed-off-by: Stefan Berger <stefanb@linux.ibm.com>
If the user did not provide the RSA keysize to use try to read it from
setup_setup.conf and if nothing is found there fall back to using the
internal default RSA keysize (2048).
Signed-off-by: Stefan Berger <stefanb@linux.ibm.com>
Factor-out read_file_lines from get_default_pcr_banks and pass the array
of lines from the config file into get_default_pcr_banks now. Now other
functions will also be able to access the lines from the config file
without having to re-read the config file.
Signed-off-by: Stefan Berger <stefanb@linux.ibm.com>
Since swtpm does not use concurrency while writing state files, set
the process umask to 0 when the state file is created or truncated for
writing and the user requested specific mode bits. This avoids an
additional syscall in the possibly timing critical path when processing
a TPM command and having to write the state.
Signed-off-by: Stefan Berger <stefanb@linux.ibm.com>
The mode bits that the user provided were only applied with open() and were
subject to masking with the value of current umask. When umask was set to
0027 the test case test_commandline was failing because the mode bits on
the create TPM state file were not the expected ones (masked by umask).
Therefore, set the mode bits using fchmod if the user provided them,
otherwise do not set them. This way the mode bits will be set to the values
the user requested.
Currently the directory storage backend was setting the mode bits to the
default value (0640) *after* opening the TPM state file. Now, if the user
did not provide any mode bits then the mode bits will be set so that the
file can be written to as owner. This ensures that at least mode bits 0600
are set by default. However, if the user provided mode bit flags then these
will be used without modification.
Signed-off-by: Stefan Berger <stefanb@linux.ibm.com>
Replace mkstemp with g_mkstemp_full and pass parameters that lead to
the same mode bits and file opening flags and mkstemp had. This addresses
a Coverity complaint regarding missing application of umask before
mkstemp.
Signed-off-by: Stefan Berger <stefanb@linux.ibm.com>
Due to a significant change in the targeted SELinux policy re-develop
the SELinux policy for swtpm. New rules in swtpm_libvirt.te are needed
when libvirt causes new interactions between swtpm and other types.
Also consider extensions to the SELinux policy previously added due to
domain XML and command lines described in the following patches:
- 63825b296c
- 7dac1dbf6f
Also:
- add rules related to user_tmp_t are due to the following paths being used
in session mode: /run/user/*/libvirt/qemu/run/swtpm
- add rules for swtpm_t accessing qemu_var_run_t file/dir/sockfile
- add rules for swtpm_localca (newly installed F40 system) needed once when
/var/lib/swtpm-localca is empty and files there are created
Signed-off-by: Stefan Berger <stefanb@linux.ibm.com>
Coverity is complaining that thread_busy needs to be locked before
reading. For consistency reasons now also lock thread_busy before reading
it. However, in this case it does not make a difference whether this lock
is held when reading thread_busy since file_ops_lock is held when the
thread_busy flag is set and when it is read with a call to this function
(worker_thread_is_busy). Also while the thread is busy no further commands
can be submitted and it can then reset the thread_busy flag without holding
the file_ops_lock.
Signed-off-by: Stefan Berger <stefanb@linux.ibm.com>
Coverity is complaining that ptm_response in the worker_thread needs to
be locked via the file_ops_lock since it is always locked when
ptm_response is accessed. However, once the thread has been started any
concurrent modification of the ptm_response is prevented with the
thread_busy flag. Therefore, add comments to the thread and ptm_reponse
variable about the locking.
Signed-off-by: Stefan Berger <stefanb@linux.ibm.com>
Even though concurrency is not possible before ptm_cuse_lowlevel_main
is called lock the file_ops_lock since Coverity is complaining that
- g_lastCommand in ptm_send_startup
- ptm_repsonse in ptm_send_startup
- tpm_running in main
are not locked. For consistency reasons now also lock these variables
even before activation of concurrency.
Signed-off-by: Stefan Berger <stefanb@linux.ibm.com>
Lock the file_ops_lock before reading the tpm_running variable so that
access to access to it is serialized among all possible threads.
Signed-off-by: Stefan Berger <stefanb@linux.ibm.com>
Separate the return code returned from change_fd_flags from the current/
original flags of the file descriptor. Return the flags in an optional
integer.
Signed-off-by: Stefan Berger <stefanb@linux.ibm.com>
The help screen states that --decryption and --allow-signing require
--tpm2. Enforce this now also when checking flag combination since
neither flags would have any effect for a TPM 1.2.
Signed-off-by: Stefan Berger <stefanb@linux.ibm.com>
On error, the caller will call options_value_free() so don't free
ovs->options to avoid a double free.
Fixes: c94a1c4cbd ("swtpm: Fix memory leak in case realloc fails")
Signed-off-by: Ross Lagerwall <ross.lagerwall@citrix.com>
If we've accepted a connection fd during the main loop, close it once
the main loop terminates.
Signed-off-by: Ross Lagerwall <ross.lagerwall@citrix.com>
Test cases using swtpm_localca were failing because swtpm_localca
now picked up the swtpm_cert installed in /usr/bin/swtpm_cert rather
than the one in the PATH. This revert fixes the issue and users will
have to adjust their PATH for out-of-PATH installations.
Resolves: https://github.com/stefanberger/swtpm/issues/829
Signed-off-by: Stefan Berger <stefanb@linux.ibm.com>
x509 certificate serial numbers can be up to 20 bytes long.
Support this via gmp library.
A serial number must not have its most significant bit set, which
would indicate a negative number. If this is the case, insert '0'
as the first byte.
Signed-off-by: Stefan Berger <stefanb@linux.ibm.com>
swtpm_localca may also receive the key parameters of other keys than
the ek, therefore introduce the --key alias for --ek and rename the
variable ekparmas to key_params throughout the code.
Extend the man page to describe the --key option as an alias that
is to be used for other public key parameters than specifically those
of an ek.
Signed-off-by: Stefan Berger <stefanb@linux.ibm.com>
To make the function creating filenames for keys less ek-specific,
pass the key_type, such as "ek", into this function.
Signed-off-by: Stefan Berger <stefanb@linux.ibm.com>
To be able to extend the flags_to_certfiles array with new certifcates
while carrying new flags for new certificate, mask-out exising EK and
platform certificate flags and set the cert_flags variable with it to limit
the view of the entries in the table.
Signed-off-by: Stefan Berger <stefanb@linux.ibm.com>
With a memoryBacking node added to the libvirt domain XML, the unlink
permission on user_tmp_t:sockfile becomes necessary to avoid an avc
denial.
<currentMemory unit='KiB'>2097152</currentMemory>
<memoryBacking>
<hugepages>
<page size='2048' unit='KiB'/>
</hugepages>
</memoryBacking>
Also add the unlink permission to the other occurrences of sock_file.
Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=2165142
Signed-off-by: Stefan Berger <stefanb@linux.ibm.com>
The following command line did not function on an x86_64 host due to missing
SELinux rules:
virt-install -v \
--name fedora-38-aarch64 \
--ram 4096 \
--disk path=fedora-38.img,cache=none \
--nographics \
--os-variant fedora38 \
--import \
--virt-type=qemu \
--arch aarch64 \
--check all=off
Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=2228423
Signed-off-by: Stefan Berger <stefanb@linux.ibm.com>
swtpm_setup and swtpm_localca may be run by a toolstack with log
messages going to a pipe via stdout. Set stdout to be unbuffered to
avoid log messages being lost if the process terminates unexpectedly.
Signed-off-by: Ross Lagerwall <ross.lagerwall@citrix.com>
The --version option was using the wrong goto label error rather than
out to now also exit with exitcode 0.
Signed-off-by: Stefan Berger <stefanb@linux.ibm.com>
Close the file descriptors passed to the swtpm process on the parent
side for faster detection of errors in the swtpm process that can
occur if swtpm was passed a profile that it cannot run with.
Signed-off-by: Stefan Berger <stefanb@linux.ibm.com>
On busy systems TSC_PhysicalPresence may time out when used with short
duration, so use medium duration instead.
Signed-off-by: Stefan Berger <stefanb@linux.ibm.com>
In case swtpm does not start properly the write() to it may work but
then the read() gets stuck. Detect a failed swtpm by adding a poll()
before the read(). Use some extended durations considering possibly
busy systems.
A terminating swtpm instance can be caused when an unacceptable
profile is passed.
Signed-off-by: Stefan Berger <stefanb@linux.ibm.com>
Fix the display of long responses that require calling PTM_GET_INFO
multiple times to get parts of the response from increasing offsets
until the whole response has been received.
Long responses are only returned when libtpms has profiles support and
several flags are passed to PTM_GET_INFO.
Signed-off-by: Stefan Berger <stefanb@linux.ibm.com>
To support install paths that are not covered by $PATH, and still allow
swtpm_setup and swtpm_localca to find swtpm and swtpm_cert executables,
implement find_program() to prepend the install path if only the program
name is given and otherwise fall back to g_find_program_in_path().
Update the man page stating that swtpm from the installation directory
(BINDIR) is tried to be used before one is attempted to be found in
the PATH.
Resolves: https://github.com/stefanberger/swtpm/issues/795
Signed-off-by: Stefan Berger <stefanb@linux.ibm.com>
The compiler (though wrongly) identifies that the @argv variable
inside of get_swtpm_capabilities() function cam be used
uninitialized. While this is a spurious warning, it's common
practice to initialize g_autofree variables to NULL.
Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
When opening a log file fails (--log file=/some/path) for
whatever reason the @logfd variable is left set to -1 (the retval
of open()). And due to how _logprintf() is written, the
subsequent attempt to log this failure (logprintf()) returns too
early not printing the useful error.
Therefore, restore the original (CONSOLE_LOGGING) value.
Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
If swtpm_setup is configured with a log file, it launches swtpm
configured with the same log file. If not, swtpm_setup logs will go to
stdout/stderr and it should configure swtpm to do the same.
Signed-off-by: Ross Lagerwall <ross.lagerwall@citrix.com>
Move existing exit label before the return statement and add another
label that includes the free(filebuffer). This avoids a false positive
by 'gcc -fanalyzer' that seems to think that free(filebuffer)
would double-free filebuffer after filebuffer = realloc(tmp, ..)
failure.
Signed-off-by: Stefan Berger <stefanb@linux.ibm.com>
Return TPM_FAIL if SWTPM_NVRAM_DecryptData() is called without a key or
if an unhandle type of encryption mode is encountered. Previously this
function would return no error but also would not do any decryption if
no key was provided. Consequently, it would then also not return a byte
array with decrypted data which in turn could led to potential NULL
pointer accesses in subsequent calls. However, all current callers check
whether they have a valid key before they call this function. So the
change is primarily done for static analyzers, such as gcc -fanalyzer,
to ease code analysis.
Signed-off-by: Stefan Berger <stefanb@linux.ibm.com>
Extend the capabilities JSON and show the support for the terminate
parameter of the --ctrl option.
Adjust test cases.
Signed-off-by: Stefan Berger <stefanb@linux.ibm.com>
Implement support for the terminate parameter for the control channel
option so that swtpm terminates once the control channel connection is
lost. The primary use case is QEMU that holds the control channel
permanently.
Resolves: https://github.com/stefanberger/swtpm/issues/753
Signed-off-by: Stefan Berger <stefanb@linux.ibm.com>
Set tpm_running = false after TPMLIB_Terminate() call on CMD_SHUTDOWN
to prevent a call to tpmlib_maybe_send_tpm2_shutdown() at the exit
of the mainloop.
Signed-off-by: Stefan Berger <stefanb@linux.ibm.com>
Also send TPM2_Shutdown when swtpm is terminated by a signal or due to
lost connection (--terminate option). Previously supported reasons for
sending the TPM2_Shutdown were primarily related to commands sent via
the command channel.
Signed-off-by: Stefan Berger <stefanb@linux.ibm.com>
Increase the number of locking retries to 300 over 3 seconds
instead of 100 over 1 second. This gives the failing side more
time to release the lock.
Signed-off-by: Stefan Berger <stefanb@linux.ibm.com>
Implement CMD_LOCK_STORAGE / PTM_LOCK_STORAGE for a user to be able to
lock the storage of the storage backend (if supported) after its lock
has been released for example when the 'savestate' blob was received
while the TPM state was migrated.
Also adjust test case and extend man pages.
Signed-off-by: Stefan Berger <stefanb@linux.ibm.com>
Advertise the capability of supporting the --migration option
in the capabilies JSON that now has the cmdarg-migration verb:
$ swtpm socket --print-capabilities | jq
{
"type": "swtpm",
"features": [
"tpm-1.2",
"tpm-2.0",
"tpm-send-command-header",
"flags-opt-startup",
"flags-opt-disable-auto-shutdown",
"cmdarg-seccomp",
"cmdarg-key-fd",
"cmdarg-pwd-fd",
"cmdarg-print-states",
"cmdarg-migration",
"nvram-backend-dir",
"nvram-backend-file"
],
"version": "0.8.0"
}
Adjust test cases and extend man page.
Signed-off-by: Stefan Berger <stefanb@linux.ibm.com>
Implement the release-lock-outgoing parameter for the --migration option
that causes the storage lock to be released once the 'savestate' blob
transfer has been initiated. To not release the lock too early users must
first get the 'permanent' and 'volatile' state blobs and the 'savestate'
blob must be transferred as the last blob.
When migrating a VM the migration may fail and execution will then resume
on the originating side. In this fallback case the swtpm on the
destination side may need some time to terminate and release the lock.
Therefore, add a loop to the code attempting to re-lock the storage
directory on the source side for a few times until on the destination
side swtpm has released the lock. Retry the locking for 100 times
with 10ms in between. The retries will only ever be necessary if a TPM
command is immediately executed upon resume [this may be difficult
to test]. The negative side effects of this could be that the loop is not
long enough to grab the lock or that a short-duration TPM command will
time out inside the VM due to the retries delaying when it is processed.
Signed-off-by: Stefan Berger <stefanb@linux.ibm.com>
Resolves: https://github.com/stefanberger/swtpm/issues/724
Introduce the --migration option along with the 'incoming' parameter
that allows to defer the locking of the storage until either
- the reception of the TPM's state is started
- a TPM command is about to be processed
Note that the reception of CMD_INIT does not enable the storage lock.
Signed-off-by: Stefan Berger <stefanb@linux.ibm.com>
Resolves: https://github.com/stefanberger/swtpm/issues/724
Move the locking of the storage into tpmlib_start() after the call to
TPMLIB_MainInit() which was previously doing the locking when the prepare
function was called in the SWTPM_NVRAM_Init() callback invoked by
TPMLIB_MainInit().
This allows for conditional locking in tpmlib_start() using a flag later
on.
Signed-off-by: Stefan Berger <stefanb@linux.ibm.com>
On OpenBSD openssl/fips.h is not available and FIPS_mode() is not
available, so implement a stub for fips_mode_enabled().
Signed-off-by: Stefan Berger <stefanb@linux.ibm.com>
Advertise the availability of the chroot option with the cmdarg-chroot
verb. Document it in the man page.
Signed-off-by: Stefan Berger <stefanb@linux.ibm.com>
Add an option to enter a chroot after starting swtpm. This is useful for
sandboxing purposes. When this option is used, it is expected that swtpm
is started as root and the --runas option is used to subsequently drop
privileges (otherwise the chroot could be escaped).
Signed-off-by: Jennifer Herbert <jennifer.herbert@citrix.com>
Signed-off-by: Ross Lagerwall <ross.lagerwall@citrix.com>
Address the following compilation error on Debian:
In file included from /usr/include/seccomp.h:821,
from seccomp_profile.c:44:
seccomp_profile.c: In function 'create_seccomp_profile':
seccomp_profile.c:115:9: error: '__NR_mount_setattr' undeclared (first use in this function)
115 | SCMP_SYS(mount_setattr),
| ^~~~~~~~
seccomp_profile.c:115:9: note: each undeclared identifier is reported only once for each function it appears in
seccomp_profile.c:172:9: error: '__NR_quotactl_fd' undeclared (first use in this function)
172 | SCMP_SYS(quotactl_fd),
| ^~~~~~~~
We need to do this since they are defined like this:
#define __SNR_mount_setattr __NR_mount_setattr
#define __SNR_quotactl_fd __NR_quotactl_fd
Signed-off-by: Stefan Berger <stefanb@linux.ibm.com>
Include openssl/opensslv.h to avoid the following error on Ubuntu:
fips.c: In function 'fips_mode_enabled':
fips.c:61:16: error: implicit declaration of function 'EVP_default_properties_is_fips_enabled' [-Werror=implicit-function-declaration]
61 | int mode = EVP_default_properties_is_fips_enabled(NULL);
| ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Resolves: https://github.com/stefanberger/libtpms/issues/345
Signed-off-by: Stefan Berger <stefanb@linux.ibm.com>
Introduce disable-auto-shutdown flag for the --flags option to disable
the sending of TPM2_Shutdown() if swtpm determines that it needs to send
this command to a TPM 2 before device reset or swtpm program termination.
Signed-off-by: Stefan Berger <stefanb@linux.ibm.com>
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>
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>
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>
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>
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>