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 * modified by Agnieszka Bielec <bielecagnieszka8 at gmail.com>
13 */
14
15 /*For memory wiping*/
16 #ifdef _MSC_VER
17 #include <windows.h>
18 #include <winbase.h> /* For SecureZeroMemory */
19 #endif
20 #if defined __STDC_LIB_EXT1__
21 #define __STDC_WANT_LIB_EXT1__ 1
22 #endif
23 #define VC_GE_2005(version) (version >= 1400)
24
25 #include <stdint.h>
26 #include <stdio.h>
27 #include <stdlib.h>
28 #include <string.h>
29
30 #include "argon2_core.h"
31 //#include "argon2_thread.h"
32 #include "blake2.h"
33 #include "blake2-impl.h"
34
35
36 #if defined(__clang__)
37 #if __has_attribute(optnone)
38 #define NOT_OPTIMIZED __attribute__((optnone))
39 #endif
40 #elif defined(__GNUC__)
41 #define GCC_VERSION \
42 (__GNUC__ * 10000 + __GNUC_MINOR__ * 100 + __GNUC_PATCHLEVEL__)
43 #if GCC_VERSION >= 40400
44 #define NOT_OPTIMIZED __attribute__((optimize("O0")))
45 #endif
46 #endif
47 #ifndef NOT_OPTIMIZED
48 #define NOT_OPTIMIZED
49 #endif
50
51 static int blake2b_long(void *pout, size_t outlen, const void *in, size_t inlen);
52
53 /***************Instance and Position constructors**********/
argon2_init_block_value(block * b,uint8_t in)54 void argon2_init_block_value(block *b, uint8_t in) {
55 memset(b->v, in, sizeof(b->v));
56 }
57
argon2_copy_block(block * dst,const block * src)58 void argon2_copy_block(block *dst, const block *src) {
59 memcpy(dst->v, src->v, sizeof(uint64_t) * ARGON2_QWORDS_IN_BLOCK);
60 }
61
argon2_xor_block(block * dst,const block * src)62 void argon2_xor_block(block *dst, const block *src) {
63 int i;
64 for (i = 0; i < ARGON2_QWORDS_IN_BLOCK; ++i) {
65 dst->v[i] ^= src->v[i];
66 }
67 }
68
load_block(block * dst,const void * input)69 static void load_block(block *dst, const void *input) {
70 unsigned i;
71 for (i = 0; i < ARGON2_QWORDS_IN_BLOCK; ++i) {
72 dst->v[i] = load64((const uint8_t *)input + i * sizeof(dst->v[i]));
73 }
74 }
75
store_block(void * output,const block * src)76 static void store_block(void *output, const block *src) {
77 unsigned i;
78 for (i = 0; i < ARGON2_QWORDS_IN_BLOCK; ++i) {
79 store64((uint8_t *)output + i * sizeof(src->v[i]), src->v[i]);
80 }
81 }
82
argon2_finalize(const argon2_context * context,argon2_instance_t * instance)83 void argon2_finalize(const argon2_context *context, argon2_instance_t *instance) {
84 if (context != NULL && instance != NULL) {
85 block blockhash;
86 uint32_t l;
87
88 argon2_copy_block(&blockhash, instance->memory + instance->lane_length - 1);
89
90 /* XOR the last blocks */
91 for (l = 1; l < instance->lanes; ++l) {
92 uint32_t last_block_in_lane =
93 l * instance->lane_length + (instance->lane_length - 1);
94 argon2_xor_block(&blockhash, instance->memory + last_block_in_lane);
95 }
96
97 /* Hash the result */
98 {
99 uint8_t blockhash_bytes[ARGON2_BLOCK_SIZE];
100 store_block(blockhash_bytes, &blockhash);
101 blake2b_long(context->out, context->outlen, blockhash_bytes,
102 ARGON2_BLOCK_SIZE);
103 }
104
105 }
106 }
107
argon2_index_alpha(const argon2_instance_t * instance,const argon2_position_t * position,uint32_t pseudo_rand,int same_lane)108 uint32_t argon2_index_alpha(const argon2_instance_t *instance,
109 const argon2_position_t *position, uint32_t pseudo_rand,
110 int same_lane) {
111 /*
112 * Pass 0:
113 * This lane : all already finished segments plus already constructed
114 * blocks in this segment
115 * Other lanes : all already finished segments
116 * Pass 1+:
117 * This lane : (SYNC_POINTS - 1) last segments plus already constructed
118 * blocks in this segment
119 * Other lanes : (SYNC_POINTS - 1) last segments
120 */
121 uint32_t reference_area_size;
122 uint64_t relative_position;
123 uint32_t start_position, absolute_position;
124
125 if (0 == position->pass) {
126 /* First pass */
127 if (0 == position->slice) {
128 /* First slice */
129 reference_area_size =
130 position->index - 1; /* all but the previous */
131 } else {
132 if (same_lane) {
133 /* The same lane => add current segment */
134 reference_area_size =
135 position->slice * instance->segment_length +
136 position->index - 1;
137 } else {
138 reference_area_size =
139 position->slice * instance->segment_length +
140 ((position->index == 0) ? (-1) : 0);
141 }
142 }
143 } else {
144 /* Second pass */
145 if (same_lane) {
146 reference_area_size = instance->lane_length -
147 instance->segment_length + position->index -
148 1;
149 } else {
150 reference_area_size = instance->lane_length -
151 instance->segment_length +
152 ((position->index == 0) ? (-1) : 0);
153 }
154 }
155
156 /* 1.2.4. Mapping pseudo_rand to 0..<reference_area_size-1> and produce
157 * relative position */
158 relative_position = pseudo_rand;
159 relative_position = relative_position * relative_position >> 32;
160 relative_position = reference_area_size - 1 -
161 (reference_area_size * relative_position >> 32);
162
163 /* 1.2.5 Computing starting position */
164 start_position = 0;
165
166 if (0 != position->pass) {
167 start_position = (position->slice == ARGON2_SYNC_POINTS - 1)
168 ? 0
169 : (position->slice + 1) * instance->segment_length;
170 }
171
172 /* 1.2.6. Computing absolute position */
173 absolute_position = (start_position + relative_position) %
174 instance->lane_length; /* absolute position */
175 return absolute_position;
176 }
177
178 #ifdef _WIN32
fill_segment_thr(void * thread_data)179 static unsigned __stdcall fill_segment_thr(void *thread_data)
180 #else
181 static void *fill_segment_thr(void *thread_data)
182 #endif
183 {
184 argon2_thread_data *my_data = (argon2_thread_data *)thread_data;
185 argon2_fill_segment(my_data->instance_ptr, my_data->pos);
186 //argon2_thread_exit();
187 return 0;
188 }
189
argon2_fill_memory_blocks(argon2_instance_t * instance)190 int argon2_fill_memory_blocks(argon2_instance_t *instance) {
191 uint32_t r, s;
192 //argon2_thread_handle_t *thread = NULL;
193 argon2_thread_data *thr_data = NULL;
194
195 if (instance == NULL || instance->lanes == 0) {
196 return ARGON2_THREAD_FAIL;
197 }
198
199 /* 1. Allocating space for threads */
200 /*thread = calloc(instance->lanes, sizeof(argon2_thread_handle_t));
201 if (thread == NULL) {
202 return ARGON2_MEMORY_ALLOCATION_ERROR;
203 }*/
204
205 thr_data = calloc(instance->lanes, sizeof(argon2_thread_data));
206 if (thr_data == NULL) {
207 //free(thread);
208 return ARGON2_MEMORY_ALLOCATION_ERROR;
209 }
210
211 for (r = 0; r < instance->passes; ++r) {
212 for (s = 0; s < ARGON2_SYNC_POINTS; ++s) {
213 //int rc;
214 uint32_t l;
215
216 /* 2. Calling threads */
217 for (l = 0; l < instance->lanes; ++l) {
218 argon2_position_t position;
219
220 /* 2.1 Join a thread if limit is exceeded */
221 if (l >= instance->threads) {
222 //rc = argon2_thread_join(thread[l - instance->threads]);
223 /*if (rc) {
224 free(thr_data);
225 //free(thread);
226 return ARGON2_THREAD_FAIL;
227 }*/
228 }
229
230 /* 2.2 Create thread */
231 position.pass = r;
232 position.lane = l;
233 position.slice = (uint8_t)s;
234 position.index = 0;
235 thr_data[l].instance_ptr =
236 instance; /* preparing the thread input */
237 memcpy(&(thr_data[l].pos), &position,
238 sizeof(argon2_position_t));
239 /*rc = argon2_thread_create(&thread[l], &fill_segment_thr,
240 (void *)&thr_data[l]);*/
241
242 fill_segment_thr((void *)&thr_data[l]);
243
244 /*if (rc) {
245 free(thr_data);
246 //free(thread);
247 return ARGON2_THREAD_FAIL;
248 }*/
249
250 /* argon2_fill_segment(instance, position); */
251 /*Non-thread equivalent of the lines above */
252 }
253
254 /* 3. Joining remaining threads */
255 for (l = instance->lanes - instance->threads; l < instance->lanes;
256 ++l) {
257 /*rc = argon2_thread_join(thread[l]);
258 if (rc) {
259 return ARGON2_THREAD_FAIL;
260 }*/
261 }
262 }
263 }
264
265 /*
266 if (thread != NULL) {
267 free(thread);
268 }
269 */
270 if (thr_data != NULL) {
271 free(thr_data);
272 }
273 return ARGON2_OK;
274 }
275
argon2_validate_inputs(const argon2_context * context)276 int argon2_validate_inputs(const argon2_context *context) {
277 if (NULL == context) {
278 return ARGON2_INCORRECT_PARAMETER;
279 }
280
281 if (NULL == context->out) {
282 return ARGON2_OUTPUT_PTR_NULL;
283 }
284
285 /* Validate output length */
286 if (ARGON2_MIN_OUTLEN > context->outlen) {
287 return ARGON2_OUTPUT_TOO_SHORT;
288 }
289
290 if (ARGON2_MAX_OUTLEN < context->outlen) {
291 return ARGON2_OUTPUT_TOO_LONG;
292 }
293
294 /* Validate password length */
295 if (NULL == context->pwd) {
296 if (0 != context->pwdlen) {
297 return ARGON2_PWD_PTR_MISMATCH;
298 }
299 } else {
300 #if 0 // -Wtype-limits
301 if (ARGON2_MIN_PWD_LENGTH > context->pwdlen) {
302 return ARGON2_PWD_TOO_SHORT;
303 }
304 #endif
305 if (ARGON2_MAX_PWD_LENGTH < context->pwdlen) {
306 return ARGON2_PWD_TOO_LONG;
307 }
308 }
309
310 /* Validate salt length */
311 if (NULL == context->salt) {
312 if (0 != context->saltlen) {
313 return ARGON2_SALT_PTR_MISMATCH;
314 }
315 } else {
316 if (ARGON2_MIN_SALT_LENGTH > context->saltlen) {
317 return ARGON2_SALT_TOO_SHORT;
318 }
319
320 if (ARGON2_MAX_SALT_LENGTH < context->saltlen) {
321 return ARGON2_SALT_TOO_LONG;
322 }
323 }
324
325 /* Validate memory cost */
326 if (ARGON2_MIN_MEMORY > context->m_cost) {
327 return ARGON2_MEMORY_TOO_LITTLE;
328 }
329 #if 0 // -Wtype-limits
330 if (ARGON2_MAX_MEMORY < context->m_cost) {
331 return ARGON2_MEMORY_TOO_MUCH;
332 }
333 #endif
334 if (context->m_cost < 8 * context->lanes) {
335 return ARGON2_MEMORY_TOO_LITTLE;
336 }
337
338 /* Validate time cost */
339 if (ARGON2_MIN_TIME > context->t_cost) {
340 return ARGON2_TIME_TOO_SMALL;
341 }
342
343 if (ARGON2_MAX_TIME < context->t_cost) {
344 return ARGON2_TIME_TOO_LARGE;
345 }
346
347 /* Validate lanes */
348 if (ARGON2_MIN_LANES > context->lanes) {
349 return ARGON2_LANES_TOO_FEW;
350 }
351
352 if (ARGON2_MAX_LANES < context->lanes) {
353 return ARGON2_LANES_TOO_MANY;
354 }
355
356 /* Validate threads */
357 if (ARGON2_MIN_THREADS > context->threads) {
358 return ARGON2_THREADS_TOO_FEW;
359 }
360
361 if (ARGON2_MAX_THREADS < context->threads) {
362 return ARGON2_THREADS_TOO_MANY;
363 }
364
365 return ARGON2_OK;
366 }
367
368 /*
369 * Function creates first 2 blocks per lane
370 * @param instance Pointer to the current instance
371 * @param blockhash Pointer to the pre-hashing digest
372 * @pre blockhash must point to @a PREHASH_SEED_LENGTH allocated values
373 */
fill_first_blocks(uint8_t * blockhash,const argon2_instance_t * instance)374 static void fill_first_blocks(uint8_t *blockhash, const argon2_instance_t *instance) {
375 uint32_t l;
376 /* Make the first and second block in each lane as G(H0||i||0) or
377 G(H0||i||1) */
378 uint8_t blockhash_bytes[ARGON2_BLOCK_SIZE];
379 for (l = 0; l < instance->lanes; ++l) {
380
381 store32(blockhash + ARGON2_PREHASH_DIGEST_LENGTH, 0);
382 store32(blockhash + ARGON2_PREHASH_DIGEST_LENGTH + 4, l);
383 blake2b_long(blockhash_bytes, ARGON2_BLOCK_SIZE, blockhash,
384 ARGON2_PREHASH_SEED_LENGTH);
385 load_block(&instance->memory[l * instance->lane_length + 0],
386 blockhash_bytes);
387
388 store32(blockhash + ARGON2_PREHASH_DIGEST_LENGTH, 1);
389 blake2b_long(blockhash_bytes, ARGON2_BLOCK_SIZE, blockhash,
390 ARGON2_PREHASH_SEED_LENGTH);
391 load_block(&instance->memory[l * instance->lane_length + 1],
392 blockhash_bytes);
393 }
394 }
395
396 /*
397 * Hashes all the inputs into @a blockhash[PREHASH_DIGEST_LENGTH], clears
398 * password and secret if needed
399 * @param context Pointer to the Argon2 internal structure containing memory
400 * pointer, and parameters for time and space requirements.
401 * @param blockhash Buffer for pre-hashing digest
402 * @param type Argon2 type
403 * @pre @a blockhash must have at least @a PREHASH_DIGEST_LENGTH bytes
404 * allocated
405 */
argon2_initial_hash(uint8_t * blockhash,argon2_context * context,argon2_type type)406 static void argon2_initial_hash(uint8_t *blockhash, argon2_context *context,
407 argon2_type type) {
408 blake2b_state BlakeHash;
409 uint8_t value[sizeof(uint32_t)];
410
411 if (NULL == context || NULL == blockhash) {
412 return;
413 }
414
415 blake2b_init(&BlakeHash, ARGON2_PREHASH_DIGEST_LENGTH);
416
417 store32(&value, context->lanes);
418 blake2b_update(&BlakeHash, (const uint8_t *)&value, sizeof(value));
419
420 store32(&value, context->outlen);
421 blake2b_update(&BlakeHash, (const uint8_t *)&value, sizeof(value));
422
423 store32(&value, context->m_cost);
424 blake2b_update(&BlakeHash, (const uint8_t *)&value, sizeof(value));
425
426 store32(&value, context->t_cost);
427 blake2b_update(&BlakeHash, (const uint8_t *)&value, sizeof(value));
428
429 store32(&value, context->version);
430 blake2b_update(&BlakeHash, (const uint8_t *)&value, sizeof(value));
431
432 store32(&value, (uint32_t)type);
433 blake2b_update(&BlakeHash, (const uint8_t *)&value, sizeof(value));
434
435 store32(&value, context->pwdlen);
436 blake2b_update(&BlakeHash, (const uint8_t *)&value, sizeof(value));
437
438 if (context->pwd != NULL) {
439 blake2b_update(&BlakeHash, (const uint8_t *)context->pwd,
440 context->pwdlen);
441 }
442
443 store32(&value, context->saltlen);
444 blake2b_update(&BlakeHash, (const uint8_t *)&value, sizeof(value));
445
446 if (context->salt != NULL) {
447 blake2b_update(&BlakeHash, (const uint8_t *)context->salt,
448 context->saltlen);
449 }
450
451 store32(&value, context->secretlen);
452 blake2b_update(&BlakeHash, (const uint8_t *)&value, sizeof(value));
453
454 if (context->secret != NULL) {
455 blake2b_update(&BlakeHash, (const uint8_t *)context->secret,
456 context->secretlen);
457 }
458
459 store32(&value, context->adlen);
460 blake2b_update(&BlakeHash, (const uint8_t *)&value, sizeof(value));
461
462 if (context->ad != NULL) {
463 blake2b_update(&BlakeHash, (const uint8_t *)context->ad,
464 context->adlen);
465 }
466
467 blake2b_final(&BlakeHash, blockhash, ARGON2_PREHASH_DIGEST_LENGTH);
468 }
469
argon2_initialize(argon2_instance_t * instance,argon2_context * context)470 int argon2_initialize(argon2_instance_t *instance, argon2_context *context) {
471 uint8_t blockhash[ARGON2_PREHASH_SEED_LENGTH];
472
473 if (instance == NULL || context == NULL)
474 return ARGON2_INCORRECT_PARAMETER;
475
476
477 /* 2. Initial hashing */
478 /* H_0 + 8 extra bytes to produce the first blocks */
479 /* uint8_t blockhash[ARGON2_PREHASH_SEED_LENGTH]; */
480 /* Hashing all inputs */
481 argon2_initial_hash(blockhash, context, instance->type);
482
483 /* 3. Creating first blocks, we always have at least two blocks in a slice
484 */
485 fill_first_blocks(blockhash, instance);
486
487 return ARGON2_OK;
488 }
489
490
blake2b_long(void * pout,size_t outlen,const void * in,size_t inlen)491 static int blake2b_long(void *pout, size_t outlen, const void *in, size_t inlen) {
492 uint8_t *out = (uint8_t *)pout;
493 blake2b_state blake_state;
494 uint8_t outlen_bytes[sizeof(uint32_t)] = {0};
495 int ret = -1;
496
497 if (outlen > UINT32_MAX) {
498 goto fail;
499 }
500
501 /* Ensure little-endian byte order! */
502 store32(outlen_bytes, (uint32_t)outlen);
503
504 #define TRY(statement) \
505 do { \
506 ret = statement; \
507 if (ret < 0) { \
508 goto fail; \
509 } \
510 } while ((void)0, 0)
511
512 if (outlen <= BLAKE2B_OUTBYTES) {
513 TRY(blake2b_init(&blake_state, outlen));
514 TRY(blake2b_update(&blake_state, outlen_bytes, sizeof(outlen_bytes)));
515 TRY(blake2b_update(&blake_state, in, inlen));
516 TRY(blake2b_final(&blake_state, out, outlen));
517 } else {
518 uint32_t toproduce;
519 uint8_t out_buffer[BLAKE2B_OUTBYTES];
520 uint8_t in_buffer[BLAKE2B_OUTBYTES];
521 TRY(blake2b_init(&blake_state, BLAKE2B_OUTBYTES));
522 TRY(blake2b_update(&blake_state, outlen_bytes, sizeof(outlen_bytes)));
523 TRY(blake2b_update(&blake_state, in, inlen));
524 TRY(blake2b_final(&blake_state, out_buffer, BLAKE2B_OUTBYTES));
525 memcpy(out, out_buffer, BLAKE2B_OUTBYTES / 2);
526 out += BLAKE2B_OUTBYTES / 2;
527 toproduce = (uint32_t)outlen - BLAKE2B_OUTBYTES / 2;
528
529 while (toproduce > BLAKE2B_OUTBYTES) {
530 memcpy(in_buffer, out_buffer, BLAKE2B_OUTBYTES);
531 TRY(blake2b(out_buffer, in_buffer, NULL,
532 BLAKE2B_OUTBYTES , BLAKE2B_OUTBYTES, 0));
533 memcpy(out, out_buffer, BLAKE2B_OUTBYTES / 2);
534 out += BLAKE2B_OUTBYTES / 2;
535 toproduce -= BLAKE2B_OUTBYTES / 2;
536 }
537
538 memcpy(in_buffer, out_buffer, BLAKE2B_OUTBYTES);
539 TRY(blake2b(out_buffer, in_buffer, NULL, toproduce,
540 BLAKE2B_OUTBYTES, 0));
541 memcpy(out, out_buffer, toproduce);
542 }
543 fail:
544 //burn(&blake_state, sizeof(blake_state));
545 return ret;
546 #undef TRY
547 }
548