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 #include "SHA1.H"
00037 #include <OpenFOAM/IOstreams.H>
00038 
00039 #include <cstring>
00040 
00041 #if defined (__GLIBC__)
00042 #  include <endian.h>
00043 #endif
00044 
00045 
00046 
00047 
00049 
00050 
00051 static const unsigned char fillbuf[64] = { 0x80, 0  };
00053 
00054 
00055 
00056 
00057 inline uint32_t Foam::SHA1::swapBytes(uint32_t n)
00058 {
00059 #ifdef __BYTE_ORDER
00060 # if (__BYTE_ORDER == __BIG_ENDIAN)
00061     return n;
00062 # else
00063     return (((n) << 24) | (((n) & 0xff00) << 8) | (((n) >> 8) & 0xff00) | ((n) >> 24));
00064 # endif
00065 
00066 #else
00067 
00068     const short x = 0x0100;
00069 
00070     
00071     if (*(reinterpret_cast<const char *>(&x)))
00072     {
00073         return n;
00074     }
00075     else
00076     {
00077         return (((n) << 24) | (((n) & 0xff00) << 8) | (((n) >> 8) & 0xff00) | ((n) >> 24));
00078     }
00079 #endif
00080 }
00081 
00082 
00083 inline void
00084 Foam::SHA1::set_uint32(unsigned char *cp, uint32_t v)
00085 {
00086     memcpy(cp, &v, sizeof(uint32_t));
00087 }
00088 
00089 
00090 
00091 
00092 
00093 void Foam::SHA1::processBytes(const void *data, size_t len)
00094 {
00095     
00096     if (finalized_)
00097     {
00098         clear();
00099     }
00100 
00101     
00102     if (bufLen_)
00103     {
00104         size_t remaining = bufLen_;
00105         size_t add =
00106         (
00107             sizeof(buffer_) - remaining > len
00108           ? len
00109           : sizeof(buffer_) - remaining
00110         );
00111 
00112         unsigned char* bufp = reinterpret_cast<unsigned char*>(buffer_);
00113 
00114         memcpy(&bufp[remaining], data, add);
00115         bufLen_ += add;
00116 
00117         if (bufLen_ > 64)
00118         {
00119             processBlock(buffer_, bufLen_ & ~63);
00120 
00121             bufLen_ &= 63;
00122             
00123             memcpy(buffer_, &bufp[(remaining + add) & ~63], bufLen_);
00124         }
00125 
00126         data = reinterpret_cast<const unsigned char*>(data) + add;
00127         len -= add;
00128     }
00129 
00130     
00131 
00132 
00133 
00134 
00135 
00136 
00137 
00138             while (len >= 64)
00139             {
00140                 processBlock(memcpy (buffer_, data, 64), 64);
00141                 data = reinterpret_cast<const unsigned char*>(data) + 64;
00142                 len -= 64;
00143             }
00144 
00145 
00146 
00147 
00148 
00149 
00150 
00151 
00152 
00153 
00154     
00155     if (len > 0)
00156     {
00157         unsigned char* bufp = reinterpret_cast<unsigned char*>(buffer_);
00158         size_t remaining = bufLen_;
00159 
00160         memcpy (&bufp[remaining], data, len);
00161         remaining += len;
00162         if (remaining >= 64)
00163         {
00164             processBlock(buffer_, 64);
00165             remaining -= 64;
00166             memcpy (buffer_, &buffer_[16], remaining);
00167         }
00168         bufLen_ = remaining;
00169     }
00170 }
00171 
00172 
00173 
00174 #define K1 0x5a827999
00175 #define K2 0x6ed9eba1
00176 #define K3 0x8f1bbcdc
00177 #define K4 0xca62c1d6
00178 
00179 
00180 #define F1(B,C,D) ( D ^ ( B & ( C ^ D ) ) )
00181 #define F2(B,C,D) (B ^ C ^ D)
00182 #define F3(B,C,D) ( ( B & C ) | ( D & ( B | C ) ) )
00183 #define F4(B,C,D) (B ^ C ^ D)
00184 
00185 
00186 
00187 
00188 void
00189 Foam::SHA1::processBlock(const void *data, size_t len)
00190 {
00191     const uint32_t *words = reinterpret_cast<const uint32_t*>(data);
00192     size_t nwords = len / sizeof(uint32_t);
00193     const uint32_t *endp = words + nwords;
00194 
00195     
00196     uint32_t x[16];
00197     uint32_t a = hashsumA_;
00198     uint32_t b = hashsumB_;
00199     uint32_t c = hashsumC_;
00200     uint32_t d = hashsumD_;
00201     uint32_t e = hashsumE_;
00202 
00203     
00204     
00205     
00206     bufTotal_[0] += len;
00207     if (bufTotal_[0] < len)
00208     {
00209         ++bufTotal_[1];
00210     }
00211 
00212     
00213 #define rol_uint32(x, nbits)  (((x) << (nbits)) | ((x) >> (32 - (nbits))))
00214 
00215 #define M(I) ( tm = x[I & 0x0F] ^ x[(I-14) & 0x0F]                            \
00216                ^ x[(I-8) & 0x0F] ^ x[(I-3) & 0x0F]                            \
00217                , (x[I & 0x0F] = rol_uint32(tm, 1)) )
00218 
00219 
00220 #define R(A,B,C,D,E,F,K,M)                                                    \
00221     do                                                                        \
00222     {                                                                         \
00223         E += rol_uint32(A, 5) + F(B, C, D) + K + M;                           \
00224         B = rol_uint32(B, 30);                                                \
00225     } while(0)
00226 
00227     while (words < endp)
00228     {
00229         uint32_t tm;
00230         for (int t = 0; t < 16; t++)
00231         {
00232             x[t] = swapBytes (*words);
00233             words++;
00234         }
00235 
00236         R( a, b, c, d, e, F1, K1, x[ 0] );
00237         R( e, a, b, c, d, F1, K1, x[ 1] );
00238         R( d, e, a, b, c, F1, K1, x[ 2] );
00239         R( c, d, e, a, b, F1, K1, x[ 3] );
00240         R( b, c, d, e, a, F1, K1, x[ 4] );
00241         R( a, b, c, d, e, F1, K1, x[ 5] );
00242         R( e, a, b, c, d, F1, K1, x[ 6] );
00243         R( d, e, a, b, c, F1, K1, x[ 7] );
00244         R( c, d, e, a, b, F1, K1, x[ 8] );
00245         R( b, c, d, e, a, F1, K1, x[ 9] );
00246         R( a, b, c, d, e, F1, K1, x[10] );
00247         R( e, a, b, c, d, F1, K1, x[11] );
00248         R( d, e, a, b, c, F1, K1, x[12] );
00249         R( c, d, e, a, b, F1, K1, x[13] );
00250         R( b, c, d, e, a, F1, K1, x[14] );
00251         R( a, b, c, d, e, F1, K1, x[15] );
00252         R( e, a, b, c, d, F1, K1, M(16) );
00253         R( d, e, a, b, c, F1, K1, M(17) );
00254         R( c, d, e, a, b, F1, K1, M(18) );
00255         R( b, c, d, e, a, F1, K1, M(19) );
00256         R( a, b, c, d, e, F2, K2, M(20) );
00257         R( e, a, b, c, d, F2, K2, M(21) );
00258         R( d, e, a, b, c, F2, K2, M(22) );
00259         R( c, d, e, a, b, F2, K2, M(23) );
00260         R( b, c, d, e, a, F2, K2, M(24) );
00261         R( a, b, c, d, e, F2, K2, M(25) );
00262         R( e, a, b, c, d, F2, K2, M(26) );
00263         R( d, e, a, b, c, F2, K2, M(27) );
00264         R( c, d, e, a, b, F2, K2, M(28) );
00265         R( b, c, d, e, a, F2, K2, M(29) );
00266         R( a, b, c, d, e, F2, K2, M(30) );
00267         R( e, a, b, c, d, F2, K2, M(31) );
00268         R( d, e, a, b, c, F2, K2, M(32) );
00269         R( c, d, e, a, b, F2, K2, M(33) );
00270         R( b, c, d, e, a, F2, K2, M(34) );
00271         R( a, b, c, d, e, F2, K2, M(35) );
00272         R( e, a, b, c, d, F2, K2, M(36) );
00273         R( d, e, a, b, c, F2, K2, M(37) );
00274         R( c, d, e, a, b, F2, K2, M(38) );
00275         R( b, c, d, e, a, F2, K2, M(39) );
00276         R( a, b, c, d, e, F3, K3, M(40) );
00277         R( e, a, b, c, d, F3, K3, M(41) );
00278         R( d, e, a, b, c, F3, K3, M(42) );
00279         R( c, d, e, a, b, F3, K3, M(43) );
00280         R( b, c, d, e, a, F3, K3, M(44) );
00281         R( a, b, c, d, e, F3, K3, M(45) );
00282         R( e, a, b, c, d, F3, K3, M(46) );
00283         R( d, e, a, b, c, F3, K3, M(47) );
00284         R( c, d, e, a, b, F3, K3, M(48) );
00285         R( b, c, d, e, a, F3, K3, M(49) );
00286         R( a, b, c, d, e, F3, K3, M(50) );
00287         R( e, a, b, c, d, F3, K3, M(51) );
00288         R( d, e, a, b, c, F3, K3, M(52) );
00289         R( c, d, e, a, b, F3, K3, M(53) );
00290         R( b, c, d, e, a, F3, K3, M(54) );
00291         R( a, b, c, d, e, F3, K3, M(55) );
00292         R( e, a, b, c, d, F3, K3, M(56) );
00293         R( d, e, a, b, c, F3, K3, M(57) );
00294         R( c, d, e, a, b, F3, K3, M(58) );
00295         R( b, c, d, e, a, F3, K3, M(59) );
00296         R( a, b, c, d, e, F4, K4, M(60) );
00297         R( e, a, b, c, d, F4, K4, M(61) );
00298         R( d, e, a, b, c, F4, K4, M(62) );
00299         R( c, d, e, a, b, F4, K4, M(63) );
00300         R( b, c, d, e, a, F4, K4, M(64) );
00301         R( a, b, c, d, e, F4, K4, M(65) );
00302         R( e, a, b, c, d, F4, K4, M(66) );
00303         R( d, e, a, b, c, F4, K4, M(67) );
00304         R( c, d, e, a, b, F4, K4, M(68) );
00305         R( b, c, d, e, a, F4, K4, M(69) );
00306         R( a, b, c, d, e, F4, K4, M(70) );
00307         R( e, a, b, c, d, F4, K4, M(71) );
00308         R( d, e, a, b, c, F4, K4, M(72) );
00309         R( c, d, e, a, b, F4, K4, M(73) );
00310         R( b, c, d, e, a, F4, K4, M(74) );
00311         R( a, b, c, d, e, F4, K4, M(75) );
00312         R( e, a, b, c, d, F4, K4, M(76) );
00313         R( d, e, a, b, c, F4, K4, M(77) );
00314         R( c, d, e, a, b, F4, K4, M(78) );
00315         R( b, c, d, e, a, F4, K4, M(79) );
00316 
00317         a = hashsumA_ += a;
00318         b = hashsumB_ += b;
00319         c = hashsumC_ += c;
00320         d = hashsumD_ += d;
00321         e = hashsumE_ += e;
00322     }
00323 }
00324 
00325 
00326 void Foam::SHA1::calcDigest(SHA1Digest& dig) const
00327 {
00328     if (bufTotal_[0] || bufTotal_[1])
00329     {
00330         unsigned char *r = dig.v_;
00331 
00332         set_uint32 (r + 0 * sizeof(uint32_t), swapBytes(hashsumA_));
00333         set_uint32 (r + 1 * sizeof(uint32_t), swapBytes(hashsumB_));
00334         set_uint32 (r + 2 * sizeof(uint32_t), swapBytes(hashsumC_));
00335         set_uint32 (r + 3 * sizeof(uint32_t), swapBytes(hashsumD_));
00336         set_uint32 (r + 4 * sizeof(uint32_t), swapBytes(hashsumE_));
00337     }
00338     else
00339     {
00340         
00341         dig.clear();
00342     }
00343 }
00344 
00345 
00346 
00347 
00348 
00349 
00350 
00351 
00352 
00353 
00354 
00355 
00356 
00357 
00358 
00359 void Foam::SHA1::clear()
00360 {
00361     hashsumA_ = 0x67452301;
00362     hashsumB_ = 0xefcdab89;
00363     hashsumC_ = 0x98badcfe;
00364     hashsumD_ = 0x10325476;
00365     hashsumE_ = 0xc3d2e1f0;
00366 
00367     bufTotal_[0] = bufTotal_[1] = 0;
00368     bufLen_ = 0;
00369 
00370     finalized_ = false;
00371 }
00372 
00373 
00374 bool Foam::SHA1::finalize()
00375 {
00376     if (!finalized_)
00377     {
00378         finalized_ = true;
00379 
00380         
00381         uint32_t bytes = bufLen_;
00382         size_t size = (bytes < 56 ? 64 : 128) / sizeof(uint32_t);
00383 
00384         
00385         bufTotal_[0] += bytes;
00386         if (bufTotal_[0] < bytes)
00387         {
00388             ++bufTotal_[1];
00389         }
00390 
00391         
00392         if (!bufTotal_[0] && !bufTotal_[1])
00393         {
00394             return false;
00395         }
00396 
00397         
00398         buffer_[size-2] = swapBytes((bufTotal_[1] << 3) | (bufTotal_[0] >> 29));
00399         buffer_[size-1] = swapBytes(bufTotal_[0] << 3);
00400 
00401         unsigned char* bufp = reinterpret_cast<unsigned char *>(buffer_);
00402 
00403         memcpy(&bufp[bytes], fillbuf, (size-2) * sizeof(uint32_t) - bytes);
00404 
00405         
00406         processBlock(buffer_, size * sizeof(uint32_t));
00407     }
00408 
00409     return true;
00410 }
00411 
00412 
00413 Foam::SHA1Digest Foam::SHA1::digest() const
00414 {
00415     SHA1Digest dig;
00416 
00417     if (finalized_)
00418     {
00419         calcDigest(dig);
00420     }
00421     else
00422     {
00423         
00424         SHA1 sha(*this);
00425         if (sha.finalize())
00426         {
00427             sha.calcDigest(dig);
00428         }
00429     }
00430 
00431     return dig;
00432 }
00433 
00434 
00435 
00436 
00437 
00438 
00439 
00440 
00441 
00442 
00443 
00444 
00445 
00446 
00447 
00448 
00449 
00450 
00451 
00452 
00453 
00454