Skip to content

Commit

Permalink
FAPI: Eventlog add H-CRTM and different locality support.
Browse files Browse the repository at this point in the history
* For H-CRTM events pcr0 has to be initialized with 4.
* A different locality can be set in an event with a
  startup locality signature.

To enable the implementation of a corresponding unit test
the function ifapi_check_profile_pcr_selection was splitted
into two functions. The new function ifapi_calculate_pcrs
is used in the unit test to check whether the expected
pcr0 is computed from the event list computed from the
binary H-CRTM firmware file. The pcr extension during
parsing the firmware was removed. The computed pcr values
were not used.

Fixes #2672.

Signed-off-by: Juergen Repp <juergen_repp@web.de>
  • Loading branch information
JuergenReppSIT committed Aug 21, 2023
1 parent b7bad34 commit 0c58171
Show file tree
Hide file tree
Showing 10 changed files with 1,380 additions and 62 deletions.
3 changes: 2 additions & 1 deletion Makefile-test.am
Original file line number Diff line number Diff line change
Expand Up @@ -92,7 +92,8 @@ FAPI_TEST_BINS = \
test/data/fapi/eventlog/sml-ima-sig-sha256-invalidated.bin \
test/data/fapi/eventlog/event-uefivar.bin \
test/data/fapi/eventlog/specid-vendordata.bin \
test/data/fapi/eventlog/sml-ima-ng-sha1.bin
test/data/fapi/eventlog/sml-ima-ng-sha1.bin \
test/data/fapi/eventlog/binary_measurements_hcrtm.bin

CLEANFILES += $(FAPI_TEST_BINS)
endif #FAPI
Expand Down
3 changes: 2 additions & 1 deletion Makefile.am
Original file line number Diff line number Diff line change
Expand Up @@ -760,7 +760,8 @@ EXTRA_DIST += \
test/data/fapi/eventlog/sml-ima-ng-sha1-invalidated.b64 \
test/data/fapi/eventlog/sml-ima-ng-sha1-invalidated.b64 \
test/data/fapi/eventlog/sml-ima-sig-sha256-invalidated.b64 \
test/data/fapi/eventlog/sml-ima-sha1-invalidated.b64
test/data/fapi/eventlog/sml-ima-sha1-invalidated.b64 \
test/data/fapi/eventlog/binary_measurements_hcrtm.b64

src_tss2_fapi_libtss2_fapi_la_LIBADD = $(libtss2_sys) $(libtss2_mu) $(libtss2_esys) \
$(libutil) $(libtss2_tctildr)
Expand Down
15 changes: 15 additions & 0 deletions src/tss2-fapi/efi_event.h
Original file line number Diff line number Diff line change
Expand Up @@ -125,4 +125,19 @@ typedef struct {
BYTE DevicePath[];
} PACKED UEFI_IMAGE_LOAD_EVENT;

/*
* EV_NO_ACTION_STRUCT is the structure of an EV_NO_ACTION event.
* Described in TCG PCClient PFP section 9.4.5.
* The Signature identifies which arm of the union applies.
*/
typedef struct {
BYTE Signature[16];
union {
BYTE StartupLocality;
} Cases;
} PACKED EV_NO_ACTION_STRUCT;

static const BYTE STARTUP_LOCALITY_SIGNATURE[16] = {0x53, 0x74, 0x61, 0x72, 0x74, 0x75, 0x70, 0x4C,
0x6F, 0x63, 0x61, 0x6C, 0x69, 0x74, 0x79, 0};

