From: Ard Biesheuvel <ardb@kernel.org>
To: linux-efi@vger.kernel.org
Cc: Ard Biesheuvel <ardb@kernel.org>, Peter Jones <pjones@redhat.com>,
Matthew Garrett <mjg59@google.com>,
Daniel Kiper <daniel.kiper@oracle.com>,
Ilias Apalodimas <ilias.apalodimas@linaro.org>,
"Xu, Min M" <min.m.xu@intel.com>
Subject: [PATCH v2 1/2] efi/libstub: refactor the initrd measuring functions
Date: Tue, 20 Sep 2022 14:27:45 +0200 [thread overview]
Message-ID: <20220920122746.3553306-2-ardb@kernel.org> (raw)
In-Reply-To: <20220920122746.3553306-1-ardb@kernel.org>
From: Ilias Apalodimas <ilias.apalodimas@linaro.org>
Currently, from the efi-stub, we are only measuring the loaded initrd,
using the TCG2 measured boot protocols. A following patch is
introducing measurements of additional components, such as the kernel
command line. On top of that, we will shortly have to support other
types of measured boot that don't expose the TCG2 protocols.
So let's prepare for that, by rejigging the efi_measure_initrd() routine
into something that we should be able to reuse for measuring other
assets, and which can be extended later to support other measured boot
protocols.
Co-developed-by: Ilias Apalodimas <ilias.apalodimas@linaro.org>
Signed-off-by: Ilias Apalodimas <ilias.apalodimas@linaro.org>
Signed-off-by: Ard Biesheuvel <ardb@kernel.org>
---
drivers/firmware/efi/libstub/efi-stub-helper.c | 120 +++++++++++++-------
1 file changed, 77 insertions(+), 43 deletions(-)
diff --git a/drivers/firmware/efi/libstub/efi-stub-helper.c b/drivers/firmware/efi/libstub/efi-stub-helper.c
index 829f732c5f37..8f9a79bc4e8e 100644
--- a/drivers/firmware/efi/libstub/efi-stub-helper.c
+++ b/drivers/firmware/efi/libstub/efi-stub-helper.c
@@ -334,6 +334,79 @@ 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 {
+ EFISTUB_EVT_INITRD,
+ EFISTUB_EVT_COUNT,
+};
+
+#define STR_WITH_SIZE(s) sizeof(s), s
+
+static const struct {
+ u32 pcr_index;
+ u32 event_id;
+ u32 event_data_len;
+ u8 event_data[52];
+} events[] = {
+ [EFISTUB_EVT_INITRD] = {
+ 9,
+ INITRD_EVENT_TAG_ID,
+ STR_WITH_SIZE("Linux initrd")
+ },
+};
+
+static efi_status_t efi_measure_tagged_event(unsigned long load_addr,
+ unsigned long load_size,
+ enum efistub_event event)
+{
+ 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){
+ .event_size = size,
+ .event_header.header_size = sizeof(evt->event_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,
+ };
+
+ 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);
+ efi_bs_call(free_pool, evt);
+
+ if (status != EFI_SUCCESS)
+ goto fail;
+ return EFI_SUCCESS;
+ }
+
+ return EFI_UNSUPPORTED;
+fail:
+ efi_warn("Failed to measure data for event %d: 0x%lx\n", event, status);
+ return status;
+}
+
/*
* Convert the unicode UEFI command line to ASCII to pass to kernel.
* Size of memory allocated return in *cmd_line_len.
@@ -626,47 +699,6 @@ efi_status_t efi_load_initrd_cmdline(efi_loaded_image_t *image,
load_addr, load_size);
}
-static const struct {
- efi_tcg2_event_t event_data;
- efi_tcg2_tagged_event_t tagged_event;
- u8 tagged_event_data[];
-} initrd_tcg2_event = {
- {
- sizeof(initrd_tcg2_event) + sizeof("Linux initrd"),
- {
- sizeof(initrd_tcg2_event.event_data.event_header),
- EFI_TCG2_EVENT_HEADER_VERSION,
- 9,
- EV_EVENT_TAG,
- },
- },
- {
- INITRD_EVENT_TAG_ID,
- sizeof("Linux initrd"),
- },
- { "Linux initrd" },
-};
-
-static void efi_measure_initrd(unsigned long load_addr, unsigned long load_size)
-{
- 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) {
- status = efi_call_proto(tcg2, hash_log_extend_event,
- 0, load_addr, load_size,
- &initrd_tcg2_event.event_data);
- if (status != EFI_SUCCESS)
- efi_warn("Failed to measure initrd data: 0x%lx\n",
- status);
- else
- efi_info("Measured initrd data into PCR %d\n",
- initrd_tcg2_event.event_data.event_header.pcr_index);
- }
-}
-
/**
* efi_load_initrd() - Load initial RAM disk
* @image: EFI loaded image protocol
@@ -692,8 +724,10 @@ efi_status_t efi_load_initrd(efi_loaded_image_t *image,
status = efi_load_initrd_dev_path(load_addr, load_size, hard_limit);
if (status == EFI_SUCCESS) {
efi_info("Loaded initrd from LINUX_EFI_INITRD_MEDIA_GUID device path\n");
- if (*load_size > 0)
- efi_measure_initrd(*load_addr, *load_size);
+ if (*load_size > 0 &&
+ efi_measure_tagged_event(*load_addr, *load_size,
+ EFISTUB_EVT_INITRD) == EFI_SUCCESS)
+ efi_info("Measured initrd data into PCR 9\n");
} else if (status == EFI_NOT_FOUND) {
status = efi_load_initrd_cmdline(image, load_addr, load_size,
soft_limit, hard_limit);
--
2.35.1
next prev parent reply other threads:[~2022-09-20 12:28 UTC|newest]
Thread overview: 3+ messages / expand[flat|nested] mbox.gz Atom feed top
2022-09-20 12:27 [PATCH v2 0/2] efi: measure kernel command line Ard Biesheuvel
2022-09-20 12:27 ` Ard Biesheuvel [this message]
2022-09-20 12:27 ` [PATCH v2 2/2] efi/libstub: measure EFI LoadOptions Ard Biesheuvel
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20220920122746.3553306-2-ardb@kernel.org \
--to=ardb@kernel.org \
--cc=daniel.kiper@oracle.com \
--cc=ilias.apalodimas@linaro.org \
--cc=linux-efi@vger.kernel.org \
--cc=min.m.xu@intel.com \
--cc=mjg59@google.com \
--cc=pjones@redhat.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox