summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorzoff99 <zoff@zoff.cc>2018-11-01 19:09:06 +0100
committeriphydf <iphydf@users.noreply.github.com>2019-01-03 11:13:27 +0000
commit78bc9e7403cb812103722384402006b33bc53e79 (patch)
treed2928c30e6583abc97426c24a72019ba3d325cb9
parent72ef08597ece599f14165722191b5650ce5dcb3f (diff)
Added test and patch for VLA stack overflow vuln.
Also added and used the new crypto_malloc and crypto_free. The latter also zeroes out the memory safely. The former only exists for symmetry (static analysis can detect asymmetric usages).
-rw-r--r--auto_tests/encryptsave_test.c24
-rw-r--r--toxcore/crypto_core.c52
2 files changed, 70 insertions, 6 deletions
diff --git a/auto_tests/encryptsave_test.c b/auto_tests/encryptsave_test.c
index 906bf3f8..19574d16 100644
--- a/auto_tests/encryptsave_test.c
+++ b/auto_tests/encryptsave_test.c
@@ -142,7 +142,8 @@ static void test_keys(void)
142 Tox_Err_Encryption encerr; 142 Tox_Err_Encryption encerr;
143 Tox_Err_Decryption decerr; 143 Tox_Err_Decryption decerr;
144 Tox_Err_Key_Derivation keyerr; 144 Tox_Err_Key_Derivation keyerr;
145 Tox_Pass_Key *key = tox_pass_key_derive((const uint8_t *)"123qweasdzxc", 12, &keyerr); 145 const uint8_t *key_char = (const uint8_t *)"123qweasdzxc";
146 Tox_Pass_Key *key = tox_pass_key_derive(key_char, 12, &keyerr);
146 ck_assert_msg(key != nullptr, "generic failure 1: %d", keyerr); 147 ck_assert_msg(key != nullptr, "generic failure 1: %d", keyerr);
147 const uint8_t *string = (const uint8_t *)"No Patrick, mayonnaise is not an instrument."; // 44 148 const uint8_t *string = (const uint8_t *)"No Patrick, mayonnaise is not an instrument."; // 44
148 149
@@ -150,8 +151,27 @@ static void test_keys(void)
150 bool ret = tox_pass_key_encrypt(key, string, 44, encrypted, &encerr); 151 bool ret = tox_pass_key_encrypt(key, string, 44, encrypted, &encerr);
151 ck_assert_msg(ret, "generic failure 2: %d", encerr); 152 ck_assert_msg(ret, "generic failure 2: %d", encerr);
152 153
154 // Testing how tox handles encryption of large messages.
155 int size_large = 30 * 1024 * 1024;
156 int ciphertext_length2a = size_large + TOX_PASS_ENCRYPTION_EXTRA_LENGTH;
157 int plaintext_length2a = size_large;
158 uint8_t *encrypted2a = (uint8_t *)malloc(ciphertext_length2a);
159 uint8_t *in_plaintext2a = (uint8_t *)malloc(plaintext_length2a);
160 ret = tox_pass_encrypt(in_plaintext2a, plaintext_length2a, key_char, 12, encrypted2a, &encerr);
161 ck_assert_msg(ret, "tox_pass_encrypt failure 2a: %d", encerr);
162
163 // Decryption of same message.
164 uint8_t *out_plaintext2a = (uint8_t *) malloc(plaintext_length2a);
165 ret = tox_pass_decrypt(encrypted2a, ciphertext_length2a, key_char, 12, out_plaintext2a, &decerr);
166 ck_assert_msg(ret, "tox_pass_decrypt failure 2a: %d", decerr);
167 ck_assert_msg(memcmp(in_plaintext2a, out_plaintext2a, plaintext_length2a) == 0, "Large message decryption failed");
168 free(encrypted2a);
169 free(in_plaintext2a);
170 free(out_plaintext2a);
171
172
153 uint8_t encrypted2[44 + TOX_PASS_ENCRYPTION_EXTRA_LENGTH]; 173 uint8_t encrypted2[44 + TOX_PASS_ENCRYPTION_EXTRA_LENGTH];
154 ret = tox_pass_encrypt(string, 44, (const uint8_t *)"123qweasdzxc", 12, encrypted2, &encerr); 174 ret = tox_pass_encrypt(string, 44, key_char, 12, encrypted2, &encerr);
155 ck_assert_msg(ret, "generic failure 3: %d", encerr); 175 ck_assert_msg(ret, "generic failure 3: %d", encerr);
156 176
157 uint8_t out1[44 + TOX_PASS_ENCRYPTION_EXTRA_LENGTH]; 177 uint8_t out1[44 + TOX_PASS_ENCRYPTION_EXTRA_LENGTH];
diff --git a/toxcore/crypto_core.c b/toxcore/crypto_core.c
index 1fd62866..0e53100a 100644
--- a/toxcore/crypto_core.c
+++ b/toxcore/crypto_core.c
@@ -30,6 +30,7 @@
30#include "ccompat.h" 30#include "ccompat.h"
31#include "crypto_core.h" 31#include "crypto_core.h"
32 32
33#include <stdlib.h>
33#include <string.h> 34#include <string.h>
34 35
35#ifndef VANILLA_NACL 36#ifndef VANILLA_NACL
@@ -82,6 +83,20 @@
82#error "CRYPTO_PUBLIC_KEY_SIZE is required to be 32 bytes for public_key_cmp to work," 83#error "CRYPTO_PUBLIC_KEY_SIZE is required to be 32 bytes for public_key_cmp to work,"
83#endif 84#endif
84 85
86static uint8_t *crypto_malloc(size_t bytes)
87{
88 return (uint8_t *)malloc(bytes);
89}
90
91static void crypto_free(uint8_t *ptr, size_t bytes)
92{
93 if (ptr != nullptr) {
94 crypto_memzero(ptr, bytes);
95 }
96
97 free(ptr);
98}
99
85int32_t public_key_cmp(const uint8_t *pk1, const uint8_t *pk2) 100int32_t public_key_cmp(const uint8_t *pk1, const uint8_t *pk2)
86{ 101{
87 return crypto_verify_32(pk1, pk2); 102 return crypto_verify_32(pk1, pk2);
@@ -142,8 +157,17 @@ int32_t encrypt_data_symmetric(const uint8_t *secret_key, const uint8_t *nonce,
142 return -1; 157 return -1;
143 } 158 }
144 159
145 VLA(uint8_t, temp_plain, length + crypto_box_ZEROBYTES); 160 const size_t size_temp_plain = length + crypto_box_ZEROBYTES;
146 VLA(uint8_t, temp_encrypted, length + crypto_box_MACBYTES + crypto_box_BOXZEROBYTES); 161 const size_t size_temp_encrypted = length + crypto_box_MACBYTES + crypto_box_BOXZEROBYTES;
162
163 uint8_t *temp_plain = crypto_malloc(size_temp_plain);
164 uint8_t *temp_encrypted = crypto_malloc(size_temp_encrypted);
165
166 if (temp_plain == nullptr || temp_encrypted == nullptr) {
167 crypto_free(temp_plain, size_temp_plain);
168 crypto_free(temp_encrypted, size_temp_encrypted);
169 return -1;
170 }
147 171
148 memset(temp_plain, 0, crypto_box_ZEROBYTES); 172 memset(temp_plain, 0, crypto_box_ZEROBYTES);
149 // Pad the message with 32 0 bytes. 173 // Pad the message with 32 0 bytes.
@@ -151,11 +175,17 @@ int32_t encrypt_data_symmetric(const uint8_t *secret_key, const uint8_t *nonce,
151 175
152 if (crypto_box_afternm(temp_encrypted, temp_plain, length + crypto_box_ZEROBYTES, nonce, 176 if (crypto_box_afternm(temp_encrypted, temp_plain, length + crypto_box_ZEROBYTES, nonce,
153 secret_key) != 0) { 177 secret_key) != 0) {
178 crypto_free(temp_plain, size_temp_plain);
179 crypto_free(temp_encrypted, size_temp_encrypted);
154 return -1; 180 return -1;
155 } 181 }
156 182
157 // Unpad the encrypted message. 183 // Unpad the encrypted message.
158 memcpy(encrypted, temp_encrypted + crypto_box_BOXZEROBYTES, length + crypto_box_MACBYTES); 184 memcpy(encrypted, temp_encrypted + crypto_box_BOXZEROBYTES, length + crypto_box_MACBYTES);
185
186 crypto_free(temp_plain, size_temp_plain);
187 crypto_free(temp_encrypted, size_temp_encrypted);
188
159 return length + crypto_box_MACBYTES; 189 return length + crypto_box_MACBYTES;
160} 190}
161 191
@@ -166,8 +196,17 @@ int32_t decrypt_data_symmetric(const uint8_t *secret_key, const uint8_t *nonce,
166 return -1; 196 return -1;
167 } 197 }
168 198
169 VLA(uint8_t, temp_plain, length + crypto_box_ZEROBYTES); 199 const size_t size_temp_plain = length + crypto_box_ZEROBYTES;
170 VLA(uint8_t, temp_encrypted, length + crypto_box_BOXZEROBYTES); 200 const size_t size_temp_encrypted = length + crypto_box_BOXZEROBYTES;
201
202 uint8_t *temp_plain = crypto_malloc(size_temp_plain);
203 uint8_t *temp_encrypted = crypto_malloc(size_temp_encrypted);
204
205 if (temp_plain == nullptr || temp_encrypted == nullptr) {
206 crypto_free(temp_plain, size_temp_plain);
207 crypto_free(temp_encrypted, size_temp_encrypted);
208 return -1;
209 }
171 210
172 memset(temp_encrypted, 0, crypto_box_BOXZEROBYTES); 211 memset(temp_encrypted, 0, crypto_box_BOXZEROBYTES);
173 // Pad the message with 16 0 bytes. 212 // Pad the message with 16 0 bytes.
@@ -175,10 +214,15 @@ int32_t decrypt_data_symmetric(const uint8_t *secret_key, const uint8_t *nonce,
175 214
176 if (crypto_box_open_afternm(temp_plain, temp_encrypted, length + crypto_box_BOXZEROBYTES, nonce, 215 if (crypto_box_open_afternm(temp_plain, temp_encrypted, length + crypto_box_BOXZEROBYTES, nonce,
177 secret_key) != 0) { 216 secret_key) != 0) {
217 crypto_free(temp_plain, size_temp_plain);
218 crypto_free(temp_encrypted, size_temp_encrypted);
178 return -1; 219 return -1;
179 } 220 }
180 221
181 memcpy(plain, temp_plain + crypto_box_ZEROBYTES, length - crypto_box_MACBYTES); 222 memcpy(plain, temp_plain + crypto_box_ZEROBYTES, length - crypto_box_MACBYTES);
223
224 crypto_free(temp_plain, size_temp_plain);
225 crypto_free(temp_encrypted, size_temp_encrypted);
182 return length - crypto_box_MACBYTES; 226 return length - crypto_box_MACBYTES;
183} 227}
184 228