Enhanced self-test routine + added macro to "safely" free SlunkCrypt instance.

This commit is contained in:
LoRd_MuldeR 2022-04-02 17:27:48 +02:00
parent 69df385d57
commit 7359ce3673
Signed by: mulder
GPG Key ID: 2B5913365F57E03F
3 changed files with 112 additions and 17 deletions

View File

@ -226,10 +226,7 @@ int encrypt(const char *const passphrase, const CHR *const input_path, const CHR
clean_up: clean_up:
if (ctx) SLUNKCRYPT_SAFE_FREE(ctx);
{
slunkcrypt_free(ctx);
}
if (file_out) if (file_out)
{ {
@ -424,10 +421,7 @@ int decrypt(const char *const passphrase, const CHR *const input_path, const CHR
clean_up: clean_up:
if (ctx) SLUNKCRYPT_SAFE_FREE(ctx);
{
slunkcrypt_free(ctx);
}
if (file_out) if (file_out)
{ {

View File

@ -106,10 +106,7 @@ static int run_testcase(const char* const message, const uint64_t nonce, const u
clean_up: clean_up:
if (ctx) SLUNKCRYPT_SAFE_FREE(ctx);
{
slunkcrypt_free(ctx);
}
if (text_temp) if (text_temp)
{ {
@ -120,9 +117,93 @@ clean_up:
return result; return result;
} }
static int run_stresstest(const uint64_t nonce)
{
static const char* const TEST_PASSPHRASE = "OrpheanBeh0lderScry!Doubt";
static const size_t LENGTH = 134217689U, CHUNKZ_ENC = 8191U, CHUNKZ_DEC = 8179U;
int status, result = EXIT_FAILURE;
size_t offset, chunk_size;
slunkcrypt_t ctx = SLUNKCRYPT_NULL;
uint8_t* const buffer = (uint8_t*)malloc(LENGTH * sizeof(uint8_t));
if (!buffer)
{
FPUTS(T("\n\nWhoops: Failed to allocate message buffer!\n\n"), stderr);
goto clean_up;
}
if (slunkcrypt_random_bytes(buffer, LENGTH) != LENGTH)
{
FPUTS(T("\n\nWhoops: Failed to generate random message!\n\n"), stderr);
goto clean_up;
}
const uint64_t checksum_original = blake2s_compute(buffer, LENGTH);
ctx = slunkcrypt_alloc(nonce, (const uint8_t*)TEST_PASSPHRASE, strlen(TEST_PASSPHRASE), SLUNKCRYPT_ENCRYPT);
if (!ctx)
{
FPUTS(g_slunkcrypt_abort_flag ? T("\n\nProcess interrupted!\n\n") : T("\n\nWhoops: Failed to initialize encoder!\n\n"), stderr);
goto clean_up;
}
for (offset = 0U; offset < LENGTH; offset += chunk_size)
{
chunk_size = ((LENGTH - offset) > CHUNKZ_ENC) ? CHUNKZ_ENC : (LENGTH - offset);
status = slunkcrypt_inplace(ctx, buffer + offset, chunk_size);
if (status != SLUNKCRYPT_SUCCESS)
{
FPUTS((status == SLUNKCRYPT_ABORTED) ? T("\n\nProcess interrupted!\n\n") : T("\n\nWhoops: Failed to encrypt the message!\n\n"), stderr);
goto clean_up;
}
}
status = slunkcrypt_reset(ctx, nonce, (const uint8_t*)TEST_PASSPHRASE, strlen(TEST_PASSPHRASE), SLUNKCRYPT_DECRYPT);
if (status != SLUNKCRYPT_SUCCESS)
{
FPUTS((status == SLUNKCRYPT_ABORTED) ? T("\n\nProcess interrupted!\n\n") : T("\n\nWhoops: Failed to initialize decoder!\n\n"), stderr);
goto clean_up;
}
for (offset = 0U; offset < LENGTH; offset += chunk_size)
{
chunk_size = ((LENGTH - offset) > CHUNKZ_DEC) ? CHUNKZ_DEC : (LENGTH - offset);
status = slunkcrypt_inplace(ctx, buffer + offset, chunk_size);
if (status != SLUNKCRYPT_SUCCESS)
{
FPUTS((status == SLUNKCRYPT_ABORTED) ? T("\n\nProcess interrupted!\n\n") : T("\n\nWhoops: Failed to decrypt the message!\n\n"), stderr);
goto clean_up;
}
}
const uint64_t checksum_decrypted = blake2s_compute(buffer, LENGTH);
if (checksum_decrypted != checksum_original)
{
FPRINTF(stderr, T("\n\nWhoops: Checksum mismatch detected! [expected: 0x%016") T(PRIX64) T(", actual: 0x%016") T(PRIX64) T("]\n\n"), checksum_original, checksum_decrypted);
goto clean_up;
}
result = EXIT_SUCCESS;
clean_up:
SLUNKCRYPT_SAFE_FREE(ctx);
if (buffer)
{
slunkcrypt_bzero(buffer, LENGTH);
free(buffer);
}
return result;
}
int run_selftest_routine(void) int run_selftest_routine(void)
{ {
static const size_t ITERATIONS = 2U;
static const uint64_t TEST_NONCE[] = { 0x243F6A8885A308D3, 0x13198A2E03707344 }; static const uint64_t TEST_NONCE[] = { 0x243F6A8885A308D3, 0x13198A2E03707344 };
const struct const struct
{ {
const char* text; const char* text;
@ -136,15 +217,17 @@ int run_selftest_routine(void)
{ TEST_DATA_3, TEST_CHCK_ORIG_3, { TEST_CHCK_ENCR_3[0U], TEST_CHCK_ENCR_3[1U] } }, { TEST_DATA_3, TEST_CHCK_ORIG_3, { TEST_CHCK_ENCR_3[0U], TEST_CHCK_ENCR_3[1U] } },
}; };
const size_t total = ARRAY_SIZE(TEST_NONCE) * ARRAY_SIZE(TEST_STAGE); const size_t total = ARRAY_SIZE(TEST_NONCE) * (ITERATIONS + ARRAY_SIZE(TEST_STAGE));
FPRINTF(stderr, T("Self-test is in progress, please be patient... stage %u/%u "), 0U, (unsigned)total); size_t count = 0U;
FPRINTF(stderr, T("Self-test is in progress, please be patient... stage %2u/%2u "), 0U, (unsigned)total);
fflush(stderr); fflush(stderr);
for (size_t i = 0U, count = 0U; i < ARRAY_SIZE(TEST_STAGE); ++i) for (size_t i = 0U; i < ARRAY_SIZE(TEST_STAGE); ++i)
{ {
for (size_t j = 0U; j < ARRAY_SIZE(TEST_NONCE); ++j) for (size_t j = 0U; j < ARRAY_SIZE(TEST_NONCE); ++j)
{ {
FPRINTF(stderr, T("\b\b\b\b%u/%u "), (unsigned)++count, (unsigned)total); FPRINTF(stderr, T("\b\b\b\b\b\b%2u/%2u "), (unsigned)++count, (unsigned)total);
fflush(stderr); fflush(stderr);
if (run_testcase(TEST_STAGE[i].text, TEST_NONCE[j], TEST_STAGE[i].check_orig, TEST_STAGE[i].check_encr[j]) != EXIT_SUCCESS) if (run_testcase(TEST_STAGE[i].text, TEST_NONCE[j], TEST_STAGE[i].check_orig, TEST_STAGE[i].check_encr[j]) != EXIT_SUCCESS)
{ {
@ -153,7 +236,20 @@ int run_selftest_routine(void)
} }
} }
FPRINTF(stderr, T("\b\b\b\b%u/%u\n\nCompleted successfully.\n\n"), (unsigned)total, (unsigned)total); for (size_t i = 0U; i < ITERATIONS; ++i)
{
for (size_t j = 0U; j < ARRAY_SIZE(TEST_NONCE); ++j)
{
FPRINTF(stderr, T("\b\b\b\b\b\b%2u/%2u "), (unsigned)++count, (unsigned)total);
fflush(stderr);
if (run_stresstest(TEST_NONCE[j]) != EXIT_SUCCESS)
{
return EXIT_FAILURE;
}
}
}
FPRINTF(stderr, T("\b\b\b\b\b\b%2u/%2u\n\nCompleted successfully.\n\n"), (unsigned)total, (unsigned)total);
fflush(stderr); fflush(stderr);
return EXIT_SUCCESS; return EXIT_SUCCESS;

View File

@ -128,6 +128,11 @@ SLUNKCRYPT_API int slunkcrypt_inplace(const slunkcrypt_t context, uint8_t *const
SLUNKCRYPT_API size_t slunkcrypt_random_bytes(uint8_t *const buffer, const size_t length); SLUNKCRYPT_API size_t slunkcrypt_random_bytes(uint8_t *const buffer, const size_t length);
SLUNKCRYPT_API void slunkcrypt_bzero(void *const buffer, const size_t length); SLUNKCRYPT_API void slunkcrypt_bzero(void *const buffer, const size_t length);
/*
* Helper macros
*/
#define SLUNKCRYPT_SAFE_FREE(X) do { if((X) != SLUNKCRYPT_NULL) { slunkcrypt_free((X)); X = SLUNKCRYPT_NULL; } } while(0)
#ifdef __cplusplus #ifdef __cplusplus
} }
#endif #endif