#include "bee2/core/blob.h"
#include "bee2/core/err.h"
#include "bee2/core/mem.h"
#include "bee2/core/util.h"
#include "bee2/crypto/belt.h"
#include "belt_lcl.h"
typedef struct
{
belt_wbl_st wbl[1];
octet s[16];
} belt_sde_st;
size_t beltSDE_keep()
{
return sizeof(belt_sde_st);
}
void beltSDEStart(void* state, const octet key[], size_t len)
{
belt_sde_st* st = (belt_sde_st*)state;
ASSERT(memIsValid(state, beltSDE_keep()));
beltWBLStart(st->wbl, key, len);
}
void beltSDEStepE(void* buf, size_t count, const octet iv[16], void* state)
{
belt_sde_st* st = (belt_sde_st*)state;
ASSERT(count % 16 == 0 && count >= 16);
ASSERT(memIsDisjoint2(buf, count, state, beltSDE_keep()));
ASSERT(memIsValid(iv, 16));
memCopy(st->s, iv, 16);
beltBlockEncr(st->s, st->wbl->key);
beltBlockXor2(buf, st->s);
beltWBLStepE(buf, count, st->wbl);
beltBlockXor2(buf, st->s);
}
void beltSDEStepD(void* buf, size_t count, const octet iv[16], void* state)
{
belt_sde_st* st = (belt_sde_st*)state;
ASSERT(count % 16 == 0 && count >= 32);
ASSERT(memIsDisjoint2(buf, count, state, beltSDE_keep()));
ASSERT(memIsValid(iv, 16));
memCopy(st->s, iv, 16);
beltBlockEncr(st->s, st->wbl->key);
beltBlockXor2(buf, st->s);
beltWBLStepD(buf, count, st->wbl);
beltBlockXor2(buf, st->s);
}
err_t beltSDEEncr(void* dest, const void* src, size_t count,
const octet key[], size_t len, const octet iv[16])
{
void* state;
if (count % 16 != 0 || count < 32 ||
len != 16 && len != 24 && len != 32 ||
!memIsValid(src, count) ||
!memIsValid(key, len) ||
!memIsValid(iv, 16) ||
!memIsValid(dest, count))
return ERR_BAD_INPUT;
state = blobCreate(beltSDE_keep());
if (state == 0)
return ERR_OUTOFMEMORY;
beltSDEStart(state, key, len);
memMove(dest, src, count);
beltSDEStepE(dest, count, iv, state);
blobClose(state);
return ERR_OK;
}
err_t beltSDEDecr(void* dest, const void* src, size_t count,
const octet key[], size_t len, const octet iv[16])
{
void* state;
if (count % 16 != 0 || count < 32 ||
len != 16 && len != 24 && len != 32 ||
!memIsValid(src, count) ||
!memIsValid(key, len) ||
!memIsValid(iv, 16) ||
!memIsValid(dest, count))
return ERR_BAD_INPUT;
state = blobCreate(beltSDE_keep());
if (state == 0)
return ERR_OUTOFMEMORY;
beltSDEStart(state, key, len);
memMove(dest, src, count);
beltSDEStepD(dest, count, iv, state);
blobClose(state);
return ERR_OK;
}