Initial commit for version 2.0.x patch release
[OpenFOAM-2.0.x.git] / src / OpenFOAM / primitives / hashes / SHA1 / SHA1.C
blob5c97cee6c448101e13875b7ea4fb4d7bcbda4c03
1 /*---------------------------------------------------------------------------*\
2   =========                 |
3   \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
4    \\    /   O peration     |
5     \\  /    A nd           | Copyright (C) 2009-2011 OpenCFD Ltd.
6      \\/     M anipulation  |
7 -------------------------------------------------------------------------------
8 License
9     This file is part of OpenFOAM.
11     OpenFOAM is free software: you can redistribute it and/or modify it
12     under the terms of the GNU General Public License as published by
13     the Free Software Foundation, either version 3 of the License, or
14     (at your option) any later version.
16     OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
17     ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
18     FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
19     for more details.
21     You should have received a copy of the GNU General Public License
22     along with OpenFOAM.  If not, see <http://www.gnu.org/licenses/>.
24 Description
25     Functions to compute SHA1 message digest of files or memory blocks
26     according to the NIST specification FIPS-180-1.
28     Adapted from the gnulib implementation written by Scott G. Miller with
29     credits to Robert Klep <robert@ilse.nl> -- Expansion function fix
31     Copyright (C) 2000, 2001, 2003, 2004, 2005, 2006, 2008 Free Software
32     Foundation, Inc.
34 \*---------------------------------------------------------------------------*/
36 #include "SHA1.H"
37 #include "IOstreams.H"
39 #include <cstring>
41 #if defined (__GLIBC__)
42 #  include <endian.h>
43 #endif
46 // * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
48 //! \cond fileScope
49 //  The bytes used to pad buffer to the next 64-byte boundary.
50 //  (RFC 1321, 3.1: Step 1)
51 static const unsigned char fillbuf[64] = { 0x80, 0 /* , 0, 0, ...  */ };
52 //! \endcond
55 // * * * * * * * * * * * * Static Member Functions * * * * * * * * * * * * * //
57 inline uint32_t Foam::SHA1::swapBytes(uint32_t n)
59 #ifdef __BYTE_ORDER
60 # if (__BYTE_ORDER == __BIG_ENDIAN)
61     return n;
62 # else
63     return
64     (
65         ((n) << 24)
66       | (((n) & 0xff00) << 8)
67       | (((n) >> 8) & 0xff00)
68       | ((n) >> 24)
69     );
70 # endif
72 #else
74     const short x = 0x0100;
76     // yields 0x01 for big endian
77     if (*(reinterpret_cast<const char*>(&x)))
78     {
79         return n;
80     }
81     else
82     {
83         return
84         (
85             ((n) << 24)
86           | (((n) & 0xff00) << 8)
87           | (((n) >> 8) & 0xff00)
88           | ((n) >> 24)
89         );
90     }
91 #endif
95 inline void
96 Foam::SHA1::set_uint32(unsigned char *cp, uint32_t v)
98     memcpy(cp, &v, sizeof(uint32_t));
102 // * * * * * * * * * * * * Private Member Functions  * * * * * * * * * * * * //
105 void Foam::SHA1::processBytes(const void *data, size_t len)
107     // already finalized, thus need to restart from nothing
108     if (finalized_)
109     {
110         clear();
111     }
113     // complete filling of internal buffer
114     if (bufLen_)
115     {
116         size_t remaining = bufLen_;
117         size_t add =
118         (
119             sizeof(buffer_) - remaining > len
120           ? len
121           : sizeof(buffer_) - remaining
122         );
124         unsigned char* bufp = reinterpret_cast<unsigned char*>(buffer_);
126         memcpy(&bufp[remaining], data, add);
127         bufLen_ += add;
129         if (bufLen_ > 64)
130         {
131             processBlock(buffer_, bufLen_ & ~63);
133             bufLen_ &= 63;
134             // The regions in the following copy operation do not
135             // (cannot) overlap
136             memcpy(buffer_, &bufp[(remaining + add) & ~63], bufLen_);
137         }
139         data = reinterpret_cast<const unsigned char*>(data) + add;
140         len -= add;
141     }
143     // Process available complete blocks
144 //    if (len >= 64)
145 //    {
146 //#if !_STRING_ARCH_unaligned
147 //# define alignof(type) offsetof (struct { char c; type x; }, x)
148 //# define UNALIGNED_P(p) (((size_t) p) % alignof (uint32_t) != 0)
149 //        if (UNALIGNED_P (data))
150 //        {
151 //            while (len > 64)
152             while (len >= 64)
153             {
154                 processBlock(memcpy(buffer_, data, 64), 64);
155                 data = reinterpret_cast<const unsigned char*>(data) + 64;
156                 len -= 64;
157             }
158 //        }
159 //        else
160 //#endif
161 //        {
162 //            processBlock(data, len & ~63);
163 //            data = reinterpret_cast<const unsigned char*>(data) + (len & ~63);
164 //            len &= 63;
165 //        }
166 //    }
168     // Move remaining bytes in internal buffer.
169     if (len > 0)
170     {
171         unsigned char* bufp = reinterpret_cast<unsigned char*>(buffer_);
172         size_t remaining = bufLen_;
174         memcpy (&bufp[remaining], data, len);
175         remaining += len;
176         if (remaining >= 64)
177         {
178             processBlock(buffer_, 64);
179             remaining -= 64;
180             memcpy(buffer_, &buffer_[16], remaining);
181         }
182         bufLen_ = remaining;
183     }
187 // SHA1 round constants
188 #define K1 0x5a827999
189 #define K2 0x6ed9eba1
190 #define K3 0x8f1bbcdc
191 #define K4 0xca62c1d6
193 // Round functions.  Note that F2 is the same as F4.
194 #define F1(B,C,D) ( D ^ ( B & ( C ^ D ) ) )
195 #define F2(B,C,D) (B ^ C ^ D)
196 #define F3(B,C,D) ( ( B & C ) | ( D & ( B | C ) ) )
197 #define F4(B,C,D) (B ^ C ^ D)
199 // Process LEN bytes of BUFFER, it is assumed that LEN % 64 == 0.
200 // Most of this code comes from GnuPG's cipher/sha1.c
202 void
203 Foam::SHA1::processBlock(const void *data, size_t len)
205     const uint32_t *words = reinterpret_cast<const uint32_t*>(data);
206     size_t nwords = len / sizeof(uint32_t);
207     const uint32_t *endp = words + nwords;
209     // calculate with sixteen words of 32-bits
210     uint32_t x[16];
211     uint32_t a = hashsumA_;
212     uint32_t b = hashsumB_;
213     uint32_t c = hashsumC_;
214     uint32_t d = hashsumD_;
215     uint32_t e = hashsumE_;
217     // First increment the byte count.
218     // RFC 1321 specifies the possible length of the file up to 2^64 bits.
219     // Here we only compute the number of bytes.  Do a double word increment.
220     bufTotal_[0] += len;
221     if (bufTotal_[0] < len)
222     {
223         ++bufTotal_[1];
224     }
226     // rotate left uint32_t by n bits
227 #define rol_uint32(x, nbits)  (((x) << (nbits)) | ((x) >> (32 - (nbits))))
229 #define M(I) ( tm = x[I & 0x0F] ^ x[(I-14) & 0x0F]                            \
230                ^ x[(I-8) & 0x0F] ^ x[(I-3) & 0x0F]                            \
231                , (x[I & 0x0F] = rol_uint32(tm, 1)) )
234 #define R(A,B,C,D,E,F,K,M)                                                    \
235     do                                                                        \
236     {                                                                         \
237         E += rol_uint32(A, 5) + F(B, C, D) + K + M;                           \
238         B = rol_uint32(B, 30);                                                \
239     } while (0)
241     while (words < endp)
242     {
243         uint32_t tm;
244         for (int t = 0; t < 16; ++t)
245         {
246             x[t] = swapBytes(*words);
247             ++words;
248         }
250         R( a, b, c, d, e, F1, K1, x[ 0] );
251         R( e, a, b, c, d, F1, K1, x[ 1] );
252         R( d, e, a, b, c, F1, K1, x[ 2] );
253         R( c, d, e, a, b, F1, K1, x[ 3] );
254         R( b, c, d, e, a, F1, K1, x[ 4] );
255         R( a, b, c, d, e, F1, K1, x[ 5] );
256         R( e, a, b, c, d, F1, K1, x[ 6] );
257         R( d, e, a, b, c, F1, K1, x[ 7] );
258         R( c, d, e, a, b, F1, K1, x[ 8] );
259         R( b, c, d, e, a, F1, K1, x[ 9] );
260         R( a, b, c, d, e, F1, K1, x[10] );
261         R( e, a, b, c, d, F1, K1, x[11] );
262         R( d, e, a, b, c, F1, K1, x[12] );
263         R( c, d, e, a, b, F1, K1, x[13] );
264         R( b, c, d, e, a, F1, K1, x[14] );
265         R( a, b, c, d, e, F1, K1, x[15] );
266         R( e, a, b, c, d, F1, K1, M(16) );
267         R( d, e, a, b, c, F1, K1, M(17) );
268         R( c, d, e, a, b, F1, K1, M(18) );
269         R( b, c, d, e, a, F1, K1, M(19) );
270         R( a, b, c, d, e, F2, K2, M(20) );
271         R( e, a, b, c, d, F2, K2, M(21) );
272         R( d, e, a, b, c, F2, K2, M(22) );
273         R( c, d, e, a, b, F2, K2, M(23) );
274         R( b, c, d, e, a, F2, K2, M(24) );
275         R( a, b, c, d, e, F2, K2, M(25) );
276         R( e, a, b, c, d, F2, K2, M(26) );
277         R( d, e, a, b, c, F2, K2, M(27) );
278         R( c, d, e, a, b, F2, K2, M(28) );
279         R( b, c, d, e, a, F2, K2, M(29) );
280         R( a, b, c, d, e, F2, K2, M(30) );
281         R( e, a, b, c, d, F2, K2, M(31) );
282         R( d, e, a, b, c, F2, K2, M(32) );
283         R( c, d, e, a, b, F2, K2, M(33) );
284         R( b, c, d, e, a, F2, K2, M(34) );
285         R( a, b, c, d, e, F2, K2, M(35) );
286         R( e, a, b, c, d, F2, K2, M(36) );
287         R( d, e, a, b, c, F2, K2, M(37) );
288         R( c, d, e, a, b, F2, K2, M(38) );
289         R( b, c, d, e, a, F2, K2, M(39) );
290         R( a, b, c, d, e, F3, K3, M(40) );
291         R( e, a, b, c, d, F3, K3, M(41) );
292         R( d, e, a, b, c, F3, K3, M(42) );
293         R( c, d, e, a, b, F3, K3, M(43) );
294         R( b, c, d, e, a, F3, K3, M(44) );
295         R( a, b, c, d, e, F3, K3, M(45) );
296         R( e, a, b, c, d, F3, K3, M(46) );
297         R( d, e, a, b, c, F3, K3, M(47) );
298         R( c, d, e, a, b, F3, K3, M(48) );
299         R( b, c, d, e, a, F3, K3, M(49) );
300         R( a, b, c, d, e, F3, K3, M(50) );
301         R( e, a, b, c, d, F3, K3, M(51) );
302         R( d, e, a, b, c, F3, K3, M(52) );
303         R( c, d, e, a, b, F3, K3, M(53) );
304         R( b, c, d, e, a, F3, K3, M(54) );
305         R( a, b, c, d, e, F3, K3, M(55) );
306         R( e, a, b, c, d, F3, K3, M(56) );
307         R( d, e, a, b, c, F3, K3, M(57) );
308         R( c, d, e, a, b, F3, K3, M(58) );
309         R( b, c, d, e, a, F3, K3, M(59) );
310         R( a, b, c, d, e, F4, K4, M(60) );
311         R( e, a, b, c, d, F4, K4, M(61) );
312         R( d, e, a, b, c, F4, K4, M(62) );
313         R( c, d, e, a, b, F4, K4, M(63) );
314         R( b, c, d, e, a, F4, K4, M(64) );
315         R( a, b, c, d, e, F4, K4, M(65) );
316         R( e, a, b, c, d, F4, K4, M(66) );
317         R( d, e, a, b, c, F4, K4, M(67) );
318         R( c, d, e, a, b, F4, K4, M(68) );
319         R( b, c, d, e, a, F4, K4, M(69) );
320         R( a, b, c, d, e, F4, K4, M(70) );
321         R( e, a, b, c, d, F4, K4, M(71) );
322         R( d, e, a, b, c, F4, K4, M(72) );
323         R( c, d, e, a, b, F4, K4, M(73) );
324         R( b, c, d, e, a, F4, K4, M(74) );
325         R( a, b, c, d, e, F4, K4, M(75) );
326         R( e, a, b, c, d, F4, K4, M(76) );
327         R( d, e, a, b, c, F4, K4, M(77) );
328         R( c, d, e, a, b, F4, K4, M(78) );
329         R( b, c, d, e, a, F4, K4, M(79) );
331         a = hashsumA_ += a;
332         b = hashsumB_ += b;
333         c = hashsumC_ += c;
334         d = hashsumD_ += d;
335         e = hashsumE_ += e;
336     }
340 void Foam::SHA1::calcDigest(SHA1Digest& dig) const
342     if (bufTotal_[0] || bufTotal_[1])
343     {
344         unsigned char *r = dig.v_;
346         set_uint32(r + 0 * sizeof(uint32_t), swapBytes(hashsumA_));
347         set_uint32(r + 1 * sizeof(uint32_t), swapBytes(hashsumB_));
348         set_uint32(r + 2 * sizeof(uint32_t), swapBytes(hashsumC_));
349         set_uint32(r + 3 * sizeof(uint32_t), swapBytes(hashsumD_));
350         set_uint32(r + 4 * sizeof(uint32_t), swapBytes(hashsumE_));
351     }
352     else
353     {
354         // no data!
355         dig.clear();
356     }
360 // * * * * * * * * * * * * * * * * Constructors  * * * * * * * * * * * * * * //
362 // * * * * * * * * * * * * * * * * Selectors * * * * * * * * * * * * * * * * //
364 // * * * * * * * * * * * * * * * * Destructor  * * * * * * * * * * * * * * * //
367 // * * * * * * * * * * * * Protected Member Functions  * * * * * * * * * * * //
370 // * * * * * * * * * * * * * * Member Functions  * * * * * * * * * * * * * * //
373 void Foam::SHA1::clear()
375     hashsumA_ = 0x67452301;
376     hashsumB_ = 0xefcdab89;
377     hashsumC_ = 0x98badcfe;
378     hashsumD_ = 0x10325476;
379     hashsumE_ = 0xc3d2e1f0;
381     bufTotal_[0] = bufTotal_[1] = 0;
382     bufLen_ = 0;
384     finalized_ = false;
388 bool Foam::SHA1::finalize()
390     if (!finalized_)
391     {
392         finalized_ = true;
394         // account for unprocessed bytes
395         uint32_t bytes = bufLen_;
396         size_t size = (bytes < 56 ? 64 : 128) / sizeof(uint32_t);
398         // count remaining bytes.
399         bufTotal_[0] += bytes;
400         if (bufTotal_[0] < bytes)
401         {
402             ++bufTotal_[1];
403         }
405         // finalized, but no data!
406         if (!bufTotal_[0] && !bufTotal_[1])
407         {
408             return false;
409         }
411         // place the 64-bit file length in *bits* at the end of the buffer.
412         buffer_[size-2] = swapBytes((bufTotal_[1] << 3) | (bufTotal_[0] >> 29));
413         buffer_[size-1] = swapBytes(bufTotal_[0] << 3);
415         unsigned char* bufp = reinterpret_cast<unsigned char *>(buffer_);
417         memcpy(&bufp[bytes], fillbuf, (size-2) * sizeof(uint32_t) - bytes);
419         // Process remaining bytes
420         processBlock(buffer_, size * sizeof(uint32_t));
421     }
423     return true;
427 Foam::SHA1Digest Foam::SHA1::digest() const
429     SHA1Digest dig;
431     if (finalized_)
432     {
433         calcDigest(dig);
434     }
435     else
436     {
437         // avoid disturbing our data - use a copy
438         SHA1 sha(*this);
439         if (sha.finalize())
440         {
441             sha.calcDigest(dig);
442         }
443     }
445     return dig;
449 // * * * * * * * * * * * * * * Member Operators  * * * * * * * * * * * * * * //
451 // void Foam::SHA1::operator=(const SHA1& rhs)
452 // {
453 //     // Check for assignment to self
454 //     if (this == &rhs)
455 //     {
456 //         FatalErrorIn("Foam::SHA1::operator=(const Foam::SHA1&)")
457 //             << "Attempted assignment to self"
458 //             << abort(FatalError);
459 //     }
460 // }
463 // ************************************************************************* //