Skip to content

Commit

Permalink
[#61] Add support of chacha20-ietf cipher
Browse files Browse the repository at this point in the history
Removed sodiumoxide, use self contained libsodium-ffi
  • Loading branch information
zonyitoo committed Aug 30, 2017
1 parent 2f536c2 commit fe07ff3
Show file tree
Hide file tree
Showing 9 changed files with 162 additions and 86 deletions.
27 changes: 8 additions & 19 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

8 changes: 1 addition & 7 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,6 @@ documentation = "https://docs.rs/shadowsocks-rust"
keywords = ["shadowsocks", "proxy", "socks", "socks5", "firewall"]
license = "MIT"

[features]
default = ["sodiumoxide"]

[lib]
name = "shadowsocks"

Expand Down Expand Up @@ -54,10 +51,7 @@ subprocess = "0.1"
serde_urlencoded = "0.5"
url = "1.5"
byte_string = "1.0"

[dependencies.sodiumoxide]
version = "0.0.15"
optional = true
libsodium-ffi = "0.1"

[target.'cfg(unix)'.dependencies]
tokio-signal = "0.1"
7 changes: 5 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ shadowsocks is a fast tunnel proxy that helps you <del>bypass firewalls</del>.
## Dependencies

* libcrypto (OpenSSL)
* libsodium (Required if you need ciphers that provided by libsodium)
* libsodium (Required for ciphers that are provided by libsodium)

## Usage

Expand All @@ -32,6 +32,8 @@ then you can find `sslocal` and `ssserver` in `$CARGO_HOME/bin`.
cargo build
```

NOTE: If you haven't installed libsodium in your system, you can set a environment variable `SODIUM_BUILD_STATIC=yes` to let `libsodium-ffi` to build from source, which requires you to have all the required build tools (including GCC, libtools, etc.).

Then `sslocal` and `ssserver` will appear in `./target`, it works similarly as the two binaries in
the official ShadowSocks' implementation.

Expand Down Expand Up @@ -107,8 +109,9 @@ List all available arguments with `-h`.

* `aes-128-cfb`, `aes-128-cfb1`, `aes-128-cfb8`, `aes-128-cfb128`
* `aes-256-cfb`, `aes-256-cfb1`, `aes-256-cfb8`, `aes-256-cfb128`
* `aes-128-ctr`
* `rc4`, `rc4-md5`
* `chacha20`, `salsa20`
* `chacha20`, `salsa20`, `chacha20-ietf`
* `dummy` (No encryption, just for debugging)
* `aes-128-gcm`, `aes-192-gcm`, `aes-256-gcm`

Expand Down
12 changes: 11 additions & 1 deletion src/crypto/cipher.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ pub enum Error {
OpenSSLError(::openssl::error::ErrorStack),
IoError(io::Error),
AeadDecryptFailed,
SodiumError,
}

impl Debug for Error {
Expand All @@ -31,6 +32,7 @@ impl Debug for Error {
Error::OpenSSLError(ref err) => write!(f, "{:?}", err),
Error::IoError(ref err) => write!(f, "{:?}", err),
Error::AeadDecryptFailed => write!(f, "AEAD decrypt failed"),
Error::SodiumError => write!(f, "Sodium error"),
}
}
}
Expand All @@ -42,6 +44,7 @@ impl Display for Error {
Error::OpenSSLError(ref err) => write!(f, "{}", err),
Error::IoError(ref err) => write!(f, "{}", err),
Error::AeadDecryptFailed => write!(f, "AeadDecryptFailed"),
Error::SodiumError => write!(f, "Sodium error"),
}
}
}
Expand All @@ -53,6 +56,7 @@ impl From<Error> for io::Error {
Error::OpenSSLError(err) => From::from(err),
Error::IoError(err) => err,
Error::AeadDecryptFailed => io::Error::new(io::ErrorKind::Other, "AEAD decrypt error"),
Error::SodiumError => io::Error::new(io::ErrorKind::Other, "Sodium error"),
}
}
}
Expand Down Expand Up @@ -82,6 +86,7 @@ const CIPHER_CHACHA20: &'static str = "chacha20";
const CIPHER_SALSA20: &'static str = "salsa20";
const CIPHER_XSALSA20: &'static str = "xsalsa20";
const CIPHER_AES_128_CTR: &'static str = "aes-128-ctr";
const CIPHER_CHACHA20_IETF: &'static str = "chacha20-ietf";

const CIPHER_DUMMY: &'static str = "dummy";

Expand Down Expand Up @@ -112,6 +117,7 @@ pub enum CipherType {
Salsa20,
XSalsa20,
Aes128Ctr,
ChaCha20Ietf,

Aes128Gcm,
Aes256Gcm,
Expand Down Expand Up @@ -148,7 +154,8 @@ impl CipherType {

CipherType::ChaCha20 |
CipherType::Salsa20 |
CipherType::XSalsa20 => 32,
CipherType::XSalsa20 |
CipherType::ChaCha20Ietf => 32,
CipherType::Aes128Ctr => 16,

CipherType::Aes128Gcm => AES_128_GCM.key_len(),
Expand Down Expand Up @@ -243,6 +250,7 @@ impl CipherType {
CipherType::Salsa20 => 8,
CipherType::XSalsa20 => 24,
CipherType::Aes128Ctr => 16,
CipherType::ChaCha20Ietf => 12,

CipherType::Aes128Gcm => AES_128_GCM.nonce_len(),
CipherType::Aes256Gcm => AES_256_GCM.nonce_len(),
Expand Down Expand Up @@ -330,6 +338,7 @@ impl FromStr for CipherType {
CIPHER_SALSA20 => Ok(CipherType::Salsa20),
CIPHER_XSALSA20 => Ok(CipherType::XSalsa20),
CIPHER_AES_128_CTR => Ok(CipherType::Aes128Ctr),
CIPHER_CHACHA20_IETF => Ok(CipherType::ChaCha20Ietf),

CIPHER_AES_128_GCM => Ok(CipherType::Aes128Gcm),
CIPHER_AES_256_GCM => Ok(CipherType::Aes256Gcm),
Expand Down Expand Up @@ -363,6 +372,7 @@ impl Display for CipherType {
CipherType::Salsa20 => write!(f, "{}", CIPHER_SALSA20),
CipherType::XSalsa20 => write!(f, "{}", CIPHER_XSALSA20),
CipherType::Aes128Ctr => write!(f, "{}", CIPHER_AES_128_CTR),
CipherType::ChaCha20Ietf => write!(f, "{}", CIPHER_CHACHA20_IETF),

CipherType::Aes128Gcm => write!(f, "{}", CIPHER_AES_128_GCM),
CipherType::Aes256Gcm => write!(f, "{}", CIPHER_AES_256_GCM),
Expand Down
4 changes: 1 addition & 3 deletions src/crypto/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,12 +18,10 @@ pub mod ring;
pub mod dummy;
pub mod aead;
pub mod stream;

#[cfg(feature = "sodiumoxide")]
pub mod sodium;

/// Crypto mode, encrypt or decrypt
#[derive(Clone, Copy)]
#[derive(Clone, Copy, Eq, PartialEq, Debug)]
pub enum CryptoMode {
Encrypt,
Decrypt,
Expand Down
6 changes: 3 additions & 3 deletions src/crypto/ring.rs
Original file line number Diff line number Diff line change
Expand Up @@ -108,7 +108,7 @@ impl AeadEncryptor for RingAeadCipher {
let buf_len = input.len() + tag_len;

let mut buf = BytesMut::with_capacity(buf_len);
buf.put(input);
buf.put_slice(input);
unsafe {
buf.set_len(buf_len);
}
Expand All @@ -128,8 +128,8 @@ impl AeadEncryptor for RingAeadCipher {
impl AeadDecryptor for RingAeadCipher {
fn decrypt(&mut self, input: &[u8], output: &mut [u8], tag: &[u8]) -> CipherResult<()> {
let mut buf = BytesMut::with_capacity(input.len() + tag.len());
buf.put(input);
buf.put(tag);
buf.put_slice(input);
buf.put_slice(tag);

let r = if let RingAeadCryptoVariant::Open(ref key, ref nonce) = self.cipher {
match open_in_place(key, nonce, &[], 0, &mut buf) {
Expand Down
Loading

0 comments on commit fe07ff3

Please sign in to comment.