mirror of
https://github.com/Xevion/easy7zip.git
synced 2025-12-06 03:14:59 -06:00
21.02
This commit is contained in:
633
C/Sha1.c
633
C/Sha1.c
@@ -1,5 +1,5 @@
|
||||
/* Sha1.c -- SHA-1 Hash
|
||||
2017-04-03 : Igor Pavlov : Public domain
|
||||
2021-04-01 : Igor Pavlov : Public domain
|
||||
This code is based on public domain code of Steve Reid from Wei Dai's Crypto++ library. */
|
||||
|
||||
#include "Precomp.h"
|
||||
@@ -10,331 +10,434 @@ This code is based on public domain code of Steve Reid from Wei Dai's Crypto++ l
|
||||
#include "RotateDefs.h"
|
||||
#include "Sha1.h"
|
||||
|
||||
// define it for speed optimization
|
||||
#if defined(_MSC_VER) && (_MSC_VER < 1900)
|
||||
// #define USE_MY_MM
|
||||
#endif
|
||||
|
||||
#ifdef MY_CPU_X86_OR_AMD64
|
||||
#ifdef _MSC_VER
|
||||
#if _MSC_VER >= 1200
|
||||
#define _SHA_SUPPORTED
|
||||
#endif
|
||||
#elif defined(__clang__)
|
||||
#if (__clang_major__ >= 8) // fix that check
|
||||
#define _SHA_SUPPORTED
|
||||
#endif
|
||||
#elif defined(__GNUC__)
|
||||
#if (__GNUC__ >= 8) // fix that check
|
||||
#define _SHA_SUPPORTED
|
||||
#endif
|
||||
#elif defined(__INTEL_COMPILER)
|
||||
#if (__INTEL_COMPILER >= 1800) // fix that check
|
||||
#define _SHA_SUPPORTED
|
||||
#endif
|
||||
#endif
|
||||
#elif defined(MY_CPU_ARM_OR_ARM64)
|
||||
#ifdef _MSC_VER
|
||||
#if _MSC_VER >= 1910
|
||||
#define _SHA_SUPPORTED
|
||||
#endif
|
||||
#elif defined(__clang__)
|
||||
#if (__clang_major__ >= 8) // fix that check
|
||||
#define _SHA_SUPPORTED
|
||||
#endif
|
||||
#elif defined(__GNUC__)
|
||||
#if (__GNUC__ >= 6) // fix that check
|
||||
#define _SHA_SUPPORTED
|
||||
#endif
|
||||
#endif
|
||||
#endif
|
||||
|
||||
void MY_FAST_CALL Sha1_UpdateBlocks(UInt32 state[5], const Byte *data, size_t numBlocks);
|
||||
|
||||
#ifdef _SHA_SUPPORTED
|
||||
void MY_FAST_CALL Sha1_UpdateBlocks_HW(UInt32 state[5], const Byte *data, size_t numBlocks);
|
||||
|
||||
static SHA1_FUNC_UPDATE_BLOCKS g_FUNC_UPDATE_BLOCKS = Sha1_UpdateBlocks;
|
||||
static SHA1_FUNC_UPDATE_BLOCKS g_FUNC_UPDATE_BLOCKS_HW;
|
||||
|
||||
#define UPDATE_BLOCKS(p) p->func_UpdateBlocks
|
||||
#else
|
||||
#define UPDATE_BLOCKS(p) Sha1_UpdateBlocks
|
||||
#endif
|
||||
|
||||
|
||||
BoolInt Sha1_SetFunction(CSha1 *p, unsigned algo)
|
||||
{
|
||||
SHA1_FUNC_UPDATE_BLOCKS func = Sha1_UpdateBlocks;
|
||||
|
||||
#ifdef _SHA_SUPPORTED
|
||||
if (algo != SHA1_ALGO_SW)
|
||||
{
|
||||
if (algo == SHA1_ALGO_DEFAULT)
|
||||
func = g_FUNC_UPDATE_BLOCKS;
|
||||
else
|
||||
{
|
||||
if (algo != SHA1_ALGO_HW)
|
||||
return False;
|
||||
func = g_FUNC_UPDATE_BLOCKS_HW;
|
||||
if (!func)
|
||||
return False;
|
||||
}
|
||||
}
|
||||
#else
|
||||
if (algo > 1)
|
||||
return False;
|
||||
#endif
|
||||
|
||||
p->func_UpdateBlocks = func;
|
||||
return True;
|
||||
}
|
||||
|
||||
|
||||
/* define it for speed optimization */
|
||||
// #define _SHA1_UNROLL
|
||||
|
||||
// allowed unroll steps: (1, 2, 4, 5, 20)
|
||||
|
||||
#ifdef _SHA1_UNROLL
|
||||
#define kNumW 16
|
||||
#define WW(i) W[(i)&15]
|
||||
#define STEP_PRE 20
|
||||
#define STEP_MAIN 20
|
||||
#else
|
||||
#define _SHA1_BIG_W
|
||||
#define STEP_PRE 5
|
||||
#define STEP_MAIN 5
|
||||
#endif
|
||||
|
||||
|
||||
#ifdef _SHA1_BIG_W
|
||||
#define kNumW 80
|
||||
#define WW(i) W[i]
|
||||
#define w(i) W[i]
|
||||
#else
|
||||
#define kNumW 16
|
||||
#define w(i) W[(i)&15]
|
||||
#endif
|
||||
|
||||
#define w0(i) (W[i] = data[i])
|
||||
#define w0(i) (W[i] = GetBe32(data + (size_t)(i) * 4))
|
||||
#define w1(i) (w(i) = rotlFixed(w((size_t)(i)-3) ^ w((size_t)(i)-8) ^ w((size_t)(i)-14) ^ w((size_t)(i)-16), 1))
|
||||
|
||||
#define w1(i) (WW(i) = rotlFixed(WW((i)-3) ^ WW((i)-8) ^ WW((i)-14) ^ WW((i)-16), 1))
|
||||
#define f0(x,y,z) ( 0x5a827999 + (z^(x&(y^z))) )
|
||||
#define f1(x,y,z) ( 0x6ed9eba1 + (x^y^z) )
|
||||
#define f2(x,y,z) ( 0x8f1bbcdc + ((x&y)|(z&(x|y))) )
|
||||
#define f3(x,y,z) ( 0xca62c1d6 + (x^y^z) )
|
||||
|
||||
#define f1(x,y,z) (z^(x&(y^z)))
|
||||
#define f2(x,y,z) (x^y^z)
|
||||
#define f3(x,y,z) ((x&y)|(z&(x|y)))
|
||||
#define f4(x,y,z) (x^y^z)
|
||||
/*
|
||||
#define T1(fx, ww) \
|
||||
tmp = e + fx(b,c,d) + ww + rotlFixed(a, 5); \
|
||||
e = d; \
|
||||
d = c; \
|
||||
c = rotlFixed(b, 30); \
|
||||
b = a; \
|
||||
a = tmp; \
|
||||
*/
|
||||
|
||||
#define RK(a,b,c,d,e, fx, w, k) e += fx(b,c,d) + w + k + rotlFixed(a,5); b = rotlFixed(b,30);
|
||||
#define T5(a,b,c,d,e, fx, ww) \
|
||||
e += fx(b,c,d) + ww + rotlFixed(a, 5); \
|
||||
b = rotlFixed(b, 30); \
|
||||
|
||||
#define R0(a,b,c,d,e, i) RK(a,b,c,d,e, f1, w0(i), 0x5A827999)
|
||||
#define R1(a,b,c,d,e, i) RK(a,b,c,d,e, f1, w1(i), 0x5A827999)
|
||||
#define R2(a,b,c,d,e, i) RK(a,b,c,d,e, f2, w1(i), 0x6ED9EBA1)
|
||||
#define R3(a,b,c,d,e, i) RK(a,b,c,d,e, f3, w1(i), 0x8F1BBCDC)
|
||||
#define R4(a,b,c,d,e, i) RK(a,b,c,d,e, f4, w1(i), 0xCA62C1D6)
|
||||
|
||||
#define RX_1_4(rx1, rx4, i) \
|
||||
rx1(a,b,c,d,e, i); \
|
||||
rx4(e,a,b,c,d, i+1); \
|
||||
rx4(d,e,a,b,c, i+2); \
|
||||
rx4(c,d,e,a,b, i+3); \
|
||||
rx4(b,c,d,e,a, i+4); \
|
||||
/*
|
||||
#define R1(i, fx, wx) \
|
||||
T1 ( fx, wx(i)); \
|
||||
|
||||
#define RX_5(rx, i) RX_1_4(rx, rx, i);
|
||||
#define R2(i, fx, wx) \
|
||||
R1 ( (i) , fx, wx); \
|
||||
R1 ( (i) + 1, fx, wx); \
|
||||
|
||||
#ifdef _SHA1_UNROLL
|
||||
#define R4(i, fx, wx) \
|
||||
R2 ( (i) , fx, wx); \
|
||||
R2 ( (i) + 2, fx, wx); \
|
||||
*/
|
||||
|
||||
#define RX_15 \
|
||||
RX_5(R0, 0); \
|
||||
RX_5(R0, 5); \
|
||||
RX_5(R0, 10);
|
||||
#define M5(i, fx, wx0, wx1) \
|
||||
T5 ( a,b,c,d,e, fx, wx0((i) ) ); \
|
||||
T5 ( e,a,b,c,d, fx, wx1((i)+1) ); \
|
||||
T5 ( d,e,a,b,c, fx, wx1((i)+2) ); \
|
||||
T5 ( c,d,e,a,b, fx, wx1((i)+3) ); \
|
||||
T5 ( b,c,d,e,a, fx, wx1((i)+4) ); \
|
||||
|
||||
#define R5(i, fx, wx) \
|
||||
M5 ( i, fx, wx, wx) \
|
||||
|
||||
|
||||
#if STEP_PRE > 5
|
||||
|
||||
#define R20_START \
|
||||
R5 ( 0, f0, w0); \
|
||||
R5 ( 5, f0, w0); \
|
||||
R5 ( 10, f0, w0); \
|
||||
M5 ( 15, f0, w0, w1); \
|
||||
|
||||
#define RX_20(rx, i) \
|
||||
RX_5(rx, i); \
|
||||
RX_5(rx, i + 5); \
|
||||
RX_5(rx, i + 10); \
|
||||
RX_5(rx, i + 15);
|
||||
#elif STEP_PRE == 5
|
||||
|
||||
#define R20_START \
|
||||
{ size_t i; for (i = 0; i < 15; i += STEP_PRE) \
|
||||
{ R5(i, f0, w0); } } \
|
||||
M5 ( 15, f0, w0, w1); \
|
||||
|
||||
#else
|
||||
|
||||
#define RX_15 { size_t i; for (i = 0; i < 15; i += 5) { RX_5(R0, i); } }
|
||||
#define RX_20(rx, ii) { size_t i; i = ii; for (; i < ii + 20; i += 5) { RX_5(rx, i); } }
|
||||
|
||||
#if STEP_PRE == 1
|
||||
#define R_PRE R1
|
||||
#elif STEP_PRE == 2
|
||||
#define R_PRE R2
|
||||
#elif STEP_PRE == 4
|
||||
#define R_PRE R4
|
||||
#endif
|
||||
|
||||
#define R20_START \
|
||||
{ size_t i; for (i = 0; i < 16; i += STEP_PRE) \
|
||||
{ R_PRE(i, f0, w0); } } \
|
||||
R4 ( 16, f0, w1); \
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
void Sha1_Init(CSha1 *p)
|
||||
|
||||
#if STEP_MAIN > 5
|
||||
|
||||
#define R20(ii, fx) \
|
||||
R5 ( (ii) , fx, w1); \
|
||||
R5 ( (ii) + 5 , fx, w1); \
|
||||
R5 ( (ii) + 10, fx, w1); \
|
||||
R5 ( (ii) + 15, fx, w1); \
|
||||
|
||||
#else
|
||||
|
||||
#if STEP_MAIN == 1
|
||||
#define R_MAIN R1
|
||||
#elif STEP_MAIN == 2
|
||||
#define R_MAIN R2
|
||||
#elif STEP_MAIN == 4
|
||||
#define R_MAIN R4
|
||||
#elif STEP_MAIN == 5
|
||||
#define R_MAIN R5
|
||||
#endif
|
||||
|
||||
#define R20(ii, fx) \
|
||||
{ size_t i; for (i = (ii); i < (ii) + 20; i += STEP_MAIN) \
|
||||
{ R_MAIN(i, fx, w1); } } \
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
void Sha1_InitState(CSha1 *p)
|
||||
{
|
||||
p->count = 0;
|
||||
p->state[0] = 0x67452301;
|
||||
p->state[1] = 0xEFCDAB89;
|
||||
p->state[2] = 0x98BADCFE;
|
||||
p->state[3] = 0x10325476;
|
||||
p->state[4] = 0xC3D2E1F0;
|
||||
p->count = 0;
|
||||
}
|
||||
|
||||
void Sha1_GetBlockDigest(CSha1 *p, const UInt32 *data, UInt32 *destDigest)
|
||||
void Sha1_Init(CSha1 *p)
|
||||
{
|
||||
p->func_UpdateBlocks =
|
||||
#ifdef _SHA_SUPPORTED
|
||||
g_FUNC_UPDATE_BLOCKS;
|
||||
#else
|
||||
NULL;
|
||||
#endif
|
||||
Sha1_InitState(p);
|
||||
}
|
||||
|
||||
|
||||
MY_NO_INLINE
|
||||
void MY_FAST_CALL Sha1_UpdateBlocks(UInt32 state[5], const Byte *data, size_t numBlocks)
|
||||
{
|
||||
UInt32 a, b, c, d, e;
|
||||
UInt32 W[kNumW];
|
||||
// if (numBlocks != 0x1264378347) return;
|
||||
if (numBlocks == 0)
|
||||
return;
|
||||
|
||||
a = p->state[0];
|
||||
b = p->state[1];
|
||||
c = p->state[2];
|
||||
d = p->state[3];
|
||||
e = p->state[4];
|
||||
|
||||
RX_15
|
||||
a = state[0];
|
||||
b = state[1];
|
||||
c = state[2];
|
||||
d = state[3];
|
||||
e = state[4];
|
||||
|
||||
RX_1_4(R0, R1, 15);
|
||||
|
||||
RX_20(R2, 20);
|
||||
RX_20(R3, 40);
|
||||
RX_20(R4, 60);
|
||||
|
||||
destDigest[0] = p->state[0] + a;
|
||||
destDigest[1] = p->state[1] + b;
|
||||
destDigest[2] = p->state[2] + c;
|
||||
destDigest[3] = p->state[3] + d;
|
||||
destDigest[4] = p->state[4] + e;
|
||||
}
|
||||
|
||||
void Sha1_UpdateBlock_Rar(CSha1 *p, UInt32 *data, int returnRes)
|
||||
{
|
||||
UInt32 a, b, c, d, e;
|
||||
UInt32 W[kNumW];
|
||||
|
||||
a = p->state[0];
|
||||
b = p->state[1];
|
||||
c = p->state[2];
|
||||
d = p->state[3];
|
||||
e = p->state[4];
|
||||
|
||||
RX_15
|
||||
|
||||
RX_1_4(R0, R1, 15);
|
||||
|
||||
RX_20(R2, 20);
|
||||
RX_20(R3, 40);
|
||||
RX_20(R4, 60);
|
||||
|
||||
p->state[0] += a;
|
||||
p->state[1] += b;
|
||||
p->state[2] += c;
|
||||
p->state[3] += d;
|
||||
p->state[4] += e;
|
||||
|
||||
if (returnRes)
|
||||
do
|
||||
{
|
||||
size_t i;
|
||||
for (i = 0 ; i < SHA1_NUM_BLOCK_WORDS; i++)
|
||||
data[i] = W[kNumW - SHA1_NUM_BLOCK_WORDS + i];
|
||||
#if STEP_PRE < 5 || STEP_MAIN < 5
|
||||
UInt32 tmp;
|
||||
#endif
|
||||
|
||||
R20_START
|
||||
R20(20, f1);
|
||||
R20(40, f2);
|
||||
R20(60, f3);
|
||||
|
||||
a += state[0];
|
||||
b += state[1];
|
||||
c += state[2];
|
||||
d += state[3];
|
||||
e += state[4];
|
||||
|
||||
state[0] = a;
|
||||
state[1] = b;
|
||||
state[2] = c;
|
||||
state[3] = d;
|
||||
state[4] = e;
|
||||
|
||||
data += 64;
|
||||
}
|
||||
while (--numBlocks);
|
||||
}
|
||||
|
||||
#define Sha1_UpdateBlock(p) Sha1_GetBlockDigest(p, p->buffer, p->state)
|
||||
|
||||
#define Sha1_UpdateBlock(p) UPDATE_BLOCKS(p)(p->state, p->buffer, 1)
|
||||
|
||||
void Sha1_Update(CSha1 *p, const Byte *data, size_t size)
|
||||
{
|
||||
unsigned pos, pos2;
|
||||
if (size == 0)
|
||||
return;
|
||||
pos = (unsigned)p->count & 0x3F;
|
||||
p->count += size;
|
||||
pos2 = pos & 3;
|
||||
pos >>= 2;
|
||||
|
||||
if (pos2 != 0)
|
||||
|
||||
{
|
||||
UInt32 w;
|
||||
pos2 = (3 - pos2) * 8;
|
||||
w = ((UInt32)*data++) << pos2;
|
||||
if (--size && pos2)
|
||||
{
|
||||
pos2 -= 8;
|
||||
w |= ((UInt32)*data++) << pos2;
|
||||
if (--size && pos2)
|
||||
{
|
||||
pos2 -= 8;
|
||||
w |= ((UInt32)*data++) << pos2;
|
||||
size--;
|
||||
}
|
||||
}
|
||||
p->buffer[pos] |= w;
|
||||
if (pos2 == 0)
|
||||
pos++;
|
||||
}
|
||||
|
||||
for (;;)
|
||||
{
|
||||
if (pos == SHA1_NUM_BLOCK_WORDS)
|
||||
{
|
||||
for (;;)
|
||||
{
|
||||
size_t i;
|
||||
Sha1_UpdateBlock(p);
|
||||
if (size < SHA1_BLOCK_SIZE)
|
||||
break;
|
||||
size -= SHA1_BLOCK_SIZE;
|
||||
for (i = 0; i < SHA1_NUM_BLOCK_WORDS; i += 2)
|
||||
{
|
||||
p->buffer[i ] = GetBe32(data);
|
||||
p->buffer[i + 1] = GetBe32(data + 4);
|
||||
data += 8;
|
||||
}
|
||||
}
|
||||
pos = 0;
|
||||
}
|
||||
if (size < 4)
|
||||
break;
|
||||
|
||||
p->buffer[pos] = GetBe32(data);
|
||||
data += 4;
|
||||
size -= 4;
|
||||
pos++;
|
||||
}
|
||||
|
||||
if (size != 0)
|
||||
{
|
||||
UInt32 w = ((UInt32)data[0]) << 24;
|
||||
if (size > 1)
|
||||
{
|
||||
w |= ((UInt32)data[1]) << 16;
|
||||
if (size > 2)
|
||||
w |= ((UInt32)data[2]) << 8;
|
||||
}
|
||||
p->buffer[pos] = w;
|
||||
}
|
||||
}
|
||||
|
||||
void Sha1_Update_Rar(CSha1 *p, Byte *data, size_t size /* , int rar350Mode */)
|
||||
{
|
||||
int returnRes = False;
|
||||
|
||||
unsigned pos = (unsigned)p->count & 0x3F;
|
||||
p->count += size;
|
||||
|
||||
while (size--)
|
||||
{
|
||||
unsigned pos2 = (pos & 3);
|
||||
UInt32 v = ((UInt32)*data++) << (8 * (3 - pos2));
|
||||
UInt32 *ref = &(p->buffer[pos >> 2]);
|
||||
pos++;
|
||||
if (pos2 == 0)
|
||||
{
|
||||
*ref = v;
|
||||
continue;
|
||||
}
|
||||
*ref |= v;
|
||||
unsigned pos = (unsigned)p->count & 0x3F;
|
||||
unsigned num;
|
||||
|
||||
if (pos == SHA1_BLOCK_SIZE)
|
||||
p->count += size;
|
||||
|
||||
num = 64 - pos;
|
||||
if (num > size)
|
||||
{
|
||||
pos = 0;
|
||||
Sha1_UpdateBlock_Rar(p, p->buffer, returnRes);
|
||||
if (returnRes)
|
||||
{
|
||||
size_t i;
|
||||
for (i = 0; i < SHA1_NUM_BLOCK_WORDS; i++)
|
||||
{
|
||||
UInt32 d = p->buffer[i];
|
||||
Byte *prev = data + i * 4 - SHA1_BLOCK_SIZE;
|
||||
SetUi32(prev, d);
|
||||
}
|
||||
}
|
||||
// returnRes = rar350Mode;
|
||||
returnRes = True;
|
||||
memcpy(p->buffer + pos, data, size);
|
||||
return;
|
||||
}
|
||||
|
||||
if (pos != 0)
|
||||
{
|
||||
size -= num;
|
||||
memcpy(p->buffer + pos, data, num);
|
||||
data += num;
|
||||
Sha1_UpdateBlock(p);
|
||||
}
|
||||
}
|
||||
{
|
||||
size_t numBlocks = size >> 6;
|
||||
UPDATE_BLOCKS(p)(p->state, data, numBlocks);
|
||||
size &= 0x3F;
|
||||
if (size == 0)
|
||||
return;
|
||||
data += (numBlocks << 6);
|
||||
memcpy(p->buffer, data, size);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void Sha1_Final(CSha1 *p, Byte *digest)
|
||||
{
|
||||
unsigned pos = (unsigned)p->count & 0x3F;
|
||||
unsigned pos2 = (pos & 3);
|
||||
UInt64 numBits;
|
||||
UInt32 w;
|
||||
unsigned i;
|
||||
|
||||
pos >>= 2;
|
||||
|
||||
w = 0;
|
||||
if (pos2 != 0)
|
||||
w = p->buffer[pos];
|
||||
p->buffer[pos++] = w | (((UInt32)0x80000000) >> (8 * pos2));
|
||||
|
||||
while (pos != (SHA1_NUM_BLOCK_WORDS - 2))
|
||||
p->buffer[pos++] = 0x80;
|
||||
|
||||
if (pos > (64 - 8))
|
||||
{
|
||||
pos &= 0xF;
|
||||
if (pos == 0)
|
||||
Sha1_UpdateBlock(p);
|
||||
p->buffer[pos++] = 0;
|
||||
while (pos != 64) { p->buffer[pos++] = 0; }
|
||||
// memset(&p->buf.buffer[pos], 0, 64 - pos);
|
||||
Sha1_UpdateBlock(p);
|
||||
pos = 0;
|
||||
}
|
||||
|
||||
/*
|
||||
if (pos & 3)
|
||||
{
|
||||
p->buffer[pos] = 0;
|
||||
p->buffer[pos + 1] = 0;
|
||||
p->buffer[pos + 2] = 0;
|
||||
pos += 3;
|
||||
pos &= ~3;
|
||||
}
|
||||
{
|
||||
for (; pos < 64 - 8; pos += 4)
|
||||
*(UInt32 *)(&p->buffer[pos]) = 0;
|
||||
}
|
||||
*/
|
||||
|
||||
memset(&p->buffer[pos], 0, (64 - 8) - pos);
|
||||
|
||||
{
|
||||
UInt64 numBits = (p->count << 3);
|
||||
SetBe32(p->buffer + 64 - 8, (UInt32)(numBits >> 32));
|
||||
SetBe32(p->buffer + 64 - 4, (UInt32)(numBits));
|
||||
}
|
||||
|
||||
numBits = (p->count << 3);
|
||||
p->buffer[SHA1_NUM_BLOCK_WORDS - 2] = (UInt32)(numBits >> 32);
|
||||
p->buffer[SHA1_NUM_BLOCK_WORDS - 1] = (UInt32)(numBits);
|
||||
Sha1_UpdateBlock(p);
|
||||
|
||||
for (i = 0; i < SHA1_NUM_DIGEST_WORDS; i++)
|
||||
{
|
||||
UInt32 v = p->state[i];
|
||||
SetBe32(digest, v);
|
||||
digest += 4;
|
||||
}
|
||||
|
||||
Sha1_Init(p);
|
||||
}
|
||||
|
||||
|
||||
void Sha1_32_PrepareBlock(const CSha1 *p, UInt32 *block, unsigned size)
|
||||
{
|
||||
const UInt64 numBits = (p->count + size) << 5;
|
||||
block[SHA1_NUM_BLOCK_WORDS - 2] = (UInt32)(numBits >> 32);
|
||||
block[SHA1_NUM_BLOCK_WORDS - 1] = (UInt32)(numBits);
|
||||
block[size++] = 0x80000000;
|
||||
while (size != (SHA1_NUM_BLOCK_WORDS - 2))
|
||||
block[size++] = 0;
|
||||
}
|
||||
|
||||
void Sha1_32_Update(CSha1 *p, const UInt32 *data, size_t size)
|
||||
{
|
||||
unsigned pos = (unsigned)p->count & 0xF;
|
||||
p->count += size;
|
||||
while (size--)
|
||||
{
|
||||
p->buffer[pos++] = *data++;
|
||||
if (pos == SHA1_NUM_BLOCK_WORDS)
|
||||
{
|
||||
pos = 0;
|
||||
Sha1_UpdateBlock(p);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Sha1_32_Final(CSha1 *p, UInt32 *digest)
|
||||
{
|
||||
UInt64 numBits;
|
||||
unsigned pos = (unsigned)p->count & 0xF;
|
||||
p->buffer[pos++] = 0x80000000;
|
||||
|
||||
while (pos != (SHA1_NUM_BLOCK_WORDS - 2))
|
||||
{
|
||||
pos &= 0xF;
|
||||
if (pos == 0)
|
||||
Sha1_UpdateBlock(p);
|
||||
p->buffer[pos++] = 0;
|
||||
}
|
||||
SetBe32(digest, p->state[0]);
|
||||
SetBe32(digest + 4, p->state[1]);
|
||||
SetBe32(digest + 8, p->state[2]);
|
||||
SetBe32(digest + 12, p->state[3]);
|
||||
SetBe32(digest + 16, p->state[4]);
|
||||
|
||||
numBits = (p->count << 5);
|
||||
p->buffer[SHA1_NUM_BLOCK_WORDS - 2] = (UInt32)(numBits >> 32);
|
||||
p->buffer[SHA1_NUM_BLOCK_WORDS - 1] = (UInt32)(numBits);
|
||||
|
||||
Sha1_GetBlockDigest(p, p->buffer, digest);
|
||||
|
||||
Sha1_Init(p);
|
||||
|
||||
|
||||
Sha1_InitState(p);
|
||||
}
|
||||
|
||||
|
||||
void Sha1_PrepareBlock(const CSha1 *p, Byte *block, unsigned size)
|
||||
{
|
||||
const UInt64 numBits = (p->count + size) << 3;
|
||||
SetBe32(&((UInt32 *)(void *)block)[SHA1_NUM_BLOCK_WORDS - 2], (UInt32)(numBits >> 32));
|
||||
SetBe32(&((UInt32 *)(void *)block)[SHA1_NUM_BLOCK_WORDS - 1], (UInt32)(numBits));
|
||||
// SetBe32((UInt32 *)(block + size), 0x80000000);
|
||||
SetUi32((UInt32 *)(void *)(block + size), 0x80);
|
||||
size += 4;
|
||||
while (size != (SHA1_NUM_BLOCK_WORDS - 2) * 4)
|
||||
{
|
||||
*((UInt32 *)(void *)(block + size)) = 0;
|
||||
size += 4;
|
||||
}
|
||||
}
|
||||
|
||||
void Sha1_GetBlockDigest(const CSha1 *p, const Byte *data, Byte *destDigest)
|
||||
{
|
||||
MY_ALIGN (16)
|
||||
UInt32 st[SHA1_NUM_DIGEST_WORDS];
|
||||
|
||||
st[0] = p->state[0];
|
||||
st[1] = p->state[1];
|
||||
st[2] = p->state[2];
|
||||
st[3] = p->state[3];
|
||||
st[4] = p->state[4];
|
||||
|
||||
UPDATE_BLOCKS(p)(st, data, 1);
|
||||
|
||||
SetBe32(destDigest + 0 , st[0]);
|
||||
SetBe32(destDigest + 1 * 4, st[1]);
|
||||
SetBe32(destDigest + 2 * 4, st[2]);
|
||||
SetBe32(destDigest + 3 * 4, st[3]);
|
||||
SetBe32(destDigest + 4 * 4, st[4]);
|
||||
}
|
||||
|
||||
|
||||
void Sha1Prepare()
|
||||
{
|
||||
#ifdef _SHA_SUPPORTED
|
||||
SHA1_FUNC_UPDATE_BLOCKS f, f_hw;
|
||||
f = Sha1_UpdateBlocks;
|
||||
f_hw = NULL;
|
||||
#ifdef MY_CPU_X86_OR_AMD64
|
||||
#ifndef USE_MY_MM
|
||||
if (CPU_IsSupported_SHA()
|
||||
&& CPU_IsSupported_SSSE3()
|
||||
// && CPU_IsSupported_SSE41()
|
||||
)
|
||||
#endif
|
||||
#else
|
||||
if (CPU_IsSupported_SHA1())
|
||||
#endif
|
||||
{
|
||||
// printf("\n========== HW SHA1 ======== \n");
|
||||
f = f_hw = Sha1_UpdateBlocks_HW;
|
||||
}
|
||||
g_FUNC_UPDATE_BLOCKS = f;
|
||||
g_FUNC_UPDATE_BLOCKS_HW = f_hw;
|
||||
#endif
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user