You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
Michael Preisach 65ca3b1498 add EUPL license 4 years ago
LICENSE add EUPL license 4 years ago
README.md add EUPL license 4 years ago
create-luks-tpm.sh add EUPL license 4 years ago
install.sh add EUPL license 4 years ago
kernel-command-line.txt removing version number of the command line params 4 years ago
passphrase-from-tpm.sh add EUPL license 4 years ago
tpm2-hook.sh add EUPL license 4 years ago
update-kernel.sh add EUPL license 4 years ago
update-luks-tpm.sh add EUPL license 4 years ago

README.md

trustedboot

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

Prerequisities

Tested system: Ubuntu 20.04 LTS with encrypted root partition. Required additional packages:

  • binutils (for objcopy, generating unified Kernel)
  • tpm2-tools
  • auditd (for logging syscalls of processes)
  • attr (for accessing security.ima file attribute)

Usage

  1. Install Ubuntu 20.04 with Full Disk Encryption with the additional packages.
  2. Execute install.sh
  3. Reboot the machine, you will still be asked for your encryption passphrase
  4. Update the TPM PCR policy with update-luks-tpm.sh
  5. During the next reboot the encrypted disk will be opened 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)
  • IMA is activated and stores hashes for every accessed file. To enforce IMA, the kernel parameter should be set to ima_appraise=enforce. Attention! When IMA file hashes are not available, this option breaks the boot process and ends up in a Kernel panic!

Details / manual installation of Trusted Boot

Ideas taken from

I used the PCRs 0-7 as policy for unlocking disk encryption. The PCRs 2,3 and 6 have the same hash value and are therefore not used. However these PCRs are included 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

  2. Create a new secret for disk encryption: tpm2_getrandom 32 -o /root/keys/fde-secret.bin

  3. Add the key to disk encryption cryptsetup luksAddKey /dev/nvme0n1p3 /root/keys/fde-secret.bin

  4. Create a primary key in the Endorsement Hierarchy mkdir -p /root/keys && tpm2_createprimary -C e -g sha256 -G ecc256 -c /root/keys/e-primary.context

  5. Install the tpm-script to initramfs cp -vf ./tpm2-hook.sh /etc/initramfs-tools/hooks/

  6. The entry in /etc/crypttab should look like this: dm_crypt-0 UUID=<uuid> none luks,discard,initramfs,keyscript=/usr/sbin/passphrase-from-tpm.sh

  7. Update initramfs update-initramfs -u -k all

  8. Create the Kernel Command Line echo "/vmlinuz-5.4.0-39-generic ima_appraise=fix ima_policy=appraise_tcb ima_policy=tcb ima_hash=sha256 root=/dev/mapper/ubuntu--vg-ubuntu--lv ro rootflags=i_version"

  9. 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-5.4.0-39-generic" --change-section-vma .linux=0x40000 \
  --add-section .initrd="/boot/initrd.img-5.4.0-39-generic" --change-section-vma .initrd=0x3000000 \
  "/usr/lib/systemd/boot/efi/linuxx64.efi.stub" "/boot/efi/EFI/Linux/Linux.efi"
  1. 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
  2. Reboot the machine
  3. 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,2,3,4,5,6,7 -L /root/keys/pcr-policy.digest
tpm2_create -g sha256 -u /root/keys/obj.pub -r /root/keys/obj.priv -C /root/keys/e-primary.context -L /root/keys/pcr-policy.digest -a "noda|adminwithpolicy|fixedparent|fixedtpm" -i /root/keys/fde-secret.bin
tpm2_load -C /root/keys/e-primary.context -u /root/keys/obj.pub -r /root/keys/obj.priv -c /root/keys/load.context
tpm2_evictcontrol -C o -c /root/keys/load.context 0x81000000
# tpm2_unseal -c 0x81000000 -p pcr:sha1:0,1,2,3,4,5,6,7 -o /root/keys/test.bin #proof that the persistence worked
rm -f /root/keys/load.context /root/keys/obj.priv /root/keys/obj.pub /root/keys/pcr-policy.digest
  1. The next reboot should work without manual disk decryption

Integrity Measurement Architecture (IMA)

References for IMA:

Attention! The above Docs are written for different versions of IMA and the Linux Kernel. Some tools are not available/working on Ubuntu 20.04.

Manual installation

To enable IMA, the Kernel needs the corresponding parameters as follows:

  • ima_appraise=
    • off - no files are checked
    • log - just log all measures files in the IMA log.
    • fix - save the file hash of each accessed file to the file attribute 'security.ima' (used)
    • enforce - only files with a valid 'security.ima' file hash can be accessed.
  • ima_policy= (more than one policy possible, kernel uses union of all policies)
    • appraise_tcb - appraises all files owned by root (used)
    • tcb - measures all executables run, all memory mapped files for execution (such as shared libraries), all Kernel modules loaded, all firmware loaded, and all files opened for read by root. (used)
    • secure_boot - appraises all loaded modules, firmware, kexec'd Kernel, and IMA policies. It also requires them to have an IMA signature as well. This is normally used with the CONFIG_INTEGRITY_TRUSTED_KEYRING option in the Kernel in "secure boot" scenario, with the public key obtained from the OEM in firmware or via the MOK (Machine Owner Key) in shim.
  • ima_hash= (used hash algorithm
    • sha1 (default)
    • sha256 (used)
    • sha512
    • ...
  • ima_template=
    • ima-ng (used)
      • template_hash=sha1(filedata-hash length, filedata-hash, pathname length, pathname)
      • filedata_hash=sha256(filedata)
    • ima-sig
      • template_hash=sha1(filedata-hash length, filedata-hash, pathname length, pathname)
      • filedata_hash=sha256(filedata)
      • append signature if present
    • ima
      • template_hash=sha1(filedata-hash, filename-hint)
      • filedata_hash=sha1(filedata)
  • rootflags=i_version - files are only measured when they are updated on the file system.

IMA file attributes

The IMA log is a virtual file in /sys/kernel/security/ima/ascii_runtime_measurements. All hashes in this file are backed as a hash chain in PCR 10.

As long as ima_apprais=fix is set, hashes of all accessed files are saved as extended file attribute. To view all extended attributes of a file use:

getfattr -m - -d /path/to/file

IMA sets security.ima with the file hash

Set IMA to enforcing

  1. For enforcing IMA, every file must be hashed. This can be done with (will take about an hour):
time find / -fstype ext4 -type f -uid 0 -exec dd if='{}' of=/dev/null count=0 status=none \; #Gentoo recommendation
  1. In /boot/kernel-command-line.txt the Kernel parameter ima_appraise=fix can be set to ima_appraise=enforce.
  2. Update the unified Kernel image with update-kernel.sh
  3. Reboot

Syscall logging with auditd

auditd is able to log every single syscall of a process.

  1. autrace [-r] /path/to/executable -with -args
  2. When the executable is finished, it returns a pid number
  3. ausearch -i -p <pid> > /path/to/auditlog saves then the complete audit log to a file.
  4. find all accessed files with
grep -Eo "=/[[:graph:]/]*" /path/to/auditlog | grep -Eo "/[[:graph:]/]*" | sort | uniq > /path/to/fileaccesslog

LICENSE

Licensed under the EUPL, Version 1.2 or – as soon they will be approved by the European Commission - subsequent versions of the EUPL (the "Licence"). You may not use this work except in compliance with the Licence.

License: European Union Public License v1.2