Home Unlock LUKS using YubiKey on Debian Bookworm
Post
Cancel

Unlock LUKS using YubiKey on Debian Bookworm

Introduction

If you own a YubiKey from yubico and you are running Debian Linux this should be right guide for you. YubiKeys are USB tokens that act like keyboards and generate one-time or static passwords. This guide will cover only LUKS passphrase generated by YubiKey 5, which will be static. Thus, the security relies on the fact that nobody can extract the key from the YubiKey. There are some ways to try to change LUKS after each login, but those are experimental and I need to explore them more before writing anything on it.

Encrypting your data in this age of mobile computing (notebook, mobile, etc) is a absolute necessity. With every additional layer of protection comes a certain degree of discomfort for the users. On one hand you have security point of view, on second hand you have user comfort. YubiKey presents a good compromise between those two.

What is often forgotten, is the fact that with the higher security levels there is more pressing need for software and hardware backups. If you plan on using YubiKey I highly recommend you having multiple YubiKeys (best having the same firmware) or alternative way to unlock your encrypted LUKS. There should also be a backup/restore plan in place! You have been warned!

YubiKey firmware

Funny is how nearly nobody talks about YubiKey’s firmware, yet it defines set of features you will be able to use. If you buy your YubiKey you are stuck with the firmware version you have forever - Here is the official announcement. What are the firmware differences? I will not go to great detail here, I will have separate post on YubiKey firmware(s) as this post would get too long. What I wanted to say is, please make sure your YubiKey firmware supports the features you need and want! If not, return it and request one with newer firmware.

Plugging the YubiKey into USB for the first time

The OS should recognize your YubiKey when plugged in:

1
2
3
4
5
6
7
8
9
10
...
[ 2609.593744] usb 1-2.1.1: new full-speed USB device number 12 using xhci_hcd
[ 2609.721175] usb 1-2.1.1: New USB device found, idVendor=1050, idProduct=0407, bcdDevice= 5.12
[ 2609.721190] usb 1-2.1.1: New USB device strings: Mfr=1, Product=2, SerialNumber=0
[ 2609.721197] usb 1-2.1.1: Product: YubiKey OTP+FIDO+CCID
[ 2609.721201] usb 1-2.1.1: Manufacturer: Yubico
[ 2609.740366] input: Yubico YubiKey OTP+FIDO+CCID as /devices/pci0000:00/0000:00:14.0/usb1/1-2/1-2.1/1-2.1.1/1-2.1.1:1.0/0003:1050:0407.000A/input/input38
[ 2609.798622] hid-generic 0003:1050:0407.000A: input,hidraw2: USB HID v1.10 Keyboard [Yubico YubiKey OTP+FIDO+CCID] on usb-0000:00:14.0-2.1.1/input0
[ 2609.800283] hid-generic 0003:1050:0407.000B: hiddev0,hidraw3: USB HID v1.10 Device [Yubico YubiKey OTP+FIDO+CCID] on usb-0000:00:14.0-2.1.1/input1
...

The key, YubiKey 5, details:

1
2
3
4
idVendor           0x1050 Yubico.com
idProduct          0x0407 Yubikey 4/5 OTP+U2F+CCID
iManufacturer           1 Yubico
iProduct                2 YubiKey OTP+FIDO+CCID

Installation on Debian

Required packages

sudo apt install yubikey-personalization yubikey-luks yubikey-manager

  • yubikey-personalization - CLI personalization tools (ykchalresp, ykinfo, ykpersonalize)for YubiKey OTP tokens. This is a tool to customize the tokens with your own cryptographic key, user id and so on.
  • yubikey-luks - YubiKey two factor authentication for LUKS disks. With this extension to the initramfs-tools, you can lock/unlock a LUKS encrypted disk (yubikey-luks-enroll, yubikey-luks-open) using your YubiKey as a second factor.
  • yubikey-manager - Python library and command line tool for configuring a YubiKey YubiKey Manager (ykman) is a command line tool for configuring a YubiKey over all transports. It is capable of reading out device information as well as configuring several aspects of a YubiKey, including enabling or disabling connection transports and programming various types of credentials.

Optional package

sudo apt install yubikey-personalization-gui

  • yubikey-personalization-gui - Install if you need GUI tool for YubiKeys. You can customize the token with your own cryptographic key and options.

YubiKey tools

ykinfo - key details

