Index: trunk/src/sh_tiger0.c
===================================================================
--- trunk/src/sh_tiger0.c	(revision 22)
+++ trunk/src/sh_tiger0.c	(revision 30)
@@ -404,33 +404,384 @@
 #ifdef USE_MD5
 /*@-type@*/
-/************************************************************************
+/* md5.c - Functions to compute MD5 message digest of files or memory blocks
+ *         according to the definition of MD5 in RFC 1321 from April 1992.
+ * Copyright (C) 1995, 1996 Free Software Foundation, Inc.
  *
- *  md5.h - Declaration of functions and data types used for MD5 sum
- *  computing library functions. 
+ * NOTE: The canonical source of this file is maintained with the GNU C
+ * Library.  Bugs can be reported to bug-glibc@prep.ai.mit.edu.
  *
- ************************************************************************/
-
-/* Written Bob Deblier <bob@virtualunlimited.com>         */
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2, or (at your option) any
+ * later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+/* Written by Ulrich Drepper <drepper@gnu.ai.mit.edu>, 1995.  */
+
 /* Hacked to work with samhain by R. Wichmann             */
-/* Need for 64bit type removed, fix for Mac OS X compiler */
-
-typedef sh_word32     uint32;
-typedef unsigned char uint8;
-
-
-
+
+typedef UINT32 md5_uint32;
 
 
 /* Structure to save state of computation between the single steps.  */
