@@ -16,23 +16,50 @@ pub const BUF_SIZE: usize = 1 << 14;
16
16
17
17
/// Wraps a writer and encrypts and authenticates everything written to it.
18
18
///
19
+ /// `EncrWriter` splits data into fixed-size fragments and encrypts and
20
+ /// authenticates each fragment separately. It appends any remaining data
21
+ /// to its in-memory buffer until it has gathered a complete fragment.
22
+ /// Therefore, using an `std::io::BufWriter` in addition usually does not
23
+ /// improve the performance of write calls. The only exception may be cases
24
+ /// when the buffer size of the `BufWriter` is significantly larger than the
25
+ /// fragment size of the `EncWriter`.
26
+ ///
27
+ /// When the `EncWriter` is dropped, any buffered content will be encrypted
28
+ /// as well as authenticated and written out. However, any errors that happen
29
+ /// in the process of flushing the buffer when the `EncWriter` is dropped will
30
+ /// be ignored. Therefore, code should call `flush` explicitly to ensure that
31
+ /// all encrypted data has been written out successfully.
19
32
/// # Examples
20
33
///
21
34
/// Let's encrypt a string and store the ciphertext in memory:
22
35
///
23
36
/// ```
24
- /// use std::io::{Write, Read, copy, repeat };
37
+ /// use std::io::{Write, Read};
25
38
/// use sio::{Key, Nonce, Aad, EncWriter};
26
- /// use sio::ring;
39
+ /// use sio::ring::AES_256_GCM;
40
+ ///
41
+ /// // Load your secret keys from a secure location or derive
42
+ /// // them using a secure (password-based) key-derivation-function, like Argon2id.
43
+ /// // Obviously, don't use this all-zeros key for anything real.
44
+ /// let key: Key<AES_256_GCM> = Key::new([0; Key::<AES_256_GCM>::SIZE]);
45
+ ///
46
+ /// // Make sure you use an unique key-nonce combination!
47
+ /// // Reusing a nonce value for the same secret key breaks
48
+ /// // the security of the encryption algorithm.
49
+ /// let nonce = Nonce::new([0; Nonce::<AES_256_GCM>::SIZE]);
50
+ ///
51
+ /// // You must be able to re-generate this aad to decrypt
52
+ /// // the ciphertext again. Usually, it's stored together with
53
+ /// // the encrypted data.
54
+ /// let aad = Aad::from("Some authenticated but not encrypted data".as_bytes());
27
55
///
28
- /// let key: Key<ring::AES_256_GCM> = Key::new([0; 32]);
29
- /// let nonce = Nonce::new([0; 8]);
30
- /// let aad = Aad::empty();
56
+ /// let mut plaintext = "Some example plaintext".as_bytes();
31
57
///
32
- /// let mut plaintext = repeat('y' as u8).take(5);
33
- /// let mut ciphertext: Vec<u8> = Vec::default();
58
+ /// let mut ciphertext: Vec<u8> = Vec::default(); // Store the ciphertext in memory.
34
59
/// let mut writer = EncWriter::new(ciphertext, &key, nonce, aad);
35
- /// copy(&mut plaintext, &mut writer).and_then(|_| writer.flush()).unwrap();
60
+ ///
61
+ /// writer.write_all(plaintext).unwrap();
62
+ /// writer.flush().unwrap(); // Complete the encryption process explicitly.
36
63
/// ```
37
64
pub struct EncWriter < A : Algorithm , W : Write > {
38
65
inner : W ,
@@ -122,6 +149,11 @@ impl<A: Algorithm, W: Write> Write for EncWriter<A, W> {
122
149
Ok ( n)
123
150
}
124
151
152
+ #[ inline]
153
+ fn write_all ( & mut self , buf : & [ u8 ] ) -> io:: Result < ( ) > {
154
+ self . write ( buf) . and ( Ok ( ( ) ) )
155
+ }
156
+
125
157
fn flush ( & mut self ) -> io:: Result < ( ) > {
126
158
if self . flushed {
127
159
return Err ( io:: Error :: from ( io:: ErrorKind :: Other ) ) ;
@@ -231,6 +263,7 @@ impl<A: Algorithm, W: Write> Write for DecWriter<A, W> {
231
263
232
264
#[ cfg( test) ]
233
265
mod tests {
266
+
234
267
use super :: ring:: AES_256_GCM ;
235
268
use super :: * ;
236
269
use std:: io:: { Read , Write } ;
0 commit comments