mirror of
https://github.com/shadowsocks/shadowsocks-rust.git
synced 2026-11-06 16:14:11 +00:00
[#61] Add support of chacha20-ietf cipher
Removed sodiumoxide, use self contained libsodium-ffi
This commit is contained in:
Generated
+8
-19
@@ -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"
|
||||
|
||||
+1
-7
@@ -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"
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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`
|
||||
|
||||
|
||||
+11
-1
@@ -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<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"),
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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),
|
||||
|
||||
+1
-3
@@ -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,
|
||||
|
||||
+3
-3
@@ -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) {
|
||||
|
||||
+130
-44
@@ -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<u8>,
|
||||
iv: Vec<u8>,
|
||||
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<B: BufMut>(&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<B: BufMut>(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<B: BufMut>(&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<B: BufMut>(&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_chacha20() {
|
||||
test_sodium(CipherType::ChaCha20);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_rust_crypto_cipher_salsa20() {
|
||||
let ct = CipherType::Salsa20;
|
||||
test_sodium(CipherType::Salsa20);
|
||||
}
|
||||
|
||||
let key = ct.bytes_to_key(b"PassWORD");
|
||||
let message = b"message";
|
||||
#[test]
|
||||
fn test_rust_crypto_cipher_xsalsa20() {
|
||||
test_sodium(CipherType::XSalsa20);
|
||||
}
|
||||
|
||||
let iv = ct.gen_init_vec();
|
||||
#[test]
|
||||
fn test_rust_crypto_cipher_aes128ctr() {
|
||||
test_sodium(CipherType::Aes128Ctr);
|
||||
}
|
||||
|
||||
let mut enc = SodiumCipher::new(ct, &key[..], &iv[..]);
|
||||
let mut encrypted_msg = Vec::new();
|
||||
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();
|
||||
dec.update(&encrypted_msg[..], &mut decrypted_msg).unwrap();
|
||||
|
||||
assert_eq!(&decrypted_msg[..], message);
|
||||
#[test]
|
||||
fn test_rust_crypto_cipher_chacha20_ietf() {
|
||||
test_sodium(CipherType::ChaCha20Ietf);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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)),
|
||||
|
||||
|
||||
+1
-2
@@ -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;
|
||||
|
||||
Reference in New Issue
Block a user