FIDO2 (YubiKey) to unlock LUKS from command line

Following the example of how to add a FIDO2 key from a YubiKey, but I can’t figure out how to use the YubiKey to unlock it form the command line. The instructions talk about unlocking at boot–but that’s not what I want.

Setup

Make a 128 MiB file, make it a block device on loop0 and setup LUKS.

$ dd if=/dev/urandom of=disk.bin bs=1M count=128 
128+0 records in
128+0 records out
134217728 bytes (134 MB, 128 MiB) copied, 0.534038 s, 251 MB/s
$ losetup /dev/loop0 disk.bin 
$ cryptsetup luksFormat -y /dev/loop0

WARNING!
========
This will overwrite data on /dev/loop0 irrevocably.

Are you sure? (Type 'yes' in capital letters): YES
Enter passphrase for temp.bin: 
Verify passphrase: 

Add the Yubikey.

$ systemd-cryptenroll /dev/loop0 --fido2-device=auto  --fido2-with-client-pin=yes
  Please enter current passphrase for disk /dev/loop0: ****                    
Requested to lock with PIN, but FIDO2 device /dev/hidraw9 does not support it, disabling.
Initializing FIDO2 credential on security token.
  (Hint: This might require confirmation of user presence on security token.)
Generating secret key on FIDO2 security token.
  In order to allow secret key generation, please confirm presence on security token.
New FIDO2 token enrolled as key slot 1.

Remove the the non-FIDO2 key.

$ cryptsetup -q -v luksKillSlot /dev/loop0 0
Keyslot 0 is selected for deletion.
Key slot 0 removed.
Command successful.

Problem

Now what? This doesn’t work:

$ cryptsetup open /dev/loop0 loop0_encrypted
Enter passphrase for disk.bin:

I now have a LUKS disk but I don’t know how to unlock it. All tutorials I found say to make modifications to /etc/crypttab and give instructions for mounts at boot. I want to mount without rebooting and (preferably) without modifying /etc/crypttab. What am I missing?

Asked By: A. Que

||

Using systemd-cryptenroll to set up the encryption suggests that you need a similar tool of the systemd family to unlock it.

Turns out it is essentially Example 3 in the systemd-specific version of the crypttab(5) man page.

sudo /usr/lib/systemd/systemd-cryptsetup attach loop0_encrypted /dev/loop0 - fido2-device=auto

The equivalent /etc/crypttab entry would be:

loop0_encrypted /dev/loop0 - fido2-device=auto

Note that for example, on Debian 12, the crypttab(5) man page says:

ON DIFFERENT CRYPTTAB FORMATS

Please note that there are several independent cryptsetup wrappers with their own crypttab format. This manpage covers Debian’s implementation for initramfs scripts and SysVinit init scripts. systemd brings its own crypttab implementation. We try to cover the differences between the systemd and our implementation in this manpage, but if in doubt, better check the systemd crypttab(5) manpage, e.g. online at https://www.freedesktop.org/software/systemd/man/crypttab.html.

Answered By: telcoM

When configuring the FIDO2 security token to require a PIN it conflicts with regular LUKS passphrase entry, since both are entered on the host via keyboard. The option --token-only is used to indicate that a PIN will be entered, instead of a passphrase, and passed to the (here presumed single) security token.

sudo cryptsetup open --token-only /dev/loop0 loop0_encrypted

Using --token-only is simple enough for manual FIDO2+PIN usage, such as when connecting external disks/USB sticks, etcetera. Having cryptsetup automatically switch to PIN entry when there are no passphrase slots does sound like a reasonable usability improvement though. (TODO: update answer if default behavior changes.)


Tested using cryptsetup v2.6.1 (tagged 2023-02-09); available in Debian 12 (Bookworm), Ubuntu 23.04 (Lunar Lobster), Fedora F38, etcetera.

From the upstream cryptsetup open docs. (Emphasis mine.)

If there is valid LUKS2 token but it requires PIN to unlock assigned keyslot, it is not used unless one of following options is added: --token-only,
--token-type where type matches desired PIN protected token or --token-id with id matching PIN protected token.

Debian 12 man page. (Emphasis mine.)

--token-only
Do not proceed further with action if token based keyslot unlock failed. Without the option, action asks for passphrase to proceed further.

It allows LUKS2 tokens protected by PIN to take precedence over interactive keyslot passphrase prompt.

Answered By: Joel Purra
Categories: Answers Tags: ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.