-
Notifications
You must be signed in to change notification settings - Fork 191
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
aead: generalization of AEADs based on stream ciphers #45
Comments
I think that AEAD is a higher level concept than steam ciphers, so it would make sense to include this functionality to the |
Another issue is that I have deliberately not impl'd the @newpavlov what do you think about adding a trait like |
Ping? I guess this will provide an api which allows encrypting/decrypting "chunk-wise" data? (The current aead api doesn't support this.) |
@cynecx AEADs are inherently all-or-nothing by design. You're probably interested in something like Rogaway's STREAM construction, which we've also discussed adding, and perhaps I can work on soon. This issue pertains to constructing AEADs from unauthenticated stream ciphers in a generic way, whereas the current implementations all contain some repetitive logic. Having a single generic core is also a single place to focus on improvements to e.g. buffering strategies. |
@tarcieri Ehrm, perhaps my comment is more or less ambiguous. I simply seek a way to do aead with known-sized data, however the environment is resource-constrained (limited ram), so I can't fully load the buffer into memory, so I would like to read the data chunks-wise and encrypt/decrypt accordingly. pseudocode: let aead = ChaCha20Poly1305::encrypt(nonce, key);
aead.update(data1); // This encrypts data1 in-place
aead.update(data2);
aead.update(data3); // there are only 3 chuncks, but only one chunk can be loaded into memory at a time.
let tag = aead.finish(); // the aead auth tag |
I'd still suggest using STREAM for that. AEADs are only safe if they do not disclosed unauthenticated data. STREAM allows for chunk-wise processing while still ensuring all chunks are authenticated. |
@tarcieri Sorry I don’t quite understand. How does encrypting in chunks affect safety? Let’s say I want to encrypt 100 bytes. I could simply use the current api as it is. However because the environment has limited memory I can only load 50 bytes at a time, so I basically have to encrypt/hash the first and second part. I don’t see why I shouldn’t use aead here and how would STREAM help here? because I see it mostly as an api limitation. |
Aah, sorry, for some AEAD modes streaming encryption is possible and safe. The security issue is around streaming decryption and exposing unauthenticated plaintexts before the MAC tag has been checked. |
We've three-ish choices for
Associated constants break trait objects completely now, but maybe they'll get fixed eventually, and generic array sucks for trait objects anyways. |
An authentication-only api could help here, so the user can authenticate and then do the decryption/encryption accordingly, however this raises ergonomics issues, like you are required to provide each buffer twice. In terms of efficiency, it would be the same, as the current implementation does two passes anyway. @tarcieri Wouldn't this also prevent RustCrypto/AEADs#74 from happening? |
Doing two passes like that where it can't take ownership of one contiguous buffer carries a risk that an attacker could potentially provide a different ciphertext for the second pass. Generally I'd consider anything besides an all-or-nothing API for decryption pretty risky. |
@tarcieri Yeah, I agree. However, how about we could drop in-place decryption then? I've settled for sodiumoxide's |
I discussed secretstream in the post about Rogaway's STREAM I linked earlier. They accomplish the same goals, but secretstream imposes its own bespoke message framing, and unlike Rogaway's STREAM doesn't have security proofs. |
I agree with Tony that AEADs need all-of-nothing APIs. We're talking about 16 byte MACs in the case of Poly1305, and never more than 32 bytes, so you can afford one tag per chunk even under rather tight memory constraints. Also, your computation time depends primarily upon the total message length, not the number of tags. There are scenarios in which MACs to not work, like fitting data into the expected disk sector size, or 512 byte Tor frames, but normally you want wide block ciphers for this, quite a different construction. |
Continuing the discussion from RustCrypto/AEADs#3 (comment)
It'd be good to have traits for implementing AEADs based on stream ciphers. The
aead
crate presents an interface which is generic enough to incorporate the one AEAD mode based on a block cipher, but most useful AEADs are based on stream ciphers, so it'd be nice to have trait(s) with blanket impls forStatelessAead
which support generic composition based on thestream-cipher
traits.I'm not sure what crate these belong in. Should the
aead
crate have astream-cipher
feature? Or should thestream-cipher
crate have anaead
feature?The text was updated successfully, but these errors were encountered: