Skip to content

Commit

Permalink
arch/x86: process DRTM policy
Browse files Browse the repository at this point in the history
Also, since this is done early, validate SLRT in the process.

The policy is looked at twice: at the very start near slaunch entrypoint
and in __start_xen().  Both times perform the same checks, but the first
time unsatisfied conditions just lead to doing no work as we can't
really report errors yet.  When the code is invoked from __start_xen(),
failed checks lead to abort() with an error message explaining the
issue.

An alternative is to store error code/message somewhere and print it
later, which would need a bit more code distributed in more than one
unit.

Signed-off-by: Sergii Dmytruk <[email protected]>
  • Loading branch information
SergiiDmytruk committed Nov 11, 2023
1 parent 77aa1cf commit 39a1478
Show file tree
Hide file tree
Showing 3 changed files with 124 additions and 9 deletions.
27 changes: 18 additions & 9 deletions xen/arch/x86/include/asm/intel_txt.h
Original file line number Diff line number Diff line change
Expand Up @@ -350,19 +350,28 @@ static inline void find_evt_log(void **evt_log, uint32_t *evt_log_size)
extern void protect_txt_mem_regions(void);
extern void txt_restore_mtrrs(bool e820_verbose);

#define DRTM_LOC 2
#define DRTM_CODE_PCR 17
#define DRTM_DATA_PCR 18
#define DRTM_LOC 2
#define DRTM_CODE_PCR 17
#define DRTM_DATA_PCR 18

/* TXT-defined use 0x4xx, TrenchBoot in Linux uses 0x5xx, use 0x6xx here. */
#define TXT_EVTYPE_MBI 0x600
#define TXT_EVTYPE_KERNEL 0x601
#define TXT_EVTYPE_INITRD 0x602

#define SHA1_DIGEST_SIZE 20
#define SHA256_DIGEST_SIZE 32
#define TXT_EVTYPE_MBI 0x600
#define TXT_EVTYPE_KERNEL 0x601
#define TXT_EVTYPE_INITRD 0x602
#define TXT_EVTYPE_KERNEL_CMDLINE 0x603
#define TXT_EVTYPE_SLRT 0x604
#define TXT_EVTYPE_OS2MLE 0x605
#define TXT_EVTYPE_MODULE 0x606
#define TXT_EVTYPE_MODULE_CMDLINE 0x607
#define TXT_EVTYPE_UEFI_MMAP 0x608
#define TXT_EVTYPE_UNKNOWN 0x6ff

#define SHA1_DIGEST_SIZE 20
#define SHA256_DIGEST_SIZE 32

void tpm_hash_extend(unsigned loc, unsigned pcr, uint8_t *buf, unsigned size,
uint32_t type, uint8_t *log_data, unsigned log_data_size);

void tpm_take_measurements(void);

#endif /* __ASSEMBLY__ */
4 changes: 4 additions & 0 deletions xen/arch/x86/setup.c
Original file line number Diff line number Diff line change
Expand Up @@ -1030,11 +1030,15 @@ void __init noreturn __start_xen(unsigned long mbi_p)
}

if ( sl_status )
{
tpm_take_measurements();

if ( mbi->mods_count > 2 )
{
mbi->mods_count = 2;
printk("Excessive multiboot modules for slaunch - limiting to 2\n");
}
}

