/* See LICENSE file for copyright and license details. */ #ifndef LIBAR2SIMPLIFIED_H #define LIBAR2SIMPLIFIED_H #include /* 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 hash * * @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 hash * * 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