argon2.c 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452
  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. #include <string.h>
  18. #include <stdlib.h>
  19. #include <stdio.h>
  20. #include "argon2.h"
  21. #include "encoding.h"
  22. #include "core.h"
  23. const char *argon2_type2string(argon2_type type, int uppercase) {
  24. switch (type) {
  25. case Argon2_d:
  26. return uppercase ? "Argon2d" : "argon2d";
  27. case Argon2_i:
  28. return uppercase ? "Argon2i" : "argon2i";
  29. case Argon2_id:
  30. return uppercase ? "Argon2id" : "argon2id";
  31. }
  32. return NULL;
  33. }
  34. int argon2_ctx(argon2_context *context, argon2_type type) {
  35. /* 1. Validate all inputs */
  36. int result = validate_inputs(context);
  37. uint32_t memory_blocks, segment_length;
  38. argon2_instance_t instance;
  39. if (ARGON2_OK != result) {
  40. return result;
  41. }
  42. if (Argon2_d != type && Argon2_i != type && Argon2_id != type) {
  43. return ARGON2_INCORRECT_TYPE;
  44. }
  45. /* 2. Align memory size */
  46. /* Minimum memory_blocks = 8L blocks, where L is the number of lanes */
  47. memory_blocks = context->m_cost;
  48. if (memory_blocks < 2 * ARGON2_SYNC_POINTS * context->lanes) {
  49. memory_blocks = 2 * ARGON2_SYNC_POINTS * context->lanes;
  50. }
  51. segment_length = memory_blocks / (context->lanes * ARGON2_SYNC_POINTS);
  52. /* Ensure that all segments have equal length */
  53. memory_blocks = segment_length * (context->lanes * ARGON2_SYNC_POINTS);
  54. instance.version = context->version;
  55. instance.memory = NULL;
  56. instance.passes = context->t_cost;
  57. instance.memory_blocks = memory_blocks;
  58. instance.segment_length = segment_length;
  59. instance.lane_length = segment_length * ARGON2_SYNC_POINTS;
  60. instance.lanes = context->lanes;
  61. instance.threads = context->threads;
  62. instance.type = type;
  63. if (instance.threads > instance.lanes) {
  64. instance.threads = instance.lanes;
  65. }
  66. /* 3. Initialization: Hashing inputs, allocating memory, filling first
  67. * blocks
  68. */
  69. result = initialize(&instance, context);
  70. if (ARGON2_OK != result) {
  71. return result;
  72. }
  73. /* 4. Filling memory */
  74. result = fill_memory_blocks(&instance);
  75. if (ARGON2_OK != result) {
  76. return result;
  77. }
  78. /* 5. Finalization */
  79. finalize(context, &instance);
  80. return ARGON2_OK;
  81. }
  82. int argon2_hash(const uint32_t t_cost, const uint32_t m_cost,
  83. const uint32_t parallelism, const void *pwd,
  84. const size_t pwdlen, const void *salt, const size_t saltlen,
  85. void *hash, const size_t hashlen, char *encoded,
  86. const size_t encodedlen, argon2_type type,
  87. const uint32_t version){
  88. argon2_context context;
  89. int result;
  90. uint8_t *out;
  91. if (pwdlen > ARGON2_MAX_PWD_LENGTH) {
  92. return ARGON2_PWD_TOO_LONG;
  93. }
  94. if (saltlen > ARGON2_MAX_SALT_LENGTH) {
  95. return ARGON2_SALT_TOO_LONG;
  96. }
  97. if (hashlen > ARGON2_MAX_OUTLEN) {
  98. return ARGON2_OUTPUT_TOO_LONG;
  99. }
  100. if (hashlen < ARGON2_MIN_OUTLEN) {
  101. return ARGON2_OUTPUT_TOO_SHORT;
  102. }
  103. out = malloc(hashlen);
  104. if (!out) {
  105. return ARGON2_MEMORY_ALLOCATION_ERROR;
  106. }
  107. context.out = (uint8_t *)out;
  108. context.outlen = (uint32_t)hashlen;
  109. context.pwd = CONST_CAST(uint8_t *)pwd;
  110. context.pwdlen = (uint32_t)pwdlen;
  111. context.salt = CONST_CAST(uint8_t *)salt;
  112. context.saltlen = (uint32_t)saltlen;
  113. context.secret = NULL;
  114. context.secretlen = 0;
  115. context.ad = NULL;
  116. context.adlen = 0;
  117. context.t_cost = t_cost;
  118. context.m_cost = m_cost;
  119. context.lanes = parallelism;
  120. context.threads = parallelism;
  121. context.allocate_cbk = NULL;
  122. context.free_cbk = NULL;
  123. context.flags = ARGON2_DEFAULT_FLAGS;
  124. context.version = version;
  125. result = argon2_ctx(&context, type);
  126. if (result != ARGON2_OK) {
  127. clear_internal_memory(out, hashlen);
  128. free(out);
  129. return result;
  130. }
  131. /* if raw hash requested, write it */
  132. if (hash) {
  133. memcpy(hash, out, hashlen);
  134. }
  135. /* if encoding requested, write it */
  136. if (encoded && encodedlen) {
  137. if (encode_string(encoded, encodedlen, &context, type) != ARGON2_OK) {
  138. clear_internal_memory(out, hashlen); /* wipe buffers if error */
  139. clear_internal_memory(encoded, encodedlen);
  140. free(out);
  141. return ARGON2_ENCODING_FAIL;
  142. }
  143. }
  144. clear_internal_memory(out, hashlen);
  145. free(out);
  146. return ARGON2_OK;
  147. }
  148. int argon2i_hash_encoded(const uint32_t t_cost, const uint32_t m_cost,
  149. const uint32_t parallelism, const void *pwd,
  150. const size_t pwdlen, const void *salt,
  151. const size_t saltlen, const size_t hashlen,
  152. char *encoded, const size_t encodedlen) {
  153. return argon2_hash(t_cost, m_cost, parallelism, pwd, pwdlen, salt, saltlen,
  154. NULL, hashlen, encoded, encodedlen, Argon2_i,
  155. ARGON2_VERSION_NUMBER);
  156. }
  157. int argon2i_hash_raw(const uint32_t t_cost, const uint32_t m_cost,
  158. const uint32_t parallelism, const void *pwd,
  159. const size_t pwdlen, const void *salt,
  160. const size_t saltlen, void *hash, const size_t hashlen) {
  161. return argon2_hash(t_cost, m_cost, parallelism, pwd, pwdlen, salt, saltlen,
  162. hash, hashlen, NULL, 0, Argon2_i, ARGON2_VERSION_NUMBER);
  163. }
  164. int argon2d_hash_encoded(const uint32_t t_cost, const uint32_t m_cost,
  165. const uint32_t parallelism, const void *pwd,
  166. const size_t pwdlen, const void *salt,
  167. const size_t saltlen, const size_t hashlen,
  168. char *encoded, const size_t encodedlen) {
  169. return argon2_hash(t_cost, m_cost, parallelism, pwd, pwdlen, salt, saltlen,
  170. NULL, hashlen, encoded, encodedlen, Argon2_d,
  171. ARGON2_VERSION_NUMBER);
  172. }
  173. int argon2d_hash_raw(const uint32_t t_cost, const uint32_t m_cost,
  174. const uint32_t parallelism, const void *pwd,
  175. const size_t pwdlen, const void *salt,
  176. const size_t saltlen, void *hash, const size_t hashlen) {
  177. return argon2_hash(t_cost, m_cost, parallelism, pwd, pwdlen, salt, saltlen,
  178. hash, hashlen, NULL, 0, Argon2_d, ARGON2_VERSION_NUMBER);
  179. }
  180. int argon2id_hash_encoded(const uint32_t t_cost, const uint32_t m_cost,
  181. const uint32_t parallelism, const void *pwd,
  182. const size_t pwdlen, const void *salt,
  183. const size_t saltlen, const size_t hashlen,
  184. char *encoded, const size_t encodedlen) {
  185. return argon2_hash(t_cost, m_cost, parallelism, pwd, pwdlen, salt, saltlen,
  186. NULL, hashlen, encoded, encodedlen, Argon2_id,
  187. ARGON2_VERSION_NUMBER);
  188. }
  189. int argon2id_hash_raw(const uint32_t t_cost, const uint32_t m_cost,
  190. const uint32_t parallelism, const void *pwd,
  191. const size_t pwdlen, const void *salt,
  192. const size_t saltlen, void *hash, const size_t hashlen) {
  193. return argon2_hash(t_cost, m_cost, parallelism, pwd, pwdlen, salt, saltlen,
  194. hash, hashlen, NULL, 0, Argon2_id,
  195. ARGON2_VERSION_NUMBER);
  196. }
  197. static int argon2_compare(const uint8_t *b1, const uint8_t *b2, size_t len) {
  198. size_t i;
  199. uint8_t d = 0U;
  200. for (i = 0U; i < len; i++) {
  201. d |= b1[i] ^ b2[i];
  202. }
  203. return (int)((1 & ((d - 1) >> 8)) - 1);
  204. }
  205. int argon2_verify(const char *encoded, const void *pwd, const size_t pwdlen,
  206. argon2_type type) {
  207. argon2_context ctx;
  208. uint8_t *desired_result = NULL;
  209. int ret = ARGON2_OK;
  210. size_t encoded_len;
  211. uint32_t max_field_len;
  212. if (pwdlen > ARGON2_MAX_PWD_LENGTH) {
  213. return ARGON2_PWD_TOO_LONG;
  214. }
  215. if (encoded == NULL) {
  216. return ARGON2_DECODING_FAIL;
  217. }
  218. encoded_len = strlen(encoded);
  219. if (encoded_len > UINT32_MAX) {
  220. return ARGON2_DECODING_FAIL;
  221. }
  222. /* No field can be longer than the encoded length */
  223. max_field_len = (uint32_t)encoded_len;
  224. ctx.saltlen = max_field_len;
  225. ctx.outlen = max_field_len;
  226. ctx.salt = malloc(ctx.saltlen);
  227. ctx.out = malloc(ctx.outlen);
  228. if (!ctx.salt || !ctx.out) {
  229. ret = ARGON2_MEMORY_ALLOCATION_ERROR;
  230. goto fail;
  231. }
  232. ctx.pwd = (uint8_t *)pwd;
  233. ctx.pwdlen = (uint32_t)pwdlen;
  234. ret = decode_string(&ctx, encoded, type);
  235. if (ret != ARGON2_OK) {
  236. goto fail;
  237. }
  238. /* Set aside the desired result, and get a new buffer. */
  239. desired_result = ctx.out;
  240. ctx.out = malloc(ctx.outlen);
  241. if (!ctx.out) {
  242. ret = ARGON2_MEMORY_ALLOCATION_ERROR;
  243. goto fail;
  244. }
  245. ret = argon2_verify_ctx(&ctx, (char *)desired_result, type);
  246. if (ret != ARGON2_OK) {
  247. goto fail;
  248. }
  249. fail:
  250. free(ctx.salt);
  251. free(ctx.out);
  252. free(desired_result);
  253. return ret;
  254. }
  255. int argon2i_verify(const char *encoded, const void *pwd, const size_t pwdlen) {
  256. return argon2_verify(encoded, pwd, pwdlen, Argon2_i);
  257. }
  258. int argon2d_verify(const char *encoded, const void *pwd, const size_t pwdlen) {
  259. return argon2_verify(encoded, pwd, pwdlen, Argon2_d);
  260. }
  261. int argon2id_verify(const char *encoded, const void *pwd, const size_t pwdlen) {
  262. return argon2_verify(encoded, pwd, pwdlen, Argon2_id);
  263. }
  264. int argon2d_ctx(argon2_context *context) {
  265. return argon2_ctx(context, Argon2_d);
  266. }
  267. int argon2i_ctx(argon2_context *context) {
  268. return argon2_ctx(context, Argon2_i);
  269. }
  270. int argon2id_ctx(argon2_context *context) {
  271. return argon2_ctx(context, Argon2_id);
  272. }
  273. int argon2_verify_ctx(argon2_context *context, const char *hash,
  274. argon2_type type) {
  275. int ret = argon2_ctx(context, type);
  276. if (ret != ARGON2_OK) {
  277. return ret;
  278. }
  279. if (argon2_compare((uint8_t *)hash, context->out, context->outlen)) {
  280. return ARGON2_VERIFY_MISMATCH;
  281. }
  282. return ARGON2_OK;
  283. }
  284. int argon2d_verify_ctx(argon2_context *context, const char *hash) {
  285. return argon2_verify_ctx(context, hash, Argon2_d);
  286. }
  287. int argon2i_verify_ctx(argon2_context *context, const char *hash) {
  288. return argon2_verify_ctx(context, hash, Argon2_i);
  289. }
  290. int argon2id_verify_ctx(argon2_context *context, const char *hash) {
  291. return argon2_verify_ctx(context, hash, Argon2_id);
  292. }
  293. const char *argon2_error_message(int error_code) {
  294. switch (error_code) {
  295. case ARGON2_OK:
  296. return "OK";
  297. case ARGON2_OUTPUT_PTR_NULL:
  298. return "Output pointer is NULL";
  299. case ARGON2_OUTPUT_TOO_SHORT:
  300. return "Output is too short";
  301. case ARGON2_OUTPUT_TOO_LONG:
  302. return "Output is too long";
  303. case ARGON2_PWD_TOO_SHORT:
  304. return "Password is too short";
  305. case ARGON2_PWD_TOO_LONG:
  306. return "Password is too long";
  307. case ARGON2_SALT_TOO_SHORT:
  308. return "Salt is too short";
  309. case ARGON2_SALT_TOO_LONG:
  310. return "Salt is too long";
  311. case ARGON2_AD_TOO_SHORT:
  312. return "Associated data is too short";
  313. case ARGON2_AD_TOO_LONG:
  314. return "Associated data is too long";
  315. case ARGON2_SECRET_TOO_SHORT:
  316. return "Secret is too short";
  317. case ARGON2_SECRET_TOO_LONG:
  318. return "Secret is too long";
  319. case ARGON2_TIME_TOO_SMALL:
  320. return "Time cost is too small";
  321. case ARGON2_TIME_TOO_LARGE:
  322. return "Time cost is too large";
  323. case ARGON2_MEMORY_TOO_LITTLE:
  324. return "Memory cost is too small";
  325. case ARGON2_MEMORY_TOO_MUCH:
  326. return "Memory cost is too large";
  327. case ARGON2_LANES_TOO_FEW:
  328. return "Too few lanes";
  329. case ARGON2_LANES_TOO_MANY:
  330. return "Too many lanes";
  331. case ARGON2_PWD_PTR_MISMATCH:
  332. return "Password pointer is NULL, but password length is not 0";
  333. case ARGON2_SALT_PTR_MISMATCH:
  334. return "Salt pointer is NULL, but salt length is not 0";
  335. case ARGON2_SECRET_PTR_MISMATCH:
  336. return "Secret pointer is NULL, but secret length is not 0";
  337. case ARGON2_AD_PTR_MISMATCH:
  338. return "Associated data pointer is NULL, but ad length is not 0";
  339. case ARGON2_MEMORY_ALLOCATION_ERROR:
  340. return "Memory allocation error";
  341. case ARGON2_FREE_MEMORY_CBK_NULL:
  342. return "The free memory callback is NULL";
  343. case ARGON2_ALLOCATE_MEMORY_CBK_NULL:
  344. return "The allocate memory callback is NULL";
  345. case ARGON2_INCORRECT_PARAMETER:
  346. return "Argon2_Context context is NULL";
  347. case ARGON2_INCORRECT_TYPE:
  348. return "There is no such version of Argon2";
  349. case ARGON2_OUT_PTR_MISMATCH:
  350. return "Output pointer mismatch";
  351. case ARGON2_THREADS_TOO_FEW:
  352. return "Not enough threads";
  353. case ARGON2_THREADS_TOO_MANY:
  354. return "Too many threads";
  355. case ARGON2_MISSING_ARGS:
  356. return "Missing arguments";
  357. case ARGON2_ENCODING_FAIL:
  358. return "Encoding failed";
  359. case ARGON2_DECODING_FAIL:
  360. return "Decoding failed";
  361. case ARGON2_THREAD_FAIL:
  362. return "Threading failure";
  363. case ARGON2_DECODING_LENGTH_FAIL:
  364. return "Some of encoded parameters are too long or too short";
  365. case ARGON2_VERIFY_MISMATCH:
  366. return "The password does not match the supplied hash";
  367. default:
  368. return "Unknown error code";
  369. }
  370. }
  371. size_t argon2_encodedlen(uint32_t t_cost, uint32_t m_cost, uint32_t parallelism,
  372. uint32_t saltlen, uint32_t hashlen, argon2_type type) {
  373. return strlen("$$v=$m=,t=,p=$$") + strlen(argon2_type2string(type, 0)) +
  374. numlen(t_cost) + numlen(m_cost) + numlen(parallelism) +
  375. b64len(saltlen) + b64len(hashlen) + numlen(ARGON2_VERSION_NUMBER) + 1;
  376. }