195 lines
8.7 KiB
Diff
195 lines
8.7 KiB
Diff
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) {
|
|
|