Skip to contentSkip to conversation

efi/libstub: Fall back to CC proto for measurement

PATCH Superseded Ard Biesheuvel 3 participants 9 messages Mar 7, 2024 – Mar 8, 2024 EFI

v2 of 3 Superseded Latest is v3 →

lore
Share & tools
lore
#0 lore raw

v2 cover efi/libstub: Fall back to CC proto for measurement

From: Ard Biesheuvel <[email protected]>

This is a follow-up to Kuppuswamy's series [0] to add TDX based measurement of the initrd and command line to the EFI stub.

In view of time wrt the merge window, I've taken the liberty of applying my review feedback to the code directly, rather than going back and forth with the author to converge on something we can both agree on.

Changes since v1:
- add patch to switch to the TCG2 spec's symbolic GUID name for the final events table
- omit flex array member in efi_cc_event_t
- avoid version confusion between CC and TCG2 both using version 2

Cc Kuppuswamy Sathyanarayanan <[email protected]>
Cc Ilias Apalodimas <[email protected]>

[0] https://lore.kernel.org/all/20240215030002.281456-1-sathyanarayanan.kuppuswamy@linux.intel.com/

Ard Biesheuvel (3):
efi/libstub: Fold efi_tcg2_tagged_event into efi_measured_event efi/tpm: Use symbolic GUID name from spec for final events table efi/libstub: Measure into CC protocol if TCG2 protocol is absent

Kuppuswamy Sathyanarayanan (2):
efi/libstub: Add Confidential Computing (CC) measurement typedefs efi/libstub: Add get_event_log() support for CC platforms

 drivers/firmware/efi/efi.c                     |  3 +-
 drivers/firmware/efi/libstub/efi-stub-helper.c | 98 ++++++++++++++------
 drivers/firmware/efi/libstub/efi-stub.c        |  2 +-
 drivers/firmware/efi/libstub/efistub.h         | 90 ++++++++++++++++--
 drivers/firmware/efi/libstub/tpm.c             | 82 ++++++++++------
 drivers/firmware/efi/libstub/x86-stub.c        |  2 +-
 include/linux/efi.h                            |  5 +-
 7 files changed, 214 insertions(+), 68 deletions(-)
Signature · 1 line
2.44.0.278.ge034bb2e1d-goog
#1 lore raw

PATCH v2 1/5 efi/libstub: Fold efi_tcg2_tagged_event into efi_measured_event

From: Ard Biesheuvel <[email protected]>

In spite of the efi_ prefix, struct efi_tcg2_tagged_event is specific to the EFI stub, and so we can tweak it to our liking if needed, e.g., to accommodate the TDX variant of the TCG2 measurement protocol.

In preparation for that, get rid of it entirely, and combine it with the efi_measured_event struct used by the measurement code.

---
 drivers/firmware/efi/libstub/efi-stub-helper.c | 38 +++++++++++---------
 drivers/firmware/efi/libstub/efistub.h         |  7 ----
 2 files changed, 22 insertions(+), 23 deletions(-)
drivers/firmware/efi/libstub/efi-stub-helper.c +22 -16
index bfa30625f5d0..186ced8371ac 100644
@@ -11,6 +11,7 @@
 
 #include <linux/efi.h>
 #include <linux/kernel.h>
+#include <linux/overflow.h>
 #include <asm/efi.h>
 #include <asm/setup.h>
 
@@ -193,7 +194,7 @@ void efi_apply_loadoptions_quirk(const void **load_options, u32 *load_options_si
 	*load_options_size = load_option_unpacked.optional_data_size;
 }
 
