argon2_sys/
lib.rs

1#![allow(non_upper_case_globals)]
2#![allow(non_camel_case_types)]
3
4/// Minimum number of lanes (degree of parallelism)
5pub const ARGON2_MIN_LANES: u64 = 1;
6/// Maximum number of lanes (degree of parallelism)
7pub const ARGON2_MAX_LANES: u64 = 0xFFFFFF;
8
9/// Minimum number of threads
10pub const ARGON2_MIN_THREADS: u64 = 1;
11/// Maximum number of threads
12pub const ARGON2_MAX_THREADS: u64 = 0xFFFFFF;
13
14/// Number of synchronization points between lanes per pass
15pub const ARGON2_SYNC_POINTS: u64 = 4;
16
17/// Minimum digest size in bytes
18pub const ARGON2_MIN_OUTLEN: u64 = 4;
19/// Maximum digest size in bytes
20pub const ARGON2_MAX_OUTLEN: u64 = 0xFFFFFF;
21
22/// Minimum number of memory blocks (each of BLOCK_SIZE bytes)
23pub const ARGON2_MIN_MEMORY: u64 = 2 * ARGON2_SYNC_POINTS;
24
25const ADDRESSING_SPACE: u64 = (std::mem::size_of::<usize>() * 8) as u64;
26
27const fn min(a: u64, b: u64) -> u64 {
28    if a < b {
29        a
30    } else {
31        b
32    }
33}
34
35const ARGON2_MAX_MEMORY_BITS: u64 = min(32, ADDRESSING_SPACE - 10 - 1);
36
37/// Maximum number of memory blocks (each of BLOCK_SIZE bytes)
38pub const ARGON2_MAX_MEMORY: u64 = min(0xFFFFFFFF, 1 << ARGON2_MAX_MEMORY_BITS);
39
40/// Minimum number of passes
41pub const ARGON2_MIN_TIME: u64 = 1;
42/// Maximum number of passes
43pub const ARGON2_MAX_TIME: u64 = 0xFFFFFFFF;
44
45/// Minimum password length in bytes
46pub const ARGON2_MIN_PWD_LENGTH: u64 = 0;
47/// Maximum password length in bytes
48pub const ARGON2_MAX_PWD_LENGTH: u64 = 0xFFFFFFFF;
49
50/// Minimum associated data length in bytes
51pub const ARGON2_MIN_AD_LENGTH: u64 = 0;
52/// Maximum associated data length in bytes
53pub const ARGON2_MAX_AD_LENGTH: u64 = 0xFFFFFFFF;
54
55/// Minimum salt length in bytes
56pub const ARGON2_MIN_SALT_LENGTH: u64 = 8;
57/// Maximum salt length in bytes
58pub const ARGON2_MAX_SALT_LENGTH: u64 = 0xFFFFFFFF;
59
60/// Minimum key length in bytes
61pub const ARGON2_MIN_SECRET: u64 = 0;
62/// Maximum key length in bytes
63pub const ARGON2_MAX_SECRET: u64 = 0xFFFFFFFF;
64
65/// Flags to determine which fields are securely wiped (default = no wipe).
66pub const ARGON2_DEFAULT_FLAGS: u32 = 0;
67pub const ARGON2_FLAG_CLEAR_PASSWORD: u32 = 1 << 0;
68pub const ARGON2_FLAG_CLEAR_SECRET: u32 = 1 << 1;
69
70pub type Argon2_ErrorCodes = libc::c_int;
71
72pub const ARGON2_OK: Argon2_ErrorCodes = 0;
73pub const ARGON2_OUTPUT_PTR_NULL: Argon2_ErrorCodes = -1;
74pub const ARGON2_OUTPUT_TOO_SHORT: Argon2_ErrorCodes = -2;
75pub const ARGON2_OUTPUT_TOO_LONG: Argon2_ErrorCodes = -3;
76pub const ARGON2_PWD_TOO_SHORT: Argon2_ErrorCodes = -4;
77pub const ARGON2_PWD_TOO_LONG: Argon2_ErrorCodes = -5;
78pub const ARGON2_SALT_TOO_SHORT: Argon2_ErrorCodes = -6;
79pub const ARGON2_SALT_TOO_LONG: Argon2_ErrorCodes = -7;
80pub const ARGON2_AD_TOO_SHORT: Argon2_ErrorCodes = -8;
81pub const ARGON2_AD_TOO_LONG: Argon2_ErrorCodes = -9;
82pub const ARGON2_SECRET_TOO_SHORT: Argon2_ErrorCodes = -10;
83pub const ARGON2_SECRET_TOO_LONG: Argon2_ErrorCodes = -11;
84pub const ARGON2_TIME_TOO_SMALL: Argon2_ErrorCodes = -12;
85pub const ARGON2_TIME_TOO_LARGE: Argon2_ErrorCodes = -13;
86pub const ARGON2_MEMORY_TOO_LITTLE: Argon2_ErrorCodes = -14;
87pub const ARGON2_MEMORY_TOO_MUCH: Argon2_ErrorCodes = -15;
88pub const ARGON2_LANES_TOO_FEW: Argon2_ErrorCodes = -16;
89pub const ARGON2_LANES_TOO_MANY: Argon2_ErrorCodes = -17;
90pub const ARGON2_PWD_PTR_MISMATCH: Argon2_ErrorCodes = -18;
91pub const ARGON2_SALT_PTR_MISMATCH: Argon2_ErrorCodes = -19;
92pub const ARGON2_SECRET_PTR_MISMATCH: Argon2_ErrorCodes = -20;
93pub const ARGON2_AD_PTR_MISMATCH: Argon2_ErrorCodes = -21;
94pub const ARGON2_MEMORY_ALLOCATION_ERROR: Argon2_ErrorCodes = -22;
95pub const ARGON2_FREE_MEMORY_CBK_NULL: Argon2_ErrorCodes = -23;
96pub const ARGON2_ALLOCATE_MEMORY_CBK_NULL: Argon2_ErrorCodes = -24;
97pub const ARGON2_INCORRECT_PARAMETER: Argon2_ErrorCodes = -25;
98pub const ARGON2_INCORRECT_TYPE: Argon2_ErrorCodes = -26;
99pub const ARGON2_OUT_PTR_MISMATCH: Argon2_ErrorCodes = -27;
100pub const ARGON2_THREADS_TOO_FEW: Argon2_ErrorCodes = -28;
101pub const ARGON2_THREADS_TOO_MANY: Argon2_ErrorCodes = -29;
102pub const ARGON2_MISSING_ARGS: Argon2_ErrorCodes = -30;
103pub const ARGON2_ENCODING_FAIL: Argon2_ErrorCodes = -31;
104pub const ARGON2_DECODING_FAIL: Argon2_ErrorCodes = -32;
105pub const ARGON2_THREAD_FAIL: Argon2_ErrorCodes = -33;
106pub const ARGON2_DECODING_LENGTH_FAIL: Argon2_ErrorCodes = -34;
107pub const ARGON2_VERIFY_MISMATCH: Argon2_ErrorCodes = -35;
108
109pub type allocate_fptr = ::std::option::Option<
110    unsafe extern "C" fn(memory: *mut *mut u8, bytes_to_allocate: libc::size_t) -> libc::c_int,
111>;
112
113pub type deallocate_fptr =
114    ::std::option::Option<unsafe extern "C" fn(memory: *mut u8, bytes_to_allocate: libc::size_t)>;
115
116
117 /// *****
118 /// 
119 /// Context: structure to hold Argon2 inputs:
120 /// - output array and its length,
121 /// - password and its length,
122 /// - salt and its length,
123 /// - secret and its length,
124 /// - associated data and its length,
125 /// - number of passes, amount of used memory (in KBytes, can be rounded up a bit)
126 /// - number of parallel threads that will be run.
127 /// 
128 /// All the parameters above affect the output hash value.
129 /// Additionally, two function pointers can be provided to allocate and
130 /// deallocate the memory (if NULL, memory will be allocated internally).
131 /// Also, three flags indicate whether to erase password, secret as soon as they
132 /// are pre-hashed (and thus not needed anymore), and the entire memory.
133 /// 
134 /// *****
135 /// 
136 /// Simplest situation: you have output array `out[8]`, password is stored in
137 /// `pwd[32]`, salt is stored in `salt[16]`, you do not have keys nor associated
138 /// data. You need to spend 1 GB of RAM and you run 5 passes of Argon2d with
139 /// 4 parallel lanes.
140 /// You want to erase the password, but you're OK with last pass not being
141 /// erased. You want to use the default memory allocator.
142 /// Then you initialize:
143 /// ```Argon2_Context(out,8,pwd,32,salt,16,NULL,0,NULL,0,5,1<<20,4,4,NULL,NULL,true,false,false,false)```
144#[repr(C)]
145#[derive(Debug, Copy, Clone)]
146pub struct Argon2_Context {
147    pub out: *mut u8,
148    pub outlen: u32,
149    pub pwd: *mut u8,
150    pub pwdlen: u32,
151    pub salt: *mut u8,
152    pub saltlen: u32,
153    pub secret: *mut u8,
154    pub secretlen: u32,
155    pub ad: *mut u8,
156    pub adlen: u32,
157    pub t_cost: u32,
158    pub m_cost: u32,
159    pub lanes: u32,
160    pub threads: u32,
161    pub version: u32,
162    pub allocate_cbk: allocate_fptr,
163    pub free_cbk: deallocate_fptr,
164    pub flags: u32,
165}
166
167pub type argon2_context = Argon2_Context;
168
169pub type Argon2_type = libc::c_uint;
170pub use Argon2_type as argon2_type;
171
172pub const Argon2_d: Argon2_type = 0;
173pub const Argon2_i: Argon2_type = 1;
174pub const Argon2_id: Argon2_type = 2;
175
176pub type Argon2_version = libc::c_uint;
177pub use Argon2_version as argon2_version;
178
179pub const ARGON2_VERSION_10: Argon2_version = 0x10;
180pub const ARGON2_VERSION_13: Argon2_version = 0x13;
181pub const ARGON2_VERSION_NUMBER: Argon2_version = ARGON2_VERSION_13;
182
183extern "C" {
184    /// Function that gives the string representation of an argon2_type.
185    ///
186    /// @param type The argon2_type that we want the string for
187    ///
188    /// @param uppercase Whether the string should have the first letter uppercase
189    ///
190    /// @return NULL if invalid type, otherwise the string representation.
191    pub fn argon2_type2string(ty: argon2_type, uppercase: libc::c_int) -> *const libc::c_char;
192
193    /// Function that performs memory-hard hashing with certain degree of parallelism
194    ///
195    /// @param  context  Pointer to the Argon2 internal structure
196    ///
197    /// @return Error code if smth is wrong, ARGON2_OK otherwise
198    pub fn argon2_ctx(context: *mut argon2_context, ty: argon2_type) -> libc::c_int;
199
200    /// Hashes a password with Argon2i, producing an encoded hash
201    ///
202    /// @param t_cost Number of iterations
203    ///
204    /// @param m_cost Sets memory usage to m_cost kibibytes
205    ///
206    /// @param parallelism Number of threads and compute lanes
207    ///
208    /// @param pwd Pointer to password
209    ///
210    /// @param pwdlen Password size in bytes
211    ///
212    /// @param salt Pointer to salt
213    ///
214    /// @param saltlen Salt size in bytes
215    ///
216    /// @param hashlen Desired length of the hash in bytes
217    ///
218    /// @param encoded Buffer where to write the encoded hash
219    ///
220    /// @param encodedlen Size of the buffer (thus max size of the encoded hash)
221    ///
222    /// @pre   Different parallelism levels will give different results
223    ///
224    /// @pre   Returns ARGON2_OK if successful
225    pub fn argon2i_hash_encoded(
226        t_cost: u32,
227        m_cost: u32,
228        parallelism: u32,
229        pwd: *const libc::c_void,
230        pwdlen: libc::size_t,
231        salt: *const libc::c_void,
232        saltlen: libc::size_t,
233        hashlen: libc::size_t,
234        encoded: *mut libc::c_char,
235        encodedlen: libc::size_t,
236    ) -> libc::c_int;
237
238    /// Hashes a password with Argon2i, producing a raw hash at @hash
239    ///
240    /// @param t_cost Number of iterations
241    ///
242    /// @param m_cost Sets memory usage to m_cost kibibytes
243    ///
244    /// @param parallelism Number of threads and compute lanes
245    ///
246    /// @param pwd Pointer to password
247    ///
248    /// @param pwdlen Password size in bytes
249    ///
250    /// @param salt Pointer to salt
251    ///
252    /// @param saltlen Salt size in bytes
253    ///
254    /// @param hash Buffer where to write the raw hash - updated by the function
255    ///
256    /// @param hashlen Desired length of the hash in bytes
257    ///
258    /// @pre   Different parallelism levels will give different results
259    ///
260    /// @pre   Returns ARGON2_OK if successful
261    pub fn argon2i_hash_raw(
262        t_cost: u32,
263        m_cost: u32,
264        parallelism: u32,
265        pwd: *const libc::c_void,
266        pwdlen: libc::size_t,
267        salt: *const libc::c_void,
268        saltlen: libc::size_t,
269        hash: *mut libc::c_void,
270        hashlen: libc::size_t,
271    ) -> libc::c_int;
272
273    pub fn argon2d_hash_encoded(
274        t_cost: u32,
275        m_cost: u32,
276        parallelism: u32,
277        pwd: *const libc::c_void,
278        pwdlen: libc::size_t,
279        salt: *const libc::c_void,
280        saltlen: libc::size_t,
281        hashlen: libc::size_t,
282        encoded: *mut libc::c_char,
283        encodedlen: libc::size_t,
284    ) -> libc::c_int;
285
286    pub fn argon2d_hash_raw(
287        t_cost: u32,
288        m_cost: u32,
289        parallelism: u32,
290        pwd: *const libc::c_void,
291        pwdlen: libc::size_t,
292        salt: *const libc::c_void,
293        saltlen: libc::size_t,
294        hash: *mut libc::c_void,
295        hashlen: libc::size_t,
296    ) -> libc::c_int;
297
298    pub fn argon2id_hash_encoded(
299        t_cost: u32,
300        m_cost: u32,
301        parallelism: u32,
302        pwd: *const libc::c_void,
303        pwdlen: libc::size_t,
304        salt: *const libc::c_void,
305        saltlen: libc::size_t,
306        hashlen: libc::size_t,
307        encoded: *mut libc::c_char,
308        encodedlen: libc::size_t,
309    ) -> libc::c_int;
310
311    pub fn argon2id_hash_raw(
312        t_cost: u32,
313        m_cost: u32,
314        parallelism: u32,
315        pwd: *const libc::c_void,
316        pwdlen: libc::size_t,
317        salt: *const libc::c_void,
318        saltlen: libc::size_t,
319        hash: *mut libc::c_void,
320        hashlen: libc::size_t,
321    ) -> libc::c_int;
322
323    pub fn argon2_hash(
324        t_cost: u32,
325        m_cost: u32,
326        parallelism: u32,
327        pwd: *const libc::c_void,
328        pwdlen: libc::size_t,
329        salt: *const libc::c_void,
330        saltlen: libc::size_t,
331        hash: *mut libc::c_void,
332        hashlen: libc::size_t,
333        encoded: *mut libc::c_char,
334        encodedlen: libc::size_t,
335        ty: argon2_type,
336        version: u32,
337    ) -> libc::c_int;
338
339    /// Verifies a password against an encoded string
340    ///
341    /// Encoded string is restricted as in validate_inputs()
342    ///
343    /// @param encoded String encoding parameters, salt, hash
344    ///
345    /// @param pwd Pointer to password
346    ///
347    /// @pre   Returns ARGON2_OK if successful
348    pub fn argon2i_verify(
349        encoded: *const libc::c_char,
350        pwd: *const libc::c_void,
351        pwdlen: libc::size_t,
352    ) -> libc::c_int;
353
354    pub fn argon2d_verify(
355        encoded: *const libc::c_char,
356        pwd: *const libc::c_void,
357        pwdlen: libc::size_t,
358    ) -> libc::c_int;
359
360    pub fn argon2id_verify(
361        encoded: *const libc::c_char,
362        pwd: *const libc::c_void,
363        pwdlen: libc::size_t,
364    ) -> libc::c_int;
365
366    pub fn argon2_verify(
367        encoded: *const libc::c_char,
368        pwd: *const libc::c_void,
369        pwdlen: libc::size_t,
370        ty: argon2_type,
371    ) -> libc::c_int;
372
373    ///  Argon2d: Version of Argon2 that picks memory blocks depending
374    ///  on the password and salt. Only for side-channel-free
375    ///  environment!!
376    /// ****
377    /// @param  context  Pointer to current Argon2 context
378    ///
379    /// @return  Zero if successful, a non zero error code otherwise
380    pub fn argon2d_ctx(context: *mut argon2_context) -> libc::c_int;
381
382    /// Argon2i: Version of Argon2 that picks memory blocks
383    /// independent on the password and salt. Good for side-channels,
384    /// but worse w.r.t. tradeoff attacks if only one pass is used.
385    /// ****
386    /// @param  context  Pointer to current Argon2 context
387    ///
388    /// @return  Zero if successful, a non zero error code otherwise
389    pub fn argon2i_ctx(context: *mut argon2_context) -> libc::c_int;
390
391    /// Argon2id: Version of Argon2 where the first half-pass over memory is
392    /// password-independent, the rest are password-dependent (on the password and
393    /// salt). OK against side channels (they reduce to 1/2-pass Argon2i), and
394    /// better with w.r.t. tradeoff attacks (similar to Argon2d).
395    /// ****
396    /// @param  context  Pointer to current Argon2 context
397    ///
398    /// @return  Zero if successful, a non zero error code otherwise
399    pub fn argon2id_ctx(context: *mut argon2_context) -> libc::c_int;
400
401    /// Verify if a given password is correct for Argon2d hashing
402    ///
403    /// @param  context  Pointer to current Argon2 context
404    ///
405    /// @param  hash  The password hash to verify. The length of the hash is
406    /// specified by the context outlen member
407    ///
408    /// @return  Zero if successful, a non zero error code otherwise
409    pub fn argon2d_verify_ctx(
410        context: *mut argon2_context,
411        hash: *const libc::c_char,
412    ) -> libc::c_int;
413
414    /// Verify if a given password is correct for Argon2i hashing
415    /// @param  context  Pointer to current Argon2 context
416    ///
417    /// @param  hash  The password hash to verify. The length of the hash is
418    /// specified by the context outlen member
419    ///
420    /// @return  Zero if successful, a non zero error code otherwise
421    pub fn argon2i_verify_ctx(
422        context: *mut argon2_context,
423        hash: *const libc::c_char,
424    ) -> libc::c_int;
425
426    /// Verify if a given password is correct for Argon2id hashing
427    ///
428    /// @param  context  Pointer to current Argon2 context
429    ///
430    /// @param  hash  The password hash to verify. The length of the hash is
431    /// specified by the context outlen member
432    ///
433    /// @return  Zero if successful, a non zero error code otherwise
434    pub fn argon2id_verify_ctx(
435        context: *mut argon2_context,
436        hash: *const libc::c_char,
437    ) -> libc::c_int;
438
439    pub fn argon2_verify_ctx(
440        context: *mut argon2_context,
441        hash: *const libc::c_char,
442        ty: argon2_type,
443    ) -> libc::c_int;
444
445    /// Get the associated error message for given error code
446    ///
447    /// @return  The error message associated with the given error code
448    pub fn argon2_error_message(error_code: libc::c_int) -> *const libc::c_char;
449
450    /// Returns the encoded hash length for the given input parameters
451    ///
452    /// @param t_cost  Number of iterations
453    ///
454    /// @param m_cost  Memory usage in kibibytes
455    ///
456    /// @param parallelism  Number of threads; used to compute lanes
457    ///
458    /// @param saltlen  Salt size in bytes
459    ///
460    /// @param hashlen  Hash size in bytes
461    ///
462    /// @param type The argon2_type that we want the encoded length for
463    ///
464    /// @return  The encoded hash length in bytes
465    pub fn argon2_encodedlen(
466        t_cost: u32,
467        m_cost: u32,
468        parallelism: u32,
469        saltlen: u32,
470        hashlen: u32,
471        ty: argon2_type,
472    ) -> libc::size_t;
473}