From 7b86bd724c9fb0870d2b23e5e4740718da9d3964 Mon Sep 17 00:00:00 2001 From: Michael Preisach Date: Mon, 29 Jun 2020 11:04:18 +0200 Subject: [PATCH] Add detailed description of the current function --- README.md | 69 ++++++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 68 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 5f731f2..c41c002 100644 --- a/README.md +++ b/README.md @@ -1,3 +1,70 @@ # trustedboot -This is a description how to enable full disk encryption where the key is managed by a tpm. \ No newline at end of file +The utility installs a Disk encryption key in the TPM and unencrypts the disk automatically during boot. +The settings for trusted boot differ for the various Linux distros and releases. +This version is tested for Ubuntu 20.04 LTS. It requires TPM-Tools 4.x as the parameters completely changed from 3.x + +## Usage +1. Install Ubuntu 20.04 with Full Disk Encryption. +1. Execute install.sh +2. Reboot the machine, you will still be asked for your encryption passphrase +3. Update the TPM PCR policy with update-luks-tpm.sh +4. The next reboot is done automatically + +## Result +- Grub is still installed, but not used (as a fallback) +- The initial key for Disk Encryption is still valid (fallback for updates) +- Initramfs is updated with the script to ask the TPM for the passphrase +- A unified kernel is generated (kernel + command line parms + initramfs) as one large EFI blob +- Therefore during Boot only PCRs 0-7 are written (GRUB uses 8-9) + +## Details / manual installation +Ideas taken from +- https://threat.tevora.com/secure-boot-tpm-2/ +- https://medium.com/@pawitp/full-disk-encryption-on-arch-linux-backed-by-tpm-2-0-c0892cab9704 +- https://medium.com/@pawitp/its-certainly-annoying-that-tpm2-tools-like-to-change-their-command-line-parameters-d5d0f4351206 + +I used the PCRs 0,1,4,5,7 as policy for unlocking disk encryption. The PCRs 2,3 and 6 have the same hash value and are therefore assumed as empty. +For additional security reasons, one may consider including these registers as well (to prevent e.g. Option ROM DMA attacks). +Furthermore I use the RNG on the TPM for secret generation and use SHA256 and ECC instead of SHA1 and RSA. + +All of the below instructions should be executed as root: +1. Install required tools +`apt install binutils tpm2-tools` +1. Create a new secret for disk encryption: +`tpm2_getrandom 32 -o /root/secret.bin` +2. Add the key to disk encryption +`cryptsetup luksAddKey /dev/nvme0n1p3 /root/secret.bin` +3. Install the tpm-script to initramfs +`cp -vf ./tpm2-hook.sh /etc/initramfs-tools/hooks/` +4. The entry in /etc/crypttab should look like this: +`dm_crypt-0 UUID= none luks,discard,initramfs,keyscript=/usr/sbin/passphrase-from-tpm.sh` +5. Update initramfs +`update-initramfs -u -k all` +6. Create the Kernel Command Line +`echo "/vmlinuz-5.4.0-39-generic root=/dev/mapper/ubuntu--vg-ubuntu--lv ro" > /boot/kernel-command-line.txt` +6. Create unified Kernel +``` +mkdir -p /boot/efi/EFI/Linux +objcopy \ + --add-section .osrel="/usr/lib/os-release" --change-section-vma .osrel=0x20000 \ + --add-section .cmdline="/boot/kernel-command-line.txt" --change-section-vma .cmdline=0x30000 \ + --add-section .linux="/boot/vmlinuz-$VERSION" --change-section-vma .linux=0x40000 \ + --add-section .initrd="/boot/initrd.img-$VERSION" --change-section-vma .initrd=0x3000000 \ + "/usr/lib/systemd/boot/efi/linuxx64.efi.stub" "/boot/efi/EFI/Linux/Linux.efi" +``` +7. Create a EFI Boot entry for the new unified kernel +`efibootmgr --create --disk /dev/nvme0n1 --part 1 --label "ubuntu unified" --loader "\EFI\BOOT\Linux\Linux.efi" --verbose` +8. Reboot the machine +9. Store the secret key in the TPM and use the now valid PCRs as policy +``` +tpm2_evictcontrol -C o -c 0x81000000 #evict an old passphrase before writing the new one +tpm2_createpolicy --policy-pcr -l sha256:0,1,4,5,7 -L /root/policy.digest +tpm2_createprimary -C e -g sha256 -G ecc256 -c /root/primary.context +tpm2_create -g sha256 -u /root/obj.pub -r /root/obj.priv -C /root/primary.context -L /root/policy.digest -a "noda|adminwithpolicy|fixedparent|fixedtpm" -i /root/secret.bin +tpm2_load -C /root/primary.context -u /root/obj.pub -r /root/obj.priv -c /root/load.context +tpm2_evictcontrol -C o -c /root/load.context 0x81000000 +# tpm2_unseal -c 0x81000000 -p pcr:sha1:0,1,4,5,7 -o /root/test.bin #proof that the persistence worked +rm -f /root/load.context /root/obj.priv /root/obj.pub /root/policy.digest /root/primary.context +``` +10. The next reboot should work automatically