aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMattias Andrée <maandree@kth.se>2022-02-14 22:34:40 +0100
committerMattias Andrée <maandree@kth.se>2022-02-14 22:40:00 +0100
commit4e0109888c11b15cfb19383fc24310999e506d04 (patch)
tree82e28debff1f2e87e660fa9b802e8f631e09d5e5
parentAdd libar2simplified_crypt and fix threading (diff)
downloadlibar2simplified-4e0109888c11b15cfb19383fc24310999e506d04.tar.gz
libar2simplified-4e0109888c11b15cfb19383fc24310999e506d04.tar.bz2
libar2simplified-4e0109888c11b15cfb19383fc24310999e506d04.tar.xz
Add documentation and make sure the password is always erased
Signed-off-by: Mattias Andrée <maandree@kth.se>
-rw-r--r--libar2simplified.h127
-rw-r--r--libar2simplified_hash.c6
2 files changed, 132 insertions, 1 deletions
diff --git a/libar2simplified.h b/libar2simplified.h
index 55eb123..567097a 100644
--- a/libar2simplified.h
+++ b/libar2simplified.h
@@ -8,21 +8,148 @@
* 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);
diff --git a/libar2simplified_hash.c b/libar2simplified_hash.c
index 4583dfb..8e4bd85 100644
--- a/libar2simplified_hash.c
+++ b/libar2simplified_hash.c
@@ -391,6 +391,7 @@ int
libar2simplified_hash(void *hash, void *msg, size_t msglen, struct libar2_argon2_parameters *params)
{
struct libar2_context ctx;
+ int ret;
memset(&ctx, 0, sizeof(ctx));
ctx.autoerase_message = 1;
@@ -402,5 +403,8 @@ libar2simplified_hash(void *hash, void *msg, size_t msglen, struct libar2_argon2
ctx.join_thread_pool = join_thread_pool;
ctx.destroy_thread_pool = destroy_thread_pool;
- return libar2_hash(hash, msg, msglen, params, &ctx);
+ ret = libar2_hash(hash, msg, msglen, params, &ctx);
+ if (ret)
+ libar2_erase(msg, msglen);
+ return ret;
}