#include "CommonDigest.h"
#include "CommonDigestPriv.h"
#include "CommonDigestSPI.h"
#include "tomcrypt.h"
#include "skein_ltc.h"
#define SELECT_HASH(X,Y,Z) case X: \
ptr->hashIndex = register_hash(&Y); \
break
int
CCDigestInit(CCDigestAlg algorithm, CCDigestRef ctx)
{
CCDigestCtxPtr ptr = (CCDigestCtxPtr) ctx;
switch(algorithm) {
SELECT_HASH(kCCDigestMD2,md2_desc,7);
SELECT_HASH(kCCDigestMD4,md4_desc,6);
SELECT_HASH(kCCDigestMD5,ltc_md5_desc,3);
SELECT_HASH(kCCDigestRMD128,rmd128_desc,8);
SELECT_HASH(kCCDigestRMD160,rmd160_desc,9);
SELECT_HASH(kCCDigestRMD256,rmd256_desc,11);
SELECT_HASH(kCCDigestRMD320,rmd320_desc,12);
SELECT_HASH(kCCDigestSHA1,sha1_desc,2);
SELECT_HASH(kCCDigestSHA224,sha224_desc,10);
SELECT_HASH(kCCDigestSHA256,sha256_desc,0);
SELECT_HASH(kCCDigestSHA384,sha384_desc,4);
SELECT_HASH(kCCDigestSHA512,sha512_desc,5);
SELECT_HASH(kCCDigestSkein128,skein512_128_desc,SKEIN512_128_LTC_TAG);
SELECT_HASH(kCCDigestSkein160,skein512_160_desc,SKEIN512_160_LTC_TAG);
SELECT_HASH(kCCDigestSkein224,skein512_224_desc,SKEIN512_224_LTC_TAG);
SELECT_HASH(kCCDigestSkein256,skein512_256_desc,SKEIN512_256_LTC_TAG);
SELECT_HASH(kCCDigestSkein384,skein512_384_desc,SKEIN512_384_LTC_TAG);
SELECT_HASH(kCCDigestSkein512,skein512_512_desc,SKEIN512_512_LTC_TAG);
default: return -1;
}
return hash_descriptor[ptr->hashIndex].init(&ptr->md);
}
int
CCDigestUpdate(CCDigestRef ctx, const void *data, size_t len)
{
CCDigestCtxPtr ptr = (CCDigestCtxPtr) ctx;
uint8_t* checkedData = (const uint8_t *)data;
if (checkedData == NULL) {
checkedData = "";
}
return hash_descriptor[ptr->hashIndex].process(&ptr->md, checkedData, len);
}
int
CCDigestFinal(CCDigestRef ctx, uint8_t *output)
{
CCDigestCtxPtr ptr = (CCDigestCtxPtr) ctx;
return hash_descriptor[ptr->hashIndex].done(&ptr->md, output);
}
int
CCDigest(CCDigestAlg algorithm, const uint8_t *data, size_t length, uint8_t *output)
{
CCDigestCtx_t c;
CCDigestCtxPtr ptr = &c;
CCDigestInit(algorithm, ptr);
uint8_t* checkedData = data;
if (checkedData == NULL) {
checkedData = "";
}
hash_descriptor[ptr->hashIndex].process(&ptr->md, checkedData, length);
return hash_descriptor[ptr->hashIndex].done(&ptr->md, output);
}
CCDigestRef
CCDigestCreate(CCDigestAlg algorithm)
{
CCDigestRef ctx;
if(!(ctx = (CCDigestCtx *) malloc(CC_DIGEST_SIZE))) {
return NULL;
}
if(CCDigestInit(algorithm, ctx) != 0) {
free(ctx);
return NULL;
}
return ctx;
}
void
CCDigestDestroy(CCDigestRef ctx)
{
bzero(ctx, sizeof(CCDigestCtx));
free(ctx);
}
void
CCDigestReset(CCDigestRef ctx)
{
CCDigestCtxPtr ptr = (CCDigestCtxPtr) ctx;
hash_descriptor[ptr->hashIndex].init(&ptr->md);
}
int
CCDigestInterrimResult(CCDigestRef ctx, uint8_t *output)
{
CCDigestCtx tmp;
memcpy(&tmp, ctx, CC_DIGEST_SIZE);
return CCDigestFinal(&tmp, output);
}
size_t
CCDigestBlockSize(CCDigestRef ctx)
{
size_t retval = 0;
CCDigestCtxPtr ptr = (CCDigestCtxPtr) ctx;
if(ptr) retval = hash_descriptor[ptr->hashIndex].blocksize;
return retval;
}
size_t
CCDigestOutputSize(CCDigestRef ctx)
{
size_t retval = 0;
CCDigestCtxPtr ptr = (CCDigestCtxPtr) ctx;
if(ptr) retval = hash_descriptor[ptr->hashIndex].hashsize;
return retval;
}