00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021 #include "sha1hash.h"
00022
00023 const SecureHashBase::Parameters SHA1Hash::par=
00024 {
00025 INIT_FIELD(hash_size) 20,
00026 INIT_FIELD(block_size) 64,
00027 INIT_FIELD(hash_ID) 0x1001,
00028 INIT_FIELD(name) "SHA1"
00029 };
00030
00031
00032 static inline uint32 sha_func0(uint32 x,uint32 y,uint32 z)
00033
00034 { return(z ^ (x & (y ^ z))); }
00035
00036 static inline uint32 sha_func1(uint32 x,uint32 y,uint32 z)
00037 { return(x ^ y ^ z); }
00038
00039 static inline uint32 sha_func2(uint32 x,uint32 y,uint32 z)
00040
00041 { return((x & y) | (z & (x | y))); }
00042
00043 static inline uint32 sha_func3(uint32 x,uint32 y,uint32 z)
00044 { return(x ^ y ^ z); }
00045
00046 static inline uint32 rotate(uint32 x,int n)
00047 { return((x<<n) | (x>>(32-n))); }
00048
00049
00050
00051 static const uint32 sha_const0 = 0x5a827999U;
00052 static const uint32 sha_const1 = 0x6ed9eba1U;
00053 static const uint32 sha_const2 = 0x8f1bbcdcU;
00054 static const uint32 sha_const3 = 0xca62c1d6U;
00055
00056 static const uint32 sha_init_state[5]=
00057 { 0x67452301U, 0xefcdab89U, 0x98badcfeU, 0x10325476U, 0xc3d2e1f0U };
00058
00059
00060
00061 #define EXPAND(pa,pb,pc,pd) \
00062 rotate(*(pa++) ^ *(pb++) ^ *(pc++) ^ *(pd++),1)
00063
00064
00065
00066
00067 void SHA1Hash::AtomicHash(const unsigned char *msg,uint32 *w)
00068 {
00069 register uint32 *p;
00070 uint32 *we=&w[16];
00071
00072
00073 for(p=w; p<we; p++)
00074 {
00075
00076
00077
00078 *p= uint32(*(msg++)); *p<<=8;
00079 *p|=uint32(*(msg++)); *p<<=8;
00080 *p|=uint32(*(msg++)); *p<<=8;
00081 *p|=uint32(*(msg++));
00082 }
00083
00084 uint32 *p_03=p-3;
00085 uint32 *p_08=p-8;
00086 uint32 *p_14=p-14;
00087 uint32 *p_16=p-16;
00088 we=&w[20];
00089 while(p<we)
00090 { *(p++) = EXPAND(p_03,p_08,p_14,p_16); }
00091
00092
00093 uint32 a=state[0], b=state[1], c=state[2], d=state[3], e=state[4];
00094 uint32 tmp,sha_const=sha_const0;
00095 for(p=w; p<we; p++)
00096 {
00097 tmp = rotate(a,5) + sha_func0(b,c,d) + e + (*p) + sha_const;
00098 e=d; d=c;
00099 c=rotate(b,30);
00100 b=a; a=tmp;
00101 }
00102 sha_const=sha_const1;
00103 for(we+=20; p<we; p++)
00104 {
00105 *p = EXPAND(p_03,p_08,p_14,p_16);
00106 tmp = rotate(a,5) + sha_func1(b,c,d) + e + (*p) + sha_const;
00107 e=d; d=c;
00108 c=rotate(b,30);
00109 b=a; a=tmp;
00110 }
00111 sha_const=sha_const2;
00112 for(we+=20; p<we; p++)
00113 {
00114 *p = EXPAND(p_03,p_08,p_14,p_16);
00115 tmp = rotate(a,5) + sha_func2(b,c,d) + e + (*p) + sha_const;
00116 e=d; d=c;
00117 c=rotate(b,30);
00118 b=a; a=tmp;
00119 }
00120 sha_const=sha_const3;
00121 for(we+=20; p<we; p++)
00122 {
00123 *p = EXPAND(p_03,p_08,p_14,p_16);
00124 tmp = rotate(a,5) + sha_func3(b,c,d) + e + (*p) + sha_const;
00125 e=d; d=c;
00126 c=rotate(b,30);
00127 b=a; a=tmp;
00128 }
00129
00130
00131 state[0]+=a;
00132 state[1]+=b;
00133 state[2]+=c;
00134 state[3]+=d;
00135 state[4]+=e;
00136 }
00137
00138
00139 void SHA1Hash::GetHash(char *buf) const
00140 {
00141 register unsigned char *hsh=(unsigned char*)buf+3;
00142 for(register const uint32 *i=state,*ie=&state[5]; i<ie; i++)
00143 {
00144 register uint32 j=*i;
00145 *(hsh--)=(unsigned char)(j & 0xffU); j>>=8;
00146 *(hsh--)=(unsigned char)(j & 0xffU); j>>=8;
00147 *(hsh--)=(unsigned char)(j & 0xffU); j>>=8;
00148 *(hsh )=(unsigned char)(j & 0xffU);
00149 hsh+=7;
00150 }
00151 }
00152
00153
00154 void SHA1Hash::reset()
00155 {
00156 length=0LLU;
00157 state[0]=sha_init_state[0];
00158 state[1]=sha_init_state[1];
00159 state[2]=sha_init_state[2];
00160 state[3]=sha_init_state[3];
00161 state[4]=sha_init_state[4];
00162 tmp_size=0;
00163 for(unsigned char *d=tmpbuf,*de=d+64; d<de; d++)
00164 { *d=(unsigned char)0; }
00165 }
00166
00167
00168 void SHA1Hash::feed(const char *_buf,size_t len)
00169 {
00170 if(!len)
00171 { return; }
00172
00173 const unsigned char *buf=(const unsigned char*)_buf;
00174 uint32 w[80];
00175
00176 if(tmp_size)
00177 {
00178 size_t needed=64-tmp_size;
00179 if(len>=needed)
00180 {
00181 for(unsigned char *d=&tmpbuf[tmp_size],*de=&tmpbuf[64]; d<de; d++)
00182 { *d=*(buf++); }
00183 AtomicHash(tmpbuf,w);
00184 len-=needed;
00185 tmp_size=0;
00186 length+=64LLU;
00187 if(!len)
00188 { return; }
00189 }
00190 else
00191 {
00192 unsigned char *d=&tmpbuf[tmp_size];
00193 tmp_size+=int(len);
00194 for(unsigned char *de=&tmpbuf[tmp_size]; d<de; d++)
00195 { *d=*(buf++); }
00196 return;
00197 }
00198 }
00199
00200 size_t l=len;
00201 for(;;)
00202 {
00203 if(l<64)
00204 { break; }
00205 AtomicHash((const unsigned char*)buf,w);
00206 buf+=64;
00207 l-=64;
00208 }
00209 length+=uint64(len-l);
00210 if(l)
00211 {
00212 for(unsigned char *d=tmpbuf,*de=d+l; d<de; d++)
00213 { *d=*(buf++); }
00214 tmp_size=int(l);
00215 }
00216 }
00217
00218
00219 void SHA1Hash::final()
00220 {
00221 uint32 w[80];
00222 int pad80=0;
00223
00224
00225
00226
00227 length+=uint64(tmp_size);
00228 if(tmp_size>=56)
00229 {
00230 unsigned char *d=&tmpbuf[tmp_size];
00231 *(d++)=(unsigned char)0x80;
00232 for(unsigned char *de=&tmpbuf[64]; d<de; d++)
00233 { *d=(unsigned char)0; }
00234 AtomicHash(tmpbuf,w);
00235 tmp_size=0;
00236 ++pad80;
00237 }
00238
00239
00240 uint64 len=length*8LLU;
00241
00242
00243
00244 unsigned char *d=&tmpbuf[tmp_size];
00245 if(!pad80)
00246 { *(d++)=(unsigned char)0x80; }
00247 for(unsigned char *de=&tmpbuf[56]; d<de; d++)
00248 { *d=(unsigned char)0; }
00249
00250
00251 uint32 word = uint32(len >> 32);
00252 d+=3;
00253 *(d--)=(unsigned char)(word & 0xffU); word>>=8;
00254 *(d--)=(unsigned char)(word & 0xffU); word>>=8;
00255 *(d--)=(unsigned char)(word & 0xffU); word>>=8;
00256 *(d )=(unsigned char)(word & 0xffU);
00257
00258
00259 word = uint32(len & 0xffffffffLLU);
00260 d+=7;
00261 *(d--)=(unsigned char)(word & 0xffU); word>>=8;
00262 *(d--)=(unsigned char)(word & 0xffU); word>>=8;
00263 *(d--)=(unsigned char)(word & 0xffU); word>>=8;
00264 *(d )=(unsigned char)(word & 0xffU);
00265
00266 AtomicHash(tmpbuf,w);
00267 tmp_size=0;
00268 }