Skip to content

Commit

Permalink
Switch to using Secure Launch Resource Table interface
Browse files Browse the repository at this point in the history
Signed-off-by: Ross Philipson <[email protected]>
Signed-off-by: Sergii Dmytruk <[email protected]>
  • Loading branch information
rossphilipson authored and SergiiDmytruk committed Oct 17, 2023
1 parent 6b65f4b commit d87efc0
Show file tree
Hide file tree
Showing 8 changed files with 270 additions and 56 deletions.
94 changes: 92 additions & 2 deletions grub-core/loader/i386/linux.c
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@
#include <grub/linux.h>
#include <grub/machine/kernel.h>
#include <grub/safemath.h>
#include <grub/slr_table.h>

GRUB_MOD_LICENSE ("GPLv3+");

Expand Down Expand Up @@ -69,6 +70,18 @@ GRUB_MOD_LICENSE ("GPLv3+");
#define KERNEL_INFO_HEADER "LToP"
#define KERNEL_INFO_MIN_SIZE_TOTAL 12

struct linux_params_efi_info
{
grub_uint32_t efi_signature;
grub_uint32_t efi_system_table;
grub_uint32_t efi_mem_desc_size;
grub_uint32_t efi_mem_desc_version;
grub_uint32_t efi_mmap;
grub_uint32_t efi_mmap_size;
grub_uint32_t efi_system_table_hi;
grub_uint32_t efi_mmap_hi;
};

static grub_dl_t my_mod;

