/* Implementation of NIST's Secure Hash Algorithm (FIPS 180-1)
*
* Adapted from an implementation by Jim Gillogly of 5 Jul 94
*
* LITTLE_ENDIAN mods from Peter Gutmann's implementation
*
* SHA-1 is a technical revision of the original SHA (FIPS 180)
* incorporating a fix for a weakness in SHA discovered by the
* National Security Agency.
*/
#ifndef HIGHFIRST /* Imported from Peter Gutmann's implementation */
/* When run on a little-endian CPU we need to perform byte reversal on an
array of longwords. It is possible to make the code endianness-
independant by fiddling around with data at the byte level, but this
makes for very slow code, so we rely on the user to sort out endianness
at compile time */
static void byteReverse( uint32 *buffer, int byteCount )
{
uint32 value;
int count;
#define r0(f, K) \
temp = S(5, A) + f(B, C, D) + E + *p0++ + K; \
E = D; \
D = C; \
C = S(30, B); \
B = A; \
A = temp
#ifdef VERSION_0
#define r1(f, K) \
temp = S(5, A) + f(B, C, D) + E + \
(*p0++ = *p1++ ^ *p2++ ^ *p3++ ^ *p4++) + K; \
E = D; \
D = C; \
C = S(30, B); \
B = A; \
A = temp
#else /* Version 1: Summer '94 update */
#define r1(f, K) \
temp = *p1++ ^ *p2++ ^ *p3++ ^ *p4++; \
temp = S(5, A) + f(B, C, D) + E + (*p0++ = S(1,temp)) + K; \
E = D; \
D = C; \
C = S(30, B); \
B = A; \
A = temp
#endif
/* This is the guts of the SHA1 calculation. If we can get 64 bytes into
the holding context->in buffer, we go ahead and process these bytes,
adding them to the accumulated message digest. If not, and finalize is
false, we just store however many bytes we can get for future use.
If finalize is true, we pad this block to 64 bytes and try to fit in the
accumulated bit length of the message (which we can do only if the
original block < 56 bytes). We return TRUE if we need to add one more
block to fit in the bit length. (Returned value is only significant if
finalize is true.) The pointer to the input buffer is advanced and its
length is updated in every case. */
int SHA1Update0(struct SHA1Context *context, unsigned char const **buf,
unsigned *len, int finalize)
{
int i, nread, nbits;
char *s;
register uint32 *p0, *p1, *p2, *p3, *p4;
uint32 A, B, C, D, E, temp;
/* Add one buffer's worth of bytes to the SHA1 calculation. If the number of
bytes in the buffer is not a multiple of 64, hold the bytes in the last
partial block in the context->in holding area for the next time this
routine is called. */
void SHA1Update(struct SHA1Context *context, unsigned char const *buf,
unsigned len)
{
unsigned len2 = len;
unsigned char const *buf2 = buf;
while (len2)
SHA1Update0(context, &buf2, &len2, FALSE);
#ifdef SHA1_DEBUG
if (SHA1_f)
fwrite(buf, 1, len, SHA1_f);
#endif
}
/* Finish off the SHA1 calculation by adding in the left over bytes in
context->in with padding and with the total bit length of the message.
May have to call SHA1Update0() twice, if there isn't enough room to
process the bit length the first time around. */
void SHA1Final(unsigned char digest[20], struct SHA1Context *context)
{
unsigned len = 0L;
uint32 *p = (uint32 *)digest;
while (SHA1Update0(context, (void *)NULL, &len, TRUE));
p[0] = context->h0; p[1] = context->h1; p[2] = context->h2;
p[3] = context->h3; p[4] = context->h4;
#ifdef SHA1_DEBUG
if (SHA1_f) {
char output_file[16];
FILE *g;
fclose(SHA1_f);
strcpy(output_file, current_dbg_file);
strcat(output_file, ".sha");
if (g = fopen(output_file,"w")) {
fprintf(g,"%08lx %08lx %08lx %08lx %08lx\n",
p[0], p[1], p[2], p[3], p[4]);
fclose(g);
}
SHA1_f = NULL;
}
#endif
#ifndef HIGHFIRST
byteReverse((uint32 *)digest, 20);
#endif
memset(context, 0, sizeof(context)); /* In case it's sensitive */
}
/* Note - the routines in this module, except for SHA1_addbuffer,
* do not "finish" the SHA1 calculation. SHA1_addbuffer finishes the
* calculation in each case, usually to append the timestamp and class info.
*/
/* Computes the message digest for a file from current position for
longcount bytes.
Uses the SHA-1 Message Digest Algorithm */
int SHA1file0_len(struct SHA1Context *shContext, FILE * f, word32 longcount)
{
int bytecount;
unsigned char buffer[1024];
SHA1Init(shContext);
/* Process 1024 bytes at a time... */
do {
if (longcount < (word32) 1024)
bytecount = (int) longcount;
else
bytecount = 1024;
bytecount = fread(buffer, 1, bytecount, f);
if (bytecount > 0) {
SHA1Update(shContext, buffer, bytecount);
longcount -= bytecount;
#ifdef MACPGP
mac_poll_for_break();
#endif
}
/* if text block was short, exit loop */
} while (bytecount == 1024);
return 0;
} /* SHA1file0_len */
/* Computes the message digest for a file from current position to EOF.
Uses the SHA1 Message Digest Algorithm */
static int SHA1file0(struct SHA1Context *shContext, FILE * inFile)
{
int bytes;
unsigned char buffer[1024];
if (inFile == NULL) {
fprintf(pgpout, LANG("\n\007Can't open file '%s'\n"), filename);
return -1;
}
SHA1file0(shContext, inFile);
fclose(inFile);
return 0;
}
/* Add a buffer's worth of data to the SHA1 computation. If a digest
* pointer is supplied, complete the computation and write the digest.
*/
void SHA1_addbuffer(struct SHA1Context *shContext, byte * buf, int buflen,
byte digest[20])
{
SHA1Update(shContext, buf, buflen);
if (digest) {
SHA1Final(digest, shContext);
burn(*shContext); /* Paranoia */
}
}