Skip to content

FreeBSD TPM2.0 support

Early boot process


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.


  • 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

Unfotunately it utilizes TPM1.2 only. The status of tgptboot development still needs to be researched.