diff --git a/576a31bcc910da517067b29667f45fbe78e812e0.patch b/576a31bcc910da517067b29667f45fbe78e812e0.patch new file mode 100644 index 0000000..0ba4e6a --- /dev/null +++ b/576a31bcc910da517067b29667f45fbe78e812e0.patch @@ -0,0 +1,194 @@ +From 576a31bcc910da517067b29667f45fbe78e812e0 Mon Sep 17 00:00:00 2001 +From: Thore Sommer +Date: Tue, 25 Apr 2023 17:24:55 +0300 +Subject: [PATCH] tpm2_eventlog: add support for replay with different + StartupLocality + +According to the "TCG PC Client Platform Firmware Profile Specification +Level 00 Version 1.05 Revision 23" section 10.4.5.3 the startup locality +is the starting value of PCR0. This can be currently either 0 or 3. + +Signed-off-by: Thore Sommer +--- + lib/efi_event.h | 1 + + lib/tpm2_eventlog.c | 31 ++++++++++++++++++++++++++++--- + lib/tpm2_eventlog.h | 2 +- + test/unit/test_tpm2_eventlog.c | 14 +++++++------- + 4 files changed, 37 insertions(+), 11 deletions(-) + +diff --git a/lib/efi_event.h b/lib/efi_event.h +index cc2ffc983..e1b295501 100644 +--- a/lib/efi_event.h ++++ b/lib/efi_event.h +@@ -45,6 +45,7 @@ + #define EV_EFI_HANDOFF_TABLES2 EV_EFI_EVENT_BASE + 0xb + #define EV_EFI_VARIABLE_BOOT2 EV_EFI_EVENT_BASE + 0xc + ++#define EV_EFI_HCRTM_EVENT EV_EFI_EVENT_BASE + 0x10 + #define EV_EFI_VARIABLE_AUTHORITY EV_EFI_EVENT_BASE + 0xe0 + + #ifndef PACKED +diff --git a/lib/tpm2_eventlog.c b/lib/tpm2_eventlog.c +index e2e27f02b..2514b524e 100644 +--- a/lib/tpm2_eventlog.c ++++ b/lib/tpm2_eventlog.c +@@ -31,7 +31,7 @@ bool digest2_accumulator_callback(TCG_DIGEST2 const *digest, size_t size, + * 'size' parameter. + */ + bool foreach_digest2(tpm2_eventlog_context *ctx, UINT32 eventType, unsigned pcr_index, +- TCG_DIGEST2 const *digest, size_t count, size_t size) { ++ TCG_DIGEST2 const *digest, size_t count, size_t size, uint8_t locality) { + + if (digest == NULL) { + LOG_ERR("digest cannot be NULL"); +@@ -81,6 +81,10 @@ bool foreach_digest2(tpm2_eventlog_context *ctx, UINT32 eventType, unsigned pcr_ + LOG_WARN("PCR%d algorithm %d unsupported", pcr_index, alg); + } + ++ if (eventType == EV_NO_ACTION && pcr && pcr_index == 0 && locality > 0 ){ ++ pcr[alg_size -1] = locality; ++ } ++ + if (eventType != EV_NO_ACTION && pcr && + !tpm2_openssl_pcr_extend(alg, pcr, digest->Digest, alg_size)) { + LOG_ERR("PCR%d extend failed", pcr_index); +@@ -184,7 +188,7 @@ bool parse_event2(TCG_EVENT_HEADER2 const *eventhdr, size_t buf_size, + ret = foreach_digest2(&ctx, eventhdr->EventType, + eventhdr->PCRIndex, + eventhdr->Digests, eventhdr->DigestCount, +- buf_size - sizeof(*eventhdr)); ++ buf_size - sizeof(*eventhdr), 0); + if (ret != true) { + return false; + } +@@ -430,6 +434,7 @@ bool foreach_event2(tpm2_eventlog_context *ctx, TCG_EVENT_HEADER2 const *eventhd + TCG_EVENT_HEADER2 const *eventhdr; + size_t event_size; + bool ret; ++ bool found_hcrtm = false; + + for (eventhdr = eventhdr_start, event_size = 0; + size > 0; +@@ -437,6 +442,7 @@ bool foreach_event2(tpm2_eventlog_context *ctx, TCG_EVENT_HEADER2 const *eventhd + size -= event_size) { + + size_t digests_size = 0; ++ uint8_t locality = 0; + + ret = parse_event2(eventhdr, size, &event_size, &digests_size); + if (!ret) { +@@ -445,6 +451,25 @@ bool foreach_event2(tpm2_eventlog_context *ctx, TCG_EVENT_HEADER2 const *eventhd + + TCG_EVENT2 *event = (TCG_EVENT2*)((uintptr_t)eventhdr->Digests + digests_size); + ++ if (eventhdr->EventType == EV_EFI_HCRTM_EVENT && eventhdr->PCRIndex == 0) { ++ found_hcrtm = true; ++ } ++ ++ /* Handle StartupLocality in replay for PCR0 */ ++ if (!found_hcrtm && eventhdr->EventType == EV_NO_ACTION && eventhdr->PCRIndex == 0) { ++ if (event_size < sizeof(EV_NO_ACTION_STRUCT)){ ++ LOG_ERR("EventSize is too small\n"); ++ return false; ++ } ++ ++ EV_NO_ACTION_STRUCT *locality_event = (EV_NO_ACTION_STRUCT*)event->Event; ++ ++ if (memcmp(locality_event->Signature, STARTUP_LOCALITY_SIGNATURE, sizeof(STARTUP_LOCALITY_SIGNATURE)) == 0){ ++ locality = locality_event->Cases.StartupLocality; ++ } ++ } ++ ++ + /* event header callback */ + if (ctx->event2hdr_cb != NULL) { + ret = ctx->event2hdr_cb(eventhdr, event_size, ctx->data); +@@ -455,7 +480,7 @@ bool foreach_event2(tpm2_eventlog_context *ctx, TCG_EVENT_HEADER2 const *eventhd + + /* digest callback foreach digest */ + ret = foreach_digest2(ctx, eventhdr->EventType, eventhdr->PCRIndex, +- eventhdr->Digests, eventhdr->DigestCount, digests_size); ++ eventhdr->Digests, eventhdr->DigestCount, digests_size, locality); + if (ret != true) { + return false; + } +diff --git a/lib/tpm2_eventlog.h b/lib/tpm2_eventlog.h +index f141e8068..0af897070 100644 +--- a/lib/tpm2_eventlog.h ++++ b/lib/tpm2_eventlog.h +@@ -45,7 +45,7 @@ bool digest2_accumulator_callback(TCG_DIGEST2 const *digest, size_t size, + + bool parse_event2body(TCG_EVENT2 const *event, UINT32 type); + bool foreach_digest2(tpm2_eventlog_context *ctx, UINT32 eventType, unsigned pcr_index, +- TCG_DIGEST2 const *event_hdr, size_t count, size_t size); ++ TCG_DIGEST2 const *event_hdr, size_t count, size_t size, uint8_t locality); + bool parse_event2(TCG_EVENT_HEADER2 const *eventhdr, size_t buf_size, + size_t *event_size, size_t *digests_size); + bool foreach_event2(tpm2_eventlog_context *ctx, TCG_EVENT_HEADER2 const *eventhdr_start, size_t size); +diff --git a/test/unit/test_tpm2_eventlog.c b/test/unit/test_tpm2_eventlog.c +index e48404d8d..1c36f907e 100644 +--- a/test/unit/test_tpm2_eventlog.c ++++ b/test/unit/test_tpm2_eventlog.c +@@ -27,7 +27,7 @@ static void test_foreach_digest2_null(void **state){ + (void)state; + tpm2_eventlog_context ctx = {0}; + +- assert_false(foreach_digest2(&ctx, 0, 0, NULL, 0, sizeof(TCG_DIGEST2))); ++ assert_false(foreach_digest2(&ctx, 0, 0, NULL, 0, sizeof(TCG_DIGEST2), 0)); + } + static void test_foreach_digest2_size(void **state) { + +@@ -36,7 +36,7 @@ static void test_foreach_digest2_size(void **state) { + TCG_DIGEST2 *digest = (TCG_DIGEST2*)buf; + tpm2_eventlog_context ctx = { .digest2_cb = foreach_digest2_test_callback }; + +- assert_false(foreach_digest2(&ctx, 0, 0, digest, 1, sizeof(TCG_DIGEST2) - 1)); ++ assert_false(foreach_digest2(&ctx, 0, 0, digest, 1, sizeof(TCG_DIGEST2) - 1, 0)); + } + static void test_foreach_digest2(void **state) { + +@@ -47,7 +47,7 @@ static void test_foreach_digest2(void **state) { + will_return(foreach_digest2_test_callback, true); + + tpm2_eventlog_context ctx = { .digest2_cb = foreach_digest2_test_callback }; +- assert_true(foreach_digest2(&ctx, 0, 0, digest, 1, TCG_DIGEST2_SHA1_SIZE)); ++ assert_true(foreach_digest2(&ctx, 0, 0, digest, 1, TCG_DIGEST2_SHA1_SIZE, 0)); + } + static void test_foreach_digest2_cbnull(void **state){ + +@@ -56,7 +56,7 @@ static void test_foreach_digest2_cbnull(void **state){ + TCG_DIGEST2* digest = (TCG_DIGEST2*)buf; + + tpm2_eventlog_context ctx = {0}; +- assert_true(foreach_digest2(&ctx, 0, 0, digest, 1, TCG_DIGEST2_SHA1_SIZE)); ++ assert_true(foreach_digest2(&ctx, 0, 0, digest, 1, TCG_DIGEST2_SHA1_SIZE, 0)); + } + static void test_sha1(void **state){ + +@@ -73,7 +73,7 @@ static void test_sha1(void **state){ + memcpy(digest->Digest, "the magic words are:", TPM2_SHA1_DIGEST_SIZE); + + tpm2_eventlog_context ctx = {0}; +- assert_true(foreach_digest2(&ctx, 0, pcr_index, digest, 1, TCG_DIGEST2_SHA1_SIZE)); ++ assert_true(foreach_digest2(&ctx, 0, pcr_index, digest, 1, TCG_DIGEST2_SHA1_SIZE, 0)); + assert_memory_equal(ctx.sha1_pcrs[pcr_index], sha1sum, sizeof(sha1sum)); + } + static void test_sha256(void **state){ +@@ -93,7 +93,7 @@ static void test_sha256(void **state){ + memcpy(digest->Digest, "The Magic Words are Squeamish Ossifrage, for RSA-129 (from 1977)", TPM2_SHA256_DIGEST_SIZE); + + tpm2_eventlog_context ctx = {0}; +- assert_true(foreach_digest2(&ctx, 0, pcr_index, digest, 1, TCG_DIGEST2_SHA256_SIZE)); ++ assert_true(foreach_digest2(&ctx, 0, pcr_index, digest, 1, TCG_DIGEST2_SHA256_SIZE, 0)); + assert_memory_equal(ctx.sha256_pcrs[pcr_index], sha256sum, sizeof(sha256sum)); + } + static void test_foreach_digest2_cbfail(void **state){ +@@ -105,7 +105,7 @@ static void test_foreach_digest2_cbfail(void **state){ + will_return(foreach_digest2_test_callback, false); + + tpm2_eventlog_context ctx = { .digest2_cb = foreach_digest2_test_callback }; +- assert_false(foreach_digest2(&ctx, 0, 0, digest, 1, TCG_DIGEST2_SHA1_SIZE)); ++ assert_false(foreach_digest2(&ctx, 0, 0, digest, 1, TCG_DIGEST2_SHA1_SIZE, 0)); + } + static void test_digest2_accumulator_callback(void **state) { + diff --git a/tpm2-tools.spec b/tpm2-tools.spec index 70c694f..414add3 100644 --- a/tpm2-tools.spec +++ b/tpm2-tools.spec @@ -2,7 +2,7 @@ Name: tpm2-tools Version: 5.2 -Release: 4%{?candidate:.%{candidate}}%{?dist} +Release: 5%{?candidate:.%{candidate}}%{?dist} Summary: A bunch of TPM testing toolS build upon tpm2-tss License: BSD @@ -44,6 +44,8 @@ Patch203: 0003-tpm2_nvread-fix-input-handling-no-nv-index.patch Patch204: 0004-tpm2_checkquote-Add-comparison-of-pcr-selection.patch Patch205: 0005-tpm2_checkquote-Fix-check-of-magic-number.patch Patch206: 0006-tpm2_setprimarypolicy-Fix-resource-leak.patch +# tpm2_eventlog: add support for replay with different StartupLocality +Patch207: %{url}/commit/576a31bcc910da517067b29667f45fbe78e812e0.patch BuildRequires: git BuildRequires: make @@ -95,6 +97,10 @@ autoreconf -i %{_mandir}/man1/tss2_*.1.gz %changelog +* Fri Mar 21 2025 Davide Cavalca - 5.2-5 +- Backport upstream bugfix for tpm2_eventlog + Resolves: RHEL-83453 + * Wed Jun 19 2024 Štěpán Horáček - 5.2-4 - Backport upstream fixes. - tpm2_checkquote: Fix check of magic number. (CVE-2024-29038)