[PATCH v2] efi_loader: Add a locality event on the eventlog

We are currently not adding any events on the eventlog apart from the SpecID event. The locality event is mandatory and must be logged before extending PCR[0].
The spec description is "The Startup Locality event should be placed in the log before any event which extends PCR[0]. This allows software which needs to parse the TCG Event Log to initialize its internal PCR[0] state correctly".
So let's add a locality even during the EventLog creation, right after our SpecID event.
Signed-off-by: Ilias Apalodimas ilias.apalodimas@linaro.org --- changes since v1: - v1 was missing the required headers changes - exit on tcg2_create_digest() failure include/efi_tcg2.h | 13 ++++++++++ lib/efi_loader/efi_tcg2.c | 52 +++++++++++++++++++++++++++++---------- 2 files changed, 52 insertions(+), 13 deletions(-)
diff --git a/include/efi_tcg2.h b/include/efi_tcg2.h index 40e241ce315c..eac76774d7ff 100644 --- a/include/efi_tcg2.h +++ b/include/efi_tcg2.h @@ -72,6 +72,7 @@ struct efi_tcg2_boot_service_capability { offsetof(struct efi_tcg2_boot_service_capability, number_of_pcr_banks)
#define TCG_EFI_SPEC_ID_EVENT_SIGNATURE_03 "Spec ID Event03" +#define TCG_EFI_STARTUP_LOCALITY_SIGNATURE "StartupLocality" #define TCG_EFI_SPEC_ID_EVENT_SPEC_VERSION_MAJOR_TPM2 2 #define TCG_EFI_SPEC_ID_EVENT_SPEC_VERSION_MINOR_TPM2 0 #define TCG_EFI_SPEC_ID_EVENT_SPEC_VERSION_ERRATA_TPM2 2 @@ -120,6 +121,18 @@ struct tcg_efi_spec_id_event { u8 vendor_info[]; } __packed;
+/** + * struct tdTCG_EfiStartupLocalityEvent + * + * @signature: The NUL-terminated ASCII string "StartupLocality" + * @startup_locality: The Locality Indicator which sent the TPM2_Startup + * command + */ +struct tcg_efi_startup_locality_event { + u8 signature[16]; + u8 startup_locality; +} __packed; + /** * struct tdEFI_TCG2_FINAL_EVENTS_TABLE * @version: version number for this structure diff --git a/lib/efi_loader/efi_tcg2.c b/lib/efi_loader/efi_tcg2.c index 797d6eb134f6..31c80b21d8b5 100644 --- a/lib/efi_loader/efi_tcg2.c +++ b/lib/efi_loader/efi_tcg2.c @@ -513,7 +513,7 @@ static efi_status_t tcg2_create_digest(const u8 *input, u32 length, sha1_context ctx; sha256_context ctx_256; sha512_context ctx_512; - u8 final[TPM2_ALG_SHA512]; + u8 final[TPM2_ALG_SHA512] = { 0 }; efi_status_t ret; u32 active; int i; @@ -530,27 +530,35 @@ static efi_status_t tcg2_create_digest(const u8 *input, u32 length, continue; switch (hash_alg) { case TPM2_ALG_SHA1: - sha1_starts(&ctx); - sha1_update(&ctx, input, length); - sha1_finish(&ctx, final); + if (input) { + sha1_starts(&ctx); + sha1_update(&ctx, input, length); + sha1_finish(&ctx, final); + } digest_list->count++; break; case TPM2_ALG_SHA256: - sha256_starts(&ctx_256); - sha256_update(&ctx_256, input, length); - sha256_finish(&ctx_256, final); + if (input) { + sha256_starts(&ctx_256); + sha256_update(&ctx_256, input, length); + sha256_finish(&ctx_256, final); + } digest_list->count++; break; case TPM2_ALG_SHA384: - sha384_starts(&ctx_512); - sha384_update(&ctx_512, input, length); - sha384_finish(&ctx_512, final); + if (input) { + sha384_starts(&ctx_512); + sha384_update(&ctx_512, input, length); + sha384_finish(&ctx_512, final); + } digest_list->count++; break; case TPM2_ALG_SHA512: - sha512_starts(&ctx_512); - sha512_update(&ctx_512, input, length); - sha512_finish(&ctx_512, final); + if (input) { + sha512_starts(&ctx_512); + sha512_update(&ctx_512, input, length); + sha512_finish(&ctx_512, final); + } digest_list->count++; break; default: @@ -1004,6 +1012,8 @@ static efi_status_t efi_init_event_log(void) struct udevice *dev; size_t spec_event_size; efi_status_t ret; + struct tcg_efi_startup_locality_event locality_event; + struct tpml_digest_values digest_list;
ret = platform_get_tpm2_device(&dev); if (ret != EFI_SUCCESS) @@ -1040,6 +1050,22 @@ static efi_status_t efi_init_event_log(void) event_log.pos = spec_event_size + sizeof(*event_header); event_log.last_event_size = event_log.pos;
+ /* Add a locality event before PCR[0] changes */ + memcpy(locality_event.signature, TCG_EFI_STARTUP_LOCALITY_SIGNATURE, + sizeof(locality_event.signature)); + /* + * Locality 0 is designated as the default Locality. This is usually + * the platform’s boot firmware, OS and applications. + */ + locality_event.startup_locality = 0; + ret = tcg2_create_digest(NULL, 0, &digest_list); + if (ret != EFI_SUCCESS) + goto out; + ret = tcg2_agile_log_append(0, EV_NO_ACTION, &digest_list, + sizeof(locality_event), (u8*)&locality_event); + if (ret != EFI_SUCCESS) + goto out; + ret = create_final_event();
out:

Responding to myself here, but after re-reading the spec, I realized this is only required, if the startup locality was set to '3'. So Heinrich please ignore this for now, I'll repost it once we have a way to read the startup locality properly
Cheers /Ilias
On Wed, 24 Mar 2021 at 09:43, Ilias Apalodimas ilias.apalodimas@linaro.org wrote:
We are currently not adding any events on the eventlog apart from the SpecID event. The locality event is mandatory and must be logged before extending PCR[0].
The spec description is "The Startup Locality event should be placed in the log before any event which extends PCR[0]. This allows software which needs to parse the TCG Event Log to initialize its internal PCR[0] state correctly".
So let's add a locality even during the EventLog creation, right after our SpecID event.
Signed-off-by: Ilias Apalodimas ilias.apalodimas@linaro.org
changes since v1:
- v1 was missing the required headers changes
- exit on tcg2_create_digest() failure
include/efi_tcg2.h | 13 ++++++++++ lib/efi_loader/efi_tcg2.c | 52 +++++++++++++++++++++++++++++---------- 2 files changed, 52 insertions(+), 13 deletions(-)
diff --git a/include/efi_tcg2.h b/include/efi_tcg2.h index 40e241ce315c..eac76774d7ff 100644 --- a/include/efi_tcg2.h +++ b/include/efi_tcg2.h @@ -72,6 +72,7 @@ struct efi_tcg2_boot_service_capability { offsetof(struct efi_tcg2_boot_service_capability, number_of_pcr_banks)
#define TCG_EFI_SPEC_ID_EVENT_SIGNATURE_03 "Spec ID Event03" +#define TCG_EFI_STARTUP_LOCALITY_SIGNATURE "StartupLocality" #define TCG_EFI_SPEC_ID_EVENT_SPEC_VERSION_MAJOR_TPM2 2 #define TCG_EFI_SPEC_ID_EVENT_SPEC_VERSION_MINOR_TPM2 0 #define TCG_EFI_SPEC_ID_EVENT_SPEC_VERSION_ERRATA_TPM2 2 @@ -120,6 +121,18 @@ struct tcg_efi_spec_id_event { u8 vendor_info[]; } __packed;
+/**
- struct tdTCG_EfiStartupLocalityEvent
- @signature: The NUL-terminated ASCII string "StartupLocality"
- @startup_locality: The Locality Indicator which sent the TPM2_Startup
command
- */
+struct tcg_efi_startup_locality_event {
u8 signature[16];
u8 startup_locality;
+} __packed;
/**
- struct tdEFI_TCG2_FINAL_EVENTS_TABLE
- @version: version number for this structure
diff --git a/lib/efi_loader/efi_tcg2.c b/lib/efi_loader/efi_tcg2.c index 797d6eb134f6..31c80b21d8b5 100644 --- a/lib/efi_loader/efi_tcg2.c +++ b/lib/efi_loader/efi_tcg2.c @@ -513,7 +513,7 @@ static efi_status_t tcg2_create_digest(const u8 *input, u32 length, sha1_context ctx; sha256_context ctx_256; sha512_context ctx_512;
u8 final[TPM2_ALG_SHA512];
u8 final[TPM2_ALG_SHA512] = { 0 }; efi_status_t ret; u32 active; int i;
@@ -530,27 +530,35 @@ static efi_status_t tcg2_create_digest(const u8 *input, u32 length, continue; switch (hash_alg) { case TPM2_ALG_SHA1:
sha1_starts(&ctx);
sha1_update(&ctx, input, length);
sha1_finish(&ctx, final);
if (input) {
sha1_starts(&ctx);
sha1_update(&ctx, input, length);
sha1_finish(&ctx, final);
} digest_list->count++; break; case TPM2_ALG_SHA256:
sha256_starts(&ctx_256);
sha256_update(&ctx_256, input, length);
sha256_finish(&ctx_256, final);
if (input) {
sha256_starts(&ctx_256);
sha256_update(&ctx_256, input, length);
sha256_finish(&ctx_256, final);
} digest_list->count++; break; case TPM2_ALG_SHA384:
sha384_starts(&ctx_512);
sha384_update(&ctx_512, input, length);
sha384_finish(&ctx_512, final);
if (input) {
sha384_starts(&ctx_512);
sha384_update(&ctx_512, input, length);
sha384_finish(&ctx_512, final);
} digest_list->count++; break; case TPM2_ALG_SHA512:
sha512_starts(&ctx_512);
sha512_update(&ctx_512, input, length);
sha512_finish(&ctx_512, final);
if (input) {
sha512_starts(&ctx_512);
sha512_update(&ctx_512, input, length);
sha512_finish(&ctx_512, final);
} digest_list->count++; break; default:
@@ -1004,6 +1012,8 @@ static efi_status_t efi_init_event_log(void) struct udevice *dev; size_t spec_event_size; efi_status_t ret;
struct tcg_efi_startup_locality_event locality_event;
struct tpml_digest_values digest_list; ret = platform_get_tpm2_device(&dev); if (ret != EFI_SUCCESS)
@@ -1040,6 +1050,22 @@ static efi_status_t efi_init_event_log(void) event_log.pos = spec_event_size + sizeof(*event_header); event_log.last_event_size = event_log.pos;
/* Add a locality event before PCR[0] changes */
memcpy(locality_event.signature, TCG_EFI_STARTUP_LOCALITY_SIGNATURE,
sizeof(locality_event.signature));
/*
* Locality 0 is designated as the default Locality. This is usually
* the platform’s boot firmware, OS and applications.
*/
locality_event.startup_locality = 0;
ret = tcg2_create_digest(NULL, 0, &digest_list);
if (ret != EFI_SUCCESS)
goto out;
ret = tcg2_agile_log_append(0, EV_NO_ACTION, &digest_list,
sizeof(locality_event), (u8*)&locality_event);
if (ret != EFI_SUCCESS)
goto out;
ret = create_final_event();
out:
2.31.0
participants (1)
-
Ilias Apalodimas