1 extern crate commoncrypto_sys;
2 extern crate hex;
3 
4 use hex::{ToHex, FromHex};
5 
6 // These password, salts, rounds and derived key values come from the test
7 // vectors stated in RFC 6070
8 const PASSWORD: &'static str = "password";
9 const SALT: &'static str = "salt";
10 
11 const DERIVED1: &'static str = "0c60c80f961f0e71f3a9b524af6012062fe037a6";
12 const DERIVED4096: &'static str = "4b007901b765489abead49d926f721d065a429c1";
13 
14 macro_rules! test_pbkdf2 {
15     (
16         $test_name: ident,
17         $prf_algorithm: ident,
18         $pw: ident,
19         $salt: ident,
20         $rounds: expr,
21         $expected_dkey: ident
22     ) => {
23         #[test]
24         fn $test_name() {
25             let derived_len = Vec::<u8>::from_hex($expected_dkey).expect("dkey from hex").len();
26             let mut pw_derived = vec![0u8; derived_len];
27             unsafe {
28                 assert_eq!(0, commoncrypto_sys::CCKeyDerivationPBKDF(
29                     commoncrypto_sys::CCPBKDFAlgorithm::kCCPBKDF2,
30                     $pw.as_ptr(), $pw.len(),
31                     $salt.as_ptr(), $salt.len(),
32                     commoncrypto_sys::CCPseudoRandomAlgorithm::$prf_algorithm,
33                     $rounds,
34                     pw_derived.as_mut_ptr(), pw_derived.len()
35                 ));
36             }
37             assert_eq!($expected_dkey, pw_derived.to_hex());
38         }
39     }
40 }
41 
42 test_pbkdf2!(pbkdf2_1, kCCPRFHmacAlgSHA1, PASSWORD, SALT, 1, DERIVED1);
43 test_pbkdf2!(pbkdf2_4096,
44              kCCPRFHmacAlgSHA1,
45              PASSWORD,
46              SALT,
47              4096,
48              DERIVED4096);
49