[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[PATCH v3 19/19] multiboot2: Support TXT Secure Launch
From: |
Sergii Dmytruk |
Subject: |
[PATCH v3 19/19] multiboot2: Support TXT Secure Launch |
Date: |
Thu, 12 Dec 2024 15:41:47 +0200 |
From: Michał Żygowski <michal.zygowski@3mdeb.com>
The code makes sure the order of policy entries is correct:
- MBI entry goes first, so the payload can measure it first on launch
- then goes SLRT and other typical entries
- MB2 modules are appended last
Signed-off-by: Michał Żygowski <michal.zygowski@3mdeb.com>
Signed-off-by: Tomasz Żyjewski <tomasz.zyjewski@3mdeb.com>
Signed-off-by: Krystian Hebel <krystian.hebel@3mdeb.com>
Signed-off-by: Sergii Dmytruk <sergii.dmytruk@3mdeb.com>
---
grub-core/loader/multiboot.c | 11 +++
grub-core/loader/multiboot_elfxx.c | 90 +++++++++++++++++++-
grub-core/loader/multiboot_mbi2.c | 132 +++++++++++++++++++++++++++++
grub-core/loader/slaunch/dlstub.c | 2 +-
include/grub/i386/txt.h | 2 +
include/grub/multiboot2.h | 3 +
include/grub/slaunch.h | 1 +
include/grub/slr_table.h | 2 +
8 files changed, 241 insertions(+), 2 deletions(-)
diff --git a/grub-core/loader/multiboot.c b/grub-core/loader/multiboot.c
index 98c1d5e99..07163739b 100644
--- a/grub-core/loader/multiboot.c
+++ b/grub-core/loader/multiboot.c
@@ -50,6 +50,7 @@
#include <grub/video.h>
#include <grub/memory.h>
#include <grub/i18n.h>
+#include <grub/slaunch.h>
GRUB_MOD_LICENSE ("GPLv3+");
@@ -191,6 +192,16 @@ grub_multiboot_boot (void)
if (err)
return err;
+#ifdef GRUB_USE_MULTIBOOT2
+ if (grub_slaunch_platform_type () != SLP_NONE)
+ {
+ err = grub_multiboot2_perform_slaunch (state.MULTIBOOT_MBI_REGISTER,
+ mbi_size);
+ if (err)
+ return grub_error (err, N_("failed to perform Multiboot2 slaunch"));
+ }
+#endif
+
if (grub_efi_is_finished)
normal_boot (GRUB_MULTIBOOT (relocator), state);
else
diff --git a/grub-core/loader/multiboot_elfxx.c
b/grub-core/loader/multiboot_elfxx.c
index 1edad0594..ee05a4d99 100644
--- a/grub-core/loader/multiboot_elfxx.c
+++ b/grub-core/loader/multiboot_elfxx.c
@@ -44,7 +44,9 @@
#error "I'm confused"
#endif
+#include <grub/i386/txt.h>
#include <grub/i386/relocator.h>
+#include <grub/slaunch.h>
#define CONCAT(a,b) CONCAT_(a, b)
#define CONCAT_(a,b) a ## b
@@ -73,6 +75,11 @@ CONCAT(grub_multiboot_load_elf, XX) (mbi_load_data_t *mld)
grub_off_t phlimit;
unsigned int i;
void *source = NULL;
+#ifdef GRUB_USE_MULTIBOOT2
+ struct grub_slaunch_params *slparams = &grub_multiboot2_slparams;
+ grub_uint32_t mle_hdr_offset;
+ struct grub_txt_mle_header *mle_hdr;
+#endif
if (ehdr->e_ident[EI_MAG0] != ELFMAG0
|| ehdr->e_ident[EI_MAG1] != ELFMAG1
@@ -127,6 +134,18 @@ CONCAT(grub_multiboot_load_elf, XX) (mbi_load_data_t *mld)
{
load_size = highest_load - mld->link_base_addr;
+#ifndef GRUB_USE_MULTIBOOT2
+ if (grub_slaunch_platform_type () != SLP_NONE)
+ return grub_error (GRUB_ERR_BAD_OS, "Only multiboot2 supported for
slaunch");
+#else
+ if (grub_slaunch_platform_type () == SLP_INTEL_TXT)
+ {
+ /* Do not go below GRUB_TXT_PMR_ALIGN. */
+ if (mld->align < GRUB_TXT_PMR_ALIGN)
+ mld->align = GRUB_TXT_PMR_ALIGN;
+ }
+#endif
+
grub_dprintf ("multiboot_loader", "align=0x%lx, preference=0x%x, "
"load_size=0x%x, avoid_efi_boot_services=%d\n",
(long) mld->align, mld->preference, load_size,
@@ -148,9 +167,57 @@ CONCAT(grub_multiboot_load_elf, XX) (mbi_load_data_t *mld)
mld->load_base_addr = get_physical_target_address (ch);
source = get_virtual_current_address (ch);
+
+#ifdef GRUB_USE_MULTIBOOT2
+ grub_memset (source, 0, load_size);
+ grub_dprintf ("multiboot_loader", "load_base_addr=0x%lx, source=0x%lx\n",
+ (long) mld->load_base_addr, (long) source);
+
+ if (grub_slaunch_platform_type () != SLP_NONE)
+ {
+ slparams->mle_start = mld->load_base_addr;
+ slparams->mle_mem = source;
+ slparams->mle_ptab_size = 0;
+ }
+
+ if (grub_slaunch_platform_type () == SLP_INTEL_TXT)
+ {
+ /*
+ * Allocate the binary together with the page tables to make one
+ * contiguous block for MLE.
+ */
+ slparams->mle_ptab_size = grub_txt_get_mle_ptab_size (load_size);
+ slparams->mle_ptab_size = ALIGN_UP (slparams->mle_ptab_size,
GRUB_TXT_PMR_ALIGN);
+
+ err = grub_relocator_alloc_chunk_align_safe (GRUB_MULTIBOOT
(relocator), &ch,
+
GRUB_MEMORY_MACHINE_UPPER_START,
+ mld->load_base_addr -
slparams->mle_ptab_size,
+
slparams->mle_ptab_size, GRUB_TXT_PMR_ALIGN,
+
GRUB_RELOCATOR_PREFERENCE_NONE, 1);
+ if (err)
+ {
+ grub_dprintf ("multiboot_loader", "Cannot allocate memory for
MLE page tables\n");
+ return err;
+ }
+
+ slparams->mle_ptab_mem = get_virtual_current_address (ch);
+ slparams->mle_ptab_target = (grub_uint64_t)
get_physical_target_address (ch);
+ grub_dprintf ("multiboot_loader", "mle_ptab_mem = %p,
mle_ptab_target = %lx, mle_ptab_size = %x\n",
+ slparams->mle_ptab_mem, (unsigned long)
slparams->mle_ptab_target,
+ (unsigned) slparams->mle_ptab_size);
+ }
+#endif
}
else
- mld->load_base_addr = mld->link_base_addr;
+ {
+#ifdef GRUB_USE_MULTIBOOT2
+ /* TODO: support non-relocatable */
+ if (grub_slaunch_platform_type () != SLP_NONE)
+ return grub_error (GRUB_ERR_BAD_OS, "Non-relocatable ELF not supported
with slaunch");
+#endif
+
+ mld->load_base_addr = mld->link_base_addr;
+ }
grub_dprintf ("multiboot_loader", "relocatable=%d, link_base_addr=0x%x, "
"load_base_addr=0x%x\n", mld->relocatable,
@@ -213,6 +280,27 @@ CONCAT(grub_multiboot_load_elf, XX) (mbi_load_data_t *mld)
}
}
+#ifdef GRUB_USE_MULTIBOOT2
+ if (grub_slaunch_platform_type () != SLP_NONE)
+ {
+ /* TODO: decide on universal way of conveying location of MLE header */
+ for (mle_hdr_offset = 0; mle_hdr_offset < 0x1000; mle_hdr_offset += 16)
+ {
+ mle_hdr = (struct grub_txt_mle_header *)((grub_addr_t)source +
mle_hdr_offset);
+ if (!grub_memcmp (mle_hdr->uuid, GRUB_TXT_MLE_UUID, 16))
+ {
+ break;
+ }
+ }
+
+ if (mle_hdr_offset >= 0x1000)
+ return grub_error (GRUB_ERR_BAD_ARGUMENT, "MLE header not found");
+
+ slparams->mle_header_offset = mle_hdr_offset;
+ slparams->mle_size = mle_hdr->mle_end - mle_hdr->mle_start;
+ }
+#endif
+
for (i = 0; i < phnum; i++)
if (phdr(i)->p_vaddr <= ehdr->e_entry
&& phdr(i)->p_vaddr + phdr(i)->p_memsz > ehdr->e_entry)
diff --git a/grub-core/loader/multiboot_mbi2.c
b/grub-core/loader/multiboot_mbi2.c
index 1945b3ac6..dcbfbed1f 100644
--- a/grub-core/loader/multiboot_mbi2.c
+++ b/grub-core/loader/multiboot_mbi2.c
@@ -36,6 +36,10 @@
#include <grub/i18n.h>
#include <grub/net.h>
#include <grub/lib/cmdline.h>
+#include <grub/i386/memory.h>
+#include <grub/i386/txt.h>
+#include <grub/slaunch.h>
+#include <grub/slr_table.h>
#if defined (GRUB_MACHINE_EFI)
#include <grub/efi/efi.h>
@@ -63,6 +67,12 @@ struct module
int cmdline_size;
};
+struct fill_policy_hook_data
+{
+ grub_uint32_t mbi_target;
+ grub_uint32_t mbi_size;
+};
+
static struct module *modules, *modules_last;
static grub_size_t cmdline_size;
static grub_size_t total_modcmd;
@@ -76,6 +86,8 @@ static void *elf_sections;
static int keep_bs = 0;
static grub_uint32_t load_base_addr;
+struct grub_slaunch_params grub_multiboot2_slparams = {0};
+
void
grub_multiboot2_add_elfsyms (grub_size_t num, grub_size_t entsize,
unsigned shndx, void *data)
@@ -119,6 +131,7 @@ grub_multiboot2_load (grub_file_t file, const char
*filename)
grub_uint32_t console_required = 0;
struct multiboot_header_tag_framebuffer *fbtag = NULL;
int accepted_consoles = GRUB_MULTIBOOT2_CONSOLE_EGA_TEXT;
+ struct grub_slaunch_params *slparams = &grub_multiboot2_slparams;
mbi_load_data_t mld;
mld.mbi_ver = 2;
@@ -275,8 +288,18 @@ grub_multiboot2_load (grub_file_t file, const char
*filename)
"load address tag without entry address tag");
}
+ if (grub_slaunch_platform_type () != SLP_NONE)
+ {
+ slparams->relocator = grub_multiboot2_relocator;
+ slparams->boot_type = GRUB_SL_BOOT_TYPE_MB2;
+ slparams->platform_type = grub_slaunch_platform_type ();
+ }
+
if (addr_tag)
{
+ if (slparams->platform_type != SLP_NONE)
+ return grub_error (GRUB_ERR_BAD_OS, "Slaunch not supported with
multiboot addr tag");
+
grub_uint64_t load_addr = (addr_tag->load_addr + 1)
? addr_tag->load_addr : (addr_tag->header_addr
- ((char *) header - (char *) mld.buffer));
@@ -390,6 +413,35 @@ grub_multiboot2_load (grub_file_t file, const char
*filename)
err = grub_multiboot2_set_console (GRUB_MULTIBOOT2_CONSOLE_EGA_TEXT,
accepted_consoles,
0, 0, 0, console_required);
+
+ if (slparams->platform_type != SLP_NONE)
+ {
+ grub_relocator_chunk_t ch;
+
+ if (grub_relocator_alloc_chunk_align_safe (grub_multiboot2_relocator,
&ch, 0x1000000,
+ UP_TO_TOP32
(GRUB_SLAUNCH_TPM_EVT_LOG_SIZE),
+
GRUB_SLAUNCH_TPM_EVT_LOG_SIZE, GRUB_PAGE_SIZE,
+
GRUB_RELOCATOR_PREFERENCE_HIGH, 1))
+ {
+ grub_free (mld.buffer);
+ return grub_error (GRUB_ERR_OUT_OF_MEMORY, "Could not allocate TPM
event log area");
+ }
+
+ slparams->tpm_evt_log_base = get_physical_target_address (ch);
+ slparams->tpm_evt_log_size = GRUB_SLAUNCH_TPM_EVT_LOG_SIZE;
+
+ if (slparams->platform_type == SLP_INTEL_TXT)
+ grub_txt_init_tpm_event_log (get_virtual_current_address (ch),
+ slparams->tpm_evt_log_size);
+
+ grub_dprintf ("multiboot_loader", "tpm_evt_log_base = 0x%lx,
tpm_evt_log_size = 0x%x\n",
+ (unsigned long) slparams->tpm_evt_log_base,
+ (unsigned) slparams->tpm_evt_log_size);
+
+ if (slparams->platform_type == SLP_INTEL_TXT)
+ grub_txt_setup_mle_ptab (slparams);
+ }
+
return err;
}
@@ -1128,3 +1180,83 @@ grub_multiboot2_set_bootdev (void)
bootdev_set = 1;
}
+
+static int
+fill_policy_hook(int is_start, int available_entries,
+ struct grub_slr_policy_entry *next_entry, void *data)
+{
+ int i = 0;
+ unsigned m;
+ struct module *cur;
+ struct fill_policy_hook_data *hook_data = data;
+
+ if (is_start)
+ {
+ if (available_entries < 1)
+ return -1;
+
+ next_entry->pcr = 18;
+ next_entry->entity_type = GRUB_SLR_ET_MULTIBOOT2_INFO;
+ next_entry->entity = hook_data->mbi_target;
+ next_entry->size = hook_data->mbi_size;
+ next_entry->flags = 0;
+ grub_strcpy (next_entry->evt_info, "Measured MB2 information");
+ i = 1;
+ }
+ else
+ {
+ if (available_entries < (int)modcnt)
+ return -1;
+
+ for (m = 0, cur = modules; m < modcnt; m++, cur = cur->next)
+ {
+ next_entry[i].pcr = 17;
+ next_entry[i].entity_type = GRUB_SLR_ET_MULTIBOOT2_MODULE;
+ next_entry[i].entity = cur->start;
+ next_entry[i].size = cur->size;
+ next_entry[i].flags = 0;
+ grub_strcpy (next_entry[i].evt_info, "Measured MB2 module");
+ i++;
+ }
+ }
+
+ return i;
+}
+
+grub_err_t
+grub_multiboot2_perform_slaunch (grub_uint32_t mbi_target,
+ grub_uint32_t mbi_size)
+{
+ grub_err_t err;
+ struct grub_slaunch_params *slparams = &grub_multiboot2_slparams;
+ struct grub_slr_entry_dl_info *dlinfo;
+ struct fill_policy_hook_data hook_data = {
+ .mbi_target = mbi_target,
+ .mbi_size = mbi_size,
+ };
+
+ slparams->boot_params_base = mbi_target;
+
+ slparams->fill_policy_hook = &fill_policy_hook;
+ slparams->fill_policy_hook_data = &hook_data;
+
+ if (slparams->platform_type == SLP_INTEL_TXT)
+ {
+ err = grub_txt_boot_prepare (slparams);
+ if (err != GRUB_ERR_NONE)
+ return grub_error (err, "TXT boot preparation failed");
+ }
+ else
+ return grub_error (GRUB_ERR_BAD_DEVICE,
+ N_("Unknown secure launcher platform type: %d\n"),
slparams->platform_type);
+
+ grub_dprintf ("multiboot_loader", "slr_table_base = 0x%lx, slr_table_size =
0x%x\n",
+ (unsigned long) slparams->slr_table_base,
+ (unsigned) slparams->slr_table_size);
+
+ dlinfo = grub_slr_next_entry_by_tag (slparams->slr_table_mem, NULL,
GRUB_SLR_ENTRY_DL_INFO);
+ dl_entry ((grub_uint64_t)(grub_addr_t) &dlinfo->bl_context);
+
+ /* If this returns, something failed miserably */
+ return GRUB_ERR_BAD_DEVICE;
+}
diff --git a/grub-core/loader/slaunch/dlstub.c
b/grub-core/loader/slaunch/dlstub.c
index d3c28645e..2cdbdd886 100644
--- a/grub-core/loader/slaunch/dlstub.c
+++ b/grub-core/loader/slaunch/dlstub.c
@@ -73,7 +73,7 @@ void dl_entry (grub_uint64_t dl_ctx)
return;
}
- if (slparams->boot_type == GRUB_SL_BOOT_TYPE_LINUX)
+ if (slparams->boot_type == GRUB_SL_BOOT_TYPE_LINUX || slparams->boot_type ==
GRUB_SL_BOOT_TYPE_MB2)
{
/* Configure relocator GETSEC[SENTER] call. */
state.eax = GRUB_SMX_LEAF_SENTER;
diff --git a/include/grub/i386/txt.h b/include/grub/i386/txt.h
index d4a6d1cd1..d2ae7b21e 100644
--- a/include/grub/i386/txt.h
+++ b/include/grub/i386/txt.h
@@ -420,6 +420,8 @@ struct grub_txt_sinit_memory_descriptor_records
/* 2.1 MLE Architecture Overview */
/* Table 1. MLE Header structure */
+#define GRUB_TXT_MLE_UUID
"\x5a\xac\x82\x90\x6f\x47\xa7\x74\x0f\x5c\x55\xa2\xcb\x51\xb6\x42"
+
struct grub_txt_mle_header
{
grub_uint8_t uuid[16];
diff --git a/include/grub/multiboot2.h b/include/grub/multiboot2.h
index 3417a1447..1a3be5f48 100644
--- a/include/grub/multiboot2.h
+++ b/include/grub/multiboot2.h
@@ -28,6 +28,7 @@
#include <grub/err.h>
extern struct grub_relocator *grub_multiboot2_relocator;
+extern struct grub_slaunch_params grub_multiboot2_slparams;
void grub_multiboot2 (int argc, char *argv[]);
void grub_module2 (int argc, char *argv[]);
@@ -43,6 +44,8 @@ void grub_multiboot2_set_bootdev (void);
void
grub_multiboot2_add_elfsyms (grub_size_t num, grub_size_t entsize,
unsigned shndx, void *data);
+grub_err_t grub_multiboot2_perform_slaunch (grub_uint32_t mbi_target,
+ grub_uint32_t mbi_size);
grub_uint32_t grub_multiboot2_get_mmap_count (void);
grub_err_t grub_multiboot2_set_video_mode (void);
diff --git a/include/grub/slaunch.h b/include/grub/slaunch.h
index f7bea641e..f63b8b379 100644
--- a/include/grub/slaunch.h
+++ b/include/grub/slaunch.h
@@ -32,6 +32,7 @@
#define GRUB_SL_BOOT_TYPE_INVALID 0
#define GRUB_SL_BOOT_TYPE_LINUX 1
#define GRUB_SL_BOOT_TYPE_EFI 2
+#define GRUB_SL_BOOT_TYPE_MB2 3
#define GRUB_KERNEL_INFO_HEADER "LToP"
#define GRUB_KERNEL_INFO_MIN_SIZE_TOTAL 12
diff --git a/include/grub/slr_table.h b/include/grub/slr_table.h
index 9dff3d0d5..b9302472b 100644
--- a/include/grub/slr_table.h
+++ b/include/grub/slr_table.h
@@ -72,6 +72,8 @@
#define GRUB_SLR_ET_CMDLINE 0x0004
#define GRUB_SLR_ET_UEFI_MEMMAP 0x0005
#define GRUB_SLR_ET_RAMDISK 0x0006
+#define GRUB_SLR_ET_MULTIBOOT2_INFO 0x0007
+#define GRUB_SLR_ET_MULTIBOOT2_MODULE 0x0008
#define GRUB_SLR_ET_TXT_OS2MLE 0x0010
#define GRUB_SLR_ET_UNUSED 0xffff
--
2.47.1
- [PATCH v3 05/19] commands/i386/tpm: Add TPM TIS and CRB driver, (continued)
- [PATCH v3 05/19] commands/i386/tpm: Add TPM TIS and CRB driver, Sergii Dmytruk, 2024/12/12
- [PATCH v3 10/19] slaunch/txt: Add Intel TXT core implementation, Sergii Dmytruk, 2024/12/12
- [PATCH v3 09/19] i386/txt: Add Intel TXT definitions header file, Sergii Dmytruk, 2024/12/12
- [PATCH v3 12/19] slaunch/txt: Add Intel TXT verification routines, Sergii Dmytruk, 2024/12/12
- [PATCH v3 13/19] i386/efi: Add DL stub as common DL event module, Sergii Dmytruk, 2024/12/12
- [PATCH v3 15/19] efi: Add Secure Launch support for efi/linux boot through EFI stub, Sergii Dmytruk, 2024/12/12
- [PATCH v3 16/19] i386/txt: Initialize TPM 1.2 event log in TXT heap, Sergii Dmytruk, 2024/12/12
- [PATCH v3 18/19] slaunch: Introduce a hook for filling SLRT policy, Sergii Dmytruk, 2024/12/12
- [PATCH v3 17/19] multiboot: Make GRUB_MULTIBOOT(make_mbi) return MBI's size, Sergii Dmytruk, 2024/12/12
- [PATCH v3 11/19] slaunch/txt: Add Intel TXT ACM module support, Sergii Dmytruk, 2024/12/12
- [PATCH v3 19/19] multiboot2: Support TXT Secure Launch,
Sergii Dmytruk <=