source: trunk/src/sh_tiger0.c@ 12

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

Minor optimisations for server

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