aboutsummaryrefslogtreecommitdiffstats
path: root/src/inexact.c
diff options
context:
space:
mode:
authorben2019-05-28 14:33:12 +0200
committerben2019-05-28 15:19:37 +0200
commitc814f3c1c2970773ebc10876882776bd10febf0f (patch)
treece401beb9b372b3c3c231cad10974f45690ea827 /src/inexact.c
parent1cad5dfaab8712d3ad39470c67e968158198b4e9 (diff)
downloadinexact-c814f3c1c2970773ebc10876882776bd10febf0f.tar.gz
inexact-c814f3c1c2970773ebc10876882776bd10febf0f.tar.bz2
inexact-c814f3c1c2970773ebc10876882776bd10febf0f.tar.xz
[FIX] Improve code security by prevent buffer overflow.
Diffstat (limited to 'src/inexact.c')
-rw-r--r--src/inexact.c247
1 files changed, 170 insertions, 77 deletions
diff --git a/src/inexact.c b/src/inexact.c
index 16d6175..2f51d30 100644
--- a/src/inexact.c
+++ b/src/inexact.c
@@ -38,12 +38,15 @@ int generate_keys(const char *seckey_filename, const char *pubkey_filename,
unsigned char *publickey_b64 = NULL;
unsigned char *privatekey_b64t = NULL;
unsigned char *publickey_b64t = NULL;
- unsigned char salt[32] = {0};
- unsigned char privatekey_buffer[64] = {0};
+ unsigned char *salt = NULL;
+ const size_t salt_len = 32;
+ unsigned char *privatekey_buffer = NULL;
+ const size_t privatekey_buffer_len = 64;
- char password[256] = {0};
+ char *password = NULL;
+ const size_t password_maxlen = 256;
char *password_out = NULL;
- char password_verif[256] = {0};
+ char *password_verif = NULL;
char *password_verif_out = NULL;
size_t password_len = 0;
size_t password_verif_len = 0;
@@ -67,6 +70,17 @@ int generate_keys(const char *seckey_filename, const char *pubkey_filename,
curve25519_key privatekey;
curve25519_key publickey;
+ salt = malloc(salt_len);
+ privatekey_buffer = malloc(privatekey_buffer_len);
+ password = malloc(password_maxlen);
+ password_verif = malloc(password_maxlen);
+
+ if (salt == NULL || privatekey_buffer == NULL || password == NULL ||
+ password_verif == NULL) {
+ printf("Malloc failed\n");
+ goto exit;
+ }
+
/* Secret (or private) key */
if (no_password) {
@@ -92,27 +106,27 @@ int generate_keys(const char *seckey_filename, const char *pubkey_filename,
printf("Chacha20 allocation failed: %d\n", ret);
goto exit;
}
- if (drng_chacha20_get(drng, salt, sizeof(salt))) {
+ if (drng_chacha20_get(drng, salt, salt_len)) {
printf("Getting random numbers failed\n");
goto exit;
}
password_out =
- readpassphrase("Password : ", password, sizeof(password), 0);
+ readpassphrase("Password : ", password, password_maxlen, 0);
if (password_out != password) {
printf("password input failed.\n");
goto exit;
}
- password_len = strlen(password);
+ password_len = strnlen(password, password_maxlen);
password_verif_out =
readpassphrase("Verifying, please re-enter : ", password_verif,
- sizeof(password_verif), 0);
+ password_maxlen, 0);
if (password_verif_out != password_verif) {
printf("password input failed.\n");
goto exit;
}
- password_verif_len = strlen(password_verif);
+ password_verif_len = strnlen(password_verif, password_maxlen);
if (password_len != password_verif_len) {
printf("Mismatch.\n");
@@ -125,20 +139,19 @@ int generate_keys(const char *seckey_filename, const char *pubkey_filename,
}
int a2res = argon2id_hash_raw(t_cost, m_cost, parallelism, password,
- password_len, salt, sizeof(salt),
- privatekey, sizeof(curve25519_key));
+ password_len, salt, salt_len, privatekey,
+ sizeof(curve25519_key));
if (a2res != ARGON2_OK) {
printf("argon2 failed.");
goto exit;
}
curve25519_donna_basepoint(publickey, privatekey);
- memcpy(privatekey_buffer, salt, sizeof(salt));
- memcpy(privatekey_buffer + sizeof(salt), publickey,
- sizeof(curve25519_key));
+ memcpy(privatekey_buffer, salt, salt_len);
+ memcpy(privatekey_buffer + salt_len, publickey, sizeof(curve25519_key));
}
- privatekey_b64 = base64_encode(privatekey_buffer, sizeof(privatekey_buffer),
+ privatekey_b64 = base64_encode(privatekey_buffer, privatekey_buffer_len,
&private_base64_len);
if (privatekey_b64 == NULL) {
printf("base64 encoding failed.\n");
@@ -219,15 +232,19 @@ exit:
memset(publickey_b64, 0, public_base64_len);
memset(publickey_b64t, 0, public_b64t_len);
memset(publickey, 0, sizeof(curve25519_key));
- memset(salt, 0, sizeof(salt));
- memset(privatekey_buffer, 0, sizeof(privatekey_buffer));
- memset(password, 0, sizeof(password));
- memset(password_verif, 0, sizeof(password_verif));
+ memset(salt, 0, salt_len);
+ memset(privatekey_buffer, 0, privatekey_buffer_len);
+ memset(password, 0, password_maxlen);
+ memset(password_verif, 0, password_maxlen);
free(privatekey_b64);
free(publickey_b64);
free(privatekey_b64t);
free(publickey_b64t);
+ free(salt);
+ free(privatekey_buffer);
+ free(password);
+ free(password_verif);
if (fs != NULL) {
fclose(fs);
@@ -253,8 +270,10 @@ int get_seckey(const char *keyfile, unsigned char *skey, unsigned char *pkey) {
FILE *fs = NULL;
- unsigned char salt[32] = {0};
- char password[256] = {0};
+ unsigned char *salt = NULL;
+ const size_t salt_len = 32;
+ char *password = NULL;
+ const size_t password_maxlen = 256;
char *password_out = NULL;
curve25519_key pubkey;
curve25519_key pubkey_from_secret;
@@ -264,8 +283,21 @@ int get_seckey(const char *keyfile, unsigned char *skey, unsigned char *pkey) {
const uint32_t m_cost = (1 << 12);
const uint32_t parallelism = 1;
+ /* max_size = base64(sizeof(curve25519_key)) = 64 * 4 / 3 + 1 -> 86 */
+ const size_t file_data_len = 87;
+ unsigned char *file_data = NULL;
+
int exitcode = 1;
+ file_data = malloc(file_data_len);
+ salt = malloc(salt_len);
+ password = malloc(password_maxlen);
+
+ if (salt == NULL || password == NULL || file_data == NULL) {
+ printf("Malloc failed\n");
+ goto exit;
+ }
+
fs = fopen(keyfile, "rb");
if (fs == NULL) {
printf("key file opening failed: %s.\n", strerror(errno));
@@ -291,15 +323,12 @@ int get_seckey(const char *keyfile, unsigned char *skey, unsigned char *pkey) {
goto exit;
}
- /* max_size = base64(sizeof(curve25519_key)) = 64 * 4 / 3 + 1 -> 86 */
- unsigned char file_data[87] = {0};
-
- if (sz > sizeof(file_data)) {
+ if (sz > file_data_len) {
printf("Bad key size\n");
goto exit;
}
- size_t readed = fread(&file_data, 1, sz, fs);
+ size_t readed = fread(file_data, 1, sz, fs);
if (readed != sz) {
printf("read file '%s' failed: %s.\n", keyfile, strerror(errno));
goto exit;
@@ -331,17 +360,17 @@ int get_seckey(const char *keyfile, unsigned char *skey, unsigned char *pkey) {
int password_protected_flag =
(memcmp(pubkey, pubkey_from_secret, sizeof(curve25519_key)) != 0);
if (password_protected_flag) {
- memcpy(salt, base64_decoded, sizeof(salt));
+ memcpy(salt, base64_decoded, salt_len);
password_out =
- readpassphrase("Password : ", password, sizeof(password), 0);
+ readpassphrase("Password : ", password, password_maxlen, 0);
if (password_out != password) {
printf("password input failed.\n");
goto exit;
}
- password_len = strlen(password);
+ password_len = strnlen(password, password_maxlen);
int a2res = argon2id_hash_raw(t_cost, m_cost, parallelism, password,
- password_len, salt, sizeof(salt), seckey,
+ password_len, salt, salt_len, seckey,
sizeof(curve25519_key));
if (a2res != ARGON2_OK) {
printf("argon2 failed.");
@@ -361,11 +390,11 @@ int get_seckey(const char *keyfile, unsigned char *skey, unsigned char *pkey) {
exitcode = 0;
exit:
- memset(file_data, 0, sizeof(file_data));
+ memset(file_data, 0, file_data_len);
memset(base64_decoded, 0, base64_decoded_len);
memset(b64t_decoded, 0, b64t_decoded_len);
- memset(salt, 0, sizeof(salt));
- memset(password, 0, sizeof(password));
+ memset(salt, 0, salt_len);
+ memset(password, 0, password_maxlen);
memset(seckey, 0, sizeof(curve25519_key));
memset(pubkey, 0, sizeof(curve25519_key));
memset(pubkey_from_secret, 0, sizeof(curve25519_key));
@@ -376,6 +405,9 @@ exit:
free(base64_decoded);
free(b64t_decoded);
+ free(salt);
+ free(password);
+ free(file_data);
return exitcode;
}
@@ -395,6 +427,15 @@ int get_pubkey(const char *keyfile, unsigned char *pkey) {
curve25519_key pubkey;
+ /* max_size = base64(sizeof(curve25519_key)) = 32 * 4 / 3 + 1 -> 44 */
+ const size_t file_data_len = 45;
+ unsigned char *file_data = malloc(file_data_len);
+
+ if (file_data == NULL) {
+ printf("Malloc failed\n");
+ goto exit;
+ }
+
int exitcode = 1;
fs = fopen(keyfile, "rb");
@@ -422,15 +463,12 @@ int get_pubkey(const char *keyfile, unsigned char *pkey) {
goto exit;
}
- /* max_size = base64(sizeof(curve25519_key)) = 32 * 4 / 3 + 1 -> 44 */
- unsigned char file_data[44] = {0};
-
- if (sz > sizeof(file_data)) {
+ if (sz > file_data_len) {
printf("Bad key size\n");
goto exit;
}
- size_t readed = fread(&file_data, 1, sz, fs);
+ size_t readed = fread(file_data, 1, sz, fs);
if (readed != sz) {
printf("read file '%s' failed: %s.\n", keyfile, strerror(errno));
goto exit;
@@ -459,7 +497,7 @@ int get_pubkey(const char *keyfile, unsigned char *pkey) {
exitcode = 0;
exit:
- memset(file_data, 0, sizeof(file_data));
+ memset(file_data, 0, file_data_len);
memset(b64t_decoded, 0, b64t_decoded_len);
memset(base64_decoded, 0, base64_decoded_len);
memset(pubkey, 0, sizeof(curve25519_key));
@@ -470,6 +508,7 @@ exit:
free(b64t_decoded);
free(base64_decoded);
+ free(file_data);
return exitcode;
}
@@ -506,7 +545,7 @@ unsigned char *encrypt_data(const unsigned char *seckey,
size_t encrypted_len = 0;
const size_t shared_secret_len = 32;
- unsigned char shared_secret[32] = {0};
+ unsigned char *shared_secret = NULL;
const size_t nonce1_len = 32;
const size_t tag0_len = 4;
@@ -516,29 +555,35 @@ unsigned char *encrypt_data(const unsigned char *seckey,
const size_t nonce0_len = 32;
const size_t header0_len = 4;
const size_t encrypted_len_expected = data_len + tag1_len;
+ const size_t salt_len = 32;
const uint8_t *key1 = 0;
const uint8_t *nonce1 = 0;
- unsigned char params[5] = {0};
- unsigned char params_encrypted[9] = {0};
+ unsigned char *params = NULL;
+ unsigned char *params_encrypted = NULL;
const uint8_t *key0 = 0;
const uint8_t *nonce0 = 0;
- unsigned char header0[4] = {0};
+ unsigned char *header0 = NULL;
struct chacha20_drng *drng = NULL;
*out_encrypted_len = 0;
- // generate shared secret from DH X25519
- curve25519_donna(shared_secret, seckey, pubkey);
+ shared_secret = malloc(shared_secret_len);
+ params = malloc(params_len);
+ params_encrypted = malloc(params_encrypted_len);
+ header0 = malloc(header0_len);
+ rand = malloc(rand_len); // generate part 1 random data
- // generate part 1 random data
- rand = malloc(rand_len);
- if (rand == NULL) {
+ if (shared_secret == NULL || params == NULL || params_encrypted == NULL ||
+ header0 == NULL || rand == NULL) {
printf("malloc failed.\n");
goto exit;
}
+ // generate shared secret from DH X25519
+ curve25519_donna(shared_secret, seckey, pubkey);
+
int ret = drng_chacha20_init(&drng);
if (ret) {
printf("Chacha20 allocation failed: %d\n", ret);
@@ -643,10 +688,13 @@ unsigned char *encrypt_data(const unsigned char *seckey,
}
if (salt) {
- memcpy(encrypted, salt, 32);
- memcpy(32 + encrypted, pubkey, 32);
- memcpy(64 + encrypted, params_encrypted, params_encrypted_len);
- memcpy(64 + encrypted + params_encrypted_len, part1, part1_len);
+ memcpy(encrypted, salt, salt_len);
+ memcpy(salt_len + encrypted, pubkey, sizeof(curve25519_key));
+ memcpy(salt_len + sizeof(curve25519_key) + encrypted, params_encrypted,
+ params_encrypted_len);
+ memcpy(salt_len + sizeof(curve25519_key) + encrypted +
+ params_encrypted_len,
+ part1, part1_len);
} else {
memcpy(encrypted, params_encrypted, params_encrypted_len);
memcpy(encrypted + params_encrypted_len, part1, part1_len);
@@ -699,6 +747,10 @@ exit:
free(encrypted1);
free(part1);
free(encrypted);
+ free(header0);
+ free(shared_secret);
+ free(params);
+ free(params_encrypted);
return out;
}
@@ -711,15 +763,25 @@ int get_symmetrickeys(unsigned char *salt_out, unsigned char *seckey_out,
const uint32_t m_cost = (1 << 12);
const uint32_t parallelism = 1;
- char password[256] = {0};
+ char *password = NULL;
char *password_out = NULL;
- char password_verif[256] = {0};
+ char *password_verif = NULL;
char *password_verif_out = NULL;
size_t password_len = 0;
size_t password_verif_len = 0;
+ const size_t password_maxlen = 256;
+ const size_t salt_len = 32;
int exitcode = 1;
+ password = malloc(password_maxlen);
+ password_verif = malloc(password_maxlen);
+
+ if (password == NULL || password_verif == NULL) {
+ printf("Malloc failed\n");
+ goto exit;
+ }
+
int ret = drng_chacha20_init(&drng);
if (ret) {
printf("Chacha20 allocation failed: %d\n", ret);
@@ -730,21 +792,20 @@ int get_symmetrickeys(unsigned char *salt_out, unsigned char *seckey_out,
goto exit;
}
- password_out = readpassphrase("Password : ", password, sizeof(password), 0);
+ password_out = readpassphrase("Password : ", password, password_maxlen, 0);
if (password_out != password) {
printf("password input failed.\n");
goto exit;
}
- password_len = strlen(password);
+ password_len = strnlen(password, password_maxlen);
- password_verif_out =
- readpassphrase("Verifying, please re-enter : ", password_verif,
- sizeof(password_verif), 0);
+ password_verif_out = readpassphrase(
+ "Verifying, please re-enter : ", password_verif, password_maxlen, 0);
if (password_verif_out != password_verif) {
printf("password input failed.\n");
goto exit;
}
- password_verif_len = strlen(password_verif);
+ password_verif_len = strnlen(password_verif, password_maxlen);
if (password_len != password_verif_len) {
printf("Mismatch.\n");
@@ -758,7 +819,7 @@ int get_symmetrickeys(unsigned char *salt_out, unsigned char *seckey_out,
int a2res =
argon2id_hash_raw(t_cost, m_cost, parallelism, password, password_len,
- salt_out, 32, seckey_out, sizeof(curve25519_key));
+ salt_out, salt_len, seckey_out, sizeof(curve25519_key));
if (a2res != ARGON2_OK) {
printf("argon2 failed.");
goto exit;
@@ -770,8 +831,10 @@ int get_symmetrickeys(unsigned char *salt_out, unsigned char *seckey_out,
exit:
drng_chacha20_destroy(drng);
- memset(password, 0, sizeof(password));
- memset(password_verif, 0, sizeof(password_verif));
+ memset(password, 0, password_maxlen);
+ memset(password_verif, 0, password_maxlen);
+ free(password);
+ free(password_verif);
return exitcode;
}
@@ -783,7 +846,7 @@ int check_get_symmetrickeys(const unsigned char *data, const size_t data_len,
const uint32_t m_cost = (1 << 12);
const uint32_t parallelism = 1;
- char password[256] = {0};
+ char *password = NULL;
char *password_out = NULL;
size_t password_len = 0;
@@ -792,11 +855,21 @@ int check_get_symmetrickeys(const unsigned char *data, const size_t data_len,
size_t data_b64t_decoded_len = 0;
size_t encrypted_len = 0;
- unsigned char salt[32] = {0};
+ unsigned char *salt = NULL;
+ const size_t salt_len = 32;
+ const size_t password_maxlen = 256;
curve25519_key pubkey_from_secret;
int exitcode = 1;
+ password = malloc(password_maxlen);
+ salt = malloc(salt_len);
+
+ if (password == NULL || salt == NULL) {
+ printf("Malloc failed\n");
+ goto exit;
+ }
+
data_b64t_decoded = b64t_decode(data, data_len, &data_b64t_decoded_len);
encrypted =
@@ -806,19 +879,19 @@ int check_get_symmetrickeys(const unsigned char *data, const size_t data_len,
goto exit;
}
- memcpy(salt, encrypted, 32);
- memcpy(pubkey_from_secret, encrypted + 32, 32);
+ memcpy(salt, encrypted, salt_len);
+ memcpy(pubkey_from_secret, encrypted + 32, sizeof(curve25519_key));
- password_out = readpassphrase("Password : ", password, sizeof(password), 0);
+ password_out = readpassphrase("Password : ", password, password_maxlen, 0);
if (password_out != password) {
printf("password input failed.\n");
goto exit;
}
- password_len = strlen(password);
+ password_len = strnlen(password, password_maxlen);
int a2res =
argon2id_hash_raw(t_cost, m_cost, parallelism, password, password_len,
- salt, 32, seckey_out, sizeof(curve25519_key));
+ salt, salt_len, seckey_out, sizeof(curve25519_key));
if (a2res != ARGON2_OK) {
printf("argon2 failed.");
goto exit;
@@ -828,7 +901,7 @@ int check_get_symmetrickeys(const unsigned char *data, const size_t data_len,
if (memcmp(pubkey_out, pubkey_from_secret, sizeof(curve25519_key)) != 0) {
printf("Wrong password\n");
memset(seckey_out, 0, sizeof(curve25519_key));
- memset(salt, 0, 32);
+ memset(salt, 0, salt_len);
memset(pubkey_out, 0, sizeof(curve25519_key));
goto exit;
}
@@ -836,12 +909,15 @@ int check_get_symmetrickeys(const unsigned char *data, const size_t data_len,
exitcode = 0;
exit:
- memset(password, 0, sizeof(password));
+ memset(password, 0, password_maxlen);
memset(encrypted, 0, encrypted_len);
memset(data_b64t_decoded, 0, data_b64t_decoded_len);
+ memset(salt, 0, salt_len);
free(encrypted);
free(data_b64t_decoded);
+ free(password);
+ free(salt);
return exitcode;
}
@@ -861,8 +937,8 @@ unsigned char *decrypt_data(const unsigned char *seckey,
unsigned char *message = NULL;
unsigned char *encrypted1 = NULL;
- size_t shared_secret_len = 32;
- unsigned char shared_secret[32] = {0};
+ const size_t shared_secret_len = 32;
+ unsigned char *shared_secret = NULL;
size_t encrypted_len = 0;
size_t data_b64t_decoded_len = 0;
@@ -884,15 +960,27 @@ unsigned char *decrypt_data(const unsigned char *seckey,
const uint8_t *nonce0 = 0;
const size_t header0_len = 4;
- unsigned char header0[4] = {0};
+ unsigned char *header0 = NULL;
const uint8_t *key0 = 0;
- unsigned char encrypted0[9] = {0};
+ unsigned char *encrypted0 = NULL;
+ const size_t encrypted0_len = 9;
const size_t params_len = 5;
- unsigned char params[5];
+ unsigned char *params = NULL;
size_t norx_params_len = 0;
const uint8_t *nonce1 = 0;
const uint8_t *key1 = 0;
+ shared_secret = malloc(shared_secret_len);
+ encrypted0 = malloc(encrypted0_len);
+ params = malloc(params_len);
+ header0 = malloc(header0_len);
+
+ if (shared_secret == NULL || encrypted0 == NULL || params == NULL ||
+ header0 == NULL) {
+ printf("Malloc failed\n");
+ goto exit;
+ }
+
// shared secret DH X25519
curve25519_donna(shared_secret, seckey, pubkey);
@@ -1031,6 +1119,11 @@ exit:
memset(&nc0, 0, sizeof(sha3_context));
memset(&nc1, 0, sizeof(sha3_context));
+ free(shared_secret);
+ free(encrypted0);
+ free(params);
+ free(header0);
+
free(data_b64t_decoded);
if (symmetric_flag)
free(encrypted - 64);