Skip to content
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

Support for streaming AES-GCM encryption #556

Open
MasterAwesome opened this issue Oct 21, 2023 · 4 comments
Open

Support for streaming AES-GCM encryption #556

MasterAwesome opened this issue Oct 21, 2023 · 4 comments

Comments

@MasterAwesome
Copy link

I couldn't find an API to support streaming AES-GCM encryption. In a way such the the whole plaintext is sent in chunks and the tag needs to be computed for the entire plaintext.

The goal is to be able to generate partial ciphertexts in memory constrained environments. Is this doable? are there any security implications of this?

@MasterAwesome
Copy link
Author

Ok I was able to implement a streaming version of GCM outside of this crate using it's primitives like ghash. When doing update calls with sizes multiples of block size the tag is generated correctly however when I'm streaming non multiples of block size it computes the wrong tag. My guess is because I'm using ghash.update_padded. Is the only way to buffer the partial blocks until it fills up the ghash block size?

@tarcieri
Copy link
Member

We don't currently support a streaming encryption API for AEADs. If you'd like to propose one, https://github.com/rustcrypto/traits is probably the right place: we use trait-based APIs. There was some discussion of streaming specific to AAD here (and there's been past discussion of this elsewhere but I'd have to dig it up):

RustCrypto/traits#62

As you've discovered, the buffering gets tricky. The rest of the AEAD implementations are designed to be one-shot, which simplifies implementing performant implementations. We have avoided working on streaming APIs like this largely because performance is not where we'd like it to be yet with the one-shot encryption APIs and trying to support streaming encryption just makes everything that much more complicated around all of the things required to make the performance of the one-shot APIs optimal (namely buffering/scheduling).

@MasterAwesome
Copy link
Author

We don't currently support a streaming encryption API for AEADs. If you'd like to propose one, https://github.com/rustcrypto/traits is probably the right place: we use trait-based APIs. There was some discussion of streaming specific to AAD here (and there's been past discussion of this elsewhere but I'd have to dig it up):

RustCrypto/traits#62

As you've discovered, the buffering gets tricky. The rest of the AEAD implementations are designed to be one-shot, which simplifies implementing performant implementations. We have avoided working on streaming APIs like this largely because performance is not where we'd like it to be yet with the one-shot encryption APIs and trying to support streaming encryption just makes everything that much more complicated around all of the things required to make the performance of the one-shot APIs optimal (namely buffering/scheduling).

This makes sense let me work on this a little more and get back to contributing. I have a working solution which buffers only one ghash block at the most, the key stream is always applied to the entire input (buffered CT is stored just for ghash future updates). NIST test vectors pass with different chunks of byte granular update calls, so I'm quite sure it works functionally, now to look at if side channels are introduced if I buffer it the way I am doing :)

It's been a really fun learning process though. I will definitely contribute back when I'm certain about the implementation for design ideas.

@tarcieri
Copy link
Member

I opened RustCrypto/traits#1364 to track a full incremental encryption API

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants
@tarcieri @MasterAwesome and others