-
Notifications
You must be signed in to change notification settings - Fork 119
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
In-place encoding and decoding #177
Comments
Seconded, I would also find this quite useful, as in-place is what I need in order to plug Given that all the existing resolvers actually do in-place encrypt/decrypt internally, it seems like this should be pretty easy to switch to, while maintaining the existing I know this would change the I'd be happy to implement this and make a pull request. |
After taking an initial shot at implementing and using this, it looks like a better addition would be to have a mutable buffer for encrypt/decrypt, but to make the authentication tag detached. That way the existing |
Taking inspiration from libsodium (https://doc.libsodium.org/secret-key_cryptography/aead/aes-256-gcm), it features combined and detached modes with the auth tag attached (the usual case) and detached respectively. Ofc it is C, so there's no aliasing concerns or bounds checks or slice arguments, would have to prototype and see what's best for Rust. |
Exposing a detached mode seems like the most important - any other interface can be built on top of that. That said, my motivating use case is writing a crate that uses If I were to guess, though - exposing I don't think it's nearly as important to bother changing this stuff in the handshake struct, since total handshake data will be vastly smaller than total transport data. @roshanr95 do you have a particular use case in mind? Would this fill that need? |
For me, it's mainly just not having to create two separate buffers and throw away one every time. Given a detached version, the combined version seems to be just a |
Yep, it'd be exactly that if your interface works with buffers that leave space for the tag. This is a mockup of what could be done for pub fn write_message_in_place_detached(
&mut self,
authtext: &[u8],
buffer: &mut [u8],
) -> Result<[u8; TAGLEN], Error> {
// ...
}
pub fn write_message_in_place(
&mut self,
authtext: &[u8],
buffer: &mut [u8],
) -> Result<(), Error> {
// Verify the buffer has enough space before splitting it
if buffer.len() < TAGLEN { return Err(Error::Input); }
let (buffer, tag_buffer) = buffer.split_at_mut(buffer.len()-TAGLEN);
// Write the message and append the tag
let tag = self.write_message_in_place_detached(authtext, buffer)?;
copy_slices!(tag, tag_buffer);
Ok(())
}
pub fn read_message_in_place_detached(
&mut self,
authtext: &[u8],
buffer: &mut [u8],
tag: &[u8; TAGLEN],
) -> Result<(), Error> {
// ...
}
pub fn read_message_in_place<'a>(
&mut self,
authtext: &[u8],
buffer: &'a mut [u8],
) -> Result<&'a [u8], Error> {
// Verify the buffer has enough space before splitting it
if buffer.len() < TAGLEN { return Err(Error::Decrypt); }
let (buffer, tag_buffer) = buffer.split_at_mut(buffer.len()-TAGLEN);
let tag: &[u8; 16] = (&*tag_buffer).try_into().unwrap();
// Read the message and return the plaintext slice on success
self.read_message_in_place_detached(authtext, buffer, tag)?;
Ok(buffer)
} I've got a working branch that implements the detached versions here: https://github.com/Cognoscan/snow/tree/cipher_in_place The interface into |
@mcginty At this point I've got what I need in a fork, so I can keep developing my own |
The
read_message
andwrite_message
functions take a&
source and&mut
destination to perform encoding and decoding. Currently this necessitates different buffers which seems wasteful. Most crypto libraries (e.g. libsodium) offer in-place encoding and decoding support which is quite convenient. Is this something desirable for snow?The text was updated successfully, but these errors were encountered: