aead_io/
lib.rs

1//! Provides a wrapper around a [`Write`](std::io::Write)/[`Read`](std::io::Read) object and a
2//! [`StreamPrimitive`](aead::stream::StreamPrimitive) to provide an easy interface for doing
3//! correct encryption.
4//!
5//! ```
6//! # use aead_io::{DecryptBE32BufReader, EncryptBE32BufWriter, ArrayBuffer};
7//! # use aead::stream::{Nonce, StreamBE32};
8//! # use aead::KeyInit;
9//! # use chacha20poly1305::{ChaCha20Poly1305, Key};
10//! # use std::io::{Read, Write, Result};
11//! # fn main() -> Result<()> {
12//! let key = b"my very super super secret key!!".into();
13//! let plaintext = b"hello world!";
14//!
15//! let mut ciphertext = Vec::default();
16//! {
17//!     let mut writer = EncryptBE32BufWriter::<ChaCha20Poly1305, _, _>::new(
18//!         key,
19//!         &Default::default(), // please use a better nonce ;)
20//!         ArrayBuffer::<128>::new(),
21//!         &mut ciphertext,
22//!     )
23//!     .unwrap();
24//!     writer.write_all(plaintext)?;
25//!     writer.flush()?;
26//! };
27//!
28//! let mut decrypted = Vec::new();
29//! {
30//!     let mut reader = DecryptBE32BufReader::<ChaCha20Poly1305, _, _>::new(
31//!         key,
32//!         ArrayBuffer::<256>::new(),
33//!         ciphertext.as_slice(),
34//!     )
35//!     .unwrap();
36//!     let _ = reader.read_to_end(&mut decrypted).unwrap();
37//! };
38//!
39//! assert_eq!(decrypted, plaintext);
40//! #
41//! # Ok(())
42//! # }
43//! ```
44//!
45//! # `no_std`, `array-buffer`
46//!
47//! This package is compatible with `no_std` environments. Just disable the default features! The
48//! std `Vec`, `io::Read` and `io::Write` interfaces are reimplemented internally via
49//! the [`Buffer`](aead::Buffer), [`CappedBuffer`](CappedBuffer),
50//! [`ResizeBuffer`](ResizeBuffer), [`Write`](Write) and
51//! [`Read`](Read) traits accordingly. There should be some default implementations
52//! for `Vec<u8>`, byte slices and a no alloc compatible [`ArrayBuffer`](ArrayBuffer)
53//! if the `array-buffer` feature is enabled
54
55#![cfg_attr(not(feature = "std"), no_std)]
56
57#[cfg(feature = "alloc")]
58extern crate alloc;
59
60#[cfg(feature = "array-buffer")]
61mod array_buffer;
62mod buffer;
63mod error;
64mod reader;
65mod rw;
66mod writer;
67
68pub use aead;
69
70#[cfg(feature = "array-buffer")]
71pub use array_buffer::ArrayBuffer;
72pub use buffer::{CappedBuffer, ResizeBuffer};
73pub use error::{Error, IntoInnerError, InvalidCapacity};
74pub use reader::DecryptBufReader;
75pub use rw::{Read, Write};
76pub use writer::EncryptBufWriter;
77
78use aead::stream::{StreamBE32, StreamLE31};
79
80/// Convenience type for constructing a [`BufWriter`](EncryptBufWriter) with a [`StreamBE32`](StreamBE32)
81pub type EncryptBE32BufWriter<A, B, W> = EncryptBufWriter<A, B, W, StreamBE32<A>>;
82/// Convenience type for constructing a [`BufWriter`](EncryptBufWriter) with a [`StreamLE31`](StreamLE31)
83pub type EncryptLE31BufWriter<A, B, W> = EncryptBufWriter<A, B, W, StreamLE31<A>>;
84/// Convenience type for constructing a [`BufReader`](DecryptBufReader) with a [`StreamBE32`](StreamBE32)
85pub type DecryptBE32BufReader<A, B, W> = DecryptBufReader<A, B, W, StreamBE32<A>>;
86/// Convenience type for constructing a [`BufReader`](DecryptBufReader) with a [`StreamLE31`](StreamLE31)
87pub type DecryptLE31BufReader<A, B, W> = DecryptBufReader<A, B, W, StreamLE31<A>>;
88
89#[cfg(feature = "std")]
90#[cfg(test)]
91mod tests {
92    use super::*;
93    use aead::generic_array::ArrayLength;
94    use aead::stream::{NewStream, Nonce, NonceSize, StreamBE32, StreamPrimitive};
95    use aead::{AeadCore, AeadInPlace, Key, KeyInit};
96    use chacha20poly1305::ChaCha20Poly1305;
97    use core::ops::Sub;
98    use std::io::{Read, Write};
99
100    fn encrypt_decrypt<A, S>(plaintext: &[u8])
101    where
102        A: AeadInPlace + KeyInit + Clone,
103        S: StreamPrimitive<A> + NewStream<A>,
104        <A as AeadCore>::NonceSize: Sub<S::NonceOverhead>,
105        NonceSize<A, S>: ArrayLength<u8>,
106    {
107        let aead = {
108            let mut key = Key::<A>::default();
109            key.copy_from_slice(b"my very super super secret key!!");
110            A::new(&key)
111        };
112        let nonce = Nonce::<A, S>::default();
113
114        let mut blob = Vec::default();
115
116        let mut writer = EncryptBufWriter::<A, _, _, S>::from_aead(
117            aead.clone(),
118            &nonce,
119            ArrayBuffer::<128>::new(),
120            &mut blob,
121        )
122        .unwrap();
123        writer.write_all(plaintext).unwrap();
124        std::io::Write::flush(&mut writer).unwrap();
125        drop(writer);
126
127        let mut reader = DecryptBufReader::<A, _, _, S>::from_aead(
128            aead,
129            ArrayBuffer::<256>::new(),
130            blob.as_slice(),
131        )
132        .unwrap();
133        let mut out = Vec::new();
134        let _ = reader.read_to_end(&mut out).unwrap();
135        assert_eq!(out, plaintext);
136    }
137
138    #[test]
139    fn short_message() {
140        let plaintext = b"hello world!";
141        encrypt_decrypt::<ChaCha20Poly1305, StreamBE32<ChaCha20Poly1305>>(plaintext);
142        encrypt_decrypt::<ChaCha20Poly1305, StreamLE31<ChaCha20Poly1305>>(plaintext);
143    }
144
145    #[test]
146    fn long_message() {
147        let plaintext = b"Lorem ipsum dolor sit amet, consectetur adipiscing elit. Curabitur eu erat non turpis viverra mollis vel a mauris. Vestibulum luctus justo vitae diam ultrices, eget vehicula velit consectetur. Sed ut sapien odio. Nullam non porttitor augue. Duis euismod, augue sed blandit eleifend, leo enim rhoncus lacus, in efficitur metus massa quis justo. Nunc velit quam, aliquam vitae enim ut, facilisis molestie odio. Phasellus nec euismod nisi, sit amet dignissim arcu. Nullam pulvinar aliquam purus ut aliquet. Sed iaculis, odio in luctus molestie, purus dui vehicula est, sed egestas erat diam sed arcu. Cras venenatis magna vitae tristique mattis.";
148        encrypt_decrypt::<ChaCha20Poly1305, StreamBE32<ChaCha20Poly1305>>(plaintext);
149        encrypt_decrypt::<ChaCha20Poly1305, StreamLE31<ChaCha20Poly1305>>(plaintext);
150    }
151}