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