ykinfo tell you the firmware version and some technical details about the key, like what key slot is used:

1
2
3
4
5
6
7
8
9
10
11
12
ykinfo -a

serial: <serial_number>
serial_hex: <serial_number_hex>
serial_modhex: <serial_number_modhex>
version: 5.1.2
touch_level: 1538
programming_sequence: 2
slot1_status: 0
slot2_status: 1
vendor_id: 1050
product_id: 407

-a switch gets you all information

One can find ykinfo bug tracker at yubikey-personalization should you find any bugs or need some feature. At Yubico one can find a table where you can match YubiKey firmware to ykinfoversion compatibility.

Most of the parameters are self-explanatory, but for those that are not, I will dig deeper in separate post as this should focus on using YubiKey on LUKS.

ykman - features enabled

To get features supported/enabled on the device use the ykman tool:

Here are my YubiKey features:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
ykman --device <serial_number> info

Device type: YubiKey 5 NFC
Serial number: <serial_number>
Firmware version: 5.1.2
Form factor: Keychain (USB-A)
Enabled USB interfaces: OTP, FIDO, CCID
NFC transport is enabled.

Applications	USB          	NFC          
FIDO2       	Enabled      	Enabled      	
OTP         	Enabled      	Enabled      	
FIDO U2F    	Enabled      	Enabled      	
OATH        	Enabled      	Enabled      	
YubiHSM Auth	Not available	Not available	
OpenPGP     	Enabled      	Enabled      	
PIV         	Enabled      	Disabled   

You can find ykman bug tracker at yubikey-manager should you find any bugs or need some feature. All the parameters here are pretty much self-explanatory.

LUKS encryption

Partitions overview

I’m using LUKS encryption on lvm2 members which have ext4 or swap. Since I have newer notebook with UEFI I have to have the /boot and /boot/efi partitions in order to boot properly. Those are unencrypted. There maybe some ways to have everything encrypted, but for simplicity I want to have it this way.

  • the vfat nvme0n1p1 is for /boot/efi
  • the ext2 for nvme0n1p2 is for /boot
  • the LUKS encrypted nvme0n1p3 contains:
    • physical volume(PV) is nvme0n1p3_crypt
    • volume group(VG) is magnetron-vg
    • with logical volumes(LV) are root, swap and home.

Here is a my drive layout:

1
2
3
4
5
6
7
8
9
10
11
lsblk --fs

NAME                       FSTYPE      FSVER    LABEL UUID                                   FSAVAIL FSUSE% MOUNTPOINTS
nvme0n1                                                                                                     
├─nvme0n1p1                vfat        FAT32          9DE1-20E0                               507.6M     1% /boot/efi
├─nvme0n1p2                ext2        1.0            dff5333f-dcde-4884-a09a-68ad7ff0029b    249.9M    42% /boot
└─nvme0n1p3                crypto_LUKS 2              db0ad5e8-a3fb-4570-bea1-3f1fb93407e4                  
  └─nvme0n1p3_crypt        LVM2_member LVM2 001       izpVno-gqNl-7ur7-O60V-I5a7-5hdt-INEmmE                
    ├─magnetron--vg-root   ext4        1.0            c495f72d-4219-4d38-afca-5a517b121b25    103.5G    14% /
    ├─magnetron--vg-swap   swap        1              d78aaa73-3760-4f66-9549-72a85fe2c43d                  [SWAP]
    └─magnetron--vg-home   ext4        1.0            672b53ba-ee76-4583-ad24-95517e015788    300.7G    26% /home

Preparing the YubiKey for use with LUKS

The ykpersonalize is the Yubico tool for configuring your Yubikey. Before the new configuration of the YubiKey make sure you have all the previous keys backed up!

The YubiKey has two slots. The first slot is, according to the manual, used for the “true OTP generation” which is not the case here. So the slot number 2 is to be used for the encryption key here.

ykpersonalize -2 -ochal-resp -ochal-hmac -ohmac-lt64 -oserial-api-visible

This command will show the following message will be displayed:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
Firmware version 5.2.4 Touch level 1280 Unconfigured

Configuration data to be written to key configuration 2:

fixed: m:
uid: n/a
key: h:XX11XX78985XXd4aXX885cXX557f90eXX261fXXX
acc_code: h:000000000000
OATH IMF: h:0
ticket_flags: CHAL_RESP
config_flags: CHAL_HMAC|HMAC_LT64
extended_flags: SERIAL_API_VISIBLE

