Store and load the Nonce as well as the CRC checksum in a byte-order-agnostic way.

This commit is contained in:
LoRd_MuldeR 2020-10-27 21:26:30 +01:00
parent ae3318a12f
commit 0f7c309034
Signed by: mulder
GPG Key ID: 2B5913365F57E03F
3 changed files with 90 additions and 42 deletions

View File

@ -189,26 +189,27 @@ static int encrypt(const char* const passphrase, const CHR* const input_path, co
FPUTS(T("Encrypting file contents, please be patient... "), stderr); FPUTS(T("Encrypting file contents, please be patient... "), stderr);
fflush(stderr); fflush(stderr);
uint64_t salt; uint64_t nonce;
if (slunkcrypt_generate_salt(&salt) != SLUNKCRYPT_SUCCESS) if (slunkcrypt_generate_nonce(&nonce) != SLUNKCRYPT_SUCCESS)
{ {
FPUTS(T("\n\nSlunkCrypt error: Failed to generate salt!\n\n"), stderr); FPUTS(T("\n\nSlunkCrypt error: Failed to generate salt!\n\n"), stderr);
goto clean_up; goto clean_up;
} }
if (fwrite(&salt, sizeof(uint64_t), 1U, file_out) < 1U) ctx = slunkcrypt_alloc(nonce, (const uint8_t*)passphrase, strlen(passphrase));
{
FPUTS(T("\n\nI/O error: Failed to write salt value!\n\n"), stderr);
goto clean_up;
}
ctx = slunkcrypt_alloc(salt, (const uint8_t*)passphrase, strlen(passphrase));
if (!ctx) if (!ctx)
{ {
FPUTS(g_slunkcrypt_abort_flag ? T("\n\nProcess interrupted!\n\n") : T("\n\nSlunkCrypt error: Failed to initialize encryption!\n\n"), stderr); FPUTS(g_slunkcrypt_abort_flag ? T("\n\nProcess interrupted!\n\n") : T("\n\nSlunkCrypt error: Failed to initialize encryption!\n\n"), stderr);
goto clean_up; goto clean_up;
} }
nonce = swap_bytes_u64(nonce);
if (fwrite(&nonce, sizeof(uint64_t), 1U, file_out) < 1U)
{
FPUTS(T("\n\nI/O error: Failed to write salt value!\n\n"), stderr);
goto clean_up;
}
clock_t clk_now, clk_update = clock(); clock_t clk_now, clk_update = clock();
uint64_t crc_actual = CRC_INITIALIZER, bytes_read = 0U; uint64_t crc_actual = CRC_INITIALIZER, bytes_read = 0U;
uint8_t buffer[BUFFER_SIZE]; uint8_t buffer[BUFFER_SIZE];
@ -261,7 +262,7 @@ static int encrypt(const char* const passphrase, const CHR* const input_path, co
goto clean_up; goto clean_up;
} }
crc_actual = 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)); const int status = slunkcrypt_encrypt_inplace(ctx, (uint8_t*)&crc_actual, sizeof(uint64_t));
if (status != SLUNKCRYPT_SUCCESS) if (status != SLUNKCRYPT_SUCCESS)
@ -334,14 +335,14 @@ static int decrypt(const char* const passphrase, const CHR* const input_path, co
FPUTS(T("Decrypting file contents, please be patient... "), stderr); FPUTS(T("Decrypting file contents, please be patient... "), stderr);
fflush(stderr); fflush(stderr);
uint64_t salt; uint64_t nonce;
if (fread(&salt, sizeof(uint64_t), 1U, file_in) < 1U) if (fread(&nonce, sizeof(uint64_t), 1U, file_in) < 1U)
{ {
FPUTS(T("\n\nI/O error: Failed to read salt value!\n\n"), stderr); FPUTS(T("\n\nI/O error: Failed to read salt value!\n\n"), stderr);
goto clean_up; goto clean_up;
} }
ctx = slunkcrypt_alloc(salt, (const uint8_t*)passphrase, strlen(passphrase)); ctx = slunkcrypt_alloc(swap_bytes_u64(nonce), (const uint8_t*)passphrase, strlen(passphrase));
if (!ctx) if (!ctx)
{ {
FPUTS(g_slunkcrypt_abort_flag ? T("\n\nProcess interrupted!\n\n") : T("\n\nSlunkCrypt error: Failed to initialize decryption!\n\n"), stderr); FPUTS(g_slunkcrypt_abort_flag ? T("\n\nProcess interrupted!\n\n") : T("\n\nSlunkCrypt error: Failed to initialize decryption!\n\n"), stderr);
@ -417,6 +418,8 @@ static int decrypt(const char* const passphrase, const CHR* const input_path, co
goto clean_up; goto clean_up;
} }
crc_expected = swap_bytes_u64(crc_expected);
FPRINTF(stderr, T("\b\b\b\b\b\b\b%5.1f%%\n\n"), 100.0); FPRINTF(stderr, T("\b\b\b\b\b\b\b%5.1f%%\n\n"), 100.0);
fflush(stderr); fflush(stderr);
@ -464,8 +467,8 @@ static int run_test_case(const char *const message, const uint64_t checksum)
const size_t length = strlen(message) + 1U; const size_t length = strlen(message) + 1U;
slunkcrypt_t ctx = SLUNKCRYPT_NULL; slunkcrypt_t ctx = SLUNKCRYPT_NULL;
uint64_t salt; uint64_t nonce;
if (slunkcrypt_generate_salt(&salt) != SLUNKCRYPT_SUCCESS) if (slunkcrypt_generate_nonce(&nonce) != SLUNKCRYPT_SUCCESS)
{ {
FPUTS(T("\n\nWhoops: Failed to generate salt!\n\n"), stderr); FPUTS(T("\n\nWhoops: Failed to generate salt!\n\n"), stderr);
return EXIT_FAILURE; return EXIT_FAILURE;
@ -485,7 +488,7 @@ static int run_test_case(const char *const message, const uint64_t checksum)
goto clean_up; goto clean_up;
} }
ctx = slunkcrypt_alloc(salt, (const uint8_t*)passphrase, strlen(passphrase)); ctx = slunkcrypt_alloc(nonce, (const uint8_t*)passphrase, strlen(passphrase));
if (!ctx) if (!ctx)
{ {
FPUTS(g_slunkcrypt_abort_flag ? T("\n\nProcess interrupted!\n\n") : T("\n\nWhoops: Failed to initialize encoder!\n\n"), stderr); FPUTS(g_slunkcrypt_abort_flag ? T("\n\nProcess interrupted!\n\n") : T("\n\nWhoops: Failed to initialize encoder!\n\n"), stderr);
@ -505,7 +508,7 @@ static int run_test_case(const char *const message, const uint64_t checksum)
goto clean_up; goto clean_up;
} }
status = slunkcrypt_reset(ctx, salt, (const uint8_t*)passphrase, strlen(passphrase)); status = slunkcrypt_reset(ctx, nonce, (const uint8_t*)passphrase, strlen(passphrase));
if (status != SLUNKCRYPT_SUCCESS) if (status != SLUNKCRYPT_SUCCESS)
{ {
FPUTS((status == SLUNKCRYPT_ABORTED) ? T("\n\nProcess interrupted!\n\n") : T("\n\nWhoops: Failed to initialize decoder!\n\n"), stderr); FPUTS((status == SLUNKCRYPT_ABORTED) ? T("\n\nProcess interrupted!\n\n") : T("\n\nWhoops: Failed to initialize decoder!\n\n"), stderr);

View File

@ -4,10 +4,10 @@
/******************************************************************************/ /******************************************************************************/
#ifdef _WIN32 #ifdef _WIN32
#define WIN32_LEAN_AND_MEAN 1 # define WIN32_LEAN_AND_MEAN 1
#define _CRT_SECURE_NO_WARNINGS 1 # define _CRT_SECURE_NO_WARNINGS 1
#else #else
#define _GNU_SOURCE 1 # define _GNU_SOURCE 1
#endif #endif
#include "utils.h" #include "utils.h"
@ -16,33 +16,40 @@
#include <sys/types.h> #include <sys/types.h>
#include <signal.h> #include <signal.h>
/* Platform support */
#ifdef _WIN32 #ifdef _WIN32
#include <Windows.h> # include <Windows.h>
#include <io.h> # include <io.h>
#include <fcntl.h> # include <fcntl.h>
#define STAT_T struct _stati64 # define STAT_T struct _stati64
#define FSTAT(X,Y) _fstati64((X),(Y)) # define FSTAT(X,Y) _fstati64((X),(Y))
#define FILENO(X) _fileno((X)) # define FILENO(X) _fileno((X))
#define S_IFMT _S_IFMT # define S_IFMT _S_IFMT
#define S_IFDIR _S_IFDIR # define S_IFDIR _S_IFDIR
#define S_IFIFO _S_IFIFO # define S_IFIFO _S_IFIFO
#ifndef _O_U8TEXT # ifndef _O_U8TEXT
#define _O_U8TEXT 0x40000 # define _O_U8TEXT 0x40000
# endif
#else
# if defined(__USE_LARGEFILE64) && (__USE_LARGEFILE64)
# define STAT_T struct stat64
# define FSTAT(X,Y) fstat64((X),(Y))
# else
# define STAT_T struct stat
# define FSTAT(X,Y) fstat((X),(Y))
# endif
# define FILENO(X) fileno((X))
#endif #endif
#ifndef _DLL
// ==========================================================================
// Terminal initialization
// ==========================================================================
/* CRT imports */
#if defined(_WIN32) && !defined(_DLL)
extern char *const _acmdln; extern char *const _acmdln;
extern wchar_t *const _wcmdln; extern wchar_t *const _wcmdln;
#endif #endif
#else
#if defined(__USE_LARGEFILE64) && (__USE_LARGEFILE64)
#define STAT_T struct stat64
#define FSTAT(X,Y) fstat64((X),(Y))
#else
#define STAT_T struct stat
#define FSTAT(X,Y) fstat((X),(Y))
#endif
#define FILENO(X) fileno((X))
#endif
void init_terminal(void) void init_terminal(void)
{ {
@ -57,6 +64,10 @@ void init_terminal(void)
#endif #endif
} }
// ==========================================================================
// Signal handling
// ==========================================================================
void setup_signal_handler(const int signo, signal_handler_t* const handler) void setup_signal_handler(const int signo, signal_handler_t* const handler)
{ {
#ifdef _WIN32 #ifdef _WIN32
@ -70,6 +81,10 @@ void setup_signal_handler(const int signo, signal_handler_t* const handler)
#endif #endif
} }
// ==========================================================================
// Character set conversion
// ==========================================================================
char* CHR_to_utf8(const CHR*const input) char* CHR_to_utf8(const CHR*const input)
{ {
#ifdef _WIN32 #ifdef _WIN32
@ -101,6 +116,35 @@ char* CHR_to_utf8(const CHR*const input)
#endif #endif
} }
// ==========================================================================
// Byte-order support
// ==========================================================================
#if defined(__BYTE_ORDER) && defined(__BIG_ENDIAN) && (__BYTE_ORDER == __BIG_ENDIAN)
# define BIG_ENDIAN_BYTE_ORDER 1
#elif defined(__BYTE_ORDER__) && defined(__ORDER_BIG_ENDIAN__) && (__BYTE_ORDER__ == __ORDER_BIG_ENDIAN__)
# define BIG_ENDIAN_BYTE_ORDER 1
#else
# define BIG_ENDIAN_BYTE_ORDER 0
#endif
uint64_t swap_bytes_u64(const uint64_t value)
{
#if BIG_ENDIAN_BYTE_ORDER
return
(((value) >> 56) & 0x00000000000000FF) | (((value) >> 40) & 0x000000000000FF00) |
(((value) >> 24) & 0x0000000000FF0000) | (((value) >> 8) & 0x00000000FF000000) |
(((value) << 8) & 0x000000FF00000000) | (((value) << 24) & 0x0000FF0000000000) |
(((value) << 40) & 0x00FF000000000000) | (((value) << 56) & 0xFF00000000000000);
#else
return value; /*nothing to do*/
#endif
}
// ==========================================================================
// File functions
// ==========================================================================
uint64_t get_file_size(FILE* const file) uint64_t get_file_size(FILE* const file)
{ {
STAT_T stat; STAT_T stat;

View File

@ -13,6 +13,7 @@ typedef void (signal_handler_t)(int);
void init_terminal(void); void init_terminal(void);
void setup_signal_handler(const int signo, signal_handler_t* const handler); void setup_signal_handler(const int signo, signal_handler_t* const handler);
uint64_t swap_bytes_u64(const uint64_t value);
char* CHR_to_utf8(const CHR *const input); 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);