argon2 0.0.1 → 0.0.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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