|
48 | 48 | //! |
49 | 49 | //! There is also an optional fourth parameter (buffer/fragment size) which we will cover later. |
50 | 50 | //! |
51 | | -//! Now, there are two important rules you have to ensure are never violated by your code: |
52 | | -//! 1. **Correctness:** |
53 | | -//! The parameters (`key'`, `nonce'` `aad'`) for decryption must match exactly the parameters |
54 | | -//! (`key`, `nonce` `aad`) used when encrypting the data. |
55 | | -//! 2. **Freshness:** |
56 | | -//! When encrypting a data stream, you must use a new `key` **or** a new `nonce` value that |
57 | | -//! has **never** been used before. |
58 | | -//! |
59 | | -//! The 1st rule is pretty obvious. If you, for example, use different keys for encryption and |
60 | | -//! decryption then the decryption will fail. The same applies to the nonce and associated data. |
61 | | -//! |
62 | | -//! The 2nd rule may be less obvious but it is at least as important as the 1st one since security |
63 | | -//! crucially depends on it. In general, the authenticated encryption algorithm (used by the |
64 | | -//! channel construction) assumes that, given the same key, the nonce value does never repeat. |
65 | | -//! Violating this assumption breaks the security properties and potentially allows decrypting |
66 | | -//! or forging data without knowing the secret key. But don't worry, there are best practices for |
67 | | -//! dealing with keys and nonce values which can help here. |
| 51 | +//! Now, there is one important rule that must never be violated by your code since security |
| 52 | +//! crucially depends on it: |
| 53 | +//! <p style="margin-left: 40px; margin-right: 50px; border:1px; border-style:solid; border-color:#000000; padding: 0.3em"> |
| 54 | +//! When encrypting a data stream you must use a new <code>key</code> <b>or</b> a new |
| 55 | +//! <code>nonce</code> value such that this particular <code>key</code>-<code>nonce</code> |
| 56 | +//! combination has <b>never</b> been used before. |
| 57 | +//! </p> |
| 58 | +//! |
| 59 | +//! In general, the authenticated encryption algorithm (used by the channel construction) assumes |
| 60 | +//! that, given the same key, the nonce value does never repeat. Violating this assumption breaks |
| 61 | +//! the security properties and potentially allows decrypting or forging data without knowing the |
| 62 | +//! secret key. Therefore, you have to make sure that you use a key-nonce combination only once. |
| 63 | +//! But don't worry, there are best practices for dealing with keys and nonce values which can help |
| 64 | +//! here. |
68 | 65 | //! |
69 | 66 | //! Next, we will take a look at some examples for encryption and decryption. |
70 | 67 | //! |
|
76 | 73 | //! use std::io; |
77 | 74 | //! use std::io::Write; |
78 | 75 | //! use std::fs::File; |
79 | | -//! use sio::{EncWriter, Key, Nonce, Aad, AES_256_GCM, Close}; |
| 76 | +//! use sio::{EncWriter, Key, Nonce, Aad, AES_256_GCM, NopCloser}; |
80 | 77 | //! |
81 | 78 | //! fn main() -> io::Result<()> { |
82 | 79 | //! // Obviously, do NOT use this demo key for anything real! |
83 | 80 | //! let secret_key: Key::<AES_256_GCM> = Key::new([0; Key::<AES_256_GCM>::SIZE]); |
84 | 81 | //! |
85 | 82 | //! let mut f = EncWriter::new( |
86 | | -//! File::create("foo.txt")?, |
| 83 | +//! NopCloser::wrap(File::create("foo.txt")?), |
87 | 84 | //! &secret_key, |
88 | 85 | //! Nonce::new([0; Nonce::<AES_256_GCM>::SIZE]), |
89 | 86 | //! Aad::empty(), |
|
96 | 93 | //! Here, we try to create and wrap the file `foo.txt` and encrypt the string |
97 | 94 | //! `"Hello World"` using the [`AES_256_GCM`](https://en.wikipedia.org/wiki/Galois/Counter_Mode) |
98 | 95 | //! algorithm before writing it to the file. Note that we call a `close` method |
99 | | -//! after writing. This is *very important* and you should take a look at the |
100 | | -//! `Close` trait for a detailed explanation. |
| 96 | +//! after writing. This is very important and you should take a look at the |
| 97 | +//! `Close` trait for a detailed explanation about why this call is necessary. |
101 | 98 | //! |
102 | 99 | //! # Decryption |
103 | 100 | //! |
104 | | -//! Similarly, you can decrypt data by wrapping a writer with a `DecWriter`. The `DecWriter` |
105 | | -//! is also generic over an authenticated encryption algorithm and expects the same |
106 | | -//! `Key`, `Nonce` and `Aad` used to encrypt the data. |
| 101 | +//! Similarly, you can decrypt data by using a `DecWriter` instead of an `EncWriter`. The |
| 102 | +//! `DecWriter` is also generic over an authenticated encryption algorithm and expects the |
| 103 | +//! same `Key`, `Nonce` and `Aad` used before to encrypt the data. |
107 | 104 | //! ```norun |
108 | 105 | //! use std::io; |
109 | 106 | //! use std::io::{Read, Write}; |
110 | 107 | //! use std::fs::File; |
111 | | -//! use sio::{DecWriter, Key, Nonce, Aad, AES_256_GCM, Close}; |
| 108 | +//! use sio::{DecWriter, Key, Nonce, Aad, AES_256_GCM, NopCloser}; |
112 | 109 | //! |
113 | 110 | //! fn main() -> io::Result<()> { |
114 | 111 | //! // Obviously, do NOT use this demo key for anything real! |
115 | 112 | //! let secret_key: Key::<AES_256_GCM> = Key::new([0; Key::<AES_256_GCM>::SIZE]); |
116 | 113 | //! |
117 | 114 | //! let mut out = DecWriter::new( |
118 | | -//! io::stdout(), |
| 115 | +//! NopCloser::wrap(io::stdout()), |
119 | 116 | //! &secret_key, |
120 | 117 | //! Nonce::new([0; Nonce::<AES_256_GCM>::SIZE]), |
121 | 118 | //! Aad::empty(), |
|
124 | 121 | //! io::copy(&mut File::open("foo.txt")?, &mut out)?; |
125 | 122 | //! out.close() |
126 | 123 | //! } |
| 124 | +//! ``` |
| 125 | +//! Here, we wrap the standard output file descriptor (STDOUT) with a `DecWriter` |
| 126 | +//! such that everything written to `out` gets decrypted and verified before passed to |
| 127 | +//! STDOUT. Than, we open the `foo.txt` file again and copy its content to `out`. Observe |
| 128 | +//! that we invoke a `close` method at the end again. Refer to the `Close` trait for an |
| 129 | +//! explanation about why this call is necessary. |
127 | 130 |
|
128 | 131 | pub use self::aead::{Aad, Algorithm, Key, Nonce}; |
129 | 132 | pub use self::error::{Invalid, NotAuthentic}; |
| 133 | +pub use self::utils::NopCloser; |
130 | 134 | pub use self::writer::{Close, DecWriter, EncWriter}; |
131 | 135 |
|
132 | 136 | mod aead; |
133 | 137 | mod error; |
| 138 | +mod utils; |
134 | 139 | mod writer; |
135 | 140 |
|
136 | 141 | #[cfg(feature = "ring")] |
|
0 commit comments