- 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+=(unsigned int)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 ((((size_t)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 ((((size_t)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;