Skip to content

Commit 3b50e31

Browse files
authored
aead: remove nonce generation APIs (#2098)
Replaces them with the `Generate` trait introduced in #2096. Moves documentation about generating random nonces to the `Nonce` type.
1 parent ccf8e9b commit 3b50e31

File tree

2 files changed

+50
-75
lines changed

2 files changed

+50
-75
lines changed

aead/src/lib.rs

Lines changed: 48 additions & 73 deletions
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ pub use arrayvec;
2929
#[cfg(feature = "bytes")]
3030
pub use bytes;
3131
#[cfg(feature = "rand_core")]
32-
pub use crypto_common::rand_core;
32+
pub use crypto_common::{Generate, rand_core};
3333
pub use inout;
3434

3535
use core::fmt;
@@ -40,10 +40,6 @@ use inout::InOutBuf;
4040
use alloc::vec::Vec;
4141
#[cfg(feature = "bytes")]
4242
use bytes::BytesMut;
43-
#[cfg(feature = "getrandom")]
44-
use crypto_common::getrandom;
45-
#[cfg(feature = "rand_core")]
46-
use rand_core::{CryptoRng, TryCryptoRng};
4743

4844
/// Error type.
4945
///
@@ -63,7 +59,53 @@ impl fmt::Display for Error {
6359

6460
impl core::error::Error for Error {}
6561

66-
/// Nonce: single-use value for ensuring ciphertexts are unique
62+
/// Nonce: single-use value for ensuring ciphertexts are unique.
63+
///
64+
/// AEAD algorithms accept a parameter to encryption/decryption called
65+
/// a "nonce" which must be unique every time encryption is performed and
66+
/// never repeated for the same key. The nonce is often prepended to the
67+
/// ciphertext, a.k.a. an explicit nonce, but may also be an implicit counter.
68+
///
69+
/// AEAD decryption takes the nonce which was originally used to produce a
70+
/// given ciphertext as a parameter along with the ciphertext itself.
71+
///
72+
/// # Generating random nonces
73+
///
74+
/// Nonces don't necessarily have to be random, but it is a simple strategy
75+
/// which can be implemented as follows using the [`Generate`] trait
76+
/// (requires `getrandom` feature):
77+
///
78+
/// ```text
79+
/// use aead::{Nonce, Generate};
80+
///
81+
/// let nonce = Nonce::<AeadAlg>::generate();
82+
/// ```
83+
///
84+
/// <div class="warning">
85+
/// AEAD algorithms often fail catastrophically if nonces are ever repeated
86+
/// (with SIV modes being an exception).
87+
///
88+
/// Using random nonces runs the risk of repeating them unless the nonce
89+
/// size is particularly large, e.g. 192-bit extended nonces used by the
90+
/// `XChaCha20Poly1305` and `XSalsa20Poly1305` constructions.
91+
///
92+
/// [NIST SP 800-38D] recommends the following:
93+
///
94+
/// > The total number of invocations of the authenticated encryption
95+
/// > function shall not exceed 2<sup>32</sup>, including all IV lengths and all
96+
/// > instances of the authenticated encryption function with the given key.
97+
///
98+
/// Following this guideline, only 4,294,967,296 messages with random
99+
/// nonces can be encrypted under a given key. While this bound is high,
100+
/// it's possible to encounter in practice, and systems which might
101+
/// reach it should consider alternatives to purely random nonces, like
102+
/// a counter or a combination of a random nonce + counter.
103+
///
104+
/// See the [`aead-stream`] crate for a ready-made implementation of the latter.
105+
/// </div>
106+
///
107+
/// [NIST SP 800-38D]: https://csrc.nist.gov/publications/detail/sp/800-38d/final
108+
/// [`aead-stream`]: https://docs.rs/aead-stream
67109
pub type Nonce<A> = Array<u8, <A as AeadCore>::NonceSize>;
68110

69111
/// Tag: authentication code which ensures ciphertexts are authentic
@@ -88,73 +130,6 @@ pub trait AeadCore {
88130

89131
/// The AEAD tag position.
90132
const TAG_POSITION: TagPosition;
91-
92-
/// Generate a random nonce for this AEAD algorithm.
93-
///
94-
/// AEAD algorithms accept a parameter to encryption/decryption called
95-
/// a "nonce" which must be unique every time encryption is performed and
96-
/// never repeated for the same key. The nonce is often prepended to the
97-
/// ciphertext. The nonce used to produce a given ciphertext must be passed
98-
/// to the decryption function in order for it to decrypt correctly.
99-
///
100-
/// Nonces don't necessarily have to be random, but it is one strategy
101-
/// which is implemented by this function.
102-
///
103-
/// # ⚠️Security Warning
104-
///
105-
/// AEAD algorithms often fail catastrophically if nonces are ever repeated
106-
/// (with SIV modes being an exception).
107-
///
108-
/// Using random nonces runs the risk of repeating them unless the nonce
109-
/// size is particularly large (e.g. 192-bit extended nonces used by the
110-
/// `XChaCha20Poly1305` and `XSalsa20Poly1305` constructions.
111-
///
112-
/// [NIST SP 800-38D] recommends the following:
113-
///
114-
/// > The total number of invocations of the authenticated encryption
115-
/// > function shall not exceed 2^32, including all IV lengths and all
116-
/// > instances of the authenticated encryption function with the given key.
117-
///
118-
/// Following this guideline, only 4,294,967,296 messages with random
119-
/// nonces can be encrypted under a given key. While this bound is high,
120-
/// it's possible to encounter in practice, and systems which might
121-
/// reach it should consider alternatives to purely random nonces, like
122-
/// a counter or a combination of a random nonce + counter.
123-
///
124-
/// See the [`aead-stream`] crate for a ready-made implementation of the latter.
125-
///
126-
/// [NIST SP 800-38D]: https://csrc.nist.gov/publications/detail/sp/800-38d/final
127-
/// [`aead-stream`]: https://docs.rs/aead-stream
128-
#[cfg(feature = "getrandom")]
129-
fn generate_nonce() -> core::result::Result<Nonce<Self>, getrandom::Error> {
130-
let mut nonce = Nonce::<Self>::default();
131-
getrandom::fill(&mut nonce)?;
132-
Ok(nonce)
133-
}
134-
135-
/// Generate a random nonce for this AEAD algorithm using the specified [`CryptoRng`].
136-
///
137-
/// See [`AeadCore::generate_nonce`] documentation for requirements for
138-
/// random nonces.
139-
#[cfg(feature = "rand_core")]
140-
fn generate_nonce_with_rng<R: CryptoRng + ?Sized>(rng: &mut R) -> Nonce<Self> {
141-
let mut nonce = Nonce::<Self>::default();
142-
rng.fill_bytes(&mut nonce);
143-
nonce
144-
}
145-
146-
/// Generate a random nonce for this AEAD algorithm using the specified [`TryCryptoRng`].
147-
///
148-
/// See [`AeadCore::generate_nonce`] documentation for requirements for
149-
/// random nonces.
150-
#[cfg(feature = "rand_core")]
151-
fn try_generate_nonce_with_rng<R: TryCryptoRng + ?Sized>(
152-
rng: &mut R,
153-
) -> core::result::Result<Nonce<Self>, R::Error> {
154-
let mut nonce = Nonce::<Self>::default();
155-
rng.try_fill_bytes(&mut nonce)?;
156-
Ok(nonce)
157-
}
158133
}
159134

160135
/// Authenticated Encryption with Associated Data (AEAD) algorithm.

crypto-common/src/lib.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,10 +19,10 @@ mod generate;
1919
pub use hybrid_array as array;
2020
pub use hybrid_array::typenum;
2121

22+
#[cfg(feature = "getrandom")]
23+
pub use getrandom::Error as RngError;
2224
#[cfg(feature = "rand_core")]
2325
pub use {generate::Generate, rand_core};
24-
#[cfg(feature = "getrandom")]
25-
pub use {getrandom, getrandom::Error as RngError};
2626

2727
use core::fmt;
2828
use hybrid_array::{

0 commit comments

Comments
 (0)