]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
efi: add EFI_TCG2_TAGGED_EVENT and helpers
authorLuca Boccassi <bluca@debian.org>
Mon, 2 Oct 2023 00:17:58 +0000 (01:17 +0100)
committerLuca Boccassi <bluca@debian.org>
Mon, 9 Oct 2023 21:22:09 +0000 (22:22 +0100)
src/boot/efi/measure.c
src/boot/efi/measure.h
src/boot/efi/proto/tcg.h

index f9aabb42be49f6e871094095e1339f7429625389..28ec6b7d8258dbd9653f22e1624f82527b7dab56 100644 (file)
@@ -42,6 +42,50 @@ static EFI_STATUS tpm1_measure_to_pcr_and_event_log(
                         &event_log_last);
 }
 
+static EFI_STATUS tpm2_measure_to_pcr_and_tagged_event_log(
+                EFI_TCG2_PROTOCOL *tcg,
+                uint32_t pcrindex,
+                EFI_PHYSICAL_ADDRESS buffer,
+                uint64_t buffer_size,
+                uint32_t event_id,
+                const char16_t *description) {
+
+        _cleanup_free_ struct event {
+                EFI_TCG2_EVENT tcg_event;
+                EFI_TCG2_TAGGED_EVENT tcg_tagged_event;
+        } _packed_ *event = NULL;
+        size_t desc_len, event_size;
+
+        assert(tcg);
+        assert(description);
+
+        desc_len = strsize16(description);
+        event_size = offsetof(EFI_TCG2_EVENT, Event) + offsetof(EFI_TCG2_TAGGED_EVENT, Event) + desc_len;
+
+        event = xmalloc0(event_size);
+
+        *event = (struct event) {
+                .tcg_event = (EFI_TCG2_EVENT) {
+                        .Size = event_size,
+                        .Header.HeaderSize = sizeof(EFI_TCG2_EVENT_HEADER),
+                        .Header.HeaderVersion = EFI_TCG2_EVENT_HEADER_VERSION,
+                        .Header.PCRIndex = pcrindex,
+                        .Header.EventType = EV_EVENT_TAG,
+                },
+                .tcg_tagged_event = {
+                        .EventId = event_id,
+                        .EventSize = desc_len,
+                },
+        };
+        memcpy(event->tcg_tagged_event.Event, description, desc_len);
+
+        return tcg->HashLogExtendEvent(
+                        tcg,
+                        0,
+                        buffer, buffer_size,
+                        &event->tcg_event);
+}
+
 static EFI_STATUS tpm2_measure_to_pcr_and_event_log(
                 EFI_TCG2_PROTOCOL *tcg,
                 uint32_t pcrindex,
@@ -185,6 +229,38 @@ EFI_STATUS tpm_log_event(uint32_t pcrindex, EFI_PHYSICAL_ADDRESS buffer, size_t
         return err;
 }
 
+EFI_STATUS tpm_log_tagged_event(
+                uint32_t pcrindex,
+                EFI_PHYSICAL_ADDRESS buffer,
+                size_t buffer_size,
+                uint32_t event_id,
+                const char16_t *description,
+                bool *ret_measured) {
+
+        EFI_TCG2_PROTOCOL *tpm2;
+        EFI_STATUS err;
+
+        assert(description || pcrindex == UINT32_MAX);
+        assert(event_id > 0);
+
+        /* If EFI_SUCCESS is returned, will initialize ret_measured to true if we actually measured
+         * something, or false if measurement was turned off. */
+
+        tpm2 = tcg2_interface_check();
+        if (!tpm2 || pcrindex == UINT32_MAX) { /* PCR disabled? */
+                if (ret_measured)
+                        *ret_measured = false;
+
+                return EFI_SUCCESS;
+        }
+
+        err = tpm2_measure_to_pcr_and_tagged_event_log(tpm2, pcrindex, buffer, buffer_size, event_id, description);
+        if (err == EFI_SUCCESS && ret_measured)
+                *ret_measured = true;
+
+        return err;
+}
+
 EFI_STATUS tpm_log_event_ascii(uint32_t pcrindex, EFI_PHYSICAL_ADDRESS buffer, size_t buffer_size, const char *description, bool *ret_measured) {
         _cleanup_free_ char16_t *c = NULL;
 
index d252f0f832b466810ea11cd26a68722c2adb8a43..c3c4e0a9ad13495e605928598fd725a36ee5249e 100644 (file)
@@ -8,6 +8,7 @@
 bool tpm_present(void);
 EFI_STATUS tpm_log_event(uint32_t pcrindex, EFI_PHYSICAL_ADDRESS buffer, size_t buffer_size, const char16_t *description, bool *ret_measured);
 EFI_STATUS tpm_log_event_ascii(uint32_t pcrindex, EFI_PHYSICAL_ADDRESS buffer, size_t buffer_size, const char *description, bool *ret_measured);
+EFI_STATUS tpm_log_tagged_event(uint32_t pcrindex, EFI_PHYSICAL_ADDRESS buffer, size_t buffer_size, uint32_t event_id, const char16_t *description, bool *ret_measured);
 EFI_STATUS tpm_log_load_options(const char16_t *cmdline, bool *ret_measured);
 
 #else
@@ -28,6 +29,12 @@ static inline EFI_STATUS tpm_log_event_ascii(uint32_t pcrindex, EFI_PHYSICAL_ADD
         return EFI_SUCCESS;
 }
 
+static inline EFI_STATUS tpm_log_tagged_event(uint32_t pcrindex, EFI_PHYSICAL_ADDRESS buffer, size_t buffer_size, uint32_t event_id, const char16_t *description, bool *ret_measured) {
+        if (ret_measured)
+                *ret_measured = false;
+        return EFI_SUCCESS;
+}
+
 static inline EFI_STATUS tpm_log_load_options(const char16_t *cmdline, bool *ret_measured) {
         if (ret_measured)
                 *ret_measured = false;
index d8802ae0e334eec41fcaf2a1953fceb07f01c097..b4b82962ef6b43f9528a0c90b2eb0b57f8398d4f 100644 (file)
@@ -11,6 +11,7 @@
 #define TCG_ALG_SHA 0x4
 #define EFI_TCG2_EVENT_HEADER_VERSION 1
 #define EV_IPL 13
+#define EV_EVENT_TAG UINT32_C(6)
 
 typedef struct {
         uint8_t Major;
@@ -70,6 +71,12 @@ typedef struct {
         uint8_t Event[];
 } _packed_ EFI_TCG2_EVENT;
 
+typedef struct {
+        uint32_t EventId;
+        uint32_t EventSize;
+        uint8_t Event[];
+} _packed_ EFI_TCG2_TAGGED_EVENT;
+
 typedef struct EFI_TCG_PROTOCOL EFI_TCG_PROTOCOL;
 struct EFI_TCG_PROTOCOL {
         EFI_STATUS (EFIAPI *StatusCheck)(