/* * SHA: Add data to context. */ void SHA1_Update(SHA1Context *ctx, const unsigned char *dataIn, unsigned int len) { register unsigned int lenB; register unsigned int togo; if (!len) return; /* accumulate the byte count. */ lenB = (unsigned int)(ctx->size) & 63U; ctx->size += len; /* * Read the data into W and process blocks as they get full */ if (lenB > 0) { togo = 64U - lenB; if (len < togo) togo = len; memcpy(ctx->B + lenB, dataIn, togo); len -= togo; dataIn += togo; lenB = (lenB + togo) & 63U; if (!lenB) { shaCompress(&ctx->H[H2X], ctx->W); } } #if !defined(HAVE_UNALIGNED_ACCESS) if ((ptrdiff_t)dataIn % sizeof(PRUint32)) { while (len >= 64U) { memcpy(ctx->B, dataIn, 64); len -= 64U; shaCompress(&ctx->H[H2X], ctx->W); dataIn += 64U; } } else #endif { while (len >= 64U) { len -= 64U; shaCompress(&ctx->H[H2X], (PRUint32 *)dataIn); dataIn += 64U; } } if (len) { memcpy(ctx->B, dataIn, len); } }
/* * SHA: Generate hash value from context */ void SHA1_End(SHA1Context *ctx, unsigned char *hashout, unsigned int *pDigestLen, unsigned int maxDigestLen) { register PRUint64 size; register PRUint32 lenB; static const unsigned char bulk_pad[64] = { 0x80,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 }; #define tmp lenB PORT_Assert (maxDigestLen >= SHA1_LENGTH); /* * Pad with a binary 1 (e.g. 0x80), then zeroes, then length in bits */ size = ctx->size; lenB = (PRUint32)size & 63; SHA1_Update(ctx, bulk_pad, (((55+64) - lenB) & 63) + 1); PORT_Assert(((PRUint32)ctx->size & 63) == 56); /* Convert size from bytes to bits. */ size <<= 3; ctx->W[14] = SHA_HTONL((PRUint32)(size >> 32)); ctx->W[15] = SHA_HTONL((PRUint32)size); shaCompress(&ctx->H[H2X], ctx->W); /* * Output hash */ SHA_STORE_RESULT; *pDigestLen = SHA1_LENGTH; }