#include "ckconfig.h"
#include "feeTypes.h"
#include "ckSHA1.h"
#if CRYPTKIT_LIBMD_DIGEST
#include <CommonCrypto/CommonDigest.h>
#else
#include "ckSHA1_priv.h"
#endif
#include "falloc.h"
#include "platform.h"
#if CRYPTKIT_LIBMD_DIGEST
typedef struct {
CC_SHA1_CTX ctx;
unsigned char digest[CC_SHA1_DIGEST_LENGTH];
} Sha1Obj;
sha1Obj sha1Alloc(void)
{
void *rtn = fmalloc(sizeof(Sha1Obj));
memset(rtn, 0, sizeof(Sha1Obj));
CC_SHA1_Init(&(((Sha1Obj *)rtn)->ctx));
return (sha1Obj)rtn;
}
void sha1Reinit(sha1Obj sha1)
{
Sha1Obj *ctx = (Sha1Obj *)sha1;
CC_SHA1_Init(&ctx->ctx);
}
void sha1Free(sha1Obj sha1)
{
memset(sha1, 0, sizeof(Sha1Obj));
ffree(sha1);
}
void sha1AddData(sha1Obj sha1,
const unsigned char *data,
unsigned dataLen)
{
Sha1Obj *ctx = (Sha1Obj *)sha1;
CC_SHA1_Update(&ctx->ctx, data, dataLen);
}
unsigned char *sha1Digest(sha1Obj sha1)
{
Sha1Obj *ctx = (Sha1Obj *)sha1;
CC_SHA1_Final(ctx->digest, &ctx->ctx);
return ctx->digest;
}
unsigned sha1DigestLen(void)
{
return CC_SHA1_DIGEST_LENGTH;
}
#else
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;
}
#endif