Mandatory mention of of ring [1], one of the goto crypto libraries for Rust.
It is also has a focus on hard to misuse API design and uses some BoringSSL primitives as well, while notably not depending on it's build system (go, Perl, ...)
A cursory glance at the code suggests that `mundane` is purely an API wrapper for BoringSSL at the moment, and does not implement any crypto in Rust.
I have never used Ring directly, but my experience dealing with it as a transitive dependency leads me to avoid it.
Ring has a policy[0] of only supporting the latest released version with users being expected to always upgrade to latest Ring. This in itself is not so bad, but coupled with the lack of any guarantees around API stability means that it can be a very tricky dependency to work with. This problem is compounded by it only being possible to link one version of Ring in to the same program.
Even if you don't depend on Ring directly, Ring could appear as a dependency of many of your dependencies. This forces you into upgrading all of your Ring-depending dependencies in lockstep. You cannot upgrade any until all of these dependencies support the same latest version of Ring.
This is a real shame because Ring otherwise looks fantastic. The API is misuse resistant and looks quite pleasant, and the documentation is thorough. Its current versioning and stability policy however is a massive liability for any project that relies on it. I hope this changes eventually.
This problem is compounded by it only being possible to link one version of Ring in to the same program.
I am planning to fix this in ring early in 2021 (January)...
Even if you don't depend on Ring directly, Ring could appear as a dependency of many of your dependencies. This forces you into upgrading all of your Ring-depending dependencies in lockstep. You cannot upgrade any until all of these dependencies support the same latest version of Ring.
Then you won't need to upgrade everything in lockstep.
That said, I still do recommend everybody only use the latest version.
Thanks, this would be great! Recently had to help someone at work update our dependencies and it was difficult to justify why it was so difficult. Ring was unfortunately the cause of the difficulty.
It does say "Every six months we have a meeting to revisit this policy. Email ... if you want to attend the next meeting."
It sounds like he's willing to listen to feedback about the policy, but would rather have focused time dedicated to discussing it rather than long drawn out inconclusive tickets.
my experience dealing with it as a transitive dependency leads me to avoid it.
This is my experience as well, it's one of the best crypto libs and the devs are topnotch, yet relying on it is often painful, many libraries out there are rendered unusable.
Yes ring is not perfect, the issue you mentioned, or things older releases being yanked just for being old don't make it easy to deal with. But it's robust in the supported cases and written by someone who has lots of experience building cryptography software. Just recently the rustls/webpki/ring stack passed a security review.
I've had the same experience in trying to use a web framework that had a dependency of a dependency of a dependency that used a yanked version of Ring. No more web framework.
I'm appreciative of all the work that has gone into Ring, its certainly not something I could have done or have any expertise in, but it is a landmine to depend on.
There isn't yet any name mangling in the C/assembly function names that would prevent collisions between two incompatible versions. I use `links = "ring-asm"` in Cargo.toml to prevent people from accidentally including two versions of ring for that reason. I am going to switch that to use a different mechanism.
There are lots of people doing awesome stuff with cryptography in Rust, including (but not limited to) the people who maintain Mundane.
You are right that ring has a much-reduced set of build dependencies compared to Mundane/BoringSSL. However, it is also true that Google implemented some build system support (to support Mundane?) that will help ring's custom build system a lot too, once I find some time to make use of it.
I found Ring a little difficult to use though, at least from a novice perspective. Wish the documentation was a little more novice focused / available.
Pure rust wouldn't be good for a cryptography library because it doesn't have features like constant-time functions that mitigate side channel attacks.
The secure constant time implementations in Ring are from OpenSSL, and written in assembly, because that sort of code cannot be written safely in C or Rust.
I’ve read that kind of perl-generated assembly and honestly it is also unreadable and unauditable. I decided not to go for it for the project I’m working on and use pure rust libraries. But note that you can write inline assembly in rust too[1]
I’ve also used tooling[2] to measure any timing issues in libraries like dalek (ed25519) and it couldn’t find any (so good luck if you’re trying to exploit that over the network)
Today I’d be more worried by memory safety bugs created by the use of C or assembly, or logic bugs due to only a few people being able to audit an implementation.
Comments
Mandatory mention of of ring [1], one of the goto crypto libraries for Rust.
It is also has a focus on hard to misuse API design and uses some BoringSSL primitives as well, while notably not depending on it's build system (go, Perl, ...)
A cursory glance at the code suggests that `mundane` is purely an API wrapper for BoringSSL at the moment, and does not implement any crypto in Rust.
[1] https://github.com/briansmith/ring
I have never used Ring directly, but my experience dealing with it as a transitive dependency leads me to avoid it.
Ring has a policy[0] of only supporting the latest released version with users being expected to always upgrade to latest Ring. This in itself is not so bad, but coupled with the lack of any guarantees around API stability means that it can be a very tricky dependency to work with. This problem is compounded by it only being possible to link one version of Ring in to the same program.
Even if you don't depend on Ring directly, Ring could appear as a dependency of many of your dependencies. This forces you into upgrading all of your Ring-depending dependencies in lockstep. You cannot upgrade any until all of these dependencies support the same latest version of Ring.
This is a real shame because Ring otherwise looks fantastic. The API is misuse resistant and looks quite pleasant, and the documentation is thorough. Its current versioning and stability policy however is a massive liability for any project that relies on it. I hope this changes eventually.
[0]: https://github.com/briansmith/ring#versioning--stability
I am planning to fix this in ring early in 2021 (January)...
Then you won't need to upgrade everything in lockstep.
That said, I still do recommend everybody only use the latest version.
This is definitely the piece that gives the current versioning policy its sharp edge, so it's great news that the fix will arrive soon.
Thanks for your hard work on Ring!
Thanks, this would be great! Recently had to help someone at work update our dependencies and it was difficult to justify why it was so difficult. Ring was unfortunately the cause of the difficulty.
It does say "Every six months we have a meeting to revisit this policy. Email ... if you want to attend the next meeting."
It sounds like he's willing to listen to feedback about the policy, but would rather have focused time dedicated to discussing it rather than long drawn out inconclusive tickets.
This is my experience as well, it's one of the best crypto libs and the devs are topnotch, yet relying on it is often painful, many libraries out there are rendered unusable.
Yes ring is not perfect, the issue you mentioned, or things older releases being yanked just for being old don't make it easy to deal with. But it's robust in the supported cases and written by someone who has lots of experience building cryptography software. Just recently the rustls/webpki/ring stack passed a security review.
I've had the same experience in trying to use a web framework that had a dependency of a dependency of a dependency that used a yanked version of Ring. No more web framework.
I'm appreciative of all the work that has gone into Ring, its certainly not something I could have done or have any expertise in, but it is a landmine to depend on.
What’s the specific reason that you can’t link in two versions?
There isn't yet any name mangling in the C/assembly function names that would prevent collisions between two incompatible versions. I use `links = "ring-asm"` in Cargo.toml to prevent people from accidentally including two versions of ring for that reason. I am going to switch that to use a different mechanism.
Another alternative is https://docs.rs/sodiumoxide/0.2.6/sodiumoxide/ - bindings to NaCL.
There are lots of people doing awesome stuff with cryptography in Rust, including (but not limited to) the people who maintain Mundane.
You are right that ring has a much-reduced set of build dependencies compared to Mundane/BoringSSL. However, it is also true that Google implemented some build system support (to support Mundane?) that will help ring's custom build system a lot too, once I find some time to make use of it.
Yeah the golang dependency just seems bizarre.
I found Ring a little difficult to use though, at least from a novice perspective. Wish the documentation was a little more novice focused / available.
Ring is not that great tbh, not pure rust and the API is quite hard to use even for cryptography practitioners.
Pure rust wouldn't be good for a cryptography library because it doesn't have features like constant-time functions that mitigate side channel attacks.
As much as C does
The secure constant time implementations in Ring are from OpenSSL, and written in assembly, because that sort of code cannot be written safely in C or Rust.
I’ve read that kind of perl-generated assembly and honestly it is also unreadable and unauditable. I decided not to go for it for the project I’m working on and use pure rust libraries. But note that you can write inline assembly in rust too[1]
[1]: https://doc.rust-lang.org/1.8.0/book/inline-assembly.html
I’ve also used tooling[2] to measure any timing issues in libraries like dalek (ed25519) and it couldn’t find any (so good luck if you’re trying to exploit that over the network)
[2]: https://github.com/rozbb/dudect-bencher
Today I’d be more worried by memory safety bugs created by the use of C or assembly, or logic bugs due to only a few people being able to audit an implementation.
Those asm docs are from Rust 1.8; the feature was completely re-written since then. https://github.com/rust-lang/rfcs/blob/master/text/2873-inli...
yes it can.