sha1c.c revision 272461
11541Srgrimes/* crypto/sha/sha1dgst.c */
222521Sdyson/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
31541Srgrimes * All rights reserved.
41541Srgrimes *
51541Srgrimes * This package is an SSL implementation written
61541Srgrimes * by Eric Young (eay@cryptsoft.com).
71541Srgrimes * The implementation was written so as to conform with Netscapes SSL.
81541Srgrimes *
91541Srgrimes * This library is free for commercial and non-commercial use as long as
101541Srgrimes * the following conditions are aheared to.  The following conditions
111541Srgrimes * apply to all code found in this distribution, be it the RC4, RSA,
121541Srgrimes * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
131541Srgrimes * included with this distribution is covered by the same copyright terms
141541Srgrimes * except that the holder is Tim Hudson (tjh@cryptsoft.com).
151541Srgrimes *
161541Srgrimes * Copyright remains Eric Young's, and as such any Copyright notices in
171541Srgrimes * the code are not to be removed.
181541Srgrimes * If this package is used in a product, Eric Young should be given attribution
191541Srgrimes * as the author of the parts of the library used.
201541Srgrimes * This can be in the form of a textual message at program startup or
211541Srgrimes * in documentation (online or textual) provided with the package.
221541Srgrimes *
231541Srgrimes * Redistribution and use in source and binary forms, with or without
241541Srgrimes * modification, are permitted provided that the following conditions
251541Srgrimes * are met:
261541Srgrimes * 1. Redistributions of source code must retain the copyright
271541Srgrimes *    notice, this list of conditions and the following disclaimer.
281541Srgrimes * 2. Redistributions in binary form must reproduce the above copyright
291541Srgrimes *    notice, this list of conditions and the following disclaimer in the
301541Srgrimes *    documentation and/or other materials provided with the distribution.
311541Srgrimes * 3. All advertising materials mentioning features or use of this software
321541Srgrimes *    must display the following acknowledgement:
3322521Sdyson *    "This product includes cryptographic software written by
3430434Sphk *     Eric Young (eay@cryptsoft.com)"
351541Srgrimes *    The word 'cryptographic' can be left out if the rouines from the library
361541Srgrimes *    being used are not cryptographic related :-).
371541Srgrimes * 4. If you include any Windows specific code (or a derivative thereof) from
3822521Sdyson *    the apps directory (application code) you must include an acknowledgement:
3918020Sbde *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
4022600Smpp *
4130354Sphk * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
421541Srgrimes * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
431541Srgrimes * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
441541Srgrimes * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
4524205Sbde * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
4624131Sbde * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
471541Srgrimes * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
4829362Speter * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
497090Sbde * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
501541Srgrimes * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
511541Srgrimes * SUCH DAMAGE.
521541Srgrimes *
531541Srgrimes * The licence and distribution terms for any publically available version or
541541Srgrimes * derivative of this code cannot be changed.  i.e. this code cannot simply be
551541Srgrimes * copied and put under another distribution licence
561541Srgrimes * [including the GNU Public Licence.]
571541Srgrimes */
581541Srgrimes
591541Srgrimes#include <sys/cdefs.h>
601541Srgrimes__FBSDID("$FreeBSD: releng/10.1/lib/libmd/sha1c.c 154479 2006-01-17 15:35:57Z phk $");
611541Srgrimes
621541Srgrimes#include <sys/types.h>
6312820Sphk
6412820Sphk#include <stdio.h>
6512820Sphk#include <string.h>
6612158Sbde
6712820Sphk#if 0
6830431Sphk#include <machine/ansi.h>	/* we use the __ variants of bit-sized types */
6930431Sphk#endif
7030431Sphk#include <machine/endian.h>
7130431Sphk
7230434Sphk#undef  SHA_0
7330431Sphk#define SHA_1
7430431Sphk#include "sha.h"
7530431Sphk#include "sha_locl.h"
7630431Sphk
7730431Sphk/*
7830431Sphk * The assembly-language code is not position-independent, so don't
7930434Sphk * try to use it in a shared library.
8030431Sphk */
8130434Sphk#ifdef PIC
8230431Sphk#undef SHA1_ASM
8330431Sphk#endif
8430431Sphk
8530431Sphkchar *SHA1_version="SHA1 part of SSLeay 0.9.0b 11-Oct-1998";
8630431Sphk
8730431Sphk/* Implemented from SHA-1 document - The Secure Hash Algorithm
8830431Sphk */
8930431Sphk
9030434Sphk#define INIT_DATA_h0 (unsigned long)0x67452301L
9130431Sphk#define INIT_DATA_h1 (unsigned long)0xefcdab89L
9230431Sphk#define INIT_DATA_h2 (unsigned long)0x98badcfeL
9330431Sphk#define INIT_DATA_h3 (unsigned long)0x10325476L
9430431Sphk#define INIT_DATA_h4 (unsigned long)0xc3d2e1f0L
9530434Sphk
9630431Sphk#define K_00_19	0x5a827999L
9730431Sphk#define K_20_39 0x6ed9eba1L
9830431Sphk#define K_40_59 0x8f1bbcdcL
9930431Sphk#define K_60_79 0xca62c1d6L
10030431Sphk
10130431Sphk#ifndef NOPROTO
10230431Sphk#  ifdef SHA1_ASM
10330434Sphk     void sha1_block_x86(SHA_CTX *c, const u_int32_t *p, int num);
10430431Sphk#    define sha1_block sha1_block_x86
10530434Sphk#  else
10630431Sphk     void sha1_block(SHA_CTX *c, const u_int32_t *p, int num);
10730431Sphk#  endif
10830431Sphk#else
10930431Sphk#  ifdef SHA1_ASM
11030431Sphk     void sha1_block_x86();
11112158Sbde#    define sha1_block sha1_block_x86
1121541Srgrimes#  else
11312820Sphk     void sha1_block();
1141541Srgrimes#  endif
1151541Srgrimes#endif
1162946Swollman
1172946Swollman
1181541Srgrimes#if BYTE_ORDER == LITTLE_ENDIAN && defined(SHA1_ASM)
1191541Srgrimes#  define	M_c2nl 		c2l
1201541Srgrimes#  define	M_p_c2nl 	p_c2l
1211541Srgrimes#  define	M_c2nl_p	c2l_p
1221549Srgrimes#  define	M_p_c2nl_p	p_c2l_p
1231541Srgrimes#  define	M_nl2c		l2c
1241541Srgrimes#else
1251541Srgrimes#  define	M_c2nl 		c2nl
1261541Srgrimes#  define	M_p_c2nl	p_c2nl
1271541Srgrimes#  define	M_c2nl_p	c2nl_p
1281541Srgrimes#  define	M_p_c2nl_p	p_c2nl_p
1291541Srgrimes#  define	M_nl2c		nl2c
1308876Srgrimes#endif
1311541Srgrimes
1321541Srgrimesvoid SHA1_Init(c)
1331541SrgrimesSHA_CTX *c;
1341541Srgrimes	{
1351541Srgrimes	c->h0=INIT_DATA_h0;
1361541Srgrimes	c->h1=INIT_DATA_h1;
1371541Srgrimes	c->h2=INIT_DATA_h2;
1381541Srgrimes	c->h3=INIT_DATA_h3;
1391541Srgrimes	c->h4=INIT_DATA_h4;
1401549Srgrimes	c->Nl=0;
1411541Srgrimes	c->Nh=0;
1421541Srgrimes	c->num=0;
1431541Srgrimes	}
1441541Srgrimes
1451541Srgrimesvoid
1461541SrgrimesSHA1_Update(c, in, len)
1471541Srgrimes	SHA_CTX *c;
1481541Srgrimes	const void *in;
14922521Sdyson	size_t len;
15022521Sdyson{
15122521Sdyson	u_int32_t *p;
1521541Srgrimes	int ew,ec,sw,sc;
1531541Srgrimes	u_int32_t l;
1541541Srgrimes	const unsigned char *data = in;
1551541Srgrimes
1561541Srgrimes	if (len == 0) return;
1571541Srgrimes
1581541Srgrimes	l=(c->Nl+(len<<3))&0xffffffffL;
15922521Sdyson	if (l < c->Nl) /* overflow */
1603311Sphk		c->Nh++;
1611541Srgrimes	c->Nh+=(len>>29);
1621541Srgrimes	c->Nl=l;
1631541Srgrimes
1641541Srgrimes	if (c->num != 0)
1651541Srgrimes		{
16622521Sdyson		p=c->data;
1673311Sphk		sw=c->num>>2;
1681541Srgrimes		sc=c->num&0x03;
1691541Srgrimes
1701541Srgrimes		if ((c->num+len) >= SHA_CBLOCK)
1711541Srgrimes			{
1721541Srgrimes			l= p[sw];
1731541Srgrimes			M_p_c2nl(data,l,sc);
1748876Srgrimes			p[sw++]=l;
1753311Sphk			for (; sw<SHA_LBLOCK; sw++)
1761541Srgrimes				{
1771541Srgrimes				M_c2nl(data,l);
1781541Srgrimes				p[sw]=l;
1791541Srgrimes				}
1801541Srgrimes			len-=(SHA_CBLOCK-c->num);
1811541Srgrimes
1821541Srgrimes			sha1_block(c,p,64);
1831541Srgrimes			c->num=0;
1841541Srgrimes			/* drop through and do the rest */
1851541Srgrimes			}
18622521Sdyson		else
18722521Sdyson			{
18822521Sdyson			c->num+=(int)len;
1899973Sjkh			if ((sc+len) < 4) /* ugly, add char's to a word */
1909973Sjkh				{
1919973Sjkh				l= p[sw];
1929973Sjkh				M_p_c2nl_p(data,l,sc,len);
19322521Sdyson				p[sw]=l;
19422521Sdyson				}
19522521Sdyson			else
19622521Sdyson				{
1979973Sjkh				ew=(c->num>>2);
1989973Sjkh				ec=(c->num&0x03);
1999973Sjkh				l= p[sw];
2009973Sjkh				M_p_c2nl(data,l,sc);
2019973Sjkh				p[sw++]=l;
20222521Sdyson				for (; sw < ew; sw++)
20322521Sdyson					{ M_c2nl(data,l); p[sw]=l; }
20422521Sdyson				if (ec)
20522521Sdyson					{
20622521Sdyson					M_c2nl_p(data,l,ec);
20722521Sdyson					p[sw]=l;
20822521Sdyson					}
20922521Sdyson				}
2101541Srgrimes			return;
21122521Sdyson			}
21222521Sdyson		}
21322521Sdyson	/* We can only do the following code for assember, the reason
21422521Sdyson	 * being that the sha1_block 'C' version changes the values
21522521Sdyson	 * in the 'data' array.  The assember code avoids this and
21622521Sdyson	 * copies it to a local array.  I should be able to do this for
2179973Sjkh	 * the C version as well....
2181541Srgrimes	 */
2191541Srgrimes#if 1
22022521Sdyson#if BYTE_ORDER == BIG_ENDIAN || defined(SHA1_ASM)
2211541Srgrimes	if ((((unsigned int)data)%sizeof(u_int32_t)) == 0)
2221541Srgrimes		{
22322521Sdyson		sw=len/SHA_CBLOCK;
2241541Srgrimes		if (sw)
22522521Sdyson			{
2261541Srgrimes			sw*=SHA_CBLOCK;
2271541Srgrimes			sha1_block(c,(u_int32_t *)data,sw);
2281541Srgrimes			data+=sw;
22922521Sdyson			len-=sw;
23022521Sdyson			}
23122521Sdyson		}
2321541Srgrimes#endif
2331541Srgrimes#endif
2341541Srgrimes	/* we now can process the input data in blocks of SHA_CBLOCK
2351541Srgrimes	 * chars and save the leftovers to c->data. */
2361541Srgrimes	p=c->data;
2371541Srgrimes	while (len >= SHA_CBLOCK)
2381541Srgrimes		{
2391549Srgrimes#if BYTE_ORDER == BIG_ENDIAN || BYTE_ORDER == LITTLE_ENDIAN
2401541Srgrimes		if (p != (u_int32_t *)data)
2411541Srgrimes			memcpy(p,data,SHA_CBLOCK);
2421541Srgrimes		data+=SHA_CBLOCK;
2431541Srgrimes#  if BYTE_ORDER == LITTLE_ENDIAN
2441541Srgrimes#    ifndef SHA1_ASM /* Will not happen */
2451541Srgrimes		for (sw=(SHA_LBLOCK/4); sw; sw--)
2461541Srgrimes			{
2471541Srgrimes			Endian_Reverse32(p[0]);
24822521Sdyson			Endian_Reverse32(p[1]);
24922521Sdyson			Endian_Reverse32(p[2]);
25022521Sdyson			Endian_Reverse32(p[3]);
2511541Srgrimes			p+=4;
2521541Srgrimes			}
2531541Srgrimes		p=c->data;
2541541Srgrimes#    endif
2551541Srgrimes#  endif
2561541Srgrimes#else
2571541Srgrimes		for (sw=(SHA_BLOCK/4); sw; sw--)
2581541Srgrimes			{
2591541Srgrimes			M_c2nl(data,l); *(p++)=l;
2601541Srgrimes			M_c2nl(data,l); *(p++)=l;
2611541Srgrimes			M_c2nl(data,l); *(p++)=l;
26222521Sdyson			M_c2nl(data,l); *(p++)=l;
26328270Swollman			}
26422521Sdyson		p=c->data;
26522521Sdyson#endif
2661541Srgrimes		sha1_block(c,p,64);
2671541Srgrimes		len-=SHA_CBLOCK;
2681541Srgrimes		}
2691541Srgrimes	ec=(int)len;
2701541Srgrimes	c->num=ec;
2711541Srgrimes	ew=(ec>>2);
2721541Srgrimes	ec&=0x03;
2731541Srgrimes
2741541Srgrimes	for (sw=0; sw < ew; sw++)
2751541Srgrimes		{ M_c2nl(data,l); p[sw]=l; }
2761541Srgrimes	M_c2nl_p(data,l,ec);
2771541Srgrimes	p[sw]=l;
2781541Srgrimes	}
2791541Srgrimes
2801549Srgrimesvoid SHA1_Transform(c,b)
2811541SrgrimesSHA_CTX *c;
2821541Srgrimesunsigned char *b;
2831541Srgrimes	{
2841541Srgrimes	u_int32_t p[16];
2851541Srgrimes#if BYTE_ORDER != BIG_ENDIAN
2861541Srgrimes	u_int32_t *q;
2871541Srgrimes	int i;
2881541Srgrimes#endif
2891541Srgrimes
29022521Sdyson#if BYTE_ORDER == BIG_ENDIAN || BYTE_ORDER == LITTLE_ENDIAN
2911541Srgrimes	memcpy(p,b,64);
2921541Srgrimes#if BYTE_ORDER == LITTLE_ENDIAN
2931541Srgrimes	q=p;
2941541Srgrimes	for (i=(SHA_LBLOCK/4); i; i--)
2951541Srgrimes		{
2961541Srgrimes		Endian_Reverse32(q[0]);
2971541Srgrimes		Endian_Reverse32(q[1]);
2981541Srgrimes		Endian_Reverse32(q[2]);
29922521Sdyson		Endian_Reverse32(q[3]);
30028270Swollman		q+=4;
30128270Swollman		}
30222521Sdyson#endif
3031541Srgrimes#else
3041541Srgrimes	q=p;
3051541Srgrimes	for (i=(SHA_LBLOCK/4); i; i--)
3061541Srgrimes		{
3071541Srgrimes		u_int32_t l;
3081541Srgrimes		c2nl(b,l); *(q++)=l;
3091541Srgrimes		c2nl(b,l); *(q++)=l;
3101541Srgrimes		c2nl(b,l); *(q++)=l;
3111541Srgrimes		c2nl(b,l); *(q++)=l;
3121549Srgrimes		}
3131541Srgrimes#endif
3141541Srgrimes	sha1_block(c,p,64);
3151541Srgrimes	}
3161541Srgrimes
3171541Srgrimes#ifndef SHA1_ASM
3181541Srgrimes
3191541Srgrimesvoid
3201541Srgrimessha1_block(c, W, num)
3211541Srgrimes	SHA_CTX *c;
3221541Srgrimes	const u_int32_t *W;
3231541Srgrimes	int num;
32422521Sdyson{
3251541Srgrimes	u_int32_t A,B,C,D,E,T;
3261541Srgrimes	u_int32_t X[16];
3271541Srgrimes
32822521Sdyson	A=c->h0;
3291541Srgrimes	B=c->h1;
33022521Sdyson	C=c->h2;
33122521Sdyson	D=c->h3;
33222521Sdyson	E=c->h4;
33322521Sdyson
33422521Sdyson	for (;;)
3351541Srgrimes		{
33622521Sdyson	BODY_00_15( 0,A,B,C,D,E,T,W);
33722521Sdyson	BODY_00_15( 1,T,A,B,C,D,E,W);
33822521Sdyson	BODY_00_15( 2,E,T,A,B,C,D,W);
33922521Sdyson	BODY_00_15( 3,D,E,T,A,B,C,W);
34022521Sdyson	BODY_00_15( 4,C,D,E,T,A,B,W);
3411541Srgrimes	BODY_00_15( 5,B,C,D,E,T,A,W);
3421541Srgrimes	BODY_00_15( 6,A,B,C,D,E,T,W);
3431541Srgrimes	BODY_00_15( 7,T,A,B,C,D,E,W);
3441549Srgrimes	BODY_00_15( 8,E,T,A,B,C,D,W);
34529362Speter	BODY_00_15( 9,D,E,T,A,B,C,W);
34629362Speter	BODY_00_15(10,C,D,E,T,A,B,W);
3471541Srgrimes	BODY_00_15(11,B,C,D,E,T,A,W);
34829362Speter	BODY_00_15(12,A,B,C,D,E,T,W);
3491541Srgrimes	BODY_00_15(13,T,A,B,C,D,E,W);
3501541Srgrimes	BODY_00_15(14,E,T,A,B,C,D,W);
3511541Srgrimes	BODY_00_15(15,D,E,T,A,B,C,W);
3521541Srgrimes	BODY_16_19(16,C,D,E,T,A,B,W,W,W,W);
3531541Srgrimes	BODY_16_19(17,B,C,D,E,T,A,W,W,W,W);
35429362Speter	BODY_16_19(18,A,B,C,D,E,T,W,W,W,W);
3551541Srgrimes	BODY_16_19(19,T,A,B,C,D,E,W,W,W,X);
35629362Speter
3571541Srgrimes	BODY_20_31(20,E,T,A,B,C,D,W,W,W,X);
35829362Speter	BODY_20_31(21,D,E,T,A,B,C,W,W,W,X);
35929362Speter	BODY_20_31(22,C,D,E,T,A,B,W,W,W,X);
36029362Speter	BODY_20_31(23,B,C,D,E,T,A,W,W,W,X);
36122521Sdyson	BODY_20_31(24,A,B,C,D,E,T,W,W,X,X);
36229362Speter	BODY_20_31(25,T,A,B,C,D,E,W,W,X,X);
3631541Srgrimes	BODY_20_31(26,E,T,A,B,C,D,W,W,X,X);
36429362Speter	BODY_20_31(27,D,E,T,A,B,C,W,W,X,X);
36529362Speter	BODY_20_31(28,C,D,E,T,A,B,W,W,X,X);
36629362Speter	BODY_20_31(29,B,C,D,E,T,A,W,W,X,X);
36722521Sdyson	BODY_20_31(30,A,B,C,D,E,T,W,X,X,X);
36829362Speter	BODY_20_31(31,T,A,B,C,D,E,W,X,X,X);
3691541Srgrimes	BODY_32_39(32,E,T,A,B,C,D,X);
3701541Srgrimes	BODY_32_39(33,D,E,T,A,B,C,X);
37122521Sdyson	BODY_32_39(34,C,D,E,T,A,B,X);
37222521Sdyson	BODY_32_39(35,B,C,D,E,T,A,X);
37322521Sdyson	BODY_32_39(36,A,B,C,D,E,T,X);
37422521Sdyson	BODY_32_39(37,T,A,B,C,D,E,X);
37522521Sdyson	BODY_32_39(38,E,T,A,B,C,D,X);
37622521Sdyson	BODY_32_39(39,D,E,T,A,B,C,X);
37722521Sdyson
37822521Sdyson	BODY_40_59(40,C,D,E,T,A,B,X);
37922521Sdyson	BODY_40_59(41,B,C,D,E,T,A,X);
38022521Sdyson	BODY_40_59(42,A,B,C,D,E,T,X);
38122521Sdyson	BODY_40_59(43,T,A,B,C,D,E,X);
38222521Sdyson	BODY_40_59(44,E,T,A,B,C,D,X);
3831541Srgrimes	BODY_40_59(45,D,E,T,A,B,C,X);
3841541Srgrimes	BODY_40_59(46,C,D,E,T,A,B,X);
3851541Srgrimes	BODY_40_59(47,B,C,D,E,T,A,X);
3861549Srgrimes	BODY_40_59(48,A,B,C,D,E,T,X);
3871541Srgrimes	BODY_40_59(49,T,A,B,C,D,E,X);
3881541Srgrimes	BODY_40_59(50,E,T,A,B,C,D,X);
3891541Srgrimes	BODY_40_59(51,D,E,T,A,B,C,X);
3901541Srgrimes	BODY_40_59(52,C,D,E,T,A,B,X);
3911541Srgrimes	BODY_40_59(53,B,C,D,E,T,A,X);
3921541Srgrimes	BODY_40_59(54,A,B,C,D,E,T,X);
39310551Sdyson	BODY_40_59(55,T,A,B,C,D,E,X);
39410551Sdyson	BODY_40_59(56,E,T,A,B,C,D,X);
3951541Srgrimes	BODY_40_59(57,D,E,T,A,B,C,X);
3961541Srgrimes	BODY_40_59(58,C,D,E,T,A,B,X);
3971541Srgrimes	BODY_40_59(59,B,C,D,E,T,A,X);
3981541Srgrimes
3991541Srgrimes	BODY_60_79(60,A,B,C,D,E,T,X);
4001541Srgrimes	BODY_60_79(61,T,A,B,C,D,E,X);
4011541Srgrimes	BODY_60_79(62,E,T,A,B,C,D,X);
4026151Sdg	BODY_60_79(63,D,E,T,A,B,C,X);
4036151Sdg	BODY_60_79(64,C,D,E,T,A,B,X);
40410551Sdyson	BODY_60_79(65,B,C,D,E,T,A,X);
40510551Sdyson	BODY_60_79(66,A,B,C,D,E,T,X);
4061541Srgrimes	BODY_60_79(67,T,A,B,C,D,E,X);
4071541Srgrimes	BODY_60_79(68,E,T,A,B,C,D,X);
4081541Srgrimes	BODY_60_79(69,D,E,T,A,B,C,X);
4091541Srgrimes	BODY_60_79(70,C,D,E,T,A,B,X);
4101541Srgrimes	BODY_60_79(71,B,C,D,E,T,A,X);
4111541Srgrimes	BODY_60_79(72,A,B,C,D,E,T,X);
4121541Srgrimes	BODY_60_79(73,T,A,B,C,D,E,X);
4131549Srgrimes	BODY_60_79(74,E,T,A,B,C,D,X);
4141541Srgrimes	BODY_60_79(75,D,E,T,A,B,C,X);
4151541Srgrimes	BODY_60_79(76,C,D,E,T,A,B,X);
4161541Srgrimes	BODY_60_79(77,B,C,D,E,T,A,X);
4171541Srgrimes	BODY_60_79(78,A,B,C,D,E,T,X);
4181541Srgrimes	BODY_60_79(79,T,A,B,C,D,E,X);
4191541Srgrimes
4201541Srgrimes	c->h0=(c->h0+E)&0xffffffffL;
4211541Srgrimes	c->h1=(c->h1+T)&0xffffffffL;
4221541Srgrimes	c->h2=(c->h2+A)&0xffffffffL;
4231541Srgrimes	c->h3=(c->h3+B)&0xffffffffL;
4241541Srgrimes	c->h4=(c->h4+C)&0xffffffffL;
4251541Srgrimes
42622521Sdyson	num-=64;
42722521Sdyson	if (num <= 0) break;
42822521Sdyson
42922521Sdyson	A=c->h0;
43022521Sdyson	B=c->h1;
4311541Srgrimes	C=c->h2;
4321541Srgrimes	D=c->h3;
4331541Srgrimes	E=c->h4;
4341541Srgrimes
4359973Sjkh	W+=16;
4361541Srgrimes		}
4371541Srgrimes	}
4381541Srgrimes#endif
4391541Srgrimes
4401541Srgrimesvoid SHA1_Final(md, c)
4411541Srgrimesunsigned char *md;
4421541SrgrimesSHA_CTX *c;
4431541Srgrimes	{
4441541Srgrimes	int i,j;
4451541Srgrimes	u_int32_t l;
4461541Srgrimes	u_int32_t *p;
4473311Sphk	static unsigned char end[4]={0x80,0x00,0x00,0x00};
4481541Srgrimes	unsigned char *cp=end;
4493311Sphk
4503311Sphk	/* c->num should definitly have room for at least one more byte. */
4513311Sphk	p=c->data;
4523311Sphk	j=c->num;
4533311Sphk	i=j>>2;
4543311Sphk#ifdef PURIFY
4553311Sphk	if ((j&0x03) == 0) p[i]=0;
4563311Sphk#endif
4573311Sphk	l=p[i];
4583311Sphk	M_p_c2nl(cp,l,j&0x03);
4593311Sphk	p[i]=l;
4603311Sphk	i++;
4613311Sphk	/* i is the next 'undefined word' */
4623311Sphk	if (c->num >= SHA_LAST_BLOCK)
4631541Srgrimes		{
4641541Srgrimes		for (; i<SHA_LBLOCK; i++)
46512820Sphk			p[i]=0;
4661541Srgrimes		sha1_block(c,p,64);
4671541Srgrimes		i=0;
4681541Srgrimes		}
4691541Srgrimes	for (; i<(SHA_LBLOCK-2); i++)
4701541Srgrimes		p[i]=0;
4711541Srgrimes	p[SHA_LBLOCK-2]=c->Nh;
4721541Srgrimes	p[SHA_LBLOCK-1]=c->Nl;
4731541Srgrimes#if BYTE_ORDER == LITTLE_ENDIAN && defined(SHA1_ASM)
4741541Srgrimes	Endian_Reverse32(p[SHA_LBLOCK-2]);
4751549Srgrimes	Endian_Reverse32(p[SHA_LBLOCK-1]);
4761541Srgrimes#endif
4771541Srgrimes	sha1_block(c,p,64);
4781541Srgrimes	cp=md;
4791541Srgrimes	l=c->h0; nl2c(l,cp);
4801541Srgrimes	l=c->h1; nl2c(l,cp);
4811549Srgrimes	l=c->h2; nl2c(l,cp);
4821541Srgrimes	l=c->h3; nl2c(l,cp);
4831541Srgrimes	l=c->h4; nl2c(l,cp);
4841541Srgrimes
4851541Srgrimes	/* clear stuff, sha1_block may be leaving some stuff on the stack
4861541Srgrimes	 * but I'm not worried :-) */
4871541Srgrimes	c->num=0;
4881541Srgrimes/*	memset((char *)&c,0,sizeof(c));*/
4891541Srgrimes	}
4901541Srgrimes
4911541Srgrimes