#if defined (__x86_64__) || defined(__i386__) // x86_64 or i386 architectures
#include <stdio.h>
#include "vng_x86_sha1.h"
#include "ltc_hashcommon.h"
#include "tomcrypt_cfg.h"
#include "tomcrypt_macros.h"
#include "tomcrypt_argchk.h"
#include "ccDescriptors.h"
#include "ccErrors.h"
#include "ccMemory.h"
#include "CommonDigest.h"
const ccDescriptor vng_x86_sha1_desc =
{
.implementation_info = &cc_sha1_impinfo,
.dtype.digest.hashsize = CC_SHA1_DIGEST_LENGTH,
.dtype.digest.blocksize = CC_SHA1_BLOCK_BYTES,
.dtype.digest.digest_info = NULL,
.dtype.digest.init = &vng_x86_sha1_init,
.dtype.digest.process = &vng_x86_sha1_process,
.dtype.digest.done = &vng_x86_sha1_done,
};
int vng_x86_sha1_init(vng_x86_sha1_ctx *ctx)
{
LTC_ARGCHK(ctx != NULL);
ctx->state[0] = 0x67452301UL;
ctx->state[1] = 0xefcdab89UL;
ctx->state[2] = 0x98badcfeUL;
ctx->state[3] = 0x10325476UL;
ctx->state[4] = 0xc3d2e1f0UL;
CC_XZEROMEM(ctx->buf, CC_SHA1_BLOCK_BYTES);
ctx->curlen = 0;
ctx->length = 0;
return CRYPT_OK;
}
int vng_x86_sha1_process(vng_x86_sha1_ctx *ctx, const unsigned char *in, unsigned long inlen)
{
unsigned long n;
int err;
int fullblocks, remainder, processed;
LTC_ARGCHK(ctx != NULL);
LTC_ARGCHK(in != NULL);
if (ctx->curlen > sizeof(ctx->buf)) {
return CRYPT_INVALID_ARG;
}
if ((ctx->length + inlen) < ctx->length) {
return CRYPT_HASH_OVERFLOW;
}
while (inlen > 0) {
if (ctx->curlen == 0 && inlen >= VNG_X86_SHA1_BLOCKSIZE && CC_XALIGNED(in, 4)) {
fullblocks = inlen / VNG_X86_SHA1_BLOCKSIZE;
processed = fullblocks * VNG_X86_SHA1_BLOCKSIZE;
sha1_x86_compress_data_order (ctx->state, in, fullblocks);
ctx->length += processed * 8;
in += processed;
inlen -= processed;
} else {
n = MIN(inlen, (VNG_X86_SHA1_BLOCKSIZE - ctx->curlen));
CC_XMEMCPY(ctx->buf + ctx->curlen, in, n);
ctx->curlen += n; in += n; inlen -= n;
if (ctx->curlen == VNG_X86_SHA1_BLOCKSIZE) {
sha1_x86_compress_data_order (ctx->state, ctx->buf, 1);
ctx->length += 8*VNG_X86_SHA1_BLOCKSIZE;
ctx->curlen = 0;
}
}
}
return CRYPT_OK;
}
int vng_x86_sha1_done(vng_x86_sha1_ctx *ctx, unsigned char *out)
{
int i;
LTC_ARGCHK(ctx != NULL);
LTC_ARGCHK(out != NULL);
if (ctx->curlen >= sizeof(ctx->buf)) {
return CRYPT_INVALID_ARG;
}
ctx->length += ctx->curlen * 8;
ctx->buf[ctx->curlen++] = (unsigned char)0x80;
if (ctx->curlen > 56) {
while (ctx->curlen < 64) {
ctx->buf[ctx->curlen++] = (unsigned char)0;
}
sha1_x86_compress_data_order(ctx->state, ctx->buf, 1);
ctx->curlen = 0;
}
while (ctx->curlen < 56) {
ctx->buf[ctx->curlen++] = (unsigned char)0;
}
CC_XSTORE64H(ctx->length, ctx->buf+56);
sha1_x86_compress_data_order(ctx->state, ctx->buf, 1);
for(i=0; i<5; i++, out+=4) CC_XSTORE32H(ctx->state[i], out);
return CRYPT_OK;
}
#endif