mooltipass / minible

Github repository containing the firmwares running on the Mooltipass Mini BLE
GNU General Public License v3.0
98 stars 21 forks source link

ssh-keygen not working - WinHello API Error -2147417829 / ED25519 support #276

Closed stef97 closed 3 years ago

stef97 commented 3 years ago

8<------------------------ BUG REPORT -----------------------------------------

Expected behavior

ssh-keygen create an SK type key pair

Actual behavior

WinHello API Error -2147417829

Step by step guide to reproduce the problem

$ ssh-keygen.exe -w winhello.dll -vvvv -t ed25519-sk -f id_ecdsa_sk -C "spare test yubikey#1" -O user=Administrator Generating public/private ed25519-sk key pair. You may need to touch your authenticator to authorize key generation. debug3: start_helper: started pid=1280 debug3: ssh_msg_send: type 5 debug3: ssh_msg_recv entering debug1: start_helper: starting /usr/lib/ssh/ssh-sk-helper debug1: sshsk_enroll: provider "winhello.dll", device "(null)", application "ssh:", userid "Administrator", flags 0x01, challenge len 0 debug1: sshsk_enroll: using random challenge debug1: sshsk_open: provider winhello.dll implements version 0x00070000 check_enroll_options: requested user Administrator init_winhello: WARNING! This should not be like this! WinHello API Error: Is user available=0, User=0. sk_enroll: WinHello API Error -2147417829:UnknownError debug1: sshsk_enroll: provider "winhello.dll" failure -1 debug1: ssh-sk-helper: Enrollment failed: invalid format debug1: main: reply len 8 debug3: ssh_msg_send: type 5 debug1: client_converse: helper returned error -4 debug3: reap_helper: pid=1280 Key enrollment failed: invalid format

Moolticute Version - If Involved

Firmware Version

AUX MCU version:
Main MCU version:

Operating System

Windows 10 version 21H1 GIT for Windows 2.32.0.2 Openssh Version 8.5p1 ( that comes with above GIT version)

Other operating systems are not supported.

8<------------------------ END BUG REPORT -------------------------------------

limpkin commented 3 years ago

