diff options
Diffstat (limited to 'toxcore/crypto_core.c')
-rw-r--r-- | toxcore/crypto_core.c | 95 |
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 | |||
84 | int encrypt_data_symmetric(const uint8_t *secret_key, const uint8_t *nonce, const uint8_t *plain, uint32_t length, | 84 | int 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 | |||
104 | int decrypt_data_symmetric(const uint8_t *secret_key, const uint8_t *nonce, const uint8_t *encrypted, uint32_t length, | 104 | int 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 | |||
123 | int encrypt_data(const uint8_t *public_key, const uint8_t *secret_key, const uint8_t *nonce, | 123 | int 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 | ||
131 | int decrypt_data(const uint8_t *public_key, const uint8_t *secret_key, const uint8_t *nonce, | 136 | int 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. */ |
141 | void increment_nonce(uint8_t *nonce) | 151 | void 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 */ |
153 | void increment_nonce_number(uint8_t *nonce, uint32_t num) | 168 | void 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) | |||
203 | int create_request(const uint8_t *send_public_key, const uint8_t *send_secret_key, uint8_t *packet, | 220 | int 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 | |||
235 | int handle_request(const uint8_t *self_public_key, const uint8_t *self_secret_key, uint8_t *public_key, uint8_t *data, | 254 | int 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); |