Skip to content

The guide to set up full chain of verified secure boot on some Linux distros using Unified Kernel Image and TPM2 chip

Notifications You must be signed in to change notification settings

iokanto/linux-secureboot-guide

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

4 Commits
 
 
 
 
 
 
 
 

Repository files navigation

This guide describe how set up system with detached LUKS header, Unified Kernel Image (UKI), Secure Boot with own keys and tpm2-totp in Devuan 5 (Debian 12) without systemd!

Now until disk partition setup system via install media

Partitioning:

Disks after setup will be similar this:

/dev/sda - main storage
/dev/sdb - usb stick with ESP (/boot/efi), LUKS header partition

Make ESP (/boot/efi) and LUKS header partitions in /dev/sdb

parted -s /dev/sdb mklabel gpt
parted -s -a optimal /dev/sdb mkpart "EFI System Partition" "fat32" "0%" "1024MiB"
parted -s -a optimal /dev/sdb mkpart "primary" "ext4" "1024MiB" "1040MiB"
parted -s /dev/sdb set 1 esp on

Make / (root) encrypted partition in /dev/sda

parted -s /dev/sda mklabel gpt
parted -s -a optimal /dev/sda mkpart "primary" "ext4" "0%" "50%"
parted -s /dev/sda set 1 lvm on

Setup encryption in main storage with detached LUKS header: (Ensure that is optimal config for selected algorithms: cryptsetup benchmark)

dd if=/dev/zero of=/tmp/header.img bs=16M count=1
cryptsetup luksFormat --offset 32768 --header /tmp/data.img --type luks2 --cipher twofish-xts-plain64 --key-size 512 --hash sha512 --pbkdf argon2id --iter-time 3000 --verify-passphrase /dev/sda1
cryptsetup open --header /tmp/data.img /dev/sda1 sda1_crypt

Setup LVM on LUKS

pvcreate /dev/mapper/sda1_crypt
vgcreate devuan-vg /dev/mapper/sda1_crypt

lvcreate -L 2G devuan-vg --name swap
lvcreate -l 100%FREE devuan-vg --name root
lvreduce -L -256M devuan-vg/root

Setup mount points, remove names of partiotions and install system from setup manager. (If ESP mounting error, try partitioning USB from setup manager)

