📄 sha1impl.c
字号:
/* Copyright 2003-2006, Voltage Security, all rights reserved.
*/
#include "vibecrypto.h"
#include "environment.h"
#include "base.h"
#include "libctx.h"
#include "algobj.h"
#include "digest.h"
#include "sha1.h"
int SHA1Init (
VoltAlgorithmObject *obj
)
{
VoltDigestClassCtx *digestCtx = (VoltDigestClassCtx *)(obj->classCtx);
VoltSHA1Ctx *sha1Ctx = (VoltSHA1Ctx *)(digestCtx->localDigestCtx);
/* Populate the SHA-1 Ctx with the initial values.
*/
sha1Ctx->countLow = 0;
sha1Ctx->countHigh = 0;
sha1Ctx->currentBlockLen = 0;
sha1Ctx->state[0] = sha1Ctx->initState[0];
sha1Ctx->state[1] = sha1Ctx->initState[1];
sha1Ctx->state[2] = sha1Ctx->initState[2];
sha1Ctx->state[3] = sha1Ctx->initState[3];
sha1Ctx->state[4] = sha1Ctx->initState[4];
return (0);
}
int SHA1Update (
VoltAlgorithmObject *obj,
unsigned char *dataToDigest,
unsigned int dataToDigestLen
)
{
unsigned int copyLen;
VoltDigestClassCtx *digestCtx = (VoltDigestClassCtx *)(obj->classCtx);
VoltSHA1Ctx *sha1Ctx = (VoltSHA1Ctx *)(digestCtx->localDigestCtx);
VoltLibCtx *libCtx = (VoltLibCtx *)(obj->voltObject.libraryCtx);
if (dataToDigest == (unsigned char *)0)
dataToDigestLen = 0;
/* Add the input length to the running total.
*/
sha1Ctx->countLow += dataToDigestLen;
if (sha1Ctx->countLow < dataToDigestLen)
sha1Ctx->countHigh++;
/* If we have any data in the currentBlock, start there.
*/
if (sha1Ctx->currentBlockLen != 0)
{
/* Copy bytes into the currentBlock. If there is enough to complete
* a block, copy enought to complete the block and then run
* SHA1Transform on it. If not, just copy the input into the block
* and update currentBlockLen.
*/
copyLen = dataToDigestLen;
if ((dataToDigestLen + sha1Ctx->currentBlockLen) >= 64)
copyLen = 64 - sha1Ctx->currentBlockLen;
Z2Memcpy (
sha1Ctx->currentBlock + sha1Ctx->currentBlockLen, dataToDigest,
copyLen);
sha1Ctx->currentBlockLen += copyLen;
/* If we don't have an entire block, we're done.
*/
if (sha1Ctx->currentBlockLen < 64)
return (0);
/* We have a block, process it.
*/
sha1Ctx->SHA1Transform ((Pointer)sha1Ctx, sha1Ctx->currentBlock);
dataToDigestLen -= copyLen;
dataToDigest += copyLen;
sha1Ctx->currentBlockLen = 0;
}
/* As long as there are complete blocks in the dataToDigest, call
* SHA1Transform on them.
*/
while (dataToDigestLen >= 64)
{
sha1Ctx->SHA1Transform ((Pointer)sha1Ctx, dataToDigest);
dataToDigestLen -= 64;
dataToDigest += 64;
}
/* If there is any data left over, copy it into the currentBlock. If
* not, we're done.
*/
if (dataToDigestLen == 0)
return (0);
Z2Memcpy (sha1Ctx->currentBlock, dataToDigest, dataToDigestLen);
sha1Ctx->currentBlockLen = dataToDigestLen;
return (0);
}
int SHA1Final (
VoltAlgorithmObject *obj,
unsigned char *digest
)
{
VoltLibCtx *libCtx = (VoltLibCtx *)(obj->voltObject.libraryCtx);
VoltDigestClassCtx *digestCtx = (VoltDigestClassCtx *)(obj->classCtx);
VoltSHA1Ctx *sha1Ctx = (VoltSHA1Ctx *)(digestCtx->localDigestCtx);
/* Perform padding.
* currentBlock | 0x80 | 0x00 00 ... 00 | length
* The length is 8 bytes, the length, in bits, of the input.
* If there is not enough space left in currentBlock to hold the 0x80
* byte and the 8 length bytes, finish up the current block with 0x80
* and 0x00 00 00 ... Then create a new block of all 00's except for
* the last 8 bytes, the length.
*/
Z2Memset (
sha1Ctx->currentBlock + sha1Ctx->currentBlockLen, 0,
64 - sha1Ctx->currentBlockLen);
if (sha1Ctx->padding == VT_SHA1_STD_PAD)
sha1Ctx->currentBlock[sha1Ctx->currentBlockLen] = 0x80;
if (sha1Ctx->currentBlockLen > 55)
{
sha1Ctx->SHA1Transform ((Pointer)sha1Ctx, sha1Ctx->currentBlock);
Z2Memset (sha1Ctx->currentBlock, 0, 64);
}
/* If padding following the SHA-1 standard (as opposed to FIPS 186),
* set the last 8 bytes to be the length. We added number of bytes,
* we want bits, so multiply by 8 (a left-shift by 3).
*/
if (sha1Ctx->padding == VT_SHA1_STD_PAD)
{
sha1Ctx->countHigh <<= 3;
sha1Ctx->countHigh |= (sha1Ctx->countLow >> 29);
sha1Ctx->countLow <<= 3;
sha1Ctx->currentBlock[56] = (unsigned char)(sha1Ctx->countHigh >> 24);
sha1Ctx->currentBlock[57] = (unsigned char)(sha1Ctx->countHigh >> 16);
sha1Ctx->currentBlock[58] = (unsigned char)(sha1Ctx->countHigh >> 8);
sha1Ctx->currentBlock[59] = (unsigned char)sha1Ctx->countHigh;
sha1Ctx->currentBlock[60] = (unsigned char)(sha1Ctx->countLow >> 24);
sha1Ctx->currentBlock[61] = (unsigned char)(sha1Ctx->countLow >> 16);
sha1Ctx->currentBlock[62] = (unsigned char)(sha1Ctx->countLow >> 8);
sha1Ctx->currentBlock[63] = (unsigned char)(sha1Ctx->countLow);
}
sha1Ctx->SHA1Transform ((Pointer)sha1Ctx, sha1Ctx->currentBlock);
/* The state is the digest.
*/
digest[0] = (unsigned char)(sha1Ctx->state[0] >> 24);
digest[1] = (unsigned char)(sha1Ctx->state[0] >> 16);
digest[2] = (unsigned char)(sha1Ctx->state[0] >> 8);
digest[3] = (unsigned char)(sha1Ctx->state[0]);
digest[4] = (unsigned char)(sha1Ctx->state[1] >> 24);
digest[5] = (unsigned char)(sha1Ctx->state[1] >> 16);
digest[6] = (unsigned char)(sha1Ctx->state[1] >> 8);
digest[7] = (unsigned char)(sha1Ctx->state[1]);
digest[8] = (unsigned char)(sha1Ctx->state[2] >> 24);
digest[9] = (unsigned char)(sha1Ctx->state[2] >> 16);
digest[10] = (unsigned char)(sha1Ctx->state[2] >> 8);
digest[11] = (unsigned char)(sha1Ctx->state[2]);
digest[12] = (unsigned char)(sha1Ctx->state[3] >> 24);
digest[13] = (unsigned char)(sha1Ctx->state[3] >> 16);
digest[14] = (unsigned char)(sha1Ctx->state[3] >> 8);
digest[15] = (unsigned char)(sha1Ctx->state[3]);
digest[16] = (unsigned char)(sha1Ctx->state[4] >> 24);
digest[17] = (unsigned char)(sha1Ctx->state[4] >> 16);
digest[18] = (unsigned char)(sha1Ctx->state[4] >> 8);
digest[19] = (unsigned char)(sha1Ctx->state[4]);
return (0);
}
void SHA1Transform (
Pointer ctx,
unsigned char *block
)
{
int index;
UInt32 *state = ((VoltSHA1Ctx *)ctx)->state;
UInt32 *W = ((VoltSHA1Ctx *)ctx)->W;
UInt32 A, B, C, D, E, temp;
A = state[0];
B = state[1];
C = state[2];
D = state[3];
E = state[4];
/* Get the block as 16 words.
*/
for (index = 0; index < 16; ++index, block += 4)
SHA1_GET_UINT32 (block, W[index])
/* Expand the block.
*/
for (index = 16; index < 80; ++index)
{
temp = W[index - 3] ^ W[index - 8] ^ W[index - 14] ^ W[index - 16];
W[index] = SHA1_ROTL (temp, 1);
}
/* The real work of SHA1Transform.
*/
/* Rounds 0 - 19
*/
for (index = 0; index < 20; ++index)
{
temp = SHA1_ROTL (A, 5) + F0 (B, C, D) + E + W[index] + SHA1_K0;
E = D;
D = C;
C = SHA1_ROTL (B, 30);
B = A;
A = temp;
}
/* Rounds 20 - 39
*/
for (index = 20; index < 40; ++index)
{
temp = SHA1_ROTL (A, 5) + F2 (B, C, D) + E + W[index] + SHA1_K2;
E = D;
D = C;
C = SHA1_ROTL (B, 30);
B = A;
A = temp;
}
/* Rounds 40 - 59
*/
for (index = 40; index < 60; ++index)
{
temp = SHA1_ROTL (A, 5) + F4 (B, C, D) + E + W[index] + SHA1_K4;
E = D;
D = C;
C = SHA1_ROTL (B, 30);
B = A;
A = temp;
}
/* Rounds 60 - 79
*/
for (index = 60; index < 80; ++index)
{
temp = SHA1_ROTL (A, 5) + F6 (B, C, D) + E + W[index] + SHA1_K6;
E = D;
D = C;
C = SHA1_ROTL (B, 30);
B = A;
A = temp;
}
/* Add the results of the rounds to the state.
*/
state[0] += A;
state[1] += B;
state[2] += C;
state[3] += D;
state[4] += E;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -