cornelinux / yubikey-luks

Two factor authentication for harddisk encryption
605 stars 58 forks source link

smartcard protected LUKS passphrase #44

Open smrt28 opened 5 years ago

smrt28 commented 5 years ago

Hi,

I have an idea to have the secret stored on Yubikey, but better than chal-resp method used by your scripts protect the secret by PIN. It would be a great protection against breaking password by torture. You have just 3 attempts to enter the PIN correctly, so you would have to withstand just 3 rounds of torture since Yubikey PIV would be locked after the 3rd attempt.

I spent some time to figure out, how to do that. Seems Yubikey has not functionality which would allow you to store raw PIN protected secret. However, I think I found the solution.

It uses PIV. PIV has slots which hold RSA secret keys. Yubikey allows you to use the keys for decryption. The decipher operation is protected by PIN. Yubikey can import and generate the keys, but it has no interface to read the keys back.

The idea is:

  1. generate and store the RSA2048 key in selected slot
  2. use the public-key to encrypt the random secret
  3. drop public key
  4. store the encrypted secret as an raw data object for given slot. AFAIK the slot-objects are used for storing certificates, but they can hold any data in general.

If you wan to get the secret, you read the encrypted secret and let Yubikey decipher. It needs PIN. It should be safe, since we don't know even the RSA public-key (dropped in step 3), so we don't even know the public RSA parameters like modulus. Due to this, I think it would be safe even with RSA512!

I create short app, which can do that: https://github.com/smrt28/yk-secret-tool

It needs a relatively new libykpiv which is not in my distro (Ubuntu 18). So, you will need the repo. from yubico or compile from sources: https://github.com/Yubico/yubico-piv-tool

It works with Yubikey 4. NEO doesn't have RETIRED slots which it uses, but you can use YKPIV_KEY_AUTHENTICATION slot (-s 21 yk-secret-tool argument - see piv.c ykpiv_select_slot() function) but I didn't try it since I'm not the NEO owner.

Example: Setup 1st slot by random secret:

$ ./yk-secret-tool -a setup -s 1
Generating key and setting secret to slot 1...
Done

Fetching the secret:

$ ./yk-secret-tool -a fetch -s 1
Yubikey PIN:
4f9a6acb66abceb989f4e46de860428760152afd46124bb05216fd92ddc7598a

Is it interesting for you?

Phiwa commented 5 years ago

I like the idea of having it PIN-protected!

Vincent43 commented 5 years ago

There are existing tools for using YubiKey as a smartcard with stored gpg key which can be protected by PIN: https://github.com/fuhry/initramfs-scencrypt.

Anyway, YubiKey secret is protected by your password and there is no better protection against breaking it by torture than using a strong one (keep in mind that final passphrase is validated against LUKS keyslot which is protected by PBKDF2 or Argon2).

smrt28 commented 5 years ago

You can store your private GPG key on Yubikey and use it for decrypting but there is no room for the encrypted secret which you would have to keep on unencrypted partition.

Argon2 protects your password against breaking on GPU but not against waterboarding . PIN helps you against the torture since you can just reveal a wrong PIN 3 times and the key on Yubikey would be destroyed.

Vincent43 commented 5 years ago

Oh, I didn't grasp that you mean torture as literal not just brute-forcing password (I'm not sure if not revealing password/PIN is the best outcome in that case :smile:)

I see there is also PUK which can reset PIN and costs us another 3 rounds of torture.

I'm not familiar with PIV so I want to ask a few questions:

Is raw data object stored on YubiKey readable from software?

If attacker fully controls software environment, do they can modify PIV management tool in a way which allow for unlimited tries of PIN?

smrt28 commented 5 years ago

Yubikey-4 PIV has about 24 slots, NEO has just 4 slots I suppose. Each slot contains 1 private key + 3KB arbitrary data. Without knowing the PIN, you can generate or import private key to any slot. Basically, without the PIN you have write-only access.

It is NOT possible to read the private key back from the slot anyhow (even with the PIN). You can use the key in the slot for encrypting, decrypting and signing (note encrypting means encrypting by private key, not by public!) . All those operations (encrypt, decrypt, sign) need PIN. If you enter 3 times incorrect PIN, the PIN would be blocked. You can use PUK to reset the PIN, however after entering 3 times incorrect PUK even the PUK would be blocked. The PUK can be blocked independently. You can make 3 attempts to change the PUK and enter 3 times incorrect PUK and it would block PUK forever, however PIN would be still functional but without possibility of resetting since PUK was blocked.

If you block both PIN and PUK, you can reset entire PIV only. The reset would delete all the keys from all the slots.

You can restrict even write access by setting "managment-key". However, it won't prevent from resetting entire PIV. Management-key should probably prevent just from overwriting the keys accidentally by the user.

The arbitrary slot-data are accessible freely without the PIN - it's like small USB stick. So to make sense they must be encrypted!

The keys stored in PIV slots are private keys (in my case they are RSA2048 keys). The key could be generated by Yubikey or you can generate (for instance by openssl utility) and import yours. In case Yubikey generates the key, you won't even see the private key. Yubukey just stores the privake key in the slot and tells you the public key only.

I use the public key to encrypt 256bit random secret and store it as the arbitrary data in the slot and drop the public key. RSA is a simple math. Decryption is just calculating A^D mod N. N is public, A is cypher text, D is private. If you drop the public key, you drop even N. So, with so many unknowns I suppose it would be safe like The Vernam Cipher.

If attacker fully control the software environment, he can "dmsetup table --showkeys". However, if "fully control" means stolen hard-drive and even Yubikey, the only way how he can break the password would be to guess the PIN. He has 3 attempts and eventually 3 attempts to try PUK (if not already blocked). He can always destroy the stored keys in Yubikey, however he won't definitely help himself.