#endif
71 changes: 56 additions & 15 deletions src/tss2-fapi/ifapi_eventlog_system.c
Original file line number Diff line number Diff line change
Expand Up @@ -102,15 +102,15 @@ bool foreach_digest2(
unsigned pcr_index,
TCG_DIGEST2 const *digest,
size_t count,
size_t size) {
size_t size,
uint8_t locality) {

if (digest == NULL) {
LOG_ERROR("digest cannot be NULL");
return false;
}

bool ret = true;
TSS2_RC r;

size_t i, j;
for (i = 0; i < count; i++) {
Expand Down Expand Up @@ -149,6 +149,13 @@ bool foreach_digest2(
LOG_WARNING("PCR%d algorithm %d unsupported", pcr_index, alg);
}

if (event_type == EV_EFI_HCRTM_EVENT && pcr && pcr_index == 0) {
/* Trusted Platform Module Library Part 1 section 34.3 */
pcr[alg_size - 1] = 0x04;
} else if (event_type == EV_NO_ACTION && pcr && pcr_index == 0 && locality > 0) {
pcr[alg_size -1] = locality;
}

if (event_type == EV_NO_ACTION) {
/* Digest for EV_NO_ACTION must consist of 0 bytes. */
for (j = 0; j < alg_size; j++) {
Expand All @@ -157,14 +164,6 @@ bool foreach_digest2(
return false;
}
}
} else {
if (pcr) {
r = ifapi_extend_pcr(alg, pcr, digest->Digest, alg_size);
if (r) {
LOG_ERROR("PCR%d extend failed", pcr_index);
return false;
}
}
}

if (ctx->digest2_cb != NULL) {
Expand Down Expand Up @@ -237,6 +236,21 @@ bool parse_event2body(TCG_EVENT2 const *event, UINT32 type) {
/* what about the device path? */
}
break;
/* TCG PC Client Platform Firmware Profile Specification Level 00 Version 1.05 Revision 23 section 10.4.1 */
case EV_EFI_HCRTM_EVENT:
{
const char hcrtm_data[] = "HCRTM";
size_t len = strlen(hcrtm_data);
BYTE *data = (BYTE *)event->Event;
if (event->EventSize != len ||
strncmp((const char *)data, hcrtm_data, len)) {
LOG_ERROR("HCRTM Event Data MUST be the string: \"%s\"", hcrtm_data);
return false;
}
}
break;


}

return true;
Expand All @@ -262,7 +276,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;
}
Expand Down Expand Up @@ -385,13 +399,15 @@ 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;
eventhdr = (TCG_EVENT_HEADER2*)((uintptr_t)eventhdr + event_size),
size -= event_size) {

size_t digests_size = 0;
uint8_t locality = 0;

ret = parse_event2(eventhdr, size, &event_size, &digests_size);
if (!ret) {
Expand All @@ -400,6 +416,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_ERROR("EventSize is too small.");
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);
Expand All @@ -410,7 +445,8 @@ 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;
}
Expand Down Expand Up @@ -567,6 +603,7 @@ ifapi_json_TCG_EVENT_TYPE_deserialize_txt(json_object *jso,
const char *token = json_object_get_string(jso);

check_oom(token);
LOG_TRACE("TCG Event: %s", token);

if (get_number(token, &i64)) {
*out = (IFAPI_EVENT_TYPE) i64;
Expand Down Expand Up @@ -606,6 +643,7 @@ TSS2_RC
ifapi_json_TCG_EVENT_TYPE_deserialize(json_object *jso, IFAPI_EVENT_TYPE *out)
{
LOG_TRACE("call");

return ifapi_json_TCG_EVENT_TYPE_deserialize_txt(jso, out);
}

Expand Down Expand Up @@ -661,6 +699,8 @@ ifapi_json_IFAPI_FIRMWARE_EVENT_deserialize(
r = ifapi_json_TCG_EVENT_TYPE_deserialize (jso2, &event_type);
return_if_error(r,"BAD VALUE");

out->event_type = event_type;

if (!ifapi_get_sub_object(jso, "event_data", &jso2)) {
LOG_ERROR("Bad value");
return TSS2_FAPI_RC_BAD_VALUE;
Expand Down Expand Up @@ -715,7 +755,10 @@ ifapi_json_IFAPI_FIRMWARE_EVENT_deserialize(
event_type == EV_IPL_PARTITION_DATA ||
event_type == EV_NONHOST_CODE ||
event_type == EV_NONHOST_CONFIG ||
event_type == EV_EFI_RUNTIME_SERVICES_DRIVER) {
event_type == EV_EFI_RUNTIME_SERVICES_DRIVER ||
/* Verification not possible. (TODO check) */
event_type == EV_EFI_HCRTM_EVENT ||
event_type == EV_EFI_VARIABLE_BOOT) {
*verify = false;
} else if (
/* Verification is possible. (TODO check) */
Expand All @@ -726,12 +769,10 @@ ifapi_json_IFAPI_FIRMWARE_EVENT_deserialize(
event_type == EV_EFI_VARIABLE_AUTHORITY ||
/* Verification is possible. */
event_type == EV_S_CRTM_VERSION ||
event_type == EV_EFI_HCRTM_EVENT ||
event_type == EV_SEPARATOR ||
event_type == EV_EFI_VARIABLE_DRIVER_CONFIG ||
event_type == EV_EFI_GPT_EVENT ||
event_type == EV_PLATFORM_CONFIG_FLAGS ||
event_type == EV_EFI_VARIABLE_BOOT ||
event_type == EV_EFI_ACTION) {
*verify = true;
} else {
Expand Down
2 changes: 1 addition & 1 deletion src/tss2-fapi/ifapi_eventlog_system.h
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,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 event_type, 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);
Expand Down
Loading

0 comments on commit 0c58171

Please sign in to comment.