00001 #include "copyright.h"
00002 #include "autoconf.h"
00003 #include "config.h"
00004 #include "externs.h"
00005 #include "sha1.h"
00006
00007 void SHA1_Init(SHA1_CONTEXT *p)
00008 {
00009 p->H[0] = 0x67452301;
00010 p->H[1] = 0xEFCDAB89;
00011 p->H[2] = 0x98BADCFE;
00012 p->H[3] = 0x10325476;
00013 p->H[4] = 0xC3D2E1F0;
00014 p->nTotal = 0;
00015 p->nblock = 0;
00016 }
00017
00018 #ifdef WIN32
00019 #define ROTL(d,n) _lrotl(d,n)
00020 #else // WIN32
00021 #define ROTL(d,n) (((d) << (n)) | ((d) >> (32-(n))))
00022 #endif // WIN32
00023
00024 #define Ch(x,y,z) (((x) & (y)) ^ (~(x) & (z)))
00025 #define Parity(x,y,z) ((x) ^ (y) ^ (z))
00026 #define Maj(x,y,z) (((x) & (y)) ^ ((x) & (z)) ^ ((y) & (z)))
00027
00028 static void SHA1_HashBlock(SHA1_CONTEXT *p)
00029 {
00030 int t;
00031 UINT32 W[80];
00032
00033
00034
00035 int j;
00036 for (t = 0, j = 0; t <= 15; t++, j += 4)
00037 {
00038 W[t] = (p->block[j ] << 24)
00039 | (p->block[j+1] << 16)
00040 | (p->block[j+2] << 8)
00041 | (p->block[j+3] );
00042 }
00043 for (t = 16; t <= 79; t++)
00044 {
00045 W[t] = ROTL(W[t-3] ^ W[t-8] ^ W[t-14] ^ W[t-16], 1);
00046 }
00047
00048 UINT32 a = p->H[0];
00049 UINT32 b = p->H[1];
00050 UINT32 c = p->H[2];
00051 UINT32 d = p->H[3];
00052 UINT32 e = p->H[4];
00053
00054 UINT32 T;
00055 for (t = 0; t <= 19; t++)
00056 {
00057 T = ROTL(a,5) + Ch(b,c,d) + e + 0x5A827999 + W[t];
00058 e = d;
00059 d = c;
00060 c = ROTL(b,30);
00061 b = a;
00062 a = T;
00063 }
00064 for (t = 20; t <= 39; t++)
00065 {
00066 T = ROTL(a,5) + Parity(b,c,d) + e + 0x6ED9EBA1 + W[t];
00067 e = d;
00068 d = c;
00069 c = ROTL(b,30);
00070 b = a;
00071 a = T;
00072 }
00073 for (t = 40; t <= 59; t++)
00074 {
00075 T = ROTL(a,5) + Maj(b,c,d) + e + 0x8F1BBCDC + W[t];
00076 e = d;
00077 d = c;
00078 c = ROTL(b,30);
00079 b = a;
00080 a = T;
00081 }
00082 for (t = 60; t <= 79; t++)
00083 {
00084 T = ROTL(a,5) + Parity(b,c,d) + e + 0xCA62C1D6 + W[t];
00085 e = d;
00086 d = c;
00087 c = ROTL(b,30);
00088 b = a;
00089 a = T;
00090 }
00091
00092 p->H[0] += a;
00093 p->H[1] += b;
00094 p->H[2] += c;
00095 p->H[3] += d;
00096 p->H[4] += e;
00097 }
00098
00099 void SHA1_Compute(SHA1_CONTEXT *p, size_t n, const char *buf)
00100 {
00101 while (n)
00102 {
00103 size_t m = sizeof(p->block) - p->nblock;
00104 if (n < m)
00105 {
00106 m = n;
00107 }
00108 memcpy(p->block + p->nblock, buf, m);
00109 buf += m;
00110 n -= m;
00111 p->nblock += m;
00112 p->nTotal += m;
00113
00114 if (p->nblock == sizeof(p->block))
00115 {
00116 SHA1_HashBlock(p);
00117 p->nblock = 0;
00118 }
00119 }
00120 }
00121
00122 void SHA1_Final(SHA1_CONTEXT *p)
00123 {
00124 p->block[p->nblock++] = 0x80;
00125 if (sizeof(p->block) - sizeof(UINT64) <= p->nblock)
00126 {
00127 memset(p->block + p->nblock, 0, sizeof(p->block) - p->nblock);
00128 SHA1_HashBlock(p);
00129 memset(p->block, 0, sizeof(p->block) - sizeof(UINT64));
00130 }
00131 else
00132 {
00133 memset(p->block + p->nblock, 0, sizeof(p->block) - p->nblock - sizeof(UINT64));
00134 }
00135 p->nTotal *= 8;
00136
00137 p->block[sizeof(p->block) - 8] = (UINT8)(p->nTotal >> 56) & 0xFF;
00138 p->block[sizeof(p->block) - 7] = (UINT8)(p->nTotal >> 48) & 0xFF;
00139 p->block[sizeof(p->block) - 6] = (UINT8)(p->nTotal >> 40) & 0xFF;
00140 p->block[sizeof(p->block) - 5] = (UINT8)(p->nTotal >> 32) & 0xFF;
00141 p->block[sizeof(p->block) - 4] = (UINT8)(p->nTotal >> 24) & 0xFF;
00142 p->block[sizeof(p->block) - 3] = (UINT8)(p->nTotal >> 16) & 0xFF;
00143 p->block[sizeof(p->block) - 2] = (UINT8)(p->nTotal >> 8) & 0xFF;
00144 p->block[sizeof(p->block) - 1] = (UINT8)(p->nTotal ) & 0xFF;
00145 SHA1_HashBlock(p);
00146 }
00147
00148 #if 0
00149
00150
00151 #define TEST_STRING "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq"
00152 int main(int argc, char *argv[])
00153 {
00154 char buffer[] = TEST_STRING;
00155
00156 SHA1_CONTEXT shac;
00157 SHA1_Init(&shac);
00158 SHA1_Compute(&shac, strlen(TEST_STRING), buffer);
00159 SHA1_Final(&shac);
00160
00161 int i;
00162 for (i = 0; i < 5; i++)
00163 {
00164 printf("%08X", shac.H[i]);
00165 }
00166 return 1;
00167 }
00168
00169 #endif