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