From 1e32d63145bd1eab33da7866dc34eb8d246ba212 Mon Sep 17 00:00:00 2001 From: Matthew Garrett Date: Sun, 9 Aug 2015 15:48:51 -0700 Subject: [PATCH] Add BIOS boot measurement Measure the on-disk grub core on BIOS systems - unlike UEFI, the firmware can't do this stage for us. --- grub-core/boot/i386/pc/boot.S | 30 ++++++++++++++++++++- grub-core/boot/i386/pc/diskboot.S | 44 +++++++++++++++++++++++++++++++ 2 files changed, 73 insertions(+), 1 deletion(-) diff --git a/grub-core/boot/i386/pc/boot.S b/grub-core/boot/i386/pc/boot.S index 2bd0b2d28..4c63247e8 100644 --- a/grub-core/boot/i386/pc/boot.S +++ b/grub-core/boot/i386/pc/boot.S @@ -24,11 +24,14 @@ * 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): @@ -85,6 +88,7 @@ fd_probe_error_string: .asciz "Floppy" movb MACRO_DOLLAR(79), %ch jmp LOCAL(final_init) +#endif .endm .macro scratch @@ -255,6 +259,7 @@ 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 @@ -274,6 +279,7 @@ real_start: andw $1, %cx jz LOCAL(chs_mode) +#endif LOCAL(lba_mode): xorw %ax, %ax @@ -317,6 +323,9 @@ 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. @@ -428,7 +437,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 @@ -451,6 +460,25 @@ 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 + + popa +#endif +boot: /* 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 1ee4cf5b2..3a324ea74 100644 --- a/grub-core/boot/i386/pc/diskboot.S +++ b/grub-core/boot/i386/pc/diskboot.S @@ -19,6 +19,8 @@ #include #include +#define TPM 1 + /* * defines for the code go here */ @@ -58,6 +60,21 @@ _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 @@ -295,6 +312,29 @@ 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 */ @@ -329,6 +369,10 @@ 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 *