libgnunetchat

library for GNUnet Messenger
Log | Files | Refs | README | LICENSE

commit 551d36ad77df853998aa5726bd7d26c945122270
parent ae5feca119e594767102ce7bcc17d1a3b7580a52
Author: TheJackiMonster <thejackimonster@gmail.com>
Date:   Mon, 17 Jan 2022 13:45:01 +0100

Fixed file encryption to not be stack limited

Signed-off-by: TheJackiMonster <thejackimonster@gmail.com>

Diffstat:
Msrc/gnunet_chat_util.c | 67+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++--------
1 file changed, 59 insertions(+), 8 deletions(-)

diff --git a/src/gnunet_chat_util.c b/src/gnunet_chat_util.c @@ -103,21 +103,47 @@ util_encrypt_file (const char *filename, if (!file) return GNUNET_SYSERR; - struct GNUNET_DISK_MapHandle *mapping; + struct GNUNET_DISK_MapHandle *mapping = NULL; void* data = GNUNET_DISK_file_map( file, &mapping, GNUNET_DISK_MAP_TYPE_READWRITE, size ); - if (!data) + if ((!data) || (!mapping)) { GNUNET_DISK_file_close(file); return GNUNET_SYSERR; } struct GNUNET_CRYPTO_SymmetricInitializationVector iv; - memset(&iv, 0, sizeof(iv)); + const uint64_t block_size = 1024*1024; + ssize_t result = -1; + + const uint64_t blocks = ((size + block_size - 1) / block_size); - ssize_t result = GNUNET_CRYPTO_symmetric_encrypt(data, size, key, &iv, data); + for (uint64_t i = 0; i < blocks; i++) + { + const uint64_t index = (blocks - i - 1); + const uint64_t offset = block_size * index; + + const uint64_t remaining = (size - offset); + void* location = ((uint8_t*) data) + offset; + + if (index > 0) + memcpy(&iv, ((uint8_t*) data) + (block_size * (index - 1)), sizeof(iv)); + else + memset(&iv, 0, sizeof(iv)); + + result = GNUNET_CRYPTO_symmetric_encrypt( + location, + remaining >= block_size? block_size : remaining, + key, + &iv, + location + ); + + if (result < 0) + break; + } if (GNUNET_OK != GNUNET_DISK_file_unmap(mapping)) result = -1; @@ -153,21 +179,46 @@ util_decrypt_file (const char *filename, if (!file) return GNUNET_SYSERR; - struct GNUNET_DISK_MapHandle *mapping; + struct GNUNET_DISK_MapHandle *mapping = NULL; void* data = GNUNET_DISK_file_map( file, &mapping, GNUNET_DISK_MAP_TYPE_READWRITE, size ); - if (!data) + if ((!data) || (!mapping)) { GNUNET_DISK_file_close(file); return GNUNET_SYSERR; } struct GNUNET_CRYPTO_SymmetricInitializationVector iv; - memset(&iv, 0, sizeof(iv)); + const uint64_t block_size = 1024*1024; + ssize_t result = -1; + + const uint64_t blocks = ((size + block_size - 1) / block_size); - ssize_t result = GNUNET_CRYPTO_symmetric_decrypt(data, size, key, &iv, data); + for (uint64_t index = 0; index < blocks; index++) + { + const uint64_t offset = block_size * index; + + const uint64_t remaining = (size - offset); + void* location = ((uint8_t*) data) + offset; + + if (index > 0) + memcpy(&iv, ((uint8_t*) data) + (block_size * (index - 1)), sizeof(iv)); + else + memset(&iv, 0, sizeof(iv)); + + result = GNUNET_CRYPTO_symmetric_decrypt( + location, + remaining >= block_size? block_size : remaining, + key, + &iv, + location + ); + + if (result < 0) + break; + } if (GNUNET_OK != GNUNET_DISK_file_unmap(mapping)) result = -1;