diff --git a/libslunkcrypt/libSlunkCrypt.vcxproj b/libslunkcrypt/libSlunkCrypt.vcxproj
index de4b636..cd70227 100644
--- a/libslunkcrypt/libSlunkCrypt.vcxproj
+++ b/libslunkcrypt/libSlunkCrypt.vcxproj
@@ -44,11 +44,14 @@
+
+
+
diff --git a/libslunkcrypt/libSlunkCrypt.vcxproj.filters b/libslunkcrypt/libSlunkCrypt.vcxproj.filters
index 78e3bd9..9e5bb18 100644
--- a/libslunkcrypt/libSlunkCrypt.vcxproj.filters
+++ b/libslunkcrypt/libSlunkCrypt.vcxproj.filters
@@ -21,6 +21,9 @@
Source Files
+
+ Source Files
+
@@ -32,5 +35,11 @@
Header Files
+
+ Header Files
+
+
+ Header Files
+
\ No newline at end of file
diff --git a/libslunkcrypt/src/compiler.h b/libslunkcrypt/src/compiler.h
new file mode 100644
index 0000000..ad2e215
--- /dev/null
+++ b/libslunkcrypt/src/compiler.h
@@ -0,0 +1,26 @@
+/******************************************************************************/
+/* SlunkCrypt, by LoRd_MuldeR */
+/* This work has been released under the CC0 1.0 Universal license! */
+/******************************************************************************/
+
+#ifndef INC_SLUNKCRYPT_COMPILER_H
+#define INC_SLUNKCRYPT_COMPILER_H
+
+/* Intel(R) oneAPI DPC++/C++ Compiler */
+#if defined(__INTEL_LLVM_COMPILER) && (!defined(__GNUC__))
+# define __GNUC__ 9
+#endif
+
+/* Compiler compatibility */
+#if defined(_MSC_VER) && (!defined(__GNUC__))
+# define INLINE __inline
+# define UNUSED __pragma(warning(suppress: 4189))
+#elif defined(__GNUC__)
+# define INLINE __inline__
+# define UNUSED __attribute__((unused))
+#else
+# define INLINE inline
+# define UNUSED
+#endif
+
+#endif
diff --git a/libslunkcrypt/src/junk.c b/libslunkcrypt/src/junk.c
index 2c8b7f2..112fdd9 100644
--- a/libslunkcrypt/src/junk.c
+++ b/libslunkcrypt/src/junk.c
@@ -11,14 +11,18 @@
#endif
/* Internal */
-#include "../include/slunkcrypt.h"
+#include "slunkcrypt.h"
+#include "compiler.h"
/* CRT */
#include
#include
#include
-/* Platform compatibility */
+// ==========================================================================
+// Platform compatibility
+// ==========================================================================
+
#ifdef _WIN32
# include
#else
@@ -26,11 +30,30 @@
# include
#endif
-/* Compiler compatibility */
+/* detect destructor support */
+#undef ATTRIB_DESTRUCTOR
#if defined(__GNUC__) || defined(__clang__)
-# define HAVE_DESTRUCTOR 1
-#else
-# define HAVE_DESTRUCTOR 0
+# define ATTRIB_DESTRUCTOR __attribute__((destructor))
+#endif
+
+/* detect getrandom() support */
+#undef SYS_GETRANDOM
+#if defined(__GLIBC__) && (__GLIBC__ >= 2) && (__GLIBC_MINOR__ >= 25)
+# define SYS_GETRANDOM 1
+# include
+#elif defined(__FreeBSD__) && (__FreeBSD__ >= 12)
+# define SYS_GETRANDOM 1
+# include
+#endif
+
+/* detect explicit_bzero() support */
+#undef EXPLICIT_BZERO
+#if defined(_WIN32) && defined(SecureZeroMemory)
+# define EXPLICIT_BZERO SecureZeroMemory
+#elif defined(__GLIBC__) && (__GLIBC__ >= 2) && (__GLIBC_MINOR__ >= 25)
+# define EXPLICIT_BZERO explicit_bzero
+#elif defined(__FreeBSD__) && (__FreeBSD__ >= 11)
+# define EXPLICIT_BZERO explicit_bzero
#endif
// ==========================================================================
@@ -68,28 +91,13 @@ static void win32_call_once(CALL_ONCE_TYPE *const control, void (*init_routine)(
// Random bytes
// ==========================================================================
-#ifdef _WIN32
-# define HAVE_GETRANDOM 0
-#else
-# if defined(__GLIBC__) && (__GLIBC__ >= 2) && (__GLIBC_MINOR__ >= 25)
-# define HAVE_GETRANDOM 1
-# elif defined(__FreeBSD__) && (__FreeBSD__ >= 12)
-# define HAVE_GETRANDOM 1
-# else
-# define HAVE_GETRANDOM 0
-# endif
-#endif
-#if HAVE_GETRANDOM
-# include
-#endif
-
/* Global state */
static CALL_ONCE_TYPE s_random_is_initialized = CALL_ONCE_INIT;
#if defined(_WIN32)
-typedef BOOLEAN(WINAPI *rtl_genrandom_t)(void *buffer, ULONG buff_size);
-static HMODULE s_dll_advapi32 = NULL;
-static rtl_genrandom_t s_rtl_genrandom = NULL;
-#elif !HAVE_GETRANDOM
+typedef BOOLEAN(WINAPI *rtlgenrandom_t)(void *buffer, ULONG buff_size);
+static HMODULE s_advapi32 = NULL;
+static rtlgenrandom_t s_rtlgenrandom = NULL;
+#elif !defined(SYS_GETRANDOM)
static const char *const DEV_RANDOM[] = { "/dev/urandom", "/dev/arandom", "/dev/random", NULL };
static int s_random_fd = -1;
#endif
@@ -98,13 +106,13 @@ static int s_random_fd = -1;
static void exit_random_source(void)
{
#if defined(_WIN32)
- s_rtl_genrandom = NULL;
- if (s_dll_advapi32)
+ s_rtlgenrandom = NULL;
+ if (s_advapi32)
{
- FreeLibrary(s_dll_advapi32);
- s_dll_advapi32 = NULL;
+ FreeLibrary(s_advapi32);
+ s_advapi32 = NULL;
}
-#elif !HAVE_GETRANDOM
+#elif !defined(SYS_GETRANDOM)
if (s_random_fd >= 0)
{
close(s_random_fd);
@@ -117,11 +125,11 @@ static void exit_random_source(void)
static void init_random_source(void)
{
#if defined(_WIN32)
- if ((s_dll_advapi32 = LoadLibraryW(L"advapi32.dll")))
+ if ((s_advapi32 = LoadLibraryW(L"advapi32.dll")))
{
- s_rtl_genrandom = (rtl_genrandom_t)GetProcAddress(s_dll_advapi32, "SystemFunction036");
+ s_rtlgenrandom = (rtlgenrandom_t) GetProcAddress(s_advapi32, "SystemFunction036");
}
-#elif !HAVE_GETRANDOM
+#elif !defined(SYS_GETRANDOM)
for (size_t i = 0U; DEV_RANDOM[i]; ++i)
{
if ((s_random_fd = open(DEV_RANDOM[i], O_RDONLY)) >= 0)
@@ -130,7 +138,7 @@ static void init_random_source(void)
}
}
#endif
-#if !HAVE_DESTRUCTOR
+#if !defined(ATTRIB_DESTRUCTOR)
atexit(exit_random_source);
#endif
}
@@ -140,12 +148,12 @@ size_t slunkcrypt_random_bytes(uint8_t* const buffer, const size_t length)
{
CALL_ONCE(&s_random_is_initialized, init_random_source);
#if defined(_WIN32)
- if (s_rtl_genrandom)
+ if (s_rtlgenrandom)
{
const ULONG buff_size = (ULONG)length;
- return s_rtl_genrandom(buffer, buff_size) ? buff_size : 0U;
+ return s_rtlgenrandom(buffer, buff_size) ? buff_size : 0U;
}
-#elif HAVE_GETRANDOM
+#elif defined(SYS_GETRANDOM)
const ssize_t result = getrandom(buffer, length, 0U);
return (result < 0) ? 0U : ((size_t)result);
#else
@@ -162,29 +170,12 @@ size_t slunkcrypt_random_bytes(uint8_t* const buffer, const size_t length)
// Zero memory
// ==========================================================================
-#ifdef _WIN32
-# ifdef SecureZeroMemory
-# define HAVE_EXPLICIT_BZERO 1
-# define explicit_bzero SecureZeroMemory
-# else
-# define HAVE_EXPLICIT_BZERO 0
-# endif
-#else
-# if defined(__GLIBC__) && (__GLIBC__ >= 2) && (__GLIBC_MINOR__ >= 25)
-# define HAVE_EXPLICIT_BZERO 1
-# elif defined(__FreeBSD__) && (__FreeBSD__ >= 11)
-# define HAVE_EXPLICIT_BZERO 1
-# else
-# define HAVE_EXPLICIT_BZERO 0
-# endif
-#endif
-
void slunkcrypt_bzero(void* const buffer, const size_t length)
{
if ((buffer) && (length > 0U))
{
-#if HAVE_EXPLICIT_BZERO
- explicit_bzero(buffer, length);
+#if defined(EXPLICIT_BZERO)
+ EXPLICIT_BZERO(buffer, length);
#else
volatile uint8_t* ptr = (volatile uint8_t*) buffer;
for (size_t i = 0U; i < length; ++i)
@@ -199,8 +190,8 @@ void slunkcrypt_bzero(void* const buffer, const size_t length)
// Destructor
// ==========================================================================
-#if HAVE_DESTRUCTOR
-__attribute__((destructor)) void slunkcrypt_destructor()
+#if defined(ATTRIB_DESTRUCTOR)
+ATTRIB_DESTRUCTOR void slunkcrypt_destructor()
{
exit_random_source();
}
diff --git a/libslunkcrypt/src/keygen.c b/libslunkcrypt/src/keygen.c
new file mode 100644
index 0000000..5bd3904
--- /dev/null
+++ b/libslunkcrypt/src/keygen.c
@@ -0,0 +1,101 @@
+/******************************************************************************/
+/* SlunkCrypt, by LoRd_MuldeR */
+/* This work has been released under the CC0 1.0 Universal license! */
+/******************************************************************************/
+
+/* Internal */
+#include "keygen.h"
+#include "compiler.h"
+
+/* CRT */
+#include
+
+/* Type */
+typedef struct
+{
+ uint64_t hi, lo;
+}
+uint128_t;
+
+// ==========================================================================
+// 128-Bit math support
+// ==========================================================================
+
+#define READ_U128(X) ((((__uint128_t)(X).hi) << 64U) | ((__uint128_t)(X).lo))
+
+static INLINE void multiply_u128(uint128_t *const out, const uint128_t lhs, const uint128_t rhs)
+{
+#if defined(__GNUC__) && defined(__SIZEOF_INT128__)
+ const __uint128_t tmp = READ_U128(lhs) * READ_U128(rhs);
+ out->hi = (uint64_t)(tmp >> 64U);
+ out->lo = (uint64_t)(tmp & 0xFFFFFFFFFFFFFFFF);
+#else
+ const uint64_t lolo = (lhs.lo & 0xFFFFFFFF) * (rhs.lo & 0xFFFFFFFF);
+ const uint64_t hilo = (lhs.lo >> 32U) * (rhs.lo & 0xFFFFFFFF);
+ const uint64_t lohi = (lhs.lo & 0xFFFFFFFF) * (rhs.lo >> 32U);
+ const uint64_t hihi = (lhs.lo >> 32U) * (rhs.lo >> 32U);
+ const uint64_t crss = (lolo >> 32U) + (hilo & 0xFFFFFFFF) + lohi;
+ out->hi = (hilo >> 32U) + (crss >> 32) + hihi;
+ out->lo = (crss << 32U) | (lolo & 0xFFFFFFFF);
+ out->hi += (lhs.hi * rhs.lo) + (lhs.lo * rhs.hi); /* 128x128=128 */
+#endif
+}
+
+// ==========================================================================
+// Hash function
+// ==========================================================================
+
+static const uint128_t HASH_OFFSETBASE_128 = { 0x6C62272E07BB0142, 0x62B821756295C58D };
+static const uint128_t HASH_MAGICPRIME_128 = { 0x0000000001000000, 0x000000000000013B };
+
+static INLINE void hash_update_u64(uint128_t* const hash, uint64_t value)
+{
+ size_t i;
+ for (i = 0U; i < sizeof(uint64_t); ++i, value >>= CHAR_BIT)
+ {
+ hash->lo ^= (uint8_t)(value & 0xFF);
+ multiply_u128(hash, *hash, HASH_MAGICPRIME_128);
+ }
+}
+
+static INLINE void hash_update_str(uint128_t *const hash, const uint8_t *const data, const size_t data_len)
+{
+ size_t i;
+ for (i = 0U; i < data_len; ++i)
+ {
+ hash->lo ^= data[i];
+ multiply_u128(hash, *hash, HASH_MAGICPRIME_128);
+ }
+}
+
+static INLINE uint128_t hash_code(const uint128_t *const seed, const uint8_t *const data, const size_t data_len)
+{
+ uint128_t hash = HASH_OFFSETBASE_128;
+ hash_update_u64(&hash, seed->lo);
+ hash_update_u64(&hash, seed->hi);
+ hash_update_str(&hash, data, data_len);
+ return hash;
+}
+
+// ==========================================================================
+// Key derivation
+// ==========================================================================
+
+static INLINE uint64_t keygen_loop(uint64_t seed, const uint64_t i, const uint8_t *const passwd, const size_t passwd_len)
+{
+ uint128_t hash = { seed, i };
+ size_t u;
+ for (u = 0U, seed = 0U; u < 99971U; ++u)
+ {
+ hash = hash_code(&hash, passwd, passwd_len);
+ seed ^= hash.hi ^ hash.lo;
+ }
+ return seed;
+}
+
+void slunkcrypt_keygen(keydata_t *const key, const uint64_t salt, const uint16_t pepper, const uint8_t *const passwd, const size_t passwd_len)
+{
+ key->a = keygen_loop(salt, 0x162603FA1CDA99D3 + (uint64_t)pepper, passwd, passwd_len);
+ key->b = keygen_loop(salt, 0xBFDEC4A6C1A46E09 + (uint64_t)pepper, passwd, passwd_len);
+ key->c = keygen_loop(salt, 0x6BA17D11624973EE + (uint64_t)pepper, passwd, passwd_len);
+}
diff --git a/libslunkcrypt/src/keygen.h b/libslunkcrypt/src/keygen.h
new file mode 100644
index 0000000..6c572bd
--- /dev/null
+++ b/libslunkcrypt/src/keygen.h
@@ -0,0 +1,20 @@
+/******************************************************************************/
+/* SlunkCrypt, by LoRd_MuldeR */
+/* This work has been released under the CC0 1.0 Universal license! */
+/******************************************************************************/
+
+#ifndef INC_SLUNKCRYPT_KEYGEN_H
+#define INC_SLUNKCRYPT_KEYGEN_H
+
+#include
+#include
+
+typedef struct
+{
+ uint64_t a, b, c;
+}
+keydata_t;
+
+void slunkcrypt_keygen(keydata_t *const key, const uint64_t salt, const uint16_t pepper, const uint8_t* const passwd, const size_t passwd_len);
+
+#endif
diff --git a/libslunkcrypt/src/slunkcrypt.c b/libslunkcrypt/src/slunkcrypt.c
index 4f07878..afefcbd 100644
--- a/libslunkcrypt/src/slunkcrypt.c
+++ b/libslunkcrypt/src/slunkcrypt.c
@@ -4,32 +4,16 @@
/******************************************************************************/
/* Internal */
-#include "../include/slunkcrypt.h"
+#include "slunkcrypt.h"
+#include "compiler.h"
+#include "keygen.h"
#include "version.h"
/* CRT */
#include
#include
-#include
-/* Intel(R) oneAPI DPC++/C++ Compiler */
-#if defined(__INTEL_LLVM_COMPILER) && (!defined(__GNUC__))
-# define __GNUC__ 9
-#endif
-
-/* Compiler compatibility */
-#if defined(_MSC_VER) && (!defined(__GNUC__))
-# define INLINE __inline
-# define UNUSED __pragma(warning(suppress: 4189))
-#elif defined(__GNUC__)
-# define INLINE __inline__
-# define UNUSED __attribute__((unused))
-#else
-# define INLINE inline
-# define UNUSED
-#endif
-
-/* Version info */
+/* Version */
const uint16_t SLUNKCRYPT_VERSION_MAJOR = LIB_VERSION_MAJOR;
const uint16_t SLUNKCRYPT_VERSION_MINOR = LIB_VERSION_MINOR;
const uint16_t SLUNKCRYPT_VERSION_PATCH = LIB_VERSION_PATCH;
@@ -42,12 +26,6 @@ const char *const SLUNKCRYPT_BUILD = __DATE__ ", " __TIME__;
// Data structures
// ==========================================================================
-typedef struct
-{
- uint64_t hi, lo;
-}
-uint128_t;
-
typedef struct
{
uint32_t x, y, z, w, v, d;
@@ -92,108 +70,19 @@ static INLINE uint32_t upper_u64(const uint64_t value)
return (uint32_t)(value >> 32U);
}
-static INLINE uint8_t byte_u64(const uint64_t value, const size_t off)
-{
- assert(off < sizeof(uint64_t));
- return (uint8_t)((value >> (CHAR_BIT * off)) & 0xFF);
-}
-
-// ==========================================================================
-// 128-Bit math support
-// ==========================================================================
-
-#define READ_U128(X) ((((__uint128_t)(X).hi) << 64U) | ((__uint128_t)(X).lo))
-
-static INLINE void multiply_u128(uint128_t *const out, const uint128_t lhs, const uint128_t rhs)
-{
-#if defined(__GNUC__) && defined(__SIZEOF_INT128__)
- const __uint128_t tmp = READ_U128(lhs) * READ_U128(rhs);
- out->hi = (uint64_t)(tmp >> 64U);
- out->lo = (uint64_t)(tmp & 0xFFFFFFFFFFFFFFFF);
-#else
- const uint64_t lolo = (lhs.lo & 0xFFFFFFFF) * (rhs.lo & 0xFFFFFFFF);
- const uint64_t hilo = (lhs.lo >> 32U) * (rhs.lo & 0xFFFFFFFF);
- const uint64_t lohi = (lhs.lo & 0xFFFFFFFF) * (rhs.lo >> 32U);
- const uint64_t hihi = (lhs.lo >> 32U) * (rhs.lo >> 32U);
- const uint64_t crss = (lolo >> 32U) + (hilo & 0xFFFFFFFF) + lohi;
- out->hi = (hilo >> 32U) + (crss >> 32) + hihi;
- out->lo = (crss << 32U) | (lolo & 0xFFFFFFFF);
- out->hi += (lhs.hi * rhs.lo) + (lhs.lo * rhs.hi); /* 128x128=128 */
-#endif
-}
-
-// ==========================================================================
-// Hash function
-// ==========================================================================
-
-static const uint128_t HASH_OFFSETBASE_128 = { 0x6C62272E07BB0142, 0x62B821756295C58D };
-static const uint128_t HASH_MAGICPRIME_128 = { 0x0000000001000000, 0x000000000000013B };
-
-static INLINE void hash_update_str(uint128_t *const hash, const uint8_t *const data, const size_t data_len)
-{
- size_t i;
- for (i = 0U; i < data_len; ++i)
- {
- hash->lo ^= data[i];
- multiply_u128(hash, *hash, HASH_MAGICPRIME_128);
- }
-}
-
-static INLINE void hash_update_u64(uint128_t *const hash, const uint64_t value)
-{
- size_t i;
- for (i = 0U; i < sizeof(uint64_t); ++i)
- {
- hash->lo ^= byte_u64(value, i);
- multiply_u128(hash, *hash, HASH_MAGICPRIME_128);
- }
-}
-
-static INLINE uint128_t hash_code(const uint128_t *const salt, const uint8_t *const data, const size_t data_len)
-{
- uint128_t hash = HASH_OFFSETBASE_128;
- hash_update_u64(&hash, salt->lo);
- hash_update_u64(&hash, salt->hi);
- hash_update_str(&hash, data, data_len);
- return hash;
-}
-
-// ==========================================================================
-// Key derivation
-// ==========================================================================
-
-static INLINE uint64_t keygen_loop(uint64_t salt, const uint64_t pepper, const uint8_t *const passwd, const size_t passwd_len)
-{
- uint128_t hash = { salt, pepper };
- size_t u;
- for (u = 0U, salt = 0U; u < 99971U; ++u)
- {
- hash = hash_code(&hash, passwd, passwd_len);
- salt ^= hash.hi ^ hash.lo;
- }
- return salt;
-}
-
-static INLINE void generate_key(uint64_t *const key, const uint64_t salt, const uint16_t pepper, const uint8_t *const passwd, const size_t passwd_len)
-{
- key[0U] = keygen_loop(salt, 0x162603FA1CDA99D3 + (uint64_t)pepper, passwd, passwd_len);
- key[1U] = keygen_loop(salt, 0xBFDEC4A6C1A46E09 + (uint64_t)pepper, passwd, passwd_len);
- key[2U] = keygen_loop(salt, 0x6BA17D11624973EE + (uint64_t)pepper, passwd, passwd_len);
-}
-
// ==========================================================================
// Deterministic random bit generator
// ==========================================================================
-static INLINE void random_init(rand_state_t *const state, const uint64_t *const key)
+static INLINE void random_init(rand_state_t *const state, const keydata_t *const key)
{
slunkcrypt_bzero(state, sizeof(rand_state_t));
- state->x = lower_u64(key[0U]);
- state->y = upper_u64(key[0U]);
- state->z = lower_u64(key[1U]);
- state->w = upper_u64(key[1U]);
- state->v = lower_u64(key[2U]);
- state->d = upper_u64(key[2U]);
+ state->x = lower_u64(key->a);
+ state->y = upper_u64(key->a);
+ state->z = lower_u64(key->b);
+ state->w = upper_u64(key->b);
+ state->v = lower_u64(key->c);
+ state->d = upper_u64(key->c);
}
static INLINE uint32_t random_next(rand_state_t *const state)
@@ -210,12 +99,12 @@ static INLINE uint32_t random_next(rand_state_t *const state)
static INLINE void random_seed(rand_state_t *const state, uint64_t salt, const uint16_t pepper, const uint8_t *const passwd, const size_t passwd_len)
{
size_t i;
- uint64_t key[3U];
+ keydata_t key;
do
{
- generate_key(key, salt++, pepper, passwd, passwd_len);
- random_init(state, key);
- slunkcrypt_bzero(&key, 3U * sizeof(uint64_t));
+ slunkcrypt_keygen(&key, salt++, pepper, passwd, passwd_len);
+ random_init(state, &key);
+ slunkcrypt_bzero(&key, sizeof(keydata_t));
}
while (!(state->x || state->y || state->z || state->w || state->v));
for (i = 0U; i < 97U; ++i)