diff --git a/libslunkcrypt/src/keygen.c b/libslunkcrypt/src/keygen.c index 849529c..2099273 100644 --- a/libslunkcrypt/src/keygen.c +++ b/libslunkcrypt/src/keygen.c @@ -15,33 +15,34 @@ typedef struct { uint64_t hi, lo; } -uint128_t; +hash128_t; // ========================================================================== // 128-Bit math support // ========================================================================== #if defined(__GNUC__) && defined(__SIZEOF_INT128__) -# define HAVE_UINT128_SUPPORT 1 -# define PACK_U128(X) ((((__uint128_t)(X).hi) << 64) | (X).lo) +# define HAVE_UINT128_T 1 +# define LOAD_U128(X) ((((__uint128_t)(X).hi) << 64) | (X).lo) #else # pragma message("Compiler does not support 128-bit math -> using fallback!") #endif -static INLINE void multiply_u128(uint128_t *const out, const uint128_t lhs, const uint128_t rhs) +static INLINE void multiply_u128(hash128_t *const out, const hash128_t lhs, const hash128_t *const rhs) { -#ifdef HAVE_UINT128_SUPPORT - const __uint128_t product = PACK_U128(lhs) * PACK_U128(rhs); - *out = (uint128_t) { product >> 64, product }; +#ifdef HAVE_UINT128_T + const __uint128_t product = LOAD_U128(lhs) * LOAD_U128(*rhs); + out->lo = (uint64_t)product; + out->hi = (uint64_t)(product >> 64); #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 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 */ + out->hi += (lhs.hi * rhs->lo) + (lhs.lo * rhs->hi); /* 128x128=128 */ #endif } @@ -49,32 +50,37 @@ static INLINE void multiply_u128(uint128_t *const out, const uint128_t lhs, cons // Hash function // ========================================================================== -static const uint128_t HASH_OFFSETBASE_128 = { 0x6C62272E07BB0142, 0x62B821756295C58D }; -static const uint128_t HASH_MAGICPRIME_128 = { 0x0000000001000000, 0x000000000000013B }; +static const hash128_t HASH_OFFSETBASE_128 = { UINT64_C(0x6C62272E07BB0142), UINT64_C(0x62B821756295C58D) }; +static const hash128_t HASH_MAGICPRIME_128 = { UINT64_C(0x0000000001000000), UINT64_C(0x000000000000013B) }; -static INLINE void hash_update_u64(uint128_t* const hash, uint64_t value) +#define HASH_UPDATE(X) do \ +{ \ + hash->lo ^= (X); \ + multiply_u128(hash, *hash, &HASH_MAGICPRIME_128); \ +} \ +while(0) + +static INLINE void hash_update_u64(hash128_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); + HASH_UPDATE((uint8_t)value); } } -static INLINE void hash_update_str(uint128_t *const hash, const uint8_t *const data, const size_t data_len) +static INLINE void hash_update_str(hash128_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); + HASH_UPDATE(data[i]); } } -static INLINE uint128_t hash_code(const uint128_t *const seed, const uint8_t *const data, const size_t data_len) +static INLINE hash128_t hash_code(const hash128_t *const seed, const uint8_t *const data, const size_t data_len) { - uint128_t hash = HASH_OFFSETBASE_128; + hash128_t hash = HASH_OFFSETBASE_128; hash_update_u64(&hash, seed->lo); hash_update_u64(&hash, seed->hi); hash_update_str(&hash, data, data_len); @@ -85,11 +91,11 @@ static INLINE uint128_t hash_code(const uint128_t *const seed, const uint8_t *co // 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, const size_t iterations) +static INLINE uint64_t keygen_loop(uint64_t seed, const uint64_t i, const uint8_t *const passwd, const size_t passwd_len, const size_t rounds) { - uint128_t hash = { seed, i }; + hash128_t hash = { seed, i }; size_t u; - for (u = 0U, seed = 0U; u < iterations; ++u) + for (u = 0U, seed = 0U; u < rounds; ++u) { hash = hash_code(&hash, passwd, passwd_len); seed ^= hash.hi ^ hash.lo; @@ -97,9 +103,9 @@ static INLINE uint64_t keygen_loop(uint64_t seed, const uint64_t i, const uint8_ 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, const size_t iterations) +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, const size_t rounds) { - key->a = keygen_loop(salt, 0x162603FA1CDA99D3 + (uint64_t)pepper, passwd, passwd_len, iterations); - key->b = keygen_loop(salt, 0xBFDEC4A6C1A46E09 + (uint64_t)pepper, passwd, passwd_len, iterations); - key->c = keygen_loop(salt, 0x6BA17D11624973EE + (uint64_t)pepper, passwd, passwd_len, iterations); + key->a = keygen_loop(salt, 0x162603FA1CDA99D3 + (uint64_t)pepper, passwd, passwd_len, rounds); + key->b = keygen_loop(salt, 0xBFDEC4A6C1A46E09 + (uint64_t)pepper, passwd, passwd_len, rounds); + key->c = keygen_loop(salt, 0x6BA17D11624973EE + (uint64_t)pepper, passwd, passwd_len, rounds); } diff --git a/libslunkcrypt/src/keygen.h b/libslunkcrypt/src/keygen.h index 419fb05..d8144dd 100644 --- a/libslunkcrypt/src/keygen.h +++ b/libslunkcrypt/src/keygen.h @@ -15,6 +15,6 @@ typedef struct } 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, const size_t iterations); +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, const size_t rounds); #endif diff --git a/libslunkcrypt/src/slunkcrypt.c b/libslunkcrypt/src/slunkcrypt.c index 26089f3..e80f09f 100644 --- a/libslunkcrypt/src/slunkcrypt.c +++ b/libslunkcrypt/src/slunkcrypt.c @@ -81,33 +81,22 @@ volatile int g_slunkcrypt_abort_flag = 0; } \ while (0) -// ========================================================================== -// Byte access (endianness agnostic) -// ========================================================================== - -static INLINE uint32_t lower_u64(const uint64_t value) -{ - return (uint32_t)(value & 0xFFFFFFFF); -} - -static INLINE uint32_t upper_u64(const uint64_t value) -{ - return (uint32_t)(value >> 32U); -} - // ========================================================================== // Deterministic random bit generator // ========================================================================== +#define RANDOM_INIT(DST_LO, DST_HI, SRC) do \ +{ \ + DST_LO = (uint32_t)(SRC); \ + DST_HI = (uint32_t)((SRC) >> 32U); \ +} \ +while (0) + 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->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); + RANDOM_INIT(state->x, state->y, key->a); + RANDOM_INIT(state->z, state->w, key->b); + RANDOM_INIT(state->v, state->d, key->c); } static INLINE uint32_t random_next(rand_state_t *const state)