-int HASH_UPDATE (HASH_CTX *c, const void *data_, unsigned long len)
- {
- const unsigned char *data=data_;
- register HASH_LONG * p;
- register unsigned long l;
- int sw,sc,ew,ec;
-
- if (len==0) return 1;
-
- l=(c->Nl+(len<<3))&0xffffffffL;
- /* 95-05-24 eay Fixed a bug with the overflow handling, thanks to
- * Wei Dai <weidai@eskimo.com> for pointing it out. */
- if (l < c->Nl) /* overflow */
- c->Nh++;
- c->Nh+=(len>>29);
- c->Nl=l;
-
- if (c->num != 0)
- {
- p=c->data;
- sw=c->num>>2;
- sc=c->num&0x03;
-
- if ((c->num+len) >= HASH_CBLOCK)
- {
- l=p[sw]; HOST_p_c2l(data,l,sc); p[sw++]=l;
- for (; sw<HASH_LBLOCK; sw++)
- {
- HOST_c2l(data,l); p[sw]=l;
- }
- HASH_BLOCK_HOST_ORDER (c,p,1);
- len-=(HASH_CBLOCK-c->num);
- c->num=0;
- /* drop through and do the rest */
- }
- else
- {
- c->num+=len;
- if ((sc+len) < 4) /* ugly, add char's to a word */
- {
- l=p[sw]; HOST_p_c2l_p(data,l,sc,len); p[sw]=l;
- }
- else
- {
- ew=(c->num>>2);
- ec=(c->num&0x03);
- if (sc)
- l=p[sw];
- HOST_p_c2l(data,l,sc);
- p[sw++]=l;
- for (; sw < ew; sw++)
- {
- HOST_c2l(data,l); p[sw]=l;
- }
- if (ec)
- {
- HOST_c2l_p(data,l,ec); p[sw]=l;
- }
- }
- return 1;
- }
- }
-
- sw=len/HASH_CBLOCK;
- if (sw > 0)
- {
-#if defined(HASH_BLOCK_DATA_ORDER_ALIGNED)
- /*
- * Note that HASH_BLOCK_DATA_ORDER_ALIGNED gets defined
- * only if sizeof(HASH_LONG)==4.
- */
- if ((((unsigned long)data)%4) == 0)
- {
- /* data is properly aligned so that we can cast it: */
- HASH_BLOCK_DATA_ORDER_ALIGNED (c,(const HASH_LONG *)data,sw);
- sw*=HASH_CBLOCK;
- data+=sw;
- len-=sw;
- }
- else
-#if !defined(HASH_BLOCK_DATA_ORDER)
- while (sw--)
- {
- memcpy (p=c->data,data,HASH_CBLOCK);
- HASH_BLOCK_DATA_ORDER_ALIGNED(c,p,1);
- data+=HASH_CBLOCK;
- len-=HASH_CBLOCK;
- }
-#endif
-#endif
-#if defined(HASH_BLOCK_DATA_ORDER)
- {
- HASH_BLOCK_DATA_ORDER(c,data,sw);
- sw*=HASH_CBLOCK;
- data+=sw;
- len-=sw;
- }
-#endif
- }
-
- if (len!=0)
- {
- p = c->data;
- c->num = len;
- ew=len>>2; /* words to copy */
- ec=len&0x03;
- for (; ew; ew--,p++)
- {
- HOST_c2l(data,l); *p=l;
- }
- HOST_c2l_p(data,l,ec);
- *p=l;
- }
- return 1;
- }
-
-
-void HASH_TRANSFORM (HASH_CTX *c, const unsigned char *data)
- {
-#if defined(HASH_BLOCK_DATA_ORDER_ALIGNED)
- if ((((unsigned long)data)%4) == 0)
- /* data is properly aligned so that we can cast it: */
- HASH_BLOCK_DATA_ORDER_ALIGNED (c,(const HASH_LONG *)data,1);
- else
-#if !defined(HASH_BLOCK_DATA_ORDER)
- {
- memcpy (c->data,data,HASH_CBLOCK);
- HASH_BLOCK_DATA_ORDER_ALIGNED (c,c->data,1);
- }
-#endif
-#endif
-#if defined(HASH_BLOCK_DATA_ORDER)
- HASH_BLOCK_DATA_ORDER (c,data,1);
-#endif
- }
-
-
-int HASH_FINAL (unsigned char *md, HASH_CTX *c)
- {
- register HASH_LONG *p;
- register unsigned long l;
- register int i,j;
- static const unsigned char end[4]={0x80,0x00,0x00,0x00};
- const unsigned char *cp=end;
-
- /* c->num should definitly have room for at least one more byte. */
- p=c->data;
- i=c->num>>2;
- j=c->num&0x03;
-
-#if 0
- /* purify often complains about the following line as an
- * Uninitialized Memory Read. While this can be true, the
- * following p_c2l macro will reset l when that case is true.
- * This is because j&0x03 contains the number of 'valid' bytes
- * already in p[i]. If and only if j&0x03 == 0, the UMR will
- * occur but this is also the only time p_c2l will do
- * l= *(cp++) instead of l|= *(cp++)
- * Many thanks to Alex Tang <altitude@cic.net> for pickup this
- * 'potential bug' */
-#ifdef PURIFY
- if (j==0) p[i]=0; /* Yeah, but that's not the way to fix it:-) */
-#endif
- l=p[i];
-#else
- l = (j==0) ? 0 : p[i];
-#endif
- HOST_p_c2l(cp,l,j); p[i++]=l; /* i is the next 'undefined word' */
-
- if (i>(HASH_LBLOCK-2)) /* save room for Nl and Nh */
- {
- if (i<HASH_LBLOCK) p[i]=0;
- HASH_BLOCK_HOST_ORDER (c,p,1);
- i=0;
- }
- for (; i<(HASH_LBLOCK-2); i++)
- p[i]=0;
-
+int HASH_UPDATE(HASH_CTX *c, const void *data_, size_t len)
+{
+ const unsigned char *data = data_;
+ unsigned char *p;
+ HASH_LONG l;
+ size_t n;
+
+ if (len == 0)
+ return 1;
+
+ l = (c->Nl + (((HASH_LONG) len) << 3)) & 0xffffffffUL;
+ /*
+ * 95-05-24 eay Fixed a bug with the overflow handling, thanks to Wei Dai
+ * <weidai@eskimo.com> for pointing it out.
+ */
+ if (l < c->Nl) /* overflow */
+ c->Nh++;
+ c->Nh += (HASH_LONG) (len >> 29); /* might cause compiler warning on
+ * 16-bit */
+ c->Nl = l;
+
+ n = c->num;
+ if (n != 0) {
+ p = (unsigned char *)c->data;
+
+ if (len >= HASH_CBLOCK || len + n >= HASH_CBLOCK) {
+ memcpy(p + n, data, HASH_CBLOCK - n);
+ HASH_BLOCK_DATA_ORDER(c, p, 1);
+ n = HASH_CBLOCK - n;
+ data += n;
+ len -= n;
+ c->num = 0;
+ memset(p, 0, HASH_CBLOCK); /* keep it zeroed */
+ } else {
+ memcpy(p + n, data, len);
+ c->num += (unsigned int)len;
+ return 1;
+ }
+ }
+
+ n = len / HASH_CBLOCK;
+ if (n > 0) {
+ HASH_BLOCK_DATA_ORDER(c, data, n);
+ n *= HASH_CBLOCK;
+ data += n;
+ len -= n;
+ }
+
+ if (len != 0) {
+ p = (unsigned char *)c->data;
+ c->num = (unsigned int)len;
+ memcpy(p, data, len);
+ }
+ return 1;
+}
+
+void HASH_TRANSFORM(HASH_CTX *c, const unsigned char *data)
+{
+ HASH_BLOCK_DATA_ORDER(c, data, 1);
+}
+
+int HASH_FINAL(unsigned char *md, HASH_CTX *c)
+{
+ unsigned char *p = (unsigned char *)c->data;
+ size_t n = c->num;
+
+ p[n] = 0x80; /* there is always room for one */
+ n++;
+
+ if (n > (HASH_CBLOCK - 8)) {
+ memset(p + n, 0, HASH_CBLOCK - n);
+ n = 0;
+ HASH_BLOCK_DATA_ORDER(c, p, 1);
+ }
+ memset(p + n, 0, HASH_CBLOCK - 8 - n);
+
+ p += HASH_CBLOCK - 8;