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