summaryrefslogtreecommitdiff
path: root/toxcore/net_crypto.c
diff options
context:
space:
mode:
authorirungentoo <irungentoo@gmail.com>2014-04-28 20:14:07 -0400
committerirungentoo <irungentoo@gmail.com>2014-04-28 20:14:07 -0400
commitb9370d519ff87020cf32f3d04b6a2c4eebcc9563 (patch)
treee98aa27e47a6e09716681bce04e62aed5c889a21 /toxcore/net_crypto.c
parent50cea69f5705a7a01e31417bae29feb920bfdd59 (diff)
Added some functions to create/handle middle level protocol packets.
Diffstat (limited to 'toxcore/net_crypto.c')
-rw-r--r--toxcore/net_crypto.c123
1 files changed, 121 insertions, 2 deletions
diff --git a/toxcore/net_crypto.c b/toxcore/net_crypto.c
index 3d36e8e0..97533512 100644
--- a/toxcore/net_crypto.c
+++ b/toxcore/net_crypto.c
@@ -94,7 +94,7 @@ static int create_cookie(uint8_t *cookie, uint8_t *bytes, uint8_t *encryption_ke
94 94
95#define COOKIE_RESPONSE_LENGTH (1 + crypto_box_NONCEBYTES + COOKIE_LENGTH + crypto_box_MACBYTES) 95#define COOKIE_RESPONSE_LENGTH (1 + crypto_box_NONCEBYTES + COOKIE_LENGTH + crypto_box_MACBYTES)
96 96
97/* Open cookie of length COOKIE_LENGTH from bytes of length COOKIE_REQUEST_PLAIN_LENGTH using encryption_key 97/* Open cookie of length COOKIE_LENGTH to bytes of length COOKIE_REQUEST_PLAIN_LENGTH using encryption_key
98 * 98 *
99 * return -1 on failure. 99 * return -1 on failure.
100 * return 0 on success. 100 * return 0 on success.
@@ -172,7 +172,7 @@ static int handle_cookie_request(Net_Crypto *c, uint8_t *request_plain, uint8_t
172 */ 172 */
173static int udp_handle_cookie_request(void *object, IP_Port source, uint8_t *packet, uint32_t length) 173static int udp_handle_cookie_request(void *object, IP_Port source, uint8_t *packet, uint32_t length)
174{ 174{
175 Net_Crypto *c = c; 175 Net_Crypto *c = object;
176 uint8_t request_plain[COOKIE_REQUEST_PLAIN_LENGTH]; 176 uint8_t request_plain[COOKIE_REQUEST_PLAIN_LENGTH];
177 uint8_t shared_key[crypto_box_BEFORENMBYTES]; 177 uint8_t shared_key[crypto_box_BEFORENMBYTES];
178 178
@@ -190,6 +190,125 @@ static int udp_handle_cookie_request(void *object, IP_Port source, uint8_t *pack
190 return 0; 190 return 0;
191} 191}
192 192
193/* Handle a cookie response packet of length encrypted with shared_key.
194 * put the cookie in the response in cookie
195 *
196 * cookie must be of length COOKIE_LENGTH.
197 *
198 * return -1 on failure.
199 * return COOKIE_LENGTH on success.
200 */
201static int handle_cookie_response(Net_Crypto *c, uint8_t *cookie, uint8_t *packet, uint32_t length, uint8_t *shared_key)
202{
203 if (length != COOKIE_RESPONSE_LENGTH)
204 return -1;
205
206 int len = decrypt_data_symmetric(shared_key, packet + 1, packet + 1 + crypto_box_NONCEBYTES,
207 length - (1 + crypto_box_NONCEBYTES), cookie);
208
209 if (len != COOKIE_LENGTH)
210 return -1;
211
212 return COOKIE_LENGTH;
213}
214
215#define HANDSHAKE_PACKET_LENGTH (1 + COOKIE_LENGTH + crypto_box_NONCEBYTES + crypto_box_NONCEBYTES + crypto_box_PUBLICKEYBYTES + crypto_box_MACBYTES)
216
217/* Create a handshake packet and put it in packet.
218 * cookie must be COOKIE_LENGTH bytes.
219 * packet must be of size HANDSHAKE_PACKET_LENGTH or bigger.
220 *
221 * return -1 on failure.
222 * return HANDSHAKE_PACKET_LENGTH on success.
223 */
224static int create_crypto_handshake(Net_Crypto *c, uint8_t *packet, uint8_t *cookie, uint8_t *nonce, uint8_t *session_pk,
225 uint8_t *peer_real_pk)
226{
227 uint8_t plain[crypto_box_NONCEBYTES + crypto_box_PUBLICKEYBYTES];
228 memcpy(plain, nonce, crypto_box_NONCEBYTES);
229 memcpy(plain + crypto_box_NONCEBYTES, session_pk, crypto_box_PUBLICKEYBYTES);
230 new_nonce(packet + 1 + COOKIE_LENGTH);
231 int len = encrypt_data(peer_real_pk, c->self_secret_key, packet + 1 + COOKIE_LENGTH, plain, sizeof(plain),
232 packet + 1 + COOKIE_LENGTH + crypto_box_NONCEBYTES);
233
234 if (len != HANDSHAKE_PACKET_LENGTH - (1 + COOKIE_LENGTH + crypto_box_NONCEBYTES))
235 return -1;
236
237 packet[0] = NET_PACKET_CRYPTO_HS;
238 memcpy(packet + 1, cookie, COOKIE_LENGTH);
239
240 return HANDSHAKE_PACKET_LENGTH;
241}
242
243/* Handle a crypto handshake packet of length.
244 * put the nonce contained in the packet in nonce,
245 * the session public key in session_pk and
246 * the real public key of the peer in peer_real_pk.
247 *
248 * nonce must be at least crypto_box_NONCEBYTES
249 * session_pk must be at least crypto_box_PUBLICKEYBYTES
250 * peer_real_pk must be at least crypto_box_PUBLICKEYBYTES
251 *
252 * return -1 on failure.
253 * return 0 on success.
254 */
255static int handle_crypto_handshake(Net_Crypto *c, uint8_t *nonce, uint8_t *session_pk, uint8_t *peer_real_pk,
256 uint8_t *packet, uint32_t length)
257{
258 if (length != HANDSHAKE_PACKET_LENGTH)
259 return -1;
260
261 uint8_t cookie_plain[COOKIE_REQUEST_PLAIN_LENGTH];
262
263 if (open_cookie(cookie_plain, packet + 1, c->secret_symmetric_key) != 0)
264 return -1;
265
266 if (crypto_cmp(cookie_plain + crypto_box_PUBLICKEYBYTES, c->self_public_key, crypto_box_PUBLICKEYBYTES) != 0)
267 return -1;
268
269 uint8_t plain[crypto_box_NONCEBYTES + crypto_box_PUBLICKEYBYTES];
270 int len = decrypt_data(cookie_plain, c->self_secret_key, packet + 1 + COOKIE_LENGTH,
271 packet + 1 + COOKIE_LENGTH + crypto_box_NONCEBYTES,
272 HANDSHAKE_PACKET_LENGTH - (1 + COOKIE_LENGTH + crypto_box_NONCEBYTES), plain);
273
274 if (len != sizeof(plain))
275 return -1;
276
277 memcpy(nonce, plain, crypto_box_NONCEBYTES);
278 memcpy(session_pk, plain + crypto_box_NONCEBYTES, crypto_box_PUBLICKEYBYTES);
279 memcpy(peer_real_pk, cookie_plain, crypto_box_PUBLICKEYBYTES);
280 return 0;
281}
282
283/* Handle a crypto handshake packet of length without opening the cookie from peer
284 * with the real public key peer_real_pk.
285 * put the nonce contained in the packet in nonce and the session public key in
286 * session_pk.
287 *
288 * nonce must be at least crypto_box_NONCEBYTES
289 * session_pk must be at least crypto_box_PUBLICKEYBYTES
290 *
291 * return -1 on failure.
292 * return 0 on success.
293 */
294static int handle_crypto_handshake_nocookie(Net_Crypto *c, uint8_t *nonce, uint8_t *session_pk, uint8_t *packet,
295 uint32_t length, uint8_t *peer_real_pk)
296{
297 if (length != HANDSHAKE_PACKET_LENGTH)
298 return -1;
299
300 uint8_t plain[crypto_box_NONCEBYTES + crypto_box_PUBLICKEYBYTES];
301 int len = decrypt_data(peer_real_pk, c->self_secret_key, packet + 1 + COOKIE_LENGTH,
302 packet + 1 + COOKIE_LENGTH + crypto_box_NONCEBYTES,
303 HANDSHAKE_PACKET_LENGTH - (1 + COOKIE_LENGTH + crypto_box_NONCEBYTES), plain);
304
305 if (len != sizeof(plain))
306 return -1;
307
308 memcpy(nonce, plain, crypto_box_NONCEBYTES);
309 memcpy(session_pk, plain + crypto_box_NONCEBYTES, crypto_box_PUBLICKEYBYTES);
310 return 0;
311}
193/* return 0 if there is no received data in the buffer. 312/* return 0 if there is no received data in the buffer.
194 * return -1 if the packet was discarded. 313 * return -1 if the packet was discarded.
195 * return length of received data if successful. 314 * return length of received data if successful.