Skip to content

Commit

Permalink
support v2 (AEAD-2022) ciphers
Browse files Browse the repository at this point in the history
  • Loading branch information
zonyitoo committed Apr 18, 2022
1 parent c1b75ed commit 0b5d9ec
Show file tree
Hide file tree
Showing 20 changed files with 656 additions and 248 deletions.
6 changes: 5 additions & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "shadowsocks-crypto"
version = "0.3.6"
version = "0.4.0"
authors = ["luozijun <[email protected]>", "ty <[email protected]>"]
edition = "2021"
license = "MIT"
Expand All @@ -19,6 +19,8 @@ v1 = []
v1-stream = ["v1", "chacha20", "aes"]
v1-aead = ["v1", "aes-gcm", "chacha20poly1305", "hkdf", "sha1"]
v1-aead-extra = ["v1-aead", "aes-gcm-siv", "ccm", "aes"]
v2 = ["aes", "aes-gcm", "blake3", "chacha20poly1305", "bytes"]

ring = ["ring-compat"]
armv8 = ["aes-gcm/armv8", "aes/armv8", "aes-gcm-siv/armv8"]
neon = ["chacha20/neon"]
Expand All @@ -34,8 +36,10 @@ ring-compat = { version = "0.4.1", optional = true }
md-5 = { version = "0.10" }
hkdf = { version = "0.12", optional = true }
sha1 = { version = "0.10", optional = true }
blake3 = { version = "1.3", optional = true }
chacha20 = { version = "0.8.1", optional = true }
aes = { version = "0.7.5", features = ["ctr"], optional = true }
bytes = { version = "1.1", optional = true }

[target.'cfg(all(unix, any(target_arch = "x86", target_arch = "x86_64")))'.dependencies]
md-5 = { version = "0.10", features = ["asm"] }
Expand Down
105 changes: 97 additions & 8 deletions src/v1/kind.rs → src/kind.rs
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
//! Cipher Kind
#[cfg(feature = "v1-aead-extra")]
use super::aeadcipher::{Aes128Ccm, Aes128GcmSiv, Aes256Ccm, Aes256GcmSiv, XChaCha20Poly1305};
use crate::v1::aeadcipher::{Aes128Ccm, Aes128GcmSiv, Aes256Ccm, Aes256GcmSiv, XChaCha20Poly1305};
#[cfg(feature = "v1-aead")]
use super::aeadcipher::{Aes128Gcm, Aes256Gcm, ChaCha20Poly1305};
use crate::v1::aeadcipher::{Aes128Gcm, Aes256Gcm, ChaCha20Poly1305};

