Backport upstream bugfix for tpm2_eventlog
tpm2_eventlog reads the UEFI TPM eventlog, and uses it to calculate the PCR values we expect the TPM to contain. If they match then we know we can use the information in the eventlog to validate we see the expected events. This commit fixes an error where the PCR calculation fails to take into account the startup details of the TPM, resulting in incorrectly calculating the expected value for PCR0. Resolves: RHEL-83453 Signed-off-by: Davide Cavalca <dcavalca@centosproject.org>
This commit is contained in:
parent
acfe6b50eb
commit
bf85ff7d7a
194
576a31bcc910da517067b29667f45fbe78e812e0.patch
Normal file
194
576a31bcc910da517067b29667f45fbe78e812e0.patch
Normal file
@ -0,0 +1,194 @@
|
||||
From 576a31bcc910da517067b29667f45fbe78e812e0 Mon Sep 17 00:00:00 2001
|
||||
From: Thore Sommer <mail@thson.de>
|
||||
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 <mail@thson.de>
|
||||
---
|
||||
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) {
|
||||
|
||||
@ -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 <dcavalca@centosproject.org> - 5.2-5
|
||||
- Backport upstream bugfix for tpm2_eventlog
|
||||
Resolves: RHEL-83453
|
||||
|
||||
* Wed Jun 19 2024 Štěpán Horáček <shoracek@redhat.com> - 5.2-4
|
||||
- Backport upstream fixes.
|
||||
- tpm2_checkquote: Fix check of magic number. (CVE-2024-29038)
|
||||
|
||||
Loading…
Reference in New Issue
Block a user