Trusted Boot

From Gentoo Wiki
Jump to: navigation, search

Trusted Boot is a technology to provide a chain of trust for all the components during boot. In this guide, we introduce this technology and how it can be enabled in Gentoo Linux.

Purpose of Trusted Boot

Introduction

Warning
Using Trusted Boot on your system is currently only recommended for development purposes.

This guide will introduce Dynamic root-of-trust using Intel's TXT to support measuring the booted kernel and initramfs before it is loaded. The measured values are extended into the TPM chip so that values can be sealed and unsealed within it.

Dynamic vs Static Root of Trust

Trusted boot relies on having a Root of Trust that all the rest relies on. Originally there was a Static Root of Trust in which each component measured the next component in the chain. This method is fickle because if anything at all changes in the bios setup or boot chain then the PCR values will end up different and difficult to predict.

Dynamic Root of Trust instead uses Intel's Trusted Execution Technology to reset to a known state during boot.

TPM Platform Configuration Registers

The TPM Chip is an integral part of Trusted Boot. The important part are the Platform Configuration Registers (PCRs), special registers that can not be set, only extended with another measurement. A TPM usually has 23 PCRs, which are reset to zero during boot and after that point, are extended. An extend operation works like:

CODE An extend operation
New PCR value = SHA1( Old PCR value . SHA1( New Measurement to be Extended ) )

TPM chips support bind and seal operations. Binding means that the data is encrypted using a key only found within the TPM and cannot be extracted. Sealing is like binding but data will only be unencrypted if the PCRs are the same values as when the data was sealed. Sealing will be very useful for our purposes.

The Big Fat Warnings

Using Trusted Boot on your system is currently only recommended for development purposes. Gentoo Hardened is working on integrating Trusted Boot properly, so please be aware that a value sealed with TPM PCRs can only be unsealed if the PCR values are exactly the same as when sealing. Make sure you have a backups of all the data and other ways to unlock your machine if the TPM will not unseal the data.

Setting up Trusted Boot

Kernel configuration

First of all, enable Intel TXT in the Linux kernel configuration. Intel TXT is supported in the main tree since 2.6.38.

KERNEL Linux kernel configuration for Trusted Boot
CONFIG_ACPI=y
CONFIG_INTEL_IOMMU=y
CONFIG_INTEL_IOMMU_DEFAULT_ON=y
CONFIG_INTEL_TXT=y

BIOS configuration

Reboot and enter your BIOS setup, look for an enable any options about VT-x, VT-d, Intel TXT. The TPM must also be set to Active, Enabled in some bios setups means that the chip is visible to the OS but cannot be used.

If using UEFI boot instead of Legacy, CSM or Compatibility Support Module needs to be enabled. The tboot program is not an EFI binary and appears not to work without CSM enabled.

After this reboot like normal and check dmesg to make sure the IOMMU is enabled:

root #dmesg | grep -i iommu
[    0.000000] Intel-IOMMU: enabled
[    0.041149] dmar: IOMMU 0: reg_base_addr fed90000 ver 1:0 cap c0000020660462 ecap f0101a
[    0.041167] dmar: IOMMU 1: reg_base_addr fed91000 ver 1:0 cap d2008020660462 ecap f010da
[    0.041314] IOAPIC id 2 under DRHD base  0xfed91000 IOMMU 1
[    0.658096] tboot: Forcing Intel-IOMMU to enabled
[    0.658176] IOMMU 0 0xfed90000: using Queued invalidation
[    0.658179] IOMMU 1 0xfed91000: using Queued invalidation
[    0.658184] IOMMU: Setting RMRR:
[    0.658200] IOMMU: Setting identity map for device 0000:00:02.0 [0xdd800000 - 0xdf9fffff]
[    0.658482] IOMMU: Setting identity map for device 0000:00:14.0 [0xdaac1000 - 0xdaad7fff]
[    0.658518] IOMMU: Setting identity map for device 0000:00:1d.0 [0xdaac1000 - 0xdaad7fff]
[    0.658542] IOMMU: Prepare 0-16MiB unity mapping for LPC
[    0.658555] IOMMU: Setting identity map for device 0000:00:1f.0 [0x0 - 0xffffff]

Install the software

root #emerge -av tboot

This will install tboot and its dependencies TrouSerS and tpm-tools. TrouSerS will install some udev rules for the tpm /dev node, you must either make udev re-read its rules or just reboot now.

Taking Ownership of the TPM

Next, we have to setup the TPM:

