Compare commits

..

1 Commits

Author SHA1 Message Date
Stefan Berger
625f10b801 ci: Add github actions script
Backport the github actions script from the master branch. In the
coveralls build, use the stable-0.9 branch of swtpm since later versions
of swtpm need later versions of libtpms.

Signed-off-by: Stefan Berger <stefanb@linux.ibm.com>
2025-06-10 09:28:48 -04:00
8 changed files with 47 additions and 175 deletions

11
CHANGES
View File

@ -1,17 +1,6 @@
CHANGES - changes for libtpms CHANGES - changes for libtpms
version 0.9.7: version 0.9.7:
- tpm2: Fix potential out-of-bound access & abort due to HMAC signing issue (CVE-2025-49133)
- tpm2: Remove assigned-to value to offset because it is unused (Coverity)
- tpm2: Insert assert ensuring *buflen != BUFLEN_EMPTY_BUFFER (Coverity)
- tpm2: Address Coverity Issue by casting '1' before shift (CID 1470813)
- tpm2: Filter bad input values to avoid underflow in FindNthSetBit (Coverity)
- tpm2: Address a possible unsigned integer underflow (Coverity)
- tpm2: Remove assigned to value to offset because it is unused (Coverity)
- tpm2: Initialize eccPublic before passing to TPMS_ECC_POINT_Unmarshal (Coverity)
- tpm2: Preserve more *target and restore them if needed (Coverity)
- tpm2: Return TPM_RC_VALUE upon decryption failure
- tpm12: Replace include of engine.h with err.h
- tpm2: Fix issue in CryptParameterEncryption() (TPM 2 errata v1.4) - tpm2: Fix issue in CryptParameterEncryption() (TPM 2 errata v1.4)
- tpm2: Sync fix in TPM2_PolicyAuthorize() with upstream - tpm2: Sync fix in TPM2_PolicyAuthorize() with upstream
- tpm2: Sync CryptParameterDecrypt implementation with upstream - tpm2: Sync CryptParameterDecrypt implementation with upstream

47
debian/changelog vendored
View File

