argon2 0.0.1 → 0.0.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (48) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +4 -0
  3. data/.travis.yml +2 -0
  4. data/README.md +25 -9
  5. data/argon2.gemspec +10 -2
  6. data/bin/console +1 -1
  7. data/bin/setup +3 -0
  8. data/ext/argon2_wrap/Makefile +72 -0
  9. data/ext/argon2_wrap/argon_wrap.c +65 -0
  10. data/ext/argon2_wrap/extconf.rb +1 -0
  11. data/ext/argon2_wrap/test.c +67 -0
  12. data/ext/phc-winner-argon2/.gitignore +7 -0
  13. data/ext/phc-winner-argon2/LICENSE +31 -0
  14. data/ext/phc-winner-argon2/Makefile +102 -0
  15. data/ext/phc-winner-argon2/README.md +193 -0
  16. data/ext/phc-winner-argon2/argon2-specs.pdf +0 -0
  17. data/ext/phc-winner-argon2/kats/argon2d +12302 -0
  18. data/ext/phc-winner-argon2/kats/argon2d.shasum +1 -0
  19. data/ext/phc-winner-argon2/kats/argon2i +12302 -0
  20. data/ext/phc-winner-argon2/kats/argon2i.shasum +1 -0
  21. data/ext/phc-winner-argon2/kats/check-sums.sh +13 -0
  22. data/ext/phc-winner-argon2/kats/test.sh +47 -0
  23. data/ext/phc-winner-argon2/src/argon2.c +360 -0
  24. data/ext/phc-winner-argon2/src/argon2.h +298 -0
  25. data/ext/phc-winner-argon2/src/bench.c +111 -0
  26. data/ext/phc-winner-argon2/src/blake2/blake2-impl.h +143 -0
  27. data/ext/phc-winner-argon2/src/blake2/blake2.h +74 -0
  28. data/ext/phc-winner-argon2/src/blake2/blake2b.c +372 -0
  29. data/ext/phc-winner-argon2/src/blake2/blamka-round-opt.h +162 -0
  30. data/ext/phc-winner-argon2/src/blake2/blamka-round-ref.h +39 -0
  31. data/ext/phc-winner-argon2/src/core.c +662 -0
  32. data/ext/phc-winner-argon2/src/core.h +226 -0
  33. data/ext/phc-winner-argon2/src/genkat.c +194 -0
  34. data/ext/phc-winner-argon2/src/genkat.h +45 -0
  35. data/ext/phc-winner-argon2/src/opt.c +173 -0
  36. data/ext/phc-winner-argon2/src/opt.h +49 -0
  37. data/ext/phc-winner-argon2/src/ref.c +175 -0
  38. data/ext/phc-winner-argon2/src/ref.h +49 -0
  39. data/ext/phc-winner-argon2/src/run.c +223 -0
  40. data/ext/phc-winner-argon2/src/thread.c +36 -0
  41. data/ext/phc-winner-argon2/src/thread.h +46 -0
  42. data/lib/argon2.rb +15 -32
  43. data/lib/argon2/constants.rb +6 -0
  44. data/lib/argon2/engine.rb +10 -0
  45. data/lib/argon2/errors.rb +36 -0
  46. data/lib/argon2/ffi_engine.rb +47 -0
  47. data/lib/argon2/version.rb +1 -1
  48. metadata +75 -11
