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