diff --git a/sachy-crypto/src/lib.rs b/sachy-crypto/src/lib.rs --- a/sachy-crypto/src/lib.rs +++ b/sachy-crypto/src/lib.rs @@ -140,7 +140,7 @@ impl SendingState<'_> { pub fn encrypt( &mut self, - msg: &mut alloc::vec::Vec, + msg: &mut dyn aead::Buffer, associated_data: &[u8], ) -> Result<(), ProtoError> { if self.counter.ct_eq(&TransportState::COUNTER_MAX).into() { @@ -169,7 +169,7 @@ impl ReceivingState<'_> { pub fn decrypt( &mut self, - msg: &mut alloc::vec::Vec, + msg: &mut dyn aead::Buffer, associated_data: &[u8], ) -> Result<(), ProtoError> { if self.counter.ct_eq(&TransportState::COUNTER_MAX).into() { @@ -287,13 +287,76 @@ } } +#[derive(Debug)] +pub struct BufferSlice<'a> { + slice: &'a mut [u8], + end: usize, +} + +impl<'a> BufferSlice<'a> { + pub fn new(slice: &'a mut [u8]) -> Self { + Self { + end: slice.len(), + slice, + } + } +} + +impl AsRef<[u8]> for BufferSlice<'_> { + fn as_ref(&self) -> &[u8] { + &self.slice[..self.end] + } +} + +impl AsMut<[u8]> for BufferSlice<'_> { + fn as_mut(&mut self) -> &mut [u8] { + &mut self.slice[..self.end] + } +} + +impl aead::Buffer for BufferSlice<'_> { + fn extend_from_slice(&mut self, other: &[u8]) -> aead::Result<()> { + let index = self.end + other.len(); + + if index > self.slice.len() { + return Err(aead::Error); + } + + self.slice[self.end..index].copy_from_slice(other); + + self.end = index; + + Ok(()) + } + + fn truncate(&mut self, len: usize) { + self.end = len; + } +} + #[cfg(test)] mod tests { use alloc::vec; + use chacha20poly1305::aead::Buffer; use dhkem::Generate; use elliptic_curve::array::Array; use super::*; + + #[test] + fn buffer_slice_works() { + let mut buf = vec![0u8; 128]; + + let mut buf_slice = BufferSlice::new(&mut buf); + + assert_eq!(buf_slice.len(), 128); + assert_eq!(buf_slice.extend_from_slice(&[0,0,0]), Err(aead::Error)); + + buf_slice.truncate(64); + + assert_eq!(buf_slice.extend_from_slice(&[0,0,0,0,0,0]), Ok(())); + assert_eq!(buf_slice.len(), 70); + } #[test] fn handshake_protocol_works() -> Result<(), ProtoError> {