You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
402 lines
10 KiB
402 lines
10 KiB
2 years ago
|
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||
|
From: Javier Martinez Canillas <javierm@redhat.com>
|
||
|
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 <javierm@redhat.com>
|
||
|
---
|
||
|
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 <grub/err.h>
|
||
|
-#include <grub/i18n.h>
|
||
|
-#include <grub/mm.h>
|
||
|
-#include <grub/tpm.h>
|
||
|
-#include <grub/misc.h>
|
||
|
-#include <grub/i386/pc/int.h>
|
||
|
-
|
||
|
-#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 <grub/lib/cmdline.h>
|
||
|
#include <grub/linux.h>
|
||
|
#include <grub/efi/sb.h>
|
||
|
-#include <grub/tpm.h>
|
||
|
|
||
|
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 <grub/symbol.h>
|
||
|
#include <grub/machine/boot.h>
|
||
|
|
||
|
-#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
|
||
|
*
|