- Even if the XOR of the plaintexts doesn’t help an attacker, it still makes the encryption very brittle [...]
This paragraph is a little weird. Encryption at the point where a nonce has been reused isn't so much brittle as it is broken. You've got P1 XOR P2, neither of which are uniform random keystreams. It's highly structured. You don't need a P1 or P2 leak to begin attacking it.
I'm sure the libraries are quite bad, but I'd also say that there's nothing wrong with not supporting GCM or (heh) GCM-SIV. Very few libraries do provide a GCM-SIV. I don't love GCM, and CTR+HMAC is a perfectly cromulent composed AE system.
- If AES just specified that you pick a random IV and prepend it to the cipher text, then users of crypto libraries wouldn't need to know what an IV is. Right?
- Right, but AES is a primitive used in a lot of protocols, and they might need to do something different with the IV. The source of randomness is also traditionally something that people want control over, because some platforms can have terrible randomness.
Even high-level libraries like crypto_secretbox still take the nonce separately. They do have a combined mode that prepends the authentication code to the cipher text, and most people who just want to encrypt something should probably look at a higher-level interface like this one instead of directly using raw AES libraries.
That being said, providing an interface where the IV is optional and the default value is a constant instead of random is still insane. That wouldn't be out of place in some Underhanded Crypto Contest where the goal is to create subtle bugs.
- AES defines a block cipher (128 bits in, 128 bits out) so there is no "before". I think that you are suggesting that default crypto libraries should work at a higher level where the documentation specifies that the resultant encrypted material is going to be, say, one IV length longer than the unencrypted material. ... which is valid I think... Part of the problem here is that the library is doing some stuff, but perhaps not enough. The function has a name that is in one sense too descriptive and in another sense not descriptive enough. The user doesn't know exactly what sort of thing they are getting.
- As someone else has already said, how you want to handle the IV depends on the application. There is no good default method useful for every case.
It is very rarely necessary to prepend an IV to the cipher text, because normally every application provides something that is useful as an IV, e.g. some unique serial number or some other kind of unique identifier.
For instance, I have an archive of data stored on tape cartridges. I have on my computer a database that allows me to search for information stored on the tapes, which tells me e.g. that the file that I want is in "Tape 174 file 103".
Each tape cartridge (6 TB per cartridge LTO-7) stores about 120 files of 50 GB each, inside which the actual archived data reside.
The archive files are encrypted. Both the 256-bit decryption key and the 128-bit CTR IV are generated simultaneously with a one-way hash function (SHA-384) by hashing some secret data (which is not used for any other purpose) concatenated with the unique name of the file, e.g. "Tape 174 file 103". Thus for any of the encrypted files, both the AES key and the CTR IV are unique and never shared with any other kind of encrypted data.
An AES-CTR encryption/decryption function, e.g. for AES-GCM, should always have separate input parameters for key & IV, without default values, to allow you to use whatever is more suitable in your environment for deriving them.
Hashing a combination of secret data and unique data, like in the example above, is usually a good method for deriving a pair of key and IV for file encryption. For things like encrypting packets of a communication connection, the key is derived only once, to avoid the overhead of switching keys and only the IV changes from packet to packet. Standards like GCM specify how this should be handled. If the value of the IV is known to an adversary, that is normally not harmful, but it is even better when the adversary does not know the value of the IV. (Cryptographic algorithms are designed to resist attacks where the attacker has maximum information, but in practice you also try to minimize the information available to the attacker.)
- Better JS option with randomized IV: https://github.com/Ekwani-Consulting/cryptou
- From the post itself, I am not sure if the author had sent a patch or some sort of a pull-request to the affected entities. Namely pyaes and aes-js.
The response might've been different if the author had already given a patch, in somewhat backward-compatible way. This doesn't even have to be a functional patch, could be a simple `@warning: usage of default IV will cause insecure storage` similar annotations on the affected functions.
Another thing to remark (and which might've been off-putting for the authors of these libraries) that the author had used term mistakes in various places. Of course in an ideal world, ego should not or would not matter, but these libraries both seem to be quite stale and possibly the authors are having other $DAYJOB responsibilities. Making it difficult to fix things that they just receive complaints about. (I am also guessing these are quite many...)
Again in relation to the points above, it might've been better to say: Cryptography evolves over time, last years' best-practices get outdated, vulnerabilities being found, replaced with newer best-practices of this year. Same will happen next year too. It's not a deliberate mistake or any type of incompetency issue, this is a matter of ever-evolving field that we know and understand better...
- This is not about best practises, or something that changed, this has always been something you need to do to make CTR mode actually secure. It was an actual mistake to hard code the IV.
- “ The response might've been different if the author had already given a patch”
For a security related issue? Not sure that is a wise decision.
- While I agree in principle, as of now the latest commit to the pyaes repo and its latest release to pypi are from 2017...
- So the next and final commit should be a message at the top of the README saying the library is unmaintained and contains serious vulnerabilities and users are advised to move to alternative XYZ.
- You get what you paid for. Please don't blame, bully or in any way personally attack the authors - they are not obliged to make changes to their (insecure) code that has been provided as-is.
- This argument doesn't hold because paid cryptography libraries aren't any better and equally provide their code as-is.
- Trail of Bits is charging hefty sums for audits. I suppose they could provide some patches.
- > He immediately created a security-fix branch and collaborated with Trail of Bits to develop stronger protection for his users.
They are willing to collaborate on fixes.
- Patches are a good starting point, and Trail of Bits may have provided them, however they would still need dev time to review, approve, and roll-out...