Yubikey Two-factor Authentication Full-disk Encryption via LUKS

A group called PrivacyIdea have created a little package to add a HMAC-SHA1 challenge-response routine to the initramfs, which means that Ubuntu can query you for a challenge to pass to the Yubikey and then use the response to unlock the LUKS volume. For the most part, I'm following these instructions, with some added comments. The process is actually very easy to do.

I've tested this on Ubuntu 14.04, 16.04 and 18.04; using a Yubikey Neo. It should work with any recent Yubikey, with firmware 2.0+, and with any version of Ubuntu after 14.04. I've also tested Ubuntu 19.04 with a Yubikey 5C, some additional work was needed but it can be made to work. There could also be other hardware HMAC-SHA1 challenge-response devices that this works with, but I'm not aware of any that exist. As always, make sure you have a backup of your data before proceeding - there shouldn't be any issues here, but there's always the chance this will destroy everything on your computer. These instructions come with no warranty.

Update: Since Ubuntu 16.04, the needed packages are in the main repositories and no PPA is needed.

Update: Since Ubuntu 19.04 the software in the main repository seems to be broken after an update to cryptsetup. See my other answer for details on how to work around the problem..

Add a comment if you have questions!


0. Prerequisites

For this to work, you will already have to have LUKS full-disk encryption set up and working. You can do this by selecting the appropriate option when installing Ubuntu. For maximum security, you should have a chosen very strong passphrase during the install. If your passphrase isn't up to scratch, you should change it to a better one before continuing (more detailed instructions here).

The method below will not replace any existing passphrases, but will instead add another passphrase to one of the LUKS slots. Hence if you lose your Yubikey you can still unlock your computer using any existing passphrase - I suggest you make a note of it and hide it away somewhere safe - you will also need it a few times during this procedure. Your new Yubikey challenge passphrase should still be reasonably strong, but doesn't have to be as long as the passphrase you used when installing Ubuntu.


1. Add PrivacyIdea PPA and install package

On Ubuntu 14.04

Open a terminal, and run the following command:

sudo add-apt-repository ppa:privacyidea/privacyidea 

Press Enter when prompted, then run:

sudo apt-get update

Then install the package with:

sudo apt-get install yubikey-luks

On Ubuntu 16.04, 18.04

There is no need for a PPA, you can install the package with:

sudo apt-get install yubikey-luks

On Ubuntu 19.04

See this answer for how to build the yubikey-luks package from source for Ubuntu 19.04.


2. Install Yubikey software

If you are using the HMAC-SHA1 functionality of the Yubikey for something else, you can skip this section. It will erase any configuration in the second Yubikey slot, so don't perform this step if you use HMAC-SHA1 for other purposes with this Yubikey.

You'll need to set up your Yubikey to work with Ubuntu by installing the required software, either from the Yubico PPA on Ubuntu 14.04 or from the main Ubuntu repository on 16.04 and later.

On Ubuntu 14.04

If you have not done so before, add the PPA and install the package with:

sudo add-apt-repository ppa:yubico/stable
sudo apt-get update
sudo apt-get install yubikey-personalization

On Ubuntu 16.04, 18.04 (and later)

sudo apt-get install yubikey-personalization

3. Initialise Yubikey Slot for HMAC-SHA1

Now we need to program the second slot of the Yubikey with a HMAC-SHA1 configuration. This will erase your previous slot configuration, which is empty by default. Again, if you are using HMAC-SHA1 for something else do not issue this command - it will erase your configuration. You can safely use the same secret key inside the Yubikey for this LUKS setup as for your other uses. (For example, with another computer using LUKS+Yubikey).

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

The terminal will display some information about the changes made. You don't need to note this down, but it will show the secret key used by the Yubikey in the HMAC-SHA1 algorithm to calculate the response when given a challenge.


4. Enroll Yubikey to LUKS Slot

Now we will edit the LUKS configuration to append the response from the Yubikey as one of the decryption keys.

The partition that we need to specify depends on whether you are using BIOS or UEFI to boot your machine. For BIOS, the encrypted volume is at /dev/sda5 by default, for UEFI it is at /dev/sda3. You can check this by opening the disks utility and confirming the path of the partition - it should either be sda3 or sda5. NOTE: On newer computers with NVMe disks, the path will be something like /dev/nvme0n1p3.

Run this in a terminal:

sudo yubikey-luks-enroll -d /dev/sda3 -s 7

