argon2-core.c 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556
  1. /*
  2. * Argon2 source code package
  3. *
  4. * Written by Daniel Dinu and Dmitry Khovratovich, 2015
  5. *
  6. * This work is licensed under a Creative Commons CC0 1.0 License/Waiver.
  7. *
  8. * You should have received a copy of the CC0 Public Domain Dedication along
  9. * with
  10. * this software. If not, see
  11. * <http://creativecommons.org/publicdomain/zero/1.0/>.
  12. */
  13. #include <errno.h>
  14. #include <stdint.h>
  15. #include <stdio.h>
  16. #include <stdlib.h>
  17. #include <string.h>
  18. #include <sys/types.h>
  19. #ifdef HAVE_SYS_MMAN_H
  20. # include <sys/mman.h>
  21. #endif
  22. #include "crypto_generichash_blake2b.h"
  23. #include "private/common.h"
  24. #include "private/implementations.h"
  25. #include "runtime.h"
  26. #include "utils.h"
  27. #include "argon2-core.h"
  28. #include "blake2b-long.h"
  29. #if !defined(MAP_ANON) && defined(MAP_ANONYMOUS)
  30. # define MAP_ANON MAP_ANONYMOUS
  31. #endif
  32. #ifndef MAP_NOCORE
  33. # ifdef MAP_CONCEAL
  34. # define MAP_NOCORE MAP_CONCEAL
  35. # else
  36. # define MAP_NOCORE 0
  37. # endif
  38. #endif
  39. #ifndef MAP_POPULATE
  40. # define MAP_POPULATE 0
  41. #endif
  42. static fill_segment_fn fill_segment = argon2_fill_segment_ref;
  43. static void
  44. load_block(block *dst, const void *input)
  45. {
  46. unsigned i;
  47. for (i = 0; i < ARGON2_QWORDS_IN_BLOCK; ++i) {
  48. dst->v[i] = LOAD64_LE((const uint8_t *) input + i * sizeof(dst->v[i]));
  49. }
  50. }
  51. static void
  52. store_block(void *output, const block *src)
  53. {
  54. unsigned i;
  55. for (i = 0; i < ARGON2_QWORDS_IN_BLOCK; ++i) {
  56. STORE64_LE((uint8_t *) output + i * sizeof(src->v[i]), src->v[i]);
  57. }
  58. }
  59. /***************Memory allocators*****************/
  60. /* Allocates memory to the given pointer
  61. * @param memory pointer to the pointer to the memory
  62. * @param m_cost number of blocks to allocate in the memory
  63. * @return ARGON2_OK if @memory is a valid pointer and memory is allocated
  64. */
  65. static int allocate_memory(block_region **region, uint32_t m_cost);
  66. static int
  67. allocate_memory(block_region **region, uint32_t m_cost)
  68. {
  69. void * base;
  70. block *memory;
  71. size_t memory_size;
  72. if (region == NULL) {
  73. return ARGON2_MEMORY_ALLOCATION_ERROR; /* LCOV_EXCL_LINE */
  74. }
  75. memory_size = sizeof(block) * m_cost;
  76. if (m_cost == 0 || memory_size / m_cost != sizeof(block)) {
  77. return ARGON2_MEMORY_ALLOCATION_ERROR; /* LCOV_EXCL_LINE */
  78. }
  79. *region = (block_region *) malloc(sizeof(block_region));
  80. if (*region == NULL) {
  81. return ARGON2_MEMORY_ALLOCATION_ERROR; /* LCOV_EXCL_LINE */
  82. }
  83. (*region)->base = (*region)->memory = NULL;
  84. #if defined(MAP_ANON) && defined(HAVE_MMAP)
  85. if ((base = mmap(NULL, memory_size, PROT_READ | PROT_WRITE,
  86. MAP_ANON | MAP_PRIVATE | MAP_NOCORE | MAP_POPULATE,
  87. -1, 0)) == MAP_FAILED) {
  88. base = NULL; /* LCOV_EXCL_LINE */
  89. } /* LCOV_EXCL_LINE */
  90. memcpy(&memory, &base, sizeof memory);
  91. #elif defined(HAVE_POSIX_MEMALIGN)
  92. if ((errno = posix_memalign((void **) &base, 64, memory_size)) != 0) {
  93. base = NULL;
  94. }
  95. memcpy(&memory, &base, sizeof memory);
  96. #else
  97. memory = NULL;
  98. if (memory_size + 63 < memory_size) {
  99. base = NULL;
  100. errno = ENOMEM;
  101. } else if ((base = malloc(memory_size + 63)) != NULL) {
  102. uint8_t *aligned = ((uint8_t *) base) + 63;
  103. aligned -= (uintptr_t) aligned & 63;
  104. memcpy(&memory, &aligned, sizeof memory);
  105. }
  106. #endif
  107. if (base == NULL) {
  108. /* LCOV_EXCL_START */
  109. free(*region);
  110. *region = NULL;
  111. return ARGON2_MEMORY_ALLOCATION_ERROR;
  112. /* LCOV_EXCL_STOP */
  113. }
  114. (*region)->base = base;
  115. (*region)->memory = memory;
  116. (*region)->size = memory_size;
  117. return ARGON2_OK;
  118. }
  119. /*********Memory functions*/
  120. /* Clears memory
  121. * @param instance pointer to the current instance
  122. * @param clear_memory indicates if we clear the memory with zeros.
  123. */
  124. static void clear_memory(argon2_instance_t *instance, int clear);
  125. static void
  126. clear_memory(argon2_instance_t *instance, int clear)
  127. {
  128. /* LCOV_EXCL_START */
  129. if (clear) {
  130. if (instance->region != NULL) {
  131. sodium_memzero(instance->region->memory,
  132. sizeof(block) * instance->memory_blocks);
  133. }
  134. if (instance->pseudo_rands != NULL) {
  135. sodium_memzero(instance->pseudo_rands,
  136. sizeof(uint64_t) * instance->segment_length);
  137. }
  138. }
  139. /* LCOV_EXCL_STOP */
  140. }
  141. /* Deallocates memory
  142. * @param memory pointer to the blocks
  143. */
  144. static void free_memory(block_region *region);
  145. static void
  146. free_memory(block_region *region)
  147. {
  148. if (region && region->base) {
  149. #if defined(MAP_ANON) && defined(HAVE_MMAP)
  150. if (munmap(region->base, region->size)) {
  151. return; /* LCOV_EXCL_LINE */
  152. }
  153. #else
  154. free(region->base);
  155. #endif
  156. }
  157. free(region);
  158. }
  159. static void
  160. argon2_free_instance(argon2_instance_t *instance, int flags)
  161. {
  162. /* Clear memory */
  163. clear_memory(instance, flags & ARGON2_FLAG_CLEAR_MEMORY);
  164. /* Deallocate the memory */
  165. free(instance->pseudo_rands);
  166. instance->pseudo_rands = NULL;
  167. free_memory(instance->region);
  168. instance->region = NULL;
  169. }
  170. void
  171. argon2_finalize(const argon2_context *context, argon2_instance_t *instance)
  172. {
  173. if (context != NULL && instance != NULL) {
  174. block blockhash;
  175. uint32_t l;
  176. copy_block(&blockhash,
  177. instance->region->memory + instance->lane_length - 1);
  178. /* XOR the last blocks */
  179. for (l = 1; l < instance->lanes; ++l) {
  180. uint32_t last_block_in_lane =
  181. l * instance->lane_length + (instance->lane_length - 1);
  182. xor_block(&blockhash,
  183. instance->region->memory + last_block_in_lane);
  184. }
  185. /* Hash the result */
  186. {
  187. uint8_t blockhash_bytes[ARGON2_BLOCK_SIZE];
  188. store_block(blockhash_bytes, &blockhash);
  189. blake2b_long(context->out, context->outlen, blockhash_bytes,
  190. ARGON2_BLOCK_SIZE);
  191. sodium_memzero(blockhash.v,
  192. ARGON2_BLOCK_SIZE); /* clear blockhash */
  193. sodium_memzero(blockhash_bytes,
  194. ARGON2_BLOCK_SIZE); /* clear blockhash_bytes */
  195. }
  196. argon2_free_instance(instance, context->flags);
  197. }
  198. }
  199. void
  200. argon2_fill_memory_blocks(argon2_instance_t *instance, uint32_t pass)
  201. {
  202. argon2_position_t position;
  203. uint32_t l;
  204. uint32_t s;
  205. if (instance == NULL || instance->lanes == 0) {
  206. return; /* LCOV_EXCL_LINE */
  207. }
  208. position.pass = pass;
  209. for (s = 0; s < ARGON2_SYNC_POINTS; ++s) {
  210. position.slice = (uint8_t) s;
  211. for (l = 0; l < instance->lanes; ++l) {
  212. position.lane = l;
  213. position.index = 0;
  214. fill_segment(instance, position);
  215. }
  216. }
  217. }
  218. int
  219. argon2_validate_inputs(const argon2_context *context)
  220. {
  221. /* LCOV_EXCL_START */
  222. if (NULL == context) {
  223. return ARGON2_INCORRECT_PARAMETER;
  224. }
  225. if (NULL == context->out) {
  226. return ARGON2_OUTPUT_PTR_NULL;
  227. }
  228. /* Validate output length */
  229. if (ARGON2_MIN_OUTLEN > context->outlen) {
  230. return ARGON2_OUTPUT_TOO_SHORT;
  231. }
  232. if (ARGON2_MAX_OUTLEN < context->outlen) {
  233. return ARGON2_OUTPUT_TOO_LONG;
  234. }
  235. /* Validate password (required param) */
  236. if (NULL == context->pwd) {
  237. if (0 != context->pwdlen) {
  238. return ARGON2_PWD_PTR_MISMATCH;
  239. }
  240. }
  241. if (ARGON2_MIN_PWD_LENGTH > context->pwdlen) {
  242. return ARGON2_PWD_TOO_SHORT;
  243. }
  244. if (ARGON2_MAX_PWD_LENGTH < context->pwdlen) {
  245. return ARGON2_PWD_TOO_LONG;
  246. }
  247. /* Validate salt (required param) */
  248. if (NULL == context->salt) {
  249. if (0 != context->saltlen) {
  250. return ARGON2_SALT_PTR_MISMATCH;
  251. }
  252. }
  253. if (ARGON2_MIN_SALT_LENGTH > context->saltlen) {
  254. return ARGON2_SALT_TOO_SHORT;
  255. }
  256. if (ARGON2_MAX_SALT_LENGTH < context->saltlen) {
  257. return ARGON2_SALT_TOO_LONG;
  258. }
  259. /* Validate secret (optional param) */
  260. if (NULL == context->secret) {
  261. if (0 != context->secretlen) {
  262. return ARGON2_SECRET_PTR_MISMATCH;
  263. }
  264. } else {
  265. if (ARGON2_MIN_SECRET > context->secretlen) {
  266. return ARGON2_SECRET_TOO_SHORT;
  267. }
  268. if (ARGON2_MAX_SECRET < context->secretlen) {
  269. return ARGON2_SECRET_TOO_LONG;
  270. }
  271. }
  272. /* Validate associated data (optional param) */
  273. if (NULL == context->ad) {
  274. if (0 != context->adlen) {
  275. return ARGON2_AD_PTR_MISMATCH;
  276. }
  277. } else {
  278. if (ARGON2_MIN_AD_LENGTH > context->adlen) {
  279. return ARGON2_AD_TOO_SHORT;
  280. }
  281. if (ARGON2_MAX_AD_LENGTH < context->adlen) {
  282. return ARGON2_AD_TOO_LONG;
  283. }
  284. }
  285. /* Validate lanes */
  286. if (ARGON2_MIN_LANES > context->lanes) {
  287. return ARGON2_LANES_TOO_FEW;
  288. }
  289. if (ARGON2_MAX_LANES < context->lanes) {
  290. return ARGON2_LANES_TOO_MANY;
  291. }
  292. /* Validate memory cost */
  293. if (ARGON2_MIN_MEMORY > context->m_cost) {
  294. return ARGON2_MEMORY_TOO_LITTLE;
  295. }
  296. if (ARGON2_MAX_MEMORY < context->m_cost) {
  297. return ARGON2_MEMORY_TOO_MUCH;
  298. }
  299. if (context->m_cost < 8 * context->lanes) {
  300. return ARGON2_MEMORY_TOO_LITTLE;
  301. }
  302. /* Validate time cost */
  303. if (ARGON2_MIN_TIME > context->t_cost) {
  304. return ARGON2_TIME_TOO_SMALL;
  305. }
  306. if (ARGON2_MAX_TIME < context->t_cost) {
  307. return ARGON2_TIME_TOO_LARGE;
  308. }
  309. /* Validate threads */
  310. if (ARGON2_MIN_THREADS > context->threads) {
  311. return ARGON2_THREADS_TOO_FEW;
  312. }
  313. if (ARGON2_MAX_THREADS < context->threads) {
  314. return ARGON2_THREADS_TOO_MANY;
  315. }
  316. /* LCOV_EXCL_STOP */
  317. return ARGON2_OK;
  318. }
  319. static void
  320. argon2_fill_first_blocks(uint8_t *blockhash, const argon2_instance_t *instance)
  321. {
  322. uint32_t l;
  323. /* Make the first and second block in each lane as G(H0||i||0) or
  324. G(H0||i||1) */
  325. uint8_t blockhash_bytes[ARGON2_BLOCK_SIZE];
  326. for (l = 0; l < instance->lanes; ++l) {
  327. STORE32_LE(blockhash + ARGON2_PREHASH_DIGEST_LENGTH, 0);
  328. STORE32_LE(blockhash + ARGON2_PREHASH_DIGEST_LENGTH + 4, l);
  329. blake2b_long(blockhash_bytes, ARGON2_BLOCK_SIZE, blockhash,
  330. ARGON2_PREHASH_SEED_LENGTH);
  331. load_block(&instance->region->memory[l * instance->lane_length + 0],
  332. blockhash_bytes);
  333. STORE32_LE(blockhash + ARGON2_PREHASH_DIGEST_LENGTH, 1);
  334. blake2b_long(blockhash_bytes, ARGON2_BLOCK_SIZE, blockhash,
  335. ARGON2_PREHASH_SEED_LENGTH);
  336. load_block(&instance->region->memory[l * instance->lane_length + 1],
  337. blockhash_bytes);
  338. }
  339. sodium_memzero(blockhash_bytes, ARGON2_BLOCK_SIZE);
  340. }
  341. static void
  342. argon2_initial_hash(uint8_t *blockhash, argon2_context *context,
  343. argon2_type type)
  344. {
  345. crypto_generichash_blake2b_state BlakeHash;
  346. uint8_t value[4U /* sizeof(uint32_t) */];
  347. if (NULL == context || NULL == blockhash) {
  348. return; /* LCOV_EXCL_LINE */
  349. }
  350. crypto_generichash_blake2b_init(&BlakeHash, NULL, 0U,
  351. ARGON2_PREHASH_DIGEST_LENGTH);
  352. STORE32_LE(value, context->lanes);
  353. crypto_generichash_blake2b_update(&BlakeHash, value, sizeof(value));
  354. STORE32_LE(value, context->outlen);
  355. crypto_generichash_blake2b_update(&BlakeHash, value, sizeof(value));
  356. STORE32_LE(value, context->m_cost);
  357. crypto_generichash_blake2b_update(&BlakeHash, value, sizeof(value));
  358. STORE32_LE(value, context->t_cost);
  359. crypto_generichash_blake2b_update(&BlakeHash, value, sizeof(value));
  360. STORE32_LE(value, ARGON2_VERSION_NUMBER);
  361. crypto_generichash_blake2b_update(&BlakeHash, value, sizeof(value));
  362. STORE32_LE(value, (uint32_t) type);
  363. crypto_generichash_blake2b_update(&BlakeHash, value, sizeof(value));
  364. STORE32_LE(value, context->pwdlen);
  365. crypto_generichash_blake2b_update(&BlakeHash, value, sizeof(value));
  366. if (context->pwd != NULL) {
  367. crypto_generichash_blake2b_update(
  368. &BlakeHash, (const uint8_t *) context->pwd, context->pwdlen);
  369. /* LCOV_EXCL_START */
  370. if (context->flags & ARGON2_FLAG_CLEAR_PASSWORD) {
  371. sodium_memzero(context->pwd, context->pwdlen);
  372. context->pwdlen = 0;
  373. }
  374. /* LCOV_EXCL_STOP */
  375. }
  376. STORE32_LE(value, context->saltlen);
  377. crypto_generichash_blake2b_update(&BlakeHash, value, sizeof(value));
  378. if (context->salt != NULL) {
  379. crypto_generichash_blake2b_update(
  380. &BlakeHash, (const uint8_t *) context->salt, context->saltlen);
  381. }
  382. STORE32_LE(value, context->secretlen);
  383. crypto_generichash_blake2b_update(&BlakeHash, value, sizeof(value));
  384. /* LCOV_EXCL_START */
  385. if (context->secret != NULL) {
  386. crypto_generichash_blake2b_update(
  387. &BlakeHash, (const uint8_t *) context->secret, context->secretlen);
  388. if (context->flags & ARGON2_FLAG_CLEAR_SECRET) {
  389. sodium_memzero(context->secret, context->secretlen);
  390. context->secretlen = 0;
  391. }
  392. }
  393. /* LCOV_EXCL_STOP */
  394. STORE32_LE(value, context->adlen);
  395. crypto_generichash_blake2b_update(&BlakeHash, value, sizeof(value));
  396. /* LCOV_EXCL_START */
  397. if (context->ad != NULL) {
  398. crypto_generichash_blake2b_update(
  399. &BlakeHash, (const uint8_t *) context->ad, context->adlen);
  400. }
  401. /* LCOV_EXCL_STOP */
  402. crypto_generichash_blake2b_final(&BlakeHash, blockhash,
  403. ARGON2_PREHASH_DIGEST_LENGTH);
  404. }
  405. int
  406. argon2_initialize(argon2_instance_t *instance, argon2_context *context)
  407. {
  408. uint8_t blockhash[ARGON2_PREHASH_SEED_LENGTH];
  409. int result = ARGON2_OK;
  410. if (instance == NULL || context == NULL) {
  411. return ARGON2_INCORRECT_PARAMETER;
  412. }
  413. /* 1. Memory allocation */
  414. if ((instance->pseudo_rands = (uint64_t *)
  415. malloc(sizeof(uint64_t) * instance->segment_length)) == NULL) {
  416. return ARGON2_MEMORY_ALLOCATION_ERROR;
  417. }
  418. result = allocate_memory(&(instance->region), instance->memory_blocks);
  419. if (ARGON2_OK != result) {
  420. argon2_free_instance(instance, context->flags);
  421. return result;
  422. }
  423. /* 2. Initial hashing */
  424. /* H_0 + 8 extra bytes to produce the first blocks */
  425. /* uint8_t blockhash[ARGON2_PREHASH_SEED_LENGTH]; */
  426. /* Hashing all inputs */
  427. argon2_initial_hash(blockhash, context, instance->type);
  428. /* Zeroing 8 extra bytes */
  429. sodium_memzero(blockhash + ARGON2_PREHASH_DIGEST_LENGTH,
  430. ARGON2_PREHASH_SEED_LENGTH - ARGON2_PREHASH_DIGEST_LENGTH);
  431. /* 3. Creating first blocks, we always have at least two blocks in a slice
  432. */
  433. argon2_fill_first_blocks(blockhash, instance);
  434. /* Clearing the hash */
  435. sodium_memzero(blockhash, ARGON2_PREHASH_SEED_LENGTH);
  436. return ARGON2_OK;
  437. }
  438. static int
  439. argon2_pick_best_implementation(void)
  440. {
  441. /* LCOV_EXCL_START */
  442. #if defined(HAVE_AVX512FINTRIN_H) && defined(HAVE_AVX2INTRIN_H) && \
  443. defined(HAVE_TMMINTRIN_H) && defined(HAVE_SMMINTRIN_H) && \
  444. !defined(__APPLE__)
  445. if (sodium_runtime_has_avx512f()) {
  446. fill_segment = argon2_fill_segment_avx512f;
  447. return 0;
  448. }
  449. #endif
  450. #if defined(HAVE_AVX2INTRIN_H) && defined(HAVE_TMMINTRIN_H) && \
  451. defined(HAVE_SMMINTRIN_H)
  452. if (sodium_runtime_has_avx2()) {
  453. fill_segment = argon2_fill_segment_avx2;
  454. return 0;
  455. }
  456. #endif
  457. #if defined(HAVE_EMMINTRIN_H) && defined(HAVE_TMMINTRIN_H)
  458. if (sodium_runtime_has_ssse3()) {
  459. fill_segment = argon2_fill_segment_ssse3;
  460. return 0;
  461. }
  462. #endif
  463. fill_segment = argon2_fill_segment_ref;
  464. return 0;
  465. /* LCOV_EXCL_STOP */
  466. }
  467. int
  468. _crypto_pwhash_argon2_pick_best_implementation(void)
  469. {
  470. return argon2_pick_best_implementation();
  471. }