diff options
author | irungentoo <irungentoo@gmail.com> | 2014-04-21 16:51:36 -0400 |
---|---|---|
committer | irungentoo <irungentoo@gmail.com> | 2014-04-21 16:51:36 -0400 |
commit | 9c6a8432ce7298766669d1e6a966b5493971afb7 (patch) | |
tree | 8fd98c412610cbcf3fa8b7c28e0a5efbe02bad77 /toxcore/net_crypto.c | |
parent | 1603ca974eae3fe0d94b597103f04acfb96fcab0 (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.c | 200 |
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. */ | ||
39 | uint8_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 | */ | ||
56 | void 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. */ | ||
62 | int 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. */ | ||
84 | int 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 | |||
110 | int 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 | |||
118 | int 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 | |||
126 | int 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 | |||
143 | int 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. */ | ||
162 | void 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 */ | ||
174 | void 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. */ | ||
203 | void 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 */ | ||
209 | void new_symmetric_key(uint8_t *key) | ||
210 | { | ||
211 | randombytes(key, crypto_secretbox_KEYBYTES); | ||
212 | } | ||
213 | |||
214 | static uint8_t base_nonce[crypto_box_NONCEBYTES]; | ||
215 | static 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.*/ | ||
222 | void 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 | ||