Authenticated Encryption in 2014
22 March 2014 ∞
I see two main use cases: one where relatively short messages or packets are encrypted and another one where files of any size could be encrypted. As the title of this post implies I deliberately ignore1 the recent AEAD submissions made in the CAESAR competition as the process will not be achieved this year. Currently what I think are the most interesting schemes for encrypting and authenticating for these two uses cases:
In a messages scenario you could either use the crypto_secretbox() function implemented in NaCl, it is based on Salsa20 for encryption and Poly1305 for authentication, or you could use ChaCha20 for encryption again combined with Poly1305 as it is currently specified for inclusion in SSL/TLS2. Assuming your protocol uses as expected deterministic nonces and somehow split messages in packets in another layer of your application thus not having to encrypt multi-terabytes files, both schemes are equally fines. The only distinction I would make is that crypto_secretbox() is more tunnel-oriented (or end-to-end) in the sense that as it doesn't provide additional data authentication, you would use it in a context where everything must be encrypted. Whereas the second scheme is a bit more versatile it can mix authenticated plaintext with encrypted-then-authenticated data.
In a file encryption scenario crypto_secretbox() is more adapted as it is based on XSalsa meaning that it accepts larger nonces than a pure Salsa or ChaCha version. Therefore it may safely uses random nonces for encryption while keeping 64 bits internally as counter which is large enough to virtually encrypt files up to 270 bytes. Moreover in this context there is usually no need for authentication of additional data so the lack of this feature in crypto_secretbox() is not a limitation in this case. The scheme based on ChaCha on the other end is not a good fit, it is not conceived for that purpose, it can't use random nonces and its size of ciphertext is limited to 238 bytes.
However for both there is a bigger problem that may prevent them to be used in encrypting large files as their interfaces require that all the data to fit in memory before starting encryption/decryption. Actually stateful encryption and decryption present an important challenge for doing it securely and efficiently in encrypt-then-mac schemes, especially for decryption because you'd want to only let the caller access the plaintext data once the ciphertext has been fully authenticated while at the same time you'd want to buffer the decryption in order to alleviate the memory footprint. Of course you could authenticate and decrypt in two separate passes but in this case it wouldn't be very efficient. So, for now there is no perfect solution for this use case.
-
I also choose not to consider schemes such as AES-CCM and AES-GCM as they'd also introduce other problems and considerations. ↩
-
OpenSSH already implements a variant and it should also be available in the near future as a new EVP_AEAD cipher in OpenSSL. ↩