summaryrefslogtreecommitdiff
path: root/toxcore/crypto_core.c
diff options
context:
space:
mode:
authorirungentoo <irungentoo@gmail.com>2014-04-21 16:51:36 -0400
committerirungentoo <irungentoo@gmail.com>2014-04-21 16:51:36 -0400
commit9c6a8432ce7298766669d1e6a966b5493971afb7 (patch)
tree8fd98c412610cbcf3fa8b7c28e0a5efbe02bad77 /toxcore/crypto_core.c
parent1603ca974eae3fe0d94b597103f04acfb96fcab0 (diff)
Crypto related cleanups.
Moved Bunch of functions from net_crypto to crypto_core. decrypt_data_fast and decrypt_data_symmetric were the same thing therefore, removed decrypt_data_fast. Replaced all the crypto_secretbox_* defines with the equivalent crypto_box_* one. New define: crypto_box_KEYBYTES that is equal to crypto_box_BEFORENMBYTES.
Diffstat (limited to 'toxcore/crypto_core.c')
-rw-r--r--toxcore/crypto_core.c168
1 files changed, 168 insertions, 0 deletions
diff --git a/toxcore/crypto_core.c b/toxcore/crypto_core.c
new file mode 100644
index 00000000..38048076
--- /dev/null
+++ b/toxcore/crypto_core.c
@@ -0,0 +1,168 @@
1/* net_crypto.c
2 *
3 * Functions for the core crypto.
4 *
5 * NOTE: This code has to be perfect. We don't mess around with encryption.
6 *
7 * Copyright (C) 2013 Tox project All Rights Reserved.
8 *
9 * This file is part of Tox.
10 *
11 * Tox is free software: you can redistribute it and/or modify
12 * it under the terms of the GNU General Public License as published by
13 * the Free Software Foundation, either version 3 of the License, or
14 * (at your option) any later version.
15 *
16 * Tox is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU General Public License for more details.
20 *
21 * You should have received a copy of the GNU General Public License
22 * along with Tox. If not, see <http://www.gnu.org/licenses/>.
23 *
24 */
25
26#ifdef HAVE_CONFIG_H
27#include "config.h"
28#endif
29
30#include "crypto_core.h"
31
32/* Use this instead of memcmp; not vulnerable to timing attacks. */
33uint8_t crypto_iszero(uint8_t *mem, uint32_t length)
34{
35 uint8_t check = 0;
36 uint32_t i;
37
38 for (i = 0; i < length; ++i) {
39 check |= mem[i];
40 }
41
42 return check; // We return zero if mem is made out of zeroes.
43}
44
45/* Precomputes the shared key from their public_key and our secret_key.
46 * This way we can avoid an expensive elliptic curve scalar multiply for each
47 * encrypt/decrypt operation.
48 * enc_key has to be crypto_box_BEFORENMBYTES bytes long.
49 */
50void encrypt_precompute(uint8_t *public_key, uint8_t *secret_key, uint8_t *enc_key)
51{
52 crypto_box_beforenm(enc_key, public_key, secret_key);
53}
54
55int encrypt_data_symmetric(uint8_t *secret_key, uint8_t *nonce, uint8_t *plain, uint32_t length, uint8_t *encrypted)
56{
57 if (length == 0)
58 return -1;
59
60 uint8_t temp_plain[length + crypto_box_ZEROBYTES];
61 uint8_t temp_encrypted[length + crypto_box_MACBYTES + crypto_box_BOXZEROBYTES];
62
63 memset(temp_plain, 0, crypto_box_ZEROBYTES);
64 memcpy(temp_plain + crypto_box_ZEROBYTES, plain, length); // Pad the message with 32 0 bytes.
65
66 if (crypto_box_afternm(temp_encrypted, temp_plain, length + crypto_box_ZEROBYTES, nonce, secret_key) != 0)
67 return -1;
68 /* Unpad the encrypted message. */
69 memcpy(encrypted, temp_encrypted + crypto_box_BOXZEROBYTES, length + crypto_box_MACBYTES);
70 return length + crypto_box_MACBYTES;
71}
72
73int decrypt_data_symmetric(uint8_t *secret_key, uint8_t *nonce, uint8_t *encrypted, uint32_t length, uint8_t *plain)
74{
75 if (length <= crypto_box_BOXZEROBYTES)
76 return -1;
77
78 uint8_t temp_plain[length + crypto_box_ZEROBYTES];
79 uint8_t temp_encrypted[length + crypto_box_BOXZEROBYTES];
80
81 memset(temp_plain, 0, crypto_box_BOXZEROBYTES);
82 memcpy(temp_encrypted + crypto_box_BOXZEROBYTES, encrypted, length); // Pad the message with 16 0 bytes.
83
84 if (crypto_box_open_afternm(temp_plain, temp_encrypted, length + crypto_box_BOXZEROBYTES, nonce, secret_key) != 0)
85 return -1;
86
87 memcpy(plain, temp_plain + crypto_box_ZEROBYTES, length - crypto_box_MACBYTES);
88 return length - crypto_box_MACBYTES;
89}
90
91int encrypt_data(uint8_t *public_key, uint8_t *secret_key, uint8_t *nonce,
92 uint8_t *plain, uint32_t length, uint8_t *encrypted)
93{
94 uint8_t k[crypto_box_BEFORENMBYTES];
95 encrypt_precompute(public_key, secret_key, k);
96 return encrypt_data_symmetric(k, nonce, plain, length, encrypted);
97}
98
99int decrypt_data(uint8_t *public_key, uint8_t *secret_key, uint8_t *nonce,
100 uint8_t *encrypted, uint32_t length, uint8_t *plain)
101{
102 uint8_t k[crypto_box_BEFORENMBYTES];
103 encrypt_precompute(public_key, secret_key, k);
104 return decrypt_data_symmetric(k, nonce, encrypted, length, plain);
105}
106
107
108/* Increment the given nonce by 1. */
109void increment_nonce(uint8_t *nonce)
110{
111 uint32_t i;
112
113 for (i = crypto_box_NONCEBYTES; i != 0; --i) {
114 ++nonce[i - 1];
115
116 if (nonce[i - 1] != 0)
117 break;
118 }
119}
120/* increment the given nonce by num */
121void increment_nonce_number(uint8_t *nonce, uint32_t num)
122{
123 uint32_t num1, num2;
124 memcpy(&num1, nonce + (crypto_box_NONCEBYTES - sizeof(num1)), sizeof(num1));
125 num1 = ntohl(num1);
126 num2 = num + num1;
127
128 if (num2 < num1) {
129 uint32_t i;
130
131 for (i = crypto_box_NONCEBYTES - sizeof(num1); i != 0; --i) {
132 ++nonce[i - 1];
133
134 if (nonce[i - 1] != 0)
135 break;
136 }
137 }
138
139 num2 = htonl(num2);
140 memcpy(nonce + (crypto_box_NONCEBYTES - sizeof(num2)), &num2, sizeof(num2));
141}
142
143/* Fill the given nonce with random bytes. */
144void random_nonce(uint8_t *nonce)
145{
146 randombytes(nonce, crypto_box_NONCEBYTES);
147}
148
149/* Fill a key crypto_box_KEYBYTES big with random bytes */
150void new_symmetric_key(uint8_t *key)
151{
152 randombytes(key, crypto_box_KEYBYTES);
153}
154
155static uint8_t base_nonce[crypto_box_NONCEBYTES];
156static uint8_t nonce_set = 0;
157
158/* Gives a nonce guaranteed to be different from previous ones.*/
159void new_nonce(uint8_t *nonce)
160{
161 if (nonce_set == 0) {
162 random_nonce(base_nonce);
163 nonce_set = 1;
164 }
165
166 increment_nonce(base_nonce);
167 memcpy(nonce, base_nonce, crypto_box_NONCEBYTES);
168} \ No newline at end of file