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 #ifndef ARGON2_CORE_H
19 #define ARGON2_CORE_H
20 
21 #include "argon2.h"
22 
23 #if defined(_MSC_VER)
24 #define ALIGN(n) __declspec(align(16))
25 #elif defined(__GNUC__) || defined(__clang)
26 #define ALIGN(x) __attribute__((__aligned__(x)))
27 #else
28 #define ALIGN(x)
29 #endif
30 
31 #define CONST_CAST(x) (x)(uintptr_t)
32 
33 /**********************Argon2 internal constants*******************************/
34 
35 enum argon2_core_constants {
36     /* Memory block size in bytes */
37     ARGON2_BLOCK_SIZE = 1024,
38     ARGON2_QWORDS_IN_BLOCK = ARGON2_BLOCK_SIZE / 8,
39     ARGON2_OWORDS_IN_BLOCK = ARGON2_BLOCK_SIZE / 16,
40 
41     /* Number of pseudo-random values generated by one call to Blake in Argon2i
42        to
43        generate reference block positions */
44     ARGON2_ADDRESSES_IN_BLOCK = 128,
45 
46     /* Pre-hashing digest length and its extension*/
47     ARGON2_PREHASH_DIGEST_LENGTH = 64,
48     ARGON2_PREHASH_SEED_LENGTH = 72
49 };
50 
51 /*************************Argon2 internal data types***********************/
52 
53 /*
54  * Structure for the (1KB) memory block implemented as 128 64-bit words.
55  * Memory blocks can be copied, XORed. Internal words can be accessed by [] (no
56  * bounds checking).
57  */
58 typedef struct block_ { uint64_t v[ARGON2_QWORDS_IN_BLOCK]; } block;
59 
60 /*****************Functions that work with the block******************/
61 
62 /* Initialize each byte of the block with @in */
63 static void init_block_value(block *b, uint8_t in);
64 
65 /* Copy block @src to block @dst */
66 static void copy_block(block *dst, const block *src);
67 
68 /* XOR @src onto @dst bytewise */
69 static void xor_block(block *dst, const block *src);
70 
71 /*
72  * Argon2 instance: memory pointer, number of passes, amount of memory, type,
73  * and derived values.
74  * Used to evaluate the number and location of blocks to construct in each
75  * thread
76  */
77 typedef struct Argon2_instance_t {
78     block *memory;          /* Memory pointer */
79     uint32_t version;
80     uint32_t passes;        /* Number of passes */
81     uint32_t memory_blocks; /* Number of blocks in memory */
82     uint32_t segment_length;
83     uint32_t lane_length;
84     uint32_t lanes;
85     uint32_t threads;
86     argon2_type type;
87     int print_internals; /* whether to print the memory blocks */
88     argon2_context *context_ptr; /* points back to original context */
89 } argon2_instance_t;
90 
91 /*
92  * Argon2 position: where we construct the block right now. Used to distribute
93  * work between threads.
94  */
95 typedef struct Argon2_position_t {
96     uint32_t pass;
97     uint32_t lane;
98     uint8_t slice;
99     uint32_t index;
100 } argon2_position_t;
101 
102 /*Struct that holds the inputs for thread handling FillSegment*/
103 typedef struct Argon2_thread_data {
104     argon2_instance_t *instance_ptr;
105     argon2_position_t pos;
106 } argon2_thread_data;
107 
108 /*************************Argon2 core functions********************************/
109 
110 /* Allocates memory to the given pointer, uses the appropriate allocator as
111  * specified in the context. Total allocated memory is num*size.
112  * @param context argon2_context which specifies the allocator
113  * @param memory pointer to the pointer to the memory
114  * @param size the size in bytes for each element to be allocated
115  * @param num the number of elements to be allocated
116  * @return ARGON2_OK if @memory is a valid pointer and memory is allocated
117  */
118 static int allocate_memory(const argon2_context *context, uint8_t **memory,
119                     size_t num, size_t size);
120 
121 /*
122  * Frees memory at the given pointer, uses the appropriate deallocator as
123  * specified in the context. Also cleans the memory using clear_internal_memory.
124  * @param context argon2_context which specifies the deallocator
125  * @param memory pointer to buffer to be freed
126  * @param size the size in bytes for each element to be deallocated
127  * @param num the number of elements to be deallocated
128  */
129 static void free_memory(const argon2_context *context, uint8_t *memory,
130                  size_t num, size_t size);
131 
132 /* Function that securely cleans the memory. This ignores any flags set
133  * regarding clearing memory. Usually one just calls clear_internal_memory.
134  * @param mem Pointer to the memory
135  * @param s Memory size in bytes
136  */
137 static void secure_wipe_memory(void *v, size_t n);
138 
139 /* Function that securely clears the memory if FLAG_clear_internal_memory is
140  * set. If the flag isn't set, this function does nothing.
141  * @param mem Pointer to the memory
142  * @param s Memory size in bytes
143  */
144 static void clear_internal_memory(void *v, size_t n);
145 
146 /*
147  * Computes absolute position of reference block in the lane following a skewed
148  * distribution and using a pseudo-random value as input
149  * @param instance Pointer to the current instance
150  * @param position Pointer to the current position
151  * @param pseudo_rand 32-bit pseudo-random value used to determine the position
152  * @param same_lane Indicates if the block will be taken from the current lane.
153  * If so we can reference the current segment
154  * @pre All pointers must be valid
155  */
156 static uint32_t index_alpha(const argon2_instance_t *instance,
157                      const argon2_position_t *position, uint32_t pseudo_rand,
158                      int same_lane);
159 
160 /*
161  * Function that validates all inputs against predefined restrictions and return
162  * an error code
163  * @param context Pointer to current Argon2 context
164  * @return ARGON2_OK if everything is all right, otherwise one of error codes
165  * (all defined in <argon2.h>
166  */
167 static int validate_inputs(const argon2_context *context);
168 
169 /*
170  * Hashes all the inputs into @a blockhash[PREHASH_DIGEST_LENGTH], clears
171  * password and secret if needed
172  * @param  context  Pointer to the Argon2 internal structure containing memory
173  * pointer, and parameters for time and space requirements.
174  * @param  blockhash Buffer for pre-hashing digest
175  * @param  type Argon2 type
176  * @pre    @a blockhash must have at least @a PREHASH_DIGEST_LENGTH bytes
177  * allocated
178  */
179 static void initial_hash(uint8_t *blockhash, argon2_context *context,
180                   argon2_type type);
181 
182 /*
183  * Function creates first 2 blocks per lane
184  * @param instance Pointer to the current instance
185  * @param blockhash Pointer to the pre-hashing digest
186  * @pre blockhash must point to @a PREHASH_SEED_LENGTH allocated values
187  */
188 static void fill_first_blocks(uint8_t *blockhash, const argon2_instance_t *instance);
189 
190 /*
191  * Function allocates memory, hashes the inputs with Blake,  and creates first
192  * two blocks. Returns the pointer to the main memory with 2 blocks per lane
193  * initialized
194  * @param  context  Pointer to the Argon2 internal structure containing memory
195  * pointer, and parameters for time and space requirements.
196  * @param  instance Current Argon2 instance
197  * @return Zero if successful, -1 if memory failed to allocate. @context->state
198  * will be modified if successful.
199  */
200 static int initialize(argon2_instance_t *instance, argon2_context *context);
201 
202 /*
203  * XORing the last block of each lane, hashing it, making the tag. Deallocates
204  * the memory.
205  * @param context Pointer to current Argon2 context (use only the out parameters
206  * from it)
207  * @param instance Pointer to current instance of Argon2
208  * @pre instance->state must point to necessary amount of memory
209  * @pre context->out must point to outlen bytes of memory
210  * @pre if context->free_cbk is not NULL, it should point to a function that
211  * deallocates memory
212  */
213 static void finalize(const argon2_context *context, argon2_instance_t *instance);
214 
215 /*
216  * Function that fills the segment using previous segments also from other
217  * threads
218  * @param context current context
219  * @param instance Pointer to the current instance
220  * @param position Current position
221  * @pre all block pointers must be valid
222  */
223 static void fill_segment(const argon2_instance_t *instance,
224                   argon2_position_t position);
225 
226 /*
227  * Function that fills the entire memory t_cost times based on the first two
228  * blocks in each lane
229  * @param instance Pointer to the current instance
230  * @return ARGON2_OK if successful, @context->state
231  */
232 static int fill_memory_blocks(argon2_instance_t *instance);
233 
234 #endif
235