summaryrefslogtreecommitdiff
path: root/toxencryptsave/toxencryptsave.c
diff options
context:
space:
mode:
Diffstat (limited to 'toxencryptsave/toxencryptsave.c')
-rw-r--r--toxencryptsave/toxencryptsave.c289
1 files changed, 120 insertions, 169 deletions
diff --git a/toxencryptsave/toxencryptsave.c b/toxencryptsave/toxencryptsave.c
index 9172f512..e2f28a58 100644
--- a/toxencryptsave/toxencryptsave.c
+++ b/toxencryptsave/toxencryptsave.c
@@ -26,8 +26,9 @@
26#endif 26#endif
27 27
28#include "toxencryptsave.h" 28#include "toxencryptsave.h"
29#include "defines.h"
29#include "../toxcore/crypto_core.h" 30#include "../toxcore/crypto_core.h"
30#include "../toxcore/tox.h" 31#define SET_ERROR_PARAMETER(param, x) {if(param) {*param = x;}}
31 32
32#ifdef VANILLA_NACL 33#ifdef VANILLA_NACL
33#include "crypto_pwhash_scryptsalsa208sha256/crypto_pwhash_scryptsalsa208sha256.h" 34#include "crypto_pwhash_scryptsalsa208sha256/crypto_pwhash_scryptsalsa208sha256.h"
@@ -35,81 +36,70 @@
35#include <crypto_hash_sha256.h> 36#include <crypto_hash_sha256.h>
36#endif 37#endif
37 38
38#define TOX_PASS_ENCRYPTION_EXTRA_LENGTH (crypto_box_MACBYTES + crypto_box_NONCEBYTES \ 39#if TOX_PASS_SALT_LENGTH != crypto_pwhash_scryptsalsa208sha256_SALTBYTES
39 + crypto_pwhash_scryptsalsa208sha256_SALTBYTES + TOX_ENC_SAVE_MAGIC_LENGTH) 40#error TOX_PASS_SALT_LENGTH is assumed to be equal to crypto_pwhash_scryptsalsa208sha256_SALTBYTES
40 41#endif
41#define TOX_PASS_KEY_LENGTH (crypto_pwhash_scryptsalsa208sha256_SALTBYTES + crypto_box_KEYBYTES)
42
43int tox_pass_encryption_extra_length()
44{
45 return TOX_PASS_ENCRYPTION_EXTRA_LENGTH;
46}
47 42
48int tox_pass_key_length() 43#if TOX_PASS_KEY_LENGTH != crypto_box_KEYBYTES
49{ 44#error TOX_PASS_KEY_LENGTH is assumed to be equal to crypto_box_KEYBYTES
50 return TOX_PASS_KEY_LENGTH; 45#endif
51}
52 46
53int tox_pass_salt_length() 47#if TOX_PASS_ENCRYPTION_EXTRA_LENGTH != (crypto_box_MACBYTES + crypto_box_NONCEBYTES + crypto_pwhash_scryptsalsa208sha256_SALTBYTES + TOX_ENC_SAVE_MAGIC_LENGTH)
54{ 48#error TOX_PASS_ENCRYPTION_EXTRA_LENGTH is assumed to be equal to (crypto_box_MACBYTES + crypto_box_NONCEBYTES + crypto_pwhash_scryptsalsa208sha256_SALTBYTES + TOX_ENC_SAVE_MAGIC_LENGTH)
55 return crypto_pwhash_scryptsalsa208sha256_SALTBYTES; 49#endif
56}
57 50
58/* This "module" provides functions analogous to tox_load and tox_save in toxcore 51/* Clients should consider alerting their users that, unlike plain data, if even one bit
59 * Clients should consider alerting their users that, unlike plain data, if even one bit
60 * becomes corrupted, the data will be entirely unrecoverable. 52 * becomes corrupted, the data will be entirely unrecoverable.
61 * Ditto if they forget their password, there is no way to recover the data. 53 * Ditto if they forget their password, there is no way to recover the data.
62 */ 54 */
63 55
64/* return size of the messenger data (for encrypted saving). */
65uint32_t tox_encrypted_size(const Tox *tox)
66{
67 return tox_size(tox) + TOX_PASS_ENCRYPTION_EXTRA_LENGTH;
68}
69
70/* This retrieves the salt used to encrypt the given data, which can then be passed to 56/* This retrieves the salt used to encrypt the given data, which can then be passed to
71 * derive_key_with_salt to produce the same key as was previously used. Any encrpyted 57 * derive_key_with_salt to produce the same key as was previously used. Any encrpyted
72 * data with this module can be used as input. 58 * data with this module can be used as input.
73 * 59 *
74 * returns -1 if the magic number is wrong 60 * returns true if magic number matches
75 * returns 0 otherwise (no guarantee about validity of data) 61 * success does not say anything about the validity of the data, only that data of
62 * the appropriate size was copied
76 */ 63 */
77int tox_get_salt(uint8_t *data, uint8_t *salt) 64bool tox_get_salt(const uint8_t *data, uint8_t *salt)
78{ 65{
79 if (memcmp(data, TOX_ENC_SAVE_MAGIC_NUMBER, TOX_ENC_SAVE_MAGIC_LENGTH) != 0) 66 if (memcmp(data, TOX_ENC_SAVE_MAGIC_NUMBER, TOX_ENC_SAVE_MAGIC_LENGTH) != 0)
80 return -1; 67 return 0;
81 68
82 data += TOX_ENC_SAVE_MAGIC_LENGTH; 69 data += TOX_ENC_SAVE_MAGIC_LENGTH;
83 memcpy(salt, data, crypto_pwhash_scryptsalsa208sha256_SALTBYTES); 70 memcpy(salt, data, crypto_pwhash_scryptsalsa208sha256_SALTBYTES);
84 return 0; 71 return 1;
85} 72}
86 73
87/* Generates a secret symmetric key from the given passphrase. out_key must be at least 74/* Generates a secret symmetric key from the given passphrase. out_key must be at least
88 * TOX_PASS_KEY_LENGTH bytes long. 75 * TOX_PASS_KEY_LENGTH bytes long.
89 * Be sure to not compromise the key! Only keep it in memory, do not write to disk. 76 * Be sure to not compromise the key! Only keep it in memory, do not write to disk.
90 * This function is fairly cheap, but irungentoo insists that you be allowed to
91 * cache the result if you want, to minimize computation for repeated encryptions.
92 * The password is zeroed after key derivation. 77 * The password is zeroed after key derivation.
93 * The key should only be used with the other functions in this module, as it 78 * The key should only be used with the other functions in this module, as it
94 * includes a salt. 79 * includes a salt.
80 * Note that this function is not deterministic; to derive the same key from a
81 * password, you also must know the random salt that was used. See below.
95 * 82 *
96 * returns 0 on success 83 * returns true on success
97 * returns -1 on failure
98 */ 84 */
99int tox_derive_key_from_pass(uint8_t *passphrase, uint32_t pplength, uint8_t *out_key) 85bool tox_derive_key_from_pass(uint8_t *passphrase, size_t pplength, TOX_PASS_KEY *out_key,
86 TOX_ERR_KEY_DERIVATION *error)
100{ 87{
101 uint8_t salt[crypto_pwhash_scryptsalsa208sha256_SALTBYTES]; 88 uint8_t salt[crypto_pwhash_scryptsalsa208sha256_SALTBYTES];
102 randombytes(salt, sizeof salt); 89 randombytes(salt, sizeof salt);
103 return tox_derive_key_with_salt(passphrase, pplength, salt, out_key); 90 return tox_derive_key_with_salt(passphrase, pplength, salt, out_key, error);
104} 91}
105 92
106/* Same as above, except with use the given salt for deterministic key derivation. 93/* Same as above, except with use the given salt for deterministic key derivation.
107 * The salt must be tox_salt_length() bytes in length. 94 * The salt must be TOX_PASS_SALT_LENGTH bytes in length.
108 */ 95 */
109int tox_derive_key_with_salt(uint8_t *passphrase, uint32_t pplength, uint8_t *salt, uint8_t *out_key) 96bool tox_derive_key_with_salt(uint8_t *passphrase, size_t pplength, uint8_t *salt, TOX_PASS_KEY *out_key,
97 TOX_ERR_KEY_DERIVATION *error)
110{ 98{
111 if (pplength == 0) 99 if (pplength == 0 || !passphrase || !salt || !out_key) {
112 return -1; 100 SET_ERROR_PARAMETER(error, TOX_ERR_KEY_DERIVATION_NULL);
101 return 0;
102 }
113 103
114 uint8_t passkey[crypto_hash_sha256_BYTES]; 104 uint8_t passkey[crypto_hash_sha256_BYTES];
115 crypto_hash_sha256(passkey, passphrase, pplength); 105 crypto_hash_sha256(passkey, passphrase, pplength);
@@ -125,27 +115,33 @@ int tox_derive_key_with_salt(uint8_t *passphrase, uint32_t pplength, uint8_t *sa
125 crypto_pwhash_scryptsalsa208sha256_OPSLIMIT_INTERACTIVE * 2, /* slightly stronger */ 115 crypto_pwhash_scryptsalsa208sha256_OPSLIMIT_INTERACTIVE * 2, /* slightly stronger */
126 crypto_pwhash_scryptsalsa208sha256_MEMLIMIT_INTERACTIVE) != 0) { 116 crypto_pwhash_scryptsalsa208sha256_MEMLIMIT_INTERACTIVE) != 0) {
127 /* out of memory most likely */ 117 /* out of memory most likely */
128 return -1; 118 SET_ERROR_PARAMETER(error, TOX_ERR_KEY_DERIVATION_FAILED);
119 return 0;
129 } 120 }
130 121
131 sodium_memzero(passkey, crypto_hash_sha256_BYTES); /* wipe plaintext pw */ 122 sodium_memzero(passkey, crypto_hash_sha256_BYTES); /* wipe plaintext pw */
132 memcpy(out_key, salt, crypto_pwhash_scryptsalsa208sha256_SALTBYTES); 123 memcpy(out_key->salt, salt, crypto_pwhash_scryptsalsa208sha256_SALTBYTES);
133 memcpy(out_key + crypto_pwhash_scryptsalsa208sha256_SALTBYTES, key, crypto_box_KEYBYTES); 124 memcpy(out_key->key, key, crypto_box_KEYBYTES);
134 return 0; 125 SET_ERROR_PARAMETER(error, TOX_ERR_KEY_DERIVATION_OK);
126 return 1;
135} 127}
136 128
137/* Encrypt arbitrary with a key produced by tox_derive_key_from_pass. The output 129/* Encrypt arbitrary with a key produced by tox_derive_key_*. The output
138 * array must be at least data_len + TOX_PASS_ENCRYPTION_EXTRA_LENGTH bytes long. 130 * array must be at least data_len + TOX_PASS_ENCRYPTION_EXTRA_LENGTH bytes long.
139 * key must be TOX_PASS_KEY_LENGTH bytes. 131 * key must be TOX_PASS_KEY_LENGTH bytes.
140 * If you already have a symmetric key from somewhere besides this module, simply 132 * If you already have a symmetric key from somewhere besides this module, simply
141 * call encrypt_data_symmetric in toxcore/crypto_core directly. 133 * call encrypt_data_symmetric in toxcore/crypto_core directly.
142 * 134 *
143 * 135 * returns true on success
144 * returns 0 on success
145 * returns -1 on failure
146 */ 136 */
147int tox_pass_key_encrypt(const uint8_t *data, uint32_t data_len, const uint8_t *key, uint8_t *out) 137bool tox_pass_key_encrypt(const uint8_t *data, size_t data_len, const TOX_PASS_KEY *key, uint8_t *out,
138 TOX_ERR_ENCRYPTION *error)
148{ 139{
140 if (data_len == 0 || !data || !key || !out) {
141 SET_ERROR_PARAMETER(error, TOX_ERR_ENCRYPTION_NULL);
142 return 0;
143 }
144
149 /* the output data consists of, in order: 145 /* the output data consists of, in order:
150 * salt, nonce, mac, enc_data 146 * salt, nonce, mac, enc_data
151 * where the mac is automatically prepended by the encrypt() 147 * where the mac is automatically prepended by the encrypt()
@@ -159,8 +155,7 @@ int tox_pass_key_encrypt(const uint8_t *data, uint32_t data_len, const uint8_t *
159 out += TOX_ENC_SAVE_MAGIC_LENGTH; 155 out += TOX_ENC_SAVE_MAGIC_LENGTH;
160 156
161 /* then add the rest prefix */ 157 /* then add the rest prefix */
162 memcpy(out, key, crypto_pwhash_scryptsalsa208sha256_SALTBYTES); 158 memcpy(out, key->salt, crypto_pwhash_scryptsalsa208sha256_SALTBYTES);
163 key += crypto_pwhash_scryptsalsa208sha256_SALTBYTES;
164 out += crypto_pwhash_scryptsalsa208sha256_SALTBYTES; 159 out += crypto_pwhash_scryptsalsa208sha256_SALTBYTES;
165 160
166 uint8_t nonce[crypto_box_NONCEBYTES]; 161 uint8_t nonce[crypto_box_NONCEBYTES];
@@ -169,177 +164,133 @@ int tox_pass_key_encrypt(const uint8_t *data, uint32_t data_len, const uint8_t *
169 out += crypto_box_NONCEBYTES; 164 out += crypto_box_NONCEBYTES;
170 165
171 /* now encrypt */ 166 /* now encrypt */
172 if (encrypt_data_symmetric(key, nonce, data, data_len, out) 167 if (encrypt_data_symmetric(key->key, nonce, data, data_len, out)
173 != data_len + crypto_box_MACBYTES) { 168 != data_len + crypto_box_MACBYTES) {
174 return -1; 169 SET_ERROR_PARAMETER(error, TOX_ERR_ENCRYPTION_FAILED);
170 return 0;
175 } 171 }
176 172
177 return 0; 173 SET_ERROR_PARAMETER(error, TOX_ERR_ENCRYPTION_OK);
174 return 1;
178} 175}
179 176
180/* Encrypts the given data with the given passphrase. The output array must be 177/* Encrypts the given data with the given passphrase. The output array must be
181 * at least data_len + TOX_PASS_ENCRYPTION_EXTRA_LENGTH bytes long. This delegates 178 * at least data_len + TOX_PASS_ENCRYPTION_EXTRA_LENGTH bytes long. This delegates
182 * to tox_derive_key_from_pass and tox_pass_key_encrypt. 179 * to tox_derive_key_from_pass and tox_pass_key_encrypt.
183 * 180 *
184 * returns 0 on success 181 * returns true on success
185 * returns -1 on failure
186 */ 182 */
187int tox_pass_encrypt(const uint8_t *data, uint32_t data_len, uint8_t *passphrase, uint32_t pplength, uint8_t *out) 183bool tox_pass_encrypt(const uint8_t *data, size_t data_len, uint8_t *passphrase, size_t pplength, uint8_t *out,
184 TOX_ERR_ENCRYPTION *error)
188{ 185{
189 uint8_t key[TOX_PASS_KEY_LENGTH]; 186 TOX_PASS_KEY key;
190 187 TOX_ERR_KEY_DERIVATION _error;
191 if (tox_derive_key_from_pass(passphrase, pplength, key) == -1)
192 return -1;
193 188
194 return tox_pass_key_encrypt(data, data_len, key, out); 189 if (!tox_derive_key_from_pass(passphrase, pplength, &key, &_error)) {
195} 190 if (_error == TOX_ERR_KEY_DERIVATION_NULL) {
196 191 SET_ERROR_PARAMETER(error, TOX_ERR_ENCRYPTION_NULL);
197/* Save the messenger data encrypted with the given password. 192 } else if (_error == TOX_ERR_KEY_DERIVATION_FAILED) {
198 * data must be at least tox_encrypted_size(). 193 SET_ERROR_PARAMETER(error, TOX_ERR_ENCRYPTION_KEY_DERIVATION_FAILED);
199 * 194 }
200 * returns 0 on success
201 * returns -1 on failure
202 */
203int tox_encrypted_save(const Tox *tox, uint8_t *data, uint8_t *passphrase, uint32_t pplength)
204{
205 /* first get plain save data */
206 uint32_t temp_size = tox_size(tox);
207 uint8_t temp_data[temp_size];
208 tox_save(tox, temp_data);
209
210 /* now encrypt */
211 return tox_pass_encrypt(temp_data, temp_size, passphrase, pplength, data);
212}
213 195
214/* Save the messenger data encrypted with the given key from tox_derive_key. 196 return 0;
215 * data must be at least tox_encrypted_size(). 197 }
216 *
217 * returns 0 on success
218 * returns -1 on failure
219 */
220int tox_encrypted_key_save(const Tox *tox, uint8_t *data, uint8_t *key)
221{
222 /* first get plain save data */
223 uint32_t temp_size = tox_size(tox);
224 uint8_t temp_data[temp_size];
225 tox_save(tox, temp_data);
226 198
227 /* encrypt */ 199 return tox_pass_key_encrypt(data, data_len, &key, out, error);
228 return tox_pass_key_encrypt(temp_data, temp_size, key, data);
229} 200}
230 201
231/* This is the inverse of tox_pass_key_encrypt, also using only keys produced by 202/* This is the inverse of tox_pass_key_encrypt, also using only keys produced by
232 * tox_derive_key_from_pass. 203 * tox_derive_key_from_pass.
233 * 204 *
234 * returns the length of the output data (== data_len - TOX_PASS_ENCRYPTION_EXTRA_LENGTH) on success 205 * the output data has size data_length - TOX_PASS_ENCRYPTION_EXTRA_LENGTH
235 * returns -1 on failure 206 *
207 * returns true on success
236 */ 208 */
237int tox_pass_key_decrypt(const uint8_t *data, uint32_t length, const uint8_t *key, uint8_t *out) 209bool tox_pass_key_decrypt(const uint8_t *data, size_t length, const TOX_PASS_KEY *key, uint8_t *out,
210 TOX_ERR_DECRYPTION *error)
238{ 211{
239 if (length <= TOX_PASS_ENCRYPTION_EXTRA_LENGTH 212 if (length <= TOX_PASS_ENCRYPTION_EXTRA_LENGTH) {
240 || 0 != memcmp(data, TOX_ENC_SAVE_MAGIC_NUMBER, TOX_ENC_SAVE_MAGIC_LENGTH)) 213 SET_ERROR_PARAMETER(error, TOX_ERR_DECRYPTION_INVALID_LENGTH);
241 return -1; 214 return 0;
215 }
216
217 if (!data || !key || !out) {
218 SET_ERROR_PARAMETER(error, TOX_ERR_DECRYPTION_NULL);
219 return 0;
220 }
221
222 if (memcmp(data, TOX_ENC_SAVE_MAGIC_NUMBER, TOX_ENC_SAVE_MAGIC_LENGTH) != 0) {
223 SET_ERROR_PARAMETER(error, TOX_ERR_DECRYPTION_BAD_FORMAT);
224 return 0;
225 }
242 226
243 data += TOX_ENC_SAVE_MAGIC_LENGTH; 227 data += TOX_ENC_SAVE_MAGIC_LENGTH;
228 data += crypto_pwhash_scryptsalsa208sha256_SALTBYTES; // salt only affects key derivation
244 229
245 uint32_t decrypt_length = length - TOX_PASS_ENCRYPTION_EXTRA_LENGTH; 230 size_t decrypt_length = length - TOX_PASS_ENCRYPTION_EXTRA_LENGTH;
246 //uint8_t salt[crypto_pwhash_scryptsalsa208sha256_SALTBYTES];
247 uint8_t nonce[crypto_box_NONCEBYTES];
248 231
249 //memcpy(salt, data, crypto_pwhash_scryptsalsa208sha256_SALTBYTES); 232 uint8_t nonce[crypto_box_NONCEBYTES];
250 key += crypto_pwhash_scryptsalsa208sha256_SALTBYTES; // ignore the salt, which is only needed for kdf
251 data += crypto_pwhash_scryptsalsa208sha256_SALTBYTES;
252 memcpy(nonce, data, crypto_box_NONCEBYTES); 233 memcpy(nonce, data, crypto_box_NONCEBYTES);
253 data += crypto_box_NONCEBYTES; 234 data += crypto_box_NONCEBYTES;
254 235
255 /* decrypt the data */ 236 /* decrypt the data */
256 if (decrypt_data_symmetric(key, nonce, data, decrypt_length + crypto_box_MACBYTES, out) 237 if (decrypt_data_symmetric(key->key, nonce, data, decrypt_length + crypto_box_MACBYTES, out)
257 != decrypt_length) { 238 != decrypt_length) {
258 return -1; 239 SET_ERROR_PARAMETER(error, TOX_ERR_DECRYPTION_FAILED);
240 return 0;
259 } 241 }
260 242
261 return decrypt_length; 243 SET_ERROR_PARAMETER(error, TOX_ERR_DECRYPTION_OK);
244 return 1;
262} 245}
263 246
264/* Decrypts the given data with the given passphrase. The output array must be 247/* Decrypts the given data with the given passphrase. The output array must be
265 * at least data_len - TOX_PASS_ENCRYPTION_EXTRA_LENGTH bytes long. 248 * at least data_len - TOX_PASS_ENCRYPTION_EXTRA_LENGTH bytes long. This delegates
249 * to tox_pass_key_decrypt.
250 *
251 * the output data has size data_length - TOX_PASS_ENCRYPTION_EXTRA_LENGTH
266 * 252 *
267 * returns the length of the output data (== data_len - TOX_PASS_ENCRYPTION_EXTRA_LENGTH) on success 253 * returns true on success
268 * returns -1 on failure
269 */ 254 */
270int tox_pass_decrypt(const uint8_t *data, uint32_t length, uint8_t *passphrase, uint32_t pplength, uint8_t *out) 255bool tox_pass_decrypt(const uint8_t *data, size_t length, uint8_t *passphrase, size_t pplength, uint8_t *out,
256 TOX_ERR_DECRYPTION *error)
271{ 257{
272 uint8_t passkey[crypto_hash_sha256_BYTES]; 258 if (length <= TOX_PASS_ENCRYPTION_EXTRA_LENGTH || pplength == 0) {
273 crypto_hash_sha256(passkey, passphrase, pplength); 259 SET_ERROR_PARAMETER(error, TOX_ERR_DECRYPTION_INVALID_LENGTH);
260 return 0;
261 }
262
263 if (!data || !passphrase || !out) {
264 SET_ERROR_PARAMETER(error, TOX_ERR_DECRYPTION_NULL);
265 return 0;
266 }
267
268 if (memcmp(data, TOX_ENC_SAVE_MAGIC_NUMBER, TOX_ENC_SAVE_MAGIC_LENGTH) != 0) {
269 SET_ERROR_PARAMETER(error, TOX_ERR_DECRYPTION_BAD_FORMAT);
270 return 0;
271 }
274 272
275 uint8_t salt[crypto_pwhash_scryptsalsa208sha256_SALTBYTES]; 273 uint8_t salt[crypto_pwhash_scryptsalsa208sha256_SALTBYTES];
276 memcpy(salt, data + TOX_ENC_SAVE_MAGIC_LENGTH, crypto_pwhash_scryptsalsa208sha256_SALTBYTES); 274 memcpy(salt, data + TOX_ENC_SAVE_MAGIC_LENGTH, crypto_pwhash_scryptsalsa208sha256_SALTBYTES);
277 275
278 /* derive the key */ 276 /* derive the key */
279 uint8_t key[crypto_box_KEYBYTES + crypto_pwhash_scryptsalsa208sha256_SALTBYTES]; 277 TOX_PASS_KEY key;
280 278
281 if (crypto_pwhash_scryptsalsa208sha256( 279 if (!tox_derive_key_with_salt(passphrase, pplength, salt, &key, NULL)) {
282 key + crypto_pwhash_scryptsalsa208sha256_SALTBYTES,
283 crypto_box_KEYBYTES, (char *)passkey, sizeof(passkey), salt,
284 crypto_pwhash_scryptsalsa208sha256_OPSLIMIT_INTERACTIVE * 2, /* slightly stronger */
285 crypto_pwhash_scryptsalsa208sha256_MEMLIMIT_INTERACTIVE) != 0) {
286 /* out of memory most likely */ 280 /* out of memory most likely */
287 return -1; 281 SET_ERROR_PARAMETER(error, TOX_ERR_DECRYPTION_KEY_DERIVATION_FAILED);
282 return 0;
288 } 283 }
289 284
290 sodium_memzero(passkey, crypto_hash_sha256_BYTES); /* wipe plaintext pw */ 285 return tox_pass_key_decrypt(data, length, &key, out, error);
291
292 return tox_pass_key_decrypt(data, length, key, out);
293}
294
295/* Load the messenger from encrypted data of size length.
296 *
297 * returns 0 on success
298 * returns -1 on failure
299 */
300int tox_encrypted_load(Tox *tox, const uint8_t *data, uint32_t length, uint8_t *passphrase, uint32_t pplength)
301{
302 uint32_t decrypt_length = length - TOX_PASS_ENCRYPTION_EXTRA_LENGTH;
303 uint8_t temp_data[decrypt_length];
304
305 if (tox_pass_decrypt(data, length, passphrase, pplength, temp_data)
306 != decrypt_length)
307 return -1;
308
309 return tox_load(tox, temp_data, decrypt_length);
310}
311
312/* Load the messenger from encrypted data of size length, with key from tox_derive_key.
313 *
314 * returns 0 on success
315 * returns -1 on failure
316 */
317int tox_encrypted_key_load(Tox *tox, const uint8_t *data, uint32_t length, uint8_t *key)
318{
319 uint32_t decrypt_length = length - TOX_PASS_ENCRYPTION_EXTRA_LENGTH;
320 uint8_t temp_data[decrypt_length];
321
322 if (tox_pass_key_decrypt(data, length, key, temp_data)
323 != decrypt_length)
324 return -1;
325
326 return tox_load(tox, temp_data, decrypt_length);
327} 286}
328 287
329/* Determines whether or not the given data is encrypted (by checking the magic number) 288/* Determines whether or not the given data is encrypted (by checking the magic number)
330 *
331 * returns 1 if it is encrypted
332 * returns 0 otherwise
333 */ 289 */
334int tox_is_data_encrypted(const uint8_t *data) 290bool tox_is_data_encrypted(const uint8_t *data)
335{ 291{
336 if (memcmp(data, TOX_ENC_SAVE_MAGIC_NUMBER, TOX_ENC_SAVE_MAGIC_LENGTH) == 0) 292 if (memcmp(data, TOX_ENC_SAVE_MAGIC_NUMBER, TOX_ENC_SAVE_MAGIC_LENGTH) == 0)
337 return 1; 293 return 1;
338 else 294 else
339 return 0; 295 return 0;
340} 296}
341
342int tox_is_save_encrypted(const uint8_t *data)
343{
344 return tox_is_data_encrypted(data);
345}