Linux – Are there more advanced LUKS key schemes, e.g. 2 of 3 keys needed

encryptionlinuxluks

It seems like the two main LUKS encryption options are:

  1. USB keyfile (see https://superuser.com/questions/149578/how-can-i-use-a-keyfile-on-a-removable-usb-drive-for-my-encrypted-root-in-debian)
  2. Typing in a password

These both have weaknesses. The first can be overcome by stealing the USB drive. In the second case, a keylogger could be used, or I could be forced to give over the password.

Would it be possible to create an encryption scheme that required both of the options? Then, if I was given an injuction to provide the password, I could destroy the USB drive (e.g. burn it on the stovetop); conversely, if someone stole my USB drive, they would need to get my password as well.

It seems the existing LUKS key slot idea is that providing a key for any key slot will unlock the device, not that one has to provide a key for all, or say "2 of 3" key slots (iirc the latter can be accomplished in a cryptographically secure manner using a Galois field).

(Also, I happen to be on an OpenSuSE system, so please keep answers distro-agnostic or something that can work on SuSE.)

Best Answer

I don't think something like this exists right out of the box, but it should be possible. I'll put together some references for you.

First there's /etc/crypttab - typically you specify a key file or password in the third slot, but some distros allow you to specify an option in the fourth field called keyscript (debian and opensuse support this: http://linux.frank4dd.com/en/man5/crypttab.htm). This script (which must be in "/lib/cryptsetup/scripts" iirc) can use the third field (what would normally be just the keyfile or password) as an argument. The keyscript's job is to send the actual decryption key to stdout, which cryptsetup then uses as the luks key in the normal fashion.

Second is that you will likely need to write the keyscript. netkeyscript (in github) is an example of a keyscript that listens on a UDP multicast socket for the password; here is another more detailed example of a custom key script, complete with an implementation in sh: http://wejn.org/how-to-make-passwordless-cryptsetup.html. How you code the keyscript (which I'll just call multifactor) I leave as an exercise to you ;)

Third is the secret splitting. you can use an open source tool called "ssss" (google for "ssss-split") to split the luks password in the manner you describe. let's say you split it into 3 pieces (a,b,c) and require any 2 of them. store "a" on the usb drive, "b" in a vault, and "c" you store with the computer (unencrypted partition), or whatever. Of course you don't want "c" to be exposed, so encrypt it with a scheme of your choice using a passphrase you can remember, and call that passphrase "c0", and the encrypted "c" on your disk is "c'". Now your crypttab will look something like

root  /dev/disk/<blah blah>  /dev/<usb>:/path/to/a+$/dev/<blah>:/path/to/c'  keyscript=multifactor

what you actually will have for the third field will of course depend on what your keyscript is willing to accept

Ideally the keyscript should be able to determine that it needs your input to decrypt one or more of the keys (e.g.: c' -> c in this case), but you can use the third field to specify that as desired. In my example above, I used a leading $ to indicate that.

I'm not sure if it's possible to make the keyscript prompt for input, possibly on stderr, since any output on stdout is taken as the luks password. It would be nice if there was a sensible fallback.

Anyway, good luck and happy hacking :)

Related Question