1 #ifdef HAVE_CONFIG_H
2 #include "config.h"
3 #endif
4 #ifdef VANILLA_NACL /* toxcore only uses this when libsodium is unavailable */
5
6 #include <errno.h>
7 #include <limits.h>
8 #include <stddef.h>
9 #include <stdint.h>
10 #include <string.h>
11 //#include <stdio.h>
12
13 #include "crypto_pwhash_scryptsalsa208sha256.h"
14 #include "crypto_scrypt.h"
15 #include "../../toxcore/crypto_core.h"
16
17 #define SETTING_SIZE(saltbytes) \
18 (sizeof "$7$" - 1U) + \
19 (1U /* N_log2 */) + (5U /* r */) + (5U /* p */) + BYTES2CHARS(saltbytes)
20
21 static int
pickparams(unsigned long long opslimit,const size_t memlimit,uint32_t * const N_log2,uint32_t * const p,uint32_t * const r)22 pickparams(unsigned long long opslimit, const size_t memlimit,
23 uint32_t * const N_log2, uint32_t * const p, uint32_t * const r)
24 {
25 unsigned long long maxN;
26 unsigned long long maxrp;
27
28 if (opslimit < 32768) {
29 opslimit = 32768;
30 }
31 *r = 8;
32 if (opslimit < memlimit / 32) {
33 *p = 1;
34 maxN = opslimit / (*r * 4);
35 for (*N_log2 = 1; *N_log2 < 63; *N_log2 += 1) {
36 if ((uint64_t)(1) << *N_log2 > maxN / 2) {
37 break;
38 }
39 }
40 } else {
41 maxN = memlimit / (*r * 128);
42 for (*N_log2 = 1; *N_log2 < 63; *N_log2 += 1) {
43 if ((uint64_t) (1) << *N_log2 > maxN / 2) {
44 break;
45 }
46 }
47 maxrp = (opslimit / 4) / ((uint64_t) (1) << *N_log2);
48 if (maxrp > 0x3fffffff) {
49 maxrp = 0x3fffffff;
50 }
51 *p = (uint32_t) (maxrp) / *r;
52 }
53 return 0;
54 }
55
56 size_t
crypto_pwhash_scryptsalsa208sha256_saltbytes(void)57 crypto_pwhash_scryptsalsa208sha256_saltbytes(void)
58 {
59 return crypto_pwhash_scryptsalsa208sha256_SALTBYTES;
60 }
61
62 size_t
crypto_pwhash_scryptsalsa208sha256_strbytes(void)63 crypto_pwhash_scryptsalsa208sha256_strbytes(void)
64 {
65 return crypto_pwhash_scryptsalsa208sha256_STRBYTES;
66 }
67
68 const char *
crypto_pwhash_scryptsalsa208sha256_strprefix(void)69 crypto_pwhash_scryptsalsa208sha256_strprefix(void)
70 {
71 return crypto_pwhash_scryptsalsa208sha256_STRPREFIX;
72 }
73
74 size_t
crypto_pwhash_scryptsalsa208sha256_opslimit_interactive(void)75 crypto_pwhash_scryptsalsa208sha256_opslimit_interactive(void)
76 {
77 return crypto_pwhash_scryptsalsa208sha256_OPSLIMIT_INTERACTIVE;
78 }
79
80 size_t
crypto_pwhash_scryptsalsa208sha256_memlimit_interactive(void)81 crypto_pwhash_scryptsalsa208sha256_memlimit_interactive(void)
82 {
83 return crypto_pwhash_scryptsalsa208sha256_MEMLIMIT_INTERACTIVE;
84 }
85
86 size_t
crypto_pwhash_scryptsalsa208sha256_opslimit_sensitive(void)87 crypto_pwhash_scryptsalsa208sha256_opslimit_sensitive(void)
88 {
89 return crypto_pwhash_scryptsalsa208sha256_OPSLIMIT_SENSITIVE;
90 }
91
92 size_t
crypto_pwhash_scryptsalsa208sha256_memlimit_sensitive(void)93 crypto_pwhash_scryptsalsa208sha256_memlimit_sensitive(void)
94 {
95 return crypto_pwhash_scryptsalsa208sha256_MEMLIMIT_SENSITIVE;
96 }
97
98 int
crypto_pwhash_scryptsalsa208sha256(unsigned char * const out,unsigned long long outlen,const char * const passwd,unsigned long long passwdlen,const unsigned char * const salt,unsigned long long opslimit,size_t memlimit)99 crypto_pwhash_scryptsalsa208sha256(unsigned char * const out,
100 unsigned long long outlen,
101 const char * const passwd,
102 unsigned long long passwdlen,
103 const unsigned char * const salt,
104 unsigned long long opslimit,
105 size_t memlimit)
106 {
107 //fprintf(stderr, "Doing that dirty thang!!!!\n");
108 uint32_t N_log2;
109 uint32_t p;
110 uint32_t r;
111
112 memset(out, 0, outlen);
113 if (passwdlen > SIZE_MAX || outlen > SIZE_MAX) {
114 errno = EFBIG;
115 return -1;
116 }
117 if (pickparams(opslimit, memlimit, &N_log2, &p, &r) != 0) {
118 errno = EINVAL;
119 return -1;
120 }
121 return crypto_pwhash_scryptsalsa208sha256_ll((const uint8_t *) passwd,
122 (size_t) passwdlen,
123 (const uint8_t *) salt,
124 crypto_pwhash_scryptsalsa208sha256_SALTBYTES,
125 (uint64_t) (1) << N_log2, r, p,
126 out, (size_t) outlen);
127 }
128
129 int
crypto_pwhash_scryptsalsa208sha256_str(char out[crypto_pwhash_scryptsalsa208sha256_STRBYTES],const char * const passwd,unsigned long long passwdlen,unsigned long long opslimit,size_t memlimit)130 crypto_pwhash_scryptsalsa208sha256_str(char out[crypto_pwhash_scryptsalsa208sha256_STRBYTES],
131 const char * const passwd,
132 unsigned long long passwdlen,
133 unsigned long long opslimit,
134 size_t memlimit)
135 {
136 uint8_t salt[crypto_pwhash_scryptsalsa208sha256_STRSALTBYTES];
137 char setting[crypto_pwhash_scryptsalsa208sha256_STRSETTINGBYTES + 1U];
138 escrypt_local_t escrypt_local;
139 uint32_t N_log2;
140 uint32_t p;
141 uint32_t r;
142
143 memset(out, 0, crypto_pwhash_scryptsalsa208sha256_STRBYTES);
144 if (passwdlen > SIZE_MAX) {
145 errno = EFBIG;
146 return -1;
147 }
148 if (pickparams(opslimit, memlimit, &N_log2, &p, &r) != 0) {
149 errno = EINVAL;
150 return -1;
151 }
152 random_bytes(salt, sizeof salt);
153 if (escrypt_gensalt_r(N_log2, r, p, salt, sizeof salt,
154 (uint8_t *) setting, sizeof setting) == NULL) {
155 errno = EINVAL;
156 return -1;
157 }
158 if (escrypt_init_local(&escrypt_local) != 0) {
159 return -1;
160 }
161 if (escrypt_r(&escrypt_local, (const uint8_t *) passwd, (size_t) passwdlen,
162 (const uint8_t *) setting, (uint8_t *) out,
163 crypto_pwhash_scryptsalsa208sha256_STRBYTES) == NULL) {
164 escrypt_free_local(&escrypt_local);
165 errno = EINVAL;
166 return -1;
167 }
168 escrypt_free_local(&escrypt_local);
169
170 (void) sizeof
171 (int[SETTING_SIZE(crypto_pwhash_scryptsalsa208sha256_STRSALTBYTES)
172 == crypto_pwhash_scryptsalsa208sha256_STRSETTINGBYTES ? 1 : -1]);
173 (void) sizeof
174 (int[crypto_pwhash_scryptsalsa208sha256_STRSETTINGBYTES + 1U +
175 crypto_pwhash_scryptsalsa208sha256_STRHASHBYTES_ENCODED + 1U
176 == crypto_pwhash_scryptsalsa208sha256_STRBYTES ? 1 : -1]);
177
178 return 0;
179 }
180
181 int
crypto_pwhash_scryptsalsa208sha256_str_verify(const char str[crypto_pwhash_scryptsalsa208sha256_STRBYTES],const char * const passwd,unsigned long long passwdlen)182 crypto_pwhash_scryptsalsa208sha256_str_verify(const char str[crypto_pwhash_scryptsalsa208sha256_STRBYTES],
183 const char * const passwd,
184 unsigned long long passwdlen)
185 {
186 char wanted[crypto_pwhash_scryptsalsa208sha256_STRBYTES];
187 escrypt_local_t escrypt_local;
188 int ret = -1;
189
190 if (memchr(str, 0, crypto_pwhash_scryptsalsa208sha256_STRBYTES) !=
191 &str[crypto_pwhash_scryptsalsa208sha256_STRBYTES - 1U]) {
192 return -1;
193 }
194 if (escrypt_init_local(&escrypt_local) != 0) {
195 return -1;
196 }
197 if (escrypt_r(&escrypt_local, (const uint8_t *) passwd, (size_t) passwdlen,
198 (const uint8_t *) str, (uint8_t *) wanted,
199 sizeof wanted) == NULL) {
200 escrypt_free_local(&escrypt_local);
201 return -1;
202 }
203 escrypt_free_local(&escrypt_local);
204 ret = crypto_memcmp((const uint8_t *) wanted, (const uint8_t *) str, sizeof wanted);
205 crypto_memzero(wanted, sizeof wanted);
206
207 return ret;
208 }
209
210 #endif
211