Setup mounting LUKS when USB is inserted

  • Write /tmp/header.img to /dev/sdb2 (because it's probably unpossible mount with LUKS header as file, need mount with LUKS header as partition)
    dd if=/tmp/data.img of=/dev/sdb2
    
  • Write to /etc/crypttab
    sda1_crypt    /dev/disk/by-id/[part which symbol link to /dev/sda1]    none    luks,header=/dev/disk/by-uuid/[part which symbol link to /dev/sdb2]
    

Follow install steps until ending setup, without GRUB install!

UKI (without Secure Boot integration):

Plug-in and mount another drive/USB stick with scripts from this repo for fast configuring and mount it to /mnt

mount /dev/sdc /mnt

Update APT preferences

./mnt/linux-secureboot-guide/system/update-apt

Add initramfs scripts

./mnt/linux-secureboot-guide/hardening/uki/install-initramfs-scripts

In /etc/fstab add to /boot/efi line noauto param for not mounting partition after start

Unmount drive

umount /mnt

Install packages to target system for generating EFI stub

in-target sh -c "apt update"
apt-install systemd-ukify systemd-boot-efi efibootmgr

Update initramfs via

in-target sh -c "update-initramfs -u"

Check if all right and reboot in new system: Now press end setup in installation media and reboot in installed system

Setup Secure Boot:

At this step you already booted in instaled system. If all OK now configure Secure Boot, first you should enable 'Setup Mode' in UEFI settings.

Caution

Perform all actions in this section at your own peril and risk, because incorrect execution can lead to a breakdown of the device!

All manipulations with Secure Boot keys were made on a device with a video chip built into the processor, on other (and even similar) devices, the inclusion of Secure Boot with a discriminated video card can lead to a black screen!

Look for more information on the network.

Install packages for generating keys and work with UEFI vars

sudo apt install efitools sbsigntool uuid-runtime
sudo rc-update del uuidd
sudo rc-service uuidd stop

Generate keys and store them encrypted on USB drive and in dir

sudo /mnt/linux-secureboot-guide/hardening/secureboot/efi-mkkeys -e -s "My OWN keys!" -o /tmp/keys/

Now in /tmp/keys appears *.key (private keys), *.crt (public keys), *.cer (public keys in DER format), *.esl (UEFI certs for enrolling in 'Setup Mode'), *.auth (singed UEFI certs for enrolling in 'User Mode')

In theory you can just enrolling generated keys without cat with existings, but for reliability, it is better to combine them with existing ones. For example, here is an example of combining your DB keys with Microsoft keys:

In system has this keys

  • Trust Certificate - PK key, used to sign KEK keys
  • Microsoft Corporation KEK CA 2011 - KEK key, used to sign db, dbx updates from Windows OS
  • Microsoft Corporation KEK 2K CA 2023 - KEK key, see above
  • Microsoft Windows Production PCA 2011 - db key, used to load Windows OS
  • Windows UEFI CA 2023 - db key, used to load Windows OS (?) but not only (?)

There is no keys, that may be used for load UEFI/other firmware, but for first time maybe usefull cat db with only cert 'Windows UEFI CA 2023'

Cat generated db.esl with 'Windows UEFI CA 2023'

openssl x509 -in /mnt/MicWinUEFICA2023.der -inform DER -out /tmp/MicWinUEFICA2023.pem -outform PEM
cert-to-efi-sig-list -g "$(cat /tmp/keys/guid.txt)" /tmp/MicWinUEFICA2023.pem /tmp/MicWinUEFICA2023.esl
cat /tmp/keys/db.esl /tmp/MicWinUEFICA2023.esl > /tmp/keys/dbMicWinUEFICA2023.esl
sign-efi-sig-list -t "$(cat /tmp/keys/timestamp.txt)" -a -k /tmp/keys/KEK.key -c /tmp/keys/KEK.crt db /tmp/keys/dbMicWinUEFICA2023.esl /tmp/keys/dbMicWinUEFICA2023.auth

Enroll keys to UEFI via efi-updatevar command in 'Setup Mode' (i.e. *.esl certs) (PK key ALWAYS MUST BE ADDED LAST!!)

sudo efi-updatevar -a -e -f db.esl db
sudo efi-updatevar -a -e -f KEK.esl KEK
sudo efi-updatevar -f PK.auth PK

If all OK, now we can delete all files in /tmp/keys, except *.key, *.crt, *.txt

rm -iv /tmp/keys/{*.cer,*.esl,*.auth}

Encrypt private keys via openssl

cd /tmp/keys
read -r -s pass
for name in PK KEK db; do
    printf '%s\n' "$pass" \
        | openssl rsa -aes256 -passout stdin -in "$name.key" -out "$name.key.enc"
    mv "$name.key.enc" "$name.key"
done
unset pass

Make correct rights to private/public keys and move them to another place

sudo mkdir -p /usr/share/keyrings/efi/
sudo mv /tmp/keys/* /usr/share/keyrings/efi/
sudo chown -R root /usr/share/keyrings/efi/*
sudo chgrp -R root /usr/share/keyrings/efi/*
sudo chmod 0600 /usr/share/keyrings/efi/*
sudo chmod 0600 /usr/share/keyrings/efi/

Now you can edit /usr/local/sbin/generate-uki and enable generating singed UKI images

tpm2-totp:

Install depends

sudo apt install git build-essential autoconf autoconf-archive automake m4 libtool pkg-config libqrencode-dev tpm2-tss-engine-dev --no-install-recommends

Now download and build tpm2-totp

git clone https://github.com/tpm2-software/tpm2-totp
cd tpm2-totp

# Apply patch that add support for initramfs-tools systems without plymouth
patch -p1 < /mnt/linux-secureboot-guide/hardening/tpm2/tpm2-totp_add-custom-secret_33e1986.patch
patch -p1 < /mnt/linux-secureboot-guide/hardening/tpm2/tpm2-totp_add-initramfs-support_33e1986.patch

./bootstrap
./configure --sysconfdir=/etc
make check
sudo make install
sudo ldconfig

Add script for correct resealing secrets

sudo /mnt/linux-secureboot-guide/hardening/tpm2/install-tpm2-totp-reseal

Update initramfs to integrate tpm2-totp in initrd

sudo update-initramfs -u

Setup tpm2-totp and generate TOTP secret

Note

After every updating UEFI/UEFI settings (including boot entries)/GPT partition/updating initramfs need reseal secret via

tpm2-totp -P - reseal

If occurs error like '0x90006 - mu:A buffer is not enough large' after reseal command, that you should clean and init tpm2-totp again after every NEW initramfs LOADED (e.g. update kernel -> update-initramfs -> reboot system -> clean/init new totp code)

Or simply use this for generating/resealing secret

tpm2-totp-reseal

This config should allowing load in normal/recovery mode without altering about changed TPM PCR's state

sudo tpm2-totp -P - -b SHA256 -p 0,1,2,3,4,5,7,9,11,13,14 init

Done! On boot it's show TOTP code, which should be equvivalent to code on phone

Sources:

  1. Partitioning

  2. LUKS

  3. UKI

  4. Secure Boot

  5. TPM

  6. Guides

    1. Secure boot

    2. Complete (UKI + Secure boot + LUKS)

About

The guide to set up full chain of verified secure boot on some Linux distros using Unified Kernel Image and TPM2 chip

Topics

Resources

Stars

Watchers

Forks

Languages