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 ykinfo
version 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
withgrep luks
again you should see the secondkey-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 yourinitramfs
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