-enum efistub_event {
+enum efistub_event_type {
 	EFISTUB_EVT_INITRD,
 	EFISTUB_EVT_LOAD_OPTIONS,
 	EFISTUB_EVT_COUNT,
@@ -219,46 +220,51 @@ static const struct {
 	},
 };
 
+union efistub_event {
+	efi_tcg2_event_t	tcg2_data;
+};
+
+struct efistub_measured_event {
+	union efistub_event	event_data;
+	u32			tagged_event_id;
+	u32			tagged_event_data_size;
+	u8			tagged_event_data[];
+} __packed;
+
 static efi_status_t efi_measure_tagged_event(unsigned long load_addr,
 					     unsigned long load_size,
-					     enum efistub_event event)
+					     enum efistub_event_type event)
 {
+	struct efistub_measured_event *evt;
+	int size = struct_size(evt, tagged_event_data,
+			       events[event].event_data_len);
 	efi_guid_t tcg2_guid = EFI_TCG2_PROTOCOL_GUID;
 	efi_tcg2_protocol_t *tcg2 = NULL;
 	efi_status_t status;
 
 	efi_bs_call(locate_protocol, &tcg2_guid, NULL, (void **)&tcg2);
 	if (tcg2) {
-		struct efi_measured_event {
-			efi_tcg2_event_t	event_data;
-			efi_tcg2_tagged_event_t tagged_event;
-			u8			tagged_event_data[];
-		} *evt;
-		int size = sizeof(*evt) + events[event].event_data_len;
-
 		status = efi_bs_call(allocate_pool, EFI_LOADER_DATA, size,
 				     (void **)&evt);
 		if (status != EFI_SUCCESS)
 			goto fail;
 
-		evt->event_data = (struct efi_tcg2_event){
+		evt->event_data.tcg2_data = (struct efi_tcg2_event){
 			.event_size			= size,
-			.event_header.header_size	= sizeof(evt->event_data.event_header),
+			.event_header.header_size	= sizeof(evt->event_data.tcg2_data.event_header),
 			.event_header.header_version	= EFI_TCG2_EVENT_HEADER_VERSION,
 			.event_header.pcr_index		= events[event].pcr_index,
 			.event_header.event_type	= EV_EVENT_TAG,
 		};
 
-		evt->tagged_event = (struct efi_tcg2_tagged_event){
-			.tagged_event_id		= events[event].event_id,
-			.tagged_event_data_size		= events[event].event_data_len,
-		};
+		evt->tagged_event_id		= events[event].event_id;
+		evt->tagged_event_data_size	= events[event].event_data_len;
 
 		memcpy(evt->tagged_event_data, events[event].event_data,
 		       events[event].event_data_len);
 
 		status = efi_call_proto(tcg2, hash_log_extend_event, 0,
-					load_addr, load_size, &evt->event_data);
+					load_addr, load_size, &evt->event_data.tcg2_data);
 		efi_bs_call(free_pool, evt);
 
 		if (status != EFI_SUCCESS)
drivers/firmware/efi/libstub/efistub.h +0 -7
index c04b82ea40f2..dae635cc3d4f 100644
@@ -843,14 +843,7 @@ struct efi_tcg2_event {
 	/* u8[] event follows here */
 } __packed;
 
-struct efi_tcg2_tagged_event {
-	u32 tagged_event_id;
-	u32 tagged_event_data_size;
-	/* u8  tagged event data follows here */
-} __packed;
-
 typedef struct efi_tcg2_event efi_tcg2_event_t;
-typedef struct efi_tcg2_tagged_event efi_tcg2_tagged_event_t;
 typedef union efi_tcg2_protocol efi_tcg2_protocol_t;
 
 union efi_tcg2_protocol {
Signature · 1 line
2.44.0.278.ge034bb2e1d-goog
reviewer Reviewed-by on v2 1/5
#2 lore raw

Re: [PATCH v2 1/5] efi/libstub: Fold efi_tcg2_tagged_event into efi_measured_event

Hi Ard,

Quoted 7 lines · Ard Biesheuvel

From: Ard Biesheuvel <[email protected]>

In spite of the efi_ prefix, struct efi_tcg2_tagged_event is specific to the EFI stub, and so we can tweak it to our liking if needed, e.g., to accommodate the TDX variant of the TCG2 measurement protocol.

Quoted 5 lines

In preparation for that, get rid of it entirely, and combine it with the efi_measured_event struct used by the measurement code.

Quoted 115 lines
---
 drivers/firmware/efi/libstub/efi-stub-helper.c | 38 +++++++++++---------
 drivers/firmware/efi/libstub/efistub.h         |  7 ----
 2 files changed, 22 insertions(+), 23 deletions(-)
drivers/firmware/efi/libstub/efi-stub-helper.c +22 -16
index bfa30625f5d0..186ced8371ac 100644
@@ -11,6 +11,7 @@
 
 #include <linux/efi.h>
 #include <linux/kernel.h>
+#include <linux/overflow.h>
 #include <asm/efi.h>
 #include <asm/setup.h>
 
@@ -193,7 +194,7 @@ void efi_apply_loadoptions_quirk(const void **load_options, u32 *load_options_si
        *load_options_size = load_option_unpacked.optional_data_size;
 }
 
-enum efistub_event {
+enum efistub_event_type {
        EFISTUB_EVT_INITRD,
        EFISTUB_EVT_LOAD_OPTIONS,
        EFISTUB_EVT_COUNT,
@@ -219,46 +220,51 @@ static const struct {
        },
 };
 
+union efistub_event {
+       efi_tcg2_event_t        tcg2_data;
+};
+
+struct efistub_measured_event {
+       union efistub_event     event_data;
+       u32                     tagged_event_id;
+       u32                     tagged_event_data_size;
+       u8                      tagged_event_data[];
+} __packed;
+
 static efi_status_t efi_measure_tagged_event(unsigned long load_addr,
                                             unsigned long load_size,
-                                            enum efistub_event event)
+                                            enum efistub_event_type event)
 {
+       struct efistub_measured_event *evt;
+       int size = struct_size(evt, tagged_event_data,
+                              events[event].event_data_len);
        efi_guid_t tcg2_guid = EFI_TCG2_PROTOCOL_GUID;
        efi_tcg2_protocol_t *tcg2 = NULL;
        efi_status_t status;
 
        efi_bs_call(locate_protocol, &tcg2_guid, NULL, (void **)&tcg2);
        if (tcg2) {
-               struct efi_measured_event {
-                       efi_tcg2_event_t        event_data;
-                       efi_tcg2_tagged_event_t tagged_event;
-                       u8                      tagged_event_data[];
-               } *evt;
-               int size = sizeof(*evt) + events[event].event_data_len;
-
                status = efi_bs_call(allocate_pool, EFI_LOADER_DATA, size,
                                     (void **)&evt);
                if (status != EFI_SUCCESS)
                        goto fail;
 
-               evt->event_data = (struct efi_tcg2_event){
+               evt->event_data.tcg2_data = (struct efi_tcg2_event){
                        .event_size                     = size,
-                       .event_header.header_size       = sizeof(evt->event_data.event_header),
+                       .event_header.header_size       = sizeof(evt->event_data.tcg2_data.event_header),
                        .event_header.header_version    = EFI_TCG2_EVENT_HEADER_VERSION,
                        .event_header.pcr_index         = events[event].pcr_index,
                        .event_header.event_type        = EV_EVENT_TAG,
                };
 
-               evt->tagged_event = (struct efi_tcg2_tagged_event){
-                       .tagged_event_id                = events[event].event_id,
-                       .tagged_event_data_size         = events[event].event_data_len,
-               };
+               evt->tagged_event_id            = events[event].event_id;
+               evt->tagged_event_data_size     = events[event].event_data_len;
 
                memcpy(evt->tagged_event_data, events[event].event_data,
                       events[event].event_data_len);
 
                status = efi_call_proto(tcg2, hash_log_extend_event, 0,
-                                       load_addr, load_size, &evt->event_data);
+                                       load_addr, load_size, &evt->event_data.tcg2_data);
                efi_bs_call(free_pool, evt);
 
                if (status != EFI_SUCCESS)
drivers/firmware/efi/libstub/efistub.h +0 -8
index c04b82ea40f2..dae635cc3d4f 100644
@@ -843,14 +843,7 @@ struct efi_tcg2_event {
        /* u8[] event follows here */
 } __packed;
 
-struct efi_tcg2_tagged_event {
-       u32 tagged_event_id;
-       u32 tagged_event_data_size;
-       /* u8  tagged event data follows here */
-} __packed;
-
 typedef struct efi_tcg2_event efi_tcg2_event_t;
-typedef struct efi_tcg2_tagged_event efi_tcg2_tagged_event_t;
 typedef union efi_tcg2_protocol efi_tcg2_protocol_t;
 
 union efi_tcg2_protocol {
--

2.44.0.278.ge034bb2e1d-goog

#3 lore raw

PATCH v2 2/5 efi/tpm: Use symbolic GUID name from spec for final events table

In reply to Ard Biesheuvel

From: Ard Biesheuvel <[email protected]>

The LINUX_EFI_ GUID identifiers are only intended to be used to refer to GUIDs that are part of the Linux implementation, and are not considered external ABI. (Famous last words).

GUIDs that already have a symbolic name in the spec should use that name, to avoid confusion between firmware components. So use the official name EFI_TCG2_FINAL_EVENTS_TABLE_GUID for the TCG2 'final events' configuration table.

---
 drivers/firmware/efi/efi.c         | 2 +-
 drivers/firmware/efi/libstub/tpm.c | 2 +-
 include/linux/efi.h                | 2 +-
 3 files changed, 3 insertions(+), 3 deletions(-)
drivers/firmware/efi/efi.c +1 -1
index 4fcda50acfa4..f6cfd29308d9 100644
@@ -597,7 +597,7 @@ static const efi_config_table_type_t common_tables[] __initconst = {
 	{EFI_MEMORY_ATTRIBUTES_TABLE_GUID,	&efi_mem_attr_table,	"MEMATTR"	},
 	{LINUX_EFI_RANDOM_SEED_TABLE_GUID,	&efi_rng_seed,		"RNG"		},
 	{LINUX_EFI_TPM_EVENT_LOG_GUID,		&efi.tpm_log,		"TPMEventLog"	},
-	{LINUX_EFI_TPM_FINAL_LOG_GUID,		&efi.tpm_final_log,	"TPMFinalLog"	},
+	{EFI_TCG2_FINAL_EVENTS_TABLE_GUID,	&efi.tpm_final_log,	"TPMFinalLog"	},
 	{LINUX_EFI_MEMRESERVE_TABLE_GUID,	&mem_reserve,		"MEMRESERVE"	},
 	{LINUX_EFI_INITRD_MEDIA_GUID,		&initrd,		"INITRD"	},
 	{EFI_RT_PROPERTIES_TABLE_GUID,		&rt_prop,		"RTPROP"	},
drivers/firmware/efi/libstub/tpm.c +1 -1
index 7acbac16eae0..a880f7374c27 100644
@@ -128,7 +128,7 @@ void efi_retrieve_tpm2_eventlog(void)
 	 * final events structure, and if so how much space they take up
 	 */
 	if (version == EFI_TCG2_EVENT_LOG_FORMAT_TCG_2)
-		final_events_table = get_efi_config_table(LINUX_EFI_TPM_FINAL_LOG_GUID);
+		final_events_table = get_efi_config_table(EFI_TCG2_FINAL_EVENTS_TABLE_GUID);
 	if (final_events_table && final_events_table->nr_events) {
 		struct tcg_pcr_event2_head *header;
 		int offset;
include/linux/efi.h +1 -1
index c74f47711f0b..464fe16411b8 100644
@@ -386,6 +386,7 @@ void efi_native_runtime_setup(void);
 #define EFI_CONSOLE_OUT_DEVICE_GUID		EFI_GUID(0xd3b36f2c, 0xd551, 0x11d4,  0x9a, 0x46, 0x00, 0x90, 0x27, 0x3f, 0xc1, 0x4d)
 #define APPLE_PROPERTIES_PROTOCOL_GUID		EFI_GUID(0x91bd12fe, 0xf6c3, 0x44fb,  0xa5, 0xb7, 0x51, 0x22, 0xab, 0x30, 0x3a, 0xe0)
 #define EFI_TCG2_PROTOCOL_GUID			EFI_GUID(0x607f766c, 0x7455, 0x42be,  0x93, 0x0b, 0xe4, 0xd7, 0x6d, 0xb2, 0x72, 0x0f)
+#define EFI_TCG2_FINAL_EVENTS_TABLE_GUID	EFI_GUID(0x1e2ed096, 0x30e2, 0x4254,  0xbd, 0x89, 0x86, 0x3b, 0xbe, 0xf8, 0x23, 0x25)
 #define EFI_LOAD_FILE_PROTOCOL_GUID		EFI_GUID(0x56ec3091, 0x954c, 0x11d2,  0x8e, 0x3f, 0x00, 0xa0, 0xc9, 0x69, 0x72, 0x3b)
 #define EFI_LOAD_FILE2_PROTOCOL_GUID		EFI_GUID(0x4006c0c1, 0xfcb3, 0x403e,  0x99, 0x6d, 0x4a, 0x6c, 0x87, 0x24, 0xe0, 0x6d)
 #define EFI_RT_PROPERTIES_TABLE_GUID		EFI_GUID(0xeb66918a, 0x7eef, 0x402a,  0x84, 0x2e, 0x93, 0x1d, 0x21, 0xc3, 0x8a, 0xe9)
@@ -411,7 +412,6 @@ void efi_native_runtime_setup(void);
 #define LINUX_EFI_LOADER_ENTRY_GUID		EFI_GUID(0x4a67b082, 0x0a4c, 0x41cf,  0xb6, 0xc7, 0x44, 0x0b, 0x29, 0xbb, 0x8c, 0x4f)
 #define LINUX_EFI_RANDOM_SEED_TABLE_GUID	EFI_GUID(0x1ce1e5bc, 0x7ceb, 0x42f2,  0x81, 0xe5, 0x8a, 0xad, 0xf1, 0x80, 0xf5, 0x7b)
 #define LINUX_EFI_TPM_EVENT_LOG_GUID		EFI_GUID(0xb7799cb0, 0xeca2, 0x4943,  0x96, 0x67, 0x1f, 0xae, 0x07, 0xb7, 0x47, 0xfa)
-#define LINUX_EFI_TPM_FINAL_LOG_GUID		EFI_GUID(0x1e2ed096, 0x30e2, 0x4254,  0xbd, 0x89, 0x86, 0x3b, 0xbe, 0xf8, 0x23, 0x25)
 #define LINUX_EFI_MEMRESERVE_TABLE_GUID		EFI_GUID(0x888eb0c6, 0x8ede, 0x4ff5,  0xa8, 0xf0, 0x9a, 0xee, 0x5c, 0xb9, 0x77, 0xc2)
 #define LINUX_EFI_INITRD_MEDIA_GUID		EFI_GUID(0x5568e427, 0x68fc, 0x4f3d,  0xac, 0x74, 0xca, 0x55, 0x52, 0x31, 0xcc, 0x68)
 #define LINUX_EFI_MOK_VARIABLE_TABLE_GUID	EFI_GUID(0xc451ed2b, 0x9694, 0x45d3,  0xba, 0xba, 0xed, 0x9f, 0x89, 0x88, 0xa3, 0x89)
Signature · 1 line
2.44.0.278.ge034bb2e1d-goog
#4 lore raw

Re: [PATCH v2 2/5] efi/tpm: Use symbolic GUID name from spec for final events table

Hi,

Quoted 7 lines · Ard Biesheuvel

From: Ard Biesheuvel <[email protected]>

The LINUX_EFI_ GUID identifiers are only intended to be used to refer to GUIDs that are part of the Linux implementation, and are not considered external ABI. (Famous last words).

Quoted 7 lines

GUIDs that already have a symbolic name in the spec should use that name, to avoid confusion between firmware components. So use the official name EFI_TCG2_FINAL_EVENTS_TABLE_GUID for the TCG2 'final events' configuration table.

---

Looks good to me.

Reviewed-by: Kuppuswamy Sathyanarayanan
<[email protected]>

Quoted 54 lines
 drivers/firmware/efi/efi.c         | 2 +-
 drivers/firmware/efi/libstub/tpm.c | 2 +-
 include/linux/efi.h                | 2 +-
 3 files changed, 3 insertions(+), 3 deletions(-)
drivers/firmware/efi/efi.c +1 -1
index 4fcda50acfa4..f6cfd29308d9 100644
@@ -597,7 +597,7 @@ static const efi_config_table_type_t common_tables[] __initconst = {
        {EFI_MEMORY_ATTRIBUTES_TABLE_GUID,      &efi_mem_attr_table,    "MEMATTR"       },
        {LINUX_EFI_RANDOM_SEED_TABLE_GUID,      &efi_rng_seed,          "RNG"           },
        {LINUX_EFI_TPM_EVENT_LOG_GUID,          &efi.tpm_log,           "TPMEventLog"   },
-       {LINUX_EFI_TPM_FINAL_LOG_GUID,          &efi.tpm_final_log,     "TPMFinalLog"   },
+       {EFI_TCG2_FINAL_EVENTS_TABLE_GUID,      &efi.tpm_final_log,     "TPMFinalLog"   },
        {LINUX_EFI_MEMRESERVE_TABLE_GUID,       &mem_reserve,           "MEMRESERVE"    },
        {LINUX_EFI_INITRD_MEDIA_GUID,           &initrd,                "INITRD"        },
        {EFI_RT_PROPERTIES_TABLE_GUID,          &rt_prop,               "RTPROP"        },
drivers/firmware/efi/libstub/tpm.c +1 -1
index 7acbac16eae0..a880f7374c27 100644
@@ -128,7 +128,7 @@ void efi_retrieve_tpm2_eventlog(void)
         * final events structure, and if so how much space they take up
         */
        if (version == EFI_TCG2_EVENT_LOG_FORMAT_TCG_2)
-               final_events_table = get_efi_config_table(LINUX_EFI_TPM_FINAL_LOG_GUID);
+               final_events_table = get_efi_config_table(EFI_TCG2_FINAL_EVENTS_TABLE_GUID);
        if (final_events_table && final_events_table->nr_events) {
                struct tcg_pcr_event2_head *header;
                int offset;
include/linux/efi.h +1 -2
index c74f47711f0b..464fe16411b8 100644
@@ -386,6 +386,7 @@ void efi_native_runtime_setup(void);
 #define EFI_CONSOLE_OUT_DEVICE_GUID            EFI_GUID(0xd3b36f2c, 0xd551, 0x11d4,  0x9a, 0x46, 0x00, 0x90, 0x27, 0x3f, 0xc1, 0x4d)
 #define APPLE_PROPERTIES_PROTOCOL_GUID         EFI_GUID(0x91bd12fe, 0xf6c3, 0x44fb,  0xa5, 0xb7, 0x51, 0x22, 0xab, 0x30, 0x3a, 0xe0)
 #define EFI_TCG2_PROTOCOL_GUID                 EFI_GUID(0x607f766c, 0x7455, 0x42be,  0x93, 0x0b, 0xe4, 0xd7, 0x6d, 0xb2, 0x72, 0x0f)
+#define EFI_TCG2_FINAL_EVENTS_TABLE_GUID       EFI_GUID(0x1e2ed096, 0x30e2, 0x4254,  0xbd, 0x89, 0x86, 0x3b, 0xbe, 0xf8, 0x23, 0x25)
 #define EFI_LOAD_FILE_PROTOCOL_GUID            EFI_GUID(0x56ec3091, 0x954c, 0x11d2,  0x8e, 0x3f, 0x00, 0xa0, 0xc9, 0x69, 0x72, 0x3b)
 #define EFI_LOAD_FILE2_PROTOCOL_GUID           EFI_GUID(0x4006c0c1, 0xfcb3, 0x403e,  0x99, 0x6d, 0x4a, 0x6c, 0x87, 0x24, 0xe0, 0x6d)
 #define EFI_RT_PROPERTIES_TABLE_GUID           EFI_GUID(0xeb66918a, 0x7eef, 0x402a,  0x84, 0x2e, 0x93, 0x1d, 0x21, 0xc3, 0x8a, 0xe9)
@@ -411,7 +412,6 @@ void efi_native_runtime_setup(void);
 #define LINUX_EFI_LOADER_ENTRY_GUID            EFI_GUID(0x4a67b082, 0x0a4c, 0x41cf,  0xb6, 0xc7, 0x44, 0x0b, 0x29, 0xbb, 0x8c, 0x4f)
 #define LINUX_EFI_RANDOM_SEED_TABLE_GUID       EFI_GUID(0x1ce1e5bc, 0x7ceb, 0x42f2,  0x81, 0xe5, 0x8a, 0xad, 0xf1, 0x80, 0xf5, 0x7b)
 #define LINUX_EFI_TPM_EVENT_LOG_GUID           EFI_GUID(0xb7799cb0, 0xeca2, 0x4943,  0x96, 0x67, 0x1f, 0xae, 0x07, 0xb7, 0x47, 0xfa)
-#define LINUX_EFI_TPM_FINAL_LOG_GUID           EFI_GUID(0x1e2ed096, 0x30e2, 0x4254,  0xbd, 0x89, 0x86, 0x3b, 0xbe, 0xf8, 0x23, 0x25)
 #define LINUX_EFI_MEMRESERVE_TABLE_GUID                EFI_GUID(0x888eb0c6, 0x8ede, 0x4ff5,  0xa8, 0xf0, 0x9a, 0xee, 0x5c, 0xb9, 0x77, 0xc2)
 #define LINUX_EFI_INITRD_MEDIA_GUID            EFI_GUID(0x5568e427, 0x68fc, 0x4f3d,  0xac, 0x74, 0xca, 0x55, 0x52, 0x31, 0xcc, 0x68)
 #define LINUX_EFI_MOK_VARIABLE_TABLE_GUID      EFI_GUID(0xc451ed2b, 0x9694, 0x45d3,  0xba, 0xba, 0xed, 0x9f, 0x89, 0x88, 0xa3, 0x89)
--

2.44.0.278.ge034bb2e1d-goog

reviewer Reviewed-by on v2 2/5
#5 lore raw

Re: [PATCH v2 2/5] efi/tpm: Use symbolic GUID name from spec for final events table

In reply to Ard Biesheuvel
Quoted 66 lines · Ard Biesheuvel

From: Ard Biesheuvel <[email protected]>

The LINUX_EFI_ GUID identifiers are only intended to be used to refer to GUIDs that are part of the Linux implementation, and are not considered external ABI. (Famous last words).

GUIDs that already have a symbolic name in the spec should use that name, to avoid confusion between firmware components. So use the official name EFI_TCG2_FINAL_EVENTS_TABLE_GUID for the TCG2 'final events' configuration table.

---
 drivers/firmware/efi/efi.c         | 2 +-
 drivers/firmware/efi/libstub/tpm.c | 2 +-
 include/linux/efi.h                | 2 +-
 3 files changed, 3 insertions(+), 3 deletions(-)
drivers/firmware/efi/efi.c +1 -1
index 4fcda50acfa4..f6cfd29308d9 100644
@@ -597,7 +597,7 @@ static const efi_config_table_type_t common_tables[] __initconst = {
        {EFI_MEMORY_ATTRIBUTES_TABLE_GUID,      &efi_mem_attr_table,    "MEMATTR"       },
        {LINUX_EFI_RANDOM_SEED_TABLE_GUID,      &efi_rng_seed,          "RNG"           },
        {LINUX_EFI_TPM_EVENT_LOG_GUID,          &efi.tpm_log,           "TPMEventLog"   },
-       {LINUX_EFI_TPM_FINAL_LOG_GUID,          &efi.tpm_final_log,     "TPMFinalLog"   },
+       {EFI_TCG2_FINAL_EVENTS_TABLE_GUID,      &efi.tpm_final_log,     "TPMFinalLog"   },
        {LINUX_EFI_MEMRESERVE_TABLE_GUID,       &mem_reserve,           "MEMRESERVE"    },
        {LINUX_EFI_INITRD_MEDIA_GUID,           &initrd,                "INITRD"        },
        {EFI_RT_PROPERTIES_TABLE_GUID,          &rt_prop,               "RTPROP"        },
drivers/firmware/efi/libstub/tpm.c +1 -1
index 7acbac16eae0..a880f7374c27 100644
@@ -128,7 +128,7 @@ void efi_retrieve_tpm2_eventlog(void)
         * final events structure, and if so how much space they take up
         */
        if (version == EFI_TCG2_EVENT_LOG_FORMAT_TCG_2)
-               final_events_table = get_efi_config_table(LINUX_EFI_TPM_FINAL_LOG_GUID);
+               final_events_table = get_efi_config_table(EFI_TCG2_FINAL_EVENTS_TABLE_GUID);
        if (final_events_table && final_events_table->nr_events) {
                struct tcg_pcr_event2_head *header;
                int offset;
include/linux/efi.h +1 -2
index c74f47711f0b..464fe16411b8 100644
@@ -386,6 +386,7 @@ void efi_native_runtime_setup(void);
 #define EFI_CONSOLE_OUT_DEVICE_GUID            EFI_GUID(0xd3b36f2c, 0xd551, 0x11d4,  0x9a, 0x46, 0x00, 0x90, 0x27, 0x3f, 0xc1, 0x4d)
 #define APPLE_PROPERTIES_PROTOCOL_GUID         EFI_GUID(0x91bd12fe, 0xf6c3, 0x44fb,  0xa5, 0xb7, 0x51, 0x22, 0xab, 0x30, 0x3a, 0xe0)
 #define EFI_TCG2_PROTOCOL_GUID                 EFI_GUID(0x607f766c, 0x7455, 0x42be,  0x93, 0x0b, 0xe4, 0xd7, 0x6d, 0xb2, 0x72, 0x0f)
+#define EFI_TCG2_FINAL_EVENTS_TABLE_GUID       EFI_GUID(0x1e2ed096, 0x30e2, 0x4254,  0xbd, 0x89, 0x86, 0x3b, 0xbe, 0xf8, 0x23, 0x25)
 #define EFI_LOAD_FILE_PROTOCOL_GUID            EFI_GUID(0x56ec3091, 0x954c, 0x11d2,  0x8e, 0x3f, 0x00, 0xa0, 0xc9, 0x69, 0x72, 0x3b)
 #define EFI_LOAD_FILE2_PROTOCOL_GUID           EFI_GUID(0x4006c0c1, 0xfcb3, 0x403e,  0x99, 0x6d, 0x4a, 0x6c, 0x87, 0x24, 0xe0, 0x6d)
 #define EFI_RT_PROPERTIES_TABLE_GUID           EFI_GUID(0xeb66918a, 0x7eef, 0x402a,  0x84, 0x2e, 0x93, 0x1d, 0x21, 0xc3, 0x8a, 0xe9)
@@ -411,7 +412,6 @@ void efi_native_runtime_setup(void);
 #define LINUX_EFI_LOADER_ENTRY_GUID            EFI_GUID(0x4a67b082, 0x0a4c, 0x41cf,  0xb6, 0xc7, 0x44, 0x0b, 0x29, 0xbb, 0x8c, 0x4f)
 #define LINUX_EFI_RANDOM_SEED_TABLE_GUID       EFI_GUID(0x1ce1e5bc, 0x7ceb, 0x42f2,  0x81, 0xe5, 0x8a, 0xad, 0xf1, 0x80, 0xf5, 0x7b)
 #define LINUX_EFI_TPM_EVENT_LOG_GUID           EFI_GUID(0xb7799cb0, 0xeca2, 0x4943,  0x96, 0x67, 0x1f, 0xae, 0x07, 0xb7, 0x47, 0xfa)
-#define LINUX_EFI_TPM_FINAL_LOG_GUID           EFI_GUID(0x1e2ed096, 0x30e2, 0x4254,  0xbd, 0x89, 0x86, 0x3b, 0xbe, 0xf8, 0x23, 0x25)
 #define LINUX_EFI_MEMRESERVE_TABLE_GUID                EFI_GUID(0x888eb0c6, 0x8ede, 0x4ff5,  0xa8, 0xf0, 0x9a, 0xee, 0x5c, 0xb9, 0x77, 0xc2)
 #define LINUX_EFI_INITRD_MEDIA_GUID            EFI_GUID(0x5568e427, 0x68fc, 0x4f3d,  0xac, 0x74, 0xca, 0x55, 0x52, 0x31, 0xcc, 0x68)
 #define LINUX_EFI_MOK_VARIABLE_TABLE_GUID      EFI_GUID(0xc451ed2b, 0x9694, 0x45d3,  0xba, 0xba, 0xed, 0x9f, 0x89, 0x88, 0xa3, 0x89)
--
Quoted 2 lines

2.44.0.278.ge034bb2e1d-goog

#6 lore raw

PATCH v2 3/5 efi/libstub: Add Confidential Computing (CC) measurement typedefs

In reply to Ard Biesheuvel

From: Kuppuswamy Sathyanarayanan <[email protected]>

If the virtual firmware implements TPM support, TCG2 protocol will be used for kernel measurements and event logging support. But in CC environment, not all platforms support or enable the TPM feature. UEFI specification [1] exposes protocol and interfaces used for kernel measurements in CC platforms without TPM support.

More details about the EFI CC measurements and logging can be found in [1].

---
 drivers/firmware/efi/libstub/efistub.h | 79 ++++++++++++++++++++
 include/linux/efi.h                    |  1 +
 2 files changed, 80 insertions(+)
drivers/firmware/efi/libstub/efistub.h +79 -0
index dae635cc3d4f..72181c04420c 100644
@@ -875,6 +875,85 @@ union efi_tcg2_protocol {
 	} mixed_mode;
 };
 
+typedef struct {
+	u8 major;
+	u8 minor;
+} efi_cc_version_t;
+
+typedef struct {
+	u8 type;
+	u8 sub_type;
+} efi_cc_type_t;
+
+/* EFI CC type/subtype defines */
+#define EFI_CC_TYPE_NONE		0
+#define EFI_CC_TYPE_AMD_SEV		1
+#define EFI_CC_TYPE_INTEL_TDX		2
+
+typedef u32 efi_cc_mr_index_t;
+
+struct efi_cc_event {
+	u32 event_size;
+	struct {
+		u32 header_size;
+		u16 header_version;
+		u32 mr_index;
+		u32 event_type;
+	} __packed event_header;
+	/* u8[] event follows here */
+} __packed;
+
+typedef struct efi_cc_event efi_cc_event_t;
+
+typedef u32 efi_cc_event_log_bitmap_t;
+typedef u32 efi_cc_event_log_format_t;
+typedef u32 efi_cc_event_algorithm_bitmap_t;
+
+typedef struct {
+	u8				size;
+	efi_cc_version_t		structure_version;
+	efi_cc_version_t		protocol_version;
+	efi_cc_event_algorithm_bitmap_t	hash_algorithm_bitmap;
+	efi_cc_event_log_bitmap_t	supported_event_logs;
+	efi_cc_type_t			cc_type;
+} efi_cc_boot_service_cap_t;
+
+#define EFI_CC_EVENT_HEADER_VERSION	1
+
+#define EFI_CC_BOOT_HASH_ALG_SHA384	0x00000004
+
+typedef union efi_cc_protocol efi_cc_protocol_t;
+
+union efi_cc_protocol {
+	struct {
+		efi_status_t
+		(__efiapi *get_capability)(efi_cc_protocol_t *,
+					   efi_cc_boot_service_cap_t *);
+
+		efi_status_t
+		(__efiapi *get_event_log)(efi_cc_protocol_t *,
+					  efi_cc_event_log_format_t,
+					  efi_physical_addr_t *,
+					  efi_physical_addr_t *,
+					  efi_bool_t *);
+
+		efi_status_t
+		(__efiapi *hash_log_extend_event)(efi_cc_protocol_t *, u64,
+						  efi_physical_addr_t, u64,
+						  const efi_cc_event_t *);
+
+		efi_status_t
+		(__efiapi *map_pcr_to_mr_index)(efi_cc_protocol_t *, u32,
+						efi_cc_mr_index_t *);
+	};
+	struct {
+		u32 get_capability;
+		u32 get_event_log;
+		u32 hash_log_extend_event;
+		u32 map_pcr_to_mr_index;
+	} mixed_mode;
+};
+
 struct riscv_efi_boot_protocol {
 	u64 revision;
 
include/linux/efi.h +1 -0
index 464fe16411b8..2493d3d4429b 100644
@@ -401,6 +401,7 @@ void efi_native_runtime_setup(void);
 #define EFI_CERT_X509_GUID			EFI_GUID(0xa5c059a1, 0x94e4, 0x4aa7, 0x87, 0xb5, 0xab, 0x15, 0x5c, 0x2b, 0xf0, 0x72)
 #define EFI_CERT_X509_SHA256_GUID		EFI_GUID(0x3bd2a492, 0x96c0, 0x4079, 0xb4, 0x20, 0xfc, 0xf9, 0x8e, 0xf1, 0x03, 0xed)
 #define EFI_CC_BLOB_GUID			EFI_GUID(0x067b1f5f, 0xcf26, 0x44c5, 0x85, 0x54, 0x93, 0xd7, 0x77, 0x91, 0x2d, 0x42)
+#define EFI_CC_MEASUREMENT_PROTOCOL_GUID	EFI_GUID(0x96751a3d, 0x72f4, 0x41a6, 0xa7, 0x94, 0xed, 0x5d, 0x0e, 0x67, 0xae, 0x6b)
 
 /*
  * This GUID is used to pass to the kernel proper the struct screen_info
Signature · 1 line
2.44.0.278.ge034bb2e1d-goog
#7 lore raw

PATCH v2 4/5 efi/libstub: Measure into CC protocol if TCG2 protocol is absent

In reply to Ard Biesheuvel

From: Ard Biesheuvel <[email protected]>

To accommodate confidential compute VMs that expose the simplified CC measurement protocol instead of the full-blown TCG2 one, fall back to the former if the latter does not exist.

The CC protocol was designed to be used in this manner, which is why the types and prototypes have been kept the same where possible. So reuse the existing code, and only deviate from the TCG2 code path where needed.

---
 drivers/firmware/efi/libstub/efi-stub-helper.c | 70 +++++++++++++++-----
 1 file changed, 53 insertions(+), 17 deletions(-)
drivers/firmware/efi/libstub/efi-stub-helper.c +53 -17
index 186ced8371ac..993c58e2221b 100644
@@ -220,8 +220,11 @@ static const struct {
 	},
 };
 
+static_assert(sizeof(efi_tcg2_event_t) == sizeof(efi_cc_event_t));
+
 union efistub_event {
 	efi_tcg2_event_t	tcg2_data;
+	efi_cc_event_t		cc_data;
 };
 
 struct efistub_measured_event {
@@ -235,44 +238,77 @@ static efi_status_t efi_measure_tagged_event(unsigned long load_addr,
 					     unsigned long load_size,
 					     enum efistub_event_type event)
 {
+	union {
+		efi_status_t
+		(__efiapi *hash_log_extend_event)(void *, u64, efi_physical_addr_t,
+						  u64, const union efistub_event *);
+		struct { u32 hash_log_extend_event; } mixed_mode;
+	} method;
 	struct efistub_measured_event *evt;
 	int size = struct_size(evt, tagged_event_data,
 			       events[event].event_data_len);
 	efi_guid_t tcg2_guid = EFI_TCG2_PROTOCOL_GUID;
 	efi_tcg2_protocol_t *tcg2 = NULL;
+	union efistub_event ev;
 	efi_status_t status;
+	void *protocol;
 
 	efi_bs_call(locate_protocol, &tcg2_guid, NULL, (void **)&tcg2);
 	if (tcg2) {
-		status = efi_bs_call(allocate_pool, EFI_LOADER_DATA, size,
-				     (void **)&evt);
-		if (status != EFI_SUCCESS)
-			goto fail;
-
-		evt->event_data.tcg2_data = (struct efi_tcg2_event){
+		ev.tcg2_data = (struct efi_tcg2_event){
 			.event_size			= size,
-			.event_header.header_size	= sizeof(evt->event_data.tcg2_data.event_header),
+			.event_header.header_size	= sizeof(ev.tcg2_data.event_header),
 			.event_header.header_version	= EFI_TCG2_EVENT_HEADER_VERSION,
 			.event_header.pcr_index		= events[event].pcr_index,
 			.event_header.event_type	= EV_EVENT_TAG,
 		};
+		protocol = tcg2;
+		method.hash_log_extend_event =
+			(void *)efi_table_attr(tcg2, hash_log_extend_event);
+	} else {
+		efi_guid_t cc_guid = EFI_CC_MEASUREMENT_PROTOCOL_GUID;
+		efi_cc_protocol_t *cc = NULL;
 
-		evt->tagged_event_id		= events[event].event_id;
-		evt->tagged_event_data_size	= events[event].event_data_len;
-
-		memcpy(evt->tagged_event_data, events[event].event_data,
-		       events[event].event_data_len);
+		efi_bs_call(locate_protocol, &cc_guid, NULL, (void **)&cc);
+		if (!cc)
+			return EFI_UNSUPPORTED;
 
-		status = efi_call_proto(tcg2, hash_log_extend_event, 0,
-					load_addr, load_size, &evt->event_data.tcg2_data);
-		efi_bs_call(free_pool, evt);
+		ev.cc_data = (struct efi_cc_event){
+			.event_size			= size,
+			.event_header.header_size	= sizeof(ev.cc_data.event_header),
+			.event_header.header_version	= EFI_CC_EVENT_HEADER_VERSION,
+			.event_header.event_type	= EV_EVENT_TAG,
+		};
 
+		status = efi_call_proto(cc, map_pcr_to_mr_index,
+					events[event].pcr_index,
+					&ev.cc_data.event_header.mr_index);
 		if (status != EFI_SUCCESS)
 			goto fail;
-		return EFI_SUCCESS;
+
+		protocol = cc;
+		method.hash_log_extend_event =
+			(void *)efi_table_attr(cc, hash_log_extend_event);
 	}
 
-	return EFI_UNSUPPORTED;
+	status = efi_bs_call(allocate_pool, EFI_LOADER_DATA, size, (void **)&evt);
+	if (status != EFI_SUCCESS)
+		goto fail;
+
+	evt->event_data			= ev;
+	evt->tagged_event_id		= events[event].event_id;
+	evt->tagged_event_data_size	= events[event].event_data_len;
+
+	memcpy(evt->tagged_event_data, events[event].event_data,
+	       events[event].event_data_len);
+
+	status = efi_fn_call(&method, hash_log_extend_event, protocol, 0,
+			     load_addr, load_size, &evt->event_data);
+	efi_bs_call(free_pool, evt);
+
+	if (status == EFI_SUCCESS)
+		return EFI_SUCCESS;
+
 fail:
 	efi_warn("Failed to measure data for event %d: 0x%lx\n", event, status);
 	return status;
Signature · 1 line
2.44.0.278.ge034bb2e1d-goog
#8 lore raw

PATCH v2 5/5 efi/libstub: Add get_event_log() support for CC platforms

In reply to Ard Biesheuvel

From: Kuppuswamy Sathyanarayanan <[email protected]>

To allow event log info access after boot, EFI boot stub extracts the event log information and installs it in an EFI configuration table. Currently, EFI boot stub only supports installation of event log only for TPM 1.2 and TPM 2.0 protocols. Extend the same support for CC protocol. Since CC platform also uses TCG2 format, reuse TPM2 support code as much as possible.

---
 drivers/firmware/efi/efi.c              |  1 +
 drivers/firmware/efi/libstub/efi-stub.c |  2 +-
 drivers/firmware/efi/libstub/efistub.h  |  4 +-
 drivers/firmware/efi/libstub/tpm.c      | 82 +++++++++++++-------
 drivers/firmware/efi/libstub/x86-stub.c |  2 +-
 include/linux/efi.h                     |  2 +
 6 files changed, 62 insertions(+), 31 deletions(-)
drivers/firmware/efi/efi.c +1 -0
index f6cfd29308d9..8859fb0b006d 100644
@@ -598,6 +598,7 @@ static const efi_config_table_type_t common_tables[] __initconst = {
 	{LINUX_EFI_RANDOM_SEED_TABLE_GUID,	&efi_rng_seed,		"RNG"		},
 	{LINUX_EFI_TPM_EVENT_LOG_GUID,		&efi.tpm_log,		"TPMEventLog"	},
 	{EFI_TCG2_FINAL_EVENTS_TABLE_GUID,	&efi.tpm_final_log,	"TPMFinalLog"	},
+	{EFI_CC_FINAL_EVENTS_TABLE_GUID,	&efi.tpm_final_log,	"CCFinalLog"	},
 	{LINUX_EFI_MEMRESERVE_TABLE_GUID,	&mem_reserve,		"MEMRESERVE"	},
 	{LINUX_EFI_INITRD_MEDIA_GUID,		&initrd,		"INITRD"	},
 	{EFI_RT_PROPERTIES_TABLE_GUID,		&rt_prop,		"RTPROP"	},
drivers/firmware/efi/libstub/efi-stub.c +1 -1
index f9c1e8a2bd1d..958a680e0660 100644
@@ -167,7 +167,7 @@ efi_status_t efi_stub_common(efi_handle_t handle,
 
 	si = setup_graphics();
 
-	efi_retrieve_tpm2_eventlog();
+	efi_retrieve_eventlog();
 
 	/* Ask the firmware to clear memory on unclean shutdown */
 	efi_enable_reset_attack_mitigation();
drivers/firmware/efi/libstub/efistub.h +3 -1
index 72181c04420c..8abd2a1195d6 100644
@@ -922,6 +922,8 @@ typedef struct {
 
 #define EFI_CC_BOOT_HASH_ALG_SHA384	0x00000004
 
+#define EFI_CC_EVENT_LOG_FORMAT_TCG_2	0x00000002
+
 typedef union efi_cc_protocol efi_cc_protocol_t;
 
 union efi_cc_protocol {
@@ -1133,7 +1135,7 @@ static inline void
 efi_enable_reset_attack_mitigation(void) { }
 #endif
 
-void efi_retrieve_tpm2_eventlog(void);
+void efi_retrieve_eventlog(void);
 
 struct screen_info *alloc_screen_info(void);
 struct screen_info *__alloc_screen_info(void);
drivers/firmware/efi/libstub/tpm.c +54 -28

112 lines not on this page · raw message

drivers/firmware/efi/libstub/x86-stub.c +1 -1
index 99429bc4b0c7..d09aa13c7ff0 100644
@@ -923,7 +923,7 @@ void __noreturn efi_stub_entry(efi_handle_t handle,
 
 	efi_random_get_seed();
 
-	efi_retrieve_tpm2_eventlog();
+	efi_retrieve_eventlog();
 
 	setup_graphics(boot_params);
 
include/linux/efi.h +2 -0
index 2493d3d4429b..a66d905caa7a 100644
@@ -402,6 +402,8 @@ void efi_native_runtime_setup(void);
 #define EFI_CERT_X509_SHA256_GUID		EFI_GUID(0x3bd2a492, 0x96c0, 0x4079, 0xb4, 0x20, 0xfc, 0xf9, 0x8e, 0xf1, 0x03, 0xed)
 #define EFI_CC_BLOB_GUID			EFI_GUID(0x067b1f5f, 0xcf26, 0x44c5, 0x85, 0x54, 0x93, 0xd7, 0x77, 0x91, 0x2d, 0x42)
 #define EFI_CC_MEASUREMENT_PROTOCOL_GUID	EFI_GUID(0x96751a3d, 0x72f4, 0x41a6, 0xa7, 0x94, 0xed, 0x5d, 0x0e, 0x67, 0xae, 0x6b)
+#define EFI_CC_FINAL_EVENTS_TABLE_GUID		EFI_GUID(0xdd4a4648, 0x2de7, 0x4665, 0x96, 0x4d, 0x21, 0xd9, 0xef, 0x5f, 0xb4, 0x46)
+
 
 /*
  * This GUID is used to pass to the kernel proper the struct screen_info
Signature · 1 line
2.44.0.278.ge034bb2e1d-goog