Skip to content

Commit 022dc69

Browse files
authored
[MEDIUM] Patch libtpms for CVE-2025-49133 (microsoft#14020)
1 parent 15ffdc3 commit 022dc69

File tree

2 files changed

+271
-1
lines changed

2 files changed

+271
-1
lines changed

SPECS/libtpms/CVE-2025-49133.patch

Lines changed: 266 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,266 @@
1+
From 83474625ad1816e55afa224dabfb4a6f29bd6123 Mon Sep 17 00:00:00 2001
2+
From: archana25-ms <[email protected]>
3+
Date: Mon, 16 Jun 2025 16:40:42 +0000
4+
Subject: [PATCH] Address CVE-2025-49133
5+
Upstream Patch Reference: https://github.com/stefanberger/libtpms/commit/9f9baccdba9cd3fc32f1355613abd094b21f7ba0
6+
---
7+
src/tpm2/CryptUtil.c | 119 +++++++++++++++++++++++-----
8+
src/tpm2/SigningCommands.c | 11 ++-
9+
src/tpm2/crypto/CryptHash_fp.h | 2 +-
10+
src/tpm2/crypto/openssl/CryptHash.c | 4 +-
11+
4 files changed, 109 insertions(+), 27 deletions(-)
12+
13+
diff --git a/src/tpm2/CryptUtil.c b/src/tpm2/CryptUtil.c
14+
index 8fae5b6..f0d8a28 100644
15+
--- a/src/tpm2/CryptUtil.c
16+
+++ b/src/tpm2/CryptUtil.c
17+
@@ -67,7 +67,7 @@
18+
#include "Tpm.h"
19+
/* 10.2.6.3 Hash/HMAC Functions */
20+
/* 10.2.6.3.1 CryptHmacSign() */
21+
-/* Sign a digest using an HMAC key. This an HMAC of a digest, not an HMAC of a message. */
22+
+/* Sign a digest using an HMAC key. This is an HMAC of a digest, not an HMAC of a message. */
23+
/* Error Returns Meaning */
24+
/* TPM_RC_HASH not a valid hash */
25+
static TPM_RC
26+
@@ -79,12 +79,18 @@ CryptHmacSign(
27+
{
28+
HMAC_STATE hmacState;
29+
UINT32 digestSize;
30+
- digestSize = CryptHmacStart2B(&hmacState, signature->signature.any.hashAlg,
31+
- &signKey->sensitive.sensitive.bits.b);
32+
- CryptDigestUpdate2B(&hmacState.hashState, &hashData->b);
33+
- CryptHmacEnd(&hmacState, digestSize,
34+
- (BYTE *)&signature->signature.hmac.digest);
35+
- return TPM_RC_SUCCESS;
36+
+
37+
+ if(signature->sigAlg == TPM_ALG_HMAC)
38+
+ {
39+
+ digestSize = CryptHmacStart2B(&hmacState,
40+
+ signature->signature.any.hashAlg,
41+
+ &signKey->sensitive.sensitive.bits.b);
42+
+ CryptDigestUpdate2B(&hmacState.hashState, &hashData->b);
43+
+ CryptHmacEnd(&hmacState, digestSize,
44+
+ (BYTE *)&signature->signature.hmac.digest);
45+
+ return TPM_RC_SUCCESS;
46+
+ }
47+
+ return TPM_RC_SCHEME;
48+
}
49+
/* 10.2.6.3.2 CryptHMACVerifySignature() */
50+
/* This function will verify a signature signed by a HMAC key. Note that a caller needs to prepare
51+
@@ -1096,7 +1102,7 @@ CryptIsSplitSign(
52+
}
53+
}
54+
/* 10.2.6.6.11 CryptIsAsymSignScheme() */
55+
-/* This function indicates if a scheme algorithm is a sign algorithm. */
56+
+/* This function indicates if a scheme algorithm is a sign algorithm valid for the public key type. */
57+
BOOL
58+
CryptIsAsymSignScheme(
59+
TPMI_ALG_PUBLIC publicType, // IN: Type of the object
60+
@@ -1125,9 +1131,11 @@ CryptIsAsymSignScheme(
61+
#if ALG_ECC
62+
// If ECC is implemented ECDSA is required
63+
case TPM_ALG_ECC:
64+
+# if !ALG_ECDSA
65+
+# error "ECDSA required if ECC enabled."
66+
+# endif
67+
switch(scheme)
68+
{
69+
- // Support for ECDSA is required for ECC
70+
case TPM_ALG_ECDSA:
71+
#if ALG_ECDAA // ECDAA is optional
72+
case TPM_ALG_ECDAA:
73+
@@ -1151,6 +1159,58 @@ CryptIsAsymSignScheme(
74+
}
75+
return isSignScheme;
76+
}
77+
+//*** CryptIsValidSignScheme()
78+
+// This function checks that a signing scheme is valid. This includes verifying
79+
+// that the scheme signing algorithm is compatible with the signing object type
80+
+// and that the scheme specifies a valid hash algorithm.
81+
+static BOOL CryptIsValidSignScheme(TPMI_ALG_PUBLIC publicType, // IN: Type of the object
82+
+ TPMT_SIG_SCHEME* scheme // IN: the signing scheme
83+
+)
84+
+{
85+
+ BOOL isValidSignScheme = TRUE;
86+
+
87+
+ switch(publicType)
88+
+ {
89+
+#if ALG_RSA
90+
+ case TPM_ALG_RSA:
91+
+ isValidSignScheme = CryptIsAsymSignScheme(publicType, scheme->scheme);
92+
+ break;
93+
+#endif // ALG_RSA
94+
+
95+
+#if ALG_ECC
96+
+ case TPM_ALG_ECC:
97+
+ isValidSignScheme = CryptIsAsymSignScheme(publicType, scheme->scheme);
98+
+ break;
99+
+#endif // ALG_ECC
100+
+
101+
+ case TPM_ALG_KEYEDHASH:
102+
+ if(scheme->scheme != TPM_ALG_HMAC)
103+
+ {
104+
+ isValidSignScheme = FALSE;
105+
+ }
106+
+ break;
107+
+
108+
+ default:
109+
+ isValidSignScheme = FALSE;
110+
+ break;
111+
+ }
112+
+
113+
+ // Ensure that a valid hash algorithm is specified. Pass 'flag' = FALSE to
114+
+ // indicate that TPM_ALG_NULL should not be treated as valid.
115+
+ //
116+
+ // NOTE: 'details' is of type TPMU_SIG_SCHEME which is a union of many
117+
+ // different signature scheme types. In all these types (including the type
118+
+ // of 'any'), the very first member is of type TPMI_ALG_HASH. Therefore,
119+
+ // when 'any.hashAlg' is set to a valid hash algorithm ID, the hash for any
120+
+ // signature scheme type will also be a valid hash algorithm ID. (All valid
121+
+ // hash algorithm IDs are the same for all signature scheme types.)
122+
+ if(!CryptHashIsValidAlg(scheme->details.any.hashAlg, /* flag = */ FALSE))
123+
+ {
124+
+ isValidSignScheme = FALSE;
125+
+ }
126+
+
127+
+ return isValidSignScheme;
128+
+}
129+
/* 10.2.6.6.12 CryptIsAsymDecryptScheme() */
130+
/* This function indicate if a scheme algorithm is a decrypt algorithm. */
131+
BOOL
132+
@@ -1205,8 +1265,9 @@ CryptIsAsymDecryptScheme(
133+
}
134+
/* 10.2.6.6.13 CryptSelectSignScheme() */
135+
/* This function is used by the attestation and signing commands. It implements the rules for
136+
- selecting the signature scheme to use in signing. This function requires that the signing key
137+
- either be TPM_RH_NULL or be loaded. */
138+
+ selecting the signature scheme to use in signing and validates that the selected scheme is
139+
+ compatible with the key type. It also ensures the selected scheme specifies a valid hash
140+
+ algorithm. This function requires that the signing key either be TPM_RH_NULL or be loaded. */
141+
/* If a default scheme is defined in object, the default scheme should be chosen, otherwise, the
142+
input scheme should be chosen. In the case that both object and input scheme has a non-NULL
143+
scheme algorithm, if the schemes are compatible, the input scheme will be chosen. */
144+
@@ -1237,25 +1298,32 @@ CryptSelectSignScheme(
145+
{
146+
// assignment to save typing.
147+
publicArea = &signObject->publicArea;
148+
- // A symmetric cipher can be used to encrypt and decrypt but it can't
149+
- // be used for signing
150+
- if(publicArea->type == TPM_ALG_SYMCIPHER)
151+
- return FALSE;
152+
- // Point to the scheme object
153+
+
154+
+ // Get a point to the scheme object
155+
if(CryptIsAsymAlgorithm(publicArea->type))
156+
- objectScheme =
157+
- (TPMT_SIG_SCHEME *)&publicArea->parameters.asymDetail.scheme;
158+
+ {
159+
+ objectScheme =
160+
+ (TPMT_SIG_SCHEME *)&publicArea->parameters.asymDetail.scheme;
161+
+ }
162+
+ else if(publicArea->type == TPM_ALG_KEYEDHASH)
163+
+ {
164+
+ objectScheme =
165+
+ (TPMT_SIG_SCHEME *)&publicArea->parameters.keyedHashDetail.scheme;
166+
+ }
167+
else
168+
- objectScheme =
169+
- (TPMT_SIG_SCHEME *)&publicArea->parameters.keyedHashDetail.scheme;
170+
+ {
171+
+ // Only asymmetric key types (RSA, ECC) and keyed hashes can be
172+
+ // used for signing. A symmetric cipher can be used to encrypt and
173+
+ // decrypt but can't be used for signing.
174+
+ return FALSE;
175+
+ }
176+
+
177+
// If the object doesn't have a default scheme, then use the
178+
// input scheme.
179+
if(objectScheme->scheme == TPM_ALG_NULL)
180+
{
181+
// Input and default can't both be NULL
182+
OK = (scheme->scheme != TPM_ALG_NULL);
183+
- // Assume that the scheme is compatible with the key. If not,
184+
- // an error will be generated in the signing operation.
185+
}
186+
else if(scheme->scheme == TPM_ALG_NULL)
187+
{
188+
@@ -1282,6 +1350,13 @@ CryptSelectSignScheme(
189+
&& (objectScheme->details.any.hashAlg
190+
== scheme->details.any.hashAlg);
191+
}
192+
+
193+
+ if(OK)
194+
+ {
195+
+ // Check that the scheme is compatible with the key type and has a
196+
+ // valid hash algorithm specified.
197+
+ OK = CryptIsValidSignScheme(publicArea->type, scheme);
198+
+ }
199+
}
200+
return OK;
201+
}
202+
diff --git a/src/tpm2/SigningCommands.c b/src/tpm2/SigningCommands.c
203+
index 529c40c..ec93c84 100644
204+
--- a/src/tpm2/SigningCommands.c
205+
+++ b/src/tpm2/SigningCommands.c
206+
@@ -116,16 +116,23 @@ TPM2_Sign(
207+
//
208+
// Input Validation
209+
if(!IsSigningObject(signObject))
210+
+ {
211+
return TPM_RCS_KEY + RC_Sign_keyHandle;
212+
+ }
213+
214+
// A key that will be used for x.509 signatures can't be used in TPM2_Sign().
215+
if(IS_ATTRIBUTE(signObject->publicArea.objectAttributes, TPMA_OBJECT, x509sign))
216+
+ {
217+
return TPM_RCS_ATTRIBUTES + RC_Sign_keyHandle;
218+
+ }
219+
220+
- // pick a scheme for sign. If the input sign scheme is not compatible with
221+
- // the default scheme, return an error.
222+
+ // Pick a scheme for signing. If the input signing scheme is not compatible
223+
+ // with the default scheme or the signing key type, return an error. If a
224+
+ // valid hash algorithm is not specified, return an error.
225+
if(!CryptSelectSignScheme(signObject, &in->inScheme))
226+
+ {
227+
return TPM_RCS_SCHEME + RC_Sign_inScheme;
228+
+ }
229+
// If validation is provided, or the key is restricted, check the ticket
230+
if(in->validation.digest.t.size != 0
231+
|| IS_ATTRIBUTE(signObject->publicArea.objectAttributes, TPMA_OBJECT, restricted))
232+
diff --git a/src/tpm2/crypto/CryptHash_fp.h b/src/tpm2/crypto/CryptHash_fp.h
233+
index adf1ba9..721d335 100644
234+
--- a/src/tpm2/crypto/CryptHash_fp.h
235+
+++ b/src/tpm2/crypto/CryptHash_fp.h
236+
@@ -77,7 +77,7 @@ CryptGetHashDef(
237+
BOOL
238+
CryptHashIsValidAlg(
239+
TPM_ALG_ID hashAlg,
240+
- BOOL flag
241+
+ BOOL isAlgNullValid
242+
);
243+
LIB_EXPORT TPM_ALG_ID
244+
CryptHashGetAlgByIndex(
245+
diff --git a/src/tpm2/crypto/openssl/CryptHash.c b/src/tpm2/crypto/openssl/CryptHash.c
246+
index cb5bd0f..eb484b8 100644
247+
--- a/src/tpm2/crypto/openssl/CryptHash.c
248+
+++ b/src/tpm2/crypto/openssl/CryptHash.c
249+
@@ -139,12 +139,12 @@ CryptGetHashDef(
250+
BOOL
251+
CryptHashIsValidAlg(
252+
TPM_ALG_ID hashAlg, // IN: the algorithm to check
253+
- BOOL flag // IN: TRUE if TPM_ALG_NULL is to be treated
254+
+ BOOL isAlgNullValid // IN: TRUE if TPM_ALG_NULL is to be treated
255+
// as a valid hash
256+
)
257+
{
258+
if(hashAlg == TPM_ALG_NULL)
259+
- return flag;
260+
+ return isAlgNullValid;
261+
return CryptGetHashDef(hashAlg) != &NULL_Def;
262+
}
263+
/* 10.2.13.4.4 CryptHashGetAlgByIndex() */
264+
--
265+
2.45.3
266+

SPECS/libtpms/libtpms.spec

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
Name: libtpms
22
Version: 0.9.6
3-
Release: 7%{?dist}
3+
Release: 8%{?dist}
44
Summary: Library providing Trusted Platform Module (TPM) functionality
55
License: BSD and TCGL
66

@@ -12,6 +12,7 @@ Source1: %{url}/releases/download/v%{version}/v%{version}.tar.gz.asc#/%{n
1212
# https://github.com/stefanberger.gpg
1313
Source2: gpgkey-B818B9CADF9089C2D5CEC66B75AD65802A0B4211.asc
1414
Patch1: 0001-Export-RSA-private-key-primes-to-OpenSSL.patch
15+
Patch2: CVE-2025-49133.patch
1516

1617
BuildRequires: autoconf
1718
BuildRequires: automake
@@ -66,6 +67,9 @@ make check
6667
%{_mandir}/man3/TPM*
6768

6869
%changelog
70+
* Tue Jun 17 2025 Archana Shettigar <[email protected]> - 0.9.6-8
71+
- Patch CVE-2025-49133
72+
6973
* Tue Sep 03 2024 Neha Agarwal <[email protected]> - 0.9.6-7
7074
- Add missing Vendor and Distribution tags.
7175

0 commit comments

Comments
 (0)