The wikis are now using the new authentication system.
If you did not migrate your account yet, visit https://idp-portal-info.suse.com/

SDB:LUKS2, TPM2 and FIDO2

Jump to: navigation, search


Tested on openSUSE

Recommended articles

Icon-manual.png

Related articles

Icon-help.png

Warning: This document describes some Proof of Concepts. The final implementation is subject to change.

Situation

This article describes how to perform:

  • Disk encryption using Linux Unified Key Setup version 2 (LUKS2).
  • Disk decryption using Trusted Platform Module version 2.0 (TPM2) or Fast Identity Online version 2.0 (FIDO2).
Warning: FIDO2 tokens need to implement the hmac-secret extension.

Procedure

Current tooling:

  • yast2 4.4.20
  • cryptsetup 2.4.1
  • grub 2.0.6
  • systemd v249
  • dracut 055

With these package versions we can apply the following scenarios:

Unencrypted boot partition

This scenario derives from the current approach to Full Disk Encrytion (FDE) with LUKS1: kernel and initrd worldwide readable.

The key is not stored in the initrd; the unlock is done via systemd-cryptsetup.

This is the most flexible approach, in terms of FIDO2, TPM2 and different algorithms. Here grub would not be involved in the decryption process itself.

Encryption using LUKS2

EFI disk layout example:

lsblk /dev/sda
NAME          MAJ:MIN RM  SIZE RO TYPE  MOUNTPOINT
sda           253:0    0   32G  0 disk  
├─sda1        253:1    0  512M  0 part  /boot/efi    (EFI)
├─sda2        253:2    0    2G  0 part  /boot        (btrfs)
└─sda3        253:3    0 29,5G  0 part  
  └─cr-auto-1 254:0    0 29,5G  0 crypt /            (btrfs)

Steps:

  1. Boot into a Live ISO.
  2. Get the disk you want to partition (e.g. with lsblk).
  3. Create the GPT disk layout (e.g. with gdisk).
  4. Encrypt the partition that will contain the root filesystem.
    # cryptsetup luksFormat -y -v --type luks2 /dev/sda3
  5. Boot using the installation media and install openSUSE using the partitions already created (Expert Partitioner), keeping the LUKS2 encryption when prompted by YaST2.

Notes:

  • These steps could be omitted when YaST2 gains LUKS2 support.

Decryption using TPM2

Steps:

  1. Install the TPM2 tools.
    # zypper install tpm2.0-tools
  2. Enroll the LUKS2 volume with TPM device.
    # systemd-cryptenroll --tpm2-device=auto --tpm2-pcrs=7 /dev/sda3
  3. Find the entry for the LUKS2 volume in /etc/crypttab (it may appear referenced by its UUID) and add the tpm2-device= option.
    cr-auto-1  /dev/sda3  none  x-initrd.attach,tpm2-device=auto
  4. Create a new dracut configuration file /etc/dracut.conf.d/91-tpm2.conf with the following content:
    add_dracutmodules+=" tpm2-tss "
  5. Regenerate the initrd.
    # dracut -f

Notes:

  • Step 4 could be omitted (upstream PR).
  • The enrollment using PCR 7 should not be used on non-EFI systems. See man systemd-cryptenroll for a more detailed explanation of PCR definitions.
  • The problem with changed PCR value still exists, but if the TPM validation fails, the user can unlock the system using a custom password or recovery key and enroll the TPM again with the new PCR value.

Decryption using FIDO2

Steps:

  1. Plug in the FIDO2 token.
  2. Install the libfido2 library.
    # zypper install libfido2-1
  3. Enroll the LUKS2 volume with the FIDO2 device.
    # systemd-cryptenroll --fido2-device=auto /dev/sda3
  4. Find the entry for the LUKS2 volume in /etc/crypttab (it may appear referenced by its UUID) and add the fido2-device= option.
    cr-auto-1  /dev/sda3  none  x-initrd.attach,fido2-device=auto
  5. Create a new dracut configuration file /etc/dracut.conf.d/91-fido2.conf with the following content:
    add_dracutmodules+=" systemd-udevd "
    install_items+=" /usr/lib64/libfido2.so.* /usr/lib64/libcryptsetup.so.* /usr/lib64/libcbor.so.* /usr/lib64/libhidapi-hidraw.so.* "
  6. Regenerate the initrd.
    # dracut -f

Notes:

  • Step 5 could be omitted using a new fido2 dracut module (upstream PR).
  • Missing plymouth implementation: the system is silently waiting for FIDO2 input.
  • If the FIDO2 key is not available and the LUKS2 volume also has a passphrase or recovery key enrolled, the system will need to boot using another initrd without the libfido2 library loaded.

