keyderiv.ha (2164B)
1 // SPDX-License-Identifier: MPL-2.0 2 // (c) Hare authors <https://harelang.org> 3 4 use crypto::argon2; 5 use errors; 6 7 // Given a password, derive a key. Given the same password, salt, memory, and 8 // passes, this function will always produce the same key. This function is 9 // designed to derive cryptographic keys from user-provided passwords, or to 10 // verify a password for user logins. 11 // 12 // The user provides a buffer for the key to be written to via the 'dest' 13 // parameter. The minimum supported length for this buffer is 4 bytes, and the 14 // recommended length is 32 bytes. 15 // 16 // The salt parameter should be randomly generated, stored alongside the key, 17 // and used in subsequent calls to produce the same key. It must be at least 8 18 // bytes, but 16 bytes is recommended. Use [[crypto::random::]] to generate a 19 // different salt for each key. 20 // 21 // The 'mem' and 'passes' functions are provided to tune the behavior of this 22 // algorithm. It is designed to be computationally expensive, and you must 23 // adjust these figures to suit your hardware and use-case. If you provide a u32 24 // for 'mem', the algorithm will dynamically allocate that many kilobytes of 25 // working memory. To allocate this memory yourself, provide a []u64 instead. 26 // The number of passes controls the amount of time spent generating the key, 27 // higher numbers take longer. 28 // 29 // To identify ideal values for these parameters, start with 100000 for 'mem' 30 // (100 MiB) and 0 for 'passes'. If it takes too long, reduce the amount of 31 // memory, and if it does not take long enough, increase the amount of memory. 32 // If you have reached the maximum amount of memory you are able to use, 33 // increase passes. 34 // 35 // The current implementation of this function uses argon2id version 1.3 with the 36 // provided number of memory blocks, passes equal to passes + 3, and parallelism 37 // set to one. 38 export fn derivekey( 39 dest: []u8, 40 salt: []u8, 41 password: []u8, 42 mem: (u32 | []u64), 43 passes: u32, 44 ) (void | errors::nomem) = { 45 const config = argon2::conf { 46 mem = mem, 47 parallel = 1, 48 passes = passes + 3, 49 version = argon2::VERSION, 50 ... 51 }; 52 return argon2::argon2id(dest, password, salt, &config); 53 };