FreeBSD TPM2.0 support
Early boot process
From: https://www.freebsd.org/doc/handbook/boot-introduction.html
Stage One and Stage Two
Conceptually, the first and second stages are part of the same program on the same area of the disk. Because of space constraints, they have been split into two, but are always installed together. They are copied from the combined /boot/boot by the FreeBSD installer or bsdlabel.
These two stages are located outside file systems, in the first track of the boot slice, starting with the first sector. This is where boot0, or any other boot manager, expects to find a program to run which will continue the boot process.
The first stage, boot1, is very simple, since it can only be 512 bytes in size. It knows just enough about the FreeBSD bsdlabel, which stores information about the slice, to find and execute boot2.
Stage two, boot2, is slightly more sophisticated, and understands the FreeBSD file system enough to find files. It can provide a simple interface to choose the kernel or loader to run. It runs loader, which is much more sophisticated and provides a boot configuration file.
So boot1 is equivalent of MBR code and boot2 is a simple command line interface to load kernel directly or a 3rd stage loader.
Stage Three
The loader is the final stage of the three-stage bootstrap process. It is located on the file system, usually as /boot/loader.
The loader is intended as an interactive method for configuration, using a built-in command set, backed up by a more powerful interpreter which has a more complex command set. Looks like stage three loader seem to be an equivalent of GRUB or other bootloader.
Last stage
Kernel is loaded. It examines for boot flags and adjusts its behavior:
Option | Description |
---|---|
-a | During kernel init, ask the device to mount as the rootfs. |
-C | Boot the root file system from a CDROM. |
-s | Boot into single-user mode. |
-v | Be more verbose during kernel startup. |
Once the kernel has finished booting, it passes control to the user process
init(8), which is located at /sbin/init, or the program path specified in the
init_path
variable in loader. This is the last stage of the boot process.
TPM support information
From investigating the source, there is very little code for TPM 2.0 interaction. Also no information found on mailing lists about TPM 2.0 support in early boot process, verification, measurements etc. The only message found was related to tpm2-tools compatibility in FreeBSD.
However I have found an interesting mail with guide to trusted gptboot
(tgptboot
). gptboot
is a part of standard FreeBSD boot path that connects
legacy MBR and GPT partitioning and tgptboot
is its hardened version.
First of all BIOS measures the PMBR (Protective Master Boot Record) code. Then
PMBR measure freebsd-boot
partition (most likely the stage two and/or stage
three) and hand control over to trusted gptboot.
tgptboot:
- select UFS partition (take gptboot(8) attributes into account)
- get KEY from TPM NVRAM
- get DATA_PATH from TPM NVRAM
- read and decrypt DATA at DATA_PATH using KEY
- set kernel environment (if specified in DATA)
- load and checksum kernel and modules (path, size and hash in DATA)
- load disk keys (if specified in DATA)
- execute kernel
https://lists.freebsd.org/pipermail/freebsd-hackers/2015-March/047376.html
Unfotunately it utilizes TPM1.2 only. The status of tgptboot development still needs to be researched.