Have you seen libsodium [1]? It's a "portable, cross-compilable, installable, packageable fork of NaCl, with a compatible API, and an extended API to improve usability even further." I've been using it in a toy project of mine and so far I'm very impressed!
In practice, people are afraid to use libsodium because it was significantly worked on by people other than DJB, and they weren't sure whether it was vetted by DJB. I've personally seen this as an actual reason for avoiding it. And the concern doesn't seem entirely misplaced.
But why? Would you be afraid to use libreSSL, because the AES implementation wasn't done by Rijmen and Daemon (inventors of AES)? Generally one feature of the Bernstein designs are that they are reasonable simple to implement securely for a competent programmer. By comparison, RSA and the likes are frigging hard to get right because of side channel attacks [1].
No, you're missing something. Nacl isn't secure merely because it implements trustworthy algorithms that its authors themselves design. It's secure because it was designed from the ground up to be secure at an implementation level, and (critically) to be misuse-resistant. Equally importantly, the implementation was done by people with a pedigree in building secure misuse-resistant crypto.
Sodium (which I like and recommend) can't make the same claim. It gets what trustworthiness it has from the fact that it's a slavish fork of Nacl that merely aims to make it compatible with more runtimes.
> It's secure because it was designed from the ground up to be secure at an implementation level, and (critically) to be misuse-resistant.
Ok, interesting. Do you happen to have an example at hand? I don't see where there is room left for much sophistication in the implementation (regarding misuse-resistance), between the well defined algorithms and the strict API that Sodium shares with NaCl. For example lets look at crypto_box (public-key authenticated encryption):
On the crypto side it uses Curve25519 (alias X25519). Its paper has a pretty clear definition how to use the public key bytes as an x-coordinate. Because of the Montgomery multiplication an implementation does not have to calculate the y-coordinate, this eliminates one potential error source. Because of (1) its twist security and because (2) any input in a small subgroup results in a zero element output (neutral element or the (0,0) point), an implementation does not have to check the public key for its validity (another error source eliminated). All these are benefits any implementation will have.
On the interface side crypto_box is as locked down as a nonce based design can be. You enter: (•) Any 32 byte public key value (X25519 makes sure no harm can be done with malicious values), (•) your 32 bytes private key (not malleable by the attacker), (•) the nonce (during decryption any input is ok, because a wrong input will just generate an authentication error; during encryption there is the danger of nonce reuse, which is also present in NaCl) and (•) the plaintext / crypttext (again, because of the mandatory authentication any malicious ciphertext input will be rejected by the library).
So I don't see how a faithful implementation of the interface and algorithm specifications can get much wrong regarding misuse-resistance. Regarding it being secure because it was designed from the ground up to be secure at an implementation level, that is something I expect from any cryptography library. After all, is there any more basic requirement than that? (Well, you could argue being interoperable with other implementations is the most fundamental requirement, but I won't accept such low expectations when I'm asking for a competent developer.)
> It gets what trustworthiness it has from the fact that it's a slavish fork of Nacl that merely aims to make it compatible with more runtimes.
I fully agree that its inheritance from NaCl is Sodiums strongest selling point and its the argument I should have been using instead. I only had it dimly in the back of my heat at that time, though, and wasn't sure enough about it to claim it as a fact. Being less lazy to look it up would have saved me this follow up post ;) (Though I am genuinely interested in my question above.)
I feel bad that I don't have a good response to this comment right when the thread got usefully technical (but maybe 'pbsd will jump in and correct me on something). The fact is that I like libsodium and do not actually believe that the port itself introduced problems --- although I'd be a little concerned about any additional crypto functionality they ever introduced.
I'm just saying: I wouldn't trust libressl if Vincent Rijmen wrote it. :)
I only arrived late here; the thread is already too large to do any proper pedantry.
I like libsodium. It demonstrates that usable packaging is important, something that DJB seems to either ignore or not understand. But I only endorse libsodium as long as you stick to the NaCl API and not the stuff it's been slowly piling on, which may or may not be OK. What it certainly does is make choosing which function to use a lot harder: do I use crypto_secretbox or crypto_aead? crypto_hash, crypto_generichash, or crypto_shorthash? crypto_auth or crypto_generichash?
One response: timing attacks. DJB is one of the most knowledgeable researchers on side-channel attacks, and he leverages this knowledge when both designing _and_ implementing his algorithms.
As well as being the author of the algorithms in NaCl, djb is also a specialist in secure software development, as tptacek mentioned.
You can be reasonably sure that his code is bug free, but they went the extra step of proving the absence of certain types of bugs using static analysis tools. One of the project's deliverables mentioned they used Frama-C to prove the absence of integer overflows, for example. (I will update this comment when I find the specific report.)
Other projects take the traditional approach of trusting that the code looks right until someone proves otherwise.
Edit: The report was probably one of these, which I can't access anymore:
All the deliverables are accessible here [1], and from the most relevant one (D5.4) the short story seems to be:
- The core library's memory safety was verified using VCC;
- A Frama-C plugin was used to verify (a limited form of) side-channel resistance.
Correctness verification seems to have been done by reimplementing NaCl in CAO, a language made during CACE for this purpose. It is not a 1:1 match to C, from what I can tell, so this does not imply correctness of the C code.
However, none of this is verifiable at all. The NaCl code has no VCC or Frama-C annotations, or associated CAO; there is absolutely no mention of this in the NaCl page. So we are forced to take the authors of that report at their word, if we want to believe them at all.
I must say, as a non-participant, I am slightly disappointed in how the deliverables of the CACE project were handled.
Nevertheless, one thing that is “left” from the verification effort is hidden options -experimental-mem-deps and -experimental-path-deps for Frama-C. These are on the automatic side of Frama-C analyses: they require a value analysis to pass on the target code, but they do not require it to be precise. And it is fun to see input length and error conditions pop up as things the execution time depend on (and in the case of a typical AES implementation, the input buffer itself):
How about an inversion of the Turing Test, where human contestants try to convince judges they are a Markov generator? Since it's difficult for people to generate randomness, this should be challenging enough to be interesting. (Not claiming it's intellectually interesting to participate in, however.)
A community should raise money to have libsodium audited by professional crypto auditors. I'm not sure appealing to the ease of implementing DJB's theories is a good idea given how screwed up a lot of the crypto in the field actually is.
All I'm saying is, in general, crypto is hard, and an easy theory doesn't change how hard it is to get an implementation exactly right.
I don't think this is a great use of crypto auditor time, for what it's worth. Microsoft SecureChannel, Truecrypt, libOTR, GnuPG, PHP mcrypt --- all much more important audit targets.
No, I'm afraid to use LibreSSL because the AES implementation wasn't done by Dan Bernstein. The issue is not so much with using algorithm implementations implemented by the algorithm designer as with using algorithm implementations implemented by somebody who knows how to program.
In this particular case, there is the issue that the AES implementation in OpenSSL has been shown in the past to be vulnerable to timing side-channel attacks over the network (again, by Dan Bernstein) and as far as I know has not been through the complete overhaul necessary to fix that problem.
I wouldn't be at all surprised if someone found exploitable side-channel attacks in third-party implementations of Salsa20 or ChaCha in the next few years.
1. https://github.com/jedisct1/libsodium