@0x0ptr could you have a look? :) thanks! (for the record: https://mooltipass.github.io/minible/fido2_openssh_from_windows was extensively tested)

0x0ptr commented 3 years ago

@stef97 @limpkin Unfortunately, the miniBLE currently does not support ED25519 curve. It only supports "ECDSA w/ SHA-256" (ES256) algorithm as specified here [1] as "-7". Though the library we use support Curve25519 it does not currently support "EdDSA" (-8) (Edwards-curve Digital Signature Algorithm) (see [2]).

So the example command that you can find here [3] should work fine and worked fine for me just now when I tested.

[1] https://www.iana.org/assignments/cose/cose.xhtml#algorithms [2] https://www.bearssl.org/tls13.html [3] https://mooltipass.github.io/minible/fido2_openssh_from_windows

limpkin commented 3 years ago

@0x0ptr thanks a lot for answering this!

stef97 commented 3 years ago

Just want to confirm that it works with ECSDA and to let you know that I appreciated the prompt response very professional Many thanks

On Fri, 23 Jul 2021 at 16:56, Mathieu @.***> wrote:

@0x0ptr https://github.com/0x0ptr thanks a lot for answering this!

— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub https://github.com/mooltipass/minible/issues/276#issuecomment-885909355, or unsubscribe https://github.com/notifications/unsubscribe-auth/ACM7LPYAERZ7GGBIR7MIEQ3TZHJPHANCNFSM5AY4TM7Q .

limpkin commented 3 years ago

thanks! i'll keep the bug open for others :)

spoelstraethan commented 3 years ago

@stef97 @limpkin Unfortunately, the miniBLE currently does not support ED25519 curve. It only supports "ECDSA w/ SHA-256" (ES256) algorithm as specified here [1] as "-7". Though the library we use support Curve25519 it does not currently support "EdDSA" (-8) (Edwards-curve Digital Signature Algorithm) (see [2]).

So the example command that you can find here [3] should work fine and worked fine for me just now when I tested.

[1] https://www.iana.org/assignments/cose/cose.xhtml#algorithms [2] https://www.bearssl.org/tls13.html [3] https://mooltipass.github.io/minible/fido2_openssh_from_windows

How hard would it be to add ed25519 as apparently newer FIDO2 Yubikeys support this and it is more cryptographically secure than ecdsa?

https://cryptsus.com/blog/how-to-secure-your-ssh-server-with-public-key-elliptic-curve-ed25519-crypto.html#:~:text=ECDSA%3A%20The%20elliptic,of%20doing%20crypto%3F

limpkin commented 3 years ago

So I've asked the creator of our cryptographic library and got this answer when asking him about ED25519 support:

Long-term plan only. Ed25519 is inconvenient, because in order to sign or verify, you need to hash the concatenation of R (part of the signature value), A (the public key) and M (the message data), in that order. Thus, when verifying, you cannot start hashing M until you already have the signature value and the public key. In an X.509 certificate chain, in TLS, the certificates come in EE-first order (first the server's certificate, then the certificate of the CA that issued it, then the certificate of the CA that issued the previous one, and so on). With RSA and ECDSA, I can hash each certificate as it comes and verify the signature only when I process the next certificate, and I don't have to buffer any complete certificate (only the signature value, which is small). With EdDSA, I would have to keep a complete certificate in RAM, until I get the public key from the next one in the chain, and that means buffering and using RAM. So far, BearSSL's X.509 processing has carefully avoided that, and that's how it fits in very low RAM.

There is an EdDSA mode called "pre-hashed" in which the "M" above is not the message itself but a hash of the message, and that would be fine for BearSSL's goals, but unfortunately this is not what people use in X.509 certificates with EdDSA. This is because the mode without the pre-hashing is called "pure" and so people want it because purity is good and thus pre-hashing is "impure". The sort-of justification is academic: it was about saying that the signature would remain secure in some specific contexts even if the hash function turned out not to be collision-resistant. I.e. it would sort-of allow use of EdDSA with MD5, except of course don't do that! EdDSA is used with SHA-512 and if SHA-512 ever turned out to be flaky in any way, in particular with regard to collisions, everybody would shun it like MD5, and having signatures supporting it would become pointless.

@0x0ptr : should we look into which mode is required (pre-hashed or not) for FIDO2 ed25519? @spoelstraethan : do yubikeys do the operations on the hardware key itself or is the key retrieved and then used on the computer?

0x0ptr commented 3 years ago

@limpkin I don't think the mode (pre-hashed or not) is applicable for us. We are only interested in signing and not verifying.

spoelstraethan commented 3 years ago

It appears that with firmware 5.2.3 they implemented OpenPGP 3.4 which brought in support for ed25519/ecdsa and apparently that algorithm support extends to the FIDO2 implementation as well.

https://developers.yubico.com/PGP/YubiKey_5.2.3_Enhancements_to_OpenPGP_3.4.html

My understanding is that the private key never leaves the device, they talk to the secure element via FIDO2, PIV or GnuPG to handle the cryptographic operations.

The Yubico page outlining creating a security key backed SSH key for GitHub has a bit more info on the fact that their older keys could only do ecdsa as well, it was with 5.2.3 that they added ed25519. https://www.yubico.com/blog/github-now-supports-ssh-security-keys/

They also mention with a FIDO2 resident key you don't need to copy the SSH pub key to each machine.

Or, if your security key supports it, you can use a FIDO2 resident key.

If your security key supports FIDO2 resident keys*, ... you can enable this when creating your SSH key:

$ ssh-keygen -t ecdsa-sk -O resident

This works the same as before, except a resident key is easier to import to a new computer because it can be loaded directly from the security key. To use the SSH key on a new computer, make sure you have ssh-agent running and simply run:

$ ssh-add -K

This will load a “key handle” into the SSH agent and make the key available for use on the new computer. This works great for short visits, but it won’t last forever – you’ll need to run ssh-add again if you reboot the computer, for example. To import the key permanently, instead run:

$ ssh-keygen -K

This will write two files into the current directory: id_ecdsa_sk_rk and id_ecdsa_sk_rk.pub. Now you just need to rename the private key file to id_ecdsa_sk and move it into your SSH directory:

$ mv id_ecdsa_sk_rk ~/.ssh/id_ecdsa_sk

0x0ptr commented 3 years ago

@spoelstraethan I have some good news! I was able to find another crypto library that provides EdDSA support. I integrated it into MiniBLE and its working:

debug1: Will attempt key: ~/.ssh/id_eddsa_sk ED25519-SK .... explicit authenticator .... Confirm user presence for key ED25519-SK .... debug1: start_helper: starting /usr/lib/ssh/ssh-sk-helper debug1: process_sign: ready to sign with key ED25519-SK, provider internal: msg len 187, compat 0x4000000 debug1: sshsk_sign: provider "internal", key ED25519-SK, flags 0x01 debug1: sk_probe: 1 device(s) detected debug1: sk_probe: selecting sk by cred debug1: xxxx: reply len 111 User presence confirmed debug1: Authentication succeeded (publickey).

I will work on getting this merged soon and it should show up in a MiniBLE FW update in the near future! Hope it helps!

limpkin commented 3 years ago

woohoo!!! thanks @0x0ptr