xref: /rk3399_rockchip-uboot/lib/sha1.c (revision 5b8031ccb4ed6e84457d883198d77efc307085dc)
178acc472SPeter Tyser /*
278acc472SPeter Tyser  *  Heiko Schocher, DENX Software Engineering, hs@denx.de.
378acc472SPeter Tyser  *  based on:
478acc472SPeter Tyser  *  FIPS-180-1 compliant SHA-1 implementation
578acc472SPeter Tyser  *
678acc472SPeter Tyser  *  Copyright (C) 2003-2006  Christophe Devine
778acc472SPeter Tyser  *
8*5b8031ccSTom Rini  * SPDX-License-Identifier:	LGPL-2.1
978acc472SPeter Tyser  */
1078acc472SPeter Tyser /*
1178acc472SPeter Tyser  *  The SHA-1 standard was published by NIST in 1993.
1278acc472SPeter Tyser  *
1378acc472SPeter Tyser  *  http://www.itl.nist.gov/fipspubs/fip180-1.htm
1478acc472SPeter Tyser  */
1578acc472SPeter Tyser 
1678acc472SPeter Tyser #ifndef _CRT_SECURE_NO_DEPRECATE
1778acc472SPeter Tyser #define _CRT_SECURE_NO_DEPRECATE 1
1878acc472SPeter Tyser #endif
1978acc472SPeter Tyser 
2078acc472SPeter Tyser #ifndef USE_HOSTCC
2178acc472SPeter Tyser #include <common.h>
2278acc472SPeter Tyser #include <linux/string.h>
2378acc472SPeter Tyser #else
2478acc472SPeter Tyser #include <string.h>
2578acc472SPeter Tyser #endif /* USE_HOSTCC */
2678acc472SPeter Tyser #include <watchdog.h>
272b9912e6SJeroen Hofstee #include <u-boot/sha1.h>
2878acc472SPeter Tyser 
2978acc472SPeter Tyser /*
3078acc472SPeter Tyser  * 32-bit integer manipulation macros (big endian)
3178acc472SPeter Tyser  */
3278acc472SPeter Tyser #ifndef GET_UINT32_BE
3378acc472SPeter Tyser #define GET_UINT32_BE(n,b,i) {				\
3478acc472SPeter Tyser 	(n) = ( (unsigned long) (b)[(i)    ] << 24 )	\
3578acc472SPeter Tyser 	    | ( (unsigned long) (b)[(i) + 1] << 16 )	\
3678acc472SPeter Tyser 	    | ( (unsigned long) (b)[(i) + 2] <<  8 )	\
3778acc472SPeter Tyser 	    | ( (unsigned long) (b)[(i) + 3]       );	\
3878acc472SPeter Tyser }
3978acc472SPeter Tyser #endif
4078acc472SPeter Tyser #ifndef PUT_UINT32_BE
4178acc472SPeter Tyser #define PUT_UINT32_BE(n,b,i) {				\
4278acc472SPeter Tyser 	(b)[(i)    ] = (unsigned char) ( (n) >> 24 );	\
4378acc472SPeter Tyser 	(b)[(i) + 1] = (unsigned char) ( (n) >> 16 );	\
4478acc472SPeter Tyser 	(b)[(i) + 2] = (unsigned char) ( (n) >>  8 );	\
4578acc472SPeter Tyser 	(b)[(i) + 3] = (unsigned char) ( (n)       );	\
4678acc472SPeter Tyser }
4778acc472SPeter Tyser #endif
4878acc472SPeter Tyser 
4978acc472SPeter Tyser /*
5078acc472SPeter Tyser  * SHA-1 context setup
5178acc472SPeter Tyser  */
5278acc472SPeter Tyser void sha1_starts (sha1_context * ctx)
5378acc472SPeter Tyser {
5478acc472SPeter Tyser 	ctx->total[0] = 0;
5578acc472SPeter Tyser 	ctx->total[1] = 0;
5678acc472SPeter Tyser 
5778acc472SPeter Tyser 	ctx->state[0] = 0x67452301;
5878acc472SPeter Tyser 	ctx->state[1] = 0xEFCDAB89;
5978acc472SPeter Tyser 	ctx->state[2] = 0x98BADCFE;
6078acc472SPeter Tyser 	ctx->state[3] = 0x10325476;
6178acc472SPeter Tyser 	ctx->state[4] = 0xC3D2E1F0;
6278acc472SPeter Tyser }
6378acc472SPeter Tyser 
64a7d1d765SSimon Glass static void sha1_process(sha1_context *ctx, const unsigned char data[64])
6578acc472SPeter Tyser {
6678acc472SPeter Tyser 	unsigned long temp, W[16], A, B, C, D, E;
6778acc472SPeter Tyser 
6878acc472SPeter Tyser 	GET_UINT32_BE (W[0], data, 0);
6978acc472SPeter Tyser 	GET_UINT32_BE (W[1], data, 4);
7078acc472SPeter Tyser 	GET_UINT32_BE (W[2], data, 8);
7178acc472SPeter Tyser 	GET_UINT32_BE (W[3], data, 12);
7278acc472SPeter Tyser 	GET_UINT32_BE (W[4], data, 16);
7378acc472SPeter Tyser 	GET_UINT32_BE (W[5], data, 20);
7478acc472SPeter Tyser 	GET_UINT32_BE (W[6], data, 24);
7578acc472SPeter Tyser 	GET_UINT32_BE (W[7], data, 28);
7678acc472SPeter Tyser 	GET_UINT32_BE (W[8], data, 32);
7778acc472SPeter Tyser 	GET_UINT32_BE (W[9], data, 36);
7878acc472SPeter Tyser 	GET_UINT32_BE (W[10], data, 40);
7978acc472SPeter Tyser 	GET_UINT32_BE (W[11], data, 44);
8078acc472SPeter Tyser 	GET_UINT32_BE (W[12], data, 48);
8178acc472SPeter Tyser 	GET_UINT32_BE (W[13], data, 52);
8278acc472SPeter Tyser 	GET_UINT32_BE (W[14], data, 56);
8378acc472SPeter Tyser 	GET_UINT32_BE (W[15], data, 60);
8478acc472SPeter Tyser 
8578acc472SPeter Tyser #define S(x,n)	((x << n) | ((x & 0xFFFFFFFF) >> (32 - n)))
8678acc472SPeter Tyser 
8778acc472SPeter Tyser #define R(t) (						\
8878acc472SPeter Tyser 	temp = W[(t -  3) & 0x0F] ^ W[(t - 8) & 0x0F] ^	\
8978acc472SPeter Tyser 	       W[(t - 14) & 0x0F] ^ W[ t      & 0x0F],	\
9078acc472SPeter Tyser 	( W[t & 0x0F] = S(temp,1) )			\
9178acc472SPeter Tyser )
9278acc472SPeter Tyser 
9378acc472SPeter Tyser #define P(a,b,c,d,e,x)	{				\
9478acc472SPeter Tyser 	e += S(a,5) + F(b,c,d) + K + x; b = S(b,30);	\
9578acc472SPeter Tyser }
9678acc472SPeter Tyser 
9778acc472SPeter Tyser 	A = ctx->state[0];
9878acc472SPeter Tyser 	B = ctx->state[1];
9978acc472SPeter Tyser 	C = ctx->state[2];
10078acc472SPeter Tyser 	D = ctx->state[3];
10178acc472SPeter Tyser 	E = ctx->state[4];
10278acc472SPeter Tyser 
10378acc472SPeter Tyser #define F(x,y,z) (z ^ (x & (y ^ z)))
10478acc472SPeter Tyser #define K 0x5A827999
10578acc472SPeter Tyser 
10678acc472SPeter Tyser 	P (A, B, C, D, E, W[0]);
10778acc472SPeter Tyser 	P (E, A, B, C, D, W[1]);
10878acc472SPeter Tyser 	P (D, E, A, B, C, W[2]);
10978acc472SPeter Tyser 	P (C, D, E, A, B, W[3]);
11078acc472SPeter Tyser 	P (B, C, D, E, A, W[4]);
11178acc472SPeter Tyser 	P (A, B, C, D, E, W[5]);
11278acc472SPeter Tyser 	P (E, A, B, C, D, W[6]);
11378acc472SPeter Tyser 	P (D, E, A, B, C, W[7]);
11478acc472SPeter Tyser 	P (C, D, E, A, B, W[8]);
11578acc472SPeter Tyser 	P (B, C, D, E, A, W[9]);
11678acc472SPeter Tyser 	P (A, B, C, D, E, W[10]);
11778acc472SPeter Tyser 	P (E, A, B, C, D, W[11]);
11878acc472SPeter Tyser 	P (D, E, A, B, C, W[12]);
11978acc472SPeter Tyser 	P (C, D, E, A, B, W[13]);
12078acc472SPeter Tyser 	P (B, C, D, E, A, W[14]);
12178acc472SPeter Tyser 	P (A, B, C, D, E, W[15]);
12278acc472SPeter Tyser 	P (E, A, B, C, D, R (16));
12378acc472SPeter Tyser 	P (D, E, A, B, C, R (17));
12478acc472SPeter Tyser 	P (C, D, E, A, B, R (18));
12578acc472SPeter Tyser 	P (B, C, D, E, A, R (19));
12678acc472SPeter Tyser 
12778acc472SPeter Tyser #undef K
12878acc472SPeter Tyser #undef F
12978acc472SPeter Tyser 
13078acc472SPeter Tyser #define F(x,y,z) (x ^ y ^ z)
13178acc472SPeter Tyser #define K 0x6ED9EBA1
13278acc472SPeter Tyser 
13378acc472SPeter Tyser 	P (A, B, C, D, E, R (20));
13478acc472SPeter Tyser 	P (E, A, B, C, D, R (21));
13578acc472SPeter Tyser 	P (D, E, A, B, C, R (22));
13678acc472SPeter Tyser 	P (C, D, E, A, B, R (23));
13778acc472SPeter Tyser 	P (B, C, D, E, A, R (24));
13878acc472SPeter Tyser 	P (A, B, C, D, E, R (25));
13978acc472SPeter Tyser 	P (E, A, B, C, D, R (26));
14078acc472SPeter Tyser 	P (D, E, A, B, C, R (27));
14178acc472SPeter Tyser 	P (C, D, E, A, B, R (28));
14278acc472SPeter Tyser 	P (B, C, D, E, A, R (29));
14378acc472SPeter Tyser 	P (A, B, C, D, E, R (30));
14478acc472SPeter Tyser 	P (E, A, B, C, D, R (31));
14578acc472SPeter Tyser 	P (D, E, A, B, C, R (32));
14678acc472SPeter Tyser 	P (C, D, E, A, B, R (33));
14778acc472SPeter Tyser 	P (B, C, D, E, A, R (34));
14878acc472SPeter Tyser 	P (A, B, C, D, E, R (35));
14978acc472SPeter Tyser 	P (E, A, B, C, D, R (36));
15078acc472SPeter Tyser 	P (D, E, A, B, C, R (37));
15178acc472SPeter Tyser 	P (C, D, E, A, B, R (38));
15278acc472SPeter Tyser 	P (B, C, D, E, A, R (39));
15378acc472SPeter Tyser 
15478acc472SPeter Tyser #undef K
15578acc472SPeter Tyser #undef F
15678acc472SPeter Tyser 
15778acc472SPeter Tyser #define F(x,y,z) ((x & y) | (z & (x | y)))
15878acc472SPeter Tyser #define K 0x8F1BBCDC
15978acc472SPeter Tyser 
16078acc472SPeter Tyser 	P (A, B, C, D, E, R (40));
16178acc472SPeter Tyser 	P (E, A, B, C, D, R (41));
16278acc472SPeter Tyser 	P (D, E, A, B, C, R (42));
16378acc472SPeter Tyser 	P (C, D, E, A, B, R (43));
16478acc472SPeter Tyser 	P (B, C, D, E, A, R (44));
16578acc472SPeter Tyser 	P (A, B, C, D, E, R (45));
16678acc472SPeter Tyser 	P (E, A, B, C, D, R (46));
16778acc472SPeter Tyser 	P (D, E, A, B, C, R (47));
16878acc472SPeter Tyser 	P (C, D, E, A, B, R (48));
16978acc472SPeter Tyser 	P (B, C, D, E, A, R (49));
17078acc472SPeter Tyser 	P (A, B, C, D, E, R (50));
17178acc472SPeter Tyser 	P (E, A, B, C, D, R (51));
17278acc472SPeter Tyser 	P (D, E, A, B, C, R (52));
17378acc472SPeter Tyser 	P (C, D, E, A, B, R (53));
17478acc472SPeter Tyser 	P (B, C, D, E, A, R (54));
17578acc472SPeter Tyser 	P (A, B, C, D, E, R (55));
17678acc472SPeter Tyser 	P (E, A, B, C, D, R (56));
17778acc472SPeter Tyser 	P (D, E, A, B, C, R (57));
17878acc472SPeter Tyser 	P (C, D, E, A, B, R (58));
17978acc472SPeter Tyser 	P (B, C, D, E, A, R (59));
18078acc472SPeter Tyser 
18178acc472SPeter Tyser #undef K
18278acc472SPeter Tyser #undef F
18378acc472SPeter Tyser 
18478acc472SPeter Tyser #define F(x,y,z) (x ^ y ^ z)
18578acc472SPeter Tyser #define K 0xCA62C1D6
18678acc472SPeter Tyser 
18778acc472SPeter Tyser 	P (A, B, C, D, E, R (60));
18878acc472SPeter Tyser 	P (E, A, B, C, D, R (61));
18978acc472SPeter Tyser 	P (D, E, A, B, C, R (62));
19078acc472SPeter Tyser 	P (C, D, E, A, B, R (63));
19178acc472SPeter Tyser 	P (B, C, D, E, A, R (64));
19278acc472SPeter Tyser 	P (A, B, C, D, E, R (65));
19378acc472SPeter Tyser 	P (E, A, B, C, D, R (66));
19478acc472SPeter Tyser 	P (D, E, A, B, C, R (67));
19578acc472SPeter Tyser 	P (C, D, E, A, B, R (68));
19678acc472SPeter Tyser 	P (B, C, D, E, A, R (69));
19778acc472SPeter Tyser 	P (A, B, C, D, E, R (70));
19878acc472SPeter Tyser 	P (E, A, B, C, D, R (71));
19978acc472SPeter Tyser 	P (D, E, A, B, C, R (72));
20078acc472SPeter Tyser 	P (C, D, E, A, B, R (73));
20178acc472SPeter Tyser 	P (B, C, D, E, A, R (74));
20278acc472SPeter Tyser 	P (A, B, C, D, E, R (75));
20378acc472SPeter Tyser 	P (E, A, B, C, D, R (76));
20478acc472SPeter Tyser 	P (D, E, A, B, C, R (77));
20578acc472SPeter Tyser 	P (C, D, E, A, B, R (78));
20678acc472SPeter Tyser 	P (B, C, D, E, A, R (79));
20778acc472SPeter Tyser 
20878acc472SPeter Tyser #undef K
20978acc472SPeter Tyser #undef F
21078acc472SPeter Tyser 
21178acc472SPeter Tyser 	ctx->state[0] += A;
21278acc472SPeter Tyser 	ctx->state[1] += B;
21378acc472SPeter Tyser 	ctx->state[2] += C;
21478acc472SPeter Tyser 	ctx->state[3] += D;
21578acc472SPeter Tyser 	ctx->state[4] += E;
21678acc472SPeter Tyser }
21778acc472SPeter Tyser 
21878acc472SPeter Tyser /*
21978acc472SPeter Tyser  * SHA-1 process buffer
22078acc472SPeter Tyser  */
221a7d1d765SSimon Glass void sha1_update(sha1_context *ctx, const unsigned char *input,
222a7d1d765SSimon Glass 		 unsigned int ilen)
22378acc472SPeter Tyser {
22478acc472SPeter Tyser 	int fill;
22578acc472SPeter Tyser 	unsigned long left;
22678acc472SPeter Tyser 
22778acc472SPeter Tyser 	if (ilen <= 0)
22878acc472SPeter Tyser 		return;
22978acc472SPeter Tyser 
23078acc472SPeter Tyser 	left = ctx->total[0] & 0x3F;
23178acc472SPeter Tyser 	fill = 64 - left;
23278acc472SPeter Tyser 
23378acc472SPeter Tyser 	ctx->total[0] += ilen;
23478acc472SPeter Tyser 	ctx->total[0] &= 0xFFFFFFFF;
23578acc472SPeter Tyser 
23678acc472SPeter Tyser 	if (ctx->total[0] < (unsigned long) ilen)
23778acc472SPeter Tyser 		ctx->total[1]++;
23878acc472SPeter Tyser 
23978acc472SPeter Tyser 	if (left && ilen >= fill) {
24078acc472SPeter Tyser 		memcpy ((void *) (ctx->buffer + left), (void *) input, fill);
24178acc472SPeter Tyser 		sha1_process (ctx, ctx->buffer);
24278acc472SPeter Tyser 		input += fill;
24378acc472SPeter Tyser 		ilen -= fill;
24478acc472SPeter Tyser 		left = 0;
24578acc472SPeter Tyser 	}
24678acc472SPeter Tyser 
24778acc472SPeter Tyser 	while (ilen >= 64) {
24878acc472SPeter Tyser 		sha1_process (ctx, input);
24978acc472SPeter Tyser 		input += 64;
25078acc472SPeter Tyser 		ilen -= 64;
25178acc472SPeter Tyser 	}
25278acc472SPeter Tyser 
25378acc472SPeter Tyser 	if (ilen > 0) {
25478acc472SPeter Tyser 		memcpy ((void *) (ctx->buffer + left), (void *) input, ilen);
25578acc472SPeter Tyser 	}
25678acc472SPeter Tyser }
25778acc472SPeter Tyser 
25878acc472SPeter Tyser static const unsigned char sha1_padding[64] = {
25978acc472SPeter Tyser 	0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
26078acc472SPeter Tyser 	   0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
26178acc472SPeter Tyser 	   0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
26278acc472SPeter Tyser 	   0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
26378acc472SPeter Tyser };
26478acc472SPeter Tyser 
26578acc472SPeter Tyser /*
26678acc472SPeter Tyser  * SHA-1 final digest
26778acc472SPeter Tyser  */
26878acc472SPeter Tyser void sha1_finish (sha1_context * ctx, unsigned char output[20])
26978acc472SPeter Tyser {
27078acc472SPeter Tyser 	unsigned long last, padn;
27178acc472SPeter Tyser 	unsigned long high, low;
27278acc472SPeter Tyser 	unsigned char msglen[8];
27378acc472SPeter Tyser 
27478acc472SPeter Tyser 	high = (ctx->total[0] >> 29)
27578acc472SPeter Tyser 		| (ctx->total[1] << 3);
27678acc472SPeter Tyser 	low = (ctx->total[0] << 3);
27778acc472SPeter Tyser 
27878acc472SPeter Tyser 	PUT_UINT32_BE (high, msglen, 0);
27978acc472SPeter Tyser 	PUT_UINT32_BE (low, msglen, 4);
28078acc472SPeter Tyser 
28178acc472SPeter Tyser 	last = ctx->total[0] & 0x3F;
28278acc472SPeter Tyser 	padn = (last < 56) ? (56 - last) : (120 - last);
28378acc472SPeter Tyser 
28478acc472SPeter Tyser 	sha1_update (ctx, (unsigned char *) sha1_padding, padn);
28578acc472SPeter Tyser 	sha1_update (ctx, msglen, 8);
28678acc472SPeter Tyser 
28778acc472SPeter Tyser 	PUT_UINT32_BE (ctx->state[0], output, 0);
28878acc472SPeter Tyser 	PUT_UINT32_BE (ctx->state[1], output, 4);
28978acc472SPeter Tyser 	PUT_UINT32_BE (ctx->state[2], output, 8);
29078acc472SPeter Tyser 	PUT_UINT32_BE (ctx->state[3], output, 12);
29178acc472SPeter Tyser 	PUT_UINT32_BE (ctx->state[4], output, 16);
29278acc472SPeter Tyser }
29378acc472SPeter Tyser 
29478acc472SPeter Tyser /*
29578acc472SPeter Tyser  * Output = SHA-1( input buffer )
29678acc472SPeter Tyser  */
297a7d1d765SSimon Glass void sha1_csum(const unsigned char *input, unsigned int ilen,
298a7d1d765SSimon Glass 	       unsigned char *output)
29978acc472SPeter Tyser {
30078acc472SPeter Tyser 	sha1_context ctx;
30178acc472SPeter Tyser 
30278acc472SPeter Tyser 	sha1_starts (&ctx);
30378acc472SPeter Tyser 	sha1_update (&ctx, input, ilen);
30478acc472SPeter Tyser 	sha1_finish (&ctx, output);
30578acc472SPeter Tyser }
30678acc472SPeter Tyser 
30778acc472SPeter Tyser /*
30878acc472SPeter Tyser  * Output = SHA-1( input buffer ). Trigger the watchdog every 'chunk_sz'
30978acc472SPeter Tyser  * bytes of input processed.
31078acc472SPeter Tyser  */
311a7d1d765SSimon Glass void sha1_csum_wd(const unsigned char *input, unsigned int ilen,
312a7d1d765SSimon Glass 		  unsigned char *output, unsigned int chunk_sz)
31378acc472SPeter Tyser {
31478acc472SPeter Tyser 	sha1_context ctx;
31578acc472SPeter Tyser #if defined(CONFIG_HW_WATCHDOG) || defined(CONFIG_WATCHDOG)
316a7d1d765SSimon Glass 	const unsigned char *end, *curr;
31778acc472SPeter Tyser 	int chunk;
31878acc472SPeter Tyser #endif
31978acc472SPeter Tyser 
32078acc472SPeter Tyser 	sha1_starts (&ctx);
32178acc472SPeter Tyser 
32278acc472SPeter Tyser #if defined(CONFIG_HW_WATCHDOG) || defined(CONFIG_WATCHDOG)
32378acc472SPeter Tyser 	curr = input;
32478acc472SPeter Tyser 	end = input + ilen;
32578acc472SPeter Tyser 	while (curr < end) {
32678acc472SPeter Tyser 		chunk = end - curr;
32778acc472SPeter Tyser 		if (chunk > chunk_sz)
32878acc472SPeter Tyser 			chunk = chunk_sz;
32978acc472SPeter Tyser 		sha1_update (&ctx, curr, chunk);
33078acc472SPeter Tyser 		curr += chunk;
33178acc472SPeter Tyser 		WATCHDOG_RESET ();
33278acc472SPeter Tyser 	}
33378acc472SPeter Tyser #else
33478acc472SPeter Tyser 	sha1_update (&ctx, input, ilen);
33578acc472SPeter Tyser #endif
33678acc472SPeter Tyser 
33778acc472SPeter Tyser 	sha1_finish (&ctx, output);
33878acc472SPeter Tyser }
33978acc472SPeter Tyser 
34078acc472SPeter Tyser /*
34178acc472SPeter Tyser  * Output = HMAC-SHA-1( input buffer, hmac key )
34278acc472SPeter Tyser  */
343a7d1d765SSimon Glass void sha1_hmac(const unsigned char *key, int keylen,
344a7d1d765SSimon Glass 	       const unsigned char *input, unsigned int ilen,
345a7d1d765SSimon Glass 	       unsigned char *output)
34678acc472SPeter Tyser {
34778acc472SPeter Tyser 	int i;
34878acc472SPeter Tyser 	sha1_context ctx;
34978acc472SPeter Tyser 	unsigned char k_ipad[64];
35078acc472SPeter Tyser 	unsigned char k_opad[64];
35178acc472SPeter Tyser 	unsigned char tmpbuf[20];
35278acc472SPeter Tyser 
35378acc472SPeter Tyser 	memset (k_ipad, 0x36, 64);
35478acc472SPeter Tyser 	memset (k_opad, 0x5C, 64);
35578acc472SPeter Tyser 
35678acc472SPeter Tyser 	for (i = 0; i < keylen; i++) {
35778acc472SPeter Tyser 		if (i >= 64)
35878acc472SPeter Tyser 			break;
35978acc472SPeter Tyser 
36078acc472SPeter Tyser 		k_ipad[i] ^= key[i];
36178acc472SPeter Tyser 		k_opad[i] ^= key[i];
36278acc472SPeter Tyser 	}
36378acc472SPeter Tyser 
36478acc472SPeter Tyser 	sha1_starts (&ctx);
36578acc472SPeter Tyser 	sha1_update (&ctx, k_ipad, 64);
36678acc472SPeter Tyser 	sha1_update (&ctx, input, ilen);
36778acc472SPeter Tyser 	sha1_finish (&ctx, tmpbuf);
36878acc472SPeter Tyser 
36978acc472SPeter Tyser 	sha1_starts (&ctx);
37078acc472SPeter Tyser 	sha1_update (&ctx, k_opad, 64);
37178acc472SPeter Tyser 	sha1_update (&ctx, tmpbuf, 20);
37278acc472SPeter Tyser 	sha1_finish (&ctx, output);
37378acc472SPeter Tyser 
37478acc472SPeter Tyser 	memset (k_ipad, 0, 64);
37578acc472SPeter Tyser 	memset (k_opad, 0, 64);
37678acc472SPeter Tyser 	memset (tmpbuf, 0, 20);
37778acc472SPeter Tyser 	memset (&ctx, 0, sizeof (sha1_context));
37878acc472SPeter Tyser }
37978acc472SPeter Tyser 
38078acc472SPeter Tyser #ifdef SELF_TEST
38178acc472SPeter Tyser /*
38278acc472SPeter Tyser  * FIPS-180-1 test vectors
38378acc472SPeter Tyser  */
38478acc472SPeter Tyser static const char sha1_test_str[3][57] = {
38578acc472SPeter Tyser 	{"abc"},
38678acc472SPeter Tyser 	{"abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq"},
38778acc472SPeter Tyser 	{""}
38878acc472SPeter Tyser };
38978acc472SPeter Tyser 
39078acc472SPeter Tyser static const unsigned char sha1_test_sum[3][20] = {
39178acc472SPeter Tyser 	{0xA9, 0x99, 0x3E, 0x36, 0x47, 0x06, 0x81, 0x6A, 0xBA, 0x3E,
39278acc472SPeter Tyser 	 0x25, 0x71, 0x78, 0x50, 0xC2, 0x6C, 0x9C, 0xD0, 0xD8, 0x9D},
39378acc472SPeter Tyser 	{0x84, 0x98, 0x3E, 0x44, 0x1C, 0x3B, 0xD2, 0x6E, 0xBA, 0xAE,
39478acc472SPeter Tyser 	 0x4A, 0xA1, 0xF9, 0x51, 0x29, 0xE5, 0xE5, 0x46, 0x70, 0xF1},
39578acc472SPeter Tyser 	{0x34, 0xAA, 0x97, 0x3C, 0xD4, 0xC4, 0xDA, 0xA4, 0xF6, 0x1E,
39678acc472SPeter Tyser 	 0xEB, 0x2B, 0xDB, 0xAD, 0x27, 0x31, 0x65, 0x34, 0x01, 0x6F}
39778acc472SPeter Tyser };
39878acc472SPeter Tyser 
39978acc472SPeter Tyser /*
40078acc472SPeter Tyser  * Checkup routine
40178acc472SPeter Tyser  */
40278acc472SPeter Tyser int sha1_self_test (void)
40378acc472SPeter Tyser {
40478acc472SPeter Tyser 	int i, j;
40578acc472SPeter Tyser 	unsigned char buf[1000];
40678acc472SPeter Tyser 	unsigned char sha1sum[20];
40778acc472SPeter Tyser 	sha1_context ctx;
40878acc472SPeter Tyser 
40978acc472SPeter Tyser 	for (i = 0; i < 3; i++) {
41078acc472SPeter Tyser 		printf ("  SHA-1 test #%d: ", i + 1);
41178acc472SPeter Tyser 
41278acc472SPeter Tyser 		sha1_starts (&ctx);
41378acc472SPeter Tyser 
41478acc472SPeter Tyser 		if (i < 2)
41578acc472SPeter Tyser 			sha1_update (&ctx, (unsigned char *) sha1_test_str[i],
41678acc472SPeter Tyser 				     strlen (sha1_test_str[i]));
41778acc472SPeter Tyser 		else {
41878acc472SPeter Tyser 			memset (buf, 'a', 1000);
41978acc472SPeter Tyser 			for (j = 0; j < 1000; j++)
42078acc472SPeter Tyser 				sha1_update (&ctx, buf, 1000);
42178acc472SPeter Tyser 		}
42278acc472SPeter Tyser 
42378acc472SPeter Tyser 		sha1_finish (&ctx, sha1sum);
42478acc472SPeter Tyser 
42578acc472SPeter Tyser 		if (memcmp (sha1sum, sha1_test_sum[i], 20) != 0) {
42678acc472SPeter Tyser 			printf ("failed\n");
42778acc472SPeter Tyser 			return (1);
42878acc472SPeter Tyser 		}
42978acc472SPeter Tyser 
43078acc472SPeter Tyser 		printf ("passed\n");
43178acc472SPeter Tyser 	}
43278acc472SPeter Tyser 
43378acc472SPeter Tyser 	printf ("\n");
43478acc472SPeter Tyser 	return (0);
43578acc472SPeter Tyser }
43678acc472SPeter Tyser #else
43778acc472SPeter Tyser int sha1_self_test (void)
43878acc472SPeter Tyser {
43978acc472SPeter Tyser 	return (0);
44078acc472SPeter Tyser }
44178acc472SPeter Tyser #endif
442