Rust crypto: Diffie-Hellman


In my implementation of a library to interface with SecretService (an API that for example Gnome Keyring implements), I need to send values encrypted with keys exchanged via Diffie-Hellman.

The pattern I'm trying to follow is secretstorage/ at master · mitya57/secretstorage · GitHub

As far as I can see, I can use the rust-crypto crate for encryption, but not DH. OpenSSL crate seems to have a DH module, but comes with the OpenSSL dependency.

If I just try to follow the python SecretStorage library, the roadblock I run into is generating the public key from the private key, which requires pow(), which only works on up to usize in the num crate.

Am I missing something really simple here? Advice and options greatly appreciated.

Hi, I'm pretty new to Rust but I think I may be able to help. In this module of the rust-crypto crate, the keypair function can be used to generate a public and private key pair. Once you've exchanged public keys, the exchange function can be used to create a shared secret key to be used for encryption. Hopefully this helps, if not, there is a rust-crypto channel on, they've been helpful when I've had questions.

Out of curiosity, does anyone actually use anything other than the plain mode (no crypto)? I assume any program capable of reading DBus's memory would be capable of reading the memory of the SecretService service.

Thanks for the suggestion! I'll probably also ask in the rust-crypto channel soon too, crypto is not an area I'm familiar with at all.

If you have a moment, the main thing I'm having trouble is how the ed25519 module fits into DH exchange. Especially, in the SS API, it says I should use the

1024 bit parameters of the standard IETF 'Second Oakley Group'

and I'm not sure how that fits into ed25519.

Currently, I'm able to negotiate an encrypted session, but I have no idea if it's valid (I do get a public key back). It's failing when trying to send an encrypted secret, so I could be doing the AES encryption step improperly instead (or also).

I don't think I can be of much help on the details of how it works, sorry. I don't really understand enough about how encryption works to be know what's going on behind the scenes. I pretty much used their symmetric key example from the rust-crypto page and made modifications as necessary to fit into my program. Best of luck getting everything sorted out :slightly_smiling:

Thanks bill, I think I've figured out what I needed.

It turns out I did need to use powm() for the DH exchange, so I used rust-gmp.

I did use the symmetric cypher for encryption, like you did.

Glad I got it working, crypto is not a place where the compiler can check my work, so I felt pretty lost for a bit. Had to go over my code very carefully.

I don't know, but python's secretstorage had crypto by default.

On an ordinary modern Linux Distro, you cannot access DBus's memory, you can only use the ptrace system call to child processes. See Linux kernel documentation on this topic. And any of those processes could run inside a sandbox (in theory, barely used, e.g. by firejail which is not mature IMHO).

I don't know whether you want to publish your code or your binaries. If you do, please let some security folks look over your code. There are many issues you might run into, e.g.:

  • timing attacks. Fixing those requires critical sections with no single branch in it and using time-constant CPU instructions. Can only be implemented in assembler language.
  • Other sidechannel stuff I don't know enough about
  • general implementation: Crypto is very hard to do right

I'm hoping it will be publishable, and it would great to have people who know crypto to look over my code. Would #rust-crypto be the best place to go?

I used rust-crypto crate for most steps, and followed the python implementation fairly closely, but I'm sure there's still stuff I could have missed.

Interesting, I didn't know that was enabled by default nowadays. However, my specific point still stands. This might protect against a MITM by an application impersonating DBus but the gnome keyring at least allows all applications run by the user to ask for any password so, if you can replace the DBus session socket and impersonate DBus, you could have just asked for the passwords.

That's correct. There are different approaches to sandbox single applications, e.g. xdg-app or firejail which solve this issue, but they are not used widely and still a work in progress.