Nitrokey / nitrokey-pro-firmware

Firmware for the Nitrokey Pro device
GNU General Public License v3.0
119 stars 22 forks source link

Support HMAC-SHA1 directly #51

Open alexara opened 5 years ago

alexara commented 5 years ago

In the future we could support HMAC-SHA1 directly, if there would be a request (no one registered it in Pro's firmware project yet).

Here's the formal request! :)

Looking forward to Nitrokey Pro supporting HMAC-SHA1 directly in order to work properly with KeePassXC, as discussed here: https://github.com/keepassxreboot/keepassxc/issues/255

muellermartin commented 5 years ago

I'd also would love to see a more flexible HMAC Challenge-Response mode where a custom challenge can be passed, intead of a counter/timer that both parties share and synchronize as used in HOTP/TOTP.

An example for this can be seen in the YubiKey API: yk_challenge_response()

This would help implementing some alternative authentication schemes as used in KeeChallenge for KeePass2 or KeePassXC (as already mentioned). An explanation for the YubiKey's implementation is also provided here (in German): https://thomas-leister.de/authentifizierungsverfahren-des-yubikeys-erklaert/#challenge-response-via-hid

szszszsz commented 5 years ago

@muellermartin Thank you for the links!

I have an untested idea, which should work with the current API: to just use the challenge as a time, set it on the device, and then simply get the response from the TOTP slot. Perhaps division against a time window would have to be done as well on the client side for the final comparison, but overall, if that is a usual HMAC, it should work. This would be backward-compatible, without the need for firmware update. Nitrokey Pro has no field updates currently.

jans23 commented 5 years ago

I recall a mechanism which prevents the time in Nitrokey Pro from being reversed. I'm not sure if it's a hard mechanism in the firmware which can't be reset or if it's enforced by the Nitrokey App only.

However, I think a proper solution would utilize Nitrokey's encryption capability and wouldn't use HMAC or OTP or alike because such won't be so secure. This implicates that Keepass would require an interface such as PKCS#11. There is such proof-of-concept for the original Keepass.

muellermartin commented 5 years ago

If the time is secured in the described way it would make no sense to break this to hack in a more general HMAC-SHA1 method. Even if this is not the case I'd rather prefer a dedicated function for this, because it seems cleaner and would be even more flexible.

HMAC-SHA1 is for authenticating a message, not encryption. You're totally right that password managers like KeePass and alike should make use of PKCS#11 to en-/decrypt their databases, but this is out of scope. HMAC-SHA1 is useful to prove that a specific hardware token is inserted in cases where there is no way for dynamic counters like in HOTP/TOTP. Therefore this is useful for alternative 2FA schemes.

LinkTed commented 5 years ago

Is there any chance that it would be implemented in the near future? It sounds that it would be a great feature for the Nitrokey.

szszszsz commented 5 years ago

@LinkTed We would like rather to use PKCS#11 instead, which is superior to HMAC-SHA1. Supporting suboptimal solution will worsen the security, by giving a false safety sense.

@muellermartin Why do you think PKCS#11 is out-of-scope?

LinkTed commented 5 years ago

I implement a program, which unlocks a password database with a hardware token. I try to use OpenSC for the Nitrokey, but it only supports decryption operation and only the algorithm RSA-PKCS. I know there is a workaround to extract the public key and encrypt the data on the software side but is PKCS#11 responsible to abstract this kind of operation?

szszszsz commented 5 years ago

@LinkTed OpenSC is supporting only decryption, as you said, since smart card does not support public key operations due to a hardware limitation. I am not aware of any other PKCS#11, which would abstract this unfortunately.

LinkTed commented 5 years ago

So, if I use OpenSC have to abstract and do the encryption stuff on my own, which is too much if you want to support the full interface (like: support all algorithm of the smartcard tokens). I think that would it make it easier for a lot of people to use the Nitrokey if there is a similar interface like in the yubikey.

@szszszsz Do you know if there is a way to use the OpenSC PKCS#11 as something like key derivation (maybe there is no need if there is an alternative way in PKCS#11)?

szszszsz commented 5 years ago

So I understand that the point is, that there is no comprehensive solution to manage the smart card operations in both ways (engaging both private and public key), is that right? Sounds counter-intuitive, but perhaps you are right. I do not see any good examples for both either at OpenSC's wiki after a brief look.

For OpenPGP v3.3 I do not see derivation in the mechanisms listing:

pkcs11-tool --list-mechanism ``` sz@stumpy ~/work> pkcs11-tool -L Available slots: Slot 0 (0x0): Nitrokey Nitrokey Pro (000000000000000000005F11) 00 00 token label : User PIN (OpenPGP card) token manufacturer : ZeitControl token model : PKCS#15 emulated token flags : login required, rng, token initialized, PIN initialized hardware version : 3.3 firmware version : 3.3 serial num : 000500005f11 pin min/max : 6/64 Slot 1 (0x1): Nitrokey Nitrokey Pro (000000000000000000005F11) 00 00 token label : User PIN (sig) (OpenPGP card) token manufacturer : ZeitControl token model : PKCS#15 emulated token flags : login required, rng, token initialized, PIN initialized hardware version : 3.3 firmware version : 3.3 serial num : 000500005f11 pin min/max : 6/64 sz@stumpy ~/work> pkcs11-tool --list-mechanism Using slot 0 with a present token (0x0) Supported mechanisms: SHA-1, digest SHA224, digest SHA256, digest SHA384, digest SHA512, digest MD5, digest RIPEMD160, digest GOSTR3411, digest RSA-PKCS, keySize={2048,2048}, hw, decrypt, sign, verify SHA1-RSA-PKCS, keySize={2048,2048}, sign, verify SHA224-RSA-PKCS, keySize={2048,2048}, sign, verify SHA256-RSA-PKCS, keySize={2048,2048}, sign, verify SHA384-RSA-PKCS, keySize={2048,2048}, sign, verify SHA512-RSA-PKCS, keySize={2048,2048}, sign, verify MD5-RSA-PKCS, keySize={2048,2048}, sign, verify RIPEMD160-RSA-PKCS, keySize={2048,2048}, sign, verify RSA-PKCS-KEY-PAIR-GEN, keySize={2048,2048}, generate_key_pair ```

Similarly for HSM (forum link), except the ECDH which would rather not help.

LinkTed commented 5 years ago

So I understand that the point is, that there is no comprehensive solution to manage the smart card operations in both ways (engaging both private and public key), is that right?

Yes. So you do not know any other solution?

szszszsz commented 5 years ago

@LinkTed Not at the moment, sorry. It seems this is the accepted way to handle crypto-operations. cc: @alex-nitrokey

muellermartin commented 5 years ago

I fear there is a misunderstanding between message authentication and encryption/signing. This issue was to get a MAC from the hardware token and not for encryption or message signing. So I want to finally know whether the Nitrokey is going to get an API for message authentication (like HMAC-SHA1) or not?

LinkTed commented 5 years ago

@muellermartin is there any reason why HMAC-SHA1 should not be used as key derivation?

szszszsz commented 5 years ago

@muellermartin Sorry for delay - I had to remind myself the history of this feature request. The initial requirement was to add HMAC-SHA1 direct use, as a mean for challenge-response for KeepassXC. However, as discussion has evolved it became clear, that better use in that case would be PKCS#11 (e.g. for decrypting the intermediary key for database). Solution based on HMAC-SHA1 does not isolate the key from the host PC, which I consider undesired. It has similar shortcomings, as the HOTP-discussed solution, with the exception that KeepassXC in its current request-response implementation always uses the same challenge. While adding support in the firmware for the direct HMAC-SHA1 request is trivial (since TOTP/HOTP is essentially this, but with own challenges - see HOTP spec: RFC#4226), we agreed it would be better in this context to not support suboptimal solutions, to not give false security sense to user (as nowadays could do encrypting user data with 3DES, or using MD5 for hashing). HOTP/TOTP use case is different in general case, since the secrets are stored in Web applications, not on the PC itself. These are our reasons to not implement support for it in Nitrokey Pro and Nitrokey Storage devices. The issue is left open to remind about the potential need from our users, and gather comments/requests in discussion, which potentially would change our minds. @muellermartin @LinkTed Do you have any other or legacy systems using HMAC-SHA1, or any other reasons justifying introduction of this feature?

szszszsz commented 5 years ago

FYI: Challenge response is apparently supported by QubesOS. https://www.qubes-os.org/doc/yubi-key/#challenge-response-mode

droidmonkey commented 4 years ago

@szszszsz need to correct your statement above. KeePassXC uses a new randomly generated challenge every time the database is saved.

phoerious commented 4 years ago

The HMAC secret also never leaves the hardware key, since KeePassXC only uses the response as input to its key derivation function. This is the major difference between KeePassXC and KeeChallenge.

prairiehare commented 4 years ago

With HMAC-SHA1 also LUKS could be better supported like the Yubikey does. The solutions I found til now for the support of LUKS decryption were far from actually useable for a broader audience and looked to me very error-prone.

LinkTed commented 4 years ago

If you want to open your LUKS partion with the Nitrokey and you are using Arch Linux then you can use the following repo initramfs-scencrypt. This is using the GPG capability of the Nirtokey.

prairiehare commented 4 years ago

If you want to open your LUKS partion with the Nitrokey and you are using Arch Linux then you can use the following repo initramfs-scencrypt. This is using the GPG capability of the Nirtokey.

Thanks for the hint. I am pretty intrigued by the concept. I am not having a an Arch Linux available right now to check it out (only Ubuntu), but going through the script it doesn't look as if there are many things very specific to a distribution, except that I have no experience with ramfs and cannot say much about that, as I usually don't like to touch things in these sensitive areas. I will set up a separate system to check that out.