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