summaryrefslogtreecommitdiff
path: root/toxcore/net_crypto.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/net_crypto.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/net_crypto.c')
-rw-r--r--toxcore/net_crypto.c200
1 files changed, 2 insertions, 198 deletions
diff --git a/toxcore/net_crypto.c b/toxcore/net_crypto.c
index ae3a69a1..d0212d11 100644
--- a/toxcore/net_crypto.c
+++ b/toxcore/net_crypto.c
@@ -35,202 +35,6 @@ static uint8_t crypt_connection_id_not_valid(Net_Crypto *c, int crypt_connection
35 return (uint32_t)crypt_connection_id >= c->crypto_connections_length; 35 return (uint32_t)crypt_connection_id >= c->crypto_connections_length;
36} 36}
37 37
38/* Use this instead of memcmp; not vulnerable to timing attacks. */
39uint8_t crypto_iszero(uint8_t *mem, uint32_t length)
40{
41 uint8_t check = 0;
42 uint32_t i;
43
44 for (i = 0; i < length; ++i) {
45 check |= mem[i];
46 }
47
48 return check; // We return zero if mem is made out of zeroes.
49}
50
51/* Precomputes the shared key from their public_key and our secret_key.
52 * This way we can avoid an expensive elliptic curve scalar multiply for each
53 * encrypt/decrypt operation.
54 * enc_key has to be crypto_box_BEFORENMBYTES bytes long.
55 */
56void encrypt_precompute(uint8_t *public_key, uint8_t *secret_key, uint8_t *enc_key)
57{
58 crypto_box_beforenm(enc_key, public_key, secret_key);
59}
60
61/* Fast encrypt. Depends on enc_key from encrypt_precompute. */
62int encrypt_data_fast(uint8_t *enc_key, uint8_t *nonce,
63 uint8_t *plain, uint32_t length, uint8_t *encrypted)
64{
65 if (length + crypto_box_MACBYTES > MAX_DATA_SIZE || length == 0)
66 return -1;
67
68 uint8_t temp_plain[MAX_DATA_SIZE + crypto_box_ZEROBYTES] = {0};
69 uint8_t temp_encrypted[MAX_DATA_SIZE + crypto_box_BOXZEROBYTES];
70
71 memcpy(temp_plain + crypto_box_ZEROBYTES, plain, length); // Pad the message with 32 0 bytes.
72
73 crypto_box_afternm(temp_encrypted, temp_plain, length + crypto_box_ZEROBYTES, nonce, enc_key);
74
75 if (crypto_iszero(temp_encrypted, crypto_box_BOXZEROBYTES) != 0)
76 return -1;
77
78 /* Unpad the encrypted message. */
79 memcpy(encrypted, temp_encrypted + crypto_box_BOXZEROBYTES, length + crypto_box_MACBYTES);
80 return length + crypto_box_MACBYTES;
81}
82
83/* Fast decrypt. Depends on enc_ley from encrypt_precompute. */
84int decrypt_data_fast(uint8_t *enc_key, uint8_t *nonce,
85 uint8_t *encrypted, uint32_t length, uint8_t *plain)
86{
87 if (length > MAX_DATA_SIZE || length <= crypto_box_BOXZEROBYTES)
88 return -1;
89
90 uint8_t temp_plain[MAX_DATA_SIZE + crypto_box_ZEROBYTES];
91 uint8_t temp_encrypted[MAX_DATA_SIZE + crypto_box_BOXZEROBYTES] = {0};
92
93 memcpy(temp_encrypted + crypto_box_BOXZEROBYTES, encrypted, length); // Pad the message with 16 0 bytes.
94
95 if (crypto_box_open_afternm(temp_plain, temp_encrypted, length + crypto_box_BOXZEROBYTES,
96 nonce, enc_key) == -1)
97 return -1;
98
99 /* If decryption is successful the first crypto_box_ZEROBYTES of the message will be zero.
100 * Apparently memcmp should not be used so we do this instead:
101 */
102 if (crypto_iszero(temp_plain, crypto_box_ZEROBYTES) != 0)
103 return -1;
104
105 /* Unpad the plain message. */
106 memcpy(plain, temp_plain + crypto_box_ZEROBYTES, length - crypto_box_MACBYTES);
107 return length - crypto_box_MACBYTES;
108}
109
110int encrypt_data(uint8_t *public_key, uint8_t *secret_key, uint8_t *nonce,
111 uint8_t *plain, uint32_t length, uint8_t *encrypted)
112{
113 uint8_t k[crypto_box_BEFORENMBYTES];
114 encrypt_precompute(public_key, secret_key, k);
115 return encrypt_data_fast(k, nonce, plain, length, encrypted);
116}
117
118int decrypt_data(uint8_t *public_key, uint8_t *secret_key, uint8_t *nonce,
119 uint8_t *encrypted, uint32_t length, uint8_t *plain)
120{
121 uint8_t k[crypto_box_BEFORENMBYTES];
122 encrypt_precompute(public_key, secret_key, k);
123 return decrypt_data_fast(k, nonce, encrypted, length, plain);
124}
125
126int encrypt_data_symmetric(uint8_t *secret_key, uint8_t *nonce, uint8_t *plain, uint32_t length, uint8_t *encrypted)
127{
128 if (length == 0)
129 return -1;
130
131 uint8_t temp_plain[length + crypto_secretbox_ZEROBYTES];
132 uint8_t temp_encrypted[length + crypto_secretbox_MACBYTES + crypto_secretbox_BOXZEROBYTES];
133
134 memset(temp_plain, 0, crypto_secretbox_ZEROBYTES);
135 memcpy(temp_plain + crypto_secretbox_ZEROBYTES, plain, length); // Pad the message with 32 0 bytes.
136
137 crypto_secretbox(temp_encrypted, temp_plain, length + crypto_secretbox_ZEROBYTES, nonce, secret_key);
138 /* Unpad the encrypted message. */
139 memcpy(encrypted, temp_encrypted + crypto_secretbox_BOXZEROBYTES, length + crypto_secretbox_MACBYTES);
140 return length + crypto_secretbox_MACBYTES;
141}
142
143int decrypt_data_symmetric(uint8_t *secret_key, uint8_t *nonce, uint8_t *encrypted, uint32_t length, uint8_t *plain)
144{
145 if (length <= crypto_secretbox_BOXZEROBYTES)
146 return -1;
147
148 uint8_t temp_plain[length + crypto_secretbox_ZEROBYTES];
149 uint8_t temp_encrypted[length + crypto_secretbox_BOXZEROBYTES];
150
151 memset(temp_plain, 0, crypto_secretbox_BOXZEROBYTES);
152 memcpy(temp_encrypted + crypto_secretbox_BOXZEROBYTES, encrypted, length); // Pad the message with 16 0 bytes.
153
154 if (crypto_secretbox_open(temp_plain, temp_encrypted, length + crypto_secretbox_BOXZEROBYTES, nonce, secret_key) == -1)
155 return -1;
156
157 memcpy(plain, temp_plain + crypto_secretbox_ZEROBYTES, length - crypto_secretbox_MACBYTES);
158 return length - crypto_secretbox_MACBYTES;
159}
160
161/* Increment the given nonce by 1. */
162void increment_nonce(uint8_t *nonce)
163{
164 uint32_t i;
165
166 for (i = crypto_box_NONCEBYTES; i != 0; --i) {
167 ++nonce[i - 1];
168
169 if (nonce[i - 1] != 0)
170 break;
171 }
172}
173/* increment the given nonce by num */
174void increment_nonce_number(uint8_t *nonce, uint32_t num)
175{
176 uint32_t num1, num2;
177 memcpy(&num1, nonce + (crypto_box_NONCEBYTES - sizeof(num1)), sizeof(num1));
178 num1 = ntohl(num1);
179 num2 = num + num1;
180
181 if (num2 < num1) {
182 uint32_t i;
183
184 for (i = crypto_box_NONCEBYTES - sizeof(num1); i != 0; --i) {
185 ++nonce[i - 1];
186
187 if (nonce[i - 1] != 0)
188 break;
189 }
190 }
191
192 num2 = htonl(num2);
193 memcpy(nonce + (crypto_box_NONCEBYTES - sizeof(num2)), &num2, sizeof(num2));
194}
195
196#if crypto_box_NONCEBYTES != crypto_secretbox_NONCEBYTES
197/*if they no longer equal each other, this function and the previous ones
198 *must be split into two.
199 */
200#error random_nonce(): crypto_box_NONCEBYTES must equal crypto_secretbox_NONCEBYTES.
201#endif
202/* Fill the given nonce with random bytes. */
203void random_nonce(uint8_t *nonce)
204{
205 randombytes(nonce, crypto_box_NONCEBYTES);
206}
207
208/* Fill a key crypto_secretbox_KEYBYTES big with random bytes */
209void new_symmetric_key(uint8_t *key)
210{
211 randombytes(key, crypto_secretbox_KEYBYTES);
212}
213
214static uint8_t base_nonce[crypto_box_NONCEBYTES];
215static uint8_t nonce_set = 0;
216
217#if crypto_box_NONCEBYTES != crypto_secretbox_NONCEBYTES
218/*if they no longer equal each other, this function must be split into two.*/
219#error new_nonce(): crypto_box_NONCEBYTES must equal crypto_secretbox_NONCEBYTES.
220#endif
221/* Gives a nonce guaranteed to be different from previous ones.*/
222void new_nonce(uint8_t *nonce)
223{
224 if (nonce_set == 0) {
225 random_nonce(base_nonce);
226 nonce_set = 1;
227 }
228
229 increment_nonce(base_nonce);
230 memcpy(nonce, base_nonce, crypto_box_NONCEBYTES);
231}
232
233
234/* return 0 if there is no received data in the buffer. 38/* return 0 if there is no received data in the buffer.
235 * return -1 if the packet was discarded. 39 * return -1 if the packet was discarded.
236 * return length of received data if successful. 40 * return length of received data if successful.
@@ -252,7 +56,7 @@ int read_cryptpacket(Net_Crypto *c, int crypt_connection_id, uint8_t *data)
252 if (temp_data[0] != 3) 56 if (temp_data[0] != 3)
253 return -1; 57 return -1;
254 58
255 int len = decrypt_data_fast(c->crypto_connections[crypt_connection_id].shared_key, 59 int len = decrypt_data_symmetric(c->crypto_connections[crypt_connection_id].shared_key,
256 c->crypto_connections[crypt_connection_id].recv_nonce, 60 c->crypto_connections[crypt_connection_id].recv_nonce,
257 temp_data + 1, length - 1, data); 61 temp_data + 1, length - 1, data);
258 62
@@ -290,7 +94,7 @@ int write_cryptpacket(Net_Crypto *c, int crypt_connection_id, uint8_t *data, uin
290 return 0; 94 return 0;
291 95
292 uint8_t temp_data[MAX_DATA_SIZE]; 96 uint8_t temp_data[MAX_DATA_SIZE];
293 int len = encrypt_data_fast(c->crypto_connections[crypt_connection_id].shared_key, 97 int len = encrypt_data_symmetric(c->crypto_connections[crypt_connection_id].shared_key,
294 c->crypto_connections[crypt_connection_id].sent_nonce, 98 c->crypto_connections[crypt_connection_id].sent_nonce,
295 data, length, temp_data + 1); 99 data, length, temp_data + 1);
296 100