summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--auto_tests/dht_test.c10
-rw-r--r--auto_tests/messenger_test.c34
-rw-r--r--auto_tests/toxav_basic_test.c3
-rw-r--r--auto_tests/toxav_many_test.c3
-rw-r--r--toxcore/DHT.c4
-rw-r--r--toxcore/crypto_core.api.h160
-rw-r--r--toxcore/crypto_core.c61
-rw-r--r--toxcore/crypto_core.h119
-rw-r--r--toxcore/util.c1
-rw-r--r--toxencryptsave/toxencryptsave.c5
10 files changed, 258 insertions, 142 deletions
diff --git a/auto_tests/dht_test.c b/auto_tests/dht_test.c
index 7734e64a..9cec1643 100644
--- a/auto_tests/dht_test.c
+++ b/auto_tests/dht_test.c
@@ -2,13 +2,13 @@
2#include "config.h" 2#include "config.h"
3#endif 3#endif
4 4
5#include <sys/param.h> 5#include "helpers.h"
6#include <time.h>
7 6
8#include "../toxcore/DHT.c" 7#include "../toxcore/DHT.c"
9#include "../toxcore/tox.h" 8#include "../toxcore/tox.h"
10 9
11#include "helpers.h" 10#include <sys/param.h>
11#include <time.h>
12 12
13 13
14// These tests currently fail. 14// These tests currently fail.
@@ -299,6 +299,10 @@ static void test_addto_lists_good(DHT *dht,
299 ck_assert_msg(client_in_list(list, length, public_key) == -1, "Good client id is in the list"); 299 ck_assert_msg(client_in_list(list, length, public_key) == -1, "Good client id is in the list");
300} 300}
301 301
302#ifndef MAX
303#define MAX(a, b) ((a) > (b) ? (a) : (b))
304#endif
305
302static void test_addto_lists(IP ip) 306static void test_addto_lists(IP ip)
303{ 307{
304 Networking_Core *net = new_networking(NULL, ip, TOX_PORT_DEFAULT); 308 Networking_Core *net = new_networking(NULL, ip, TOX_PORT_DEFAULT);
diff --git a/auto_tests/messenger_test.c b/auto_tests/messenger_test.c
index eed52a31..03697ce6 100644
--- a/auto_tests/messenger_test.c
+++ b/auto_tests/messenger_test.c
@@ -14,18 +14,27 @@
14#include "config.h" 14#include "config.h"
15#endif 15#endif
16 16
17#include "helpers.h"
18
17#include "../testing/misc_tools.c" // hex_string_to_bin 19#include "../testing/misc_tools.c" // hex_string_to_bin
18#include "../toxcore/Messenger.h" 20#include "../toxcore/Messenger.h"
21
19#include <check.h> 22#include <check.h>
20#include <stdint.h> 23#include <stdint.h>
21#include <string.h> 24#include <string.h>
22#include <sys/types.h> 25#include <sys/types.h>
23 26
24#include "helpers.h" 27#if VANILLA_NACL
28#include <crypto_box.h> // crypto_box_PUBLICKEYBYTES and other defines.
29#else
30#include <sodium.h>
31#endif
25 32
26#define REALLY_BIG_NUMBER ((1) << (sizeof(uint16_t) * 7)) 33#define REALLY_BIG_NUMBER ((1) << (sizeof(uint16_t) * 7))
27#define STRINGS_EQUAL(X, Y) (strcmp(X, Y) == 0) 34#define STRINGS_EQUAL(X, Y) (strcmp(X, Y) == 0)
28 35
36static bool enable_broken_tests = false;
37
29static const char *friend_id_str = "e4b3d5030bc99494605aecc33ceec8875640c1d74aa32790e821b17e98771c4a00000000f1db"; 38static const char *friend_id_str = "e4b3d5030bc99494605aecc33ceec8875640c1d74aa32790e821b17e98771c4a00000000f1db";
30 39
31/* in case we need more than one ID for a test */ 40/* in case we need more than one ID for a test */
@@ -121,11 +130,10 @@ START_TEST(test_m_delfriend)
121} 130}
122END_TEST 131END_TEST
123 132
124#if 0
125START_TEST(test_m_addfriend) 133START_TEST(test_m_addfriend)
126{ 134{
127 char *good_data = "test"; 135 const char *good_data = "test";
128 char *bad_data = ""; 136 const char *bad_data = "";
129 137
130 int good_len = strlen(good_data); 138 int good_len = strlen(good_data);
131 int bad_len = strlen(bad_data); 139 int bad_len = strlen(bad_data);
@@ -134,30 +142,29 @@ START_TEST(test_m_addfriend)
134 + crypto_box_ZEROBYTES + 100); 142 + crypto_box_ZEROBYTES + 100);
135 143
136 /* TODO(irungentoo): Update this properly to latest master */ 144 /* TODO(irungentoo): Update this properly to latest master */
137 if (m_addfriend(m, (uint8_t *)friend_id, (uint8_t *)good_data, really_bad_len) != FAERR_TOOLONG) { 145 if (m_addfriend(m, (const uint8_t *)friend_id, (const uint8_t *)good_data, really_bad_len) != FAERR_TOOLONG) {
138 ck_abort_msg("m_addfriend did NOT catch the following length: %d\n", really_bad_len); 146 ck_abort_msg("m_addfriend did NOT catch the following length: %d\n", really_bad_len);
139 } 147 }
140 148
141 /* this will return an error if the original m_addfriend_norequest() failed */ 149 /* this will return an error if the original m_addfriend_norequest() failed */
142 if (m_addfriend(m, (uint8_t *)friend_id, (uint8_t *)good_data, good_len) != FAERR_ALREADYSENT) { 150 if (m_addfriend(m, (const uint8_t *)friend_id, (const uint8_t *)good_data, good_len) != FAERR_ALREADYSENT) {
143 ck_abort_msg("m_addfriend did NOT catch adding a friend we already have.\n" 151 ck_abort_msg("m_addfriend did NOT catch adding a friend we already have.\n"
144 "(this can be caused by the error of m_addfriend_norequest in" 152 "(this can be caused by the error of m_addfriend_norequest in"
145 " the beginning of the suite)\n"); 153 " the beginning of the suite)\n");
146 } 154 }
147 155
148 if (m_addfriend(m, (uint8_t *)good_id_b, (uint8_t *)bad_data, bad_len) != FAERR_NOMESSAGE) { 156 if (m_addfriend(m, (const uint8_t *)good_id_b, (const uint8_t *)bad_data, bad_len) != FAERR_NOMESSAGE) {
149 ck_abort_msg("m_addfriend did NOT catch the following length: %d\n", bad_len); 157 ck_abort_msg("m_addfriend did NOT catch the following length: %d\n", bad_len);
150 } 158 }
151 159
152 /* this should REALLY return an error */ 160 /* this should REALLY return an error */
153 /* TODO(irungentoo): validate client_id in m_addfriend? */ 161 /* TODO(irungentoo): validate client_id in m_addfriend? */
154 if (m_addfriend((uint8_t *)bad_id, (uint8_t *)good_data, good_len) >= 0) { 162 if (m_addfriend(m, (const uint8_t *)bad_id, (const uint8_t *)good_data, good_len) >= 0) {
155 ck_abort_msg("The following ID passed through " 163 ck_abort_msg("The following ID passed through "
156 "m_addfriend without an error:\n'%s'\n", bad_id_str); 164 "m_addfriend without an error:\n'%s'\n", bad_id_str);
157 } 165 }
158} 166}
159END_TEST 167END_TEST
160#endif
161 168
162START_TEST(test_setname) 169START_TEST(test_setname)
163{ 170{
@@ -193,7 +200,7 @@ END_TEST
193 * ideas: 200 * ideas:
194 * if we have access to the friends list, we could 201 * if we have access to the friends list, we could
195 * just add a status manually ourselves. */ 202 * just add a status manually ourselves. */
196/* 203#if 0
197START_TEST(test_m_copy_userstatus) 204START_TEST(test_m_copy_userstatus)
198{ 205{
199 assert(m_copy_userstatus(-1, buf, MAX_USERSTATUS_LENGTH) == -1); 206 assert(m_copy_userstatus(-1, buf, MAX_USERSTATUS_LENGTH) == -1);
@@ -203,7 +210,7 @@ START_TEST(test_m_copy_userstatus)
203 assert(STRINGS_EQUAL(name_buf, friend_id_status)); 210 assert(STRINGS_EQUAL(name_buf, friend_id_status));
204} 211}
205END_TEST 212END_TEST
206*/ 213#endif
207 214
208START_TEST(test_getname) 215START_TEST(test_getname)
209{ 216{
@@ -316,7 +323,10 @@ static Suite *messenger_suite(void)
316 DEFTESTCASE(m_get_userstatus_size); 323 DEFTESTCASE(m_get_userstatus_size);
317 DEFTESTCASE(m_set_userstatus); 324 DEFTESTCASE(m_set_userstatus);
318 325
319 /* DEFTESTCASE(m_addfriend); */ 326 if (enable_broken_tests) {
327 DEFTESTCASE(m_addfriend);
328 }
329
320 DEFTESTCASE(m_friend_exists); 330 DEFTESTCASE(m_friend_exists);
321 DEFTESTCASE(m_get_friend_connectionstatus); 331 DEFTESTCASE(m_get_friend_connectionstatus);
322 DEFTESTCASE(m_delfriend); 332 DEFTESTCASE(m_delfriend);
diff --git a/auto_tests/toxav_basic_test.c b/auto_tests/toxav_basic_test.c
index b5028da4..767fca87 100644
--- a/auto_tests/toxav_basic_test.c
+++ b/auto_tests/toxav_basic_test.c
@@ -20,7 +20,8 @@
20#include "../toxcore/util.h" 20#include "../toxcore/util.h"
21 21
22 22
23#if defined(_WIN32) || defined(__WIN32__) || defined (WIN32) 23#if defined(_WIN32) || defined(__WIN32__) || defined(WIN32)
24#include <windows.h>
24#define c_sleep(x) Sleep(1*x) 25#define c_sleep(x) Sleep(1*x)
25#else 26#else
26#include <unistd.h> 27#include <unistd.h>
diff --git a/auto_tests/toxav_many_test.c b/auto_tests/toxav_many_test.c
index 59e4f94b..b33b93c8 100644
--- a/auto_tests/toxav_many_test.c
+++ b/auto_tests/toxav_many_test.c
@@ -19,7 +19,8 @@
19#include "../toxcore/tox.h" 19#include "../toxcore/tox.h"
20#include "../toxcore/util.h" 20#include "../toxcore/util.h"
21 21
22#if defined(_WIN32) || defined(__WIN32__) || defined (WIN32) 22#if defined(_WIN32) || defined(__WIN32__) || defined(WIN32)
23#include <windows.h>
23#define c_sleep(x) Sleep(1*x) 24#define c_sleep(x) Sleep(1*x)
24#else 25#else
25#include <pthread.h> 26#include <pthread.h>
diff --git a/toxcore/DHT.c b/toxcore/DHT.c
index e31405fd..23faf57b 100644
--- a/toxcore/DHT.c
+++ b/toxcore/DHT.c
@@ -197,7 +197,7 @@ int create_request(const uint8_t *send_public_key, const uint8_t *send_secret_ke
197 197
198 uint8_t *nonce = packet + 1 + CRYPTO_PUBLIC_KEY_SIZE * 2; 198 uint8_t *nonce = packet + 1 + CRYPTO_PUBLIC_KEY_SIZE * 2;
199 random_nonce(nonce); 199 random_nonce(nonce);
200 uint8_t temp[MAX_CRYPTO_REQUEST_SIZE]; // TODO(irungentoo): sodium_memzero before exit function 200 uint8_t temp[MAX_CRYPTO_REQUEST_SIZE]; // TODO(irungentoo): crypto_memzero before exit function
201 memcpy(temp + 1, data, length); 201 memcpy(temp + 1, data, length);
202 temp[0] = request_id; 202 temp[0] = request_id;
203 int len = encrypt_data(recv_public_key, send_secret_key, nonce, temp, length + 1, 203 int len = encrypt_data(recv_public_key, send_secret_key, nonce, temp, length + 1,
@@ -238,7 +238,7 @@ int handle_request(const uint8_t *self_public_key, const uint8_t *self_secret_ke
238 238
239 memcpy(public_key, packet + 1 + CRYPTO_PUBLIC_KEY_SIZE, CRYPTO_PUBLIC_KEY_SIZE); 239 memcpy(public_key, packet + 1 + CRYPTO_PUBLIC_KEY_SIZE, CRYPTO_PUBLIC_KEY_SIZE);
240 const uint8_t *nonce = packet + 1 + CRYPTO_PUBLIC_KEY_SIZE * 2; 240 const uint8_t *nonce = packet + 1 + CRYPTO_PUBLIC_KEY_SIZE * 2;
241 uint8_t temp[MAX_CRYPTO_REQUEST_SIZE]; // TODO(irungentoo): sodium_memzero before exit function 241 uint8_t temp[MAX_CRYPTO_REQUEST_SIZE]; // TODO(irungentoo): crypto_memzero before exit function
242 int len1 = decrypt_data(public_key, self_secret_key, nonce, 242 int len1 = decrypt_data(public_key, self_secret_key, nonce,
243 packet + 1 + CRYPTO_PUBLIC_KEY_SIZE * 2 + CRYPTO_NONCE_SIZE, 243 packet + 1 + CRYPTO_PUBLIC_KEY_SIZE * 2 + CRYPTO_NONCE_SIZE,
244 length - (CRYPTO_PUBLIC_KEY_SIZE * 2 + CRYPTO_NONCE_SIZE + 1), temp); 244 length - (CRYPTO_PUBLIC_KEY_SIZE * 2 + CRYPTO_NONCE_SIZE + 1), temp);
diff --git a/toxcore/crypto_core.api.h b/toxcore/crypto_core.api.h
index 78a17280..6f0b1b0b 100644
--- a/toxcore/crypto_core.api.h
+++ b/toxcore/crypto_core.api.h
@@ -21,10 +21,12 @@
21 * along with Tox. If not, see <http://www.gnu.org/licenses/>. 21 * along with Tox. If not, see <http://www.gnu.org/licenses/>.
22 * 22 *
23 */ 23 */
24#ifndef CORE_CRYPTO_H 24#ifndef CRYPTO_CORE_H
25#define CORE_CRYPTO_H 25#define CRYPTO_CORE_H
26 26
27#include "network.h" 27#include <stdbool.h>
28#include <stdint.h>
29#include <stdlib.h>
28%} 30%}
29 31
30/** 32/**
@@ -38,12 +40,12 @@ const CRYPTO_PUBLIC_KEY_SIZE = 32;
38const CRYPTO_SECRET_KEY_SIZE = 32; 40const CRYPTO_SECRET_KEY_SIZE = 32;
39 41
40/** 42/**
41 * The number of bytes in a shared key computed from public and secret key. 43 * The number of bytes in a shared key computed from public and secret keys.
42 */ 44 */
43const CRYPTO_SHARED_KEY_SIZE = 32; 45const CRYPTO_SHARED_KEY_SIZE = 32;
44 46
45/** 47/**
46 * The number of bytes in a random symmetric key. 48 * The number of bytes in a symmetric key.
47 */ 49 */
48const CRYPTO_SYMMETRIC_KEY_SIZE = CRYPTO_SHARED_KEY_SIZE; 50const CRYPTO_SYMMETRIC_KEY_SIZE = CRYPTO_SHARED_KEY_SIZE;
49 51
@@ -68,20 +70,44 @@ const CRYPTO_SHA256_SIZE = 32;
68 */ 70 */
69const CRYPTO_SHA512_SIZE = 64; 71const CRYPTO_SHA512_SIZE = 64;
70 72
73/**
74 * A `memcmp`-like function whose running time does not depend on the input
75 * bytes, only on the input length. Useful to compare sensitive data where
76 * timing attacks could reveal that data.
77 *
78 * This means for instance that comparing "aaaa" and "aaaa" takes 4 time, and
79 * "aaaa" and "baaa" also takes 4 time. With a regular `memcmp`, the latter may
80 * take 1 time, because it immediately knows that the two strings are not equal.
81 */
71static int32_t crypto_memcmp(const void *p1, const void *p2, size_t length); 82static int32_t crypto_memcmp(const void *p1, const void *p2, size_t length);
83
84/**
85 * A `bzero`-like function which won't be optimised away by the compiler. Some
86 * compilers will inline `bzero` or `memset` if they can prove that there will
87 * be no reads to the written data. Use this function if you want to be sure the
88 * memory is indeed zeroed.
89 */
72static void crypto_memzero(void *data, size_t length); 90static void crypto_memzero(void *data, size_t length);
73 91
74static void crypto_sha256(uint8_t *hash, const uint8_t[length] data); 92/**
75static void crypto_sha512(uint8_t *hash, const uint8_t[length] data); 93 * Compute a SHA256 hash (32 bytes).
94 */
95static void crypto_sha256(uint8_t[CRYPTO_SHA256_SIZE] hash, const uint8_t[length] data);
76 96
77static void crypto_derive_public_key(uint8_t *public_key, uint8_t *secret_key); 97/**
98 * Compute a SHA512 hash (64 bytes).
99 */
100static void crypto_sha512(uint8_t[CRYPTO_SHA512_SIZE] hash, const uint8_t[length] data);
78 101
79/** 102/**
80 * compare 2 public keys of length CRYPTO_PUBLIC_KEY_SIZE, not vulnerable to timing attacks. 103 * Compare 2 public keys of length CRYPTO_PUBLIC_KEY_SIZE, not vulnerable to
81 * returns 0 if both mem locations of length are equal, 104 * timing attacks.
82 * return -1 if they are not. 105 *
106 * @return 0 if both mem locations of length are equal, -1 if they are not.
83 */ 107 */
84static int32_t public_key_cmp(const uint8_t *pk1, const uint8_t *pk2); 108static int32_t public_key_cmp(
109 const uint8_t[CRYPTO_PUBLIC_KEY_SIZE] pk1,
110 const uint8_t[CRYPTO_PUBLIC_KEY_SIZE] pk2);
85 111
86/** 112/**
87 * Return a random 32 bit integer. 113 * Return a random 32 bit integer.
@@ -94,88 +120,120 @@ static uint32_t random_int();
94static uint64_t random_64b(); 120static uint64_t random_64b();
95 121
96/** 122/**
97 * Check if a Tox public key CRYPTO_PUBLIC_KEY_SIZE is valid or not. 123 * Check if a Tox public key CRYPTO_PUBLIC_KEY_SIZE is valid or not. This
98 * This should only be used for input validation. 124 * should only be used for input validation.
99 * 125 *
100 * return 0 if it isn't. 126 * @return false if it isn't, true if it is.
101 * return 1 if it is. 127 */
128static bool public_key_valid(const uint8_t[CRYPTO_PUBLIC_KEY_SIZE] public_key);
129
130/**
131 * Generate a new random keypair. Every call to this function is likely to
132 * generate a different keypair.
102 */ 133 */
103static int32_t public_key_valid(const uint8_t *public_key); 134static int32_t crypto_new_keypair(
135 uint8_t[CRYPTO_PUBLIC_KEY_SIZE] public_key,
136 uint8_t[CRYPTO_SECRET_KEY_SIZE] secret_key);
104 137
105static int32_t crypto_new_keypair(uint8_t *public_key, uint8_t *secret_key); 138/**
139 * Derive the public key from a given secret key.
140 */
141static void crypto_derive_public_key(
142 uint8_t[CRYPTO_PUBLIC_KEY_SIZE] public_key,
143 const uint8_t[CRYPTO_SECRET_KEY_SIZE] secret_key);
106 144
107/** 145/**
108 * Encrypts plain of length length to encrypted of length + 16 using the 146 * Encrypt plain text of the given length to encrypted of length +
109 * public key(32 bytes) of the receiver and the secret key of the sender and a 24 byte nonce. 147 * $CRYPTO_MAC_SIZE using the public key ($CRYPTO_PUBLIC_KEY_SIZE bytes) of the
148 * receiver and the secret key of the sender and a $CRYPTO_NONCE_SIZE byte
149 * nonce.
110 * 150 *
111 * return -1 if there was a problem. 151 * @return -1 if there was a problem, length of encrypted data if everything
112 * return length of encrypted data if everything was fine. 152 * was fine.
113 */ 153 */
114static int32_t encrypt_data( 154static int32_t encrypt_data(
115 const uint8_t *public_key, const uint8_t *secret_key, const uint8_t *nonce, 155 const uint8_t[CRYPTO_PUBLIC_KEY_SIZE] public_key,
116 const uint8_t *plain, uint32_t length, uint8_t *encrypted); 156 const uint8_t[CRYPTO_SECRET_KEY_SIZE] secret_key,
157 const uint8_t[CRYPTO_NONCE_SIZE] nonce,
158 const uint8_t[length] plain,
159 uint8_t *encrypted);
117 160
118 161
119/** 162/**
120 * Decrypts encrypted of length length to plain of length length - 16 using the 163 * Decrypt encrypted text of the given length to plain text of the given length
121 * public key(32 bytes) of the sender, the secret key of the receiver and a 24 byte nonce. 164 * - $CRYPTO_MAC_SIZE using the public key ($CRYPTO_PUBLIC_KEY_SIZE bytes) of
165 * the sender, the secret key of the receiver and a $CRYPTO_NONCE_SIZE byte
166 * nonce.
122 * 167 *
123 * return -1 if there was a problem (decryption failed). 168 * @return -1 if there was a problem (decryption failed), length of plain text
124 * return length of plain data if everything was fine. 169 * data if everything was fine.
125 */ 170 */
126static int32_t decrypt_data( 171static int32_t decrypt_data(
127 const uint8_t *public_key, const uint8_t *secret_key, const uint8_t *nonce, 172 const uint8_t[CRYPTO_PUBLIC_KEY_SIZE] public_key,
128 const uint8_t *encrypted, uint32_t length, uint8_t *plain); 173 const uint8_t[CRYPTO_SECRET_KEY_SIZE] secret_key,
174 const uint8_t[CRYPTO_NONCE_SIZE] nonce,
175 const uint8_t[length] encrypted,
176 uint8_t *plain);
129 177
130/** 178/**
131 * Fast encrypt/decrypt operations. Use if this is not a one-time communication. 179 * Fast encrypt/decrypt operations. Use if this is not a one-time communication.
132 * encrypt_precompute does the shared-key generation once so it does not have 180 * $encrypt_precompute does the shared-key generation once so it does not have
133 * to be preformed on every encrypt/decrypt. 181 * to be preformed on every encrypt/decrypt.
134 */ 182 */
135static int32_t encrypt_precompute( 183static int32_t encrypt_precompute(
136 const uint8_t *public_key, const uint8_t *secret_key, uint8_t *enc_key); 184 const uint8_t[CRYPTO_PUBLIC_KEY_SIZE] public_key,
185 const uint8_t[CRYPTO_SECRET_KEY_SIZE] secret_key,
186 uint8_t[CRYPTO_SHARED_KEY_SIZE] shared_key);
137 187
138/** 188/**
139 * Encrypts plain of length length to encrypted of length + 16 using a 189 * Encrypts plain of length length to encrypted of length + $CRYPTO_MAC_SIZE
140 * secret key CRYPTO_SYMMETRIC_KEY_SIZE big and a 24 byte nonce. 190 * using a shared key $CRYPTO_SYMMETRIC_KEY_SIZE big and a $CRYPTO_NONCE_SIZE
191 * byte nonce.
141 * 192 *
142 * return -1 if there was a problem. 193 * @return -1 if there was a problem, length of encrypted data if everything
143 * return length of encrypted data if everything was fine. 194 * was fine.
144 */ 195 */
145static int32_t encrypt_data_symmetric( 196static int32_t encrypt_data_symmetric(
146 const uint8_t *secret_key, const uint8_t *nonce, const uint8_t *plain, 197 const uint8_t[CRYPTO_SHARED_KEY_SIZE] shared_key,
147 uint32_t length, uint8_t *encrypted); 198 const uint8_t[CRYPTO_NONCE_SIZE] nonce,
199 const uint8_t[length] plain,
200 uint8_t *encrypted);
148 201
149/** 202/**
150 * Decrypts encrypted of length length to plain of length length - 16 using a 203 * Decrypts encrypted of length length to plain of length length -
151 * secret key CRYPTO_SYMMETRIC_KEY_SIZE big and a 24 byte nonce. 204 * $CRYPTO_MAC_SIZE using a shared key CRYPTO_SHARED_KEY_SIZE big and a
205 * $CRYPTO_NONCE_SIZE byte nonce.
152 * 206 *
153 * return -1 if there was a problem (decryption failed). 207 * @return -1 if there was a problem (decryption failed), length of plain data
154 * return length of plain data if everything was fine. 208 * if everything was fine.
155 */ 209 */
156static int32_t decrypt_data_symmetric( 210static int32_t decrypt_data_symmetric(
157 const uint8_t *secret_key, const uint8_t *nonce, const uint8_t *encrypted, 211 const uint8_t[CRYPTO_SHARED_KEY_SIZE] shared_key,
158 uint32_t length, uint8_t *plain); 212 const uint8_t[CRYPTO_NONCE_SIZE] nonce,
213 const uint8_t[length] encrypted,
214 uint8_t *plain);
159 215
160/** 216/**
161 * Increment the given nonce by 1. 217 * Increment the given nonce by 1 in big endian (rightmost byte incremented
218 * first).
162 */ 219 */
163static void increment_nonce(uint8_t *nonce); 220static void increment_nonce(uint8_t[CRYPTO_NONCE_SIZE] nonce);
164 221
165/** 222/**
166 * Increment the given nonce by num. 223 * Increment the given nonce by a given number. The number should be in host
224 * byte order.
167 */ 225 */
168static void increment_nonce_number(uint8_t *nonce, uint32_t host_order_num); 226static void increment_nonce_number(uint8_t[CRYPTO_NONCE_SIZE] nonce, uint32_t host_order_num);
169 227
170/** 228/**
171 * Fill the given nonce with random bytes. 229 * Fill the given nonce with random bytes.
172 */ 230 */
173static void random_nonce(uint8_t *nonce); 231static void random_nonce(uint8_t[CRYPTO_NONCE_SIZE] nonce);
174 232
175/** 233/**
176 * Fill a key CRYPTO_SYMMETRIC_KEY_SIZE big with random bytes. 234 * Fill a key CRYPTO_SYMMETRIC_KEY_SIZE big with random bytes.
177 */ 235 */
178static void new_symmetric_key(uint8_t *key); 236static void new_symmetric_key(uint8_t[CRYPTO_SYMMETRIC_KEY_SIZE] key);
179 237
180/** 238/**
181 * Fill an array of bytes with random values. 239 * Fill an array of bytes with random values.
@@ -183,5 +241,5 @@ static void new_symmetric_key(uint8_t *key);
183static void random_bytes(uint8_t[length] bytes); 241static void random_bytes(uint8_t[length] bytes);
184 242
185%{ 243%{
186#endif 244#endif /* CRYPTO_CORE_H */
187%} 245%}
diff --git a/toxcore/crypto_core.c b/toxcore/crypto_core.c
index d4f7c562..d3a3e1fc 100644
--- a/toxcore/crypto_core.c
+++ b/toxcore/crypto_core.c
@@ -29,6 +29,10 @@
29 29
30#include "crypto_core.h" 30#include "crypto_core.h"
31 31
32#include "network.h"
33
34#include <string.h>
35
32#ifndef VANILLA_NACL 36#ifndef VANILLA_NACL
33/* We use libsodium by default. */ 37/* We use libsodium by default. */
34#include <sodium.h> 38#include <sodium.h>
@@ -41,9 +45,6 @@
41#include <crypto_verify_32.h> 45#include <crypto_verify_32.h>
42#include <randombytes.h> 46#include <randombytes.h>
43#define crypto_box_MACBYTES (crypto_box_ZEROBYTES - crypto_box_BOXZEROBYTES) 47#define crypto_box_MACBYTES (crypto_box_ZEROBYTES - crypto_box_BOXZEROBYTES)
44/* I know */
45#define sodium_memcmp(a, b, c) memcmp(a, b, c)
46#define sodium_memzero(a, c) memset(a, 0, c)
47#endif 48#endif
48 49
49#if CRYPTO_PUBLIC_KEY_SIZE != crypto_box_PUBLICKEYBYTES 50#if CRYPTO_PUBLIC_KEY_SIZE != crypto_box_PUBLICKEYBYTES
@@ -78,19 +79,14 @@
78#error CRYPTO_SHA512_SIZE should be equal to crypto_hash_sha512_BYTES 79#error CRYPTO_SHA512_SIZE should be equal to crypto_hash_sha512_BYTES
79#endif 80#endif
80 81
81/* compare 2 public keys of length crypto_box_PUBLICKEYBYTES, not vulnerable to timing attacks. 82int32_t public_key_cmp(const uint8_t *pk1, const uint8_t *pk2)
82 returns 0 if both mem locations of length are equal,
83 return -1 if they are not. */
84int public_key_cmp(const uint8_t *pk1, const uint8_t *pk2)
85{ 83{
86#if crypto_box_PUBLICKEYBYTES != 32 84#if CRYPTO_PUBLIC_KEY_SIZE != 32
87#error crypto_box_PUBLICKEYBYTES is required to be 32 bytes for public_key_cmp to work, 85#error CRYPTO_PUBLIC_KEY_SIZE is required to be 32 bytes for public_key_cmp to work,
88#endif 86#endif
89 return crypto_verify_32(pk1, pk2); 87 return crypto_verify_32(pk1, pk2);
90} 88}
91 89
92/* return a random number.
93 */
94uint32_t random_int(void) 90uint32_t random_int(void)
95{ 91{
96 uint32_t randnum; 92 uint32_t randnum;
@@ -105,13 +101,7 @@ uint64_t random_64b(void)
105 return randnum; 101 return randnum;
106} 102}
107 103
108/* Check if a Tox public key crypto_box_PUBLICKEYBYTES is valid or not. 104bool public_key_valid(const uint8_t *public_key)
109 * This should only be used for input validation.
110 *
111 * return 0 if it isn't.
112 * return 1 if it is.
113 */
114int public_key_valid(const uint8_t *public_key)
115{ 105{
116 if (public_key[31] >= 128) { /* Last bit of key is always zero. */ 106 if (public_key[31] >= 128) { /* Last bit of key is always zero. */
117 return 0; 107 return 0;
@@ -123,15 +113,15 @@ int public_key_valid(const uint8_t *public_key)
123/* Precomputes the shared key from their public_key and our secret_key. 113/* Precomputes the shared key from their public_key and our secret_key.
124 * This way we can avoid an expensive elliptic curve scalar multiply for each 114 * This way we can avoid an expensive elliptic curve scalar multiply for each
125 * encrypt/decrypt operation. 115 * encrypt/decrypt operation.
126 * enc_key has to be crypto_box_BEFORENMBYTES bytes long. 116 * shared_key has to be crypto_box_BEFORENMBYTES bytes long.
127 */ 117 */
128int encrypt_precompute(const uint8_t *public_key, const uint8_t *secret_key, uint8_t *enc_key) 118int32_t encrypt_precompute(const uint8_t *public_key, const uint8_t *secret_key, uint8_t *shared_key)
129{ 119{
130 return crypto_box_beforenm(enc_key, public_key, secret_key); 120 return crypto_box_beforenm(shared_key, public_key, secret_key);
131} 121}
132 122
133int encrypt_data_symmetric(const uint8_t *secret_key, const uint8_t *nonce, const uint8_t *plain, uint32_t length, 123int32_t encrypt_data_symmetric(const uint8_t *secret_key, const uint8_t *nonce, const uint8_t *plain, size_t length,
134 uint8_t *encrypted) 124 uint8_t *encrypted)
135{ 125{
136 if (length == 0 || !secret_key || !nonce || !plain || !encrypted) { 126 if (length == 0 || !secret_key || !nonce || !plain || !encrypted) {
137 return -1; 127 return -1;
@@ -152,8 +142,8 @@ int encrypt_data_symmetric(const uint8_t *secret_key, const uint8_t *nonce, cons
152 return length + crypto_box_MACBYTES; 142 return length + crypto_box_MACBYTES;
153} 143}
154 144
155int decrypt_data_symmetric(const uint8_t *secret_key, const uint8_t *nonce, const uint8_t *encrypted, uint32_t length, 145int32_t decrypt_data_symmetric(const uint8_t *secret_key, const uint8_t *nonce, const uint8_t *encrypted, size_t length,
156 uint8_t *plain) 146 uint8_t *plain)
157{ 147{
158 if (length <= crypto_box_BOXZEROBYTES || !secret_key || !nonce || !encrypted || !plain) { 148 if (length <= crypto_box_BOXZEROBYTES || !secret_key || !nonce || !encrypted || !plain) {
159 return -1; 149 return -1;
@@ -173,8 +163,8 @@ int decrypt_data_symmetric(const uint8_t *secret_key, const uint8_t *nonce, cons
173 return length - crypto_box_MACBYTES; 163 return length - crypto_box_MACBYTES;
174} 164}
175 165
176int encrypt_data(const uint8_t *public_key, const uint8_t *secret_key, const uint8_t *nonce, 166int32_t encrypt_data(const uint8_t *public_key, const uint8_t *secret_key, const uint8_t *nonce,
177 const uint8_t *plain, uint32_t length, uint8_t *encrypted) 167 const uint8_t *plain, size_t length, uint8_t *encrypted)
178{ 168{
179 if (!public_key || !secret_key) { 169 if (!public_key || !secret_key) {
180 return -1; 170 return -1;
@@ -187,8 +177,8 @@ int encrypt_data(const uint8_t *public_key, const uint8_t *secret_key, const uin
187 return ret; 177 return ret;
188} 178}
189 179
190int decrypt_data(const uint8_t *public_key, const uint8_t *secret_key, const uint8_t *nonce, 180int32_t decrypt_data(const uint8_t *public_key, const uint8_t *secret_key, const uint8_t *nonce,
191 const uint8_t *encrypted, uint32_t length, uint8_t *plain) 181 const uint8_t *encrypted, size_t length, uint8_t *plain)
192{ 182{
193 if (!public_key || !secret_key) { 183 if (!public_key || !secret_key) {
194 return -1; 184 return -1;
@@ -263,7 +253,7 @@ int32_t crypto_new_keypair(uint8_t *public_key, uint8_t *secret_key)
263 return crypto_box_keypair(public_key, secret_key); 253 return crypto_box_keypair(public_key, secret_key);
264} 254}
265 255
266void crypto_derive_public_key(uint8_t *public_key, uint8_t *secret_key) 256void crypto_derive_public_key(uint8_t *public_key, const uint8_t *secret_key)
267{ 257{
268 crypto_scalarmult_curve25519_base(public_key, secret_key); 258 crypto_scalarmult_curve25519_base(public_key, secret_key);
269} 259}
@@ -280,12 +270,23 @@ void crypto_sha512(uint8_t *hash, const uint8_t *data, size_t length)
280 270
281void crypto_memzero(void *data, size_t length) 271void crypto_memzero(void *data, size_t length)
282{ 272{
273#ifdef VANILLA_NACL
274 /* TODO(c-toxcore#347): this is insecure. We need to provide our own
275 * secure memzero/memcmp for NaCL. */
276 memset(data, 0, length);
277#else
283 sodium_memzero(data, length); 278 sodium_memzero(data, length);
279#endif
284} 280}
285 281
286int32_t crypto_memcmp(const void *p1, const void *p2, size_t length) 282int32_t crypto_memcmp(const void *p1, const void *p2, size_t length)
287{ 283{
284#ifdef VANILLA_NACL
285 /* TODO(c-toxcore#347): Implement secure memcmp. */
286 return memcmp(p1, p2, length);
287#else
288 return sodium_memcmp(p1, p2, length); 288 return sodium_memcmp(p1, p2, length);
289#endif
289} 290}
290 291
291void random_bytes(uint8_t *data, size_t length) 292void random_bytes(uint8_t *data, size_t length)
diff --git a/toxcore/crypto_core.h b/toxcore/crypto_core.h
index a5cea019..56476e38 100644
--- a/toxcore/crypto_core.h
+++ b/toxcore/crypto_core.h
@@ -20,10 +20,12 @@
20 * along with Tox. If not, see <http://www.gnu.org/licenses/>. 20 * along with Tox. If not, see <http://www.gnu.org/licenses/>.
21 * 21 *
22 */ 22 */
23#ifndef CORE_CRYPTO_H 23#ifndef CRYPTO_CORE_H
24#define CORE_CRYPTO_H 24#define CRYPTO_CORE_H
25 25
26#include "network.h" 26#include <stdbool.h>
27#include <stdint.h>
28#include <stdlib.h>
27 29
28/** 30/**
29 * The number of bytes in a Tox public key. 31 * The number of bytes in a Tox public key.
@@ -40,14 +42,14 @@ uint32_t crypto_public_key_size(void);
40uint32_t crypto_secret_key_size(void); 42uint32_t crypto_secret_key_size(void);
41 43
42/** 44/**
43 * The number of bytes in a shared key computed from public and secret key. 45 * The number of bytes in a shared key computed from public and secret keys.
44 */ 46 */
45#define CRYPTO_SHARED_KEY_SIZE 32 47#define CRYPTO_SHARED_KEY_SIZE 32
46 48
47uint32_t crypto_shared_key_size(void); 49uint32_t crypto_shared_key_size(void);
48 50
49/** 51/**
50 * The number of bytes in a random symmetric key. 52 * The number of bytes in a symmetric key.
51 */ 53 */
52#define CRYPTO_SYMMETRIC_KEY_SIZE CRYPTO_SHARED_KEY_SIZE 54#define CRYPTO_SYMMETRIC_KEY_SIZE CRYPTO_SHARED_KEY_SIZE
53 55
@@ -82,20 +84,40 @@ uint32_t crypto_sha256_size(void);
82 84
83uint32_t crypto_sha512_size(void); 85uint32_t crypto_sha512_size(void);
84 86
87/**
88 * A `memcmp`-like function whose running time does not depend on the input
89 * bytes, only on the input length. Useful to compare sensitive data where
90 * timing attacks could reveal that data.
91 *
92 * This means for instance that comparing "aaaa" and "aaaa" takes 4 time, and
93 * "aaaa" and "baaa" also takes 4 time. With a regular `memcmp`, the latter may
94 * take 1 time, because it immediately knows that the two strings are not equal.
95 */
85int32_t crypto_memcmp(const void *p1, const void *p2, size_t length); 96int32_t crypto_memcmp(const void *p1, const void *p2, size_t length);
86 97
98/**
99 * A `bzero`-like function which won't be optimised away by the compiler. Some
100 * compilers will inline `bzero` or `memset` if they can prove that there will
101 * be no reads to the written data. Use this function if you want to be sure the
102 * memory is indeed zeroed.
103 */
87void crypto_memzero(void *data, size_t length); 104void crypto_memzero(void *data, size_t length);
88 105
106/**
107 * Compute a SHA256 hash (32 bytes).
108 */
89void crypto_sha256(uint8_t *hash, const uint8_t *data, size_t length); 109void crypto_sha256(uint8_t *hash, const uint8_t *data, size_t length);
90 110
111/**
112 * Compute a SHA512 hash (64 bytes).
113 */
91void crypto_sha512(uint8_t *hash, const uint8_t *data, size_t length); 114void crypto_sha512(uint8_t *hash, const uint8_t *data, size_t length);
92 115
93void crypto_derive_public_key(uint8_t *public_key, uint8_t *secret_key);
94
95/** 116/**
96 * compare 2 public keys of length CRYPTO_PUBLIC_KEY_SIZE, not vulnerable to timing attacks. 117 * Compare 2 public keys of length CRYPTO_PUBLIC_KEY_SIZE, not vulnerable to
97 * returns 0 if both mem locations of length are equal, 118 * timing attacks.
98 * return -1 if they are not. 119 *
120 * @return 0 if both mem locations of length are equal, -1 if they are not.
99 */ 121 */
100int32_t public_key_cmp(const uint8_t *pk1, const uint8_t *pk2); 122int32_t public_key_cmp(const uint8_t *pk1, const uint8_t *pk2);
101 123
@@ -110,70 +132,86 @@ uint32_t random_int(void);
110uint64_t random_64b(void); 132uint64_t random_64b(void);
111 133
112/** 134/**
113 * Check if a Tox public key CRYPTO_PUBLIC_KEY_SIZE is valid or not. 135 * Check if a Tox public key CRYPTO_PUBLIC_KEY_SIZE is valid or not. This
114 * This should only be used for input validation. 136 * should only be used for input validation.
115 * 137 *
116 * return 0 if it isn't. 138 * @return false if it isn't, true if it is.
117 * return 1 if it is.
118 */ 139 */
119int32_t public_key_valid(const uint8_t *public_key); 140bool public_key_valid(const uint8_t *public_key);
120 141
142/**
143 * Generate a new random keypair. Every call to this function is likely to
144 * generate a different keypair.
145 */
121int32_t crypto_new_keypair(uint8_t *public_key, uint8_t *secret_key); 146int32_t crypto_new_keypair(uint8_t *public_key, uint8_t *secret_key);
122 147
123/** 148/**
124 * Encrypts plain of length length to encrypted of length + 16 using the 149 * Derive the public key from a given secret key.
125 * public key(32 bytes) of the receiver and the secret key of the sender and a 24 byte nonce. 150 */
151void crypto_derive_public_key(uint8_t *public_key, const uint8_t *secret_key);
152
153/**
154 * Encrypt plain text of the given length to encrypted of length +
155 * CRYPTO_MAC_SIZE using the public key (CRYPTO_PUBLIC_KEY_SIZE bytes) of the
156 * receiver and the secret key of the sender and a CRYPTO_NONCE_SIZE byte
157 * nonce.
126 * 158 *
127 * return -1 if there was a problem. 159 * @return -1 if there was a problem, length of encrypted data if everything
128 * return length of encrypted data if everything was fine. 160 * was fine.
129 */ 161 */
130int32_t encrypt_data(const uint8_t *public_key, const uint8_t *secret_key, const uint8_t *nonce, const uint8_t *plain, 162int32_t encrypt_data(const uint8_t *public_key, const uint8_t *secret_key, const uint8_t *nonce, const uint8_t *plain,
131 uint32_t length, uint8_t *encrypted); 163 size_t length, uint8_t *encrypted);
132 164
133/** 165/**
134 * Decrypts encrypted of length length to plain of length length - 16 using the 166 * Decrypt encrypted text of the given length to plain text of the given length
135 * public key(32 bytes) of the sender, the secret key of the receiver and a 24 byte nonce. 167 * - CRYPTO_MAC_SIZE using the public key (CRYPTO_PUBLIC_KEY_SIZE bytes) of
168 * the sender, the secret key of the receiver and a CRYPTO_NONCE_SIZE byte
169 * nonce.
136 * 170 *
137 * return -1 if there was a problem (decryption failed). 171 * @return -1 if there was a problem (decryption failed), length of plain text
138 * return length of plain data if everything was fine. 172 * data if everything was fine.
139 */ 173 */
140int32_t decrypt_data(const uint8_t *public_key, const uint8_t *secret_key, const uint8_t *nonce, 174int32_t decrypt_data(const uint8_t *public_key, const uint8_t *secret_key, const uint8_t *nonce,
141 const uint8_t *encrypted, uint32_t length, uint8_t *plain); 175 const uint8_t *encrypted, size_t length, uint8_t *plain);
142 176
143/** 177/**
144 * Fast encrypt/decrypt operations. Use if this is not a one-time communication. 178 * Fast encrypt/decrypt operations. Use if this is not a one-time communication.
145 * encrypt_precompute does the shared-key generation once so it does not have 179 * encrypt_precompute does the shared-key generation once so it does not have
146 * to be preformed on every encrypt/decrypt. 180 * to be preformed on every encrypt/decrypt.
147 */ 181 */
148int32_t encrypt_precompute(const uint8_t *public_key, const uint8_t *secret_key, uint8_t *enc_key); 182int32_t encrypt_precompute(const uint8_t *public_key, const uint8_t *secret_key, uint8_t *shared_key);
149 183
150/** 184/**
151 * Encrypts plain of length length to encrypted of length + 16 using a 185 * Encrypts plain of length length to encrypted of length + CRYPTO_MAC_SIZE
152 * secret key CRYPTO_SYMMETRIC_KEY_SIZE big and a 24 byte nonce. 186 * using a shared key CRYPTO_SYMMETRIC_KEY_SIZE big and a CRYPTO_NONCE_SIZE
187 * byte nonce.
153 * 188 *
154 * return -1 if there was a problem. 189 * @return -1 if there was a problem, length of encrypted data if everything
155 * return length of encrypted data if everything was fine. 190 * was fine.
156 */ 191 */
157int32_t encrypt_data_symmetric(const uint8_t *secret_key, const uint8_t *nonce, const uint8_t *plain, uint32_t length, 192int32_t encrypt_data_symmetric(const uint8_t *shared_key, const uint8_t *nonce, const uint8_t *plain, size_t length,
158 uint8_t *encrypted); 193 uint8_t *encrypted);
159 194
160/** 195/**
161 * Decrypts encrypted of length length to plain of length length - 16 using a 196 * Decrypts encrypted of length length to plain of length length -
162 * secret key CRYPTO_SYMMETRIC_KEY_SIZE big and a 24 byte nonce. 197 * CRYPTO_MAC_SIZE using a shared key CRYPTO_SHARED_KEY_SIZE big and a
198 * CRYPTO_NONCE_SIZE byte nonce.
163 * 199 *
164 * return -1 if there was a problem (decryption failed). 200 * @return -1 if there was a problem (decryption failed), length of plain data
165 * return length of plain data if everything was fine. 201 * if everything was fine.
166 */ 202 */
167int32_t decrypt_data_symmetric(const uint8_t *secret_key, const uint8_t *nonce, const uint8_t *encrypted, 203int32_t decrypt_data_symmetric(const uint8_t *shared_key, const uint8_t *nonce, const uint8_t *encrypted, size_t length,
168 uint32_t length, uint8_t *plain); 204 uint8_t *plain);
169 205
170/** 206/**
171 * Increment the given nonce by 1. 207 * Increment the given nonce by 1 in big endian (rightmost byte incremented
208 * first).
172 */ 209 */
173void increment_nonce(uint8_t *nonce); 210void increment_nonce(uint8_t *nonce);
174 211
175/** 212/**
176 * Increment the given nonce by num. 213 * Increment the given nonce by a given number. The number should be in host
214 * byte order.
177 */ 215 */
178void increment_nonce_number(uint8_t *nonce, uint32_t host_order_num); 216void increment_nonce_number(uint8_t *nonce, uint32_t host_order_num);
179 217
@@ -192,5 +230,4 @@ void new_symmetric_key(uint8_t *key);
192 */ 230 */
193void random_bytes(uint8_t *bytes, size_t length); 231void random_bytes(uint8_t *bytes, size_t length);
194 232
195#endif 233#endif /* CRYPTO_CORE_H */
196
diff --git a/toxcore/util.c b/toxcore/util.c
index 2dfa360e..7a390ea9 100644
--- a/toxcore/util.c
+++ b/toxcore/util.c
@@ -29,6 +29,7 @@
29#include "util.h" 29#include "util.h"
30 30
31#include "crypto_core.h" /* for CRYPTO_PUBLIC_KEY_SIZE */ 31#include "crypto_core.h" /* for CRYPTO_PUBLIC_KEY_SIZE */
32#include "network.h" /* for current_time_monotonic */
32 33
33#include <time.h> 34#include <time.h>
34 35
diff --git a/toxencryptsave/toxencryptsave.c b/toxencryptsave/toxencryptsave.c
index 360952ad..bd56e780 100644
--- a/toxencryptsave/toxencryptsave.c
+++ b/toxencryptsave/toxencryptsave.c
@@ -33,8 +33,11 @@
33#ifdef VANILLA_NACL 33#ifdef VANILLA_NACL
34#include <crypto_hash_sha256.h> 34#include <crypto_hash_sha256.h>
35#include "crypto_pwhash_scryptsalsa208sha256/crypto_pwhash_scryptsalsa208sha256.h" 35#include "crypto_pwhash_scryptsalsa208sha256/crypto_pwhash_scryptsalsa208sha256.h"
36#endif 36#else
37#include <sodium.h> 37#include <sodium.h>
38#endif
39
40#include <string.h>
38 41
39#if TOX_PASS_SALT_LENGTH != crypto_pwhash_scryptsalsa208sha256_SALTBYTES 42#if TOX_PASS_SALT_LENGTH != crypto_pwhash_scryptsalsa208sha256_SALTBYTES
40#error TOX_PASS_SALT_LENGTH is assumed to be equal to crypto_pwhash_scryptsalsa208sha256_SALTBYTES 43#error TOX_PASS_SALT_LENGTH is assumed to be equal to crypto_pwhash_scryptsalsa208sha256_SALTBYTES