rc_crypto/
pbkdf2.rs
1use crate::error::*;
6use nss::pbkdf2::pbkdf2_key_derive;
7pub use nss::pbkdf2::HashAlgorithm;
8pub fn derive(
36 passphrase: &[u8],
37 salt: &[u8],
38 iterations: u32,
39 hash_algorithm: HashAlgorithm,
40 out: &mut [u8],
41) -> Result<()> {
42 pbkdf2_key_derive(passphrase, salt, iterations, hash_algorithm, out)?;
43 Ok(())
44}
45
46#[cfg(test)]
47mod tests {
48 use super::*;
49 use nss::ensure_initialized;
50
51 #[test]
52 fn test_generate_correct_out() {
53 ensure_initialized();
54 let expected = "120fb6cffcf8b32c43e7225256c4f837a86548c92ccc35480805987cb70be17b";
55 let mut out = vec![0u8; 32];
56 let password = b"password";
57 let salt = b"salt";
58 derive(password, salt, 1, HashAlgorithm::SHA256, &mut out).unwrap();
59 assert_eq!(expected, hex::encode(out));
60 }
61
62 #[test]
63 fn test_longer_key() {
64 ensure_initialized();
65 let expected = "120fb6cffcf8b32c43e7225256c4f837a86548c92ccc35480805987cb70be17b4dbf3a2f3dad3377264bb7b8e8330d4efc7451418617dabef683735361cdc18c";
66 let password = b"password";
67 let salt = b"salt";
68 let mut out = vec![0u8; 64];
69 derive(password, salt, 1, HashAlgorithm::SHA256, &mut out).unwrap();
70 assert_eq!(expected, hex::encode(out));
71 }
72
73 #[test]
74 fn test_more_iterations() {
75 ensure_initialized();
76 let expected = "ae4d0c95af6b46d32d0adff928f06dd02a303f8ef3c251dfd6e2d85a95474c43";
77 let password = b"password";
78 let salt = b"salt";
79 let mut out = vec![0u8; 32];
80 derive(password, salt, 2, HashAlgorithm::SHA256, &mut out).unwrap();
81 assert_eq!(expected, hex::encode(out));
82 }
83
84 #[test]
85 fn test_odd_length() {
86 ensure_initialized();
87 let expected = "ad35240ac683febfaf3cd49d845473fbbbaa2437f5f82d5a415ae00ac76c6bfccf";
88 let password = b"password";
89 let salt = b"salt";
90 let mut out = vec![0u8; 33];
91 derive(password, salt, 3, HashAlgorithm::SHA256, &mut out).unwrap();
92 assert_eq!(expected, hex::encode(out));
93 }
94
95 #[test]
96 fn test_nulls() {
97 ensure_initialized();
98 let expected = "e25d526987819f966e324faa4a";
99 let password = b"passw\x00rd";
100 let salt = b"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00";
101 let mut out = vec![0u8; 13];
102 derive(password, salt, 5, HashAlgorithm::SHA256, &mut out).unwrap();
103 assert_eq!(expected, hex::encode(out));
104 }
105
106 #[test]
107 fn test_password_null() {
108 ensure_initialized();
109 let expected = "62384466264daadc4144018c6bd864648272b34da8980d31521ffcce92ae003b";
110 let password = b"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00";
111 let salt = b"salt";
112 let mut out = vec![0u8; 32];
113 derive(password, salt, 2, HashAlgorithm::SHA256, &mut out).unwrap();
114 assert_eq!(expected, hex::encode(out));
115 }
116
117 #[test]
118 fn test_empty_password() {
119 ensure_initialized();
120 let expected = "f135c27993baf98773c5cdb40a5706ce6a345cde61b000a67858650cd6a324d7";
121 let mut out = vec![0u8; 32];
122 let password = b"";
123 let salt = b"salt";
124 derive(password, salt, 1, HashAlgorithm::SHA256, &mut out).unwrap();
125 assert_eq!(expected, hex::encode(out));
126 }
127
128 #[test]
129 fn test_empty_salt() {
130 ensure_initialized();
131 let expected = "c1232f10f62715fda06ae7c0a2037ca19b33cf103b727ba56d870c11f290a2ab";
132 let mut out = vec![0u8; 32];
133 let password = b"password";
134 let salt = b"";
135 derive(password, salt, 1, HashAlgorithm::SHA256, &mut out).unwrap();
136 assert_eq!(expected, hex::encode(out));
137 }
138
139 #[test]
140 fn test_tiny_out() {
141 ensure_initialized();
142 let expected = "12";
143 let mut out = vec![0u8; 1];
144 let password = b"password";
145 let salt = b"salt";
146 derive(password, salt, 1, HashAlgorithm::SHA256, &mut out).unwrap();
147 assert_eq!(expected, hex::encode(out));
148 }
149
150 #[test]
151 fn test_rejects_zero_iterations() {
152 ensure_initialized();
153 let mut out = vec![0u8; 32];
154 let password = b"password";
155 let salt = b"salt";
156 assert!(derive(password, salt, 0, HashAlgorithm::SHA256, &mut out).is_err());
157 }
158
159 #[test]
160 fn test_rejects_empty_out() {
161 ensure_initialized();
162 let mut out = vec![0u8; 0];
163 let password = b"password";
164 let salt = b"salt";
165 assert!(derive(password, salt, 1, HashAlgorithm::SHA256, &mut out).is_err());
166 }
167
168 #[test]
169 fn test_rejects_gaigantic_salt() {
170 ensure_initialized();
171 if (u32::MAX as usize) < usize::MAX {
172 let salt = vec![0; (u32::MAX as usize) + 1];
173 let mut out = vec![0u8; 1];
174 let password = b"password";
175 assert!(derive(password, &salt, 1, HashAlgorithm::SHA256, &mut out).is_err());
176 }
177 }
178 #[test]
179 fn test_rejects_gaigantic_password() {
180 ensure_initialized();
181 if (u32::MAX as usize) < usize::MAX {
182 let password = vec![0; (u32::MAX as usize) + 1];
183 let mut out = vec![0u8; 1];
184 let salt = b"salt";
185 assert!(derive(&password, salt, 1, HashAlgorithm::SHA256, &mut out).is_err());
186 }
187 }
188
189 #[test]
190 fn test_rejects_gaigantic_out() {
191 ensure_initialized();
192 if (u32::MAX as usize) < usize::MAX {
193 let password = b"password";
194 let mut out = vec![0; (u32::MAX as usize) + 1];
195 let salt = b"salt";
196 assert!(derive(password, salt, 1, HashAlgorithm::SHA256, &mut out).is_err());
197 }
198 }
199
200 #[test]
201 fn test_rejects_gaigantic_iterations() {
202 ensure_initialized();
203 let password = b"password";
204 let mut out = vec![0; 32];
205 let salt = b"salt";
206 assert!(derive(password, salt, u32::MAX, HashAlgorithm::SHA256, &mut out).is_err());
207 }
208}