@ -1,52 +1,41 @@
libtpms (0.9.7) RELEASED; urgency=high libtpms (0.9.7) RELEASED; urgency=medium
* tpm2: Fix potential out-of-bound access & abort due to HMAC signing issue (CVE-2025-49133) - tpm2: Fix issue in CryptParameterEncryption() (TPM 2 errata v1.4)
* tpm2: Remove assigned-to value to offset because it is unused (Coverity) - tpm2: Sync fix in TPM2_PolicyAuthorize() with upstream
* tpm2: Insert assert ensuring *buflen != BUFLEN_EMPTY_BUFFER (Coverity) - tpm2: Sync CryptParameterDecrypt implementation with upstream
* tpm2: Address Coverity Issue by casting '1' before shift (CID 1470813) - tpm2: Fix issue related to CryptGenerateKeyDes (TPM 2 errata v1.4)
* tpm2: Filter bad input values to avoid underflow in FindNthSetBit (Coverity) - tpm2: Check size of TPM2B_NAME buffer before reading 2 bytes from it
* tpm2: Address a possible unsigned integer underflow (Coverity)
* tpm2: Remove assigned to value to offset because it is unused (Coverity)
* tpm2: Initialize eccPublic before passing to TPMS_ECC_POINT_Unmarshal (Coverity)
* tpm2: Preserve more *target and restore them if needed (Coverity)
* tpm2: Return TPM_RC_VALUE upon decryption failure
* tpm12: Replace include of engine.h with err.h
* tpm2: Fix issue in CryptParameterEncryption() (TPM 2 errata v1.4)
* tpm2: Sync fix in TPM2_PolicyAuthorize() with upstream
* tpm2: Sync CryptParameterDecrypt implementation with upstream
* tpm2: Fix issue related to CryptGenerateKeyDes (TPM 2 errata v1.4)
* tpm2: Check size of TPM2B_NAME buffer before reading 2 bytes from it
-- Stefan Berger <stefanb@linux.ibm.com> Tue, 10 Jun 2025 00:00:00 -0500 -- Stefan Berger <stefanb@linux.ibm.com> Mon, 14 Aug 2023 09:00:00 -0500
libtpms (0.9.6) RELEASED; urgency=high libtpms (0.9.6) RELEASED; urgency=high
* tpm2: Check size of buffer before accessing it (CVE-2023-1017 & -1018) - tpm2: Check size of buffer before accessing it (CVE-2023-1017 & -1018)
-- Stefan Berger <stefanb@linux.ibm.com> Tue, 28 Feb 2023 09:00:00 -0500 -- Stefan Berger <stefanb@linux.ibm.com> Tue, 28 Feb 2023 09:00:00 -0500
libtpms (0.9.5) RELEASED; urgency=medium libtpms (0.9.5) RELEASED; urgency=medium
* tpm2: Do not set RSA_FLAG_NO_BLINDING on RSA keys anymore - tpm2: Do not set RSA_FLAG_NO_BLINDING on RSA keys anymore
* tpm2: Fix a potential overflow expression (coverity) - tpm2: Fix a potential overflow expression (coverity)
* tpm2: Fix size check in CryptSecretDecrypt - tpm2: Fix size check in CryptSecretDecrypt
-- Stefan Berger <stefanb@linux.ibm.com> Fri, 01 Jul 2022 09:00:00 -0500 -- Stefan Berger <stefanb@linux.ibm.com> Fri, 01 Jul 2022 09:00:00 -0500
libtpms (0.9.4) RELEASED; urgency=medium libtpms (0.9.4) RELEASED; urgency=medium
* tpm: #undef printf in case it is #define'd (OSS-Fuzz) - tpm: #undef printf in case it is #define'd (OSS-Fuzz)
* tpm2: Check return code of BN_div() - tpm2: Check return code of BN_div()
* tpm2: Initialize variables due to gcc complaint (s390x, false positive) - tpm2: Initialize variables due to gcc complaint (s390x, false positive)
* tpm12: Initialize variables due to gcc complaint (s390x, false positive) - tpm12: Initialize variables due to gcc complaint (s390x, false positive)
* build-sys: Fix configure script to support _FORTIFY_SOURCE=3 - build-sys: Fix configure script to support _FORTIFY_SOURCE=3
-- Stefan Berger <stefanb@linux.ibm.com> Mon, 25 Apr 2022 09:00:00 -0500 -- Stefan Berger <stefanb@linux.ibm.com> Mon, 25 Apr 2022 09:00:00 -0500
libtpms (0.9.3) RELEASED; urgency=medium libtpms (0.9.3) RELEASED; urgency=medium
* build-sys: Add probing for -fstack-protector - build-sys: Add probing for -fstack-protector
* tpm2: Do not call EVP_PKEY_CTX_set0_rsa_oaep_label() for label of size (OSSL 3) - tpm2: Do not call EVP_PKEY_CTX_set0_rsa_oaep_label() for label of size (OSSL 3)
-- Stefan Berger <stefanb@linux.ibm.com> Mon, 07 Mar 2022 09:00:00 -0500 -- Stefan Berger <stefanb@linux.ibm.com> Mon, 07 Mar 2022 09:00:00 -0500

14
dist/libtpms.spec vendored
View File

