[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[PATCH 20/24] multiboot2: Implement TXT slaunch support
From: |
Sergii Dmytruk |
Subject: |
[PATCH 20/24] multiboot2: Implement TXT slaunch support |
Date: |
Mon, 26 Aug 2024 15:44:30 +0300 |
From: Michał Żygowski <michal.zygowski@3mdeb.com>
The code makes sure that MBI entry goes first in DRTM, so the payload
can measure it first on launch.
SLRT table is allocated on the heap first, size for it is reserved
inside TXT heap by TXT code and data is later copied into its final
place.
To avoid mismatch between OS SINIT data MLE size and MLE size from
MLE header, take the mle_size from MLE header as is (without aligning
it).
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 | 23 ++++++-
grub-core/loader/multiboot_elfxx.c | 88 ++++++++++++++++++++++++++-
grub-core/loader/multiboot_mbi2.c | 96 ++++++++++++++++++++++++++++++
include/grub/multiboot2.h | 2 +
4 files changed, 207 insertions(+), 2 deletions(-)
diff --git a/grub-core/loader/multiboot.c b/grub-core/loader/multiboot.c
index 8288a1f49..bd2de587f 100644
--- a/grub-core/loader/multiboot.c
+++ b/grub-core/loader/multiboot.c
@@ -52,6 +52,7 @@
#include <grub/i18n.h>
#if defined (__i386__) || defined (__x86_64__)
#include <grub/i386/slaunch.h>
+#include <grub/i386/txt.h>
#endif
GRUB_MOD_LICENSE ("GPLv3+");
@@ -164,7 +165,17 @@ efi_boot (struct grub_relocator *rel __attribute__
((unused)),
static void
normal_boot (struct grub_relocator *rel, struct grub_relocator32_state state)
{
- state.edi = SLP_NONE;
+ struct grub_slaunch_params *slparams = grub_slaunch_params();
+ state.edi = grub_slaunch_platform_type ();
+
+ if (state.edi == SLP_INTEL_TXT)
+ {
+ /* Configure relocator GETSEC[SENTER] call. */
+ state.eax = GRUB_SMX_LEAF_SENTER;
+ state.ebx = slparams->dce_base;
+ state.ecx = slparams->dce_size;
+ state.edx = 0;
+ }
grub_relocator32_boot (rel, state, 0);
}
@@ -194,6 +205,16 @@ grub_multiboot_boot (void)
if (err)
return err;
+#ifdef GRUB_USE_MULTIBOOT2
+ if (grub_slaunch_platform_type () == SLP_INTEL_TXT)
+ {
+ err = grub_multiboot2_prepare_slaunch_txt (state.MULTIBOOT_MBI_REGISTER,
+ mbi_size);
+ if (err)
+ return err;
+ }
+#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..6bf3010fb 100644
--- a/grub-core/loader/multiboot_elfxx.c
+++ b/grub-core/loader/multiboot_elfxx.c
@@ -44,6 +44,8 @@
#error "I'm confused"
#endif
+#include <grub/i386/slaunch.h>
+#include <grub/i386/txt.h>
#include <grub/i386/relocator.h>
#define CONCAT(a,b) CONCAT_(a, b)
@@ -73,6 +75,9 @@ CONCAT(grub_multiboot_load_elf, XX) (mbi_load_data_t *mld)
grub_off_t phlimit;
unsigned int i;
void *source = NULL;
+ struct grub_slaunch_params *slparams = grub_slaunch_params();
+ grub_uint32_t mle_hdr_offset;
+ struct grub_txt_mle_header *mle_hdr;
if (ehdr->e_ident[EI_MAG0] != ELFMAG0
|| ehdr->e_ident[EI_MAG1] != ELFMAG1
@@ -127,6 +132,28 @@ CONCAT(grub_multiboot_load_elf, XX) (mbi_load_data_t *mld)
{
load_size = highest_load - mld->link_base_addr;
+ if (grub_slaunch_platform_type () == SLP_INTEL_TXT)
+ {
+#ifndef GRUB_USE_MULTIBOOT2
+ return grub_error (GRUB_ERR_BAD_OS, "Only multiboot2 supported for
slaunch");
+#else
+ /*
+ * We 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);
+
+ /* Do not go below GRUB_TXT_PMR_ALIGN. */
+ if (mld->align < GRUB_TXT_PMR_ALIGN)
+ mld->align = GRUB_TXT_PMR_ALIGN;
+#endif
+ }
+ else
+ {
+ slparams->mle_ptab_size = 0;
+ }
+
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 +175,44 @@ 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);
+ grub_memset (get_virtual_current_address (ch), 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_INTEL_TXT)
+ {
+#ifndef GRUB_USE_MULTIBOOT2
+ return grub_error (GRUB_ERR_BAD_OS, "Only multiboot2 supported for
slaunch");
+#else
+ slparams->mle_start = mld->load_base_addr;
+ slparams->mle_mem = source;
+
+ 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;
+ {
+ mld->load_base_addr = mld->link_base_addr;
+ /* TODO: support non-relocatable */
+ if (grub_slaunch_platform_type () == SLP_INTEL_TXT)
+ return grub_error (GRUB_ERR_BAD_OS, "Non-relocatable ELF not supported
with slaunch");
+ }
grub_dprintf ("multiboot_loader", "relocatable=%d, link_base_addr=0x%x, "
"load_base_addr=0x%x\n", mld->relocatable,
@@ -213,6 +275,30 @@ CONCAT(grub_multiboot_load_elf, XX) (mbi_load_data_t *mld)
}
}
+ if (grub_slaunch_platform_type () == SLP_INTEL_TXT)
+ {
+ slparams->mle_header_offset = 0xffffffff;
+
+ /* 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 ((void *)mle_hdr->uuid, GRUB_TXT_MLE_UUID, 16) )
+ {
+ slparams->mle_header_offset = mle_hdr_offset;
+ break;
+ }
+ }
+
+ if (slparams->mle_header_offset == 0xffffffff)
+ return grub_error (GRUB_ERR_BAD_ARGUMENT, "MLE header not found");
+
+ grub_dprintf ("slaunch", "slparams->mle_header_offset: 0x%08x\n",
+ slparams->mle_header_offset);
+
+ slparams->mle_size = mle_hdr->mle_end - mle_hdr->mle_start;
+ }
+
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..40b859fb5 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/slaunch.h>
+#include <grub/i386/txt.h>
+#include <grub/slr_table.h>
#if defined (GRUB_MACHINE_EFI)
#include <grub/efi/efi.h>
@@ -277,6 +281,9 @@ grub_multiboot2_load (grub_file_t file, const char
*filename)
if (addr_tag)
{
+ if (grub_slaunch_platform_type () == SLP_INTEL_TXT)
+ 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 +397,34 @@ 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 (grub_slaunch_platform_type () == SLP_INTEL_TXT)
+ {
+ grub_relocator_chunk_t ch;
+ struct grub_slaunch_params *slparams = grub_slaunch_params();
+
+ 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;
+
+ grub_txt_init_tpm_event_log(get_virtual_current_address (ch),
+ slparams->tpm_evt_log_size);
+
+ grub_dprintf ("multiboot_loader", "tpm_evt_log_base = %lx,
tpm_evt_log_size = %x\n",
+ (unsigned long) slparams->tpm_evt_log_base,
+ (unsigned) slparams->tpm_evt_log_size);
+
+ grub_txt_setup_mle_ptab (slparams);
+ }
+
return err;
}
@@ -1128,3 +1163,64 @@ grub_multiboot2_set_bootdev (void)
bootdev_set = 1;
}
+
+static void
+add_multiboot2_slrt_policy_entries (void)
+{
+ unsigned i;
+ struct module *cur;
+
+ for (i = 0, cur = modules; i < modcnt; i++, cur = cur->next)
+ {
+ grub_slaunch_add_slrt_policy_entry (17,
+ GRUB_SLR_ET_MULTIBOOT2_MODULE,
+ /*flags=*/0,
+ cur->start,
+ cur->size,
+ "Measured MB2 module");
+ }
+}
+
+grub_err_t
+grub_multiboot2_prepare_slaunch_txt (grub_uint32_t mbi_target,
+ grub_uint32_t mbi_size)
+{
+ grub_err_t err;
+ struct grub_slaunch_params *slparams = grub_slaunch_params ();
+
+ slparams->boot_params_addr = mbi_target;
+
+ slparams->slr_table_base = GRUB_SLAUNCH_STORE_IN_OS2MLE;
+ slparams->slr_table_size = GRUB_PAGE_SIZE;
+
+ slparams->slr_table_mem = grub_zalloc (slparams->slr_table_size);
+ if (slparams->slr_table_mem == NULL)
+ return GRUB_ERR_OUT_OF_MEMORY;
+
+ err = grub_txt_boot_prepare (slparams);
+ if (err != GRUB_ERR_NONE)
+ {
+ grub_printf ("TXT boot preparation failed");
+ return err;
+ }
+
+ grub_slaunch_add_slrt_policy_entry (18,
+ GRUB_SLR_ET_MULTIBOOT2_INFO,
+ /*flags=*/0,
+ mbi_target,
+ mbi_size,
+ "Measured MB2 information");
+ grub_slaunch_add_slrt_policy_entries ();
+ grub_txt_add_slrt_policy_entries ();
+ add_multiboot2_slrt_policy_entries ();
+ grub_slaunch_finish_slr_table ();
+
+ grub_dprintf ("multiboot_loader", "slr_table_base = %lx, slr_table_size =
%x\n",
+ (unsigned long) slparams->slr_table_base,
+ (unsigned) slparams->slr_table_size);
+ grub_memcpy ((void *)(grub_addr_t) slparams->slr_table_base,
+ slparams->slr_table_mem,
+ slparams->slr_table_size);
+
+ return GRUB_ERR_NONE;
+}
diff --git a/include/grub/multiboot2.h b/include/grub/multiboot2.h
index 3417a1447..2e843d24e 100644
--- a/include/grub/multiboot2.h
+++ b/include/grub/multiboot2.h
@@ -43,6 +43,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_prepare_slaunch_txt (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);
--
2.46.0
- [PATCH 06/24] i386/memory: Define GRUB_PAGE_MASK constant and GRUB_PAGE_{UP, DOWN} macros, (continued)
- [PATCH 06/24] i386/memory: Define GRUB_PAGE_MASK constant and GRUB_PAGE_{UP, DOWN} macros, Sergii Dmytruk, 2024/08/26
- [PATCH 04/24] i386/memory: Rename PAGE_SHIFT to GRUB_PAGE_SHIFT, Sergii Dmytruk, 2024/08/26
- [PATCH 07/24] mmap: Add grub_mmap_get_lowest() and grub_mmap_get_highest(), Sergii Dmytruk, 2024/08/26
- [PATCH 08/24] i386/tpm: Rename tpm module to tpm_verifier, Sergii Dmytruk, 2024/08/26
- [PATCH 09/24] i386/tpm: Add TPM TIS and CRB driver, Sergii Dmytruk, 2024/08/26
- [PATCH 10/24] include/grub: Introduce Secure Launch Resource Table (SLRT), Sergii Dmytruk, 2024/08/26
- [PATCH 11/24] i386/slaunch: Add basic platform support for secure launch, Sergii Dmytruk, 2024/08/26
- [PATCH 12/24] i386/txt: Add Intel TXT definitions header file, Sergii Dmytruk, 2024/08/26
- [PATCH 13/24] i386/txt: Add Intel TXT core implementation, Sergii Dmytruk, 2024/08/26
- [PATCH 16/24] i386/txt: Initialize TPM 1.2 event log in TXT heap, Sergii Dmytruk, 2024/08/26
- [PATCH 20/24] multiboot2: Implement TXT slaunch support,
Sergii Dmytruk <=
- [PATCH 17/24] i386/slaunch: Add secure launch framework and commands, Sergii Dmytruk, 2024/08/26
- [PATCH 14/24] i386/txt: Add Intel TXT ACM module support, Sergii Dmytruk, 2024/08/26
- [PATCH 19/24] multiboot: Make GRUB_MULTIBOOT(make_mbi) return MBI's size, Sergii Dmytruk, 2024/08/26
- [PATCH 15/24] i386/txt: Add Intel TXT verification routines, Sergii Dmytruk, 2024/08/26
- [PATCH 18/24] loader/i386/linux.c: Fix cleanup if kernel doesn't support 64-bit addressing, Sergii Dmytruk, 2024/08/26
- [PATCH 22/24] i386/slaunch: Add support for AMD SKINIT, Sergii Dmytruk, 2024/08/26
- [PATCH 23/24] multiboot2: Support AMD SKINIT, Sergii Dmytruk, 2024/08/26
- [PATCH 21/24] i386/skinit: Add AMD SKINIT implementation, Sergii Dmytruk, 2024/08/26
- [PATCH 24/24] i386/linux: Add support for AMD SKINIT, Sergii Dmytruk, 2024/08/26