Blame SOURCES/0231-drop-TPM-support-for-legacy-BIOS.patch

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