diff --git a/.cirrus.yml b/.cirrus.yml index 3e97767..bf8fb43 100644 --- a/.cirrus.yml +++ b/.cirrus.yml @@ -7,18 +7,18 @@ task: - rustup component add rustfmt - cargo fmt -- --check build_script: - - cargo build --verbose --all + - cargo build --verbose --all-features - name: linux (nightly) container: image: rustlang/rust:nightly build_script: - - cargo build --verbose --all - - cargo bench --verbose --all --no-run + - cargo build --verbose --all-features + - cargo bench --verbose --all-features --no-run cargo_cache: folder: $CARGO_HOME/registry test_script: - - cargo test --all - - cargo test --all --features=aesgcm + - cargo test --features=c20p1305 + - cargo test --features=aesgcm before_cache_script: rm -rf $CARGO_HOME/registry/index diff --git a/Cargo.toml b/Cargo.toml index e9382ac..7e1c7d7 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,8 +1,8 @@ [package] name = "sio" -version = "0.2.0" +version = "0.3.0" authors = ["Andreas Auernhammer "] -edition = "2018" +edition = "2021" description = "Secure IO" license = "MIT" @@ -24,4 +24,4 @@ c20p1305 = ["ring"] aesgcm = ["ring"] [dependencies] -ring = { version = "0.14.6", optional = true } +ring = { version = "0.16", optional = true } diff --git a/benches/writer.rs b/benches/writer.rs index 82e7f6b..533897c 100644 --- a/benches/writer.rs +++ b/benches/writer.rs @@ -10,19 +10,21 @@ use std::{io, io::Write}; extern crate test; use test::Bencher; +#[allow(clippy::upper_case_acronyms)] #[cfg(feature = "aesgcm")] type AEAD = AES_256_GCM; +#[allow(clippy::upper_case_acronyms)] #[cfg(not(feature = "aesgcm"))] type AEAD = CHACHA20_POLY1305; fn buffer_size() -> usize { - const BUFFER_SIZE: &'static str = "SIO_BUF_SIZE"; + const BUFFER_SIZE: &str = "SIO_BUF_SIZE"; if let Ok(value) = std::env::var(BUFFER_SIZE) { let value: usize = value .as_str() .parse() - .expect(format!("'{}' is not a number", BUFFER_SIZE).as_str()); + .unwrap_or_else(|_| panic!("'{}' is not a number", BUFFER_SIZE)); 1024 * value } else { sio::BUF_SIZE @@ -35,14 +37,15 @@ fn encrypt_write_1k(b: &mut Bencher) -> io::Result<()> { let mut writer = EncWriter::with_buffer_size( io::sink(), &key, - Nonce::new([0; Nonce::::SIZE]), + Nonce::new([0; Nonce::SIZE]), Aad::empty(), buffer_size(), ) .expect("Failed to create EncWriter"); + #[allow(clippy::identity_op)] let buf: &[u8] = &[0; 1 * 1024]; - b.bytes = 1 * 1024; + b.bytes = buf.len() as u64; b.iter(|| { writer.write_all(buf).expect("encryption failed"); }); @@ -55,7 +58,7 @@ fn encrypt_write_64k(b: &mut Bencher) -> io::Result<()> { let mut writer = EncWriter::with_buffer_size( io::sink(), &key, - Nonce::new([0; Nonce::::SIZE]), + Nonce::new([0; Nonce::SIZE]), Aad::empty(), buffer_size(), ) @@ -75,7 +78,7 @@ fn encrypt_write_512k(b: &mut Bencher) -> io::Result<()> { let mut writer = EncWriter::with_buffer_size( io::sink(), &key, - Nonce::new([0; Nonce::::SIZE]), + Nonce::new([0; Nonce::SIZE]), Aad::empty(), buffer_size(), ) @@ -95,7 +98,7 @@ fn encrypt_write_1mb(b: &mut Bencher) -> io::Result<()> { let mut writer = EncWriter::with_buffer_size( io::sink(), &key, - Nonce::new([0; Nonce::::SIZE]), + Nonce::new([0; Nonce::SIZE]), Aad::empty(), buffer_size(), ) @@ -116,13 +119,13 @@ fn decrypt_write_1k(b: &mut Bencher) -> io::Result<()> { DecWriter::with_buffer_size( io::sink(), &key, - Nonce::new([0; Nonce::::SIZE]), + Nonce::new([0; Nonce::SIZE]), Aad::empty(), buffer_size(), ) .expect("Failed to create DecWriter"), &key, - Nonce::new([0; Nonce::::SIZE]), + Nonce::new([0; Nonce::SIZE]), Aad::empty(), buffer_size(), ) @@ -143,13 +146,13 @@ fn decrypt_write_64k(b: &mut Bencher) -> io::Result<()> { DecWriter::with_buffer_size( io::sink(), &key, - Nonce::new([0; Nonce::::SIZE]), + Nonce::new([0; Nonce::SIZE]), Aad::empty(), buffer_size(), ) .expect("Failed to create DecWriter"), &key, - Nonce::new([0; Nonce::::SIZE]), + Nonce::new([0; Nonce::SIZE]), Aad::empty(), buffer_size(), ) @@ -170,13 +173,13 @@ fn decrypt_write_512k(b: &mut Bencher) -> io::Result<()> { DecWriter::with_buffer_size( io::sink(), &key, - Nonce::new([0; Nonce::::SIZE]), + Nonce::new([0; Nonce::SIZE]), Aad::empty(), buffer_size(), ) .expect("Failed to create DecWriter"), &key, - Nonce::new([0; Nonce::::SIZE]), + Nonce::new([0; Nonce::SIZE]), Aad::empty(), buffer_size(), ) @@ -197,13 +200,13 @@ fn decrypt_write_1mb(b: &mut Bencher) -> io::Result<()> { DecWriter::with_buffer_size( io::sink(), &key, - Nonce::new([0; Nonce::::SIZE]), + Nonce::new([0; Nonce::SIZE]), Aad::empty(), buffer_size(), ) .expect("Failed to create DecWriter"), &key, - Nonce::new([0; Nonce::::SIZE]), + Nonce::new([0; Nonce::SIZE]), Aad::empty(), buffer_size(), ) diff --git a/src/aead.rs b/src/aead.rs index 60240b7..993309c 100644 --- a/src/aead.rs +++ b/src/aead.rs @@ -2,7 +2,7 @@ // Use of this source code is governed by a license that can be // found in the LICENSE file. -use crate::error::{Exceeded, Invalid, NotAuthentic}; +use crate::error::{Invalid, NotAuthentic}; use std::marker::PhantomData; pub trait Algorithm { @@ -10,18 +10,16 @@ pub trait Algorithm { const NONCE_LEN: usize; const TAG_LEN: usize; - fn new(key: &[u8; 32]) -> Self; + fn new(key: &[u8; 32], nonce: Nonce) -> Self; fn seal_in_place<'a>( - &self, - nonce: &[u8; 12], + &mut self, aad: &[u8], - in_out: &'a mut [u8], + in_out: &'a mut Vec, ) -> Result<&'a [u8], Invalid>; fn open_in_place<'a>( - &self, - nonce: &[u8; 12], + &mut self, aad: &[u8], in_out: &'a mut [u8], ) -> Result<&'a [u8], NotAuthentic>; @@ -43,17 +41,18 @@ impl AsRef<[u8; 32]> for Key { } } -pub struct Nonce([u8; 8], PhantomData); +#[derive(Copy, Clone)] +pub struct Nonce([u8; 8]); -impl Nonce { - pub const SIZE: usize = A::NONCE_LEN - 4; +impl Nonce { + pub const SIZE: usize = ::ring::aead::NONCE_LEN - 4; pub fn new(bytes: [u8; 8]) -> Self { - Nonce(bytes, PhantomData) + Nonce(bytes) } } -impl AsRef<[u8; 8]> for Nonce { +impl AsRef<[u8; 8]> for Nonce { fn as_ref(&self) -> &[u8; 8] { &self.0 } @@ -81,7 +80,7 @@ impl<'a, A: Algorithm> Clone for Aad<'a, A> { impl<'a, A: Algorithm> AsRef<[u8]> for Aad<'a, A> { #[inline] fn as_ref(&self) -> &[u8] { - &self.0 + self.0 } } @@ -92,29 +91,39 @@ impl<'a, A: Algorithm> From<&'a [u8]> for Aad<'a, A> { } } -pub(crate) struct Counter { +pub(crate) struct Counter { nonce: [u8; 12], pub seq_num: u32, exceeded: bool, - phantom_data: PhantomData, } -impl Counter { - pub fn zero(nonce: Nonce) -> Self { +impl Counter { + fn new(nonce: Nonce, seq_num: u32) -> Self { let mut value = [0; 12]; - &mut value[..8].copy_from_slice(&nonce.0); + value[..8].copy_from_slice(&nonce.0); Counter { nonce: value, - seq_num: 0, + seq_num, exceeded: false, - phantom_data: PhantomData, } } #[inline] - pub fn next<'a>(&'a mut self) -> Result<&'a [u8; 12], Exceeded> { + pub fn zero(nonce: Nonce) -> Self { + Self::new(nonce, 0) + } + + #[inline] + pub fn one(nonce: Nonce) -> Self { + Self::new(nonce, 1) + } +} + +impl ::ring::aead::NonceSequence for Counter { + #[inline] + fn advance(&mut self) -> Result<::ring::aead::Nonce, ::ring::error::Unspecified> { if self.exceeded { - return Err(Exceeded); + return Err(::ring::error::Unspecified); } self.nonce[8..].copy_from_slice(self.seq_num.to_le_bytes().as_ref()); @@ -123,6 +132,6 @@ impl Counter { } else { self.exceeded = true; } - Ok(&self.nonce) + Ok(::ring::aead::Nonce::assume_unique_for_key(self.nonce)) } } diff --git a/src/aesgcm.rs b/src/aesgcm.rs index 80af9f6..c791036 100644 --- a/src/aesgcm.rs +++ b/src/aesgcm.rs @@ -4,14 +4,15 @@ extern crate ring; -use crate::aead::Algorithm; +use crate::aead::{Algorithm, Counter}; use crate::error::{Invalid, NotAuthentic}; -use ring::aead; +use crate::Nonce; +use ring::aead::{self, BoundKey}; #[allow(non_camel_case_types)] pub struct AES_256_GCM { - seal_key: aead::SealingKey, - open_key: aead::OpeningKey, + seal_key: aead::SealingKey, + open_key: aead::OpeningKey, } impl Algorithm for AES_256_GCM { @@ -19,44 +20,39 @@ impl Algorithm for AES_256_GCM { const NONCE_LEN: usize = 96 / 8; const TAG_LEN: usize = 128 / 8; - fn new(key: &[u8; Self::KEY_LEN]) -> Self { + fn new(key: &[u8; Self::KEY_LEN], nonce: Nonce) -> Self { Self { - seal_key: aead::SealingKey::new(&aead::AES_256_GCM, key).unwrap(), - open_key: aead::OpeningKey::new(&aead::AES_256_GCM, key).unwrap(), + seal_key: aead::SealingKey::new( + aead::UnboundKey::new(&aead::AES_256_GCM, key).unwrap(), + Counter::zero(nonce), + ), + open_key: aead::OpeningKey::new( + aead::UnboundKey::new(&aead::AES_256_GCM, key).unwrap(), + Counter::one(nonce), + ), } } fn seal_in_place<'a>( - &self, - nonce: &[u8; Self::NONCE_LEN], + &mut self, aad: &[u8], - in_out: &'a mut [u8], + in_out: &'a mut Vec, ) -> Result<&'a [u8], Invalid> { - match aead::seal_in_place( - &self.seal_key, - aead::Nonce::assume_unique_for_key(*nonce), - aead::Aad::from(aad), - in_out, - Self::TAG_LEN, - ) { - Ok(len) => Ok(&in_out[..len]), + match self + .seal_key + .seal_in_place_append_tag(aead::Aad::from(aad), in_out) + { + Ok(()) => Ok(in_out.as_slice()), Err(_) => Err(Invalid::BufSize), } } fn open_in_place<'a>( - &self, - nonce: &[u8; Self::NONCE_LEN], + &mut self, aad: &[u8], in_out: &'a mut [u8], ) -> Result<&'a [u8], NotAuthentic> { - match aead::open_in_place( - &self.open_key, - aead::Nonce::assume_unique_for_key(*nonce), - aead::Aad::from(aad), - 0, - in_out, - ) { + match self.open_key.open_in_place(aead::Aad::from(aad), in_out) { Ok(val) => Ok(val), Err(_) => Err(NotAuthentic), } diff --git a/src/c20p1305.rs b/src/c20p1305.rs index c3ceabe..cc2dea5 100644 --- a/src/c20p1305.rs +++ b/src/c20p1305.rs @@ -4,14 +4,15 @@ extern crate ring; -use crate::aead::Algorithm; +use crate::aead::{Algorithm, Counter}; use crate::error::{Invalid, NotAuthentic}; -use ring::aead; +use crate::Nonce; +use ring::aead::{self, BoundKey}; #[allow(non_camel_case_types)] pub struct CHACHA20_POLY1305 { - seal_key: aead::SealingKey, - open_key: aead::OpeningKey, + seal_key: aead::SealingKey, + open_key: aead::OpeningKey, } impl Algorithm for CHACHA20_POLY1305 { @@ -19,44 +20,39 @@ impl Algorithm for CHACHA20_POLY1305 { const NONCE_LEN: usize = 96 / 8; const TAG_LEN: usize = 128 / 8; - fn new(key: &[u8; Self::KEY_LEN]) -> Self { + fn new(key: &[u8; Self::KEY_LEN], nonce: Nonce) -> Self { Self { - seal_key: aead::SealingKey::new(&aead::CHACHA20_POLY1305, key).unwrap(), - open_key: aead::OpeningKey::new(&aead::CHACHA20_POLY1305, key).unwrap(), + seal_key: aead::SealingKey::new( + aead::UnboundKey::new(&aead::CHACHA20_POLY1305, key).unwrap(), + Counter::zero(nonce), + ), + open_key: aead::OpeningKey::new( + aead::UnboundKey::new(&aead::CHACHA20_POLY1305, key).unwrap(), + Counter::one(nonce), + ), } } fn seal_in_place<'a>( - &self, - nonce: &[u8; Self::NONCE_LEN], + &mut self, aad: &[u8], - in_out: &'a mut [u8], + in_out: &'a mut Vec, ) -> Result<&'a [u8], Invalid> { - match aead::seal_in_place( - &self.seal_key, - aead::Nonce::assume_unique_for_key(*nonce), - aead::Aad::from(aad), - in_out, - Self::TAG_LEN, - ) { - Ok(len) => Ok(&in_out[..len]), + match self + .seal_key + .seal_in_place_append_tag(aead::Aad::from(aad), in_out) + { + Ok(()) => Ok(in_out.as_slice()), Err(_) => Err(Invalid::BufSize), } } fn open_in_place<'a>( - &self, - nonce: &[u8; Self::NONCE_LEN], + &mut self, aad: &[u8], in_out: &'a mut [u8], ) -> Result<&'a [u8], NotAuthentic> { - match aead::open_in_place( - &self.open_key, - aead::Nonce::assume_unique_for_key(*nonce), - aead::Aad::from(aad), - 0, - in_out, - ) { + match self.open_key.open_in_place(aead::Aad::from(aad), in_out) { Ok(val) => Ok(val), Err(_) => Err(NotAuthentic), } diff --git a/src/error.rs b/src/error.rs index c8eb4d9..0fec4cb 100644 --- a/src/error.rs +++ b/src/error.rs @@ -89,19 +89,15 @@ pub enum Invalid { BufSize, } -impl Error for Invalid { - fn description(&self) -> &str { - match self { - Invalid::Key => "sio::Invalid::Key", - Invalid::Nonce => "sio::Invalid::Nonce", - Invalid::BufSize => "sio::Invalid::BufSize", - } - } -} +impl Error for Invalid {} impl fmt::Display for Invalid { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - write!(f, "{}", self.description()) + match self { + Invalid::Key => "sio::Invalid::Key".fmt(f), + Invalid::Nonce => "sio::Invalid::Nonce".fmt(f), + Invalid::BufSize => "sio::Invalid::BufSize".fmt(f), + } } } diff --git a/src/lib.rs b/src/lib.rs index f801b81..239e6ab 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -65,7 +65,7 @@ //! //! You can encrypt data by wrapping a writer with an `EncWriter`. The `EncWriter` is generic over //! an authenticated encryption algorithm and takes a `Key`, a `Nonce` and some `Aad`. -//! ```norun +//! ```no_run,ignore //! use std::io; //! use std::io::Write; //! use std::fs::File; @@ -78,7 +78,7 @@ //! let mut f = EncWriter::new( //! NopCloser::wrap(File::create("foo.txt")?), //! &secret_key, -//! Nonce::new([0; Nonce::::SIZE]), +//! Nonce::new([0; Nonce::SIZE]), //! Aad::empty(), //! ); //! @@ -97,7 +97,7 @@ //! Similarly, you can decrypt data by using a `DecWriter` instead of an `EncWriter`. The //! `DecWriter` is also generic over an authenticated encryption algorithm and expects the //! same `Key`, `Nonce` and `Aad` used before to encrypt the data. -//! ```norun +//! ```no_run,ignore //! use std::io; //! use std::io::{Read, Write}; //! use std::fs::File; @@ -110,7 +110,7 @@ //! let mut out = DecWriter::new( //! NopCloser::wrap(io::stdout()), //! &secret_key, -//! Nonce::new([0; Nonce::::SIZE]), +//! Nonce::new([0; Nonce::SIZE]), //! Aad::empty(), //! ); //! diff --git a/src/utils.rs b/src/utils.rs index f7df7c6..685f29b 100644 --- a/src/utils.rs +++ b/src/utils.rs @@ -63,7 +63,7 @@ impl Close for io::LineWriter { /// // Make sure you use an unique key-nonce combination! /// // Reusing a nonce value for the same secret key breaks /// // the security of the encryption algorithm. -/// let nonce = Nonce::new([0; Nonce::::SIZE]); +/// let nonce = Nonce::new([0; Nonce::SIZE]); /// /// // You must be able to re-generate this aad to decrypt /// // the ciphertext again. Usually, it's stored together with diff --git a/src/writer.rs b/src/writer.rs index 9a4d034..f7ac661 100644 --- a/src/writer.rs +++ b/src/writer.rs @@ -2,7 +2,6 @@ // Use of this source code is governed by a license that can be // found in the LICENSE file. -use super::aead::Counter; use super::{Aad, Algorithm, Invalid, Key, Nonce, BUF_SIZE, MAX_BUF_SIZE}; use std::io; use std::io::Write; @@ -40,7 +39,7 @@ use std::thread::panicking; /// // Make sure you use an unique key-nonce combination! /// // Reusing a nonce value for the same secret key breaks /// // the security of the encryption algorithm. -/// let nonce = Nonce::new([0; Nonce::::SIZE]); +/// let nonce = Nonce::new([0; Nonce::SIZE]); /// /// // You must be able to re-generate this aad to decrypt /// // the ciphertext again. Usually, it's stored together with @@ -58,10 +57,9 @@ use std::thread::panicking; pub struct EncWriter { inner: W, algorithm: A, - buffer: Box<[u8]>, + buffer: Vec, pos: usize, buf_size: usize, - nonce: Counter, aad: [u8; 16 + 1], // TODO: replace with [u8; A::TAG_LEN + 1] // If an error occurs, we must fail any subsequent write of flush operation. @@ -96,7 +94,7 @@ impl EncWriter { /// // Make sure you use an unique key-nonce combination! /// // Reusing a nonce value for the same secret key breaks /// // the security of the encryption algorithm. - /// let nonce = Nonce::new([0; Nonce::::SIZE]); + /// let nonce = Nonce::new([0; Nonce::SIZE]); /// /// // You must be able to re-generate this aad to decrypt /// // the ciphertext again. Usually, it's stored together with @@ -111,7 +109,7 @@ impl EncWriter { /// /// writer.close().unwrap(); // Complete the encryption process explicitly. /// ``` - pub fn new(inner: W, key: &Key, nonce: Nonce, aad: Aad) -> Self { + pub fn new(inner: W, key: &Key, nonce: Nonce, aad: Aad) -> Self { Self::with_buffer_size(inner, key, nonce, aad, BUF_SIZE).unwrap() } @@ -143,7 +141,7 @@ impl EncWriter { /// // Make sure you use an unique key-nonce combination! /// // Reusing a nonce value for the same secret key breaks /// // the security of the encryption algorithm. - /// let nonce = Nonce::new([0; Nonce::::SIZE]); + /// let nonce = Nonce::new([0; Nonce::SIZE]); /// /// // You must be able to re-generate this aad to decrypt /// // the ciphertext again. Usually, it's stored together with @@ -168,32 +166,27 @@ impl EncWriter { pub fn with_buffer_size( inner: W, key: &Key, - nonce: Nonce, + nonce: Nonce, aad: Aad, buf_size: usize, ) -> Result { if buf_size == 0 || buf_size > MAX_BUF_SIZE { return Err(Invalid::BufSize); } - let algorithm = A::new(key.as_ref()); - let mut nonce = Counter::zero(nonce); - let mut associated_data = [0; 1 + 16]; + let mut algorithm = A::new(key.as_ref(), nonce); + let mut associated_data = Default::default(); algorithm - .seal_in_place( - &nonce.next().unwrap(), - aad.as_ref(), - &mut associated_data[1..], - ) + .seal_in_place(aad.as_ref(), &mut associated_data) .unwrap(); + associated_data.insert(0, 0); Ok(EncWriter { - inner: inner, - algorithm: A::new(key.as_ref()), - buffer: vec![0; buf_size + A::TAG_LEN].into_boxed_slice(), + inner, + algorithm, + buffer: vec![0; buf_size], pos: 0, - buf_size: buf_size, - nonce: nonce, - aad: associated_data, + buf_size, + aad: associated_data.try_into().unwrap(), errored: false, closed: false, }) @@ -213,19 +206,8 @@ impl EncWriter { /// Encrypt and authenticate the buffer and write the ciphertext /// to the inner writer. fn write_buffer(&mut self, len: usize) -> io::Result<()> { - let nonce = match self.nonce.next() { - Ok(nonce) => nonce, - Err(err) => { - self.errored = true; - return Err(err.into()); - } - }; - - let ciphertext = match self.algorithm.seal_in_place( - nonce, - &self.aad, - &mut self.buffer[..len + A::TAG_LEN], - ) { + self.buffer.truncate(len); + let ciphertext = match self.algorithm.seal_in_place(&self.aad, &mut self.buffer) { Ok(ciphertext) => ciphertext, Err(err) => { self.errored = true; @@ -309,14 +291,12 @@ impl Drop for EncWriter { fn drop(&mut self) { // We must not check whether the EncWriter has been closed if // we encountered an error during a write or flush call. - if !self.errored { - if !self.closed { - // We don't want to panic again if some code (between - // EncWriter::new(...) and EncWriter.close()) already - // panic'd. Otherwise we would cause a "double-panic". - if !panicking() { - panic!("EncWriter must be closed explicitly via the close method before being dropped!") - } + if !self.errored && !self.closed { + // We don't want to panic again if some code (between + // EncWriter::new(...) and EncWriter.close()) already + // panic'd. Otherwise we would cause a "double-panic". + if !panicking() { + panic!("EncWriter must be closed explicitly via the close method before being dropped!") } } } @@ -353,7 +333,7 @@ impl Drop for EncWriter { /// let key: Key = Key::new([0; Key::::SIZE]); /// /// // Use the same nonce that was used during encryption. -/// let nonce = Nonce::new([0; Nonce::::SIZE]); +/// let nonce = Nonce::new([0; Nonce::SIZE]); /// /// // Use the same associated data (AAD) that was used during encryption. /// let aad = Aad::from("Some authenticated but not encrypted data".as_bytes()); @@ -376,7 +356,6 @@ pub struct DecWriter { buffer: Box<[u8]>, pos: usize, buf_size: usize, - nonce: Counter, aad: [u8; 16 + 1], // TODO: replace with [u8; A::TAG_LEN + 1] // If an error occurs, we must fail any subsequent write of flush operation. @@ -409,7 +388,7 @@ impl DecWriter { /// let key: Key = Key::new([0; Key::::SIZE]); /// /// // Use the same nonce that was used during encryption. - /// let nonce = Nonce::new([0; Nonce::::SIZE]); + /// let nonce = Nonce::new([0; Nonce::SIZE]); /// /// // Use the same associated data (AAD) that was used during encryption. /// let aad = Aad::from("Some authenticated but not encrypted data".as_bytes()); @@ -428,7 +407,7 @@ impl DecWriter { /// /// println!("{}", String::from_utf8_lossy(plaintext.as_slice())); // Let's print the plaintext. /// ``` - pub fn new(inner: W, key: &Key, nonce: Nonce, aad: Aad) -> Self { + pub fn new(inner: W, key: &Key, nonce: Nonce, aad: Aad) -> Self { Self::with_buffer_size(inner, key, nonce, aad, BUF_SIZE).unwrap() } @@ -459,7 +438,7 @@ impl DecWriter { /// let key: Key = Key::new([0; Key::::SIZE]); /// /// // Use the same nonce that was used for encryption. - /// let nonce = Nonce::new([0; Nonce::::SIZE]); + /// let nonce = Nonce::new([0; Nonce::SIZE]); /// /// // Use the same associated data (AAD) that was used for encryption. /// let aad = Aad::from("Some authenticated but not encrypted data".as_bytes()); @@ -488,32 +467,27 @@ impl DecWriter { pub fn with_buffer_size( inner: W, key: &Key, - nonce: Nonce, + nonce: Nonce, aad: Aad, buf_size: usize, ) -> Result { if buf_size == 0 || buf_size > MAX_BUF_SIZE { return Err(Invalid::BufSize); } - let algorithm = A::new(key.as_ref()); - let mut nonce = Counter::zero(nonce); - let mut associated_data = [0; 1 + 16]; + let mut algorithm = A::new(key.as_ref(), nonce); + let mut associated_data = Vec::with_capacity(16 + 1); algorithm - .seal_in_place( - &nonce.next().unwrap(), - aad.as_ref(), - &mut associated_data[1..], - ) + .seal_in_place(aad.as_ref(), &mut associated_data) .unwrap(); + associated_data.insert(0, 0); Ok(DecWriter { - inner: inner, - algorithm: A::new(key.as_ref()), + inner, + algorithm, buffer: vec![0; buf_size + A::TAG_LEN].into_boxed_slice(), pos: 0, - buf_size: buf_size, - nonce: nonce, - aad: associated_data, + buf_size, + aad: associated_data.try_into().unwrap(), errored: false, closed: false, }) @@ -533,26 +507,17 @@ impl DecWriter { /// Decrypt and verifies the buffer and write the plaintext /// to the inner writer. fn write_buffer(&mut self, len: usize) -> io::Result<()> { - let nonce = match self.nonce.next() { - Ok(nonce) => nonce, + let plaintext = match self + .algorithm + .open_in_place(&self.aad, &mut self.buffer[..len]) + { + Ok(plaintext) => plaintext, Err(err) => { self.errored = true; return Err(err.into()); } }; - let plaintext = - match self - .algorithm - .open_in_place(nonce, &self.aad, &mut self.buffer[..len]) - { - Ok(plaintext) => plaintext, - Err(err) => { - self.errored = true; - return Err(err.into()); - } - }; - match self.inner.write_all(plaintext) { Ok(v) => Ok(v), Err(err) => { @@ -629,14 +594,12 @@ impl Drop for DecWriter { fn drop(&mut self) { // We must not check whether the DecWriter has been closed if // we encountered an error during a write or flush call. - if !self.errored { - if !self.closed { - // We don't want to panic again if some code (between - // DecWriter::new(...) and DecWriter.close()) already - // panic'd. Otherwise we would cause a "double-panic". - if !panicking() { - panic!("DecWriter must be closed explicitly via the close method before being dropped!") - } + if !self.errored && !self.closed { + // We don't want to panic again if some code (between + // DecWriter::new(...) and DecWriter.close()) already + // panic'd. Otherwise we would cause a "double-panic". + if !panicking() { + panic!("DecWriter must be closed explicitly via the close method before being dropped!") } } } @@ -697,12 +660,12 @@ mod internal { /// io::BufWriter::new(EncWriter::new( /// io::sink(), /// &inner_key, -/// Nonce::new([0; Nonce::::SIZE]), +/// Nonce::new([0; Nonce::SIZE]), /// Aad::empty(), /// ).closer() // Without this `closer` call the code would not compile. /// ), /// &outer_key, -/// Nonce::new([0; Nonce::::SIZE]), +/// Nonce::new([0; Nonce::SIZE]), /// Aad::empty(), /// ); /// @@ -735,7 +698,7 @@ impl Closer { #[inline(always)] pub fn wrap(inner: W) -> Self { Self { - inner: inner, + inner, closed: false, errored: false, } diff --git a/tests/closer_tests.rs b/tests/closer_tests.rs index 8a037f2..b15f0da 100644 --- a/tests/closer_tests.rs +++ b/tests/closer_tests.rs @@ -5,9 +5,11 @@ use sio::*; use std::{io, io::Write}; +#[allow(clippy::upper_case_acronyms)] #[cfg(feature = "aesgcm")] type AEAD = AES_256_GCM; +#[allow(clippy::upper_case_acronyms)] #[cfg(not(feature = "aesgcm"))] type AEAD = CHACHA20_POLY1305; @@ -35,7 +37,7 @@ fn enc_writer_missing_close() { let _ = EncWriter::new( Vec::default(), &key, - Nonce::new([0; Nonce::::SIZE]), + Nonce::new([0; Nonce::SIZE]), Aad::empty(), ); } @@ -47,7 +49,7 @@ fn enc_writer_missing_close_after_write() { let mut writer = EncWriter::new( Vec::default(), &key, - Nonce::new([0; Nonce::::SIZE]), + Nonce::new([0; Nonce::SIZE]), Aad::empty(), ); let _ = writer.write_all(b"Hello World"); @@ -56,12 +58,7 @@ fn enc_writer_missing_close_after_write() { #[test] fn enc_writer_missing_close_after_error() { let key: Key = Key::new([0; Key::::SIZE]); - let mut writer = EncWriter::new( - BadSink, - &key, - Nonce::new([0; Nonce::::SIZE]), - Aad::empty(), - ); + let mut writer = EncWriter::new(BadSink, &key, Nonce::new([0; Nonce::SIZE]), Aad::empty()); let _ = writer.write_all(&[0; BUF_SIZE + 1]); } @@ -72,7 +69,7 @@ fn enc_writer_missing_close_after_panic() { let _ = EncWriter::new( Vec::default(), &key, - Nonce::new([0; Nonce::::SIZE]), + Nonce::new([0; Nonce::SIZE]), Aad::empty(), ); panic!(); @@ -85,7 +82,7 @@ fn dec_writer_missing_close() { let _ = DecWriter::new( Vec::default(), &key, - Nonce::new([0; Nonce::::SIZE]), + Nonce::new([0; Nonce::SIZE]), Aad::empty(), ); } @@ -97,7 +94,7 @@ fn dec_writer_missing_close_after_write() { let mut writer = DecWriter::new( Vec::default(), &key, - Nonce::new([0; Nonce::::SIZE]), + Nonce::new([0; Nonce::SIZE]), Aad::empty(), ); let _ = writer.write_all(b"Hello World"); @@ -106,12 +103,7 @@ fn dec_writer_missing_close_after_write() { #[test] fn dec_writer_missing_close_after_error() { let key: Key = Key::new([0; Key::::SIZE]); - let mut writer = DecWriter::new( - io::sink(), - &key, - Nonce::new([0; Nonce::::SIZE]), - Aad::empty(), - ); + let mut writer = DecWriter::new(io::sink(), &key, Nonce::new([0; Nonce::SIZE]), Aad::empty()); let _ = writer.write_all(&[0; BUF_SIZE + AEAD::TAG_LEN + 1]); } @@ -122,7 +114,7 @@ fn dec_writer_missing_close_after_panic() { let _ = DecWriter::new( Vec::default(), &key, - Nonce::new([0; Nonce::::SIZE]), + Nonce::new([0; Nonce::SIZE]), Aad::empty(), ); panic!(); diff --git a/tests/writer_tests.rs b/tests/writer_tests.rs index e2eb437..9b57c4c 100644 --- a/tests/writer_tests.rs +++ b/tests/writer_tests.rs @@ -5,9 +5,11 @@ use sio::*; use std::{io, io::Write}; +#[allow(clippy::upper_case_acronyms)] #[cfg(feature = "aesgcm")] type AEAD = AES_256_GCM; +#[allow(clippy::upper_case_acronyms)] #[cfg(not(feature = "aesgcm"))] type AEAD = CHACHA20_POLY1305; @@ -22,7 +24,7 @@ fn write() -> io::Result<()> { let mut writer = EncWriter::new( &mut ciphertext, &key, - Nonce::new([0; Nonce::::SIZE]), + Nonce::new([0; Nonce::SIZE]), Aad::empty(), ); let half = data.len() / 2; @@ -34,7 +36,7 @@ fn write() -> io::Result<()> { let mut writer = DecWriter::new( &mut plaintext, &key, - Nonce::new([0; Nonce::::SIZE]), + Nonce::new([0; Nonce::SIZE]), Aad::empty(), ); let half = ciphertext.len() / 2; @@ -58,7 +60,7 @@ fn write_empty() -> io::Result<()> { EncWriter::new( &mut ciphertext, &key, - Nonce::new([0; Nonce::::SIZE]), + Nonce::new([0; Nonce::SIZE]), Aad::empty(), ) .close() @@ -68,7 +70,7 @@ fn write_empty() -> io::Result<()> { let mut writer = DecWriter::new( &mut plaintext, &key, - Nonce::new([0; Nonce::::SIZE]), + Nonce::new([0; Nonce::SIZE]), Aad::empty(), ); writer @@ -91,13 +93,13 @@ fn close() -> io::Result<()> { DecWriter::new( &mut plaintext, &key, - Nonce::new([0; Nonce::::SIZE]), + Nonce::new([0; Nonce::SIZE]), Aad::empty(), ) .closer(), ), &key, - Nonce::new([0; Nonce::::SIZE]), + Nonce::new([0; Nonce::SIZE]), Aad::empty(), ); writer.write_all(&data).and_then(|_| writer.close())?;