00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047 #include <stdio.h>
00048 #include <stdlib.h>
00049 #include <fcntl.h>
00050 #include <string.h>
00051
00052 #ifndef MACOS
00053 # include <sys/stat.h>
00054 # include <sys/types.h>
00055 #endif
00056 #ifndef WIN32
00057 # include <unistd.h>
00058 # define INT64 long long
00059 #else
00060 # define snprintf _snprintf
00061 # define INT64 __int64
00062 #endif
00063
00064 #define switch_endianness(x) (x<<24 & 0xff000000) | \
00065 (x<<8 & 0x00ff0000) | \
00066 (x>>8 & 0x0000ff00) | \
00067 (x>>24 & 0x000000ff)
00068
00069
00070 #define Ai 0x67452301
00071 #define Bi 0xefcdab89
00072 #define Ci 0x98badcfe
00073 #define Di 0x10325476
00074 #define Ei 0xc3d2e1f0
00075
00076
00077 #define K1 0x5a827999
00078 #define K2 0x6ed9eba1
00079 #define K3 0x8f1bbcdc
00080 #define K4 0xca62c1d6
00081
00082
00083 #define f1(B,C,D) ((B & C) | ((~B) & D))
00084 #define f2(B,C,D) (B ^ C ^ D)
00085 #define f3(B,C,D) ((B & C) | (B & D) | (C & D))
00086
00087
00088 #define rol1(x) ((x<<1) | ((x>>31) & 1))
00089 #define rol5(A) ((A<<5) | ((A>>27) & 0x1f))
00090 #define rol30(B) ((B<<30) | ((B>>2) & 0x3fffffff))
00091
00092
00093
00094
00095
00096
00097 int
00098 sha_hash(int *data, int *hash)
00099 {
00100 int W[80];
00101 unsigned int A=hash[0], B=hash[1], C=hash[2], D=hash[3], E=hash[4];
00102 unsigned int t, x, TEMP;
00103
00104 for (t=0; t<16; t++)
00105 {
00106 #ifndef WORDS_BIGENDIAN
00107 W[t]=switch_endianness(data[t]);
00108 #else
00109 W[t]=data[t];
00110 #endif
00111 }
00112
00113
00114
00115 for (t=16; t<80; t++)
00116 {
00117 x=W[t-3] ^ W[t-8] ^ W[t-14] ^ W[t-16];
00118 W[t]=rol1(x);
00119 }
00120
00121
00122
00123
00124 for (t=0; t<20; t++)
00125 {
00126 TEMP=rol5(A) + f1(B,C,D) + E + W[t] + K1;
00127 E=D;
00128 D=C;
00129 C=rol30(B);
00130 B=A;
00131 A=TEMP;
00132 }
00133 for (; t<40; t++)
00134 {
00135 TEMP=rol5(A) + f2(B,C,D) + E + W[t] + K2;
00136 E=D;
00137 D=C;
00138 C=rol30(B);
00139 B=A;
00140 A=TEMP;
00141 }
00142 for (; t<60; t++)
00143 {
00144 TEMP=rol5(A) + f3(B,C,D) + E + W[t] + K3;
00145 E=D;
00146 D=C;
00147 C=rol30(B);
00148 B=A;
00149 A=TEMP;
00150 }
00151 for (; t<80; t++)
00152 {
00153 TEMP=rol5(A) + f2(B,C,D) + E + W[t] + K4;
00154 E=D;
00155 D=C;
00156 C=rol30(B);
00157 B=A;
00158 A=TEMP;
00159 }
00160 hash[0]+=A;
00161 hash[1]+=B;
00162 hash[2]+=C;
00163 hash[3]+=D;
00164 hash[4]+=E;
00165 return 0;
00166 }
00167
00168
00169
00170
00171
00172
00173 int
00174 sha_init(int *hash)
00175 {
00176 hash[0]=Ai;
00177 hash[1]=Bi;
00178 hash[2]=Ci;
00179 hash[3]=Di;
00180 hash[4]=Ei;
00181 return 0;
00182 }
00183
00184 int strprintsha(char *dest, int *hashval)
00185 {
00186 int x;
00187 char *hashstr = dest;
00188 for (x=0; x<5; x++)
00189 {
00190 snprintf(hashstr, 9, "%08x", hashval[x]);
00191 hashstr+=8;
00192 }
00193
00194
00195
00196 *hashstr = 0;
00197
00198 return 0;
00199 }
00200
00201 char *shahash(const char *str)
00202 {
00203 char read_buffer[65];
00204
00205 int c=1, i;
00206
00207 INT64 length=0;
00208
00209 int strsz;
00210 static char final[40];
00211 int *hashval;
00212
00213 hashval = (int *)malloc(20);
00214
00215 sha_init(hashval);
00216
00217 strsz = strlen(str);
00218
00219 if(strsz == 0)
00220 {
00221 memset(read_buffer, 0, 65);
00222 read_buffer[0] = 0x80;
00223 sha_hash((int *)read_buffer, hashval);
00224 }
00225
00226 while (strsz>0)
00227 {
00228 memset(read_buffer, 0, 65);
00229 strncpy((char*)read_buffer, str, 64);
00230 c = strlen((char *)read_buffer);
00231 length+=c;
00232 strsz-=c;
00233 if (strsz<=0)
00234 {
00235 length<<=3;
00236 read_buffer[c]=(char)0x80;
00237 for (i=c+1; i<64; i++)
00238 read_buffer[i]=0;
00239 if (c>55)
00240 {
00241
00242 sha_hash((int *)read_buffer, hashval);
00243 for (i=0; i<14; i++)
00244 ((int*)read_buffer)[i]=0;
00245 }
00246 #ifndef WORDS_BIGENDIAN
00247 for (i=0; i<8; i++)
00248 {
00249 read_buffer[56+i]=(char)(length>>(56-(i*8))) & 0xff;
00250 }
00251 #else
00252 memcpy(read_buffer+56, &length, 8);
00253 #endif
00254 }
00255
00256 sha_hash((int *)read_buffer, hashval);
00257 str+=64;
00258 }
00259
00260 strprintsha((char *)final, hashval);
00261 free(hashval);
00262 return (char *)final;
00263 }