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!
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.
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
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.
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.
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
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.
To get features supported/enabled on the device use the
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.
I’m using LUKS encryption on lvm2 members which have
swap. Since I have newer notebook with UEFI I have to have the
/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
- the ext2 for
- the LUKS encrypted
- 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
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.
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
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
- 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
grep luksagain you should see the second
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>
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)
- You need to make sure that your
/etc/crypttabis 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
initramfsis updated with the new setup (you don’t need this step if your
initramfswas already updated):
sudo update-initramfs -u
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.
- 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
ykinfoparameters and what they actually mean