Revamped the stepping algorithm.
This commit is contained in:
parent
8ebf71ba73
commit
e6511aec5e
@ -95,7 +95,7 @@ SLUNKCRYPT_API extern volatile int g_slunkcrypt_abort_flag;
|
||||
/*
|
||||
* Nonce generator
|
||||
*/
|
||||
SLUNKCRYPT_API int slunkcrypt_generate_nonce(uint64_t* const nonce);
|
||||
SLUNKCRYPT_API int slunkcrypt_generate_nonce(uint64_t *const nonce);
|
||||
|
||||
/*
|
||||
* Allocate, reset or free state
|
||||
@ -107,14 +107,14 @@ SLUNKCRYPT_API void slunkcrypt_free(const slunkcrypt_t context);
|
||||
/*
|
||||
* Encryption routines
|
||||
*/
|
||||
SLUNKCRYPT_API int slunkcrypt_process(const slunkcrypt_t context, const uint8_t *const input, uint8_t* const output, size_t length);
|
||||
SLUNKCRYPT_API int slunkcrypt_process(const slunkcrypt_t context, const uint8_t *const input, uint8_t *const output, size_t length);
|
||||
SLUNKCRYPT_API int slunkcrypt_process_inplace(const slunkcrypt_t context, uint8_t *const buffer, size_t length);
|
||||
|
||||
/*
|
||||
* Auxiliary functions
|
||||
*/
|
||||
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 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);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
@ -28,7 +28,7 @@
|
||||
const uint16_t SLUNKCRYPT_VERSION_MAJOR = MY_VERSION_MAJOR;
|
||||
const uint16_t SLUNKCRYPT_VERSION_MINOR = MY_VERSION_MINOR;
|
||||
const uint16_t SLUNKCRYPT_VERSION_PATCH = MY_VERSION_PATCH;
|
||||
const char* const SLUNKCRYPT_BUILD = __DATE__ " " __TIME__;
|
||||
const char *const SLUNKCRYPT_BUILD = __DATE__ " " __TIME__;
|
||||
|
||||
/* Const */
|
||||
#define HASH_MAGIC_PRIME 0x00000100000001B3ull
|
||||
@ -55,15 +55,13 @@ typedef struct
|
||||
{
|
||||
uint32_t x, y, z, w, v, d;
|
||||
}
|
||||
xorsh_state_t;
|
||||
rand_state_t;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
boolean reverse_mode;
|
||||
uint8_t wheel[256U][256U];
|
||||
uint8_t step[241U];
|
||||
uint8_t rotation[256U];
|
||||
uint8_t counter;
|
||||
rand_state_t random;
|
||||
}
|
||||
crypt_state_t;
|
||||
|
||||
@ -77,7 +75,7 @@ volatile int g_slunkcrypt_abort_flag = 0;
|
||||
{ \
|
||||
if (g_slunkcrypt_abort_flag) \
|
||||
{ \
|
||||
goto abort_request; \
|
||||
goto aborted; \
|
||||
} \
|
||||
} \
|
||||
while (0)
|
||||
@ -112,7 +110,7 @@ static FORCE_INLINE uint8_t byte_u64(const uint64_t value, const size_t off)
|
||||
// Hash function
|
||||
// ==========================================================================
|
||||
|
||||
static FORCE_INLINE void hash_update_str(uint64_t* const hash, const uint8_t* const data, const size_t data_len)
|
||||
static FORCE_INLINE void hash_update_str(uint64_t* const hash, const uint8_t *const data, const size_t data_len)
|
||||
{
|
||||
size_t i;
|
||||
for (i = 0U; i < data_len; ++i)
|
||||
@ -121,7 +119,7 @@ static FORCE_INLINE void hash_update_str(uint64_t* const hash, const uint8_t* co
|
||||
}
|
||||
}
|
||||
|
||||
static FORCE_INLINE void hash_update_u64(uint64_t* const hash, const uint64_t value)
|
||||
static FORCE_INLINE void hash_update_u64(uint64_t *const hash, const uint64_t value)
|
||||
{
|
||||
size_t i;
|
||||
for (i = 0U; i < sizeof(uint64_t); ++i)
|
||||
@ -130,7 +128,7 @@ static FORCE_INLINE void hash_update_u64(uint64_t* const hash, const uint64_t va
|
||||
}
|
||||
}
|
||||
|
||||
static FORCE_INLINE void hash_update_u16(uint64_t* const hash, const uint16_t value)
|
||||
static FORCE_INLINE void hash_update_u16(uint64_t *const hash, const uint16_t value)
|
||||
{
|
||||
size_t i;
|
||||
for (i = 0U; i < sizeof(uint16_t); ++i)
|
||||
@ -139,7 +137,7 @@ static FORCE_INLINE void hash_update_u16(uint64_t* const hash, const uint16_t va
|
||||
}
|
||||
}
|
||||
|
||||
static uint64_t hash_code_init(const uint64_t salt, const uint16_t i, const uint8_t* const data, const size_t data_len)
|
||||
static uint64_t hash_code_init(const uint64_t salt, const uint16_t i, const uint8_t *const data, const size_t data_len)
|
||||
{
|
||||
uint64_t hash = HASH_OFFSET_BASE;
|
||||
hash_update_u64(&hash, salt);
|
||||
@ -148,7 +146,7 @@ static uint64_t hash_code_init(const uint64_t salt, const uint16_t i, const uint
|
||||
return hash;
|
||||
}
|
||||
|
||||
static uint64_t hash_code_next(const uint64_t salt, const uint8_t* const data, const size_t data_len)
|
||||
static uint64_t hash_code_next(const uint64_t salt, const uint8_t *const data, const size_t data_len)
|
||||
{
|
||||
uint64_t hash = HASH_OFFSET_BASE;
|
||||
hash_update_u64(&hash, salt);
|
||||
@ -160,7 +158,7 @@ static uint64_t hash_code_next(const uint64_t salt, const uint8_t* const data, c
|
||||
// Key derivation
|
||||
// ==========================================================================
|
||||
|
||||
static FORCE_INLINE uint64_t keygen_loop(uint64_t salt, const uint16_t i, const uint8_t* const passwd, const size_t passwd_len)
|
||||
static FORCE_INLINE uint64_t keygen_loop(uint64_t salt, const uint16_t i, const uint8_t *const passwd, const size_t passwd_len)
|
||||
{
|
||||
size_t u;
|
||||
uint64_t result = salt = hash_code_init(salt, i, passwd, passwd_len);
|
||||
@ -171,7 +169,7 @@ static FORCE_INLINE uint64_t keygen_loop(uint64_t salt, const uint16_t i, const
|
||||
return result;
|
||||
}
|
||||
|
||||
static void generate_key(key_data_t *const key, const uint64_t salt, const uint16_t pepper, const uint8_t* const passwd, const size_t passwd_len)
|
||||
static void generate_key(key_data_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, (pepper & 0x3FFF) | 0x0000, passwd, passwd_len);
|
||||
key->b = keygen_loop(salt, (pepper & 0x3FFF) | 0x4000, passwd, passwd_len);
|
||||
@ -182,9 +180,9 @@ static void generate_key(key_data_t *const key, const uint64_t salt, const uint1
|
||||
// Deterministic random bit generator
|
||||
// ==========================================================================
|
||||
|
||||
static void random_init(xorsh_state_t *const state, const key_data_t *const key)
|
||||
static void random_init(rand_state_t *const state, const key_data_t *const key)
|
||||
{
|
||||
slunkcrypt_bzero(state, sizeof(xorsh_state_t));
|
||||
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);
|
||||
@ -193,7 +191,7 @@ static void random_init(xorsh_state_t *const state, const key_data_t *const key)
|
||||
state->d = upper_u64(key->c);
|
||||
}
|
||||
|
||||
static uint32_t random_next(xorsh_state_t *const state)
|
||||
static uint32_t random_next(rand_state_t *const state)
|
||||
{
|
||||
const uint32_t t = state->x ^ (state->x >> 2);
|
||||
state->x = state->y;
|
||||
@ -204,7 +202,7 @@ static uint32_t random_next(xorsh_state_t *const state)
|
||||
return (state->d += 0x000587C5) + state->v;
|
||||
}
|
||||
|
||||
static void random_seed(xorsh_state_t *const state, uint64_t salt, const uint16_t pepper, const uint8_t *const passwd, const size_t passwd_len)
|
||||
static 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;
|
||||
key_data_t key;
|
||||
@ -225,29 +223,27 @@ static void random_seed(xorsh_state_t *const state, uint64_t salt, const uint16_
|
||||
// Initialization
|
||||
// ==========================================================================
|
||||
|
||||
static int initialize_state(crypt_state_t *const crypt_state, const uint64_t nonce, const uint8_t *const passwd, const size_t passwd_len, const int mode)
|
||||
static int initialize_state(crypt_state_t *const state, const uint64_t nonce, const uint8_t *const passwd, const size_t passwd_len, const int mode)
|
||||
{
|
||||
xorsh_state_t rand_state;
|
||||
uint8_t temp[256U][256U];
|
||||
size_t r, i;
|
||||
|
||||
/* initialize state */
|
||||
slunkcrypt_bzero(crypt_state, sizeof(crypt_state_t));
|
||||
const boolean reverse = crypt_state->reverse_mode = INT_TO_BOOL(mode);
|
||||
slunkcrypt_bzero(state, sizeof(crypt_state_t));
|
||||
const boolean reverse = state->reverse_mode = INT_TO_BOOL(mode);
|
||||
|
||||
/* set up wheels and initial rotation */
|
||||
/* set up the wheel permutations */
|
||||
for (r = 0U; r < 256U; ++r)
|
||||
{
|
||||
random_seed(&rand_state, nonce, (uint16_t)r, passwd, passwd_len);
|
||||
crypt_state->rotation[reverse ? (255U - r) : r] = (uint8_t)random_next(&rand_state);
|
||||
random_seed(&state->random, nonce, (uint16_t)r, passwd, passwd_len);
|
||||
for (i = 0U; i < 256U; ++i)
|
||||
{
|
||||
const size_t j = random_next(&rand_state) % (i + 1U);
|
||||
const size_t j = random_next(&state->random) % (i + 1U);
|
||||
if (j != i)
|
||||
{
|
||||
crypt_state->wheel[r][i] = crypt_state->wheel[r][j];
|
||||
state->wheel[r][i] = state->wheel[r][j];
|
||||
}
|
||||
crypt_state->wheel[r][j] = (uint8_t)i;
|
||||
state->wheel[r][j] = (uint8_t)i;
|
||||
}
|
||||
CHECK_ABORTED();
|
||||
}
|
||||
@ -259,37 +255,23 @@ static int initialize_state(crypt_state_t *const crypt_state, const uint64_t non
|
||||
{
|
||||
for (i = 0U; i < 256U; ++i)
|
||||
{
|
||||
temp[r][crypt_state->wheel[r][i]] = (uint8_t)i;
|
||||
temp[r][state->wheel[r][i]] = (uint8_t)i;
|
||||
}
|
||||
}
|
||||
for (r = 0U; r < 256U; ++r)
|
||||
{
|
||||
memcpy(crypt_state->wheel[255U - r], temp[r], 256U);
|
||||
memcpy(state->wheel[255U - r], temp[r], 256U);
|
||||
}
|
||||
slunkcrypt_bzero(temp, sizeof(temp));
|
||||
CHECK_ABORTED();
|
||||
}
|
||||
|
||||
/* set up stepping */
|
||||
random_seed(&rand_state, nonce, 256U, passwd, passwd_len);
|
||||
for (i = 0U; i < 241U; ++i)
|
||||
{
|
||||
const size_t j = random_next(&rand_state) % (i + 1U);
|
||||
if (j != i)
|
||||
{
|
||||
crypt_state->step[i] = crypt_state->step[j];
|
||||
}
|
||||
crypt_state->step[j] = (uint8_t)(reverse ? (249U - i) : (6U + i));
|
||||
}
|
||||
|
||||
/* final clean-up */
|
||||
slunkcrypt_bzero(&rand_state, sizeof(xorsh_state_t));
|
||||
random_seed(&state->random, nonce, 256U, passwd, passwd_len);
|
||||
return SLUNKCRYPT_SUCCESS;
|
||||
|
||||
/* user abort request */
|
||||
abort_request:
|
||||
slunkcrypt_bzero(&rand_state, sizeof(xorsh_state_t));
|
||||
slunkcrypt_bzero(crypt_state, sizeof(crypt_state_t));
|
||||
aborted:
|
||||
slunkcrypt_bzero(state, sizeof(crypt_state_t));
|
||||
return SLUNKCRYPT_ABORTED;
|
||||
}
|
||||
|
||||
@ -297,39 +279,29 @@ abort_request:
|
||||
// Encrypt / Decrypt
|
||||
// ==========================================================================
|
||||
|
||||
static FORCE_INLINE void increment(uint8_t *const arr, const size_t offset, const size_t limit, const boolean reverse)
|
||||
static FORCE_INLINE void calculate_offsets(uint8_t *const offset, rand_state_t *const state, const boolean reverse)
|
||||
{
|
||||
uint32_t temp = 0U;
|
||||
size_t i;
|
||||
for (i = offset; i < limit; ++i)
|
||||
for (i = 0U; i < 256U; ++i, temp >>= CHAR_BIT)
|
||||
{
|
||||
if (++arr[reverse ? (255U - i) : i] != 0U)
|
||||
if (!temp)
|
||||
{
|
||||
break; /*no carry*/
|
||||
temp = random_next(state);
|
||||
}
|
||||
offset[reverse ? (255U - i) : i] = (uint8_t)temp;
|
||||
}
|
||||
}
|
||||
|
||||
static FORCE_INLINE void odometer_step(uint8_t *const arr, const boolean reverse)
|
||||
{
|
||||
increment(arr, 0U, 6U, LOGICAL_XOR(reverse, 0));
|
||||
increment(arr, 0U, 3U, LOGICAL_XOR(reverse, 1));
|
||||
increment(arr, 3U, 6U, LOGICAL_XOR(reverse, 1));
|
||||
increment(arr, 6U, 9U, LOGICAL_XOR(reverse, 1));
|
||||
}
|
||||
|
||||
static FORCE_INLINE uint8_t process_next_symbol(crypt_state_t *const crypt_state, uint8_t value)
|
||||
static FORCE_INLINE uint8_t process_next_symbol(crypt_state_t *const crypt_state_t, uint8_t value)
|
||||
{
|
||||
uint8_t offset[256U];
|
||||
size_t i;
|
||||
calculate_offsets(offset, &crypt_state_t->random, crypt_state_t->reverse_mode);
|
||||
for (i = 0U; i < 256U; ++i)
|
||||
{
|
||||
const uint8_t offset = crypt_state->rotation[i];
|
||||
value = (crypt_state->wheel[i][(value + offset) & 0xFF] - offset) & 0xFF;
|
||||
value = (crypt_state_t->wheel[i][(value + offset[i]) & 0xFF] - offset[i]) & 0xFF;
|
||||
}
|
||||
|
||||
++crypt_state->rotation[crypt_state->step[crypt_state->counter]];
|
||||
crypt_state->counter = (crypt_state->counter + 1U) % 241U;
|
||||
odometer_step(crypt_state->rotation, crypt_state->reverse_mode);
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
@ -337,7 +309,7 @@ static FORCE_INLINE uint8_t process_next_symbol(crypt_state_t *const crypt_state
|
||||
// Public API
|
||||
// ==========================================================================
|
||||
|
||||
int slunkcrypt_generate_nonce(uint64_t* const nonce)
|
||||
int slunkcrypt_generate_nonce(uint64_t *const nonce)
|
||||
{
|
||||
if (!nonce)
|
||||
{
|
||||
@ -378,7 +350,7 @@ slunkcrypt_t slunkcrypt_alloc(const uint64_t nonce, const uint8_t *const passwd,
|
||||
|
||||
int slunkcrypt_reset(const slunkcrypt_t context, const uint64_t nonce, const uint8_t *const passwd, const size_t passwd_len, const int mode)
|
||||
{
|
||||
crypt_state_t* const state = (crypt_state_t*)context;
|
||||
crypt_state_t *const state = (crypt_state_t*)context;
|
||||
int result = SLUNKCRYPT_FAILURE;
|
||||
if ((!state) || (!passwd) || (passwd_len < SLUNKCRYPT_PWDLEN_MIN) || (passwd_len > SLUNKCRYPT_PWDLEN_MAX) || (mode < SLUNKCRYPT_ENCRYPT) || (mode > SLUNKCRYPT_DECRYPT))
|
||||
{
|
||||
@ -411,7 +383,7 @@ int slunkcrypt_process(const slunkcrypt_t context, const uint8_t *const input, u
|
||||
|
||||
return SLUNKCRYPT_SUCCESS;
|
||||
|
||||
abort_request:
|
||||
aborted:
|
||||
slunkcrypt_bzero(state, sizeof(crypt_state_t));
|
||||
return SLUNKCRYPT_ABORTED;
|
||||
}
|
||||
@ -436,14 +408,14 @@ int slunkcrypt_process_inplace(const slunkcrypt_t context, uint8_t *const buffer
|
||||
|
||||
return SLUNKCRYPT_SUCCESS;
|
||||
|
||||
abort_request:
|
||||
aborted:
|
||||
slunkcrypt_bzero(state, sizeof(crypt_state_t));
|
||||
return SLUNKCRYPT_ABORTED;
|
||||
}
|
||||
|
||||
void slunkcrypt_free(const slunkcrypt_t context)
|
||||
{
|
||||
crypt_state_t* const state = (crypt_state_t*)context;
|
||||
crypt_state_t *const state = (crypt_state_t*)context;
|
||||
if (state)
|
||||
{
|
||||
slunkcrypt_bzero(state, sizeof(crypt_state_t));
|
||||
|
Loading…
Reference in New Issue
Block a user