Adjust I/O buffer size according to file size + allow slightly bigger maximum buffer size.

This commit is contained in:
LoRd_MuldeR 2022-04-12 23:55:08 +02:00
parent 8b1b8aec64
commit 2cee77b108
Signed by: mulder
GPG Key ID: 2B5913365F57E03F
3 changed files with 41 additions and 28 deletions

View File

@ -28,7 +28,7 @@
static const uint64_t MAGIC_NUMBER = 0x243F6A8885A308D3ull; static const uint64_t MAGIC_NUMBER = 0x243F6A8885A308D3ull;
#define BUFFER_SIZE 65536U #define MAX_BUFFER_SIZE 1048576U // 1 MiB
// ========================================================================== // ==========================================================================
// Auxiliary functions // Auxiliary functions
@ -36,25 +36,36 @@ static const uint64_t MAGIC_NUMBER = 0x243F6A8885A308D3ull;
static int open_files(FILE **const file_in, FILE **const file_out, const CHR *const input_path, const CHR *const output_path) static int open_files(FILE **const file_in, FILE **const file_out, const CHR *const input_path, const CHR *const output_path)
{ {
if (!(*file_in = FOPEN(input_path, T("rb")))) if (!(*file_in = FOPEN(input_path, "rb")))
{ {
FPRINTF(stderr, T("Error: Failed to open input file \"%") T(PRISTR) T("\" for reading!\n\n%") T(PRISTR) T("\n\n"), input_path, STRERROR(errno)); FPRINTF(stderr, T("Error: Failed to open input file \"%") T(PRISTR) T("\" for reading!\n\n%") T(PRISTR) T("\n\n"), input_path, STRERROR(errno));
*file_out = NULL; *file_out = NULL;
return EXIT_FAILURE; return EXIT_FAILURE;
} }
if (!(*file_out = FOPEN(output_path, T("wb")))) if (!(*file_out = FOPEN(output_path, "wb")))
{ {
FPRINTF(stderr, T("Error: Failed to open output file \"%") T(PRISTR) T("\" for writing!\n\n%") T(PRISTR) T("\n\n"), output_path, STRERROR(errno)); FPRINTF(stderr, T("Error: Failed to open output file \"%") T(PRISTR) T("\" for writing!\n\n%") T(PRISTR) T("\n\n"), output_path, STRERROR(errno));
return EXIT_FAILURE; return EXIT_FAILURE;
} }
setvbuf(*file_in, NULL, _IOFBF, (((8U * BUFFER_SIZE) + (BUFSIZ - 1U)) / BUFSIZ) * BUFSIZ); //setvbuf(*file_in, NULL, _IOFBF, (((8U * BUFFER_SIZE) + (BUFSIZ - 1U)) / BUFSIZ) * BUFSIZ);
setvbuf(*file_out, NULL, _IOFBF, (((8U * BUFFER_SIZE) + (BUFSIZ - 1U)) / BUFSIZ) * BUFSIZ); //setvbuf(*file_out, NULL, _IOFBF, (((8U * BUFFER_SIZE) + (BUFSIZ - 1U)) / BUFSIZ) * BUFSIZ);
return EXIT_SUCCESS; return EXIT_SUCCESS;
} }
static size_t get_buffer_size(const uint64_t file_size)
{
const uint64_t upper_limit = file_size / 101U;
size_t pwr2, result = 0U;
for (pwr2 = 1U; (pwr2 <= MAX_BUFFER_SIZE) && (pwr2 <= upper_limit); pwr2 <<= 1)
{
result = pwr2;
}
return BOUND(BUFSIZ, result, MAX_BUFFER_SIZE);
}
static void init_slunk_param(slunkparam_t *const param, const crypt_options_t *const options) static void init_slunk_param(slunkparam_t *const param, const crypt_options_t *const options)
{ {
slunkcrypt_bzero(param, sizeof(slunkparam_t)); slunkcrypt_bzero(param, sizeof(slunkparam_t));
@ -83,14 +94,9 @@ int encrypt(const char *const passphrase, const CHR *const input_path, const CHR
slunkcrypt_t ctx = SLUNKCRYPT_NULL; slunkcrypt_t ctx = SLUNKCRYPT_NULL;
slunkparam_t param; slunkparam_t param;
FILE *file_in = NULL, *file_out = NULL; FILE *file_in = NULL, *file_out = NULL;
int result = EXIT_FAILURE, status; uint8_t *buffer = NULL;
size_t buffer_size = BUFSIZ;
uint8_t *buffer = malloc(BUFFER_SIZE * sizeof(uint8_t)); int result = EXIT_FAILURE, status = -1;
if (!buffer)
{
FPUTS(T("Error: Failed to allocate the I/O buffer!\n\n"), stderr);
goto clean_up;
}
if (open_files(&file_in, &file_out, input_path, output_path) != EXIT_SUCCESS) if (open_files(&file_in, &file_out, input_path, output_path) != EXIT_SUCCESS)
{ {
@ -109,6 +115,12 @@ int encrypt(const char *const passphrase, const CHR *const input_path, const CHR
goto clean_up; goto clean_up;
} }
if (!(buffer = malloc((buffer_size = get_buffer_size(file_size)) * sizeof(uint8_t))))
{
FPUTS(T("Error: Failed to allocate the I/O buffer!\n\n"), stderr);
goto clean_up;
}
FPUTS(T("Encrypting file contents, please be patient... "), stderr); FPUTS(T("Encrypting file contents, please be patient... "), stderr);
fflush(stderr); fflush(stderr);
@ -145,7 +157,7 @@ int encrypt(const char *const passphrase, const CHR *const input_path, const CHR
while (bytes_read < file_size) while (bytes_read < file_size)
{ {
const uint64_t bytes_remaining = file_size - bytes_read; const uint64_t bytes_remaining = file_size - bytes_read;
const size_t request_len = (bytes_remaining < BUFFER_SIZE) ? ((size_t)bytes_remaining) : BUFFER_SIZE; const size_t request_len = (bytes_remaining < buffer_size) ? ((size_t)bytes_remaining) : buffer_size;
const size_t count = fread(buffer, sizeof(uint8_t), request_len, file_in); const size_t count = fread(buffer, sizeof(uint8_t), request_len, file_in);
if (count > 0U) if (count > 0U)
{ {
@ -247,7 +259,7 @@ clean_up:
if (buffer) if (buffer)
{ {
slunkcrypt_bzero(buffer, BUFFER_SIZE * sizeof(uint8_t)); slunkcrypt_bzero(buffer, buffer_size * sizeof(uint8_t));
free(buffer); free(buffer);
} }
@ -267,14 +279,9 @@ int decrypt(const char *const passphrase, const CHR *const input_path, const CHR
slunkcrypt_t ctx = SLUNKCRYPT_NULL; slunkcrypt_t ctx = SLUNKCRYPT_NULL;
slunkparam_t param; slunkparam_t param;
FILE *file_in = NULL, *file_out = NULL; FILE *file_in = NULL, *file_out = NULL;
int result = EXIT_FAILURE, status; uint8_t *buffer = NULL;
size_t buffer_size = BUFSIZ;
uint8_t *buffer = malloc(BUFFER_SIZE * sizeof(uint8_t)); int result = EXIT_FAILURE, status = -1;
if (!buffer)
{
FPUTS(T("Error: Failed to allocate the I/O buffer!\n\n"), stderr);
goto clean_up;
}
if (open_files(&file_in, &file_out, input_path, output_path) != EXIT_SUCCESS) if (open_files(&file_in, &file_out, input_path, output_path) != EXIT_SUCCESS)
{ {
@ -297,6 +304,12 @@ int decrypt(const char *const passphrase, const CHR *const input_path, const CHR
FPRINTF(stderr, T("Warning: File size is *not* an integer multiple of %u, ignoring excess bytes!\n\n"), (unsigned)sizeof(uint64_t)); FPRINTF(stderr, T("Warning: File size is *not* an integer multiple of %u, ignoring excess bytes!\n\n"), (unsigned)sizeof(uint64_t));
} }
if (!(buffer = malloc((buffer_size = get_buffer_size(file_size)) * sizeof(uint8_t))))
{
FPUTS(T("Error: Failed to allocate the I/O buffer!\n\n"), stderr);
goto clean_up;
}
FPUTS(T("Decrypting file contents, please be patient... "), stderr); FPUTS(T("Decrypting file contents, please be patient... "), stderr);
fflush(stderr); fflush(stderr);
@ -328,7 +341,7 @@ int decrypt(const char *const passphrase, const CHR *const input_path, const CHR
while (bytes_read < read_limit) while (bytes_read < read_limit)
{ {
const uint64_t bytes_remaining = read_limit - bytes_read; const uint64_t bytes_remaining = read_limit - bytes_read;
const size_t request_len = (bytes_remaining < BUFFER_SIZE) ? ((size_t)bytes_remaining) : BUFFER_SIZE; const size_t request_len = (bytes_remaining < buffer_size) ? ((size_t)bytes_remaining) : buffer_size;
const size_t count = fread(buffer, sizeof(uint8_t), request_len, file_in); const size_t count = fread(buffer, sizeof(uint8_t), request_len, file_in);
if (count > 0U) if (count > 0U)
{ {
@ -442,7 +455,7 @@ clean_up:
if (buffer) if (buffer)
{ {
slunkcrypt_bzero(buffer, BUFFER_SIZE * sizeof(uint8_t)); slunkcrypt_bzero(buffer, buffer_size * sizeof(uint8_t));
free(buffer); free(buffer);
} }

View File

@ -73,7 +73,7 @@
# define FPUTS(X,Y) fputws((X),(Y)) # define FPUTS(X,Y) fputws((X),(Y))
# define FPRINTF(X,Y,...) fwprintf((X),(Y),__VA_ARGS__) # define FPRINTF(X,Y,...) fwprintf((X),(Y),__VA_ARGS__)
# define REMOVE(X) _wremove((X)) # define REMOVE(X) _wremove((X))
# define FOPEN(X,Y) _wfsopen((X),(Y),_SH_SECURE) # define FOPEN(X,Y) _wfsopen((X),_T(Y) L"S",_SH_SECURE)
# define STRERROR(X) _wcserror((X)) # define STRERROR(X) _wcserror((X))
# ifdef __USE_MINGW_ANSI_STDIO # ifdef __USE_MINGW_ANSI_STDIO
# define PRISTR "ls" # define PRISTR "ls"

View File

@ -65,7 +65,7 @@ char *read_passphrase(const CHR *const file_name)
goto finish; goto finish;
} }
passphrase_file = STRICMP(file_name, T("-")) ? FOPEN(file_name, T("rb")) : stdin; passphrase_file = STRICMP(file_name, T("-")) ? FOPEN(file_name, "rb") : stdin;
if (!passphrase_file) if (!passphrase_file)
{ {
FPRINTF(stderr, T("Error: Failed to open passphrase file \"%") T(PRISTR) T("\" for reading!\n\n%") T(PRISTR) T("\n\n"), file_name, STRERROR(errno)); FPRINTF(stderr, T("Error: Failed to open passphrase file \"%") T(PRISTR) T("\" for reading!\n\n%") T(PRISTR) T("\n\n"), file_name, STRERROR(errno));