#[cfg(feature = "v1-stream")]
use super::streamcipher::{
use crate::v1::streamcipher::{
Aes128Cfb1,
Aes128Cfb128,
Aes128Cfb8,
Expand Down Expand Up @@ -45,6 +45,13 @@ use super::streamcipher::{
Rc4Md5,
};

#[cfg(feature = "v2")]
use crate::v2::crypto::{
Aes128Gcm as Aead2022Aes128Gcm,
Aes256Gcm as Aead2022Aes256Gcm,
ChaCha20Poly1305 as Aead2022ChaCha20Poly1305,
};

/// Category of ciphers
#[derive(Clone, Debug, Copy, PartialEq, Eq)]
pub enum CipherCategory {
Expand All @@ -58,6 +65,10 @@ pub enum CipherCategory {
#[cfg(feature = "v1-aead")]
#[cfg_attr(docrs, doc(cfg(feature = "v1-aead")))]
Aead,
/// AEAD ciphers 2022 with enhanced security
#[cfg(feature = "v2")]
#[cfg_attr(docrs, doc(cfg(feature = "v2")))]
Aead2022,
}

/// ShadowSocks cipher type
Expand Down Expand Up @@ -216,6 +227,21 @@ pub enum CipherKind {
#[cfg_attr(docrs, doc(cfg(feature = "v1-aead-extra")))]
/// AEAD_XCHACHA20_POLY1305
XCHACHA20_POLY1305,

#[cfg(feature = "v2")]
#[cfg_attr(docrs, doc(cfg(feature = "v2")))]
/// 2022-blake3-aes-128-gcm
AEAD2022_BLAKE3_AES_128_GCM,

#[cfg(feature = "v2")]
#[cfg_attr(docrs, doc(cfg(feature = "v2")))]
/// 2022-blake3-aes-128-gcm
AEAD2022_BLAKE3_AES_256_GCM,

#[cfg(feature = "v2")]
#[cfg_attr(docrs, doc(cfg(feature = "v2")))]
/// 2022-blake3-chacha20-poly1305
AEAD2022_BLAKE3_CHACHA20_POLY1305,
}

impl CipherKind {
Expand All @@ -231,6 +257,11 @@ impl CipherKind {
return CipherCategory::Aead;
}

#[cfg(feature = "v2")]
if self.is_aead_2022() {
return CipherCategory::Aead2022;
}

CipherCategory::None
}

Expand Down Expand Up @@ -271,6 +302,16 @@ impl CipherKind {
}
}

#[cfg(feature = "v2")]
pub fn is_aead_2022(&self) -> bool {
use self::CipherKind::*;

match *self {
AEAD2022_BLAKE3_AES_128_GCM | AEAD2022_BLAKE3_AES_256_GCM | AEAD2022_BLAKE3_CHACHA20_POLY1305 => true,
_ => false,
}
}

/// Key length of the cipher
pub fn key_len(&self) -> usize {
use self::CipherKind::*;
Expand Down Expand Up @@ -376,6 +417,13 @@ impl CipherKind {

#[cfg(feature = "v1-aead-extra")]
XCHACHA20_POLY1305 => XChaCha20Poly1305::key_size(),

#[cfg(feature = "v2")]
AEAD2022_BLAKE3_AES_128_GCM => Aead2022Aes128Gcm::key_size(),
#[cfg(feature = "v2")]
AEAD2022_BLAKE3_AES_256_GCM => Aead2022Aes256Gcm::key_size(),
#[cfg(feature = "v2")]
AEAD2022_BLAKE3_CHACHA20_POLY1305 => Aead2022ChaCha20Poly1305::key_size(),
}
}

Expand Down Expand Up @@ -434,7 +482,7 @@ impl CipherKind {
}

/// AEAD Cipher's TAG length
#[cfg(feature = "v1-aead")]
#[cfg(any(feature = "v1-aead", feature = "v2"))]
pub fn tag_len(&self) -> usize {
use self::CipherKind::*;

Expand All @@ -457,18 +505,45 @@ impl CipherKind {
#[cfg(feature = "v1-aead-extra")]
XCHACHA20_POLY1305 => XChaCha20Poly1305::tag_size(),

#[cfg(feature = "v2")]
AEAD2022_BLAKE3_AES_128_GCM => Aead2022Aes128Gcm::tag_size(),
#[cfg(feature = "v2")]
AEAD2022_BLAKE3_AES_256_GCM => Aead2022Aes256Gcm::tag_size(),
#[cfg(feature = "v2")]
AEAD2022_BLAKE3_CHACHA20_POLY1305 => Aead2022ChaCha20Poly1305::tag_size(),

_ => panic!("only support AEAD ciphers"),
}
}

/// AEAD Cipher's SALT length
#[cfg(feature = "v1-aead")]
#[cfg(any(feature = "v1-aead", feature = "v2"))]
pub fn salt_len(&self) -> usize {
if !self.is_aead() {
panic!("only support AEAD ciphers");
#[cfg(feature = "v1-aead")]
if self.is_aead() {
return self.key_len();
}

#[cfg(feature = "v2")]
if self.is_aead_2022() {
return self.key_len();
}

self.key_len()
panic!("only support AEAD ciphers");
}

/// AEAD Cipher's nonce length
#[cfg(feature = "v2")]
pub fn nonce_len(&self) -> usize {
use crate::v2::udp::{AesGcmCipher, ChaCha20Poly1305Cipher};

match *self {
CipherKind::AEAD2022_BLAKE3_AES_128_GCM | CipherKind::AEAD2022_BLAKE3_AES_256_GCM => {
AesGcmCipher::nonce_size()
}
CipherKind::AEAD2022_BLAKE3_CHACHA20_POLY1305 => ChaCha20Poly1305Cipher::nonce_size(),
_ => panic!("only support AEAD 2022 ciphers"),
}
}
}

Expand Down Expand Up @@ -577,6 +652,13 @@ impl core::fmt::Display for CipherKind {

#[cfg(feature = "v1-aead-extra")]
CipherKind::XCHACHA20_POLY1305 => "xchacha20-ietf-poly1305",

#[cfg(feature = "v2")]
CipherKind::AEAD2022_BLAKE3_AES_128_GCM => "2022-blake3-aes-128-gcm",
#[cfg(feature = "v2")]
CipherKind::AEAD2022_BLAKE3_AES_256_GCM => "2022-blake3-aes-256-gcm",
#[cfg(feature = "v2")]
CipherKind::AEAD2022_BLAKE3_CHACHA20_POLY1305 => "2022-blake3-chacha20-poly1305",
})
}
}
Expand Down Expand Up @@ -714,6 +796,13 @@ impl core::str::FromStr for CipherKind {
#[cfg(feature = "v1-aead-extra")]
"xchacha20-ietf-poly1305" => Ok(XCHACHA20_POLY1305),

#[cfg(feature = "v2")]
"2022-blake3-aes-128-gcm" => Ok(AEAD2022_BLAKE3_AES_128_GCM),
#[cfg(feature = "v2")]
"2022-blake3-aes-256-gcm" => Ok(AEAD2022_BLAKE3_AES_256_GCM),
#[cfg(feature = "v2")]
"2022-blake3-chacha20-poly1305" => Ok(AEAD2022_BLAKE3_CHACHA20_POLY1305),

_ => Err(ParseCipherKindError),
}
}
Expand Down
127 changes: 127 additions & 0 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,3 +5,130 @@
#[cfg(feature = "v1")]
#[cfg_attr(docrs, doc(cfg(feature = "v1")))]
pub mod v1;

#[cfg(feature = "v2")]
#[cfg_attr(docrs, doc(cfg(feature = "v2")))]
pub mod v2;

