Skip to content

Commit

Permalink
chacha20+salsa20: remove extended-nonce feature gating (#271)
Browse files Browse the repository at this point in the history
Removes feature gating of `xchacha20` and `xsalsa20`, making them an
always-enabled part of the API.

This cuts down on a growingly excessive number of feature combinations.
  • Loading branch information
tarcieri authored Aug 29, 2021
1 parent 2e64ad5 commit 9e9ee30
Show file tree
Hide file tree
Showing 10 changed files with 32 additions and 69 deletions.
3 changes: 1 addition & 2 deletions .github/workflows/chacha20.yml
Original file line number Diff line number Diff line change
Expand Up @@ -42,8 +42,7 @@ jobs:
- run: cargo build --target ${{ matrix.target }} --release --no-default-features --features hchacha
- run: cargo build --target ${{ matrix.target }} --release --no-default-features --features legacy
- run: cargo build --target ${{ matrix.target }} --release --no-default-features --features rng
- run: cargo build --target ${{ matrix.target }} --release --no-default-features --features xchacha
- run: cargo build --target ${{ matrix.target }} --release --no-default-features --features cipher,force-soft,legacy,rng,xchacha,zeroize
- run: cargo build --target ${{ matrix.target }} --release --no-default-features --features cipher,force-soft,legacy,rng,zeroize

# Tests for runtime AVX2 detection
autodetect:
Expand Down
9 changes: 5 additions & 4 deletions chacha20/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@ edition = "2018"

[dependencies]
cfg-if = "1"

# optional dependencies
cipher = { version = "0.3", optional = true }
rand_core = { version = "0.6", optional = true, default-features = false }
zeroize = { version = ">=1, <1.5", optional = true, default-features = false }
Expand All @@ -30,15 +32,14 @@ cipher = { version = "0.3", features = ["dev"] }
hex-literal = "0.2"

[features]
default = ["xchacha"]
default = ["cipher"]
expose-core = []
force-soft = []
hchacha = ["xchacha"]
hchacha = ["cipher"]
legacy = ["cipher"]
rng = ["rand_core"]
std = ["cipher/std"]
xchacha = ["cipher"]

[package.metadata.docs.rs]
features = ["legacy", "rng", "std", "xchacha"]
features = ["legacy", "rng", "std"]
rustdoc-args = ["--cfg", "docsrs"]
4 changes: 1 addition & 3 deletions chacha20/src/backend.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,12 +14,10 @@ cfg_if! {
pub(crate) mod autodetect;
pub(crate) mod avx2;
pub(crate) mod sse2;
pub(crate) mod soft;

pub(crate) use self::autodetect::BUFFER_SIZE;
pub use self::autodetect::Core;

#[cfg(feature = "xchacha")]
pub(crate) mod soft;
} else {
pub(crate) mod soft;
pub(crate) use self::soft::BUFFER_SIZE;
Expand Down
15 changes: 9 additions & 6 deletions chacha20/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
//! - [`ChaCha20`]: standard IETF variant with 96-bit nonce
//! - [`ChaCha20Legacy`]: (gated under the `legacy` feature) "djb" variant with 64-bit nonce
//! - [`ChaCha8`] / [`ChaCha12`]: reduced round variants of ChaCha20
//! - [`XChaCha20`]: (gated under the `xchacha20` feature) 192-bit extended nonce variant
//! - [`XChaCha20`]: 192-bit extended nonce variant
//! - [`XChaCha8`] / [`XChaCha12`]: reduced round variants of XChaCha20
//!
//! # ⚠️ Security Warning: [Hazmat!]
Expand Down Expand Up @@ -42,6 +42,8 @@
//! # Usage
//!
//! ```
//! # #[cfg(feature = "cipher")]
//! # {
//! use chacha20::{ChaCha20, Key, Nonce};
//! use chacha20::cipher::{NewCipher, StreamCipher, StreamCipherSeek};
//!
Expand All @@ -61,6 +63,7 @@
//! cipher.seek(0);
//! cipher.apply_keystream(&mut data);
//! assert_eq!(data, [1, 2, 3, 4, 5, 6, 7]);
//! # }
//! ```
//!
//! [RFC 8439]: https://tools.ietf.org/html/rfc8439
Expand All @@ -85,14 +88,17 @@ mod max_blocks;
#[cfg(feature = "rng")]
mod rng;
mod rounds;
#[cfg(feature = "xchacha")]
#[cfg(feature = "cipher")]
mod xchacha;

#[cfg(feature = "cipher")]
pub use cipher;

#[cfg(feature = "cipher")]
pub use crate::chacha::{ChaCha, ChaCha12, ChaCha20, ChaCha8, Key, Nonce};
pub use crate::{
chacha::{ChaCha, ChaCha12, ChaCha20, ChaCha8, Key, Nonce},
xchacha::{XChaCha, XChaCha12, XChaCha20, XChaCha8, XNonce},
};

#[cfg(feature = "expose-core")]
pub use crate::{
Expand All @@ -111,9 +117,6 @@ pub use rng::{
ChaCha12Rng, ChaCha12RngCore, ChaCha20Rng, ChaCha20RngCore, ChaCha8Rng, ChaCha8RngCore,
};

#[cfg(feature = "xchacha")]
pub use self::xchacha::{XChaCha, XChaCha12, XChaCha20, XChaCha8, XNonce};

/// Size of a ChaCha20 block in bytes
pub const BLOCK_SIZE: usize = 64;

Expand Down
14 changes: 0 additions & 14 deletions chacha20/src/xchacha.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,6 @@ use cipher::{
use core::convert::TryInto;

/// EXtended ChaCha20 nonce (192-bits/24-bytes)
#[cfg_attr(docsrs, doc(cfg(feature = "xchacha")))]
pub type XNonce = cipher::Nonce<XChaCha20>;

/// XChaCha20 is a ChaCha20 variant with an extended 192-bit (24-byte) nonce.
Expand All @@ -34,24 +33,12 @@ pub type XNonce = cipher::Nonce<XChaCha20>;
/// and is documented in an (expired) IETF draft:
///
/// <https://tools.ietf.org/html/draft-arciszewski-xchacha-03>
///
/// The `xchacha` Cargo feature must be enabled in order to use this
/// (which it is by default).
#[cfg_attr(docsrs, doc(cfg(feature = "xchacha")))]
pub type XChaCha20 = XChaCha<R20>;

/// XChaCha12 stream cipher (reduced-round variant of [`XChaCha20`] with 12 rounds)
///
/// The `xchacha` Cargo feature must be enabled in order to use this
/// (which it is by default).
#[cfg_attr(docsrs, doc(cfg(feature = "xchacha")))]
pub type XChaCha12 = XChaCha<R12>;

/// XChaCha8 stream cipher (reduced-round variant of [`XChaCha20`] with 8 rounds)
///
/// The `xchacha` Cargo feature must be enabled in order to use this
/// (which it is by default).
#[cfg_attr(docsrs, doc(cfg(feature = "xchacha")))]
pub type XChaCha8 = XChaCha<R8>;

/// XChaCha family stream cipher, generic around a number of rounds.
Expand All @@ -60,7 +47,6 @@ pub type XChaCha8 = XChaCha<R8>;
/// a specific number of rounds.
///
/// Generally [`XChaCha20`] is preferred.
#[cfg_attr(docsrs, doc(cfg(feature = "xchacha")))]
pub struct XChaCha<R: Rounds>(ChaCha<R, C64>);

impl<R: Rounds> NewCipher for XChaCha<R> {
Expand Down
26 changes: 7 additions & 19 deletions chacha20/tests/lib.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
//! Tests for ChaCha20 (IETF and "djb" versions) as well as XChaCha20
#![cfg(feature = "cipher")]

use chacha20::ChaCha20;

// IETF version of ChaCha20 (96-bit nonce)
Expand All @@ -10,9 +12,7 @@ mod overflow {
use cipher::{NewCipher, StreamCipher, StreamCipherSeek};

const OFFSET_256GB: u64 = 256u64 << 30;
#[cfg(feature = "xchacha")]
const OFFSET_256PB: u64 = 256u64 << 50;
#[cfg(feature = "xchacha")]
const OFFSET_1ZB: u128 = (64u128) << 64;

#[test]
Expand Down Expand Up @@ -114,7 +114,6 @@ mod overflow {
}
}

#[cfg(feature = "xchacha")]
#[test]
fn xchacha_256gb() {
let mut cipher = chacha20::XChaCha20::new(&Default::default(), &Default::default());
Expand All @@ -132,7 +131,6 @@ mod overflow {
.expect("Couldn't encrypt past the last byte of 256GB");
}

#[cfg(feature = "xchacha")]
#[test]
fn xchacha_upper_limit() {
let mut cipher = chacha20::XChaCha20::new(&Default::default(), &Default::default());
Expand All @@ -149,7 +147,6 @@ mod overflow {
.expect_err("Could encrypt past 1 zebibyte");
}

#[cfg(feature = "xchacha")]
#[test]
fn xchacha_has_a_big_counter() {
let mut cipher = chacha20::XChaCha20::new(&Default::default(), &Default::default());
Expand Down Expand Up @@ -219,17 +216,9 @@ mod chacha20test {
// <https://datatracker.ietf.org/doc/html/rfc8439#section-2.4.2>
//

const KEY: [u8; 32] = hex!(
"
000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f
"
);
const KEY: [u8; 32] = hex!("000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f");

const IV: [u8; 12] = hex!(
"
000000000000004a00000000
"
);
const IV: [u8; 12] = hex!("000000000000004a00000000");

const PLAINTEXT: [u8; 114] = hex!(
"
Expand All @@ -241,7 +230,7 @@ mod chacha20test {
746865206675747572652c2073756e73
637265656e20776f756c642062652069
742e
"
"
);

const KEYSTREAM: [u8; 114] = hex!(
Expand All @@ -251,7 +240,7 @@ mod chacha20test {
9334794cba40c63e34cdea212c4cf07d41b769a6749f3f
630f4122cafe28ec4dc47e26d4346d70b98c73f3e9c53a
c40c5945398b6eda1a832c89c167eacd901d7e2bf363
"
"
);

const CIPHERTEXT: [u8; 114] = hex!(
Expand All @@ -264,7 +253,7 @@ mod chacha20test {
52bc514d16ccf806818ce91ab7793736
5af90bbf74a35be6b40b8eedf2785e42
874d
"
"
);

#[test]
Expand Down Expand Up @@ -294,7 +283,6 @@ mod chacha20test {
}
}

#[cfg(feature = "xchacha")]
#[rustfmt::skip]
mod xchacha20 {
use chacha20::{Key, XChaCha20, XNonce};
Expand Down
10 changes: 5 additions & 5 deletions salsa20/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -12,17 +12,17 @@ edition = "2018"

[dependencies]
cipher = "0.3"
zeroize = { version = "=1.3", optional = true, default-features = false }

# optional dependencies
zeroize = { version = ">=1, <1.4", optional = true, default-features = false }

[dev-dependencies]
cipher = { version = "0.3", features = ["dev"] }

[features]
default = ["xsalsa20"]
expose-core = []
hsalsa20 = ["xsalsa20"]
xsalsa20 = []
hsalsa20 = []

[package.metadata.docs.rs]
features = ["hsalsa20", "xsalsa20"]
features = ["hsalsa20"]
rustdoc-args = ["--cfg", "docsrs"]
9 changes: 4 additions & 5 deletions salsa20/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -62,10 +62,12 @@ pub use cipher;
mod core;
mod rounds;
mod salsa;
#[cfg(feature = "xsalsa20")]
mod xsalsa;

pub use crate::salsa::{Key, Nonce, Salsa, Salsa12, Salsa20, Salsa8};
pub use crate::{
salsa::{Key, Nonce, Salsa, Salsa12, Salsa20, Salsa8},
xsalsa::{XNonce, XSalsa20},
};

#[cfg(feature = "expose-core")]
pub use crate::{
Expand All @@ -76,9 +78,6 @@ pub use crate::{
#[cfg(feature = "hsalsa20")]
pub use crate::xsalsa::hsalsa20;

#[cfg(feature = "xsalsa20")]
pub use crate::xsalsa::{XNonce, XSalsa20};

/// Size of a Salsa20 block in bytes
pub const BLOCK_SIZE: usize = 64;

Expand Down
2 changes: 0 additions & 2 deletions salsa20/src/xsalsa.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@ use cipher::{
use core::convert::TryInto;

/// EXtended Salsa20 nonce (192-bit/24-byte)
#[cfg_attr(docsrs, doc(cfg(feature = "xsalsa20")))]
pub type XNonce = cipher::Nonce<XSalsa20>;

/// XSalsa20 is a Salsa20 variant with an extended 192-bit (24-byte) nonce.
Expand All @@ -21,7 +20,6 @@ pub type XNonce = cipher::Nonce<XSalsa20>;
///
/// The `xsalsa20` Cargo feature must be enabled in order to use this
/// (which it is by default).
#[cfg_attr(docsrs, doc(cfg(feature = "xsalsa20")))]
pub struct XSalsa20(Salsa20);

impl NewCipher for XSalsa20 {
Expand Down
9 changes: 0 additions & 9 deletions salsa20/tests/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,9 @@
use cipher::{generic_array::GenericArray, NewCipher, StreamCipher, StreamCipherSeek};
use salsa20::Salsa20;
#[cfg(feature = "xsalsa20")]
use salsa20::XSalsa20;

cipher::stream_cipher_seek_test!(salsa20_seek, Salsa20);
#[cfg(feature = "xsalsa20")]
cipher::stream_cipher_seek_test!(xsalsa20_seek, XSalsa20);

#[cfg(test)]
Expand All @@ -15,7 +13,6 @@ const KEY_BYTES: usize = 32;
#[cfg(test)]
const IV_BYTES: usize = 8;

#[cfg(feature = "xsalsa20")]
#[cfg(test)]
const IV_BYTES_XSALSA20: usize = 24;

Expand All @@ -37,7 +34,6 @@ const KEY_LONG: [u8; KEY_BYTES] = [
27, 28, 29, 30, 31, 32,
];

#[cfg(feature = "xsalsa20")]
#[cfg(test)]
const KEY_XSALSA20: [u8; KEY_BYTES] = *b"this is 32-byte key for xsalsa20";

Expand All @@ -53,7 +49,6 @@ const IVHI: [u8; IV_BYTES] = [0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01];
#[cfg(test)]
const IV_LONG: [u8; IV_BYTES] = [3, 1, 4, 1, 5, 9, 2, 6];

#[cfg(feature = "xsalsa20")]
#[cfg(test)]
const IV_XSALSA20: [u8; IV_BYTES_XSALSA20] = *b"24-byte nonce for xsalsa";

Expand Down Expand Up @@ -101,7 +96,6 @@ const EXPECTED_LONG: [u8; 256] = [
0xcb, 0xe6, 0xa7, 0x16, 0x1e, 0x86, 0x53, 0xce, 0x93, 0x91, 0xe1, 0xe6, 0x71, 0x0e, 0xd4, 0xf1,
];

#[cfg(feature = "xsalsa20")]
#[cfg(test)]
const EXPECTED_XSALSA20_ZEROS: [u8; 64] = [
0x48, 0x48, 0x29, 0x7f, 0xeb, 0x1f, 0xb5, 0x2f, 0xb6, 0x6d, 0x81, 0x60, 0x9b, 0xd5, 0x47, 0xfa,
Expand All @@ -110,7 +104,6 @@ const EXPECTED_XSALSA20_ZEROS: [u8; 64] = [
0x40, 0x50, 0xd0, 0x8c, 0xe6, 0xd3, 0xa1, 0x51, 0xec, 0x26, 0x5f, 0x3a, 0x58, 0xe4, 0x76, 0x48,
];

#[cfg(feature = "xsalsa20")]
#[cfg(test)]
const EXPECTED_XSALSA20_HELLO_WORLD: [u8; 12] = [
0x00, 0x2d, 0x45, 0x13, 0x84, 0x3f, 0xc2, 0x40, 0xc4, 0x01, 0xe5, 0x41,
Expand Down Expand Up @@ -186,7 +179,6 @@ fn salsa20_offsets() {
}
}

#[cfg(feature = "xsalsa20")]
#[test]
fn xsalsa20_encrypt_zeros() {
let key = GenericArray::from(KEY_XSALSA20);
Expand All @@ -201,7 +193,6 @@ fn xsalsa20_encrypt_zeros() {
}
}

#[cfg(feature = "xsalsa20")]
#[test]
fn xsalsa20_encrypt_hello_world() {
let key = GenericArray::from(KEY_XSALSA20);
Expand Down

0 comments on commit 9e9ee30

Please sign in to comment.