FreeFOAM The Cross-Platform CFD Toolkit
Hosted by SourceForge:
Get FreeFOAM at SourceForge.net.
            Fast, secure and Free Open Source software downloads

SHA1.C

Go to the documentation of this file.
00001 /*---------------------------------------------------------------------------*\
00002   =========                 |
00003   \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
00004    \\    /   O peration     |
00005     \\  /    A nd           | Copyright (C) 1991-2010 OpenCFD Ltd.
00006      \\/     M anipulation  |
00007 -------------------------------------------------------------------------------
00008 License
00009     This file is part of OpenFOAM.
00010 
00011     OpenFOAM is free software: you can redistribute it and/or modify it
00012     under the terms of the GNU General Public License as published by
00013     the Free Software Foundation, either version 3 of the License, or
00014     (at your option) any later version.
00015 
00016     OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
00017     ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
00018     FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
00019     for more details.
00020 
00021     You should have received a copy of the GNU General Public License
00022     along with OpenFOAM.  If not, see <http://www.gnu.org/licenses/>.
00023 
00024 Description
00025     Functions to compute SHA1 message digest of files or memory blocks
00026     according to the NIST specification FIPS-180-1.
00027 
00028     Adapted from the gnulib implementation written by Scott G. Miller with
00029     credits to Robert Klep <robert@ilse.nl> -- Expansion function fix
00030 
00031     Copyright (C) 2000, 2001, 2003, 2004, 2005, 2006, 2008 Free Software
00032     Foundation, Inc.
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 // * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
00047 
00049 //  The bytes used to pad buffer to the next 64-byte boundary.
00050 //  (RFC 1321, 3.1: Step 1)
00051 static const unsigned char fillbuf[64] = { 0x80, 0 /* , 0, 0, ...  */ };
00053 
00054 
00055 // * * * * * * * * * * * * Static Member Functions * * * * * * * * * * * * * //
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     // yields 0x01 for big endian
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 // * * * * * * * * * * * * Private Member Functions  * * * * * * * * * * * * //
00091 
00092 
00093 void Foam::SHA1::processBytes(const void *data, size_t len)
00094 {
00095     // already finalized, thus need to restart from nothing
00096     if (finalized_)
00097     {
00098         clear();
00099     }
00100 
00101     // complete filling of internal buffer
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             // The regions in the following copy operation do not (cannot) overlap
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     // Process available complete blocks
00131 //    if (len >= 64)
00132 //    {
00133 //#if !_STRING_ARCH_unaligned
00134 //# define alignof(type) offsetof (struct { char c; type x; }, x)
00135 //# define UNALIGNED_P(p) (((size_t) p) % alignof (uint32_t) != 0)
00136 //        if (UNALIGNED_P (data))
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 //        else
00146 //#endif
00147 //        {
00148 //            processBlock(data, len & ~63);
00149 //            data = reinterpret_cast<const unsigned char*>(data) + (len & ~63);
00150 //            len &= 63;
00151 //        }
00152 //    }
00153 
00154     // Move remaining bytes in internal buffer.
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 // SHA1 round constants
00174 #define K1 0x5a827999
00175 #define K2 0x6ed9eba1
00176 #define K3 0x8f1bbcdc
00177 #define K4 0xca62c1d6
00178 
00179 // Round functions.  Note that F2 is the same as F4.
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 // Process LEN bytes of BUFFER, it is assumed that LEN % 64 == 0.
00186 // Most of this code comes from GnuPG's cipher/sha1.c
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     // calculate with sixteen words of 32-bits
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     // First increment the byte count.
00204     // RFC 1321 specifies the possible length of the file up to 2^64 bits.
00205     // Here we only compute the number of bytes.  Do a double word increment.
00206     bufTotal_[0] += len;
00207     if (bufTotal_[0] < len)
00208     {
00209         ++bufTotal_[1];
00210     }
00211 
00212     // rotate left uint32_t by n bits
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         // no data!
00341         dig.clear();
00342     }
00343 }
00344 
00345 
00346 // * * * * * * * * * * * * * * * * Constructors  * * * * * * * * * * * * * * //
00347 
00348 // * * * * * * * * * * * * * * * * Selectors * * * * * * * * * * * * * * * * //
00349 
00350 // * * * * * * * * * * * * * * * * Destructor  * * * * * * * * * * * * * * * //
00351 
00352 
00353 // * * * * * * * * * * * * Protected Member Functions  * * * * * * * * * * * //
00354 
00355 
00356 // * * * * * * * * * * * * * * Member Functions  * * * * * * * * * * * * * * //
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         // account for unprocessed bytes
00381         uint32_t bytes = bufLen_;
00382         size_t size = (bytes < 56 ? 64 : 128) / sizeof(uint32_t);
00383 
00384         // count remaining bytes.
00385         bufTotal_[0] += bytes;
00386         if (bufTotal_[0] < bytes)
00387         {
00388             ++bufTotal_[1];
00389         }
00390 
00391         // finalized, but no data!
00392         if (!bufTotal_[0] && !bufTotal_[1])
00393         {
00394             return false;
00395         }
00396 
00397         // place the 64-bit file length in *bits* at the end of the buffer.
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         // Process remaining bytes
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         // avoid disturbing our data - use a copy
00424         SHA1 sha(*this);
00425         if (sha.finalize())
00426         {
00427             sha.calcDigest(dig);
00428         }
00429     }
00430 
00431     return dig;
00432 }
00433 
00434 
00435 // * * * * * * * * * * * * * * Member Operators  * * * * * * * * * * * * * * //
00436 
00437 // void Foam::SHA1::operator=(const SHA1& rhs)
00438 // {
00439 //     // Check for assignment to self
00440 //     if (this == &rhs)
00441 //     {
00442 //         FatalErrorIn("Foam::SHA1::operator=(const Foam::SHA1&)")
00443 //             << "Attempted assignment to self"
00444 //             << abort(FatalError);
00445 //     }
00446 // }
00447 
00448 // * * * * * * * * * * * * * * Friend Functions  * * * * * * * * * * * * * * //
00449 
00450 
00451 // * * * * * * * * * * * * * * Friend Operators * * * * * * * * * * * * * * //
00452 
00453 
00454 // ************************ vim: set sw=4 sts=4 et: ************************ //
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines