Package: release.debian.org Severity: normal Tags: bookworm X-Debbugs-Cc: libt...@packages.debian.org Control: affects -1 + src:libtpms User: release.debian....@packages.debian.org Usertags: pu
Fixes a low severity security issue. The identical patch has been applied in unstable for quite a while and all the autopkgtests with rev deps as triggered with desusine also looked good. Debdiff below. Cheers, Moritz diff -Nru libtpms-0.9.2/debian/changelog libtpms-0.9.2/debian/changelog --- libtpms-0.9.2/debian/changelog 2023-03-07 22:32:00.000000000 +0100 +++ libtpms-0.9.2/debian/changelog 2025-08-25 22:42:00.000000000 +0200 @@ -1,3 +1,9 @@ +libtpms (0.9.2-3.1+deb12u1) bookworm; urgency=medium + + * CVE-2025-49133 (Closes: #1107617) + + -- Moritz Mühlenhoff <j...@debian.org> Mon, 25 Aug 2025 22:42:00 +0200 + libtpms (0.9.2-3.1) unstable; urgency=medium * Non-maintainer upload. diff -Nru libtpms-0.9.2/debian/patches/CVE-2025-49133.patch libtpms-0.9.2/debian/patches/CVE-2025-49133.patch --- libtpms-0.9.2/debian/patches/CVE-2025-49133.patch 1970-01-01 01:00:00.000000000 +0100 +++ libtpms-0.9.2/debian/patches/CVE-2025-49133.patch 2025-08-25 22:41:56.000000000 +0200 @@ -0,0 +1,256 @@ +Origin: upstream, 9f9baccdba9cd3fc32f1355613abd094b21f7ba0 +From: Stefan Berger <stef...@linux.ibm.com> +Date: Tue, 9 Jul 2024 16:45:42 -0400 +Subject: tpm2: Fix potential out-of-bound access & abort due to HMAC signing issue + +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. + +--- libtpms-0.9.2.orig/src/tpm2/CryptUtil.c ++++ libtpms-0.9.2/src/tpm2/CryptUtil.c +@@ -67,7 +67,7 @@ + #include "Tpm.h" + /* 10.2.6.3 Hash/HMAC Functions */ + /* 10.2.6.3.1 CryptHmacSign() */ +-/* Sign a digest using an HMAC key. This an HMAC of a digest, not an HMAC of a message. */ ++/* Sign a digest using an HMAC key. This is an HMAC of a digest, not an HMAC of a message. */ + /* Error Returns Meaning */ + /* TPM_RC_HASH not a valid hash */ + static TPM_RC +@@ -79,12 +79,18 @@ CryptHmacSign( + { + HMAC_STATE hmacState; + UINT32 digestSize; +- digestSize = CryptHmacStart2B(&hmacState, signature->signature.any.hashAlg, +- &signKey->sensitive.sensitive.bits.b); +- CryptDigestUpdate2B(&hmacState.hashState, &hashData->b); +- CryptHmacEnd(&hmacState, digestSize, +- (BYTE *)&signature->signature.hmac.digest); +- return TPM_RC_SUCCESS; ++ ++ if(signature->sigAlg == TPM_ALG_HMAC) ++ { ++ digestSize = CryptHmacStart2B(&hmacState, ++ signature->signature.any.hashAlg, ++ &signKey->sensitive.sensitive.bits.b); ++ 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() */ + /* This function will verify a signature signed by a HMAC key. Note that a caller needs to prepare +@@ -1096,7 +1102,7 @@ CryptIsSplitSign( + } + } + /* 10.2.6.6.11 CryptIsAsymSignScheme() */ +-/* This function indicates if a scheme algorithm is a sign algorithm. */ ++/* This function indicates if a scheme algorithm is a sign algorithm valid for the public key type. */ + BOOL + CryptIsAsymSignScheme( + TPMI_ALG_PUBLIC publicType, // IN: Type of the object +@@ -1125,9 +1131,11 @@ CryptIsAsymSignScheme( + #if ALG_ECC + // If ECC is implemented ECDSA is required + case TPM_ALG_ECC: ++# if !ALG_ECDSA ++# error "ECDSA required if ECC enabled." ++# endif + switch(scheme) + { +- // Support for ECDSA is required for ECC + case TPM_ALG_ECDSA: + #if ALG_ECDAA // ECDAA is optional + case TPM_ALG_ECDAA: +@@ -1151,6 +1159,58 @@ CryptIsAsymSignScheme( + } + 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() */ + /* This function indicate if a scheme algorithm is a decrypt algorithm. */ + BOOL +@@ -1205,8 +1265,9 @@ CryptIsAsymDecryptScheme( + } + /* 10.2.6.6.13 CryptSelectSignScheme() */ + /* This function is used by the attestation and signing commands. It implements the rules for +- selecting the signature scheme to use in signing. This function requires that the signing key +- either be TPM_RH_NULL or be loaded. */ ++ selecting the signature scheme to use in signing and validates that the selected scheme is ++ compatible with the key type. It also ensures the selected scheme specifies a valid hash ++ 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 + 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. */ +@@ -1237,25 +1298,32 @@ CryptSelectSignScheme( + { + // assignment to save typing. + publicArea = &signObject->publicArea; +- // A symmetric cipher can be used to encrypt and decrypt but it can't +- // be used for signing +- if(publicArea->type == TPM_ALG_SYMCIPHER) +- return FALSE; +- // Point to the scheme object ++ ++ // Get a point to the scheme object + if(CryptIsAsymAlgorithm(publicArea->type)) +- objectScheme = +- (TPMT_SIG_SCHEME *)&publicArea->parameters.asymDetail.scheme; ++ { ++ objectScheme = ++ (TPMT_SIG_SCHEME *)&publicArea->parameters.asymDetail.scheme; ++ } ++ else if(publicArea->type == TPM_ALG_KEYEDHASH) ++ { ++ objectScheme = ++ (TPMT_SIG_SCHEME *)&publicArea->parameters.keyedHashDetail.scheme; ++ } + else +- objectScheme = +- (TPMT_SIG_SCHEME *)&publicArea->parameters.keyedHashDetail.scheme; ++ { ++ // Only asymmetric key types (RSA, ECC) and keyed hashes can be ++ // 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 + // input scheme. + if(objectScheme->scheme == TPM_ALG_NULL) + { + // Input and default can't both be 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) + { +@@ -1282,6 +1350,13 @@ CryptSelectSignScheme( + && (objectScheme->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; + } +--- libtpms-0.9.2.orig/src/tpm2/SigningCommands.c ++++ libtpms-0.9.2/src/tpm2/SigningCommands.c +@@ -116,16 +116,23 @@ TPM2_Sign( + // + // Input Validation + if(!IsSigningObject(signObject)) ++ { + return TPM_RCS_KEY + RC_Sign_keyHandle; ++ } + + // 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)) ++ { + return TPM_RCS_ATTRIBUTES + RC_Sign_keyHandle; ++ } + +- // pick a scheme for sign. If the input sign scheme is not compatible with +- // the default scheme, return an error. ++ // Pick a scheme for signing. If the input signing scheme is not compatible ++ // with the default scheme or the signing key type, return an error. If a ++ // valid hash algorithm is not specified, return an error. + if(!CryptSelectSignScheme(signObject, &in->inScheme)) ++ { + return TPM_RCS_SCHEME + RC_Sign_inScheme; ++ } + // If validation is provided, or the key is restricted, check the ticket + if(in->validation.digest.t.size != 0 + || IS_ATTRIBUTE(signObject->publicArea.objectAttributes, TPMA_OBJECT, restricted)) +--- libtpms-0.9.2.orig/src/tpm2/crypto/CryptHash_fp.h ++++ libtpms-0.9.2/src/tpm2/crypto/CryptHash_fp.h +@@ -77,7 +77,7 @@ CryptGetHashDef( + BOOL + CryptHashIsValidAlg( + TPM_ALG_ID hashAlg, +- BOOL flag ++ BOOL isAlgNullValid + ); + LIB_EXPORT TPM_ALG_ID + CryptHashGetAlgByIndex( +--- libtpms-0.9.2.orig/src/tpm2/crypto/openssl/CryptHash.c ++++ libtpms-0.9.2/src/tpm2/crypto/openssl/CryptHash.c +@@ -139,12 +139,12 @@ CryptGetHashDef( + BOOL + CryptHashIsValidAlg( + TPM_ALG_ID hashAlg, // IN: the algorithm to check +- BOOL flag // IN: TRUE if TPM_ALG_NULL is to be treated ++ BOOL isAlgNullValid // IN: TRUE if TPM_ALG_NULL is to be treated + // as a valid hash + ) + { + if(hashAlg == TPM_ALG_NULL) +- return flag; ++ return isAlgNullValid; + return CryptGetHashDef(hashAlg) != &NULL_Def; + } + /* 10.2.13.4.4 CryptHashGetAlgByIndex() */ diff -Nru libtpms-0.9.2/debian/patches/series libtpms-0.9.2/debian/patches/series --- libtpms-0.9.2/debian/patches/series 2023-03-07 22:32:00.000000000 +0100 +++ libtpms-0.9.2/debian/patches/series 2025-08-25 22:41:38.000000000 +0200 @@ -3,3 +3,4 @@ do_not_inline_makeiv.patch no_local_check.patch tpm2-Check-size-of-buffer-before-accessing-it-CVE-20.patch +CVE-2025-49133.patch