-
Notifications
You must be signed in to change notification settings - Fork 17
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Noise box update #523
Comments
In terms of "starter pack" algorithms for the new noise boxes I would Since it is not possible to conceal that these are noise boxes when w.r.t. noise-java, maybe use it, but use BouncyCastle crypto? Since |
I see the performance advances and the ability to switch to different algorithms when one algorithm is exposed to be weak by providing more cipher suites. But: the main argument for using Noise was the indistinguishability of cipher texts (except from the lengths). By adding information on the used algorithms in plain, which might be chosen depending on the device, identities and their drop messages might become observable. I am not in favor of learning the algorithm by trying to decrypt the cipher text as well, since an identity already has to find messages addressed to her by trying to decrypt them. As long as there is no better solution for this issue I would suggest to chose the best algorithms (one symm., one asymm.) regarding security and performance (preferably with reasons for the choices), or stick to the current algorithms. Regarding the implementation, even if using the JCE interface is very clean, I suggest to use established libraries since Noise mostly uses established algorithms. Lastly, I would like to explicitly name the index DMs which would need to be reencrypted due to the KDF update. |
If we go for a single algorithm then I think ChaCha20-Poly1305 is preferable to AES-GCM, since it is better suited for short (<2.5K drop length limit) messages. [though the difference in energy use and runtime is likely academic with all the android stuff going on anyway, and considering this is a chat application and not a 500k-msg/second broker]. That being said there is no problem per se in sticking with AES-GCM. The spec recommends ("Application responsibilities")
|
Okay, that sounds reasonable. Especially since mobile devices might suffer from receiving drop messages as soon as real drop ID collisions are provoked. Yes, prepending a version field is sensible but providing multiple cipher suites, which usage depends on the client device, could reveal information on the client. |
I see/understand your concerns there |
spike needed |
(don't know what spike means in this context, but: )
|
spike is devmanagement term for "someone needs to spend an hour / a couple hours to see how this can be done and how much work that may be". |
We can and should update the noise protocol. When we do this, we should first switch to another crypto provider to remove as much self-maintained code as possible. After we switched to another cryptoprovider (libsodium or bouncy/spongycastle) for the noise box crypto, we can implement both KDF methods and increment the version byte of the encrypted drop message. |
|
We will take a look at libsodium instead of Bouncycastle. Even if we can't replace TweetNaCl, maybe we can replace BouncyCastle. From an end user perspective, this would probably increase the performance. Replacing both BouncyCastle and TweetNaCl would be great, since we wouldn't have to maintain the TweetNaCl bindings ourselves. They are fiddly on Android and an annoyance to set up on desktop development systems. I'll port our noise stuff to libsodium and run them side by side for testing, then can we implemented the updated noise protocol. This will of course be just a proof of concept and will have to be reviewed by people who actually understand the crypto stuff before we put it into production. From a software perspective, this means that the CryptoUtils will become an Interface with our current implementation as the default implementation and a drop in replacement with the alternative implementation. |
I think it would be wise to split it up first, since it holds unrelated functionality in one class at the moment (encrypting files, encrypting noiseboxes... at least these two should be in separate interfaces). |
Indeed. I'll make one noise-stuff interface and one symmetric-stuff interface at least. Maybe I'll split it up further. |
So...I evaluated this libsodium stuff. My findings are:
Spike done. |
To thoroughly discuss the end of this spike it would be good to have all points mentioned (see above) here addressed in some way. E.g.:
|
Primitives:
TweetNaCl vs. *Castle vs libsodium: We don't use TweetNaCl, only a subset of it, implementing Curve25519 crypto and nothing else. The full TweetNaCl is (API wise) identical to NaCl identical to libsodium. All of these implement: ChaCha20-Poly1305, BLAKE2 or SHA2-512, Curve25519, Ed25519. None of them is alone sufficient to support the current state of our crypto. Because AES-GCM is only available if hardware support is available, which is nothing we can rely on. *Castle implements all crypto in pure Java. I have a bad feeling about that. It doesn't seem to have ever been audited / reviewed. In recent versions it also includes Curve25519. OpenSSL (in recent versions) has all the algos we need (including Curve25519, which is more accurately called X25519 in libcrypto). This is what eg. Signal uses (and of course countless others). Even though OpenSSL has had many vulnerabilities in the past (many of these were in fact developed with|for OpenSSL, and first patched in it - only later other libraries where updated), and still suffers from some poor APIs, I think it is a solid choice if cross-platform crypto is needed with many primitives. |
Comparison between the libs: TweetNaCl:
Bouncy/Spongy:
Sodium:
OpenSSL:
|
Oh right, I totally forgot how slow the castles are. |
Currently about 20s for a 20mb file slow :( |
For detailed benchmarks of OpenSSL across many different CPUs I'll refer to: borgbackup/borg#45 (comment) These more or less transfer 1:1 to other optimized libraries (libsodium/NaCl) Notice how even the little ARM Cortex A53 manages to crank out almost 250 MB/s with ChaCha20-Poly1305. Also notice how BLAKE2 is not always the better choice compared to SHA-2 (the aforementioned ARM box w/ NEON). Btw.: AES-OCB may look very nice in these benchmarks, almost always outperforming everyone else, but bear in mind that it comes with a license fee when deployed in a non-OSI-licensed piece of software. |
@jan-schreib If you'd like to take a look at the build-pain for libsodium-jni, esp. on Windows. Maybe it is not so bad… |
When implementing the update we also want to work towards personalizing the noise boxes, since they are used in different context and an attacker should not be able to swap noise boxes from different contexts (even if their contents might not make sense in the swapped context, blocking the possibility at this level makes it easier and safer to use)¹. In noise protocol terms this would mean that we assign a bytestring to every context and use it as the prologue (which is hashed by both parties into the handshake hash For example, noise boxes for the index API would get ¹ The cryptographic principle here is called the Horton principle: authenticate what is meant, not what is said. |
Our current noise implementation is not compliant to the current standard.
IMO the only difference to a proper Noise_X_25519_AESGCM_SHA512 is the KDF which was changed from a homebrew version to the independentenly used and published HKDF.
Since the change would invalidate all drop messages etc., these need to be re-encrypted when upgrading.
When making the change, a provision for proper crypto agility should be made as well. E.g. a type byte prefix or a plain-text prefix. Currently this would be possible via SUITE_NAME, since SUITE_NAME is mixed into the KDF this would equire a trial decryption for each possible algorithm, therefore the approach is not feasible.
There is a now a current noise implementation by Rhys Weatherley available: https://github.com/rweather/noise-java (MIT). It is based on the JCE interface and therefore implements a good bit of crypto (25519, 448, ChaCha, Blake) in Java itself. Development of it started last month.
Pinging @roeslpa
The text was updated successfully, but these errors were encountered: