From b51a93b417069c9fb39a1bdd941f0bc034996f0a Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Mon, 24 Nov 2025 08:45:14 -0700 Subject: [PATCH] aead: remove nonce generation APIs Replaces them with the `Generate` trait from #2096. Moves documentation about generating random nonces to the `Nonce` type. --- aead/src/lib.rs | 121 ++++++++++++++++----------------------- crypto-common/src/lib.rs | 4 +- 2 files changed, 50 insertions(+), 75 deletions(-) diff --git a/aead/src/lib.rs b/aead/src/lib.rs index e950a48bc..a7afa3c6f 100644 --- a/aead/src/lib.rs +++ b/aead/src/lib.rs @@ -29,7 +29,7 @@ pub use arrayvec; #[cfg(feature = "bytes")] pub use bytes; #[cfg(feature = "rand_core")] -pub use crypto_common::rand_core; +pub use crypto_common::{Generate, rand_core}; pub use inout; use core::fmt; @@ -40,10 +40,6 @@ use inout::InOutBuf; use alloc::vec::Vec; #[cfg(feature = "bytes")] use bytes::BytesMut; -#[cfg(feature = "getrandom")] -use crypto_common::getrandom; -#[cfg(feature = "rand_core")] -use rand_core::{CryptoRng, TryCryptoRng}; /// Error type. /// @@ -63,7 +59,53 @@ impl fmt::Display for Error { impl core::error::Error for Error {} -/// Nonce: single-use value for ensuring ciphertexts are unique +/// Nonce: single-use value for ensuring ciphertexts are unique. +/// +/// AEAD algorithms accept a parameter to encryption/decryption called +/// a "nonce" which must be unique every time encryption is performed and +/// never repeated for the same key. The nonce is often prepended to the +/// ciphertext, a.k.a. an explicit nonce, but may also be an implicit counter. +/// +/// AEAD decryption takes the nonce which was originally used to produce a +/// given ciphertext as a parameter along with the ciphertext itself. +/// +/// # Generating random nonces +/// +/// Nonces don't necessarily have to be random, but it is a simple strategy +/// which can be implemented as follows using the [`Generate`] trait +/// (requires `getrandom` feature): +/// +/// ```text +/// use aead::{Nonce, Generate}; +/// +/// let nonce = Nonce::::generate(); +/// ``` +/// +///
+/// AEAD algorithms often fail catastrophically if nonces are ever repeated +/// (with SIV modes being an exception). +/// +/// Using random nonces runs the risk of repeating them unless the nonce +/// size is particularly large, e.g. 192-bit extended nonces used by the +/// `XChaCha20Poly1305` and `XSalsa20Poly1305` constructions. +/// +/// [NIST SP 800-38D] recommends the following: +/// +/// > The total number of invocations of the authenticated encryption +/// > function shall not exceed 232, including all IV lengths and all +/// > instances of the authenticated encryption function with the given key. +/// +/// Following this guideline, only 4,294,967,296 messages with random +/// nonces can be encrypted under a given key. While this bound is high, +/// it's possible to encounter in practice, and systems which might +/// reach it should consider alternatives to purely random nonces, like +/// a counter or a combination of a random nonce + counter. +/// +/// See the [`aead-stream`] crate for a ready-made implementation of the latter. +///
+/// +/// [NIST SP 800-38D]: https://csrc.nist.gov/publications/detail/sp/800-38d/final +/// [`aead-stream`]: https://docs.rs/aead-stream pub type Nonce = Array::NonceSize>; /// Tag: authentication code which ensures ciphertexts are authentic @@ -88,73 +130,6 @@ pub trait AeadCore { /// The AEAD tag position. const TAG_POSITION: TagPosition; - - /// Generate a random nonce for this AEAD algorithm. - /// - /// AEAD algorithms accept a parameter to encryption/decryption called - /// a "nonce" which must be unique every time encryption is performed and - /// never repeated for the same key. The nonce is often prepended to the - /// ciphertext. The nonce used to produce a given ciphertext must be passed - /// to the decryption function in order for it to decrypt correctly. - /// - /// Nonces don't necessarily have to be random, but it is one strategy - /// which is implemented by this function. - /// - /// # ⚠️Security Warning - /// - /// AEAD algorithms often fail catastrophically if nonces are ever repeated - /// (with SIV modes being an exception). - /// - /// Using random nonces runs the risk of repeating them unless the nonce - /// size is particularly large (e.g. 192-bit extended nonces used by the - /// `XChaCha20Poly1305` and `XSalsa20Poly1305` constructions. - /// - /// [NIST SP 800-38D] recommends the following: - /// - /// > The total number of invocations of the authenticated encryption - /// > function shall not exceed 2^32, including all IV lengths and all - /// > instances of the authenticated encryption function with the given key. - /// - /// Following this guideline, only 4,294,967,296 messages with random - /// nonces can be encrypted under a given key. While this bound is high, - /// it's possible to encounter in practice, and systems which might - /// reach it should consider alternatives to purely random nonces, like - /// a counter or a combination of a random nonce + counter. - /// - /// See the [`aead-stream`] crate for a ready-made implementation of the latter. - /// - /// [NIST SP 800-38D]: https://csrc.nist.gov/publications/detail/sp/800-38d/final - /// [`aead-stream`]: https://docs.rs/aead-stream - #[cfg(feature = "getrandom")] - fn generate_nonce() -> core::result::Result, getrandom::Error> { - let mut nonce = Nonce::::default(); - getrandom::fill(&mut nonce)?; - Ok(nonce) - } - - /// Generate a random nonce for this AEAD algorithm using the specified [`CryptoRng`]. - /// - /// See [`AeadCore::generate_nonce`] documentation for requirements for - /// random nonces. - #[cfg(feature = "rand_core")] - fn generate_nonce_with_rng(rng: &mut R) -> Nonce { - let mut nonce = Nonce::::default(); - rng.fill_bytes(&mut nonce); - nonce - } - - /// Generate a random nonce for this AEAD algorithm using the specified [`TryCryptoRng`]. - /// - /// See [`AeadCore::generate_nonce`] documentation for requirements for - /// random nonces. - #[cfg(feature = "rand_core")] - fn try_generate_nonce_with_rng( - rng: &mut R, - ) -> core::result::Result, R::Error> { - let mut nonce = Nonce::::default(); - rng.try_fill_bytes(&mut nonce)?; - Ok(nonce) - } } /// Authenticated Encryption with Associated Data (AEAD) algorithm. diff --git a/crypto-common/src/lib.rs b/crypto-common/src/lib.rs index 929f660c0..3a577fc3b 100644 --- a/crypto-common/src/lib.rs +++ b/crypto-common/src/lib.rs @@ -19,10 +19,10 @@ mod generate; pub use hybrid_array as array; pub use hybrid_array::typenum; +#[cfg(feature = "getrandom")] +pub use getrandom::Error as RngError; #[cfg(feature = "rand_core")] pub use {generate::Generate, rand_core}; -#[cfg(feature = "getrandom")] -pub use {getrandom, getrandom::Error as RngError}; use core::fmt; use hybrid_array::{