summaryrefslogtreecommitdiff
path: root/toxcore/crypto_core.c
diff options
context:
space:
mode:
authorRoman Proskuryakov <humbug@deeptown.org>2016-01-24 19:16:40 +0300
committerRoman Proskuryakov <humbug@deeptown.org>2016-01-27 02:14:59 +0300
commited3a794c9bf6380801ee21c816505f457b6a1348 (patch)
tree14e1b8fa1c8c1b7f45b08bae5e0b6169054c3751 /toxcore/crypto_core.c
parent61f8e65c0157049ac26bf9b081ba6842d7defdeb (diff)
fix: compare sensitive data with sodium_memcmp
fix: make increment_nonce & increment_nonce_number independent of user-controlled input fix: make crypto_core more stable agains null ptr dereference
Diffstat (limited to 'toxcore/crypto_core.c')
-rw-r--r--toxcore/crypto_core.c95
1 files changed, 58 insertions, 37 deletions
diff --git a/toxcore/crypto_core.c b/toxcore/crypto_core.c
index d1549b2a..679ba669 100644
--- a/toxcore/crypto_core.c
+++ b/toxcore/crypto_core.c
@@ -84,7 +84,7 @@ void encrypt_precompute(const uint8_t *public_key, const uint8_t *secret_key, ui
84int encrypt_data_symmetric(const uint8_t *secret_key, const uint8_t *nonce, const uint8_t *plain, uint32_t length, 84int encrypt_data_symmetric(const uint8_t *secret_key, const uint8_t *nonce, const uint8_t *plain, uint32_t length,
85 uint8_t *encrypted) 85 uint8_t *encrypted)
86{ 86{
87 if (length == 0) 87 if (length == 0 || !secret_key || !nonce || !plain || !encrypted)
88 return -1; 88 return -1;
89 89
90 uint8_t temp_plain[length + crypto_box_ZEROBYTES]; 90 uint8_t temp_plain[length + crypto_box_ZEROBYTES];
@@ -104,7 +104,7 @@ int encrypt_data_symmetric(const uint8_t *secret_key, const uint8_t *nonce, cons
104int decrypt_data_symmetric(const uint8_t *secret_key, const uint8_t *nonce, const uint8_t *encrypted, uint32_t length, 104int decrypt_data_symmetric(const uint8_t *secret_key, const uint8_t *nonce, const uint8_t *encrypted, uint32_t length,
105 uint8_t *plain) 105 uint8_t *plain)
106{ 106{
107 if (length <= crypto_box_BOXZEROBYTES) 107 if (length <= crypto_box_BOXZEROBYTES || !secret_key || !nonce || !encrypted || !plain)
108 return -1; 108 return -1;
109 109
110 uint8_t temp_plain[length + crypto_box_ZEROBYTES]; 110 uint8_t temp_plain[length + crypto_box_ZEROBYTES];
@@ -123,53 +123,70 @@ int decrypt_data_symmetric(const uint8_t *secret_key, const uint8_t *nonce, cons
123int encrypt_data(const uint8_t *public_key, const uint8_t *secret_key, const uint8_t *nonce, 123int encrypt_data(const uint8_t *public_key, const uint8_t *secret_key, const uint8_t *nonce,
124 const uint8_t *plain, uint32_t length, uint8_t *encrypted) 124 const uint8_t *plain, uint32_t length, uint8_t *encrypted)
125{ 125{
126 if (!public_key || !secret_key)
127 return -1;
128
126 uint8_t k[crypto_box_BEFORENMBYTES]; 129 uint8_t k[crypto_box_BEFORENMBYTES];
127 encrypt_precompute(public_key, secret_key, k); 130 encrypt_precompute(public_key, secret_key, k);
128 return encrypt_data_symmetric(k, nonce, plain, length, encrypted); 131 int ret = encrypt_data_symmetric(k, nonce, plain, length, encrypted);
132 sodium_memzero(k, sizeof k);
133 return ret;
129} 134}
130 135
131int decrypt_data(const uint8_t *public_key, const uint8_t *secret_key, const uint8_t *nonce, 136int decrypt_data(const uint8_t *public_key, const uint8_t *secret_key, const uint8_t *nonce,
132 const uint8_t *encrypted, uint32_t length, uint8_t *plain) 137 const uint8_t *encrypted, uint32_t length, uint8_t *plain)
133{ 138{
139 if (!public_key || !secret_key)
140 return -1;
141
134 uint8_t k[crypto_box_BEFORENMBYTES]; 142 uint8_t k[crypto_box_BEFORENMBYTES];
135 encrypt_precompute(public_key, secret_key, k); 143 encrypt_precompute(public_key, secret_key, k);
136 return decrypt_data_symmetric(k, nonce, encrypted, length, plain); 144 int ret = decrypt_data_symmetric(k, nonce, encrypted, length, plain);
145 sodium_memzero(k, sizeof k);
146 return ret;
137} 147}
138 148
139 149
140/* Increment the given nonce by 1. */ 150/* Increment the given nonce by 1. */
141void increment_nonce(uint8_t *nonce) 151void increment_nonce(uint8_t *nonce)
142{ 152{
143 uint32_t i; 153 /* FIXME use increment_nonce_number(nonce, 1) or sodium_increment (change to little endian)
144 154 * NOTE don't use breaks inside this loop
145 for (i = crypto_box_NONCEBYTES; i != 0; --i) { 155 * In particular, make sure, as far as possible,
146 ++nonce[i - 1]; 156 * that loop bounds and their potential underflow or overflow
147 157 * are independent of user-controlled input (you may have heard of the Heartbleed bug).
148 if (nonce[i - 1] != 0) 158 */
149 break; 159 uint32_t i = crypto_box_NONCEBYTES;
160 uint_fast16_t carry = 1U;
161 for (; i != 0; --i) {
162 carry += (uint_fast16_t) nonce[i - 1];
163 nonce[i - 1] = (uint8_t) carry;
164 carry >>= 8;
150 } 165 }
151} 166}
152/* increment the given nonce by num */ 167/* increment the given nonce by num */
153void increment_nonce_number(uint8_t *nonce, uint32_t num) 168void increment_nonce_number(uint8_t *nonce, uint32_t host_order_num)
154{ 169{
155 uint32_t num1, num2; 170 /* NOTE don't use breaks inside this loop
156 memcpy(&num1, nonce + (crypto_box_NONCEBYTES - sizeof(num1)), sizeof(num1)); 171 * In particular, make sure, as far as possible,
157 num1 = ntohl(num1); 172 * that loop bounds and their potential underflow or overflow
158 num2 = num + num1; 173 * are independent of user-controlled input (you may have heard of the Heartbleed bug).
159 174 */
160 if (num2 < num1) { 175 const uint32_t big_endian_num = htonl(host_order_num);
161 uint32_t i; 176 const uint8_t* const num_vec = (const uint8_t*) &big_endian_num;
162 177 uint8_t num_as_nonce[crypto_box_NONCEBYTES] = {0};
163 for (i = crypto_box_NONCEBYTES - sizeof(num1); i != 0; --i) { 178 num_as_nonce[crypto_box_NONCEBYTES - 4] = num_vec[0];
164 ++nonce[i - 1]; 179 num_as_nonce[crypto_box_NONCEBYTES - 3] = num_vec[1];
165 180 num_as_nonce[crypto_box_NONCEBYTES - 2] = num_vec[2];
166 if (nonce[i - 1] != 0) 181 num_as_nonce[crypto_box_NONCEBYTES - 1] = num_vec[3];
167 break; 182
168 } 183 uint32_t i = crypto_box_NONCEBYTES;
184 uint_fast16_t carry = 0U;
185 for (; i != 0; --i) {
186 carry += (uint_fast16_t) nonce[i] + (uint_fast16_t) num_as_nonce[i];
187 nonce[i] = (unsigned char) carry;
188 carry >>= 8;
169 } 189 }
170
171 num2 = htonl(num2);
172 memcpy(nonce + (crypto_box_NONCEBYTES - sizeof(num2)), &num2, sizeof(num2));
173} 190}
174 191
175/* Fill the given nonce with random bytes. */ 192/* Fill the given nonce with random bytes. */
@@ -203,15 +220,18 @@ void new_nonce(uint8_t *nonce)
203int create_request(const uint8_t *send_public_key, const uint8_t *send_secret_key, uint8_t *packet, 220int create_request(const uint8_t *send_public_key, const uint8_t *send_secret_key, uint8_t *packet,
204 const uint8_t *recv_public_key, const uint8_t *data, uint32_t length, uint8_t request_id) 221 const uint8_t *recv_public_key, const uint8_t *data, uint32_t length, uint8_t request_id)
205{ 222{
223 if (!send_public_key || !packet || !recv_public_key || !data)
224 return -1;
225
206 if (MAX_CRYPTO_REQUEST_SIZE < length + 1 + crypto_box_PUBLICKEYBYTES * 2 + crypto_box_NONCEBYTES + 1 + 226 if (MAX_CRYPTO_REQUEST_SIZE < length + 1 + crypto_box_PUBLICKEYBYTES * 2 + crypto_box_NONCEBYTES + 1 +
207 crypto_box_MACBYTES) 227 crypto_box_MACBYTES)
208 return -1; 228 return -1;
209 229
210 uint8_t nonce[crypto_box_NONCEBYTES]; 230 uint8_t* nonce = packet + 1 + crypto_box_PUBLICKEYBYTES * 2;
211 uint8_t temp[MAX_CRYPTO_REQUEST_SIZE]; 231 new_nonce(nonce);
232 uint8_t temp[MAX_CRYPTO_REQUEST_SIZE]; // FIXME sodium_memzero before exit function
212 memcpy(temp + 1, data, length); 233 memcpy(temp + 1, data, length);
213 temp[0] = request_id; 234 temp[0] = request_id;
214 new_nonce(nonce);
215 int len = encrypt_data(recv_public_key, send_secret_key, nonce, temp, length + 1, 235 int len = encrypt_data(recv_public_key, send_secret_key, nonce, temp, length + 1,
216 1 + crypto_box_PUBLICKEYBYTES * 2 + crypto_box_NONCEBYTES + packet); 236 1 + crypto_box_PUBLICKEYBYTES * 2 + crypto_box_NONCEBYTES + packet);
217 237
@@ -221,7 +241,6 @@ int create_request(const uint8_t *send_public_key, const uint8_t *send_secret_ke
221 packet[0] = NET_PACKET_CRYPTO; 241 packet[0] = NET_PACKET_CRYPTO;
222 memcpy(packet + 1, recv_public_key, crypto_box_PUBLICKEYBYTES); 242 memcpy(packet + 1, recv_public_key, crypto_box_PUBLICKEYBYTES);
223 memcpy(packet + 1 + crypto_box_PUBLICKEYBYTES, send_public_key, crypto_box_PUBLICKEYBYTES); 243 memcpy(packet + 1 + crypto_box_PUBLICKEYBYTES, send_public_key, crypto_box_PUBLICKEYBYTES);
224 memcpy(packet + 1 + crypto_box_PUBLICKEYBYTES * 2, nonce, crypto_box_NONCEBYTES);
225 244
226 return len + 1 + crypto_box_PUBLICKEYBYTES * 2 + crypto_box_NONCEBYTES; 245 return len + 1 + crypto_box_PUBLICKEYBYTES * 2 + crypto_box_NONCEBYTES;
227} 246}
@@ -235,17 +254,19 @@ int create_request(const uint8_t *send_public_key, const uint8_t *send_secret_ke
235int handle_request(const uint8_t *self_public_key, const uint8_t *self_secret_key, uint8_t *public_key, uint8_t *data, 254int handle_request(const uint8_t *self_public_key, const uint8_t *self_secret_key, uint8_t *public_key, uint8_t *data,
236 uint8_t *request_id, const uint8_t *packet, uint16_t length) 255 uint8_t *request_id, const uint8_t *packet, uint16_t length)
237{ 256{
257 if (!self_public_key || !public_key || !data || !request_id || !packet)
258 return -1;
259
238 if (length <= crypto_box_PUBLICKEYBYTES * 2 + crypto_box_NONCEBYTES + 1 + crypto_box_MACBYTES || 260 if (length <= crypto_box_PUBLICKEYBYTES * 2 + crypto_box_NONCEBYTES + 1 + crypto_box_MACBYTES ||
239 length > MAX_CRYPTO_REQUEST_SIZE) 261 length > MAX_CRYPTO_REQUEST_SIZE)
240 return -1; 262 return -1;
241 263
242 if (memcmp(packet + 1, self_public_key, crypto_box_PUBLICKEYBYTES) != 0) 264 if (public_key_cmp(packet + 1, self_public_key) != 0)
243 return -1; 265 return -1;
244 266
245 memcpy(public_key, packet + 1 + crypto_box_PUBLICKEYBYTES, crypto_box_PUBLICKEYBYTES); 267 memcpy(public_key, packet + 1 + crypto_box_PUBLICKEYBYTES, crypto_box_PUBLICKEYBYTES);
246 uint8_t nonce[crypto_box_NONCEBYTES]; 268 const uint8_t* nonce = packet + 1 + crypto_box_PUBLICKEYBYTES * 2;
247 uint8_t temp[MAX_CRYPTO_REQUEST_SIZE]; 269 uint8_t temp[MAX_CRYPTO_REQUEST_SIZE]; // FIXME sodium_memzero before exit function
248 memcpy(nonce, packet + 1 + crypto_box_PUBLICKEYBYTES * 2, crypto_box_NONCEBYTES);
249 int len1 = decrypt_data(public_key, self_secret_key, nonce, 270 int len1 = decrypt_data(public_key, self_secret_key, nonce,
250 packet + 1 + crypto_box_PUBLICKEYBYTES * 2 + crypto_box_NONCEBYTES, 271 packet + 1 + crypto_box_PUBLICKEYBYTES * 2 + crypto_box_NONCEBYTES,
251 length - (crypto_box_PUBLICKEYBYTES * 2 + crypto_box_NONCEBYTES + 1), temp); 272 length - (crypto_box_PUBLICKEYBYTES * 2 + crypto_box_NONCEBYTES + 1), temp);