Yubikeys can support ED25519 key operations as of version >=5.7. You can access these features via their PIV module that supports storing and managing ED25519 keys via PKCS#11. The private key is stored on the HSM and utilised through ssh-agent.
I started investigating and writing this up in zulip#general>radicle ssh keys on yubikey.
As of radicle 1.2.0 I was unable to use the stored private key on the Yubikey via ssh-agent and the Yubikey’s PKCS#11 lib (note this was a crude attempt without understanding the core crypto operations required):
$ rad auth
✗ Error: ssh keygen: I/O error: entity not found
(likely because I moved the keys/radicle file hoping radicle would fall back onto ssh-agent)
If Radicle can rely entirely on ssh-agent for crypto functions then there shouldn’t be a reason why this couldn’t work. However if it can’t there may need to be a PKCS#11 integration (Cryptoki for rust) added.
It’s worth noting that supporting PKCS#11 would allow other HSMs to be used not just Yubikey e.g. NitroKey has support for PKCS#11
I’ve investigated this a little further, my approach so far has been:
ssh-agentAgentSignerover theMemorySignerwhilst runningradto prevent theI/Oerrors seen in my original postssh-agentAgentSignerto run all cryptographic operationsradicle-nodepackage specifically requires access to theMemorySignerwith it’s secret key to perform ECDH for the Noise XK peer communication establishmentSignertypePKCS11Signerand get it to sign successfully with private keys stored on a HSM (via SoftHSM v2 and rust-cryptoki)PKCS11Signerto enable secure peer connectionsThe issue I’m stuck up against now (4.) is that HSMs typically (SoftHSM and Yubikey) restrict the usage of private keys to certain abilities, so
ed25519keys are for signing ONLY, performing ECDH would require ax25519key. Radicle however reuses theed25519key for both signing and ECDH.…However there does exist formulas for converting from Edwards (ed25519) to Montgomary (cv/x25519) curves and back again, but this starts getting outside of my expertise and generally gives me the heebs:
Montgomery to Twisted Edwards:
Twisted Edwards to Montgomery:
I believe
libsodiumhas these capabilities, however I’m aware one of them is expressed with signed integers and the other not so you can end up with 2 possible results in one of the converstions.I think this approach would require taking a
ed25519private key, translating it tox25519and importing it onto the HSM… But I don’t know what would happen if you had a rad client using theed25519ECDH operation that exists currently trying to derive a shared secret with ax25519key on another clients HSM, would the shared secrets be equal? I suspect not :dizzy_face:One other approach I haven’t explored is looking at using the
OpenPGPCard Interface abilities of the Yubikey, however I suspect it will be similar,ed25519for signing andcv/x25519for ECDH.If anyone else has any great ideas, they are more than welcome! I may attempt the
ed25519key tox25519conversion and see if I get any mileage out of it. If that doesn’t work it may turn into a core decision for spliting key usage or enabling the ability to have split usage when multiple identities are supported.