Fix an HMAC signing issue that may causes an out-of-bounds access in a
TPM2B that in turn was running into an assert() in libtpms causing an
abort. The signing issue was due to an inconsistent pairing of the signKey
and signScheme parameters, where the signKey is ALG_KEYEDHASH key and
inScheme is an ECC or RSA scheme.
This fixes CVE-2025-49133.
Signed-off-by: Stefan Berger <stefanb@linux.ibm.com>
Address a false positive issue detect by Coverity (CID 1517797)
about *buflen.
Per this assignment of buflen
cached_blobs[st].buflen = buffer ? buflen : BUFLEN_EMPTY_BUFFER;
the following is true:
If cached_blobs[].buffer is NULL then *buflen = BUFLEN_EMPTY_BUFFER
If cached_blobs[].buffer is not NULL then *buflen != BUFLEN_EMPTY_BUFFER
Signed-off-by: Stefan Berger <stefanb@linux.ibm.com>
Cast the '1' to UINT64 before shifting it.
Since the shift value is always below 32 it would have never exceeded
the 32bit value it was using before the cast.
Signed-off-by: Stefan Berger <stefanb@linux.ibm.com>
Address the following Coverity complaint (1550494) by filtering out bad
input values:
"Expression i--, which is equal to 65535, where i is known to be equal
to 0, underflows the type that receives it, an unsigned integer 16 bits
wide."
aSize is typcially 2048 and n is always >= 1 per the input parameter.
Therefore no side-effects are expected from this filter.
Signed-off-by: Stefan Berger <stefanb@linux.ibm.com>
Resolve the following Coverity complaint:
"Expression command->sessionNum - 1U, which is equal to 4294967295,
where command->sessionNum is known to be equal to 0, underflows the
type that receives it, an unsigned integer 32 bits wide."
Signed-off-by: Stefan Berger <stefanb@linux.ibm.com>
Resolve the following Coverity complaint by removing assignment to offset:
"Assigning value from offset + 148UL to offset here, but that stored
value is overwritten before it can be used."
Signed-off-by: Stefan Berger <stefanb@linux.ibm.com>
Resolve the following Coverity complaint:
"Using uninitialized value eccPublic when calling TPMS_ECC_POINT_Unmarshal."
Signed-off-by: Stefan Berger <stefanb@linux.ibm.com>
When decryption fails then return TPM_RC_VALUE rather than TPM_RC_FAILURE.
The old error code could indicate to an application or driver that
something is wrong with the TPM (has possibly gone into failure mode) even
though only the decryption failed, possibly due to a wrong key.
Signed-off-by: Stefan Berger <stefanb@linux.ibm.com>
Fedora Rawhide and CentOS 10 do not support OpenSSL engine anymore.
Therefore, replace include of engine.h with err.h since the engine is not
needed anyway but we only need the prototype of ERR_get_error_line_data.
Add missing includes for evp.h and rsa.h.
Signed-off-by: Stefan Berger <stefanb@linux.ibm.com>
When an object is later marshalled in TPM2_ContextSave, the publicOnly
attribute isn't taken into account and therefore potentially stale
sensitive information can be marshalled, which is a problem if the
buffer sizes it contains have values that are too large - this
triggers assertion failures.
Avoid this by clearing out the sensitive area upon ObjectLoad if not
provided, making the behaviour consistent with when a fresh, unused,
object entry is used.
Signed-off-by: Rob Shearman <rob@graphiant.com>
Sync with upstream to fix issue in CryptParameterEncryption() from TPM 2
errate v1.4 2.6.1:
"The functions CryptParameterEncryption() and CryptParameterDecryption() in
the reference code in Part 4, 10.2.6.6.5 and 10.2.6.6.6 do not correctly
check the size of the parameter buffer to be encrypted or decrypted. To fix
the issue, the functions should be corrected to check that the parameter
buffer (a TPM2B type field) is at least 2 bytes in length and should use
the function UINT16_Unmarshal() to read the size of the buffer instead of"
BYTE_ARRAY_TO_UINT16().
[...]
The fixed CryptParameterEncryption() function will enter failure mode and
return TPM_RC_FAILURE if the internal response buffer does not contain
enough data for the UINT16 size field."
Signed-off-by: Stefan Berger <stefanb@linux.ibm.com>
Fix the following issue from TPM 2 errata v1.4 2.6.3:
"The function CryptGenerateKeyDes() in the reference code in Part 4,
0.2.9.2.3 does not correctly check the symmetric key size provided in the
sensitive parameter. To fix the issue, the function will check that the
size of the requested TDES key is a multiple of 8 bytes or otherwise the
TPM will return TPM_RC_SYMMETRIC."
Signed-off-by: Stefan Berger <stefanb@linux.ibm.com>
Fix the missing buffer size check that the TPM 2 errata v1.4 mentions in
2.6.2 by adding a buffer size check before reading 2 bytes from a
TPM2B_NAME buffer. There's no known CVE for this.
Signed-off-by: Stefan Berger <stefanb@linux.ibm.com>
Check that there are sufficient bytes in the buffer before reading the
cipherSize from it. Also, reduce the bufferSize variable by the number
of bytes that make up the cipherSize to avoid reading and writing bytes
beyond the buffer in subsequent steps that do in-place decryption.
This fixes CVE-2023-1017 & CVE-2023-1018.
Signed-off-by: Stefan Berger <stefanb@linux.ibm.com>
Do not set the RSA_FLAG_NO_BLINDING on RSA keys anymore. The BoringSSL
documentation states the following:
"RSA_FLAG_NO_BLINDING disables blinding of private operations, which is
a dangerous thing to do. It is deprecated and should not be used. It will
be ignored whenever possible."
So, follow this documentation. OpenSSL does not seem to say much about it.
Signed-off-by: Stefan Berger <stefanb@linux.ibm.com>
Check the secret size against the size of the buffer, not the size
member that has not been set yet.
Reported by Coverity.
Signed-off-by: Ross Lagerwall <ross.lagerwall@citrix.com>
The build environment used by OSS-Fuzz reports this error.
In file included from /src/libtpms/src/tpm_debug.c:42:
/src/libtpms/src/tpm_debug.h:69:9: error: 'printf' macro redefined [-Werror,-Wmacro-redefined]
#define printf(...) TPMLIB_LogPrintf(__VA_ARGS__);
: ^
/usr/include/x86_64-linux-gnu/bits/stdio2.h:110:11: note: previous definition is here
# define printf(...) \
^
1 error generated.
The simple fix is to #undef printf in case it is #define'd.
Signed-off-by: Stefan Berger <stefanb@linux.ibm.com>
Openssl 3.0 did return an error if EVP_PKEY_CTX_set0_rsa_oaep_label was called
with label size 0. The function should only be called if the size of the label
is greater 0.
With this fix TPM2_RSA_Encrypt/Decrypt did work with OpenSSL 1.1 and 3.0
for encryption without label.
Signed-off-by: Juergen Repp <juergen.repp@sit.fraunhofer.de>
If s_ContextSlotMask was not set since the TPM 2 was not initialized
by a call to TPM_Manufacture() or the state was not resumed, then
initialize the s_ContextSlotMask to 0xffff.
This situation can occur if a VM with an attached swtpm was started
and the VM's firmware either doesn't support TPM or didn't get to
initialize the vTPM.
The following commands recreated the issue with a SeaBIOS-only VM that
had no attached hard disk but an attached TPM 2:
virsh start BIOS-only-VM ; virsh save BIOS-only-VM save.bin ; \
virsh restore save.bin
Error: Failed to restore domain from save.bin
error: internal error: qemu unexpectedly closed the monitor: \
2022-01-04T19:26:18.835851Z qemu-system-x86_64: tpm-emulator: Setting the stateblob (type 2) failed with a TPM error 0x3 a parameter is bad
2022-01-04T19:26:18.835899Z qemu-system-x86_64: error while loading state for instance 0x0 of device 'tpm-emulator'
2022-01-04T19:26:18.835929Z qemu-system-x86_64: load of migration failed: Input/output error
Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=2035731
Signed-off-by: Stefan Berger <stefanb@linux.ibm.com>
exp_array_size is always initialized if `rc == TPM_RC_SUCCESS` and never used
if `rc != TPM_RC_SUCCESS` but some compilers have trouble noticing this.
Signed-off-by: kpcyrd <git@rxv.cc>
To avoid timeouts on short-running commands, such as TPM2_PCR_Extend,
avoid triggering the writing of the permanent state of the TPM 2
if only the clock was updated. So the clock by itself will not cause
the permanent state to be written out anymore but there have to be
other reasons as well.
The state will still be written out upon a TPM2_Shutdown, which is
supposed to be the last command to be sent to the TPM when shutting
down the VM/vTPM. Also, the permanent state will still carry the
latest clock value if it is retrieved via control channel for
VM/VTPM suspend.
The case that may be affected, but is of lesser importance, is the one
where swtpm's volatile state is written to storage using 'swtpm_ioctl -v'
and then swtpm is terminated and restarted (similar to suspend/resume)
and the permanent state file is read from storage but does not contain
the latest clock value. In this case the go.clock will be updated when
the first command after resume is executed.
This fixes the swtpm issue https://github.com/stefanberger/swtpm/issues/597.
Signed-off-by: Stefan Berger <stefanb@linux.ibm.com>
Instead of using -Wno-deprecated-declarations use
-DOPENSSL_SUPPRESS_DEPRECATED to only suppress OpenSSL deprecated
declarations warnings.
Signed-off-by: Stefan Berger <stefanb@linux.ibm.com>
OpenSSL 3.0 has changed the signature of EVP_PKEY_get0_RSA() from
struct rsa_st *EVP_PKEY_get0_RSA(EVP_PKEY *pkey);
to
const struct rsa_st *EVP_PKEY_get0_RSA(const EVP_PKEY *pkey);
We now have to use EVP_PKEY_get1_RSA with this signature so that we can
access the RSA key. The signature of that function hasn't changed between
OpenSSL 1.1.0 and 3.0.0.
struct rsa_st *EVP_PKEY_get1_RSA(EVP_PKEY *pkey);
Free the additional reference held on the RSA key.
Signed-off-by: Stefan Berger <stefanb@linux.ibm.com>
Event sequence objects were never properly marshalled and when their state
was saved and later restored their state may have been corrupted. Fix this
now by also marshalling the state of event sequence objects.
Bump up the version of the HASH_OBJECT's header to '3' so that previously
written state can be resumed if an event sequence object is encountered
and we only unmarshal an event sequence object when the version is at least
'3'.
Fixes issue #259.
Signed-off-by: Stefan Berger <stefanb@linux.ibm.com>
Make the expected array size of compile-time constants dependent on
the version of the header. This way we can add elements to the array
while bumping up the version of the header.
Signed-off-by: Stefan Berger <stefanb@linux.ibm.com>
Extend the test case data generation script with sm4. Since several
distros' openssl do not support sm4, we need to test for whether sm4
is supported by the installed openssl.
Signed-off-by: Stefan Berger <stefanb@linux.ibm.com>
Use the EC_POINT_set/get_affine_coordinates function on OpenSSL >= 1.1.
These function are a 1:1 replacement for the
EC_POINT_set/get_affine_coordinates_GFp functions and are available
since OpenSSL 1.1 and are deprecated in OpenSSL 3.0.
This patch addresses one aspect of the OpenSSL 3.0 issues raised in
issue #215.
Signed-off-by: Stefan Berger <stefanb@linux.ibm.com>
The NVRAM entries in s_indexOrderlyRam array do not need to contain a
0-sized terminating node. Instead, the entries may fill up this 512
byte array so that no NV_RAM_HEADER structure fits anymore. The fact
that no more NV_RAM_HEADER structure fits is also an indicator for the
last entry. We need to account for this in the code marshalling and
unmarshalling the entries so that we stop marshalling the entries
then and similarly stop unmarshalling.
Signed-off-by: Stefan Berger <stefanb@linux.ibm.com>
Initialize a while OBJECT before using it. This is necessary since
an OBJECT may also be used as a HASH_OBJECT via the ANY_OBJECT
union and that HASH_OBJECT can leave bad size inidicators in TPM2B
buffer in the OBJECT. To get rid of this problem we reset the whole
OBJECT to 0 before using it. This is as if the memory for the
OBJECT was just initialized.
Signed-off-by: Stefan Berger <stefanb@linux.ibm.com>
Fix the following compiler warning from gcc 10.3.0 by using memcpy
instead of MemoryCopy (fixes issue #229).
tpm2/NVDynamic.c: In function 'NvRamGetEnd':
tpm2/NVDynamic.c:378:12: warning: function may return address of local variable [-Wreturn-local-addr]
378 | return iter;
| ^
tpm2/NVDynamic.c:339:26: note: declared here
339 | NV_RAM_HEADER header;
| ^
tpm2/NVDynamic.c: In function 'NvRamGetIndex':
tpm2/NVDynamic.c:411:12: warning: function may return address of local variable [-Wreturn-local-addr]
411 | return currentAddr;
| ^
tpm2/NVDynamic.c:339:26: note: declared here
339 | NV_RAM_HEADER header;
| ^
Signed-off-by: Stefan Berger <stefanb@linux.ibm.com>
Restore the original value of the memory location where data from
a stream was unmarshalled and the unmarshalled value was found to
be illegal. The goal is to not keep illegal values in memory.
Signed-off-by: Stefan Berger <stefanb@linux.ibm.com>