summaryrefslogtreecommitdiff
path: root/toxencryptsave
diff options
context:
space:
mode:
authorirungentoo <irungentoo@gmail.com>2014-09-13 21:29:33 -0400
committerirungentoo <irungentoo@gmail.com>2014-09-13 21:29:33 -0400
commitcbb526e83fcb0a1dd73228c8765ef29491caff2a (patch)
tree768dc51ba8057ccf806130fc5cdab1d6548a73a6 /toxencryptsave
parented7bed6b59134b074db1586866cb1ef57ce1ba54 (diff)
parenteb58cdc9645e2209d2e6597732aa238953f7df9b (diff)
Merge branch 'encrypted_data' of https://github.com/dubslow/toxcore
Diffstat (limited to 'toxencryptsave')
-rw-r--r--toxencryptsave/Makefile.inc49
-rw-r--r--toxencryptsave/crypto_pwhash_scryptsalsa208sha256/crypto_auth_hmacsha256.h65
-rw-r--r--toxencryptsave/crypto_pwhash_scryptsalsa208sha256/crypto_hash_sha256.h61
-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/hash_sha256.c300
-rw-r--r--toxencryptsave/crypto_pwhash_scryptsalsa208sha256/hmac_hmacsha256.c115
-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.c91
-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/toxencryptsave.c174
-rw-r--r--toxencryptsave/toxencryptsave.h68
23 files changed, 2938 insertions, 0 deletions
diff --git a/toxencryptsave/Makefile.inc b/toxencryptsave/Makefile.inc
new file mode 100644
index 00000000..b4f06c90
--- /dev/null
+++ b/toxencryptsave/Makefile.inc
@@ -0,0 +1,49 @@
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/crypto_pwhash_scryptsalsa208sha256/hmac_hmacsha256.c \
24 ../toxencryptsave/crypto_pwhash_scryptsalsa208sha256/crypto_auth_hmacsha256.h \
25 ../toxencryptsave/crypto_pwhash_scryptsalsa208sha256/crypto_hash_sha256.h \
26 ../toxencryptsave/crypto_pwhash_scryptsalsa208sha256/hash_sha256.c \
27 ../toxencryptsave/toxencryptsave.h \
28 ../toxencryptsave/toxencryptsave.c
29
30
31libtoxencryptsave_la_CFLAGS = -I$(top_srcdir) \
32 -I$(top_srcdir)/toxcore \
33 $(LIBSODIUM_CFLAGS) \
34 $(NACL_CFLAGS) \
35 $(PTHREAD_CFLAGS)
36
37libtoxencryptsave_la_LDFLAGS = $(TOXCORE_LT_LDFLAGS) \
38 $(EXTRA_LT_LDFLAGS) \
39 $(LIBSODIUM_LDFLAGS) \
40 $(NACL_LDFLAGS) \
41 $(MATH_LDFLAGS) \
42 $(RT_LIBS) \
43 $(WINSOCK2_LIBS)
44
45libtoxencryptsave_la_LIBADD = $(LIBSODIUM_LIBS) \
46 $(NACL_OBJECTS) \
47 $(NAC_LIBS) \
48 $(PTHREAD_LIBS) \
49 libtoxcore.la
diff --git a/toxencryptsave/crypto_pwhash_scryptsalsa208sha256/crypto_auth_hmacsha256.h b/toxencryptsave/crypto_pwhash_scryptsalsa208sha256/crypto_auth_hmacsha256.h
new file mode 100644
index 00000000..994c0942
--- /dev/null
+++ b/toxencryptsave/crypto_pwhash_scryptsalsa208sha256/crypto_auth_hmacsha256.h
@@ -0,0 +1,65 @@
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_auth_hmacsha256_H
7#define crypto_auth_hmacsha256_H
8
9#include <stddef.h>
10#include "crypto_hash_sha256.h"
11#include "export.h"
12
13#ifdef __cplusplus
14# if __GNUC__
15# pragma GCC diagnostic ignored "-Wlong-long"
16# endif
17extern "C" {
18#endif
19
20typedef struct crypto_auth_hmacsha256_state {
21 crypto_hash_sha256_state ictx;
22 crypto_hash_sha256_state octx;
23} crypto_auth_hmacsha256_state;
24
25#define crypto_auth_hmacsha256_BYTES 32U
26SODIUM_EXPORT
27size_t crypto_auth_hmacsha256_bytes(void);
28
29#define crypto_auth_hmacsha256_KEYBYTES 32U
30SODIUM_EXPORT
31size_t crypto_auth_hmacsha256_keybytes(void);
32
33SODIUM_EXPORT
34int crypto_auth_hmacsha256(unsigned char *out,
35 const unsigned char *in,
36 unsigned long long inlen,
37 const unsigned char *k);
38
39SODIUM_EXPORT
40int crypto_auth_hmacsha256_verify(const unsigned char *h,
41 const unsigned char *in,
42 unsigned long long inlen,
43 const unsigned char *k);
44
45SODIUM_EXPORT
46int crypto_auth_hmacsha256_init(crypto_auth_hmacsha256_state *state,
47 const unsigned char *key,
48 size_t keylen);
49
50SODIUM_EXPORT
51int crypto_auth_hmacsha256_update(crypto_auth_hmacsha256_state *state,
52 const unsigned char *in,
53 unsigned long long inlen);
54
55SODIUM_EXPORT
56int crypto_auth_hmacsha256_final(crypto_auth_hmacsha256_state *state,
57 unsigned char *out);
58
59#ifdef __cplusplus
60}
61#endif
62
63#endif
64
65#endif
diff --git a/toxencryptsave/crypto_pwhash_scryptsalsa208sha256/crypto_hash_sha256.h b/toxencryptsave/crypto_pwhash_scryptsalsa208sha256/crypto_hash_sha256.h
new file mode 100644
index 00000000..cc6e3df1
--- /dev/null
+++ b/toxencryptsave/crypto_pwhash_scryptsalsa208sha256/crypto_hash_sha256.h
@@ -0,0 +1,61 @@
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_hash_sha256_H
7#define crypto_hash_sha256_H
8
9/*
10 * WARNING: Unless you absolutely need to use SHA256 for interoperatibility,
11 * purposes, you might want to consider crypto_generichash() instead.
12 * Unlike SHA256, crypto_generichash() is not vulnerable to length
13 * extension attacks.
14 */
15
16#include <stddef.h>
17#include <stdint.h>
18#include <stdlib.h>
19
20#include "export.h"
21
22#ifdef __cplusplus
23# if __GNUC__
24# pragma GCC diagnostic ignored "-Wlong-long"
25# endif
26extern "C" {
27#endif
28
29typedef struct crypto_hash_sha256_state {
30 uint32_t state[8];
31 uint32_t count[2];
32 unsigned char buf[64];
33} crypto_hash_sha256_state;
34
35#define crypto_hash_sha256_BYTES 32U
36SODIUM_EXPORT
37size_t crypto_hash_sha256_bytes(void);
38
39SODIUM_EXPORT
40int crypto_hash_sha256(unsigned char *out, const unsigned char *in,
41 unsigned long long inlen);
42
43SODIUM_EXPORT
44int crypto_hash_sha256_init(crypto_hash_sha256_state *state);
45
46SODIUM_EXPORT
47int crypto_hash_sha256_update(crypto_hash_sha256_state *state,
48 const unsigned char *in,
49 unsigned long long inlen);
50
51SODIUM_EXPORT
52int crypto_hash_sha256_final(crypto_hash_sha256_state *state,
53 unsigned char *out);
54
55#ifdef __cplusplus
56}
57#endif
58
59#endif
60
61#endif
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/hash_sha256.c b/toxencryptsave/crypto_pwhash_scryptsalsa208sha256/hash_sha256.c
new file mode 100644
index 00000000..2fddc126
--- /dev/null
+++ b/toxencryptsave/crypto_pwhash_scryptsalsa208sha256/hash_sha256.c
@@ -0,0 +1,300 @@
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//#include "api.h"
34#include "crypto_hash_sha256.h"
35#include "utils.h"
36
37#include <sys/types.h>
38
39#include <limits.h>
40#include <stdint.h>
41#include <stdlib.h>
42#include <string.h>
43
44/* Avoid namespace collisions with BSD <sys/endian.h>. */
45#define be32dec _sha256_be32dec
46#define be32enc _sha256_be32enc
47
48static inline uint32_t
49be32dec(const void *pp)
50{
51 const uint8_t *p = (uint8_t const *)pp;
52
53 return ((uint32_t)(p[3]) + ((uint32_t)(p[2]) << 8) +
54 ((uint32_t)(p[1]) << 16) + ((uint32_t)(p[0]) << 24));
55}
56
57static inline void
58be32enc(void *pp, uint32_t x)
59{
60 uint8_t * p = (uint8_t *)pp;
61
62 p[3] = x & 0xff;
63 p[2] = (x >> 8) & 0xff;
64 p[1] = (x >> 16) & 0xff;
65 p[0] = (x >> 24) & 0xff;
66}
67
68static void
69be32enc_vect(unsigned char *dst, const uint32_t *src, size_t len)
70{
71 size_t i;
72
73 for (i = 0; i < len / 4; i++) {
74 be32enc(dst + i * 4, src[i]);
75 }
76}
77
78static void
79be32dec_vect(uint32_t *dst, const unsigned char *src, size_t len)
80{
81 size_t i;
82
83 for (i = 0; i < len / 4; i++) {
84 dst[i] = be32dec(src + i * 4);
85 }
86}
87
88#define Ch(x, y, z) ((x & (y ^ z)) ^ z)
89#define Maj(x, y, z) ((x & (y | z)) | (y & z))
90#define SHR(x, n) (x >> n)
91#define ROTR(x, n) ((x >> n) | (x << (32 - n)))
92#define S0(x) (ROTR(x, 2) ^ ROTR(x, 13) ^ ROTR(x, 22))
93#define S1(x) (ROTR(x, 6) ^ ROTR(x, 11) ^ ROTR(x, 25))
94#define s0(x) (ROTR(x, 7) ^ ROTR(x, 18) ^ SHR(x, 3))
95#define s1(x) (ROTR(x, 17) ^ ROTR(x, 19) ^ SHR(x, 10))
96
97#define RND(a, b, c, d, e, f, g, h, k) \
98 t0 = h + S1(e) + Ch(e, f, g) + k; \
99 t1 = S0(a) + Maj(a, b, c); \
100 d += t0; \
101 h = t0 + t1;
102
103#define RNDr(S, W, i, k) \
104 RND(S[(64 - i) % 8], S[(65 - i) % 8], \
105 S[(66 - i) % 8], S[(67 - i) % 8], \
106 S[(68 - i) % 8], S[(69 - i) % 8], \
107 S[(70 - i) % 8], S[(71 - i) % 8], \
108 W[i] + k)
109
110static void
111SHA256_Transform(uint32_t *state, const unsigned char block[64])
112{
113 uint32_t W[64];
114 uint32_t S[8];
115 uint32_t t0, t1;
116 int i;
117
118 be32dec_vect(W, block, 64);
119 for (i = 16; i < 64; i++) {
120 W[i] = s1(W[i - 2]) + W[i - 7] + s0(W[i - 15]) + W[i - 16];
121 }
122
123 memcpy(S, state, 32);
124
125 RNDr(S, W, 0, 0x428a2f98);
126 RNDr(S, W, 1, 0x71374491);
127 RNDr(S, W, 2, 0xb5c0fbcf);
128 RNDr(S, W, 3, 0xe9b5dba5);
129 RNDr(S, W, 4, 0x3956c25b);
130 RNDr(S, W, 5, 0x59f111f1);
131 RNDr(S, W, 6, 0x923f82a4);
132 RNDr(S, W, 7, 0xab1c5ed5);
133 RNDr(S, W, 8, 0xd807aa98);
134 RNDr(S, W, 9, 0x12835b01);
135 RNDr(S, W, 10, 0x243185be);
136 RNDr(S, W, 11, 0x550c7dc3);
137 RNDr(S, W, 12, 0x72be5d74);
138 RNDr(S, W, 13, 0x80deb1fe);
139 RNDr(S, W, 14, 0x9bdc06a7);
140 RNDr(S, W, 15, 0xc19bf174);
141 RNDr(S, W, 16, 0xe49b69c1);
142 RNDr(S, W, 17, 0xefbe4786);
143 RNDr(S, W, 18, 0x0fc19dc6);
144 RNDr(S, W, 19, 0x240ca1cc);
145 RNDr(S, W, 20, 0x2de92c6f);
146 RNDr(S, W, 21, 0x4a7484aa);
147 RNDr(S, W, 22, 0x5cb0a9dc);
148 RNDr(S, W, 23, 0x76f988da);
149 RNDr(S, W, 24, 0x983e5152);
150 RNDr(S, W, 25, 0xa831c66d);
151 RNDr(S, W, 26, 0xb00327c8);
152 RNDr(S, W, 27, 0xbf597fc7);
153 RNDr(S, W, 28, 0xc6e00bf3);
154 RNDr(S, W, 29, 0xd5a79147);
155 RNDr(S, W, 30, 0x06ca6351);
156 RNDr(S, W, 31, 0x14292967);
157 RNDr(S, W, 32, 0x27b70a85);
158 RNDr(S, W, 33, 0x2e1b2138);
159 RNDr(S, W, 34, 0x4d2c6dfc);
160 RNDr(S, W, 35, 0x53380d13);
161 RNDr(S, W, 36, 0x650a7354);
162 RNDr(S, W, 37, 0x766a0abb);
163 RNDr(S, W, 38, 0x81c2c92e);
164 RNDr(S, W, 39, 0x92722c85);
165 RNDr(S, W, 40, 0xa2bfe8a1);
166 RNDr(S, W, 41, 0xa81a664b);
167 RNDr(S, W, 42, 0xc24b8b70);
168 RNDr(S, W, 43, 0xc76c51a3);
169 RNDr(S, W, 44, 0xd192e819);
170 RNDr(S, W, 45, 0xd6990624);
171 RNDr(S, W, 46, 0xf40e3585);
172 RNDr(S, W, 47, 0x106aa070);
173 RNDr(S, W, 48, 0x19a4c116);
174 RNDr(S, W, 49, 0x1e376c08);
175 RNDr(S, W, 50, 0x2748774c);
176 RNDr(S, W, 51, 0x34b0bcb5);
177 RNDr(S, W, 52, 0x391c0cb3);
178 RNDr(S, W, 53, 0x4ed8aa4a);
179 RNDr(S, W, 54, 0x5b9cca4f);
180 RNDr(S, W, 55, 0x682e6ff3);
181 RNDr(S, W, 56, 0x748f82ee);
182 RNDr(S, W, 57, 0x78a5636f);
183 RNDr(S, W, 58, 0x84c87814);
184 RNDr(S, W, 59, 0x8cc70208);
185 RNDr(S, W, 60, 0x90befffa);
186 RNDr(S, W, 61, 0xa4506ceb);
187 RNDr(S, W, 62, 0xbef9a3f7);
188 RNDr(S, W, 63, 0xc67178f2);
189
190 for (i = 0; i < 8; i++) {
191 state[i] += S[i];
192 }
193
194 sodium_memzero((void *) W, sizeof W);
195 sodium_memzero((void *) S, sizeof S);
196 sodium_memzero((void *) &t0, sizeof t0);
197 sodium_memzero((void *) &t1, sizeof t1);
198}
199
200static unsigned char PAD[64] = {
201 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
202 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
203 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
204 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
205};
206
207static void
208SHA256_Pad(crypto_hash_sha256_state *state)
209{
210 unsigned char len[8];
211 uint32_t r, plen;
212
213 be32enc_vect(len, state->count, 8);
214
215 r = (state->count[1] >> 3) & 0x3f;
216 plen = (r < 56) ? (56 - r) : (120 - r);
217 crypto_hash_sha256_update(state, PAD, (unsigned long long) plen);
218
219 crypto_hash_sha256_update(state, len, 8);
220}
221
222int
223crypto_hash_sha256_init(crypto_hash_sha256_state *state)
224{
225 state->count[0] = state->count[1] = 0;
226
227 state->state[0] = 0x6A09E667;
228 state->state[1] = 0xBB67AE85;
229 state->state[2] = 0x3C6EF372;
230 state->state[3] = 0xA54FF53A;
231 state->state[4] = 0x510E527F;
232 state->state[5] = 0x9B05688C;
233 state->state[6] = 0x1F83D9AB;
234 state->state[7] = 0x5BE0CD19;
235
236 return 0;
237}
238
239int
240crypto_hash_sha256_update(crypto_hash_sha256_state *state,
241 const unsigned char *in,
242 unsigned long long inlen)
243{
244 uint32_t bitlen[2];
245 uint32_t r;
246
247 r = (state->count[1] >> 3) & 0x3f;
248
249 bitlen[1] = ((uint32_t)inlen) << 3;
250 bitlen[0] = (uint32_t)(inlen >> 29);
251
252 if ((state->count[1] += bitlen[1]) < bitlen[1]) {
253 state->count[0]++;
254 }
255 state->count[0] += bitlen[0];
256
257 if (inlen < 64 - r) {
258 memcpy(&state->buf[r], in, inlen);
259 return 0;
260 }
261 memcpy(&state->buf[r], in, 64 - r);
262 SHA256_Transform(state->state, state->buf);
263 in += 64 - r;
264 inlen -= 64 - r;
265
266 while (inlen >= 64) {
267 SHA256_Transform(state->state, in);
268 in += 64;
269 inlen -= 64;
270 }
271 memcpy(state->buf, in, inlen);
272
273 return 0;
274}
275
276int
277crypto_hash_sha256_final(crypto_hash_sha256_state *state,
278 unsigned char *out)
279{
280 SHA256_Pad(state);
281 be32enc_vect(out, state->state, 32);
282 sodium_memzero((void *) state, sizeof *state);
283
284 return 0;
285}
286
287int
288crypto_hash(unsigned char *out, const unsigned char *in,
289 unsigned long long inlen)
290{
291 crypto_hash_sha256_state state;
292
293 crypto_hash_sha256_init(&state);
294 crypto_hash_sha256_update(&state, in, inlen);
295 crypto_hash_sha256_final(&state, out);
296
297 return 0;
298}
299
300#endif
diff --git a/toxencryptsave/crypto_pwhash_scryptsalsa208sha256/hmac_hmacsha256.c b/toxencryptsave/crypto_pwhash_scryptsalsa208sha256/hmac_hmacsha256.c
new file mode 100644
index 00000000..2a268075
--- /dev/null
+++ b/toxencryptsave/crypto_pwhash_scryptsalsa208sha256/hmac_hmacsha256.c
@@ -0,0 +1,115 @@
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//#include "api.h"
34#include "crypto_auth_hmacsha256.h"
35#include "crypto_hash_sha256.h"
36#include "utils.h"
37
38#include <sys/types.h>
39
40#include <stdint.h>
41#include <string.h>
42
43int
44crypto_auth_hmacsha256_init(crypto_auth_hmacsha256_state *state,
45 const unsigned char *key,
46 size_t keylen)
47{
48 unsigned char pad[64];
49 unsigned char khash[32];
50 size_t i;
51
52 if (keylen > 64) {
53 crypto_hash_sha256_init(&state->ictx);
54 crypto_hash_sha256_update(&state->ictx, key, keylen);
55 crypto_hash_sha256_final(&state->ictx, khash);
56 key = khash;
57 keylen = 32;
58 }
59 crypto_hash_sha256_init(&state->ictx);
60 memset(pad, 0x36, 64);
61 for (i = 0; i < keylen; i++) {
62 pad[i] ^= key[i];
63 }
64 crypto_hash_sha256_update(&state->ictx, pad, 64);
65
66 crypto_hash_sha256_init(&state->octx);
67 memset(pad, 0x5c, 64);
68 for (i = 0; i < keylen; i++) {
69 pad[i] ^= key[i];
70 }
71 crypto_hash_sha256_update(&state->octx, pad, 64);
72
73 sodium_memzero((void *) khash, sizeof khash);
74
75 return 0;
76}
77
78int
79crypto_auth_hmacsha256_update(crypto_auth_hmacsha256_state *state,
80 const unsigned char *in,
81 unsigned long long inlen)
82{
83 crypto_hash_sha256_update(&state->ictx, in, inlen);
84
85 return 0;
86}
87
88int
89crypto_auth_hmacsha256_final(crypto_auth_hmacsha256_state *state,
90 unsigned char *out)
91{
92 unsigned char ihash[32];
93
94 crypto_hash_sha256_final(&state->ictx, ihash);
95 crypto_hash_sha256_update(&state->octx, ihash, 32);
96 crypto_hash_sha256_final(&state->octx, out);
97
98 sodium_memzero((void *) ihash, sizeof ihash);
99
100 return 0;
101}
102
103int
104crypto_auth(unsigned char *out, const unsigned char *in,
105 unsigned long long inlen, const unsigned char *k)
106{
107 crypto_auth_hmacsha256_state state;
108
109 crypto_auth_hmacsha256_init(&state, k, crypto_auth_hmacsha256_KEYBYTES);
110 crypto_auth_hmacsha256_update(&state, in, inlen);
111 crypto_auth_hmacsha256_final(&state, out);
112
113 return 0;
114}
115#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..01eb7dff
--- /dev/null
+++ b/toxencryptsave/crypto_pwhash_scryptsalsa208sha256/pbkdf2-sha256.c
@@ -0,0 +1,91 @@
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_auth_hmacsha256.h"
39#include "pbkdf2-sha256.h"
40#include "sysendian.h"
41#include "utils.h"
42
43/**
44 * PBKDF2_SHA256(passwd, passwdlen, salt, saltlen, c, buf, dkLen):
45 * Compute PBKDF2(passwd, salt, c, dkLen) using HMAC-SHA256 as the PRF, and
46 * write the output to buf. The value dkLen must be at most 32 * (2^32 - 1).
47 */
48void
49PBKDF2_SHA256(const uint8_t * passwd, size_t passwdlen, const uint8_t * salt,
50 size_t saltlen, uint64_t c, uint8_t * buf, size_t dkLen)
51{
52 crypto_auth_hmacsha256_state PShctx, hctx;
53 size_t i;
54 uint8_t ivec[4];
55 uint8_t U[32];
56 uint8_t T[32];
57 uint64_t j;
58 int k;
59 size_t clen;
60
61 crypto_auth_hmacsha256_init(&PShctx, passwd, passwdlen);
62 crypto_auth_hmacsha256_update(&PShctx, salt, saltlen);
63
64 for (i = 0; i * 32 < dkLen; i++) {
65 be32enc(ivec, (uint32_t)(i + 1));
66 memcpy(&hctx, &PShctx, sizeof(crypto_auth_hmacsha256_state));
67 crypto_auth_hmacsha256_update(&hctx, ivec, 4);
68 crypto_auth_hmacsha256_final(&hctx, U);
69
70 memcpy(T, U, 32);
71
72 for (j = 2; j <= c; j++) {
73 crypto_auth_hmacsha256_init(&hctx, passwd, passwdlen);
74 crypto_auth_hmacsha256_update(&hctx, U, 32);
75 crypto_auth_hmacsha256_final(&hctx, U);
76
77 for (k = 0; k < 32; k++) {
78 T[k] ^= U[k];
79 }
80 }
81
82 clen = dkLen - i * 32;
83 if (clen > 32) {
84 clen = 32;
85 }
86 memcpy(&buf[i * 32], T, clen);
87 }
88 sodium_memzero((void *) &PShctx, sizeof PShctx);
89}
90
91#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/toxencryptsave.c b/toxencryptsave/toxencryptsave.c
new file mode 100644
index 00000000..89c47a03
--- /dev/null
+++ b/toxencryptsave/toxencryptsave.c
@@ -0,0 +1,174 @@
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 "../toxcore/crypto_core.h"
30
31#ifdef VANILLA_NACL
32#include "crypto_pwhash_scryptsalsa208sha256/crypto_pwhash_scryptsalsa208sha256.h"
33#include "crypto_pwhash_scryptsalsa208sha256/utils.h" /* sodium_memzero */
34#endif
35
36/* This "module" provides functions analogous to tox_load and tox_save in toxcore
37 * Clients should consider alerting their users that, unlike plain data, if even one bit
38 * becomes corrupted, the data will be entirely unrecoverable.
39 * Ditto if they forget their password, there is no way to recover the data.
40 */
41
42/* return size of the messenger data (for encrypted saving). */
43uint32_t tox_encrypted_size(const Tox *tox)
44{
45 return tox_size(tox) + crypto_box_MACBYTES + crypto_box_NONCEBYTES
46 + crypto_pwhash_scryptsalsa208sha256_SALTBYTES + TOX_ENC_SAVE_MAGIC_LENGTH;
47}
48
49/* Save the messenger data encrypted with the given password.
50 * data must be at least tox_encrypted_size().
51 *
52 * returns 0 on success
53 * returns -1 on failure
54 */
55int tox_encrypted_save(const Tox *tox, uint8_t *data, uint8_t *passphrase, uint32_t pplength)
56{
57 if (pplength == 0)
58 return -1;
59
60 /* First derive a key from the password */
61 /* http://doc.libsodium.org/key_derivation/README.html */
62 /* note that, according to the documentation, a generic pwhash interface will be created
63 * once the pwhash competition (https://password-hashing.net/) is over */
64 uint8_t salt[crypto_pwhash_scryptsalsa208sha256_SALTBYTES];
65 uint8_t key[crypto_box_KEYBYTES];
66 randombytes(salt, sizeof salt);
67
68 if (crypto_pwhash_scryptsalsa208sha256(
69 key, sizeof(key), passphrase, pplength, salt,
70 crypto_pwhash_scryptsalsa208sha256_OPSLIMIT_INTERACTIVE * 2, /* slightly stronger */
71 crypto_pwhash_scryptsalsa208sha256_MEMLIMIT_INTERACTIVE) != 0) {
72 /* out of memory most likely */
73 return -1;
74 }
75
76 /* calling sodium_memzero segfaults, but printing passphrase works, so... libsodium bug?
77 * ...eh, it's not segfaulting anywhere else, so I'll assume pebkac...
78 sodium_memzero(passphrase, pplength); /* wipe plaintext pw */
79
80 /* next get plain save data */
81 uint32_t temp_size = tox_size(tox);
82 uint8_t temp_data[temp_size];
83 tox_save(tox, temp_data);
84
85 /* the output data consists of, in order:
86 * magic number, salt, nonce, mac, enc_data
87 * where the mac is automatically prepended by the encrypt()
88 * the magic+salt+nonce is called the prefix
89 * I'm not sure what else I'm supposed to do with the salt and nonce, since we
90 * need them to decrypt the data
91 */
92
93 /* first add the prefix */
94 uint8_t nonce[crypto_box_NONCEBYTES];
95 random_nonce(nonce);
96
97 memcpy(data, TOX_ENC_SAVE_MAGIC_NUMBER, TOX_ENC_SAVE_MAGIC_LENGTH);
98 data += TOX_ENC_SAVE_MAGIC_LENGTH;
99 memcpy(data, salt, crypto_pwhash_scryptsalsa208sha256_SALTBYTES);
100 data += crypto_pwhash_scryptsalsa208sha256_SALTBYTES;
101 memcpy(data, nonce, crypto_box_NONCEBYTES);
102 data += crypto_box_NONCEBYTES;
103
104 /* now encrypt */
105 if (encrypt_data_symmetric(key, nonce, temp_data, temp_size, data)
106 != temp_size + crypto_box_MACBYTES) {
107 return -1;
108 }
109
110 return 0;
111}
112
113/* Load the messenger from encrypted data of size length.
114 *
115 * returns 0 on success
116 * returns -1 on failure
117 */
118int tox_encrypted_load(Tox *tox, const uint8_t *data, uint32_t length, uint8_t *passphrase, uint32_t pplength)
119{
120 if (length <= crypto_box_MACBYTES + crypto_box_NONCEBYTES + crypto_pwhash_scryptsalsa208sha256_SALTBYTES +
121 TOX_ENC_SAVE_MAGIC_LENGTH)
122 return -1;
123
124 if (memcmp(data, TOX_ENC_SAVE_MAGIC_NUMBER, TOX_ENC_SAVE_MAGIC_LENGTH) != 0)
125 return -1;
126
127 data += TOX_ENC_SAVE_MAGIC_LENGTH;
128
129 uint32_t decrypt_length = length - crypto_box_MACBYTES - crypto_box_NONCEBYTES
130 - crypto_pwhash_scryptsalsa208sha256_SALTBYTES - TOX_ENC_SAVE_MAGIC_LENGTH;
131 uint8_t salt[crypto_pwhash_scryptsalsa208sha256_SALTBYTES];
132 uint8_t nonce[crypto_box_NONCEBYTES];
133
134 memcpy(salt, data, crypto_pwhash_scryptsalsa208sha256_SALTBYTES);
135 data += crypto_pwhash_scryptsalsa208sha256_SALTBYTES;
136 memcpy(nonce, data, crypto_box_NONCEBYTES);
137 data += crypto_box_NONCEBYTES;
138
139 /* derive the key */
140 uint8_t key[crypto_box_KEYBYTES];
141
142 if (crypto_pwhash_scryptsalsa208sha256(
143 key, sizeof(key), passphrase, pplength, salt,
144 crypto_pwhash_scryptsalsa208sha256_OPSLIMIT_INTERACTIVE * 2, /* slightly stronger */
145 crypto_pwhash_scryptsalsa208sha256_MEMLIMIT_INTERACTIVE) != 0) {
146 /* out of memory most likely */
147 return -1;
148 }
149
150 /* sodium_memzero(passphrase, pplength); /* wipe plaintext pw */
151
152 /* decrypt the data */
153 uint8_t temp_data[decrypt_length];
154
155 if (decrypt_data_symmetric(key, nonce, data, decrypt_length + crypto_box_MACBYTES, temp_data)
156 != decrypt_length) {
157 return -1;
158 }
159
160 return tox_load(tox, temp_data, decrypt_length);
161}
162
163/* Determines whether or not the given data is encrypted (by checking the magic number)
164 *
165 * returns 1 if it is encrypted
166 * returns 0 otherwise
167 */
168int tox_is_data_encrypted(const uint8_t *data)
169{
170 if (memcmp(data, TOX_ENC_SAVE_MAGIC_NUMBER, TOX_ENC_SAVE_MAGIC_LENGTH) == 0)
171 return 1;
172 else
173 return 0;
174}
diff --git a/toxencryptsave/toxencryptsave.h b/toxencryptsave/toxencryptsave.h
new file mode 100644
index 00000000..64617b27
--- /dev/null
+++ b/toxencryptsave/toxencryptsave.h
@@ -0,0 +1,68 @@
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#include "../toxcore/tox.h"
28
29#ifdef __cplusplus
30extern "C" {
31#endif
32
33/* This "module" provides functions analogous to tox_load and tox_save in toxcore
34 * Clients should consider alerting their users that, unlike plain data, if even one bit
35 * becomes corrupted, the data will be entirely unrecoverable.
36 * Ditto if they forget their password, there is no way to recover the data.
37 */
38
39/* return size of the messenger data (for encrypted saving). */
40uint32_t tox_encrypted_size(const Tox *tox);
41
42/* Save the messenger data encrypted with the given password.
43 * data must be at least tox_encrypted_size().
44 *
45 * returns 0 on success
46 * returns -1 on failure
47 */
48int tox_encrypted_save(const Tox *tox, uint8_t *data, uint8_t *passphrase, uint32_t pplength);
49
50/* Load the messenger from encrypted data of size length.
51 *
52 * returns 0 on success
53 * returns -1 on failure
54 */
55int tox_encrypted_load(Tox *tox, const uint8_t *data, uint32_t length, uint8_t *passphrase, uint32_t pplength);
56
57/* Determines whether or not the given data is encrypted (by checking the magic number)
58 *
59 * returns 1 if it is encrypted
60 * returns 0 otherwise
61 */
62int tox_is_data_encrypted(const uint8_t *data);
63
64#ifdef __cplusplus
65}
66#endif
67
68#endif