#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"
typedef struct
{
u32 key[8];
} belt_ecb_st;
size_t beltECB_keep()
{
return sizeof(belt_ecb_st);
}
void beltECBStart(void* state, const octet key[], size_t len)
{
belt_ecb_st* st = (belt_ecb_st*)state;
ASSERT(memIsValid(state, beltECB_keep()));
beltKeyExpand2(st->key, key, len);
}
void beltECBStepE(void* buf, size_t count, void* state)
{
belt_ecb_st* st = (belt_ecb_st*)state;
ASSERT(count >= 16);
ASSERT(memIsDisjoint2(buf, count, state, beltECB_keep()));
while(count >= 16)
{
beltBlockEncr(buf, st->key);
buf = (octet*)buf + 16;
count -= 16;
}
if (count)
{
memSwap((octet*)buf - 16, buf, count);
beltBlockEncr((octet*)buf - 16, st->key);
}
}
void beltECBStepD(void* buf, size_t count, void* state)
{
belt_ecb_st* st = (belt_ecb_st*)state;
ASSERT(count >= 16);
ASSERT(memIsDisjoint2(buf, count, state, beltECB_keep()));
while(count >= 16)
{
beltBlockDecr(buf, st->key);
buf = (octet*)buf + 16;
count -= 16;
}
if (count)
{
memSwap((octet*)buf - 16, buf, count);
beltBlockDecr((octet*)buf - 16, st->key);
}
}
err_t beltECBEncr(void* dest, const void* src, size_t count,
const octet key[], size_t len)
{
void* state;
if (count < 16 ||
len != 16 && len != 24 && len != 32 ||
!memIsValid(src, count) ||
!memIsValid(key, len) ||
!memIsValid(dest, count))
return ERR_BAD_INPUT;
state = blobCreate(beltECB_keep());
if (state == 0)
return ERR_OUTOFMEMORY;
beltECBStart(state, key, len);
memMove(dest, src, count);
beltECBStepE(dest, count, state);
blobClose(state);
return ERR_OK;
}
err_t beltECBDecr(void* dest, const void* src, size_t count,
const octet key[], size_t len)
{
void* state;
if (count < 16 ||
len != 16 && len != 24 && len != 32 ||
!memIsValid(src, count) ||
!memIsValid(key, len) ||
!memIsValid(dest, count))
return ERR_BAD_INPUT;
state = blobCreate(beltECB_keep());
if (state == 0)
return ERR_OUTOFMEMORY;
beltECBStart(state, key, len);
memMove(dest, src, count);
beltECBStepD(dest, count, state);
blobClose(state);
return ERR_OK;
}