static grub_size_t linux_mem_size;
Expand Down Expand Up @@ -248,11 +261,28 @@ allocate_pages (grub_size_t prot_size, grub_size_t *align,

slparams->mle_start = prot_mode_target;
slparams->mle_size = prot_size;
slparams->mle_mem = prot_mode_mem;

grub_dprintf ("linux", "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);

if (grub_relocator_alloc_chunk_align (relocator, &ch, 0x1000000,
0xffffffff - GRUB_PAGE_SIZE,
GRUB_PAGE_SIZE, GRUB_PAGE_SIZE,
GRUB_RELOCATOR_PREFERENCE_NONE, 1))
goto fail;

slparams->slr_table_base = get_physical_target_address (ch);
slparams->slr_table_size = GRUB_PAGE_SIZE;
slparams->slr_table_mem = get_virtual_current_address (ch);

grub_memset (slparams->slr_table_mem, 0, slparams->slr_table_size);

grub_dprintf ("linux", "slr_table_base = %lx, slr_table_size = %x\n",
(unsigned long) slparams->slr_table_base,
(unsigned) slparams->slr_table_size);

if (grub_relocator_alloc_chunk_align (relocator, &ch, 0x1000000,
0xffffffff - GRUB_SLAUNCH_TPM_EVT_LOG_SIZE,
GRUB_SLAUNCH_TPM_EVT_LOG_SIZE, GRUB_PAGE_SIZE,
Expand Down Expand Up @@ -468,6 +498,60 @@ grub_linux_boot_mmap_fill (grub_uint64_t addr, grub_uint64_t size,
return 0;
}

static void
grub_linux_setup_slr_table (struct grub_slaunch_params *slparams)
{
struct linux_kernel_params *boot_params = (void *) (grub_addr_t) slparams->boot_params_addr;
struct linux_params_efi_info *efi_info;

/* A bit of work to extract the v2.08 EFI info from the linux params */
efi_info = (void *)((grub_uint8_t *)&boot_params->v0208 + 2*sizeof(grub_uint32_t));

grub_slaunch_add_slrt_policy_entry (18,
GRUB_SLR_ET_BOOT_PARAMS,
/*flags=*/0,
(grub_addr_t) boot_params,
GRUB_PAGE_SIZE,
"Measured boot parameters");

if (boot_params->setup_data)
grub_slaunch_add_slrt_policy_entry (18,
GRUB_SLR_ET_SETUP_DATA,
GRUB_SLR_POLICY_IMPLICIT_SIZE,
boot_params->setup_data,
/*size=*/0,
"Measured Kernel setup_data");

/* TODO the cmdline ptr can have hi bits but for now assume always < 4G */
grub_slaunch_add_slrt_policy_entry (18,
GRUB_SLR_ET_CMDLINE,
/*flags=*/0,
boot_params->cmd_line_ptr,
boot_params->cmdline_size,
"Measured Kernel command line");

if (!grub_memcmp(&efi_info->efi_signature, "EL64", sizeof(grub_uint32_t)))
{
grub_uint64_t mmap_addr =
((grub_uint64_t) efi_info->efi_mmap_hi << 32) | efi_info->efi_mmap;
grub_slaunch_add_slrt_policy_entry (18,
GRUB_SLR_ET_UEFI_MEMMAP,
/*flags=*/0,
mmap_addr,
efi_info->efi_mmap_size,
"Measured EFI memory map");
}

if (boot_params->ramdisk_image)
/* TODO the initrd image and size can have hi bits but for now assume always < 4G */
grub_slaunch_add_slrt_policy_entry (17,
GRUB_SLR_ET_RAMDISK,
/*flags=*/0,
boot_params->ramdisk_image,
boot_params->ramdisk_size,
"Measured Kernel initrd");
}

static grub_err_t
grub_linux_boot (void)
{
Expand Down Expand Up @@ -645,6 +729,9 @@ grub_linux_boot (void)
grub_dprintf ("linux", "ap_wake_block = %lx, ap_wake_block_size = %lx\n",
(unsigned long) slparams->ap_wake_block,
(unsigned long) ap_wake_block_size);

/* Grab the real mode target address, this is the boot params page. */
slparams->boot_params_addr = ctx.real_mode_target;
}

grub_dprintf ("linux", "real_mode_mem = %p\n",
Expand Down Expand Up @@ -673,6 +760,8 @@ grub_linux_boot (void)

ctx.params->secure_boot = grub_efi_get_secureboot ();

grub_dprintf ("linux", "EFI exit boot services\n");

err = grub_efi_finish_boot_services (&efi_mmap_size, efi_mmap_buf, NULL,
&efi_desc_size, &efi_desc_version);
if (err)
Expand Down Expand Up @@ -714,13 +803,14 @@ grub_linux_boot (void)

if (state.edi == SLP_INTEL_TXT)
{
slparams->boot_params_addr = (grub_uint32_t) ctx.real_mode_target;

err = grub_txt_boot_prepare (slparams);

if (err != GRUB_ERR_NONE)
return err;

grub_linux_setup_slr_table (slparams);
grub_slaunch_finish_slr_table ();

/* Configure relocator GETSEC[SENTER] call. */
state.eax = GRUB_SMX_LEAF_SENTER;
state.ebx = slparams->dce_base;
Expand Down
87 changes: 87 additions & 0 deletions grub-core/loader/i386/slaunch.c
Original file line number Diff line number Diff line change
Expand Up @@ -23,11 +23,13 @@
#include <grub/misc.h>
#include <grub/types.h>
#include <grub/dl.h>
#include <grub/slr_table.h>
#include <grub/cpu/relocator.h>
#include <grub/i386/cpuid.h>
#include <grub/i386/msr.h>
#include <grub/i386/mmio.h>
#include <grub/i386/slaunch.h>
#include <grub/i386/tpm.h>
#include <grub/i386/txt.h>

GRUB_MOD_LICENSE ("GPLv3+");
Expand All @@ -38,6 +40,13 @@ static void *slaunch_module = NULL;

static struct grub_slaunch_params slparams;

/* Area to collect and build SLR Table information. */
static struct grub_slr_entry_dl_info slr_dl_info_staging;
static struct grub_slr_entry_log_info slr_log_info_staging;
static grub_uint8_t slr_policy_buf[GRUB_PAGE_SIZE];
static struct grub_slr_entry_policy *slr_policy_staging =
(struct grub_slr_entry_policy *)slr_policy_buf;

grub_uint32_t
grub_slaunch_platform_type (void)
{
Expand All @@ -56,6 +65,84 @@ grub_slaunch_params (void)
return &slparams;
}

void
grub_slaunch_init_slrt_storage (int arch)
{
struct grub_txt_mle_header *mle_header =
(void *) ((grub_uint8_t *) slparams.mle_mem + slparams.mle_header_offset);

/* Setup the generic bits of the SLRT. */
grub_slr_init_table(slparams.slr_table_mem, arch, slparams.slr_table_size);

/* Setup DCE and DLME information. */
slr_dl_info_staging.hdr.tag = GRUB_SLR_ENTRY_DL_INFO;
slr_dl_info_staging.hdr.size = sizeof(struct grub_slr_entry_dl_info);
slr_dl_info_staging.dce_base = slparams.dce_base;
slr_dl_info_staging.dce_size = slparams.dce_size;
slr_dl_info_staging.dlme_entry = mle_header->entry_point;

slr_log_info_staging.hdr.tag = GRUB_SLR_ENTRY_LOG_INFO;
slr_log_info_staging.hdr.size = sizeof(struct grub_slr_entry_log_info);
slr_log_info_staging.addr = slparams.tpm_evt_log_base;
slr_log_info_staging.size = slparams.tpm_evt_log_size;
slr_log_info_staging.format =
(grub_get_tpm_ver () == GRUB_TPM_20) ?
GRUB_SLR_DRTM_TPM20_LOG : GRUB_SLR_DRTM_TPM12_LOG;

slr_policy_staging->hdr.tag = GRUB_SLR_ENTRY_DRTM_POLICY;
slr_policy_staging->hdr.size = sizeof(struct grub_slr_entry_policy);
slr_policy_staging->revision = GRUB_SLR_TABLE_REVISION;
slr_policy_staging->nr_entries = 0;

/* The SLR table should be measured too, at least parts of it. */
grub_slaunch_add_slrt_policy_entry (18,
GRUB_SLR_ET_SLRT,
GRUB_SLR_POLICY_IMPLICIT_SIZE,
slparams.slr_table_base,
/*size=*/0,
"Measured SLR Table");
}

void
grub_slaunch_add_slrt_policy_entry (grub_uint16_t pcr,
grub_uint16_t entity_type,
grub_uint16_t flags,
grub_uint64_t entity,
grub_uint64_t size,
const char *evt_info)
{
struct grub_slr_policy_entry *entry =
(void *)((grub_uint8_t *)slr_policy_staging +
sizeof(struct grub_slr_entry_policy) +
slr_policy_staging->nr_entries*sizeof(*entry));

if (slr_policy_staging->hdr.size + sizeof(*entry) > sizeof(slr_policy_buf))
grub_fatal("Not enough space for adding policy entry: %s! The buffer is full.",
evt_info);

entry->pcr = pcr;
entry->entity_type = entity_type;
entry->flags = flags;
entry->entity = entity;
entry->size = size;

grub_strncpy(entry->evt_info, evt_info, sizeof(entry->evt_info) - 1);
entry->evt_info[sizeof(entry->evt_info) - 1] = '\0';

slr_policy_staging->hdr.size += sizeof(*entry);
++slr_policy_staging->nr_entries;
}

void
grub_slaunch_finish_slr_table (void)
{
struct grub_slr_table *slr_table = slparams.slr_table_mem;

grub_slr_add_entry (slr_table, &slr_dl_info_staging.hdr);
grub_slr_add_entry (slr_table, &slr_log_info_staging.hdr);
grub_slr_add_entry (slr_table, &slr_policy_staging->hdr);
}

static grub_err_t
grub_cmd_slaunch (grub_command_t cmd __attribute__ ((unused)),
int argc __attribute__ ((unused)),
Expand Down
Loading

0 comments on commit d87efc0

Please sign in to comment.