From e5ed38164c8f2495f2631f00eda0fc2df8ecbd65 Mon Sep 17 00:00:00 2001 From: Juergen Repp Date: Tue, 31 Oct 2023 11:08:41 +0100 Subject: [PATCH] FAPI: Fix check of magic number in verify quote. After deserializing the quote info it was not checked whether the magic number in the attest is equal TPM2_GENERATED_VALUE. So an malicious attacker could generate arbitrary quote data which was not detected by Fapi_VerifyQuote. Now the number magic number is checket in verify quote and also in the deserialization of TPM2_GENERATED. The check is also added to the Unmarshal function for TPMS_ATTEST. Fixes: CVE-2024-29040 Signed-off-by: Juergen Repp Signed-off-by: Andreas Fuchs --- src/tss2-fapi/api/Fapi_VerifyQuote.c | 5 +++++ src/tss2-fapi/tpm_json_deserialize.c | 11 +++++++++-- src/tss2-mu/tpms-types.c | 23 ++++++++++++++++++++++- 3 files changed, 36 insertions(+), 3 deletions(-) diff --git a/src/tss2-fapi/api/Fapi_VerifyQuote.c b/src/tss2-fapi/api/Fapi_VerifyQuote.c index fda532397..fb3be193e 100644 --- a/src/tss2-fapi/api/Fapi_VerifyQuote.c +++ b/src/tss2-fapi/api/Fapi_VerifyQuote.c @@ -286,6 +286,11 @@ Fapi_VerifyQuote_Finish( &command->fapi_quote_info); goto_if_error(r, "Get quote info.", error_cleanup); + if (command->fapi_quote_info.attest.magic != TPM2_GENERATED_VALUE) { + goto_error(r, TSS2_FAPI_RC_SIGNATURE_VERIFICATION_FAILED, + "Attest without TPM2 generated value", error_cleanup); + } + /* Verify the signature over the attest2b structure. */ r = ifapi_verify_signature_quote(&key_object, command->signature, diff --git a/src/tss2-fapi/tpm_json_deserialize.c b/src/tss2-fapi/tpm_json_deserialize.c index ab7debf09..aa6650066 100644 --- a/src/tss2-fapi/tpm_json_deserialize.c +++ b/src/tss2-fapi/tpm_json_deserialize.c @@ -698,6 +698,7 @@ ifapi_json_TPM2_GENERATED_deserialize(json_object *jso, TPM2_GENERATED *out) const char *s = json_object_get_string(jso); const char *str = strip_prefix(s, "TPM_", "TPM2_", "GENERATED_", NULL); LOG_TRACE("called for %s parsing %s", s, str); + TSS2_RC r; if (str) { for (size_t i = 0; i < sizeof(tab) / sizeof(tab[0]); i++) { @@ -707,8 +708,14 @@ ifapi_json_TPM2_GENERATED_deserialize(json_object *jso, TPM2_GENERATED *out) } } } - - return ifapi_json_UINT32_deserialize(jso, out); + r = ifapi_json_UINT32_deserialize(jso, out); + return_if_error(r, "Could not deserialize UINT32"); + if (*out != TPM2_GENERATED_VALUE) { + return_error2(TSS2_FAPI_RC_BAD_VALUE, + "Value %x not equal TPM self generated value %x", + *out, TPM2_GENERATED_VALUE); + } + return TSS2_RC_SUCCESS; } /** Deserialize a TPM2_ALG_ID json object. diff --git a/src/tss2-mu/tpms-types.c b/src/tss2-mu/tpms-types.c index 3ad725203..56aca0c33 100644 --- a/src/tss2-mu/tpms-types.c +++ b/src/tss2-mu/tpms-types.c @@ -22,6 +22,27 @@ #define VAL #define TAB_SIZE(tab) (sizeof(tab) / sizeof(tab[0])) +static TSS2_RC +TPM2_GENERATED_Unmarshal( + uint8_t const buffer[], + size_t buffer_size, + size_t *offset, + TPM2_GENERATED *magic) +{ + TPM2_GENERATED mymagic = 0; + TSS2_RC rc = Tss2_MU_UINT32_Unmarshal(buffer, buffer_size, offset, &mymagic); + if (rc != TSS2_RC_SUCCESS) { + return rc; + } + if (mymagic != TPM2_GENERATED_VALUE) { + LOG_ERROR("Bad magic in tpms_attest"); + return TSS2_SYS_RC_BAD_VALUE; + } + if (magic != NULL) + *magic = mymagic; + return TSS2_RC_SUCCESS; +} + #define TPMS_PCR_MARSHAL(type, firstFieldMarshal) \ TSS2_RC \ Tss2_MU_##type##_Marshal(const type *src, uint8_t buffer[], \ @@ -1219,7 +1240,7 @@ TPMS_MARSHAL_7_U(TPMS_ATTEST, attested, ADDR, Tss2_MU_TPMU_ATTEST_Marshal) TPMS_UNMARSHAL_7_U(TPMS_ATTEST, - magic, Tss2_MU_UINT32_Unmarshal, + magic, TPM2_GENERATED_Unmarshal, type, Tss2_MU_TPM2_ST_Unmarshal, qualifiedSigner, Tss2_MU_TPM2B_NAME_Unmarshal, extraData, Tss2_MU_TPM2B_DATA_Unmarshal,