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. The computation of the pcrs based on
the replay of the eventlog is caried out by the new
function ifapi_calculate_pcrs.

Fixes #2672.

Signed-off-by: Juergen Repp <juergen_repp@web.de>
  • Loading branch information
JuergenReppSIT authored and AndreasFuchsTPM committed Nov 30, 2023
1 parent 718c478 commit 027926b
Show file tree
Hide file tree
Showing 10 changed files with 1,351 additions and 109 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 @@ -786,7 +786,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
78 changes: 26 additions & 52 deletions src/tss2-fapi/ifapi_eventlog_system.c
Original file line number Diff line number Diff line change
Expand Up @@ -99,7 +99,6 @@ bool digest2_accumulator_callback(TCG_DIGEST2 const *digest, size_t size,
bool foreach_digest2(
tpm2_eventlog_context *ctx,
UINT32 event_type,
unsigned pcr_index,
TCG_DIGEST2 const *digest,
size_t count,
size_t size) {
Expand All @@ -110,7 +109,6 @@ bool foreach_digest2(
}

bool ret = true;
TSS2_RC r;

size_t i, j;
for (i = 0; i < count; i++) {
Expand All @@ -126,29 +124,6 @@ bool foreach_digest2(
return false;
}

uint8_t *pcr = NULL;
if (pcr_index > TPM2_MAX_PCRS) {
LOG_ERROR("PCR%d > max %d", pcr_index, TPM2_MAX_PCRS);
return false;
} else if (alg == TPM2_ALG_SHA1) {
pcr = ctx->sha1_pcrs[pcr_index];
ctx->sha1_used |= (1 << pcr_index);
} else if (alg == TPM2_ALG_SHA256) {
pcr = ctx->sha256_pcrs[pcr_index];
ctx->sha256_used |= (1 << pcr_index);
} else if (alg == TPM2_ALG_SHA384) {
pcr = ctx->sha384_pcrs[pcr_index];
ctx->sha384_used |= (1 << pcr_index);
} else if (alg == TPM2_ALG_SHA512) {
pcr = ctx->sha512_pcrs[pcr_index];
ctx->sha512_used |= (1 << pcr_index);
} else if (alg == TPM2_ALG_SM3_256) {
pcr = ctx->sm3_256_pcrs[pcr_index];
ctx->sm3_256_used |= (1 << pcr_index);
} else {
LOG_WARNING("PCR%d algorithm %d unsupported", pcr_index, alg);
}

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 +132,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 +204,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 @@ -260,7 +242,7 @@ bool parse_event2(TCG_EVENT_HEADER2 const *eventhdr, size_t buf_size,
.data = digests_size,
.digest2_cb = digest2_accumulator_callback,
};
ret = foreach_digest2(&ctx, eventhdr->EventType, eventhdr->PCRIndex,
ret = foreach_digest2(&ctx, eventhdr->EventType,
eventhdr->Digests, eventhdr->DigestCount,
buf_size - sizeof(*eventhdr));
if (ret != true) {
Expand Down Expand Up @@ -310,9 +292,6 @@ bool parse_sha1_log_event(TCG_EVENT const *event, size_t size,

bool foreach_sha1_log_event(tpm2_eventlog_context *ctx, TCG_EVENT const *eventhdr_start, size_t size) {

uint8_t *pcr = NULL;
TSS2_RC r;

if (eventhdr_start == NULL) {
LOG_ERROR("invalid parameter");
return false;
Expand Down Expand Up @@ -350,16 +329,6 @@ bool foreach_sha1_log_event(tpm2_eventlog_context *ctx, TCG_EVENT const *eventhd
return ret;
}

pcr = ctx->sha1_pcrs[eventhdr->pcrIndex];
if (pcr && eventhdr->eventType != EV_NO_ACTION ) {
r = ifapi_extend_pcr(TPM2_ALG_SHA1, pcr, &eventhdr->digest[0], 20);
if (r) {
LOG_ERROR("PCR%d extend failed", eventhdr->pcrIndex);
return false;
}
ctx->sha1_used |= (1 << eventhdr->pcrIndex);
}

/* event data callback */
if (ctx->event2_cb != NULL) {
ret = ctx->event2_cb(event, eventhdr->eventType, ctx->data);
Expand Down Expand Up @@ -409,7 +378,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,
ret = foreach_digest2(ctx, eventhdr->EventType,
eventhdr->Digests, eventhdr->DigestCount, digests_size);
if (ret != true) {
return false;
Expand Down Expand Up @@ -567,6 +536,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 +576,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 @@ -633,7 +604,7 @@ check_out_string(const IFAPI_FIRMWARE_EVENT *in, const char *string) {
*
* @param[in] jso the json object to be deserialized.
* @param[out] out the deserialzed binary object.
* @param[out] verify swithc whether the digest can be verified.
* @param[out] verify switch whether the digest can be verified.
* @retval TSS2_RC_SUCCESS if the function call was a success.
* @retval TSS2_FAPI_RC_BAD_VALUE if the json object can't be deserialized.
* @retval TSS2_FAPI_RC_BAD_REFERENCE a invalid null pointer is passed.
Expand Down Expand Up @@ -661,6 +632,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 +688,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 +702,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
12 changes: 1 addition & 11 deletions src/tss2-fapi/ifapi_eventlog_system.h
Original file line number Diff line number Diff line change
Expand Up @@ -34,16 +34,6 @@ typedef struct {
EVENT2_CALLBACK event2hdr_cb;
DIGEST2_CALLBACK digest2_cb;
EVENT2DATA_CALLBACK event2_cb;
uint32_t sha1_used;
uint32_t sha256_used;
uint32_t sha384_used;
uint32_t sha512_used;
uint32_t sm3_256_used;
uint8_t sha1_pcrs[TPM2_MAX_PCRS][TPM2_SHA1_DIGEST_SIZE];
uint8_t sha256_pcrs[TPM2_MAX_PCRS][TPM2_SHA256_DIGEST_SIZE];
uint8_t sha384_pcrs[TPM2_MAX_PCRS][TPM2_SHA384_DIGEST_SIZE];
uint8_t sha512_pcrs[TPM2_MAX_PCRS][TPM2_SHA512_DIGEST_SIZE];
uint8_t sm3_256_pcrs[TPM2_MAX_PCRS][TPM2_SM3_256_DIGEST_SIZE];
} tpm2_eventlog_context;

/** Firmware event information stored in log
Expand All @@ -58,7 +48,7 @@ bool digest2_accumulator_callback(TCG_DIGEST2 const *digest, size_t size,
void *data);

bool parse_event2body(TCG_EVENT2 const *event, UINT32 type);
bool foreach_digest2(tpm2_eventlog_context *ctx, UINT32 event_type, unsigned pcr_index,
bool foreach_digest2(tpm2_eventlog_context *ctx, UINT32 event_type,
TCG_DIGEST2 const *event_hdr, size_t count, size_t size);
bool parse_event2(TCG_EVENT_HEADER2 const *eventhdr, size_t buf_size,
size_t *event_size, size_t *digests_size);
Expand Down
Loading

0 comments on commit 027926b

Please sign in to comment.