diff options
Diffstat (limited to 'toxencryptsave')
20 files changed, 2701 insertions, 0 deletions
diff --git a/toxencryptsave/Makefile.inc b/toxencryptsave/Makefile.inc new file mode 100644 index 00000000..1155e954 --- /dev/null +++ b/toxencryptsave/Makefile.inc | |||
@@ -0,0 +1,45 @@ | |||
1 | lib_LTLIBRARIES += libtoxencryptsave.la | ||
2 | |||
3 | libtoxencryptsave_la_include_HEADERS = \ | ||
4 | ../toxencryptsave/toxencryptsave.h | ||
5 | |||
6 | libtoxencryptsave_la_includedir = $(includedir)/tox | ||
7 | |||
8 | libtoxencryptsave_la_SOURCES = ../toxencryptsave/crypto_pwhash_scryptsalsa208sha256/crypto_pwhash_scryptsalsa208sha256.h \ | ||
9 | ../toxencryptsave/crypto_pwhash_scryptsalsa208sha256/crypto_scrypt.h \ | ||
10 | ../toxencryptsave/crypto_pwhash_scryptsalsa208sha256/pbkdf2-sha256.c \ | ||
11 | ../toxencryptsave/crypto_pwhash_scryptsalsa208sha256/pwhash_scryptsalsa208sha256.c \ | ||
12 | ../toxencryptsave/crypto_pwhash_scryptsalsa208sha256/runtime.h \ | ||
13 | ../toxencryptsave/crypto_pwhash_scryptsalsa208sha256/utils.c \ | ||
14 | ../toxencryptsave/crypto_pwhash_scryptsalsa208sha256/crypto_scrypt-common.c \ | ||
15 | ../toxencryptsave/crypto_pwhash_scryptsalsa208sha256/export.h \ | ||
16 | ../toxencryptsave/crypto_pwhash_scryptsalsa208sha256/pbkdf2-sha256.h \ | ||
17 | ../toxencryptsave/crypto_pwhash_scryptsalsa208sha256/runtime.c \ | ||
18 | ../toxencryptsave/crypto_pwhash_scryptsalsa208sha256/scrypt_platform.c \ | ||
19 | ../toxencryptsave/crypto_pwhash_scryptsalsa208sha256/sysendian.h \ | ||
20 | ../toxencryptsave/crypto_pwhash_scryptsalsa208sha256/utils.h \ | ||
21 | ../toxencryptsave/crypto_pwhash_scryptsalsa208sha256/nosse/pwhash_scryptsalsa208sha256_nosse.c \ | ||
22 | ../toxencryptsave/crypto_pwhash_scryptsalsa208sha256/sse/pwhash_scryptsalsa208sha256_sse.c \ | ||
23 | ../toxencryptsave/toxencryptsave.h \ | ||
24 | ../toxencryptsave/toxencryptsave.c | ||
25 | |||
26 | |||
27 | libtoxencryptsave_la_CFLAGS = -I$(top_srcdir) \ | ||
28 | -I$(top_srcdir)/toxcore \ | ||
29 | $(LIBSODIUM_CFLAGS) \ | ||
30 | $(NACL_CFLAGS) \ | ||
31 | $(PTHREAD_CFLAGS) | ||
32 | |||
33 | libtoxencryptsave_la_LDFLAGS = $(TOXCORE_LT_LDFLAGS) \ | ||
34 | $(EXTRA_LT_LDFLAGS) \ | ||
35 | $(LIBSODIUM_LDFLAGS) \ | ||
36 | $(NACL_LDFLAGS) \ | ||
37 | $(MATH_LDFLAGS) \ | ||
38 | $(RT_LIBS) \ | ||
39 | $(WINSOCK2_LIBS) | ||
40 | |||
41 | libtoxencryptsave_la_LIBADD = $(LIBSODIUM_LIBS) \ | ||
42 | $(NACL_OBJECTS) \ | ||
43 | $(NAC_LIBS) \ | ||
44 | $(PTHREAD_LIBS) \ | ||
45 | libtoxcore.la | ||
diff --git a/toxencryptsave/crypto_pwhash_scryptsalsa208sha256/crypto_pwhash_scryptsalsa208sha256.h b/toxencryptsave/crypto_pwhash_scryptsalsa208sha256/crypto_pwhash_scryptsalsa208sha256.h new file mode 100644 index 00000000..5cb32f8d --- /dev/null +++ b/toxencryptsave/crypto_pwhash_scryptsalsa208sha256/crypto_pwhash_scryptsalsa208sha256.h | |||
@@ -0,0 +1,92 @@ | |||
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 | #ifndef crypto_pwhash_scryptsalsa208sha256_H | ||
7 | #define crypto_pwhash_scryptsalsa208sha256_H | ||
8 | |||
9 | #include <stddef.h> | ||
10 | #include <stdint.h> | ||
11 | |||
12 | #include "export.h" | ||
13 | |||
14 | #ifdef __cplusplus | ||
15 | # if __GNUC__ | ||
16 | # pragma GCC diagnostic ignored "-Wlong-long" | ||
17 | # endif | ||
18 | extern "C" { | ||
19 | #endif | ||
20 | |||
21 | #define crypto_pwhash_scryptsalsa208sha256_SALTBYTES 32U | ||
22 | SODIUM_EXPORT | ||
23 | size_t crypto_pwhash_scryptsalsa208sha256_saltbytes(void); | ||
24 | |||
25 | #define crypto_pwhash_scryptsalsa208sha256_STRBYTES 102U | ||
26 | SODIUM_EXPORT | ||
27 | size_t crypto_pwhash_scryptsalsa208sha256_strbytes(void); | ||
28 | |||
29 | #define crypto_pwhash_scryptsalsa208sha256_STRPREFIX "$7$" | ||
30 | SODIUM_EXPORT | ||
31 | const char *crypto_pwhash_scryptsalsa208sha256_strprefix(void); | ||
32 | |||
33 | #define crypto_pwhash_scryptsalsa208sha256_OPSLIMIT_INTERACTIVE 524288ULL | ||
34 | SODIUM_EXPORT | ||
35 | size_t crypto_pwhash_scryptsalsa208sha256_opslimit_interactive(void); | ||
36 | |||
37 | #define crypto_pwhash_scryptsalsa208sha256_MEMLIMIT_INTERACTIVE 16777216ULL | ||
38 | SODIUM_EXPORT | ||
39 | size_t crypto_pwhash_scryptsalsa208sha256_memlimit_interactive(void); | ||
40 | |||
41 | #define crypto_pwhash_scryptsalsa208sha256_OPSLIMIT_SENSITIVE 33554432ULL | ||
42 | SODIUM_EXPORT | ||
43 | size_t crypto_pwhash_scryptsalsa208sha256_opslimit_sensitive(void); | ||
44 | |||
45 | #define crypto_pwhash_scryptsalsa208sha256_MEMLIMIT_SENSITIVE 1073741824ULL | ||
46 | SODIUM_EXPORT | ||
47 | size_t crypto_pwhash_scryptsalsa208sha256_memlimit_sensitive(void); | ||
48 | |||
49 | SODIUM_EXPORT | ||
50 | int crypto_pwhash_scryptsalsa208sha256(unsigned char * const out, | ||
51 | unsigned long long outlen, | ||
52 | const char * const passwd, | ||
53 | unsigned long long passwdlen, | ||
54 | const unsigned char * const salt, | ||
55 | unsigned long long opslimit, | ||
56 | size_t memlimit); | ||
57 | |||
58 | SODIUM_EXPORT | ||
59 | int crypto_pwhash_scryptsalsa208sha256_str(char out[crypto_pwhash_scryptsalsa208sha256_STRBYTES], | ||
60 | const char * const passwd, | ||
61 | unsigned long long passwdlen, | ||
62 | unsigned long long opslimit, | ||
63 | size_t memlimit); | ||
64 | |||
65 | SODIUM_EXPORT | ||
66 | int crypto_pwhash_scryptsalsa208sha256_str_verify(const char str[crypto_pwhash_scryptsalsa208sha256_STRBYTES], | ||
67 | const char * const passwd, | ||
68 | unsigned long long passwdlen); | ||
69 | |||
70 | SODIUM_EXPORT | ||
71 | int crypto_pwhash_scryptsalsa208sha256_ll(const uint8_t * passwd, size_t passwdlen, | ||
72 | const uint8_t * salt, size_t saltlen, | ||
73 | uint64_t N, uint32_t r, uint32_t p, | ||
74 | uint8_t * buf, size_t buflen); | ||
75 | |||
76 | #ifdef __cplusplus | ||
77 | } | ||
78 | #endif | ||
79 | |||
80 | /* Backward compatibility with version 0.5.0 */ | ||
81 | |||
82 | #define crypto_pwhash_scryptxsalsa208sha256_SALTBYTES crypto_pwhash_scryptsalsa208sha256_SALTBYTES | ||
83 | #define crypto_pwhash_scryptxsalsa208sha256_saltbytes crypto_pwhash_scryptsalsa208sha256_saltbytes | ||
84 | #define crypto_pwhash_scryptxsalsa208sha256_STRBYTES crypto_pwhash_scryptsalsa208sha256_STRBYTES | ||
85 | #define crypto_pwhash_scryptxsalsa208sha256_strbytes crypto_pwhash_scryptsalsa208sha256_strbytes | ||
86 | #define crypto_pwhash_scryptxsalsa208sha256 crypto_pwhash_scryptsalsa208sha256 | ||
87 | #define crypto_pwhash_scryptxsalsa208sha256_str crypto_pwhash_scryptsalsa208sha256_str | ||
88 | #define crypto_pwhash_scryptxsalsa208sha256_str_verify crypto_pwhash_scryptsalsa208sha256_str_verify | ||
89 | |||
90 | #endif | ||
91 | |||
92 | #endif | ||
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 | |||
34 | static const char * const itoa64 = | ||
35 | "./0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"; | ||
36 | |||
37 | static uint8_t * | ||
38 | encode64_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 | |||
54 | static uint8_t * | ||
55 | encode64(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 | |||
77 | static int | ||
78 | decode64_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 | |||
90 | static const uint8_t * | ||
91 | decode64_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 | |||
111 | uint8_t * | ||
112 | escrypt_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 | |||
187 | uint8_t * | ||
188 | escrypt_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 | |||
229 | int | ||
230 | crypto_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 | ||
diff --git a/toxencryptsave/crypto_pwhash_scryptsalsa208sha256/crypto_scrypt.h b/toxencryptsave/crypto_pwhash_scryptsalsa208sha256/crypto_scrypt.h new file mode 100644 index 00000000..3f0b7d72 --- /dev/null +++ b/toxencryptsave/crypto_pwhash_scryptsalsa208sha256/crypto_scrypt.h | |||
@@ -0,0 +1,93 @@ | |||
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 2009 Colin Percival | ||
8 | * Copyright 2013 Alexander Peslyak | ||
9 | * All rights reserved. | ||
10 | * | ||
11 | * Redistribution and use in source and binary forms, with or without | ||
12 | * modification, are permitted provided that the following conditions | ||
13 | * are met: | ||
14 | * 1. Redistributions of source code must retain the above copyright | ||
15 | * notice, this list of conditions and the following disclaimer. | ||
16 | * 2. Redistributions in binary form must reproduce the above copyright | ||
17 | * notice, this list of conditions and the following disclaimer in the | ||
18 | * documentation and/or other materials provided with the distribution. | ||
19 | * | ||
20 | * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND | ||
21 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | ||
22 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | ||
23 | * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE | ||
24 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | ||
25 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS | ||
26 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | ||
27 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT | ||
28 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY | ||
29 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF | ||
30 | * SUCH DAMAGE. | ||
31 | * | ||
32 | * This file was originally written by Colin Percival as part of the Tarsnap | ||
33 | * online backup system. | ||
34 | */ | ||
35 | #ifndef _CRYPTO_SCRYPT_H_ | ||
36 | #define _CRYPTO_SCRYPT_H_ | ||
37 | |||
38 | #include <stdint.h> | ||
39 | |||
40 | #define crypto_pwhash_scryptsalsa208sha256_STRPREFIXBYTES 14 | ||
41 | #define crypto_pwhash_scryptsalsa208sha256_STRSETTINGBYTES 57 | ||
42 | #define crypto_pwhash_scryptsalsa208sha256_STRSALTBYTES 32 | ||
43 | #define crypto_pwhash_scryptsalsa208sha256_STRSALTBYTES_ENCODED 43 | ||
44 | #define crypto_pwhash_scryptsalsa208sha256_STRHASHBYTES 32 | ||
45 | #define crypto_pwhash_scryptsalsa208sha256_STRHASHBYTES_ENCODED 43 | ||
46 | |||
47 | #define BYTES2CHARS(bytes) ((((bytes) * 8) + 5) / 6) | ||
48 | |||
49 | typedef struct { | ||
50 | void * base, * aligned; | ||
51 | size_t size; | ||
52 | } escrypt_region_t; | ||
53 | |||
54 | typedef escrypt_region_t escrypt_local_t; | ||
55 | |||
56 | extern int escrypt_init_local(escrypt_local_t * __local); | ||
57 | |||
58 | extern int escrypt_free_local(escrypt_local_t * __local); | ||
59 | |||
60 | extern void *alloc_region(escrypt_region_t * region, size_t size); | ||
61 | extern int free_region(escrypt_region_t * region); | ||
62 | |||
63 | typedef int (*escrypt_kdf_t)(escrypt_local_t * __local, | ||
64 | const uint8_t * __passwd, size_t __passwdlen, | ||
65 | const uint8_t * __salt, size_t __saltlen, | ||
66 | uint64_t __N, uint32_t __r, uint32_t __p, | ||
67 | uint8_t * __buf, size_t __buflen); | ||
68 | |||
69 | extern int escrypt_kdf_nosse(escrypt_local_t * __local, | ||
70 | const uint8_t * __passwd, size_t __passwdlen, | ||
71 | const uint8_t * __salt, size_t __saltlen, | ||
72 | uint64_t __N, uint32_t __r, uint32_t __p, | ||
73 | uint8_t * __buf, size_t __buflen); | ||
74 | |||
75 | extern int escrypt_kdf_sse(escrypt_local_t * __local, | ||
76 | const uint8_t * __passwd, size_t __passwdlen, | ||
77 | const uint8_t * __salt, size_t __saltlen, | ||
78 | uint64_t __N, uint32_t __r, uint32_t __p, | ||
79 | uint8_t * __buf, size_t __buflen); | ||
80 | |||
81 | extern uint8_t * escrypt_r(escrypt_local_t * __local, | ||
82 | const uint8_t * __passwd, size_t __passwdlen, | ||
83 | const uint8_t * __setting, | ||
84 | uint8_t * __buf, size_t __buflen); | ||
85 | |||
86 | extern uint8_t * escrypt_gensalt_r( | ||
87 | uint32_t __N_log2, uint32_t __r, uint32_t __p, | ||
88 | const uint8_t * __src, size_t __srclen, | ||
89 | uint8_t * __buf, size_t __buflen); | ||
90 | |||
91 | #endif /* !_CRYPTO_SCRYPT_H_ */ | ||
92 | |||
93 | #endif | ||
diff --git a/toxencryptsave/crypto_pwhash_scryptsalsa208sha256/export.h b/toxencryptsave/crypto_pwhash_scryptsalsa208sha256/export.h new file mode 100644 index 00000000..ee5b30f7 --- /dev/null +++ b/toxencryptsave/crypto_pwhash_scryptsalsa208sha256/export.h | |||
@@ -0,0 +1,38 @@ | |||
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 | #ifndef __SODIUM_EXPORT_H__ | ||
7 | #define __SODIUM_EXPORT_H__ | ||
8 | |||
9 | #ifndef __GNUC__ | ||
10 | # ifdef __attribute__ | ||
11 | # undef __attribute__ | ||
12 | # endif | ||
13 | # define __attribute__(a) | ||
14 | #endif | ||
15 | |||
16 | #ifdef SODIUM_STATIC | ||
17 | # define SODIUM_EXPORT | ||
18 | #else | ||
19 | # if defined(_MSC_VER) | ||
20 | # ifdef DLL_EXPORT | ||
21 | # define SODIUM_EXPORT __declspec(dllexport) | ||
22 | # else | ||
23 | # define SODIUM_EXPORT __declspec(dllimport) | ||
24 | # endif | ||
25 | # else | ||
26 | # if defined(__SUNPRO_C) | ||
27 | # define SODIUM_EXPORT __attribute__ __global | ||
28 | # elif defined(_MSG_VER) | ||
29 | # define SODIUM_EXPORT extern __declspec(dllexport) | ||
30 | # else | ||
31 | # define SODIUM_EXPORT __attribute__ ((visibility ("default"))) | ||
32 | # endif | ||
33 | # endif | ||
34 | #endif | ||
35 | |||
36 | #endif | ||
37 | |||
38 | #endif | ||
diff --git a/toxencryptsave/crypto_pwhash_scryptsalsa208sha256/nosse/pwhash_scryptsalsa208sha256_nosse.c b/toxencryptsave/crypto_pwhash_scryptsalsa208sha256/nosse/pwhash_scryptsalsa208sha256_nosse.c new file mode 100644 index 00000000..97d9ba68 --- /dev/null +++ b/toxencryptsave/crypto_pwhash_scryptsalsa208sha256/nosse/pwhash_scryptsalsa208sha256_nosse.c | |||
@@ -0,0 +1,309 @@ | |||
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 2009 Colin Percival | ||
8 | * Copyright 2013 Alexander Peslyak | ||
9 | * All rights reserved. | ||
10 | * | ||
11 | * Redistribution and use in source and binary forms, with or without | ||
12 | * modification, are permitted provided that the following conditions | ||
13 | * are met: | ||
14 | * 1. Redistributions of source code must retain the above copyright | ||
15 | * notice, this list of conditions and the following disclaimer. | ||
16 | * 2. Redistributions in binary form must reproduce the above copyright | ||
17 | * notice, this list of conditions and the following disclaimer in the | ||
18 | * documentation and/or other materials provided with the distribution. | ||
19 | * | ||
20 | * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND | ||
21 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | ||
22 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | ||
23 | * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE | ||
24 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | ||
25 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS | ||
26 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | ||
27 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT | ||
28 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY | ||
29 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF | ||
30 | * SUCH DAMAGE. | ||
31 | * | ||
32 | * This file was originally written by Colin Percival as part of the Tarsnap | ||
33 | * online backup system. | ||
34 | */ | ||
35 | |||
36 | #include <errno.h> | ||
37 | #include <limits.h> | ||
38 | #include <stdint.h> | ||
39 | #include <stdlib.h> | ||
40 | #include <string.h> | ||
41 | |||
42 | #include "../pbkdf2-sha256.h" | ||
43 | #include "../sysendian.h" | ||
44 | #include "../crypto_scrypt.h" | ||
45 | |||
46 | static inline void | ||
47 | blkcpy(void * dest, const void * src, size_t len) | ||
48 | { | ||
49 | size_t * D = (size_t *) dest; | ||
50 | const size_t * S = (const size_t *) src; | ||
51 | size_t L = len / sizeof(size_t); | ||
52 | size_t i; | ||
53 | |||
54 | for (i = 0; i < L; i++) | ||
55 | D[i] = S[i]; | ||
56 | } | ||
57 | |||
58 | static inline void | ||
59 | blkxor(void * dest, const void * src, size_t len) | ||
60 | { | ||
61 | size_t * D = (size_t *) dest; | ||
62 | const size_t * S = (const size_t *) src; | ||
63 | size_t L = len / sizeof(size_t); | ||
64 | size_t i; | ||
65 | |||
66 | for (i = 0; i < L; i++) | ||
67 | D[i] ^= S[i]; | ||
68 | } | ||
69 | |||
70 | /** | ||
71 | * salsa20_8(B): | ||
72 | * Apply the salsa20/8 core to the provided block. | ||
73 | */ | ||
74 | static void | ||
75 | salsa20_8(uint32_t B[16]) | ||
76 | { | ||
77 | uint32_t x[16]; | ||
78 | size_t i; | ||
79 | |||
80 | blkcpy(x, B, 64); | ||
81 | for (i = 0; i < 8; i += 2) { | ||
82 | #define R(a,b) (((a) << (b)) | ((a) >> (32 - (b)))) | ||
83 | /* Operate on columns. */ | ||
84 | x[ 4] ^= R(x[ 0]+x[12], 7); x[ 8] ^= R(x[ 4]+x[ 0], 9); | ||
85 | x[12] ^= R(x[ 8]+x[ 4],13); x[ 0] ^= R(x[12]+x[ 8],18); | ||
86 | |||
87 | x[ 9] ^= R(x[ 5]+x[ 1], 7); x[13] ^= R(x[ 9]+x[ 5], 9); | ||
88 | x[ 1] ^= R(x[13]+x[ 9],13); x[ 5] ^= R(x[ 1]+x[13],18); | ||
89 | |||
90 | x[14] ^= R(x[10]+x[ 6], 7); x[ 2] ^= R(x[14]+x[10], 9); | ||
91 | x[ 6] ^= R(x[ 2]+x[14],13); x[10] ^= R(x[ 6]+x[ 2],18); | ||
92 | |||
93 | x[ 3] ^= R(x[15]+x[11], 7); x[ 7] ^= R(x[ 3]+x[15], 9); | ||
94 | x[11] ^= R(x[ 7]+x[ 3],13); x[15] ^= R(x[11]+x[ 7],18); | ||
95 | |||
96 | /* Operate on rows. */ | ||
97 | x[ 1] ^= R(x[ 0]+x[ 3], 7); x[ 2] ^= R(x[ 1]+x[ 0], 9); | ||
98 | x[ 3] ^= R(x[ 2]+x[ 1],13); x[ 0] ^= R(x[ 3]+x[ 2],18); | ||
99 | |||
100 | x[ 6] ^= R(x[ 5]+x[ 4], 7); x[ 7] ^= R(x[ 6]+x[ 5], 9); | ||
101 | x[ 4] ^= R(x[ 7]+x[ 6],13); x[ 5] ^= R(x[ 4]+x[ 7],18); | ||
102 | |||
103 | x[11] ^= R(x[10]+x[ 9], 7); x[ 8] ^= R(x[11]+x[10], 9); | ||
104 | x[ 9] ^= R(x[ 8]+x[11],13); x[10] ^= R(x[ 9]+x[ 8],18); | ||
105 | |||
106 | x[12] ^= R(x[15]+x[14], 7); x[13] ^= R(x[12]+x[15], 9); | ||
107 | x[14] ^= R(x[13]+x[12],13); x[15] ^= R(x[14]+x[13],18); | ||
108 | #undef R | ||
109 | } | ||
110 | for (i = 0; i < 16; i++) | ||
111 | B[i] += x[i]; | ||
112 | } | ||
113 | |||
114 | /** | ||
115 | * blockmix_salsa8(Bin, Bout, X, r): | ||
116 | * Compute Bout = BlockMix_{salsa20/8, r}(Bin). The input Bin must be 128r | ||
117 | * bytes in length; the output Bout must also be the same size. The | ||
118 | * temporary space X must be 64 bytes. | ||
119 | */ | ||
120 | static void | ||
121 | blockmix_salsa8(const uint32_t * Bin, uint32_t * Bout, uint32_t * X, size_t r) | ||
122 | { | ||
123 | size_t i; | ||
124 | |||
125 | /* 1: X <-- B_{2r - 1} */ | ||
126 | blkcpy(X, &Bin[(2 * r - 1) * 16], 64); | ||
127 | |||
128 | /* 2: for i = 0 to 2r - 1 do */ | ||
129 | for (i = 0; i < 2 * r; i += 2) { | ||
130 | /* 3: X <-- H(X \xor B_i) */ | ||
131 | blkxor(X, &Bin[i * 16], 64); | ||
132 | salsa20_8(X); | ||
133 | |||
134 | /* 4: Y_i <-- X */ | ||
135 | /* 6: B' <-- (Y_0, Y_2 ... Y_{2r-2}, Y_1, Y_3 ... Y_{2r-1}) */ | ||
136 | blkcpy(&Bout[i * 8], X, 64); | ||
137 | |||
138 | /* 3: X <-- H(X \xor B_i) */ | ||
139 | blkxor(X, &Bin[i * 16 + 16], 64); | ||
140 | salsa20_8(X); | ||
141 | |||
142 | /* 4: Y_i <-- X */ | ||
143 | /* 6: B' <-- (Y_0, Y_2 ... Y_{2r-2}, Y_1, Y_3 ... Y_{2r-1}) */ | ||
144 | blkcpy(&Bout[i * 8 + r * 16], X, 64); | ||
145 | } | ||
146 | } | ||
147 | |||
148 | /** | ||
149 | * integerify(B, r): | ||
150 | * Return the result of parsing B_{2r-1} as a little-endian integer. | ||
151 | */ | ||
152 | static inline uint64_t | ||
153 | integerify(const void * B, size_t r) | ||
154 | { | ||
155 | const uint32_t * X = (const uint32_t *)((uintptr_t)(B) + (2 * r - 1) * 64); | ||
156 | |||
157 | return (((uint64_t)(X[1]) << 32) + X[0]); | ||
158 | } | ||
159 | |||
160 | /** | ||
161 | * smix(B, r, N, V, XY): | ||
162 | * Compute B = SMix_r(B, N). The input B must be 128r bytes in length; | ||
163 | * the temporary storage V must be 128rN bytes in length; the temporary | ||
164 | * storage XY must be 256r + 64 bytes in length. The value N must be a | ||
165 | * power of 2 greater than 1. The arrays B, V, and XY must be aligned to a | ||
166 | * multiple of 64 bytes. | ||
167 | */ | ||
168 | static void | ||
169 | smix(uint8_t * B, size_t r, uint64_t N, uint32_t * V, uint32_t * XY) | ||
170 | { | ||
171 | uint32_t * X = XY; | ||
172 | uint32_t * Y = &XY[32 * r]; | ||
173 | uint32_t * Z = &XY[64 * r]; | ||
174 | uint64_t i; | ||
175 | uint64_t j; | ||
176 | size_t k; | ||
177 | |||
178 | /* 1: X <-- B */ | ||
179 | for (k = 0; k < 32 * r; k++) | ||
180 | X[k] = le32dec(&B[4 * k]); | ||
181 | |||
182 | /* 2: for i = 0 to N - 1 do */ | ||
183 | for (i = 0; i < N; i += 2) { | ||
184 | /* 3: V_i <-- X */ | ||
185 | blkcpy(&V[i * (32 * r)], X, 128 * r); | ||
186 | |||
187 | /* 4: X <-- H(X) */ | ||
188 | blockmix_salsa8(X, Y, Z, r); | ||
189 | |||
190 | /* 3: V_i <-- X */ | ||
191 | blkcpy(&V[(i + 1) * (32 * r)], Y, 128 * r); | ||
192 | |||
193 | /* 4: X <-- H(X) */ | ||
194 | blockmix_salsa8(Y, X, Z, r); | ||
195 | } | ||
196 | |||
197 | /* 6: for i = 0 to N - 1 do */ | ||
198 | for (i = 0; i < N; i += 2) { | ||
199 | /* 7: j <-- Integerify(X) mod N */ | ||
200 | j = integerify(X, r) & (N - 1); | ||
201 | |||
202 | /* 8: X <-- H(X \xor V_j) */ | ||
203 | blkxor(X, &V[j * (32 * r)], 128 * r); | ||
204 | blockmix_salsa8(X, Y, Z, r); | ||
205 | |||
206 | /* 7: j <-- Integerify(X) mod N */ | ||
207 | j = integerify(Y, r) & (N - 1); | ||
208 | |||
209 | /* 8: X <-- H(X \xor V_j) */ | ||
210 | blkxor(Y, &V[j * (32 * r)], 128 * r); | ||
211 | blockmix_salsa8(Y, X, Z, r); | ||
212 | } | ||
213 | /* 10: B' <-- X */ | ||
214 | for (k = 0; k < 32 * r; k++) | ||
215 | le32enc(&B[4 * k], X[k]); | ||
216 | } | ||
217 | |||
218 | /** | ||
219 | * escrypt_kdf(local, passwd, passwdlen, salt, saltlen, | ||
220 | * N, r, p, buf, buflen): | ||
221 | * Compute scrypt(passwd[0 .. passwdlen - 1], salt[0 .. saltlen - 1], N, r, | ||
222 | * p, buflen) and write the result into buf. The parameters r, p, and buflen | ||
223 | * must satisfy r * p < 2^30 and buflen <= (2^32 - 1) * 32. The parameter N | ||
224 | * must be a power of 2 greater than 1. | ||
225 | * | ||
226 | * Return 0 on success; or -1 on error. | ||
227 | */ | ||
228 | int | ||
229 | escrypt_kdf_nosse(escrypt_local_t * local, | ||
230 | 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 | size_t B_size, V_size, XY_size, need; | ||
236 | uint8_t * B; | ||
237 | uint32_t * V, * XY; | ||
238 | size_t r = _r, p = _p; | ||
239 | uint32_t i; | ||
240 | |||
241 | /* Sanity-check parameters. */ | ||
242 | #if SIZE_MAX > UINT32_MAX | ||
243 | if (buflen > (((uint64_t)(1) << 32) - 1) * 32) { | ||
244 | errno = EFBIG; | ||
245 | return -1; | ||
246 | } | ||
247 | #endif | ||
248 | if ((uint64_t)(r) * (uint64_t)(p) >= (1 << 30)) { | ||
249 | errno = EFBIG; | ||
250 | return -1; | ||
251 | } | ||
252 | if (((N & (N - 1)) != 0) || (N < 2)) { | ||
253 | errno = EINVAL; | ||
254 | return -1; | ||
255 | } | ||
256 | if (r == 0 || p == 0) { | ||
257 | errno = EINVAL; | ||
258 | return -1; | ||
259 | } | ||
260 | if ((r > SIZE_MAX / 128 / p) || | ||
261 | #if SIZE_MAX / 256 <= UINT32_MAX | ||
262 | (r > SIZE_MAX / 256) || | ||
263 | #endif | ||
264 | (N > SIZE_MAX / 128 / r)) { | ||
265 | errno = ENOMEM; | ||
266 | return -1; | ||
267 | } | ||
268 | |||
269 | /* Allocate memory. */ | ||
270 | B_size = (size_t)128 * r * p; | ||
271 | V_size = (size_t)128 * r * N; | ||
272 | need = B_size + V_size; | ||
273 | if (need < V_size) { | ||
274 | errno = ENOMEM; | ||
275 | return -1; | ||
276 | } | ||
277 | XY_size = (size_t)256 * r + 64; | ||
278 | need += XY_size; | ||
279 | if (need < XY_size) { | ||
280 | errno = ENOMEM; | ||
281 | return -1; | ||
282 | } | ||
283 | if (local->size < need) { | ||
284 | if (free_region(local)) | ||
285 | return -1; | ||
286 | if (!alloc_region(local, need)) | ||
287 | return -1; | ||
288 | } | ||
289 | B = (uint8_t *)local->aligned; | ||
290 | V = (uint32_t *)((uint8_t *)B + B_size); | ||
291 | XY = (uint32_t *)((uint8_t *)V + V_size); | ||
292 | |||
293 | /* 1: (B_0 ... B_{p-1}) <-- PBKDF2(P, S, 1, p * MFLen) */ | ||
294 | PBKDF2_SHA256(passwd, passwdlen, salt, saltlen, 1, B, B_size); | ||
295 | |||
296 | /* 2: for i = 0 to p - 1 do */ | ||
297 | for (i = 0; i < p; i++) { | ||
298 | /* 3: B_i <-- MF(B_i, N) */ | ||
299 | smix(&B[(size_t)128 * i * r], r, N, V, XY); | ||
300 | } | ||
301 | |||
302 | /* 5: DK <-- PBKDF2(P, B, 1, dkLen) */ | ||
303 | PBKDF2_SHA256(passwd, passwdlen, B, B_size, 1, buf, buflen); | ||
304 | |||
305 | /* Success! */ | ||
306 | return 0; | ||
307 | } | ||
308 | |||
309 | #endif | ||
diff --git a/toxencryptsave/crypto_pwhash_scryptsalsa208sha256/note_to_maintainers.txt b/toxencryptsave/crypto_pwhash_scryptsalsa208sha256/note_to_maintainers.txt new file mode 100644 index 00000000..66bbfe2d --- /dev/null +++ b/toxencryptsave/crypto_pwhash_scryptsalsa208sha256/note_to_maintainers.txt | |||
@@ -0,0 +1,14 @@ | |||
1 | This folder is only meant for use with nacl, i.e. when sodium is unavailable. | ||
2 | |||
3 | |||
4 | The files in this folder were mostly copied from | ||
5 | https://github.com/jedisct1/libsodium/tree/0.7.0/src/libsodium/crypto_pwhash/scryptsalsa208sha256, | ||
6 | with #ifdef VANILLA_NACL added around each of them as required for this module. | ||
7 | |||
8 | export.h, utils.h, and runtime.h were copied from | ||
9 | https://github.com/jedisct1/libsodium/tree/0.7.0/src/libsodium/include/sodium. | ||
10 | utils.h was significantly truncated. | ||
11 | |||
12 | utils.c and runtime.c were copied from | ||
13 | https://github.com/jedisct1/libsodium/blob/0.7.0/src/libsodium/sodium. | ||
14 | utils.c was also significantly truncated. | ||
diff --git a/toxencryptsave/crypto_pwhash_scryptsalsa208sha256/pbkdf2-sha256.c b/toxencryptsave/crypto_pwhash_scryptsalsa208sha256/pbkdf2-sha256.c new file mode 100644 index 00000000..3dfe54db --- /dev/null +++ b/toxencryptsave/crypto_pwhash_scryptsalsa208sha256/pbkdf2-sha256.c | |||
@@ -0,0 +1,97 @@ | |||
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 2005,2007,2009 Colin Percival | ||
8 | * All rights reserved. | ||
9 | * | ||
10 | * Redistribution and use in source and binary forms, with or without | ||
11 | * modification, are permitted provided that the following conditions | ||
12 | * are met: | ||
13 | * 1. Redistributions of source code must retain the above copyright | ||
14 | * notice, this list of conditions and the following disclaimer. | ||
15 | * 2. Redistributions in binary form must reproduce the above copyright | ||
16 | * notice, this list of conditions and the following disclaimer in the | ||
17 | * documentation and/or other materials provided with the distribution. | ||
18 | * | ||
19 | * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND | ||
20 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | ||
21 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | ||
22 | * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE | ||
23 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | ||
24 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS | ||
25 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | ||
26 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT | ||
27 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY | ||
28 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF | ||
29 | * SUCH DAMAGE. | ||
30 | */ | ||
31 | |||
32 | #include <sys/types.h> | ||
33 | |||
34 | #include <stdint.h> | ||
35 | #include <stdlib.h> | ||
36 | #include <string.h> | ||
37 | |||
38 | #include <crypto_hash_sha256.h> | ||
39 | #include <crypto_auth_hmacsha256.h> | ||
40 | |||
41 | #include "pbkdf2-sha256.h" | ||
42 | #include "sysendian.h" | ||
43 | #include "utils.h" | ||
44 | |||
45 | /** | ||
46 | * PBKDF2_SHA256(passwd, passwdlen, salt, saltlen, c, buf, dkLen): | ||
47 | * Compute PBKDF2(passwd, salt, c, dkLen) using HMAC-SHA256 as the PRF, and | ||
48 | * write the output to buf. The value dkLen must be at most 32 * (2^32 - 1). | ||
49 | */ | ||
50 | void | ||
51 | PBKDF2_SHA256(const uint8_t * passwd, size_t passwdlen, const uint8_t * salt, | ||
52 | size_t saltlen, uint64_t c, uint8_t * buf, size_t dkLen) | ||
53 | { | ||
54 | uint8_t key[32] = {0}; | ||
55 | size_t i; | ||
56 | uint8_t salt_and_ivec[saltlen + 4]; | ||
57 | uint8_t U[32]; | ||
58 | uint8_t T[32]; | ||
59 | uint64_t j; | ||
60 | int k; | ||
61 | size_t clen; | ||
62 | |||
63 | if (passwdlen > 32) { | ||
64 | /* For some reason libsodium allows 64byte keys meaning keys | ||
65 | * between 32byte and 64bytes are not compatible with libsodium. | ||
66 | toxencryptsave should only give 32byte passwds so this isn't an issue here.*/ | ||
67 | crypto_hash_sha256(key, passwd, passwdlen); | ||
68 | } else { | ||
69 | memcpy(key, passwd, passwdlen); | ||
70 | } | ||
71 | |||
72 | memcpy(salt_and_ivec, salt, saltlen); | ||
73 | |||
74 | for (i = 0; i * 32 < dkLen; i++) { | ||
75 | be32enc(salt_and_ivec + saltlen, (uint32_t)(i + 1)); | ||
76 | crypto_auth_hmacsha256(U, salt_and_ivec, sizeof(salt_and_ivec), key); | ||
77 | |||
78 | memcpy(T, U, 32); | ||
79 | |||
80 | for (j = 2; j <= c; j++) { | ||
81 | crypto_auth_hmacsha256(U, U, 32, key); | ||
82 | |||
83 | for (k = 0; k < 32; k++) { | ||
84 | T[k] ^= U[k]; | ||
85 | } | ||
86 | } | ||
87 | |||
88 | clen = dkLen - i * 32; | ||
89 | if (clen > 32) { | ||
90 | clen = 32; | ||
91 | } | ||
92 | memcpy(&buf[i * 32], T, clen); | ||
93 | } | ||
94 | sodium_memzero((void *) key, sizeof(key)); | ||
95 | } | ||
96 | |||
97 | #endif | ||
diff --git a/toxencryptsave/crypto_pwhash_scryptsalsa208sha256/pbkdf2-sha256.h b/toxencryptsave/crypto_pwhash_scryptsalsa208sha256/pbkdf2-sha256.h new file mode 100644 index 00000000..b74bc6a3 --- /dev/null +++ b/toxencryptsave/crypto_pwhash_scryptsalsa208sha256/pbkdf2-sha256.h | |||
@@ -0,0 +1,52 @@ | |||
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 2005,2007,2009 Colin Percival | ||
8 | * All rights reserved. | ||
9 | * | ||
10 | * Redistribution and use in source and binary forms, with or without | ||
11 | * modification, are permitted provided that the following conditions | ||
12 | * are met: | ||
13 | * 1. Redistributions of source code must retain the above copyright | ||
14 | * notice, this list of conditions and the following disclaimer. | ||
15 | * 2. Redistributions in binary form must reproduce the above copyright | ||
16 | * notice, this list of conditions and the following disclaimer in the | ||
17 | * documentation and/or other materials provided with the distribution. | ||
18 | * | ||
19 | * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND | ||
20 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | ||
21 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | ||
22 | * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE | ||
23 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | ||
24 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS | ||
25 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | ||
26 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT | ||
27 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY | ||
28 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF | ||
29 | * SUCH DAMAGE. | ||
30 | * | ||
31 | */ | ||
32 | |||
33 | #ifndef _SHA256_H_ | ||
34 | #define _SHA256_H_ | ||
35 | |||
36 | #include <sys/types.h> | ||
37 | |||
38 | #include <stdint.h> | ||
39 | |||
40 | #include "crypto_auth_hmacsha256.h" | ||
41 | |||
42 | /** | ||
43 | * PBKDF2_SHA256(passwd, passwdlen, salt, saltlen, c, buf, dkLen): | ||
44 | * Compute PBKDF2(passwd, salt, c, dkLen) using HMAC-SHA256 as the PRF, and | ||
45 | * write the output to buf. The value dkLen must be at most 32 * (2^32 - 1). | ||
46 | */ | ||
47 | void PBKDF2_SHA256(const uint8_t *, size_t, const uint8_t *, size_t, | ||
48 | uint64_t, uint8_t *, size_t); | ||
49 | |||
50 | #endif /* !_SHA256_H_ */ | ||
51 | |||
52 | #endif | ||
diff --git a/toxencryptsave/crypto_pwhash_scryptsalsa208sha256/pwhash_scryptsalsa208sha256.c b/toxencryptsave/crypto_pwhash_scryptsalsa208sha256/pwhash_scryptsalsa208sha256.c new file mode 100644 index 00000000..52c51abc --- /dev/null +++ b/toxencryptsave/crypto_pwhash_scryptsalsa208sha256/pwhash_scryptsalsa208sha256.c | |||
@@ -0,0 +1,211 @@ | |||
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 "randombytes.h" | ||
16 | #include "utils.h" | ||
17 | |||
18 | #define SETTING_SIZE(saltbytes) \ | ||
19 | (sizeof "$7$" - 1U) + \ | ||
20 | (1U /* N_log2 */) + (5U /* r */) + (5U /* p */) + BYTES2CHARS(saltbytes) | ||
21 | |||
22 | static int | ||
23 | pickparams(unsigned long long opslimit, const size_t memlimit, | ||
24 | uint32_t * const N_log2, uint32_t * const p, uint32_t * const r) | ||
25 | { | ||
26 | unsigned long long maxN; | ||
27 | unsigned long long maxrp; | ||
28 | |||
29 | if (opslimit < 32768) { | ||
30 | opslimit = 32768; | ||
31 | } | ||
32 | *r = 8; | ||
33 | if (opslimit < memlimit / 32) { | ||
34 | *p = 1; | ||
35 | maxN = opslimit / (*r * 4); | ||
36 | for (*N_log2 = 1; *N_log2 < 63; *N_log2 += 1) { | ||
37 | if ((uint64_t)(1) << *N_log2 > maxN / 2) { | ||
38 | break; | ||
39 | } | ||
40 | } | ||
41 | } else { | ||
42 | maxN = memlimit / (*r * 128); | ||
43 | for (*N_log2 = 1; *N_log2 < 63; *N_log2 += 1) { | ||
44 | if ((uint64_t) (1) << *N_log2 > maxN / 2) { | ||
45 | break; | ||
46 | } | ||
47 | } | ||
48 | maxrp = (opslimit / 4) / ((uint64_t) (1) << *N_log2); | ||
49 | if (maxrp > 0x3fffffff) { | ||
50 | maxrp = 0x3fffffff; | ||
51 | } | ||
52 | *p = (uint32_t) (maxrp) / *r; | ||
53 | } | ||
54 | return 0; | ||
55 | } | ||
56 | |||
57 | size_t | ||
58 | crypto_pwhash_scryptsalsa208sha256_saltbytes(void) | ||
59 | { | ||
60 | return crypto_pwhash_scryptsalsa208sha256_SALTBYTES; | ||
61 | } | ||
62 | |||
63 | size_t | ||
64 | crypto_pwhash_scryptsalsa208sha256_strbytes(void) | ||
65 | { | ||
66 | return crypto_pwhash_scryptsalsa208sha256_STRBYTES; | ||
67 | } | ||
68 | |||
69 | const char * | ||
70 | crypto_pwhash_scryptsalsa208sha256_strprefix(void) | ||
71 | { | ||
72 | return crypto_pwhash_scryptsalsa208sha256_STRPREFIX; | ||
73 | } | ||
74 | |||
75 | size_t | ||
76 | crypto_pwhash_scryptsalsa208sha256_opslimit_interactive(void) | ||
77 | { | ||
78 | return crypto_pwhash_scryptsalsa208sha256_OPSLIMIT_INTERACTIVE; | ||
79 | } | ||
80 | |||
81 | size_t | ||
82 | crypto_pwhash_scryptsalsa208sha256_memlimit_interactive(void) | ||
83 | { | ||
84 | return crypto_pwhash_scryptsalsa208sha256_MEMLIMIT_INTERACTIVE; | ||
85 | } | ||
86 | |||
87 | size_t | ||
88 | crypto_pwhash_scryptsalsa208sha256_opslimit_sensitive(void) | ||
89 | { | ||
90 | return crypto_pwhash_scryptsalsa208sha256_OPSLIMIT_SENSITIVE; | ||
91 | } | ||
92 | |||
93 | size_t | ||
94 | crypto_pwhash_scryptsalsa208sha256_memlimit_sensitive(void) | ||
95 | { | ||
96 | return crypto_pwhash_scryptsalsa208sha256_MEMLIMIT_SENSITIVE; | ||
97 | } | ||
98 | |||
99 | int | ||
100 | crypto_pwhash_scryptsalsa208sha256(unsigned char * const out, | ||
101 | unsigned long long outlen, | ||
102 | const char * const passwd, | ||
103 | unsigned long long passwdlen, | ||
104 | const unsigned char * const salt, | ||
105 | unsigned long long opslimit, | ||
106 | size_t memlimit) | ||
107 | { | ||
108 | //fprintf(stderr, "Doing that dirty thang!!!!\n"); | ||
109 | uint32_t N_log2; | ||
110 | uint32_t p; | ||
111 | uint32_t r; | ||
112 | |||
113 | memset(out, 0, outlen); | ||
114 | if (passwdlen > SIZE_MAX || outlen > SIZE_MAX) { | ||
115 | errno = EFBIG; | ||
116 | return -1; | ||
117 | } | ||
118 | if (pickparams(opslimit, memlimit, &N_log2, &p, &r) != 0) { | ||
119 | errno = EINVAL; | ||
120 | return -1; | ||
121 | } | ||
122 | return crypto_pwhash_scryptsalsa208sha256_ll((const uint8_t *) passwd, | ||
123 | (size_t) passwdlen, | ||
124 | (const uint8_t *) salt, | ||
125 | crypto_pwhash_scryptsalsa208sha256_SALTBYTES, | ||
126 | (uint64_t) (1) << N_log2, r, p, | ||
127 | out, (size_t) outlen); | ||
128 | } | ||
129 | |||
130 | int | ||
131 | crypto_pwhash_scryptsalsa208sha256_str(char out[crypto_pwhash_scryptsalsa208sha256_STRBYTES], | ||
132 | const char * const passwd, | ||
133 | unsigned long long passwdlen, | ||
134 | unsigned long long opslimit, | ||
135 | size_t memlimit) | ||
136 | { | ||
137 | uint8_t salt[crypto_pwhash_scryptsalsa208sha256_STRSALTBYTES]; | ||
138 | char setting[crypto_pwhash_scryptsalsa208sha256_STRSETTINGBYTES + 1U]; | ||
139 | escrypt_local_t escrypt_local; | ||
140 | uint32_t N_log2; | ||
141 | uint32_t p; | ||
142 | uint32_t r; | ||
143 | |||
144 | memset(out, 0, crypto_pwhash_scryptsalsa208sha256_STRBYTES); | ||
145 | if (passwdlen > SIZE_MAX) { | ||
146 | errno = EFBIG; | ||
147 | return -1; | ||
148 | } | ||
149 | if (pickparams(opslimit, memlimit, &N_log2, &p, &r) != 0) { | ||
150 | errno = EINVAL; | ||
151 | return -1; | ||
152 | } | ||
153 | randombytes(salt, sizeof salt); | ||
154 | if (escrypt_gensalt_r(N_log2, r, p, salt, sizeof salt, | ||
155 | (uint8_t *) setting, sizeof setting) == NULL) { | ||
156 | errno = EINVAL; | ||
157 | return -1; | ||
158 | } | ||
159 | if (escrypt_init_local(&escrypt_local) != 0) { | ||
160 | return -1; | ||
161 | } | ||
162 | if (escrypt_r(&escrypt_local, (const uint8_t *) passwd, (size_t) passwdlen, | ||
163 | (const uint8_t *) setting, (uint8_t *) out, | ||
164 | crypto_pwhash_scryptsalsa208sha256_STRBYTES) == NULL) { | ||
165 | escrypt_free_local(&escrypt_local); | ||
166 | errno = EINVAL; | ||
167 | return -1; | ||
168 | } | ||
169 | escrypt_free_local(&escrypt_local); | ||
170 | |||
171 | (void) sizeof | ||
172 | (int[SETTING_SIZE(crypto_pwhash_scryptsalsa208sha256_STRSALTBYTES) | ||
173 | == crypto_pwhash_scryptsalsa208sha256_STRSETTINGBYTES ? 1 : -1]); | ||
174 | (void) sizeof | ||
175 | (int[crypto_pwhash_scryptsalsa208sha256_STRSETTINGBYTES + 1U + | ||
176 | crypto_pwhash_scryptsalsa208sha256_STRHASHBYTES_ENCODED + 1U | ||
177 | == crypto_pwhash_scryptsalsa208sha256_STRBYTES ? 1 : -1]); | ||
178 | |||
179 | return 0; | ||
180 | } | ||
181 | |||
182 | int | ||
183 | crypto_pwhash_scryptsalsa208sha256_str_verify(const char str[crypto_pwhash_scryptsalsa208sha256_STRBYTES], | ||
184 | const char * const passwd, | ||
185 | unsigned long long passwdlen) | ||
186 | { | ||
187 | char wanted[crypto_pwhash_scryptsalsa208sha256_STRBYTES]; | ||
188 | escrypt_local_t escrypt_local; | ||
189 | int ret = -1; | ||
190 | |||
191 | if (memchr(str, 0, crypto_pwhash_scryptsalsa208sha256_STRBYTES) != | ||
192 | &str[crypto_pwhash_scryptsalsa208sha256_STRBYTES - 1U]) { | ||
193 | return -1; | ||
194 | } | ||
195 | if (escrypt_init_local(&escrypt_local) != 0) { | ||
196 | return -1; | ||
197 | } | ||
198 | if (escrypt_r(&escrypt_local, (const uint8_t *) passwd, (size_t) passwdlen, | ||
199 | (const uint8_t *) str, (uint8_t *) wanted, | ||
200 | sizeof wanted) == NULL) { | ||
201 | escrypt_free_local(&escrypt_local); | ||
202 | return -1; | ||
203 | } | ||
204 | escrypt_free_local(&escrypt_local); | ||
205 | ret = sodium_memcmp(wanted, str, sizeof wanted); | ||
206 | sodium_memzero(wanted, sizeof wanted); | ||
207 | |||
208 | return ret; | ||
209 | } | ||
210 | |||
211 | #endif | ||
diff --git a/toxencryptsave/crypto_pwhash_scryptsalsa208sha256/runtime.c b/toxencryptsave/crypto_pwhash_scryptsalsa208sha256/runtime.c new file mode 100644 index 00000000..9b5c5131 --- /dev/null +++ b/toxencryptsave/crypto_pwhash_scryptsalsa208sha256/runtime.c | |||
@@ -0,0 +1,140 @@ | |||
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 | #ifdef HAVE_ANDROID_GETCPUFEATURES | ||
7 | # include <cpu-features.h> | ||
8 | #endif | ||
9 | |||
10 | #include "runtime.h" | ||
11 | |||
12 | typedef struct CPUFeatures_ { | ||
13 | int initialized; | ||
14 | int has_neon; | ||
15 | int has_sse2; | ||
16 | int has_sse3; | ||
17 | } CPUFeatures; | ||
18 | |||
19 | static CPUFeatures _cpu_features; | ||
20 | |||
21 | #define CPUID_SSE2 0x04000000 | ||
22 | #define CPUIDECX_SSE3 0x00000001 | ||
23 | |||
24 | static int | ||
25 | _sodium_runtime_arm_cpu_features(CPUFeatures * const cpu_features) | ||
26 | { | ||
27 | #ifndef __arm__ | ||
28 | cpu_features->has_neon = 0; | ||
29 | return -1; | ||
30 | #else | ||
31 | # ifdef __APPLE__ | ||
32 | # ifdef __ARM_NEON__ | ||
33 | cpu_features->has_neon = 1; | ||
34 | # else | ||
35 | cpu_features->has_neon = 0; | ||
36 | # endif | ||
37 | # elif defined(HAVE_ANDROID_GETCPUFEATURES) && defined(ANDROID_CPU_ARM_FEATURE_NEON) | ||
38 | cpu_features->has_neon = | ||
39 | (android_getCpuFeatures() & ANDROID_CPU_ARM_FEATURE_NEON) != 0x0; | ||
40 | # else | ||
41 | cpu_features->has_neon = 0; | ||
42 | # endif | ||
43 | return 0; | ||
44 | #endif | ||
45 | } | ||
46 | |||
47 | static void | ||
48 | _cpuid(unsigned int cpu_info[4U], const unsigned int cpu_info_type) | ||
49 | { | ||
50 | #ifdef _MSC_VER | ||
51 | __cpuidex((int *) cpu_info, cpu_info_type, 0); | ||
52 | #elif defined(HAVE_CPUID) | ||
53 | cpu_info[0] = cpu_info[1] = cpu_info[2] = cpu_info[3] = 0; | ||
54 | # ifdef __i386__ | ||
55 | __asm__ __volatile__ ("pushfl; pushfl; " | ||
56 | "popl %0; " | ||
57 | "movl %0, %1; xorl %2, %0; " | ||
58 | "pushl %0; " | ||
59 | "popfl; pushfl; popl %0; popfl" : | ||
60 | "=&r" (cpu_info[0]), "=&r" (cpu_info[1]) : | ||
61 | "i" (0x200000)); | ||
62 | if (((cpu_info[0] ^ cpu_info[1]) & 0x200000) == 0x0) { | ||
63 | return; | ||
64 | } | ||
65 | # endif | ||
66 | # ifdef __i386__ | ||
67 | __asm__ __volatile__ ("xchgl %%ebx, %k1; cpuid; xchgl %%ebx, %k1" : | ||
68 | "=a" (cpu_info[0]), "=&r" (cpu_info[1]), | ||
69 | "=c" (cpu_info[2]), "=d" (cpu_info[3]) : | ||
70 | "0" (cpu_info_type), "2" (0U)); | ||
71 | # elif defined(__x86_64__) | ||
72 | __asm__ __volatile__ ("xchgq %%rbx, %q1; cpuid; xchgq %%rbx, %q1" : | ||
73 | "=a" (cpu_info[0]), "=&r" (cpu_info[1]), | ||
74 | "=c" (cpu_info[2]), "=d" (cpu_info[3]) : | ||
75 | "0" (cpu_info_type), "2" (0U)); | ||
76 | # else | ||
77 | __asm__ __volatile__ ("cpuid" : | ||
78 | "=a" (cpu_info[0]), "=b" (cpu_info[1]), | ||
79 | "=c" (cpu_info[2]), "=d" (cpu_info[3]) : | ||
80 | "0" (cpu_info_type), "2" (0U)); | ||
81 | # endif | ||
82 | #else | ||
83 | cpu_info[0] = cpu_info[1] = cpu_info[2] = cpu_info[3] = 0; | ||
84 | #endif | ||
85 | } | ||
86 | |||
87 | static int | ||
88 | _sodium_runtime_intel_cpu_features(CPUFeatures * const cpu_features) | ||
89 | { | ||
90 | unsigned int cpu_info[4]; | ||
91 | unsigned int id; | ||
92 | |||
93 | _cpuid(cpu_info, 0x0); | ||
94 | if ((id = cpu_info[0]) == 0U) { | ||
95 | return -1; | ||
96 | } | ||
97 | _cpuid(cpu_info, 0x00000001); | ||
98 | #ifndef HAVE_EMMINTRIN_H | ||
99 | cpu_features->has_sse2 = 0; | ||
100 | #else | ||
101 | cpu_features->has_sse2 = ((cpu_info[3] & CPUID_SSE2) != 0x0); | ||
102 | #endif | ||
103 | |||
104 | #ifndef HAVE_PMMINTRIN_H | ||
105 | cpu_features->has_sse3 = 0; | ||
106 | #else | ||
107 | cpu_features->has_sse3 = ((cpu_info[2] & CPUIDECX_SSE3) != 0x0); | ||
108 | #endif | ||
109 | |||
110 | return 0; | ||
111 | } | ||
112 | |||
113 | int | ||
114 | sodium_runtime_get_cpu_features(void) | ||
115 | { | ||
116 | int ret = -1; | ||
117 | |||
118 | ret &= _sodium_runtime_arm_cpu_features(&_cpu_features); | ||
119 | ret &= _sodium_runtime_intel_cpu_features(&_cpu_features); | ||
120 | _cpu_features.initialized = 1; | ||
121 | |||
122 | return ret; | ||
123 | } | ||
124 | |||
125 | int | ||
126 | sodium_runtime_has_neon(void) { | ||
127 | return _cpu_features.has_neon; | ||
128 | } | ||
129 | |||
130 | int | ||
131 | sodium_runtime_has_sse2(void) { | ||
132 | return _cpu_features.has_sse2; | ||
133 | } | ||
134 | |||
135 | int | ||
136 | sodium_runtime_has_sse3(void) { | ||
137 | return _cpu_features.has_sse3; | ||
138 | } | ||
139 | |||
140 | #endif | ||
diff --git a/toxencryptsave/crypto_pwhash_scryptsalsa208sha256/runtime.h b/toxencryptsave/crypto_pwhash_scryptsalsa208sha256/runtime.h new file mode 100644 index 00000000..874915ef --- /dev/null +++ b/toxencryptsave/crypto_pwhash_scryptsalsa208sha256/runtime.h | |||
@@ -0,0 +1,33 @@ | |||
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 | #ifndef __SODIUM_RUNTIME_H__ | ||
7 | #define __SODIUM_RUNTIME_H__ 1 | ||
8 | |||
9 | #include "export.h" | ||
10 | |||
11 | #ifdef __cplusplus | ||
12 | extern "C" { | ||
13 | #endif | ||
14 | |||
15 | SODIUM_EXPORT | ||
16 | int sodium_runtime_get_cpu_features(void); | ||
17 | |||
18 | SODIUM_EXPORT | ||
19 | int sodium_runtime_has_neon(void); | ||
20 | |||
21 | SODIUM_EXPORT | ||
22 | int sodium_runtime_has_sse2(void); | ||
23 | |||
24 | SODIUM_EXPORT | ||
25 | int sodium_runtime_has_sse3(void); | ||
26 | |||
27 | #ifdef __cplusplus | ||
28 | } | ||
29 | #endif | ||
30 | |||
31 | #endif | ||
32 | |||
33 | #endif | ||
diff --git a/toxencryptsave/crypto_pwhash_scryptsalsa208sha256/scrypt_platform.c b/toxencryptsave/crypto_pwhash_scryptsalsa208sha256/scrypt_platform.c new file mode 100644 index 00000000..58196514 --- /dev/null +++ b/toxencryptsave/crypto_pwhash_scryptsalsa208sha256/scrypt_platform.c | |||
@@ -0,0 +1,107 @@ | |||
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 | #ifdef HAVE_SYS_MMAN_H | ||
27 | # include <sys/mman.h> | ||
28 | #endif | ||
29 | #include <errno.h> | ||
30 | #include <stdlib.h> | ||
31 | |||
32 | #include "crypto_scrypt.h" | ||
33 | #include "runtime.h" | ||
34 | |||
35 | #if !defined(MAP_ANON) && defined(MAP_ANONYMOUS) | ||
36 | # define MAP_ANON MAP_ANONYMOUS | ||
37 | #endif | ||
38 | |||
39 | void * | ||
40 | alloc_region(escrypt_region_t * region, size_t size) | ||
41 | { | ||
42 | uint8_t * base, * aligned; | ||
43 | #ifdef MAP_ANON | ||
44 | if ((base = (uint8_t *) mmap(NULL, size, PROT_READ | PROT_WRITE, | ||
45 | #ifdef MAP_NOCORE | ||
46 | MAP_ANON | MAP_PRIVATE | MAP_NOCORE, | ||
47 | #else | ||
48 | MAP_ANON | MAP_PRIVATE, | ||
49 | #endif | ||
50 | -1, 0)) == MAP_FAILED) | ||
51 | base = NULL; | ||
52 | aligned = base; | ||
53 | #elif defined(HAVE_POSIX_MEMALIGN) | ||
54 | if ((errno = posix_memalign((void **) &base, 64, size)) != 0) | ||
55 | base = NULL; | ||
56 | aligned = base; | ||
57 | #else | ||
58 | base = aligned = NULL; | ||
59 | if (size + 63 < size) | ||
60 | errno = ENOMEM; | ||
61 | else if ((base = (uint8_t *) malloc(size + 63)) != NULL) { | ||
62 | aligned = base + 63; | ||
63 | aligned -= (uintptr_t)aligned & 63; | ||
64 | } | ||
65 | #endif | ||
66 | region->base = base; | ||
67 | region->aligned = aligned; | ||
68 | region->size = base ? size : 0; | ||
69 | return aligned; | ||
70 | } | ||
71 | |||
72 | static inline void | ||
73 | init_region(escrypt_region_t * region) | ||
74 | { | ||
75 | region->base = region->aligned = NULL; | ||
76 | region->size = 0; | ||
77 | } | ||
78 | |||
79 | int | ||
80 | free_region(escrypt_region_t * region) | ||
81 | { | ||
82 | if (region->base) { | ||
83 | #ifdef MAP_ANON | ||
84 | if (munmap(region->base, region->size)) | ||
85 | return -1; | ||
86 | #else | ||
87 | free(region->base); | ||
88 | #endif | ||
89 | } | ||
90 | init_region(region); | ||
91 | return 0; | ||
92 | } | ||
93 | |||
94 | int | ||
95 | escrypt_init_local(escrypt_local_t * local) | ||
96 | { | ||
97 | init_region(local); | ||
98 | return 0; | ||
99 | } | ||
100 | |||
101 | int | ||
102 | escrypt_free_local(escrypt_local_t * local) | ||
103 | { | ||
104 | return free_region(local); | ||
105 | } | ||
106 | |||
107 | #endif | ||
diff --git a/toxencryptsave/crypto_pwhash_scryptsalsa208sha256/sse/pwhash_scryptsalsa208sha256_sse.c b/toxencryptsave/crypto_pwhash_scryptsalsa208sha256/sse/pwhash_scryptsalsa208sha256_sse.c new file mode 100644 index 00000000..856a655e --- /dev/null +++ b/toxencryptsave/crypto_pwhash_scryptsalsa208sha256/sse/pwhash_scryptsalsa208sha256_sse.c | |||
@@ -0,0 +1,398 @@ | |||
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 2009 Colin Percival | ||
8 | * Copyright 2012,2013 Alexander Peslyak | ||
9 | * All rights reserved. | ||
10 | * | ||
11 | * Redistribution and use in source and binary forms, with or without | ||
12 | * modification, are permitted provided that the following conditions | ||
13 | * are met: | ||
14 | * 1. Redistributions of source code must retain the above copyright | ||
15 | * notice, this list of conditions and the following disclaimer. | ||
16 | * 2. Redistributions in binary form must reproduce the above copyright | ||
17 | * notice, this list of conditions and the following disclaimer in the | ||
18 | * documentation and/or other materials provided with the distribution. | ||
19 | * | ||
20 | * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND | ||
21 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | ||
22 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | ||
23 | * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE | ||
24 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | ||
25 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS | ||
26 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | ||
27 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT | ||
28 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY | ||
29 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF | ||
30 | * SUCH DAMAGE. | ||
31 | * | ||
32 | * This file was originally written by Colin Percival as part of the Tarsnap | ||
33 | * online backup system. | ||
34 | */ | ||
35 | |||
36 | #if defined(HAVE_EMMINTRIN_H) || defined(_MSC_VER) | ||
37 | #if __GNUC__ | ||
38 | # pragma GCC target("sse2") | ||
39 | #endif | ||
40 | #include <emmintrin.h> | ||
41 | #if defined(__XOP__) && defined(DISABLED) | ||
42 | # include <x86intrin.h> | ||
43 | #endif | ||
44 | |||
45 | #include <errno.h> | ||
46 | #include <limits.h> | ||
47 | #include <stdint.h> | ||
48 | #include <stdlib.h> | ||
49 | #include <string.h> | ||
50 | |||
51 | #include "../pbkdf2-sha256.h" | ||
52 | #include "../sysendian.h" | ||
53 | #include "../crypto_scrypt.h" | ||
54 | |||
55 | #if defined(__XOP__) && defined(DISABLED) | ||
56 | #define ARX(out, in1, in2, s) \ | ||
57 | out = _mm_xor_si128(out, _mm_roti_epi32(_mm_add_epi32(in1, in2), s)); | ||
58 | #else | ||
59 | #define ARX(out, in1, in2, s) \ | ||
60 | { \ | ||
61 | __m128i T = _mm_add_epi32(in1, in2); \ | ||
62 | out = _mm_xor_si128(out, _mm_slli_epi32(T, s)); \ | ||
63 | out = _mm_xor_si128(out, _mm_srli_epi32(T, 32-s)); \ | ||
64 | } | ||
65 | #endif | ||
66 | |||
67 | #define SALSA20_2ROUNDS \ | ||
68 | /* Operate on "columns". */ \ | ||
69 | ARX(X1, X0, X3, 7) \ | ||
70 | ARX(X2, X1, X0, 9) \ | ||
71 | ARX(X3, X2, X1, 13) \ | ||
72 | ARX(X0, X3, X2, 18) \ | ||
73 | \ | ||
74 | /* Rearrange data. */ \ | ||
75 | X1 = _mm_shuffle_epi32(X1, 0x93); \ | ||
76 | X2 = _mm_shuffle_epi32(X2, 0x4E); \ | ||
77 | X3 = _mm_shuffle_epi32(X3, 0x39); \ | ||
78 | \ | ||
79 | /* Operate on "rows". */ \ | ||
80 | ARX(X3, X0, X1, 7) \ | ||
81 | ARX(X2, X3, X0, 9) \ | ||
82 | ARX(X1, X2, X3, 13) \ | ||
83 | ARX(X0, X1, X2, 18) \ | ||
84 | \ | ||
85 | /* Rearrange data. */ \ | ||
86 | X1 = _mm_shuffle_epi32(X1, 0x39); \ | ||
87 | X2 = _mm_shuffle_epi32(X2, 0x4E); \ | ||
88 | X3 = _mm_shuffle_epi32(X3, 0x93); | ||
89 | |||
90 | /** | ||
91 | * Apply the salsa20/8 core to the block provided in (X0 ... X3) ^ (Z0 ... Z3). | ||
92 | */ | ||
93 | #define SALSA20_8_XOR(in, out) \ | ||
94 | { \ | ||
95 | __m128i Y0 = X0 = _mm_xor_si128(X0, (in)[0]); \ | ||
96 | __m128i Y1 = X1 = _mm_xor_si128(X1, (in)[1]); \ | ||
97 | __m128i Y2 = X2 = _mm_xor_si128(X2, (in)[2]); \ | ||
98 | __m128i Y3 = X3 = _mm_xor_si128(X3, (in)[3]); \ | ||
99 | SALSA20_2ROUNDS \ | ||
100 | SALSA20_2ROUNDS \ | ||
101 | SALSA20_2ROUNDS \ | ||
102 | SALSA20_2ROUNDS \ | ||
103 | (out)[0] = X0 = _mm_add_epi32(X0, Y0); \ | ||
104 | (out)[1] = X1 = _mm_add_epi32(X1, Y1); \ | ||
105 | (out)[2] = X2 = _mm_add_epi32(X2, Y2); \ | ||
106 | (out)[3] = X3 = _mm_add_epi32(X3, Y3); \ | ||
107 | } | ||
108 | |||
109 | /** | ||
110 | * blockmix_salsa8(Bin, Bout, r): | ||
111 | * Compute Bout = BlockMix_{salsa20/8, r}(Bin). The input Bin must be 128r | ||
112 | * bytes in length; the output Bout must also be the same size. | ||
113 | */ | ||
114 | static inline void | ||
115 | blockmix_salsa8(const __m128i * Bin, __m128i * Bout, size_t r) | ||
116 | { | ||
117 | __m128i X0, X1, X2, X3; | ||
118 | size_t i; | ||
119 | |||
120 | /* 1: X <-- B_{2r - 1} */ | ||
121 | X0 = Bin[8 * r - 4]; | ||
122 | X1 = Bin[8 * r - 3]; | ||
123 | X2 = Bin[8 * r - 2]; | ||
124 | X3 = Bin[8 * r - 1]; | ||
125 | |||
126 | /* 3: X <-- H(X \xor B_i) */ | ||
127 | /* 4: Y_i <-- X */ | ||
128 | /* 6: B' <-- (Y_0, Y_2 ... Y_{2r-2}, Y_1, Y_3 ... Y_{2r-1}) */ | ||
129 | SALSA20_8_XOR(Bin, Bout) | ||
130 | |||
131 | /* 2: for i = 0 to 2r - 1 do */ | ||
132 | r--; | ||
133 | for (i = 0; i < r;) { | ||
134 | /* 3: X <-- H(X \xor B_i) */ | ||
135 | /* 4: Y_i <-- X */ | ||
136 | /* 6: B' <-- (Y_0, Y_2 ... Y_{2r-2}, Y_1, Y_3 ... Y_{2r-1}) */ | ||
137 | SALSA20_8_XOR(&Bin[i * 8 + 4], &Bout[(r + i) * 4 + 4]) | ||
138 | |||
139 | i++; | ||
140 | |||
141 | /* 3: X <-- H(X \xor B_i) */ | ||
142 | /* 4: Y_i <-- X */ | ||
143 | /* 6: B' <-- (Y_0, Y_2 ... Y_{2r-2}, Y_1, Y_3 ... Y_{2r-1}) */ | ||
144 | SALSA20_8_XOR(&Bin[i * 8], &Bout[i * 4]) | ||
145 | } | ||
146 | |||
147 | /* 3: X <-- H(X \xor B_i) */ | ||
148 | /* 4: Y_i <-- X */ | ||
149 | /* 6: B' <-- (Y_0, Y_2 ... Y_{2r-2}, Y_1, Y_3 ... Y_{2r-1}) */ | ||
150 | SALSA20_8_XOR(&Bin[i * 8 + 4], &Bout[(r + i) * 4 + 4]) | ||
151 | } | ||
152 | |||
153 | #define XOR4(in) \ | ||
154 | X0 = _mm_xor_si128(X0, (in)[0]); \ | ||
155 | X1 = _mm_xor_si128(X1, (in)[1]); \ | ||
156 | X2 = _mm_xor_si128(X2, (in)[2]); \ | ||
157 | X3 = _mm_xor_si128(X3, (in)[3]); | ||
158 | |||
159 | #define XOR4_2(in1, in2) \ | ||
160 | X0 = _mm_xor_si128((in1)[0], (in2)[0]); \ | ||
161 | X1 = _mm_xor_si128((in1)[1], (in2)[1]); \ | ||
162 | X2 = _mm_xor_si128((in1)[2], (in2)[2]); \ | ||
163 | X3 = _mm_xor_si128((in1)[3], (in2)[3]); | ||
164 | |||
165 | static inline uint32_t | ||
166 | blockmix_salsa8_xor(const __m128i * Bin1, const __m128i * Bin2, __m128i * Bout, | ||
167 | size_t r) | ||
168 | { | ||
169 | __m128i X0, X1, X2, X3; | ||
170 | size_t i; | ||
171 | |||
172 | /* 1: X <-- B_{2r - 1} */ | ||
173 | XOR4_2(&Bin1[8 * r - 4], &Bin2[8 * r - 4]) | ||
174 | |||
175 | /* 3: X <-- H(X \xor B_i) */ | ||
176 | /* 4: Y_i <-- X */ | ||
177 | /* 6: B' <-- (Y_0, Y_2 ... Y_{2r-2}, Y_1, Y_3 ... Y_{2r-1}) */ | ||
178 | XOR4(Bin1) | ||
179 | SALSA20_8_XOR(Bin2, Bout) | ||
180 | |||
181 | /* 2: for i = 0 to 2r - 1 do */ | ||
182 | r--; | ||
183 | for (i = 0; i < r;) { | ||
184 | /* 3: X <-- H(X \xor B_i) */ | ||
185 | /* 4: Y_i <-- X */ | ||
186 | /* 6: B' <-- (Y_0, Y_2 ... Y_{2r-2}, Y_1, Y_3 ... Y_{2r-1}) */ | ||
187 | XOR4(&Bin1[i * 8 + 4]) | ||
188 | SALSA20_8_XOR(&Bin2[i * 8 + 4], &Bout[(r + i) * 4 + 4]) | ||
189 | |||
190 | i++; | ||
191 | |||
192 | /* 3: X <-- H(X \xor B_i) */ | ||
193 | /* 4: Y_i <-- X */ | ||
194 | /* 6: B' <-- (Y_0, Y_2 ... Y_{2r-2}, Y_1, Y_3 ... Y_{2r-1}) */ | ||
195 | XOR4(&Bin1[i * 8]) | ||
196 | SALSA20_8_XOR(&Bin2[i * 8], &Bout[i * 4]) | ||
197 | } | ||
198 | |||
199 | /* 3: X <-- H(X \xor B_i) */ | ||
200 | /* 4: Y_i <-- X */ | ||
201 | /* 6: B' <-- (Y_0, Y_2 ... Y_{2r-2}, Y_1, Y_3 ... Y_{2r-1}) */ | ||
202 | XOR4(&Bin1[i * 8 + 4]) | ||
203 | SALSA20_8_XOR(&Bin2[i * 8 + 4], &Bout[(r + i) * 4 + 4]) | ||
204 | |||
205 | return _mm_cvtsi128_si32(X0); | ||
206 | } | ||
207 | |||
208 | #undef ARX | ||
209 | #undef SALSA20_2ROUNDS | ||
210 | #undef SALSA20_8_XOR | ||
211 | #undef XOR4 | ||
212 | #undef XOR4_2 | ||
213 | |||
214 | /** | ||
215 | * integerify(B, r): | ||
216 | * Return the result of parsing B_{2r-1} as a little-endian integer. | ||
217 | */ | ||
218 | static inline uint32_t | ||
219 | integerify(const void * B, size_t r) | ||
220 | { | ||
221 | return *(const uint32_t *)((uintptr_t)(B) + (2 * r - 1) * 64); | ||
222 | } | ||
223 | |||
224 | /** | ||
225 | * smix(B, r, N, V, XY): | ||
226 | * Compute B = SMix_r(B, N). The input B must be 128r bytes in length; | ||
227 | * the temporary storage V must be 128rN bytes in length; the temporary | ||
228 | * storage XY must be 256r + 64 bytes in length. The value N must be a | ||
229 | * power of 2 greater than 1. The arrays B, V, and XY must be aligned to a | ||
230 | * multiple of 64 bytes. | ||
231 | */ | ||
232 | static void | ||
233 | smix(uint8_t * B, size_t r, uint32_t N, void * V, void * XY) | ||
234 | { | ||
235 | size_t s = 128 * r; | ||
236 | __m128i * X = (__m128i *) V, * Y; | ||
237 | uint32_t * X32 = (uint32_t *) V; | ||
238 | uint32_t i, j; | ||
239 | size_t k; | ||
240 | |||
241 | /* 1: X <-- B */ | ||
242 | /* 3: V_i <-- X */ | ||
243 | for (k = 0; k < 2 * r; k++) { | ||
244 | for (i = 0; i < 16; i++) { | ||
245 | X32[k * 16 + i] = | ||
246 | le32dec(&B[(k * 16 + (i * 5 % 16)) * 4]); | ||
247 | } | ||
248 | } | ||
249 | |||
250 | /* 2: for i = 0 to N - 1 do */ | ||
251 | for (i = 1; i < N - 1; i += 2) { | ||
252 | /* 4: X <-- H(X) */ | ||
253 | /* 3: V_i <-- X */ | ||
254 | Y = (__m128i *)((uintptr_t)(V) + i * s); | ||
255 | blockmix_salsa8(X, Y, r); | ||
256 | |||
257 | /* 4: X <-- H(X) */ | ||
258 | /* 3: V_i <-- X */ | ||
259 | X = (__m128i *)((uintptr_t)(V) + (i + 1) * s); | ||
260 | blockmix_salsa8(Y, X, r); | ||
261 | } | ||
262 | |||
263 | /* 4: X <-- H(X) */ | ||
264 | /* 3: V_i <-- X */ | ||
265 | Y = (__m128i *)((uintptr_t)(V) + i * s); | ||
266 | blockmix_salsa8(X, Y, r); | ||
267 | |||
268 | /* 4: X <-- H(X) */ | ||
269 | /* 3: V_i <-- X */ | ||
270 | X = (__m128i *) XY; | ||
271 | blockmix_salsa8(Y, X, r); | ||
272 | |||
273 | X32 = (uint32_t *) XY; | ||
274 | Y = (__m128i *)((uintptr_t)(XY) + s); | ||
275 | |||
276 | /* 7: j <-- Integerify(X) mod N */ | ||
277 | j = integerify(X, r) & (N - 1); | ||
278 | |||
279 | /* 6: for i = 0 to N - 1 do */ | ||
280 | for (i = 0; i < N; i += 2) { | ||
281 | __m128i * V_j = (__m128i *)((uintptr_t)(V) + j * s); | ||
282 | |||
283 | /* 8: X <-- H(X \xor V_j) */ | ||
284 | /* 7: j <-- Integerify(X) mod N */ | ||
285 | j = blockmix_salsa8_xor(X, V_j, Y, r) & (N - 1); | ||
286 | V_j = (__m128i *)((uintptr_t)(V) + j * s); | ||
287 | |||
288 | /* 8: X <-- H(X \xor V_j) */ | ||
289 | /* 7: j <-- Integerify(X) mod N */ | ||
290 | j = blockmix_salsa8_xor(Y, V_j, X, r) & (N - 1); | ||
291 | } | ||
292 | |||
293 | /* 10: B' <-- X */ | ||
294 | for (k = 0; k < 2 * r; k++) { | ||
295 | for (i = 0; i < 16; i++) { | ||
296 | le32enc(&B[(k * 16 + (i * 5 % 16)) * 4], | ||
297 | X32[k * 16 + i]); | ||
298 | } | ||
299 | } | ||
300 | } | ||
301 | |||
302 | /** | ||
303 | * escrypt_kdf(local, passwd, passwdlen, salt, saltlen, | ||
304 | * N, r, p, buf, buflen): | ||
305 | * Compute scrypt(passwd[0 .. passwdlen - 1], salt[0 .. saltlen - 1], N, r, | ||
306 | * p, buflen) and write the result into buf. The parameters r, p, and buflen | ||
307 | * must satisfy r * p < 2^30 and buflen <= (2^32 - 1) * 32. The parameter N | ||
308 | * must be a power of 2 greater than 1. | ||
309 | * | ||
310 | * Return 0 on success; or -1 on error. | ||
311 | */ | ||
312 | int | ||
313 | escrypt_kdf_sse(escrypt_local_t * local, | ||
314 | const uint8_t * passwd, size_t passwdlen, | ||
315 | const uint8_t * salt, size_t saltlen, | ||
316 | uint64_t N, uint32_t _r, uint32_t _p, | ||
317 | uint8_t * buf, size_t buflen) | ||
318 | { | ||
319 | size_t B_size, V_size, XY_size, need; | ||
320 | uint8_t * B; | ||
321 | uint32_t * V, * XY; | ||
322 | size_t r = _r, p = _p; | ||
323 | uint32_t i; | ||
324 | |||
325 | /* Sanity-check parameters. */ | ||
326 | #if SIZE_MAX > UINT32_MAX | ||
327 | if (buflen > (((uint64_t)(1) << 32) - 1) * 32) { | ||
328 | errno = EFBIG; | ||
329 | return -1; | ||
330 | } | ||
331 | #endif | ||
332 | if ((uint64_t)(r) * (uint64_t)(p) >= (1 << 30)) { | ||
333 | errno = EFBIG; | ||
334 | return -1; | ||
335 | } | ||
336 | if (N > UINT32_MAX) { | ||
337 | errno = EFBIG; | ||
338 | return -1; | ||
339 | } | ||
340 | if (((N & (N - 1)) != 0) || (N < 2)) { | ||
341 | errno = EINVAL; | ||
342 | return -1; | ||
343 | } | ||
344 | if (r == 0 || p == 0) { | ||
345 | errno = EINVAL; | ||
346 | return -1; | ||
347 | } | ||
348 | if ((r > SIZE_MAX / 128 / p) || | ||
349 | #if SIZE_MAX / 256 <= UINT32_MAX | ||
350 | (r > SIZE_MAX / 256) || | ||
351 | #endif | ||
352 | (N > SIZE_MAX / 128 / r)) { | ||
353 | errno = ENOMEM; | ||
354 | return -1; | ||
355 | } | ||
356 | |||
357 | /* Allocate memory. */ | ||
358 | B_size = (size_t)128 * r * p; | ||
359 | V_size = (size_t)128 * r * N; | ||
360 | need = B_size + V_size; | ||
361 | if (need < V_size) { | ||
362 | errno = ENOMEM; | ||
363 | return -1; | ||
364 | } | ||
365 | XY_size = (size_t)256 * r + 64; | ||
366 | need += XY_size; | ||
367 | if (need < XY_size) { | ||
368 | errno = ENOMEM; | ||
369 | return -1; | ||
370 | } | ||
371 | if (local->size < need) { | ||
372 | if (free_region(local)) | ||
373 | return -1; | ||
374 | if (!alloc_region(local, need)) | ||
375 | return -1; | ||
376 | } | ||
377 | B = (uint8_t *)local->aligned; | ||
378 | V = (uint32_t *)((uint8_t *)B + B_size); | ||
379 | XY = (uint32_t *)((uint8_t *)V + V_size); | ||
380 | |||
381 | /* 1: (B_0 ... B_{p-1}) <-- PBKDF2(P, S, 1, p * MFLen) */ | ||
382 | PBKDF2_SHA256(passwd, passwdlen, salt, saltlen, 1, B, B_size); | ||
383 | |||
384 | /* 2: for i = 0 to p - 1 do */ | ||
385 | for (i = 0; i < p; i++) { | ||
386 | /* 3: B_i <-- MF(B_i, N) */ | ||
387 | smix(&B[(size_t)128 * i * r], r, N, V, XY); | ||
388 | } | ||
389 | |||
390 | /* 5: DK <-- PBKDF2(P, B, 1, dkLen) */ | ||
391 | PBKDF2_SHA256(passwd, passwdlen, B, B_size, 1, buf, buflen); | ||
392 | |||
393 | /* Success! */ | ||
394 | return 0; | ||
395 | } | ||
396 | #endif | ||
397 | |||
398 | #endif | ||
diff --git a/toxencryptsave/crypto_pwhash_scryptsalsa208sha256/sysendian.h b/toxencryptsave/crypto_pwhash_scryptsalsa208sha256/sysendian.h new file mode 100644 index 00000000..04e5c1ed --- /dev/null +++ b/toxencryptsave/crypto_pwhash_scryptsalsa208sha256/sysendian.h | |||
@@ -0,0 +1,153 @@ | |||
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 | #ifndef _SYSENDIAN_H_ | ||
7 | #define _SYSENDIAN_H_ | ||
8 | |||
9 | #include <stdint.h> | ||
10 | |||
11 | /* Avoid namespace collisions with BSD <sys/endian.h>. */ | ||
12 | #define be16dec scrypt_be16dec | ||
13 | #define be16enc scrypt_be16enc | ||
14 | #define be32dec scrypt_be32dec | ||
15 | #define be32enc scrypt_be32enc | ||
16 | #define be64dec scrypt_be64dec | ||
17 | #define be64enc scrypt_be64enc | ||
18 | #define le16dec scrypt_le16dec | ||
19 | #define le16enc scrypt_le16enc | ||
20 | #define le32dec scrypt_le32dec | ||
21 | #define le32enc scrypt_le32enc | ||
22 | #define le64dec scrypt_le64dec | ||
23 | #define le64enc scrypt_le64enc | ||
24 | |||
25 | static inline uint16_t | ||
26 | be16dec(const void *pp) | ||
27 | { | ||
28 | const uint8_t *p = (uint8_t const *)pp; | ||
29 | |||
30 | return ((uint16_t)(p[1]) + ((uint16_t)(p[0]) << 8)); | ||
31 | } | ||
32 | |||
33 | static inline void | ||
34 | be16enc(void *pp, uint16_t x) | ||
35 | { | ||
36 | uint8_t * p = (uint8_t *)pp; | ||
37 | |||
38 | p[1] = x & 0xff; | ||
39 | p[0] = (x >> 8) & 0xff; | ||
40 | } | ||
41 | |||
42 | static inline uint32_t | ||
43 | be32dec(const void *pp) | ||
44 | { | ||
45 | const uint8_t *p = (uint8_t const *)pp; | ||
46 | |||
47 | return ((uint32_t)(p[3]) + ((uint32_t)(p[2]) << 8) + | ||
48 | ((uint32_t)(p[1]) << 16) + ((uint32_t)(p[0]) << 24)); | ||
49 | } | ||
50 | |||
51 | static inline void | ||
52 | be32enc(void *pp, uint32_t x) | ||
53 | { | ||
54 | uint8_t * p = (uint8_t *)pp; | ||
55 | |||
56 | p[3] = x & 0xff; | ||
57 | p[2] = (x >> 8) & 0xff; | ||
58 | p[1] = (x >> 16) & 0xff; | ||
59 | p[0] = (x >> 24) & 0xff; | ||
60 | } | ||
61 | |||
62 | static inline uint64_t | ||
63 | be64dec(const void *pp) | ||
64 | { | ||
65 | const uint8_t *p = (uint8_t const *)pp; | ||
66 | |||
67 | return ((uint64_t)(p[7]) + ((uint64_t)(p[6]) << 8) + | ||
68 | ((uint64_t)(p[5]) << 16) + ((uint64_t)(p[4]) << 24) + | ||
69 | ((uint64_t)(p[3]) << 32) + ((uint64_t)(p[2]) << 40) + | ||
70 | ((uint64_t)(p[1]) << 48) + ((uint64_t)(p[0]) << 56)); | ||
71 | } | ||
72 | |||
73 | static inline void | ||
74 | be64enc(void *pp, uint64_t x) | ||
75 | { | ||
76 | uint8_t * p = (uint8_t *)pp; | ||
77 | |||
78 | p[7] = x & 0xff; | ||
79 | p[6] = (x >> 8) & 0xff; | ||
80 | p[5] = (x >> 16) & 0xff; | ||
81 | p[4] = (x >> 24) & 0xff; | ||
82 | p[3] = (x >> 32) & 0xff; | ||
83 | p[2] = (x >> 40) & 0xff; | ||
84 | p[1] = (x >> 48) & 0xff; | ||
85 | p[0] = (x >> 56) & 0xff; | ||
86 | } | ||
87 | |||
88 | static inline uint16_t | ||
89 | le16dec(const void *pp) | ||
90 | { | ||
91 | const uint8_t *p = (uint8_t const *)pp; | ||
92 | |||
93 | return ((uint16_t)(p[0]) + ((uint16_t)(p[1]) << 8)); | ||
94 | } | ||
95 | |||
96 | static inline void | ||
97 | le16enc(void *pp, uint16_t x) | ||
98 | { | ||
99 | uint8_t * p = (uint8_t *)pp; | ||
100 | |||
101 | p[0] = x & 0xff; | ||
102 | p[1] = (x >> 8) & 0xff; | ||
103 | } | ||
104 | |||
105 | static inline uint32_t | ||
106 | le32dec(const void *pp) | ||
107 | { | ||
108 | const uint8_t *p = (uint8_t const *)pp; | ||
109 | |||
110 | return ((uint32_t)(p[0]) + ((uint32_t)(p[1]) << 8) + | ||
111 | ((uint32_t)(p[2]) << 16) + ((uint32_t)(p[3]) << 24)); | ||
112 | } | ||
113 | |||
114 | static inline void | ||
115 | le32enc(void *pp, uint32_t x) | ||
116 | { | ||
117 | uint8_t * p = (uint8_t *)pp; | ||
118 | |||
119 | p[0] = x & 0xff; | ||
120 | p[1] = (x >> 8) & 0xff; | ||
121 | p[2] = (x >> 16) & 0xff; | ||
122 | p[3] = (x >> 24) & 0xff; | ||
123 | } | ||
124 | |||
125 | static inline uint64_t | ||
126 | le64dec(const void *pp) | ||
127 | { | ||
128 | const uint8_t *p = (uint8_t const *)pp; | ||
129 | |||
130 | return ((uint64_t)(p[0]) + ((uint64_t)(p[1]) << 8) + | ||
131 | ((uint64_t)(p[2]) << 16) + ((uint64_t)(p[3]) << 24) + | ||
132 | ((uint64_t)(p[4]) << 32) + ((uint64_t)(p[5]) << 40) + | ||
133 | ((uint64_t)(p[6]) << 48) + ((uint64_t)(p[7]) << 56)); | ||
134 | } | ||
135 | |||
136 | static inline void | ||
137 | le64enc(void *pp, uint64_t x) | ||
138 | { | ||
139 | uint8_t * p = (uint8_t *)pp; | ||
140 | |||
141 | p[0] = x & 0xff; | ||
142 | p[1] = (x >> 8) & 0xff; | ||
143 | p[2] = (x >> 16) & 0xff; | ||
144 | p[3] = (x >> 24) & 0xff; | ||
145 | p[4] = (x >> 32) & 0xff; | ||
146 | p[5] = (x >> 40) & 0xff; | ||
147 | p[6] = (x >> 48) & 0xff; | ||
148 | p[7] = (x >> 56) & 0xff; | ||
149 | } | ||
150 | |||
151 | #endif /* !_SYSENDIAN_H_ */ | ||
152 | |||
153 | #endif | ||
diff --git a/toxencryptsave/crypto_pwhash_scryptsalsa208sha256/utils.c b/toxencryptsave/crypto_pwhash_scryptsalsa208sha256/utils.c new file mode 100644 index 00000000..e61ccf3e --- /dev/null +++ b/toxencryptsave/crypto_pwhash_scryptsalsa208sha256/utils.c | |||
@@ -0,0 +1,78 @@ | |||
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 | #ifndef __STDC_WANT_LIB_EXT1__ | ||
7 | # define __STDC_WANT_LIB_EXT1__ 1 | ||
8 | #endif | ||
9 | #include <assert.h> | ||
10 | #include <errno.h> | ||
11 | #include <limits.h> | ||
12 | #include <signal.h> | ||
13 | #include <stddef.h> | ||
14 | #include <stdint.h> | ||
15 | #include <stdlib.h> | ||
16 | #include <string.h> | ||
17 | |||
18 | #ifdef HAVE_SYS_MMAN_H | ||
19 | # include <sys/mman.h> | ||
20 | #endif | ||
21 | |||
22 | #include "utils.h" | ||
23 | |||
24 | #ifdef _WIN32 | ||
25 | # include <windows.h> | ||
26 | # include <wincrypt.h> | ||
27 | #else | ||
28 | # include <unistd.h> | ||
29 | #endif | ||
30 | |||
31 | #ifdef HAVE_WEAK_SYMBOLS | ||
32 | __attribute__((weak)) void | ||
33 | __sodium_dummy_symbol_to_prevent_lto(void * const pnt, const size_t len) | ||
34 | { | ||
35 | (void) pnt; | ||
36 | (void) len; | ||
37 | } | ||
38 | #endif | ||
39 | |||
40 | void | ||
41 | sodium_memzero(void * const pnt, const size_t len) | ||
42 | { | ||
43 | #ifdef _WIN32 | ||
44 | SecureZeroMemory(pnt, len); | ||
45 | #elif defined(HAVE_MEMSET_S) | ||
46 | if (memset_s(pnt, (rsize_t) len, 0, (rsize_t) len) != 0) { | ||
47 | abort(); | ||
48 | } | ||
49 | #elif defined(HAVE_EXPLICIT_BZERO) | ||
50 | explicit_bzero(pnt, len); | ||
51 | #elif HAVE_WEAK_SYMBOLS | ||
52 | memset(pnt, 0, len); | ||
53 | __sodium_dummy_symbol_to_prevent_lto(pnt, len); | ||
54 | #else | ||
55 | volatile unsigned char *pnt_ = (volatile unsigned char *) pnt; | ||
56 | size_t i = (size_t) 0U; | ||
57 | |||
58 | while (i < len) { | ||
59 | pnt_[i++] = 0U; | ||
60 | } | ||
61 | #endif | ||
62 | } | ||
63 | |||
64 | int | ||
65 | sodium_memcmp(const void * const b1_, const void * const b2_, size_t len) | ||
66 | { | ||
67 | const unsigned char *b1 = (const unsigned char *) b1_; | ||
68 | const unsigned char *b2 = (const unsigned char *) b2_; | ||
69 | size_t i; | ||
70 | unsigned char d = (unsigned char) 0U; | ||
71 | |||
72 | for (i = 0U; i < len; i++) { | ||
73 | d |= b1[i] ^ b2[i]; | ||
74 | } | ||
75 | return (int) ((1 & ((d - 1) >> 8)) - 1); | ||
76 | } | ||
77 | |||
78 | #endif | ||
diff --git a/toxencryptsave/crypto_pwhash_scryptsalsa208sha256/utils.h b/toxencryptsave/crypto_pwhash_scryptsalsa208sha256/utils.h new file mode 100644 index 00000000..fb2020c3 --- /dev/null +++ b/toxencryptsave/crypto_pwhash_scryptsalsa208sha256/utils.h | |||
@@ -0,0 +1,40 @@ | |||
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 | #ifndef __SODIUM_UTILS_H__ | ||
7 | #define __SODIUM_UTILS_H__ | ||
8 | |||
9 | #include <stddef.h> | ||
10 | |||
11 | #include "export.h" | ||
12 | |||
13 | #ifdef __cplusplus | ||
14 | extern "C" { | ||
15 | #endif | ||
16 | |||
17 | #if defined(__cplusplus) || !defined(__STDC_VERSION__) || __STDC_VERSION__ < 199901L | ||
18 | # define _SODIUM_C99(X) | ||
19 | #else | ||
20 | # define _SODIUM_C99(X) X | ||
21 | #endif | ||
22 | |||
23 | SODIUM_EXPORT | ||
24 | void sodium_memzero(void * const pnt, const size_t len); | ||
25 | |||
26 | /* WARNING: sodium_memcmp() must be used to verify if two secret keys | ||
27 | * are equal, in constant time. | ||
28 | * It returns 0 if the keys are equal, and -1 if they differ. | ||
29 | * This function is not designed for lexicographical comparisons. | ||
30 | */ | ||
31 | SODIUM_EXPORT | ||
32 | int sodium_memcmp(const void * const b1_, const void * const b2_, size_t len); | ||
33 | |||
34 | #ifdef __cplusplus | ||
35 | } | ||
36 | #endif | ||
37 | |||
38 | #endif | ||
39 | |||
40 | #endif | ||
diff --git a/toxencryptsave/defines.h b/toxencryptsave/defines.h new file mode 100644 index 00000000..e3fca073 --- /dev/null +++ b/toxencryptsave/defines.h | |||
@@ -0,0 +1,2 @@ | |||
1 | #define TOX_ENC_SAVE_MAGIC_NUMBER "toxEsave" | ||
2 | #define TOX_ENC_SAVE_MAGIC_LENGTH 8 | ||
diff --git a/toxencryptsave/toxencryptsave.c b/toxencryptsave/toxencryptsave.c new file mode 100644 index 00000000..13a34dea --- /dev/null +++ b/toxencryptsave/toxencryptsave.c | |||
@@ -0,0 +1,346 @@ | |||
1 | /* toxencryptsave.c | ||
2 | * | ||
3 | * The Tox encrypted save functions. | ||
4 | * | ||
5 | * Copyright (C) 2013 Tox project All Rights Reserved. | ||
6 | * | ||
7 | * This file is part of Tox. | ||
8 | * | ||
9 | * Tox is free software: you can redistribute it and/or modify | ||
10 | * it under the terms of the GNU General Public License as published by | ||
11 | * the Free Software Foundation, either version 3 of the License, or | ||
12 | * (at your option) any later version. | ||
13 | * | ||
14 | * Tox is distributed in the hope that it will be useful, | ||
15 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
16 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
17 | * GNU General Public License for more details. | ||
18 | * | ||
19 | * You should have received a copy of the GNU General Public License | ||
20 | * along with Tox. If not, see <http://www.gnu.org/licenses/>. | ||
21 | * | ||
22 | */ | ||
23 | |||
24 | #ifdef HAVE_CONFIG_H | ||
25 | #include "config.h" | ||
26 | #endif | ||
27 | |||
28 | #include "toxencryptsave.h" | ||
29 | #include "defines.h" | ||
30 | #include "../toxcore/crypto_core.h" | ||
31 | #include "../toxcore/tox.h" | ||
32 | |||
33 | #ifdef VANILLA_NACL | ||
34 | #include "crypto_pwhash_scryptsalsa208sha256/crypto_pwhash_scryptsalsa208sha256.h" | ||
35 | #include "crypto_pwhash_scryptsalsa208sha256/utils.h" /* sodium_memzero */ | ||
36 | #include <crypto_hash_sha256.h> | ||
37 | #endif | ||
38 | |||
39 | #define TOX_PASS_ENCRYPTION_EXTRA_LENGTH (crypto_box_MACBYTES + crypto_box_NONCEBYTES \ | ||
40 | + crypto_pwhash_scryptsalsa208sha256_SALTBYTES + TOX_ENC_SAVE_MAGIC_LENGTH) | ||
41 | |||
42 | #define TOX_PASS_KEY_LENGTH (crypto_pwhash_scryptsalsa208sha256_SALTBYTES + crypto_box_KEYBYTES) | ||
43 | |||
44 | int tox_pass_encryption_extra_length() | ||
45 | { | ||
46 | return TOX_PASS_ENCRYPTION_EXTRA_LENGTH; | ||
47 | } | ||
48 | |||
49 | int tox_pass_key_length() | ||
50 | { | ||
51 | return TOX_PASS_KEY_LENGTH; | ||
52 | } | ||
53 | |||
54 | int tox_pass_salt_length() | ||
55 | { | ||
56 | return crypto_pwhash_scryptsalsa208sha256_SALTBYTES; | ||
57 | } | ||
58 | |||
59 | /* This "module" provides functions analogous to tox_load and tox_save in toxcore | ||
60 | * Clients should consider alerting their users that, unlike plain data, if even one bit | ||
61 | * becomes corrupted, the data will be entirely unrecoverable. | ||
62 | * Ditto if they forget their password, there is no way to recover the data. | ||
63 | */ | ||
64 | |||
65 | /* return size of the messenger data (for encrypted saving). */ | ||
66 | uint32_t tox_encrypted_size(const Tox *tox) | ||
67 | { | ||
68 | return tox_save_size(tox) + TOX_PASS_ENCRYPTION_EXTRA_LENGTH; | ||
69 | } | ||
70 | |||
71 | /* This retrieves the salt used to encrypt the given data, which can then be passed to | ||
72 | * derive_key_with_salt to produce the same key as was previously used. Any encrpyted | ||
73 | * data with this module can be used as input. | ||
74 | * | ||
75 | * returns -1 if the magic number is wrong | ||
76 | * returns 0 otherwise (no guarantee about validity of data) | ||
77 | */ | ||
78 | int tox_get_salt(uint8_t *data, uint8_t *salt) | ||
79 | { | ||
80 | if (memcmp(data, TOX_ENC_SAVE_MAGIC_NUMBER, TOX_ENC_SAVE_MAGIC_LENGTH) != 0) | ||
81 | return -1; | ||
82 | |||
83 | data += TOX_ENC_SAVE_MAGIC_LENGTH; | ||
84 | memcpy(salt, data, crypto_pwhash_scryptsalsa208sha256_SALTBYTES); | ||
85 | return 0; | ||
86 | } | ||
87 | |||
88 | /* Generates a secret symmetric key from the given passphrase. out_key must be at least | ||
89 | * TOX_PASS_KEY_LENGTH bytes long. | ||
90 | * Be sure to not compromise the key! Only keep it in memory, do not write to disk. | ||
91 | * This function is fairly cheap, but irungentoo insists that you be allowed to | ||
92 | * cache the result if you want, to minimize computation for repeated encryptions. | ||
93 | * The password is zeroed after key derivation. | ||
94 | * The key should only be used with the other functions in this module, as it | ||
95 | * includes a salt. | ||
96 | * | ||
97 | * returns 0 on success | ||
98 | * returns -1 on failure | ||
99 | */ | ||
100 | int tox_derive_key_from_pass(uint8_t *passphrase, uint32_t pplength, uint8_t *out_key) | ||
101 | { | ||
102 | uint8_t salt[crypto_pwhash_scryptsalsa208sha256_SALTBYTES]; | ||
103 | randombytes(salt, sizeof salt); | ||
104 | return tox_derive_key_with_salt(passphrase, pplength, salt, out_key); | ||
105 | } | ||
106 | |||
107 | /* Same as above, except with use the given salt for deterministic key derivation. | ||
108 | * The salt must be tox_salt_length() bytes in length. | ||
109 | */ | ||
110 | int tox_derive_key_with_salt(uint8_t *passphrase, uint32_t pplength, uint8_t *salt, uint8_t *out_key) | ||
111 | { | ||
112 | if (pplength == 0) | ||
113 | return -1; | ||
114 | |||
115 | uint8_t passkey[crypto_hash_sha256_BYTES]; | ||
116 | crypto_hash_sha256(passkey, passphrase, pplength); | ||
117 | |||
118 | uint8_t key[crypto_box_KEYBYTES]; | ||
119 | |||
120 | /* Derive a key from the password */ | ||
121 | /* http://doc.libsodium.org/key_derivation/README.html */ | ||
122 | /* note that, according to the documentation, a generic pwhash interface will be created | ||
123 | * once the pwhash competition (https://password-hashing.net/) is over */ | ||
124 | if (crypto_pwhash_scryptsalsa208sha256( | ||
125 | key, sizeof(key), (char *)passkey, sizeof(passkey), salt, | ||
126 | crypto_pwhash_scryptsalsa208sha256_OPSLIMIT_INTERACTIVE * 2, /* slightly stronger */ | ||
127 | crypto_pwhash_scryptsalsa208sha256_MEMLIMIT_INTERACTIVE) != 0) { | ||
128 | /* out of memory most likely */ | ||
129 | return -1; | ||
130 | } | ||
131 | |||
132 | sodium_memzero(passkey, crypto_hash_sha256_BYTES); /* wipe plaintext pw */ | ||
133 | memcpy(out_key, salt, crypto_pwhash_scryptsalsa208sha256_SALTBYTES); | ||
134 | memcpy(out_key + crypto_pwhash_scryptsalsa208sha256_SALTBYTES, key, crypto_box_KEYBYTES); | ||
135 | return 0; | ||
136 | } | ||
137 | |||
138 | /* Encrypt arbitrary with a key produced by tox_derive_key_from_pass. The output | ||
139 | * array must be at least data_len + TOX_PASS_ENCRYPTION_EXTRA_LENGTH bytes long. | ||
140 | * key must be TOX_PASS_KEY_LENGTH bytes. | ||
141 | * If you already have a symmetric key from somewhere besides this module, simply | ||
142 | * call encrypt_data_symmetric in toxcore/crypto_core directly. | ||
143 | * | ||
144 | * | ||
145 | * returns 0 on success | ||
146 | * returns -1 on failure | ||
147 | */ | ||
148 | int tox_pass_key_encrypt(const uint8_t *data, uint32_t data_len, const uint8_t *key, uint8_t *out) | ||
149 | { | ||
150 | /* the output data consists of, in order: | ||
151 | * salt, nonce, mac, enc_data | ||
152 | * where the mac is automatically prepended by the encrypt() | ||
153 | * the salt+nonce is called the prefix | ||
154 | * I'm not sure what else I'm supposed to do with the salt and nonce, since we | ||
155 | * need them to decrypt the data | ||
156 | */ | ||
157 | |||
158 | /* first add the magic number */ | ||
159 | memcpy(out, TOX_ENC_SAVE_MAGIC_NUMBER, TOX_ENC_SAVE_MAGIC_LENGTH); | ||
160 | out += TOX_ENC_SAVE_MAGIC_LENGTH; | ||
161 | |||
162 | /* then add the rest prefix */ | ||
163 | memcpy(out, key, crypto_pwhash_scryptsalsa208sha256_SALTBYTES); | ||
164 | key += crypto_pwhash_scryptsalsa208sha256_SALTBYTES; | ||
165 | out += crypto_pwhash_scryptsalsa208sha256_SALTBYTES; | ||
166 | |||
167 | uint8_t nonce[crypto_box_NONCEBYTES]; | ||
168 | random_nonce(nonce); | ||
169 | memcpy(out, nonce, crypto_box_NONCEBYTES); | ||
170 | out += crypto_box_NONCEBYTES; | ||
171 | |||
172 | /* now encrypt */ | ||
173 | if (encrypt_data_symmetric(key, nonce, data, data_len, out) | ||
174 | != data_len + crypto_box_MACBYTES) { | ||
175 | return -1; | ||
176 | } | ||
177 | |||
178 | return 0; | ||
179 | } | ||
180 | |||
181 | /* Encrypts the given data with the given passphrase. The output array must be | ||
182 | * at least data_len + TOX_PASS_ENCRYPTION_EXTRA_LENGTH bytes long. This delegates | ||
183 | * to tox_derive_key_from_pass and tox_pass_key_encrypt. | ||
184 | * | ||
185 | * returns 0 on success | ||
186 | * returns -1 on failure | ||
187 | */ | ||
188 | int tox_pass_encrypt(const uint8_t *data, uint32_t data_len, uint8_t *passphrase, uint32_t pplength, uint8_t *out) | ||
189 | { | ||
190 | uint8_t key[TOX_PASS_KEY_LENGTH]; | ||
191 | |||
192 | if (tox_derive_key_from_pass(passphrase, pplength, key) == -1) | ||
193 | return -1; | ||
194 | |||
195 | return tox_pass_key_encrypt(data, data_len, key, out); | ||
196 | } | ||
197 | |||
198 | /* Save the messenger data encrypted with the given password. | ||
199 | * data must be at least tox_encrypted_size(). | ||
200 | * | ||
201 | * returns 0 on success | ||
202 | * returns -1 on failure | ||
203 | */ | ||
204 | int tox_encrypted_save(const Tox *tox, uint8_t *data, uint8_t *passphrase, uint32_t pplength) | ||
205 | { | ||
206 | /* first get plain save data */ | ||
207 | uint32_t temp_size = tox_save_size(tox); | ||
208 | uint8_t temp_data[temp_size]; | ||
209 | tox_save(tox, temp_data); | ||
210 | |||
211 | /* now encrypt */ | ||
212 | return tox_pass_encrypt(temp_data, temp_size, passphrase, pplength, data); | ||
213 | } | ||
214 | |||
215 | /* Save the messenger data encrypted with the given key from tox_derive_key. | ||
216 | * data must be at least tox_encrypted_size(). | ||
217 | * | ||
218 | * returns 0 on success | ||
219 | * returns -1 on failure | ||
220 | */ | ||
221 | int tox_encrypted_key_save(const Tox *tox, uint8_t *data, uint8_t *key) | ||
222 | { | ||
223 | /* first get plain save data */ | ||
224 | uint32_t temp_size = tox_save_size(tox); | ||
225 | uint8_t temp_data[temp_size]; | ||
226 | tox_save(tox, temp_data); | ||
227 | |||
228 | /* encrypt */ | ||
229 | return tox_pass_key_encrypt(temp_data, temp_size, key, data); | ||
230 | } | ||
231 | |||
232 | /* This is the inverse of tox_pass_key_encrypt, also using only keys produced by | ||
233 | * tox_derive_key_from_pass. | ||
234 | * | ||
235 | * returns the length of the output data (== data_len - TOX_PASS_ENCRYPTION_EXTRA_LENGTH) on success | ||
236 | * returns -1 on failure | ||
237 | */ | ||
238 | int tox_pass_key_decrypt(const uint8_t *data, uint32_t length, const uint8_t *key, uint8_t *out) | ||
239 | { | ||
240 | if (length <= TOX_PASS_ENCRYPTION_EXTRA_LENGTH | ||
241 | || 0 != memcmp(data, TOX_ENC_SAVE_MAGIC_NUMBER, TOX_ENC_SAVE_MAGIC_LENGTH)) | ||
242 | return -1; | ||
243 | |||
244 | data += TOX_ENC_SAVE_MAGIC_LENGTH; | ||
245 | |||
246 | uint32_t decrypt_length = length - TOX_PASS_ENCRYPTION_EXTRA_LENGTH; | ||
247 | //uint8_t salt[crypto_pwhash_scryptsalsa208sha256_SALTBYTES]; | ||
248 | uint8_t nonce[crypto_box_NONCEBYTES]; | ||
249 | |||
250 | //memcpy(salt, data, crypto_pwhash_scryptsalsa208sha256_SALTBYTES); | ||
251 | key += crypto_pwhash_scryptsalsa208sha256_SALTBYTES; // ignore the salt, which is only needed for kdf | ||
252 | data += crypto_pwhash_scryptsalsa208sha256_SALTBYTES; | ||
253 | memcpy(nonce, data, crypto_box_NONCEBYTES); | ||
254 | data += crypto_box_NONCEBYTES; | ||
255 | |||
256 | /* decrypt the data */ | ||
257 | if (decrypt_data_symmetric(key, nonce, data, decrypt_length + crypto_box_MACBYTES, out) | ||
258 | != decrypt_length) { | ||
259 | return -1; | ||
260 | } | ||
261 | |||
262 | return decrypt_length; | ||
263 | } | ||
264 | |||
265 | /* Decrypts the given data with the given passphrase. The output array must be | ||
266 | * at least data_len - TOX_PASS_ENCRYPTION_EXTRA_LENGTH bytes long. | ||
267 | * | ||
268 | * returns the length of the output data (== data_len - TOX_PASS_ENCRYPTION_EXTRA_LENGTH) on success | ||
269 | * returns -1 on failure | ||
270 | */ | ||
271 | int tox_pass_decrypt(const uint8_t *data, uint32_t length, uint8_t *passphrase, uint32_t pplength, uint8_t *out) | ||
272 | { | ||
273 | uint8_t passkey[crypto_hash_sha256_BYTES]; | ||
274 | crypto_hash_sha256(passkey, passphrase, pplength); | ||
275 | |||
276 | uint8_t salt[crypto_pwhash_scryptsalsa208sha256_SALTBYTES]; | ||
277 | memcpy(salt, data + TOX_ENC_SAVE_MAGIC_LENGTH, crypto_pwhash_scryptsalsa208sha256_SALTBYTES); | ||
278 | |||
279 | /* derive the key */ | ||
280 | uint8_t key[crypto_box_KEYBYTES + crypto_pwhash_scryptsalsa208sha256_SALTBYTES]; | ||
281 | |||
282 | if (crypto_pwhash_scryptsalsa208sha256( | ||
283 | key + crypto_pwhash_scryptsalsa208sha256_SALTBYTES, | ||
284 | crypto_box_KEYBYTES, (char *)passkey, sizeof(passkey), salt, | ||
285 | crypto_pwhash_scryptsalsa208sha256_OPSLIMIT_INTERACTIVE * 2, /* slightly stronger */ | ||
286 | crypto_pwhash_scryptsalsa208sha256_MEMLIMIT_INTERACTIVE) != 0) { | ||
287 | /* out of memory most likely */ | ||
288 | return -1; | ||
289 | } | ||
290 | |||
291 | sodium_memzero(passkey, crypto_hash_sha256_BYTES); /* wipe plaintext pw */ | ||
292 | |||
293 | return tox_pass_key_decrypt(data, length, key, out); | ||
294 | } | ||
295 | |||
296 | /* Load the messenger from encrypted data of size length. | ||
297 | * | ||
298 | * returns 0 on success | ||
299 | * returns -1 on failure | ||
300 | */ | ||
301 | int tox_encrypted_load(Tox *tox, const uint8_t *data, uint32_t length, uint8_t *passphrase, uint32_t pplength) | ||
302 | { | ||
303 | uint32_t decrypt_length = length - TOX_PASS_ENCRYPTION_EXTRA_LENGTH; | ||
304 | uint8_t temp_data[decrypt_length]; | ||
305 | |||
306 | if (tox_pass_decrypt(data, length, passphrase, pplength, temp_data) | ||
307 | != decrypt_length) | ||
308 | return -1; | ||
309 | |||
310 | return tox_load(tox, temp_data, decrypt_length); | ||
311 | } | ||
312 | |||
313 | /* Load the messenger from encrypted data of size length, with key from tox_derive_key. | ||
314 | * | ||
315 | * returns 0 on success | ||
316 | * returns -1 on failure | ||
317 | */ | ||
318 | int tox_encrypted_key_load(Tox *tox, const uint8_t *data, uint32_t length, uint8_t *key) | ||
319 | { | ||
320 | uint32_t decrypt_length = length - TOX_PASS_ENCRYPTION_EXTRA_LENGTH; | ||
321 | uint8_t temp_data[decrypt_length]; | ||
322 | |||
323 | if (tox_pass_key_decrypt(data, length, key, temp_data) | ||
324 | != decrypt_length) | ||
325 | return -1; | ||
326 | |||
327 | return tox_load(tox, temp_data, decrypt_length); | ||
328 | } | ||
329 | |||
330 | /* Determines whether or not the given data is encrypted (by checking the magic number) | ||
331 | * | ||
332 | * returns 1 if it is encrypted | ||
333 | * returns 0 otherwise | ||
334 | */ | ||
335 | int tox_is_data_encrypted(const uint8_t *data) | ||
336 | { | ||
337 | if (memcmp(data, TOX_ENC_SAVE_MAGIC_NUMBER, TOX_ENC_SAVE_MAGIC_LENGTH) == 0) | ||
338 | return 1; | ||
339 | else | ||
340 | return 0; | ||
341 | } | ||
342 | |||
343 | int tox_is_save_encrypted(const uint8_t *data) | ||
344 | { | ||
345 | return tox_is_data_encrypted(data); | ||
346 | } | ||
diff --git a/toxencryptsave/toxencryptsave.h b/toxencryptsave/toxencryptsave.h new file mode 100644 index 00000000..da13f312 --- /dev/null +++ b/toxencryptsave/toxencryptsave.h | |||
@@ -0,0 +1,196 @@ | |||
1 | /* toxencryptsave.h | ||
2 | * | ||
3 | * The Tox encrypted save functions. | ||
4 | * | ||
5 | * Copyright (C) 2013 Tox project All Rights Reserved. | ||
6 | * | ||
7 | * This file is part of Tox. | ||
8 | * | ||
9 | * Tox is free software: you can redistribute it and/or modify | ||
10 | * it under the terms of the GNU General Public License as published by | ||
11 | * the Free Software Foundation, either version 3 of the License, or | ||
12 | * (at your option) any later version. | ||
13 | * | ||
14 | * Tox is distributed in the hope that it will be useful, | ||
15 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
16 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
17 | * GNU General Public License for more details. | ||
18 | * | ||
19 | * You should have received a copy of the GNU General Public License | ||
20 | * along with Tox. If not, see <http://www.gnu.org/licenses/>. | ||
21 | * | ||
22 | */ | ||
23 | |||
24 | #ifndef TOXENCRYPTSAVE_H | ||
25 | #define TOXENCRYPTSAVE_H | ||
26 | |||
27 | #ifdef __cplusplus | ||
28 | extern "C" { | ||
29 | #endif | ||
30 | |||
31 | #include <stdint.h> | ||
32 | |||
33 | #ifndef TOX_DEFINED | ||
34 | #define TOX_DEFINED | ||
35 | typedef struct Tox Tox; | ||
36 | #endif | ||
37 | |||
38 | // these functions provide access to these defines in toxencryptsave.c, which | ||
39 | // otherwise aren't actually available in clients... | ||
40 | int tox_pass_encryption_extra_length(); | ||
41 | |||
42 | int tox_pass_key_length(); | ||
43 | |||
44 | int tox_pass_salt_length(); | ||
45 | |||
46 | /* return size of the messenger data (for encrypted Messenger saving). */ | ||
47 | uint32_t tox_encrypted_size(const Tox *tox); | ||
48 | |||
49 | /* This "module" provides functions analogous to tox_load and tox_save in toxcore, | ||
50 | * as well as functions for encryption of arbitrary client data (e.g. chat logs). | ||
51 | * | ||
52 | * It is conceptually organized into two parts. The first part are the functions | ||
53 | * with "key" in the name. To use these functions, first derive an encryption key | ||
54 | * from a password with tox_derive_key_from_pass, and use the returned key to | ||
55 | * encrypt the data. The second part takes the password itself instead of the key, | ||
56 | * and then delegates to the first part to derive the key before de/encryption, | ||
57 | * which can simplify client code; however, key derivation is very expensive | ||
58 | * compared to the actual encryption, so clients that do a lot of encryption should | ||
59 | * favor using the first part intead of the second part. | ||
60 | * | ||
61 | * The encrypted data is prepended with a magic number, to aid validity checking | ||
62 | * (no guarantees are made of course). | ||
63 | * | ||
64 | * Clients should consider alerting their users that, unlike plain data, if even one bit | ||
65 | * becomes corrupted, the data will be entirely unrecoverable. | ||
66 | * Ditto if they forget their password, there is no way to recover the data. | ||
67 | */ | ||
68 | |||
69 | |||
70 | /******************************* BEGIN PART 2 ******************************* | ||
71 | * For simplicty, the second part of the module is presented first. The API for | ||
72 | * the first part is analgous, with some extra functions for key handling. If | ||
73 | * your code spends too much time using these functions, consider using the part | ||
74 | * 1 functions instead. | ||
75 | */ | ||
76 | |||
77 | /* Encrypts the given data with the given passphrase. The output array must be | ||
78 | * at least data_len + tox_pass_encryption_extra_length() bytes long. This delegates | ||
79 | * to tox_derive_key_from_pass and tox_pass_key_encrypt. | ||
80 | * | ||
81 | * tox_encrypted_save() is a good example of how to use this function. | ||
82 | * | ||
83 | * returns 0 on success | ||
84 | * returns -1 on failure | ||
85 | */ | ||
86 | int tox_pass_encrypt(const uint8_t *data, uint32_t data_len, uint8_t *passphrase, uint32_t pplength, uint8_t *out); | ||
87 | |||
88 | /* Save the messenger data encrypted with the given password. | ||
89 | * data must be at least tox_encrypted_size(). | ||
90 | * | ||
91 | * returns 0 on success | ||
92 | * returns -1 on failure | ||
93 | */ | ||
94 | int tox_encrypted_save(const Tox *tox, uint8_t *data, uint8_t *passphrase, uint32_t pplength); | ||
95 | |||
96 | /* Decrypts the given data with the given passphrase. The output array must be | ||
97 | * at least data_len - tox_pass_encryption_extra_length() bytes long. This delegates | ||
98 | * to tox_pass_key_decrypt. | ||
99 | * | ||
100 | * tox_encrypted_load() is a good example of how to use this function. | ||
101 | * | ||
102 | * returns the length of the output data (== data_len - tox_pass_encryption_extra_length()) on success | ||
103 | * returns -1 on failure | ||
104 | */ | ||
105 | int tox_pass_decrypt(const uint8_t *data, uint32_t length, uint8_t *passphrase, uint32_t pplength, uint8_t *out); | ||
106 | |||
107 | /* Load the messenger from encrypted data of size length. | ||
108 | * | ||
109 | * returns 0 on success | ||
110 | * returns -1 on failure | ||
111 | */ | ||
112 | int tox_encrypted_load(Tox *tox, const uint8_t *data, uint32_t length, uint8_t *passphrase, uint32_t pplength); | ||
113 | |||
114 | |||
115 | /******************************* BEGIN PART 1 ******************************* | ||
116 | * And now part "1", which does the actual encryption, and is rather less cpu | ||
117 | * intensive than part one. The first 3 functions are for key handling. | ||
118 | */ | ||
119 | |||
120 | /* Generates a secret symmetric key from the given passphrase. out_key must be at least | ||
121 | * tox_pass_key_length() bytes long. | ||
122 | * Be sure to not compromise the key! Only keep it in memory, do not write to disk. | ||
123 | * The password is zeroed after key derivation. | ||
124 | * The key should only be used with the other functions in this module, as it | ||
125 | * includes a salt. | ||
126 | * Note that this function is not deterministic; to derive the same key from a | ||
127 | * password, you also must know the random salt that was used. See below. | ||
128 | * | ||
129 | * returns 0 on success | ||
130 | * returns -1 on failure | ||
131 | */ | ||
132 | int tox_derive_key_from_pass(uint8_t *passphrase, uint32_t pplength, uint8_t *out_key); | ||
133 | |||
134 | /* Same as above, except with use the given salt for deterministic key derivation. | ||
135 | * The salt must be tox_salt_length() bytes in length. | ||
136 | */ | ||
137 | int tox_derive_key_with_salt(uint8_t *passphrase, uint32_t pplength, uint8_t *salt, uint8_t *out_key); | ||
138 | |||
139 | /* This retrieves the salt used to encrypt the given data, which can then be passed to | ||
140 | * derive_key_with_salt to produce the same key as was previously used. Any encrpyted | ||
141 | * data with this module can be used as input. | ||
142 | * | ||
143 | * returns -1 if the magic number is wrong | ||
144 | * returns 0 otherwise (no guarantee about validity of data) | ||
145 | */ | ||
146 | int tox_get_salt(uint8_t *data, uint8_t *salt); | ||
147 | |||
148 | /* Now come the functions that are analogous to the part 2 functions. */ | ||
149 | |||
150 | /* Encrypt arbitrary with a key produced by tox_derive_key_. The output | ||
151 | * array must be at least data_len + tox_pass_encryption_extra_length() bytes long. | ||
152 | * key must be tox_pass_key_length() bytes. | ||
153 | * If you already have a symmetric key from somewhere besides this module, simply | ||
154 | * call encrypt_data_symmetric in toxcore/crypto_core directly. | ||
155 | * | ||
156 | * returns 0 on success | ||
157 | * returns -1 on failure | ||
158 | */ | ||
159 | int tox_pass_key_encrypt(const uint8_t *data, uint32_t data_len, const uint8_t *key, uint8_t *out); | ||
160 | |||
161 | /* Save the messenger data encrypted with the given key from tox_derive_key. | ||
162 | * data must be at least tox_encrypted_size(). | ||
163 | * | ||
164 | * returns 0 on success | ||
165 | * returns -1 on failure | ||
166 | */ | ||
167 | int tox_encrypted_key_save(const Tox *tox, uint8_t *data, uint8_t *key); | ||
168 | |||
169 | /* This is the inverse of tox_pass_key_encrypt, also using only keys produced by | ||
170 | * tox_derive_key_from_pass. | ||
171 | * | ||
172 | * returns the length of the output data (== data_len - tox_pass_encryption_extra_length()) on success | ||
173 | * returns -1 on failure | ||
174 | */ | ||
175 | int tox_pass_key_decrypt(const uint8_t *data, uint32_t length, const uint8_t *key, uint8_t *out); | ||
176 | |||
177 | /* Load the messenger from encrypted data of size length, with key from tox_derive_key. | ||
178 | * | ||
179 | * returns 0 on success | ||
180 | * returns -1 on failure | ||
181 | */ | ||
182 | int tox_encrypted_key_load(Tox *tox, const uint8_t *data, uint32_t length, uint8_t *key); | ||
183 | |||
184 | /* Determines whether or not the given data is encrypted (by checking the magic number) | ||
185 | * | ||
186 | * returns 1 if it is encrypted | ||
187 | * returns 0 otherwise | ||
188 | */ | ||
189 | int tox_is_data_encrypted(const uint8_t *data); | ||
190 | int tox_is_save_encrypted(const uint8_t *data); // poorly-named alias for backwards compat (oh irony...) | ||
191 | |||
192 | #ifdef __cplusplus | ||
193 | } | ||
194 | #endif | ||
195 | |||
196 | #endif | ||