From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 From: Javier Martinez Canillas Date: Fri, 21 Sep 2018 17:51:16 +0200 Subject: [PATCH] drop TPM support for legacy BIOS Currently there's TPM support for both EFI and legacy BIOS. A software interrupt call interface is used in legacy BIOS to communicate with the TPM chips. But with some BIOS firmwares, the machine just hangs after doing a BIOS interrupt call for the TCG_HashLogExtendEvent command. It's hard to know what exactly is causing this, but the Trousers project mentions in their docs that they don't use TCG_HashLogExtendEvent [0] due the command not working reliable on some BIOS. The TCG_CompactHashLogExtendEvent is less fragile, since it has a simpler interface, doesn't require to setup any data structure and doesn't return anything. So it could be used to do measurements and logs events instead. But even when using this command can be a workaround on some systems, it doesn't guarantee that could not fail on others. So since the TPM support for some legacy BIOS don't work and can lead to machines failing to boot, let's just drop it and only support TPM for EFI. [0]: http://trousers.sourceforge.net/grub.html Resolves: rhbz#1579835 Signed-off-by: Javier Martinez Canillas --- grub-core/Makefile.core.def | 1 - grub-core/kern/i386/pc/tpm.c | 145 -------------------------------------- grub-core/loader/i386/pc/linux.c | 4 -- include/grub/tpm.h | 2 +- grub-core/boot/i386/pc/boot.S | 30 +------- grub-core/boot/i386/pc/diskboot.S | 44 ------------ 6 files changed, 2 insertions(+), 224 deletions(-) delete mode 100644 grub-core/kern/i386/pc/tpm.c diff --git a/grub-core/Makefile.core.def b/grub-core/Makefile.core.def index cf3d549d2..fb0a1e0ba 100644 --- a/grub-core/Makefile.core.def +++ b/grub-core/Makefile.core.def @@ -246,7 +246,6 @@ kernel = { i386_pc = kern/i386/pc/init.c; i386_pc = kern/i386/pc/mmap.c; - i386_pc = kern/i386/pc/tpm.c; i386_pc = term/i386/pc/console.c; i386_qemu = bus/pci.c; diff --git a/grub-core/kern/i386/pc/tpm.c b/grub-core/kern/i386/pc/tpm.c deleted file mode 100644 index f6f264aff..000000000 --- a/grub-core/kern/i386/pc/tpm.c +++ /dev/null @@ -1,145 +0,0 @@ -#include -#include -#include -#include -#include -#include - -#define TCPA_MAGIC 0x41504354 - -static int tpm_presence = -1; - -int tpm_present(void); - -int tpm_present(void) -{ - struct grub_bios_int_registers regs; - - if (tpm_presence != -1) - return tpm_presence; - - regs.flags = GRUB_CPU_INT_FLAGS_DEFAULT; - regs.eax = 0xbb00; - regs.ebx = TCPA_MAGIC; - grub_bios_interrupt (0x1a, ®s); - - if (regs.eax == 0) - tpm_presence = 1; - else - tpm_presence = 0; - - return tpm_presence; -} - -grub_err_t -grub_tpm_execute(PassThroughToTPM_InputParamBlock *inbuf, - PassThroughToTPM_OutputParamBlock *outbuf) -{ - struct grub_bios_int_registers regs; - grub_addr_t inaddr, outaddr; - - if (!tpm_present()) - return 0; - - inaddr = (grub_addr_t) inbuf; - outaddr = (grub_addr_t) outbuf; - regs.flags = GRUB_CPU_INT_FLAGS_DEFAULT; - regs.eax = 0xbb02; - regs.ebx = TCPA_MAGIC; - regs.ecx = 0; - regs.edx = 0; - regs.es = (inaddr & 0xffff0000) >> 4; - regs.edi = inaddr & 0xffff; - regs.ds = outaddr >> 4; - regs.esi = outaddr & 0xf; - - grub_bios_interrupt (0x1a, ®s); - - if (regs.eax) - { - tpm_presence = 0; - return grub_error (GRUB_ERR_IO, N_("TPM error %x, disabling TPM"), regs.eax); - } - - return 0; -} - -typedef struct { - grub_uint32_t pcrindex; - grub_uint32_t eventtype; - grub_uint8_t digest[20]; - grub_uint32_t eventdatasize; - grub_uint8_t event[0]; -} GRUB_PACKED Event; - -typedef struct { - grub_uint16_t ipblength; - grub_uint16_t reserved; - grub_uint32_t hashdataptr; - grub_uint32_t hashdatalen; - grub_uint32_t pcr; - grub_uint32_t reserved2; - grub_uint32_t logdataptr; - grub_uint32_t logdatalen; -} GRUB_PACKED EventIncoming; - -typedef struct { - grub_uint16_t opblength; - grub_uint16_t reserved; - grub_uint32_t eventnum; - grub_uint8_t hashvalue[20]; -} GRUB_PACKED EventOutgoing; - -grub_err_t -grub_tpm_log_event(unsigned char *buf, grub_size_t size, grub_uint8_t pcr, - const char *description) -{ - struct grub_bios_int_registers regs; - EventIncoming incoming; - EventOutgoing outgoing; - Event *event; - grub_uint32_t datalength; - - if (!tpm_present()) - return 0; - - datalength = grub_strlen(description); - event = grub_zalloc(datalength + sizeof(Event)); - if (!event) - return grub_error (GRUB_ERR_OUT_OF_MEMORY, - N_("cannot allocate TPM event buffer")); - - event->pcrindex = pcr; - event->eventtype = 0x0d; - event->eventdatasize = grub_strlen(description); - grub_memcpy(event->event, description, datalength); - - incoming.ipblength = sizeof(incoming); - incoming.hashdataptr = (grub_uint32_t)buf; - incoming.hashdatalen = size; - incoming.pcr = pcr; - incoming.logdataptr = (grub_uint32_t)event; - incoming.logdatalen = datalength + sizeof(Event); - - regs.flags = GRUB_CPU_INT_FLAGS_DEFAULT; - regs.eax = 0xbb01; - regs.ebx = TCPA_MAGIC; - regs.ecx = 0; - regs.edx = 0; - regs.es = (((grub_addr_t) &incoming) & 0xffff0000) >> 4; - regs.edi = ((grub_addr_t) &incoming) & 0xffff; - regs.ds = (((grub_addr_t) &outgoing) & 0xffff0000) >> 4; - regs.esi = ((grub_addr_t) &outgoing) & 0xffff; - - grub_bios_interrupt (0x1a, ®s); - - grub_free(event); - - if (regs.eax) - { - tpm_presence = 0; - return grub_error (GRUB_ERR_IO, N_("TPM error %x, disabling TPM"), regs.eax); - } - - return 0; -} diff --git a/grub-core/loader/i386/pc/linux.c b/grub-core/loader/i386/pc/linux.c index cfff25c21..783a3cd93 100644 --- a/grub-core/loader/i386/pc/linux.c +++ b/grub-core/loader/i386/pc/linux.c @@ -36,7 +36,6 @@ #include #include #include -#include GRUB_MOD_LICENSE ("GPLv3+"); @@ -162,9 +161,6 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)), goto fail; } - grub_tpm_measure (kernel, len, GRUB_BINARY_PCR, "grub_linux16", "Kernel"); - grub_print_error(); - grub_memcpy (&lh, kernel, sizeof (lh)); kernel_offset = sizeof (lh); diff --git a/include/grub/tpm.h b/include/grub/tpm.h index 972a5edc8..ce52be4ff 100644 --- a/include/grub/tpm.h +++ b/include/grub/tpm.h @@ -69,7 +69,7 @@ typedef struct { grub_err_t EXPORT_FUNC(grub_tpm_measure) (unsigned char *buf, grub_size_t size, grub_uint8_t pcr, const char *kind, const char *description); -#if defined (GRUB_MACHINE_EFI) || defined (GRUB_MACHINE_PCBIOS) +#if defined (GRUB_MACHINE_EFI) grub_err_t grub_tpm_execute(PassThroughToTPM_InputParamBlock *inbuf, PassThroughToTPM_OutputParamBlock *outbuf); grub_err_t grub_tpm_log_event(unsigned char *buf, grub_size_t size, diff --git a/grub-core/boot/i386/pc/boot.S b/grub-core/boot/i386/pc/boot.S index acab37369..ea167fe12 100644 --- a/grub-core/boot/i386/pc/boot.S +++ b/grub-core/boot/i386/pc/boot.S @@ -24,14 +24,11 @@ * defines for the code go here */ -#define TPM 1 - /* Print message string */ #define MSG(x) movw $x, %si; call LOCAL(message) #define ERR(x) movw $x, %si; jmp LOCAL(error_message) .macro floppy -#ifndef TPM part_start: LOCAL(probe_values): @@ -88,7 +85,6 @@ fd_probe_error_string: .asciz "Floppy" movb MACRO_DOLLAR(79), %ch jmp LOCAL(final_init) -#endif .endm .macro scratch @@ -256,7 +252,6 @@ real_start: /* set %si to the disk address packet */ movw $disk_address_packet, %si -#ifndef TPM /* check if LBA is supported */ movb $0x41, %ah movw $0x55aa, %bx @@ -276,7 +271,6 @@ real_start: andw $1, %cx jz LOCAL(chs_mode) -#endif LOCAL(lba_mode): xorw %ax, %ax @@ -320,9 +314,6 @@ LOCAL(lba_mode): jmp LOCAL(copy_buffer) LOCAL(chs_mode): -#ifdef TPM - jmp LOCAL(general_error) -#else /* * Determine the hard disk geometry from the BIOS! * We do this first, so that LS-120 IDE floppies work correctly. @@ -434,7 +425,7 @@ setup_sectors: jc LOCAL(read_error) movw %es, %bx -#endif /* TPM */ + LOCAL(copy_buffer): /* * We need to save %cx and %si because the startup code in @@ -457,25 +448,6 @@ LOCAL(copy_buffer): popw %ds popa -#ifdef TPM - pusha - - movw $0xBB00, %ax /* TCG_StatusCheck */ - int $0x1A - test %eax, %eax - jnz boot /* No TPM or TPM deactivated */ - - movw $0xBB07, %ax /* TCG_CompactHashLogExtendEvent */ - movw $GRUB_BOOT_MACHINE_KERNEL_ADDR, %di - xorl %esi, %esi - movl $0x41504354, %ebx /* TCPA */ - movl $0x200, %ecx /* Measure 512 bytes */ - movl $0x8, %edx /* PCR 8 */ - int $0x1A - -boot: - popa -#endif /* boot kernel */ jmp *(LOCAL(kernel_address)) diff --git a/grub-core/boot/i386/pc/diskboot.S b/grub-core/boot/i386/pc/diskboot.S index f4744ec6f..68d31de0c 100644 --- a/grub-core/boot/i386/pc/diskboot.S +++ b/grub-core/boot/i386/pc/diskboot.S @@ -19,8 +19,6 @@ #include #include -#define TPM 1 - /* * defines for the code go here */ @@ -55,21 +53,6 @@ _start: /* this sets up for the first run through "bootloop" */ movw $LOCAL(firstlist), %di -#ifdef TPM - /* clear EAX to remove potential garbage */ - xorl %eax, %eax - /* 8(%di) = number of sectors to read */ - movw 8(%di), %ax - - /* Multiply number of sectors to read with 512 bytes. EAX is 32bit - * which is large enough to hold values of up to 4GB. I doubt there - * will ever be a core.img larger than that. ;-) */ - shll $9, %eax - - /* write result to bytes_to_measure var */ - movl %eax, bytes_to_measure -#endif - /* save the sector number of the second sector in %ebp */ movl (%di), %ebp @@ -307,29 +290,6 @@ LOCAL(copy_buffer): /* END OF MAIN LOOP */ LOCAL(bootit): -#ifdef TPM - pusha - movw $0xBB07, %ax /* TCG_CompactHashLogExtendEvent */ - - movw $0x0, %bx - movw %bx, %es - - /* We've already measured the first 512 bytes, now measure the rest */ - xorl %edi, %edi - movw $(GRUB_BOOT_MACHINE_KERNEL_ADDR + 0x200), %di - - movl $0x41504354, %ebx /* EBX = "TCPA" */ - - /* %ecx = The length, in bytes, of the buffer to measure */ - movl $bytes_to_measure, %esi - movl (%esi), %ecx - xorl %esi, %esi - movl $0x9, %edx /* PCR 9 */ - - int $0x1A - - popa -#endif /* print a newline */ MSG(notification_done) popw %dx /* this makes sure %dl is our "boot" drive */ @@ -364,10 +324,6 @@ geometry_error_string: .asciz "Geom" read_error_string: .asciz "Read" general_error_string: .asciz " Error" -#ifdef TPM -bytes_to_measure: .long 0 -#endif - /* * message: write the string pointed to by %si *