use openssl crate on crates.io

This commit is contained in:
Y. T. Chung
2015-12-13 22:41:29 +08:00
parent 63a34a6ba2
commit 555d06bf65
4 changed files with 72 additions and 492 deletions

View File

@@ -12,11 +12,6 @@ name = "shadowsocks"
default = [
"cipher-aes-cfb",
"cipher-aes-ofb",
"cipher-bf-cfb",
"cipher-cast5-cfb",
"cipher-des-cfb",
"cipher-rc2-cfb",
"cipher-rc4",
"cipher-chacha20",
@@ -26,16 +21,7 @@ default = [
]
cipher-aes-cfb = []
cipher-aes-ofb = []
cipher-aes-ctr = []
cipher-bf-cfb = []
cipher-camellia-cfb = []
cipher-cast5-cfb = []
cipher-des-cfb = []
cipher-idea-cfb = []
cipher-rc2-cfb = []
cipher-rc4 = []
cipher-seed-cfb = []
cipher-chacha20 = []
cipher-salsa20 = []
@@ -72,6 +58,7 @@ qrcode = "^0.1.6"
env_logger = "^0.3.2"
rust-crypto = "^0.2.34"
ip = "1.0.0"
openssl = "^0.7.1"
[dependencies.lru-cache]
git = "https://github.com/zonyitoo/lru-cache.git"

View File

@@ -24,6 +24,10 @@
extern crate libc;
extern crate test;
use std::convert::From;
use openssl::crypto::symm;
pub mod cipher;
pub mod openssl;
pub mod digest;
@@ -36,3 +40,12 @@ pub enum CryptoMode {
Encrypt,
Decrypt
}
impl From<CryptoMode> for symm::Mode {
fn from(m: CryptoMode) -> symm::Mode {
match m {
CryptoMode::Encrypt => symm::Mode::Encrypt,
CryptoMode::Decrypt => symm::Mode::Decrypt,
}
}
}

View File

@@ -21,9 +21,8 @@
//! Cipher defined with Rust binding for libcrypto (OpenSSL)
#![allow(dead_code)]
extern crate libc;
use std::convert::From;
use std::io::Write;
use crypto::cipher::{Cipher, CipherType, CipherResult};
use crypto::cipher;
@@ -32,385 +31,55 @@ use crypto::digest::Digest;
use crypto::digest;
use crypto::CryptoMode;
use std::ptr;
use std::clone::Clone;
mod ffi {
extern crate libc;
#[allow(non_camel_case_types)]
pub type EVP_CIPHER_CTX = libc::c_void;
#[allow(non_camel_case_types)]
pub type EVP_CIPHER = libc::c_void;
#[allow(non_camel_case_types)]
pub type EVP_MD_CTX = libc::c_void;
#[allow(non_camel_case_types)]
pub type EVP_MD = libc::c_void;
#[allow(non_camel_case_types)]
pub type ENGINE = libc::c_void;
pub const CRYPTO_MODE_ENCRYPT: libc::c_int = 1;
pub const CRYPTO_MODE_DECRYPT: libc::c_int = 0;
#[allow(dead_code)]
#[link(name = "crypto")]
extern {
pub fn EVP_CIPHER_CTX_new() -> *mut EVP_CIPHER_CTX;
pub fn EVP_CIPHER_CTX_cleanup(ctx: *mut EVP_CIPHER_CTX);
pub fn EVP_CIPHER_CTX_free(ctx: *mut EVP_CIPHER_CTX);
pub fn EVP_CIPHER_CTX_copy(out: *mut EVP_CIPHER_CTX, ctx_in: *const EVP_CIPHER_CTX) -> libc::c_int;
pub fn EVP_CipherInit_ex(ctx: *mut EVP_CIPHER_CTX, evp: *const EVP_CIPHER, engine: *mut ENGINE,
key: *const libc::c_uchar, iv: *const libc::c_uchar, mode: libc::c_int)
-> libc::c_int;
pub fn EVP_CipherUpdate(ctx: *mut EVP_CIPHER_CTX,
outbuf: *mut libc::c_uchar, outlen: *mut libc::c_int,
inbuf: *const libc::c_uchar, inlen: libc::c_int) -> libc::c_int;
pub fn EVP_CipherFinal(ctx: *mut EVP_CIPHER_CTX, res: *mut libc::c_uchar, len: *mut libc::c_int)
-> libc::c_int;
// Ciphers
#[cfg(feature = "cipher-aes-cfb")]
pub fn EVP_aes_128_cfb1() -> *const EVP_CIPHER;
#[cfg(feature = "cipher-aes-cfb")]
pub fn EVP_aes_128_cfb8() -> *const EVP_CIPHER;
#[cfg(feature = "cipher-aes-cfb")]
pub fn EVP_aes_128_cfb128() -> *const EVP_CIPHER;
#[cfg(feature = "cipher-aes-cfb")]
pub fn EVP_aes_192_cfb1() -> *const EVP_CIPHER;
#[cfg(feature = "cipher-aes-cfb")]
pub fn EVP_aes_192_cfb8() -> *const EVP_CIPHER;
#[cfg(feature = "cipher-aes-cfb")]
pub fn EVP_aes_192_cfb128() -> *const EVP_CIPHER;
#[cfg(feature = "cipher-aes-cfb")]
pub fn EVP_aes_256_cfb1() -> *const EVP_CIPHER;
#[cfg(feature = "cipher-aes-cfb")]
pub fn EVP_aes_256_cfb8() -> *const EVP_CIPHER;
#[cfg(feature = "cipher-aes-cfb")]
pub fn EVP_aes_256_cfb128() -> *const EVP_CIPHER;
#[cfg(feature = "cipher-aes-ofb")]
pub fn EVP_aes_128_ofb() -> *const EVP_CIPHER;
#[cfg(feature = "cipher-aes-ofb")]
pub fn EVP_aes_192_ofb() -> *const EVP_CIPHER;
#[cfg(feature = "cipher-aes-ofb")]
pub fn EVP_aes_256_ofb() -> *const EVP_CIPHER;
#[cfg(feature = "cipher-aes-ctr")]
pub fn EVP_aes_128_ctr() -> *const EVP_CIPHER;
#[cfg(feature = "cipher-aes-ctr")]
pub fn EVP_aes_192_ctr() -> *const EVP_CIPHER;
#[cfg(feature = "cipher-aes-ctr")]
pub fn EVP_aes_256_ctr() -> *const EVP_CIPHER;
#[cfg(feature = "cipher-bf-cfb")]
pub fn EVP_bf_cfb64() -> *const EVP_CIPHER;
#[cfg(feature = "cipher-camellia-cfb")]
pub fn EVP_camellia_128_cfb128() -> *const EVP_CIPHER;
#[cfg(feature = "cipher-camellia-cfb")]
pub fn EVP_camellia_192_cfb128() -> *const EVP_CIPHER;
#[cfg(feature = "cipher-camellia-cfb")]
pub fn EVP_camellia_256_cfb128() -> *const EVP_CIPHER;
#[cfg(feature = "cipher-cast5-cfb")]
pub fn EVP_cast5_cfb64() -> *const EVP_CIPHER;
#[cfg(feature = "cipher-des-cfb")]
pub fn EVP_des_cfb64() -> *const EVP_CIPHER;
#[cfg(feature = "cipher-idea-cfb")]
pub fn EVP_idea_cfb64() -> *const EVP_CIPHER;
#[cfg(feature = "cipher-rc2-cfb")]
pub fn EVP_rc2_cfb64() -> *const EVP_CIPHER;
#[cfg(feature = "cipher-seed-cfb")]
pub fn EVP_seed_cfb128() -> *const EVP_CIPHER;
#[cfg(feature = "cipher-rc4")]
pub fn EVP_rc4() -> *const EVP_CIPHER;
// MD
pub fn EVP_MD_CTX_create() -> *mut EVP_MD_CTX;
pub fn EVP_MD_CTX_init(ctx: *mut EVP_MD_CTX);
pub fn EVP_MD_CTX_cleanup(ctx: *mut EVP_MD_CTX);
pub fn EVP_MD_CTX_destroy(ctx: *mut EVP_MD_CTX);
pub fn EVP_MD_CTX_copy_ex(out: *mut EVP_MD_CTX, ctx_in: *const EVP_MD_CTX) -> libc::c_int;
pub fn EVP_DigestInit_ex(ctx: *mut EVP_MD_CTX, md_type: *const EVP_MD, engine: *mut ENGINE) -> libc::c_int;
pub fn EVP_DigestUpdate(ctx: *const EVP_MD_CTX, d: *const libc::c_void, cnt: libc::size_t) -> libc::c_int;
pub fn EVP_DigestFinal_ex(ctx: *const EVP_MD_CTX, md: *mut libc::c_uchar, s: *mut libc::size_t);
pub fn EVP_md5() -> *const EVP_MD;
pub fn EVP_sha() -> *const EVP_MD;
pub fn EVP_sha1() -> *const EVP_MD;
}
}
pub struct OpenSSLDigest {
md_ctx: *mut ffi::EVP_MD_CTX,
digest_len: usize,
}
impl OpenSSLDigest {
pub fn new(t: digest::DigestType) -> OpenSSLDigest {
let ctx = unsafe {
let md_ctx = ffi::EVP_MD_CTX_create();
assert!(!md_ctx.is_null());
ffi::EVP_MD_CTX_init(md_ctx);
md_ctx
};
let md = OpenSSLDigest::get_md(t);
unsafe {
ffi::EVP_DigestInit_ex(ctx, md, ptr::null_mut());
}
OpenSSLDigest {
md_ctx: ctx,
digest_len: t.digest_len(),
}
}
fn get_md(t: digest::DigestType) -> *const ffi::EVP_MD {
unsafe {
match t {
digest::DigestType::Md5 => ffi::EVP_md5(),
digest::DigestType::Sha => ffi::EVP_sha(),
digest::DigestType::Sha1 => ffi::EVP_sha1(),
}
}
}
}
impl Digest for OpenSSLDigest {
fn update(&mut self, data: &[u8]) {
unsafe {
if ffi::EVP_DigestUpdate(self.md_ctx, data.as_ptr() as *const libc::c_void, data.len() as libc::size_t)
!= 1 as libc::c_int {
panic!("Failed to call EVP_DigestUpdate");
}
}
}
fn digest(&mut self) -> Vec<u8> {
let mut dig = Vec::with_capacity(self.digest_len);
unsafe {
dig.set_len(self.digest_len);
ffi::EVP_DigestFinal_ex(self.md_ctx, dig.as_mut_ptr(), ptr::null_mut());
}
dig
}
}
impl Clone for OpenSSLDigest {
fn clone(&self) -> OpenSSLDigest {
let ctx = unsafe {
let md_ctx = ffi::EVP_MD_CTX_create();
assert!(!md_ctx.is_null());
if ffi::EVP_MD_CTX_copy_ex(md_ctx, self.md_ctx) != 1 as libc::c_int {
ffi::EVP_MD_CTX_destroy(md_ctx);
panic!("Failed to call EVP_MD_CTX_copy_ex");
}
md_ctx
};
OpenSSLDigest {
md_ctx: ctx,
digest_len: self.digest_len,
}
}
}
impl Drop for OpenSSLDigest {
fn drop(&mut self) {
unsafe {
ffi::EVP_MD_CTX_cleanup(self.md_ctx);
ffi::EVP_MD_CTX_destroy(self.md_ctx);
}
}
}
unsafe impl Send for OpenSSLDigest {}
use openssl::crypto::symm;
use openssl::crypto::hash;
pub struct OpenSSLCrypto {
evp_ctx: *mut ffi::EVP_CIPHER_CTX,
cipher_type: CipherType,
inner: symm::Crypter,
}
impl OpenSSLCrypto {
pub fn new(cipher_type: cipher::CipherType, key: &[u8], iv: &[u8], mode: CryptoMode) -> OpenSSLCrypto {
let ctx = unsafe {
let cipher = OpenSSLCrypto::get_cipher(cipher_type);
let t = match cipher_type {
#[cfg(feature = "cipher-aes-cfb")]
CipherType::Aes128Cfb => symm::Type::AES_128_CFB128,
#[cfg(feature = "cipher-aes-cfb1")]
CipherType::Aes128Cfb1 => symm::Type::AES_128_CFB1,
#[cfg(feature = "cipher-aes-cfb128")]
CipherType::Aes128Cfb128 => symm::Type::AES_128_CFB128,
#[cfg(feature = "cipher-aes-cfb")]
CipherType::Aes256Cfb => symm::Type::AES_256_CFB128,
#[cfg(feature = "cipher-aes-cfb1")]
CipherType::Aes256Cfb1 => symm::Type::AES_256_CFB1,
#[cfg(feature = "cipher-aes-cfb128")]
CipherType::Aes256Cfb128 => symm::Type::AES_256_CFB128,
debug_assert!(iv.len() >= cipher_type.block_size());
debug_assert!(key.len() == cipher_type.key_size());
let evp_ctx = ffi::EVP_CIPHER_CTX_new();
assert!(!evp_ctx.is_null());
let op = match mode {
CryptoMode::Encrypt => ffi::CRYPTO_MODE_ENCRYPT,
CryptoMode::Decrypt => ffi::CRYPTO_MODE_DECRYPT,
};
if ffi::EVP_CipherInit_ex(evp_ctx, cipher, ptr::null_mut(), key.as_ptr(),
iv.as_ptr(), op) != 1 as libc::c_int {
ffi::EVP_CIPHER_CTX_free(evp_ctx);
panic!("EVP_CipherInit error");
}
evp_ctx
#[cfg(feature = "cipher-rc4")]
CipherType::Rc4 => symm::Type::RC4_128,
_ => panic!("Cipher type {:?} does not supported by OpenSSLCrypt yet", cipher_type),
};
let cipher = symm::Crypter::new(t);
cipher.init(From::from(mode), key, iv);
OpenSSLCrypto {
evp_ctx: ctx,
cipher_type: cipher_type,
inner: cipher,
}
}
fn get_cipher(cipher_type: cipher::CipherType) -> *const ffi::EVP_CIPHER {
unsafe {
match cipher_type {
#[cfg(feature = "cipher-aes-cfb")]
cipher::CipherType::Aes128Cfb => ffi::EVP_aes_128_cfb128(),
#[cfg(feature = "cipher-aes-cfb")]
cipher::CipherType::Aes128Cfb1 => ffi::EVP_aes_128_cfb1(),
#[cfg(feature = "cipher-aes-cfb")]
cipher::CipherType::Aes128Cfb8 => ffi::EVP_aes_128_cfb8(),
#[cfg(feature = "cipher-aes-cfb")]
cipher::CipherType::Aes128Cfb128 => ffi::EVP_aes_128_cfb128(),
#[cfg(feature = "cipher-aes-cfb")]
cipher::CipherType::Aes192Cfb => ffi::EVP_aes_192_cfb128(),
#[cfg(feature = "cipher-aes-cfb")]
cipher::CipherType::Aes192Cfb1 => ffi::EVP_aes_192_cfb1(),
#[cfg(feature = "cipher-aes-cfb")]
cipher::CipherType::Aes192Cfb8 => ffi::EVP_aes_192_cfb8(),
#[cfg(feature = "cipher-aes-cfb")]
cipher::CipherType::Aes192Cfb128 => ffi::EVP_aes_192_cfb128(),
#[cfg(feature = "cipher-aes-cfb")]
cipher::CipherType::Aes256Cfb => ffi::EVP_aes_256_cfb128(),
#[cfg(feature = "cipher-aes-cfb")]
cipher::CipherType::Aes256Cfb1 => ffi::EVP_aes_256_cfb1(),
#[cfg(feature = "cipher-aes-cfb")]
cipher::CipherType::Aes256Cfb8 => ffi::EVP_aes_256_cfb8(),
#[cfg(feature = "cipher-aes-cfb")]
cipher::CipherType::Aes256Cfb128 => ffi::EVP_aes_256_cfb128(),
#[cfg(feature = "cipher-aes-ofb")]
cipher::CipherType::Aes128Ofb => ffi::EVP_aes_128_ofb(),
#[cfg(feature = "cipher-aes-ofb")]
cipher::CipherType::Aes192Ofb => ffi::EVP_aes_192_ofb(),
#[cfg(feature = "cipher-aes-ofb")]
cipher::CipherType::Aes256Ofb => ffi::EVP_aes_256_ofb(),
#[cfg(feature = "cipher-aes-ctr")]
cipher::CipherType::Aes128Ctr => ffi::EVP_aes_128_ctr(),
#[cfg(feature = "cipher-aes-ctr")]
cipher::CipherType::Aes192Ctr => ffi::EVP_aes_192_ctr(),
#[cfg(feature = "cipher-aes-ctr")]
cipher::CipherType::Aes256Ctr => ffi::EVP_aes_256_ctr(),
#[cfg(feature = "cipher-bf-cfb")]
cipher::CipherType::BfCfb => ffi::EVP_bf_cfb64(),
#[cfg(feature = "cipher-camellia-cfb")]
cipher::CipherType::Camellia128Cfb => ffi::EVP_camellia_128_cfb128(),
#[cfg(feature = "cipher-camellia-cfb")]
cipher::CipherType::Camellia192Cfb => ffi::EVP_camellia_192_cfb128(),
#[cfg(feature = "cipher-camellia-cfb")]
cipher::CipherType::Camellia256Cfb => ffi::EVP_camellia_256_cfb128(),
#[cfg(feature = "cipher-cast5-cfb")]
cipher::CipherType::Cast5Cfb => ffi::EVP_cast5_cfb64(),
#[cfg(feature = "cipher-des-cfb")]
cipher::CipherType::DesCfb => ffi::EVP_des_cfb64(),
#[cfg(feature = "cipher-idea-cfb")]
cipher::CipherType::IdeaCfb => ffi::EVP_idea_cfb64(),
#[cfg(feature = "cipher-rc2-cfb")]
cipher::CipherType::Rc2Cfb => ffi::EVP_rc2_cfb64(),
#[cfg(feature = "cipher-seed-cfb")]
cipher::CipherType::SeedCfb => ffi::EVP_seed_cfb128(),
#[cfg(feature = "cipher-rc4")]
cipher::CipherType::Rc4 => ffi::EVP_rc4(),
_ => { panic!("Unsupported cipher type of OpenSSL") },
}
}
}
pub fn update(&self, data: &[u8], out: &mut Vec<u8>) -> CipherResult<()> {
let pdata: *const u8 = data.as_ptr();
let datalen: libc::c_int = data.len() as libc::c_int;
out.reserve(data.len() + self.cipher_type.block_size());
let mut len: libc::c_int = 0;
let orig_len = out.len();
let pres: *mut u8 = out[orig_len..].as_mut_ptr();
unsafe {
if ffi::EVP_CipherUpdate(self.evp_ctx,
pres, &mut len,
pdata, datalen) != 1 {
return Err(cipher::Error {
kind: cipher::ErrorKind::OpenSSLError,
desc: "Failed on EVP_CipherUpdate",
detail: None,
});
}
}
unsafe { out.set_len(orig_len + len as usize) }
pub fn update(&mut self, data: &[u8], out: &mut Vec<u8>) -> CipherResult<()> {
let output = self.inner.update(data);
out.extend(output.into_iter());
Ok(())
}
pub fn finalize(&self, out: &mut Vec<u8>) -> CipherResult<()> {
let mut len: libc::c_int = 0;
let orig_len = out.len();
out.reserve(self.cipher_type.block_size());
unsafe {
if ffi::EVP_CipherFinal(self.evp_ctx, out.as_mut_ptr(), &mut len) != 1 {
return Err(cipher::Error {
kind: cipher::ErrorKind::OpenSSLError,
desc: "Failed on EVP_CipherFinal",
detail: None,
});
}
}
unsafe { out.set_len(orig_len + len as usize) }
pub fn finalize(&mut self, out: &mut Vec<u8>) -> CipherResult<()> {
let output = self.inner.finalize();
out.extend(output.into_iter());
Ok(())
}
}
impl Clone for OpenSSLCrypto {
fn clone(&self) -> OpenSSLCrypto {
let ctx = unsafe {
let ctx = ffi::EVP_CIPHER_CTX_new();
if ffi::EVP_CIPHER_CTX_copy(ctx, self.evp_ctx) != 1 {
ffi::EVP_CIPHER_CTX_free(ctx);
panic!("Failed to call EVP_CIPHER_CTX_copy");
}
ctx
};
OpenSSLCrypto {
evp_ctx: ctx,
cipher_type: self.cipher_type,
}
}
}
impl Drop for OpenSSLCrypto {
fn drop(&mut self) {
unsafe {
ffi::EVP_CIPHER_CTX_cleanup(self.evp_ctx);
ffi::EVP_CIPHER_CTX_free(self.evp_ctx);
}
}
}
/// The Cipher binding for OpenSSL's `libcrypto`.
///
/// It should be noticed that the decipher needs to read the iv (initialization vector)
@@ -438,7 +107,6 @@ impl Drop for OpenSSLCrypto {
///
/// assert!(&decrypted_message[..] == message.as_bytes());
/// ```
#[derive(Clone)]
pub struct OpenSSLCipher {
worker: OpenSSLCrypto,
}
@@ -451,6 +119,8 @@ impl OpenSSLCipher {
}
}
unsafe impl Send for OpenSSLCipher {}
impl Cipher for OpenSSLCipher {
fn update(&mut self, data: &[u8], out: &mut Vec<u8>) -> CipherResult<()> {
self.worker.update(data, out)
@@ -461,123 +131,32 @@ impl Cipher for OpenSSLCipher {
}
}
unsafe impl Send for OpenSSLCipher {}
pub struct OpenSSLDigest {
inner: hash::Hasher,
}
#[cfg(test)]
mod test_openssl {
extern crate test;
use crypto::cipher::{self, Cipher};
use crypto::openssl::OpenSSLCipher;
use crypto::CryptoMode;
impl OpenSSLDigest {
pub fn new(t: digest::DigestType) -> OpenSSLDigest {
let t = match t {
digest::DigestType::Md5 => hash::Type::MD5,
digest::DigestType::Sha => hash::Type::SHA512,
digest::DigestType::Sha1 => hash::Type::SHA1,
};
#[test]
fn test_default_ciphers() {
let message = "hello world";
let key = "passwordhaha";
println!("ORIGINAL {:?}", message.as_bytes());
let types = [
cipher::CipherType::Aes128Cfb,
cipher::CipherType::Aes128Cfb1,
cipher::CipherType::Aes128Cfb8,
cipher::CipherType::Aes128Cfb128,
cipher::CipherType::Aes192Cfb,
cipher::CipherType::Aes192Cfb1,
cipher::CipherType::Aes192Cfb8,
cipher::CipherType::Aes192Cfb128,
cipher::CipherType::Aes256Cfb,
cipher::CipherType::Aes256Cfb1,
cipher::CipherType::Aes256Cfb8,
cipher::CipherType::Aes256Cfb128,
cipher::CipherType::Aes128Ofb,
cipher::CipherType::Aes192Ofb,
cipher::CipherType::Aes256Ofb,
cipher::CipherType::BfCfb,
cipher::CipherType::Cast5Cfb,
cipher::CipherType::DesCfb,
cipher::CipherType::Rc2Cfb,
];
for t in types.iter() {
let k = t.bytes_to_key(key.as_bytes());
let iv = t.gen_init_vec();
let mut enc = OpenSSLCipher::new(*t, &k[..], &iv[..], CryptoMode::Encrypt);
let mut encrypted_msg = Vec::new();
enc.update(message.as_bytes(), &mut encrypted_msg).unwrap();
enc.finalize(&mut encrypted_msg).unwrap();
println!("ENC {:?}", encrypted_msg);
let mut dec = OpenSSLCipher::new(*t, &k[..], &iv[..], CryptoMode::Decrypt);
let mut decrypted_msg = Vec::new();
dec.update(&encrypted_msg[..], &mut decrypted_msg).unwrap();
dec.finalize(&mut decrypted_msg).unwrap();
println!("DEC {:?}", &decrypted_msg[..]);
assert_eq!(message.as_bytes(), &decrypted_msg[..]);
OpenSSLDigest {
inner: hash::Hasher::new(t),
}
}
#[bench]
fn bench_openssl_default_cipher_encrypt(b: &mut test::Bencher) {
use rand::random;
let msg_size: usize = 0xffff;
let mut test_data = Vec::new();
for _ in 0..100 {
let msg = (0..msg_size).map(|_| random::<u8>()).collect::<Vec<u8>>();
let key = (1..random::<usize>() % 63).map(|_| random::<u8>()).collect::<Vec<u8>>();
let k = cipher::CipherType::Aes256Cfb.bytes_to_key(&key[..]);
let v = cipher::CipherType::Aes256Cfb.gen_init_vec();
test_data.push((msg, k, v));
}
b.iter(|| {
let (ref msg, ref key, ref iv) = test_data[random::<usize>() % test_data.len()];
let mut enc = OpenSSLCipher::new(cipher::CipherType::Aes256Cfb,
&key[..], &iv[..], CryptoMode::Encrypt);
let mut out = Vec::new();
enc.update(&msg[..], &mut out).unwrap();
});
b.bytes = msg_size as u64;
}
#[bench]
fn bench_openssl_default_cipher_decrypt(b: &mut test::Bencher) {
use rand::random;
let msg_size: usize = 0xffff;
let mut test_data = Vec::new();
for _ in 0..100 {
let msg = (0..msg_size).map(|_| random::<u8>()).collect::<Vec<u8>>();
let key = (1..random::<usize>() % 63).map(|_| random::<u8>()).collect::<Vec<u8>>();
let k = cipher::CipherType::Aes256Cfb.bytes_to_key(&key[..]);
let v = cipher::CipherType::Aes256Cfb.gen_init_vec();
let mut cipher = OpenSSLCipher::new(cipher::CipherType::Aes256Cfb,
&k[..], &v[..], CryptoMode::Encrypt);
let mut encrypted_msg = Vec::new();
cipher.update(&msg[..], &mut encrypted_msg).unwrap();
test_data.push((k, v, encrypted_msg));
}
b.iter(|| {
let (ref key, ref iv, ref encrypted_msg) = test_data[random::<usize>() % test_data.len()];
let mut cipher = OpenSSLCipher::new(cipher::CipherType::Aes256Cfb,
&key[..], &iv[..], CryptoMode::Decrypt);
let mut out = Vec::new();
cipher.update(&encrypted_msg[..], &mut out).unwrap();
});
b.bytes = msg_size as u64;
}
}
unsafe impl Send for OpenSSLDigest {}
impl Digest for OpenSSLDigest {
fn update(&mut self, data: &[u8]) {
let _ = self.inner.write(data);
}
fn digest(&mut self) -> Vec<u8> {
self.inner.finish()
}
}

View File

@@ -36,6 +36,7 @@ extern crate coio;
extern crate crypto as rust_crypto;
extern crate ip;
extern crate openssl;
pub const VERSION: &'static str = env!("CARGO_PKG_VERSION");