diff --git a/Cargo.lock b/Cargo.lock
index b77d48eab808..fce103533f9a 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -12,6 +12,7 @@ dependencies = [
"futures 0.1.15 (registry+https://github.com/rust-lang/crates.io-index)",
"lazy_static 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.2.30 (registry+https://github.com/rust-lang/crates.io-index)",
+ "libsodium-ffi 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)",
"log 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)",
"lru_time_cache 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)",
"md-5 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -23,7 +24,6 @@ dependencies = [
"scoped-tls 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
"serde_json 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)",
"serde_urlencoded 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)",
- "sodiumoxide 0.0.15 (registry+https://github.com/rust-lang/crates.io-index)",
"subprocess 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)",
"time 0.1.38 (registry+https://github.com/rust-lang/crates.io-index)",
"tokio-core 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -244,7 +244,7 @@ dependencies = [
[[package]]
name = "itoa"
-version = "0.3.2"
+version = "0.3.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
@@ -272,8 +272,8 @@ version = "0.2.30"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
-name = "libsodium-sys"
-version = "0.0.15"
+name = "libsodium-ffi"
+version = "0.1.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"libc 0.2.30 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -545,7 +545,7 @@ version = "1.0.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"dtoa 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)",
- "itoa 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)",
+ "itoa 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)",
"num-traits 0.1.40 (registry+https://github.com/rust-lang/crates.io-index)",
"serde 1.0.11 (registry+https://github.com/rust-lang/crates.io-index)",
]
@@ -556,7 +556,7 @@ version = "0.5.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"dtoa 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)",
- "itoa 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)",
+ "itoa 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)",
"serde 1.0.11 (registry+https://github.com/rust-lang/crates.io-index)",
"url 1.5.1 (registry+https://github.com/rust-lang/crates.io-index)",
]
@@ -566,16 +566,6 @@ name = "slab"
version = "0.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-[[package]]
-name = "sodiumoxide"
-version = "0.0.15"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-dependencies = [
- "libc 0.2.30 (registry+https://github.com/rust-lang/crates.io-index)",
- "libsodium-sys 0.0.15 (registry+https://github.com/rust-lang/crates.io-index)",
- "serde 1.0.11 (registry+https://github.com/rust-lang/crates.io-index)",
-]
-
[[package]]
name = "strsim"
version = "0.6.0"
@@ -790,12 +780,12 @@ dependencies = [
"checksum generic-array 0.8.2 (registry+https://github.com/rust-lang/crates.io-index)" = "6181b378c58e5aacf4d3e17836737465cb2857750b53f6b46672a3509f2a8d9d"
"checksum idna 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "014b298351066f1512874135335d62a789ffe78a9974f94b43ed5621951eaf7d"
"checksum iovec 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "29d062ee61fccdf25be172e70f34c9f6efc597e1fb8f6526e8437b2046ab26be"
-"checksum itoa 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)" = "f74cf6ca1bdbc28496a2b9798ab7fccc2ca5a42cace95bb2b219577216a5fb90"
+"checksum itoa 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "ac17257442c2ed77dbc9fd555cf83c58b0c7f7d0e8f2ae08c0ac05c72842e1f6"
"checksum kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "7507624b29483431c0ba2d82aece8ca6cdba9382bff4ddd0f7490560c056098d"
"checksum lazy_static 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)" = "3b37545ab726dd833ec6420aaba8231c5b320814b9029ad585555d2a03e94fbf"
"checksum lazycell 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "3b585b7a6811fb03aa10e74b278a0f00f8dd9b45dc681f148bb29fa5cb61859b"
"checksum libc 0.2.30 (registry+https://github.com/rust-lang/crates.io-index)" = "2370ca07ec338939e356443dac2296f581453c35fe1e3a3ed06023c49435f915"
-"checksum libsodium-sys 0.0.15 (registry+https://github.com/rust-lang/crates.io-index)" = "45e6d6bd0f1b72068272e1689693e3218f192221fae7a2046081f60035540df8"
+"checksum libsodium-ffi 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "5fb58d1e29baea19145d12f3b17d2caf3e4da0ae2f181abb138e94fb226e43b6"
"checksum log 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)" = "880f77541efa6e5cc74e76910c9884d9859683118839d6a1dc3b11e63512565b"
"checksum lru_time_cache 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "4bf17862cdf1a87c7cc0cccc498552f3e564d2ae61069f83d2279a932af4a00c"
"checksum magenta 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "4bf0336886480e671965f794bc9b6fce88503563013d1bfb7a502c81fe3ac527"
@@ -831,7 +821,6 @@ dependencies = [
"checksum serde_json 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "48b04779552e92037212c3615370f6bd57a40ebba7f20e554ff9f55e41a69a7b"
"checksum serde_urlencoded 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "ce0fd303af908732989354c6f02e05e2e6d597152870f2c6990efb0577137480"
"checksum slab 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "17b4fcaed89ab08ef143da37bc52adbcc04d4a69014f4c1208d6b51f0c47bc23"
-"checksum sodiumoxide 0.0.15 (registry+https://github.com/rust-lang/crates.io-index)" = "769317362b6ba15fe135147c9ea97dc773c76a312a5b91282dea27bcfed3596c"
"checksum strsim 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "b4d15c810519a91cf877e7e36e63fe068815c678181439f2f29e2562147c3694"
"checksum subprocess 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)" = "78a77399f1ffa6f2ee3595ab8e329381bbeaf640d59073821519e6a0aa957f9d"
"checksum term_size 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "e2b6b55df3198cc93372e85dd2ed817f0e38ce8cc0f22eb32391bfad9c4bf209"
diff --git a/Cargo.toml b/Cargo.toml
index 6371cfe5dcbb..930d08781ee0 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -8,9 +8,6 @@ documentation = "https://docs.rs/shadowsocks-rust"
keywords = ["shadowsocks", "proxy", "socks", "socks5", "firewall"]
license = "MIT"
-[features]
-default = ["sodiumoxide"]
-
[lib]
name = "shadowsocks"
@@ -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"
diff --git a/README.md b/README.md
index 1f0ad63bc522..211a44628d80 100644
--- a/README.md
+++ b/README.md
@@ -12,7 +12,7 @@ shadowsocks is a fast tunnel proxy that helps you bypass firewalls.
## Dependencies
* libcrypto (OpenSSL)
-* libsodium (Required if you need ciphers that provided by libsodium)
+* libsodium (Required for ciphers that are provided by libsodium)
## Usage
@@ -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.
@@ -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`
diff --git a/src/crypto/cipher.rs b/src/crypto/cipher.rs
index fdcde6a18922..ba5d2350f6d2 100644
--- a/src/crypto/cipher.rs
+++ b/src/crypto/cipher.rs
@@ -22,6 +22,7 @@ pub enum Error {
OpenSSLError(::openssl::error::ErrorStack),
IoError(io::Error),
AeadDecryptFailed,
+ SodiumError,
}
impl Debug for Error {
@@ -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"),
}
}
}
@@ -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"),
}
}
}
@@ -53,6 +56,7 @@ impl From 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"),
}
}
}
@@ -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";
@@ -112,6 +117,7 @@ pub enum CipherType {
Salsa20,
XSalsa20,
Aes128Ctr,
+ ChaCha20Ietf,
Aes128Gcm,
Aes256Gcm,
@@ -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(),
@@ -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(),
@@ -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),
@@ -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),
diff --git a/src/crypto/mod.rs b/src/crypto/mod.rs
index ebf594ce0237..6e4c109b03ee 100644
--- a/src/crypto/mod.rs
+++ b/src/crypto/mod.rs
@@ -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,
diff --git a/src/crypto/ring.rs b/src/crypto/ring.rs
index 48407e1b3765..e5d5665cbd6c 100644
--- a/src/crypto/ring.rs
+++ b/src/crypto/ring.rs
@@ -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);
}
@@ -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) {
diff --git a/src/crypto/sodium.rs b/src/crypto/sodium.rs
index f843c6c6c465..3ed50ba7639e 100644
--- a/src/crypto/sodium.rs
+++ b/src/crypto/sodium.rs
@@ -1,53 +1,139 @@
//! Cipher defined with libsodium
-use bytes::BufMut;
-use sodiumoxide::crypto::stream::{aes128ctr, chacha20, salsa20, xsalsa20};
+use bytes::{BufMut, BytesMut};
use crypto::{CipherResult, CipherType, StreamCipher};
+use libc::c_ulonglong;
+use libsodium_ffi::{crypto_stream_aes128ctr_xor, crypto_stream_chacha20_ietf_xor_ic, crypto_stream_chacha20_xor_ic,
+ crypto_stream_salsa20_xor_ic, crypto_stream_xsalsa20_xor_ic};
+
+use crypto::cipher::Error;
/// Cipher provided by Rust-Crypto
-pub enum SodiumCipher {
- ChaCha20(chacha20::Key, chacha20::Nonce),
- Salsa20(salsa20::Key, salsa20::Nonce),
- XSalsa20(xsalsa20::Key, xsalsa20::Nonce),
- Aes128Ctr(aes128ctr::Key, aes128ctr::Nonce),
+pub struct SodiumCipher {
+ cipher_type: CipherType,
+ key: Vec,
+ iv: Vec,
+ counter: usize,
}
+const SODIUM_BLOCK_SIZE: usize = 64;
+
impl SodiumCipher {
/// Creates an instance
pub fn new(t: CipherType, key: &[u8], iv: &[u8]) -> SodiumCipher {
+ match t {
+ CipherType::ChaCha20 |
+ CipherType::Salsa20 |
+ CipherType::XSalsa20 |
+ CipherType::Aes128Ctr |
+ CipherType::ChaCha20Ietf => {}
+ _ => panic!("sodium cipher does not support {:?} cipher", t),
+ }
+
+ SodiumCipher {
+ cipher_type: t,
+ key: key.to_owned(),
+ iv: iv.to_owned(),
+ counter: 0,
+ }
+ }
+
+ fn padding_len(&self) -> usize {
+ self.counter % SODIUM_BLOCK_SIZE
+ }
+
+ fn process(&mut self, data: &[u8], out: &mut B) -> CipherResult<()> {
+ let padding = self.padding_len();
+
+ let mut plain_text = vec![0u8; data.len() + padding];
+ (&mut plain_text[padding..]).copy_from_slice(&data);
+
+ let mut out_buf = BytesMut::with_capacity((data.len() + padding) * 2);
+
+ crypto_stream_xor_ic(self.cipher_type,
+ self.counter / SODIUM_BLOCK_SIZE,
+ &self.iv,
+ &self.key,
+ &plain_text,
+ &mut out_buf)?;
+
+ out.put_slice(&out_buf[padding..padding + data.len()]);
+
+ self.counter += data.len();
+ Ok(())
+ }
+}
+
+fn crypto_stream_xor_ic(t: CipherType,
+ ic: usize,
+ iv: &[u8],
+ key: &[u8],
+ data: &[u8],
+ out: &mut B)
+ -> CipherResult<()> {
+ assert!(data.len() <= unsafe { out.bytes_mut().len() });
+
+ let ret = unsafe {
match t {
CipherType::ChaCha20 => {
- SodiumCipher::ChaCha20(chacha20::Key::from_slice(key).unwrap(),
- chacha20::Nonce::from_slice(iv).unwrap())
+ crypto_stream_chacha20_xor_ic(out.bytes_mut().as_mut_ptr(),
+ data.as_ptr(),
+ data.len() as c_ulonglong,
+ iv.as_ptr(),
+ ic as c_ulonglong,
+ key.as_ptr())
+ }
+ CipherType::ChaCha20Ietf => {
+ crypto_stream_chacha20_ietf_xor_ic(out.bytes_mut().as_mut_ptr(),
+ data.as_ptr(),
+ data.len() as c_ulonglong,
+ iv.as_ptr(),
+ ic as u32,
+ key.as_ptr())
}
CipherType::Salsa20 => {
- SodiumCipher::Salsa20(salsa20::Key::from_slice(key).unwrap(), salsa20::Nonce::from_slice(iv).unwrap())
+ crypto_stream_salsa20_xor_ic(out.bytes_mut().as_mut_ptr(),
+ data.as_ptr(),
+ data.len() as c_ulonglong,
+ iv.as_ptr(),
+ ic as c_ulonglong,
+ key.as_ptr())
}
CipherType::XSalsa20 => {
- SodiumCipher::XSalsa20(xsalsa20::Key::from_slice(key).unwrap(),
- xsalsa20::Nonce::from_slice(iv).unwrap())
+ crypto_stream_xsalsa20_xor_ic(out.bytes_mut().as_mut_ptr(),
+ data.as_ptr(),
+ data.len() as c_ulonglong,
+ iv.as_ptr(),
+ ic as c_ulonglong,
+ key.as_ptr())
}
CipherType::Aes128Ctr => {
- SodiumCipher::Aes128Ctr(aes128ctr::Key::from_slice(key).unwrap(),
- aes128ctr::Nonce::from_slice(iv).unwrap())
+ crypto_stream_aes128ctr_xor(out.bytes_mut().as_mut_ptr(),
+ data.as_ptr(),
+ data.len() as c_ulonglong,
+ iv.as_ptr(),
+ key.as_ptr())
}
- _ => panic!("Rust Crypto does not support {:?} cipher", t),
+ _ => unreachable!(),
}
+ };
+
+ if ret != 0 {
+ Err(Error::SodiumError)
+ } else {
+ unsafe {
+ out.advance_mut(data.len());
+ }
+
+ Ok(())
}
}
impl StreamCipher for SodiumCipher {
fn update(&mut self, data: &[u8], out: &mut B) -> CipherResult<()> {
- match *self {
- SodiumCipher::ChaCha20(ref key, ref nonce) => out.put(chacha20::stream_xor(data, nonce, key)),
- SodiumCipher::Salsa20(ref key, ref nonce) => out.put(salsa20::stream_xor(data, nonce, key)),
- SodiumCipher::XSalsa20(ref key, ref nonce) => out.put(xsalsa20::stream_xor(data, nonce, key)),
- SodiumCipher::Aes128Ctr(ref key, ref nonce) => out.put(aes128ctr::stream_xor(data, nonce, key)),
- }
-
- Ok(())
+ self.process(data, out)
}
fn finalize(&mut self, _: &mut B) -> CipherResult<()> {
@@ -66,47 +152,47 @@ mod test {
use super::*;
use crypto::{CipherType, StreamCipher};
- #[test]
- fn test_rust_crypto_cipher_chacha20() {
- let ct = CipherType::ChaCha20;
-
+ fn test_sodium(ct: CipherType) {
let key = ct.bytes_to_key(b"PassWORD");
let message = b"message";
let iv = ct.gen_init_vec();
let mut enc = SodiumCipher::new(ct, &key[..], &iv[..]);
- let mut encrypted_msg = Vec::new();
+ let mut encrypted_msg = Vec::with_capacity(enc.buffer_size(&message[..]));
enc.update(message, &mut encrypted_msg).unwrap();
assert_ne!(message, &encrypted_msg[..]);
let mut dec = SodiumCipher::new(ct, &key[..], &iv[..]);
- let mut decrypted_msg = Vec::new();
+ let mut decrypted_msg = Vec::with_capacity(dec.buffer_size(&encrypted_msg));
dec.update(&encrypted_msg[..], &mut decrypted_msg).unwrap();
assert_eq!(&decrypted_msg[..], message);
}
#[test]
- fn test_rust_crypto_cipher_salsa20() {
- let ct = CipherType::Salsa20;
-
- let key = ct.bytes_to_key(b"PassWORD");
- let message = b"message";
-
- let iv = ct.gen_init_vec();
+ fn test_rust_crypto_cipher_chacha20() {
+ test_sodium(CipherType::ChaCha20);
+ }
- let mut enc = SodiumCipher::new(ct, &key[..], &iv[..]);
- let mut encrypted_msg = Vec::new();
- enc.update(message, &mut encrypted_msg).unwrap();
+ #[test]
+ fn test_rust_crypto_cipher_salsa20() {
+ test_sodium(CipherType::Salsa20);
+ }
- assert_ne!(message, &encrypted_msg[..]);
+ #[test]
+ fn test_rust_crypto_cipher_xsalsa20() {
+ test_sodium(CipherType::XSalsa20);
+ }
- let mut dec = SodiumCipher::new(ct, &key[..], &iv[..]);
- let mut decrypted_msg = Vec::new();
- dec.update(&encrypted_msg[..], &mut decrypted_msg).unwrap();
+ #[test]
+ fn test_rust_crypto_cipher_aes128ctr() {
+ test_sodium(CipherType::Aes128Ctr);
+ }
- assert_eq!(&decrypted_msg[..], message);
+ #[test]
+ fn test_rust_crypto_cipher_chacha20_ietf() {
+ test_sodium(CipherType::ChaCha20Ietf);
}
}
diff --git a/src/crypto/stream.rs b/src/crypto/stream.rs
index dda226bd6e62..d8f01f822f52 100644
--- a/src/crypto/stream.rs
+++ b/src/crypto/stream.rs
@@ -5,7 +5,6 @@ use crypto::cipher::{CipherCategory, CipherResult, CipherType};
use crypto::dummy;
use crypto::openssl;
use crypto::rc4_md5;
-#[cfg(feature = "sodiumoxide")]
use crypto::sodium;
use crypto::table;
@@ -85,8 +84,6 @@ define_stream_ciphers! {
pub DummyCipher => dummy::DummyCipher,
pub Rc4Md5Cipher => rc4_md5::Rc4Md5Cipher,
pub OpenSSLCipher => openssl::OpenSSLCipher,
-
- #[cfg(feature = "sodiumoxide")]
pub SodiumCipher => sodium::SodiumCipher,
}
@@ -98,11 +95,11 @@ pub fn new_stream(t: CipherType, key: &[u8], iv: &[u8], mode: CryptoMode) -> Str
CipherType::Table => StreamCipherVariant::new(table::TableCipher::new(key, mode)),
CipherType::Dummy => StreamCipherVariant::new(dummy::DummyCipher),
- #[cfg(feature = "sodiumoxide")]
CipherType::ChaCha20 |
CipherType::Salsa20 |
CipherType::XSalsa20 |
- CipherType::Aes128Ctr => StreamCipherVariant::new(sodium::SodiumCipher::new(t, key, iv)),
+ CipherType::Aes128Ctr |
+ CipherType::ChaCha20Ietf => StreamCipherVariant::new(sodium::SodiumCipher::new(t, key, iv)),
CipherType::Rc4Md5 => StreamCipherVariant::new(rc4_md5::Rc4Md5Cipher::new(key, iv, mode)),
diff --git a/src/lib.rs b/src/lib.rs
index 0e2c8cde4574..d5dbe320993b 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -83,8 +83,7 @@ extern crate md_5 as md5;
extern crate digest;
extern crate ring;
extern crate openssl;
-#[cfg(feature = "sodiumoxide")]
-extern crate sodiumoxide;
+extern crate libsodium_ffi;
#[macro_use]
extern crate futures;