bitmap_fill(module_map, mbi->mods_count);
__clear_bit(0, module_map); /* Dom0 kernel is always first */
Expand Down
102 changes: 102 additions & 0 deletions xen/arch/x86/tpm.c
Original file line number Diff line number Diff line change
Expand Up @@ -978,4 +978,106 @@ void __stdcall tpm_extend_mbi(uint32_t *mbi)
tpm_hash_extend(DRTM_LOC, DRTM_DATA_PCR, (uint8_t *)mbi, *mbi,
TXT_EVTYPE_MBI, NULL, 0);
}
#else
static struct slr_entry_policy *tpm_get_policy(void)
{
struct txt_os_mle_data *os_mle;
struct slr_table *slrt;
struct slr_entry_policy *policy;

os_mle = txt_os_mle_data_start(__va(read_txt_reg(TXTCR_HEAP_BASE)));

slrt = __va(os_mle->slrt);
if ( slrt->magic != SLR_TABLE_MAGIC )
panic("SLRT has invalid magic value: %#08x!\n", slrt->magic);
/* XXX: are newer revisions allowed? */
if ( slrt->revision != SLR_TABLE_REVISION )
panic("SLRT is of unsupported revision: %#04x!\n", slrt->revision);
if ( slrt->architecture != SLR_INTEL_TXT )
panic("SLRT is for unexpected architecture: %#04x!\n",
slrt->architecture);
if ( slrt->size > slrt->max_size )
panic("SLRT is larger than its max size: %#08x > %#08x!\n",
slrt->size, slrt->max_size);
if ( slr_next_entry_by_tag(slrt, NULL, SLR_ENTRY_INTEL_INFO) == NULL )
panic("SLRT is missing Intel-specific information!\n");

policy = (struct slr_entry_policy *)
slr_next_entry_by_tag(slrt, NULL, SLR_ENTRY_DRTM_POLICY);
if (policy == NULL)
panic("SLRT is missing DRTM policy!\n");

/* SLRT policy entry must be the first one (so measuring order matches
* policy order) and point to SLRT. */
/* XXX: are newer revisions allowed? */
if ( policy->revision != SLR_POLICY_REVISION )
panic("DRTM policy in SLRT is of unsupported revision: %#04x!\n",
slrt->revision);
if ( policy->nr_entries == 0 )
panic("DRTM policy in SLRT is empty!\n");

return policy;
}

void tpm_take_measurements(void)
{
struct txt_os_mle_data *os_mle;
struct slr_table *slrt;
struct slr_entry_policy *policy;
struct slr_policy_entry *policy_entry;
uint16_t i;

os_mle = txt_os_mle_data_start(__va(read_txt_reg(TXTCR_HEAP_BASE)));
slrt = __va(os_mle->slrt);

policy = tpm_get_policy();
policy_entry = (struct slr_policy_entry *)
((uint8_t *)policy + sizeof(*policy));
if ( policy_entry[0].entity_type != SLR_ET_MULTIBOOT_INFO ) {
panic("First entry of DRTM policy in SLRT has wrong type: %#04x!\n",
policy_entry[0].entity_type);
}

for ( i = 1; i < policy->nr_entries; i++ ) {
uint64_t start = policy_entry[i].entity;
uint64_t size = policy_entry[i].size;
uint32_t event_type = TXT_EVTYPE_UNKNOWN;

switch ( policy_entry[i].entity_type ) {
case SLR_ET_MULTIBOOT_INFO:
panic("Duplicated MBI entry in DRTM of Secure Launch at %d\n", i);

case SLR_ET_SLRT:
event_type = TXT_EVTYPE_SLRT;
break;
case SLR_ET_CMDLINE:
event_type = TXT_EVTYPE_KERNEL_CMDLINE;
break;
case SLR_ET_UEFI_MEMMAP:
event_type = TXT_EVTYPE_UEFI_MMAP;
break;
case SLR_ET_RAMDISK:
event_type = TXT_EVTYPE_INITRD;
break;
case SLR_ET_TXT_OS2MLE:
event_type = TXT_EVTYPE_OS2MLE;
break;
case SLR_ET_MULTIBOOT_MODULE:
event_type = TXT_EVTYPE_MODULE;
break;
case SLR_ET_MULTIBOOT_MODULE_CMDLINE:
event_type = TXT_EVTYPE_MODULE_CMDLINE;
break;

case SLR_ET_UNUSED:
continue;
}

map_pages_to_xen(start, maddr_to_mfn(start), PFN_UP(size),
__PAGE_HYPERVISOR_RO);
tpm_hash_extend(DRTM_LOC, policy_entry[i].pcr, (uint8_t *)start, size,
event_type, NULL, 0);
destroy_xen_mappings(start, start + PFN_UP(size) * PAGE_SIZE);
}
}
#endif

0 comments on commit 39a1478

Please sign in to comment.