libgnunetchat

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

commit 5ad18ea2e0f08ba3b12cc00a0d38ceb51fff3763
parent 167219b009bd1fa85bfb104e368f28eba2059052
Author: Jacki <jacki@thejackimonster.de>
Date:   Thu, 21 May 2026 00:39:09 +0200

Fix iv selection during bigger file encryption

Signed-off-by: Jacki <jacki@thejackimonster.de>

Diffstat:
Msrc/gnunet_chat_lib.c | 30+++++++++++++++++-------------
Msrc/gnunet_chat_util.c | 32+++++++++++++++++++++-----------
2 files changed, 38 insertions(+), 24 deletions(-)

diff --git a/src/gnunet_chat_lib.c b/src/gnunet_chat_lib.c @@ -2731,43 +2731,47 @@ GNUNET_CHAT_file_open_preview (struct GNUNET_CHAT_File *file) if (!file) return NULL; - + if (file->preview) return file->preview; - + char *filename = handle_create_file_path( file->handle, &(file->hash) ); if (!filename) return NULL; - + if (GNUNET_YES != GNUNET_DISK_file_test(filename)) goto free_filename; - + if (!(file->key)) { file->preview = filename; return file->preview; } - + file->preview = GNUNET_DISK_mktemp( file->name? file->name : "" ); if (!(file->preview)) goto free_filename; - + remove(file->preview); - if ((GNUNET_OK != GNUNET_DISK_file_copy(filename, file->preview)) || - (GNUNET_OK != util_decrypt_file(file->preview, - &(file->hash), file->key))) - { - GNUNET_free(file->preview); - file->preview = NULL; - } + if (GNUNET_OK != GNUNET_DISK_file_copy(filename, file->preview)) + goto cleanup_preview; + + if (GNUNET_OK == util_decrypt_file(file->preview, &(file->hash), file->key)) + goto free_filename; + remove(file->preview); + +cleanup_preview: + GNUNET_free(file->preview); + file->preview = NULL; + free_filename: GNUNET_free(filename); return file->preview; diff --git a/src/gnunet_chat_util.c b/src/gnunet_chat_util.c @@ -176,7 +176,6 @@ util_encrypt_file (const char *filename, return GNUNET_SYSERR; } - struct GNUNET_CRYPTO_SymmetricInitializationVector iv; const uint64_t block_size = 1024*1024; ssize_t result = 0; @@ -185,14 +184,18 @@ util_encrypt_file (const char *filename, if (!key) goto skip_encryption; + struct GNUNET_CRYPTO_SymmetricInitializationVector first_iv; + if (GNUNET_YES != GNUNET_CRYPTO_hkdf_gnunet ( - &iv, sizeof (iv), + &first_iv, sizeof (first_iv), GNUNET_CHAT_SALT_FILE, sizeof (GNUNET_CHAT_SALT_FILE), key, sizeof (*key), GNUNET_CRYPTO_kdf_arg_auto(hash))) return GNUNET_SYSERR; + + struct GNUNET_CRYPTO_SymmetricInitializationVector iv; for (uint64_t i = 0; i < blocks; i++) { @@ -204,6 +207,8 @@ util_encrypt_file (const char *filename, if (index > 0) memcpy(&iv, ((uint8_t*) data) + (block_size * (index - 1)), sizeof(iv)); + else + memcpy(&iv, &first_iv, sizeof(iv)); result = GNUNET_CRYPTO_symmetric_encrypt( location, @@ -249,10 +254,10 @@ util_decrypt_file (const char *filename, filename, GNUNET_DISK_OPEN_READWRITE, GNUNET_DISK_PERM_USER_READ | GNUNET_DISK_PERM_USER_WRITE ); - + if (!file) return GNUNET_SYSERR; - + struct GNUNET_DISK_MapHandle *mapping = NULL; void* data = GNUNET_DISK_file_map( file, &mapping, GNUNET_DISK_MAP_TYPE_READWRITE, size @@ -263,8 +268,7 @@ util_decrypt_file (const char *filename, GNUNET_DISK_file_close(file); return GNUNET_SYSERR; } - - struct GNUNET_CRYPTO_SymmetricInitializationVector iv; + const uint64_t block_size = 1024*1024; struct GNUNET_HashCode check; ssize_t result = 0; @@ -273,15 +277,19 @@ util_decrypt_file (const char *filename, if (!key) goto skip_decryption; - + + struct GNUNET_CRYPTO_SymmetricInitializationVector first_iv; + if (GNUNET_YES != GNUNET_CRYPTO_hkdf_gnunet ( - &iv, sizeof (iv), + &first_iv, sizeof (first_iv), GNUNET_CHAT_SALT_FILE, sizeof (GNUNET_CHAT_SALT_FILE), key, sizeof (*key), GNUNET_CRYPTO_kdf_arg_auto(hash))) return GNUNET_SYSERR; + + struct GNUNET_CRYPTO_SymmetricInitializationVector iv; for (uint64_t index = 0; index < blocks; index++) { @@ -292,6 +300,8 @@ util_decrypt_file (const char *filename, if (index > 0) memcpy(&iv, ((uint8_t*) data) + (block_size * (index - 1)), sizeof(iv)); + else + memcpy(&iv, &first_iv, sizeof(iv)); result = GNUNET_CRYPTO_symmetric_decrypt( location, @@ -304,7 +314,7 @@ util_decrypt_file (const char *filename, if (result < 0) break; } - + skip_decryption: GNUNET_CRYPTO_hash(data, size, &check); @@ -319,10 +329,10 @@ skip_decryption: if (GNUNET_OK != GNUNET_DISK_file_close(file)) result = -1; - + if (result < 0) return GNUNET_SYSERR; - + return GNUNET_OK; }