Vincent43 commented 5 years ago

It is NOT possible to read the private key back from the slot anyhow (even with the PIN).

Assuming you fully trust YubiKey closed source firmware/hardware :smile:.

If you enter 3 times incorrect PIN, the PIN would be blocked. You can use PUK to reset the PIN, however after entering 3 times incorrect PUK even the PUK would be blocked. The PUK can be blocked independently. You can make 3 attempts to change the PUK and enter 3 times incorrect PUK and it would block PUK forever, however PIN would be still functional but without possibility of resetting since PUK was blocked.

Yeah, this is how it works in theory but what happens if you can create rogue PIV client which may communicate with YubiKey in some special way and/or read the source code of PIV applet stored inside YubiKey and find where are the potential flaws.

The YubiKey is a great tool but not a foolproof one. It was already found that keys generated on it were flawed once. There were ways to hack Trezor devices. I don't have a reason to not trust YubiKey but if we add additional threats like physical violence to our security model then we shouldn't ignore the others as well.

The arbitrary slot-data are accessible freely without the PIN - it's like small USB stick. So to make sense they must be encrypted!

Ok, so it isn't much different than above gpg smartcard approach other than no need for extra storage space somewhere.

If attacker fully control the software environment, he can "dmsetup table --showkeys".

Not with LUKS2 format (unless we can hack the kernel) but I meant environment before unlocking is done.

smrt28 commented 5 years ago

It is NOT possible to read the private key back from the slot anyhow (even with the PIN).

Assuming you fully trust YubiKey closed source firmware/hardware .

It's like 2-phase authentication. It combines something you have with something you know. If one of those fails, there is still the second one. So, at least you can't make the things worse.

I think this is about the implementation. I'm not supposed to assume anything. I just implement the things. It's up to users to decide whether they trust Yubico and use it.

Yeah, this is how it works in theory but what happens if you can create rogue PIV client which may communicate with YubiKey in some special way and/or read the source code of PIV applet stored inside YubiKey and find where are the potential flaws.

See my answer above. Btw, how can you be sure about the same with chal-resp-hmac? I think, if Yubikey had no backdoors, then PIV advantages are clearly visible against chal-resp-hamc.

The YubiKey is a great tool but not a foolproof one. It was already found that keys generated on it were flawed once. There were ways to hack Trezor devices. I don't have a reason to not trust YubiKey but if we add additional threats like physical violence to our security model then we shouldn't ignore the others as well.

As I wrote, this question is not interesting for me.

If attacker fully control the software environment, he can "dmsetup table --showkeys".

Not with LUKS2 format (unless we can hack the kernel) but I meant environment before unlocking is done.

It's the same. Just little more complicated if you have root access.

Vincent43 commented 5 years ago

It's like 2-phase authentication. It combines something you have with something you know. If one of those fails, there is still the second one. So, at least you can't make the things worse.

No, if Yubikey secret leaks then everything is gone. No need to waterboarding :smile:

I think this is about the implementation. I'm not supposed to assume anything. I just implement the things. It's up to users to decide whether they trust Yubico and use it.

Implementation is as important as theoretical concept. On the one hand you assume an extreme scenario of physical violence where user can't trust themselves they can keep their memorized secret secure on the other you take for granted something written in docs, not even actual code. Don't take me wrong, your concept is great but by mentioning torture and waterboarding you raised the bar up through the roof :smile:.

See my answer above. Btw, how can you be sure about the same with chal-resp-hmac? I think, if Yubikey had no backdoors, then PIV advantages are clearly visible against chal-resp-hamc.

The benefit of chal-resp-hmac is that you don't have to store additional secrets which, if revealed do compromise security (the secret key used for calculating hmac doesn't reveal anything on its own) other than having challenge kept in your memory (which may be equivalent of remembering the PIN). What isn't stored cannot be leaked. It's simpler with less steps (generate/upload key once + provide challenge,calculate hmac on unlock vs generate key-pair, create/encrypt secret, upload key/secret once + provide PIN,decrypt secret on unlock). It's also more versatile as changing LUKS passphrase require only to provide different challenge rather than generating new key-pair and encrypting new secret.

There is a trade-off. PIN will be easier to remember than a strong challenge at cost of trusting of YubiKey internals to do their job. That's not a new concept as I already pointed out that there are existing smartcard+gpg implementations which work very similar (one of them will be part of official cryptsetup package in debian/ubuntu soon). I don't know if using GPG is better than pure RSA in PIV but perhaps more bloated :smile:. In the end, choosing which one is better is matter a of personal taste I guess.

The PIV approach is definitely an interesting alternative and deserves fully working implementation. This repo isn't very active so you may use your own and adapt existing initramfs/format/enroll/open scripts to it. Maybe even propose it for inclusion in debian cryptsetup package which repo I linked above?

cornelinux commented 3 years ago

I am a big fan of using smartcards (as in uses assymmetric cryptography with a private key protected within the card) and have been doing this since 2005. If you would want to do it right, LUKS itself should be capable of protecting the encryption key (DEK) with the private key stored in the smartcard. This actually was my first idea since all commercial enterprise FDE tools do it this way. I checked and asked with LUKS if there would ever be the possibility to assymmetrically encrypt the DEK, but this was not planned.

Protecting a passphrase in a secure way using the smartcard functionality but then passing a simple static passphrase to LUKS is somehow snakeoil to me. For this scenario my attack vector would still be the same as it is now: replace the initramfs and dump the slot passphrase (KEK) to a location where I could pick it up.

Imho the big effort is not worth the gain (for me).