/* See LICENSE file for copyright and license details. */
#ifndef LIBAR2SIMPLIFIED_H
#define LIBAR2SIMPLIFIED_H
#include <libar2.h>
/* These are useful when the database stores parameters and
* hash separately, when the application uses a pepper, or
* when composing multiple hash functions: */
/**
* Encode hashing parameters, with or without hashing result
*
* This function extends the standard format for Argon2 by
* letting the exact salt or tag (hash) be unspecified, but
* the length specified using an asterisk-prefixed, decimal
* integer
*
* `params->key` and `params->ad` will not be included in
* the returned string
*
* @param params The hashing parameters, if `params->salt`
* is `NULL` the salt's length is encoded
* instead of an actual salt
* @param hash The tag, or `NULL` the tag's length is
* encoded instead of an actual tag
* @return The hashing parameter string,
* or `NULL` on failure; shall be dellocated
* using free(3) when no longer needed
*/
LIBAR2_PUBLIC__ LIBAR2_NONNULL__(1)
char *libar2simplified_encode(const struct libar2_argon2_parameters *params, void *hash);
/**
* Encode tag (hashing result) without parameters
*
* @param params The hashing parameters (used to get the tag length)
* @param hash The binary tag (hashing result)
* @return `hash` encoded with base64, or `NULL`
* on failure; shall be dellocated using
* free(3) when no longer needed
*/
LIBAR2_PUBLIC__ LIBAR2_NONNULL__(1, 2)
char *libar2simplified_encode_hash(const struct libar2_argon2_parameters *params, void *hash);
/**
* Decode hashing parameters
*
* If the salt's lengths is encoded, but not an
* actual salt, a random salt will be created
*
* The hashing string does not encode information
* about `params->key` or `params->ad`, therefore
* `params->key` and `params->ad` will be set to
* `NULL` and `params->keylen` and `params->adlen`
* will be set to 0
*
* @param str The hashing parameter string to decode
* @param tagp Output parameter for the tag (hash
* result), or `NULL`. Unless `NULL`,
* `NULL` will be stored in `*tagp` if
* `str` includes a tag length instead
* of an actual tag, otherwise unless
* `NULL`, the beginning of the tag, in
* `str`, will be stored in `*tagp`.
* `*endp` will (unless `endp` or `*tagp`
* is `NULL`) mark the end of the tag.
* @param endp Output parameter for the end of the
* hashing parameter string, or `NULL`.
* Unless `NULL`, one position beyond
* the last byte in `str` determined to
* be part of the hashing parameter
* string will be stored in `*endp`.
* The application shall make sure that
* `**endp` is a valid termination of
* the hashing parameter string; typically
* this would be a ':' or a NUL byte.
* @param random_byte_generator Random number generator function, used
* to generate salt if `str` does not
* contain one. The function shall output
* `n` random bytes (only the lower 6 bits
* in each byte need to be random) to
* `out` and return 0. On failure, the
* function shall return -1. If `NULL`,
* the function will use a random number
* generator provided by the C standard
* library or the operating system.
* @return Decoded hashing parameters. Shall be
* deallocated using free(3) when no longer
* needed. Be aware than the allocation
* size of the returned object will exceed
* the size of the return type.
*/
LIBAR2_PUBLIC__ LIBAR2_NONNULL__(1)
struct libar2_argon2_parameters *
libar2simplified_decode(const char *str, char **tagp, char **endp, int (*random_byte_generator)(char *out, size_t n));
/**
* Calculate a password hashing
*
* @param hash Output parameter for the tag (hash result).
* This must be a buffer than is at least
* `libar2_hash_buf_size(params)` bytes large.
* @param msg The message (password) to hash. Will be
* erased (not deallocated) some time before
* the function returns.
* @param msglen The number of bytes in `msg`
* @param params Hashing parameters
* @return 0 on success, -1 on failure
*/
LIBAR2_PUBLIC__ LIBAR2_NONNULL__(1, 4)
int libar2simplified_hash(void *hash, void *msg, size_t msglen, struct libar2_argon2_parameters *params);
/* This one is useful you just want to do it crypt(3)-style: */
/**
* Calculate a password hashing
*
* This function works like crypt(3), except that it only supports
* Argon2, it will erase the input password, the return buffer is
* provided in the third parameter or (if `NULL`) is dynamically
* allocated, and it will generate a salt if one is not provided
*
* Assumming `params` contains a salt and a tag (hash), `msg`
* is (in all likelyhood) the password it was created with if
* the returned string is identical to `params`. It is
* recommended, to hinder timing attack, that this check is done
* by comparing all characters in the strings, even if a mismatch
* is found early.
*
* This function is generally not recommend. It should only be
* used for /etc/shadow and similar files. Other applications should
* use `libar2simplified_hash` and provide an application-specific,
* random, pepper. Applications are also recommended to use
* `libar2simplified_hash` so that they can compose password hashing
* functions and automatically harden passwords, without knowing
* their plain-text, when the hashing configuration is determined
* to be too weak.
*
* @param msg The password to hash. NB! Will be erased (not
* deallocated) some time before the function returns.
* @param params Hashing parameter string
* @param rv Output parameter for the hasing, or `NULL`.
* Unless `NULL`, this must be a buffer than is at least
* `libar2_hash_buf_size(libar2simplified_decode(params,
* NULL, NULL, NULL))` bytes large.
* @return The hashing result, including hashing parameters.
* `NULL` on failure. On success, `rv` is returned
* unless `rv` is `NULL`. If `rv` is `NULL`, the
* returned shall be deallocated using free(3) when
* it is no longer needed
*/
LIBAR2_PUBLIC__ LIBAR2_NONNULL__(1, 2)
char *libar2simplified_crypt(char *msg, const char *params, char *rv);
#endif