Loading openssl-sys/src/lib.rs +6 −0 Original line number Diff line number Diff line Loading @@ -129,6 +129,8 @@ pub const MBSTRING_UTF8: c_int = MBSTRING_FLAG; pub const NID_ext_key_usage: c_int = 126; pub const NID_key_usage: c_int = 83; pub const PKCS5_SALT_LEN: c_int = 8; pub const SSL_CTRL_OPTIONS: c_int = 32; pub const SSL_CTRL_CLEAR_OPTIONS: c_int = 77; Loading Loading @@ -410,6 +412,10 @@ extern "C" { // fn EVP_aes_256_gcm() -> EVP_CIPHER; pub fn EVP_rc4() -> *const EVP_CIPHER; pub fn EVP_BytesToKey(typ: *const EVP_CIPHER, md: *const EVP_MD, salt: *const u8, data: *const u8, datalen: c_int, count: c_int, key: *mut u8, iv: *mut u8) -> c_int; pub fn EVP_CIPHER_CTX_new() -> *mut EVP_CIPHER_CTX; pub fn EVP_CIPHER_CTX_set_padding(ctx: *mut EVP_CIPHER_CTX, padding: c_int) -> c_int; pub fn EVP_CIPHER_CTX_free(ctx: *mut EVP_CIPHER_CTX); Loading openssl/src/crypto/mod.rs +2 −0 Original line number Diff line number Diff line Loading @@ -22,3 +22,5 @@ pub mod pkey; pub mod rand; pub mod symm; pub mod memcmp; mod symm_internal; No newline at end of file openssl/src/crypto/pkcs5.rs +109 −0 Original line number Diff line number Diff line use libc::c_int; use std::ptr::null; use crypto::symm_internal::evpc; use crypto::hash; use crypto::symm; use ffi; #[derive(Clone, Eq, PartialEq, Hash, Debug)] pub struct KeyIvPair { pub key: Vec<u8>, pub iv: Vec<u8> } /// Derives a key and an IV from various parameters. /// /// If specified `salt` must be 8 bytes in length. /// /// If the total key and IV length is less than 16 bytes and MD5 is used then /// the algorithm is compatible with the key derivation algorithm from PKCS#5 /// v1.5 or PBKDF1 from PKCS#5 v2.0. /// /// New applications should not use this and instead use `pbkdf2_hmac_sha1` or /// another more modern key derivation algorithm. pub fn evp_bytes_to_key_pbkdf1_compatible(typ: symm::Type, message_digest_type: hash::Type, data: &[u8], salt: Option<&[u8]>, count: u32) -> KeyIvPair { unsafe { let salt_ptr = match salt { Some(salt) => { assert_eq!(salt.len(), ffi::PKCS5_SALT_LEN as usize); salt.as_ptr() }, None => null() }; ffi::init(); let (evp, keylen, _) = evpc(typ); let message_digest = message_digest_type.evp_md(); let mut key = vec![0; keylen as usize]; let mut iv = vec![0; keylen as usize]; let ret: c_int = ffi::EVP_BytesToKey(evp, message_digest, salt_ptr, data.as_ptr(), data.len() as c_int, count as c_int, key.as_mut_ptr(), iv.as_mut_ptr()); assert!(ret == keylen as c_int); KeyIvPair { key: key, iv: iv } } } /// Derives a key from a password and salt using the PBKDF2-HMAC-SHA1 algorithm. pub fn pbkdf2_hmac_sha1(pass: &str, salt: &[u8], iter: usize, keylen: usize) -> Vec<u8> { unsafe { Loading @@ -27,6 +90,9 @@ pub fn pbkdf2_hmac_sha1(pass: &str, salt: &[u8], iter: usize, keylen: usize) -> #[cfg(test)] mod tests { use crypto::hash; use crypto::symm; // Test vectors from // http://tools.ietf.org/html/draft-josefsson-pbkdf2-test-vectors-06 #[test] Loading Loading @@ -116,4 +182,47 @@ mod tests { ) ); } #[test] fn test_evp_bytes_to_key_pbkdf1_compatible() { let salt = [ 16_u8, 34_u8, 19_u8, 23_u8, 141_u8, 4_u8, 207_u8, 221_u8 ]; let data = [ 143_u8, 210_u8, 75_u8, 63_u8, 214_u8, 179_u8, 155_u8, 241_u8, 242_u8, 31_u8, 154_u8, 56_u8, 198_u8, 145_u8, 192_u8, 64_u8, 2_u8, 245_u8, 167_u8, 220_u8, 55_u8, 119_u8, 233_u8, 136_u8, 139_u8, 27_u8, 71_u8, 242_u8, 119_u8, 175_u8, 65_u8, 207_u8 ]; let expected_key = vec![ 249_u8, 115_u8, 114_u8, 97_u8, 32_u8, 213_u8, 165_u8, 146_u8, 58_u8, 87_u8, 234_u8, 3_u8, 43_u8, 250_u8, 97_u8, 114_u8, 26_u8, 98_u8, 245_u8, 246_u8, 238_u8, 177_u8, 229_u8, 161_u8, 183_u8, 224_u8, 174_u8, 3_u8, 6_u8, 244_u8, 236_u8, 255_u8 ]; let expected_iv = vec![ 4_u8, 223_u8, 153_u8, 219_u8, 28_u8, 142_u8, 234_u8, 68_u8, 227_u8, 69_u8, 98_u8, 107_u8, 208_u8, 14_u8, 236_u8, 60_u8, 0_u8, 0_u8, 0_u8, 0_u8, 0_u8, 0_u8, 0_u8, 0_u8, 0_u8, 0_u8, 0_u8, 0_u8, 0_u8, 0_u8, 0_u8, 0_u8 ]; assert_eq!( super::evp_bytes_to_key_pbkdf1_compatible( symm::Type::AES_256_CBC, hash::Type::SHA1, &data, Some(&salt), 1 ), super::KeyIvPair { key: expected_key, iv: expected_iv } ); } } openssl/src/crypto/symm.rs +1 −23 Original line number Diff line number Diff line Loading @@ -2,6 +2,7 @@ use std::iter::repeat; use std::convert::AsRef; use libc::{c_int}; use crypto::symm_internal::evpc; use ffi; #[derive(Copy, Clone)] Loading Loading @@ -34,29 +35,6 @@ pub enum Type { RC4_128, } fn evpc(t: Type) -> (*const ffi::EVP_CIPHER, u32, u32) { unsafe { match t { Type::AES_128_ECB => (ffi::EVP_aes_128_ecb(), 16, 16), Type::AES_128_CBC => (ffi::EVP_aes_128_cbc(), 16, 16), #[cfg(feature = "aes_xts")] Type::AES_128_XTS => (ffi::EVP_aes_128_xts(), 32, 16), #[cfg(feature = "aes_ctr")] Type::AES_128_CTR => (ffi::EVP_aes_128_ctr(), 16, 0), //AES_128_GCM => (EVP_aes_128_gcm(), 16, 16), Type::AES_256_ECB => (ffi::EVP_aes_256_ecb(), 32, 16), Type::AES_256_CBC => (ffi::EVP_aes_256_cbc(), 32, 16), #[cfg(feature = "aes_xts")] Type::AES_256_XTS => (ffi::EVP_aes_256_xts(), 64, 16), #[cfg(feature = "aes_ctr")] Type::AES_256_CTR => (ffi::EVP_aes_256_ctr(), 32, 0), //AES_256_GCM => (EVP_aes_256_gcm(), 32, 16), Type::RC4_128 => (ffi::EVP_rc4(), 16, 0), } } } /// Represents a symmetric cipher context. pub struct Crypter { Loading openssl/src/crypto/symm_internal.rs 0 → 100644 +26 −0 Original line number Diff line number Diff line use crypto::symm; use ffi; pub fn evpc(t: symm::Type) -> (*const ffi::EVP_CIPHER, u32, u32) { unsafe { match t { symm::Type::AES_128_ECB => (ffi::EVP_aes_128_ecb(), 16, 16), symm::Type::AES_128_CBC => (ffi::EVP_aes_128_cbc(), 16, 16), #[cfg(feature = "aes_xts")] symm::Type::AES_128_XTS => (ffi::EVP_aes_128_xts(), 32, 16), #[cfg(feature = "aes_ctr")] symm::Type::AES_128_CTR => (ffi::EVP_aes_128_ctr(), 16, 0), //AES_128_GCM => (EVP_aes_128_gcm(), 16, 16), symm::Type::AES_256_ECB => (ffi::EVP_aes_256_ecb(), 32, 16), symm::Type::AES_256_CBC => (ffi::EVP_aes_256_cbc(), 32, 16), #[cfg(feature = "aes_xts")] symm::Type::AES_256_XTS => (ffi::EVP_aes_256_xts(), 64, 16), #[cfg(feature = "aes_ctr")] symm::Type::AES_256_CTR => (ffi::EVP_aes_256_ctr(), 32, 0), //AES_256_GCM => (EVP_aes_256_gcm(), 32, 16), symm::Type::RC4_128 => (ffi::EVP_rc4(), 16, 0), } } } No newline at end of file Loading
openssl-sys/src/lib.rs +6 −0 Original line number Diff line number Diff line Loading @@ -129,6 +129,8 @@ pub const MBSTRING_UTF8: c_int = MBSTRING_FLAG; pub const NID_ext_key_usage: c_int = 126; pub const NID_key_usage: c_int = 83; pub const PKCS5_SALT_LEN: c_int = 8; pub const SSL_CTRL_OPTIONS: c_int = 32; pub const SSL_CTRL_CLEAR_OPTIONS: c_int = 77; Loading Loading @@ -410,6 +412,10 @@ extern "C" { // fn EVP_aes_256_gcm() -> EVP_CIPHER; pub fn EVP_rc4() -> *const EVP_CIPHER; pub fn EVP_BytesToKey(typ: *const EVP_CIPHER, md: *const EVP_MD, salt: *const u8, data: *const u8, datalen: c_int, count: c_int, key: *mut u8, iv: *mut u8) -> c_int; pub fn EVP_CIPHER_CTX_new() -> *mut EVP_CIPHER_CTX; pub fn EVP_CIPHER_CTX_set_padding(ctx: *mut EVP_CIPHER_CTX, padding: c_int) -> c_int; pub fn EVP_CIPHER_CTX_free(ctx: *mut EVP_CIPHER_CTX); Loading
openssl/src/crypto/mod.rs +2 −0 Original line number Diff line number Diff line Loading @@ -22,3 +22,5 @@ pub mod pkey; pub mod rand; pub mod symm; pub mod memcmp; mod symm_internal; No newline at end of file
openssl/src/crypto/pkcs5.rs +109 −0 Original line number Diff line number Diff line use libc::c_int; use std::ptr::null; use crypto::symm_internal::evpc; use crypto::hash; use crypto::symm; use ffi; #[derive(Clone, Eq, PartialEq, Hash, Debug)] pub struct KeyIvPair { pub key: Vec<u8>, pub iv: Vec<u8> } /// Derives a key and an IV from various parameters. /// /// If specified `salt` must be 8 bytes in length. /// /// If the total key and IV length is less than 16 bytes and MD5 is used then /// the algorithm is compatible with the key derivation algorithm from PKCS#5 /// v1.5 or PBKDF1 from PKCS#5 v2.0. /// /// New applications should not use this and instead use `pbkdf2_hmac_sha1` or /// another more modern key derivation algorithm. pub fn evp_bytes_to_key_pbkdf1_compatible(typ: symm::Type, message_digest_type: hash::Type, data: &[u8], salt: Option<&[u8]>, count: u32) -> KeyIvPair { unsafe { let salt_ptr = match salt { Some(salt) => { assert_eq!(salt.len(), ffi::PKCS5_SALT_LEN as usize); salt.as_ptr() }, None => null() }; ffi::init(); let (evp, keylen, _) = evpc(typ); let message_digest = message_digest_type.evp_md(); let mut key = vec![0; keylen as usize]; let mut iv = vec![0; keylen as usize]; let ret: c_int = ffi::EVP_BytesToKey(evp, message_digest, salt_ptr, data.as_ptr(), data.len() as c_int, count as c_int, key.as_mut_ptr(), iv.as_mut_ptr()); assert!(ret == keylen as c_int); KeyIvPair { key: key, iv: iv } } } /// Derives a key from a password and salt using the PBKDF2-HMAC-SHA1 algorithm. pub fn pbkdf2_hmac_sha1(pass: &str, salt: &[u8], iter: usize, keylen: usize) -> Vec<u8> { unsafe { Loading @@ -27,6 +90,9 @@ pub fn pbkdf2_hmac_sha1(pass: &str, salt: &[u8], iter: usize, keylen: usize) -> #[cfg(test)] mod tests { use crypto::hash; use crypto::symm; // Test vectors from // http://tools.ietf.org/html/draft-josefsson-pbkdf2-test-vectors-06 #[test] Loading Loading @@ -116,4 +182,47 @@ mod tests { ) ); } #[test] fn test_evp_bytes_to_key_pbkdf1_compatible() { let salt = [ 16_u8, 34_u8, 19_u8, 23_u8, 141_u8, 4_u8, 207_u8, 221_u8 ]; let data = [ 143_u8, 210_u8, 75_u8, 63_u8, 214_u8, 179_u8, 155_u8, 241_u8, 242_u8, 31_u8, 154_u8, 56_u8, 198_u8, 145_u8, 192_u8, 64_u8, 2_u8, 245_u8, 167_u8, 220_u8, 55_u8, 119_u8, 233_u8, 136_u8, 139_u8, 27_u8, 71_u8, 242_u8, 119_u8, 175_u8, 65_u8, 207_u8 ]; let expected_key = vec![ 249_u8, 115_u8, 114_u8, 97_u8, 32_u8, 213_u8, 165_u8, 146_u8, 58_u8, 87_u8, 234_u8, 3_u8, 43_u8, 250_u8, 97_u8, 114_u8, 26_u8, 98_u8, 245_u8, 246_u8, 238_u8, 177_u8, 229_u8, 161_u8, 183_u8, 224_u8, 174_u8, 3_u8, 6_u8, 244_u8, 236_u8, 255_u8 ]; let expected_iv = vec![ 4_u8, 223_u8, 153_u8, 219_u8, 28_u8, 142_u8, 234_u8, 68_u8, 227_u8, 69_u8, 98_u8, 107_u8, 208_u8, 14_u8, 236_u8, 60_u8, 0_u8, 0_u8, 0_u8, 0_u8, 0_u8, 0_u8, 0_u8, 0_u8, 0_u8, 0_u8, 0_u8, 0_u8, 0_u8, 0_u8, 0_u8, 0_u8 ]; assert_eq!( super::evp_bytes_to_key_pbkdf1_compatible( symm::Type::AES_256_CBC, hash::Type::SHA1, &data, Some(&salt), 1 ), super::KeyIvPair { key: expected_key, iv: expected_iv } ); } }
openssl/src/crypto/symm.rs +1 −23 Original line number Diff line number Diff line Loading @@ -2,6 +2,7 @@ use std::iter::repeat; use std::convert::AsRef; use libc::{c_int}; use crypto::symm_internal::evpc; use ffi; #[derive(Copy, Clone)] Loading Loading @@ -34,29 +35,6 @@ pub enum Type { RC4_128, } fn evpc(t: Type) -> (*const ffi::EVP_CIPHER, u32, u32) { unsafe { match t { Type::AES_128_ECB => (ffi::EVP_aes_128_ecb(), 16, 16), Type::AES_128_CBC => (ffi::EVP_aes_128_cbc(), 16, 16), #[cfg(feature = "aes_xts")] Type::AES_128_XTS => (ffi::EVP_aes_128_xts(), 32, 16), #[cfg(feature = "aes_ctr")] Type::AES_128_CTR => (ffi::EVP_aes_128_ctr(), 16, 0), //AES_128_GCM => (EVP_aes_128_gcm(), 16, 16), Type::AES_256_ECB => (ffi::EVP_aes_256_ecb(), 32, 16), Type::AES_256_CBC => (ffi::EVP_aes_256_cbc(), 32, 16), #[cfg(feature = "aes_xts")] Type::AES_256_XTS => (ffi::EVP_aes_256_xts(), 64, 16), #[cfg(feature = "aes_ctr")] Type::AES_256_CTR => (ffi::EVP_aes_256_ctr(), 32, 0), //AES_256_GCM => (EVP_aes_256_gcm(), 32, 16), Type::RC4_128 => (ffi::EVP_rc4(), 16, 0), } } } /// Represents a symmetric cipher context. pub struct Crypter { Loading
openssl/src/crypto/symm_internal.rs 0 → 100644 +26 −0 Original line number Diff line number Diff line use crypto::symm; use ffi; pub fn evpc(t: symm::Type) -> (*const ffi::EVP_CIPHER, u32, u32) { unsafe { match t { symm::Type::AES_128_ECB => (ffi::EVP_aes_128_ecb(), 16, 16), symm::Type::AES_128_CBC => (ffi::EVP_aes_128_cbc(), 16, 16), #[cfg(feature = "aes_xts")] symm::Type::AES_128_XTS => (ffi::EVP_aes_128_xts(), 32, 16), #[cfg(feature = "aes_ctr")] symm::Type::AES_128_CTR => (ffi::EVP_aes_128_ctr(), 16, 0), //AES_128_GCM => (EVP_aes_128_gcm(), 16, 16), symm::Type::AES_256_ECB => (ffi::EVP_aes_256_ecb(), 32, 16), symm::Type::AES_256_CBC => (ffi::EVP_aes_256_cbc(), 32, 16), #[cfg(feature = "aes_xts")] symm::Type::AES_256_XTS => (ffi::EVP_aes_256_xts(), 64, 16), #[cfg(feature = "aes_ctr")] symm::Type::AES_256_CTR => (ffi::EVP_aes_256_ctr(), 32, 0), //AES_256_GCM => (EVP_aes_256_gcm(), 32, 16), symm::Type::RC4_128 => (ffi::EVP_rc4(), 16, 0), } } } No newline at end of file