Radish alpha
h
rad:z3gqcJUoA1n9HaHKufZs5FCSGazv5
Radicle Heartwood Protocol & Stack
Radicle
Git
Using Yubikey to store private key and perform cryptographic functions
Open ade opened 10 months ago type=feature

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

ade commented 10 months ago

I’ve investigated this a little further, my approach so far has been:

  1. :white_check_mark: Can I preference the ssh-agent AgentSigner over the MemorySigner whilst running rad to prevent the I/O errors seen in my original post
  2. :x: Can I get radicle to use ssh-agent AgentSigner to run all cryptographic operations
  • Whilst you can have radicle use the signer for CLI interactions, the radicle-node package specifically requires access to the MemorySigner with it’s secret key to perform ECDH for the Noise XK peer communication establishment
  1. :white_check_mark: Can I build a new Signer type PKCS11Signer and get it to sign successfully with private keys stored on a HSM (via SoftHSM v2 and rust-cryptoki)
  2. :x: Can I implement the necessary ECDH methods on the PKCS11Signer to enable secure peer connections

The 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 ed25519 keys are for signing ONLY, performing ECDH would require a x25519 key. Radicle however reuses the ed25519 key 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:

Given a point (u, v) on the Montgomery curve, the corresponding point (x, y) on the twisted Edwards curve can be calculated as: x = (v + 1) / (v - 1) and y = (u - 1) / (u + 1).

Twisted Edwards to Montgomery:

Given a point (x, y) on the twisted Edwards curve, the corresponding point (u, v) on the Montgomery curve can be calculated as: u = (y + 1) / (y - 1) and v = (x + 1) / (x - 1).

I believe libsodium has 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 ed25519 private key, translating it to x25519 and importing it onto the HSM… But I don’t know what would happen if you had a rad client using the ed25519 ECDH operation that exists currently trying to derive a shared secret with a x25519 key 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 OpenPGP Card Interface abilities of the Yubikey, however I suspect it will be similar, ed25519 for signing and cv/x25519 for ECDH.

If anyone else has any great ideas, they are more than welcome! I may attempt the ed25519 key to x25519 conversion 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.