xref: /rk3399_rockchip-uboot/lib/sha1.c (revision 87e494a1b4b10b2144fb1d62f0a848caabcfb69b)
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  *
85b8031ccSTom 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 
29*87e494a1SLoic Poulain #include <linux/compiler.h>
30*87e494a1SLoic Poulain 
31*87e494a1SLoic Poulain #ifdef USE_HOSTCC
32*87e494a1SLoic Poulain #undef __weak
33*87e494a1SLoic Poulain #define __weak
34*87e494a1SLoic Poulain #undef __maybe_unused
35*87e494a1SLoic Poulain #define __maybe_unused
36*87e494a1SLoic Poulain #endif
37*87e494a1SLoic Poulain 
38da29f299SAndrew Duda const uint8_t sha1_der_prefix[SHA1_DER_LEN] = {
39da29f299SAndrew Duda 	0x30, 0x21, 0x30, 0x09, 0x06, 0x05, 0x2b, 0x0e,
40da29f299SAndrew Duda 	0x03, 0x02, 0x1a, 0x05, 0x00, 0x04, 0x14
41da29f299SAndrew Duda };
42da29f299SAndrew Duda 
4378acc472SPeter Tyser /*
4478acc472SPeter Tyser  * 32-bit integer manipulation macros (big endian)
4578acc472SPeter Tyser  */
4678acc472SPeter Tyser #ifndef GET_UINT32_BE
4778acc472SPeter Tyser #define GET_UINT32_BE(n,b,i) {				\
4878acc472SPeter Tyser 	(n) = ( (unsigned long) (b)[(i)    ] << 24 )	\
4978acc472SPeter Tyser 	    | ( (unsigned long) (b)[(i) + 1] << 16 )	\
5078acc472SPeter Tyser 	    | ( (unsigned long) (b)[(i) + 2] <<  8 )	\
5178acc472SPeter Tyser 	    | ( (unsigned long) (b)[(i) + 3]       );	\
5278acc472SPeter Tyser }
5378acc472SPeter Tyser #endif
5478acc472SPeter Tyser #ifndef PUT_UINT32_BE
5578acc472SPeter Tyser #define PUT_UINT32_BE(n,b,i) {				\
5678acc472SPeter Tyser 	(b)[(i)    ] = (unsigned char) ( (n) >> 24 );	\
5778acc472SPeter Tyser 	(b)[(i) + 1] = (unsigned char) ( (n) >> 16 );	\
5878acc472SPeter Tyser 	(b)[(i) + 2] = (unsigned char) ( (n) >>  8 );	\
5978acc472SPeter Tyser 	(b)[(i) + 3] = (unsigned char) ( (n)       );	\
6078acc472SPeter Tyser }
6178acc472SPeter Tyser #endif
6278acc472SPeter Tyser 
6378acc472SPeter Tyser /*
6478acc472SPeter Tyser  * SHA-1 context setup
6578acc472SPeter Tyser  */
6678acc472SPeter Tyser void sha1_starts (sha1_context * ctx)
6778acc472SPeter Tyser {
6878acc472SPeter Tyser 	ctx->total[0] = 0;
6978acc472SPeter Tyser 	ctx->total[1] = 0;
7078acc472SPeter Tyser 
7178acc472SPeter Tyser 	ctx->state[0] = 0x67452301;
7278acc472SPeter Tyser 	ctx->state[1] = 0xEFCDAB89;
7378acc472SPeter Tyser 	ctx->state[2] = 0x98BADCFE;
7478acc472SPeter Tyser 	ctx->state[3] = 0x10325476;
7578acc472SPeter Tyser 	ctx->state[4] = 0xC3D2E1F0;
7678acc472SPeter Tyser }
7778acc472SPeter Tyser 
78*87e494a1SLoic Poulain static void __maybe_unused sha1_process_one(sha1_context *ctx, const unsigned char data[64])
7978acc472SPeter Tyser {
8078acc472SPeter Tyser 	unsigned long temp, W[16], A, B, C, D, E;
8178acc472SPeter Tyser 
8278acc472SPeter Tyser 	GET_UINT32_BE (W[0], data, 0);
8378acc472SPeter Tyser 	GET_UINT32_BE (W[1], data, 4);
8478acc472SPeter Tyser 	GET_UINT32_BE (W[2], data, 8);
8578acc472SPeter Tyser 	GET_UINT32_BE (W[3], data, 12);
8678acc472SPeter Tyser 	GET_UINT32_BE (W[4], data, 16);
8778acc472SPeter Tyser 	GET_UINT32_BE (W[5], data, 20);
8878acc472SPeter Tyser 	GET_UINT32_BE (W[6], data, 24);
8978acc472SPeter Tyser 	GET_UINT32_BE (W[7], data, 28);
9078acc472SPeter Tyser 	GET_UINT32_BE (W[8], data, 32);
9178acc472SPeter Tyser 	GET_UINT32_BE (W[9], data, 36);
9278acc472SPeter Tyser 	GET_UINT32_BE (W[10], data, 40);
9378acc472SPeter Tyser 	GET_UINT32_BE (W[11], data, 44);
9478acc472SPeter Tyser 	GET_UINT32_BE (W[12], data, 48);
9578acc472SPeter Tyser 	GET_UINT32_BE (W[13], data, 52);
9678acc472SPeter Tyser 	GET_UINT32_BE (W[14], data, 56);
9778acc472SPeter Tyser 	GET_UINT32_BE (W[15], data, 60);
9878acc472SPeter Tyser 
9978acc472SPeter Tyser #define S(x,n)	((x << n) | ((x & 0xFFFFFFFF) >> (32 - n)))
10078acc472SPeter Tyser 
10178acc472SPeter Tyser #define R(t) (						\
10278acc472SPeter Tyser 	temp = W[(t -  3) & 0x0F] ^ W[(t - 8) & 0x0F] ^	\
10378acc472SPeter Tyser 	       W[(t - 14) & 0x0F] ^ W[ t      & 0x0F],	\
10478acc472SPeter Tyser 	( W[t & 0x0F] = S(temp,1) )			\
10578acc472SPeter Tyser )
10678acc472SPeter Tyser 
10778acc472SPeter Tyser #define P(a,b,c,d,e,x)	{				\
10878acc472SPeter Tyser 	e += S(a,5) + F(b,c,d) + K + x; b = S(b,30);	\
10978acc472SPeter Tyser }
11078acc472SPeter Tyser 
11178acc472SPeter Tyser 	A = ctx->state[0];
11278acc472SPeter Tyser 	B = ctx->state[1];
11378acc472SPeter Tyser 	C = ctx->state[2];
11478acc472SPeter Tyser 	D = ctx->state[3];
11578acc472SPeter Tyser 	E = ctx->state[4];
11678acc472SPeter Tyser 
11778acc472SPeter Tyser #define F(x,y,z) (z ^ (x & (y ^ z)))
11878acc472SPeter Tyser #define K 0x5A827999
11978acc472SPeter Tyser 
12078acc472SPeter Tyser 	P (A, B, C, D, E, W[0]);
12178acc472SPeter Tyser 	P (E, A, B, C, D, W[1]);
12278acc472SPeter Tyser 	P (D, E, A, B, C, W[2]);
12378acc472SPeter Tyser 	P (C, D, E, A, B, W[3]);
12478acc472SPeter Tyser 	P (B, C, D, E, A, W[4]);
12578acc472SPeter Tyser 	P (A, B, C, D, E, W[5]);
12678acc472SPeter Tyser 	P (E, A, B, C, D, W[6]);
12778acc472SPeter Tyser 	P (D, E, A, B, C, W[7]);
12878acc472SPeter Tyser 	P (C, D, E, A, B, W[8]);
12978acc472SPeter Tyser 	P (B, C, D, E, A, W[9]);
13078acc472SPeter Tyser 	P (A, B, C, D, E, W[10]);
13178acc472SPeter Tyser 	P (E, A, B, C, D, W[11]);
13278acc472SPeter Tyser 	P (D, E, A, B, C, W[12]);
13378acc472SPeter Tyser 	P (C, D, E, A, B, W[13]);
13478acc472SPeter Tyser 	P (B, C, D, E, A, W[14]);
13578acc472SPeter Tyser 	P (A, B, C, D, E, W[15]);
13678acc472SPeter Tyser 	P (E, A, B, C, D, R (16));
13778acc472SPeter Tyser 	P (D, E, A, B, C, R (17));
13878acc472SPeter Tyser 	P (C, D, E, A, B, R (18));
13978acc472SPeter Tyser 	P (B, C, D, E, A, R (19));
14078acc472SPeter Tyser 
14178acc472SPeter Tyser #undef K
14278acc472SPeter Tyser #undef F
14378acc472SPeter Tyser 
14478acc472SPeter Tyser #define F(x,y,z) (x ^ y ^ z)
14578acc472SPeter Tyser #define K 0x6ED9EBA1
14678acc472SPeter Tyser 
14778acc472SPeter Tyser 	P (A, B, C, D, E, R (20));
14878acc472SPeter Tyser 	P (E, A, B, C, D, R (21));
14978acc472SPeter Tyser 	P (D, E, A, B, C, R (22));
15078acc472SPeter Tyser 	P (C, D, E, A, B, R (23));
15178acc472SPeter Tyser 	P (B, C, D, E, A, R (24));
15278acc472SPeter Tyser 	P (A, B, C, D, E, R (25));
15378acc472SPeter Tyser 	P (E, A, B, C, D, R (26));
15478acc472SPeter Tyser 	P (D, E, A, B, C, R (27));
15578acc472SPeter Tyser 	P (C, D, E, A, B, R (28));
15678acc472SPeter Tyser 	P (B, C, D, E, A, R (29));
15778acc472SPeter Tyser 	P (A, B, C, D, E, R (30));
15878acc472SPeter Tyser 	P (E, A, B, C, D, R (31));
15978acc472SPeter Tyser 	P (D, E, A, B, C, R (32));
16078acc472SPeter Tyser 	P (C, D, E, A, B, R (33));
16178acc472SPeter Tyser 	P (B, C, D, E, A, R (34));
16278acc472SPeter Tyser 	P (A, B, C, D, E, R (35));
16378acc472SPeter Tyser 	P (E, A, B, C, D, R (36));
16478acc472SPeter Tyser 	P (D, E, A, B, C, R (37));
16578acc472SPeter Tyser 	P (C, D, E, A, B, R (38));
16678acc472SPeter Tyser 	P (B, C, D, E, A, R (39));
16778acc472SPeter Tyser 
16878acc472SPeter Tyser #undef K
16978acc472SPeter Tyser #undef F
17078acc472SPeter Tyser 
17178acc472SPeter Tyser #define F(x,y,z) ((x & y) | (z & (x | y)))
17278acc472SPeter Tyser #define K 0x8F1BBCDC
17378acc472SPeter Tyser 
17478acc472SPeter Tyser 	P (A, B, C, D, E, R (40));
17578acc472SPeter Tyser 	P (E, A, B, C, D, R (41));
17678acc472SPeter Tyser 	P (D, E, A, B, C, R (42));
17778acc472SPeter Tyser 	P (C, D, E, A, B, R (43));
17878acc472SPeter Tyser 	P (B, C, D, E, A, R (44));
17978acc472SPeter Tyser 	P (A, B, C, D, E, R (45));
18078acc472SPeter Tyser 	P (E, A, B, C, D, R (46));
18178acc472SPeter Tyser 	P (D, E, A, B, C, R (47));
18278acc472SPeter Tyser 	P (C, D, E, A, B, R (48));
18378acc472SPeter Tyser 	P (B, C, D, E, A, R (49));
18478acc472SPeter Tyser 	P (A, B, C, D, E, R (50));
18578acc472SPeter Tyser 	P (E, A, B, C, D, R (51));
18678acc472SPeter Tyser 	P (D, E, A, B, C, R (52));
18778acc472SPeter Tyser 	P (C, D, E, A, B, R (53));
18878acc472SPeter Tyser 	P (B, C, D, E, A, R (54));
18978acc472SPeter Tyser 	P (A, B, C, D, E, R (55));
19078acc472SPeter Tyser 	P (E, A, B, C, D, R (56));
19178acc472SPeter Tyser 	P (D, E, A, B, C, R (57));
19278acc472SPeter Tyser 	P (C, D, E, A, B, R (58));
19378acc472SPeter Tyser 	P (B, C, D, E, A, R (59));
19478acc472SPeter Tyser 
19578acc472SPeter Tyser #undef K
19678acc472SPeter Tyser #undef F
19778acc472SPeter Tyser 
19878acc472SPeter Tyser #define F(x,y,z) (x ^ y ^ z)
19978acc472SPeter Tyser #define K 0xCA62C1D6
20078acc472SPeter Tyser 
20178acc472SPeter Tyser 	P (A, B, C, D, E, R (60));
20278acc472SPeter Tyser 	P (E, A, B, C, D, R (61));
20378acc472SPeter Tyser 	P (D, E, A, B, C, R (62));
20478acc472SPeter Tyser 	P (C, D, E, A, B, R (63));
20578acc472SPeter Tyser 	P (B, C, D, E, A, R (64));
20678acc472SPeter Tyser 	P (A, B, C, D, E, R (65));
20778acc472SPeter Tyser 	P (E, A, B, C, D, R (66));
20878acc472SPeter Tyser 	P (D, E, A, B, C, R (67));
20978acc472SPeter Tyser 	P (C, D, E, A, B, R (68));
21078acc472SPeter Tyser 	P (B, C, D, E, A, R (69));
21178acc472SPeter Tyser 	P (A, B, C, D, E, R (70));
21278acc472SPeter Tyser 	P (E, A, B, C, D, R (71));
21378acc472SPeter Tyser 	P (D, E, A, B, C, R (72));
21478acc472SPeter Tyser 	P (C, D, E, A, B, R (73));
21578acc472SPeter Tyser 	P (B, C, D, E, A, R (74));
21678acc472SPeter Tyser 	P (A, B, C, D, E, R (75));
21778acc472SPeter Tyser 	P (E, A, B, C, D, R (76));
21878acc472SPeter Tyser 	P (D, E, A, B, C, R (77));
21978acc472SPeter Tyser 	P (C, D, E, A, B, R (78));
22078acc472SPeter Tyser 	P (B, C, D, E, A, R (79));
22178acc472SPeter Tyser 
22278acc472SPeter Tyser #undef K
22378acc472SPeter Tyser #undef F
22478acc472SPeter Tyser 
22578acc472SPeter Tyser 	ctx->state[0] += A;
22678acc472SPeter Tyser 	ctx->state[1] += B;
22778acc472SPeter Tyser 	ctx->state[2] += C;
22878acc472SPeter Tyser 	ctx->state[3] += D;
22978acc472SPeter Tyser 	ctx->state[4] += E;
23078acc472SPeter Tyser }
23178acc472SPeter Tyser 
232*87e494a1SLoic Poulain __weak void sha1_process(sha1_context *ctx, const unsigned char *data,
233*87e494a1SLoic Poulain 			 unsigned int blocks)
234*87e494a1SLoic Poulain {
235*87e494a1SLoic Poulain 	if (!blocks)
236*87e494a1SLoic Poulain 		return;
237*87e494a1SLoic Poulain 
238*87e494a1SLoic Poulain 	while (blocks--) {
239*87e494a1SLoic Poulain 		sha1_process_one(ctx, data);
240*87e494a1SLoic Poulain 		data += 64;
241*87e494a1SLoic Poulain 	}
242*87e494a1SLoic Poulain }
243*87e494a1SLoic Poulain 
24478acc472SPeter Tyser /*
24578acc472SPeter Tyser  * SHA-1 process buffer
24678acc472SPeter Tyser  */
247a7d1d765SSimon Glass void sha1_update(sha1_context *ctx, const unsigned char *input,
248a7d1d765SSimon Glass 		 unsigned int ilen)
24978acc472SPeter Tyser {
25078acc472SPeter Tyser 	int fill;
25178acc472SPeter Tyser 	unsigned long left;
25278acc472SPeter Tyser 
25378acc472SPeter Tyser 	if (ilen <= 0)
25478acc472SPeter Tyser 		return;
25578acc472SPeter Tyser 
25678acc472SPeter Tyser 	left = ctx->total[0] & 0x3F;
25778acc472SPeter Tyser 	fill = 64 - left;
25878acc472SPeter Tyser 
25978acc472SPeter Tyser 	ctx->total[0] += ilen;
26078acc472SPeter Tyser 	ctx->total[0] &= 0xFFFFFFFF;
26178acc472SPeter Tyser 
26278acc472SPeter Tyser 	if (ctx->total[0] < (unsigned long) ilen)
26378acc472SPeter Tyser 		ctx->total[1]++;
26478acc472SPeter Tyser 
26578acc472SPeter Tyser 	if (left && ilen >= fill) {
26678acc472SPeter Tyser 		memcpy ((void *) (ctx->buffer + left), (void *) input, fill);
267*87e494a1SLoic Poulain 		sha1_process(ctx, ctx->buffer, 1);
26878acc472SPeter Tyser 		input += fill;
26978acc472SPeter Tyser 		ilen -= fill;
27078acc472SPeter Tyser 		left = 0;
27178acc472SPeter Tyser 	}
27278acc472SPeter Tyser 
273*87e494a1SLoic Poulain 	sha1_process(ctx, input, ilen / 64);
274*87e494a1SLoic Poulain 	input += ilen / 64 * 64;
275*87e494a1SLoic Poulain 	ilen = ilen % 64;
27678acc472SPeter Tyser 
27778acc472SPeter Tyser 	if (ilen > 0) {
27878acc472SPeter Tyser 		memcpy ((void *) (ctx->buffer + left), (void *) input, ilen);
27978acc472SPeter Tyser 	}
28078acc472SPeter Tyser }
28178acc472SPeter Tyser 
28278acc472SPeter Tyser static const unsigned char sha1_padding[64] = {
28378acc472SPeter Tyser 	0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
28478acc472SPeter Tyser 	   0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
28578acc472SPeter Tyser 	   0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
28678acc472SPeter Tyser 	   0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
28778acc472SPeter Tyser };
28878acc472SPeter Tyser 
28978acc472SPeter Tyser /*
29078acc472SPeter Tyser  * SHA-1 final digest
29178acc472SPeter Tyser  */
29278acc472SPeter Tyser void sha1_finish (sha1_context * ctx, unsigned char output[20])
29378acc472SPeter Tyser {
29478acc472SPeter Tyser 	unsigned long last, padn;
29578acc472SPeter Tyser 	unsigned long high, low;
29678acc472SPeter Tyser 	unsigned char msglen[8];
29778acc472SPeter Tyser 
29878acc472SPeter Tyser 	high = (ctx->total[0] >> 29)
29978acc472SPeter Tyser 		| (ctx->total[1] << 3);
30078acc472SPeter Tyser 	low = (ctx->total[0] << 3);
30178acc472SPeter Tyser 
30278acc472SPeter Tyser 	PUT_UINT32_BE (high, msglen, 0);
30378acc472SPeter Tyser 	PUT_UINT32_BE (low, msglen, 4);
30478acc472SPeter Tyser 
30578acc472SPeter Tyser 	last = ctx->total[0] & 0x3F;
30678acc472SPeter Tyser 	padn = (last < 56) ? (56 - last) : (120 - last);
30778acc472SPeter Tyser 
30878acc472SPeter Tyser 	sha1_update (ctx, (unsigned char *) sha1_padding, padn);
30978acc472SPeter Tyser 	sha1_update (ctx, msglen, 8);
31078acc472SPeter Tyser 
31178acc472SPeter Tyser 	PUT_UINT32_BE (ctx->state[0], output, 0);
31278acc472SPeter Tyser 	PUT_UINT32_BE (ctx->state[1], output, 4);
31378acc472SPeter Tyser 	PUT_UINT32_BE (ctx->state[2], output, 8);
31478acc472SPeter Tyser 	PUT_UINT32_BE (ctx->state[3], output, 12);
31578acc472SPeter Tyser 	PUT_UINT32_BE (ctx->state[4], output, 16);
31678acc472SPeter Tyser }
31778acc472SPeter Tyser 
31878acc472SPeter Tyser /*
31978acc472SPeter Tyser  * Output = SHA-1( input buffer )
32078acc472SPeter Tyser  */
321a7d1d765SSimon Glass void sha1_csum(const unsigned char *input, unsigned int ilen,
322a7d1d765SSimon Glass 	       unsigned char *output)
32378acc472SPeter Tyser {
32478acc472SPeter Tyser 	sha1_context ctx;
32578acc472SPeter Tyser 
32678acc472SPeter Tyser 	sha1_starts (&ctx);
32778acc472SPeter Tyser 	sha1_update (&ctx, input, ilen);
32878acc472SPeter Tyser 	sha1_finish (&ctx, output);
32978acc472SPeter Tyser }
33078acc472SPeter Tyser 
33178acc472SPeter Tyser /*
33278acc472SPeter Tyser  * Output = SHA-1( input buffer ). Trigger the watchdog every 'chunk_sz'
33378acc472SPeter Tyser  * bytes of input processed.
33478acc472SPeter Tyser  */
335a7d1d765SSimon Glass void sha1_csum_wd(const unsigned char *input, unsigned int ilen,
336a7d1d765SSimon Glass 		  unsigned char *output, unsigned int chunk_sz)
33778acc472SPeter Tyser {
33878acc472SPeter Tyser 	sha1_context ctx;
33978acc472SPeter Tyser #if defined(CONFIG_HW_WATCHDOG) || defined(CONFIG_WATCHDOG)
340a7d1d765SSimon Glass 	const unsigned char *end, *curr;
34178acc472SPeter Tyser 	int chunk;
34278acc472SPeter Tyser #endif
34378acc472SPeter Tyser 
34478acc472SPeter Tyser 	sha1_starts (&ctx);
34578acc472SPeter Tyser 
34678acc472SPeter Tyser #if defined(CONFIG_HW_WATCHDOG) || defined(CONFIG_WATCHDOG)
34778acc472SPeter Tyser 	curr = input;
34878acc472SPeter Tyser 	end = input + ilen;
34978acc472SPeter Tyser 	while (curr < end) {
35078acc472SPeter Tyser 		chunk = end - curr;
35178acc472SPeter Tyser 		if (chunk > chunk_sz)
35278acc472SPeter Tyser 			chunk = chunk_sz;
35378acc472SPeter Tyser 		sha1_update (&ctx, curr, chunk);
35478acc472SPeter Tyser 		curr += chunk;
35578acc472SPeter Tyser 		WATCHDOG_RESET ();
35678acc472SPeter Tyser 	}
35778acc472SPeter Tyser #else
35878acc472SPeter Tyser 	sha1_update (&ctx, input, ilen);
35978acc472SPeter Tyser #endif
36078acc472SPeter Tyser 
36178acc472SPeter Tyser 	sha1_finish (&ctx, output);
36278acc472SPeter Tyser }
36378acc472SPeter Tyser 
36478acc472SPeter Tyser /*
36578acc472SPeter Tyser  * Output = HMAC-SHA-1( input buffer, hmac key )
36678acc472SPeter Tyser  */
367a7d1d765SSimon Glass void sha1_hmac(const unsigned char *key, int keylen,
368a7d1d765SSimon Glass 	       const unsigned char *input, unsigned int ilen,
369a7d1d765SSimon Glass 	       unsigned char *output)
37078acc472SPeter Tyser {
37178acc472SPeter Tyser 	int i;
37278acc472SPeter Tyser 	sha1_context ctx;
37378acc472SPeter Tyser 	unsigned char k_ipad[64];
37478acc472SPeter Tyser 	unsigned char k_opad[64];
37578acc472SPeter Tyser 	unsigned char tmpbuf[20];
37678acc472SPeter Tyser 
37778acc472SPeter Tyser 	memset (k_ipad, 0x36, 64);
37878acc472SPeter Tyser 	memset (k_opad, 0x5C, 64);
37978acc472SPeter Tyser 
38078acc472SPeter Tyser 	for (i = 0; i < keylen; i++) {
38178acc472SPeter Tyser 		if (i >= 64)
38278acc472SPeter Tyser 			break;
38378acc472SPeter Tyser 
38478acc472SPeter Tyser 		k_ipad[i] ^= key[i];
38578acc472SPeter Tyser 		k_opad[i] ^= key[i];
38678acc472SPeter Tyser 	}
38778acc472SPeter Tyser 
38878acc472SPeter Tyser 	sha1_starts (&ctx);
38978acc472SPeter Tyser 	sha1_update (&ctx, k_ipad, 64);
39078acc472SPeter Tyser 	sha1_update (&ctx, input, ilen);
39178acc472SPeter Tyser 	sha1_finish (&ctx, tmpbuf);
39278acc472SPeter Tyser 
39378acc472SPeter Tyser 	sha1_starts (&ctx);
39478acc472SPeter Tyser 	sha1_update (&ctx, k_opad, 64);
39578acc472SPeter Tyser 	sha1_update (&ctx, tmpbuf, 20);
39678acc472SPeter Tyser 	sha1_finish (&ctx, output);
39778acc472SPeter Tyser 
39878acc472SPeter Tyser 	memset (k_ipad, 0, 64);
39978acc472SPeter Tyser 	memset (k_opad, 0, 64);
40078acc472SPeter Tyser 	memset (tmpbuf, 0, 20);
40178acc472SPeter Tyser 	memset (&ctx, 0, sizeof (sha1_context));
40278acc472SPeter Tyser }
40378acc472SPeter Tyser 
40478acc472SPeter Tyser #ifdef SELF_TEST
40578acc472SPeter Tyser /*
40678acc472SPeter Tyser  * FIPS-180-1 test vectors
40778acc472SPeter Tyser  */
40878acc472SPeter Tyser static const char sha1_test_str[3][57] = {
40978acc472SPeter Tyser 	{"abc"},
41078acc472SPeter Tyser 	{"abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq"},
41178acc472SPeter Tyser 	{""}
41278acc472SPeter Tyser };
41378acc472SPeter Tyser 
41478acc472SPeter Tyser static const unsigned char sha1_test_sum[3][20] = {
41578acc472SPeter Tyser 	{0xA9, 0x99, 0x3E, 0x36, 0x47, 0x06, 0x81, 0x6A, 0xBA, 0x3E,
41678acc472SPeter Tyser 	 0x25, 0x71, 0x78, 0x50, 0xC2, 0x6C, 0x9C, 0xD0, 0xD8, 0x9D},
41778acc472SPeter Tyser 	{0x84, 0x98, 0x3E, 0x44, 0x1C, 0x3B, 0xD2, 0x6E, 0xBA, 0xAE,
41878acc472SPeter Tyser 	 0x4A, 0xA1, 0xF9, 0x51, 0x29, 0xE5, 0xE5, 0x46, 0x70, 0xF1},
41978acc472SPeter Tyser 	{0x34, 0xAA, 0x97, 0x3C, 0xD4, 0xC4, 0xDA, 0xA4, 0xF6, 0x1E,
42078acc472SPeter Tyser 	 0xEB, 0x2B, 0xDB, 0xAD, 0x27, 0x31, 0x65, 0x34, 0x01, 0x6F}
42178acc472SPeter Tyser };
42278acc472SPeter Tyser 
42378acc472SPeter Tyser /*
42478acc472SPeter Tyser  * Checkup routine
42578acc472SPeter Tyser  */
42678acc472SPeter Tyser int sha1_self_test (void)
42778acc472SPeter Tyser {
42878acc472SPeter Tyser 	int i, j;
42978acc472SPeter Tyser 	unsigned char buf[1000];
43078acc472SPeter Tyser 	unsigned char sha1sum[20];
43178acc472SPeter Tyser 	sha1_context ctx;
43278acc472SPeter Tyser 
43378acc472SPeter Tyser 	for (i = 0; i < 3; i++) {
43478acc472SPeter Tyser 		printf ("  SHA-1 test #%d: ", i + 1);
43578acc472SPeter Tyser 
43678acc472SPeter Tyser 		sha1_starts (&ctx);
43778acc472SPeter Tyser 
43878acc472SPeter Tyser 		if (i < 2)
43978acc472SPeter Tyser 			sha1_update (&ctx, (unsigned char *) sha1_test_str[i],
44078acc472SPeter Tyser 				     strlen (sha1_test_str[i]));
44178acc472SPeter Tyser 		else {
44278acc472SPeter Tyser 			memset (buf, 'a', 1000);
44378acc472SPeter Tyser 			for (j = 0; j < 1000; j++)
44478acc472SPeter Tyser 				sha1_update (&ctx, buf, 1000);
44578acc472SPeter Tyser 		}
44678acc472SPeter Tyser 
44778acc472SPeter Tyser 		sha1_finish (&ctx, sha1sum);
44878acc472SPeter Tyser 
44978acc472SPeter Tyser 		if (memcmp (sha1sum, sha1_test_sum[i], 20) != 0) {
45078acc472SPeter Tyser 			printf ("failed\n");
45178acc472SPeter Tyser 			return (1);
45278acc472SPeter Tyser 		}
45378acc472SPeter Tyser 
45478acc472SPeter Tyser 		printf ("passed\n");
45578acc472SPeter Tyser 	}
45678acc472SPeter Tyser 
45778acc472SPeter Tyser 	printf ("\n");
45878acc472SPeter Tyser 	return (0);
45978acc472SPeter Tyser }
46078acc472SPeter Tyser #else
46178acc472SPeter Tyser int sha1_self_test (void)
46278acc472SPeter Tyser {
46378acc472SPeter Tyser 	return (0);
46478acc472SPeter Tyser }
46578acc472SPeter Tyser #endif
466