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;
#define BUFFER_SIZE 65536U
#define MAX_BUFFER_SIZE 1048576U // 1 MiB
// ==========================================================================
// 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)
{
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));
*file_out = NULL;
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));
return EXIT_FAILURE;
}
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_in, NULL, _IOFBF, (((8U * BUFFER_SIZE) + (BUFSIZ - 1U)) / BUFSIZ) * BUFSIZ);
//setvbuf(*file_out, NULL, _IOFBF, (((8U * BUFFER_SIZE) + (BUFSIZ - 1U)) / BUFSIZ) * BUFSIZ);
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)
{
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;
slunkparam_t param;
FILE *file_in = NULL, *file_out = NULL;
int result = EXIT_FAILURE, status;
uint8_t *buffer = malloc(BUFFER_SIZE * sizeof(uint8_t));
if (!buffer)
{
FPUTS(T("Error: Failed to allocate the I/O buffer!\n\n"), stderr);
goto clean_up;
}
uint8_t *buffer = NULL;
size_t buffer_size = BUFSIZ;
int result = EXIT_FAILURE, status = -1;
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;
}
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);
fflush(stderr);
@ -145,7 +157,7 @@ int encrypt(const char *const passphrase, const CHR *const input_path, const CHR
while (bytes_read < file_size)
{
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);
if (count > 0U)
{
@ -247,7 +259,7 @@ clean_up:
if (buffer)
{
slunkcrypt_bzero(buffer, BUFFER_SIZE * sizeof(uint8_t));
slunkcrypt_bzero(buffer, buffer_size * sizeof(uint8_t));
free(buffer);
}
@ -267,14 +279,9 @@ int decrypt(const char *const passphrase, const CHR *const input_path, const CHR
slunkcrypt_t ctx = SLUNKCRYPT_NULL;
slunkparam_t param;
FILE *file_in = NULL, *file_out = NULL;
int result = EXIT_FAILURE, status;
uint8_t *buffer = malloc(BUFFER_SIZE * sizeof(uint8_t));
if (!buffer)
{
FPUTS(T("Error: Failed to allocate the I/O buffer!\n\n"), stderr);
goto clean_up;
}
uint8_t *buffer = NULL;
size_t buffer_size = BUFSIZ;
int result = EXIT_FAILURE, status = -1;
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));
}
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);
fflush(stderr);
@ -328,7 +341,7 @@ int decrypt(const char *const passphrase, const CHR *const input_path, const CHR
while (bytes_read < read_limit)
{
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);
if (count > 0U)
{
@ -442,7 +455,7 @@ clean_up:
if (buffer)
{
slunkcrypt_bzero(buffer, BUFFER_SIZE * sizeof(uint8_t));
slunkcrypt_bzero(buffer, buffer_size * sizeof(uint8_t));
free(buffer);
}

View File

@ -73,7 +73,7 @@
# define FPUTS(X,Y) fputws((X),(Y))
# define FPRINTF(X,Y,...) fwprintf((X),(Y),__VA_ARGS__)
# 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))
# ifdef __USE_MINGW_ANSI_STDIO
# define PRISTR "ls"

View File

@ -65,7 +65,7 @@ char *read_passphrase(const CHR *const file_name)
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)
{
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));