summaryrefslogtreecommitdiff
path: root/toxencryptsave
diff options
context:
space:
mode:
Diffstat (limited to 'toxencryptsave')
-rw-r--r--toxencryptsave/Makefile.inc45
-rw-r--r--toxencryptsave/crypto_pwhash_scryptsalsa208sha256/crypto_pwhash_scryptsalsa208sha256.h92
-rw-r--r--toxencryptsave/crypto_pwhash_scryptsalsa208sha256/crypto_scrypt-common.c257
-rw-r--r--toxencryptsave/crypto_pwhash_scryptsalsa208sha256/crypto_scrypt.h93
-rw-r--r--toxencryptsave/crypto_pwhash_scryptsalsa208sha256/export.h38
-rw-r--r--toxencryptsave/crypto_pwhash_scryptsalsa208sha256/nosse/pwhash_scryptsalsa208sha256_nosse.c309
-rw-r--r--toxencryptsave/crypto_pwhash_scryptsalsa208sha256/note_to_maintainers.txt14
-rw-r--r--toxencryptsave/crypto_pwhash_scryptsalsa208sha256/pbkdf2-sha256.c97
-rw-r--r--toxencryptsave/crypto_pwhash_scryptsalsa208sha256/pbkdf2-sha256.h52
-rw-r--r--toxencryptsave/crypto_pwhash_scryptsalsa208sha256/pwhash_scryptsalsa208sha256.c211
-rw-r--r--toxencryptsave/crypto_pwhash_scryptsalsa208sha256/runtime.c140
-rw-r--r--toxencryptsave/crypto_pwhash_scryptsalsa208sha256/runtime.h33
-rw-r--r--toxencryptsave/crypto_pwhash_scryptsalsa208sha256/scrypt_platform.c107
-rw-r--r--toxencryptsave/crypto_pwhash_scryptsalsa208sha256/sse/pwhash_scryptsalsa208sha256_sse.c398
-rw-r--r--toxencryptsave/crypto_pwhash_scryptsalsa208sha256/sysendian.h153
-rw-r--r--toxencryptsave/crypto_pwhash_scryptsalsa208sha256/utils.c78
-rw-r--r--toxencryptsave/crypto_pwhash_scryptsalsa208sha256/utils.h40
-rw-r--r--toxencryptsave/defines.h2
-rw-r--r--toxencryptsave/toxencryptsave.c346
-rw-r--r--toxencryptsave/toxencryptsave.h196
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 @@
1lib_LTLIBRARIES += libtoxencryptsave.la
2
3libtoxencryptsave_la_include_HEADERS = \
4 ../toxencryptsave/toxencryptsave.h
5
6libtoxencryptsave_la_includedir = $(includedir)/tox
7
8libtoxencryptsave_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
27libtoxencryptsave_la_CFLAGS = -I$(top_srcdir) \
28 -I$(top_srcdir)/toxcore \
29 $(LIBSODIUM_CFLAGS) \
30 $(NACL_CFLAGS) \
31 $(PTHREAD_CFLAGS)
32
33libtoxencryptsave_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
41libtoxencryptsave_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
18extern "C" {
19#endif
20
21#define crypto_pwhash_scryptsalsa208sha256_SALTBYTES 32U
22SODIUM_EXPORT
23size_t crypto_pwhash_scryptsalsa208sha256_saltbytes(void);
24
25#define crypto_pwhash_scryptsalsa208sha256_STRBYTES 102U
26SODIUM_EXPORT
27size_t crypto_pwhash_scryptsalsa208sha256_strbytes(void);
28
29#define crypto_pwhash_scryptsalsa208sha256_STRPREFIX "$7$"
30SODIUM_EXPORT
31const char *crypto_pwhash_scryptsalsa208sha256_strprefix(void);
32
33#define crypto_pwhash_scryptsalsa208sha256_OPSLIMIT_INTERACTIVE 524288ULL
34SODIUM_EXPORT
35size_t crypto_pwhash_scryptsalsa208sha256_opslimit_interactive(void);
36
37#define crypto_pwhash_scryptsalsa208sha256_MEMLIMIT_INTERACTIVE 16777216ULL
38SODIUM_EXPORT
39size_t crypto_pwhash_scryptsalsa208sha256_memlimit_interactive(void);
40
41#define crypto_pwhash_scryptsalsa208sha256_OPSLIMIT_SENSITIVE 33554432ULL
42SODIUM_EXPORT
43size_t crypto_pwhash_scryptsalsa208sha256_opslimit_sensitive(void);
44
45#define crypto_pwhash_scryptsalsa208sha256_MEMLIMIT_SENSITIVE 1073741824ULL
46SODIUM_EXPORT
47size_t crypto_pwhash_scryptsalsa208sha256_memlimit_sensitive(void);
48
49SODIUM_EXPORT
50int 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
58SODIUM_EXPORT
59int 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
65SODIUM_EXPORT
66int crypto_pwhash_scryptsalsa208sha256_str_verify(const char str[crypto_pwhash_scryptsalsa208sha256_STRBYTES],
67 const char * const passwd,
68 unsigned long long passwdlen);
69
70SODIUM_EXPORT
71int 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
34static const char * const itoa64 =
35 "./0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
36
37static uint8_t *
38encode64_uint32(uint8_t * dst, size_t dstlen, uint32_t src, uint32_t srcbits)
39{
40 uint32_t bit;
41
42 for (bit = 0; bit < srcbits; bit += 6) {
43 if (dstlen < 1) {
44 return NULL;
45 }
46 *dst++ = itoa64[src & 0x3f];
47 dstlen--;
48 src >>= 6;
49 }
50
51 return dst;
52}
53
54static uint8_t *
55encode64(uint8_t * dst, size_t dstlen, const uint8_t * src, size_t srclen)
56{
57 size_t i;
58
59 for (i = 0; i < srclen; ) {
60 uint8_t * dnext;
61 uint32_t value = 0, bits = 0;
62 do {
63 value |= (uint32_t)src[i++] << bits;
64 bits += 8;
65 } while (bits < 24 && i < srclen);
66 dnext = encode64_uint32(dst, dstlen, value, bits);
67 if (!dnext) {
68 return NULL;
69 }
70 dstlen -= dnext - dst;
71 dst = dnext;
72 }
73
74 return dst;
75}
76
77static int
78decode64_one(uint32_t * dst, uint8_t src)
79{
80 const char *ptr = strchr(itoa64, src);
81
82 if (ptr) {
83 *dst = ptr - itoa64;
84 return 0;
85 }
86 *dst = 0;
87 return -1;
88}
89
90static const uint8_t *
91decode64_uint32(uint32_t * dst, uint32_t dstbits, const uint8_t * src)
92{
93 uint32_t bit;
94 uint32_t value;
95
96 value = 0;
97 for (bit = 0; bit < dstbits; bit += 6) {
98 uint32_t one;
99 if (decode64_one(&one, *src)) {
100 *dst = 0;
101 return NULL;
102 }
103 src++;
104 value |= one << bit;
105 }
106
107 *dst = value;
108 return src;
109}
110
111uint8_t *
112escrypt_r(escrypt_local_t * local, const uint8_t * passwd, size_t passwdlen,
113 const uint8_t * setting, uint8_t * buf, size_t buflen)
114{
115 uint8_t hash[crypto_pwhash_scryptsalsa208sha256_STRHASHBYTES];
116 escrypt_kdf_t escrypt_kdf;
117 const uint8_t *src;
118 const uint8_t *salt;
119 uint8_t *dst;
120 size_t prefixlen;
121 size_t saltlen;
122 size_t need;
123 uint64_t N;
124 uint32_t N_log2;
125 uint32_t r;
126 uint32_t p;
127
128 if (setting[0] != '$' || setting[1] != '7' || setting[2] != '$') {
129 return NULL;
130 }
131 src = setting + 3;
132
133 if (decode64_one(&N_log2, *src)) {
134 return NULL;
135 }
136 src++;
137 N = (uint64_t)1 << N_log2;
138
139 src = decode64_uint32(&r, 30, src);
140 if (!src) {
141 return NULL;
142 }
143 src = decode64_uint32(&p, 30, src);
144 if (!src) {
145 return NULL;
146 }
147 prefixlen = src - setting;
148
149 salt = src;
150 src = (uint8_t *) strrchr((char *)salt, '$');
151 if (src) {
152 saltlen = src - salt;
153 } else {
154 saltlen = strlen((char *)salt);
155 }
156 need = prefixlen + saltlen + 1 +
157 crypto_pwhash_scryptsalsa208sha256_STRHASHBYTES_ENCODED + 1;
158 if (need > buflen || need < saltlen) {
159 return NULL;
160 }
161#if defined(HAVE_EMMINTRIN_H) || defined(_MSC_VER)
162 escrypt_kdf =
163 sodium_runtime_has_sse2() ? escrypt_kdf_sse : escrypt_kdf_nosse;
164#else
165 escrypt_kdf = escrypt_kdf_nosse;
166#endif
167 if (escrypt_kdf(local, passwd, passwdlen, salt, saltlen,
168 N, r, p, hash, sizeof(hash))) {
169 return NULL;
170 }
171
172 dst = buf;
173 memcpy(dst, setting, prefixlen + saltlen);
174 dst += prefixlen + saltlen;
175 *dst++ = '$';
176
177 dst = encode64(dst, buflen - (dst - buf), hash, sizeof(hash));
178 sodium_memzero(hash, sizeof hash);
179 if (!dst || dst >= buf + buflen) { /* Can't happen */
180 return NULL;
181 }
182 *dst = 0; /* NUL termination */
183
184 return buf;
185}
186
187uint8_t *
188escrypt_gensalt_r(uint32_t N_log2, uint32_t r, uint32_t p,
189 const uint8_t * src, size_t srclen,
190 uint8_t * buf, size_t buflen)
191{
192 uint8_t *dst;
193 size_t prefixlen =
194 (sizeof "$7$" - 1U) + (1U /* N_log2 */) + (5U /* r */) + (5U /* p */);
195 size_t saltlen = BYTES2CHARS(srclen);
196 size_t need;
197
198 need = prefixlen + saltlen + 1;
199 if (need > buflen || need < saltlen || saltlen < srclen) {
200 return NULL;
201 }
202 if (N_log2 > 63 || ((uint64_t)r * (uint64_t)p >= (1U << 30))) {
203 return NULL;
204 }
205 dst = buf;
206 *dst++ = '$';
207 *dst++ = '7';
208 *dst++ = '$';
209
210 *dst++ = itoa64[N_log2];
211
212 dst = encode64_uint32(dst, buflen - (dst - buf), r, 30);
213 if (!dst) { /* Can't happen */
214 return NULL;
215 }
216 dst = encode64_uint32(dst, buflen - (dst - buf), p, 30);
217 if (!dst) { /* Can't happen */
218 return NULL;
219 }
220 dst = encode64(dst, buflen - (dst - buf), src, srclen);
221 if (!dst || dst >= buf + buflen) { /* Can't happen */
222 return NULL;
223 }
224 *dst = 0; /* NUL termination */
225
226 return buf;
227}
228
229int
230crypto_pwhash_scryptsalsa208sha256_ll(const uint8_t * passwd, size_t passwdlen,
231 const uint8_t * salt, size_t saltlen,
232 uint64_t N, uint32_t r, uint32_t p,
233 uint8_t * buf, size_t buflen)
234{
235 escrypt_kdf_t escrypt_kdf;
236 escrypt_local_t local;
237 int retval;
238
239 if (escrypt_init_local(&local)) {
240 return -1;
241 }
242#if defined(HAVE_EMMINTRIN_H) || defined(_MSC_VER)
243 escrypt_kdf =
244 sodium_runtime_has_sse2() ? escrypt_kdf_sse : escrypt_kdf_nosse;
245#else
246 escrypt_kdf = escrypt_kdf_nosse;
247#endif
248 retval = escrypt_kdf(&local,
249 passwd, passwdlen, salt, saltlen,
250 N, r, p, buf, buflen);
251 if (escrypt_free_local(&local)) {
252 return -1;
253 }
254 return retval;
255}
256
257#endif
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
49typedef struct {
50 void * base, * aligned;
51 size_t size;
52} escrypt_region_t;
53
54typedef escrypt_region_t escrypt_local_t;
55
56extern int escrypt_init_local(escrypt_local_t * __local);
57
58extern int escrypt_free_local(escrypt_local_t * __local);
59
60extern void *alloc_region(escrypt_region_t * region, size_t size);
61extern int free_region(escrypt_region_t * region);
62
63typedef 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
69extern 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
75extern 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
81extern 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
86extern 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
46static inline void
47blkcpy(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
58static inline void
59blkxor(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 */
74static void
75salsa20_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 */
120static void
121blockmix_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 */
152static inline uint64_t
153integerify(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 */
168static void
169smix(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 */
228int
229escrypt_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 @@
1This folder is only meant for use with nacl, i.e. when sodium is unavailable.
2
3
4The files in this folder were mostly copied from
5https://github.com/jedisct1/libsodium/tree/0.7.0/src/libsodium/crypto_pwhash/scryptsalsa208sha256,
6with #ifdef VANILLA_NACL added around each of them as required for this module.
7
8export.h, utils.h, and runtime.h were copied from
9https://github.com/jedisct1/libsodium/tree/0.7.0/src/libsodium/include/sodium.
10utils.h was significantly truncated.
11
12utils.c and runtime.c were copied from
13https://github.com/jedisct1/libsodium/blob/0.7.0/src/libsodium/sodium.
14utils.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 */
50void
51PBKDF2_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 */
47void 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
22static int
23pickparams(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
57size_t
58crypto_pwhash_scryptsalsa208sha256_saltbytes(void)
59{
60 return crypto_pwhash_scryptsalsa208sha256_SALTBYTES;
61}
62
63size_t
64crypto_pwhash_scryptsalsa208sha256_strbytes(void)
65{
66 return crypto_pwhash_scryptsalsa208sha256_STRBYTES;
67}
68
69const char *
70crypto_pwhash_scryptsalsa208sha256_strprefix(void)
71{
72 return crypto_pwhash_scryptsalsa208sha256_STRPREFIX;
73}
74
75size_t
76crypto_pwhash_scryptsalsa208sha256_opslimit_interactive(void)
77{
78 return crypto_pwhash_scryptsalsa208sha256_OPSLIMIT_INTERACTIVE;
79}
80
81size_t
82crypto_pwhash_scryptsalsa208sha256_memlimit_interactive(void)
83{
84 return crypto_pwhash_scryptsalsa208sha256_MEMLIMIT_INTERACTIVE;
85}
86
87size_t
88crypto_pwhash_scryptsalsa208sha256_opslimit_sensitive(void)
89{
90 return crypto_pwhash_scryptsalsa208sha256_OPSLIMIT_SENSITIVE;
91}
92
93size_t
94crypto_pwhash_scryptsalsa208sha256_memlimit_sensitive(void)
95{
96 return crypto_pwhash_scryptsalsa208sha256_MEMLIMIT_SENSITIVE;
97}
98
99int
100crypto_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
130int
131crypto_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
182int
183crypto_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
12typedef struct CPUFeatures_ {
13 int initialized;
14 int has_neon;
15 int has_sse2;
16 int has_sse3;
17} CPUFeatures;
18
19static CPUFeatures _cpu_features;
20
21#define CPUID_SSE2 0x04000000
22#define CPUIDECX_SSE3 0x00000001
23
24static 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
47static 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
87static 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
113int
114sodium_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
125int
126sodium_runtime_has_neon(void) {
127 return _cpu_features.has_neon;
128}
129
130int
131sodium_runtime_has_sse2(void) {
132 return _cpu_features.has_sse2;
133}
134
135int
136sodium_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
12extern "C" {
13#endif
14
15SODIUM_EXPORT
16int sodium_runtime_get_cpu_features(void);
17
18SODIUM_EXPORT
19int sodium_runtime_has_neon(void);
20
21SODIUM_EXPORT
22int sodium_runtime_has_sse2(void);
23
24SODIUM_EXPORT
25int 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
39void *
40alloc_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
72static inline void
73init_region(escrypt_region_t * region)
74{
75 region->base = region->aligned = NULL;
76 region->size = 0;
77}
78
79int
80free_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
94int
95escrypt_init_local(escrypt_local_t * local)
96{
97 init_region(local);
98 return 0;
99}
100
101int
102escrypt_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 */
114static inline void
115blockmix_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
165static inline uint32_t
166blockmix_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 */
218static inline uint32_t
219integerify(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 */
232static void
233smix(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 */
312int
313escrypt_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
25static inline uint16_t
26be16dec(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
33static inline void
34be16enc(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
42static inline uint32_t
43be32dec(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
51static inline void
52be32enc(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
62static inline uint64_t
63be64dec(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
73static inline void
74be64enc(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
88static inline uint16_t
89le16dec(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
96static inline void
97le16enc(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
105static inline uint32_t
106le32dec(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
114static inline void
115le32enc(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
125static inline uint64_t
126le64dec(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
136static inline void
137le64enc(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
40void
41sodium_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
64int
65sodium_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
14extern "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
23SODIUM_EXPORT
24void 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 */
31SODIUM_EXPORT
32int 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
44int tox_pass_encryption_extra_length()
45{
46 return TOX_PASS_ENCRYPTION_EXTRA_LENGTH;
47}
48
49int tox_pass_key_length()
50{
51 return TOX_PASS_KEY_LENGTH;
52}
53
54int 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). */
66uint32_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 */
78int 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 */
100int 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 */
110int 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 */
148int 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 */
188int 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 */
204int 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 */
221int 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 */
238int 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 */
271int 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 */
301int 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 */
318int 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 */
335int 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
343int 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
28extern "C" {
29#endif
30
31#include <stdint.h>
32
33#ifndef TOX_DEFINED
34#define TOX_DEFINED
35typedef 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...
40int tox_pass_encryption_extra_length();
41
42int tox_pass_key_length();
43
44int tox_pass_salt_length();
45
46/* return size of the messenger data (for encrypted Messenger saving). */
47uint32_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 */
86int 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 */
94int 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 */
105int 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 */
112int 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 */
132int 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 */
137int 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 */
146int 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 */
159int 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 */
167int 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 */
175int 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 */
182int 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 */
189int tox_is_data_encrypted(const uint8_t *data);
190int 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