From 43c951f743e68fac5f45119eda7c994882a1d489 Mon Sep 17 00:00:00 2001 From: Alex Crichton Date: Fri, 30 Sep 2016 00:43:05 -0700 Subject: Add support for OpenSSL 1.1.0 This commit is relatively major refactoring of the `openssl-sys` crate as well as the `openssl` crate itself. The end goal here was to support OpenSSL 1.1.0, and lots of other various tweaks happened along the way. The major new features are: * OpenSSL 1.1.0 is supported * OpenSSL 0.9.8 is no longer supported (aka all OSX users by default) * All FFI bindings are verified with the `ctest` crate (same way as the `libc` crate) * CI matrixes are vastly expanded to include 32/64 of all platforms, more OpenSSL version coverage, as well as ARM coverage on Linux * The `c_helpers` module is completely removed along with the `gcc` dependency. * The `openssl-sys` build script was completely rewritten * Now uses `OPENSSL_DIR` to find the installation, not include/lib env vars. * Better error messages for mismatched versions. * Better error messages for failing to find OpenSSL on a platform (more can be done here) * Probing of OpenSSL build-time configuration to inform the API of the `*-sys` crate. * Many Cargo features have been removed as they're now enabled by default. As this is a breaking change to both the `openssl` and `openssl-sys` crates this will necessitate a major version bump of both. There's still a few more API questions remaining but let's hash that out on a PR! Closes #452 --- openssl/src/crypto/pkcs5.rs | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) (limited to 'openssl/src/crypto/pkcs5.rs') diff --git a/openssl/src/crypto/pkcs5.rs b/openssl/src/crypto/pkcs5.rs index ef84fbe1..adcbc9db 100644 --- a/openssl/src/crypto/pkcs5.rs +++ b/openssl/src/crypto/pkcs5.rs @@ -82,7 +82,7 @@ pub fn pbkdf2_hmac_sha1(pass: &[u8], ffi::init(); - try_ssl!(ffi::PKCS5_PBKDF2_HMAC_SHA1(pass.as_ptr(), + try_ssl!(ffi::PKCS5_PBKDF2_HMAC_SHA1(pass.as_ptr() as *const _, pass.len() as c_int, salt.as_ptr(), salt.len() as c_int, @@ -94,7 +94,6 @@ pub fn pbkdf2_hmac_sha1(pass: &[u8], } /// Derives a key from a password and salt using the PBKDF2-HMAC algorithm with a digest function. -#[cfg(feature = "pkcs5_pbkdf2_hmac")] pub fn pbkdf2_hmac(pass: &[u8], salt: &[u8], iter: usize, @@ -104,7 +103,7 @@ pub fn pbkdf2_hmac(pass: &[u8], unsafe { let mut out = vec![0; keylen]; ffi::init(); - try_ssl!(ffi::PKCS5_PBKDF2_HMAC(pass.as_ptr(), + try_ssl!(ffi::PKCS5_PBKDF2_HMAC(pass.as_ptr() as *const _, pass.len() as c_int, salt.as_ptr(), salt.len() as c_int, @@ -162,7 +161,6 @@ mod tests { // Test vectors from // https://git.lysator.liu.se/nettle/nettle/blob/nettle_3.1.1_release_20150424/testsuite/pbkdf2-test.c #[test] - #[cfg(feature = "pkcs5_pbkdf2_hmac")] fn test_pbkdf2_hmac_sha256() { assert_eq!(super::pbkdf2_hmac(b"passwd", b"salt", 1, hash::Type::SHA256, 16).unwrap(), vec![0x55_u8, 0xac_u8, 0x04_u8, 0x6e_u8, 0x56_u8, 0xe3_u8, 0x08_u8, 0x9f_u8, @@ -176,7 +174,6 @@ mod tests { // Test vectors from // https://git.lysator.liu.se/nettle/nettle/blob/nettle_3.1.1_release_20150424/testsuite/pbkdf2-test.c #[test] - #[cfg(feature = "pkcs5_pbkdf2_hmac")] fn test_pbkdf2_hmac_sha512() { assert_eq!(super::pbkdf2_hmac(b"password", b"NaCL", 1, hash::Type::SHA512, 64).unwrap(), vec![0x73_u8, 0xde_u8, 0xcf_u8, 0xa5_u8, 0x8a_u8, 0xa2_u8, 0xe8_u8, 0x4f_u8, -- cgit v1.2.3 From c171be551ac8d22c91cbf550e21215ae2c8b6abc Mon Sep 17 00:00:00 2001 From: Steven Fackler Date: Sat, 15 Oct 2016 15:23:29 -0700 Subject: De-enumify message digests --- openssl/src/crypto/pkcs5.rs | 25 ++++++++++++------------- 1 file changed, 12 insertions(+), 13 deletions(-) (limited to 'openssl/src/crypto/pkcs5.rs') diff --git a/openssl/src/crypto/pkcs5.rs b/openssl/src/crypto/pkcs5.rs index adcbc9db..56ce3e26 100644 --- a/openssl/src/crypto/pkcs5.rs +++ b/openssl/src/crypto/pkcs5.rs @@ -2,8 +2,7 @@ use libc::c_int; use std::ptr; use ffi; -use HashTypeInternals; -use crypto::hash; +use crypto::hash::MessageDigest; use crypto::symm; use error::ErrorStack; @@ -24,7 +23,7 @@ pub struct KeyIvPair { /// 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, + message_digest_type: MessageDigest, data: &[u8], salt: Option<&[u8]>, count: u32) @@ -41,7 +40,7 @@ pub fn evp_bytes_to_key_pbkdf1_compatible(typ: symm::Type, ffi::init(); let typ = typ.as_ptr(); - let message_digest_type = message_digest_type.evp_md(); + let message_digest_type = message_digest_type.as_ptr(); let len = ffi::EVP_BytesToKey(typ, message_digest_type, @@ -97,7 +96,7 @@ pub fn pbkdf2_hmac_sha1(pass: &[u8], pub fn pbkdf2_hmac(pass: &[u8], salt: &[u8], iter: usize, - hash: hash::Type, + hash: MessageDigest, keylen: usize) -> Result, ErrorStack> { unsafe { @@ -108,7 +107,7 @@ pub fn pbkdf2_hmac(pass: &[u8], salt.as_ptr(), salt.len() as c_int, iter as c_int, - hash.evp_md(), + hash.as_ptr(), keylen as c_int, out.as_mut_ptr())); Ok(out) @@ -117,7 +116,7 @@ pub fn pbkdf2_hmac(pass: &[u8], #[cfg(test)] mod tests { - use crypto::hash; + use crypto::hash::MessageDigest; use crypto::symm; // Test vectors from @@ -162,11 +161,11 @@ mod tests { // https://git.lysator.liu.se/nettle/nettle/blob/nettle_3.1.1_release_20150424/testsuite/pbkdf2-test.c #[test] fn test_pbkdf2_hmac_sha256() { - assert_eq!(super::pbkdf2_hmac(b"passwd", b"salt", 1, hash::Type::SHA256, 16).unwrap(), + assert_eq!(super::pbkdf2_hmac(b"passwd", b"salt", 1, MessageDigest::sha256(), 16).unwrap(), vec![0x55_u8, 0xac_u8, 0x04_u8, 0x6e_u8, 0x56_u8, 0xe3_u8, 0x08_u8, 0x9f_u8, 0xec_u8, 0x16_u8, 0x91_u8, 0xc2_u8, 0x25_u8, 0x44_u8, 0xb6_u8, 0x05_u8]); - assert_eq!(super::pbkdf2_hmac(b"Password", b"NaCl", 80000, hash::Type::SHA256, 16).unwrap(), + assert_eq!(super::pbkdf2_hmac(b"Password", b"NaCl", 80000, MessageDigest::sha256(), 16).unwrap(), vec![0x4d_u8, 0xdc_u8, 0xd8_u8, 0xf6_u8, 0x0b_u8, 0x98_u8, 0xbe_u8, 0x21_u8, 0x83_u8, 0x0c_u8, 0xee_u8, 0x5e_u8, 0xf2_u8, 0x27_u8, 0x01_u8, 0xf9_u8]); } @@ -175,7 +174,7 @@ mod tests { // https://git.lysator.liu.se/nettle/nettle/blob/nettle_3.1.1_release_20150424/testsuite/pbkdf2-test.c #[test] fn test_pbkdf2_hmac_sha512() { - assert_eq!(super::pbkdf2_hmac(b"password", b"NaCL", 1, hash::Type::SHA512, 64).unwrap(), + assert_eq!(super::pbkdf2_hmac(b"password", b"NaCL", 1, MessageDigest::sha512(), 64).unwrap(), vec![0x73_u8, 0xde_u8, 0xcf_u8, 0xa5_u8, 0x8a_u8, 0xa2_u8, 0xe8_u8, 0x4f_u8, 0x94_u8, 0x77_u8, 0x1a_u8, 0x75_u8, 0x73_u8, 0x6b_u8, 0xb8_u8, 0x8b_u8, 0xd3_u8, 0xc7_u8, 0xb3_u8, 0x82_u8, 0x70_u8, 0xcf_u8, 0xb5_u8, 0x0c_u8, @@ -185,7 +184,7 @@ mod tests { 0x60_u8, 0x60_u8, 0xa0_u8, 0x9f_u8, 0x76_u8, 0x41_u8, 0x5e_u8, 0x9f_u8, 0x71_u8, 0xea_u8, 0x47_u8, 0xf9_u8, 0xe9_u8, 0x06_u8, 0x43_u8, 0x06_u8]); - assert_eq!(super::pbkdf2_hmac(b"pass\0word", b"sa\0lt", 1, hash::Type::SHA512, 64).unwrap(), + assert_eq!(super::pbkdf2_hmac(b"pass\0word", b"sa\0lt", 1, MessageDigest::sha512(), 64).unwrap(), vec![0x71_u8, 0xa0_u8, 0xec_u8, 0x84_u8, 0x2a_u8, 0xbd_u8, 0x5c_u8, 0x67_u8, 0x8b_u8, 0xcf_u8, 0xd1_u8, 0x45_u8, 0xf0_u8, 0x9d_u8, 0x83_u8, 0x52_u8, 0x2f_u8, 0x93_u8, 0x36_u8, 0x15_u8, 0x60_u8, 0x56_u8, 0x3c_u8, 0x4d_u8, @@ -198,7 +197,7 @@ mod tests { assert_eq!(super::pbkdf2_hmac(b"passwordPASSWORDpassword", b"salt\0\0\0", 50, - hash::Type::SHA512, + MessageDigest::sha512(), 64).unwrap(), vec![0x01_u8, 0x68_u8, 0x71_u8, 0xa4_u8, 0xc4_u8, 0xb7_u8, 0x5f_u8, 0x96_u8, 0x85_u8, 0x7f_u8, 0xd2_u8, 0xb9_u8, 0xf8_u8, 0xca_u8, 0x28_u8, 0x02_u8, @@ -230,7 +229,7 @@ mod tests { 0_u8, 0_u8, 0_u8]; assert_eq!(super::evp_bytes_to_key_pbkdf1_compatible(symm::Type::AES_256_CBC, - hash::Type::SHA1, + MessageDigest::sha1(), &data, Some(&salt), 1).unwrap(), -- cgit v1.2.3 From 1cecaeb62dc7e37b84e7a6758828a90bd6eb63b6 Mon Sep 17 00:00:00 2001 From: Steven Fackler Date: Sat, 15 Oct 2016 15:47:40 -0700 Subject: De-enumify Cipher --- openssl/src/crypto/pkcs5.rs | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) (limited to 'openssl/src/crypto/pkcs5.rs') diff --git a/openssl/src/crypto/pkcs5.rs b/openssl/src/crypto/pkcs5.rs index 56ce3e26..9d348b89 100644 --- a/openssl/src/crypto/pkcs5.rs +++ b/openssl/src/crypto/pkcs5.rs @@ -3,7 +3,7 @@ use std::ptr; use ffi; use crypto::hash::MessageDigest; -use crypto::symm; +use crypto::symm::Cipher; use error::ErrorStack; #[derive(Clone, Eq, PartialEq, Hash, Debug)] @@ -22,8 +22,8 @@ pub struct KeyIvPair { /// /// 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: MessageDigest, +pub fn evp_bytes_to_key_pbkdf1_compatible(cipher: Cipher, + digest: MessageDigest, data: &[u8], salt: Option<&[u8]>, count: u32) @@ -39,11 +39,11 @@ pub fn evp_bytes_to_key_pbkdf1_compatible(typ: symm::Type, ffi::init(); - let typ = typ.as_ptr(); - let message_digest_type = message_digest_type.as_ptr(); + let cipher = cipher.as_ptr(); + let digest = digest.as_ptr(); - let len = ffi::EVP_BytesToKey(typ, - message_digest_type, + let len = ffi::EVP_BytesToKey(cipher, + digest, salt_ptr, data.as_ptr(), data.len() as c_int, @@ -57,8 +57,8 @@ pub fn evp_bytes_to_key_pbkdf1_compatible(typ: symm::Type, let mut key = vec![0; len as usize]; let mut iv = vec![0; len as usize]; - try_ssl!(ffi::EVP_BytesToKey(typ, - message_digest_type, + try_ssl!(ffi::EVP_BytesToKey(cipher, + digest, salt_ptr, data.as_ptr(), data.len() as c_int, @@ -117,7 +117,7 @@ pub fn pbkdf2_hmac(pass: &[u8], #[cfg(test)] mod tests { use crypto::hash::MessageDigest; - use crypto::symm; + use crypto::symm::Cipher; // Test vectors from // http://tools.ietf.org/html/draft-josefsson-pbkdf2-test-vectors-06 @@ -228,7 +228,7 @@ mod tests { 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, + assert_eq!(super::evp_bytes_to_key_pbkdf1_compatible(Cipher::aes_256_cbc(), MessageDigest::sha1(), &data, Some(&salt), -- cgit v1.2.3 From 73ccfe7a29f55d4823fe9530e3c326d0b3099d6b Mon Sep 17 00:00:00 2001 From: Steven Fackler Date: Sun, 16 Oct 2016 16:42:56 -0700 Subject: Continue error handling cleanup Also overhaul/clean up pkcs5 internals --- openssl/src/crypto/pkcs5.rs | 249 ++++++++++++++++++-------------------------- 1 file changed, 100 insertions(+), 149 deletions(-) (limited to 'openssl/src/crypto/pkcs5.rs') diff --git a/openssl/src/crypto/pkcs5.rs b/openssl/src/crypto/pkcs5.rs index 9d348b89..8bcb9b31 100644 --- a/openssl/src/crypto/pkcs5.rs +++ b/openssl/src/crypto/pkcs5.rs @@ -2,6 +2,7 @@ use libc::c_int; use std::ptr; use ffi; +use cvt; use crypto::hash::MessageDigest; use crypto::symm::Cipher; use error::ErrorStack; @@ -9,26 +10,27 @@ use error::ErrorStack; #[derive(Clone, Eq, PartialEq, Hash, Debug)] pub struct KeyIvPair { pub key: Vec, - pub iv: Vec, + pub iv: Option>, } /// Derives a key and an IV from various parameters. /// -/// If specified `salt` must be 8 bytes in length. +/// 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(cipher: Cipher, - digest: MessageDigest, - data: &[u8], - salt: Option<&[u8]>, - count: u32) - -> Result { +/// New applications should not use this and instead use +/// `pkcs5_pbkdf2_hmac_sha1` or another more modern key derivation algorithm. +pub fn bytes_to_key(cipher: Cipher, + digest: MessageDigest, + data: &[u8], + salt: Option<&[u8]>, + count: i32) + -> Result { unsafe { + assert!(data.len() <= c_int::max_value() as usize); let salt_ptr = match salt { Some(salt) => { assert_eq!(salt.len(), ffi::PKCS5_SALT_LEN as usize); @@ -39,78 +41,58 @@ pub fn evp_bytes_to_key_pbkdf1_compatible(cipher: Cipher, ffi::init(); + let mut iv = cipher.iv_len().map(|l| vec![0; l]); + let cipher = cipher.as_ptr(); let digest = digest.as_ptr(); - let len = ffi::EVP_BytesToKey(cipher, - digest, - salt_ptr, - data.as_ptr(), - data.len() as c_int, - count as c_int, - ptr::null_mut(), - ptr::null_mut()); - if len == 0 { - return Err(ErrorStack::get()); - } + let len = try!(cvt(ffi::EVP_BytesToKey(cipher, + digest, + salt_ptr, + ptr::null(), + data.len() as c_int, + count.into(), + ptr::null_mut(), + ptr::null_mut()))); let mut key = vec![0; len as usize]; - let mut iv = vec![0; len as usize]; + let iv_ptr = iv.as_mut().map(|v| v.as_mut_ptr()).unwrap_or(ptr::null_mut()); - try_ssl!(ffi::EVP_BytesToKey(cipher, + try!(cvt(ffi::EVP_BytesToKey(cipher, digest, salt_ptr, data.as_ptr(), data.len() as c_int, count as c_int, key.as_mut_ptr(), - iv.as_mut_ptr())); + iv_ptr))); Ok(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: &[u8], - salt: &[u8], - iter: usize, - keylen: usize) - -> Result, ErrorStack> { - unsafe { - let mut out = vec![0; keylen]; - - ffi::init(); - - try_ssl!(ffi::PKCS5_PBKDF2_HMAC_SHA1(pass.as_ptr() as *const _, - pass.len() as c_int, - salt.as_ptr(), - salt.len() as c_int, - iter as c_int, - keylen as c_int, - out.as_mut_ptr())); - Ok(out) - } -} - /// Derives a key from a password and salt using the PBKDF2-HMAC algorithm with a digest function. pub fn pbkdf2_hmac(pass: &[u8], salt: &[u8], iter: usize, hash: MessageDigest, - keylen: usize) - -> Result, ErrorStack> { + key: &mut [u8]) + -> Result<(), ErrorStack> { unsafe { - let mut out = vec![0; keylen]; + assert!(pass.len() <= c_int::max_value() as usize); + assert!(salt.len() <= c_int::max_value() as usize); + assert!(key.len() <= c_int::max_value() as usize); + ffi::init(); - try_ssl!(ffi::PKCS5_PBKDF2_HMAC(pass.as_ptr() as *const _, - pass.len() as c_int, - salt.as_ptr(), - salt.len() as c_int, - iter as c_int, - hash.as_ptr(), - keylen as c_int, - out.as_mut_ptr())); - Ok(out) + cvt(ffi::PKCS5_PBKDF2_HMAC(pass.as_ptr() as *const _, + pass.len() as c_int, + salt.as_ptr(), + salt.len() as c_int, + iter as c_int, + hash.as_ptr(), + key.len() as c_int, + key.as_mut_ptr())) + .map(|_| ()) } } @@ -119,97 +101,68 @@ mod tests { use crypto::hash::MessageDigest; use crypto::symm::Cipher; - // Test vectors from - // http://tools.ietf.org/html/draft-josefsson-pbkdf2-test-vectors-06 - #[test] - fn test_pbkdf2_hmac_sha1() { - assert_eq!(super::pbkdf2_hmac_sha1(b"password", b"salt", 1, 20).unwrap(), - vec![0x0c_u8, 0x60_u8, 0xc8_u8, 0x0f_u8, 0x96_u8, 0x1f_u8, 0x0e_u8, 0x71_u8, - 0xf3_u8, 0xa9_u8, 0xb5_u8, 0x24_u8, 0xaf_u8, 0x60_u8, 0x12_u8, 0x06_u8, - 0x2f_u8, 0xe0_u8, 0x37_u8, 0xa6_u8]); - - assert_eq!(super::pbkdf2_hmac_sha1(b"password", b"salt", 2, 20).unwrap(), - vec![0xea_u8, 0x6c_u8, 0x01_u8, 0x4d_u8, 0xc7_u8, 0x2d_u8, 0x6f_u8, 0x8c_u8, - 0xcd_u8, 0x1e_u8, 0xd9_u8, 0x2a_u8, 0xce_u8, 0x1d_u8, 0x41_u8, 0xf0_u8, - 0xd8_u8, 0xde_u8, 0x89_u8, 0x57_u8]); - - assert_eq!(super::pbkdf2_hmac_sha1(b"password", b"salt", 4096, 20).unwrap(), - vec![0x4b_u8, 0x00_u8, 0x79_u8, 0x01_u8, 0xb7_u8, 0x65_u8, 0x48_u8, 0x9a_u8, - 0xbe_u8, 0xad_u8, 0x49_u8, 0xd9_u8, 0x26_u8, 0xf7_u8, 0x21_u8, 0xd0_u8, - 0x65_u8, 0xa4_u8, 0x29_u8, 0xc1_u8]); - - assert_eq!(super::pbkdf2_hmac_sha1(b"password", b"salt", 16777216, 20).unwrap(), - vec![0xee_u8, 0xfe_u8, 0x3d_u8, 0x61_u8, 0xcd_u8, 0x4d_u8, 0xa4_u8, 0xe4_u8, - 0xe9_u8, 0x94_u8, 0x5b_u8, 0x3d_u8, 0x6b_u8, 0xa2_u8, 0x15_u8, 0x8c_u8, - 0x26_u8, 0x34_u8, 0xe9_u8, 0x84_u8]); - - assert_eq!(super::pbkdf2_hmac_sha1(b"passwordPASSWORDpassword", - b"saltSALTsaltSALTsaltSALTsaltSALTsalt", - 4096, - 25).unwrap(), - vec![0x3d_u8, 0x2e_u8, 0xec_u8, 0x4f_u8, 0xe4_u8, 0x1c_u8, 0x84_u8, 0x9b_u8, - 0x80_u8, 0xc8_u8, 0xd8_u8, 0x36_u8, 0x62_u8, 0xc0_u8, 0xe4_u8, 0x4a_u8, - 0x8b_u8, 0x29_u8, 0x1a_u8, 0x96_u8, 0x4c_u8, 0xf2_u8, 0xf0_u8, 0x70_u8, - 0x38_u8]); - - assert_eq!(super::pbkdf2_hmac_sha1(b"pass\x00word", b"sa\x00lt", 4096, 16).unwrap(), - vec![0x56_u8, 0xfa_u8, 0x6a_u8, 0xa7_u8, 0x55_u8, 0x48_u8, 0x09_u8, 0x9d_u8, - 0xcc_u8, 0x37_u8, 0xd7_u8, 0xf0_u8, 0x34_u8, 0x25_u8, 0xe0_u8, 0xc3_u8]); - } - // Test vectors from // https://git.lysator.liu.se/nettle/nettle/blob/nettle_3.1.1_release_20150424/testsuite/pbkdf2-test.c #[test] - fn test_pbkdf2_hmac_sha256() { - assert_eq!(super::pbkdf2_hmac(b"passwd", b"salt", 1, MessageDigest::sha256(), 16).unwrap(), - vec![0x55_u8, 0xac_u8, 0x04_u8, 0x6e_u8, 0x56_u8, 0xe3_u8, 0x08_u8, 0x9f_u8, - 0xec_u8, 0x16_u8, 0x91_u8, 0xc2_u8, 0x25_u8, 0x44_u8, 0xb6_u8, 0x05_u8]); - - assert_eq!(super::pbkdf2_hmac(b"Password", b"NaCl", 80000, MessageDigest::sha256(), 16).unwrap(), - vec![0x4d_u8, 0xdc_u8, 0xd8_u8, 0xf6_u8, 0x0b_u8, 0x98_u8, 0xbe_u8, 0x21_u8, - 0x83_u8, 0x0c_u8, 0xee_u8, 0x5e_u8, 0xf2_u8, 0x27_u8, 0x01_u8, 0xf9_u8]); + fn pbkdf2_hmac_sha256() { + let mut buf = [0; 16]; + + super::pbkdf2_hmac(b"passwd", b"salt", 1, MessageDigest::sha256(), &mut buf).unwrap(); + assert_eq!(buf, + &[0x55_u8, 0xac_u8, 0x04_u8, 0x6e_u8, 0x56_u8, 0xe3_u8, 0x08_u8, 0x9f_u8, + 0xec_u8, 0x16_u8, 0x91_u8, 0xc2_u8, 0x25_u8, 0x44_u8, 0xb6_u8, 0x05_u8][..]); + + super::pbkdf2_hmac(b"Password", b"NaCl", 80000, MessageDigest::sha256(), &mut buf).unwrap(); + assert_eq!(buf, + &[0x4d_u8, 0xdc_u8, 0xd8_u8, 0xf6_u8, 0x0b_u8, 0x98_u8, 0xbe_u8, 0x21_u8, + 0x83_u8, 0x0c_u8, 0xee_u8, 0x5e_u8, 0xf2_u8, 0x27_u8, 0x01_u8, 0xf9_u8][..]); } // Test vectors from // https://git.lysator.liu.se/nettle/nettle/blob/nettle_3.1.1_release_20150424/testsuite/pbkdf2-test.c #[test] - fn test_pbkdf2_hmac_sha512() { - assert_eq!(super::pbkdf2_hmac(b"password", b"NaCL", 1, MessageDigest::sha512(), 64).unwrap(), - vec![0x73_u8, 0xde_u8, 0xcf_u8, 0xa5_u8, 0x8a_u8, 0xa2_u8, 0xe8_u8, 0x4f_u8, - 0x94_u8, 0x77_u8, 0x1a_u8, 0x75_u8, 0x73_u8, 0x6b_u8, 0xb8_u8, 0x8b_u8, - 0xd3_u8, 0xc7_u8, 0xb3_u8, 0x82_u8, 0x70_u8, 0xcf_u8, 0xb5_u8, 0x0c_u8, - 0xb3_u8, 0x90_u8, 0xed_u8, 0x78_u8, 0xb3_u8, 0x05_u8, 0x65_u8, 0x6a_u8, - 0xf8_u8, 0x14_u8, 0x8e_u8, 0x52_u8, 0x45_u8, 0x2b_u8, 0x22_u8, 0x16_u8, - 0xb2_u8, 0xb8_u8, 0x09_u8, 0x8b_u8, 0x76_u8, 0x1f_u8, 0xc6_u8, 0x33_u8, - 0x60_u8, 0x60_u8, 0xa0_u8, 0x9f_u8, 0x76_u8, 0x41_u8, 0x5e_u8, 0x9f_u8, - 0x71_u8, 0xea_u8, 0x47_u8, 0xf9_u8, 0xe9_u8, 0x06_u8, 0x43_u8, 0x06_u8]); - - assert_eq!(super::pbkdf2_hmac(b"pass\0word", b"sa\0lt", 1, MessageDigest::sha512(), 64).unwrap(), - vec![0x71_u8, 0xa0_u8, 0xec_u8, 0x84_u8, 0x2a_u8, 0xbd_u8, 0x5c_u8, 0x67_u8, - 0x8b_u8, 0xcf_u8, 0xd1_u8, 0x45_u8, 0xf0_u8, 0x9d_u8, 0x83_u8, 0x52_u8, - 0x2f_u8, 0x93_u8, 0x36_u8, 0x15_u8, 0x60_u8, 0x56_u8, 0x3c_u8, 0x4d_u8, - 0x0d_u8, 0x63_u8, 0xb8_u8, 0x83_u8, 0x29_u8, 0x87_u8, 0x10_u8, 0x90_u8, - 0xe7_u8, 0x66_u8, 0x04_u8, 0xa4_u8, 0x9a_u8, 0xf0_u8, 0x8f_u8, 0xe7_u8, - 0xc9_u8, 0xf5_u8, 0x71_u8, 0x56_u8, 0xc8_u8, 0x79_u8, 0x09_u8, 0x96_u8, - 0xb2_u8, 0x0f_u8, 0x06_u8, 0xbc_u8, 0x53_u8, 0x5e_u8, 0x5a_u8, 0xb5_u8, - 0x44_u8, 0x0d_u8, 0xf7_u8, 0xe8_u8, 0x78_u8, 0x29_u8, 0x6f_u8, 0xa7_u8]); - - assert_eq!(super::pbkdf2_hmac(b"passwordPASSWORDpassword", - b"salt\0\0\0", - 50, - MessageDigest::sha512(), - 64).unwrap(), - vec![0x01_u8, 0x68_u8, 0x71_u8, 0xa4_u8, 0xc4_u8, 0xb7_u8, 0x5f_u8, 0x96_u8, - 0x85_u8, 0x7f_u8, 0xd2_u8, 0xb9_u8, 0xf8_u8, 0xca_u8, 0x28_u8, 0x02_u8, - 0x3b_u8, 0x30_u8, 0xee_u8, 0x2a_u8, 0x39_u8, 0xf5_u8, 0xad_u8, 0xca_u8, - 0xc8_u8, 0xc9_u8, 0x37_u8, 0x5f_u8, 0x9b_u8, 0xda_u8, 0x1c_u8, 0xcd_u8, - 0x1b_u8, 0x6f_u8, 0x0b_u8, 0x2f_u8, 0xc3_u8, 0xad_u8, 0xda_u8, 0x50_u8, - 0x54_u8, 0x12_u8, 0xe7_u8, 0x9d_u8, 0x89_u8, 0x00_u8, 0x56_u8, 0xc6_u8, - 0x2e_u8, 0x52_u8, 0x4c_u8, 0x7d_u8, 0x51_u8, 0x15_u8, 0x4b_u8, 0x1a_u8, - 0x85_u8, 0x34_u8, 0x57_u8, 0x5b_u8, 0xd0_u8, 0x2d_u8, 0xee_u8, 0x39_u8]); + fn pbkdf2_hmac_sha512() { + let mut buf = [0; 64]; + + super::pbkdf2_hmac(b"password", b"NaCL", 1, MessageDigest::sha512(), &mut buf).unwrap(); + assert_eq!(&buf[..], + &[0x73_u8, 0xde_u8, 0xcf_u8, 0xa5_u8, 0x8a_u8, 0xa2_u8, 0xe8_u8, 0x4f_u8, + 0x94_u8, 0x77_u8, 0x1a_u8, 0x75_u8, 0x73_u8, 0x6b_u8, 0xb8_u8, 0x8b_u8, + 0xd3_u8, 0xc7_u8, 0xb3_u8, 0x82_u8, 0x70_u8, 0xcf_u8, 0xb5_u8, 0x0c_u8, + 0xb3_u8, 0x90_u8, 0xed_u8, 0x78_u8, 0xb3_u8, 0x05_u8, 0x65_u8, 0x6a_u8, + 0xf8_u8, 0x14_u8, 0x8e_u8, 0x52_u8, 0x45_u8, 0x2b_u8, 0x22_u8, 0x16_u8, + 0xb2_u8, 0xb8_u8, 0x09_u8, 0x8b_u8, 0x76_u8, 0x1f_u8, 0xc6_u8, 0x33_u8, + 0x60_u8, 0x60_u8, 0xa0_u8, 0x9f_u8, 0x76_u8, 0x41_u8, 0x5e_u8, 0x9f_u8, + 0x71_u8, 0xea_u8, 0x47_u8, 0xf9_u8, 0xe9_u8, 0x06_u8, 0x43_u8, 0x06_u8][..]); + + super::pbkdf2_hmac(b"pass\0word", b"sa\0lt", 1, MessageDigest::sha512(), &mut buf).unwrap(); + assert_eq!(&buf[..], + &[0x71_u8, 0xa0_u8, 0xec_u8, 0x84_u8, 0x2a_u8, 0xbd_u8, 0x5c_u8, 0x67_u8, + 0x8b_u8, 0xcf_u8, 0xd1_u8, 0x45_u8, 0xf0_u8, 0x9d_u8, 0x83_u8, 0x52_u8, + 0x2f_u8, 0x93_u8, 0x36_u8, 0x15_u8, 0x60_u8, 0x56_u8, 0x3c_u8, 0x4d_u8, + 0x0d_u8, 0x63_u8, 0xb8_u8, 0x83_u8, 0x29_u8, 0x87_u8, 0x10_u8, 0x90_u8, + 0xe7_u8, 0x66_u8, 0x04_u8, 0xa4_u8, 0x9a_u8, 0xf0_u8, 0x8f_u8, 0xe7_u8, + 0xc9_u8, 0xf5_u8, 0x71_u8, 0x56_u8, 0xc8_u8, 0x79_u8, 0x09_u8, 0x96_u8, + 0xb2_u8, 0x0f_u8, 0x06_u8, 0xbc_u8, 0x53_u8, 0x5e_u8, 0x5a_u8, 0xb5_u8, + 0x44_u8, 0x0d_u8, 0xf7_u8, 0xe8_u8, 0x78_u8, 0x29_u8, 0x6f_u8, 0xa7_u8][..]); + + super::pbkdf2_hmac(b"passwordPASSWORDpassword", + b"salt\0\0\0", + 50, + MessageDigest::sha512(), + &mut buf).unwrap(); + assert_eq!(&buf[..], + &[0x01_u8, 0x68_u8, 0x71_u8, 0xa4_u8, 0xc4_u8, 0xb7_u8, 0x5f_u8, 0x96_u8, + 0x85_u8, 0x7f_u8, 0xd2_u8, 0xb9_u8, 0xf8_u8, 0xca_u8, 0x28_u8, 0x02_u8, + 0x3b_u8, 0x30_u8, 0xee_u8, 0x2a_u8, 0x39_u8, 0xf5_u8, 0xad_u8, 0xca_u8, + 0xc8_u8, 0xc9_u8, 0x37_u8, 0x5f_u8, 0x9b_u8, 0xda_u8, 0x1c_u8, 0xcd_u8, + 0x1b_u8, 0x6f_u8, 0x0b_u8, 0x2f_u8, 0xc3_u8, 0xad_u8, 0xda_u8, 0x50_u8, + 0x54_u8, 0x12_u8, 0xe7_u8, 0x9d_u8, 0x89_u8, 0x00_u8, 0x56_u8, 0xc6_u8, + 0x2e_u8, 0x52_u8, 0x4c_u8, 0x7d_u8, 0x51_u8, 0x15_u8, 0x4b_u8, 0x1a_u8, + 0x85_u8, 0x34_u8, 0x57_u8, 0x5b_u8, 0xd0_u8, 0x2d_u8, 0xee_u8, 0x39_u8][..]); } #[test] - fn test_evp_bytes_to_key_pbkdf1_compatible() { + fn bytes_to_key() { 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, @@ -224,18 +177,16 @@ mod tests { 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(Cipher::aes_256_cbc(), - MessageDigest::sha1(), - &data, - Some(&salt), - 1).unwrap(), + 69_u8, 98_u8, 107_u8, 208_u8, 14_u8, 236_u8, 60_u8]; + + assert_eq!(super::bytes_to_key(Cipher::aes_256_cbc(), + MessageDigest::sha1(), + &data, + Some(&salt), + 1).unwrap(), super::KeyIvPair { key: expected_key, - iv: expected_iv, + iv: Some(expected_iv), }); } } -- cgit v1.2.3 From 98b7f2f9352e4d92b44245d0737f9a45adb4ae2b Mon Sep 17 00:00:00 2001 From: Steven Fackler Date: Sat, 22 Oct 2016 09:16:38 -0700 Subject: Flatten crypto module --- openssl/src/crypto/pkcs5.rs | 192 -------------------------------------------- 1 file changed, 192 deletions(-) delete mode 100644 openssl/src/crypto/pkcs5.rs (limited to 'openssl/src/crypto/pkcs5.rs') diff --git a/openssl/src/crypto/pkcs5.rs b/openssl/src/crypto/pkcs5.rs deleted file mode 100644 index 8bcb9b31..00000000 --- a/openssl/src/crypto/pkcs5.rs +++ /dev/null @@ -1,192 +0,0 @@ -use libc::c_int; -use std::ptr; -use ffi; - -use cvt; -use crypto::hash::MessageDigest; -use crypto::symm::Cipher; -use error::ErrorStack; - -#[derive(Clone, Eq, PartialEq, Hash, Debug)] -pub struct KeyIvPair { - pub key: Vec, - pub iv: Option>, -} - -/// 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 -/// `pkcs5_pbkdf2_hmac_sha1` or another more modern key derivation algorithm. -pub fn bytes_to_key(cipher: Cipher, - digest: MessageDigest, - data: &[u8], - salt: Option<&[u8]>, - count: i32) - -> Result { - unsafe { - assert!(data.len() <= c_int::max_value() as usize); - let salt_ptr = match salt { - Some(salt) => { - assert_eq!(salt.len(), ffi::PKCS5_SALT_LEN as usize); - salt.as_ptr() - } - None => ptr::null(), - }; - - ffi::init(); - - let mut iv = cipher.iv_len().map(|l| vec![0; l]); - - let cipher = cipher.as_ptr(); - let digest = digest.as_ptr(); - - let len = try!(cvt(ffi::EVP_BytesToKey(cipher, - digest, - salt_ptr, - ptr::null(), - data.len() as c_int, - count.into(), - ptr::null_mut(), - ptr::null_mut()))); - - let mut key = vec![0; len as usize]; - let iv_ptr = iv.as_mut().map(|v| v.as_mut_ptr()).unwrap_or(ptr::null_mut()); - - try!(cvt(ffi::EVP_BytesToKey(cipher, - digest, - salt_ptr, - data.as_ptr(), - data.len() as c_int, - count as c_int, - key.as_mut_ptr(), - iv_ptr))); - - Ok(KeyIvPair { key: key, iv: iv }) - } -} - -/// Derives a key from a password and salt using the PBKDF2-HMAC algorithm with a digest function. -pub fn pbkdf2_hmac(pass: &[u8], - salt: &[u8], - iter: usize, - hash: MessageDigest, - key: &mut [u8]) - -> Result<(), ErrorStack> { - unsafe { - assert!(pass.len() <= c_int::max_value() as usize); - assert!(salt.len() <= c_int::max_value() as usize); - assert!(key.len() <= c_int::max_value() as usize); - - ffi::init(); - cvt(ffi::PKCS5_PBKDF2_HMAC(pass.as_ptr() as *const _, - pass.len() as c_int, - salt.as_ptr(), - salt.len() as c_int, - iter as c_int, - hash.as_ptr(), - key.len() as c_int, - key.as_mut_ptr())) - .map(|_| ()) - } -} - -#[cfg(test)] -mod tests { - use crypto::hash::MessageDigest; - use crypto::symm::Cipher; - - // Test vectors from - // https://git.lysator.liu.se/nettle/nettle/blob/nettle_3.1.1_release_20150424/testsuite/pbkdf2-test.c - #[test] - fn pbkdf2_hmac_sha256() { - let mut buf = [0; 16]; - - super::pbkdf2_hmac(b"passwd", b"salt", 1, MessageDigest::sha256(), &mut buf).unwrap(); - assert_eq!(buf, - &[0x55_u8, 0xac_u8, 0x04_u8, 0x6e_u8, 0x56_u8, 0xe3_u8, 0x08_u8, 0x9f_u8, - 0xec_u8, 0x16_u8, 0x91_u8, 0xc2_u8, 0x25_u8, 0x44_u8, 0xb6_u8, 0x05_u8][..]); - - super::pbkdf2_hmac(b"Password", b"NaCl", 80000, MessageDigest::sha256(), &mut buf).unwrap(); - assert_eq!(buf, - &[0x4d_u8, 0xdc_u8, 0xd8_u8, 0xf6_u8, 0x0b_u8, 0x98_u8, 0xbe_u8, 0x21_u8, - 0x83_u8, 0x0c_u8, 0xee_u8, 0x5e_u8, 0xf2_u8, 0x27_u8, 0x01_u8, 0xf9_u8][..]); - } - - // Test vectors from - // https://git.lysator.liu.se/nettle/nettle/blob/nettle_3.1.1_release_20150424/testsuite/pbkdf2-test.c - #[test] - fn pbkdf2_hmac_sha512() { - let mut buf = [0; 64]; - - super::pbkdf2_hmac(b"password", b"NaCL", 1, MessageDigest::sha512(), &mut buf).unwrap(); - assert_eq!(&buf[..], - &[0x73_u8, 0xde_u8, 0xcf_u8, 0xa5_u8, 0x8a_u8, 0xa2_u8, 0xe8_u8, 0x4f_u8, - 0x94_u8, 0x77_u8, 0x1a_u8, 0x75_u8, 0x73_u8, 0x6b_u8, 0xb8_u8, 0x8b_u8, - 0xd3_u8, 0xc7_u8, 0xb3_u8, 0x82_u8, 0x70_u8, 0xcf_u8, 0xb5_u8, 0x0c_u8, - 0xb3_u8, 0x90_u8, 0xed_u8, 0x78_u8, 0xb3_u8, 0x05_u8, 0x65_u8, 0x6a_u8, - 0xf8_u8, 0x14_u8, 0x8e_u8, 0x52_u8, 0x45_u8, 0x2b_u8, 0x22_u8, 0x16_u8, - 0xb2_u8, 0xb8_u8, 0x09_u8, 0x8b_u8, 0x76_u8, 0x1f_u8, 0xc6_u8, 0x33_u8, - 0x60_u8, 0x60_u8, 0xa0_u8, 0x9f_u8, 0x76_u8, 0x41_u8, 0x5e_u8, 0x9f_u8, - 0x71_u8, 0xea_u8, 0x47_u8, 0xf9_u8, 0xe9_u8, 0x06_u8, 0x43_u8, 0x06_u8][..]); - - super::pbkdf2_hmac(b"pass\0word", b"sa\0lt", 1, MessageDigest::sha512(), &mut buf).unwrap(); - assert_eq!(&buf[..], - &[0x71_u8, 0xa0_u8, 0xec_u8, 0x84_u8, 0x2a_u8, 0xbd_u8, 0x5c_u8, 0x67_u8, - 0x8b_u8, 0xcf_u8, 0xd1_u8, 0x45_u8, 0xf0_u8, 0x9d_u8, 0x83_u8, 0x52_u8, - 0x2f_u8, 0x93_u8, 0x36_u8, 0x15_u8, 0x60_u8, 0x56_u8, 0x3c_u8, 0x4d_u8, - 0x0d_u8, 0x63_u8, 0xb8_u8, 0x83_u8, 0x29_u8, 0x87_u8, 0x10_u8, 0x90_u8, - 0xe7_u8, 0x66_u8, 0x04_u8, 0xa4_u8, 0x9a_u8, 0xf0_u8, 0x8f_u8, 0xe7_u8, - 0xc9_u8, 0xf5_u8, 0x71_u8, 0x56_u8, 0xc8_u8, 0x79_u8, 0x09_u8, 0x96_u8, - 0xb2_u8, 0x0f_u8, 0x06_u8, 0xbc_u8, 0x53_u8, 0x5e_u8, 0x5a_u8, 0xb5_u8, - 0x44_u8, 0x0d_u8, 0xf7_u8, 0xe8_u8, 0x78_u8, 0x29_u8, 0x6f_u8, 0xa7_u8][..]); - - super::pbkdf2_hmac(b"passwordPASSWORDpassword", - b"salt\0\0\0", - 50, - MessageDigest::sha512(), - &mut buf).unwrap(); - assert_eq!(&buf[..], - &[0x01_u8, 0x68_u8, 0x71_u8, 0xa4_u8, 0xc4_u8, 0xb7_u8, 0x5f_u8, 0x96_u8, - 0x85_u8, 0x7f_u8, 0xd2_u8, 0xb9_u8, 0xf8_u8, 0xca_u8, 0x28_u8, 0x02_u8, - 0x3b_u8, 0x30_u8, 0xee_u8, 0x2a_u8, 0x39_u8, 0xf5_u8, 0xad_u8, 0xca_u8, - 0xc8_u8, 0xc9_u8, 0x37_u8, 0x5f_u8, 0x9b_u8, 0xda_u8, 0x1c_u8, 0xcd_u8, - 0x1b_u8, 0x6f_u8, 0x0b_u8, 0x2f_u8, 0xc3_u8, 0xad_u8, 0xda_u8, 0x50_u8, - 0x54_u8, 0x12_u8, 0xe7_u8, 0x9d_u8, 0x89_u8, 0x00_u8, 0x56_u8, 0xc6_u8, - 0x2e_u8, 0x52_u8, 0x4c_u8, 0x7d_u8, 0x51_u8, 0x15_u8, 0x4b_u8, 0x1a_u8, - 0x85_u8, 0x34_u8, 0x57_u8, 0x5b_u8, 0xd0_u8, 0x2d_u8, 0xee_u8, 0x39_u8][..]); - } - #[test] - fn bytes_to_key() { - 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]; - - assert_eq!(super::bytes_to_key(Cipher::aes_256_cbc(), - MessageDigest::sha1(), - &data, - Some(&salt), - 1).unwrap(), - super::KeyIvPair { - key: expected_key, - iv: Some(expected_iv), - }); - } -} -- cgit v1.2.3