summaryrefslogtreecommitdiff
path: root/toxencryptsave/crypto_pwhash_scryptsalsa208sha256/crypto_scrypt-common.c
diff options
context:
space:
mode:
Diffstat (limited to 'toxencryptsave/crypto_pwhash_scryptsalsa208sha256/crypto_scrypt-common.c')
-rw-r--r--toxencryptsave/crypto_pwhash_scryptsalsa208sha256/crypto_scrypt-common.c257
1 files changed, 257 insertions, 0 deletions
diff --git a/toxencryptsave/crypto_pwhash_scryptsalsa208sha256/crypto_scrypt-common.c b/toxencryptsave/crypto_pwhash_scryptsalsa208sha256/crypto_scrypt-common.c
new file mode 100644
index 00000000..5a5c5525
--- /dev/null
+++ b/toxencryptsave/crypto_pwhash_scryptsalsa208sha256/crypto_scrypt-common.c
@@ -0,0 +1,257 @@
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/*-
7 * Copyright 2013 Alexander Peslyak
8 * All rights reserved.
9 *
10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted.
12 *
13 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
14 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
15 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
16 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
17 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
18 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
19 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
20 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
21 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
22 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
23 * SUCH DAMAGE.
24 */
25
26#include <stdint.h>
27#include <string.h>
28
29#include "crypto_pwhash_scryptsalsa208sha256.h"
30#include "crypto_scrypt.h"
31#include "runtime.h"
32#include "utils.h"
33
34static const char * const itoa64 =
35 "./0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
36
37static uint8_t *
38encode64_uint32(uint8_t * dst, size_t dstlen, uint32_t src, uint32_t srcbits)
39{
40 uint32_t bit;
41
42 for (bit = 0; bit < srcbits; bit += 6) {
43 if (dstlen < 1) {
44 return NULL;
45 }
46 *dst++ = itoa64[src & 0x3f];
47 dstlen--;
48 src >>= 6;
49 }
50
51 return dst;
52}
53
54static uint8_t *
55encode64(uint8_t * dst, size_t dstlen, const uint8_t * src, size_t srclen)
56{
57 size_t i;
58
59 for (i = 0; i < srclen; ) {
60 uint8_t * dnext;
61 uint32_t value = 0, bits = 0;
62 do {
63 value |= (uint32_t)src[i++] << bits;
64 bits += 8;
65 } while (bits < 24 && i < srclen);
66 dnext = encode64_uint32(dst, dstlen, value, bits);
67 if (!dnext) {
68 return NULL;
69 }
70 dstlen -= dnext - dst;
71 dst = dnext;
72 }
73
74 return dst;
75}
76
77static int
78decode64_one(uint32_t * dst, uint8_t src)
79{
80 const char *ptr = strchr(itoa64, src);
81
82 if (ptr) {
83 *dst = ptr - itoa64;
84 return 0;
85 }
86 *dst = 0;
87 return -1;
88}
89
90static const uint8_t *
91decode64_uint32(uint32_t * dst, uint32_t dstbits, const uint8_t * src)
92{
93 uint32_t bit;
94 uint32_t value;
95
96 value = 0;
97 for (bit = 0; bit < dstbits; bit += 6) {
98 uint32_t one;
99 if (decode64_one(&one, *src)) {
100 *dst = 0;
101 return NULL;
102 }
103 src++;
104 value |= one << bit;
105 }
106
107 *dst = value;
108 return src;
109}
110
111uint8_t *
112escrypt_r(escrypt_local_t * local, const uint8_t * passwd, size_t passwdlen,
113 const uint8_t * setting, uint8_t * buf, size_t buflen)
114{
115 uint8_t hash[crypto_pwhash_scryptsalsa208sha256_STRHASHBYTES];
116 escrypt_kdf_t escrypt_kdf;
117 const uint8_t *src;
118 const uint8_t *salt;
119 uint8_t *dst;
120 size_t prefixlen;
121 size_t saltlen;
122 size_t need;
123 uint64_t N;
124 uint32_t N_log2;
125 uint32_t r;
126 uint32_t p;
127
128 if (setting[0] != '$' || setting[1] != '7' || setting[2] != '$') {
129 return NULL;
130 }
131 src = setting + 3;
132
133 if (decode64_one(&N_log2, *src)) {
134 return NULL;
135 }
136 src++;
137 N = (uint64_t)1 << N_log2;
138
139 src = decode64_uint32(&r, 30, src);
140 if (!src) {
141 return NULL;
142 }
143 src = decode64_uint32(&p, 30, src);
144 if (!src) {
145 return NULL;
146 }
147 prefixlen = src - setting;
148
149 salt = src;
150 src = (uint8_t *) strrchr((char *)salt, '$');
151 if (src) {
152 saltlen = src - salt;
153 } else {
154 saltlen = strlen((char *)salt);
155 }
156 need = prefixlen + saltlen + 1 +
157 crypto_pwhash_scryptsalsa208sha256_STRHASHBYTES_ENCODED + 1;
158 if (need > buflen || need < saltlen) {
159 return NULL;
160 }
161#if defined(HAVE_EMMINTRIN_H) || defined(_MSC_VER)
162 escrypt_kdf =
163 sodium_runtime_has_sse2() ? escrypt_kdf_sse : escrypt_kdf_nosse;
164#else
165 escrypt_kdf = escrypt_kdf_nosse;
166#endif
167 if (escrypt_kdf(local, passwd, passwdlen, salt, saltlen,
168 N, r, p, hash, sizeof(hash))) {
169 return NULL;
170 }
171
172 dst = buf;
173 memcpy(dst, setting, prefixlen + saltlen);
174 dst += prefixlen + saltlen;
175 *dst++ = '$';
176
177 dst = encode64(dst, buflen - (dst - buf), hash, sizeof(hash));
178 sodium_memzero(hash, sizeof hash);
179 if (!dst || dst >= buf + buflen) { /* Can't happen */
180 return NULL;
181 }
182 *dst = 0; /* NUL termination */
183
184 return buf;
185}
186
187uint8_t *
188escrypt_gensalt_r(uint32_t N_log2, uint32_t r, uint32_t p,
189 const uint8_t * src, size_t srclen,
190 uint8_t * buf, size_t buflen)
191{
192 uint8_t *dst;
193 size_t prefixlen =
194 (sizeof "$7$" - 1U) + (1U /* N_log2 */) + (5U /* r */) + (5U /* p */);
195 size_t saltlen = BYTES2CHARS(srclen);
196 size_t need;
197
198 need = prefixlen + saltlen + 1;
199 if (need > buflen || need < saltlen || saltlen < srclen) {
200 return NULL;
201 }
202 if (N_log2 > 63 || ((uint64_t)r * (uint64_t)p >= (1U << 30))) {
203 return NULL;
204 }
205 dst = buf;
206 *dst++ = '$';
207 *dst++ = '7';
208 *dst++ = '$';
209
210 *dst++ = itoa64[N_log2];
211
212 dst = encode64_uint32(dst, buflen - (dst - buf), r, 30);
213 if (!dst) { /* Can't happen */
214 return NULL;
215 }
216 dst = encode64_uint32(dst, buflen - (dst - buf), p, 30);
217 if (!dst) { /* Can't happen */
218 return NULL;
219 }
220 dst = encode64(dst, buflen - (dst - buf), src, srclen);
221 if (!dst || dst >= buf + buflen) { /* Can't happen */
222 return NULL;
223 }
224 *dst = 0; /* NUL termination */
225
226 return buf;
227}
228
229int
230crypto_pwhash_scryptsalsa208sha256_ll(const uint8_t * passwd, size_t passwdlen,
231 const uint8_t * salt, size_t saltlen,
232 uint64_t N, uint32_t r, uint32_t p,
233 uint8_t * buf, size_t buflen)
234{
235 escrypt_kdf_t escrypt_kdf;
236 escrypt_local_t local;
237 int retval;
238
239 if (escrypt_init_local(&local)) {
240 return -1;
241 }
242#if defined(HAVE_EMMINTRIN_H) || defined(_MSC_VER)
243 escrypt_kdf =
244 sodium_runtime_has_sse2() ? escrypt_kdf_sse : escrypt_kdf_nosse;
245#else
246 escrypt_kdf = escrypt_kdf_nosse;
247#endif
248 retval = escrypt_kdf(&local,
249 passwd, passwdlen, salt, saltlen,
250 N, r, p, buf, buflen);
251 if (escrypt_free_local(&local)) {
252 return -1;
253 }
254 return retval;
255}
256
257#endif