crypto::argon2
This module provides an implementation of the argon2 key derivation function as
described by RFC 9106. This is the recommended algorithm for password hashing in
Hare programs, and for deriving keys for use with other cryptographic
algorithms. Some thought must be given to the appropriate configuration for your
use case. Some general advice is provided here; if in doubt, consult the RFC.
The argon2 parameters are configured via the config structure. To determine
the appropriate configuration parameters for a particular use-case, consult
section 4 of the RFC. Otherwise, sane defaults for common scenarios are provided
via default_config and low_mem_config; consult the docs of each
configuration for details.
Once a suitable configuration has been selected, the user must provide a salt.
This salt should be stored alongside the hash, should be unique for each
password, and should be random: see crypto::random. The salt and hash
lengths are configurable, the recommended defaults are 16 and 32 bytes
respectively.
Equipped with the necessary parameters, the user may call the appropriate argon2
variant via argon2d, argon2i, or argon2id. If unsure which to use,
choose argon2id. The RFC is the authoratative source on the appropriate
argon2 variant and configuration parameters for your use-case.
This is a low-level module which implements cryptographic primitives. Direct use
of cryptographic primitives is not recommended for non-experts, as incorrect use
of these primitives can easily lead to the introduction of security
vulnerabilities. Non-experts are advised to use the high-level operations
available in the top-level crypto module.
Be advised that Hare's cryptography implementations have not been audited.
Index
Types
type config;
Constants
const BLOCKSIZE: u32;
const VERSION: u8;
Globals
let default_config: config;
let low_mem_config: config;
Functions
fn argon2d([]u8, []u8, []u8, *config) (void | nomem);
fn argon2i([]u8, []u8, []u8, *config) (void | nomem);
fn argon2id([]u8, []u8, []u8, *config) (void | nomem);
Types
type config
type config = struct {
mem: (u32 | []u64),
parallel: u32,
passes: u32,
version: u8,
secret: []u8,
data: []u8,
};
This type provides configuration options for the argon2 algorithm. Most users
will find default_config or low_mem_config suitable for their needs
without providing a custom configuration. If writing a custom configuration,
consult the RFC for advice on selecting suitable values for your use-case.
'parallel' specifies the number of parallel processes. 'pass' configures the
number of iterations. Both values must be at least one. Note: the Hare
implementation of argon2 does not process hashes in parallel, though it will
still compute the correct hash if this value is greater than one.
'version' specifies the version of the argon2 function. The implementation
currently only supports version 1.3. Use VERSION here.
'secret' and 'data' are optional byte arrays that are applied to the initial
state. Consult the RFC for details.
The 'mem' parameter is used to configure working memory used during the
computation. The argon2 algorithm requires a large amount of memory to
compute hashes. If 'mem' set to a u32, it is interpreted as the desired
number of 1024-byte blocks the implementation shall allocate for you. If the
caller wants to manage the allocation itself, provide a []u8 instead. The
length of this slice must be at least 8 times the value of 'parallel' in
blocks, and must be a multiple of BLOCKSIZE. To have the implementation
allocate 64 KiB, set 'mem' to 64. To use the same amount of caller-provided
memory, provide a slice of length 64 * BLOCKSIZE.
Constants
def BLOCKSIZE
def BLOCKSIZE: u32;
Number of u64 elements of one block.
def VERSION
def VERSION: u8;
Latest version of argon2 supported by this implementation (1.3).
Globals
let default_config
const default_config: config;
The default recommended configuration for most use cases. This configuration
uses 2 GiB of working memory. A 16-byte 'salt' and 32-byte 'dest' parameter
is recommended in combination with this configuration.
let low_mem_config
const low_mem_config: config;
The default recommended configuration for memory-constrained use cases. This
configuration uses 64 MiB of working memory. A 16-byte 'salt' and 32-byte
'dest' parameter is recommended in combination with this configuration.
Functions
fn argon2d
fn argon2d(dest: []u8, password: []u8, salt: []u8, cfg: *config) (void | nomem);
Computes an argon2d hash, writing the digest to 'dest'. A 'salt' length of 16
bytes is recommended, and 8 bytes is the minimum. A 'dest' length of 32 bytes
is recommended, and 4 bytes is the minimum.
The argon2d mode uses data-dependent memory access and is suitable for
applications with no threats of side-channel timing attacks.
fn argon2i
fn argon2i(dest: []u8, password: []u8, salt: []u8, cfg: *config) (void | nomem);
Computes an argon2i hash, writing the digest to 'dest'. A 'salt' length of 16
bytes is recommended, and 8 bytes is the minimum. A 'dest' length of 32 bytes
is recommended, and 4 bytes is the minimum.
The argon2i mode uses data-independent memory access and is suitable for
password hashing and key derivation. It makes more passes over memory to
protect from trade-off attacks.
fn argon2id
fn argon2id(dest: []u8, password: []u8, salt: []u8, cfg: *config) (void | nomem);
Computes an argon2id hash, writing the digest to 'dest'. A 'salt' length of
16 bytes is recommended, and 8 bytes is the minimum. A 'dest' length of 32
bytes is recommended, and 4 bytes is the minimum.
The argon2id mode works by using argon2i for the first half of the first pass
and argon2d further on. It provides therefore protection from side-channel
attacks and brute-force cost savings due to memory trade-offs.
If you are unsure which variant to use, argon2id is recommended.