root #/etc/init.d/tcsd start
root #tpm_takeownership -y -z

This will take ownership of the TPM chip using the well known password for both the Owner and SRK passwords. We will change the owner password later on, this is just for testing the initial parts.

Intel TXT SINIT module

Intel TXT requires an SINIT module that is signed by Intel and trusted by the CPU. The module for your specific CPU must be downloaded from: https://software.intel.com/en-us/articles/intel-trusted-execution-technology

Download, extract and copy the SINIT module into /boot/.

Grub config

root #mount /boot/
root #grub2-mkconfig -o /boot/grub/grub.cfg

At this point, rebooting and choosing the tboot option should start like normal using the default launch control policy.

Checking the PCR values

root #find /sys -name pcrs -exec cat {} \;
PCR-00: 32 92 01 6D CF D3 5E 57 2B 20 B9 84 BD 2F E9 65 16 0B 73 7F 
PCR-01: FD 5C 64 0B 90 A8 8C 9D A8 0A D3 DD DC 31 90 4E 78 E6 7C AB 
PCR-02: 45 6B 2C 1E 90 94 2D 55 EA 24 58 ED 04 2A FA 0E A0 9B 0A 4E 
PCR-03: B2 A8 3B 0E BF 2F 83 74 29 9A 5B 2B DF C3 1E A9 55 AD 72 36 
PCR-04: 50 B0 99 06 08 7C F6 CB CC DC 3C 1C F3 5E 63 51 65 0E BA 48 
PCR-05: 45 A3 23 38 2B D9 33 F0 8E 7F 0E 25 6B C8 24 9E 40 95 B1 EC 
PCR-06: EE 1B 0F 99 7D 75 17 B2 86 BC 9D 73 A4 CF 74 2C 65 A7 69 BE 
PCR-07: B2 A8 3B 0E BF 2F 83 74 29 9A 5B 2B DF C3 1E A9 55 AD 72 36 
PCR-08: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 
PCR-09: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 
PCR-10: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 
PCR-11: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 
PCR-12: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 
PCR-13: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 
PCR-14: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 
PCR-15: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 
PCR-16: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 
PCR-17: C4 97 E4 AA FF ED 57 69 2A E3 31 A8 E7 DC BB DE 6F FB 5A 52 
PCR-18: D9 95 C2 48 4E 2A 27 D3 47 B1 19 87 4F C4 58 EB 8C E0 44 A0 
PCR-19: 23 A1 15 D8 79 CB 7F 34 B4 5B 25 99 FE 21 2C 5D 33 F4 5A E6 
PCR-20: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 
PCR-21: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 
PCR-22: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 
PCR-23: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 

PCRs 0-7 are used by the static root of trust measurements and PCR 17-19 are used by Intel TXT. If Intel TXT is not launched, PCR 17-23 would be filled with FF instead of reset to 0 and extended with measurements.

root #txt-stat
Intel(r) TXT Configuration Registers:
	STS: 0x00018091
	    senter_done: TRUE
	    sexit_done: FALSE
	    mem_config_lock: FALSE
	    private_open: TRUE
	    locality_1_open: TRUE
	    locality_2_open: TRUE
	ESTS: 0x00
	    txt_reset: FALSE
	E2STS: 0x000000000000000e
	    secrets: TRUE
	ERRORCODE: 0x00000000
	DIDVID: 0x00000001b0028086
	    vendor_id: 0x8086
	    device_id: 0xb002
	    revision_id: 0x1
	FSBIF: 0xffffffffffffffff
	QPIIF: 0x000000009d003000
	SINIT.BASE: 0xdcf00000
	SINIT.SIZE: 131072B (0x20000)
	HEAP.BASE: 0xdcf20000
	HEAP.SIZE: 917504B (0xe0000)
	DPR: 0x00000000dd000041
	    lock: TRUE
	    top: 0xdd000000
	    size: 4MB (4194304B)
	PUBLIC.KEY:
	    2d 67 dd d7 5e f9 33 92 66 a5 6f 27 18 95 55 ae 
	    77 a2 b0 de 77 42 22 e5 de 24 8d be b8 e3 3d d7 

***********************************************************
	 TXT measured launch: TRUE
	 secrets flag set: TRUE
***********************************************************

The senter_done: TRUE and ERRORCODE: 0x00000000 are the important parts that shows Intel TXT was launched correctly and we are in a secure envrionment.

Setting the Launch Control Policy