This will write to slot 7 of the LUKS configuration, follow the prompts in the installer (they vary slightly depending on which version you're running).

Then you're all done! You should be able to reboot your computer, and if your Yubikey is inserted then you can type in your challenge password and use the Yubikey as a second factor to unlock the LUKS partition and boot the system. Once you've decrypted the hard drive you can remove the Yubikey.

If you lose your Yubikey you can still enter your original (hopefully very long) passphrase to decrypt the hard drive, and then you can follow this procedure again to register a new Yubikey.


Changing the encryption challenge passphrase

Changing the password at a later date is quite simple, just use this command to reset the secret key. It is not entirely necessary to reset the secret key, but it won't hurt. Bear in mind that this will destroy the previous secret key, do not do this if you use HMAC-SHA1 for something else with this Yubikey. (For example, with another computer using LUKS+Yubikey).

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

Then, similar to Step 4, above, to enroll a new password into the LUKS key slot, except opt to clear Slot 7 with this command:

sudo yubikey-luks-enroll -d /dev/sda3 -s 7 -c

When prompted to Enter any remaining passphrase, use your backup passphrase - not the Yubikey challenge passphrase. Then enter a new Yubikey challenge passphrase, twice, then finally you will need to enter the backup passphrase one last time.

Now your old Yubikey challenge passphrase has been removed and only your new one will decrypt the hard drive. Your previous backup passphrase will still be the same. You can change that passphrase by following the links in Step 0.


Note on security implications

Adding a Yubikey will add a certain level of security to your system - someone has to know both the challenge passphrase and have your Yubikey to be able to unlock your hard drive (or find your initial passphrase, which you are now using as a backup). However, it is technically feasible for an attacker to decrypt the hard drive if they know your challenge passphrase (for example, by "shoulder surfing" you while you type it in) and can gain access to your Yubikey for only a short time. Using the challenge passphrase they could get the response from the Yubikey and store it, and then use it to decrypt the hard drive at any time without the Yubikey. Or, again if an attacker or a piece of malware knew your passphrase and was able to run code on a machine connected to your Yubikey they could also issue the challenge and store the response. It is therefore still extremely important to be vigilant when entering your challenge passphrase, and to ensure that you always have the Yubikey in a safe location. You should also only ever plug it into a machine that you trust. If you lose track of your Yubikey and suspect someone may have been using it to try to learn the decryption key, perform steps 2 and 3 again to reset the secret key inside the Yubikey and choose a new challenge passphrase. Note that if an adversary has managed to learn one of your passphrases (either the HMAC-SHA1 response from the Yubikey, or your backup) they could make a backup of the LUKS master key, and then use that to decrypt your hard drive even if you change the passphrase in the future. The man page for cryptsetup explains this, look at the luksHeaderBackup section. If you suspect this has happened then you must make an entirely new LUKS volume to protect your data.


Update for Ubuntu 20.04:

Omit 1 and 2 step

Becaue now in Ubuntu 20.04 repo all of the packages are available, so just install yubikey-luks as:

sudo apt install yubikey-luks

Step 3

One thing to concern here, you might want to add a parameter -ochal-btn-trig to the command ykpersonalize.

What does it do? It will wait 15s for button press on YubiKey (ofc if you have a button on yubikey), up2u.

Step 5

When you restart your computer, you won't see a message from /etc/ykluks.cfg, why? Because somehow this script doesn't modify a /etc/crypttab.

Okey, so now we have to modify a /etc/crypttab, to add: keyscript=/usr/share/yubikey-luks/ykluks-keyscript,

How it might looks like before modification?

cat /etc/crypttab  
[partition] UUID=1b2c1618-dc62-4d32-ab30-ebc23cb28cea none luks,discard

Your partition can be anything, fe: sda3_crypt, even if you have your system on sdb don't worry, ignore it.

How it might looks like after modification?

cat /etc/crypttab  
[partition] UUID=1b2c1618-dc62-4d32-ab30-ebc23cb28cea none luks,keyscript=/usr/share/yubikey-luks/ykluks-keyscript,discard

Just add part with keyscript.

VERY IMPORTANT: Don't miss the COMMA between options, because you will screw the config.

VERY IMPORTANT v2: Before next step, validate the keyscript path, check if you have this file, if not, idk sorry.

Step 6:

sudo update-initramfs -u

Credits

Knowledge shared from: https://infosec-handbook.eu/blog/yubikey-luks/

And that's it, you are welcome.


Update for Ubuntu 19.04:

It seems like as of Ubuntu 19.04 (and maybe 18.10, I didn't try that release), cryptsetup has changed just enough to break how yubikey-luks used to work. This commit from the upstream repository seems to implement a fix, but the original repository doesn't seem to have been updated since October 2018. I found this fork of the repo which has the fix, as well as a few other bits of tidying-up, and managed to build a package which works on 19.04.

Since I couldn't find an existing build of the updated fork, the method for getting yubikey-luks working involves getting the source code and building the DEB package locally, then installing it.

Follow the steps in my previous answer, except replace step 1 with the below:


1. Fetch yubikey-luks source, build and install package

Install build dependencies with:

sudo apt install dh-exec devscripts expect yubikey-personalization

Then download and extract the source archive:

mkdir ~/tmp
cd ~/tmp
wget -O yubikey-luks.zip https://github.com/thuandt/yubikey-luks/archive/master.zip
unzip yubikey-luks.zip
cd yubikey-luks-*

Build the package with:

make builddeb NO_SIGN=1

Then install it:

sudo dpkg -i DEBUILD/yubikey-luks_*.deb

Then continue following the remainder of the steps in my first answer.

Hopefully by 19.10 the version of yubikey-luks in the main Ubuntu archive can be updated so that manually building isn't required.

As a bonus, the newer version has a configuration file, which can be found at /etc/ykluks.cfg. The message shown on boot can be configured in this file.