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)
|
static int encrypt(const char* const passphrase, const CHR* const input_path, const CHR* const output_path)
|
||||||
{
|
{
|
||||||
slunkcrypt_t ctx = SLUNKCRYPT_NULL;
|
slunkcrypt_t ctx = SLUNKCRYPT_NULL;
|
||||||
FILE * file_in = NULL, * file_out = 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)
|
if (open_files(&file_in, &file_out, input_path, output_path) != EXIT_SUCCESS)
|
||||||
{
|
{
|
||||||
@ -235,8 +235,7 @@ static int encrypt(const char* const passphrase, const CHR* const input_path, co
|
|||||||
{
|
{
|
||||||
crc_actual = crc64_update(crc_actual, buffer, count);
|
crc_actual = crc64_update(crc_actual, buffer, count);
|
||||||
bytes_read += count;
|
bytes_read += count;
|
||||||
const int status = slunkcrypt_encrypt_inplace(ctx, buffer, count);
|
if ((status = slunkcrypt_encrypt_inplace(ctx, buffer, count)) != SLUNKCRYPT_SUCCESS)
|
||||||
if (status != SLUNKCRYPT_SUCCESS)
|
|
||||||
{
|
{
|
||||||
FPUTS((status == SLUNKCRYPT_ABORTED) ? T("\n\nProcess interrupted!\n\n") : T("\n\nSlunkCrypt error: Failed to encrypt data!\n\n"), stderr);
|
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;
|
||||||
@ -265,16 +264,35 @@ static int encrypt(const char* const passphrase, const CHR* const input_path, co
|
|||||||
goto clean_up;
|
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);
|
FPUTS(T("\n\nI/O error: Input file could not be fully read!\n\n"), stderr);
|
||||||
goto clean_up;
|
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));
|
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_encrypt_inplace(ctx, (uint8_t*)&crc_actual, sizeof(uint64_t))) != SLUNKCRYPT_SUCCESS)
|
||||||
if (status != SLUNKCRYPT_SUCCESS)
|
|
||||||
{
|
{
|
||||||
FPUTS((status == SLUNKCRYPT_ABORTED) ? T("\n\nProcess interrupted!\n\n") : T("\n\nSlunkCrypt error: Failed to encrypt checksum!\n\n"), stderr);
|
FPUTS((status == SLUNKCRYPT_ABORTED) ? T("\n\nProcess interrupted!\n\n") : T("\n\nSlunkCrypt error: Failed to encrypt checksum!\n\n"), stderr);
|
||||||
goto clean_up;
|
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;
|
slunkcrypt_t ctx = SLUNKCRYPT_NULL;
|
||||||
FILE *file_in = NULL, *file_out = 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)
|
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);
|
FPUTS(T("I/O error: Failed to determine size of input file!\n\n"), stderr);
|
||||||
goto clean_up;
|
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);
|
FPUTS(T("Error: Input file is too small! Truncated?\n\n"), stderr);
|
||||||
goto clean_up;
|
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();
|
clock_t clk_now, clk_update = clock();
|
||||||
uint64_t crc_actual = CRC_INITIALIZER, bytes_read = sizeof(uint64_t);
|
uint64_t crc_actual = CRC_INITIALIZER, bytes_read = sizeof(uint64_t);
|
||||||
uint8_t buffer[BUFFER_SIZE];
|
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);
|
FPRINTF(stderr, T("%5.1f%% "), 0.0);
|
||||||
fflush(stderr);
|
fflush(stderr);
|
||||||
@ -374,8 +392,7 @@ static int decrypt(const char* const passphrase, const CHR* const input_path, co
|
|||||||
if (count > 0U)
|
if (count > 0U)
|
||||||
{
|
{
|
||||||
bytes_read += count;
|
bytes_read += count;
|
||||||
const int status = slunkcrypt_decrypt_inplace(ctx, buffer, count);
|
if ((status = slunkcrypt_decrypt_inplace(ctx, buffer, count)) != SLUNKCRYPT_SUCCESS)
|
||||||
if (status != SLUNKCRYPT_SUCCESS)
|
|
||||||
{
|
{
|
||||||
FPUTS((status == SLUNKCRYPT_ABORTED) ? T("\n\nProcess interrupted!\n\n") : T("\n\nSlunkCrypt error: Failed to decrypt data!\n\n"), stderr);
|
FPUTS((status == SLUNKCRYPT_ABORTED) ? T("\n\nProcess interrupted!\n\n") : T("\n\nSlunkCrypt error: Failed to decrypt data!\n\n"), stderr);
|
||||||
goto clean_up;
|
goto clean_up;
|
||||||
@ -405,12 +422,43 @@ static int decrypt(const char* const passphrase, const CHR* const input_path, co
|
|||||||
goto clean_up;
|
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);
|
FPUTS(T("\n\nI/O error: Input file could not be fully read!\n\n"), stderr);
|
||||||
goto clean_up;
|
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);
|
crc_actual = crc64_finish(crc_actual);
|
||||||
|
|
||||||
uint64_t crc_expected;
|
uint64_t crc_expected;
|
||||||
@ -420,8 +468,7 @@ static int decrypt(const char* const passphrase, const CHR* const input_path, co
|
|||||||
goto clean_up;
|
goto clean_up;
|
||||||
}
|
}
|
||||||
|
|
||||||
const int status = slunkcrypt_decrypt_inplace(ctx, (uint8_t*)&crc_expected, sizeof(uint64_t));
|
if ((status = slunkcrypt_decrypt_inplace(ctx, (uint8_t*)&crc_expected, sizeof(uint64_t))) != SLUNKCRYPT_SUCCESS)
|
||||||
if (status != SLUNKCRYPT_SUCCESS)
|
|
||||||
{
|
{
|
||||||
FPUTS((status == SLUNKCRYPT_ABORTED) ? T("\n\nProcess interrupted!\n\n") : T("\n\nSlunkCrypt error: Failed to decrypt checksum!\n\n"), stderr);
|
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;
|
||||||
|
@ -18,4 +18,7 @@ char* CHR_to_utf8(const CHR *const input);
|
|||||||
uint64_t get_file_size(FILE* const file);
|
uint64_t get_file_size(FILE* const file);
|
||||||
const CHR *get_file_name(const CHR *path);
|
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
|
#endif
|
||||||
|
Loading…
Reference in New Issue
Block a user