pwhash.h 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281
  1. #define hydro_pwhash_ENC_ALGBYTES 1
  2. #define hydro_pwhash_HASH_ALGBYTES 1
  3. #define hydro_pwhash_THREADSBYTES 1
  4. #define hydro_pwhash_OPSLIMITBYTES 8
  5. #define hydro_pwhash_MEMLIMITBYTES 8
  6. #define hydro_pwhash_HASHBYTES 32
  7. #define hydro_pwhash_SALTBYTES 16
  8. #define hydro_pwhash_PARAMSBYTES \
  9. (hydro_pwhash_HASH_ALGBYTES + hydro_pwhash_THREADSBYTES + hydro_pwhash_OPSLIMITBYTES + \
  10. hydro_pwhash_MEMLIMITBYTES + hydro_pwhash_SALTBYTES + hydro_pwhash_HASHBYTES)
  11. #define hydro_pwhash_ENC_ALG 0x01
  12. #define hydro_pwhash_HASH_ALG 0x01
  13. #define hydro_pwhash_CONTEXT "hydro_pw"
  14. static int
  15. _hydro_pwhash_hash(uint8_t out[hydro_random_SEEDBYTES], size_t h_len,
  16. const uint8_t salt[hydro_pwhash_SALTBYTES], const char *passwd,
  17. size_t passwd_len, const char ctx[hydro_pwhash_CONTEXTBYTES],
  18. const uint8_t master_key[hydro_pwhash_MASTERKEYBYTES], uint64_t opslimit,
  19. size_t memlimit, uint8_t threads)
  20. {
  21. _hydro_attr_aligned_(16) uint8_t state[gimli_BLOCKBYTES];
  22. hydro_hash_state h_st;
  23. uint8_t tmp64_u8[8];
  24. uint64_t i;
  25. uint8_t tmp8;
  26. COMPILER_ASSERT(hydro_pwhash_MASTERKEYBYTES >= hydro_hash_KEYBYTES);
  27. hydro_hash_init(&h_st, ctx, master_key);
  28. STORE64_LE(tmp64_u8, (uint64_t) passwd_len);
  29. hydro_hash_update(&h_st, tmp64_u8, sizeof tmp64_u8);
  30. hydro_hash_update(&h_st, passwd, passwd_len);
  31. hydro_hash_update(&h_st, salt, hydro_pwhash_SALTBYTES);
  32. tmp8 = hydro_pwhash_HASH_ALG;
  33. hydro_hash_update(&h_st, &tmp8, 1);
  34. hydro_hash_update(&h_st, &threads, 1);
  35. STORE64_LE(tmp64_u8, (uint64_t) memlimit);
  36. hydro_hash_update(&h_st, tmp64_u8, sizeof tmp64_u8);
  37. STORE64_LE(tmp64_u8, (uint64_t) h_len);
  38. hydro_hash_update(&h_st, tmp64_u8, sizeof tmp64_u8);
  39. hydro_hash_final(&h_st, (uint8_t *) (void *) &state, sizeof state);
  40. gimli_core_u8(state, 1);
  41. COMPILER_ASSERT(gimli_RATE >= 8);
  42. for (i = 0; i < opslimit; i++) {
  43. mem_zero(state, gimli_RATE);
  44. STORE64_LE(state, i);
  45. gimli_core_u8(state, 0);
  46. }
  47. mem_zero(state, gimli_RATE);
  48. COMPILER_ASSERT(hydro_random_SEEDBYTES == gimli_CAPACITY);
  49. memcpy(out, state + gimli_RATE, hydro_random_SEEDBYTES);
  50. hydro_memzero(state, sizeof state);
  51. return 0;
  52. }
  53. void
  54. hydro_pwhash_keygen(uint8_t master_key[hydro_pwhash_MASTERKEYBYTES])
  55. {
  56. hydro_random_buf(master_key, hydro_pwhash_MASTERKEYBYTES);
  57. }
  58. int
  59. hydro_pwhash_deterministic(uint8_t *h, size_t h_len, const char *passwd, size_t passwd_len,
  60. const char ctx[hydro_pwhash_CONTEXTBYTES],
  61. const uint8_t master_key[hydro_pwhash_MASTERKEYBYTES], uint64_t opslimit,
  62. size_t memlimit, uint8_t threads)
  63. {
  64. uint8_t seed[hydro_random_SEEDBYTES];
  65. COMPILER_ASSERT(sizeof zero >= hydro_pwhash_SALTBYTES);
  66. COMPILER_ASSERT(sizeof zero >= hydro_pwhash_MASTERKEYBYTES);
  67. (void) memlimit;
  68. if (_hydro_pwhash_hash(seed, h_len, zero, passwd, passwd_len, ctx, master_key, opslimit,
  69. memlimit, threads) != 0) {
  70. return -1;
  71. }
  72. hydro_random_buf_deterministic(h, h_len, seed);
  73. hydro_memzero(seed, sizeof seed);
  74. return 0;
  75. }
  76. int
  77. hydro_pwhash_create(uint8_t stored[hydro_pwhash_STOREDBYTES], const char *passwd, size_t passwd_len,
  78. const uint8_t master_key[hydro_pwhash_MASTERKEYBYTES], uint64_t opslimit,
  79. size_t memlimit, uint8_t threads)
  80. {
  81. uint8_t *const enc_alg = &stored[0];
  82. uint8_t *const secretbox = &enc_alg[hydro_pwhash_ENC_ALGBYTES];
  83. uint8_t *const hash_alg = &secretbox[hydro_secretbox_HEADERBYTES];
  84. uint8_t *const threads_u8 = &hash_alg[hydro_pwhash_HASH_ALGBYTES];
  85. uint8_t *const opslimit_u8 = &threads_u8[hydro_pwhash_THREADSBYTES];
  86. uint8_t *const memlimit_u8 = &opslimit_u8[hydro_pwhash_OPSLIMITBYTES];
  87. uint8_t *const salt = &memlimit_u8[hydro_pwhash_MEMLIMITBYTES];
  88. uint8_t *const h = &salt[hydro_pwhash_SALTBYTES];
  89. COMPILER_ASSERT(hydro_pwhash_STOREDBYTES >= hydro_pwhash_ENC_ALGBYTES +
  90. hydro_secretbox_HEADERBYTES +
  91. hydro_pwhash_PARAMSBYTES);
  92. (void) memlimit;
  93. mem_zero(stored, hydro_pwhash_STOREDBYTES);
  94. *enc_alg = hydro_pwhash_ENC_ALG;
  95. *hash_alg = hydro_pwhash_HASH_ALG;
  96. *threads_u8 = threads;
  97. STORE64_LE(opslimit_u8, opslimit);
  98. STORE64_LE(memlimit_u8, (uint64_t) memlimit);
  99. hydro_random_buf(salt, hydro_pwhash_SALTBYTES);
  100. COMPILER_ASSERT(sizeof zero >= hydro_pwhash_MASTERKEYBYTES);
  101. if (_hydro_pwhash_hash(h, hydro_pwhash_HASHBYTES, salt, passwd, passwd_len,
  102. hydro_pwhash_CONTEXT, zero, opslimit, memlimit, threads) != 0) {
  103. return -1;
  104. }
  105. COMPILER_ASSERT(hydro_pwhash_MASTERKEYBYTES == hydro_secretbox_KEYBYTES);
  106. return hydro_secretbox_encrypt(secretbox, hash_alg, hydro_pwhash_PARAMSBYTES,
  107. (uint64_t) *enc_alg, hydro_pwhash_CONTEXT, master_key);
  108. }
  109. static int
  110. _hydro_pwhash_verify(uint8_t computed_h[hydro_pwhash_HASHBYTES],
  111. const uint8_t stored[hydro_pwhash_STOREDBYTES], const char *passwd,
  112. size_t passwd_len, const uint8_t master_key[hydro_pwhash_MASTERKEYBYTES],
  113. uint64_t opslimit_max, size_t memlimit_max, uint8_t threads_max)
  114. {
  115. const uint8_t *const enc_alg = &stored[0];
  116. const uint8_t *const secretbox = &enc_alg[hydro_pwhash_ENC_ALGBYTES];
  117. uint8_t params[hydro_pwhash_PARAMSBYTES];
  118. uint8_t *const hash_alg = &params[0];
  119. uint8_t *const threads_u8 = &hash_alg[hydro_pwhash_HASH_ALGBYTES];
  120. uint8_t *const opslimit_u8 = &threads_u8[hydro_pwhash_THREADSBYTES];
  121. uint8_t *const memlimit_u8 = &opslimit_u8[hydro_pwhash_OPSLIMITBYTES];
  122. uint8_t *const salt = &memlimit_u8[hydro_pwhash_MEMLIMITBYTES];
  123. uint8_t *const h = &salt[hydro_pwhash_SALTBYTES];
  124. uint64_t opslimit;
  125. size_t memlimit;
  126. uint8_t threads;
  127. (void) memlimit;
  128. if (*enc_alg != hydro_pwhash_ENC_ALG) {
  129. return -1;
  130. }
  131. if (hydro_secretbox_decrypt(params, secretbox,
  132. hydro_secretbox_HEADERBYTES + hydro_pwhash_PARAMSBYTES,
  133. (uint64_t) *enc_alg, hydro_pwhash_CONTEXT, master_key) != 0) {
  134. return -1;
  135. }
  136. if (*hash_alg != hydro_pwhash_HASH_ALG || (opslimit = LOAD64_LE(opslimit_u8)) > opslimit_max ||
  137. (memlimit = (size_t) LOAD64_LE(memlimit_u8)) > memlimit_max ||
  138. (threads = *threads_u8) > threads_max) {
  139. return -1;
  140. }
  141. if (_hydro_pwhash_hash(computed_h, hydro_pwhash_HASHBYTES, salt, passwd, passwd_len,
  142. hydro_pwhash_CONTEXT, zero, opslimit, memlimit, threads) == 0 &&
  143. hydro_equal(computed_h, h, hydro_pwhash_HASHBYTES) == 1) {
  144. return 0;
  145. }
  146. return -1;
  147. }
  148. int
  149. hydro_pwhash_verify(const uint8_t stored[hydro_pwhash_STOREDBYTES], const char *passwd,
  150. size_t passwd_len, const uint8_t master_key[hydro_pwhash_MASTERKEYBYTES],
  151. uint64_t opslimit_max, size_t memlimit_max, uint8_t threads_max)
  152. {
  153. uint8_t computed_h[hydro_pwhash_HASHBYTES];
  154. int ret;
  155. ret = _hydro_pwhash_verify(computed_h, stored, passwd, passwd_len, master_key, opslimit_max,
  156. memlimit_max, threads_max);
  157. hydro_memzero(computed_h, sizeof computed_h);
  158. return ret;
  159. }
  160. int
  161. hydro_pwhash_derive_static_key(uint8_t *static_key, size_t static_key_len,
  162. const uint8_t stored[hydro_pwhash_STOREDBYTES], const char *passwd,
  163. size_t passwd_len, const char ctx[hydro_pwhash_CONTEXTBYTES],
  164. const uint8_t master_key[hydro_pwhash_MASTERKEYBYTES],
  165. uint64_t opslimit_max, size_t memlimit_max, uint8_t threads_max)
  166. {
  167. uint8_t computed_h[hydro_pwhash_HASHBYTES];
  168. if (_hydro_pwhash_verify(computed_h, stored, passwd, passwd_len, master_key, opslimit_max,
  169. memlimit_max, threads_max) != 0) {
  170. hydro_memzero(computed_h, sizeof computed_h);
  171. return -1;
  172. }
  173. COMPILER_ASSERT(hydro_kdf_CONTEXTBYTES <= hydro_pwhash_CONTEXTBYTES);
  174. COMPILER_ASSERT(hydro_kdf_KEYBYTES <= hydro_pwhash_HASHBYTES);
  175. hydro_kdf_derive_from_key(static_key, static_key_len, 0, ctx, computed_h);
  176. hydro_memzero(computed_h, sizeof computed_h);
  177. return 0;
  178. }
  179. int
  180. hydro_pwhash_reencrypt(uint8_t stored[hydro_pwhash_STOREDBYTES],
  181. const uint8_t master_key[hydro_pwhash_MASTERKEYBYTES],
  182. const uint8_t new_master_key[hydro_pwhash_MASTERKEYBYTES])
  183. {
  184. uint8_t *const enc_alg = &stored[0];
  185. uint8_t *const secretbox = &enc_alg[hydro_pwhash_ENC_ALGBYTES];
  186. uint8_t *const params = &secretbox[hydro_secretbox_HEADERBYTES];
  187. if (*enc_alg != hydro_pwhash_ENC_ALG) {
  188. return -1;
  189. }
  190. if (hydro_secretbox_decrypt(secretbox, secretbox,
  191. hydro_secretbox_HEADERBYTES + hydro_pwhash_PARAMSBYTES,
  192. (uint64_t) *enc_alg, hydro_pwhash_CONTEXT, master_key) != 0) {
  193. return -1;
  194. }
  195. memmove(params, secretbox, hydro_pwhash_PARAMSBYTES);
  196. return hydro_secretbox_encrypt(secretbox, params, hydro_pwhash_PARAMSBYTES, (uint64_t) *enc_alg,
  197. hydro_pwhash_CONTEXT, new_master_key);
  198. }
  199. int
  200. hydro_pwhash_upgrade(uint8_t stored[hydro_pwhash_STOREDBYTES],
  201. const uint8_t master_key[hydro_pwhash_MASTERKEYBYTES], uint64_t opslimit,
  202. size_t memlimit, uint8_t threads)
  203. {
  204. uint8_t *const enc_alg = &stored[0];
  205. uint8_t *const secretbox = &enc_alg[hydro_pwhash_ENC_ALGBYTES];
  206. uint8_t *const params = &secretbox[hydro_secretbox_HEADERBYTES];
  207. uint8_t *const hash_alg = &params[0];
  208. uint8_t *const threads_u8 = &hash_alg[hydro_pwhash_HASH_ALGBYTES];
  209. uint8_t *const opslimit_u8 = &threads_u8[hydro_pwhash_THREADSBYTES];
  210. uint8_t *const memlimit_u8 = &opslimit_u8[hydro_pwhash_OPSLIMITBYTES];
  211. uint8_t *const salt = &memlimit_u8[hydro_pwhash_MEMLIMITBYTES];
  212. uint8_t *const h = &salt[hydro_pwhash_SALTBYTES];
  213. _hydro_attr_aligned_(16) uint8_t state[gimli_BLOCKBYTES];
  214. uint64_t i;
  215. uint64_t opslimit_prev;
  216. if (*enc_alg != hydro_pwhash_ENC_ALG) {
  217. return -1;
  218. }
  219. if (hydro_secretbox_decrypt(secretbox, secretbox,
  220. hydro_secretbox_HEADERBYTES + hydro_pwhash_PARAMSBYTES,
  221. (uint64_t) *enc_alg, hydro_pwhash_CONTEXT, master_key) != 0) {
  222. return -1;
  223. }
  224. memmove(params, secretbox, hydro_pwhash_PARAMSBYTES);
  225. opslimit_prev = LOAD64_LE(opslimit_u8);
  226. if (*hash_alg != hydro_pwhash_HASH_ALG) {
  227. mem_zero(stored, hydro_pwhash_STOREDBYTES);
  228. return -1;
  229. }
  230. COMPILER_ASSERT(hydro_random_SEEDBYTES == gimli_CAPACITY);
  231. memcpy(state + gimli_RATE, h, hydro_random_SEEDBYTES);
  232. for (i = opslimit_prev; i < opslimit; i++) {
  233. mem_zero(state, gimli_RATE);
  234. STORE64_LE(state, i);
  235. gimli_core_u8(state, 0);
  236. }
  237. mem_zero(state, gimli_RATE);
  238. memcpy(h, state + gimli_RATE, hydro_random_SEEDBYTES);
  239. *threads_u8 = threads;
  240. STORE64_LE(opslimit_u8, opslimit);
  241. STORE64_LE(memlimit_u8, (uint64_t) memlimit);
  242. return hydro_secretbox_encrypt(secretbox, params, hydro_pwhash_PARAMSBYTES, (uint64_t) *enc_alg,
  243. hydro_pwhash_CONTEXT, master_key);
  244. }