aboutsummaryrefslogtreecommitdiffstats
path: root/libar2simplified.h
blob: 567097a3e04d03edfb5e8bc35f3120ba128342dd (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
/* 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