dcavalca / rpms / grub2

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