dcavalca / rpms / grub2

Forked from rpms/grub2 3 years ago
Clone

Blame SOURCES/0129-Add-BIOS-boot-measurement.patch

d9d99f
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
d9d99f
From: Matthew Garrett <mjg59@coreos.com>
d9d99f
Date: Sun, 9 Aug 2015 15:48:51 -0700
d9d99f
Subject: [PATCH] Add BIOS boot measurement
d9d99f
d9d99f
Measure the on-disk grub core on BIOS systems - unlike UEFI, the firmware
d9d99f
can't do this stage for us.
d9d99f
---
d9d99f
 grub-core/boot/i386/pc/boot.S     | 30 +++++++++++++++++++++++++-
d9d99f
 grub-core/boot/i386/pc/diskboot.S | 44 +++++++++++++++++++++++++++++++++++++++
d9d99f
 2 files changed, 73 insertions(+), 1 deletion(-)
d9d99f
d9d99f
diff --git a/grub-core/boot/i386/pc/boot.S b/grub-core/boot/i386/pc/boot.S
d9d99f
index ea167fe1206..c1df86dec0b 100644
d9d99f
--- a/grub-core/boot/i386/pc/boot.S
d9d99f
+++ b/grub-core/boot/i386/pc/boot.S
d9d99f
@@ -24,11 +24,14 @@
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
@@ -85,6 +88,7 @@ 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
@@ -252,6 +256,7 @@ 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
@@ -271,6 +276,7 @@ real_start:
d9d99f
 
d9d99f
 	andw	$1, %cx
d9d99f
 	jz	LOCAL(chs_mode)
d9d99f
+#endif
d9d99f
 
d9d99f
 LOCAL(lba_mode):
d9d99f
 	xorw	%ax, %ax
d9d99f
@@ -314,6 +320,9 @@ 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
@@ -425,7 +434,7 @@ setup_sectors:
d9d99f
 	jc	LOCAL(read_error)
d9d99f
 
d9d99f
 	movw	%es, %bx
d9d99f
-
d9d99f
+#endif /* TPM */
d9d99f
 LOCAL(copy_buffer):
d9d99f
 	/*
d9d99f
 	 * We need to save %cx and %si because the startup code in
d9d99f
@@ -448,6 +457,25 @@ 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
+	popa
d9d99f
+#endif
d9d99f
+boot:
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 68d31de0c4c..f4744ec6fcb 100644
d9d99f
--- a/grub-core/boot/i386/pc/diskboot.S
d9d99f
+++ b/grub-core/boot/i386/pc/diskboot.S
d9d99f
@@ -19,6 +19,8 @@
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
@@ -53,6 +55,21 @@ _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
@@ -290,6 +307,29 @@ 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
@@ -324,6 +364,10 @@ 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
  *