argon2/
config.rs

1// Copyright (c) 2017 Martijn Rijkeboer <[email protected]>
2//
3// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
4// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
5// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
6// option. This file may not be copied, modified, or distributed
7// except according to those terms.
8
9use crate::thread_mode::ThreadMode;
10use crate::variant::Variant;
11use crate::version::Version;
12
13/// Structure containing configuration settings.
14///
15/// # Examples
16///
17/// ```
18/// use argon2::{Config, ThreadMode, Variant, Version};
19///
20/// let config = Config::default();
21/// assert_eq!(config.ad, &[]);
22/// assert_eq!(config.hash_length, 32);
23/// assert_eq!(config.lanes, 1);
24/// assert_eq!(config.mem_cost, 19 * 1024);
25/// assert_eq!(config.secret, &[]);
26/// assert_eq!(config.time_cost, 2);
27/// assert_eq!(config.variant, Variant::Argon2id);
28/// assert_eq!(config.thread_mode, ThreadMode::Sequential);
29/// assert_eq!(config.version, Version::Version13);
30/// ```
31#[derive(Clone, Debug, PartialEq)]
32pub struct Config<'a> {
33    /// The associated data.
34    pub ad: &'a [u8],
35
36    /// The length of the resulting hash.
37    pub hash_length: u32,
38
39    /// The number of lanes.
40    pub lanes: u32,
41
42    /// The amount of memory requested (KB).
43    pub mem_cost: u32,
44
45    /// The key.
46    pub secret: &'a [u8],
47
48    /// The thread mode.
49    pub thread_mode: ThreadMode,
50
51    /// The number of passes.
52    pub time_cost: u32,
53
54    /// The variant.
55    pub variant: Variant,
56
57    /// The version number.
58    pub version: Version,
59}
60
61impl<'a> Config<'a> {
62    /// Default configuration used by the original C implementation.
63    pub fn original() -> Config<'a> {
64        Config {
65            ad: &[],
66            hash_length: 32,
67            lanes: 1,
68            mem_cost: 4096,
69            secret: &[],
70            thread_mode: ThreadMode::default(),
71            time_cost: 3,
72            variant: Variant::Argon2i,
73            version: Version::Version13,
74        }
75    }
76
77    /// OWASP recommended configuration with t=1 and 46 MiB memory.
78    pub fn owasp1() -> Config<'a> {
79        Config {
80            ad: &[],
81            hash_length: 32,
82            lanes: 1,
83            mem_cost: 47104,
84            secret: &[],
85            thread_mode: ThreadMode::default(),
86            time_cost: 1,
87            variant: Variant::Argon2id,
88            version: Version::Version13,
89        }
90    }
91
92    /// OWASP recommended configuration with t=2 and 19 MiB memory.
93    pub fn owasp2() -> Config<'a> {
94        Config {
95            ad: &[],
96            hash_length: 32,
97            lanes: 1,
98            mem_cost: 19456,
99            secret: &[],
100            thread_mode: ThreadMode::default(),
101            time_cost: 2,
102            variant: Variant::Argon2id,
103            version: Version::Version13,
104        }
105    }
106
107    /// OWASP recommended configuration with t=3 and 12 MiB memory.
108    pub fn owasp3() -> Config<'a> {
109        Config {
110            ad: &[],
111            hash_length: 32,
112            lanes: 1,
113            mem_cost: 12288,
114            secret: &[],
115            thread_mode: ThreadMode::default(),
116            time_cost: 3,
117            variant: Variant::Argon2id,
118            version: Version::Version13,
119        }
120    }
121
122    /// OWASP recommended configuration with t=4 and 9 MiB memory.
123    pub fn owasp4() -> Config<'a> {
124        Config {
125            ad: &[],
126            hash_length: 32,
127            lanes: 1,
128            mem_cost: 9216,
129            secret: &[],
130            thread_mode: ThreadMode::default(),
131            time_cost: 4,
132            variant: Variant::Argon2id,
133            version: Version::Version13,
134        }
135    }
136
137    /// OWASP recommended configuration with t=5 and 7 MiB memory.
138    pub fn owasp5() -> Config<'a> {
139        Config {
140            ad: &[],
141            hash_length: 32,
142            lanes: 1,
143            mem_cost: 7168,
144            secret: &[],
145            thread_mode: ThreadMode::default(),
146            time_cost: 5,
147            variant: Variant::Argon2id,
148            version: Version::Version13,
149        }
150    }
151
152    /// RFC9106 recommended configuration with t=1 and 2 GiB memory.
153    pub fn rfc9106() -> Config<'a> {
154        Config {
155            ad: &[],
156            hash_length: 32,
157            lanes: 1,
158            mem_cost: 2097152,
159            secret: &[],
160            thread_mode: ThreadMode::default(),
161            time_cost: 1,
162            variant: Variant::Argon2id,
163            version: Version::Version13,
164        }
165    }
166
167    /// RFC9106 recommended configuration for memory-constrained environments.
168    pub fn rfc9106_low_mem() -> Config<'a> {
169        Config {
170            ad: &[],
171            hash_length: 32,
172            lanes: 1,
173            mem_cost: 65536,
174            secret: &[],
175            thread_mode: ThreadMode::default(),
176            time_cost: 3,
177            variant: Variant::Argon2id,
178            version: Version::Version13,
179        }
180    }
181
182    pub fn uses_sequential(&self) -> bool {
183        self.thread_mode == ThreadMode::Sequential || self.lanes == 1
184    }
185}
186
187impl<'a> Default for Config<'a> {
188    /// OWASP recommended configuration with t=2 and 19 MiB memory.
189    fn default() -> Config<'a> {
190        Config::owasp2()
191    }
192}
193
194#[cfg(test)]
195mod tests {
196
197    use crate::config::Config;
198    use crate::thread_mode::ThreadMode;
199    use crate::variant::Variant;
200    use crate::version::Version;
201
202    #[test]
203    fn default_returns_correct_instance() {
204        let config = Config::default();
205        assert_eq!(config.ad, &[]);
206        assert_eq!(config.hash_length, 32);
207        assert_eq!(config.lanes, 1);
208        assert_eq!(config.mem_cost, 19 * 1024);
209        assert_eq!(config.secret, &[]);
210        assert_eq!(config.thread_mode, ThreadMode::Sequential);
211        assert_eq!(config.time_cost, 2);
212        assert_eq!(config.variant, Variant::Argon2id);
213        assert_eq!(config.version, Version::Version13);
214    }
215
216    #[test]
217    fn original_returns_correct_instance() {
218        let config = Config::original();
219        assert_eq!(config.ad, &[]);
220        assert_eq!(config.hash_length, 32);
221        assert_eq!(config.lanes, 1);
222        assert_eq!(config.mem_cost, 4096);
223        assert_eq!(config.secret, &[]);
224        assert_eq!(config.thread_mode, ThreadMode::Sequential);
225        assert_eq!(config.time_cost, 3);
226        assert_eq!(config.variant, Variant::Argon2i);
227        assert_eq!(config.version, Version::Version13);
228    }
229
230    #[test]
231    fn owasp1_returns_correct_instance() {
232        let config = Config::owasp1();
233        assert_eq!(config.ad, &[]);
234        assert_eq!(config.hash_length, 32);
235        assert_eq!(config.lanes, 1);
236        assert_eq!(config.mem_cost, 46 * 1024);
237        assert_eq!(config.secret, &[]);
238        assert_eq!(config.thread_mode, ThreadMode::Sequential);
239        assert_eq!(config.time_cost, 1);
240        assert_eq!(config.variant, Variant::Argon2id);
241        assert_eq!(config.version, Version::Version13);
242    }
243
244    #[test]
245    fn owasp2_returns_correct_instance() {
246        let config = Config::owasp2();
247        assert_eq!(config.ad, &[]);
248        assert_eq!(config.hash_length, 32);
249        assert_eq!(config.lanes, 1);
250        assert_eq!(config.mem_cost, 19 * 1024);
251        assert_eq!(config.secret, &[]);
252        assert_eq!(config.thread_mode, ThreadMode::Sequential);
253        assert_eq!(config.time_cost, 2);
254        assert_eq!(config.variant, Variant::Argon2id);
255        assert_eq!(config.version, Version::Version13);
256    }
257
258    #[test]
259    fn owasp3_returns_correct_instance() {
260        let config = Config::owasp3();
261        assert_eq!(config.ad, &[]);
262        assert_eq!(config.hash_length, 32);
263        assert_eq!(config.lanes, 1);
264        assert_eq!(config.mem_cost, 12 * 1024);
265        assert_eq!(config.secret, &[]);
266        assert_eq!(config.thread_mode, ThreadMode::Sequential);
267        assert_eq!(config.time_cost, 3);
268        assert_eq!(config.variant, Variant::Argon2id);
269        assert_eq!(config.version, Version::Version13);
270    }
271
272    #[test]
273    fn owasp4_returns_correct_instance() {
274        let config = Config::owasp4();
275        assert_eq!(config.ad, &[]);
276        assert_eq!(config.hash_length, 32);
277        assert_eq!(config.lanes, 1);
278        assert_eq!(config.mem_cost, 9 * 1024);
279        assert_eq!(config.secret, &[]);
280        assert_eq!(config.thread_mode, ThreadMode::Sequential);
281        assert_eq!(config.time_cost, 4);
282        assert_eq!(config.variant, Variant::Argon2id);
283        assert_eq!(config.version, Version::Version13);
284    }
285
286    #[test]
287    fn owasp5_returns_correct_instance() {
288        let config = Config::owasp5();
289        assert_eq!(config.ad, &[]);
290        assert_eq!(config.hash_length, 32);
291        assert_eq!(config.lanes, 1);
292        assert_eq!(config.mem_cost, 7 * 1024);
293        assert_eq!(config.secret, &[]);
294        assert_eq!(config.thread_mode, ThreadMode::Sequential);
295        assert_eq!(config.time_cost, 5);
296        assert_eq!(config.variant, Variant::Argon2id);
297        assert_eq!(config.version, Version::Version13);
298    }
299
300    #[test]
301    fn rfc9106_returns_correct_instance() {
302        let config = Config::rfc9106();
303        assert_eq!(config.ad, &[]);
304        assert_eq!(config.hash_length, 32);
305        assert_eq!(config.lanes, 1);
306        assert_eq!(config.mem_cost, 2 * 1024 * 1024);
307        assert_eq!(config.secret, &[]);
308        assert_eq!(config.thread_mode, ThreadMode::Sequential);
309        assert_eq!(config.time_cost, 1);
310        assert_eq!(config.variant, Variant::Argon2id);
311        assert_eq!(config.version, Version::Version13);
312    }
313
314    #[test]
315    fn rfc9106_low_mem_returns_correct_instance() {
316        let config = Config::rfc9106_low_mem();
317        assert_eq!(config.ad, &[]);
318        assert_eq!(config.hash_length, 32);
319        assert_eq!(config.lanes, 1);
320        assert_eq!(config.mem_cost, 64 * 1024);
321        assert_eq!(config.secret, &[]);
322        assert_eq!(config.thread_mode, ThreadMode::Sequential);
323        assert_eq!(config.time_cost, 3);
324        assert_eq!(config.variant, Variant::Argon2id);
325        assert_eq!(config.version, Version::Version13);
326    }
327}