#include "SHA1.h"
#include "SHA1_priv.h"
#include "platform.h"
#include <stdlib.h>
#define fmalloc(s) malloc(s)
#define ffree(p) free(p)
typedef struct {
SHS_INFO context;
int isDone;
BYTE dataBuf[SHS_BLOCKSIZE];
unsigned bufBytes; } sha1Inst;
sha1Obj sha1Alloc(void)
{
sha1Inst *sinst;
sinst = (sha1Inst *)fmalloc(sizeof(sha1Inst));
if(sinst == NULL) {
return NULL;
}
shsInit(&sinst->context);
sha1Reinit((sha1Obj)sinst);
return (sha1Obj)sinst;
}
void sha1Reinit(sha1Obj sha1)
{
sha1Inst *sinst = (sha1Inst *) sha1;
shsInit(&sinst->context);
sinst->isDone = 0;
sinst->bufBytes = 0;
}
void sha1Free(sha1Obj sha1)
{
sha1Inst *sinst = (sha1Inst *) sha1;
memset(sha1, 0, sizeof(sha1Inst));
ffree(sinst);
}
void sha1AddData(sha1Obj sha1,
const unsigned char *data,
unsigned dataLen)
{
sha1Inst *sinst = (sha1Inst *) sha1;
unsigned toMove;
unsigned blocks;
if(sinst->isDone) {
return;
}
if(sinst->bufBytes != 0) {
toMove = SHS_BLOCKSIZE - sinst->bufBytes;
if(toMove > dataLen) {
toMove = dataLen;
}
memmove(sinst->dataBuf+sinst->bufBytes, data, toMove);
data += toMove;
dataLen -= toMove;
sinst->bufBytes += toMove;
if(sinst->bufBytes == SHS_BLOCKSIZE) {
shsUpdate(&sinst->context, sinst->dataBuf, SHS_BLOCKSIZE);
sinst->bufBytes = 0;
}
}
blocks = dataLen / SHS_BLOCKSIZE;
toMove = blocks * SHS_BLOCKSIZE;
if(toMove != 0) {
shsUpdate(&sinst->context, data, toMove);
data += toMove;
dataLen -= toMove;
}
if(dataLen != 0) {
memmove(sinst->dataBuf, data, dataLen);
sinst->bufBytes = dataLen;
}
}
unsigned char *sha1Digest(sha1Obj sha1)
{
sha1Inst *sinst = (sha1Inst *) sha1;
if(!sinst->isDone) {
if(sinst->bufBytes != 0) {
shsUpdate(&sinst->context, sinst->dataBuf,
sinst->bufBytes);
sinst->bufBytes = 0;
}
shsFinal(&sinst->context);
sinst->isDone = 1;
}
return (unsigned char *)sinst->context.digest;
}
unsigned sha1DigestLen(void)
{
return SHS_DIGESTSIZE;
}