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,162 @@
1
+ #ifndef BLAKE_ROUND_MKA_OPT_H
2
+ #define BLAKE_ROUND_MKA_OPT_H
3
+
4
+ #include "blake2-impl.h"
5
+
6
+ #if defined(_MSC_VER)
7
+ #include <intrin.h>
8
+ #endif
9
+
10
+ #include <immintrin.h>
11
+ #if defined(__XOP__) && (defined(__GNUC__) || defined(__clang__))
12
+ #include <x86intrin.h>
13
+ #endif
14
+
15
+ #if !defined(__XOP__)
16
+ #if defined(__SSSE3__)
17
+ #define r16 \
18
+ (_mm_setr_epi8(2, 3, 4, 5, 6, 7, 0, 1, 10, 11, 12, 13, 14, 15, 8, 9))
19
+ #define r24 \
20
+ (_mm_setr_epi8(3, 4, 5, 6, 7, 0, 1, 2, 11, 12, 13, 14, 15, 8, 9, 10))
21
+ #define _mm_roti_epi64(x, c) \
22
+ (-(c) == 32) \
23
+ ? _mm_shuffle_epi32((x), _MM_SHUFFLE(2, 3, 0, 1)) \
24
+ : (-(c) == 24) \
25
+ ? _mm_shuffle_epi8((x), r24) \
26
+ : (-(c) == 16) \
27
+ ? _mm_shuffle_epi8((x), r16) \
28
+ : (-(c) == 63) \
29
+ ? _mm_xor_si128(_mm_srli_epi64((x), -(c)), \
30
+ _mm_add_epi64((x), (x))) \
31
+ : _mm_xor_si128(_mm_srli_epi64((x), -(c)), \
32
+ _mm_slli_epi64((x), 64 - (-(c))))
33
+ #else /* defined(__SSE2__) */
34
+ #define _mm_roti_epi64(r, c) \
35
+ _mm_xor_si128(_mm_srli_epi64((r), -(c)), _mm_slli_epi64((r), 64 - (-(c))))
36
+ #endif
37
+ #else
38
+ #endif
39
+
40
+ static BLAKE2_INLINE __m128i fBlaMka(__m128i x, __m128i y) {
41
+ const __m128i z = _mm_mul_epu32(x, y);
42
+ return _mm_add_epi64(_mm_add_epi64(x, y), _mm_add_epi64(z, z));
43
+ }
44
+
45
+ #define G1(A0, B0, C0, D0, A1, B1, C1, D1) \
46
+ do { \
47
+ A0 = fBlaMka(A0, B0); \
48
+ A1 = fBlaMka(A1, B1); \
49
+ \
50
+ D0 = _mm_xor_si128(D0, A0); \
51
+ D1 = _mm_xor_si128(D1, A1); \
52
+ \
53
+ D0 = _mm_roti_epi64(D0, -32); \
54
+ D1 = _mm_roti_epi64(D1, -32); \
55
+ \
56
+ C0 = fBlaMka(C0, D0); \
57
+ C1 = fBlaMka(C1, D1); \
58
+ \
59
+ B0 = _mm_xor_si128(B0, C0); \
60
+ B1 = _mm_xor_si128(B1, C1); \
61
+ \
62
+ B0 = _mm_roti_epi64(B0, -24); \
63
+ B1 = _mm_roti_epi64(B1, -24); \
64
+ } while ((void)0, 0)
65
+
66
+ #define G2(A0, B0, C0, D0, A1, B1, C1, D1) \
67
+ do { \
68
+ A0 = fBlaMka(A0, B0); \
69
+ A1 = fBlaMka(A1, B1); \
70
+ \
71
+ D0 = _mm_xor_si128(D0, A0); \
72
+ D1 = _mm_xor_si128(D1, A1); \
73
+ \
74
+ D0 = _mm_roti_epi64(D0, -16); \
75
+ D1 = _mm_roti_epi64(D1, -16); \
76
+ \
77
+ C0 = fBlaMka(C0, D0); \
78
+ C1 = fBlaMka(C1, D1); \
79
+ \
80
+ B0 = _mm_xor_si128(B0, C0); \
81
+ B1 = _mm_xor_si128(B1, C1); \
82
+ \
83
+ B0 = _mm_roti_epi64(B0, -63); \
84
+ B1 = _mm_roti_epi64(B1, -63); \
85
+ } while ((void)0, 0)
86
+
87
+ #if defined(__SSSE3__)
88
+ #define DIAGONALIZE(A0, B0, C0, D0, A1, B1, C1, D1) \
89
+ do { \
90
+ __m128i t0 = _mm_alignr_epi8(B1, B0, 8); \
91
+ __m128i t1 = _mm_alignr_epi8(B0, B1, 8); \
92
+ B0 = t0; \
93
+ B1 = t1; \
94
+ \
95
+ t0 = C0; \
96
+ C0 = C1; \
97
+ C1 = t0; \
98
+ \
99
+ t0 = _mm_alignr_epi8(D1, D0, 8); \
100
+ t1 = _mm_alignr_epi8(D0, D1, 8); \
101
+ D0 = t1; \
102
+ D1 = t0; \
103
+ } while ((void)0, 0)
104
+
105
+ #define UNDIAGONALIZE(A0, B0, C0, D0, A1, B1, C1, D1) \
106
+ do { \
107
+ __m128i t0 = _mm_alignr_epi8(B0, B1, 8); \
108
+ __m128i t1 = _mm_alignr_epi8(B1, B0, 8); \
109
+ B0 = t0; \
110
+ B1 = t1; \
111
+ \
112
+ t0 = C0; \
113
+ C0 = C1; \
114
+ C1 = t0; \
115
+ \
116
+ t0 = _mm_alignr_epi8(D0, D1, 8); \
117
+ t1 = _mm_alignr_epi8(D1, D0, 8); \
118
+ D0 = t1; \
119
+ D1 = t0; \
120
+ } while ((void)0, 0)
121
+ #else /* SSE2 */
122
+ #define DIAGONALIZE(A0, B0, C0, D0, A1, B1, C1, D1) \
123
+ do { \
124
+ __m128i t0 = D0; \
125
+ __m128i t1 = B0; \
126
+ D0 = C0; \
127
+ C0 = C1; \
128
+ C1 = D0; \
129
+ D0 = _mm_unpackhi_epi64(D1, _mm_unpacklo_epi64(t0, t0)); \
130
+ D1 = _mm_unpackhi_epi64(t0, _mm_unpacklo_epi64(D1, D1)); \
131
+ B0 = _mm_unpackhi_epi64(B0, _mm_unpacklo_epi64(B1, B1)); \
132
+ B1 = _mm_unpackhi_epi64(B1, _mm_unpacklo_epi64(t1, t1)); \
133
+ } while ((void)0, 0)
134
+
135
+ #define UNDIAGONALIZE(A0, B0, C0, D0, A1, B1, C1, D1) \
136
+ do { \
137
+ __m128i t0 = C0; \
138
+ C0 = C1; \
139
+ C1 = t0; \
140
+ t0 = B0; \
141
+ __m128i t1 = D0; \
142
+ B0 = _mm_unpackhi_epi64(B1, _mm_unpacklo_epi64(B0, B0)); \
143
+ B1 = _mm_unpackhi_epi64(t0, _mm_unpacklo_epi64(B1, B1)); \
144
+ D0 = _mm_unpackhi_epi64(D0, _mm_unpacklo_epi64(D1, D1)); \
145
+ D1 = _mm_unpackhi_epi64(D1, _mm_unpacklo_epi64(t1, t1)); \
146
+ } while ((void)0, 0)
147
+ #endif
148
+
149
+ #define BLAKE2_ROUND(A0, A1, B0, B1, C0, C1, D0, D1) \
150
+ do { \
151
+ G1(A0, B0, C0, D0, A1, B1, C1, D1); \
152
+ G2(A0, B0, C0, D0, A1, B1, C1, D1); \
153
+ \
154
+ DIAGONALIZE(A0, B0, C0, D0, A1, B1, C1, D1); \
155
+ \
156
+ G1(A0, B0, C0, D0, A1, B1, C1, D1); \
157
+ G2(A0, B0, C0, D0, A1, B1, C1, D1); \
158
+ \
159
+ UNDIAGONALIZE(A0, B0, C0, D0, A1, B1, C1, D1); \
160
+ } while ((void)0, 0)
161
+
162
+ #endif
@@ -0,0 +1,39 @@
1
+ #ifndef BLAKE_ROUND_MKA_H
2
+ #define BLAKE_ROUND_MKA_H
3
+
4
+ #include "blake2.h"
5
+ #include "blake2-impl.h"
6
+
7
+ /*designed by the Lyra PHC team */
8
+ static BLAKE2_INLINE uint64_t fBlaMka(uint64_t x, uint64_t y) {
9
+ const uint64_t m = UINT64_C(0xFFFFFFFF);
10
+ const uint64_t xy = (x & m) * (y & m);
11
+ return x + y + 2 * xy;
12
+ }
13
+
14
+ #define G(a, b, c, d) \
15
+ do { \
16
+ a = fBlaMka(a, b); \
17
+ d = rotr64(d ^ a, 32); \
18
+ c = fBlaMka(c, d); \
19
+ b = rotr64(b ^ c, 24); \
20
+ a = fBlaMka(a, b); \
21
+ d = rotr64(d ^ a, 16); \
22
+ c = fBlaMka(c, d); \
23
+ b = rotr64(b ^ c, 63); \
24
+ } while ((void)0, 0)
25
+
26
+ #define BLAKE2_ROUND_NOMSG(v0, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, \
27
+ v12, v13, v14, v15) \
28
+ do { \
29
+ G(v0, v4, v8, v12); \
30
+ G(v1, v5, v9, v13); \
31
+ G(v2, v6, v10, v14); \
32
+ G(v3, v7, v11, v15); \
33
+ G(v0, v5, v10, v15); \
34
+ G(v1, v6, v11, v12); \
35
+ G(v2, v7, v8, v13); \
36
+ G(v3, v4, v9, v14); \
37
+ } while ((void)0, 0)
38
+
39
+ #endif
@@ -0,0 +1,662 @@
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
+ /*For memory wiping*/
15
+ #ifdef _MSC_VER
16
+ #include <windows.h>
17
+ #include <winbase.h> /* For SecureZeroMemory */
18
+ #endif
19
+ #if defined __STDC_LIB_EXT1__
20
+ #define __STDC_WANT_LIB_EXT1__ 1
21
+ #endif
22
+ #define VC_GE_2005(version) (version >= 1400)
23
+
24
+ #include <inttypes.h>
25
+ #include <stdio.h>
26
+ #include <stdlib.h>
27
+ #include <string.h>
28
+
29
+ #include "argon2.h"
30
+ #include "core.h"
31
+ #include "thread.h"
32
+ #include "blake2/blake2.h"
33
+ #include "blake2/blake2-impl.h"
34
+
35
+ #ifdef GENKAT
36
+ #include "genkat.h"
37
+ #endif
38
+
39
+ #if defined(__clang__)
40
+ #if __has_attribute(optnone)
41
+ #define NOT_OPTIMIZED __attribute__((optnone))
42
+ #endif
43
+ #elif defined(__GNUC__)
44
+ #define GCC_VERSION \
45
+ (__GNUC__ * 10000 + __GNUC_MINOR__ * 100 + __GNUC_PATCHLEVEL__)
46
+ #if GCC_VERSION >= 40400
47
+ #define NOT_OPTIMIZED __attribute__((optimize("O0")))
48
+ #endif
49
+ #endif
50
+ #ifndef NOT_OPTIMIZED
51
+ #define NOT_OPTIMIZED
52
+ #endif
53
+
54
+ /***************Instance and Position constructors**********/
55
+ void init_block_value(block *b, uint8_t in) { memset(b->v, in, sizeof(b->v)); }
56
+
57
+ void copy_block(block *dst, const block *src) {
58
+ memcpy(dst->v, src->v, sizeof(uint64_t) * ARGON2_WORDS_IN_BLOCK);
59
+ }
60
+
61
+ void xor_block(block *dst, const block *src) {
62
+ int i;
63
+ for (i = 0; i < ARGON2_WORDS_IN_BLOCK; ++i) {
64
+ dst->v[i] ^= src->v[i];
65
+ }
66
+ }
67
+
68
+ static void load_block(block *dst, const void *input) {
69
+ unsigned i;
70
+ for (i = 0; i < ARGON2_WORDS_IN_BLOCK; ++i) {
71
+ dst->v[i] = load64((const uint8_t *)input + i * sizeof(dst->v[i]));
72
+ }
73
+ }
74
+
75
+ static void store_block(void *output, const block *src) {
76
+ unsigned i;
77
+ for (i = 0; i < ARGON2_WORDS_IN_BLOCK; ++i) {
78
+ store64((uint8_t *)output + i * sizeof(src->v[i]), src->v[i]);
79
+ }
80
+ }
81
+
82
+ /***************Memory allocators*****************/
83
+ int allocate_memory(block **memory, uint32_t m_cost) {
84
+ if (memory != NULL) {
85
+ size_t memory_size = sizeof(block) * m_cost;
86
+ if (m_cost != 0 &&
87
+ memory_size / m_cost !=
88
+ sizeof(block)) { /*1. Check for multiplication overflow*/
89
+ return ARGON2_MEMORY_ALLOCATION_ERROR;
90
+ }
91
+
92
+ *memory = (block *)malloc(memory_size); /*2. Try to allocate*/
93
+
94
+ if (!*memory) {
95
+ return ARGON2_MEMORY_ALLOCATION_ERROR;
96
+ }
97
+
98
+ return ARGON2_OK;
99
+ } else {
100
+ return ARGON2_MEMORY_ALLOCATION_ERROR;
101
+ }
102
+ }
103
+
104
+ void NOT_OPTIMIZED secure_wipe_memory(void *v, size_t n) {
105
+ #if defined(_MSC_VER) && VC_GE_2005(_MSC_VER)
106
+ SecureZeroMemory(v, n);
107
+ #elif defined memset_s
108
+ memset_s(v, n);
109
+ #elif defined(__OpenBSD__)
110
+ explicit_bzero(v, n);
111
+ #else
112
+ static void *(*const volatile memset_sec)(void *, int, size_t) = &memset;
113
+ memset_sec(v, 0, n);
114
+ #endif
115
+ }
116
+
117
+ /*********Memory functions*/
118
+
119
+ void clear_memory(argon2_instance_t *instance, int clear) {
120
+ if (instance->memory != NULL && clear) {
121
+ secure_wipe_memory(instance->memory,
122
+ sizeof(block) * instance->memory_blocks);
123
+ }
124
+ }
125
+
126
+ void free_memory(block *memory) { free(memory); }
127
+
128
+ void finalize(const argon2_context *context, argon2_instance_t *instance) {
129
+ if (context != NULL && instance != NULL) {
130
+ block blockhash;
131
+ uint32_t l;
132
+
133
+ copy_block(&blockhash, instance->memory + instance->lane_length - 1);
134
+
135
+ /* XOR the last blocks */
136
+ for (l = 1; l < instance->lanes; ++l) {
137
+ uint32_t last_block_in_lane =
138
+ l * instance->lane_length + (instance->lane_length - 1);
139
+ xor_block(&blockhash, instance->memory + last_block_in_lane);
140
+ }
141
+
142
+ /* Hash the result */
143
+ {
144
+ uint8_t blockhash_bytes[ARGON2_BLOCK_SIZE];
145
+ store_block(blockhash_bytes, &blockhash);
146
+ blake2b_long(context->out, context->outlen, blockhash_bytes,
147
+ ARGON2_BLOCK_SIZE);
148
+ secure_wipe_memory(blockhash.v,
149
+ ARGON2_BLOCK_SIZE); /* clear blockhash */
150
+ secure_wipe_memory(blockhash_bytes,
151
+ ARGON2_BLOCK_SIZE); /* clear blockhash_bytes */
152
+ }
153
+
154
+ #ifdef GENKAT
155
+ print_tag(context->out, context->outlen);
156
+ #endif
157
+
158
+ /* Clear memory */
159
+ clear_memory(instance, context->flags & ARGON2_FLAG_CLEAR_PASSWORD);
160
+
161
+ /* Deallocate the memory */
162
+ if (NULL != context->free_cbk) {
163
+ context->free_cbk((uint8_t *)instance->memory,
164
+ instance->memory_blocks * sizeof(block));
165
+ } else {
166
+ free_memory(instance->memory);
167
+ }
168
+ }
169
+ }
170
+
171
+ uint32_t index_alpha(const argon2_instance_t *instance,
172
+ const argon2_position_t *position, uint32_t pseudo_rand,
173
+ int same_lane) {
174
+ /*
175
+ * Pass 0:
176
+ * This lane : all already finished segments plus already constructed
177
+ * blocks in this segment
178
+ * Other lanes : all already finished segments
179
+ * Pass 1+:
180
+ * This lane : (SYNC_POINTS - 1) last segments plus already constructed
181
+ * blocks in this segment
182
+ * Other lanes : (SYNC_POINTS - 1) last segments
183
+ */
184
+ uint32_t reference_area_size;
185
+ uint64_t relative_position;
186
+ uint32_t start_position, absolute_position;
187
+
188
+ if (0 == position->pass) {
189
+ /* First pass */
190
+ if (0 == position->slice) {
191
+ /* First slice */
192
+ reference_area_size =
193
+ position->index - 1; /* all but the previous */
194
+ } else {
195
+ if (same_lane) {
196
+ /* The same lane => add current segment */
197
+ reference_area_size =
198
+ position->slice * instance->segment_length +
199
+ position->index - 1;
200
+ } else {
201
+ reference_area_size =
202
+ position->slice * instance->segment_length +
203
+ ((position->index == 0) ? (-1) : 0);
204
+ }
205
+ }
206
+ } else {
207
+ /* Second pass */
208
+ if (same_lane) {
209
+ reference_area_size = instance->lane_length -
210
+ instance->segment_length + position->index -
211
+ 1;
212
+ } else {
213
+ reference_area_size = instance->lane_length -
214
+ instance->segment_length +
215
+ ((position->index == 0) ? (-1) : 0);
216
+ }
217
+ }
218
+
219
+ /* 1.2.4. Mapping pseudo_rand to 0..<reference_area_size-1> and produce
220
+ * relative position */
221
+ relative_position = pseudo_rand;
222
+ relative_position = relative_position * relative_position >> 32;
223
+ relative_position = reference_area_size - 1 -
224
+ (reference_area_size * relative_position >> 32);
225
+
226
+ /* 1.2.5 Computing starting position */
227
+ start_position = 0;
228
+
229
+ if (0 != position->pass) {
230
+ start_position = (position->slice == ARGON2_SYNC_POINTS - 1)
231
+ ? 0
232
+ : (position->slice + 1) * instance->segment_length;
233
+ }
234
+
235
+ /* 1.2.6. Computing absolute position */
236
+ absolute_position = (start_position + relative_position) %
237
+ instance->lane_length; /* absolute position */
238
+ return absolute_position;
239
+ }
240
+
241
+ #ifdef _WIN32
242
+ static unsigned __stdcall fill_segment_thr(void *thread_data)
243
+ #else
244
+ static void *fill_segment_thr(void *thread_data)
245
+ #endif
246
+ {
247
+ argon2_thread_data *my_data = (argon2_thread_data *)thread_data;
248
+ fill_segment(my_data->instance_ptr, my_data->pos);
249
+ argon2_thread_exit();
250
+ return 0;
251
+ }
252
+
253
+ void fill_memory_blocks(argon2_instance_t *instance) {
254
+ uint32_t r, s;
255
+ argon2_thread_handle_t *thread = NULL;
256
+ argon2_thread_data *thr_data = NULL;
257
+
258
+ if (instance == NULL || instance->lanes == 0) {
259
+ return;
260
+ }
261
+
262
+ /* 1. Allocating space for threads */
263
+ thread = calloc(instance->lanes, sizeof(argon2_thread_handle_t));
264
+ if (thread == NULL) {
265
+ return;
266
+ }
267
+
268
+ thr_data = calloc(instance->lanes, sizeof(argon2_thread_data));
269
+ if (thr_data == NULL) {
270
+ free(thread);
271
+ return;
272
+ }
273
+
274
+ for (r = 0; r < instance->passes; ++r) {
275
+ for (s = 0; s < ARGON2_SYNC_POINTS; ++s) {
276
+ int rc;
277
+ uint32_t l;
278
+
279
+ /* 2. Calling threads */
280
+ for (l = 0; l < instance->lanes; ++l) {
281
+ argon2_position_t position;
282
+
283
+ /* 2.1 Join a thread if limit is exceeded */
284
+ if (l >= instance->threads) {
285
+ rc = argon2_thread_join(thread[l - instance->threads]);
286
+ if (rc) {
287
+ printf(
288
+ "ERROR; return code from pthread_join() #1 is %d\n",
289
+ rc);
290
+ exit(-1);
291
+ }
292
+ }
293
+
294
+ /* 2.2 Create thread */
295
+ position.pass = r;
296
+ position.lane = l;
297
+ position.slice = (uint8_t)s;
298
+ position.index = 0;
299
+ thr_data[l].instance_ptr =
300
+ instance; /* preparing the thread input */
301
+ memcpy(&(thr_data[l].pos), &position,
302
+ sizeof(argon2_position_t));
303
+ rc = argon2_thread_create(&thread[l], &fill_segment_thr,
304
+ (void *)&thr_data[l]);
305
+ if (rc) {
306
+ printf("ERROR; return code from argon2_thread_create() is "
307
+ "%d\n",
308
+ rc);
309
+ exit(-1);
310
+ }
311
+
312
+ /* FillSegment(instance, position); */
313
+ /*Non-thread equivalent of the lines above */
314
+ }
315
+
316
+ /* 3. Joining remaining threads */
317
+ for (l = instance->lanes - instance->threads; l < instance->lanes;
318
+ ++l) {
319
+ rc = argon2_thread_join(thread[l]);
320
+ if (rc) {
321
+ printf("ERROR; return code from pthread_join() is %d\n",
322
+ rc);
323
+ exit(-1);
324
+ }
325
+ }
326
+ }
327
+
328
+ #ifdef GENKAT
329
+ internal_kat(instance, r); /* Print all memory blocks */
330
+ #endif
331
+ }
332
+
333
+ if (thread != NULL) {
334
+ free(thread);
335
+ }
336
+ if (thr_data != NULL) {
337
+ free(thr_data);
338
+ }
339
+ }
340
+
341
+ int validate_inputs(const argon2_context *context) {
342
+ if (NULL == context) {
343
+ return ARGON2_INCORRECT_PARAMETER;
344
+ }
345
+
346
+ if (NULL == context->out) {
347
+ return ARGON2_OUTPUT_PTR_NULL;
348
+ }
349
+
350
+ /* Validate output length */
351
+ if (ARGON2_MIN_OUTLEN > context->outlen) {
352
+ return ARGON2_OUTPUT_TOO_SHORT;
353
+ }
354
+
355
+ if (ARGON2_MAX_OUTLEN < context->outlen) {
356
+ return ARGON2_OUTPUT_TOO_LONG;
357
+ }
358
+
359
+ /* Validate password length */
360
+ if (NULL == context->pwd) {
361
+ if (0 != context->pwdlen) {
362
+ return ARGON2_PWD_PTR_MISMATCH;
363
+ }
364
+ } else {
365
+ if (ARGON2_MIN_PWD_LENGTH != 0 && /* TODO: Is this condition right? */
366
+ ARGON2_MIN_PWD_LENGTH > context->pwdlen) {
367
+ return ARGON2_PWD_TOO_SHORT;
368
+ }
369
+
370
+ if (ARGON2_MAX_PWD_LENGTH < context->pwdlen) {
371
+ return ARGON2_PWD_TOO_LONG;
372
+ }
373
+ }
374
+
375
+ /* Validate salt length */
376
+ if (NULL == context->salt) {
377
+ if (0 != context->saltlen) {
378
+ return ARGON2_SALT_PTR_MISMATCH;
379
+ }
380
+ } else {
381
+ if (ARGON2_MIN_SALT_LENGTH > context->saltlen) {
382
+ return ARGON2_SALT_TOO_SHORT;
383
+ }
384
+
385
+ if (ARGON2_MAX_SALT_LENGTH < context->saltlen) {
386
+ return ARGON2_SALT_TOO_LONG;
387
+ }
388
+ }
389
+
390
+ /* Validate secret length */
391
+ if (NULL == context->secret) {
392
+ if (0 != context->secretlen) {
393
+ return ARGON2_SECRET_PTR_MISMATCH;
394
+ }
395
+ } else {
396
+ if (ARGON2_MIN_SECRET > context->secretlen) {
397
+ return ARGON2_SECRET_TOO_SHORT;
398
+ }
399
+
400
+ if (ARGON2_MAX_SECRET < context->secretlen) {
401
+ return ARGON2_SECRET_TOO_LONG;
402
+ }
403
+ }
404
+
405
+ /* Validate associated data */
406
+ if (NULL == context->ad) {
407
+ if (0 != context->adlen) {
408
+ return ARGON2_AD_PTR_MISMATCH;
409
+ }
410
+ } else {
411
+ if (ARGON2_MIN_AD_LENGTH > context->adlen) {
412
+ return ARGON2_AD_TOO_SHORT;
413
+ }
414
+
415
+ if (ARGON2_MAX_AD_LENGTH < context->adlen) {
416
+ return ARGON2_AD_TOO_LONG;
417
+ }
418
+ }
419
+
420
+ /* Validate memory cost */
421
+ if (ARGON2_MIN_MEMORY > context->m_cost) {
422
+ return ARGON2_MEMORY_TOO_LITTLE;
423
+ }
424
+
425
+ if (ARGON2_MAX_MEMORY < context->m_cost) {
426
+ return ARGON2_MEMORY_TOO_MUCH;
427
+ }
428
+
429
+ /* Validate time cost */
430
+ if (ARGON2_MIN_TIME > context->t_cost) {
431
+ return ARGON2_TIME_TOO_SMALL;
432
+ }
433
+
434
+ if (ARGON2_MAX_TIME < context->t_cost) {
435
+ return ARGON2_TIME_TOO_LARGE;
436
+ }
437
+
438
+ /* Validate lanes */
439
+ if (ARGON2_MIN_LANES > context->lanes) {
440
+ return ARGON2_LANES_TOO_FEW;
441
+ }
442
+
443
+ if (ARGON2_MAX_LANES < context->lanes) {
444
+ return ARGON2_LANES_TOO_MANY;
445
+ }
446
+
447
+ /* Validate threads */
448
+ if (ARGON2_MIN_THREADS > context->threads) {
449
+ return ARGON2_THREADS_TOO_FEW;
450
+ }
451
+
452
+ if (ARGON2_MAX_THREADS < context->threads) {
453
+ return ARGON2_THREADS_TOO_MANY;
454
+ }
455
+
456
+ if (NULL != context->allocate_cbk && NULL == context->free_cbk) {
457
+ return ARGON2_FREE_MEMORY_CBK_NULL;
458
+ }
459
+
460
+ if (NULL == context->allocate_cbk && NULL != context->free_cbk) {
461
+ return ARGON2_ALLOCATE_MEMORY_CBK_NULL;
462
+ }
463
+
464
+ return ARGON2_OK;
465
+ }
466
+
467
+ void fill_first_blocks(uint8_t *blockhash, const argon2_instance_t *instance) {
468
+ uint32_t l;
469
+ /* Make the first and second block in each lane as G(H0||i||0) or
470
+ G(H0||i||1) */
471
+ uint8_t blockhash_bytes[ARGON2_BLOCK_SIZE];
472
+ for (l = 0; l < instance->lanes; ++l) {
473
+
474
+ store32(blockhash + ARGON2_PREHASH_DIGEST_LENGTH, 0);
475
+ store32(blockhash + ARGON2_PREHASH_DIGEST_LENGTH + 4, l);
476
+ blake2b_long(blockhash_bytes, ARGON2_BLOCK_SIZE, blockhash,
477
+ ARGON2_PREHASH_SEED_LENGTH);
478
+ load_block(&instance->memory[l * instance->lane_length + 0],
479
+ blockhash_bytes);
480
+
481
+ store32(blockhash + ARGON2_PREHASH_DIGEST_LENGTH, 1);
482
+ blake2b_long(blockhash_bytes, ARGON2_BLOCK_SIZE, blockhash,
483
+ ARGON2_PREHASH_SEED_LENGTH);
484
+ load_block(&instance->memory[l * instance->lane_length + 1],
485
+ blockhash_bytes);
486
+ }
487
+ secure_wipe_memory(blockhash_bytes, ARGON2_BLOCK_SIZE);
488
+ }
489
+
490
+ void initial_hash(uint8_t *blockhash, argon2_context *context,
491
+ argon2_type type) {
492
+ blake2b_state BlakeHash;
493
+ uint8_t value[sizeof(uint32_t)];
494
+
495
+ if (NULL == context || NULL == blockhash) {
496
+ return;
497
+ }
498
+
499
+ blake2b_init(&BlakeHash, ARGON2_PREHASH_DIGEST_LENGTH);
500
+
501
+ store32(&value, context->lanes);
502
+ blake2b_update(&BlakeHash, (const uint8_t *)&value, sizeof(value));
503
+
504
+ store32(&value, context->outlen);
505
+ blake2b_update(&BlakeHash, (const uint8_t *)&value, sizeof(value));
506
+
507
+ store32(&value, context->m_cost);
508
+ blake2b_update(&BlakeHash, (const uint8_t *)&value, sizeof(value));
509
+
510
+ store32(&value, context->t_cost);
511
+ blake2b_update(&BlakeHash, (const uint8_t *)&value, sizeof(value));
512
+
513
+ store32(&value, ARGON2_VERSION_NUMBER);
514
+ blake2b_update(&BlakeHash, (const uint8_t *)&value, sizeof(value));
515
+
516
+ store32(&value, (uint32_t)type);
517
+ blake2b_update(&BlakeHash, (const uint8_t *)&value, sizeof(value));
518
+
519
+ store32(&value, context->pwdlen);
520
+ blake2b_update(&BlakeHash, (const uint8_t *)&value, sizeof(value));
521
+
522
+ if (context->pwd != NULL) {
523
+ blake2b_update(&BlakeHash, (const uint8_t *)context->pwd,
524
+ context->pwdlen);
525
+
526
+ if (context->flags & ARGON2_FLAG_CLEAR_PASSWORD) {
527
+ secure_wipe_memory(context->pwd, context->pwdlen);
528
+ context->pwdlen = 0;
529
+ }
530
+ }
531
+
532
+ store32(&value, context->saltlen);
533
+ blake2b_update(&BlakeHash, (const uint8_t *)&value, sizeof(value));
534
+
535
+ if (context->salt != NULL) {
536
+ blake2b_update(&BlakeHash, (const uint8_t *)context->salt,
537
+ context->saltlen);
538
+ }
539
+
540
+ store32(&value, context->secretlen);
541
+ blake2b_update(&BlakeHash, (const uint8_t *)&value, sizeof(value));
542
+
543
+ if (context->secret != NULL) {
544
+ blake2b_update(&BlakeHash, (const uint8_t *)context->secret,
545
+ context->secretlen);
546
+
547
+ if (context->flags & ARGON2_FLAG_CLEAR_SECRET) {
548
+ secure_wipe_memory(context->secret, context->secretlen);
549
+ context->secretlen = 0;
550
+ }
551
+ }
552
+
553
+ store32(&value, context->adlen);
554
+ blake2b_update(&BlakeHash, (const uint8_t *)&value, sizeof(value));
555
+
556
+ if (context->ad != NULL) {
557
+ blake2b_update(&BlakeHash, (const uint8_t *)context->ad,
558
+ context->adlen);
559
+ }
560
+
561
+ blake2b_final(&BlakeHash, blockhash, ARGON2_PREHASH_DIGEST_LENGTH);
562
+ }
563
+
564
+ int initialize(argon2_instance_t *instance, argon2_context *context) {
565
+ uint8_t blockhash[ARGON2_PREHASH_SEED_LENGTH];
566
+ int result = ARGON2_OK;
567
+
568
+ if (instance == NULL || context == NULL)
569
+ return ARGON2_INCORRECT_PARAMETER;
570
+
571
+ /* 1. Memory allocation */
572
+
573
+ if (NULL != context->allocate_cbk) {
574
+ uint8_t *p;
575
+ result = context->allocate_cbk(&p, instance->memory_blocks *
576
+ ARGON2_BLOCK_SIZE);
577
+ if (ARGON2_OK != result) {
578
+ return result;
579
+ }
580
+ memcpy(&(instance->memory), p, sizeof(instance->memory));
581
+ } else {
582
+ result = allocate_memory(&(instance->memory), instance->memory_blocks);
583
+ if (ARGON2_OK != result) {
584
+ return result;
585
+ }
586
+ }
587
+
588
+ /* 2. Initial hashing */
589
+ /* H_0 + 8 extra bytes to produce the first blocks */
590
+ /* uint8_t blockhash[ARGON2_PREHASH_SEED_LENGTH]; */
591
+ /* Hashing all inputs */
592
+ initial_hash(blockhash, context, instance->type);
593
+ /* Zeroing 8 extra bytes */
594
+ secure_wipe_memory(blockhash + ARGON2_PREHASH_DIGEST_LENGTH,
595
+ ARGON2_PREHASH_SEED_LENGTH -
596
+ ARGON2_PREHASH_DIGEST_LENGTH);
597
+
598
+ #ifdef GENKAT
599
+ initial_kat(blockhash, context, instance->type);
600
+ #endif
601
+
602
+ /* 3. Creating first blocks, we always have at least two blocks in a slice
603
+ */
604
+ fill_first_blocks(blockhash, instance);
605
+ /* Clearing the hash */
606
+ secure_wipe_memory(blockhash, ARGON2_PREHASH_SEED_LENGTH);
607
+
608
+ return ARGON2_OK;
609
+ }
610
+
611
+ int argon2_core(argon2_context *context, argon2_type type) {
612
+ /* 1. Validate all inputs */
613
+ int result = validate_inputs(context);
614
+ uint32_t memory_blocks, segment_length;
615
+ argon2_instance_t instance;
616
+
617
+ if (ARGON2_OK != result) {
618
+ return result;
619
+ }
620
+
621
+ if (Argon2_d != type && Argon2_i != type) {
622
+ return ARGON2_INCORRECT_TYPE;
623
+ }
624
+
625
+ /* 2. Align memory size */
626
+ /* Minimum memory_blocks = 8L blocks, where L is the number of lanes */
627
+ memory_blocks = context->m_cost;
628
+
629
+ if (memory_blocks < 2 * ARGON2_SYNC_POINTS * context->lanes) {
630
+ memory_blocks = 2 * ARGON2_SYNC_POINTS * context->lanes;
631
+ }
632
+
633
+ segment_length = memory_blocks / (context->lanes * ARGON2_SYNC_POINTS);
634
+ /* Ensure that all segments have equal length */
635
+ memory_blocks = segment_length * (context->lanes * ARGON2_SYNC_POINTS);
636
+
637
+ instance.memory = NULL;
638
+ instance.passes = context->t_cost;
639
+ instance.memory_blocks = memory_blocks;
640
+ instance.segment_length = segment_length;
641
+ instance.lane_length = segment_length * ARGON2_SYNC_POINTS;
642
+ instance.lanes = context->lanes;
643
+ instance.threads = context->threads;
644
+ instance.type = type;
645
+
646
+ /* 3. Initialization: Hashing inputs, allocating memory, filling first
647
+ * blocks
648
+ */
649
+ result = initialize(&instance, context);
650
+
651
+ if (ARGON2_OK != result) {
652
+ return result;
653
+ }
654
+
655
+ /* 4. Filling memory */
656
+ fill_memory_blocks(&instance);
657
+
658
+ /* 5. Finalization */
659
+ finalize(context, &instance);
660
+
661
+ return ARGON2_OK;
662
+ }