summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--auto_tests/crypto_test.c31
-rw-r--r--auto_tests/messenger_test.c22
-rw-r--r--toxcore/Messenger.c69
-rw-r--r--toxcore/Messenger.h18
-rw-r--r--toxcore/network.h1
-rw-r--r--toxcore/tox.c29
-rw-r--r--toxcore/tox.h31
7 files changed, 200 insertions, 1 deletions
diff --git a/auto_tests/crypto_test.c b/auto_tests/crypto_test.c
index 806ea7b8..95cdefcd 100644
--- a/auto_tests/crypto_test.c
+++ b/auto_tests/crypto_test.c
@@ -246,6 +246,36 @@ START_TEST(test_large_data)
246} 246}
247END_TEST 247END_TEST
248 248
249START_TEST(test_large_data_symmetric)
250{
251 unsigned char k[crypto_secretbox_KEYBYTES];
252
253 unsigned char n[crypto_secretbox_NONCEBYTES];
254
255 unsigned char m1[16 * 16 * 16];
256 unsigned char c1[sizeof(m1) + crypto_box_MACBYTES];
257 unsigned char m1prime[sizeof(m1)];
258
259 int c1len;
260 int m1plen;
261
262 //Generate random messages
263 rand_bytes(m1, sizeof(m1));
264 rand_bytes(n, crypto_box_NONCEBYTES);
265
266 //Generate key
267 new_symmetric_key(k);
268
269 c1len = encrypt_data_symmetric(k, n, m1, sizeof(m1), c1);
270 ck_assert_msg(c1len == sizeof(m1) + crypto_box_MACBYTES, "could not encrypt data");
271
272 m1plen = decrypt_data_symmetric(k, n, c1, c1len, m1prime);
273
274 ck_assert_msg(m1plen == sizeof(m1), "decrypted text lengths differ");
275 ck_assert_msg(memcmp(m1prime, m1, sizeof(m1)) == 0, "decrypted texts differ");
276}
277END_TEST
278
249#define DEFTESTCASE(NAME) \ 279#define DEFTESTCASE(NAME) \
250 TCase *NAME = tcase_create(#NAME); \ 280 TCase *NAME = tcase_create(#NAME); \
251 tcase_add_test(NAME, test_##NAME); \ 281 tcase_add_test(NAME, test_##NAME); \
@@ -263,6 +293,7 @@ Suite *crypto_suite(void)
263 DEFTESTCASE(fast_known); 293 DEFTESTCASE(fast_known);
264 DEFTESTCASE_SLOW(endtoend, 15); /* waiting up to 15 seconds */ 294 DEFTESTCASE_SLOW(endtoend, 15); /* waiting up to 15 seconds */
265 DEFTESTCASE(large_data); 295 DEFTESTCASE(large_data);
296 DEFTESTCASE(large_data_symmetric);
266 297
267 return s; 298 return s;
268} 299}
diff --git a/auto_tests/messenger_test.c b/auto_tests/messenger_test.c
index cfbc4967..5c8e242e 100644
--- a/auto_tests/messenger_test.c
+++ b/auto_tests/messenger_test.c
@@ -310,6 +310,27 @@ START_TEST(test_messenger_state_saveloadsave)
310} 310}
311END_TEST 311END_TEST
312 312
313START_TEST(test_messenger_state_saveload_encrypted)
314{
315 uint8_t addr[FRIEND_ADDRESS_SIZE];
316 getaddress(m, addr);
317 Messenger *m_temp = new_messenger(TOX_ENABLE_IPV6_DEFAULT);
318
319 size_t size = messenger_size_encrypted(m);
320 uint8_t buffer[size];
321 messenger_save_encrypted(m, buffer, "Gentoo", sizeof("Gentoo"));
322
323 ck_assert_msg(messenger_load_encrypted(m_temp, buffer, size, "Ubuntu", sizeof("Ubuntu")) == -1,
324 "Bad password didn't make the function fail.");
325 ck_assert_msg(messenger_load_encrypted(m_temp, buffer, size, "Gentoo", sizeof("Gentoo")) == 0,
326 "Good password didn't make the function succeed.");
327 uint8_t addr1[FRIEND_ADDRESS_SIZE];
328 getaddress(m_temp, addr1);
329 ck_assert_msg(memcmp(addr1, addr, FRIEND_ADDRESS_SIZE) == 0, "Didn't load messenger successfully");
330 kill_messenger(m_temp);
331}
332END_TEST
333
313#define DEFTESTCASE(NAME) \ 334#define DEFTESTCASE(NAME) \
314 TCase *tc_##NAME = tcase_create(#NAME); \ 335 TCase *tc_##NAME = tcase_create(#NAME); \
315 tcase_add_test(tc_##NAME, test_##NAME); \ 336 tcase_add_test(tc_##NAME, test_##NAME); \
@@ -321,6 +342,7 @@ Suite *messenger_suite(void)
321 342
322 DEFTESTCASE(dht_state_saveloadsave); 343 DEFTESTCASE(dht_state_saveloadsave);
323 DEFTESTCASE(messenger_state_saveloadsave); 344 DEFTESTCASE(messenger_state_saveloadsave);
345 DEFTESTCASE(messenger_state_saveload_encrypted);
324 346
325 DEFTESTCASE(getself_name); 347 DEFTESTCASE(getself_name);
326 DEFTESTCASE(m_get_userstatus_size); 348 DEFTESTCASE(m_get_userstatus_size);
diff --git a/toxcore/Messenger.c b/toxcore/Messenger.c
index b3c8fb40..78c83519 100644
--- a/toxcore/Messenger.c
+++ b/toxcore/Messenger.c
@@ -2264,6 +2264,75 @@ int messenger_load(Messenger *m, uint8_t *data, uint32_t length)
2264 return -1; 2264 return -1;
2265} 2265}
2266 2266
2267/* return the size of data to pass to messenger_save_encrypted(...)
2268 *
2269 */
2270uint32_t messenger_size_encrypted(Messenger *m)
2271{
2272 return messenger_size(m) + crypto_secretbox_MACBYTES + crypto_secretbox_NONCEBYTES;
2273}
2274
2275/* Save the messenger, encrypting the data with key of length key_length
2276 *
2277 * return 0 on success.
2278 * return -1 on failure.
2279 */
2280int messenger_save_encrypted(Messenger *m, uint8_t *data, uint8_t *key, uint16_t key_length)
2281{
2282 uint32_t m_size = messenger_size(m);
2283 uint8_t *plain_messenger = malloc(m_size);
2284
2285 if (plain_messenger == NULL)
2286 return -1;
2287
2288 messenger_save(m, plain_messenger);
2289
2290 /* Hash the key with SHA256 to get a 32byte key. */
2291 uint8_t hash[crypto_hash_sha256_BYTES];
2292 crypto_hash_sha256(hash, key, key_length);
2293 random_nonce(data);
2294 encrypt_data_symmetric(hash, data, plain_messenger, m_size, data + crypto_secretbox_NONCEBYTES);
2295
2296 memset(plain_messenger, 0, m_size);
2297 free(plain_messenger);
2298 memset(hash, 0, crypto_hash_sha256_BYTES);
2299 return 0;
2300}
2301
2302/* Load the messenger from data of size length encrypted with key of key_length.
2303 *
2304 * return 0 on success.
2305 * return -1 on failure.
2306 */
2307int messenger_load_encrypted(Messenger *m, uint8_t *data, uint32_t length, uint8_t *key, uint16_t key_length)
2308{
2309 if (length <= crypto_secretbox_MACBYTES + crypto_secretbox_NONCEBYTES)
2310 return -1;
2311
2312 uint8_t *plain_messenger = malloc(length);
2313
2314 if (plain_messenger == NULL)
2315 return -1;
2316
2317 /* Hash the key with SHA256 to get a 32byte key. */
2318 uint8_t hash[crypto_hash_sha256_BYTES];
2319 crypto_hash_sha256(hash, key, key_length);
2320 int len = decrypt_data_symmetric(hash, data, data + crypto_secretbox_NONCEBYTES, length - crypto_secretbox_NONCEBYTES,
2321 plain_messenger);
2322 int ret;
2323
2324 if ((uint32_t)len == length - crypto_secretbox_NONCEBYTES - crypto_secretbox_MACBYTES) {
2325 ret = messenger_load(m, plain_messenger, length - crypto_secretbox_NONCEBYTES - crypto_secretbox_MACBYTES);
2326 } else {
2327 ret = -1;
2328 }
2329
2330 memset(plain_messenger, 0, length);
2331 free(plain_messenger);
2332 memset(hash, 0, crypto_hash_sha256_BYTES);
2333 return ret;
2334}
2335
2267/* Return the number of friends in the instance m. 2336/* Return the number of friends in the instance m.
2268 * You should use this to determine how much memory to allocate 2337 * You should use this to determine how much memory to allocate
2269 * for copy_friendlist. */ 2338 * for copy_friendlist. */
diff --git a/toxcore/Messenger.h b/toxcore/Messenger.h
index 61d7f86c..3cfd5065 100644
--- a/toxcore/Messenger.h
+++ b/toxcore/Messenger.h
@@ -652,6 +652,24 @@ void messenger_save(Messenger *m, uint8_t *data);
652/* Load the messenger from data of size length. */ 652/* Load the messenger from data of size length. */
653int messenger_load(Messenger *m, uint8_t *data, uint32_t length); 653int messenger_load(Messenger *m, uint8_t *data, uint32_t length);
654 654
655/* return the size of data to pass to messenger_save_encrypted(...)
656 */
657uint32_t messenger_size_encrypted(Messenger *m);
658
659/* Save the messenger, encrypting the data with key of length key_length
660 *
661 * return 0 on success.
662 * return -1 on failure.
663 */
664int messenger_save_encrypted(Messenger *m, uint8_t *data, uint8_t *key, uint16_t key_length);
665
666/* Load the messenger from data of size length encrypted with key of key_length.
667 *
668 * return 0 on success.
669 * return -1 on failure.
670 */
671int messenger_load_encrypted(Messenger *m, uint8_t *data, uint32_t length, uint8_t *key, uint16_t key_length);
672
655/* Return the number of friends in the instance m. 673/* Return the number of friends in the instance m.
656 * You should use this to determine how much memory to allocate 674 * You should use this to determine how much memory to allocate
657 * for copy_friendlist. */ 675 * for copy_friendlist. */
diff --git a/toxcore/network.h b/toxcore/network.h
index 24c7ed04..02c43e57 100644
--- a/toxcore/network.h
+++ b/toxcore/network.h
@@ -82,6 +82,7 @@ typedef int sock_t;
82#include <crypto_box.h> 82#include <crypto_box.h>
83#include <crypto_secretbox.h> 83#include <crypto_secretbox.h>
84#include <randombytes.h> 84#include <randombytes.h>
85#include <crypto_hash_sha256.h>
85#define crypto_box_MACBYTES (crypto_box_ZEROBYTES - crypto_box_BOXZEROBYTES) 86#define crypto_box_MACBYTES (crypto_box_ZEROBYTES - crypto_box_BOXZEROBYTES)
86#endif 87#endif
87 88
diff --git a/toxcore/tox.c b/toxcore/tox.c
index 87fbdf35..04e412be 100644
--- a/toxcore/tox.c
+++ b/toxcore/tox.c
@@ -749,3 +749,32 @@ int tox_load(Tox *tox, uint8_t *data, uint32_t length)
749 return messenger_load(m, data, length); 749 return messenger_load(m, data, length);
750} 750}
751 751
752/* return the size of data to pass to messenger_save_encrypted(...)
753 */
754uint32_t tox_size_encrypted(Tox *tox)
755{
756 Messenger *m = tox;
757 return messenger_size_encrypted(m);
758}
759
760/* Save the messenger, encrypting the data with key of length key_length
761 *
762 * return 0 on success.
763 * return -1 on failure.
764 */
765int tox_save_encrypted(Tox *tox, uint8_t *data, uint8_t *key, uint16_t key_length)
766{
767 Messenger *m = tox;
768 return messenger_save_encrypted(m, data, key, key_length);
769}
770
771/* Load the messenger from data of size length encrypted with key of key_length.
772 *
773 * return 0 on success.
774 * return -1 on failure.
775 */
776int tox_load_encrypted(Tox *tox, uint8_t *data, uint32_t length, uint8_t *key, uint16_t key_length)
777{
778 Messenger *m = tox;
779 return messenger_load_encrypted(m, data, length, key, key_length);
780}
diff --git a/toxcore/tox.h b/toxcore/tox.h
index 8d551c69..0ffeba62 100644
--- a/toxcore/tox.h
+++ b/toxcore/tox.h
@@ -657,9 +657,38 @@ uint32_t tox_size(Tox *tox);
657/* Save the messenger in data (must be allocated memory of size Messenger_size()). */ 657/* Save the messenger in data (must be allocated memory of size Messenger_size()). */
658void tox_save(Tox *tox, uint8_t *data); 658void tox_save(Tox *tox, uint8_t *data);
659 659
660/* Load the messenger from data of size length. */ 660/* Load the messenger from data of size length.
661 *
662 * returns 0 on success
663 * returns -1 on failure
664 */
661int tox_load(Tox *tox, uint8_t *data, uint32_t length); 665int tox_load(Tox *tox, uint8_t *data, uint32_t length);
662 666
667/**/
668
669/* return the size of data to pass to messenger_save_encrypted(...)
670 */
671uint32_t tox_size_encrypted(Tox *tox);
672
673/* Save the messenger, encrypting the data with key of length key_length
674 *
675 * This functions simply calls and then encrypt the output of tox_save(..)
676 * with crypto_secretbox(...) from NaCl/libsodium with the key
677 * given to crypto_secretbox(...) being the SHA256 sum of the key
678 * passed to this function.
679 *
680 * return 0 on success.
681 * return -1 on failure.
682 */
683int tox_save_encrypted(Tox *tox, uint8_t *data, uint8_t *key, uint16_t key_length);
684
685/* Load the messenger from data of size length encrypted with key of key_length.
686 *
687 * return 0 on success.
688 * return -1 on failure.
689 */
690int tox_load_encrypted(Tox *tox, uint8_t *data, uint32_t length, uint8_t *key, uint16_t key_length);
691
663 692
664#ifdef __cplusplus 693#ifdef __cplusplus
665} 694}