Encrypted boot partition

Warning: This setup is limited to EFI systems.
Warning: With the current state of grub2, we will cannot skip entering the decryption passphrase in the bootloader.

This is the most secure, but also most complex approach.

Encryption using LUKS2

EFI disk layout example:

lsblk /dev/sda
NAME          MAJ:MIN RM  SIZE RO TYPE  MOUNTPOINT
sda           253:0    0   32G  0 disk  
├─sda1        253:1    0  512M  0 part  /boot/efi    (EFI)
├─sda2        253:2    0  128M  0 part  /boot/grub2  (ext2)
└─sda3        253:3    0 31,4G  0 part
  └─cr-auto-1 254:0    0 31,4G  0 crypt /            (btrfs)
Warning: Make sure that Secure Boot is disabled, otherwise you will not be able to load specific modules in grub.

Steps:

  1. Boot into a Live ISO.
  2. Get the disk you want to partition (e.g. with lsblk).
  3. Create the GPT disk layout (e.g. with gdisk).
  4. Encrypt the partition that will contain the root filesystem (grub 2.0.6 only supports pbkdf2 key derivation).
    # cryptsetup luksFormat -y -v --type luks2 --pbkdf pbkdf2 /dev/sda3
  5. Boot using the installation media and install openSUSE using the partitions already created (Expert Partitioner), keeping the LUKS2 encryption when prompted by YaST2.
  6. Boot into a Live ISO (grub2-install does not load modules properly yet, therefore we have to boot back into the live image to fix the bootloader).
  7. Mount all required partitions.
    # cryptsetup luksOpen /dev/sda3 luks-part
    # mount /dev/mapper/luks-part /mnt
    # mount /dev/sda1 /mnt/boot/efi
    # mount /dev/sda2 /mnt/boot/grub2
    # for i in /dev /dev/pts /proc /sys /run; do mount -B $i /mnt$i; done
  8. Change root to the mounted system.
    # chroot /mnt
  9. Install grub2-x86_64-efi.
    # zypper install grub2-x86_64-efi
  10. Install needed LUKS2 modules into grub.
    # grub2-install --target=x86_64-efi --modules="luks2 part_gpt cryptodisk gcry_rijndael pbkdf2 gcry_sha512 btrfs gcry_sha256 gcry_sha1 ext2 luks"
  11. Create the script luks2.sh with the following content:
    #!/bin/bash
    [ $# -lt 1 ] && exit 1
    CONFIG=$(mktemp /tmp/grub-config.XXXXX)
    cat >"$CONFIG" <<EOF
    cryptomount -u "$1"
    set prefix=(hd0,gpt2)
    set root=crypto0
    insmod normal
    normal
    EOF
    grub2-mkimage \
        -p '(hd0,gpt2)' \
        -O x86_64-efi \
        -c "$CONFIG" \
        -o /tmp/image \
        luks2 part_gpt cryptodisk gcry_rijndael pbkdf2 gcry_sha512 btrfs gcry_sha256 gcry_sha1 ext2 luks
    rm "$CONFIG"
  12. Run luks2.sh, passing the UUID of the encrypted root partition without any hyphens '-'. E.g.:
    # ./luks2.sh 4f68bce3e8cd4db196e7fbcaf984b709
  13. Copy new grub image to EFI partition.
    # cp /tmp/image /boot/efi/EFI/opensuse/grubx64.efi
  14. Generate a new grub config file.
    # grub2-mkconfig -o /boot/grub2/grub.cfg

Notes:

  1. grub2 needs to be improved in regards to LUKS2 detection (upstream patches in review).
  2. grub2 can only handle pbkdf2, argon2 will not come any time soon (the patch to allow allocating large chunks of memory dynamically is in review).
  3. grub2-install does not automatically load all required crypto modules yet, so they must be manually specified.

Decryption using TPM2

Notes:

  • grub2 needs support for verifying the TPM value.
  • Possibility to get locked out from the system in case the PCR value changes (e.g. during a firmware upgrade and the new value has not been deployed), also know as PCR fragility (or PCR brittleness).
  • Locked out of btrfs-snapshots in case the PCR-value changed.

Decryption using FIDO2

Notes:

  • The firmware would have to provide the correct USB drivers for the FIDO2 device to access tokens there, otherwise we need to include all required FIDO2 libraries and device port to our grub, which would result in a larger grub image.

See also

External links