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**********/
60void init_block_value(block *b, uint8_t in) { memset(b->v, in, sizeof(b->v)); }
61
62void copy_block(block *dst, const block *src) {
63    memcpy(dst->v, src->v, sizeof(uint64_t) * ARGON2_QWORDS_IN_BLOCK);
64}
65
66void 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
73static 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
80static 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
89int 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
115void 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(__NetBSD__)
129#define HAVE_EXPLICIT_MEMSET 1
130#elif defined(__GLIBC__) && defined(__GLIBC_PREREQ)
131#if __GLIBC_PREREQ(2,25)
132#define HAVE_EXPLICIT_BZERO 1
133#endif
134#endif
135
136void NOT_OPTIMIZED secure_wipe_memory(void *v, size_t n) {
137#if defined(_MSC_VER) && VC_GE_2005(_MSC_VER)
138    SecureZeroMemory(v, n);
139#elif defined memset_s
140    memset_s(v, n, 0, n);
141#elif defined(HAVE_EXPLICIT_BZERO)
142    explicit_bzero(v, n);
143#elif defined(HAVE_EXPLICIT_MEMSET)
144    explicit_memset(v, 0, n);
145#else
146    static void *(*const volatile memset_sec)(void *, int, size_t) = &memset;
147    memset_sec(v, 0, n);
148#endif
149}
150
151/* Memory clear flag defaults to true. */
152int FLAG_clear_internal_memory = 1;
153void clear_internal_memory(void *v, size_t n) {
154  if (FLAG_clear_internal_memory && v) {
155    secure_wipe_memory(v, n);
156  }
157}
158
159void finalize(const argon2_context *context, argon2_instance_t *instance) {
160    if (context != NULL && instance != NULL) {
161        block blockhash;
162        uint32_t l;
163
164        copy_block(&blockhash, instance->memory + instance->lane_length - 1);
165
166        /* XOR the last blocks */
167        for (l = 1; l < instance->lanes; ++l) {
168            uint32_t last_block_in_lane =
169                l * instance->lane_length + (instance->lane_length - 1);
170            xor_block(&blockhash, instance->memory + last_block_in_lane);
171        }
172
173        /* Hash the result */
174        {
175            uint8_t blockhash_bytes[ARGON2_BLOCK_SIZE];
176            store_block(blockhash_bytes, &blockhash);
177            blake2b_long(context->out, context->outlen, blockhash_bytes,
178                         ARGON2_BLOCK_SIZE);
179            /* clear blockhash and blockhash_bytes */
180            clear_internal_memory(blockhash.v, ARGON2_BLOCK_SIZE);
181            clear_internal_memory(blockhash_bytes, ARGON2_BLOCK_SIZE);
182        }
183
184#ifdef GENKAT
185        print_tag(context->out, context->outlen);
186#endif
187
188        free_memory(context, (uint8_t *)instance->memory,
189                    instance->memory_blocks, sizeof(block));
190    }
191}
192
193uint32_t index_alpha(const argon2_instance_t *instance,
194                     const argon2_position_t *position, uint32_t pseudo_rand,
195                     int same_lane) {
196    /*
197     * Pass 0:
198     *      This lane : all already finished segments plus already constructed
199     * blocks in this segment
200     *      Other lanes : all already finished segments
201     * Pass 1+:
202     *      This lane : (SYNC_POINTS - 1) last segments plus already constructed
203     * blocks in this segment
204     *      Other lanes : (SYNC_POINTS - 1) last segments
205     */
206    uint32_t reference_area_size;
207    uint64_t relative_position;
208    uint32_t start_position, absolute_position;
209
210    if (0 == position->pass) {
211        /* First pass */
212        if (0 == position->slice) {
213            /* First slice */
214            reference_area_size =
215                position->index - 1; /* all but the previous */
216        } else {
217            if (same_lane) {
218                /* The same lane => add current segment */
219                reference_area_size =
220                    position->slice * instance->segment_length +
221                    position->index - 1;
222            } else {
223                reference_area_size =
224                    position->slice * instance->segment_length +
225                    ((position->index == 0) ? (-1) : 0);
226            }
227        }
228    } else {
229        /* Second pass */
230        if (same_lane) {
231            reference_area_size = instance->lane_length -
232                                  instance->segment_length + position->index -
233                                  1;
234        } else {
235            reference_area_size = instance->lane_length -
236                                  instance->segment_length +
237                                  ((position->index == 0) ? (-1) : 0);
238        }
239    }
240
241    /* 1.2.4. Mapping pseudo_rand to 0..<reference_area_size-1> and produce
242     * relative position */
243    relative_position = pseudo_rand;
244    relative_position = relative_position * relative_position >> 32;
245    relative_position = reference_area_size - 1 -
246                        (reference_area_size * relative_position >> 32);
247
248    /* 1.2.5 Computing starting position */
249    start_position = 0;
250
251    if (0 != position->pass) {
252        start_position = (position->slice == ARGON2_SYNC_POINTS - 1)
253                             ? 0
254                             : (position->slice + 1) * instance->segment_length;
255    }
256
257    /* 1.2.6. Computing absolute position */
258    absolute_position = (start_position + relative_position) %
259                        instance->lane_length; /* absolute position */
260    return absolute_position;
261}
262
263/* Single-threaded version for p=1 case */
264static int fill_memory_blocks_st(argon2_instance_t *instance) {
265    uint32_t r, s, l;
266
267    for (r = 0; r < instance->passes; ++r) {
268        for (s = 0; s < ARGON2_SYNC_POINTS; ++s) {
269            for (l = 0; l < instance->lanes; ++l) {
270                argon2_position_t position = {r, l, (uint8_t)s, 0};
271                fill_segment(instance, position);
272            }
273        }
274#ifdef GENKAT
275        internal_kat(instance, r); /* Print all memory blocks */
276#endif
277    }
278    return ARGON2_OK;
279}
280
281#if !defined(ARGON2_NO_THREADS)
282
283#ifdef _WIN32
284static unsigned __stdcall fill_segment_thr(void *thread_data)
285#else
286static void *fill_segment_thr(void *thread_data)
287#endif
288{
289    argon2_thread_data *my_data = thread_data;
290    fill_segment(my_data->instance_ptr, my_data->pos);
291    argon2_thread_exit();
292    return 0;
293}
294
295/* Multi-threaded version for p > 1 case */
296static int fill_memory_blocks_mt(argon2_instance_t *instance) {
297    uint32_t r, s;
298    argon2_thread_handle_t *thread = NULL;
299    argon2_thread_data *thr_data = NULL;
300    int rc = ARGON2_OK;
301
302    /* 1. Allocating space for threads */
303    thread = calloc(instance->lanes, sizeof(argon2_thread_handle_t));
304    if (thread == NULL) {
305        rc = ARGON2_MEMORY_ALLOCATION_ERROR;
306        goto fail;
307    }
308
309    thr_data = calloc(instance->lanes, sizeof(argon2_thread_data));
310    if (thr_data == NULL) {
311        rc = ARGON2_MEMORY_ALLOCATION_ERROR;
312        goto fail;
313    }
314
315    for (r = 0; r < instance->passes; ++r) {
316        for (s = 0; s < ARGON2_SYNC_POINTS; ++s) {
317            uint32_t l, ll;
318
319            /* 2. Calling threads */
320            for (l = 0; l < instance->lanes; ++l) {
321                argon2_position_t position;
322
323                /* 2.1 Join a thread if limit is exceeded */
324                if (l >= instance->threads) {
325                    if (argon2_thread_join(thread[l - instance->threads])) {
326                        rc = ARGON2_THREAD_FAIL;
327                        goto fail;
328                    }
329                }
330
331                /* 2.2 Create thread */
332                position.pass = r;
333                position.lane = l;
334                position.slice = (uint8_t)s;
335                position.index = 0;
336                thr_data[l].instance_ptr =
337                    instance; /* preparing the thread input */
338                memcpy(&(thr_data[l].pos), &position,
339                       sizeof(argon2_position_t));
340                if (argon2_thread_create(&thread[l], &fill_segment_thr,
341                                         (void *)&thr_data[l])) {
342                    /* Wait for already running threads */
343                    for (ll = 0; ll < l; ++ll)
344                        argon2_thread_join(thread[ll]);
345                    rc = ARGON2_THREAD_FAIL;
346                    goto fail;
347                }
348
349                /* fill_segment(instance, position); */
350                /*Non-thread equivalent of the lines above */
351            }
352
353            /* 3. Joining remaining threads */
354            for (l = instance->lanes - instance->threads; l < instance->lanes;
355                 ++l) {
356                if (argon2_thread_join(thread[l])) {
357                    rc = ARGON2_THREAD_FAIL;
358                    goto fail;
359                }
360            }
361        }
362
363#ifdef GENKAT
364        internal_kat(instance, r); /* Print all memory blocks */
365#endif
366    }
367
368fail:
369    if (thread != NULL) {
370        free(thread);
371    }
372    if (thr_data != NULL) {
373        free(thr_data);
374    }
375    return rc;
376}
377
378#endif /* ARGON2_NO_THREADS */
379
380int fill_memory_blocks(argon2_instance_t *instance) {
381	if (instance == NULL || instance->lanes == 0) {
382	    return ARGON2_INCORRECT_PARAMETER;
383    }
384#if defined(ARGON2_NO_THREADS)
385    return fill_memory_blocks_st(instance);
386#else
387    return instance->threads == 1 ?
388			fill_memory_blocks_st(instance) : fill_memory_blocks_mt(instance);
389#endif
390}
391
392int validate_inputs(const argon2_context *context) {
393    if (NULL == context) {
394        return ARGON2_INCORRECT_PARAMETER;
395    }
396
397    if (NULL == context->out) {
398        return ARGON2_OUTPUT_PTR_NULL;
399    }
400
401    /* Validate output length */
402    if (ARGON2_MIN_OUTLEN > context->outlen) {
403        return ARGON2_OUTPUT_TOO_SHORT;
404    }
405
406    if (ARGON2_MAX_OUTLEN < context->outlen) {
407        return ARGON2_OUTPUT_TOO_LONG;
408    }
409
410    /* Validate password (required param) */
411    if (NULL == context->pwd) {
412        if (0 != context->pwdlen) {
413            return ARGON2_PWD_PTR_MISMATCH;
414        }
415    }
416
417    if (ARGON2_MIN_PWD_LENGTH + 1 > context->pwdlen + 1) {
418      return ARGON2_PWD_TOO_SHORT;
419    }
420
421    if (ARGON2_MAX_PWD_LENGTH < context->pwdlen) {
422        return ARGON2_PWD_TOO_LONG;
423    }
424
425    /* Validate salt (required param) */
426    if (NULL == context->salt) {
427        if (0 != context->saltlen) {
428            return ARGON2_SALT_PTR_MISMATCH;
429        }
430    }
431
432    if (ARGON2_MIN_SALT_LENGTH > context->saltlen) {
433        return ARGON2_SALT_TOO_SHORT;
434    }
435
436    if (ARGON2_MAX_SALT_LENGTH < context->saltlen) {
437        return ARGON2_SALT_TOO_LONG;
438    }
439
440    /* Validate secret (optional param) */
441    if (NULL == context->secret) {
442        if (0 != context->secretlen) {
443            return ARGON2_SECRET_PTR_MISMATCH;
444        }
445    } else {
446        if (ARGON2_MIN_SECRET + 1 > context->secretlen + 1) {
447            return ARGON2_SECRET_TOO_SHORT;
448        }
449        if (ARGON2_MAX_SECRET < context->secretlen) {
450            return ARGON2_SECRET_TOO_LONG;
451        }
452    }
453
454    /* Validate associated data (optional param) */
455    if (NULL == context->ad) {
456        if (0 != context->adlen) {
457            return ARGON2_AD_PTR_MISMATCH;
458        }
459    } else {
460        if (ARGON2_MIN_AD_LENGTH + 1 > context->adlen + 1) {
461            return ARGON2_AD_TOO_SHORT;
462        }
463        if (ARGON2_MAX_AD_LENGTH < context->adlen) {
464            return ARGON2_AD_TOO_LONG;
465        }
466    }
467
468    /* Validate memory cost */
469    if (ARGON2_MIN_MEMORY > context->m_cost) {
470        return ARGON2_MEMORY_TOO_LITTLE;
471    }
472
473    if (ARGON2_MAX_MEMORY - 1 < context->m_cost - 1) {
474        return ARGON2_MEMORY_TOO_MUCH;
475    }
476
477    if (context->m_cost < 8 * context->lanes) {
478        return ARGON2_MEMORY_TOO_LITTLE;
479    }
480
481    /* Validate time cost */
482    if (ARGON2_MIN_TIME > context->t_cost) {
483        return ARGON2_TIME_TOO_SMALL;
484    }
485
486    if (ARGON2_MAX_TIME < context->t_cost) {
487        return ARGON2_TIME_TOO_LARGE;
488    }
489
490    /* Validate lanes */
491    if (ARGON2_MIN_LANES > context->lanes) {
492        return ARGON2_LANES_TOO_FEW;
493    }
494
495    if (ARGON2_MAX_LANES < context->lanes) {
496        return ARGON2_LANES_TOO_MANY;
497    }
498
499    /* Validate threads */
500    if (ARGON2_MIN_THREADS > context->threads) {
501        return ARGON2_THREADS_TOO_FEW;
502    }
503
504    if (ARGON2_MAX_THREADS < context->threads) {
505        return ARGON2_THREADS_TOO_MANY;
506    }
507
508    if (NULL != context->allocate_cbk && NULL == context->free_cbk) {
509        return ARGON2_FREE_MEMORY_CBK_NULL;
510    }
511
512    if (NULL == context->allocate_cbk && NULL != context->free_cbk) {
513        return ARGON2_ALLOCATE_MEMORY_CBK_NULL;
514    }
515
516    return ARGON2_OK;
517}
518
519void fill_first_blocks(uint8_t *blockhash, const argon2_instance_t *instance) {
520    uint32_t l;
521    /* Make the first and second block in each lane as G(H0||0||i) or
522       G(H0||1||i) */
523    uint8_t blockhash_bytes[ARGON2_BLOCK_SIZE];
524    for (l = 0; l < instance->lanes; ++l) {
525
526        store32(blockhash + ARGON2_PREHASH_DIGEST_LENGTH, 0);
527        store32(blockhash + ARGON2_PREHASH_DIGEST_LENGTH + 4, l);
528        blake2b_long(blockhash_bytes, ARGON2_BLOCK_SIZE, blockhash,
529                     ARGON2_PREHASH_SEED_LENGTH);
530        load_block(&instance->memory[l * instance->lane_length + 0],
531                   blockhash_bytes);
532
533        store32(blockhash + ARGON2_PREHASH_DIGEST_LENGTH, 1);
534        blake2b_long(blockhash_bytes, ARGON2_BLOCK_SIZE, blockhash,
535                     ARGON2_PREHASH_SEED_LENGTH);
536        load_block(&instance->memory[l * instance->lane_length + 1],
537                   blockhash_bytes);
538    }
539    clear_internal_memory(blockhash_bytes, ARGON2_BLOCK_SIZE);
540}
541
542void initial_hash(uint8_t *blockhash, argon2_context *context,
543                  argon2_type type) {
544    blake2b_state BlakeHash;
545    uint8_t value[sizeof(uint32_t)];
546
547    if (NULL == context || NULL == blockhash) {
548        return;
549    }
550
551    blake2b_init(&BlakeHash, ARGON2_PREHASH_DIGEST_LENGTH);
552
553    store32(&value, context->lanes);
554    blake2b_update(&BlakeHash, (const uint8_t *)&value, sizeof(value));
555
556    store32(&value, context->outlen);
557    blake2b_update(&BlakeHash, (const uint8_t *)&value, sizeof(value));
558
559    store32(&value, context->m_cost);
560    blake2b_update(&BlakeHash, (const uint8_t *)&value, sizeof(value));
561
562    store32(&value, context->t_cost);
563    blake2b_update(&BlakeHash, (const uint8_t *)&value, sizeof(value));
564
565    store32(&value, context->version);
566    blake2b_update(&BlakeHash, (const uint8_t *)&value, sizeof(value));
567
568    store32(&value, (uint32_t)type);
569    blake2b_update(&BlakeHash, (const uint8_t *)&value, sizeof(value));
570
571    store32(&value, context->pwdlen);
572    blake2b_update(&BlakeHash, (const uint8_t *)&value, sizeof(value));
573
574    if (context->pwd != NULL) {
575        blake2b_update(&BlakeHash, (const uint8_t *)context->pwd,
576                       context->pwdlen);
577
578        if (context->flags & ARGON2_FLAG_CLEAR_PASSWORD) {
579            secure_wipe_memory(context->pwd, context->pwdlen);
580            context->pwdlen = 0;
581        }
582    }
583
584    store32(&value, context->saltlen);
585    blake2b_update(&BlakeHash, (const uint8_t *)&value, sizeof(value));
586
587    if (context->salt != NULL) {
588        blake2b_update(&BlakeHash, (const uint8_t *)context->salt,
589                       context->saltlen);
590    }
591
592    store32(&value, context->secretlen);
593    blake2b_update(&BlakeHash, (const uint8_t *)&value, sizeof(value));
594
595    if (context->secret != NULL) {
596        blake2b_update(&BlakeHash, (const uint8_t *)context->secret,
597                       context->secretlen);
598
599        if (context->flags & ARGON2_FLAG_CLEAR_SECRET) {
600            secure_wipe_memory(context->secret, context->secretlen);
601            context->secretlen = 0;
602        }
603    }
604
605    store32(&value, context->adlen);
606    blake2b_update(&BlakeHash, (const uint8_t *)&value, sizeof(value));
607
608    if (context->ad != NULL) {
609        blake2b_update(&BlakeHash, (const uint8_t *)context->ad,
610                       context->adlen);
611    }
612
613    blake2b_final(&BlakeHash, blockhash, ARGON2_PREHASH_DIGEST_LENGTH);
614}
615
616int initialize(argon2_instance_t *instance, argon2_context *context) {
617    uint8_t blockhash[ARGON2_PREHASH_SEED_LENGTH];
618    int result = ARGON2_OK;
619
620    if (instance == NULL || context == NULL)
621        return ARGON2_INCORRECT_PARAMETER;
622    instance->context_ptr = context;
623
624    /* 1. Memory allocation */
625    result = allocate_memory(context, (uint8_t **)&(instance->memory),
626                             instance->memory_blocks, sizeof(block));
627    if (result != ARGON2_OK) {
628        return result;
629    }
630
631    /* 2. Initial hashing */
632    /* H_0 + 8 extra bytes to produce the first blocks */
633    /* uint8_t blockhash[ARGON2_PREHASH_SEED_LENGTH]; */
634    /* Hashing all inputs */
635    initial_hash(blockhash, context, instance->type);
636    /* Zeroing 8 extra bytes */
637    clear_internal_memory(blockhash + ARGON2_PREHASH_DIGEST_LENGTH,
638                          ARGON2_PREHASH_SEED_LENGTH -
639                              ARGON2_PREHASH_DIGEST_LENGTH);
640
641#ifdef GENKAT
642    initial_kat(blockhash, context, instance->type);
643#endif
644
645    /* 3. Creating first blocks, we always have at least two blocks in a slice
646     */
647    fill_first_blocks(blockhash, instance);
648    /* Clearing the hash */
649    clear_internal_memory(blockhash, ARGON2_PREHASH_SEED_LENGTH);
650
651    return ARGON2_OK;
652}
653