argon2_core.h 8.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245
  1. /*
  2. Copyright (c) 2018 tevador
  3. This file is part of RandomX.
  4. RandomX is free software: you can redistribute it and/or modify
  5. it under the terms of the GNU General Public License as published by
  6. the Free Software Foundation, either version 3 of the License, or
  7. (at your option) any later version.
  8. RandomX is distributed in the hope that it will be useful,
  9. but WITHOUT ANY WARRANTY; without even the implied warranty of
  10. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  11. GNU General Public License for more details.
  12. You should have received a copy of the GNU General Public License
  13. along with RandomX. If not, see<http://www.gnu.org/licenses/>.
  14. */
  15. /* Original code from Argon2 reference source code package used under CC0 Licence
  16. * https://github.com/P-H-C/phc-winner-argon2
  17. * Copyright 2015
  18. * Daniel Dinu, Dmitry Khovratovich, Jean-Philippe Aumasson, and Samuel Neves
  19. */
  20. #ifndef ARGON2_CORE_H
  21. #define ARGON2_CORE_H
  22. #include <stdint.h>
  23. #include "argon2.h"
  24. #if defined(__cplusplus)
  25. extern "C" {
  26. #endif
  27. #define CONST_CAST(x) (x)(uintptr_t)
  28. /**********************Argon2 internal constants*******************************/
  29. enum argon2_core_constants {
  30. /* Memory block size in bytes */
  31. ARGON2_BLOCK_SIZE = 1024,
  32. ARGON2_QWORDS_IN_BLOCK = ARGON2_BLOCK_SIZE / 8,
  33. ARGON2_OWORDS_IN_BLOCK = ARGON2_BLOCK_SIZE / 16,
  34. ARGON2_HWORDS_IN_BLOCK = ARGON2_BLOCK_SIZE / 32,
  35. ARGON2_512BIT_WORDS_IN_BLOCK = ARGON2_BLOCK_SIZE / 64,
  36. /* Number of pseudo-random values generated by one call to Blake in Argon2i
  37. to
  38. generate reference block positions */
  39. ARGON2_ADDRESSES_IN_BLOCK = 128,
  40. /* Pre-hashing digest length and its extension*/
  41. ARGON2_PREHASH_DIGEST_LENGTH = 64,
  42. ARGON2_PREHASH_SEED_LENGTH = 72
  43. };
  44. /*************************Argon2 internal data types***********************/
  45. /*
  46. * Structure for the (1KB) memory block implemented as 128 64-bit words.
  47. * Memory blocks can be copied, XORed. Internal words can be accessed by [] (no
  48. * bounds checking).
  49. */
  50. typedef struct block_ { uint64_t v[ARGON2_QWORDS_IN_BLOCK]; } block;
  51. /*****************Functions that work with the block******************/
  52. /* Initialize each byte of the block with @in */
  53. void init_block_value(block *b, uint8_t in);
  54. /* Copy block @src to block @dst */
  55. void copy_block(block *dst, const block *src);
  56. /* XOR @src onto @dst bytewise */
  57. void xor_block(block *dst, const block *src);
  58. /*
  59. * Argon2 instance: memory pointer, number of passes, amount of memory, type,
  60. * and derived values.
  61. * Used to evaluate the number and location of blocks to construct in each
  62. * thread
  63. */
  64. typedef struct Argon2_instance_t {
  65. block *memory; /* Memory pointer */
  66. uint32_t version;
  67. uint32_t passes; /* Number of passes */
  68. uint32_t memory_blocks; /* Number of blocks in memory */
  69. uint32_t segment_length;
  70. uint32_t lane_length;
  71. uint32_t lanes;
  72. uint32_t threads;
  73. argon2_type type;
  74. int print_internals; /* whether to print the memory blocks */
  75. argon2_context *context_ptr; /* points back to original context */
  76. } argon2_instance_t;
  77. /*
  78. * Argon2 position: where we construct the block right now. Used to distribute
  79. * work between threads.
  80. */
  81. typedef struct Argon2_position_t {
  82. uint32_t pass;
  83. uint32_t lane;
  84. uint8_t slice;
  85. uint32_t index;
  86. } argon2_position_t;
  87. /*Struct that holds the inputs for thread handling FillSegment*/
  88. typedef struct Argon2_thread_data {
  89. argon2_instance_t *instance_ptr;
  90. argon2_position_t pos;
  91. } argon2_thread_data;
  92. /*************************Argon2 core functions********************************/
  93. /* Allocates memory to the given pointer, uses the appropriate allocator as
  94. * specified in the context. Total allocated memory is num*size.
  95. * @param context argon2_context which specifies the allocator
  96. * @param memory pointer to the pointer to the memory
  97. * @param size the size in bytes for each element to be allocated
  98. * @param num the number of elements to be allocated
  99. * @return ARGON2_OK if @memory is a valid pointer and memory is allocated
  100. */
  101. int allocate_memory(const argon2_context *context, uint8_t **memory,
  102. size_t num, size_t size);
  103. /*
  104. * Frees memory at the given pointer, uses the appropriate deallocator as
  105. * specified in the context. Also cleans the memory using clear_internal_memory.
  106. * @param context argon2_context which specifies the deallocator
  107. * @param memory pointer to buffer to be freed
  108. * @param size the size in bytes for each element to be deallocated
  109. * @param num the number of elements to be deallocated
  110. */
  111. void free_memory(const argon2_context *context, uint8_t *memory,
  112. size_t num, size_t size);
  113. /* Function that securely cleans the memory. This ignores any flags set
  114. * regarding clearing memory. Usually one just calls clear_internal_memory.
  115. * @param mem Pointer to the memory
  116. * @param s Memory size in bytes
  117. */
  118. void secure_wipe_memory(void *v, size_t n);
  119. /* Function that securely clears the memory if FLAG_clear_internal_memory is
  120. * set. If the flag isn't set, this function does nothing.
  121. * @param mem Pointer to the memory
  122. * @param s Memory size in bytes
  123. */
  124. void clear_internal_memory(void *v, size_t n);
  125. /*
  126. * Computes absolute position of reference block in the lane following a skewed
  127. * distribution and using a pseudo-random value as input
  128. * @param instance Pointer to the current instance
  129. * @param position Pointer to the current position
  130. * @param pseudo_rand 32-bit pseudo-random value used to determine the position
  131. * @param same_lane Indicates if the block will be taken from the current lane.
  132. * If so we can reference the current segment
  133. * @pre All pointers must be valid
  134. */
  135. uint32_t index_alpha(const argon2_instance_t *instance,
  136. const argon2_position_t *position, uint32_t pseudo_rand,
  137. int same_lane);
  138. /*
  139. * Function that validates all inputs against predefined restrictions and return
  140. * an error code
  141. * @param context Pointer to current Argon2 context
  142. * @return ARGON2_OK if everything is all right, otherwise one of error codes
  143. * (all defined in <argon2.h>
  144. */
  145. int validate_inputs(const argon2_context *context);
  146. /*
  147. * Hashes all the inputs into @a blockhash[PREHASH_DIGEST_LENGTH], clears
  148. * password and secret if needed
  149. * @param context Pointer to the Argon2 internal structure containing memory
  150. * pointer, and parameters for time and space requirements.
  151. * @param blockhash Buffer for pre-hashing digest
  152. * @param type Argon2 type
  153. * @pre @a blockhash must have at least @a PREHASH_DIGEST_LENGTH bytes
  154. * allocated
  155. */
  156. void initial_hash(uint8_t *blockhash, argon2_context *context,
  157. argon2_type type);
  158. /*
  159. * Function creates first 2 blocks per lane
  160. * @param instance Pointer to the current instance
  161. * @param blockhash Pointer to the pre-hashing digest
  162. * @pre blockhash must point to @a PREHASH_SEED_LENGTH allocated values
  163. */
  164. void fill_first_blocks(uint8_t *blockhash, const argon2_instance_t *instance);
  165. /*
  166. * Function allocates memory, hashes the inputs with Blake, and creates first
  167. * two blocks. Returns the pointer to the main memory with 2 blocks per lane
  168. * initialized
  169. * @param context Pointer to the Argon2 internal structure containing memory
  170. * pointer, and parameters for time and space requirements.
  171. * @param instance Current Argon2 instance
  172. * @return Zero if successful, -1 if memory failed to allocate. @context->state
  173. * will be modified if successful.
  174. */
  175. int argon_initialize(argon2_instance_t *instance, argon2_context *context);
  176. /*
  177. * XORing the last block of each lane, hashing it, making the tag. Deallocates
  178. * the memory.
  179. * @param context Pointer to current Argon2 context (use only the out parameters
  180. * from it)
  181. * @param instance Pointer to current instance of Argon2
  182. * @pre instance->state must point to necessary amount of memory
  183. * @pre context->out must point to outlen bytes of memory
  184. * @pre if context->free_cbk is not NULL, it should point to a function that
  185. * deallocates memory
  186. */
  187. void finalize(const argon2_context *context, argon2_instance_t *instance);
  188. /*
  189. * Function that fills the segment using previous segments also from other
  190. * threads
  191. * @param context current context
  192. * @param instance Pointer to the current instance
  193. * @param position Current position
  194. * @pre all block pointers must be valid
  195. */
  196. void fill_segment(const argon2_instance_t *instance,
  197. argon2_position_t position);
  198. /*
  199. * Function that fills the entire memory t_cost times based on the first two
  200. * blocks in each lane
  201. * @param instance Pointer to the current instance
  202. * @return ARGON2_OK if successful, @context->state
  203. */
  204. int fill_memory_blocks(argon2_instance_t *instance);
  205. #if defined(__cplusplus)
  206. }
  207. #endif
  208. #endif