Skip to content

Commit

Permalink
multiboot2: Switch to using SLRT interface
Browse files Browse the repository at this point in the history
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.

Signed-off-by: Sergii Dmytruk <[email protected]>
  • Loading branch information
SergiiDmytruk committed Dec 4, 2023
1 parent ba8dbc9 commit b293777
Show file tree
Hide file tree
Showing 6 changed files with 111 additions and 20 deletions.
14 changes: 14 additions & 0 deletions grub-core/loader/i386/txt/txt.c
Original file line number Diff line number Diff line change
Expand Up @@ -586,6 +586,20 @@ init_txt_heap (struct grub_slaunch_params *slparams, struct grub_txt_acm_header
size = (grub_uint64_t *) ((grub_addr_t) os_mle_data - sizeof (grub_uint64_t));
*size = sizeof (*os_mle_data) + sizeof (grub_uint64_t);

if (slparams->slr_table_base == GRUB_SLAUNCH_STORE_IN_OS2MLE)
{
/* SLRT needs to be at least 4-byte aligned per specification. */
slparams->slr_table_base =
ALIGN_UP ((grub_addr_t) os_mle_data + sizeof (*os_mle_data), 4);

/* Recompute size including SLRT table in it. */
*size = (slparams->slr_table_base + slparams->slr_table_size)
- ((grub_addr_t) os_mle_data - sizeof (grub_uint64_t));

/* Size of heap sections should be a multiple of 8. */
*size = ALIGN_UP (*size, 8);
}

grub_memset (os_mle_data, 0, sizeof (*os_mle_data));

os_mle_data->version = GRUB_SL_OS_MLE_STRUCT_VERSION;
Expand Down
21 changes: 10 additions & 11 deletions grub-core/loader/multiboot.c
Original file line number Diff line number Diff line change
Expand Up @@ -165,22 +165,11 @@ efi_boot (struct grub_relocator *rel __attribute__ ((unused)),
static void
normal_boot (struct grub_relocator *rel, struct grub_relocator32_state state)
{
grub_err_t err;
struct grub_slaunch_params *slparams = grub_slaunch_params();
state.edi = grub_slaunch_platform_type ();

if (state.edi == SLP_INTEL_TXT)
{
err = grub_txt_boot_prepare (slparams);

if (err != GRUB_ERR_NONE)
{
grub_printf ("TXT boot preparation failed");
return;
}

grub_slaunch_finish_slr_table ();

/* Configure relocator GETSEC[SENTER] call. */
state.eax = GRUB_SMX_LEAF_SENTER;
state.ebx = slparams->dce_base;
Expand Down Expand Up @@ -216,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
Expand Down
60 changes: 60 additions & 0 deletions grub-core/loader/multiboot_mbi2.c
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@
#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>
Expand Down Expand Up @@ -1167,3 +1168,62 @@ 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_MULTIBOOT_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->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_MULTIBOOT_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;
}
14 changes: 14 additions & 0 deletions include/grub/i386/slaunch.h
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,19 @@

#define GRUB_SLAUNCH_TPM_EVT_LOG_SIZE (8 * GRUB_PAGE_SIZE)

/*
* Special value for slr_table_base of struct grub_slaunch_params that indicates
* that the table should be stored near OS2MLE data (right after it).
*
* In this case:
* 1. Platform-specific code (e.g., TXT-code) is responsible for setting
* slr_table_base to its final value
* 2. SLRT should be copied from slr_table_mem to slr_table_base after invoking
* grub_slaunch_finish_slr_table () by the code which used this special
* value.
*/
#define GRUB_SLAUNCH_STORE_IN_OS2MLE ((grub_uint64_t) 0xFFFFFFFFFFFFFFFF)

#ifndef ASM_FILE

#include <grub/i386/linux.h>
Expand All @@ -36,6 +49,7 @@ struct grub_slaunch_params
{
grub_uint32_t boot_params_addr;
grub_uint64_t slr_table_base;
/* This is size of SLRT buffer, so maximum size of the table. */
grub_uint32_t slr_table_size;
void *slr_table_mem;
grub_uint32_t mle_start;
Expand Down
2 changes: 2 additions & 0 deletions include/grub/multiboot2.h
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down
20 changes: 11 additions & 9 deletions include/grub/slr_table.h
Original file line number Diff line number Diff line change
Expand Up @@ -65,15 +65,17 @@
#define GRUB_SLR_ENTRY_END 0xffff

/* Entity Types */
#define GRUB_SLR_ET_UNSPECIFIED 0x0000
#define GRUB_SLR_ET_SLRT 0x0001
#define GRUB_SLR_ET_BOOT_PARAMS 0x0002
#define GRUB_SLR_ET_SETUP_DATA 0x0003
#define GRUB_SLR_ET_CMDLINE 0x0004
#define GRUB_SLR_ET_UEFI_MEMMAP 0x0005
#define GRUB_SLR_ET_RAMDISK 0x0006
#define GRUB_SLR_ET_TXT_OS2MLE 0x0010
#define GRUB_SLR_ET_UNUSED 0xffff
#define GRUB_SLR_ET_UNSPECIFIED 0x0000
#define GRUB_SLR_ET_SLRT 0x0001
#define GRUB_SLR_ET_BOOT_PARAMS 0x0002
#define GRUB_SLR_ET_SETUP_DATA 0x0003
#define GRUB_SLR_ET_CMDLINE 0x0004
#define GRUB_SLR_ET_UEFI_MEMMAP 0x0005
#define GRUB_SLR_ET_RAMDISK 0x0006
#define GRUB_SLR_ET_MULTIBOOT_INFO 0x0007
#define GRUB_SLR_ET_MULTIBOOT_MODULE 0x0008
#define GRUB_SLR_ET_TXT_OS2MLE 0x0010
#define GRUB_SLR_ET_UNUSED 0xffff

/*
* Primary SLR Table Header
Expand Down

0 comments on commit b293777

Please sign in to comment.