📄 sha256.c
字号:
/* */
/******************************************************************************/
void __FLINT_API
sha1finish_l (UCHAR *HashRes, SHASTAT *hws, UCHAR *clear, ULONG length)
{
unsigned i;
/* Number of bytes in complete blocks */
ULONG blength = (length >> 6) << 6;
/* Process complete blocks in clear */
sha1hash_l (hws, clear, blength);
/* Add length of message in clear to hws->total */
ADDC (hws->total,length - blength);
/* Process last incomplete block with padding and length of message */
sha1_digest (hws->stomach, clear + blength, hws->total);
/* Note: Hash result is stored in Big-Endian representation. */
for (i = 0; i < 20; i += 4)
{
*(HashRes+i) = (UCHAR)(hws->stomach[i>>2] >> 24); /*lint !e661 !e662 */
*(HashRes+i+1) = (UCHAR)(hws->stomach[i>>2] >> 16); /*lint !e661 !e662 */
*(HashRes+i+2) = (UCHAR)(hws->stomach[i>>2] >> 8); /*lint !e661 !e662 */
*(HashRes+i+3) = (UCHAR)(hws->stomach[i>>2] );
}
return;
}
/*****************************************************************************/
/* SHA-256 API */
/*****************************************************************************/
/******************************************************************************/
/* */
/* Function: Hashing of a message of length byte in a single step */
/* Syntax: void sha1_l (UCHAR *HashRes, UCHAR *clear, ULONG length); */
/* Input: UCHAR *clear (Pointer to message block) */
/* ULONG length (Length of message block) */
/* Output: UCHAR *HashRes (Hash Value) */
/* Returns: - */
/* */
/******************************************************************************/
void __FLINT_API
sha256_l (UCHAR *HashRes, UCHAR *clear, ULONG length)
{
SHA256STAT hws;
sha256init_l (&hws);
sha256finish_l (HashRes, &hws, clear, length);
#ifdef FLINT_SECURE
ZeroUcharArray (&hws, sizeof (hws));
#endif
}
/******************************************************************************/
/* Functions for blockwise hashing a message in several steps */
/* Procedure: Initialization with sha256init_l */
/* Hashing of block1,block2,...,blockn with function sha256hash_l */
/* Finish operation with function sha256finish_l */
/******************************************************************************/
/******************************************************************************/
/* */
/* Function: Initialization of SHA-256 function */
/* Syntax: void sha256init_l (SHASTAT *hws); */
/* Input: SHA256STAT *hws (SHA-256 status buffer) */
/* Output: - */
/* Returns: - */
/* */
/******************************************************************************/
void __FLINT_API
sha256init_l (SHA256STAT *hws)
{
sha256_appetize (hws->stomach);
hws->total[0] = 0;
hws->total[1] = 0;
}
/******************************************************************************/
/* */
/* Function: Hashing of a message block */
/* Syntax: int sha256hash_1 (SHA256STAT *hws, UCHAR *clear, */
/* ULONG length); */
/* Input: SHA256STAT *hws (SHA-256 status buffer) */
/* UCHAR *clear (Pointer to message block) */
/* ULONG length (Length of message block i bytes = 0 mod 64) */
/* Output: - */
/* Returns: E_CLINT_OK if everything is O.K. */
/* E_CLINT_SHA if length != 0 mod 64 */
/* */
/******************************************************************************/
int __FLINT_API
sha256hash_l (SHA256STAT *hws, UCHAR *clear, ULONG length)
{
ULONG ULBlock[16]; /* message block holding 16 values of type ULONG */
ULONG noofblocks; /* Number of blocks of 16 ULONG-vyluse */
ULONG i, j; /* Counter */
/* If incomplete 64 byte block exists... */
if (length & 63)
{
return E_CLINT_SHA; /* ...return error code */
}
/* Number of 64 byte message blocks in clear */
noofblocks = length >> 6;
/* Process 64 byte message blocks in clear */
for (i = 0; i < noofblocks; i++)
{
for (j = 0; j < 16; j++)
{
ULBlock[j] = UC2ULBE (clear);
clear += 4;
}
sha256_swallow (hws->stomach, ULBlock);
}
/* Verarbeite 64-Byte-Bloecke von clear */
ADDC (hws->total, length);
#ifdef FLINT_SECURE
/* Overwrite temporary variables */
Zero4Ulong (&ULBlock[0], &ULBlock[1], &ULBlock[2], &ULBlock[3]);
Zero4Ulong (&ULBlock[4], &ULBlock[5], &ULBlock[6], &ULBlock[7]);
Zero4Ulong (&ULBlock[8], &ULBlock[9], &ULBlock[10], &ULBlock[11]);
Zero4Ulong (&ULBlock[12], &ULBlock[13], &ULBlock[14], &ULBlock[15]);
#endif
return 0;
}
/******************************************************************************/
/* */
/* Function: Finish hash function SHA-256 */
/* Syntax: void sha256finish_l (UCHAR *HashRes, SHA256STAT *hws, */
/* UCHAR *clear, ULONG length); */
/* Input: SHA256STAT *hws (SHA-256 status buffer) */
/* UCHAR *clear (Pointer to the last message block */
/* ULONG length (Length of message block in bytes) */
/* Output: UCHAR HashRes (Hash value) */
/* Returns: - */
/* */
/******************************************************************************/
void __FLINT_API
sha256finish_l (UCHAR *HashRes, SHA256STAT *hws, UCHAR *clear, ULONG length)
{
unsigned i;
/* Number of bytes in complete blocks */
ULONG blength = (length >> 6) << 6;
/* Process complete blocks in clear */
sha256hash_l (hws, clear, blength);
/* Add length of message in clear to hws->total */
ADDC (hws->total,length - blength);
/* Process last incomplete block with padding and length of message */
sha256_digest (hws->stomach, clear + blength, hws->total);
/* Note: Hash result is stored in Big-Endian representation. */
for (i = 0; i < 32; i += 4)
{
*(HashRes+i) = (UCHAR)(hws->stomach[i>>2] >> 24); /*lint !e661 !e662 */
*(HashRes+i+1) = (UCHAR)(hws->stomach[i>>2] >> 16); /*lint !e661 !e662 */
*(HashRes+i+2) = (UCHAR)(hws->stomach[i>>2] >> 8); /*lint !e661 !e662 */
*(HashRes+i+3) = (UCHAR)(hws->stomach[i>>2] );
}
return;
}
/******************************************************************************/
/* SHA-1 kernel functions */
/******************************************************************************/
static void
sha1_appetize (ULONG *stomach)
{
stomach[0] = 0x67452301UL;
stomach[1] = 0xefcdab89UL;
stomach[2] = 0x98badcfeUL;
stomach[3] = 0x10325476UL;
stomach[4] = 0xc3d2e1f0UL;
return;
}
static void
sha1_swallow (ULONG *stomach, ULONG *ULBlock)
{
int round;
ULONG x;
ULONG a = stomach[0];
ULONG b = stomach[1];
ULONG c = stomach[2];
ULONG d = stomach[3];
ULONG e = stomach[4];
/*lint -e123 Don't complain about "Macros ... defined with arguments" */
for (round = 0; round < 16; round++)
{
x = ROL((a), 5) + (d^(b&(c^d))) + e + ULBlock[round] + 0x5A827999L;
CHAIN (a, b, c, d, e, x);
}
for (round = 16; round < 20; round++)
{
x = ROL((a), 5) + (d^(b&(c^d))) + e + XPND(ULBlock, round) + 0x5A827999L;
CHAIN (a, b, c, d, e, x);
}
for (round = 20; round < 40; round++)
{
x = ROL((a), 5) + (b^c^d) + e + XPND(ULBlock, round) + 0x6ED9EBA1L;
CHAIN (a, b, c, d, e, x);
}
for (round = 40; round < 60; round++)
{
x = ROL((a), 5) + ((b&c)|(d&(b|c))) + e + XPND(ULBlock, round) + 0x8F1BBCDCL;
CHAIN (a, b, c, d, e, x);
}
for (round = 60; round < 80; round++)
{
x = ROL((a), 5) + (b^c^d) + e + XPND(ULBlock, round) + 0xCA62C1D6L;
CHAIN (a, b, c, d, e, x);
}
/* Result in stomach */
stomach[0] += a;
stomach[1] += b;
stomach[2] += c;
stomach[3] += d;
stomach[4] += e;
#ifdef FLINT_SECURE
/* Overwrite temporary variables */
Zero4Ulong (&a, &b, &c, &d);
ZeroUlong (&e);
#endif
return;
}
static void
sha1_digest (ULONG *stomach, UCHAR *clear, ULONG total[])
{
ULONG i,j, k, rest;
ULONG ULBlock[16];
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -