i recently set up my laptop with a new install of gentoo linux. i’ve been using gentoo for years, but not on my laptop recently.
since encryption was no issue back then i had to get myself up to speed with cryptsetup and initramfs, which you can build yourself in gentoo. there is an option via genkernel to do this automatically, but where is the fun in that?
my basic setup includes two partitions. sda1 is boot, sda2 contains a crypt device, which contains the root partition and the user’s home partition in a lvm container.
this post is about cryptsetup and the method i use to swap the password for the container on every bootup with a cycling challenge response provided by the yubikey. let’s get to it!
the yubikey is a hardware token that looks like a usb stick. it has no moving parts and is very robust. it has a user button which triggers one time passwords. having inserted the yubikey into a usb slot it emulates a keyboard and enters the password. i’ve been keeping it on my bunch of keys for some time now and it has not been damaged. it provides different methods to authenticate a user to a system. i’m not going to discuss every possibility, i’ll just mention two. you can read about the others on their website.
the one time password (OTP) can be used with yubico’s authentication servers. this requires an active internet connection. the yubikey will generate a one time password based on a cycling number, it’s unique id and a secret that is only known by yubico and the key itself. normally this OTP is used in combination with a remembered user password and both credentials have to be valid to login. e.g: there is a yubikey wordpress plugin.
the challenge response is a feature that is available since yubikey version 2.2. those were available since september 2010. it supports HMAC-SHA1 and the yubikey OTP algorithm. for my cryptsetup i used the synchronous (no user interation) HMAC-SHA1 variant.
as the yubikey supports 2 slots where any configuration can be put (challenge response, yubikey OTP, static password, OATH), i used slot 2 for the challenge response option and left slot 1 as is. this left me the option to use the factory preset yubico setup with yubico’s servers if i needed it.
as the yubikey alone is not a safe option (just imagine someone stealing it together with the laptop), i wanted to implement two factor authentication. meaning, a user password has to be provided together with the yubikey in the usb slot to unlock the device. this provides enough security: 256 bit encryption on the device itself, 160 bit on the yubikey and a decently strong user password that is combined with the challenge response of the yubikey. and of course the challenge changes at every boot up.
to change the challenge in a secure way, the new password is written after the crypt device is mounted. the new password is written in a file on the just mounted and encrypted file system. it is set in the luks header and deleted just after.
the init script i came up with can be found on github, feel free to mess with it, fork it and improve it! if you are planning on using the script i highly recommend to backup your luks header with a known password in case something goes wrong.
all in all it seems like a quite secure solution. post to the comments if you want to share what you think.
4 replies on “cryptsetup and the yubikey…”
This sounds amazing, my question is about the new password that is written after the crypt device is mounted. Is this done in an atomic way such that a power failure, kernel panic, etc couldn’t result in the updated token being lost before it is written back out? Or how big/likely is the window where that could happen?
Good question. I’ve not considered this a problem yet. Mainly because I don’t expect a kernel panic in a well tested command like this and also because I’m running this on my Laptop, which has a battery attached.
The script uses the ‘cryptsetup luksChangeKey’ command. You should read the man pages or the source code to see how atomic this is. I’m guessing that a power failure could always be a problem.
But you run into similar problems when loosing your yubikey. Without your yubikey you are not able to reproduce the response part of the password.
If you only set this ONE password in the LUKS header you cannot decrypt your partition. A way out of this is to store a second password. This either be a password set with another yubikey or a very long static password. I would recommend backing up the LUKS header BEFORE you set a challenge response password on this device. This way you can replace the broken LUKS header, either because it had a power failure or you lost your yubikey. Use a password you can remember or back it up somewhere safe.
hth
Florian
Hi.
Wouldn’t it be nice to also add the non-alterable device serial number that can be read (unless disabled in the device configuration) via an API call to the cryptsetup encryption key ?
Tormen
Would this work on qubes ?