-typedef struct
-{
-        uint32 h[4];
-        uint32 data[16];
-        uint8  offset;
-        uint32  nblocks;
-        int  count;
+typedef struct md5_ctx
+{
+  md5_uint32 A;
+  md5_uint32 B;
+  md5_uint32 C;
+  md5_uint32 D;
+
+  md5_uint32 total[2];
+  md5_uint32 buflen;
+  char buffer[128];
 } md5Param;
 
-static uint32 md5hinit[4] = { 0x67452301, 0xefcdab89, 0x98badcfe, 0x10325476 };
+/*
+ * The following three functions are build up the low level used in
+ * the functions `md5_stream' and `md5_buffer'.
+ */
+
+/* Initialize structure containing state of computation.
+   (RFC 1321, 3.3: Step 3)  */
+static void md5_init_ctx (struct md5_ctx *ctx);
+
+/* Starting with the result of former calls of this function (or the
+   initialization function update the context for the next LEN bytes
+   starting at BUFFER.
+   It is necessary that LEN is a multiple of 64!!! */
+static void md5_process_block (const void *buffer, size_t len,
+				    struct md5_ctx *ctx);
+
+/* Starting with the result of former calls of this function (or the
+   initialization function update the context for the next LEN bytes
+   starting at BUFFER.
+   It is NOT required that LEN is a multiple of 64.  */
+static void md5_process_bytes (const void *buffer, size_t len,
+				    struct md5_ctx *ctx);
+
+/* Process the remaining bytes in the buffer and put result from CTX
+   in first 16 bytes following RESBUF.  The result is always in little
+   endian byte order, so that a byte-wise output yields to the wanted
+   ASCII representation of the message digest.
+
+   IMPORTANT: On some systems it is required that RESBUF is correctly
+   aligned for a 32 bits value.  */
+static void *md5_finish_ctx (struct md5_ctx *ctx, void *resbuf);
+
+
+/* Put result from CTX in first 16 bytes following RESBUF.  The result is
+   always in little endian byte order, so that a byte-wise output yields
+   to the wanted ASCII representation of the message digest.
+
+   IMPORTANT: On some systems it is required that RESBUF is correctly
+   aligned for a 32 bits value.  */
+static void *md5_read_ctx (const struct md5_ctx *ctx, void *resbuf);
+
+#if WORDS_BIGENDIAN
+static md5_uint32 swapu32(md5_uint32 n)
+{
+  return (    ((n & 0xffU) << 24) |
+	      ((n & 0xff00U) << 8) |
+	      ((n & 0xff0000U) >> 8) |
+	      ((n & 0xff000000U) >> 24) );
+}
+#define SWAP(n) swapu32(n)
+#else
+#define SWAP(n) (n)
+#endif
+
+/* This array contains the bytes used to pad the buffer to the next
+   64-byte boundary.  (RFC 1321, 3.1: Step 1)  */
+static const unsigned char fillbuf[64] = { 0x80, 0 /* , 0, 0, ...  */  };
+
+/* Initialize structure containing state of computation.
+   (RFC 1321, 3.3: Step 3)  */
+static void md5_init_ctx(struct md5_ctx *ctx)
+{
+  ctx->A = 0x67452301;
+  ctx->B = 0xefcdab89;
+  ctx->C = 0x98badcfe;
+  ctx->D = 0x10325476;
+
+  ctx->total[0] = ctx->total[1] = 0;
+  ctx->buflen = 0;
+}
+
+/* Put result from CTX in first 16 bytes following RESBUF.  The result
+   must be in little endian byte order.
+
+   IMPORTANT: On some systems it is required that RESBUF is correctly
+   aligned for a 32 bits value.  */
+static void *md5_read_ctx(const struct md5_ctx *ctx, void *resbuf)
+{
+  ((md5_uint32 *) resbuf)[0] = SWAP(ctx->A);
+  ((md5_uint32 *) resbuf)[1] = SWAP(ctx->B);
+  ((md5_uint32 *) resbuf)[2] = SWAP(ctx->C);
+  ((md5_uint32 *) resbuf)[3] = SWAP(ctx->D);
+
+  return resbuf;
+}
+
+/* Process the remaining bytes in the internal buffer and the usual
+   prolog according to the standard and write the result to RESBUF.
+
+   IMPORTANT: On some systems it is required that RESBUF is correctly
+   aligned for a 32 bits value.  */
+static void *md5_finish_ctx(struct md5_ctx *ctx, void *resbuf)
+{
+  /* Take yet unprocessed bytes into account.  */
+  md5_uint32 bytes = ctx->buflen;
+  size_t pad;
+
+  /* Now count remaining bytes.  */
+  ctx->total[0] += bytes;
+  if (ctx->total[0] < bytes)
+    ++ctx->total[1];
+
+  pad = bytes >= 56 ? 64 + 56 - bytes : 56 - bytes;
+  memcpy(&ctx->buffer[bytes], fillbuf, pad);
+
+  /* Put the 64-bit file length in *bits* at the end of the buffer.  */
+  *(md5_uint32 *) & ctx->buffer[bytes + pad] = SWAP(ctx->total[0] << 3);
+  *(md5_uint32 *) & ctx->buffer[bytes + pad + 4] =
+    SWAP((ctx->total[1] << 3) | (ctx->total[0] >> 29));
+
+  /* Process last bytes.  */
+  md5_process_block(ctx->buffer, bytes + pad + 8, ctx);
+
+  return md5_read_ctx(ctx, resbuf);
+}
+
+/* Compute MD5 message digest for LEN bytes beginning at BUFFER.  The
+   result is always in little endian byte order, so that a byte-wise
+   output yields to the wanted ASCII representation of the message
+   digest.  */
+void *md5_buffer(const char *buffer, size_t len, void *resblock)
+{
+  struct md5_ctx ctx;
+
+  /* Initialize the computation context.  */
+  md5_init_ctx(&ctx);
+
+  /* Process whole buffer but last len % 64 bytes.  */
+  md5_process_bytes(buffer, len, &ctx);
+
+  /* Put result in desired memory area.  */
+  return md5_finish_ctx(&ctx, resblock);
+}
+
+static void md5_process_bytes(const void *buffer, size_t len, struct md5_ctx *ctx)
+{
+  /* When we already have some bits in our internal buffer concatenate
+     both inputs first.  */
+  if (ctx->buflen != 0) {
+    size_t left_over = ctx->buflen;
+    size_t add = 128 - left_over > len ? len : 128 - left_over;
+
+    memcpy(&ctx->buffer[left_over], buffer, add);
+    ctx->buflen += add;
+
+    if (left_over + add > 64) {
+      md5_process_block(ctx->buffer, (left_over + add) & ~63, ctx);
+      /* The regions in the following copy operation cannot overlap.  */
+      memcpy(ctx->buffer, &ctx->buffer[(left_over + add) & ~63],
+	     (left_over + add) & 63);
+      ctx->buflen = (left_over + add) & 63;
+    }
+
+    buffer = (const char *) buffer + add;
+    len -= add;
+  }
+
+  /* Process available complete blocks.  */
+  if (len > 64) {
+    md5_process_block(buffer, len & ~63, ctx);
+    buffer = (const char *) buffer + (len & ~63);
+    len &= 63;
+  }
+
+  /* Move remaining bytes in internal buffer.  */
+  if (len > 0) {
+    memcpy(ctx->buffer, buffer, len);
+    ctx->buflen = len;
+  }
+}
+
+/* These are the four functions used in the four steps of the MD5 algorithm
+   and defined in the RFC 1321.  The first function is a little bit optimized
+   (as found in Colin Plumbs public domain implementation).  */
+/* #define FF(b, c, d) ((b & c) | (~b & d)) */
+#define FF(b, c, d) (d ^ (b & (c ^ d)))
+#define FG(b, c, d) FF (d, b, c)
+#define FH(b, c, d) (b ^ c ^ d)
+#define FI(b, c, d) (c ^ (b | ~d))
+
+/* Process LEN bytes of BUFFER, accumulating context into CTX.
+   It is assumed that LEN % 64 == 0.  */
+static void md5_process_block(const void *buffer, size_t len, struct md5_ctx *ctx)
+{
+  md5_uint32 correct_words[16];
+  const md5_uint32 *words = buffer;
+  size_t nwords = len / sizeof(md5_uint32);
+  const md5_uint32 *endp = words + nwords;
+  md5_uint32 A = ctx->A;
+  md5_uint32 B = ctx->B;
+  md5_uint32 C = ctx->C;
+  md5_uint32 D = ctx->D;
+
+  /* First increment the byte count.  RFC 1321 specifies the possible
+     length of the file up to 2^64 bits.  Here we only compute the
+     number of bytes.  Do a double word increment.  */
+  ctx->total[0] += len;
+  if (ctx->total[0] < len)
+    ++ctx->total[1];
+
+  /* Process all bytes in the buffer with 64 bytes in each round of
+     the loop.  */
+  while (words < endp) {
+    md5_uint32 *cwp = correct_words;
+    md5_uint32 A_save = A;
+    md5_uint32 B_save = B;
+    md5_uint32 C_save = C;
+    md5_uint32 D_save = D;
+
+    /* First round: using the given function, the context and a constant
+       the next context is computed.  Because the algorithms processing
+       unit is a 32-bit word and it is determined to work on words in
+       little endian byte order we perhaps have to change the byte order
+       before the computation.  To reduce the work for the next steps
+       we store the swapped words in the array CORRECT_WORDS.  */
+
+#define OP(a, b, c, d, s, T)						\
+      do								\
+        {								\
+	  a += FF (b, c, d) + (*cwp++ = SWAP (*words)) + T;		\
+	  ++words;							\
+	  CYCLIC (a, s);						\
+	  a += b;							\
+        }								\
+      while (0)
+
+    /* It is unfortunate that C does not provide an operator for
+       cyclic rotation.  Hope the C compiler is smart enough.  */
+#define CYCLIC(w, s) (w = (w << s) | (w >> (32 - s)))
+
+    /* Before we start, one word to the strange constants.
+       They are defined in RFC 1321 as
+
+       T[i] = (int) (4294967296.0 * fabs (sin (i))), i=1..64
+    */
+
+    /* Round 1.  */
+    OP(A, B, C, D, 7, 0xd76aa478);
+    OP(D, A, B, C, 12, 0xe8c7b756);
+    OP(C, D, A, B, 17, 0x242070db);
+    OP(B, C, D, A, 22, 0xc1bdceee);
+    OP(A, B, C, D, 7, 0xf57c0faf);
+    OP(D, A, B, C, 12, 0x4787c62a);
+    OP(C, D, A, B, 17, 0xa8304613);
+    OP(B, C, D, A, 22, 0xfd469501);
+    OP(A, B, C, D, 7, 0x698098d8);
+    OP(D, A, B, C, 12, 0x8b44f7af);
+    OP(C, D, A, B, 17, 0xffff5bb1);
+    OP(B, C, D, A, 22, 0x895cd7be);
+    OP(A, B, C, D, 7, 0x6b901122);
+    OP(D, A, B, C, 12, 0xfd987193);
+    OP(C, D, A, B, 17, 0xa679438e);
+    OP(B, C, D, A, 22, 0x49b40821);
+    /* For the second to fourth round we have the possibly swapped words
+       in CORRECT_WORDS.  Redefine the macro to take an additional first
+       argument specifying the function to use.  */
+#undef OP
+#define OP(f, a, b, c, d, k, s, T)					\
+      do 								\
+	{								\
+	  a += f (b, c, d) + correct_words[k] + T;			\
+	  CYCLIC (a, s);						\
+	  a += b;							\
+	}								\
+      while (0)
+
+    /* Round 2.  */
+    OP(FG, A, B, C, D, 1, 5, 0xf61e2562);
+    OP(FG, D, A, B, C, 6, 9, 0xc040b340);
+    OP(FG, C, D, A, B, 11, 14, 0x265e5a51);
+    OP(FG, B, C, D, A, 0, 20, 0xe9b6c7aa);
+    OP(FG, A, B, C, D, 5, 5, 0xd62f105d);
+    OP(FG, D, A, B, C, 10, 9, 0x02441453);
+    OP(FG, C, D, A, B, 15, 14, 0xd8a1e681);
+    OP(FG, B, C, D, A, 4, 20, 0xe7d3fbc8);
+    OP(FG, A, B, C, D, 9, 5, 0x21e1cde6);
+    OP(FG, D, A, B, C, 14, 9, 0xc33707d6);
+    OP(FG, C, D, A, B, 3, 14, 0xf4d50d87);
+    OP(FG, B, C, D, A, 8, 20, 0x455a14ed);
+    OP(FG, A, B, C, D, 13, 5, 0xa9e3e905);
+    OP(FG, D, A, B, C, 2, 9, 0xfcefa3f8);
+    OP(FG, C, D, A, B, 7, 14, 0x676f02d9);
+    OP(FG, B, C, D, A, 12, 20, 0x8d2a4c8a);
+
+    /* Round 3.  */
+    OP(FH, A, B, C, D, 5, 4, 0xfffa3942);
+    OP(FH, D, A, B, C, 8, 11, 0x8771f681);
+    OP(FH, C, D, A, B, 11, 16, 0x6d9d6122);
+    OP(FH, B, C, D, A, 14, 23, 0xfde5380c);
+    OP(FH, A, B, C, D, 1, 4, 0xa4beea44);
+    OP(FH, D, A, B, C, 4, 11, 0x4bdecfa9);
+    OP(FH, C, D, A, B, 7, 16, 0xf6bb4b60);
+    OP(FH, B, C, D, A, 10, 23, 0xbebfbc70);
+    OP(FH, A, B, C, D, 13, 4, 0x289b7ec6);
+    OP(FH, D, A, B, C, 0, 11, 0xeaa127fa);
+    OP(FH, C, D, A, B, 3, 16, 0xd4ef3085);
+    OP(FH, B, C, D, A, 6, 23, 0x04881d05);
+    OP(FH, A, B, C, D, 9, 4, 0xd9d4d039);
+    OP(FH, D, A, B, C, 12, 11, 0xe6db99e5);
+    OP(FH, C, D, A, B, 15, 16, 0x1fa27cf8);
+    OP(FH, B, C, D, A, 2, 23, 0xc4ac5665);
+
+    /* Round 4.  */
+    OP(FI, A, B, C, D, 0, 6, 0xf4292244);
+    OP(FI, D, A, B, C, 7, 10, 0x432aff97);
+    OP(FI, C, D, A, B, 14, 15, 0xab9423a7);
+    OP(FI, B, C, D, A, 5, 21, 0xfc93a039);
+    OP(FI, A, B, C, D, 12, 6, 0x655b59c3);
+    OP(FI, D, A, B, C, 3, 10, 0x8f0ccc92);
+    OP(FI, C, D, A, B, 10, 15, 0xffeff47d);
+    OP(FI, B, C, D, A, 1, 21, 0x85845dd1);
+    OP(FI, A, B, C, D, 8, 6, 0x6fa87e4f);
+    OP(FI, D, A, B, C, 15, 10, 0xfe2ce6e0);
+    OP(FI, C, D, A, B, 6, 15, 0xa3014314);
+    OP(FI, B, C, D, A, 13, 21, 0x4e0811a1);
+    OP(FI, A, B, C, D, 4, 6, 0xf7537e82);
+    OP(FI, D, A, B, C, 11, 10, 0xbd3af235);
+    OP(FI, C, D, A, B, 2, 15, 0x2ad7d2bb);
+    OP(FI, B, C, D, A, 9, 21, 0xeb86d391);
+
+    /* Add the starting values of the context.  */
+    A += A_save;
+    B += B_save;
+    C += C_save;
+    D += D_save;
+  }
+
+  /* Put checksum in context given as argument.  */
+  ctx->A = A;
+  ctx->B = B;
+  ctx->C = C;
+  ctx->D = D;
+}
+
+
+/*----------------------------------------------------------------------------
+ *--------end of md5.c
+ *----------------------------------------------------------------------------*/
 
  
@@ -438,265 +789,41 @@
 {
         unsigned int i;
-        memcpy(p->h, md5hinit, 16);
+
+        md5_init_ctx(p);
 	
         for (i = 0; i < 16; i += 8)
 	  {
-	    p->data[i]   = 0x00;
-	    p->data[i+1] = 0x00;
-	    p->data[i+2] = 0x00;
-	    p->data[i+3] = 0x00;
-	    p->data[i+4] = 0x00;
-	    p->data[i+5] = 0x00;
-	    p->data[i+6] = 0x00;
-	    p->data[i+7] = 0x00;
+	    p->buffer[i]   = 0x00;
+	    p->buffer[i+1] = 0x00;
+	    p->buffer[i+2] = 0x00;
+	    p->buffer[i+3] = 0x00;
+	    p->buffer[i+4] = 0x00;
+	    p->buffer[i+5] = 0x00;
+	    p->buffer[i+6] = 0x00;
+	    p->buffer[i+7] = 0x00;
 	  }
 	
-        /* memset(p->data, 0x00, 64); */
-        p->offset = (uint8) 0;
-	p->nblocks = 0;
         return 0;
 }
 
-#if defined(__GNUC__) && defined(__i386__)
-static inline UINT32
-ROTL32( UINT32 x, int s)
-{
-        __asm__("roll %%cl,%0"
-                :"=r" (x)
-                :"0" (x),"c" (s));
-        return x;
-}
-#else
-#define ROTL32(x, s) (((x) << (s)) | ((x) >> (32 - (s))))
-#endif
-
-
-#define FF(a, b, c, d, w, s, t) \
-        a += ((b&(c^d))^d) + w + t;     \
-        a = ROTL32(a, s);       \
-        a += b;
-
-#define GG(a, b, c, d, w, s, t) \
-        a += ((d&(b^c))^c) + w + t;     \
-        a = ROTL32(a, s);       \
-        a += b;
-
-#define HH(a, b, c, d, w, s, t) \
-        a += (b^c^d) + w + t;   \
-        a = ROTL32(a, s);       \
-        a += b;
-
-#define II(a, b, c, d, w, s, t) \
-        a += (c^(b|~d)) + w + t;        \
-        a = ROTL32(a, s);       \
-        a += b;
-
-#if WORDS_BIGENDIAN
-uint32 swapu32(uint32 n)
-{
-        return (    ((n & 0xffU) << 24) |
-                                ((n & 0xff00U) << 8) |
-                                ((n & 0xff0000U) >> 8) |
-                                ((n & 0xff000000U) >> 24) );
-}
-#endif
-
-static
-void md5Process(md5Param* p)
-{
-        register uint32 a,b,c,d;
-        register uint32* w;
-        #if WORDS_BIGENDIAN
-        register sh_byte t;
-        #endif
-
-        w = p->data;
-        #if WORDS_BIGENDIAN
-        t = 16;
-        while (t--)
-        {
-                register uint32 temp = swapu32(*w);
-                *(w++) = temp;
-        }
-        w = p->data;
-        #endif
-
-        a = p->h[0]; b = p->h[1]; c = p->h[2]; d = p->h[3];
-
-        FF(a, b, c, d, (*w++),  7, 0xd76aa478);
-        FF(d, a, b, c, (*w++), 12, 0xe8c7b756);
-        FF(c, d, a, b, (*w++), 17, 0x242070db);
-        FF(b, c, d, a, (*w++), 22, 0xc1bdceee);
-        FF(a, b, c, d, (*w++),  7, 0xf57c0faf);
-        FF(d, a, b, c, (*w++), 12, 0x4787c62a);
-        FF(c, d, a, b, (*w++), 17, 0xa8304613);
-        FF(b, c, d, a, (*w++), 22, 0xfd469501);
-        FF(a, b, c, d, (*w++),  7, 0x698098d8);
-        FF(d, a, b, c, (*w++), 12, 0x8b44f7af);
-        FF(c, d, a, b, (*w++), 17, 0xffff5bb1);
-        FF(b, c, d, a, (*w++), 22, 0x895cd7be);
-        FF(a, b, c, d, (*w++),  7, 0x6b901122);
-        FF(d, a, b, c, (*w++), 12, 0xfd987193);
-        FF(c, d, a, b, (*w++), 17, 0xa679438e);
-        FF(b, c, d, a, (*w++), 22, 0x49b40821);
-
-	w = p->data;
-
-        GG(a, b, c, d, w[ 1],  5, 0xf61e2562);
-        GG(d, a, b, c, w[ 6],  9, 0xc040b340);
-        GG(c, d, a, b, w[11], 14, 0x265e5a51);
-        GG(b, c, d, a, w[ 0], 20, 0xe9b6c7aa);
-        GG(a, b, c, d, w[ 5],  5, 0xd62f105d);
-        GG(d, a, b, c, w[10],  9, 0x02441453);
-        GG(c, d, a, b, w[15], 14, 0xd8a1e681);
-        GG(b, c, d, a, w[ 4], 20, 0xe7d3fbc8);
-        GG(a, b, c, d, w[ 9],  5, 0x21e1cde6);
-        GG(d, a, b, c, w[14],  9, 0xc33707d6);
-        GG(c, d, a, b, w[ 3], 14, 0xf4d50d87);
-        GG(b, c, d, a, w[ 8], 20, 0x455a14ed);
-        GG(a, b, c, d, w[13],  5, 0xa9e3e905);
-        GG(d, a, b, c, w[ 2],  9, 0xfcefa3f8);
-        GG(c, d, a, b, w[ 7], 14, 0x676f02d9);
-        GG(b, c, d, a, w[12], 20, 0x8d2a4c8a);
-
-        HH(a, b, c, d, w[ 5],  4, 0xfffa3942);
-        HH(d, a, b, c, w[ 8], 11, 0x8771f681);
-        HH(c, d, a, b, w[11], 16, 0x6d9d6122);
-        HH(b, c, d, a, w[14], 23, 0xfde5380c);
-        HH(a, b, c, d, w[ 1],  4, 0xa4beea44);
-        HH(d, a, b, c, w[ 4], 11, 0x4bdecfa9);
-        HH(c, d, a, b, w[ 7], 16, 0xf6bb4b60);
-        HH(b, c, d, a, w[10], 23, 0xbebfbc70);
-        HH(a, b, c, d, w[13],  4, 0x289b7ec6);
-        HH(d, a, b, c, w[ 0], 11, 0xeaa127fa);
-        HH(c, d, a, b, w[ 3], 16, 0xd4ef3085);
-        HH(b, c, d, a, w[ 6], 23, 0x04881d05);
-        HH(a, b, c, d, w[ 9],  4, 0xd9d4d039);
-        HH(d, a, b, c, w[12], 11, 0xe6db99e5);
-        HH(c, d, a, b, w[15], 16, 0x1fa27cf8);
-        HH(b, c, d, a, w[ 2], 23, 0xc4ac5665);
-
-        II(a, b, c, d, w[ 0],  6, 0xf4292244);
-        II(d, a, b, c, w[ 7], 10, 0x432aff97);
-        II(c, d, a, b, w[14], 15, 0xab9423a7);
-        II(b, c, d, a, w[ 5], 21, 0xfc93a039);
-        II(a, b, c, d, w[12],  6, 0x655b59c3);
-        II(d, a, b, c, w[ 3], 10, 0x8f0ccc92);
-        II(c, d, a, b, w[10], 15, 0xffeff47d);
-        II(b, c, d, a, w[ 1], 21, 0x85845dd1);
-        II(a, b, c, d, w[ 8],  6, 0x6fa87e4f);
-        II(d, a, b, c, w[15], 10, 0xfe2ce6e0);
-        II(c, d, a, b, w[ 6], 15, 0xa3014314);
-        II(b, c, d, a, w[13], 21, 0x4e0811a1);
-        II(a, b, c, d, w[ 4],  6, 0xf7537e82);
-        II(d, a, b, c, w[11], 10, 0xbd3af235);
-        II(c, d, a, b, w[ 2], 15, 0x2ad7d2bb);
-        II(b, c, d, a, w[ 9], 21, 0xeb86d391);
-
-        p->h[0] += a;
-        p->h[1] += b;
-        p->h[2] += c;
-        p->h[3] += d;
-}
-
 int md5Update(md5Param* p, const sh_byte* data, int size)
 {
-        register int proclength;
-
-        while (size > 0)
-        {
-	  proclength = (((int)p->offset + size) > 64) ? 
-	    (64 - (int)p->offset) : size;
-	  memcpy(((sh_byte *) p->data) + p->offset, data, (size_t) proclength);
-	  size -= proclength;
-	  data += proclength;
-	  p->offset += proclength;
-	  
-	  if (p->offset == (uint8) 64)
-	    {
-	      md5Process(p);
-	      p->offset = (uint8) 0;
-	      p->nblocks++;
-	    }
-        }
-        return 0;
-}
-
-static void md5Finish(md5Param* p)
-{
-        uint32 t, msb, lsb;
-	uint8 * pp;
-        register uint8 *ptr;
-
-        msb = 0;
-	t = p->nblocks;
-	if( (lsb = t << 6) < t ) /* multiply by 64 to make a byte count */
-	  msb++;
-	msb += t >> 26;
-	t = lsb;
-	if( (lsb = t + (uint32)p->offset) < t ) /* add the count */
-	  msb++;
-	t = lsb;
-	if( (lsb = t << 3) < t ) /* multiply by 8 to make a bit count */
-	  msb++;
-	msb += t >> 29;
-
-	ptr = ((uint8 *) p->data) + p->offset++;
-
- 
-        *(ptr++) = (uint8) 0x80;
-
-        if (p->offset > (uint8)56)
-        {
-                while (p->offset++ < 64)
-                        *(ptr++) = 0;
-
-                md5Process(p);
-                p->offset = 0;
-        }
-
-        ptr = ((uint8 *) p->data) + p->offset;
-        while (p->offset++ < 56)
-                *(ptr++) = 0;
-
-	/* append the 64 bit count */
-	*(ptr++) = lsb	   ;
-	*(ptr++) = lsb >>  8;
-	*(ptr++) = lsb >> 16;
-	*(ptr++) = lsb >> 24;
-	*(ptr++) = msb	   ;
-	*(ptr++) = msb >>  8;
-	*(ptr++) = msb >> 16;
-	*(ptr++) = msb >> 24;
-
-        md5Process(p);
-
-	pp = (uint8 *) p->data;
-#ifdef WORDS_BIGENDIAN
-#define X(a) do { *pp++ = (*p).a; *pp++ = (*p).a >> 8;      \
-		  *pp++ = (*p).a >> 16; *pp++ = (*p).a >> 24; } while(0)
-#else /* little endian */
-    /*#define X(a) do { *(uint32*)p = p->##a ; p += 4; } while(0)*/
-    /* Unixware's cpp doesn't like the above construct so we do it his way:
-     * (reported by Allan Clark) */
-#define X(a) do { *(uint32*)pp = (*p).a ; pp += 4; } while(0)
-#endif
-	X(h[0]);
-	X(h[1]);
-	X(h[2]);
-	X(h[3]);
-#undef X
-
-        p->offset = 0;
-}
-
-int md5Digest(md5Param* p, uint32* data)
-{
-        md5Finish(p);
-        memcpy(data, p->h, 16);
+  md5_process_bytes(data, size, p);
+  return 0;
+}
+
+static void md5Finish(md5Param* p, void *resblock)
+{
+  (void) md5_finish_ctx(p, resblock);
+}
+
+int md5Digest(md5Param* p, md5_uint32* data)
+{
+        md5Finish(p, data);
         (void) md5Reset(p);
         return 0;
 }
 /*@+type@*/
+
 
 /* Compute MD5 message digest for bytes read from STREAM.  The
@@ -708,7 +835,8 @@
   /* Important: BLOCKSIZE must be a multiple of 64.  */
   static const int BLOCKSIZE = 8192;
-  md5Param ctx;
+  struct md5_ctx ctx;
   char buffer[8264]; /* BLOCKSIZE + 72  AIX compiler chokes */
-  off_t sum = 0;
+  size_t sum;
+
   SL_TICKET  fd;
   char * tmp;
@@ -797,5 +925,5 @@
        BLOCKSIZE % 64 == 0
     */
-    (void) md5Update(&ctx, (sh_byte*) buffer, BLOCKSIZE);
+    md5_process_block(buffer, BLOCKSIZE, &ctx);
     sh.statistics.bytes_hashed += BLOCKSIZE;
 
@@ -816,5 +944,5 @@
   if (sum > 0)
     {
-      (void) md5Update(&ctx, (sh_byte*) buffer, (int) sum);
+      md5_process_bytes(buffer, sum, &ctx);
       sh.statistics.bytes_hashed += BLOCKSIZE;
     }
