Monocypher is portable (C99/C++), pretty fast, and has low memory footprint (generated binary between 30kB and 60kB). Problem: it isn't trusted yet. (I'd like to run a bug bounty, but I'm not sure how I should go about it.)
TweetNaCl is portable (C89), has low memory footprint, and is made by trustworthy professional cryptographers. Problem: it is slow.
Libsodium is blazing fast on modern processors, has portable implementations, and is trusted. Problem: it is pretty big, and I hate the auto tools.
Edit: of course, those recommendations only hold if you have a trustworthy RNG.
IOW, Cortex M0 territory.
Small IoT is about this size, so I think many will be interested in some answers... any answers.
Say, for securely transmitting sensor data to an x86 server (or similar) without hardcoding symmetric keys on the devices.
If speed doesn't matter, TweetNaCl is even smaller.
If those aren't enough still, you may want to dive in, learn a ton about crypto (starting with https://www.crypto101.io/), and investigate the sponge construction, whose versatility may allow you to shrink the code even more. Perhaps. I'm in over my head at this point.
Neither TweetNaCl nor 'loup-vaillant's library really addresses the low-footprint concern.
I've deployed TLS in 50 KiB flash and 6 Kb RAM. But I could rely on hardware support for some public key operations and could pick a single ciphersuite, and controlled the server end as well.
The boring answer is that you'll need to identify the set of primitives you need and then find a library that matches. I can't think of any single primitive that would break that budget, so it'll depend on how many you need!
1. How much of your flash budget is eaten up by the application?
2. What performance do you need for different use cases and operations?
Generally, RAM is often the least of your problems. And if you are into Cortex M0 or even M0+ territory, your MCU will quite probably sport an AES-128 core. Even if it is slow you should try and use that.(As for the original question, I don't know BearSSL enough to have an opinion. It does seem however to get even further than Monocypher on the constant time thing. Monocypher needs the platform to provide constant time 64-bit multiplication. Most do, but not all.)
Would you be willing to be personally liable for that data leak?
(Put aside the philosophical question of whether or not it's reasonably for developers to be personally liable for their software failures - I'm interested in how far your confidence in your cryptography goes).
Embedded crypto gets weird fast. General recommendations are a little tricky, but: is that device talking to the internet directly or some kind of IoT hub or whatever?
On smaller systems, things get weird. If you can't afford go/openssl, there aren't a lot of things I'm very confident in. BearSSL near the top of the list. That's still double-digits kilobytes of RAM though, so maybe I just ate all your budget. You might be in one of the cases where a NOISE protocol instance is in fact the right answer; depends a little on what else the box is doing and how frequently.
Sorry, I get that it's not a satisfying answer :-) It's complicated!
I would have told you something differently before NOISE and NaCl, particularly Curve25519. We could have done AESCTRHMACSHA256 a long time ago and be basically a good as XSalsa20-Poly1305, but Curve25519 was a huge leap compared to the DH2048 you were likely to do before.
Noise is potentially very interesting, particularly for the embedded space, but it'll be a while before it's safe to use.
IMO the interesting aspect with the development of Noise will be if it can avoid bloat. From the mailing list I can see that there's solid awareness of that risk (would assume Trevor is aware anyway), but it will be interesting to see how the simplicity of pattern API will handle things like signatures, when they're inevitably added. I see at least one Noise-using project has already made the leap on that front.
You’re right that they’ve gotten less scrutiny, but they also need less scrutiny. (I’m not saying more isn’t better.) TLS carries a lot baggage from phlogiston era crypto and is significantly more complex than a dumb NOISE impl.
Note that I qualified my suggestion to “you need to have someone around for that” and that I also mentioned low cost. Specifically, I imagine you’d instantiate NOISE with some boring primitives, ideally in a memory safe language, and spend some time and money pointing Tamarin at it, for example. If you don’t have that, fine, get a tiny TLS stack. I’m just saying that a priori I can’t tell you I have less faith in random mbedTLS-containing ROM vs NOISE-with-reasonable-implementor. (I appreciate that we’re comparing apples to oranges with a concrete ROM vs an abstract protocol.) I also happily appreciate that we’re in territory where the constraints are too restrictive to make blanket recommendations.
Let me rephrase: would you agree that there are platforms that actually shipped with garbage crypto where it’s plausible that they could’ve made NOISE work but didn’t embed a TLS stack because size/perf?
Comparing between those two options is a question of appetite for risk, your threat model, and the level of competency you have available. On the latter note, _at the moment_, I think the subset of people who are capable of taking advantage of Noise would be largely similar to the same subset you could safely task with designing and implementing a custom AKE+messaging protocol from scratch anyway. I think the level of competency you need available is on the very far end of the spectrum. Edit: and on the risk point, even if the library has been eyeballed less, at least you know with mbedTLS that if a bug drops you'll get a patch pretty quickly. If you goof up your Noise impl you're on your tod.
mbed TLS also doesn't seem to be particularly well vetted and has had a number of compromises due to implementation issues.
Cryptography and libraries/standards are gradually building towards a world in which higher-and-higher level abstractions let inexperienced web/high-level application developers build safe systems. The same isn't really true for the lower-end of the embedded space, and consequently you can't really produce an equivalent set of (reasonable) guidelines like the ones linked.