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