📄 sha256.c
字号:
memset (ULBlock, 0, sizeof (ULONG) << 4);
/* Padding to achieve block lengthe of 512 Bit */
/* by example of the message "abc" of length l = 24 bit: */
/* 1. One bit "1" is appended to the end of the masseage. */
/* 2. k "0"-bits are appended, with k the smallest non-negative */
/* solution of l+1+k = 448 mod 512, in this example k = 448-1-24 */
/* = 423, 7 bit following the single "1" plus additional */
/* 13 ULONGs (i.e. 416 bit) in the positions ULBlock[1]...[13]. */
/* 3. The length of the message is appended in 64 bit (2 ULONGs). */
/* Note: Opposite to MD4, MD5 and RIPEMD MSW is stored first and */
/* LSW is preceding MSW. */
/* */
/* 01100001 01100010 01100011 1 000...00 00...011000 */
/* "a" "b" "c" 1+ 423Bit 64 bit (length) */
/* Message length modulo 64 ULONG-blocks (512 bit) */
rest = total[0] & 0x3f;
/* Insert ULONGs into ULBlock */
for (i = 0; i < (rest >> 2); i++)
{
ULBlock[i] = UC2ULBE (clear);
clear += 4;
}
/* Remaining UCHARs go into ULBLock. Invariant: 0 <= i <= 15 */
for (j = i << 2, k = 3; j < rest; j++, k--)
{
ULBlock[i] |= (ULONG)*clear++ << (k << 3);
}
/* Append 0x80 to ULBlock: At least one byte is still free */
ULBlock[i] |= (ULONG)0x80 << (k << 3);
if (rest > 55) /* No space left for appending the message length (8 Byte), */
{ /* therefore store length into the following block */
sha1_swallow (stomach, ULBlock);
memset (ULBlock, 0, sizeof (ULONG) << 4);
}
/* Append message length in bit, MSW first, LSW preceding MSW */
ULBlock[14] = (total[0] >> 29) | (total[1] << 3);
ULBlock[15] = total[0] << 3;
sha1_swallow (stomach, ULBlock);
#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;
}
/******************************************************************************/
/* SHA-256 kernel functions */
/******************************************************************************/
static void
sha256_appetize (ULONG *stomach)
{
stomach[0] = 0x6a09e667UL;
stomach[1] = 0xbb67ae85UL;
stomach[2] = 0x3c6ef372UL;
stomach[3] = 0xa54ff53aUL;
stomach[4] = 0x510e527fUL;
stomach[5] = 0x9b05688cUL;
stomach[6] = 0x1f83d9abUL;
stomach[7] = 0x5be0cd19UL;
return;
}
static void
sha256_swallow (ULONG *stomach, ULONG *ULBlock)
{
ULONG WW[64];
int round;
ULONG T1, T2;
ULONG a = stomach[0];
ULONG b = stomach[1];
ULONG c = stomach[2];
ULONG d = stomach[3];
ULONG e = stomach[4];
ULONG f = stomach[5];
ULONG g = stomach[6];
ULONG h = stomach[7];
/*lint -e123 Don't complain about "Macros ... defined with arguments" */
for (round = 0; round < 16; round++)
{
WW[round] = *(ULBlock + round);
}
for (round = 16; round < 64; round++)
{
WW[round] = SIG256_1(WW[round - 2]) + WW[round - 7] +
SIG256_0(WW[round - 15]) + WW[round - 16];
}
for (round = 0; round < 64; round++)
{
T1 = h + SUM256_1(e) + Ch(e, f, g) + K256[round] + WW[round];
T2 = SUM256_0(a) + Maj(a, b, c);
h = g;
g = f;
f = e;
e = d + T1;
d = c;
c = b;
b = a;
a = T1 + T2;
}
/* Result in stomach */
stomach[0] += a;
stomach[1] += b;
stomach[2] += c;
stomach[3] += d;
stomach[4] += e;
stomach[5] += f;
stomach[6] += g;
stomach[7] += h;
#ifdef FLINT_SECURE
/* Overwrite temporary variables */
Zero4Ulong (&a, &b, &c, &d);
Zero4Ulong (&e, &f, &g, &h);
#endif
return;
}
static void
sha256_digest (ULONG *stomach, UCHAR *clear, ULONG total[])
{
ULONG i,j, k, rest;
ULONG ULBlock[16];
memset (ULBlock, 0, sizeof (ULONG) << 4);
/* Padding to achieve block lengthe of 512 Bit is exactly as in SHA-1 */
/* Message length modulo 64 ULONG-blocks (512 bit) */
rest = total[0] & 0x3f;
/* Insert ULONGs into ULBlock */
for (i = 0; i < (rest >> 2); i++)
{
ULBlock[i] = UC2ULBE (clear);
clear += 4;
}
/* Remaining UCHARs go into ULBLock. Invariant: 0 <= i <= 15 */
for (j = i << 2, k = 3; j < rest; j++, k--)
{
ULBlock[i] |= (ULONG)*clear++ << (k << 3);
}
/* Append 10000000 = 0x80 to ULBlock: At least one byte is still free */
ULBlock[i] |= (ULONG)0x80 << (k << 3);
if (rest > 55) /* No space left for appending the message length (8 Byte), */
{ /* therefore store length into the following block */
sha256_swallow (stomach, ULBlock);
memset (ULBlock, 0, sizeof (ULONG) << 4);
}
/* Append message length in bit, MSW first, LSW preceding MSW */
ULBlock[14] = (total[0] >> 29) | (total[1] << 3);
ULBlock[15] = total[0] << 3;
sha256_swallow (stomach, ULBlock);
#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;
}
#ifdef FLINT_SECURE
/******************************************************************************/
/* */
/* Function: Purging of variables */
/* Syntax: ZeroUlong (ULONG *a); */
/* Input: ULONG *a (Pointer to ULONG variable to be purged) */
/* Output: *a overwritten by 0 */
/* Returns: - */
/* */
/******************************************************************************/
static inline void
ZeroUlong (ULONG *a)
{
*a = 0;
}
/******************************************************************************/
/* */
/* Function: Purging of variables */
/* Syntax: Zero2Ulong (ULONG *a, ULONG *b); */
/* Input: ULONG *a (Pointer to ULONG variable to be purged) */
/* ULONG *b (Pointer to ULONG variable to be purged) */
/* Output: *a, *b overwritten by 0 */
/* Returns: - */
/* */
/******************************************************************************/
static inline void
Zero2Ulong (ULONG *a, ULONG *b)
{
*a = *b = 0;
}
/******************************************************************************/
/* */
/* Function: Purging of variables */
/* Syntax: Zero4Ulong (ULONG *a, ULONG *b, ULONG *c, ULONG *d); */
/* Input: ULONG *a (Pointer to ULONG variable to be purged) */
/* ULONG *b (Pointer to ULONG variable to be purged) */
/* ULONG *c (Pointer to ULONG variable to be purged) */
/* ULONG *d (Pointer to ULONG variable to be purged) */
/* Output: *a, *b, *c and *d overwritten by 0 */
/* Returns: - */
/* */
/******************************************************************************/
static inline void
Zero4Ulong (ULONG *a, ULONG *b, ULONG *c, ULONG *d)
{
*a = *b = *c = *d = 0;
}
/******************************************************************************/
/* */
/* Function: Purging of Array */
/* Syntax: ZeroUcharArray (UCHAR *a, int Len); */
/* Input: UCHAR *a (Pointer to array of UCHARs) */
/* int Len (Length of array in byte) */
/* Output: Array overwritten by 0 */
/* Returns: - */
/* */
/******************************************************************************/
static inline void
ZeroUcharArray (void *a, size_t Len)
{
memset ((UCHAR*)a, 0, Len);
}
#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -