📄 sha512impl.c
字号:
/* Copyright 2005-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 "sha512.h"
#include "errorctx.h"
int SHA512SetDigestInitState (
VoltAlgorithmObject *obj,
VtItem *newState
)
{
int status, index;
UInt64 current;
unsigned char *buffer;
VoltDigestClassCtx *digestCtx = (VoltDigestClassCtx *)(obj->classCtx);
VoltSHA512Ctx *sha512Ctx = (VoltSHA512Ctx *)(digestCtx->localDigestCtx);
VOLT_DECLARE_FNCT_LINE (fnctLine)
do
{
/* Make sure we have a new state and the length is correct.
*/
VOLT_SET_FNCT_LINE (fnctLine)
status = VT_ERROR_INVALID_ASSOCIATED_INFO;
if ( (newState->data == (unsigned char *)0) || (newState->len != 64) )
break;
buffer = newState->data;
for (index = 0; index < 8; ++index)
{
/* Get the next four bytes of the state as an int.
*/
current =
((UInt64)(buffer[0]) << 56) +
((UInt64)(buffer[1]) << 48) +
((UInt64)(buffer[2]) << 40) +
((UInt64)(buffer[3]) << 32) +
((UInt64)(buffer[4]) << 24) +
((UInt64)(buffer[5]) << 16) +
((UInt64)(buffer[6]) << 8) +
((UInt64)(buffer[7]));
sha512Ctx->initState[index] = current;
buffer += 8;
}
status = 0;
} while (0);
VOLT_LOG_ERROR_INFO_COMPARE (
status, 0, obj, status, 0, VT_ERROR_TYPE_PRIMARY,
(char *)0, "SHA512SetDigestInitState", fnctLine, (char *)0)
return (status);
}
int SHA512Init (
VoltAlgorithmObject *obj
)
{
VoltDigestClassCtx *digestCtx = (VoltDigestClassCtx *)(obj->classCtx);
VoltSHA512Ctx *sha512Ctx = (VoltSHA512Ctx *)(digestCtx->localDigestCtx);
/* Populate the SHA-512 Ctx with the initial values.
*/
sha512Ctx->countLow = 0;
sha512Ctx->countHigh = 0;
sha512Ctx->currentBlockLen = 0;
sha512Ctx->state[0] = sha512Ctx->initState[0];
sha512Ctx->state[1] = sha512Ctx->initState[1];
sha512Ctx->state[2] = sha512Ctx->initState[2];
sha512Ctx->state[3] = sha512Ctx->initState[3];
sha512Ctx->state[4] = sha512Ctx->initState[4];
sha512Ctx->state[5] = sha512Ctx->initState[5];
sha512Ctx->state[6] = sha512Ctx->initState[6];
sha512Ctx->state[7] = sha512Ctx->initState[7];
return (0);
}
int SHA512Update (
VoltAlgorithmObject *obj,
unsigned char *dataToDigest,
unsigned int dataToDigestLen
)
{
unsigned int copyLen;
VoltDigestClassCtx *digestCtx = (VoltDigestClassCtx *)(obj->classCtx);
VoltSHA512Ctx *sha512Ctx = (VoltSHA512Ctx *)(digestCtx->localDigestCtx);
VoltLibCtx *libCtx = (VoltLibCtx *)(obj->voltObject.libraryCtx);
if (dataToDigest == (unsigned char *)0)
dataToDigestLen = 0;
/* Add the input length to the running total.
*/
sha512Ctx->countLow += dataToDigestLen;
if (sha512Ctx->countLow < dataToDigestLen)
sha512Ctx->countHigh++;
/* If we have any data in the currentBlock, start there.
*/
if (sha512Ctx->currentBlockLen != 0)
{
/* Copy bytes into the currentBlock. If there is enough to complete
* a block, copy enought to complete the block and then run
* SHA512Transform on it. If not, just copy the input into the block
* and update currentBlockLen.
*/
copyLen = dataToDigestLen;
if ((dataToDigestLen + sha512Ctx->currentBlockLen) >= 128)
copyLen = 128 - sha512Ctx->currentBlockLen;
Z2Memcpy (
sha512Ctx->currentBlock + sha512Ctx->currentBlockLen, dataToDigest,
copyLen);
sha512Ctx->currentBlockLen += copyLen;
/* If we don't have an entire block, we're done.
*/
if (sha512Ctx->currentBlockLen < 128)
return (0);
/* We have a block, process it.
*/
sha512Ctx->SHA512Transform ((Pointer)sha512Ctx, sha512Ctx->currentBlock);
dataToDigestLen -= copyLen;
dataToDigest += copyLen;
sha512Ctx->currentBlockLen = 0;
}
/* As long as there are complete blocks in the dataToDigest, call
* SHA512Transform on them.
*/
while (dataToDigestLen >= 128)
{
sha512Ctx->SHA512Transform ((Pointer)sha512Ctx, dataToDigest);
dataToDigestLen -= 128;
dataToDigest += 128;
}
/* If there is any data left over, copy it into the currentBlock. If
* not, we're done.
*/
if (dataToDigestLen == 0)
return (0);
Z2Memcpy (sha512Ctx->currentBlock, dataToDigest, dataToDigestLen);
sha512Ctx->currentBlockLen = dataToDigestLen;
return (0);
}
int SHA512Final (
VoltAlgorithmObject *obj,
unsigned char *digest
)
{
int indexD, indexS, shiftCount;
UInt64 currentValue;
VoltLibCtx *libCtx = (VoltLibCtx *)(obj->voltObject.libraryCtx);
VoltDigestClassCtx *digestCtx = (VoltDigestClassCtx *)(obj->classCtx);
VoltSHA512Ctx *sha512Ctx = (VoltSHA512Ctx *)(digestCtx->localDigestCtx);
/* Perform padding.
* currentBlock | 0x80 | 0x00 00 ... 00 | length
* The length is 16 bytes, the length, in bits, of the input.
* If there is not enough space left in currentBlock to hold the 0x80
* byte and the 16 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 16 bytes, the length.
*/
Z2Memset (
sha512Ctx->currentBlock + sha512Ctx->currentBlockLen, 0,
128 - sha512Ctx->currentBlockLen);
sha512Ctx->currentBlock[sha512Ctx->currentBlockLen] = 0x80;
if (sha512Ctx->currentBlockLen > 111)
{
sha512Ctx->SHA512Transform ((Pointer)sha512Ctx, sha512Ctx->currentBlock);
Z2Memset (sha512Ctx->currentBlock, 0, 128);
}
/* Set the last 16 bytes to be the length. We added number of bytes,
* we want bits, so multiply by 8 (a left-shift by 3).
*/
sha512Ctx->countHigh <<= 3;
sha512Ctx->countHigh |= (sha512Ctx->countLow >> 61);
sha512Ctx->countLow <<= 3;
sha512Ctx->currentBlock[112] = (unsigned char)(sha512Ctx->countHigh >> 56);
sha512Ctx->currentBlock[113] = (unsigned char)(sha512Ctx->countHigh >> 48);
sha512Ctx->currentBlock[114] = (unsigned char)(sha512Ctx->countHigh >> 40);
sha512Ctx->currentBlock[115] = (unsigned char)(sha512Ctx->countHigh >> 32);
sha512Ctx->currentBlock[116] = (unsigned char)(sha512Ctx->countHigh >> 24);
sha512Ctx->currentBlock[117] = (unsigned char)(sha512Ctx->countHigh >> 16);
sha512Ctx->currentBlock[118] = (unsigned char)(sha512Ctx->countHigh >> 8);
sha512Ctx->currentBlock[119] = (unsigned char)(sha512Ctx->countHigh);
sha512Ctx->currentBlock[120] = (unsigned char)(sha512Ctx->countLow >> 56);
sha512Ctx->currentBlock[121] = (unsigned char)(sha512Ctx->countLow >> 48);
sha512Ctx->currentBlock[122] = (unsigned char)(sha512Ctx->countLow >> 40);
sha512Ctx->currentBlock[123] = (unsigned char)(sha512Ctx->countLow >> 32);
sha512Ctx->currentBlock[124] = (unsigned char)(sha512Ctx->countLow >> 24);
sha512Ctx->currentBlock[125] = (unsigned char)(sha512Ctx->countLow >> 16);
sha512Ctx->currentBlock[126] = (unsigned char)(sha512Ctx->countLow >> 8);
sha512Ctx->currentBlock[127] = (unsigned char)(sha512Ctx->countLow);
sha512Ctx->SHA512Transform ((Pointer)sha512Ctx, sha512Ctx->currentBlock);
/* The state is the digest.
*/
for (indexS = 0; indexS < 8; ++indexS)
{
currentValue = sha512Ctx->state[indexS];
for (indexD = 0, shiftCount = 56; indexD < 8; ++indexD, shiftCount -= 8)
digest[indexD] = (unsigned char)(currentValue >> shiftCount);
digest += 8;
}
return (0);
}
void SHA512Transform (
Pointer ctx,
unsigned char *block
)
{
int index;
UInt64 *state = ((VoltSHA512Ctx *)ctx)->state;
UInt64 *W = ((VoltSHA512Ctx *)ctx)->W;
UInt64 *K = ((VoltSHA512Ctx *)ctx)->K;
UInt64 A, B, C, D, E, F, G, H, T1, T2;
/* Initialize the working variables.
*/
A = state[0];
B = state[1];
C = state[2];
D = state[3];
E = state[4];
F = state[5];
G = state[6];
H = state[7];
/* Get the block as 16 words.
*/
for (index = 0; index < 16; ++index, block += 8)
{
SHA512_GET_UINT64 (block, W[index])
}
/* Expand the block.
*/
for (index = 16; index < 80; ++index)
{
T1 = SHA512_SIGMA_1 (W[index - 2]);
T2 = SHA512_SIGMA_0 (W[index - 15]);
W[index] = T1 + W[index - 7] + T2 + W[index - 16];
}
/* Adjust the working variables 80 times.
*/
for (index = 0; index < 80; ++index)
{
T1 =
H + SHA512_CAP_SIGMA_1 (E) + SHA512_CH (E, F, G) + K[index] + W[index];
T2 = SHA512_CAP_SIGMA_0 (A) + SHA512_MAJ (A, B, C);
H = G;
G = F;
F = E;
E = D + T1;
D = C;
C = B;
B = A;
A = T1 + T2;
}
state[0] += A;
state[1] += B;
state[2] += C;
state[3] += D;
state[4] += E;
state[5] += F;
state[6] += G;
state[7] += H;
return;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -