83 comments

[ 3.6 ms ] story [ 139 ms ] thread
Hilarious build-time dependencies. You need Perl and Go and a C++ toolchain to build a Rust library!
Can't misuse it if you can't even build it.
Note that these are the requirements of the BoringSSL dependency, not the project itself.
That might make BoringSSL a poor fit for use outside of golang.

I mean this is kinda like a rust library with a dependency on a Java JVM.

It's not a runtime dependency.
It looks like that's because it's backed by an established SSL library. So this is more of a safely-typed Rust wrapper around that (which means they aren't rolling their own crypto, which is typically considered a good thing)
> which means they aren't rolling their own crypto

I will point out that BoringSSL is also mainly developed by Google, so...kinda?

I still trust it, just a kinda interesting fact

I think the intended meaning of "your own crypto" is "greenfield crypto"
I’d still rather use a pure rust implementation
Roll your own crypto library and see how far you get - there's a reason we all just depend on OpenSSL. Using rust wont make it easier to write it all from scratch.
I actually do roll my own crypto library :D
Or they could've used a formally verified crypto library such as HACL*.
(comment deleted)
Theres a Rust library that uses a Python script to generate part of its Rust code, checks that generated Rust code into git and the crates.io package does not include the Python script, so you can't actually build the crate from source properly.
Technically, you can avoid depending on Perl and Go (which are used to generate some assembly code) but you still need C++ toolchain to build most of the BoringSSL.

It is still possible to [make Mundane] link against system's OpenSSL. However, that's a bit different set of worms to locate it, auto-generate working FFI bindings, etc.

Couldn't the assembly code be generated with constexpr?
So, judging from zero docs, it's hard to misuse because you wouldn't even know how to use it.
This may be the documentation: https://docs.rs/mundane/0.4.3/mundane/ It's not great, but it's something.

You're right though, they should at a minimum link to it more prominently.

I don't want to crap on the project, but it seems like good user docs would be... the second most important thing after API design in terms of making a library hard to misuse. Maybe I'm wrong here though
Documentation for Rust crates goes in a standard location (which does get linked to from the crates.io page), though of course it'd be better if you didn't have to know that in order to find it from GitHub
I went to both crates.io and docs.rs.

Documentation as is is virtually non-existent there. Unless you're already familiar with how these functions are supposed to work.

It's kind of a faux pas, I think, to claim ergonomics as a top priority and not have good quality documentation anywhere in sight.
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

(comment deleted)
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.
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

> 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.
> I am planning to fix this in ring early in 2021 (January)...

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!

> 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.

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.

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.
(comment deleted)
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.

Ring is not that great tbh, not pure rust and the API is quite hard to use even for cryptography practitioners.
(comment deleted)
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.

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 don't know what this is doing here.

ring is also hard to misuse, and more actively maintained by far.

(comment deleted)
This is a good place to link to Orion [1], a pure-Rust crypto project for AEAD, stream ciphers, KDFs, MACs, and plain hashing. There hasn't yet been a formal security audit (hard to justify until there's a significant user base), but the API is tough to beat for usability and hard-to-misuse-ability (docs [2]).

It's an unproven library, but the author takes security pretty seriously. There's no unsafe, heavy testing, and fuzzing done for both safety (fuzzing with a sanitizer) and constant-time operation verification to minimize the danger of a timing attack.

Here's an example of the API.

    let key = aead::SecretKey::default();
    let ciphertext = aead::seal(&key, "msg".as_bytes())?;
    let plaintext = aead::open(&key, &ciphertext)?;
It doesn't get much easier than that. Also, notice the lack of a user-facing nonce. Can't screw it up if it isn't there.

There are also lots of details that are right in the library. Traits like PartialEq are implemented using constant-time operations so that users don't have to know or remember to use special operations provided by the library for comparison. Methods that return types without these protections (like getting the raw bytes out of a PasswordHash) are helpfully named things like "unprotected_as_encoded".

[1] https://github.com/brycx/orion

[2] https://docs.rs/orion/0.15.5/orion/aead/index.html#example

Orion looks cool, but i'm curious - where would one learn how to use a library like Orion? Eg, if Orion is aimed at easy to use - i'm still not the target audience. But, i do write software that i want to allow users to sign. To encrypt their data at rest. To verify signatures.

Where would i learn what i need to use smart tools by other people? Where would i learn enough to decide how to choose solving my above problems with Orion vs GPG?

That's been my biggest problem with crypto. I know enough to know to be wary, but not much beyond that. Choosing tools with that mindset is difficult. And so far, taking a crypto class is just teaching me fundamentals of building my own protocols - where as i just want to use existing tech, safely, and in the right situations.

That's a good question, and I'd be interested in hearing more about what parts of the library you're hung up on. The intention of the library is definitely to cater to people who don't know anything about crypto.

My naive guess, without knowing exactly what the sticking point is for you, is that Orion could do a better job on the modules page [1] explaining exactly what each module is for and when to use it.

Right now, I'd say the state of the library, rather than its intention, is that it's extremely usable for people who pretty much know what they want, and fairly hard for the average developer to misuse.

But I believe the author would be very interested in something that makes the library cater better to people who don't want to learn crypto, but just want to get things done using it.

[1] https://docs.rs/orion/0.15.5/orion/index.html#modules

EDIT: After some thought, I think I would say that the API for Orion is maybe an 8/10 for beginners, but the documentation is still at maybe 5/10 or 6/10 for beginners. Someone who is familiar with crypto would probably be able to look at the documentation and know what they're doing, but for someone unfamiliar with crypto, I can see how there isn't a ton in the way of explanation of the various primitives. That would be a good area for improvement for the library.

Sorry for the delay. Your guess is correct. I reach the modules page with a goal in mind, "I want to sign some data", "I want to generate a key pair to sign some data", etc - and am left questioning where to go next. Now, that sounds lazy, but it's more.. cautious - as i mentioned i am very wary of a potential footgun that would leave me using the wrong tool or the right tool in the wrong way. So without very, very explicit goal oriented documentation i'm left confused, unsure which module should be used to do what i seek.

Crypto puts people who know the unknowns in an awkward position. If i was fully ignorant i'd probably find more progress, as i'd be willing to just throw bytes around and see what works. Yet i've seen so many horror stories and tales of caution that i'm left never knowing if it's safe to do X in Y scenario.

Combine that with my goal of using this code in Desktop, Mobile, WASM (maybe web, definitely mobile, etc) - and a bunch of scary new attack vectors get introduced and compound confusion.

It's difficult to know where to start haha. Anyway, hopefully this answers your question :)

The libsodium's docs [1] are awesome in this regard, particularly the sections (and subsections) on secret-key and public-key cryptography.

If you study those docs you'll get the modern terminology used by most other libraries as well as the intended use-cases for the different cryptographic constructs.

Your examples point to public-key use-cases, and I don't see any public-key crypto support in this Orion library, so probably you just wouldn't use it ;)

[1] https://doc.libsodium.org/

Author and maintainer of Orion here.

I really appreciate your feedback, thank you! After reading this, I think your point-of-view hasn't been taken correctly into account when creating and reviewing the documentation. I'll definitely take this up to consideration in regards to possible improvements.

Appreciate it! I also heavily appreciate attempts to make crypto more usable for general software devs.

For some more insight (as someone else was asking), i replied with a bit more depth here: https://news.ycombinator.com/item?id=25449538

Thanks for the awesome looking library. I'll go ahead and fumble my way through it soon, i'm sure it's not as complex as i'm making it. I'm just not sure what usage is "safe" - so i look forward to documentation that helps me understand Safety in this context :)

I develop a Rust security application. As much as I want to use a pure Rust crypto library, the #1 factor for me is that it is audited. Unfortunately, libsodium (Sodium Oxide in Rust) and Rust-Crypto are the only ones that satisfies those requirements. libsodium being the only one that isn't easy to misuse. I wish I could help crowdfund a cryptographic analysis of all of the Rust crypto projects. It would certainly make cross compilation easier.
Yeah, that's why I tried to mention right up front that it isn't (yet) audited. I didn't want to give anyone the wrong impression. It's a bit of a chicken-and-egg problem, too, where it's hard to justify the expense of an audit if few people use the library, and it's hard to find people to use the library when it isn't audited.

Here's the tracking issue for a first security audit: https://github.com/brycx/orion/issues/21.

Near the bottom of that issue, an employee from NCC reached out and said that they may be interested in funding an audit for Orion, though it's been a couple months and that hasn't gone anywhere (that I know of).

> Near the bottom of that issue, an employee from NCC reached out and said that they may be interested in funding an audit for Orion

Small correction: It was actually an employee of Mobilecoin, the company that funded the audits for RustCrypto, which were performed by NCC.

Monocypher has been audited last summer (no bug were found), and it has third party Rust bindings. I guess that could be another alternative?
Probably the Google-sponsored cryptography library you want to use is Tink, whose maintainers include Daniel Bleichenbacher, Sophie Schmieg, and Thai Duong.

https://github.com/google/tink

Probably the Google-sponsored cryptography library you want to use depends on the language you're using... Not much point in using Tink if they don't expose a C-api or any other ergonomic form to make Rust bindings.
Looks like an unusable mess for C++, this seems to be common problem with all of these crypto libraries-- just too many files and too complex of a build system(shocker not everyone uses CMake).
As someone who sometimes uses e.g. FreeBSD, I'll take CMake over someone's hand-crafted Makefile any day.
CMake is the de-facto standard for C++ build systems - its not the simplest, but it does an outstanding job at being widespread and reliable.
Time for some shameless plugs! Themis [1] has been doing this “hard to misuse” thing for quite a few years. It has major focus on interoperability: supports a dozen of languages, with Rust among them, across all major desktop, mobile, and web platforms.

It tries really hard to hide all the crypto mumbo-jumbo from the users so that they don’t have to be experts in algorithm choice and protocol design in order to safely use a library instead of shooting themselves in a foot.

Themis is also a wrapper over OpenSSL/BoringSSL, relying on proven crypto implementations instead of trading a simpler build system for god knows how many sleeper primitive implementation bugs. However, binary packages exist for major distros, so if you don't want to build from source you can avoid that easily.

Also, docs for humans do exist [2], packages exist, etc.

[1]: https://github.com/cossacklabs/themis/

[2]: https://docs.cossacklabs.com/themis/

I see raggi has patched, is this what they’re using in Fuchsia?
> Disclaimer: Mundane is not an officially supported Google product.

Because google support wouldn't be reliable enough /s

But honestly, doesn't the license usually tell such things?

Tensorflow readme.md doesn't have that disclaimer, so I think it really does mean something.
If it's not using Bazel to build, it's probably not used much inside Google.
I am wondering why they don’t use the google/tink project on GitHub where you already have a fair amount of languages (Java, C++, Go, Python) doing AEAD, etc. Just add another language, and reuse the protobuf definitions.
From the BoringSSL readme:

> BoringSSL is a fork of OpenSSL that is designed to meet Google's needs.

> Although BoringSSL is an open source project, it is not intended for general use, as OpenSSL is. We don't recommend that third parties depend upon it. Doing so is likely to be frustrating because there are no guarantees of API or ABI stability.

Well, mundane isn't 3rd party, since it comes out of google as well.
Will this decrypt nacl/sodium messages? If different choices were made so that it wont, what was the motivation?
> In order to avoid errors at link time due to conflicting symbols, we build BoringSSL with a custom prefix for all of its symbols which is based on the name and version of this crate. That way, even if multiple different versions of Mundane are present in the same dependency graph, none of the symbols from one version's BoringSSL will conflict with the symbols from another version's BoringSSL.

This is awesome! I love you!

(comment deleted)