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