pwhash_argon2i.c 7.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290
  1. #include <errno.h>
  2. #include <limits.h>
  3. #include <stddef.h>
  4. #include <stdint.h>
  5. #include <stdlib.h>
  6. #include <string.h>
  7. #include "argon2-core.h"
  8. #include "argon2-encoding.h"
  9. #include "argon2.h"
  10. #include "crypto_pwhash.h"
  11. #include "crypto_pwhash_argon2i.h"
  12. #include "crypto_pwhash_argon2id.h"
  13. #include "private/common.h"
  14. #include "randombytes.h"
  15. #include "utils.h"
  16. #define STR_HASHBYTES 32U
  17. int
  18. crypto_pwhash_argon2i_alg_argon2i13(void)
  19. {
  20. return crypto_pwhash_argon2i_ALG_ARGON2I13;
  21. }
  22. size_t
  23. crypto_pwhash_argon2i_bytes_min(void)
  24. {
  25. COMPILER_ASSERT(crypto_pwhash_argon2i_BYTES_MIN >= ARGON2_MIN_OUTLEN);
  26. return crypto_pwhash_argon2i_BYTES_MIN;
  27. }
  28. size_t
  29. crypto_pwhash_argon2i_bytes_max(void)
  30. {
  31. COMPILER_ASSERT(crypto_pwhash_argon2i_BYTES_MAX <= ARGON2_MAX_OUTLEN);
  32. return crypto_pwhash_argon2i_BYTES_MAX;
  33. }
  34. size_t
  35. crypto_pwhash_argon2i_passwd_min(void)
  36. {
  37. COMPILER_ASSERT(crypto_pwhash_argon2i_PASSWD_MIN >= ARGON2_MIN_PWD_LENGTH);
  38. return crypto_pwhash_argon2i_PASSWD_MIN;
  39. }
  40. size_t
  41. crypto_pwhash_argon2i_passwd_max(void)
  42. {
  43. COMPILER_ASSERT(crypto_pwhash_argon2i_PASSWD_MAX <= ARGON2_MAX_PWD_LENGTH);
  44. return crypto_pwhash_argon2i_PASSWD_MAX;
  45. }
  46. size_t
  47. crypto_pwhash_argon2i_saltbytes(void)
  48. {
  49. COMPILER_ASSERT(crypto_pwhash_argon2i_SALTBYTES >= ARGON2_MIN_SALT_LENGTH);
  50. COMPILER_ASSERT(crypto_pwhash_argon2i_SALTBYTES <= ARGON2_MAX_SALT_LENGTH);
  51. return crypto_pwhash_argon2i_SALTBYTES;
  52. }
  53. size_t
  54. crypto_pwhash_argon2i_strbytes(void)
  55. {
  56. return crypto_pwhash_argon2i_STRBYTES;
  57. }
  58. const char*
  59. crypto_pwhash_argon2i_strprefix(void)
  60. {
  61. return crypto_pwhash_argon2i_STRPREFIX;
  62. }
  63. size_t
  64. crypto_pwhash_argon2i_opslimit_min(void)
  65. {
  66. COMPILER_ASSERT(crypto_pwhash_argon2i_OPSLIMIT_MIN >= ARGON2_MIN_TIME);
  67. return crypto_pwhash_argon2i_OPSLIMIT_MIN;
  68. }
  69. size_t
  70. crypto_pwhash_argon2i_opslimit_max(void)
  71. {
  72. COMPILER_ASSERT(crypto_pwhash_argon2i_OPSLIMIT_MAX <= ARGON2_MAX_TIME);
  73. return crypto_pwhash_argon2i_OPSLIMIT_MAX;
  74. }
  75. size_t
  76. crypto_pwhash_argon2i_memlimit_min(void)
  77. {
  78. COMPILER_ASSERT((crypto_pwhash_argon2i_MEMLIMIT_MIN / 1024U) >= ARGON2_MIN_MEMORY);
  79. return crypto_pwhash_argon2i_MEMLIMIT_MIN;
  80. }
  81. size_t
  82. crypto_pwhash_argon2i_memlimit_max(void)
  83. {
  84. COMPILER_ASSERT((crypto_pwhash_argon2i_MEMLIMIT_MAX / 1024U) <= ARGON2_MAX_MEMORY);
  85. return crypto_pwhash_argon2i_MEMLIMIT_MAX;
  86. }
  87. size_t
  88. crypto_pwhash_argon2i_opslimit_interactive(void)
  89. {
  90. return crypto_pwhash_argon2i_OPSLIMIT_INTERACTIVE;
  91. }
  92. size_t
  93. crypto_pwhash_argon2i_memlimit_interactive(void)
  94. {
  95. return crypto_pwhash_argon2i_MEMLIMIT_INTERACTIVE;
  96. }
  97. size_t
  98. crypto_pwhash_argon2i_opslimit_moderate(void)
  99. {
  100. return crypto_pwhash_argon2i_OPSLIMIT_MODERATE;
  101. }
  102. size_t
  103. crypto_pwhash_argon2i_memlimit_moderate(void)
  104. {
  105. return crypto_pwhash_argon2i_MEMLIMIT_MODERATE;
  106. }
  107. size_t
  108. crypto_pwhash_argon2i_opslimit_sensitive(void)
  109. {
  110. return crypto_pwhash_argon2i_OPSLIMIT_SENSITIVE;
  111. }
  112. size_t
  113. crypto_pwhash_argon2i_memlimit_sensitive(void)
  114. {
  115. return crypto_pwhash_argon2i_MEMLIMIT_SENSITIVE;
  116. }
  117. int
  118. crypto_pwhash_argon2i(unsigned char *const out, unsigned long long outlen,
  119. const char *const passwd, unsigned long long passwdlen,
  120. const unsigned char *const salt,
  121. unsigned long long opslimit, size_t memlimit, int alg)
  122. {
  123. memset(out, 0, outlen);
  124. if (outlen > crypto_pwhash_argon2i_BYTES_MAX) {
  125. errno = EFBIG;
  126. return -1;
  127. }
  128. if (outlen < crypto_pwhash_argon2i_BYTES_MIN) {
  129. errno = EINVAL;
  130. return -1;
  131. }
  132. if (passwdlen > crypto_pwhash_argon2i_PASSWD_MAX ||
  133. opslimit > crypto_pwhash_argon2i_OPSLIMIT_MAX ||
  134. memlimit > crypto_pwhash_argon2i_MEMLIMIT_MAX) {
  135. errno = EFBIG;
  136. return -1;
  137. }
  138. if (passwdlen < crypto_pwhash_argon2i_PASSWD_MIN ||
  139. opslimit < crypto_pwhash_argon2i_OPSLIMIT_MIN ||
  140. memlimit < crypto_pwhash_argon2i_MEMLIMIT_MIN) {
  141. errno = EINVAL;
  142. return -1;
  143. }
  144. switch (alg) {
  145. case crypto_pwhash_argon2i_ALG_ARGON2I13:
  146. if (argon2i_hash_raw((uint32_t) opslimit, (uint32_t) (memlimit / 1024U),
  147. (uint32_t) 1U, passwd, (size_t) passwdlen, salt,
  148. (size_t) crypto_pwhash_argon2i_SALTBYTES, out,
  149. (size_t) outlen) != ARGON2_OK) {
  150. return -1; /* LCOV_EXCL_LINE */
  151. }
  152. return 0;
  153. default:
  154. errno = EINVAL;
  155. return -1;
  156. }
  157. }
  158. int
  159. crypto_pwhash_argon2i_str(char out[crypto_pwhash_argon2i_STRBYTES],
  160. const char *const passwd,
  161. unsigned long long passwdlen,
  162. unsigned long long opslimit, size_t memlimit)
  163. {
  164. unsigned char salt[crypto_pwhash_argon2i_SALTBYTES];
  165. memset(out, 0, crypto_pwhash_argon2i_STRBYTES);
  166. if (passwdlen > crypto_pwhash_argon2i_PASSWD_MAX ||
  167. opslimit > crypto_pwhash_argon2i_OPSLIMIT_MAX ||
  168. memlimit > crypto_pwhash_argon2i_MEMLIMIT_MAX) {
  169. errno = EFBIG;
  170. return -1;
  171. }
  172. if (passwdlen < crypto_pwhash_argon2i_PASSWD_MIN ||
  173. opslimit < crypto_pwhash_argon2i_OPSLIMIT_MIN ||
  174. memlimit < crypto_pwhash_argon2i_MEMLIMIT_MIN) {
  175. errno = EINVAL;
  176. return -1;
  177. }
  178. randombytes_buf(salt, sizeof salt);
  179. if (argon2i_hash_encoded((uint32_t) opslimit, (uint32_t) (memlimit / 1024U),
  180. (uint32_t) 1U, passwd, (size_t) passwdlen, salt,
  181. sizeof salt, STR_HASHBYTES, out,
  182. crypto_pwhash_argon2i_STRBYTES) != ARGON2_OK) {
  183. return -1; /* LCOV_EXCL_LINE */
  184. }
  185. return 0;
  186. }
  187. int
  188. crypto_pwhash_argon2i_str_verify(const char str[crypto_pwhash_argon2i_STRBYTES],
  189. const char *const passwd,
  190. unsigned long long passwdlen)
  191. {
  192. int verify_ret;
  193. if (passwdlen > crypto_pwhash_argon2i_PASSWD_MAX) {
  194. errno = EFBIG;
  195. return -1;
  196. }
  197. /* LCOV_EXCL_START */
  198. if (passwdlen < crypto_pwhash_argon2i_PASSWD_MIN) {
  199. errno = EINVAL;
  200. return -1;
  201. }
  202. /* LCOV_EXCL_STOP */
  203. verify_ret = argon2i_verify(str, passwd, (size_t) passwdlen);
  204. if (verify_ret == ARGON2_OK) {
  205. return 0;
  206. }
  207. if (verify_ret == ARGON2_VERIFY_MISMATCH) {
  208. errno = EINVAL;
  209. }
  210. return -1;
  211. }
  212. static int
  213. _needs_rehash(const char *str, unsigned long long opslimit, size_t memlimit,
  214. argon2_type type)
  215. {
  216. unsigned char *fodder;
  217. argon2_context ctx;
  218. size_t fodder_len;
  219. int ret = -1;
  220. fodder_len = strlen(str);
  221. memlimit /= 1024U;
  222. if (opslimit > UINT32_MAX || memlimit > UINT32_MAX ||
  223. fodder_len >= crypto_pwhash_STRBYTES) {
  224. errno = EINVAL;
  225. return -1;
  226. }
  227. memset(&ctx, 0, sizeof ctx);
  228. if ((fodder = (unsigned char *) calloc(fodder_len, 1U)) == NULL) {
  229. return -1; /* LCOV_EXCL_LINE */
  230. }
  231. ctx.out = ctx.pwd = ctx.salt = fodder;
  232. ctx.outlen = ctx.pwdlen = ctx.saltlen = (uint32_t) fodder_len;
  233. ctx.ad = ctx.secret = NULL;
  234. ctx.adlen = ctx.secretlen = 0U;
  235. if (decode_string(&ctx, str, type) != 0) {
  236. errno = EINVAL;
  237. ret = -1;
  238. } else if (ctx.t_cost != (uint32_t) opslimit ||
  239. ctx.m_cost != (uint32_t) memlimit) {
  240. ret = 1;
  241. } else {
  242. ret = 0;
  243. }
  244. free(fodder);
  245. return ret;
  246. }
  247. int
  248. crypto_pwhash_argon2i_str_needs_rehash(const char str[crypto_pwhash_argon2i_STRBYTES],
  249. unsigned long long opslimit, size_t memlimit)
  250. {
  251. return _needs_rehash(str, opslimit, memlimit, Argon2_i);
  252. }
  253. int
  254. crypto_pwhash_argon2id_str_needs_rehash(const char str[crypto_pwhash_argon2id_STRBYTES],
  255. unsigned long long opslimit, size_t memlimit)
  256. {
  257. return _needs_rehash(str, opslimit, memlimit, Argon2_id);
  258. }