2020-10-12 19:10:19 +02:00
|
|
|
/******************************************************************************/
|
2020-10-19 21:56:12 +02:00
|
|
|
/* SlunkCrypt, by LoRd_MuldeR <MuldeR2@GMX.de> */
|
2020-10-12 19:10:19 +02:00
|
|
|
/* This work has been released under the CC0 1.0 Universal license! */
|
|
|
|
/******************************************************************************/
|
|
|
|
|
|
|
|
#ifdef _WIN32
|
|
|
|
#define _CRT_RAND_S 1
|
|
|
|
#endif
|
|
|
|
|
2020-10-26 19:56:45 +01:00
|
|
|
/* Internal */
|
|
|
|
#include "../include/slunkcrypt.h"
|
|
|
|
#include "version.h"
|
|
|
|
|
|
|
|
/* CRT */
|
2020-10-12 19:10:19 +02:00
|
|
|
#include <string.h>
|
2020-10-26 19:56:45 +01:00
|
|
|
#include <limits.h>
|
2020-10-24 21:06:37 +02:00
|
|
|
#include <assert.h>
|
2020-10-12 19:10:19 +02:00
|
|
|
|
2020-10-26 19:56:45 +01:00
|
|
|
/* Compiler compatibility */
|
|
|
|
#if defined(_MSC_VER)
|
|
|
|
# define FORCE_INLINE __forceinline
|
|
|
|
# define UNUSED __pragma(warning(suppress: 4189))
|
|
|
|
#elif defined(__GNUC__)
|
|
|
|
# define FORCE_INLINE __attribute__((always_inline)) inline
|
|
|
|
# define UNUSED __attribute__((unused))
|
2020-10-15 21:56:36 +02:00
|
|
|
#else
|
2020-10-26 19:56:45 +01:00
|
|
|
# define FORCE_INLINE inline
|
|
|
|
# define UNUSED
|
2020-10-15 21:56:36 +02:00
|
|
|
#endif
|
|
|
|
|
2020-10-20 15:21:00 +02:00
|
|
|
/* Version info */
|
|
|
|
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__;
|
|
|
|
|
2020-10-24 21:06:37 +02:00
|
|
|
/* Const */
|
|
|
|
#define MAGIC_PRIME 0x00000100000001B3ull
|
|
|
|
|
2020-10-20 15:21:00 +02:00
|
|
|
// ==========================================================================
|
|
|
|
// Data structures
|
|
|
|
// ==========================================================================
|
2020-10-12 19:10:19 +02:00
|
|
|
|
2020-10-16 17:37:04 +02:00
|
|
|
typedef struct
|
|
|
|
{
|
|
|
|
uint64_t a, b;
|
|
|
|
}
|
2020-10-16 18:07:45 +02:00
|
|
|
key_data_t;
|
2020-10-16 17:37:04 +02:00
|
|
|
|
2020-10-12 19:10:19 +02:00
|
|
|
typedef struct
|
|
|
|
{
|
2020-10-14 13:39:12 +02:00
|
|
|
uint8_t wheel_fwd[256U][256U];
|
|
|
|
uint8_t wheel_bwd[256U][256U];
|
2020-10-14 14:02:05 +02:00
|
|
|
uint8_t step_fwd[256U];
|
|
|
|
uint8_t step_bwd[256U];
|
2020-10-15 21:56:36 +02:00
|
|
|
uint8_t rotation_fwd[2U][256U];
|
|
|
|
uint8_t rotation_bwd[2U][256U];
|
2020-10-14 13:39:12 +02:00
|
|
|
uint8_t counter;
|
2020-10-12 19:10:19 +02:00
|
|
|
}
|
|
|
|
crypt_state_t;
|
|
|
|
|
|
|
|
typedef struct
|
|
|
|
{
|
|
|
|
uint32_t a, b, c, d;
|
|
|
|
uint32_t counter;
|
|
|
|
}
|
|
|
|
rand_state_t;
|
|
|
|
|
2020-10-18 20:41:02 +02:00
|
|
|
// ==========================================================================
|
|
|
|
// Abort flag
|
|
|
|
// ==========================================================================
|
|
|
|
|
2020-10-19 21:56:12 +02:00
|
|
|
volatile int g_slunkcrypt_abort_flag = 0;
|
2020-10-18 20:41:02 +02:00
|
|
|
|
|
|
|
#define CHECK_ABORTED() do \
|
|
|
|
{ \
|
2020-10-19 21:56:12 +02:00
|
|
|
if (g_slunkcrypt_abort_flag) \
|
2020-10-18 20:41:02 +02:00
|
|
|
{ \
|
2020-10-19 21:56:12 +02:00
|
|
|
return SLUNKCRYPT_ABORTED; \
|
2020-10-18 20:41:02 +02:00
|
|
|
} \
|
|
|
|
} \
|
|
|
|
while (0)
|
|
|
|
|
2020-10-24 21:06:37 +02:00
|
|
|
// ==========================================================================
|
|
|
|
// Byte access (endianness agnostic)
|
|
|
|
// ==========================================================================
|
|
|
|
|
|
|
|
static FORCE_INLINE uint32_t lower_u64(const uint64_t value)
|
|
|
|
{
|
|
|
|
return (uint32_t)(value & 0xFFFFFFFF);
|
|
|
|
}
|
|
|
|
|
|
|
|
static FORCE_INLINE uint32_t upper_u64(const uint64_t value)
|
|
|
|
{
|
|
|
|
return (uint32_t)((value > 32U) & 0xFFFFFFFF);
|
|
|
|
}
|
|
|
|
|
|
|
|
static FORCE_INLINE uint8_t byte_u16(const uint16_t value, const size_t off)
|
|
|
|
{
|
|
|
|
assert(index < sizeof(uint16_t));
|
|
|
|
return (uint8_t)((value >> (CHAR_BIT * off)) & 0xFF);
|
|
|
|
}
|
|
|
|
|
|
|
|
static FORCE_INLINE uint8_t byte_u64(const uint64_t value, const size_t off)
|
|
|
|
{
|
|
|
|
assert(index < sizeof(uint64_t));
|
|
|
|
return (uint8_t)((value >> (CHAR_BIT * off)) & 0xFF);
|
|
|
|
}
|
|
|
|
|
2020-10-12 19:10:19 +02:00
|
|
|
// ==========================================================================
|
|
|
|
// Hash function
|
|
|
|
// ==========================================================================
|
|
|
|
|
2020-10-24 21:06:37 +02:00
|
|
|
static FORCE_INLINE void hash_update_str(uint64_t* const hash, const uint8_t* const data, const size_t data_len)
|
2020-10-12 19:10:19 +02:00
|
|
|
{
|
|
|
|
for (size_t i = 0U; i < data_len; ++i)
|
|
|
|
{
|
2020-10-24 21:06:37 +02:00
|
|
|
*hash = ((*hash) ^ data[i]) * MAGIC_PRIME;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
static FORCE_INLINE void hash_update_u64(uint64_t* const hash, const uint64_t value)
|
|
|
|
{
|
|
|
|
for (size_t i = 0U; i < sizeof(uint64_t); ++i)
|
|
|
|
{
|
|
|
|
*hash = ((*hash) ^ byte_u64(value, i)) * MAGIC_PRIME;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
static FORCE_INLINE void hash_update_u16(uint64_t* const hash, const uint16_t value)
|
|
|
|
{
|
|
|
|
for (size_t i = 0U; i < sizeof(uint16_t); ++i)
|
|
|
|
{
|
|
|
|
*hash = ((*hash) ^ byte_u16(value, i)) * MAGIC_PRIME;
|
2020-10-12 19:10:19 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-10-12 23:10:47 +02:00
|
|
|
static uint64_t hash_code(const uint64_t salt, const uint16_t pepper, const uint8_t* const data, const size_t data_len)
|
2020-10-12 19:10:19 +02:00
|
|
|
{
|
2020-10-24 21:06:37 +02:00
|
|
|
uint64_t hash = 0xCBF29CE484222325ull;
|
|
|
|
hash_update_u64(&hash, salt);
|
|
|
|
hash_update_u16(&hash, pepper);
|
|
|
|
hash_update_str(&hash, data, data_len);
|
|
|
|
return hash;
|
2020-10-12 19:10:19 +02:00
|
|
|
}
|
|
|
|
|
2020-10-16 17:37:04 +02:00
|
|
|
// ==========================================================================
|
|
|
|
// Key derivation
|
|
|
|
// ==========================================================================
|
|
|
|
|
|
|
|
static FORCE_INLINE uint64_t keygen_loop(uint64_t value, const uint16_t pepper, const uint8_t* const passwd, const size_t passwd_len)
|
|
|
|
{
|
|
|
|
for (size_t i = 0U; i < 99971U; ++i)
|
|
|
|
{
|
2020-10-16 23:50:16 +02:00
|
|
|
value ^= hash_code(value, pepper, passwd, passwd_len);
|
2020-10-16 17:37:04 +02:00
|
|
|
}
|
|
|
|
return value;
|
|
|
|
}
|
|
|
|
|
2020-10-16 18:07:45 +02:00
|
|
|
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)
|
2020-10-16 17:37:04 +02:00
|
|
|
{
|
|
|
|
key->a = keygen_loop(salt, pepper & 0x7FFF, passwd, passwd_len);
|
|
|
|
key->b = keygen_loop(salt, pepper | 0x8000, passwd, passwd_len);
|
|
|
|
}
|
|
|
|
|
2020-10-12 19:10:19 +02:00
|
|
|
// ==========================================================================
|
|
|
|
// PRNG
|
|
|
|
// ==========================================================================
|
|
|
|
|
|
|
|
static void random_init(rand_state_t* const state, const uint64_t seed_0, const uint64_t seed_1)
|
|
|
|
{
|
2020-10-19 21:56:12 +02:00
|
|
|
slunkcrypt_bzero(state, sizeof(rand_state_t));
|
2020-10-24 21:06:37 +02:00
|
|
|
state->a = lower_u64(seed_0);
|
|
|
|
state->b = upper_u64(seed_0);
|
|
|
|
state->c = lower_u64(seed_1);
|
|
|
|
state->d = upper_u64(seed_1);
|
2020-10-12 19:10:19 +02:00
|
|
|
}
|
|
|
|
|
2020-10-16 17:37:04 +02:00
|
|
|
static uint32_t random_next(rand_state_t *const state)
|
2020-10-12 19:10:19 +02:00
|
|
|
{
|
|
|
|
uint32_t t = state->d;
|
|
|
|
const uint32_t s = state->a;
|
|
|
|
state->d = state->c;
|
|
|
|
state->c = state->b;
|
|
|
|
state->b = s;
|
|
|
|
t ^= t >> 2;
|
|
|
|
t ^= t << 1;
|
|
|
|
t ^= s ^ (s << 4);
|
|
|
|
state->a = t;
|
|
|
|
return t + (state->counter += 362437U);
|
|
|
|
}
|
|
|
|
|
2020-10-16 17:37:04 +02:00
|
|
|
static void random_seed(rand_state_t* const state, const uint64_t salt, const uint16_t pepper, const uint8_t *const passwd, const size_t passwd_len)
|
2020-10-12 19:10:19 +02:00
|
|
|
{
|
2020-10-16 18:07:45 +02:00
|
|
|
key_data_t key;
|
2020-10-16 17:37:04 +02:00
|
|
|
generate_key(&key, salt, pepper, passwd, passwd_len);
|
|
|
|
random_init(state, key.a, key.b);
|
2020-10-19 21:56:12 +02:00
|
|
|
slunkcrypt_bzero(&key, sizeof(key_data_t));
|
2020-10-16 23:50:16 +02:00
|
|
|
for (size_t i = 0U; i < 97U; ++i)
|
2020-10-12 19:10:19 +02:00
|
|
|
{
|
2020-10-26 19:56:45 +01:00
|
|
|
UNUSED volatile uint32_t u = random_next(state);
|
2020-10-12 19:10:19 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// ==========================================================================
|
|
|
|
// Initialization
|
|
|
|
// ==========================================================================
|
|
|
|
|
2020-10-26 19:56:45 +01:00
|
|
|
static int initialize_state(crypt_state_t* const crypt_state, const uint64_t nonce, const uint8_t* const passwd, const size_t passwd_len)
|
2020-10-12 19:10:19 +02:00
|
|
|
{
|
2020-10-19 21:56:12 +02:00
|
|
|
slunkcrypt_bzero(crypt_state, sizeof(crypt_state_t));
|
2020-10-16 17:37:04 +02:00
|
|
|
|
2020-10-14 14:02:05 +02:00
|
|
|
/* set up wheels and initial rotation */
|
2020-10-12 19:10:19 +02:00
|
|
|
rand_state_t rand_state;
|
|
|
|
for (size_t r = 0U; r < 256U; ++r)
|
|
|
|
{
|
2020-10-26 19:56:45 +01:00
|
|
|
random_seed(&rand_state, nonce, (uint16_t)r, passwd, passwd_len);
|
2020-10-15 21:56:36 +02:00
|
|
|
crypt_state->rotation_bwd[0U][255U - r] = crypt_state->rotation_fwd[0U][r] = (uint8_t)random_next(&rand_state);
|
|
|
|
crypt_state->rotation_bwd[1U][255U - r] = crypt_state->rotation_fwd[1U][r] = 0U;
|
2020-10-12 19:10:19 +02:00
|
|
|
for (size_t i = 0U; i < 256U; ++i)
|
|
|
|
{
|
|
|
|
const size_t j = random_next(&rand_state) % (i + 1U);
|
|
|
|
if (j != i)
|
|
|
|
{
|
2020-10-14 13:39:12 +02:00
|
|
|
crypt_state->wheel_fwd[r][i] = crypt_state->wheel_fwd[r][j];
|
2020-10-12 19:10:19 +02:00
|
|
|
}
|
2020-10-14 13:39:12 +02:00
|
|
|
crypt_state->wheel_fwd[r][j] = (uint8_t)i;
|
2020-10-12 19:10:19 +02:00
|
|
|
}
|
|
|
|
for (size_t i = 0U; i < 256U; ++i)
|
|
|
|
{
|
2020-10-14 13:39:12 +02:00
|
|
|
const size_t j = crypt_state->wheel_fwd[r][i];
|
2020-10-14 14:02:05 +02:00
|
|
|
crypt_state->wheel_bwd[255U - r][j] = (uint8_t)i;
|
2020-10-12 19:10:19 +02:00
|
|
|
}
|
2020-10-18 20:41:02 +02:00
|
|
|
CHECK_ABORTED();
|
2020-10-12 19:10:19 +02:00
|
|
|
}
|
2020-10-14 14:02:05 +02:00
|
|
|
|
|
|
|
/* set up stepping */
|
2020-10-26 19:56:45 +01:00
|
|
|
random_seed(&rand_state, nonce, 256U, passwd, passwd_len);
|
2020-10-14 13:39:12 +02:00
|
|
|
for (size_t i = 0U; i < 256U; ++i)
|
|
|
|
{
|
|
|
|
const size_t j = random_next(&rand_state) % (i + 1U);
|
|
|
|
if (j != i)
|
|
|
|
{
|
2020-10-14 14:02:05 +02:00
|
|
|
crypt_state->step_fwd[i] = crypt_state->step_fwd[j];
|
|
|
|
crypt_state->step_bwd[i] = crypt_state->step_bwd[j];
|
2020-10-14 13:39:12 +02:00
|
|
|
}
|
2020-10-14 14:02:05 +02:00
|
|
|
crypt_state->step_fwd[j] = (uint8_t)i;
|
|
|
|
crypt_state->step_bwd[j] = (uint8_t)(255U - i);
|
2020-10-14 13:39:12 +02:00
|
|
|
}
|
2020-10-14 14:02:05 +02:00
|
|
|
|
2020-10-19 21:56:12 +02:00
|
|
|
slunkcrypt_bzero(&rand_state, sizeof(rand_state_t));
|
|
|
|
return SLUNKCRYPT_SUCCESS;
|
2020-10-12 19:10:19 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
// ==========================================================================
|
|
|
|
// Encrypt / Decrypt
|
|
|
|
// ==========================================================================
|
|
|
|
|
2020-10-15 21:56:36 +02:00
|
|
|
static FORCE_INLINE void increment(uint8_t *const arr, const int rev)
|
|
|
|
{
|
|
|
|
for (size_t i = 0U; i < 256U; ++i)
|
|
|
|
{
|
|
|
|
if (++arr[rev ? (255U - i) : i] != 0U)
|
|
|
|
{
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
static FORCE_INLINE uint8_t process_enc(crypt_state_t* const crypt_state, uint8_t value)
|
2020-10-12 19:10:19 +02:00
|
|
|
{
|
|
|
|
for (size_t i = 0U; i < 256U; ++i)
|
|
|
|
{
|
2020-10-15 21:56:36 +02:00
|
|
|
const uint8_t offset = crypt_state->rotation_fwd[0U][i] + crypt_state->rotation_fwd[1U][i];
|
|
|
|
value = crypt_state->wheel_fwd[i][(value + offset) & 0xFF];
|
2020-10-12 19:10:19 +02:00
|
|
|
}
|
2020-10-15 21:56:36 +02:00
|
|
|
++crypt_state->rotation_fwd[0U][crypt_state->step_fwd[crypt_state->counter++]];
|
|
|
|
increment(crypt_state->rotation_fwd[1U], 0);
|
2020-10-12 19:10:19 +02:00
|
|
|
return value;
|
|
|
|
}
|
|
|
|
|
2020-10-15 21:56:36 +02:00
|
|
|
static FORCE_INLINE uint8_t process_dec(crypt_state_t* const crypt_state, uint8_t value)
|
2020-10-12 19:10:19 +02:00
|
|
|
{
|
2020-10-14 14:02:05 +02:00
|
|
|
for (size_t i = 0U; i < 256U; ++i)
|
2020-10-12 19:10:19 +02:00
|
|
|
{
|
2020-10-15 21:56:36 +02:00
|
|
|
const uint8_t offset = crypt_state->rotation_bwd[0U][i] + crypt_state->rotation_bwd[1U][i];
|
|
|
|
value = (crypt_state->wheel_bwd[i][value] - offset) & 0xFF;
|
2020-10-12 19:10:19 +02:00
|
|
|
}
|
2020-10-15 21:56:36 +02:00
|
|
|
++crypt_state->rotation_bwd[0U][crypt_state->step_bwd[crypt_state->counter++]];
|
|
|
|
increment(crypt_state->rotation_bwd[1U], 1);
|
2020-10-12 19:10:19 +02:00
|
|
|
return value;
|
|
|
|
}
|
|
|
|
|
|
|
|
// ==========================================================================
|
|
|
|
// Public API
|
|
|
|
// ==========================================================================
|
|
|
|
|
2020-10-26 19:56:45 +01:00
|
|
|
int slunkcrypt_generate_nonce(uint64_t* const nonce)
|
2020-10-12 19:10:19 +02:00
|
|
|
{
|
2020-10-26 19:56:45 +01:00
|
|
|
if (!nonce)
|
2020-10-12 19:10:19 +02:00
|
|
|
{
|
2020-10-19 21:56:12 +02:00
|
|
|
return SLUNKCRYPT_FAILURE;
|
2020-10-12 19:10:19 +02:00
|
|
|
}
|
2020-10-14 14:02:05 +02:00
|
|
|
do
|
|
|
|
{
|
2020-10-26 19:56:45 +01:00
|
|
|
if (slunkcrypt_random_bytes((uint8_t*)nonce, sizeof(uint64_t)) != 0)
|
2020-10-14 14:02:05 +02:00
|
|
|
{
|
2020-10-19 21:56:12 +02:00
|
|
|
return SLUNKCRYPT_FAILURE;
|
2020-10-14 14:02:05 +02:00
|
|
|
}
|
|
|
|
}
|
2020-10-26 19:56:45 +01:00
|
|
|
while (!(*nonce));
|
2020-10-19 21:56:12 +02:00
|
|
|
return SLUNKCRYPT_SUCCESS;
|
2020-10-12 19:10:19 +02:00
|
|
|
}
|
|
|
|
|
2020-10-26 19:56:45 +01:00
|
|
|
slunkcrypt_t slunkcrypt_alloc(const uint64_t nonce, const uint8_t *const passwd, const size_t passwd_len)
|
2020-10-12 19:10:19 +02:00
|
|
|
{
|
2020-10-20 15:21:00 +02:00
|
|
|
if ((!passwd) || (passwd_len < SLUNKCRYPT_PWDLEN_MIN) || (passwd_len > SLUNKCRYPT_PWDLEN_MAX))
|
2020-10-12 19:10:19 +02:00
|
|
|
{
|
2020-10-19 21:56:12 +02:00
|
|
|
return SLUNKCRYPT_NULL;
|
2020-10-12 19:10:19 +02:00
|
|
|
}
|
2020-10-12 23:10:47 +02:00
|
|
|
crypt_state_t* const state = (crypt_state_t*)malloc(sizeof(crypt_state_t));
|
2020-10-12 19:10:19 +02:00
|
|
|
if (!state)
|
|
|
|
{
|
2020-10-19 21:56:12 +02:00
|
|
|
return SLUNKCRYPT_NULL;
|
2020-10-18 20:41:02 +02:00
|
|
|
}
|
2020-10-26 19:56:45 +01:00
|
|
|
if (initialize_state(state, nonce, passwd, passwd_len) == SLUNKCRYPT_SUCCESS)
|
2020-10-18 20:41:02 +02:00
|
|
|
{
|
2020-10-19 21:56:12 +02:00
|
|
|
return ((slunkcrypt_t)state);
|
2020-10-18 20:41:02 +02:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2020-10-19 21:56:12 +02:00
|
|
|
slunkcrypt_bzero(state, sizeof(crypt_state_t));
|
|
|
|
return SLUNKCRYPT_NULL;
|
2020-10-12 19:10:19 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-10-26 19:56:45 +01:00
|
|
|
int slunkcrypt_reset(const slunkcrypt_t context, const uint64_t nonce, const uint8_t *const passwd, const size_t passwd_len)
|
2020-10-14 13:39:12 +02:00
|
|
|
{
|
|
|
|
crypt_state_t* const state = (crypt_state_t*)context;
|
2020-10-20 15:21:00 +02:00
|
|
|
if ((!state) || (!passwd) || (passwd_len < SLUNKCRYPT_PWDLEN_MIN) || (passwd_len > SLUNKCRYPT_PWDLEN_MAX))
|
2020-10-14 13:39:12 +02:00
|
|
|
{
|
2020-10-19 21:56:12 +02:00
|
|
|
return SLUNKCRYPT_FAILURE;
|
2020-10-14 13:39:12 +02:00
|
|
|
}
|
2020-10-26 19:56:45 +01:00
|
|
|
const int result = initialize_state(state, nonce, passwd, passwd_len);
|
2020-10-19 21:56:12 +02:00
|
|
|
if (result != SLUNKCRYPT_SUCCESS)
|
2020-10-18 20:41:02 +02:00
|
|
|
{
|
2020-10-19 21:56:12 +02:00
|
|
|
slunkcrypt_bzero(state, sizeof(crypt_state_t));
|
2020-10-18 20:41:02 +02:00
|
|
|
}
|
|
|
|
return result;
|
2020-10-14 13:39:12 +02:00
|
|
|
}
|
|
|
|
|
2020-10-19 21:56:12 +02:00
|
|
|
int slunkcrypt_encrypt(const slunkcrypt_t context, const uint8_t* const input, uint8_t* const output, size_t length)
|
2020-10-12 19:10:19 +02:00
|
|
|
{
|
|
|
|
crypt_state_t* const state = (crypt_state_t*)context;
|
2020-10-14 13:39:12 +02:00
|
|
|
if (!state)
|
2020-10-12 19:10:19 +02:00
|
|
|
{
|
2020-10-19 21:56:12 +02:00
|
|
|
return SLUNKCRYPT_FAILURE;
|
2020-10-12 19:10:19 +02:00
|
|
|
}
|
2020-10-20 15:21:00 +02:00
|
|
|
if (length > 0U)
|
2020-10-12 19:10:19 +02:00
|
|
|
{
|
2020-10-20 15:21:00 +02:00
|
|
|
for (size_t i = 0; i < length; ++i)
|
|
|
|
{
|
|
|
|
output[i] = process_enc(state, input[i]);
|
|
|
|
CHECK_ABORTED();
|
|
|
|
}
|
2020-10-12 19:10:19 +02:00
|
|
|
}
|
2020-10-19 21:56:12 +02:00
|
|
|
return SLUNKCRYPT_SUCCESS;
|
2020-10-12 19:10:19 +02:00
|
|
|
}
|
|
|
|
|
2020-10-19 21:56:12 +02:00
|
|
|
int slunkcrypt_encrypt_inplace(const slunkcrypt_t context, uint8_t* const buffer, size_t length)
|
2020-10-12 19:10:19 +02:00
|
|
|
{
|
|
|
|
crypt_state_t* const state = (crypt_state_t*)context;
|
2020-10-14 13:39:12 +02:00
|
|
|
if (!state)
|
2020-10-12 19:10:19 +02:00
|
|
|
{
|
2020-10-19 21:56:12 +02:00
|
|
|
return SLUNKCRYPT_FAILURE;
|
2020-10-12 19:10:19 +02:00
|
|
|
}
|
2020-10-20 15:21:00 +02:00
|
|
|
if (length > 0U)
|
2020-10-12 19:10:19 +02:00
|
|
|
{
|
2020-10-20 15:21:00 +02:00
|
|
|
for (size_t i = 0; i < length; ++i)
|
|
|
|
{
|
|
|
|
buffer[i] = process_enc(state, buffer[i]);
|
|
|
|
CHECK_ABORTED();
|
|
|
|
}
|
2020-10-12 19:10:19 +02:00
|
|
|
}
|
2020-10-19 21:56:12 +02:00
|
|
|
return SLUNKCRYPT_SUCCESS;
|
2020-10-12 19:10:19 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2020-10-19 21:56:12 +02:00
|
|
|
int slunkcrypt_decrypt(const slunkcrypt_t context, const uint8_t* const input, uint8_t* const output, size_t length)
|
2020-10-12 19:10:19 +02:00
|
|
|
{
|
|
|
|
crypt_state_t* const state = (crypt_state_t*)context;
|
2020-10-14 13:39:12 +02:00
|
|
|
if (!state)
|
2020-10-12 19:10:19 +02:00
|
|
|
{
|
2020-10-19 21:56:12 +02:00
|
|
|
return SLUNKCRYPT_FAILURE;
|
2020-10-12 19:10:19 +02:00
|
|
|
}
|
2020-10-20 15:21:00 +02:00
|
|
|
if (length > 0U)
|
2020-10-12 19:10:19 +02:00
|
|
|
{
|
2020-10-20 15:21:00 +02:00
|
|
|
for (size_t i = 0; i < length; ++i)
|
|
|
|
{
|
|
|
|
output[i] = process_dec(state, input[i]);
|
|
|
|
CHECK_ABORTED();
|
|
|
|
}
|
2020-10-12 19:10:19 +02:00
|
|
|
}
|
2020-10-19 21:56:12 +02:00
|
|
|
return SLUNKCRYPT_SUCCESS;
|
2020-10-12 19:10:19 +02:00
|
|
|
}
|
|
|
|
|
2020-10-19 21:56:12 +02:00
|
|
|
int slunkcrypt_decrypt_inplace(const slunkcrypt_t context, uint8_t* const buffer, size_t length)
|
2020-10-12 19:10:19 +02:00
|
|
|
{
|
|
|
|
crypt_state_t* const state = (crypt_state_t*)context;
|
2020-10-14 13:39:12 +02:00
|
|
|
if (!state)
|
2020-10-12 19:10:19 +02:00
|
|
|
{
|
2020-10-19 21:56:12 +02:00
|
|
|
return SLUNKCRYPT_FAILURE;
|
2020-10-12 19:10:19 +02:00
|
|
|
}
|
2020-10-20 15:21:00 +02:00
|
|
|
if (length > 0U)
|
2020-10-12 19:10:19 +02:00
|
|
|
{
|
2020-10-20 15:21:00 +02:00
|
|
|
for (size_t i = 0; i < length; ++i)
|
|
|
|
{
|
|
|
|
buffer[i] = process_dec(state, buffer[i]);
|
|
|
|
CHECK_ABORTED();
|
|
|
|
}
|
2020-10-12 19:10:19 +02:00
|
|
|
}
|
2020-10-19 21:56:12 +02:00
|
|
|
return SLUNKCRYPT_SUCCESS;
|
2020-10-12 19:10:19 +02:00
|
|
|
}
|
|
|
|
|
2020-10-19 21:56:12 +02:00
|
|
|
void slunkcrypt_free(const slunkcrypt_t context)
|
2020-10-12 19:10:19 +02:00
|
|
|
{
|
|
|
|
crypt_state_t* const state = (crypt_state_t*)context;
|
2020-10-14 13:39:12 +02:00
|
|
|
if (state)
|
2020-10-12 19:10:19 +02:00
|
|
|
{
|
2020-10-19 21:56:12 +02:00
|
|
|
slunkcrypt_bzero(state, sizeof(crypt_state_t));
|
2020-10-14 13:39:12 +02:00
|
|
|
free(state);
|
2020-10-12 19:10:19 +02:00
|
|
|
}
|
|
|
|
}
|