source: trunk/src/sh_tiger0.c@ 18

Last change on this file since 18 was 18, checked in by rainer, 19 years ago

Optimized version of tiger algorithm, and basic ingredients for unit testing (part 2)

File size: 41.5 KB
Line 
1#include "config_xor.h"
2
3#define USE_MD5
4#define USE_SHA1
5
6#include <stdio.h>
7#include <string.h>
8
9#include <sys/types.h>
10#ifdef HAVE_UNISTD_H
11#include <unistd.h>
12#endif
13#ifdef HAVE_MEMORY_H
14#include <memory.h>
15#endif
16
17#if defined(HAVE_MLOCK) && !defined(HAVE_BROKEN_MLOCK)
18#include <sys/mman.h>
19#endif
20
21#include "sh_tiger.h"
22
23#include "sh_unix.h"
24#include "sh_error.h"
25#include "sh_utils.h"
26
27#define PRIV_MAX 32768
28
29#if defined(TIGER_64_BIT)
30#if defined(HAVE_LONG_64)
31typedef unsigned long int word64;
32#elif defined(HAVE_LONG_LONG_64)
33typedef unsigned long long int word64;
34#else
35#error No 64 bit type found !
36#endif
37#endif
38
39#if defined(HAVE_INT_32)
40typedef unsigned int sh_word32;
41#define MYFORMAT (_("%08X%08X%08X%08X%08X%08X"))
42#define GPGFORMAT (_("%08X %08X %08X %08X %08X %08X"))
43#elif defined(HAVE_LONG_32)
44typedef unsigned long sh_word32;
45#define MYFORMAT (_("%08lX%08lX%08lX%08lX%08lX%08lX"))
46#define GPGFORMAT (_("%08lX %08lX %08lX %08lX %08lX %08lX"))
47#elif defined(HAVE_SHORT_32)
48typedef unsigned short sh_word32;
49#define MYFORMAT (_("%08X%08X%08X%08X%08X%08X"))
50#define GPGFORMAT (_("%08X %08X %08X %08X %08X %08X"))
51#else
52#error No 32 bit type found !
53#endif
54
55typedef unsigned char sh_byte;
56
57#undef FIL__
58#define FIL__ _("sh_tiger0.c")
59
60#if defined(TIGER_64_BIT)
61
62void tiger_t(word64 *str, word64 length, word64 * res);
63void tiger(word64 *str, word64 length, word64 * res);
64
65#ifdef TIGER_DBG
66static void tiger_dbg(word64 res[3], int step,
67 unsigned long nblocks, unsigned long ncount)
68{
69 return;
70}
71#endif
72#else
73void tiger(sh_word32 *str, sh_word32 length, sh_word32 * res);
74void tiger_t(sh_word32 *str, sh_word32 length, sh_word32 * res);
75
76#ifdef TIGER_DBG
77static
78void tiger_dbg(sh_word32 res[6], int step,
79 unsigned long nblocks, unsigned long ncount)
80{
81 fprintf(stderr,
82 _("ST %d BLK %2ld CT %2ld %08lX %08lX %08lX %08lX %08lX %08lX\n"),
83 step,
84 nblocks,
85 ncount,
86 (sh_word32)(res[1]),
87 (sh_word32)(res[0]),
88 (sh_word32)(res[3]),
89 (sh_word32)(res[2]),
90 (sh_word32)(res[5]),
91 (sh_word32)(res[4]) );
92}
93#endif
94#endif
95
96/* this is the wrapper function -- not part of the tiger reference
97 * implementation
98 */
99SL_TICKET tiger_fd = (-1);
100
101static sh_byte buffer[PRIV_MAX + 72];
102
103#if defined(TIGER_64_BIT)
104static
105word64 * sh_tiger_hash_val (char * filename, TigerType what,
106 unsigned long Length, int timeout)
107#else
108static
109sh_word32 * sh_tiger_hash_val (char * filename, TigerType what,
110 unsigned long Length, int timeout)
111#endif
112{
113 SL_TICKET fd;
114 int i, j, tt;
115 int count = 0;
116 int blk;
117 char * tmp;
118 sh_byte * bptr;
119 sh_byte bbuf[64];
120
121 static int lockflag = SL_FALSE;
122
123 unsigned long pages_read;
124 uid_t euid;
125
126 unsigned long ncount = 0, nblocks = 0;
127 unsigned long t, msb, lsb;
128
129#if defined (SH_WITH_CLIENT) || defined (SH_STANDALONE)
130 /*@-nestedextern@*/
131 extern long IO_Limit;
132 /*@+nestedextern@*/
133#endif
134
135#if defined(TIGER_64_BIT)
136#define TIGER_CAST (word64*)
137 static word64 res[3];
138 res[0]= (word64) 0x0123456789ABCDEFLL;
139 res[1]= (word64) 0xFEDCBA9876543210LL;
140 res[2]= (word64) 0xF096A5B4C3B2E187LL;
141#else
142#define TIGER_CAST (sh_word32*)
143 static sh_word32 res[6];
144 res[0]= (sh_word32) 0x89ABCDEF;
145 res[1]= (sh_word32) 0x01234567;
146 res[2]= (sh_word32) 0x76543210;
147 res[3]= (sh_word32) 0xFEDCBA98;
148 res[4]= (sh_word32) 0xC3B2E187;
149 res[5]= (sh_word32) 0xF096A5B4;
150#endif
151
152 SL_ENTER(_("sh_tiger_hash_val"));
153
154 if (what == TIGER_FD || what == TIGER_FILE)
155 {
156 if (what == TIGER_FD)
157 {
158 fd = tiger_fd;
159 TPT((0,FIL__, __LINE__, _("msg=<TIGER_FD>, fd=<%ld>\n"), tiger_fd));
160 }
161 else
162 {
163 TPT((0,FIL__, __LINE__, _("msg=<TIGER_FILE>, path=<%s>\n"),
164 (filename == NULL ? _("(null)") : filename) ));
165 fd = sl_open_read (filename, SL_YESPRIV);
166 }
167
168 if (SL_ISERROR (fd))
169 {
170 TPT((0, FIL__, __LINE__, _("msg=<SL_ISERROR (%ld)>\n"), tiger_fd));
171 tmp = sh_util_safe_name (filename);
172 (void) sl_get_euid(&euid);
173 sh_error_handle (ShDFLevel[SH_ERR_T_FILE], FIL__, __LINE__, (int)fd,
174 MSG_E_ACCESS, (long) euid, tmp);
175 SH_FREE(tmp);
176 SL_RETURN( NULL, _("sh_tiger_hash_val"));
177 }
178
179#if defined(HAVE_MLOCK) && !defined(HAVE_BROKEN_MLOCK)
180 if (lockflag == SL_FALSE && skey->mlock_failed == SL_FALSE)
181 {
182 if ( (-1) == sh_unix_mlock((char *)buffer,(PRIV_MAX)*sizeof(sh_byte)))
183 skey->mlock_failed = SL_TRUE;
184 lockflag = SL_TRUE;
185 }
186#else
187 if (lockflag == SL_FALSE && skey->mlock_failed == SL_FALSE)
188 {
189 skey->mlock_failed = SL_TRUE;
190 lockflag = SL_TRUE;
191 }
192#endif
193
194#ifdef TIGER_DBG
195 tiger_dbg (res, 0, nblocks, ncount);
196#endif
197
198 pages_read = 0;
199
200 while (1)
201 {
202 if (timeout > 0)
203 count = sl_read_timeout (fd, buffer, PRIV_MAX, timeout);
204 else
205 count = sl_read (fd, buffer, PRIV_MAX);
206
207 ++pages_read;
208
209 if (SL_ISERROR (count))
210 {
211 if (sig_termfast == 1) {
212 SL_RETURN( NULL, _("sh_tiger_hash_val"));
213 }
214 TPT((0, FIL__ , __LINE__ , _("msg=<SL_ISERROR (%ld)>\n"), count));
215 tmp = sh_util_safe_name (filename);
216 if (count == SL_TIMEOUT)
217 {
218 if (timeout != 7) {
219 sh_error_handle (SH_ERR_ERR, FIL__, __LINE__, count,
220 MSG_E_TIMEOUT, timeout, tmp);
221 }
222 }
223 else
224 sh_error_handle (ShDFLevel[SH_ERR_T_FILE], FIL__, __LINE__,
225 count, MSG_E_READ, tmp);
226 SH_FREE(tmp);
227 memset (bbuf, 0, 64);
228 memset (buffer, 0, PRIV_MAX);
229
230 SL_RETURN( NULL, _("sh_tiger_hash_val"));
231 }
232
233 blk = (count / 64); /* number of 64-byte words */
234
235 /* nblocks += blk; number of 64-byte words
236 * count cannot be negative here, see 'if (SL_ISERROR (count))'
237 */
238 tt = blk*64;
239
240 ncount = (unsigned long) (count - tt);
241
242 nblocks += blk;
243 sh.statistics.bytes_hashed += tt;
244
245 bptr = buffer; tt = 0;
246 for (i = 0; i < blk; ++i)
247 {
248 bptr = &buffer[tt]; tt += 64;
249
250 tiger_t(TIGER_CAST bptr, 64, res);
251
252#ifdef TIGER_DBG
253 tiger_dbg (res, 3, nblocks, ncount);
254#endif
255 }
256
257 if (blk < (PRIV_MAX / 64)) /* this must be (PRIV_MAX / 64) */
258 break;
259
260#if defined (SH_WITH_CLIENT) || defined (SH_STANDALONE)
261 if (sig_termfast == 1)
262 {
263 memset (bbuf, 0, 64);
264 memset (buffer, 0, PRIV_MAX);
265
266 SL_RETURN( NULL, _("sh_tiger_hash_val"));
267 }
268 if ((IO_Limit) > 0 && (pages_read == 32)) /* check for I/O limit */
269 {
270 sh_unix_io_pause ();
271 pages_read = 0;
272 }
273#endif
274 }
275
276 TPT((0, FIL__, __LINE__ , _("msg=<Last block.>\n")));
277
278 /* copy incomplete block
279 */
280 j = 0;
281 for (i = 0; i < 64; i += 4)
282 {
283 bbuf[i] = (sh_byte) '\0';
284 bbuf[i+1] = (sh_byte) '\0';
285 bbuf[i+2] = (sh_byte) '\0';
286 bbuf[i+3] = (sh_byte) '\0';
287 }
288 for (i = (count/64) * 64; i < count; ++i)
289 /*@-usedef@*/bbuf[j++] = buffer[i];/*@+usedef@*/
290
291#ifdef TIGER_DBG
292 tiger_dbg (res, 5, nblocks, ncount);
293#endif
294
295 msb = 0;
296 t = nblocks;
297 if( (lsb = t << 6) < t )
298 msb++;
299 msb += t >> 26;
300 t = lsb;
301 if( (lsb = t + ncount) < t )
302 msb++;
303 t = lsb;
304 if( (lsb = t << 3) < t )
305 msb++;
306 msb += t >> 29;
307
308 if( j < 56 )
309 {
310 bbuf[j++] = (sh_byte) 0x01; ++ncount;
311 while( j < 56 )
312 { bbuf[j++] = (sh_byte) 0; ++ncount; }
313 }
314 else
315 {
316 bbuf[j++] = (sh_byte) 0x01;
317 while( j < 64 )
318 bbuf[j++] = (sh_byte) 0;
319 tiger_t(TIGER_CAST bbuf, 64, res);
320 sh.statistics.bytes_hashed += 64;
321 ++nblocks; ncount = 0;
322 for (i = 0; i < 56; i += 4)
323 {
324 bbuf[i] = (sh_byte) '\0';
325 bbuf[i+1] = (sh_byte) '\0';
326 bbuf[i+2] = (sh_byte) '\0';
327 bbuf[i+3] = (sh_byte) '\0';
328 }
329 /* memset(bbuf, 0, 56 ); */
330 }
331
332#ifdef TIGER_DBG
333 tiger_dbg (res, 6, nblocks, ncount);
334#endif
335
336 bbuf[56] = (sh_byte) (lsb );
337 bbuf[57] = (sh_byte) (lsb >> 8);
338 bbuf[58] = (sh_byte) (lsb >> 16);
339 bbuf[59] = (sh_byte) (lsb >> 24);
340 bbuf[60] = (sh_byte) (msb );
341 bbuf[61] = (sh_byte) (msb >> 8);
342 bbuf[62] = (sh_byte) (msb >> 16);
343 bbuf[63] = (sh_byte) (msb >> 24);
344
345 tiger_t(TIGER_CAST bbuf, 64, res);
346 sh.statistics.bytes_hashed += 64;
347
348#ifdef TIGER_DBG
349 tiger_dbg (res, 7, nblocks, ncount);
350#endif
351
352 for (i = 0; i < 64; i += 4)
353 {
354 bbuf[i] = (sh_byte) '\0';
355 bbuf[i+1] = (sh_byte) '\0';
356 bbuf[i+2] = (sh_byte) '\0';
357 bbuf[i+3] = (sh_byte) '\0';
358 }
359
360 bptr = buffer;
361
362 memcpy(bptr, bbuf, 64); bptr += 64;
363 memcpy(bptr, bbuf, 64); bptr += 64;
364 memcpy(bptr, buffer, 128); bptr += 128;
365 memcpy(bptr, buffer, 256); bptr += 256;
366 memcpy(bptr, buffer, 512); bptr += 512;
367 memcpy(bptr, buffer, 1024); bptr += 1024;
368 memcpy(bptr, buffer, 2048); bptr += 2048;
369 memcpy(bptr, buffer, 4096); bptr += 4096;
370 memcpy(bptr, buffer, 8192); bptr += 8192;
371 memcpy(bptr, buffer,16384);
372
373 if (what == TIGER_FILE)
374 (void) sl_close (fd);
375 else
376 tiger_fd = (-1);
377
378
379 SL_RETURN( res, _("sh_tiger_hash_val"));
380 }
381
382 if (what == TIGER_DATA && filename != NULL)
383 {
384 tiger(TIGER_CAST filename, (sh_word32) Length, res);
385 SL_RETURN(res, _("sh_tiger_hash_val"));
386 }
387 SL_RETURN( NULL, _("sh_tiger_hash_val"));
388}
389
390/* Thu Oct 18 18:53:33 CEST 2001
391 */
392
393#ifdef USE_MD5
394/*@-type@*/
395/************************************************************************
396 *
397 * md5.h - Declaration of functions and data types used for MD5 sum
398 * computing library functions.
399 *
400 ************************************************************************/
401
402/* Written Bob Deblier <bob@virtualunlimited.com> */
403/* Hacked to work with samhain by R. Wichmann */
404/* Need for 64bit type removed, fix for Mac OS X compiler */
405
406typedef sh_word32 uint32;
407typedef unsigned char uint8;
408
409
410
411
412
413/* Structure to save state of computation between the single steps. */
414typedef struct
415{
416 uint32 h[4];
417 uint32 data[16];
418 uint8 offset;
419 uint32 nblocks;
420 int count;
421} md5Param;
422
423static uint32 md5hinit[4] = { 0x67452301, 0xefcdab89, 0x98badcfe, 0x10325476 };
424
425
426int md5Reset(register md5Param* p)
427{
428 unsigned int i;
429 memcpy(p->h, md5hinit, 16);
430
431 for (i = 0; i < 16; i += 8)
432 {
433 p->data[i] = 0x00;
434 p->data[i+1] = 0x00;
435 p->data[i+2] = 0x00;
436 p->data[i+3] = 0x00;
437 p->data[i+4] = 0x00;
438 p->data[i+5] = 0x00;
439 p->data[i+6] = 0x00;
440 p->data[i+7] = 0x00;
441 }
442
443 /* memset(p->data, 0x00, 64); */
444 p->offset = (uint8) 0;
445 p->nblocks = 0;
446 return 0;
447}
448
449#if defined(__GNUC__) && defined(__i386__)
450static inline UINT32
451ROTL32( UINT32 x, int s)
452{
453 __asm__("roll %%cl,%0"
454 :"=r" (x)
455 :"0" (x),"c" (s));
456 return x;
457}
458#else
459#define ROTL32(x, s) (((x) << (s)) | ((x) >> (32 - (s))))
460#endif
461
462
463#define FF(a, b, c, d, w, s, t) \
464 a += ((b&(c^d))^d) + w + t; \
465 a = ROTL32(a, s); \
466 a += b;
467
468#define GG(a, b, c, d, w, s, t) \
469 a += ((d&(b^c))^c) + w + t; \
470 a = ROTL32(a, s); \
471 a += b;
472
473#define HH(a, b, c, d, w, s, t) \
474 a += (b^c^d) + w + t; \
475 a = ROTL32(a, s); \
476 a += b;
477
478#define II(a, b, c, d, w, s, t) \
479 a += (c^(b|~d)) + w + t; \
480 a = ROTL32(a, s); \
481 a += b;
482
483#if WORDS_BIGENDIAN
484uint32 swapu32(uint32 n)
485{
486 return ( ((n & 0xffU) << 24) |
487 ((n & 0xff00U) << 8) |
488 ((n & 0xff0000U) >> 8) |
489 ((n & 0xff000000U) >> 24) );
490}
491#endif
492
493static
494void md5Process(md5Param* p)
495{
496 register uint32 a,b,c,d;
497 register uint32* w;
498 #if WORDS_BIGENDIAN
499 register sh_byte t;
500 #endif
501
502 w = p->data;
503 #if WORDS_BIGENDIAN
504 t = 16;
505 while (t--)
506 {
507 register uint32 temp = swapu32(*w);
508 *(w++) = temp;
509 }
510 w = p->data;
511 #endif
512
513 a = p->h[0]; b = p->h[1]; c = p->h[2]; d = p->h[3];
514
515 FF(a, b, c, d, (*w++), 7, 0xd76aa478);
516 FF(d, a, b, c, (*w++), 12, 0xe8c7b756);
517 FF(c, d, a, b, (*w++), 17, 0x242070db);
518 FF(b, c, d, a, (*w++), 22, 0xc1bdceee);
519 FF(a, b, c, d, (*w++), 7, 0xf57c0faf);
520 FF(d, a, b, c, (*w++), 12, 0x4787c62a);
521 FF(c, d, a, b, (*w++), 17, 0xa8304613);
522 FF(b, c, d, a, (*w++), 22, 0xfd469501);
523 FF(a, b, c, d, (*w++), 7, 0x698098d8);
524 FF(d, a, b, c, (*w++), 12, 0x8b44f7af);
525 FF(c, d, a, b, (*w++), 17, 0xffff5bb1);
526 FF(b, c, d, a, (*w++), 22, 0x895cd7be);
527 FF(a, b, c, d, (*w++), 7, 0x6b901122);
528 FF(d, a, b, c, (*w++), 12, 0xfd987193);
529 FF(c, d, a, b, (*w++), 17, 0xa679438e);
530 FF(b, c, d, a, (*w++), 22, 0x49b40821);
531
532 w = p->data;
533
534 GG(a, b, c, d, w[ 1], 5, 0xf61e2562);
535 GG(d, a, b, c, w[ 6], 9, 0xc040b340);
536 GG(c, d, a, b, w[11], 14, 0x265e5a51);
537 GG(b, c, d, a, w[ 0], 20, 0xe9b6c7aa);
538 GG(a, b, c, d, w[ 5], 5, 0xd62f105d);
539 GG(d, a, b, c, w[10], 9, 0x02441453);
540 GG(c, d, a, b, w[15], 14, 0xd8a1e681);
541 GG(b, c, d, a, w[ 4], 20, 0xe7d3fbc8);
542 GG(a, b, c, d, w[ 9], 5, 0x21e1cde6);
543 GG(d, a, b, c, w[14], 9, 0xc33707d6);
544 GG(c, d, a, b, w[ 3], 14, 0xf4d50d87);
545 GG(b, c, d, a, w[ 8], 20, 0x455a14ed);
546 GG(a, b, c, d, w[13], 5, 0xa9e3e905);
547 GG(d, a, b, c, w[ 2], 9, 0xfcefa3f8);
548 GG(c, d, a, b, w[ 7], 14, 0x676f02d9);
549 GG(b, c, d, a, w[12], 20, 0x8d2a4c8a);
550
551 HH(a, b, c, d, w[ 5], 4, 0xfffa3942);
552 HH(d, a, b, c, w[ 8], 11, 0x8771f681);
553 HH(c, d, a, b, w[11], 16, 0x6d9d6122);
554 HH(b, c, d, a, w[14], 23, 0xfde5380c);
555 HH(a, b, c, d, w[ 1], 4, 0xa4beea44);
556 HH(d, a, b, c, w[ 4], 11, 0x4bdecfa9);
557 HH(c, d, a, b, w[ 7], 16, 0xf6bb4b60);
558 HH(b, c, d, a, w[10], 23, 0xbebfbc70);
559 HH(a, b, c, d, w[13], 4, 0x289b7ec6);
560 HH(d, a, b, c, w[ 0], 11, 0xeaa127fa);
561 HH(c, d, a, b, w[ 3], 16, 0xd4ef3085);
562 HH(b, c, d, a, w[ 6], 23, 0x04881d05);
563 HH(a, b, c, d, w[ 9], 4, 0xd9d4d039);
564 HH(d, a, b, c, w[12], 11, 0xe6db99e5);
565 HH(c, d, a, b, w[15], 16, 0x1fa27cf8);
566 HH(b, c, d, a, w[ 2], 23, 0xc4ac5665);
567
568 II(a, b, c, d, w[ 0], 6, 0xf4292244);
569 II(d, a, b, c, w[ 7], 10, 0x432aff97);
570 II(c, d, a, b, w[14], 15, 0xab9423a7);
571 II(b, c, d, a, w[ 5], 21, 0xfc93a039);
572 II(a, b, c, d, w[12], 6, 0x655b59c3);
573 II(d, a, b, c, w[ 3], 10, 0x8f0ccc92);
574 II(c, d, a, b, w[10], 15, 0xffeff47d);
575 II(b, c, d, a, w[ 1], 21, 0x85845dd1);
576 II(a, b, c, d, w[ 8], 6, 0x6fa87e4f);
577 II(d, a, b, c, w[15], 10, 0xfe2ce6e0);
578 II(c, d, a, b, w[ 6], 15, 0xa3014314);
579 II(b, c, d, a, w[13], 21, 0x4e0811a1);
580 II(a, b, c, d, w[ 4], 6, 0xf7537e82);
581 II(d, a, b, c, w[11], 10, 0xbd3af235);
582 II(c, d, a, b, w[ 2], 15, 0x2ad7d2bb);
583 II(b, c, d, a, w[ 9], 21, 0xeb86d391);
584
585 p->h[0] += a;
586 p->h[1] += b;
587 p->h[2] += c;
588 p->h[3] += d;
589}
590
591int md5Update(md5Param* p, const sh_byte* data, int size)
592{
593 register int proclength;
594
595 while (size > 0)
596 {
597 proclength = (((int)p->offset + size) > 64) ?
598 (64 - (int)p->offset) : size;
599 memcpy(((sh_byte *) p->data) + p->offset, data, (size_t) proclength);
600 size -= proclength;
601 data += proclength;
602 p->offset += proclength;
603
604 if (p->offset == (uint8) 64)
605 {
606 md5Process(p);
607 p->offset = (uint8) 0;
608 p->nblocks++;
609 }
610 }
611 return 0;
612}
613
614static void md5Finish(md5Param* p)
615{
616 uint32 t, msb, lsb;
617 uint8 * pp;
618 register uint8 *ptr;
619
620 msb = 0;
621 t = p->nblocks;
622 if( (lsb = t << 6) < t ) /* multiply by 64 to make a byte count */
623 msb++;
624 msb += t >> 26;
625 t = lsb;
626 if( (lsb = t + (uint32)p->offset) < t ) /* add the count */
627 msb++;
628 t = lsb;
629 if( (lsb = t << 3) < t ) /* multiply by 8 to make a bit count */
630 msb++;
631 msb += t >> 29;
632
633 ptr = ((uint8 *) p->data) + p->offset++;
634
635
636 *(ptr++) = (uint8) 0x80;
637
638 if (p->offset > (uint8)56)
639 {
640 while (p->offset++ < 64)
641 *(ptr++) = 0;
642
643 md5Process(p);
644 p->offset = 0;
645 }
646
647 ptr = ((uint8 *) p->data) + p->offset;
648 while (p->offset++ < 56)
649 *(ptr++) = 0;
650
651 /* append the 64 bit count */
652 *(ptr++) = lsb ;
653 *(ptr++) = lsb >> 8;
654 *(ptr++) = lsb >> 16;
655 *(ptr++) = lsb >> 24;
656 *(ptr++) = msb ;
657 *(ptr++) = msb >> 8;
658 *(ptr++) = msb >> 16;
659 *(ptr++) = msb >> 24;
660
661 md5Process(p);
662
663 pp = (uint8 *) p->data;
664#ifdef WORDS_BIGENDIAN
665#define X(a) do { *pp++ = (*p).a; *pp++ = (*p).a >> 8; \
666 *pp++ = (*p).a >> 16; *pp++ = (*p).a >> 24; } while(0)
667#else /* little endian */
668 /*#define X(a) do { *(uint32*)p = p->##a ; p += 4; } while(0)*/
669 /* Unixware's cpp doesn't like the above construct so we do it his way:
670 * (reported by Allan Clark) */
671#define X(a) do { *(uint32*)pp = (*p).a ; pp += 4; } while(0)
672#endif
673 X(h[0]);
674 X(h[1]);
675 X(h[2]);
676 X(h[3]);
677#undef X
678
679 p->offset = 0;
680}
681
682int md5Digest(md5Param* p, uint32* data)
683{
684 md5Finish(p);
685 memcpy(data, p->h, 16);
686 (void) md5Reset(p);
687 return 0;
688}
689/*@+type@*/
690
691/* Compute MD5 message digest for bytes read from STREAM. The
692 resulting message digest number will be written into the 16 bytes
693 beginning at RESBLOCK. */
694static int md5_stream(char * filename, void *resblock, int timeout)
695{
696 /* Important: BLOCKSIZE must be a multiple of 64. */
697 static const int BLOCKSIZE = 8192;
698 md5Param ctx;
699 char buffer[8264]; /* BLOCKSIZE + 72 AIX compiler chokes */
700 off_t sum = 0;
701 SL_TICKET fd;
702 char * tmp;
703 uid_t euid;
704
705 unsigned long pages_read;
706#if defined (SH_WITH_CLIENT) || defined (SH_STANDALONE)
707 /*@-nestedextern@*/
708 extern long IO_Limit;
709 /*@+nestedextern@*/
710#endif
711
712 /* Initialize the computation context. */
713 (void) md5Reset (&ctx);
714
715 fd = tiger_fd;
716
717 if (SL_ISERROR (fd))
718 {
719 TPT((0, FIL__, __LINE__, _("msg=<SL_ISERROR (%ld)>\n"), tiger_fd));
720 tmp = sh_util_safe_name (filename);
721 (void) sl_get_euid(&euid);
722 sh_error_handle (ShDFLevel[SH_ERR_T_FILE], FIL__, __LINE__, fd,
723 MSG_E_ACCESS, (long) euid, tmp);
724 SH_FREE(tmp);
725 return -1;
726 }
727
728 pages_read = 0;
729
730 /* Iterate over full file contents. */
731 while (1 == 1) {
732 /* We read the file in blocks of BLOCKSIZE bytes. One call of the
733 computation function processes the whole buffer so that with the
734 next round of the loop another block can be read. */
735 off_t n;
736 sum = 0;
737
738 /* Read block. Take care for partial reads. */
739 do {
740
741 n = (off_t) sl_read_timeout (fd, buffer + sum,
742 (size_t) BLOCKSIZE - sum, timeout);
743
744 if (SL_ISERROR (n))
745 {
746 if (sig_termfast == 1)
747 return -1;
748 TPT((0, FIL__ , __LINE__ , _("msg=<SL_ISERROR (%ld)>\n"), n));
749 tmp = sh_util_safe_name (filename);
750 if (n == SL_TIMEOUT)
751 {
752 if (timeout != 7) {
753 sh_error_handle (SH_ERR_ERR, FIL__, __LINE__, n, MSG_E_TIMEOUT,
754 timeout, tmp);
755 }
756 }
757 else
758 sh_error_handle (ShDFLevel[SH_ERR_T_FILE], FIL__, __LINE__, n,
759 MSG_E_READ, tmp);
760 SH_FREE(tmp);
761 return -1;
762 }
763
764 sum += n;
765 }
766 while (sum < (off_t) BLOCKSIZE
767 && n != 0);
768
769 ++pages_read;
770
771 /* If end of file is reached, end the loop. */
772 if (n == 0)
773 break;
774
775 /* Process buffer with BLOCKSIZE bytes. Note that
776 BLOCKSIZE % 64 == 0
777 */
778 (void) md5Update(&ctx, (sh_byte*) buffer, BLOCKSIZE);
779 sh.statistics.bytes_hashed += BLOCKSIZE;
780
781#if defined (SH_WITH_CLIENT) || defined (SH_STANDALONE)
782 if ((IO_Limit) > 0 && (pages_read == 32)) /* check for I/O limit */
783 {
784 sh_unix_io_pause ();
785 pages_read = 0;
786 }
787 if (sig_termfast == 1)
788 {
789 return -1;
790 }
791#endif
792 }
793
794 /* Add the last bytes if necessary. */
795 if (sum > 0)
796 {
797 (void) md5Update(&ctx, (sh_byte*) buffer, (int) sum);
798 sh.statistics.bytes_hashed += BLOCKSIZE;
799 }
800
801 /* Construct result in desired memory. */
802 (void) md5Digest(&ctx, resblock);
803
804 return 0;
805}
806
807static
808char * sh_tiger_md5_hash (char * filename, TigerType what,
809 unsigned long Length, int timeout)
810{
811 int cnt = (int) Length;
812 static char out[KEY_LEN+1];
813 unsigned char md5buffer[16];
814
815 if (what != TIGER_FD)
816 {
817 sh_error_handle (ShDFLevel[SH_ERR_T_FILE], FIL__, __LINE__, 0,
818 MSG_E_SUBGEN, _("Not TIGER_FD"),
819 _("sh_tiger_md5_hash"));
820 out[0] = '\0';
821 return out;
822 }
823
824 (void) md5_stream (filename, md5buffer, timeout);
825
826 /*@-bufferoverflowhigh -usedef@*/
827 for (cnt = 0; cnt < 16; ++cnt)
828 sprintf (&out[cnt*2], _("%02X"), /* known to fit */
829 (unsigned int) md5buffer[cnt]);
830 /*@+bufferoverflowhigh +usedef@*/
831 for (cnt = 32; cnt < KEY_LEN; ++cnt)
832 out[cnt] = '0';
833 out[KEY_LEN] = '\0';
834
835 return out;
836}
837
838/* USE_MD5 */
839#endif
840
841/***************************************************************
842 *
843 * SHA1
844 *
845 ***************************************************************/
846
847#ifdef USE_SHA1
848/*@-type@*/
849
850typedef unsigned char sha_word8;
851typedef sh_word32 sha_word32;
852
853/* The SHA block size and message digest sizes, in bytes */
854
855#define SHA_DATASIZE 64
856#define SHA_DATALEN 16
857#define SHA_DIGESTSIZE 20
858#define SHA_DIGESTLEN 5
859/* The structure for storing SHA info */
860
861typedef struct sha_ctx {
862 sha_word32 digest[SHA_DIGESTLEN]; /* Message digest */
863 sha_word32 count_l, count_h; /* 64-bit block count */
864 sha_word8 block[SHA_DATASIZE]; /* SHA data buffer */
865 int index; /* index into buffer */
866} SHA_CTX;
867
868static void sha_init(struct sha_ctx *ctx);
869static void sha_update(struct sha_ctx *ctx, sha_word8 *buffer,sha_word32 len);
870static void sha_final(struct sha_ctx *ctx);
871static void sha_digest(struct sha_ctx *ctx, sha_word8 *s);
872
873
874/* The SHA f()-functions. The f1 and f3 functions can be optimized to
875 save one boolean operation each - thanks to Rich Schroeppel,
876 rcs@cs.arizona.edu for discovering this */
877
878/*#define f1(x,y,z) ( ( x & y ) | ( ~x & z ) ) // Rounds 0-19 */
879#define f1(x,y,z) ( z ^ ( x & ( y ^ z ) ) ) /* Rounds 0-19 */
880#define f2(x,y,z) ( x ^ y ^ z ) /* Rounds 20-39 */
881/*#define f3(x,y,z) ( ( x & y ) | ( x & z ) | ( y & z ) ) // Rounds 40-59 */
882#define f3(x,y,z) ( ( x & y ) | ( z & ( x | y ) ) ) /* Rounds 40-59 */
883#define f4(x,y,z) ( x ^ y ^ z ) /* Rounds 60-79 */
884
885/* The SHA Mysterious Constants */
886
887#define K1 0x5A827999L /* Rounds 0-19 */
888#define K2 0x6ED9EBA1L /* Rounds 20-39 */
889#define K3 0x8F1BBCDCL /* Rounds 40-59 */
890#define K4 0xCA62C1D6L /* Rounds 60-79 */
891
892/* SHA initial values */
893
894#define h0init 0x67452301L
895#define h1init 0xEFCDAB89L
896#define h2init 0x98BADCFEL
897#define h3init 0x10325476L
898#define h4init 0xC3D2E1F0L
899
900/* 32-bit rotate left - kludged with shifts */
901
902#define ROTL(n,X) ( ( (X) << (n) ) | ( (X) >> ( 32 - (n) ) ) )
903
904/* The initial expanding function. The hash function is defined over an
905 80-word expanded input array W, where the first 16 are copies of the input
906 data, and the remaining 64 are defined by
907
908 W[ i ] = W[ i - 16 ] ^ W[ i - 14 ] ^ W[ i - 8 ] ^ W[ i - 3 ]
909
910 This implementation generates these values on the fly in a circular
911 buffer - thanks to Colin Plumb, colin@nyx10.cs.du.edu for this
912 optimization.
913
914 The updated SHA changes the expanding function by adding a rotate of 1
915 bit. Thanks to Jim Gillogly, jim@rand.org, and an anonymous contributor
916 for this information */
917
918#define expand(W,i) ( W[ i & 15 ] = \
919 ROTL( 1, ( W[ i & 15 ] ^ W[ (i - 14) & 15 ] ^ \
920 W[ (i - 8) & 15 ] ^ W[ (i - 3) & 15 ] ) ) )
921
922
923/* The prototype SHA sub-round. The fundamental sub-round is:
924
925 a' = e + ROTL( 5, a ) + f( b, c, d ) + k + data;
926 b' = a;
927 c' = ROTL( 30, b );
928 d' = c;
929 e' = d;
930
931 but this is implemented by unrolling the loop 5 times and renaming the
932 variables ( e, a, b, c, d ) = ( a', b', c', d', e' ) each iteration.
933 This code is then replicated 20 times for each of the 4 functions, using
934 the next 20 values from the W[] array each time */
935
936#define subRound(a, b, c, d, e, f, k, data) \
937 ( e += ROTL( 5, a ) + f( b, c, d ) + k + data, b = ROTL( 30, b ) )
938
939/* Initialize the SHA values */
940
941static void sha_init(struct sha_ctx *ctx)
942{
943 /* Set the h-vars to their initial values */
944 ctx->digest[ 0 ] = h0init;
945 ctx->digest[ 1 ] = h1init;
946 ctx->digest[ 2 ] = h2init;
947 ctx->digest[ 3 ] = h3init;
948 ctx->digest[ 4 ] = h4init;
949
950 /* Initialize bit count */
951 ctx->count_l = ctx->count_h = 0;
952
953 /* Initialize buffer */
954 ctx->index = 0;
955}
956
957/* Perform the SHA transformation. Note that this code, like MD5, seems to
958 break some optimizing compilers due to the complexity of the expressions
959 and the size of the basic block. It may be necessary to split it into
960 sections, e.g. based on the four subrounds
961
962 Note that this function destroys the data area */
963
964static void sha_transform(struct sha_ctx *ctx, sha_word32 *data )
965{
966 register sha_word32 A, B, C, D, E; /* Local vars */
967
968 /* Set up first buffer and local data buffer */
969 A = ctx->digest[0];
970 B = ctx->digest[1];
971 C = ctx->digest[2];
972 D = ctx->digest[3];
973 E = ctx->digest[4];
974
975 /* Heavy mangling, in 4 sub-rounds of 20 interations each. */
976 subRound( A, B, C, D, E, f1, K1, data[ 0] );
977 subRound( E, A, B, C, D, f1, K1, data[ 1] );
978 subRound( D, E, A, B, C, f1, K1, data[ 2] );
979 subRound( C, D, E, A, B, f1, K1, data[ 3] );
980 subRound( B, C, D, E, A, f1, K1, data[ 4] );
981 subRound( A, B, C, D, E, f1, K1, data[ 5] );
982 subRound( E, A, B, C, D, f1, K1, data[ 6] );
983 subRound( D, E, A, B, C, f1, K1, data[ 7] );
984 subRound( C, D, E, A, B, f1, K1, data[ 8] );
985 subRound( B, C, D, E, A, f1, K1, data[ 9] );
986 subRound( A, B, C, D, E, f1, K1, data[10] );
987 subRound( E, A, B, C, D, f1, K1, data[11] );
988 subRound( D, E, A, B, C, f1, K1, data[12] );
989 subRound( C, D, E, A, B, f1, K1, data[13] );
990 subRound( B, C, D, E, A, f1, K1, data[14] );
991 subRound( A, B, C, D, E, f1, K1, data[15] );
992 subRound( E, A, B, C, D, f1, K1, expand( data, 16 ) );
993 subRound( D, E, A, B, C, f1, K1, expand( data, 17 ) );
994 subRound( C, D, E, A, B, f1, K1, expand( data, 18 ) );
995 subRound( B, C, D, E, A, f1, K1, expand( data, 19 ) );
996
997 subRound( A, B, C, D, E, f2, K2, expand( data, 20 ) );
998 subRound( E, A, B, C, D, f2, K2, expand( data, 21 ) );
999 subRound( D, E, A, B, C, f2, K2, expand( data, 22 ) );
1000 subRound( C, D, E, A, B, f2, K2, expand( data, 23 ) );
1001 subRound( B, C, D, E, A, f2, K2, expand( data, 24 ) );
1002 subRound( A, B, C, D, E, f2, K2, expand( data, 25 ) );
1003 subRound( E, A, B, C, D, f2, K2, expand( data, 26 ) );
1004 subRound( D, E, A, B, C, f2, K2, expand( data, 27 ) );
1005 subRound( C, D, E, A, B, f2, K2, expand( data, 28 ) );
1006 subRound( B, C, D, E, A, f2, K2, expand( data, 29 ) );
1007 subRound( A, B, C, D, E, f2, K2, expand( data, 30 ) );
1008 subRound( E, A, B, C, D, f2, K2, expand( data, 31 ) );
1009 subRound( D, E, A, B, C, f2, K2, expand( data, 32 ) );
1010 subRound( C, D, E, A, B, f2, K2, expand( data, 33 ) );
1011 subRound( B, C, D, E, A, f2, K2, expand( data, 34 ) );
1012 subRound( A, B, C, D, E, f2, K2, expand( data, 35 ) );
1013 subRound( E, A, B, C, D, f2, K2, expand( data, 36 ) );
1014 subRound( D, E, A, B, C, f2, K2, expand( data, 37 ) );
1015 subRound( C, D, E, A, B, f2, K2, expand( data, 38 ) );
1016 subRound( B, C, D, E, A, f2, K2, expand( data, 39 ) );
1017
1018 subRound( A, B, C, D, E, f3, K3, expand( data, 40 ) );
1019 subRound( E, A, B, C, D, f3, K3, expand( data, 41 ) );
1020 subRound( D, E, A, B, C, f3, K3, expand( data, 42 ) );
1021 subRound( C, D, E, A, B, f3, K3, expand( data, 43 ) );
1022 subRound( B, C, D, E, A, f3, K3, expand( data, 44 ) );
1023 subRound( A, B, C, D, E, f3, K3, expand( data, 45 ) );
1024 subRound( E, A, B, C, D, f3, K3, expand( data, 46 ) );
1025 subRound( D, E, A, B, C, f3, K3, expand( data, 47 ) );
1026 subRound( C, D, E, A, B, f3, K3, expand( data, 48 ) );
1027 subRound( B, C, D, E, A, f3, K3, expand( data, 49 ) );
1028 subRound( A, B, C, D, E, f3, K3, expand( data, 50 ) );
1029 subRound( E, A, B, C, D, f3, K3, expand( data, 51 ) );
1030 subRound( D, E, A, B, C, f3, K3, expand( data, 52 ) );
1031 subRound( C, D, E, A, B, f3, K3, expand( data, 53 ) );
1032 subRound( B, C, D, E, A, f3, K3, expand( data, 54 ) );
1033 subRound( A, B, C, D, E, f3, K3, expand( data, 55 ) );
1034 subRound( E, A, B, C, D, f3, K3, expand( data, 56 ) );
1035 subRound( D, E, A, B, C, f3, K3, expand( data, 57 ) );
1036 subRound( C, D, E, A, B, f3, K3, expand( data, 58 ) );
1037 subRound( B, C, D, E, A, f3, K3, expand( data, 59 ) );
1038
1039 subRound( A, B, C, D, E, f4, K4, expand( data, 60 ) );
1040 subRound( E, A, B, C, D, f4, K4, expand( data, 61 ) );
1041 subRound( D, E, A, B, C, f4, K4, expand( data, 62 ) );
1042 subRound( C, D, E, A, B, f4, K4, expand( data, 63 ) );
1043 subRound( B, C, D, E, A, f4, K4, expand( data, 64 ) );
1044 subRound( A, B, C, D, E, f4, K4, expand( data, 65 ) );
1045 subRound( E, A, B, C, D, f4, K4, expand( data, 66 ) );
1046 subRound( D, E, A, B, C, f4, K4, expand( data, 67 ) );
1047 subRound( C, D, E, A, B, f4, K4, expand( data, 68 ) );
1048 subRound( B, C, D, E, A, f4, K4, expand( data, 69 ) );
1049 subRound( A, B, C, D, E, f4, K4, expand( data, 70 ) );
1050 subRound( E, A, B, C, D, f4, K4, expand( data, 71 ) );
1051 subRound( D, E, A, B, C, f4, K4, expand( data, 72 ) );
1052 subRound( C, D, E, A, B, f4, K4, expand( data, 73 ) );
1053 subRound( B, C, D, E, A, f4, K4, expand( data, 74 ) );
1054 subRound( A, B, C, D, E, f4, K4, expand( data, 75 ) );
1055 subRound( E, A, B, C, D, f4, K4, expand( data, 76 ) );
1056 subRound( D, E, A, B, C, f4, K4, expand( data, 77 ) );
1057 subRound( C, D, E, A, B, f4, K4, expand( data, 78 ) );
1058 subRound( B, C, D, E, A, f4, K4, expand( data, 79 ) );
1059
1060 /* Build message digest */
1061 ctx->digest[0] += A;
1062 ctx->digest[1] += B;
1063 ctx->digest[2] += C;
1064 ctx->digest[3] += D;
1065 ctx->digest[4] += E;
1066}
1067
1068#if 1
1069
1070#ifndef EXTRACT_UCHAR
1071#define EXTRACT_UCHAR(p) (*(unsigned char *)(p))
1072#endif
1073
1074#define STRING2INT(s) ((((((EXTRACT_UCHAR(s) << 8) \
1075 | EXTRACT_UCHAR(s+1)) << 8) \
1076 | EXTRACT_UCHAR(s+2)) << 8) \
1077 | EXTRACT_UCHAR(s+3))
1078#else
1079sha_word32 STRING2INT(word8 *s)
1080{
1081 sha_word32 r;
1082 int i;
1083
1084 for (i = 0, r = 0; i < 4; i++, s++)
1085 r = (r << 8) | *s;
1086 return r;
1087}
1088#endif
1089
1090static void sha_block(struct sha_ctx *ctx, sha_word8 *block)
1091{
1092 sha_word32 data[SHA_DATALEN];
1093 int i;
1094
1095 /* Update block count */
1096 /*@-boolops@*/
1097 if (!++ctx->count_l)
1098 ++ctx->count_h;
1099 /*@+boolops@*/
1100
1101 /* Endian independent conversion */
1102 for (i = 0; i<SHA_DATALEN; i++, block += 4)
1103 data[i] = STRING2INT(block);
1104
1105 sha_transform(ctx, data);
1106}
1107
1108static void sha_update(struct sha_ctx *ctx, sha_word8 *buffer, sha_word32 len)
1109{
1110 if (ctx->index != 0)
1111 { /* Try to fill partial block */
1112 unsigned left = SHA_DATASIZE - ctx->index;
1113 if (len < left)
1114 {
1115 memmove(ctx->block + ctx->index, buffer, len);
1116 ctx->index += len;
1117 return; /* Finished */
1118 }
1119 else
1120 {
1121 memmove(ctx->block + ctx->index, buffer, left);
1122 sha_block(ctx, ctx->block);
1123 buffer += left;
1124 len -= left;
1125 }
1126 }
1127 while (len >= SHA_DATASIZE)
1128 {
1129 sha_block(ctx, buffer);
1130 buffer += SHA_DATASIZE;
1131 len -= SHA_DATASIZE;
1132 }
1133 /*@-predboolint@*/
1134 if ((ctx->index = len)) /* This assignment is intended */
1135 /*@+predboolint@*/
1136 /* Buffer leftovers */
1137 memmove(ctx->block, buffer, len);
1138}
1139
1140/* Final wrapup - pad to SHA_DATASIZE-byte boundary with the bit pattern
1141 1 0* (64-bit count of bits processed, MSB-first) */
1142
1143static void sha_final(struct sha_ctx *ctx)
1144{
1145 sha_word32 data[SHA_DATALEN];
1146 int i;
1147 int words;
1148
1149 i = ctx->index;
1150 /* Set the first char of padding to 0x80. This is safe since there is
1151 always at least one byte free */
1152 ctx->block[i++] = 0x80;
1153
1154 /* Fill rest of word */
1155 /*@-predboolint@*/
1156 for( ; i & 3; i++)
1157 ctx->block[i] = 0;
1158 /*@+predboolint@*/
1159
1160 /* i is now a multiple of the word size 4 */
1161 /*@-shiftimplementation@*/
1162 words = i >> 2;
1163 /*@+shiftimplementation@*/
1164 for (i = 0; i < words; i++)
1165 data[i] = STRING2INT(ctx->block + 4*i);
1166
1167 if (words > (SHA_DATALEN-2))
1168 { /* No room for length in this block. Process it and
1169 * pad with another one */
1170 for (i = words ; i < SHA_DATALEN; i++)
1171 data[i] = 0;
1172 sha_transform(ctx, data);
1173 for (i = 0; i < (SHA_DATALEN-2); i++)
1174 data[i] = 0;
1175 }
1176 else
1177 for (i = words ; i < SHA_DATALEN - 2; i++)
1178 data[i] = 0;
1179 /* Theres 512 = 2^9 bits in one block */
1180 /*@-shiftimplementation@*/
1181 data[SHA_DATALEN-2] = (ctx->count_h << 9) | (ctx->count_l >> 23);
1182 data[SHA_DATALEN-1] = (ctx->count_l << 9) | (ctx->index << 3);
1183 /*@+shiftimplementation@*/
1184 sha_transform(ctx, data);
1185}
1186
1187static void sha_digest(struct sha_ctx *ctx, sha_word8 *s)
1188{
1189 int i;
1190
1191 for (i = 0; i < SHA_DIGESTLEN; i++)
1192 {
1193 *s++ = ctx->digest[i] >> 24;
1194 *s++ = 0xff & (ctx->digest[i] >> 16);
1195 *s++ = 0xff & (ctx->digest[i] >> 8);
1196 *s++ = 0xff & ctx->digest[i];
1197 }
1198}
1199/*@+type@*/
1200
1201/* Compute SHA1 message digest for bytes read from STREAM. The
1202 resulting message digest number will be written into the 16 bytes
1203 beginning at RESBLOCK. */
1204static int sha1_stream(char * filename, void *resblock, int timeout)
1205{
1206 /* Important: BLOCKSIZE must be a multiple of 64. */
1207 static const int BLOCKSIZE = 4096;
1208 struct sha_ctx ctx;
1209 char buffer[4168]; /* BLOCKSIZE + 72 AIX compiler chokes */
1210 off_t sum = 0;
1211 SL_TICKET fd;
1212 char * tmp;
1213 uid_t euid;
1214
1215 unsigned long pages_read;
1216#if defined (SH_WITH_CLIENT) || defined (SH_STANDALONE)
1217 /*@-nestedextern@*/
1218 extern long IO_Limit;
1219 /*@+nestedextern@*/
1220#endif
1221
1222 /* Initialize the computation context. */
1223 (void) sha_init(&ctx);
1224
1225 fd = tiger_fd;
1226
1227 if (SL_ISERROR (fd))
1228 {
1229 TPT((0, FIL__, __LINE__, _("msg=<SL_ISERROR (%ld)>\n"), tiger_fd));
1230 tmp = sh_util_safe_name (filename);
1231 (void) sl_get_euid(&euid);
1232 sh_error_handle (ShDFLevel[SH_ERR_T_FILE], FIL__, __LINE__, fd,
1233 MSG_E_ACCESS, (long) euid, tmp);
1234 SH_FREE(tmp);
1235 return -1;
1236 }
1237
1238 /* Iterate over full file contents. */
1239
1240 pages_read = 0;
1241
1242 while (1 == 1) {
1243 /* We read the file in blocks of BLOCKSIZE bytes. One call of the
1244 computation function processes the whole buffer so that with the
1245 next round of the loop another block can be read. */
1246 off_t n;
1247 sum = 0;
1248
1249 /* Read block. Take care for partial reads. */
1250 do {
1251 n = (off_t) sl_read_timeout(fd, buffer + sum,
1252 (size_t) BLOCKSIZE - sum, timeout);
1253
1254 if (SL_ISERROR (n))
1255 {
1256 if (sig_termfast == 1)
1257 return -1;
1258
1259 TPT((0, FIL__ , __LINE__ , _("msg=<SL_ISERROR (%ld)>\n"), n));
1260 tmp = sh_util_safe_name (filename);
1261 if (n == SL_TIMEOUT)
1262 {
1263 if (timeout != 7) {
1264 sh_error_handle (SH_ERR_ERR, FIL__, __LINE__, n, MSG_E_TIMEOUT,
1265 timeout, tmp);
1266 }
1267 }
1268 else
1269 {
1270 sh_error_handle (ShDFLevel[SH_ERR_T_FILE], FIL__, __LINE__, n,
1271 MSG_E_READ, tmp);
1272 }
1273 SH_FREE(tmp);
1274 return -1;
1275 }
1276
1277 sum += n;
1278 }
1279 while (sum < (off_t)BLOCKSIZE
1280 && n != 0);
1281
1282 ++pages_read;
1283
1284 /* If end of file is reached, end the loop. */
1285 if (n == 0)
1286 break;
1287
1288 /* Process buffer with BLOCKSIZE bytes. Note that
1289 BLOCKSIZE % 64 == 0
1290 */
1291 sha_update(&ctx, (sha_word8*) buffer, (sha_word32) BLOCKSIZE);
1292 sh.statistics.bytes_hashed += BLOCKSIZE;
1293
1294#if defined (SH_WITH_CLIENT) || defined (SH_STANDALONE)
1295 if ((IO_Limit) > 0 && (pages_read == 32)) /* check for I/O limit */
1296 {
1297 sh_unix_io_pause ();
1298 pages_read = 0;
1299 }
1300 if (sig_termfast == 1)
1301 {
1302 return -1;
1303 }
1304#endif
1305
1306 }
1307
1308 /* Add the last bytes if necessary. */
1309 if (sum > 0)
1310 {
1311 sha_update(&ctx, (sha_word8*) buffer, (sha_word32) sum);
1312 sh.statistics.bytes_hashed += sum;
1313 }
1314
1315 sha_final (&ctx);
1316
1317 /* Construct result in desired memory. */
1318 sha_digest (&ctx, resblock);
1319 return 0;
1320}
1321
1322
1323static char * sh_tiger_sha1_hash (char * filename, TigerType what,
1324 unsigned long Length, int timeout)
1325{
1326 int cnt = (int) Length; /* fix compiler warning */
1327 static char out[KEY_LEN+1];
1328 unsigned char sha1buffer[20];
1329
1330 if (what != TIGER_FD)
1331 {
1332 sh_error_handle (ShDFLevel[SH_ERR_T_FILE], FIL__, __LINE__, 0,
1333 MSG_E_SUBGEN, _("Not TIGER_FD"),
1334 _("sh_tiger_sha1_hash"));
1335 out[0] = '\0';
1336 return out;
1337 }
1338
1339 (void) sha1_stream (filename, sha1buffer, timeout);
1340
1341 /*@-bufferoverflowhigh -usedef@*/
1342 for (cnt = 0; cnt < 20; ++cnt)
1343 sprintf (&out[cnt*2], _("%02X"), /* known to fit */
1344 (unsigned int) sha1buffer[cnt]);
1345 /*@+bufferoverflowhigh +usedef@*/
1346 for (cnt = 40; cnt < KEY_LEN; ++cnt)
1347 out[cnt] = '0';
1348 out[KEY_LEN] = '\0';
1349
1350 return out;
1351}
1352
1353/* ifdef USE_SHA1 */
1354#endif
1355
1356static int hash_type = 0;
1357
1358int sh_tiger_get_hashtype ()
1359{
1360 return hash_type;
1361}
1362
1363int sh_tiger_hashtype (char * c)
1364{
1365 SL_ENTER( _("sh_tiger_hashtype"));
1366
1367 if (!c)
1368 {
1369 SL_RETURN( -1, _("sh_tiger_hashtype"));
1370 }
1371
1372 if (0 == strcmp(c, _("TIGER192")))
1373 hash_type = 0;
1374#ifdef USE_MD5
1375 else if (0 == strcmp(c, _("SHA1")))
1376 hash_type = 1;
1377#endif
1378#ifdef USE_SHA1
1379 else if (0 == strcmp(c, _("MD5")))
1380 hash_type = 2;
1381#endif
1382 else
1383 {
1384 SL_RETURN( -1, _("sh_tiger_hashtype"));
1385 }
1386 SL_RETURN( 0, _("sh_tiger_hashtype"));
1387}
1388
1389static char * sh_tiger_hash_internal (char * filename, TigerType what,
1390 unsigned long Length, int timeout);
1391
1392char * sh_tiger_hash (char * filename, TigerType what,
1393 unsigned long Length)
1394{
1395 return sh_tiger_hash_internal (filename, what, Length, 0);
1396}
1397
1398char * sh_tiger_generic_hash (char * filename, TigerType what,
1399 unsigned long Length, int timeout)
1400{
1401#ifdef USE_SHA1
1402 if (hash_type == 1)
1403 return sh_tiger_sha1_hash (filename, what, Length, timeout);
1404#endif
1405#ifdef USE_MD5
1406 if (hash_type == 2)
1407 return sh_tiger_md5_hash (filename, what, Length, timeout);
1408#endif
1409 return sh_tiger_hash_internal (filename, what, Length, timeout);
1410}
1411
1412/*
1413 * ------- end new --------- */
1414
1415static char * sh_tiger_hash_internal (char * filename, TigerType what,
1416 unsigned long Length, int timeout)
1417{
1418#if defined(TIGER_64_BIT)
1419 word64 * res;
1420#else
1421 sh_word32 * res;
1422#endif
1423 static char out[KEY_LEN+1];
1424
1425 SL_ENTER( _("sh_tiger_hash"));
1426
1427 res = sh_tiger_hash_val (filename, what, Length, timeout);
1428
1429 if (res != NULL)
1430 {
1431 /*@-bufferoverflowhigh -formatconst@*/
1432#if defined(TIGER_64_BIT)
1433 sprintf(out, /* known to fit */
1434 MYFORMAT,
1435 (sh_word32)(res[0]>>32),
1436 (sh_word32)(res[0]),
1437 (sh_word32)(res[1]>>32),
1438 (sh_word32)(res[1]),
1439 (sh_word32)(res[2]>>32),
1440 (sh_word32)(res[2]) );
1441#else
1442 sprintf(out, /* known to fit */
1443 MYFORMAT,
1444 (sh_word32)(res[1]),
1445 (sh_word32)(res[0]),
1446 (sh_word32)(res[3]),
1447 (sh_word32)(res[2]),
1448 (sh_word32)(res[5]),
1449 (sh_word32)(res[4]) );
1450#endif
1451 /*@+bufferoverflowhigh@*/
1452 out[KEY_LEN] = '\0';
1453 SL_RETURN( out, _("sh_tiger_hash"));
1454
1455 }
1456
1457 SL_RETURN( _("000000000000000000000000000000000000000000000000"),
1458 _("sh_tiger_hash"));
1459}
1460
1461char * sh_tiger_hash_gpg (char * filename, TigerType what,
1462 unsigned long Length)
1463{
1464 size_t len;
1465 char * out;
1466 char outhash[48+6+1];
1467#if defined(TIGER_64_BIT)
1468 word64 * res;
1469#else
1470 sh_word32 * res;
1471#endif
1472
1473 SL_ENTER(_("sh_tiger_hash_gpg"));
1474
1475 res = sh_tiger_hash_val (filename, what, Length, 0);
1476 if (res != NULL)
1477 {
1478 /*@-bufferoverflowhigh -formatconst@*/
1479#if defined(TIGER_64_BIT)
1480 sprintf(outhash, /* known to fit */
1481 GPGFORMAT,
1482 (sh_word32)(res[0]>>32),
1483 (sh_word32)(res[0]),
1484 (sh_word32)(res[1]>>32),
1485 (sh_word32)(res[1]),
1486 (sh_word32)(res[2]>>32),
1487 (sh_word32)(res[2]) );
1488#else
1489 sprintf(outhash, /* known to fit */
1490 GPGFORMAT,
1491 (sh_word32)(res[1]),
1492 (sh_word32)(res[0]),
1493 (sh_word32)(res[3]),
1494 (sh_word32)(res[2]),
1495 (sh_word32)(res[5]),
1496 (sh_word32)(res[4]) );
1497#endif
1498 /*@+bufferoverflowhigh@*/
1499 outhash[48 + 6] = '\0';
1500 }
1501 else
1502 {
1503 /*@-bufferoverflowhigh@*/
1504 sprintf(outhash, /* known to fit */
1505 _("00000000 00000000 00000000 00000000 00000000 00000000"));
1506 /*@+bufferoverflowhigh@*/
1507 }
1508
1509 if (what == TIGER_FILE)
1510 len = sl_strlen (filename) + 2 + 48 + 6;
1511 else
1512 len = 48 + 6;
1513
1514 out = SH_ALLOC(len + 1);
1515
1516 if (what == TIGER_FILE)
1517 {
1518 (void) sl_strlcpy (out, filename, len+1);
1519 (void) sl_strlcat (out, _(": "), len+1);
1520 (void) sl_strlcat (out, outhash, len+1);
1521 }
1522 else
1523 {
1524 (void) sl_strlcpy (out, outhash, len+1);
1525 }
1526 SL_RETURN( out, _("sh_tiger_hash_gpg"));
1527}
1528
1529
1530UINT32 * sh_tiger_hash_uint32 (char * filename,
1531 TigerType what,
1532 unsigned long Length)
1533{
1534#if defined(TIGER_64_BIT)
1535 word64 * res;
1536#else
1537 sh_word32 * res;
1538#endif
1539
1540 static UINT32 out[6];
1541
1542 SL_ENTER(_("sh_tiger_hash_uint32"));
1543
1544 out[0] = 0; out[1] = 0; out[2] = 0;
1545 out[3] = 0; out[4] = 0; out[5] = 0;
1546
1547 res = sh_tiger_hash_val (filename, what, Length, 0);
1548
1549 if (res != NULL)
1550 {
1551#if defined(TIGER_64_BIT)
1552 out[0] = (UINT32)(res[0]>>32);
1553 out[1] = (UINT32)(res[0]);
1554 out[2] = (UINT32)(res[1]>>32);
1555 out[3] = (UINT32)(res[1]);
1556 out[4] = (UINT32)(res[2]>>32);
1557 out[5] = (UINT32)(res[2]);
1558#else
1559 out[0] = (UINT32)(res[1]);
1560 out[1] = (UINT32)(res[0]);
1561 out[2] = (UINT32)(res[3]);
1562 out[3] = (UINT32)(res[2]);
1563 out[4] = (UINT32)(res[5]);
1564 out[5] = (UINT32)(res[4]);
1565#endif
1566 }
1567
1568 SL_RETURN(out, _("sh_tiger_hash_uint32"));
1569}
1570
1571
1572
1573
Note: See TracBrowser for help on using the repository browser.