From 7759ac9c7851530ba3fdae9583229215f9c45da9 Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Sun, 24 Jul 2022 19:41:34 -0600 Subject: [PATCH] Enable `getrandom` feature by defaut; improve docs The `getrandom` feature transitively activates `aead/getrandom` and makes `aead::OsRng` available. RNG access is pretty essential for successful use of these crates. It's needed to generate random keys as the very least. The documentation has also been updated to show the generation of random keys, as opposed to using a hardcoded one. --- Cargo.lock | 1 - aes-gcm-siv/Cargo.toml | 2 +- aes-gcm-siv/src/lib.rs | 102 ++++++++++++++---------------- aes-gcm-siv/tests/aes128gcmsiv.rs | 4 +- aes-gcm-siv/tests/aes256gcmsiv.rs | 4 +- aes-gcm/Cargo.toml | 2 +- aes-gcm/src/lib.rs | 83 ++++++++++++------------ aes-gcm/tests/aes128gcm.rs | 2 +- aes-gcm/tests/aes256gcm.rs | 2 +- aes-gcm/tests/other_ivlen.rs | 2 +- aes-siv/Cargo.toml | 2 +- aes-siv/src/lib.rs | 57 +++++++++-------- ccm/Cargo.toml | 2 +- ccm/src/lib.rs | 32 +++++----- chacha20poly1305/Cargo.toml | 2 +- chacha20poly1305/src/lib.rs | 85 +++++++++++++------------ deoxys/Cargo.toml | 2 +- deoxys/src/lib.rs | 26 ++++---- eax/Cargo.toml | 2 +- eax/src/lib.rs | 26 ++++---- mgm/Cargo.toml | 2 +- mgm/src/lib.rs | 22 +++---- xsalsa20poly1305/Cargo.toml | 8 +-- xsalsa20poly1305/src/lib.rs | 65 ++++++++++++++----- 24 files changed, 289 insertions(+), 248 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index e9058e8e..a1503960 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -747,7 +747,6 @@ version = "0.9.0-pre.2" dependencies = [ "aead", "poly1305", - "rand_core", "salsa20", "subtle", "zeroize", diff --git a/aes-gcm-siv/Cargo.toml b/aes-gcm-siv/Cargo.toml index 5188c440..2df00a44 100644 --- a/aes-gcm-siv/Cargo.toml +++ b/aes-gcm-siv/Cargo.toml @@ -29,7 +29,7 @@ zeroize = { version = "1", default-features = false } aead = { version = "0.5", features = ["dev"], default-features = false } [features] -default = ["aes", "alloc"] +default = ["aes", "alloc", "getrandom"] std = ["aead/std", "alloc"] alloc = ["aead/alloc"] getrandom = ["aead/getrandom"] diff --git a/aes-gcm-siv/src/lib.rs b/aes-gcm-siv/src/lib.rs index d54f0595..90e63215 100644 --- a/aes-gcm-siv/src/lib.rs +++ b/aes-gcm-siv/src/lib.rs @@ -1,32 +1,20 @@ -//! [AES-GCM-SIV][1] ([RFC 8452][2]): high-performance +//! [AES-auth tag-SIV][1] ([RFC 8452][2]): high-performance //! [Authenticated Encryption with Associated Data (AEAD)][3] cipher which also //! provides [nonce reuse misuse resistance][4]. //! -//! Suitable as a general purpose symmetric encryption cipher, AES-GCM-SIV also -//! removes many of the "sharp edges" of AES-GCM, providing significantly better +//! Suitable as a general purpose symmetric encryption cipher, AES-auth tag-SIV also +//! removes many of the "sharp edges" of AES-auth tag, providing significantly better //! security bounds while simultaneously eliminating the most catastrophic risks -//! of nonce reuse that exist in AES-GCM. +//! of nonce reuse that exist in AES-auth tag. //! -//! Decryption performance is equivalent to AES-GCM. +//! Decryption performance is equivalent to AES-auth tag. //! Encryption is marginally slower. //! //! See also: //! -//! - [Adam Langley: AES-GCM-SIV][5] +//! - [Adam Langley: AES-auth tag-SIV][5] //! - [Coda Hale: Towards A Safer Footgun][6] //! -//! ## Performance Notes -//! -//! By default this crate will use software implementations of both AES and -//! the POLYVAL universal hash function. -//! -//! When targeting modern x86/x86_64 CPUs, use the following `RUSTFLAGS` to -//! take advantage of high performance AES-NI and CLMUL CPU intrinsics: -//! -//! ```text -//! RUSTFLAGS="-Ctarget-cpu=sandybridge -Ctarget-feature=+aes,+sse2,+sse4.1,+ssse3" -//! ``` -//! //! ## Security Warning //! //! No security audits of this crate have ever been performed. @@ -51,23 +39,22 @@ //! //! Simple usage (allocating, no associated data): //! -//! ``` -//! use aes_gcm_siv::{Aes256GcmSiv, Key, Nonce}; // Or `Aes128GcmSiv` -//! use aes_gcm_siv::aead::{Aead, KeyInit}; -//! -//! let key = Key::::from_slice(b"an example very very secret key."); -//! let cipher = Aes256GcmSiv::new(key); +#![cfg_attr(all(feature = "getrandom", feature = "std"), doc = "```")] +#![cfg_attr(not(all(feature = "getrandom", feature = "std")), doc = "```ignore")] +//! # fn main() -> Result<(), Box> { +//! use aes_gcm_siv::{ +//! aead::{Aead, KeyInit, OsRng}, +//! Aes256GcmSiv, Nonce // Or `Aes128GcmSiv` +//! }; //! +//! let key = Aes256GcmSiv::generate_key(&mut OsRng); +//! let cipher = Aes256GcmSiv::new(&key); //! let nonce = Nonce::from_slice(b"unique nonce"); // 96-bits; unique per message -//! -//! let ciphertext = cipher.encrypt(nonce, b"plaintext message".as_ref()) -//! .expect("encryption failure!"); // NOTE: handle this error to avoid panics! -//! -//! -//! let plaintext = cipher.decrypt(nonce, ciphertext.as_ref()) -//! .expect("decryption failure!"); // NOTE: handle this error to avoid panics! -//! +//! let ciphertext = cipher.encrypt(nonce, b"plaintext message".as_ref())?; +//! let plaintext = cipher.decrypt(nonce, ciphertext.as_ref())?; //! assert_eq!(&plaintext, b"plaintext message"); +//! # Ok(()) +//! # } //! ``` //! //! ## In-place Usage (eliminates `alloc` requirement) @@ -85,34 +72,41 @@ //! which can then be passed as the `buffer` parameter to the in-place encrypt //! and decrypt methods: //! -//! ``` -//! # #[cfg(feature = "heapless")] -//! # { -//! use aes_gcm_siv::{Aes256GcmSiv, Key, Nonce}; // Or `Aes128GcmSiv` -//! use aes_gcm_siv::aead::{AeadInPlace, KeyInit}; -//! use aes_gcm_siv::aead::heapless::Vec; -//! -//! let key = Key::::from_slice(b"an example very very secret key."); -//! let cipher = Aes256GcmSiv::new(key); -//! +#![cfg_attr( + all(feature = "getrandom", feature = "heapless", feature = "std"), + doc = "```" +)] +#![cfg_attr( + not(all(feature = "getrandom", feature = "heapless", feature = "std")), + doc = "```ignore" +)] +//! # fn main() -> Result<(), Box> { +//! use aes_gcm_siv::{ +//! aead::{AeadInPlace, KeyInit, OsRng, heapless::Vec}, +//! Aes256GcmSiv, Nonce, // Or `Aes128GcmSiv` +//! }; +//! +//! let key = Aes256GcmSiv::generate_key(&mut OsRng); +//! let cipher = Aes256GcmSiv::new(&key); //! let nonce = Nonce::from_slice(b"unique nonce"); // 96-bits; unique per message //! -//! let mut buffer: Vec = Vec::new(); +//! let mut buffer: Vec = Vec::new(); // Note: buffer needs 16-bytes overhead for auth tag tag //! buffer.extend_from_slice(b"plaintext message"); //! //! // Encrypt `buffer` in-place, replacing the plaintext contents with ciphertext -//! cipher.encrypt_in_place(nonce, b"", &mut buffer).expect("encryption failure!"); +//! cipher.encrypt_in_place(nonce, b"", &mut buffer)?; //! //! // `buffer` now contains the message ciphertext //! assert_ne!(&buffer, b"plaintext message"); //! //! // Decrypt `buffer` in-place, replacing its ciphertext context with the original plaintext -//! cipher.decrypt_in_place(nonce, b"", &mut buffer).expect("decryption failure!"); +//! cipher.decrypt_in_place(nonce, b"", &mut buffer)?; //! assert_eq!(&buffer, b"plaintext message"); +//! # Ok(()) //! # } //! ``` //! -//! [1]: https://en.wikipedia.org/wiki/AES-GCM-SIV +//! [1]: https://en.wikipedia.org/wiki/AES-auth tag-SIV //! [2]: https://tools.ietf.org/html/rfc8452 //! [3]: https://en.wikipedia.org/wiki/Authenticated_encryption //! [4]: https://github.com/miscreant/meta/wiki/Nonce-Reuse-Misuse-Resistance @@ -150,27 +144,27 @@ pub const P_MAX: u64 = 1 << 36; /// Maximum length of ciphertext (from RFC 8452 Section 6) pub const C_MAX: u64 = (1 << 36) + 16; -/// AES-GCM-SIV nonces +/// AES-auth tag-SIV nonces pub type Nonce = GenericArray; -/// AES-GCM-SIV tags +/// AES-auth tag-SIV tags pub type Tag = GenericArray; -/// AES-GCM-SIV with a 128-bit key +/// AES-auth tag-SIV with a 128-bit key #[cfg(feature = "aes")] pub type Aes128GcmSiv = AesGcmSiv; -/// AES-GCM-SIV with a 256-bit key +/// AES-auth tag-SIV with a 256-bit key #[cfg(feature = "aes")] pub type Aes256GcmSiv = AesGcmSiv; /// Counter mode with a 32-bit little endian counter. type Ctr32LE = ctr::CtrCore; -/// AES-GCM-SIV: Misuse-Resistant Authenticated Encryption Cipher (RFC 8452) +/// AES-auth tag-SIV: Misuse-Resistant Authenticated Encryption Cipher (RFC 8452) #[derive(Clone)] pub struct AesGcmSiv { - /// Key generating key used to derive AES-GCM-SIV subkeys + /// Key generating key used to derive AES-auth tag-SIV subkeys key_generating_key: Aes, } @@ -239,7 +233,7 @@ where } } -/// AES-GCM-SIV: Misuse-Resistant Authenticated Encryption Cipher (RFC 8452) +/// AES-auth tag-SIV: Misuse-Resistant Authenticated Encryption Cipher (RFC 8452) struct Cipher where Aes: BlockCipher + BlockEncrypt, @@ -258,7 +252,7 @@ impl Cipher where Aes: BlockCipher + BlockEncrypt + KeyInit, { - /// Initialize AES-GCM-SIV, deriving per-nonce message-authentication and + /// Initialize AES-auth tag-SIV, deriving per-nonce message-authentication and /// message-encryption keys. pub(crate) fn new(key_generating_key: &Aes, nonce: &Nonce) -> Self { let mut mac_key = polyval::Key::default(); diff --git a/aes-gcm-siv/tests/aes128gcmsiv.rs b/aes-gcm-siv/tests/aes128gcmsiv.rs index bb57c845..5b759b87 100644 --- a/aes-gcm-siv/tests/aes128gcmsiv.rs +++ b/aes-gcm-siv/tests/aes128gcmsiv.rs @@ -1,4 +1,4 @@ -//! AES-128-GCM-SIV tests +//! AES-128-auth tag-SIV tests #[macro_use] mod common; @@ -7,7 +7,7 @@ use self::common::TestVector; use aes_gcm_siv::aead::{generic_array::GenericArray, Aead, KeyInit, Payload}; use aes_gcm_siv::Aes128GcmSiv; -/// Test vectors from RFC8452 Appendix C.1: AEAD_AES_128_GCM_SIV +/// Test vectors from RFC8452 Appendix C.1: AEAD_AES_128_auth tag_SIV /// const TEST_VECTORS: &[TestVector<[u8; 16]>] = &[ TestVector { diff --git a/aes-gcm-siv/tests/aes256gcmsiv.rs b/aes-gcm-siv/tests/aes256gcmsiv.rs index 6cc76bf0..c9f625b6 100644 --- a/aes-gcm-siv/tests/aes256gcmsiv.rs +++ b/aes-gcm-siv/tests/aes256gcmsiv.rs @@ -1,4 +1,4 @@ -//! AES-256-GCM-SIV tests +//! AES-256-auth tag-SIV tests #[macro_use] mod common; @@ -7,7 +7,7 @@ use self::common::TestVector; use aes_gcm_siv::aead::{generic_array::GenericArray, Aead, KeyInit, Payload}; use aes_gcm_siv::Aes256GcmSiv; -/// Test vectors from RFC8452 Appendix C.2. AEAD_AES_256_GCM_SIV +/// Test vectors from RFC8452 Appendix C.2. AEAD_AES_256_auth tag_SIV /// const TEST_VECTORS: &[TestVector<[u8; 32]>] = &[ TestVector { diff --git a/aes-gcm/Cargo.toml b/aes-gcm/Cargo.toml index 8b8bb527..a86706de 100644 --- a/aes-gcm/Cargo.toml +++ b/aes-gcm/Cargo.toml @@ -30,7 +30,7 @@ aead = { version = "0.5", features = ["dev"], default-features = false } hex-literal = "0.3" [features] -default = ["aes", "alloc"] +default = ["aes", "alloc", "getrandom"] std = ["aead/std", "alloc"] alloc = ["aead/alloc"] getrandom = ["aead/getrandom"] diff --git a/aes-gcm/src/lib.rs b/aes-gcm/src/lib.rs index a501d581..4582b5cd 100644 --- a/aes-gcm/src/lib.rs +++ b/aes-gcm/src/lib.rs @@ -1,18 +1,6 @@ -//! AES-GCM: [Authenticated Encryption and Associated Data (AEAD)][1] cipher +//! AES-auth tag: [Authenticated Encryption and Associated Data (AEAD)][1] cipher //! based on AES in [Galois/Counter Mode][2]. //! -//! ## Performance Notes -//! -//! By default this crate will use software implementations of both AES and -//! the POLYVAL universal hash function. -//! -//! When targeting modern x86/x86_64 CPUs, use the following `RUSTFLAGS` to -//! take advantage of high performance AES-NI and CLMUL CPU intrinsics: -//! -//! ```text -//! RUSTFLAGS="-Ctarget-cpu=sandybridge -Ctarget-feature=+aes,+sse2,+sse4.1,+ssse3" -//! ``` -//! //! ## Security Notes //! //! This crate has received one [security audit by NCC Group][3], with no significant @@ -31,22 +19,22 @@ //! //! Simple usage (allocating, no associated data): //! -//! ``` -//! use aes_gcm::{Aes256Gcm, Key, Nonce}; // Or `Aes128Gcm` -//! use aes_gcm::aead::{Aead, KeyInit}; -//! -//! let key = Key::::from_slice(b"an example very very secret key."); -//! let cipher = Aes256Gcm::new(key); +#![cfg_attr(all(feature = "getrandom", feature = "std"), doc = "```")] +#![cfg_attr(not(all(feature = "getrandom", feature = "std")), doc = "```ignore")] +//! # fn main() -> Result<(), Box> { +//! use aes_gcm::{ +//! aead::{Aead, KeyInit, OsRng}, +//! Aes256Gcm, Nonce // Or `Aes128Gcm` +//! }; //! +//! let key = Aes256Gcm::generate_key(&mut OsRng); +//! let cipher = Aes256Gcm::new(&key); //! let nonce = Nonce::from_slice(b"unique nonce"); // 96-bits; unique per message -//! -//! let ciphertext = cipher.encrypt(nonce, b"plaintext message".as_ref()) -//! .expect("encryption failure!"); // NOTE: handle this error to avoid panics! -//! -//! let plaintext = cipher.decrypt(nonce, ciphertext.as_ref()) -//! .expect("decryption failure!"); // NOTE: handle this error to avoid panics! -//! +//! let ciphertext = cipher.encrypt(nonce, b"plaintext message".as_ref())?; +//! let plaintext = cipher.decrypt(nonce, ciphertext.as_ref())?; //! assert_eq!(&plaintext, b"plaintext message"); +//! # Ok(()) +//! # } //! ``` //! //! ## In-place Usage (eliminates `alloc` requirement) @@ -64,29 +52,38 @@ //! which can then be passed as the `buffer` parameter to the in-place encrypt //! and decrypt methods: //! -#![cfg_attr(feature = "heapless", doc = " ```")] -#![cfg_attr(not(feature = "heapless"), doc = " ```ignore")] -//! use aes_gcm::{Aes256Gcm, Key, Nonce}; // Or `Aes128Gcm` -//! use aes_gcm::aead::{AeadInPlace, KeyInit}; -//! use aes_gcm::aead::heapless::Vec; -//! -//! let key = Key::::from_slice(b"an example very very secret key."); -//! let cipher = Aes256Gcm::new(key); +#![cfg_attr( + all(feature = "getrandom", feature = "heapless", feature = "std"), + doc = "```" +)] +#![cfg_attr( + not(all(feature = "getrandom", feature = "heapless", feature = "std")), + doc = "```ignore" +)] +//! # fn main() -> Result<(), Box> { +//! use aes_gcm::{ +//! aead::{AeadInPlace, KeyInit, OsRng, heapless::Vec}, +//! Aes256Gcm, Nonce, // Or `Aes128Gcm` +//! }; //! +//! let key = Aes256Gcm::generate_key(&mut OsRng); +//! let cipher = Aes256Gcm::new(&key); //! let nonce = Nonce::from_slice(b"unique nonce"); // 96-bits; unique per message //! -//! let mut buffer: Vec = Vec::new(); // Buffer needs 16-bytes overhead for GCM tag +//! let mut buffer: Vec = Vec::new(); // Note: buffer needs 16-bytes overhead for auth tag tag //! buffer.extend_from_slice(b"plaintext message"); //! //! // Encrypt `buffer` in-place, replacing the plaintext contents with ciphertext -//! cipher.encrypt_in_place(nonce, b"", &mut buffer).expect("encryption failure!"); +//! cipher.encrypt_in_place(nonce, b"", &mut buffer)?; //! //! // `buffer` now contains the message ciphertext //! assert_ne!(&buffer, b"plaintext message"); //! //! // Decrypt `buffer` in-place, replacing its ciphertext context with the original plaintext -//! cipher.decrypt_in_place(nonce, b"", &mut buffer).expect("decryption failure!"); +//! cipher.decrypt_in_place(nonce, b"", &mut buffer)?; //! assert_eq!(&buffer, b"plaintext message"); +//! # Ok(()) +//! # } //! ``` //! //! [1]: https://en.wikipedia.org/wiki/Authenticated_encryption @@ -131,18 +128,18 @@ pub const P_MAX: u64 = 1 << 36; /// Maximum length of ciphertext pub const C_MAX: u64 = (1 << 36) + 16; -/// AES-GCM nonces +/// AES-auth tag nonces pub type Nonce = GenericArray; -/// AES-GCM tags +/// AES-auth tag tags pub type Tag = GenericArray; -/// AES-GCM with a 128-bit key and 96-bit nonce +/// AES-auth tag with a 128-bit key and 96-bit nonce #[cfg(feature = "aes")] #[cfg_attr(docsrs, doc(cfg(feature = "aes")))] pub type Aes128Gcm = AesGcm; -/// AES-GCM with a 256-bit key and 96-bit nonce +/// AES-auth tag with a 256-bit key and 96-bit nonce #[cfg(feature = "aes")] #[cfg_attr(docsrs, doc(cfg(feature = "aes")))] pub type Aes256Gcm = AesGcm; @@ -153,7 +150,7 @@ type Block = GenericArray; /// Counter mode with a 32-bit big endian counter. type Ctr32BE = ctr::CtrCore; -/// AES-GCM: generic over an underlying AES implementation and nonce size. +/// AES-auth tag: generic over an underlying AES implementation and nonce size. /// /// This type is generic to support substituting alternative AES implementations /// (e.g. embedded hardware implementations) @@ -161,7 +158,7 @@ type Ctr32BE = ctr::CtrCore; /// It is NOT intended to be instantiated with any block cipher besides AES! /// Doing so runs the risk of unintended cryptographic properties! /// -/// The `N` generic parameter can be used to instantiate AES-GCM with other +/// The `N` generic parameter can be used to instantiate AES-auth tag with other /// nonce sizes, however it's recommended to use it with `typenum::U12`, /// the default of 96-bits. /// diff --git a/aes-gcm/tests/aes128gcm.rs b/aes-gcm/tests/aes128gcm.rs index 8b449918..7d4e5db0 100644 --- a/aes-gcm/tests/aes128gcm.rs +++ b/aes-gcm/tests/aes128gcm.rs @@ -1,4 +1,4 @@ -//! AES-128-GCM tests +//! AES-128-auth tag tests #[macro_use] mod common; diff --git a/aes-gcm/tests/aes256gcm.rs b/aes-gcm/tests/aes256gcm.rs index 317fe12a..82c9f1f6 100644 --- a/aes-gcm/tests/aes256gcm.rs +++ b/aes-gcm/tests/aes256gcm.rs @@ -1,4 +1,4 @@ -//! AES-256-GCM tests +//! AES-256-auth tag tests #[macro_use] mod common; diff --git a/aes-gcm/tests/other_ivlen.rs b/aes-gcm/tests/other_ivlen.rs index b3915a51..66b14d03 100644 --- a/aes-gcm/tests/other_ivlen.rs +++ b/aes-gcm/tests/other_ivlen.rs @@ -1,4 +1,4 @@ -//! Tests for AES-GCM when used with non-96-bit IVs. +//! Tests for AES-auth tag when used with non-96-bit IVs. //! //! Vectors taken from NIST CAVS vectors' `gcmEncryptExtIV128.rsp` file: //! diff --git a/aes-siv/Cargo.toml b/aes-siv/Cargo.toml index 70ae48c6..9a1fe969 100644 --- a/aes-siv/Cargo.toml +++ b/aes-siv/Cargo.toml @@ -34,7 +34,7 @@ blobby = "0.3" hex-literal = "0.3" [features] -default = ["alloc"] +default = ["alloc", "getrandom"] std = ["aead/std", "alloc"] alloc = ["aead/alloc"] getrandom = ["aead/getrandom"] diff --git a/aes-siv/src/lib.rs b/aes-siv/src/lib.rs index 62846b77..d1ed2754 100644 --- a/aes-siv/src/lib.rs +++ b/aes-siv/src/lib.rs @@ -6,22 +6,22 @@ //! //! Simple usage (allocating, no associated data): //! -//! ``` -//! use aes_siv::{Aes128SivAead, Key, Nonce}; // Or `Aes256SivAead` -//! use aes_siv::aead::{Aead, KeyInit}; -//! -//! let key = Key::::from_slice(b"an example very very secret key."); -//! let cipher = Aes128SivAead::new(key); +#![cfg_attr(all(feature = "getrandom", feature = "std"), doc = "```")] +#![cfg_attr(not(all(feature = "getrandom", feature = "std")), doc = "```ignore")] +//! # fn main() -> Result<(), Box> { +//! use aes_siv::{ +//! aead::{Aead, KeyInit, OsRng}, +//! Aes256SivAead, Nonce // Or `Aes128SivAead` +//! }; //! +//! let key = Aes256SivAead::generate_key(&mut OsRng); +//! let cipher = Aes256SivAead::new(&key); //! let nonce = Nonce::from_slice(b"any unique nonce"); // 128-bits; unique per message -//! -//! let ciphertext = cipher.encrypt(nonce, b"plaintext message".as_ref()) -//! .expect("encryption failure!"); // NOTE: handle this error to avoid panics! -//! -//! let plaintext = cipher.decrypt(nonce, ciphertext.as_ref()) -//! .expect("decryption failure!"); // NOTE: handle this error to avoid panics! -//! +//! let ciphertext = cipher.encrypt(nonce, b"plaintext message".as_ref())?; +//! let plaintext = cipher.decrypt(nonce, ciphertext.as_ref())?; //! assert_eq!(&plaintext, b"plaintext message"); +//! # Ok(()) +//! # } //! ``` //! //! ## In-place Usage (eliminates `alloc` requirement) @@ -39,30 +39,37 @@ //! which can then be passed as the `buffer` parameter to the in-place encrypt //! and decrypt methods: //! -//! ``` -//! # #[cfg(feature = "heapless")] -//! # { -//! use aes_siv::{Aes128SivAead, Key, Nonce}; // Or `Aes256SivAead` -//! use aes_siv::aead::{AeadInPlace, KeyInit}; -//! use aes_siv::aead::heapless::Vec; -//! -//! let key = Key::::from_slice(b"an example very very secret key."); -//! let cipher = Aes128SivAead::new(key); +#![cfg_attr( + all(feature = "getrandom", feature = "heapless", feature = "std"), + doc = "```" +)] +#![cfg_attr( + not(all(feature = "getrandom", feature = "heapless", feature = "std")), + doc = "```ignore" +)] +//! # fn main() -> Result<(), Box> { +//! use aes_siv::{ +//! aead::{AeadInPlace, KeyInit, OsRng, heapless::Vec}, +//! Aes256SivAead, Nonce, // Or `Aes128SivAead` +//! }; //! +//! let key = Aes256SivAead::generate_key(&mut OsRng); +//! let cipher = Aes256SivAead::new(&key); //! let nonce = Nonce::from_slice(b"any unique nonce"); // 128-bits; unique per message //! -//! let mut buffer: Vec = Vec::new(); +//! let mut buffer: Vec = Vec::new(); // Note: buffer needs 16-bytes overhead for auth tag tag //! buffer.extend_from_slice(b"plaintext message"); //! //! // Encrypt `buffer` in-place, replacing the plaintext contents with ciphertext -//! cipher.encrypt_in_place(nonce, b"", &mut buffer).expect("encryption failure!"); +//! cipher.encrypt_in_place(nonce, b"", &mut buffer)?; //! //! // `buffer` now contains the message ciphertext //! assert_ne!(&buffer, b"plaintext message"); //! //! // Decrypt `buffer` in-place, replacing its ciphertext context with the original plaintext -//! cipher.decrypt_in_place(nonce, b"", &mut buffer).expect("decryption failure!"); +//! cipher.decrypt_in_place(nonce, b"", &mut buffer)?; //! assert_eq!(&buffer, b"plaintext message"); +//! # Ok(()) //! # } //! ``` //! diff --git a/ccm/Cargo.toml b/ccm/Cargo.toml index 787e3ecb..fd055209 100644 --- a/ccm/Cargo.toml +++ b/ccm/Cargo.toml @@ -25,7 +25,7 @@ aes = { version = "0.8.1" } hex-literal = "0.3.4" [features] -default = ["alloc"] +default = ["alloc", "getrandom"] std = ["aead/std", "alloc"] alloc = ["aead/alloc"] getrandom = ["aead/getrandom"] diff --git a/ccm/src/lib.rs b/ccm/src/lib.rs index 3bd4b370..36fb6ead 100644 --- a/ccm/src/lib.rs +++ b/ccm/src/lib.rs @@ -6,27 +6,29 @@ //! //! Simple usage (allocating, no associated data): //! -//! ``` -//! use ccm::{Ccm, consts::{U10, U13}}; -//! use ccm::aead::{Aead, KeyInit, generic_array::GenericArray}; +#![cfg_attr(all(feature = "getrandom", feature = "std"), doc = "```")] +#![cfg_attr(not(all(feature = "getrandom", feature = "std")), doc = "```ignore")] +//! # fn main() -> Result<(), Box> { //! use aes::Aes256; +//! use ccm::{ +//! aead::{Aead, KeyInit, OsRng, generic_array::GenericArray}, +//! consts::{U10, U13}, +//! Ccm, +//! }; //! -//! // AES-CCM type with tag and nonce size equal to 10 and 13 bytes respectively -//! type AesCcm = Ccm; -//! -//! let key = GenericArray::from_slice(b"an example very very secret key."); -//! let cipher = AesCcm::new(key); +//! // AES-256-CCM type with tag and nonce size equal to 10 and 13 bytes respectively +//! pub type Aes256Ccm = Ccm; //! +//! let key = Aes256Ccm::generate_key(&mut OsRng); +//! let cipher = Aes256Ccm::new(&key); //! let nonce = GenericArray::from_slice(b"unique nonce."); // 13-bytes; unique per message -//! -//! let ciphertext = cipher.encrypt(nonce, b"plaintext message".as_ref()) -//! .expect("encryption failure!"); // NOTE: handle this error to avoid panics! -//! -//! let plaintext = cipher.decrypt(nonce, ciphertext.as_ref()) -//! .expect("decryption failure!"); // NOTE: handle this error to avoid panics! -//! +//! let ciphertext = cipher.encrypt(nonce, b"plaintext message".as_ref())?; +//! let plaintext = cipher.decrypt(nonce, ciphertext.as_ref())?; //! assert_eq!(&plaintext, b"plaintext message"); +//! # Ok(()) +//! # } //! ``` +//! //! This crate implements traits from the [`aead`] crate and is capable to perfrom //! encryption and decryption in-place wihout relying on `alloc`. //! diff --git a/chacha20poly1305/Cargo.toml b/chacha20poly1305/Cargo.toml index ea4eb02a..02873edf 100644 --- a/chacha20poly1305/Cargo.toml +++ b/chacha20poly1305/Cargo.toml @@ -28,7 +28,7 @@ zeroize = { version = "1", default-features = false } aead = { version = "0.5", features = ["dev"], default-features = false } [features] -default = ["alloc"] +default = ["alloc", "getrandom"] std = ["aead/std", "alloc"] alloc = ["aead/alloc"] getrandom = ["aead/getrandom"] diff --git a/chacha20poly1305/src/lib.rs b/chacha20poly1305/src/lib.rs index 46b763a1..32afe2a0 100644 --- a/chacha20poly1305/src/lib.rs +++ b/chacha20poly1305/src/lib.rs @@ -30,23 +30,21 @@ //! //! # Usage //! -//! ``` -//! # #[cfg(feature = "alloc")] -//! # { -//! use chacha20poly1305::{ChaCha20Poly1305, Key, Nonce}; // Or `XChaCha20Poly1305` -//! use chacha20poly1305::aead::{Aead, KeyInit}; -//! -//! let key = Key::from_slice(b"an example very very secret key."); // 32-bytes -//! let cipher = ChaCha20Poly1305::new(key); -//! +#![cfg_attr(all(feature = "getrandom", feature = "std"), doc = "```")] +#![cfg_attr(not(all(feature = "getrandom", feature = "std")), doc = "```ignore")] +//! # fn main() -> Result<(), Box> { +//! use chacha20poly1305::{ +//! aead::{Aead, KeyInit, OsRng}, +//! ChaCha20Poly1305, Nonce +//! }; +//! +//! let key = ChaCha20Poly1305::generate_key(&mut OsRng); +//! let cipher = ChaCha20Poly1305::new(&key); //! let nonce = Nonce::from_slice(b"unique nonce"); // 12-bytes; unique per message -//! -//! let ciphertext = cipher.encrypt(nonce, b"plaintext message".as_ref()) -//! .expect("encryption failure!"); // NOTE: handle this error to avoid panics! -//! let plaintext = cipher.decrypt(nonce, ciphertext.as_ref()) -//! .expect("decryption failure!"); // NOTE: handle this error to avoid panics! -//! +//! let ciphertext = cipher.encrypt(nonce, b"plaintext message".as_ref())?; +//! let plaintext = cipher.decrypt(nonce, ciphertext.as_ref())?; //! assert_eq!(&plaintext, b"plaintext message"); +//! # Ok(()) //! # } //! ``` //! @@ -65,30 +63,37 @@ //! which can then be passed as the `buffer` parameter to the in-place encrypt //! and decrypt methods: //! -//! ``` -//! # #[cfg(feature = "heapless")] -//! # { -//! use chacha20poly1305::{ChaCha20Poly1305, Key, Nonce}; // Or `XChaCha20Poly1305` -//! use chacha20poly1305::aead::{AeadInPlace, KeyInit}; -//! use chacha20poly1305::aead::heapless::Vec; -//! -//! let key = Key::from_slice(b"an example very very secret key."); -//! let cipher = ChaCha20Poly1305::new(key); -//! -//! let nonce = Nonce::from_slice(b"unique nonce"); // 96-bits; unique per message +#![cfg_attr( + all(feature = "getrandom", feature = "heapless", feature = "std"), + doc = "```" +)] +#![cfg_attr( + not(all(feature = "getrandom", feature = "heapless", feature = "std")), + doc = "```ignore" +)] +//! # fn main() -> Result<(), Box> { +//! use chacha20poly1305::{ +//! aead::{AeadInPlace, KeyInit, OsRng, heapless::Vec}, +//! ChaCha20Poly1305, Nonce, +//! }; +//! +//! let key = ChaCha20Poly1305::generate_key(&mut OsRng); +//! let cipher = ChaCha20Poly1305::new(&key); +//! let nonce = Nonce::from_slice(b"unique nonce"); // 12-bytes; unique per message //! -//! let mut buffer: Vec = Vec::new(); +//! let mut buffer: Vec = Vec::new(); // Note: buffer needs 16-bytes overhead for auth tag tag //! buffer.extend_from_slice(b"plaintext message"); //! //! // Encrypt `buffer` in-place, replacing the plaintext contents with ciphertext -//! cipher.encrypt_in_place(nonce, b"", &mut buffer).expect("encryption failure!"); +//! cipher.encrypt_in_place(nonce, b"", &mut buffer)?; //! //! // `buffer` now contains the message ciphertext //! assert_ne!(&buffer, b"plaintext message"); //! //! // Decrypt `buffer` in-place, replacing its ciphertext context with the original plaintext -//! cipher.decrypt_in_place(nonce, b"", &mut buffer).expect("decryption failure!"); +//! cipher.decrypt_in_place(nonce, b"", &mut buffer)?; //! assert_eq!(&buffer, b"plaintext message"); +//! # Ok(()) //! # } //! ``` //! @@ -121,19 +126,21 @@ //! //! # Usage //! -//! ``` -//! # #[cfg(feature = "alloc")] -//! # { -//! use chacha20poly1305::{XChaCha20Poly1305, Key, XNonce}; -//! use chacha20poly1305::aead::{Aead, KeyInit}; -//! -//! let key = Key::from_slice(b"an example very very secret key."); // 32-bytes -//! let aead = XChaCha20Poly1305::new(key); +#![cfg_attr(all(feature = "getrandom", feature = "std"), doc = "```")] +#![cfg_attr(not(all(feature = "getrandom", feature = "std")), doc = "```ignore")] +//! # fn main() -> Result<(), Box> { +//! use chacha20poly1305::{ +//! aead::{Aead, KeyInit, OsRng}, +//! XChaCha20Poly1305, XNonce +//! }; //! +//! let key = XChaCha20Poly1305::generate_key(&mut OsRng); +//! let cipher = XChaCha20Poly1305::new(&key); //! let nonce = XNonce::from_slice(b"extra long unique nonce!"); // 24-bytes; unique -//! let ciphertext = aead.encrypt(nonce, b"plaintext message".as_ref()).expect("encryption failure!"); -//! let plaintext = aead.decrypt(nonce, ciphertext.as_ref()).expect("decryption failure!"); +//! let ciphertext = cipher.encrypt(nonce, b"plaintext message".as_ref())?; +//! let plaintext = cipher.decrypt(nonce, ciphertext.as_ref())?; //! assert_eq!(&plaintext, b"plaintext message"); +//! # Ok(()) //! # } //! ``` //! diff --git a/deoxys/Cargo.toml b/deoxys/Cargo.toml index 48eb13d7..ea1bb791 100644 --- a/deoxys/Cargo.toml +++ b/deoxys/Cargo.toml @@ -28,7 +28,7 @@ aead = { version = "0.5", features = ["dev"], default-features = false } hex-literal = "0.3" [features] -default = ["alloc"] +default = ["alloc", "getrandom"] std = ["aead/std", "alloc"] alloc = ["aead/alloc"] getrandom = ["aead/getrandom"] diff --git a/deoxys/src/lib.rs b/deoxys/src/lib.rs index 72846400..bc096a69 100644 --- a/deoxys/src/lib.rs +++ b/deoxys/src/lib.rs @@ -13,22 +13,24 @@ //! **USE AT YOUR OWN RISK.** //! //! # Usage -//! ``` -//! use deoxys::{DeoxysII256, Key, Nonce}; // Can be `DeoxysI128`, `DeoxysI256`, `DeoxysII128` of `DeoxysII256` -//! use deoxys::aead::{Aead, KeyInit}; //! -//! let key = Key::::from_slice(b"an example very very secret key."); -//! let cipher = DeoxysII256::new(key); +#![cfg_attr(all(feature = "getrandom", feature = "std"), doc = "```")] +#![cfg_attr(not(all(feature = "getrandom", feature = "std")), doc = "```ignore")] +//! # fn main() -> Result<(), Box> { +//! use deoxys::{ +//! aead::{Aead, KeyInit, OsRng}, +//! DeoxysII256, // Can be `DeoxysI128`, `DeoxysI256`, `DeoxysII128` of `DeoxysII256` +//! Nonce // Or `Aes128Gcm` +//! }; //! +//! let key = DeoxysII256::generate_key(&mut OsRng); +//! let cipher = DeoxysII256::new(&key); //! let nonce = Nonce::from_slice(b"unique nonce123"); // 64-bits for Deoxys-I or 120-bits for Deoxys-II; unique per message -//! -//! let ciphertext = cipher.encrypt(nonce, b"plaintext message".as_ref()) -//! .expect("encryption failure!"); // NOTE: handle this error to avoid panics! -//! -//! let plaintext = cipher.decrypt(nonce, ciphertext.as_ref()) -//! .expect("decryption failure!"); // NOTE: handle this error to avoid panics! -//! +//! let ciphertext = cipher.encrypt(nonce, b"plaintext message".as_ref())?; +//! let plaintext = cipher.decrypt(nonce, ciphertext.as_ref())?; //! assert_eq!(&plaintext, b"plaintext message"); +//! # Ok(()) +//! # } //! ``` //! //! ## Usage with AAD diff --git a/eax/Cargo.toml b/eax/Cargo.toml index 0326f431..3b2d4a56 100644 --- a/eax/Cargo.toml +++ b/eax/Cargo.toml @@ -31,7 +31,7 @@ aead = { version = "0.5", features = ["dev"], default-features = false } aes = "0.7" [features] -default = ["alloc"] +default = ["alloc", "getrandom"] std = ["aead/std", "alloc"] alloc = ["aead/alloc"] getrandom = ["aead/getrandom"] diff --git a/eax/src/lib.rs b/eax/src/lib.rs index 576e470d..c708e4ce 100644 --- a/eax/src/lib.rs +++ b/eax/src/lib.rs @@ -5,23 +5,25 @@ //! //! Simple usage (allocating, no associated data): //! -//! ``` +#![cfg_attr(all(feature = "getrandom", feature = "std"), doc = "```")] +#![cfg_attr(not(all(feature = "getrandom", feature = "std")), doc = "```ignore")] +//! # fn main() -> Result<(), Box> { //! use aes::Aes256; -//! use eax::Eax; -//! use eax::aead::{Aead, KeyInit, generic_array::GenericArray}; +//! use eax::{ +//! aead::{Aead, KeyInit, OsRng, generic_array::GenericArray}, +//! Eax, Nonce +//! }; //! -//! let key = GenericArray::from_slice(b"an example very very secret key."); -//! let cipher = Eax::::new(key); +//! pub type Aes256Eax = Eax; //! +//! let key = Aes256Eax::generate_key(&mut OsRng); +//! let cipher = Aes256Eax::new(&key); //! let nonce = GenericArray::from_slice(b"my unique nonces"); // 128-bits; unique per message -//! -//! let ciphertext = cipher.encrypt(nonce, b"plaintext message".as_ref()) -//! .expect("encryption failure!"); // NOTE: handle this error to avoid panics! -//! -//! let plaintext = cipher.decrypt(nonce, ciphertext.as_ref()) -//! .expect("decryption failure!"); // NOTE: handle this error to avoid panics! -//! +//! let ciphertext = cipher.encrypt(nonce, b"plaintext message".as_ref())?; +//! let plaintext = cipher.decrypt(nonce, ciphertext.as_ref())?; //! assert_eq!(&plaintext, b"plaintext message"); +//! # Ok(()) +//! # } //! ``` //! //! ## In-place Usage (eliminates `alloc` requirement) diff --git a/mgm/Cargo.toml b/mgm/Cargo.toml index 6137069c..d9a81c15 100644 --- a/mgm/Cargo.toml +++ b/mgm/Cargo.toml @@ -29,7 +29,7 @@ magma = "0.7" hex-literal = "0.2" [features] -default = ["alloc"] +default = ["alloc", "getrandom"] std = ["aead/std", "alloc"] alloc = ["aead/alloc"] getrandom = ["aead/getrandom"] diff --git a/mgm/src/lib.rs b/mgm/src/lib.rs index e4522a3e..cf602392 100644 --- a/mgm/src/lib.rs +++ b/mgm/src/lib.rs @@ -1,27 +1,25 @@ //! Generic implementation of [Multilinear Galous Mode][1] [AEAD] construction. //! //! # Example -//! ``` -//! # #[cfg(feature = "alloc")] -//! # { -//! use mgm::Mgm; +#![cfg_attr(all(feature = "getrandom", feature = "std"), doc = "```")] +#![cfg_attr(not(all(feature = "getrandom", feature = "std")), doc = "```ignore")] +//! # fn main() -> Result<(), Box> { //! use kuznyechik::Kuznyechik; -//! use mgm::aead::{Aead, KeyInit, generic_array::GenericArray}; +//! use mgm::Mgm; +//! use mgm::aead::{Aead, KeyInit, OsRng, generic_array::GenericArray}; //! -//! let key = GenericArray::from_slice(b"very secret key very secret key "); -//! let cipher = Mgm::::new(key); +//! let key = Mgm::::generate_key(&mut OsRng); +//! let cipher = Mgm::::new(&key); //! //! // 127-bit nonce value, since API has to accept 128 bits, first nonce bit //! // MUST be equal to zero, otherwise encryption and decryption will fail //! let nonce = GenericArray::from_slice(b"unique nonce val"); //! -//! // NOTE: handle errors to avoid panics! -//! let ciphertext = cipher.encrypt(nonce, b"plaintext message".as_ref()) -//! .expect("encryption failure!"); -//! let plaintext = cipher.decrypt(nonce, ciphertext.as_ref()) -//! .expect("decryption failure!"); +//! let ciphertext = cipher.encrypt(nonce, b"plaintext message".as_ref())?; +//! let plaintext = cipher.decrypt(nonce, ciphertext.as_ref())?; //! //! assert_eq!(&plaintext, b"plaintext message"); +//! # Ok(()) //! # } //! ``` //! diff --git a/xsalsa20poly1305/Cargo.toml b/xsalsa20poly1305/Cargo.toml index 5131a6c3..3bbe0788 100644 --- a/xsalsa20poly1305/Cargo.toml +++ b/xsalsa20poly1305/Cargo.toml @@ -19,16 +19,16 @@ rust-version = "1.56" aead = { version = "0.5", default-features = false } salsa20 = { version = "0.10", features = ["zeroize"] } poly1305 = "=0.8.0-pre.2" -rand_core = { version = "0.6", optional = true } subtle = { version = "2", default-features = false } zeroize = { version = "1", default-features = false } [features] -default = ["alloc", "rand_core", "aead/rand_core"] -std = ["aead/std", "alloc", "rand_core/std"] +default = ["alloc", "getrandom"] +std = ["aead/std", "alloc"] alloc = ["aead/alloc"] -getrandom = ["aead/getrandom"] +getrandom = ["aead/getrandom", "rand_core"] heapless = ["aead/heapless"] +rand_core = ["aead/rand_core"] stream = ["aead/stream"] [package.metadata.docs.rs] diff --git a/xsalsa20poly1305/src/lib.rs b/xsalsa20poly1305/src/lib.rs index 80cd47c8..37328760 100644 --- a/xsalsa20poly1305/src/lib.rs +++ b/xsalsa20poly1305/src/lib.rs @@ -21,23 +21,22 @@ //! //! # Usage //! -//! ``` -//! use xsalsa20poly1305::XSalsa20Poly1305; -//! use xsalsa20poly1305::aead::{Aead, KeyInit, generic_array::GenericArray}; -//! -//! let key = GenericArray::from_slice(b"an example very very secret key."); -//! let cipher = XSalsa20Poly1305::new(key); -//! -//! // 24-bytes; unique per message -//! // Use `xsalsa20poly1305::generate_nonce()` to randomly generate one -//! let nonce = GenericArray::from_slice(b"extra long unique nonce!"); -//! -//! let ciphertext = cipher.encrypt(nonce, b"plaintext message".as_ref()) -//! .expect("encryption failure!"); // NOTE: handle this error to avoid panics! -//! let plaintext = cipher.decrypt(nonce, ciphertext.as_ref()) -//! .expect("decryption failure!"); // NOTE: handle this error to avoid panics! +#![cfg_attr(all(feature = "getrandom", feature = "std"), doc = "```")] +#![cfg_attr(not(all(feature = "getrandom", feature = "std")), doc = "```ignore")] +//! # fn main() -> Result<(), Box> { +//! use xsalsa20poly1305::{ +//! aead::{Aead, KeyInit, OsRng}, +//! XSalsa20Poly1305, Nonce +//! }; //! +//! let key = XSalsa20Poly1305::generate_key(&mut OsRng); +//! let cipher = XSalsa20Poly1305::new(&key); +//! let nonce = XSalsa20Poly1305::generate_nonce(&mut OsRng); // unique per message +//! let ciphertext = cipher.encrypt(&nonce, b"plaintext message".as_ref())?; +//! let plaintext = cipher.decrypt(&nonce, ciphertext.as_ref())?; //! assert_eq!(&plaintext, b"plaintext message"); +//! # Ok(()) +//! # } //! ``` //! //! ## In-place Usage (eliminates `alloc` requirement) @@ -55,6 +54,40 @@ //! which can then be passed as the `buffer` parameter to the in-place encrypt //! and decrypt methods: //! +#![cfg_attr( + all(feature = "getrandom", feature = "heapless", feature = "std"), + doc = "```" +)] +#![cfg_attr( + not(all(feature = "getrandom", feature = "heapless", feature = "std")), + doc = "```ignore" +)] +//! # fn main() -> Result<(), Box> { +//! use xsalsa20poly1305::{ +//! aead::{AeadInPlace, KeyInit, OsRng, heapless::Vec}, +//! XSalsa20Poly1305, Nonce, +//! }; +//! +//! let key = XSalsa20Poly1305::generate_key(&mut OsRng); +//! let cipher = XSalsa20Poly1305::new(&key); +//! let nonce = XSalsa20Poly1305::generate_nonce(&mut OsRng); // unique per message +//! +//! let mut buffer: Vec = Vec::new(); // Note: buffer needs 16-bytes overhead for auth tag tag +//! buffer.extend_from_slice(b"plaintext message"); +//! +//! // Encrypt `buffer` in-place, replacing the plaintext contents with ciphertext +//! cipher.encrypt_in_place(&nonce, b"", &mut buffer)?; +//! +//! // `buffer` now contains the message ciphertext +//! assert_ne!(&buffer, b"plaintext message"); +//! +//! // Decrypt `buffer` in-place, replacing its ciphertext context with the original plaintext +//! cipher.decrypt_in_place(&nonce, b"", &mut buffer)?; +//! assert_eq!(&buffer, b"plaintext message"); +//! # Ok(()) +//! # } +//! ``` +//! //! ``` //! # #[cfg(feature = "heapless")] //! # { @@ -114,7 +147,7 @@ use salsa20::{ use zeroize::Zeroize; #[cfg(feature = "rand_core")] -use rand_core::{CryptoRng, RngCore}; +use aead::rand_core::{CryptoRng, RngCore}; /// Size of an XSalsa20Poly1305 key in bytes pub const KEY_SIZE: usize = 32;