Simplified crypt_state_t by merging separate fwd/bwd arrays.

This commit is contained in:
LoRd_MuldeR 2021-04-01 15:39:54 +02:00
parent 471e08737b
commit 8ebf71ba73
Signed by: mulder
GPG Key ID: 2B5913365F57E03F

View File

@ -34,8 +34,11 @@ const char* const SLUNKCRYPT_BUILD = __DATE__ " " __TIME__;
#define HASH_MAGIC_PRIME 0x00000100000001B3ull
#define HASH_OFFSET_BASE 0xCBF29CE484222325ull
/* Utils */
#define BOOLIFY(X) (!!(X))
/* Types */
typedef _Bool boolean;
/* Utilities */
#define INT_TO_BOOL(X) ((boolean)(!(!(X))))
#define LOGICAL_XOR(X,Y) ((Y) ? (!(X)) : (X))
// ==========================================================================
@ -52,17 +55,14 @@ typedef struct
{
uint32_t x, y, z, w, v, d;
}
rand_state_t;
xorsh_state_t;
typedef struct
{
uint8_t reverse_mode;
uint8_t wheel_fwd[256U][256U];
uint8_t wheel_bwd[256U][256U];
uint8_t step_fwd[241U];
uint8_t step_bwd[241U];
uint8_t rotation_fwd[256U];
uint8_t rotation_bwd[256U];
boolean reverse_mode;
uint8_t wheel[256U][256U];
uint8_t step[241U];
uint8_t rotation[256U];
uint8_t counter;
}
crypt_state_t;
@ -77,7 +77,7 @@ volatile int g_slunkcrypt_abort_flag = 0;
{ \
if (g_slunkcrypt_abort_flag) \
{ \
return SLUNKCRYPT_ABORTED; \
goto abort_request; \
} \
} \
while (0)
@ -179,12 +179,12 @@ static void generate_key(key_data_t *const key, const uint64_t salt, const uint1
}
// ==========================================================================
// PRNG
// Deterministic random bit generator
// ==========================================================================
static void random_init(rand_state_t *const state, const key_data_t *const key)
static void random_init(xorsh_state_t *const state, const key_data_t *const key)
{
slunkcrypt_bzero(state, sizeof(rand_state_t));
slunkcrypt_bzero(state, sizeof(xorsh_state_t));
state->x = lower_u64(key->a);
state->y = upper_u64(key->a);
state->z = lower_u64(key->b);
@ -193,7 +193,7 @@ static void random_init(rand_state_t *const state, const key_data_t *const key)
state->d = upper_u64(key->c);
}
static uint32_t random_next(rand_state_t *const state)
static uint32_t random_next(xorsh_state_t *const state)
{
const uint32_t t = state->x ^ (state->x >> 2);
state->x = state->y;
@ -204,7 +204,7 @@ static uint32_t random_next(rand_state_t *const state)
return (state->d += 0x000587C5) + state->v;
}
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)
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)
{
size_t i;
key_data_t key;
@ -225,33 +225,48 @@ static void random_seed(rand_state_t *const state, uint64_t salt, const uint16_t
// 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 reverse)
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)
{
rand_state_t rand_state;
xorsh_state_t rand_state;
uint8_t temp[256U][256U];
size_t r, i;
/* initialize state */
slunkcrypt_bzero(crypt_state, sizeof(crypt_state_t));
crypt_state->reverse_mode = BOOLIFY(reverse);
const boolean reverse = crypt_state->reverse_mode = INT_TO_BOOL(mode);
/* set up wheels and initial rotation */
for (r = 0U; r < 256U; ++r)
{
random_seed(&rand_state, nonce, (uint16_t)r, passwd, passwd_len);
crypt_state->rotation_bwd[255U - r] = crypt_state->rotation_fwd[r] = (uint8_t)random_next(&rand_state);
crypt_state->rotation[reverse ? (255U - r) : r] = (uint8_t)random_next(&rand_state);
for (i = 0U; i < 256U; ++i)
{
const size_t j = random_next(&rand_state) % (i + 1U);
if (j != i)
{
crypt_state->wheel_fwd[r][i] = crypt_state->wheel_fwd[r][j];
crypt_state->wheel[r][i] = crypt_state->wheel[r][j];
}
crypt_state->wheel_fwd[r][j] = (uint8_t)i;
crypt_state->wheel[r][j] = (uint8_t)i;
}
CHECK_ABORTED();
}
/* reverse the wheels, if requested */
if (reverse)
{
for (r = 0U; r < 256U; ++r)
{
for (i = 0U; i < 256U; ++i)
{
crypt_state->wheel_bwd[255U - r][crypt_state->wheel_fwd[r][i]] = (uint8_t)i;
temp[r][crypt_state->wheel[r][i]] = (uint8_t)i;
}
}
for (r = 0U; r < 256U; ++r)
{
memcpy(crypt_state->wheel[255U - r], temp[r], 256U);
}
slunkcrypt_bzero(temp, sizeof(temp));
CHECK_ABORTED();
}
@ -262,67 +277,59 @@ static int initialize_state(crypt_state_t *const crypt_state, const uint64_t non
const size_t j = random_next(&rand_state) % (i + 1U);
if (j != i)
{
crypt_state->step_fwd[i] = crypt_state->step_fwd[j];
crypt_state->step_bwd[i] = crypt_state->step_bwd[j];
crypt_state->step[i] = crypt_state->step[j];
}
crypt_state->step_fwd[j] = (uint8_t)( 6U + i);
crypt_state->step_bwd[j] = (uint8_t)(249U - i);
crypt_state->step[j] = (uint8_t)(reverse ? (249U - i) : (6U + i));
}
/* final clean-up */
slunkcrypt_bzero(&rand_state, sizeof(rand_state_t));
slunkcrypt_bzero(&rand_state, sizeof(xorsh_state_t));
return SLUNKCRYPT_SUCCESS;
/* user abort request */
abort_request:
slunkcrypt_bzero(&rand_state, sizeof(xorsh_state_t));
slunkcrypt_bzero(crypt_state, sizeof(crypt_state_t));
return SLUNKCRYPT_ABORTED;
}
// ==========================================================================
// Encrypt / Decrypt
// ==========================================================================
static FORCE_INLINE void increment(uint8_t *const arr, const size_t offset, const size_t limit, const int bwd)
static FORCE_INLINE void increment(uint8_t *const arr, const size_t offset, const size_t limit, const boolean reverse)
{
size_t i;
for (i = offset; i < limit; ++i)
{
if (++arr[bwd ? (255U - i) : i] != 0U)
if (++arr[reverse ? (255U - i) : i] != 0U)
{
break; /*no carry*/
}
}
}
static FORCE_INLINE void odometer_step(uint8_t *const arr, const int bwd)
static FORCE_INLINE void odometer_step(uint8_t *const arr, const boolean reverse)
{
increment(arr, 0U, 6U, LOGICAL_XOR(bwd, 0));
increment(arr, 0U, 3U, LOGICAL_XOR(bwd, 1));
increment(arr, 3U, 6U, LOGICAL_XOR(bwd, 1));
increment(arr, 6U, 9U, LOGICAL_XOR(bwd, 1));
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_encrypt(crypt_state_t *const crypt_state, uint8_t value)
static FORCE_INLINE uint8_t process_next_symbol(crypt_state_t *const crypt_state, uint8_t value)
{
size_t i;
for (i = 0U; i < 256U; ++i)
{
const uint8_t rotation = crypt_state->rotation_fwd[i];
value = (crypt_state->wheel_fwd[i][(value + rotation) & 0xFF] - rotation) & 0xFF;
const uint8_t offset = crypt_state->rotation[i];
value = (crypt_state->wheel[i][(value + offset) & 0xFF] - offset) & 0xFF;
}
++crypt_state->rotation_fwd[crypt_state->step_fwd[crypt_state->counter]];
odometer_step(crypt_state->rotation_fwd, 0);
crypt_state->counter = (crypt_state->counter + 1U) % 241U;
return value;
}
static FORCE_INLINE uint8_t process_decrypt(crypt_state_t *const crypt_state, uint8_t value)
{
size_t i;
for (i = 0U; i < 256U; ++i)
{
const uint8_t rotation = crypt_state->rotation_bwd[i];
value = (crypt_state->wheel_bwd[i][(value + rotation) & 0xFF] - rotation) & 0xFF;
}
++crypt_state->rotation_bwd[crypt_state->step_bwd[crypt_state->counter]];
odometer_step(crypt_state->rotation_bwd, 1);
++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;
}
@ -384,42 +391,54 @@ int slunkcrypt_reset(const slunkcrypt_t context, const uint64_t nonce, const uin
return result;
}
int slunkcrypt_process(const slunkcrypt_t context, const uint8_t* const input, uint8_t* const output, size_t length)
int slunkcrypt_process(const slunkcrypt_t context, const uint8_t *const input, uint8_t *const output, size_t length)
{
crypt_state_t* const state = (crypt_state_t*)context;
crypt_state_t *const state = (crypt_state_t*)context;
if (!state)
{
return SLUNKCRYPT_FAILURE;
}
if (length > 0U)
{
size_t i;
for (i = 0; i < length; ++i)
{
output[i] = state->reverse_mode ? process_decrypt(state, input[i]) : process_encrypt(state, input[i]);
output[i] = process_next_symbol(state, input[i]);
CHECK_ABORTED();
}
}
return SLUNKCRYPT_SUCCESS;
abort_request:
slunkcrypt_bzero(state, sizeof(crypt_state_t));
return SLUNKCRYPT_ABORTED;
}
int slunkcrypt_process_inplace(const slunkcrypt_t context, uint8_t* const buffer, size_t length)
int slunkcrypt_process_inplace(const slunkcrypt_t context, uint8_t *const buffer, size_t length)
{
crypt_state_t* const state = (crypt_state_t*)context;
crypt_state_t *const state = (crypt_state_t*)context;
if (!state)
{
return SLUNKCRYPT_FAILURE;
}
if (length > 0U)
{
size_t i;
for (i = 0; i < length; ++i)
{
buffer[i] = state->reverse_mode ? process_decrypt(state, buffer[i]) : process_encrypt(state, buffer[i]);
buffer[i] = process_next_symbol(state, buffer[i]);
CHECK_ABORTED();
}
}
return SLUNKCRYPT_SUCCESS;
abort_request:
slunkcrypt_bzero(state, sizeof(crypt_state_t));
return SLUNKCRYPT_ABORTED;
}
void slunkcrypt_free(const slunkcrypt_t context)