Implemented a simple padding scheme.
This commit is contained in:
parent
99dec75db7
commit
c530556e94
@ -175,8 +175,8 @@ static void sigint_handler(const int sig)
|
||||
static int encrypt(const char* const passphrase, const CHR* const input_path, const CHR* const output_path)
|
||||
{
|
||||
slunkcrypt_t ctx = SLUNKCRYPT_NULL;
|
||||
FILE * file_in = NULL, * file_out = NULL;
|
||||
int result = EXIT_FAILURE;
|
||||
FILE *file_in = NULL, *file_out = NULL;
|
||||
int result = EXIT_FAILURE, status;
|
||||
|
||||
if (open_files(&file_in, &file_out, input_path, output_path) != EXIT_SUCCESS)
|
||||
{
|
||||
@ -235,11 +235,10 @@ static int encrypt(const char* const passphrase, const CHR* const input_path, co
|
||||
{
|
||||
crc_actual = crc64_update(crc_actual, buffer, count);
|
||||
bytes_read += count;
|
||||
const int status = slunkcrypt_encrypt_inplace(ctx, buffer, count);
|
||||
if (status != SLUNKCRYPT_SUCCESS)
|
||||
if ((status = slunkcrypt_encrypt_inplace(ctx, buffer, count)) != SLUNKCRYPT_SUCCESS)
|
||||
{
|
||||
FPUTS((status == SLUNKCRYPT_ABORTED) ? T("\n\nProcess interrupted!\n\n") : T("\n\nSlunkCrypt error: Failed to encrypt data!\n\n"), stderr);
|
||||
goto clean_up;
|
||||
goto clean_up;
|
||||
}
|
||||
if (fwrite(buffer, sizeof(uint8_t), count, file_out) < count)
|
||||
{
|
||||
@ -265,16 +264,35 @@ static int encrypt(const char* const passphrase, const CHR* const input_path, co
|
||||
goto clean_up;
|
||||
}
|
||||
|
||||
if (bytes_read < file_size)
|
||||
if (bytes_read != file_size)
|
||||
{
|
||||
FPUTS(T("\n\nI/O error: Input file could not be fully read!\n\n"), stderr);
|
||||
goto clean_up;
|
||||
}
|
||||
|
||||
const size_t padding = sizeof(uint64_t) - (file_size % sizeof(uint64_t));
|
||||
if (slunkcrypt_random_bytes(buffer, padding) < padding)
|
||||
{
|
||||
FPUTS(T("\n\nSlunkCrypt error: Failed to generate random data!\n\n"), stderr);
|
||||
goto clean_up;
|
||||
}
|
||||
|
||||
SET_NIBBLE(buffer[padding - 1U], padding);
|
||||
if ((status = slunkcrypt_encrypt_inplace(ctx, buffer, padding)) != SLUNKCRYPT_SUCCESS)
|
||||
{
|
||||
FPUTS((status == SLUNKCRYPT_ABORTED) ? T("\n\nProcess interrupted!\n\n") : T("\n\nSlunkCrypt error: Failed to encrypt data!\n\n"), stderr);
|
||||
goto clean_up;
|
||||
}
|
||||
|
||||
if (fwrite(buffer, sizeof(uint8_t), padding, file_out) < padding)
|
||||
{
|
||||
FPUTS(T("\n\nI/O error: Failed to write padding data!\n\n"), stderr);
|
||||
goto clean_up;
|
||||
}
|
||||
|
||||
crc_actual = swap_bytes_u64(crc64_finish(crc_actual));
|
||||
|
||||
const int status = slunkcrypt_encrypt_inplace(ctx, (uint8_t*)&crc_actual, sizeof(uint64_t));
|
||||
if (status != SLUNKCRYPT_SUCCESS)
|
||||
if ((status = slunkcrypt_encrypt_inplace(ctx, (uint8_t*)&crc_actual, sizeof(uint64_t))) != SLUNKCRYPT_SUCCESS)
|
||||
{
|
||||
FPUTS((status == SLUNKCRYPT_ABORTED) ? T("\n\nProcess interrupted!\n\n") : T("\n\nSlunkCrypt error: Failed to encrypt checksum!\n\n"), stderr);
|
||||
goto clean_up;
|
||||
@ -322,7 +340,7 @@ static int decrypt(const char* const passphrase, const CHR* const input_path, co
|
||||
{
|
||||
slunkcrypt_t ctx = SLUNKCRYPT_NULL;
|
||||
FILE *file_in = NULL, *file_out = NULL;
|
||||
int result = EXIT_FAILURE;
|
||||
int result = EXIT_FAILURE, status;
|
||||
|
||||
if (open_files(&file_in, &file_out, input_path, output_path) != EXIT_SUCCESS)
|
||||
{
|
||||
@ -335,7 +353,7 @@ static int decrypt(const char* const passphrase, const CHR* const input_path, co
|
||||
FPUTS(T("I/O error: Failed to determine size of input file!\n\n"), stderr);
|
||||
goto clean_up;
|
||||
}
|
||||
else if (file_size < 16U)
|
||||
else if (file_size < (3U * sizeof(uint64_t)))
|
||||
{
|
||||
FPUTS(T("Error: Input file is too small! Truncated?\n\n"), stderr);
|
||||
goto clean_up;
|
||||
@ -361,7 +379,7 @@ static int decrypt(const char* const passphrase, const CHR* const input_path, co
|
||||
clock_t clk_now, clk_update = clock();
|
||||
uint64_t crc_actual = CRC_INITIALIZER, bytes_read = sizeof(uint64_t);
|
||||
uint8_t buffer[BUFFER_SIZE];
|
||||
const uint64_t read_limit = file_size - sizeof(uint64_t);
|
||||
const uint64_t read_limit = file_size - (2U * sizeof(uint64_t));
|
||||
|
||||
FPRINTF(stderr, T("%5.1f%% "), 0.0);
|
||||
fflush(stderr);
|
||||
@ -374,8 +392,7 @@ static int decrypt(const char* const passphrase, const CHR* const input_path, co
|
||||
if (count > 0U)
|
||||
{
|
||||
bytes_read += count;
|
||||
const int status = slunkcrypt_decrypt_inplace(ctx, buffer, count);
|
||||
if (status != SLUNKCRYPT_SUCCESS)
|
||||
if ((status = slunkcrypt_decrypt_inplace(ctx, buffer, count)) != SLUNKCRYPT_SUCCESS)
|
||||
{
|
||||
FPUTS((status == SLUNKCRYPT_ABORTED) ? T("\n\nProcess interrupted!\n\n") : T("\n\nSlunkCrypt error: Failed to decrypt data!\n\n"), stderr);
|
||||
goto clean_up;
|
||||
@ -405,12 +422,43 @@ static int decrypt(const char* const passphrase, const CHR* const input_path, co
|
||||
goto clean_up;
|
||||
}
|
||||
|
||||
if (bytes_read < read_limit)
|
||||
if (bytes_read != read_limit)
|
||||
{
|
||||
FPUTS(T("\n\nI/O error: Input file could not be fully read!\n\n"), stderr);
|
||||
goto clean_up;
|
||||
}
|
||||
|
||||
if (fread(buffer, sizeof(uint8_t), sizeof(uint64_t), file_in) < sizeof(uint64_t))
|
||||
{
|
||||
FPUTS(T("\n\nI/O error: Failed to read final block!\n\n"), stderr);
|
||||
goto clean_up;
|
||||
}
|
||||
|
||||
if ((status = slunkcrypt_decrypt_inplace(ctx, buffer, sizeof(uint64_t))) != SLUNKCRYPT_SUCCESS)
|
||||
{
|
||||
FPUTS((status == SLUNKCRYPT_ABORTED) ? T("\n\nProcess interrupted!\n\n") : T("\n\nSlunkCrypt error: Failed to decrypt data!\n\n"), stderr);
|
||||
goto clean_up;
|
||||
}
|
||||
|
||||
const size_t padding = GET_NIBBLE(buffer[sizeof(uint64_t) - 1U]);
|
||||
if ((!padding) || (padding > sizeof(uint64_t)))
|
||||
{
|
||||
FPRINTF(stderr, T("\n\nPadding error: Erroneous padding length encountered! [0x%02X]\n\n"), (unsigned int)padding);
|
||||
FPUTS(T("Wrong passphrase or corrupted file?\n\n"), stderr);
|
||||
goto clean_up;
|
||||
}
|
||||
|
||||
if (padding != sizeof(uint64_t))
|
||||
{
|
||||
const size_t count = sizeof(uint64_t) - padding;
|
||||
if (fwrite(buffer, sizeof(uint8_t), count, file_out) < count)
|
||||
{
|
||||
FPUTS(T("failed!\n\nI/O error: Failed to write decrypted data!\n\n"), stderr);
|
||||
goto clean_up;
|
||||
}
|
||||
crc_actual = crc64_update(crc_actual, buffer, count);
|
||||
}
|
||||
|
||||
crc_actual = crc64_finish(crc_actual);
|
||||
|
||||
uint64_t crc_expected;
|
||||
@ -420,11 +468,10 @@ static int decrypt(const char* const passphrase, const CHR* const input_path, co
|
||||
goto clean_up;
|
||||
}
|
||||
|
||||
const int status = slunkcrypt_decrypt_inplace(ctx, (uint8_t*)&crc_expected, sizeof(uint64_t));
|
||||
if (status != SLUNKCRYPT_SUCCESS)
|
||||
if ((status = slunkcrypt_decrypt_inplace(ctx, (uint8_t*)&crc_expected, sizeof(uint64_t))) != SLUNKCRYPT_SUCCESS)
|
||||
{
|
||||
FPUTS((status == SLUNKCRYPT_ABORTED) ? T("\n\nProcess interrupted!\n\n") : T("\n\nSlunkCrypt error: Failed to decrypt checksum!\n\n"), stderr);
|
||||
goto clean_up;
|
||||
goto clean_up;
|
||||
}
|
||||
|
||||
crc_expected = swap_bytes_u64(crc_expected);
|
||||
|
@ -18,4 +18,7 @@ char* CHR_to_utf8(const CHR *const input);
|
||||
uint64_t get_file_size(FILE* const file);
|
||||
const CHR *get_file_name(const CHR *path);
|
||||
|
||||
#define GET_NIBBLE(X) ((X) & 0x0F)
|
||||
#define SET_NIBBLE(X, Y) do { X = ((X) & 0xF0) | ((Y) & 0x0F); } while(0)
|
||||
|
||||
#endif
|
||||
|
Loading…
Reference in New Issue
Block a user