Skip to content
This repository has been archived by the owner on Sep 18, 2020. It is now read-only.

Commit

Permalink
Add BIOS boot measurement
Browse files Browse the repository at this point in the history
Measure the on-disk grub core on BIOS systems - unlike UEFI, the firmware
can't do this stage for us.
  • Loading branch information
Matthew Garrett committed Jan 5, 2016
1 parent f22ee44 commit 1e32d63
Show file tree
Hide file tree
Showing 2 changed files with 73 additions and 1 deletion.
30 changes: 29 additions & 1 deletion grub-core/boot/i386/pc/boot.S
Expand Up @@ -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):
Expand Down Expand Up @@ -85,6 +88,7 @@ fd_probe_error_string: .asciz "Floppy"
movb MACRO_DOLLAR(79), %ch

jmp LOCAL(final_init)
#endif
.endm

.macro scratch
Expand Down Expand Up @@ -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
Expand All @@ -274,6 +279,7 @@ real_start:

andw $1, %cx
jz LOCAL(chs_mode)
#endif

LOCAL(lba_mode):
xorw %ax, %ax
Expand Down Expand Up @@ -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.
Expand Down Expand Up @@ -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
Expand All @@ -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))

Expand Down
44 changes: 44 additions & 0 deletions grub-core/boot/i386/pc/diskboot.S
Expand Up @@ -19,6 +19,8 @@
#include <grub/symbol.h>
#include <grub/machine/boot.h>

#define TPM 1

/*
* defines for the code go here
*/
Expand Down Expand Up @@ -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

Expand Down Expand Up @@ -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 */
Expand Down Expand Up @@ -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
*
Expand Down

0 comments on commit 1e32d63

Please sign in to comment.