pub mod kind;

pub use self::kind::{CipherCategory, CipherKind};

/// Get available ciphers in string representation
///
/// Commonly used for checking users' configuration input
pub const fn available_ciphers() -> &'static [&'static str] {
&[
"plain",
"none",
#[cfg(feature = "v1-stream")]
"table",
#[cfg(feature = "v1-stream")]
"rc4-md5",
// Stream Ciphers
#[cfg(feature = "v1-stream")]
"aes-128-ctr",
#[cfg(feature = "v1-stream")]
"aes-192-ctr",
#[cfg(feature = "v1-stream")]
"aes-256-ctr",
#[cfg(feature = "v1-stream")]
"aes-128-cfb",
#[cfg(feature = "v1-stream")]
"aes-128-cfb1",
#[cfg(feature = "v1-stream")]
"aes-128-cfb8",
#[cfg(feature = "v1-stream")]
"aes-128-cfb128",
#[cfg(feature = "v1-stream")]
"aes-192-cfb",
#[cfg(feature = "v1-stream")]
"aes-192-cfb1",
#[cfg(feature = "v1-stream")]
"aes-192-cfb8",
#[cfg(feature = "v1-stream")]
"aes-192-cfb128",
#[cfg(feature = "v1-stream")]
"aes-256-cfb",
#[cfg(feature = "v1-stream")]
"aes-256-cfb1",
#[cfg(feature = "v1-stream")]
"aes-256-cfb8",
#[cfg(feature = "v1-stream")]
"aes-256-cfb128",
#[cfg(feature = "v1-stream")]
"aes-128-ofb",
#[cfg(feature = "v1-stream")]
"aes-192-ofb",
#[cfg(feature = "v1-stream")]
"aes-256-ofb",
#[cfg(feature = "v1-stream")]
"camellia-128-ctr",
#[cfg(feature = "v1-stream")]
"camellia-192-ctr",
#[cfg(feature = "v1-stream")]
"camellia-256-ctr",
#[cfg(feature = "v1-stream")]
"camellia-128-cfb",
#[cfg(feature = "v1-stream")]
"camellia-128-cfb1",
#[cfg(feature = "v1-stream")]
"camellia-128-cfb8",
#[cfg(feature = "v1-stream")]
"camellia-128-cfb128",
#[cfg(feature = "v1-stream")]
"camellia-192-cfb",
#[cfg(feature = "v1-stream")]
"camellia-192-cfb1",
#[cfg(feature = "v1-stream")]
"camellia-192-cfb8",
#[cfg(feature = "v1-stream")]
"camellia-192-cfb128",
#[cfg(feature = "v1-stream")]
"camellia-256-cfb",
#[cfg(feature = "v1-stream")]
"camellia-256-cfb1",
#[cfg(feature = "v1-stream")]
"camellia-256-cfb8",
#[cfg(feature = "v1-stream")]
"camellia-256-cfb128",
#[cfg(feature = "v1-stream")]
"camellia-128-ofb",
#[cfg(feature = "v1-stream")]
"camellia-192-ofb",
#[cfg(feature = "v1-stream")]
"camellia-256-ofb",
#[cfg(feature = "v1-stream")]
"rc4",
#[cfg(feature = "v1-stream")]
"chacha20-ietf",
// AEAD Ciphers
#[cfg(feature = "v1-aead")]
"aes-128-gcm",
#[cfg(feature = "v1-aead")]
"aes-256-gcm",
#[cfg(feature = "v1-aead")]
"chacha20-ietf-poly1305",
#[cfg(feature = "v1-aead-extra")]
"aes-128-ccm",
#[cfg(feature = "v1-aead-extra")]
"aes-256-ccm",
#[cfg(feature = "v1-aead-extra")]
"aes-128-gcm-siv",
#[cfg(feature = "v1-aead-extra")]
"aes-256-gcm-siv",
#[cfg(feature = "v1-aead-extra")]
"xchacha20-ietf-poly1305",
// #[cfg(feature = "v1-aead-extra")]
// "sm4-gcm",
// #[cfg(feature = "v1-aead-extra")]
// "sm4-ccm",
// AEAD 2022 Ciphers
#[cfg(feature = "v2")]
"2022-blake3-aes-128-gcm",
#[cfg(feature = "v2")]
"2022-blake3-aes-256-gcm",
#[cfg(feature = "v2")]
"2022-blake3-chacha20-poly1305",
]
}
7 changes: 6 additions & 1 deletion src/v1/aeadcipher/mod.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use crate::v1::CipherKind;
use crate::kind::{CipherCategory, CipherKind};

#[cfg(feature = "v1-aead-extra")]
mod aes_ccm;
Expand Down Expand Up @@ -152,6 +152,11 @@ impl AeadCipher {
self.cipher.kind()
}

#[inline(always)]
pub fn category(&self) -> CipherCategory {
CipherCategory::Aead
}

#[inline(always)]
pub fn tag_len(&self) -> usize {
self.cipher.kind().tag_len()
Expand Down
Loading

0 comments on commit 0b5d9ec

Please sign in to comment.