8 #include "crypto_pwhash_scryptsalsa208sha256.h"
9 #include "crypto_scrypt.h"
10 #include "randombytes.h"
13 #define SETTING_SIZE(saltbytes) \
14 (sizeof "$7$" - 1U) + \
15 (1U /* N_log2 */) + (5U /* r */) + (5U /* p */) + BYTES2CHARS(saltbytes)
18 pickparams(unsigned long long opslimit, const size_t memlimit,
19 uint32_t * const N_log2, uint32_t * const p, uint32_t * const r)
21 unsigned long long maxN;
22 unsigned long long maxrp;
24 if (opslimit < 32768) {
28 if (opslimit < memlimit / 32) {
30 maxN = opslimit / (*r * 4);
31 for (*N_log2 = 1; *N_log2 < 63; *N_log2 += 1) {
32 if ((uint64_t)(1) << *N_log2 > maxN / 2) {
37 maxN = memlimit / ((size_t) *r * 128);
38 for (*N_log2 = 1; *N_log2 < 63; *N_log2 += 1) {
39 if ((uint64_t) (1) << *N_log2 > maxN / 2) {
43 maxrp = (opslimit / 4) / ((uint64_t) (1) << *N_log2);
45 if (maxrp > 0x3fffffff) {
49 *p = (uint32_t) (maxrp) / *r;
55 crypto_pwhash_scryptsalsa208sha256_saltbytes(void)
57 return crypto_pwhash_scryptsalsa208sha256_SALTBYTES;
61 crypto_pwhash_scryptsalsa208sha256_strbytes(void)
63 return crypto_pwhash_scryptsalsa208sha256_STRBYTES;
67 crypto_pwhash_scryptsalsa208sha256_strprefix(void)
69 return crypto_pwhash_scryptsalsa208sha256_STRPREFIX;
73 crypto_pwhash_scryptsalsa208sha256_opslimit_interactive(void)
75 return crypto_pwhash_scryptsalsa208sha256_OPSLIMIT_INTERACTIVE;
79 crypto_pwhash_scryptsalsa208sha256_memlimit_interactive(void)
81 return crypto_pwhash_scryptsalsa208sha256_MEMLIMIT_INTERACTIVE;
85 crypto_pwhash_scryptsalsa208sha256_opslimit_sensitive(void)
87 return crypto_pwhash_scryptsalsa208sha256_OPSLIMIT_SENSITIVE;
91 crypto_pwhash_scryptsalsa208sha256_memlimit_sensitive(void)
93 return crypto_pwhash_scryptsalsa208sha256_MEMLIMIT_SENSITIVE;
97 crypto_pwhash_scryptsalsa208sha256(unsigned char * const out,
98 unsigned long long outlen,
99 const char * const passwd,
100 unsigned long long passwdlen,
101 const unsigned char * const salt,
102 unsigned long long opslimit,
109 memset(out, 0, outlen);
110 if (passwdlen > SIZE_MAX || outlen > SIZE_MAX) {
111 errno = EFBIG; /* LCOV_EXCL_LINE */
112 return -1; /* LCOV_EXCL_LINE */
114 if (pickparams(opslimit, memlimit, &N_log2, &p, &r) != 0) {
115 errno = EINVAL; /* LCOV_EXCL_LINE */
116 return -1; /* LCOV_EXCL_LINE */
118 return crypto_pwhash_scryptsalsa208sha256_ll((const uint8_t *) passwd,
120 (const uint8_t *) salt,
121 crypto_pwhash_scryptsalsa208sha256_SALTBYTES,
122 (uint64_t) (1) << N_log2, r, p,
123 out, (size_t) outlen);
127 crypto_pwhash_scryptsalsa208sha256_str(char out[crypto_pwhash_scryptsalsa208sha256_STRBYTES],
128 const char * const passwd,
129 unsigned long long passwdlen,
130 unsigned long long opslimit,
133 uint8_t salt[crypto_pwhash_scryptsalsa208sha256_STRSALTBYTES];
134 char setting[crypto_pwhash_scryptsalsa208sha256_STRSETTINGBYTES + 1U];
135 escrypt_local_t escrypt_local;
140 memset(out, 0, crypto_pwhash_scryptsalsa208sha256_STRBYTES);
141 if (passwdlen > SIZE_MAX) {
142 errno = EFBIG; /* LCOV_EXCL_LINE */
143 return -1; /* LCOV_EXCL_LINE */
145 if (pickparams(opslimit, memlimit, &N_log2, &p, &r) != 0) {
146 errno = EINVAL; /* LCOV_EXCL_LINE */
147 return -1; /* LCOV_EXCL_LINE */
149 randombytes_buf(salt, sizeof salt);
150 if (escrypt_gensalt_r(N_log2, r, p, salt, sizeof salt,
151 (uint8_t *) setting, sizeof setting) == NULL) {
152 errno = EINVAL; /* LCOV_EXCL_LINE */
153 return -1; /* LCOV_EXCL_LINE */
155 if (escrypt_init_local(&escrypt_local) != 0) {
156 return -1; /* LCOV_EXCL_LINE */
158 if (escrypt_r(&escrypt_local, (const uint8_t *) passwd, (size_t) passwdlen,
159 (const uint8_t *) setting, (uint8_t *) out,
160 crypto_pwhash_scryptsalsa208sha256_STRBYTES) == NULL) {
161 /* LCOV_EXCL_START */
162 escrypt_free_local(&escrypt_local);
167 escrypt_free_local(&escrypt_local);
170 (int[SETTING_SIZE(crypto_pwhash_scryptsalsa208sha256_STRSALTBYTES)
171 == crypto_pwhash_scryptsalsa208sha256_STRSETTINGBYTES ? 1 : -1]);
173 (int[crypto_pwhash_scryptsalsa208sha256_STRSETTINGBYTES + 1U +
174 crypto_pwhash_scryptsalsa208sha256_STRHASHBYTES_ENCODED + 1U
175 == crypto_pwhash_scryptsalsa208sha256_STRBYTES ? 1 : -1]);
181 crypto_pwhash_scryptsalsa208sha256_str_verify(const char str[crypto_pwhash_scryptsalsa208sha256_STRBYTES],
182 const char * const passwd,
183 unsigned long long passwdlen)
185 char wanted[crypto_pwhash_scryptsalsa208sha256_STRBYTES];
186 escrypt_local_t escrypt_local;
189 if (memchr(str, 0, crypto_pwhash_scryptsalsa208sha256_STRBYTES) !=
190 &str[crypto_pwhash_scryptsalsa208sha256_STRBYTES - 1U]) {
193 if (escrypt_init_local(&escrypt_local) != 0) {
194 return -1; /* LCOV_EXCL_LINE */
196 if (escrypt_r(&escrypt_local, (const uint8_t *) passwd, (size_t) passwdlen,
197 (const uint8_t *) str, (uint8_t *) wanted,
198 sizeof wanted) == NULL) {
199 escrypt_free_local(&escrypt_local);
202 escrypt_free_local(&escrypt_local);
203 ret = sodium_memcmp(wanted, str, sizeof wanted);
204 sodium_memzero(wanted, sizeof wanted);