@ -112,19 +112,7 @@ rm -f $RPM_BUILD_ROOT%{_libdir}/libtpms.la
%postun -p /sbin/ldconfig %postun -p /sbin/ldconfig
%changelog %changelog
* Mon Aug 14 2023 Stefan Berger - 0.9.7-1
* Tue Jun 10 2025 Stefan Berger - 0.9.7-1
- tpm2: Fix potential out-of-bound access & abort due to HMAC signing issue (CVE-2025-49133)
- tpm2: Remove assigned-to value to offset because it is unused (Coverity)
- tpm2: Insert assert ensuring *buflen != BUFLEN_EMPTY_BUFFER (Coverity)
- tpm2: Address Coverity Issue by casting '1' before shift (CID 1470813)
- tpm2: Filter bad input values to avoid underflow in FindNthSetBit (Coverity)
- tpm2: Address a possible unsigned integer underflow (Coverity)
- tpm2: Remove assigned to value to offset because it is unused (Coverity)
- tpm2: Initialize eccPublic before passing to TPMS_ECC_POINT_Unmarshal (Coverity)
- tpm2: Preserve more *target and restore them if needed (Coverity)
- tpm2: Return TPM_RC_VALUE upon decryption failure
- tpm12: Replace include of engine.h with err.h
- tpm2: Fix issue in CryptParameterEncryption() (TPM 2 errata v1.4) - tpm2: Fix issue in CryptParameterEncryption() (TPM 2 errata v1.4)
- tpm2: Sync fix in TPM2_PolicyAuthorize() with upstream - tpm2: Sync fix in TPM2_PolicyAuthorize() with upstream
- tpm2: Sync CryptParameterDecrypt implementation with upstream - tpm2: Sync CryptParameterDecrypt implementation with upstream

14
dist/libtpms.spec.in vendored
View File

@ -112,19 +112,7 @@ rm -f $RPM_BUILD_ROOT%{_libdir}/libtpms.la
%postun -p /sbin/ldconfig %postun -p /sbin/ldconfig
%changelog %changelog
* Mon Aug 14 2023 Stefan Berger - 0.9.7-1
* Tue Jun 10 2025 Stefan Berger - 0.9.7-1
- tpm2: Fix potential out-of-bound access & abort due to HMAC signing issue (CVE-2025-49133)
- tpm2: Remove assigned-to value to offset because it is unused (Coverity)
- tpm2: Insert assert ensuring *buflen != BUFLEN_EMPTY_BUFFER (Coverity)
- tpm2: Address Coverity Issue by casting '1' before shift (CID 1470813)
- tpm2: Filter bad input values to avoid underflow in FindNthSetBit (Coverity)
- tpm2: Address a possible unsigned integer underflow (Coverity)
- tpm2: Remove assigned to value to offset because it is unused (Coverity)
- tpm2: Initialize eccPublic before passing to TPMS_ECC_POINT_Unmarshal (Coverity)
- tpm2: Preserve more *target and restore them if needed (Coverity)
- tpm2: Return TPM_RC_VALUE upon decryption failure
- tpm12: Replace include of engine.h with err.h
- tpm2: Fix issue in CryptParameterEncryption() (TPM 2 errata v1.4) - tpm2: Fix issue in CryptParameterEncryption() (TPM 2 errata v1.4)
- tpm2: Sync fix in TPM2_PolicyAuthorize() with upstream - tpm2: Sync fix in TPM2_PolicyAuthorize() with upstream
- tpm2: Sync CryptParameterDecrypt implementation with upstream - tpm2: Sync CryptParameterDecrypt implementation with upstream

View File