The Launch Control Policy is used by the SINIT so control launching into the TXT environment. It controls which Measured Launch Environment (MLE, tboot in this case), PCRs are allowed. It also can contain the Verified Launch Policy which tboot will use later to verify the kernel and initrd.


The LCP can contain one or more policy lists which contain one or more policy elements. The policy lists can be signed or unsigned. We will use signed lists because the value extended into PCR18 will be the hash of the public key instead of the hash of the whole policy. This means policy upgrades will leave PCR18 unchanged so any sealed values are still accessible.


root ## Policy element for MLE
root ## $CMDLINE_TBOOT should be the arguments that are passed to tboot on the grub commandline
root #lcp_mlehash -c "$CMDLINE_TBOOT" /boot/tboot.gz > mle_hash
root #lcp_crtpolelt --create --ctrl 0x01 --type mle --minver 17 --out mle.elt mle_hash
root ## Policy element for PCRs
root #egrep "^PCR-00" /sys/class/tpm/tpm0/device/pcrs > pcrs.txt
root #lcp_crtpolelt --create --ctrl 0x01 --type pconf --out pconf.elt pcrs.txt


Next create the Verified Launch Policy that tboot will use to verify the kernel and initrd. --ctrl 0x00 disables the EXTEND_PCR_17 flag, which means that tboot will not extend the hash of the first module into PCR18. With that flag set, tboot will always extend the hash of the first module into PCR18. If another PCR is specified as well, that pcr will be extended in addition to pcr18. Instead we extend the kernel and initrd into pcr19/20 and leave pcr18 untouched. This means kernel upgrades will not break anything sealed to PCR18.


root ## Create the Verified Launch Policy
root #tb_polgen --create --ctrl 0x00 --type continue vl.pol
root ## $CMDLINE_KERNEL should be the arguments that are passed to the kernel
root #tb_polgen --add --num 0 --pcr 19 --hash image --cmdline "$CMDLINE_KERNEL" --image /boot/vmlinuz-"$KVERS" vl.pol
root #tb_polgen --add --num 1 --pcr 20 --hash image --cmdline "" --image /boot/initramfs-genkernel-x86_64-"$KVERS" vl.pol
root #lcp_crtpolelt --create --ctrl 0x01 --type custom --out vl.elt --uuid tboot vl.pol


Put all the elements into a policy list, sign the list then make the policy and data. Policies with type list (as opposed to ANY) need to have a separate list.data because the TPM can not store all the data.


root #lcp_crtpollist --create --out list_unsig.lst mle.elt pconf.elt vl.elt
root #cp list_unsig.lst list_sig.lst
root #lcp_crtpollist --sign --pub pubkey.pem --priv privkey.pem --out list_sig.lst
root #lcp_crtpol2 --create --ctrl 0x00 --type list --pol list.pol --data list.data list_sig.lst


Make sure the required indexes are defined in the TPM:


root ## define the error index
root #tpmnv_defindex -i 0x20000002 -s 8 -pv 0 -rl 0x07 -wl 0x07 -p $OWNER_PASSWORD
root ## define the TXT launch control policy locality
root #tpmnv_defindex -i owner -s 0x36 -p $OWNER_PASSWORD


The list.pol has to be written to the TPM index for the LCP. If using a signed list policy, the list.pol will be unchanged between versions so later upgrades will only require copying list.data to /boot. Make sure /etc/default/grub-tboot contains: GRUB_TBOOT_POLICY_DATA='list.data'


root ## write list.pol into the TPM
root #lcp_writepol -i owner -f list.pol -p $OWNER_PASSWORD
root #cp list.data /boot/list.data
root #grub2-mkconfig -o /boot/grub/grub.cfg

Sealing data in the TPM

The following will seal something with the TPM to pcr18. You must have backups of the cleartext because if PCR18 changes or the TPM is reset, there is no way of decrypting the data again.

root #tpm_sealdata -z -p18 -i unencrypted.txt -o sealed.bin


Unsealing the data again can only be done when the PCR is the same as when originally sealed with the following command:

root #tpm_unsealdata -z -i sealed.bin -o output_unencrypted.txt

Changing the well-known-password

As the tcsd is the only portal to access the TPM, you have always to start the Trusted Core Service Daemon before altering any information.

root #/etc/init.d/tcsd start
root #tpm_changeownerauth -z -s -o
Enter new SRK password: 
Confirm password: 
Enter new owner password: 
Confirm password: 

This will change the passwords for both the Owner and SRK (Storage Root Key).