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