top | item 47109433

(no title)

jopsen | 9 days ago

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?

discuss

order

tux3|9 days ago

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.

pseudohadamard|7 days ago

The problem isn't just the code, it's the use of incredibly brittle but eminently fashionable modes like GCM and CTR, and algorithms like ChaCha20 that only work in CTR mode. Older modes like CBC are pretty abuse-resistant, repeat an IV or use an all-zero IV and the whole thing is very lightly less secure while with something like GCM you get a catastrophic failure of security. And if you use CBC+HMAC you typically get key separation as an inherent property of the setup. The solution isn't to gaze into the middle distance and say "well everyone should just use SIV" (which has problems of its own) but to default to safer modes that don't fail catastrophically when used in the straightforward, obvious way.

upofadown|8 days ago

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.

adrian_b|9 days ago

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