OSDN Git Service

Enhanced self-test routine + added macro to "safely" free SlunkCrypt instance.
authorLoRd_MuldeR <mulder2@gmx.de>
Sat, 2 Apr 2022 15:27:48 +0000 (17:27 +0200)
committerLoRd_MuldeR <mulder2@gmx.de>
Sat, 2 Apr 2022 15:27:48 +0000 (17:27 +0200)
frontend/src/crypt.c
frontend/src/selftest.c
libslunkcrypt/include/slunkcrypt.h

index a376c46..1845b55 100644 (file)
@@ -226,10 +226,7 @@ int encrypt(const char *const passphrase, const CHR *const input_path, const CHR
 
 clean_up:
 
-       if (ctx)
-       {
-               slunkcrypt_free(ctx);
-       }
+       SLUNKCRYPT_SAFE_FREE(ctx);
 
        if (file_out)
        {
@@ -424,10 +421,7 @@ int decrypt(const char *const passphrase, const CHR *const input_path, const CHR
 
 clean_up:
 
-       if (ctx)
-       {
-               slunkcrypt_free(ctx);
-       }
+       SLUNKCRYPT_SAFE_FREE(ctx);
 
        if (file_out)
        {
index c21e9fe..cefe7bb 100644 (file)
@@ -106,10 +106,7 @@ static int run_testcase(const char* const message, const uint64_t nonce, const u
 
 clean_up:
 
-       if (ctx)
-       {
-               slunkcrypt_free(ctx);
-       }
+       SLUNKCRYPT_SAFE_FREE(ctx);
 
        if (text_temp)
        {
@@ -120,9 +117,93 @@ clean_up:
        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)
 {
+       static const size_t ITERATIONS = 2U;
        static const uint64_t TEST_NONCE[] = { 0x243F6A8885A308D3, 0x13198A2E03707344 };
+
        const struct
        {
                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] } },
        };
 
-       const size_t total = ARRAY_SIZE(TEST_NONCE) * ARRAY_SIZE(TEST_STAGE);
-       FPRINTF(stderr, T("Self-test is in progress, please be patient... stage %u/%u "), 0U, (unsigned)total);
+       const size_t total = ARRAY_SIZE(TEST_NONCE) * (ITERATIONS + ARRAY_SIZE(TEST_STAGE));
+       size_t count = 0U;
+
+       FPRINTF(stderr, T("Self-test is in progress, please be patient... stage %2u/%2u "), 0U, (unsigned)total);
        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)
                {
-                       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);
                        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);
 
        return EXIT_SUCCESS;
index ce9c7f8..fc57c87 100644 (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 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
 }
 #endif