@ -66,7 +66,7 @@
#include "Tpm.h" #include "Tpm.h"
/* 10.2.6.3 Hash/HMAC Functions */ /* 10.2.6.3 Hash/HMAC Functions */
/* 10.2.6.3.1 CryptHmacSign() */ /* 10.2.6.3.1 CryptHmacSign() */
/* Sign a digest using an HMAC key. This is an HMAC of a digest, not an HMAC of a message. */ /* Sign a digest using an HMAC key. This an HMAC of a digest, not an HMAC of a message. */
/* Error Returns Meaning */ /* Error Returns Meaning */
/* TPM_RC_HASH not a valid hash */ /* TPM_RC_HASH not a valid hash */
static TPM_RC static TPM_RC
@ -78,18 +78,12 @@ CryptHmacSign(
{ {
HMAC_STATE hmacState; HMAC_STATE hmacState;
UINT32 digestSize; UINT32 digestSize;
digestSize = CryptHmacStart2B(&hmacState, signature->signature.any.hashAlg,
if(signature->sigAlg == TPM_ALG_HMAC) &signKey->sensitive.sensitive.bits.b);
{ CryptDigestUpdate2B(&hmacState.hashState, &hashData->b);
digestSize = CryptHmacStart2B(&hmacState, CryptHmacEnd(&hmacState, digestSize,
signature->signature.any.hashAlg, (BYTE *)&signature->signature.hmac.digest);
&signKey->sensitive.sensitive.bits.b); return TPM_RC_SUCCESS;
CryptDigestUpdate2B(&hmacState.hashState, &hashData->b);
CryptHmacEnd(&hmacState, digestSize,
(BYTE *)&signature->signature.hmac.digest);
return TPM_RC_SUCCESS;
}
return TPM_RC_SCHEME;
} }
/* 10.2.6.3.2 CryptHMACVerifySignature() */ /* 10.2.6.3.2 CryptHMACVerifySignature() */
/* This function will verify a signature signed by a HMAC key. Note that a caller needs to prepare /* This function will verify a signature signed by a HMAC key. Note that a caller needs to prepare
@ -1113,7 +1107,7 @@ CryptIsSplitSign(
} }
} }
/* 10.2.6.6.11 CryptIsAsymSignScheme() */ /* 10.2.6.6.11 CryptIsAsymSignScheme() */
/* This function indicates if a scheme algorithm is a sign algorithm valid for the public key type. */ /* This function indicates if a scheme algorithm is a sign algorithm. */
BOOL BOOL
CryptIsAsymSignScheme( CryptIsAsymSignScheme(
TPMI_ALG_PUBLIC publicType, // IN: Type of the object TPMI_ALG_PUBLIC publicType, // IN: Type of the object
@ -1142,11 +1136,9 @@ CryptIsAsymSignScheme(
#if ALG_ECC #if ALG_ECC
// If ECC is implemented ECDSA is required // If ECC is implemented ECDSA is required
case TPM_ALG_ECC: case TPM_ALG_ECC:
# if !ALG_ECDSA
# error "ECDSA required if ECC enabled."
# endif
switch(scheme) switch(scheme)
{ {
// Support for ECDSA is required for ECC
case TPM_ALG_ECDSA: case TPM_ALG_ECDSA:
#if ALG_ECDAA // ECDAA is optional #if ALG_ECDAA // ECDAA is optional
case TPM_ALG_ECDAA: case TPM_ALG_ECDAA:
@ -1170,58 +1162,6 @@ CryptIsAsymSignScheme(
} }
return isSignScheme; return isSignScheme;
} }
//*** CryptIsValidSignScheme()
// This function checks that a signing scheme is valid. This includes verifying
// that the scheme signing algorithm is compatible with the signing object type
// and that the scheme specifies a valid hash algorithm.
static BOOL CryptIsValidSignScheme(TPMI_ALG_PUBLIC publicType, // IN: Type of the object
TPMT_SIG_SCHEME* scheme // IN: the signing scheme
)
{
BOOL isValidSignScheme = TRUE;
switch(publicType)
{
#if ALG_RSA
case TPM_ALG_RSA:
isValidSignScheme = CryptIsAsymSignScheme(publicType, scheme->scheme);
break;
#endif // ALG_RSA
#if ALG_ECC
case TPM_ALG_ECC:
isValidSignScheme = CryptIsAsymSignScheme(publicType, scheme->scheme);
break;
#endif // ALG_ECC
case TPM_ALG_KEYEDHASH:
if(scheme->scheme != TPM_ALG_HMAC)
{
isValidSignScheme = FALSE;
}
break;
default:
isValidSignScheme = FALSE;
break;
}
// Ensure that a valid hash algorithm is specified. Pass 'flag' = FALSE to
// indicate that TPM_ALG_NULL should not be treated as valid.
//
// NOTE: 'details' is of type TPMU_SIG_SCHEME which is a union of many
// different signature scheme types. In all these types (including the type
// of 'any'), the very first member is of type TPMI_ALG_HASH. Therefore,
// when 'any.hashAlg' is set to a valid hash algorithm ID, the hash for any
// signature scheme type will also be a valid hash algorithm ID. (All valid
// hash algorithm IDs are the same for all signature scheme types.)
if(!CryptHashIsValidAlg(scheme->details.any.hashAlg, /* flag = */ FALSE))
{
isValidSignScheme = FALSE;
}
return isValidSignScheme;
}
/* 10.2.6.6.12 CryptIsAsymDecryptScheme() */ /* 10.2.6.6.12 CryptIsAsymDecryptScheme() */
/* This function indicate if a scheme algorithm is a decrypt algorithm. */ /* This function indicate if a scheme algorithm is a decrypt algorithm. */
BOOL BOOL
@ -1276,9 +1216,8 @@ CryptIsAsymDecryptScheme(
} }
/* 10.2.6.6.13 CryptSelectSignScheme() */ /* 10.2.6.6.13 CryptSelectSignScheme() */
/* This function is used by the attestation and signing commands. It implements the rules for /* This function is used by the attestation and signing commands. It implements the rules for
selecting the signature scheme to use in signing and validates that the selected scheme is selecting the signature scheme to use in signing. This function requires that the signing key
compatible with the key type. It also ensures the selected scheme specifies a valid hash either be TPM_RH_NULL or be loaded. */
algorithm. This function requires that the signing key either be TPM_RH_NULL or be loaded. */
/* If a default scheme is defined in object, the default scheme should be chosen, otherwise, the /* If a default scheme is defined in object, the default scheme should be chosen, otherwise, the
input scheme should be chosen. In the case that both object and input scheme has a non-NULL input scheme should be chosen. In the case that both object and input scheme has a non-NULL
scheme algorithm, if the schemes are compatible, the input scheme will be chosen. */ scheme algorithm, if the schemes are compatible, the input scheme will be chosen. */
@ -1309,32 +1248,25 @@ CryptSelectSignScheme(
{ {
// assignment to save typing. // assignment to save typing.
publicArea = &signObject->publicArea; publicArea = &signObject->publicArea;
// A symmetric cipher can be used to encrypt and decrypt but it can't
// Get a point to the scheme object // be used for signing
if(publicArea->type == TPM_ALG_SYMCIPHER)
return FALSE;
// Point to the scheme object
if(CryptIsAsymAlgorithm(publicArea->type)) if(CryptIsAsymAlgorithm(publicArea->type))
{ objectScheme =
objectScheme = (TPMT_SIG_SCHEME *)&publicArea->parameters.asymDetail.scheme;
(TPMT_SIG_SCHEME *)&publicArea->parameters.asymDetail.scheme;
}
else if(publicArea->type == TPM_ALG_KEYEDHASH)
{
objectScheme =
(TPMT_SIG_SCHEME *)&publicArea->parameters.keyedHashDetail.scheme;
}
else else
{ objectScheme =
// Only asymmetric key types (RSA, ECC) and keyed hashes can be (TPMT_SIG_SCHEME *)&publicArea->parameters.keyedHashDetail.scheme;
// used for signing. A symmetric cipher can be used to encrypt and
// decrypt but can't be used for signing.
return FALSE;
}
// If the object doesn't have a default scheme, then use the // If the object doesn't have a default scheme, then use the
// input scheme. // input scheme.
if(objectScheme->scheme == TPM_ALG_NULL) if(objectScheme->scheme == TPM_ALG_NULL)
{ {
// Input and default can't both be NULL // Input and default can't both be NULL
OK = (scheme->scheme != TPM_ALG_NULL); OK = (scheme->scheme != TPM_ALG_NULL);
// Assume that the scheme is compatible with the key. If not,
// an error will be generated in the signing operation.
} }
else if(scheme->scheme == TPM_ALG_NULL) else if(scheme->scheme == TPM_ALG_NULL)
{ {
@ -1361,13 +1293,6 @@ CryptSelectSignScheme(
&& (objectScheme->details.any.hashAlg && (objectScheme->details.any.hashAlg
== scheme->details.any.hashAlg); == scheme->details.any.hashAlg);
} }
if(OK)
{
// Check that the scheme is compatible with the key type and has a
// valid hash algorithm specified.
OK = CryptIsValidSignScheme(publicArea->type, scheme);
}
} }
return OK; return OK;
} }

View File

@ -116,23 +116,16 @@ TPM2_Sign(
// //
// Input Validation // Input Validation
if(!IsSigningObject(signObject)) if(!IsSigningObject(signObject))
{
return TPM_RCS_KEY + RC_Sign_keyHandle; return TPM_RCS_KEY + RC_Sign_keyHandle;
}
// A key that will be used for x.509 signatures can't be used in TPM2_Sign(). // A key that will be used for x.509 signatures can't be used in TPM2_Sign().
if(IS_ATTRIBUTE(signObject->publicArea.objectAttributes, TPMA_OBJECT, x509sign)) if(IS_ATTRIBUTE(signObject->publicArea.objectAttributes, TPMA_OBJECT, x509sign))
{
return TPM_RCS_ATTRIBUTES + RC_Sign_keyHandle; return TPM_RCS_ATTRIBUTES + RC_Sign_keyHandle;
}
// Pick a scheme for signing. If the input signing scheme is not compatible // pick a scheme for sign. If the input sign scheme is not compatible with
// with the default scheme or the signing key type, return an error. If a // the default scheme, return an error.
// valid hash algorithm is not specified, return an error.
if(!CryptSelectSignScheme(signObject, &in->inScheme)) if(!CryptSelectSignScheme(signObject, &in->inScheme))
{
return TPM_RCS_SCHEME + RC_Sign_inScheme; return TPM_RCS_SCHEME + RC_Sign_inScheme;
}
// If validation is provided, or the key is restricted, check the ticket // If validation is provided, or the key is restricted, check the ticket
if(in->validation.digest.t.size != 0 if(in->validation.digest.t.size != 0
|| IS_ATTRIBUTE(signObject->publicArea.objectAttributes, TPMA_OBJECT, restricted)) || IS_ATTRIBUTE(signObject->publicArea.objectAttributes, TPMA_OBJECT, restricted))

View File

@ -77,7 +77,7 @@ CryptGetHashDef(
BOOL BOOL
CryptHashIsValidAlg( CryptHashIsValidAlg(
TPM_ALG_ID hashAlg, TPM_ALG_ID hashAlg,
BOOL isAlgNullValid BOOL flag
); );
LIB_EXPORT TPM_ALG_ID LIB_EXPORT TPM_ALG_ID
CryptHashGetAlgByIndex( CryptHashGetAlgByIndex(

View File

@ -139,12 +139,12 @@ CryptGetHashDef(
BOOL BOOL
CryptHashIsValidAlg( CryptHashIsValidAlg(
TPM_ALG_ID hashAlg, // IN: the algorithm to check TPM_ALG_ID hashAlg, // IN: the algorithm to check
BOOL isAlgNullValid // IN: TRUE if TPM_ALG_NULL is to be treated BOOL flag // IN: TRUE if TPM_ALG_NULL is to be treated
// as a valid hash // as a valid hash
) )
{ {
if(hashAlg == TPM_ALG_NULL) if(hashAlg == TPM_ALG_NULL)
return isAlgNullValid; return flag;
return CryptGetHashDef(hashAlg) != &NULL_Def; return CryptGetHashDef(hashAlg) != &NULL_Def;
} }
/* 10.2.13.4.4 CryptHashGetAlgByIndex() */ /* 10.2.13.4.4 CryptHashGetAlgByIndex() */