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