[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
SHA patch
Hello there,
After some work with the SHS (or is the implementation actually
the SHA?) code listed in _Applied Cryptography_, I have patched it to
allow updates of buffer sizes that are not a multiple of
SHS_BLOCKSIZE. The patched version works for the different groupings
of the test data "abc", e.g.,
update(abc)
update(a) + update(bc)
update(ab) + update(c)
Since the "abc" case tests only the logic of shsUpdate() [all the
transformation invocations are actually performed by shsFinal()], I
ran the original code and the modified code on several files and
(fortunately) received the same hash values for the two
implementations.
shsUpdate() follows. You may need to define a bcopy->memcpy macro.
michael
=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
void
shsUpdate(SHS_INFO *shsInfo, BYTE *buffer, int count)
{
int offset, need;
/* determine if there are left over bytes in the
shs data. they are handled specially below */
offset = (int) ((shsInfo->countLo >> 3) & 0x3f);
need = SHS_BLOCKSIZE - offset;
/* update bitcount */
if ((shsInfo->countLo + ((LONG) count << 3)) < shsInfo->countLo)
shsInfo->countHi++; /* carry from low to high bitCount */
shsInfo->countLo += ((LONG) count << 3);
shsInfo->countHi += ((LONG) count >> 29);
/* if there were indeed left over data bytes,
see if the incoming data is sufficient to
fill to SHS_BLOCKSIZE. if not, copy the
incoming data and return; otherwise fill
the block, perform a transformation, and
continue as usual */
if (offset)
{
if (count < need)
{
bcopy(buffer, (BYTE *) shsInfo->data + offset, count);
return;
}
else
{
bcopy(buffer, (BYTE *) shsInfo->data + offset, need);
#ifdef LITTLE_ENDIAN
byteReverse(shsInfo->data, SHS_BLOCKSIZE);
#endif
shsTransform(shsInfo);
buffer += need;
count -= need;
}
}
/* process data in SHS_BLOCKSIZE chunks */
while (count >= SHS_BLOCKSIZE)
{
bcopy(buffer, shsInfo->data, SHS_BLOCKSIZE);
#ifdef LITTLE_ENDIAN
byteReverse(shsInfo->data, SHS_BLOCKSIZE);
#endif
shsTransform(shsInfo);
buffer += SHS_BLOCKSIZE;
count -= SHS_BLOCKSIZE;
}
/* store the left over data */
bcopy(buffer, shsInfo->data, count);
}