@@ -0,0 +1 @@
1
+ d94efacfa5efcdfeb513c829cccda7d9003640e1de64b12fad80f92aad1ab8a4 argon2i
@@ -0,0 +1,13 @@
1
+ #!/bin/sh
2
+
3
+ for file in `ls | grep '^[a-z2]*$' | xargs`
4
+ do
5
+ new=`shasum -a 256 $file`
6
+ old=`cat $file.shasum`
7
+ if [ "$new" = "$old" ]
8
+ then
9
+ echo $file "\t" OK
10
+ else
11
+ echo $file "\t" ERROR
12
+ fi
13
+ done
@@ -0,0 +1,47 @@
1
+ #!/bin/sh
2
+
3
+ make genkat > /dev/null
4
+ if [ $? -ne 0 ]
5
+ then
6
+ exit $?
7
+ fi
8
+
9
+ printf "argon2i "
10
+ ./genkat i > tmp
11
+ if diff tmp kats/argon2i
12
+ then printf "OK"
13
+ else printf "ERROR"
14
+ fi
15
+ printf "\n"
16
+
17
+ printf "argon2d "
18
+ ./genkat d > tmp
19
+ if diff tmp kats/argon2d
20
+ then printf "OK"
21
+ else printf "ERROR"
22
+ fi
23
+ printf "\n"
24
+
25
+ make genkat OPT=TRUE > /dev/null
26
+ if [ $? -ne 0 ]
27
+ then
28
+ exit $?
29
+ fi
30
+
31
+ printf "argon2i "
32
+ ./genkat i > tmp
33
+ if diff tmp kats/argon2i
34
+ then printf "OK"
35
+ else printf "ERROR"
36
+ fi
37
+ printf "\n"
38
+
39
+ printf "argon2d "
40
+ ./genkat d > tmp
41
+ if diff tmp kats/argon2d
42
+ then printf "OK"
43
+ else printf "ERROR"
44
+ fi
45
+ printf "\n"
46
+
47
+ rm -f tmp
@@ -0,0 +1,360 @@
1
+ /*
2
+ * Argon2 source code package
3
+ *
4
+ * Written by Daniel Dinu and Dmitry Khovratovich, 2015
5
+ *
6
+ * This work is licensed under a Creative Commons CC0 1.0 License/Waiver.
7
+ *
8
+ * You should have received a copy of the CC0 Public Domain Dedication along
9
+ * with
10
+ * this software. If not, see
11
+ * <http://creativecommons.org/publicdomain/zero/1.0/>.
12
+ */
13
+
14
+ #include <stdint.h>
15
+ #include <string.h>
16
+ #include <stdio.h>
17
+ #include <limits.h>
18
+
19
+ #include "argon2.h"
20
+ #include "core.h"
21
+
22
+ /* Error messages */
23
+ static const char *Argon2_ErrorMessage[] = {
24
+ /*{ARGON2_OK, */ "OK",
25
+ /*},
26
+
27
+ {ARGON2_OUTPUT_PTR_NULL, */ "Output pointer is NULL",
28
+ /*},
29
+
30
+ {ARGON2_OUTPUT_TOO_SHORT, */ "Output is too short",
31
+ /*},
32
+ {ARGON2_OUTPUT_TOO_LONG, */ "Output is too long",
33
+ /*},
34
+
35
+ {ARGON2_PWD_TOO_SHORT, */ "Password is too short",
36
+ /*},
37
+ {ARGON2_PWD_TOO_LONG, */ "Password is too long",
38
+ /*},
39
+
40
+ {ARGON2_SALT_TOO_SHORT, */ "Salt is too short",
41
+ /*},
42
+ {ARGON2_SALT_TOO_LONG, */ "Salt is too long",
43
+ /*},
44
+
45
+ {ARGON2_AD_TOO_SHORT, */ "Associated data is too short",
46
+ /*},
47
+ {ARGON2_AD_TOO_LONG, */ "Associated date is too long",
48
+ /*},
49
+
50
+ {ARGON2_SECRET_TOO_SHORT, */ "Secret is too short",
51
+ /*},
52
+ {ARGON2_SECRET_TOO_LONG, */ "Secret is too long",
53
+ /*},
54
+
55
+ {ARGON2_TIME_TOO_SMALL, */ "Time cost is too small",
56
+ /*},
57
+ {ARGON2_TIME_TOO_LARGE, */ "Time cost is too large",
58
+ /*},
59
+
60
+ {ARGON2_MEMORY_TOO_LITTLE, */ "Memory cost is too small",
61
+ /*},
62
+ {ARGON2_MEMORY_TOO_MUCH, */ "Memory cost is too large",
63
+ /*},
64
+
65
+ {ARGON2_LANES_TOO_FEW, */ "Too few lanes",
66
+ /*},
67
+ {ARGON2_LANES_TOO_MANY, */ "Too many lanes",
68
+ /*},
69
+
70
+ {ARGON2_PWD_PTR_MISMATCH, */ "Password pointer is NULL, but password length is not 0",
71
+ /*},
72
+ {ARGON2_SALT_PTR_MISMATCH, */ "Salt pointer is NULL, but salt length is not 0",
73
+ /*},
74
+ {ARGON2_SECRET_PTR_MISMATCH, */ "Secret pointer is NULL, but secret length is not 0",
75
+ /*},
76
+ {ARGON2_AD_PTR_MISMATCH, */ "Associated data pointer is NULL, but ad length is not 0",
77
+ /*},
78
+
79
+ {ARGON2_MEMORY_ALLOCATION_ERROR, */ "Memory allocation error",
80
+ /*},
81
+
82
+ {ARGON2_FREE_MEMORY_CBK_NULL, */ "The free memory callback is NULL",
83
+ /*},
84
+ {ARGON2_ALLOCATE_MEMORY_CBK_NULL, */ "The allocate memory callback is NULL",
85
+ /*},
86
+
87
+ {ARGON2_INCORRECT_PARAMETER, */ "Argon2_Context context is NULL",
88
+ /*},
89
+ {ARGON2_INCORRECT_TYPE, */ "There is no such version of Argon2",
90
+ /*},
91
+
92
+ {ARGON2_OUT_PTR_MISMATCH, */ "Output pointer mismatch",
93
+ /*},
94
+
95
+ {ARGON2_THREADS_TOO_FEW, */ "Not enough threads",
96
+ /*},
97
+ {ARGON2_THREADS_TOO_MANY, */ "Too many threads",
98
+ /*},
99
+ {ARGON2_MISSING_ARGS, */ "Missing arguments", /*},*/
100
+ };
101
+
102
+ int hash_argon2i(void *out, size_t outlen, const void *in, size_t inlen,
103
+ const void *salt, size_t saltlen, unsigned int t_cost,
104
+ unsigned int m_cost) {
105
+
106
+ argon2_context context;
107
+
108
+ /* Detect and reject overflowing sizes */
109
+ /* TODO: This should probably be fixed in the function signature */
110
+ if (inlen > UINT32_MAX) {
111
+ return ARGON2_PWD_TOO_LONG;
112
+ }
113
+
114
+ if (outlen > UINT32_MAX) {
115
+ return ARGON2_OUTPUT_TOO_LONG;
116
+ }
117
+
118
+ if (saltlen > UINT32_MAX) {
119
+ return ARGON2_SALT_TOO_LONG;
120
+ }
121
+
122
+ context.out = (uint8_t *)out;
123
+ context.outlen = (uint32_t)outlen;
124
+ context.pwd = (uint8_t *)in;
125
+ context.pwdlen = (uint32_t)inlen;
126
+ context.salt = (uint8_t *)salt;
127
+ context.saltlen = (uint32_t)saltlen;
128
+ context.secret = NULL;
129
+ context.secretlen = 0;
130
+ context.ad = NULL;
131
+ context.adlen = 0;
132
+ context.t_cost = t_cost;
133
+ context.m_cost = m_cost;
134
+ context.lanes = 1;
135
+ context.threads = 1;
136
+ context.allocate_cbk = NULL;
137
+ context.free_cbk = NULL;
138
+ context.flags = ARGON2_DEFAULT_FLAGS;
139
+
140
+ return argon2_core(&context, Argon2_i);
141
+ }
142
+
143
+ int hash_argon2d(void *out, size_t outlen, const void *in, size_t inlen,
144
+ const void *salt, size_t saltlen, unsigned int t_cost,
145
+ unsigned int m_cost) {
146
+ argon2_context context;
147
+
148
+ /* Detect and reject overflowing sizes */
149
+ /* TODO: This should probably be fixed in the function signature */
150
+ if (inlen > UINT32_MAX) {
151
+ return ARGON2_PWD_TOO_LONG;
152
+ }
153
+
154
+ if (outlen > UINT32_MAX) {
155
+ return ARGON2_OUTPUT_TOO_LONG;
156
+ }
157
+
158
+ if (saltlen > UINT32_MAX) {
159
+ return ARGON2_SALT_TOO_LONG;
160
+ }
161
+
162
+ context.out = (uint8_t *)out;
163
+ context.outlen = (uint32_t)outlen;
164
+ context.pwd = (uint8_t *)in;
165
+ context.pwdlen = (uint32_t)inlen;
166
+ context.salt = (uint8_t *)salt;
167
+ context.saltlen = (uint32_t)saltlen;
168
+ context.secret = NULL;
169
+ context.secretlen = 0;
170
+ context.ad = NULL;
171
+ context.adlen = 0;
172
+ context.t_cost = t_cost;
173
+ context.m_cost = m_cost;
174
+ context.lanes = 1;
175
+ context.threads = 1;
176
+ context.allocate_cbk = NULL;
177
+ context.free_cbk = NULL;
178
+ context.flags = ARGON2_DEFAULT_FLAGS;
179
+
180
+ return argon2_core(&context, Argon2_d);
181
+ }
182
+
183
+ int argon2d(argon2_context *context) { return argon2_core(context, Argon2_d); }
184
+
185
+ int argon2i(argon2_context *context) { return argon2_core(context, Argon2_i); }
186
+
187
+ int verify_d(argon2_context *context, const char *hash) {
188
+ int result;
189
+ if (0 == context->outlen || NULL == hash) {
190
+ return ARGON2_OUT_PTR_MISMATCH;
191
+ }
192
+
193
+ result = argon2_core(context, Argon2_d);
194
+
195
+ if (ARGON2_OK != result) {
196
+ return result;
197
+ }
198
+
199
+ return 0 == memcmp(hash, context->out, context->outlen);
200
+ }
201
+
202
+ const char *error_message(int error_code) {
203
+ enum {
204
+ /* Make sure---at compile time---that the enum size matches the array
205
+ size */
206
+ ERROR_STRING_CHECK =
207
+ 1 /
208
+ !!((sizeof(Argon2_ErrorMessage) / sizeof(Argon2_ErrorMessage[0])) ==
209
+ ARGON2_ERROR_CODES_LENGTH)
210
+ };
211
+ if (error_code < ARGON2_ERROR_CODES_LENGTH) {
212
+ return Argon2_ErrorMessage[(argon2_error_codes)error_code];
213
+ }
214
+ return "Unknown error code.";
215
+ }
216
+
217
+ /* encoding/decoding helpers */
218
+
219
+ /*
220
+ * Some macros for constant-time comparisons. These work over values in
221
+ * the 0..255 range. Returned value is 0x00 on "false", 0xFF on "true".
222
+ */
223
+ #define EQ(x, y) ((((0U - ((unsigned)(x) ^ (unsigned)(y))) >> 8) & 0xFF) ^ 0xFF)
224
+ #define GT(x, y) ((((unsigned)(y) - (unsigned)(x)) >> 8) & 0xFF)
225
+ #define GE(x, y) (GT(y, x) ^ 0xFF)
226
+ #define LT(x, y) GT(y, x)
227
+ #define LE(x, y) GE(y, x)
228
+
229
+ /*
230
+ * Convert value x (0..63) to corresponding Base64 character.
231
+ */
232
+ static int b64_byte_to_char(unsigned x) {
233
+ return (LT(x, 26) & (x + 'A')) |
234
+ (GE(x, 26) & LT(x, 52) & (x + ('a' - 26))) |
235
+ (GE(x, 52) & LT(x, 62) & (x + ('0' - 52))) | (EQ(x, 62) & '+') |
236
+ (EQ(x, 63) & '/');
237
+ }
238
+
239
+ /*
240
+ * Convert some bytes to Base64. 'dst_len' is the length (in characters)
241
+ * of the output buffer 'dst'; if that buffer is not large enough to
242
+ * receive the result (including the terminating 0), then (size_t)-1
243
+ * is returned. Otherwise, the zero-terminated Base64 string is written
244
+ * in the buffer, and the output length (counted WITHOUT the terminating
245
+ * zero) is returned.
246
+ */
247
+ static size_t to_base64(char *dst, size_t dst_len, const void *src,
248
+ size_t src_len) {
249
+ size_t olen;
250
+ const unsigned char *buf;
251
+ unsigned acc, acc_len;
252
+
253
+ olen = (src_len / 3) << 2;
254
+ switch (src_len % 3) {
255
+ case 2:
256
+ olen++;
257
+ /* fall through */
258
+ case 1:
259
+ olen += 2;
260
+ break;
261
+ }
262
+ if (dst_len <= olen) {
263
+ return (size_t)-1;
264
+ }
265
+ acc = 0;
266
+ acc_len = 0;
267
+ buf = (const unsigned char *)src;
268
+ while (src_len-- > 0) {
269
+ acc = (acc << 8) + (*buf++);
270
+ acc_len += 8;
271
+ while (acc_len >= 6) {
272
+ acc_len -= 6;
273
+ *dst++ = b64_byte_to_char((acc >> acc_len) & 0x3F);
274
+ }
275
+ }
276
+ if (acc_len > 0) {
277
+ *dst++ = b64_byte_to_char((acc << (6 - acc_len)) & 0x3F);
278
+ }
279
+ *dst++ = 0;
280
+ return olen;
281
+ }
282
+
283
+ /* ==================================================================== */
284
+ /*
285
+ * Code specific to Argon2i.
286
+ *
287
+ * The code below applies the following format:
288
+ *
289
+ * $argon2i$m=<num>,t=<num>,p=<num>[,keyid=<bin>][,data=<bin>][$<bin>[$<bin>]]
290
+ *
291
+ * where <num> is a decimal integer (positive, fits in an 'unsigned long')
292
+ * and <bin> is Base64-encoded data (no '=' padding characters, no newline
293
+ * or whitespace). The "keyid" is a binary identifier for a key (up to 8
294
+ * bytes); "data" is associated data (up to 32 bytes). When the 'keyid'
295
+ * (resp. the 'data') is empty, then it is ommitted from the output.
296
+ *
297
+ * The last two binary chunks (encoded in Base64) are, in that order,
298
+ * the salt and the output. Both are optional, but you cannot have an
299
+ * output without a salt. The binary salt length is between 8 and 48 bytes.
300
+ * The output length is always exactly 32 bytes.
301
+ */
302
+
303
+ int encode_string(char *dst, size_t dst_len, argon2_context *ctx) {
304
+ #define SS(str) \
305
+ do { \
306
+ size_t pp_len = strlen(str); \
307
+ if (pp_len >= dst_len) { \
308
+ return 0; \
309
+ } \
310
+ memcpy(dst, str, pp_len + 1); \
311
+ dst += pp_len; \
312
+ dst_len -= pp_len; \
313
+ } while (0)
314
+
315
+ #define SX(x) \
316
+ do { \
317
+ char tmp[30]; \
318
+ sprintf(tmp, "%lu", (unsigned long)(x)); \
319
+ SS(tmp); \
320
+ } while (0);
321
+
322
+ #define SB(buf, len) \
323
+ do { \
324
+ size_t sb_len = to_base64(dst, dst_len, buf, len); \
325
+ if (sb_len == (size_t)-1) { \
326
+ return 0; \
327
+ } \
328
+ dst += sb_len; \
329
+ dst_len -= sb_len; \
330
+ } while (0);
331
+
332
+ SS("$argon2i$m=");
333
+ SX(ctx->m_cost);
334
+ SS(",t=");
335
+ SX(ctx->t_cost);
336
+ SS(",p=");
337
+ SX(ctx->lanes);
338
+
339
+ if (ctx->adlen > 0) {
340
+ SS(",data=");
341
+ SB(ctx->ad, ctx->adlen);
342
+ }
343
+
344
+ if (ctx->saltlen == 0)
345
+ return 1;
346
+
347
+ SS("$");
348
+ SB(ctx->salt, ctx->saltlen);
349
+
350
+ if (ctx->outlen == 0)
351
+ return 1;
352
+
353
+ SS("$");
354
+ SB(ctx->out, ctx->outlen);
355
+ return 1;
356
+
357
+ #undef SS
358
+ #undef SX
359
+ #undef SB
360
+ }
@@ -0,0 +1,298 @@
1
+ /*
2
+ * Argon2 source code package
3
+ *
4
+ * Written by Daniel Dinu and Dmitry Khovratovich, 2015
5
+ *
6
+ * This work is licensed under a Creative Commons CC0 1.0 License/Waiver.
7
+ *
8
+ * You should have received a copy of the CC0 Public Domain Dedication along
9
+ * with
10
+ * this software. If not, see
11
+ * <http://creativecommons.org/publicdomain/zero/1.0/>.
12
+ */
13
+ #ifndef ARGON2_H
14
+ #define ARGON2_H
15
+
16
+ #include <stdint.h>
17
+ #include <stddef.h>
18
+ #include <limits.h>
19
+
20
+ #if defined(__cplusplus)
21
+ extern "C" {
22
+ #endif
23
+
24
+ /*************************Argon2 input parameter
25
+ * restrictions**************************************************/
26
+
27
+ /* Minimum and maximum number of lanes (degree of parallelism) */
28
+ #define ARGON2_MIN_LANES UINT32_C(1)
29
+ #define ARGON2_MAX_LANES UINT32_C(0xFFFFFF)
30
+
31
+ /* Minimum and maximum number of threads */
32
+ #define ARGON2_MIN_THREADS UINT32_C(1)
33
+ #define ARGON2_MAX_THREADS UINT32_C(0xFFFFFF)
34
+
35
+ /* Number of synchronization points between lanes per pass */
36
+ #define ARGON2_SYNC_POINTS UINT32_C(4)
37
+
38
+ /* Minimum and maximum digest size in bytes */
39
+ #define ARGON2_MIN_OUTLEN UINT32_C(4)
40
+ #define ARGON2_MAX_OUTLEN UINT32_C(0xFFFFFFFF)
41
+
42
+ /* Minimum and maximum number of memory blocks (each of BLOCK_SIZE bytes) */
43
+ #define ARGON2_MIN_MEMORY (2 * ARGON2_SYNC_POINTS) /* 2 blocks per slice */
44
+
45
+ #define ARGON2_MIN(a, b) ((a) < (b) ? (a) : (b))
46
+ /* Max memory size is half the addressing space, topping at 2^32 blocks (4 TB)
47
+ */
48
+ #define ARGON2_MAX_MEMORY_BITS \
49
+ ARGON2_MIN(UINT32_C(32), (sizeof(void *) * CHAR_BIT - 10 - 1))
50
+ #define ARGON2_MAX_MEMORY \
51
+ ARGON2_MIN(UINT32_C(0xFFFFFFFF), UINT64_C(1) << ARGON2_MAX_MEMORY_BITS)
52
+
53
+ /* Minimum and maximum number of passes */
54
+ #define ARGON2_MIN_TIME UINT32_C(1)
55
+ #define ARGON2_MAX_TIME UINT32_C(0xFFFFFFFF)
56
+
57
+ /* Minimum and maximum password length in bytes */
58
+ #define ARGON2_MIN_PWD_LENGTH UINT32_C(0)
59
+ #define ARGON2_MAX_PWD_LENGTH UINT32_C(0xFFFFFFFF)
60
+
61
+ /* Minimum and maximum associated data length in bytes */
62
+ #define ARGON2_MIN_AD_LENGTH UINT32_C(0)
63
+ #define ARGON2_MAX_AD_LENGTH UINT32_C(0xFFFFFFFF)
64
+
65
+ /* Minimum and maximum salt length in bytes */
66
+ #define ARGON2_MIN_SALT_LENGTH UINT32_C(8)
67
+ #define ARGON2_MAX_SALT_LENGTH UINT32_C(0xFFFFFFFF)
68
+
69
+ /* Minimum and maximum key length in bytes */
70
+ #define ARGON2_MIN_SECRET UINT32_C(0)
71
+ #define ARGON2_MAX_SECRET UINT32_C(0xFFFFFFFF)
72
+
73
+ #define ARGON2_FLAG_CLEAR_PASSWORD (UINT32_C(1) << 0)
74
+ #define ARGON2_FLAG_CLEAR_SECRET (UINT32_C(1) << 1)
75
+ #define ARGON2_FLAG_CLEAR_MEMORY (UINT32_C(1) << 2)
76
+ #define ARGON2_DEFAULT_FLAGS \
77
+ (ARGON2_FLAG_CLEAR_PASSWORD | ARGON2_FLAG_CLEAR_MEMORY)
78
+
79
+ /* Error codes */
80
+ typedef enum Argon2_ErrorCodes {
81
+ ARGON2_OK = 0,
82
+
83
+ ARGON2_OUTPUT_PTR_NULL = 1,
84
+
85
+ ARGON2_OUTPUT_TOO_SHORT = 2,
86
+ ARGON2_OUTPUT_TOO_LONG = 3,
87
+
88
+ ARGON2_PWD_TOO_SHORT = 4,
89
+ ARGON2_PWD_TOO_LONG = 5,
90
+
91
+ ARGON2_SALT_TOO_SHORT = 6,
92
+ ARGON2_SALT_TOO_LONG = 7,
93
+
94
+ ARGON2_AD_TOO_SHORT = 8,
95
+ ARGON2_AD_TOO_LONG = 9,
96
+
97
+ ARGON2_SECRET_TOO_SHORT = 10,
98
+ ARGON2_SECRET_TOO_LONG = 11,
99
+
100
+ ARGON2_TIME_TOO_SMALL = 12,
101
+ ARGON2_TIME_TOO_LARGE = 13,
102
+
103
+ ARGON2_MEMORY_TOO_LITTLE = 14,
104
+ ARGON2_MEMORY_TOO_MUCH = 15,
105
+
106
+ ARGON2_LANES_TOO_FEW = 16,
107
+ ARGON2_LANES_TOO_MANY = 17,
108
+
109
+ ARGON2_PWD_PTR_MISMATCH = 18, /* NULL ptr with non-zero length */
110
+ ARGON2_SALT_PTR_MISMATCH = 19, /* NULL ptr with non-zero length */
111
+ ARGON2_SECRET_PTR_MISMATCH = 20, /* NULL ptr with non-zero length */
112
+ ARGON2_AD_PTR_MISMATCH = 21, /* NULL ptr with non-zero length */
113
+
114
+ ARGON2_MEMORY_ALLOCATION_ERROR = 22,
115
+
116
+ ARGON2_FREE_MEMORY_CBK_NULL = 23,
117
+ ARGON2_ALLOCATE_MEMORY_CBK_NULL = 24,
118
+
119
+ ARGON2_INCORRECT_PARAMETER = 25,
120
+ ARGON2_INCORRECT_TYPE = 26,
121
+
122
+ ARGON2_OUT_PTR_MISMATCH = 27,
123
+
124
+ ARGON2_THREADS_TOO_FEW = 28,
125
+ ARGON2_THREADS_TOO_MANY = 29,
126
+
127
+ ARGON2_MISSING_ARGS = 30,
128
+
129
+ ARGON2_ERROR_CODES_LENGTH /* Do NOT remove; Do NOT add error codes after
130
+ this
131
+ error code */
132
+ } argon2_error_codes;
133
+
134
+ /* Memory allocator types --- for external allocation */
135
+ typedef int (*allocate_fptr)(uint8_t **memory, size_t bytes_to_allocate);
136
+ typedef void (*deallocate_fptr)(uint8_t *memory, size_t bytes_to_allocate);
137
+
138
+ /* Argon2 external data structures */
139
+
140
+ /*
141
+ *****Context: structure to hold Argon2 inputs:
142
+ * output array and its length,
143
+ * password and its length,
144
+ * salt and its length,
145
+ * secret and its length,
146
+ * associated data and its length,
147
+ * number of passes, amount of used memory (in KBytes, can be rounded up a bit)
148
+ * number of parallel threads that will be run.
149
+ * All the parameters above affect the output hash value.
150
+ * Additionally, two function pointers can be provided to allocate and
151
+ deallocate the memory (if NULL, memory will be allocated internally).
152
+ * Also, three flags indicate whether to erase password, secret as soon as they
153
+ are pre-hashed (and thus not needed anymore), and the entire memory
154
+ ****************************
155
+ Simplest situation: you have output array out[8], password is stored in
156
+ pwd[32], salt is stored in salt[16], you do not have keys nor associated data.
157
+ You need to spend 1 GB of RAM and you run 5 passes of Argon2d with 4 parallel
158
+ lanes.
159
+ You want to erase the password, but you're OK with last pass not being erased.
160
+ You want to use the default memory allocator.
161
+ Then you initialize
162
+ Argon2_Context(out,8,pwd,32,salt,16,NULL,0,NULL,0,5,1<<20,4,4,NULL,NULL,true,false,false,false).
163
+ */
164
+ typedef struct Argon2_Context {
165
+ uint8_t *out; /* output array */
166
+ uint32_t outlen; /* digest length */
167
+
168
+ uint8_t *pwd; /* password array */
169
+ uint32_t pwdlen; /* password length */
170
+
171
+ uint8_t *salt; /* salt array */
172
+ uint32_t saltlen; /* salt length */
173
+
174
+ uint8_t *secret; /* key array */
175
+ uint32_t secretlen; /* key length */
176
+
177
+ uint8_t *ad; /* associated data array */
178
+ uint32_t adlen; /* associated data length */
179
+
180
+ uint32_t t_cost; /* number of passes */
181
+ uint32_t m_cost; /* amount of memory requested (KB) */
182
+ uint32_t lanes; /* number of lanes */
183
+ uint32_t threads; /* maximum number of threads */
184
+
185
+ allocate_fptr allocate_cbk; /* pointer to memory allocator */
186
+ deallocate_fptr free_cbk; /* pointer to memory deallocator */
187
+
188
+ uint32_t flags; /* array of bool options */
189
+ } argon2_context;
190
+
191
+ /**
192
+ * Function to hash the inputs in the memory-hard fashion (uses Argon2i)
193
+ * @param out Pointer to the memory where the hash digest will be written
194
+ * @param outlen Digest length in bytes
195
+ * @param in Pointer to the input (password)
196
+ * @param inlen Input length in bytes
197
+ * @param salt Pointer to the salt
198
+ * @param saltlen Salt length in bytes
199
+ * @pre @a out must have at least @a outlen bytes allocated
200
+ * @pre @a in must be at least @inlen bytes long
201
+ * @pre @a saltlen must be at least @saltlen bytes long
202
+ * @return Zero if successful, 1 otherwise.
203
+ */
204
+ int hash_argon2i(void *out, size_t outlen, const void *in, size_t inlen,
205
+ const void *salt, size_t saltlen, unsigned int t_cost,
206
+ unsigned int m_cost);
207
+
208
+ /* same for argon2d */
209
+ int hash_argon2d(void *out, size_t outlen, const void *in, size_t inlen,
210
+ const void *salt, size_t saltlen, unsigned int t_cost,
211
+ unsigned int m_cost);
212
+
213
+ /*
214
+ * **************Argon2d: Version of Argon2 that picks memory blocks depending
215
+ * on the password and salt. Only for side-channel-free
216
+ * environment!!***************
217
+ * @param context Pointer to current Argon2 context
218
+ * @return Zero if successful, a non zero error code otherwise
219
+ */
220
+ int argon2d(argon2_context *context);
221
+
222
+ /*
223
+ * * **************Argon2i: Version of Argon2 that picks memory blocks
224
+ *independent on the password and salt. Good for side-channels,
225
+ ******************* but worse w.r.t. tradeoff attacks if
226
+ *******************only one pass is used***************
227
+ * @param context Pointer to current Argon2 context
228
+ * @return Zero if successful, a non zero error code otherwise
229
+ */
230
+ int argon2i(argon2_context *context);
231
+
232
+ /*
233
+ * * **************Argon2di: Reserved name***************
234
+ * @param context Pointer to current Argon2 context
235
+ * @return Zero if successful, a non zero error code otherwise
236
+ */
237
+ int argon2di(argon2_context *context);
238
+
239
+ /*
240
+ * * **************Argon2ds: Argon2d hardened against GPU attacks, 20%
241
+ * slower***************
242
+ * @param context Pointer to current Argon2 context
243
+ * @return Zero if successful, a non zero error code otherwise
244
+ */
245
+ int argon2ds(argon2_context *context);
246
+
247
+ /*
248
+ * * **************Argon2id: First half-pass over memory is
249
+ *password-independent, the rest are password-dependent
250
+ ********************OK against side channels: they reduce to 1/2-pass
251
+ *Argon2i***************
252
+ * @param context Pointer to current Argon2 context
253
+ * @return Zero if successful, a non zero error code otherwise
254
+ */
255
+ int argon2id(argon2_context *context);
256
+
257
+ /*
258
+ * Verify if a given password is correct for Argon2d hashing
259
+ * @param context Pointer to current Argon2 context
260
+ * @param hash The password hash to verify. The length of the hash is
261
+ * specified by the context outlen member
262
+ * @return Zero if successful, a non zero error code otherwise
263
+ */
264
+ int verify_d(argon2_context *context, const char *hash);
265
+
266
+ /*
267
+ * Get the associated error message for given error code
268
+ * @return The error message associated with the given error code
269
+ */
270
+ const char *error_message(int error_code);
271
+
272
+ /* ==================================================================== */
273
+ /*
274
+ * Code specific to Argon2i.
275
+ *
276
+ * The code below applies the following format:
277
+ *
278
+ * $argon2i$m=<num>,t=<num>,p=<num>[,keyid=<bin>][,data=<bin>][$<bin>[$<bin>]]
279
+ *
280
+ * where <num> is a decimal integer (positive, fits in an 'unsigned long')
281
+ * and <bin> is Base64-encoded data (no '=' padding characters, no newline
282
+ * or whitespace). The "keyid" is a binary identifier for a key (up to 8
283
+ * bytes); "data" is associated data (up to 32 bytes). When the 'keyid'
284
+ * (resp. the 'data') is empty, then it is ommitted from the output.
285
+ *
286
+ * The last two binary chunks (encoded in Base64) are, in that order,
287
+ * the salt and the output. Both are optional, but you cannot have an
288
+ * output without a salt. The binary salt length is between 8 and 48 bytes.
289
+ * The output length is always exactly 32 bytes.
290
+ */
291
+
292
+ int encode_string(char *dst, size_t dst_len, argon2_context *ctx);
293
+
294
+ #if defined(__cplusplus)
295
+ }
296
+ #endif
297
+
298
+ #endif