Commit? (y/n) [n]: y

The command switches explained (man pages):

-2 use the second slot. This is for YubiKey II only and is then normally used for static key generation. In this configuration, the option flags -oappend-cr, -ostatic-ticket, -ostrong-pw1, -ostrong-pw2 and -oman-update are set by default.

-ochal-resp “challenge-response” mode, the mode we want to configure for logins.

-ochal-hmac This is our “message authentication code” for the challenge. Message authentication codes are used for providing integrity to a message. HMAC uses a hash function (for example SHA-1) for calculating a hash of our message and an outer and inner pad. The outer and inner pads are just constants, that are added to the stream on different moments during the hash calculation. If you want to read more about HMAC, you can do this here: https://tools.ietf.org/html/rfc2104

-ochmac-lt64 This means we calculate the HMAC on less than 64 bytes input.

-oserial-api-visible The Yubikey will allow its serial number to be read using an API call.

Adding YubiKey to LUKS encrypted drive

The LUKS encryption is able to have up to 7 different keys to unlock it.

  • To check current state of your LUKS encryption you do the luksDump on it:
    sudo cryptsetup luksDump /dev/nvme0n1p3

  • To see how many keyslots you are using:
    sudo cryptsetup luksDump /dev/nvme0n1p3 | grep luks

If you are using password only for unlocking you should simply get 0: luks2, where 0 is the key-slot position.

  • To add a key to second key-slot. You will have to enter your original password which was used previously to unlock the encrypted hard-drive section:
    sudo cryptsetup luksAddKey --key-slot 2 /dev/nvme0n1p3

Terminal will display:

1
2
3
Enter any existing passphrase: <original_password>
Enter new passphrase for key slot: <new_password>
Verify passphrase: <confirm_new_password>
  • If you perform the luksDump with grep luks again you should see the second key-slot occupied:
    sudo cryptsetup luksDump /dev/nvme0n1p3 | grep luks
1
2
0: luks2
2: luks2
  • To enroll the YubiKey into the LUKS:
    sudo yubikey-luks-enroll -c -s 2 -d /dev/nvme0n1p3

Terminal will display:

1
2
3
4
5
6
7
8
9
10
11
12
clearing slot
setting slot to 2.
setting disk to /dev/nvme0n1p3.
This script will utilize slot 2 on drive /dev/nvme0n1p3.  If this is not what you intended, exit now!
Killing LUKS slot 2
Enter any remaining passphrase: <original_password>

Adding yubikey to initrd
Please enter the yubikey challenge password. This is the password that will only work while your yubikey is installed in your computer: <new_password>
Please enter the yubikey challenge password again: <confirm_new_password>

Please provide an existing passphrase. This is NOT the passphrase you just entered, this is the passphrase that you currently use to unlock your LUKS encrypted drive: <original_password>

Switches explained:

1
2
3
4
-c     Clear the chosen LUKS slot at first.
-s     The LUKS slot to save the passphrase to. (default: 7)
-d     The disk device to work with (default: /dev/sda3)

System changes needed in order to boot/unlock your system with YubiKey

  • You need to make sure that your /etc/crypttab is done correctly Here is overview of mine:
1
2
3
4
5
6
7
batcat /etc/crypttab 
───────┬────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
       │ File: /etc/crypttab
       │ Size: 127 B
───────┼────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
   1   │ nvme0n1p3_crypt UUID=db0ad5e8-a3fb-3240-bea1-3f1fb93407e4 none luks,keyscript=/usr/share/yubikey-luks/ykluks-keyscript,discard
───────┴────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
  • Make sure your initramfs is updated with the new setup (you don’t need this step if your initramfs was already updated):
    sudo update-initramfs -u

Note on YubiKey challenge during boot

If the YubiKey is plugged in at the moment when the system is asking for password, it will not recognize the YubiKey! The usb device list will be updated only after the password is entered. The password needs to be input again or just plugin the YubiKey before booting your notebook.

Further YubiKey/LUKS exploration

  • Improve security by changing LUKS key after each login (remove the static LUKS passphrase generated by YubiKey)
  • Explore firmware YubiKey revisions
  • Look into the details of ykinfo parameters and what they actually mean
This post is licensed under CC BY 4.0 by the author.