TQ
dev.com

Blog about software development

Subscribe

LUKS with USB unlock

21 Jan 2022 - by 'Maurits van der Schee'

I feel that using full disk encryption of laptops is a must. Not to protect against attacks with physical access (to the unencrypted boot loader or unprotected BIOS), but to avoid leaking data when the laptop is either lost or stolen. Entering a long passphrase is not very convenient, especially when you are sharing the device with multiple people. This post will explain how to unlock your computer by inserting a USB drive containing a key file, while still allowing to unlock using a passphrase. At the end of the post we describe how to conveniently hide the USB drive in Windows and Linux.

USB keys for LUKS disk encryption

Instructions

I have tested the below steps on Ubuntu 22.04 and these are expected to be correct for any recent Debian based distribution.

1) Install the "uuid" tool

sudo apt install uuid

2) Create a random key name using the "uuid" tool:

uuid

will show a random UUID, mine was:

85125e5e-7bc4-11ec-afea-67650910c179

3) Create a 256 byte key file with random data (.lek = LUKS Encryption Key):

dd if=/dev/urandom bs=1 count=256 > 85125e5e-7bc4-11ec-afea-67650910c179.lek

4) Insert a USB drive. It gets mounted somewhere in "/media", let's find it:

lsblk

will show that the 16GB USB stick is mounted as "/media/maurits/B54D-B744":

NAME                   MAJ:MIN RM   SIZE RO TYPE  MOUNTPOINT
sdb                      8:0    1  14,7G  0 disk  
└─sdb1                   8:1    1  14,7G  0 part  /media/maurits/B54D-B744
...

5) Copy the key file to the USB drive:

cp 85125e5e-7bc4-11ec-afea-67650910c179.lek /media/maurits/B54D-B744

6) Find the encrypted volume:

sudo blkid --match-token TYPE=crypto_LUKS -o device

will show:

/dev/sda3

5) Add the key file to the LUKS volume:

sudo cryptsetup luksAddKey /dev/sda3 85125e5e-7bc4-11ec-afea-67650910c179.lek

This does not affect the existing hand-entered passphrase from the installer (in slot 0).

6) Delete the key file (it is loaded in LUKS and copied to the USB drive):

rm 85125e5e-7bc4-11ec-afea-67650910c179.lek

7) Edit /etc/crypttab. You should see a line like:

sda3_crypt UUID=b9570e0f-3bd3-40b0-801f-ee20ac460207 none luks,discard

Modify it to:

sda3_crypt UUID=b9570e0f-3bd3-40b0-801f-ee20ac460207 85125e5e-7bc4-11ec-afea-67650910c179 luks,discard,keyscript=/bin/luksunlockusb

8) Add a script that will search for the key on USB drives during boot:

cat << "END" > luksunlockusb
#!/bin/sh
set -e
if [ ! -e /mnt ]; then
    mkdir -p /mnt
    sleep 3
fi
for usbpartition in /dev/disk/by-id/usb-*-part1; do
    usbdevice=$(readlink -f $usbpartition)
    if mount -t vfat $usbdevice /mnt 2>/dev/null; then
        if [ -e /mnt/$CRYPTTAB_KEY.lek ]; then
            cat /mnt/$CRYPTTAB_KEY.lek
            umount $usbdevice
            exit
        fi
        umount $usbdevice
    fi
done
/lib/cryptsetup/askpass "Insert USB key and press ENTER: "
END

9) Make the script executable and move it to the right location:

chmod 755 luksunlockusb
sudo mv luksunlockusb /bin/luksunlockusb

10) Debian 11 only, add some modules to the /etc/initramfs-tools/modules file:

vfat
nls_cp437
nls_ascii
usb_storage

11) Include the "luksunlockusb" script (and modules) in the initial ram file system using:

sudo update-initramfs -u

12) Done. Reboot and enjoy!

Note that next to inserting the USB drive you can still enter the old passphrase during the boot even though the script has changed the prompt.

Creating a hidden partition

In order to hide the USB drive (prevent the partition from mounting in Linux and Windows) you can create a new GPT partition table on the USB drive and add only a bootable EFI Startup Partition (ESP) to hold your keys. This partition must be the first partition on the drive and have a minimum size of 16 megabytes. Technically it may contain any other content and may be followed by one or more partitions of any type. I prefer to leave them with only this single hidden partition as it prevents (non-technical) people from using the USB stick as a drive (I use key shaped USB drives). You can find some of my scripts on my GitHub:

https://github.com/mevdschee/bitlocker-luks-tools

The boot process explained

When using LUKS you need an unencrypted partition (boot partition) to read the initial ram file system (initrd) and kernel image (vmlinuz) from. This will show the screen in which a passphrase for decryption of the encrypted disk is asked. This two-staged boot process can be altered to do other things as well. In today's post I have shown how to scan USB drives for a keyfile and in a previous post I have shown how to add a simple SSH server.

Avoid leaking data in case of hardware theft

In security the exercise of trying to identify security risks and rank them based on their damage and likeliness is called "threat modelling". In may on situations with laptops a large risk with considerable damage is hardware theft or otherwise lost devices. Full disk encryption will protect you against leaking data in this relative likely event, reducing the damages considerably.

Links


PS: Liked this article? Please share it on Facebook, Twitter or LinkedIn.