aboutsummaryrefslogtreecommitdiffstats
path: root/libar2simplified.h
blob: e58e68c97fdd4e4cc46fcc710d0e551ba644ddcd (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
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
/* See LICENSE file for copyright and license details. */
#ifndef LIBAR2SIMPLIFIED_H
#define LIBAR2SIMPLIFIED_H

#include <libar2.h>

/**
 * Get a recommended set of hashing parameter
 * 
 * These shall not be taken too seriously, they are
 * just for getting you up and running. You should
 * tweak the them to your requirements.
 * 
 * @param   side_channel_free  Whether the environment is considered safe
 *                             enought against side-channel attacks, use 0 if
 *                             you don't know (it is very unlikely that it is)
 * @return                     Hashing parameters than can be used for
 *                             `libar2simplified_crypt` or `libar2simplified_decode`
 */
#if defined(__GNUC__)
__attribute__((const))
#endif
const char *libar2simplified_recommendation(int side_channel_free);

/* 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; where `params` is the returned
 * pointer
 * 
 * @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));

/**
 * 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; where `params` is the returned
 * pointer
 * 
 * @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.
 * @param   user_data              Will be parsed as is as the third argument of
 *                                 `random_byte_generator` and is otherwise unused.
 * @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_r(const char *str, char **tagp, char **endp,
                          int (*random_byte_generator)(char *out, size_t n, void *user_data), void *user_data);

/**
 * 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);

/* Lower-level functions: */

/**
 * Initialises the context argument for `libar2_hash`,
 * with all auto-erase options turned off
 * 
 * This function provides a dynamic memory management
 * functions that erase memory before it is deallocated.
 * It also also provides a multi-threading support using
 * a thread pool.
 * 
 * @param  ctxp  Output parameter
 */
LIBAR2_PUBLIC__
void libar2simplified_init_context(struct libar2_context *ctxp);

#endif