1 /*---------------------------------------------------------------------------*\
3 \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
5 \\ / A nd | Copyright (C) 2009-2011 OpenCFD Ltd.
7 -------------------------------------------------------------------------------
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
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/>.
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
34 \*---------------------------------------------------------------------------*/
37 #include "IOstreams.H"
41 #if defined (__GLIBC__)
46 // * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
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, ... */ };
55 // * * * * * * * * * * * * Static Member Functions * * * * * * * * * * * * * //
57 inline uint32_t Foam::SHA1::swapBytes(uint32_t n)
60 # if (__BYTE_ORDER == __BIG_ENDIAN)
66 | (((n) & 0xff00) << 8)
67 | (((n) >> 8) & 0xff00)
74 const short x = 0x0100;
76 // yields 0x01 for big endian
77 if (*(reinterpret_cast<const char*>(&x)))
86 | (((n) & 0xff00) << 8)
87 | (((n) >> 8) & 0xff00)
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
113 // complete filling of internal buffer
116 size_t remaining = bufLen_;
119 sizeof(buffer_) - remaining > len
121 : sizeof(buffer_) - remaining
124 unsigned char* bufp = reinterpret_cast<unsigned char*>(buffer_);
126 memcpy(&bufp[remaining], data, add);
131 processBlock(buffer_, bufLen_ & ~63);
134 // The regions in the following copy operation do not
136 memcpy(buffer_, &bufp[(remaining + add) & ~63], bufLen_);
139 data = reinterpret_cast<const unsigned char*>(data) + add;
143 // Process available complete blocks
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))
154 processBlock(memcpy(buffer_, data, 64), 64);
155 data = reinterpret_cast<const unsigned char*>(data) + 64;
162 // processBlock(data, len & ~63);
163 // data = reinterpret_cast<const unsigned char*>(data) + (len & ~63);
168 // Move remaining bytes in internal buffer.
171 unsigned char* bufp = reinterpret_cast<unsigned char*>(buffer_);
172 size_t remaining = bufLen_;
174 memcpy (&bufp[remaining], data, len);
178 processBlock(buffer_, 64);
180 memcpy(buffer_, &buffer_[16], remaining);
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
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
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.
221 if (bufTotal_[0] < len)
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) \
237 E += rol_uint32(A, 5) + F(B, C, D) + K + M; \
238 B = rol_uint32(B, 30); \
244 for (int t = 0; t < 16; ++t)
246 x[t] = swapBytes(*words);
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) );
340 void Foam::SHA1::calcDigest(SHA1Digest& dig) const
342 if (bufTotal_[0] || bufTotal_[1])
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_));
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;
388 bool Foam::SHA1::finalize()
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)
405 // finalized, but no data!
406 if (!bufTotal_[0] && !bufTotal_[1])
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));
427 Foam::SHA1Digest Foam::SHA1::digest() const
437 // avoid disturbing our data - use a copy
449 // * * * * * * * * * * * * * * Member Operators * * * * * * * * * * * * * * //
451 // void Foam::SHA1::operator=(const SHA1& rhs)
453 // // Check for assignment to self
456 // FatalErrorIn("Foam::SHA1::operator=(const Foam::SHA1&)")
457 // << "Attempted assignment to self"
458 // << abort(FatalError);
463 // ************************************************************************* //