Observations regarding the encryption specification (as of 2024-11-11) #17
Replies: 1 comment
-
@cipriancraciun Sorry for the delayed reply. Thanks for the review and questions! Encryption
This is true for the original ChaCha20-DJB and XSalsa20. However, libraries do not always provide a 64-bit counter option. See https://pycryptodome.readthedocs.io/en/latest/src/cipher/chacha20.html: only ChCha20-DJB is available with 64-bit counter. On the other hand, some implementations of ChaCha20-DJB still have a 32-bit counter:
https://docs.rs/chacha20/latest/chacha20/ There is a ChaCha20 package in Golang that implements ChaCha20 only with a 32-bit counter: https://pkg.go.dev/golang.org/x/crypto/chacha20 The RFC describes the version with a 32-bit counter; this version is most commonly represented in libraries in the same way, and implementing a nonce counter is easy, so I chose ChaCha20-IETF. CSPRNG
Using a broken entropy source can lead to catastrophic consequences.
Cryptographers advise relying on system entropy sources such as
https://www.latacora.com/blog/2018/04/03/cryptographic-right-answers/
https://github.com/samuel-lucas6/Cryptography-Guidelines#random-numbers I prefer to keep the code simple and not overcomplicate the code with things that won't have a reliably positive effect. |
Beta Was this translation helpful? Give feedback.
-
As requested in volution/z-tokens#39 I'll try to make a few observations on your proposed encryption scheme.
Please note I'm not a cryptographer, thus do take my inputs with a large amount of skepticism. That being said, I have also implemented a similar encryption tool as noted above, with similar properties to
tird
, thus some observations are based on my experience.I'll base all my observations on the published specification as of the following commit (i.e. 2024-11-11):
I'll break my observations into themes to make the discussion simpler, and I'll try to sort them in order of importance.
On salting / nonces
First of all, why having half of the salt / nonce at the beginning, and the other half at the end? (I have some ideas why you might want that, but I would like to know your reasons first.)
Then, why having two independently stored salts, one for pre-hashing the password / key files, and one for applying Argon? I understand that for each purpose, one should have independent salts / nonces / roots, however:
By using the same salt for both the password and key files, they (or their content) are interchangeable. Is this by design?
Padding
Based on what I deduce, the padding (and the salt) are not included in the MAC. Why?
If one changes the salt, it would definitively break the MAC, however if the attacker changes the padding (its contents, not its length), the change might go undetected. This doesn't break the security of the encrypted data, however it might have some other unintended consequences.
As with the salt, why having the padding both at the beginning and at the end of the cipher text? What is the gained advantage?
Key material
The following observations are mainly based on my own work on z-tokens, and I've written more about them here:
Why are you treating the password and key files the same? There is the missed opportunity to apply different (Argon2) work factors for each of these independently, starting from the observation that the key files might hold more entropy (if properly generated), thus might require less Argon2 effort.
Also, see my second article above, if one wants to use a large key file, for example make the risk of key file exfiltration harder in case the size of the key file is much larger than the network bandwidth available, the way you are pre-hashing them (and the way Argon2 works), it allows the attacker to just exfiltrate the hash. (Although in your case, depending on how Blake2b works, this might be saved by the fact that pre-hash depends on the encrypted file salt.)
What happens when the same key file is used twice? You do apply sorting, but do you eliminate duplicates?
Encryption
Why are you using ChaCha20 in a "chunked" fashion? ChaCha20, with a fixed nonce (say all zeroes in your case, because the key is unique for each individual encrypted file) can be used for up to 2^64 512 bits blocks (i.e. more than a modern file-system allows storing in a single file).
MAC
Why are you including in the MAC (Blake2b) input stream also the salt header and footer?
Functionally the MAC key is already dependent (via Argon2 and before that via Blake) on the salt. Furthermore, the cipher text (via the encryption key) is already dependent on the salt due to the same reasons.
(As noted in the padding section, why not include also the padding contents?)
All in all, based on my experience, except for the fact that you aren't including the padding in the MAC, I see no other major issue.
Finally some food-for-thought: what happens when the encryption device doesn't have a trustworthy entropy source?
One solution, that I've seen suggested and I've also employed, is to generate the salt as a hash of some random data (whose quality might be questionable), plus the additional data (in your case the comment), plus the plain-text, all keyed by the initial passphrase / key files.
To properly implement this might require you shuffle a bit the workflow.)
Thus, in the worst case scenario, when the entropy source is completely broken and generates deterministic data, the encryption becomes deterministic, and the attacker can at worst see if the same message is transmitted / stored twice without breaking the encryption.
For more details see AES-GCM-SIV.
Beta Was this translation helpful? Give feedback.
All reactions