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