xref: /OK3568_Linux_fs/u-boot/lib/sha1.c (revision 4882a59341e53eb6f0b4789bf948001014eff981)
1*4882a593Smuzhiyun /*
2*4882a593Smuzhiyun  *  Heiko Schocher, DENX Software Engineering, hs@denx.de.
3*4882a593Smuzhiyun  *  based on:
4*4882a593Smuzhiyun  *  FIPS-180-1 compliant SHA-1 implementation
5*4882a593Smuzhiyun  *
6*4882a593Smuzhiyun  *  Copyright (C) 2003-2006  Christophe Devine
7*4882a593Smuzhiyun  *
8*4882a593Smuzhiyun  * SPDX-License-Identifier:	LGPL-2.1
9*4882a593Smuzhiyun  */
10*4882a593Smuzhiyun /*
11*4882a593Smuzhiyun  *  The SHA-1 standard was published by NIST in 1993.
12*4882a593Smuzhiyun  *
13*4882a593Smuzhiyun  *  http://www.itl.nist.gov/fipspubs/fip180-1.htm
14*4882a593Smuzhiyun  */
15*4882a593Smuzhiyun 
16*4882a593Smuzhiyun #ifndef _CRT_SECURE_NO_DEPRECATE
17*4882a593Smuzhiyun #define _CRT_SECURE_NO_DEPRECATE 1
18*4882a593Smuzhiyun #endif
19*4882a593Smuzhiyun 
20*4882a593Smuzhiyun #ifndef USE_HOSTCC
21*4882a593Smuzhiyun #include <common.h>
22*4882a593Smuzhiyun #include <linux/string.h>
23*4882a593Smuzhiyun #else
24*4882a593Smuzhiyun #include <string.h>
25*4882a593Smuzhiyun #endif /* USE_HOSTCC */
26*4882a593Smuzhiyun #include <watchdog.h>
27*4882a593Smuzhiyun #include <u-boot/sha1.h>
28*4882a593Smuzhiyun 
29*4882a593Smuzhiyun #include <linux/compiler.h>
30*4882a593Smuzhiyun 
31*4882a593Smuzhiyun #ifdef USE_HOSTCC
32*4882a593Smuzhiyun #undef __weak
33*4882a593Smuzhiyun #define __weak
34*4882a593Smuzhiyun #undef __maybe_unused
35*4882a593Smuzhiyun #define __maybe_unused
36*4882a593Smuzhiyun #endif
37*4882a593Smuzhiyun 
38*4882a593Smuzhiyun const uint8_t sha1_der_prefix[SHA1_DER_LEN] = {
39*4882a593Smuzhiyun 	0x30, 0x21, 0x30, 0x09, 0x06, 0x05, 0x2b, 0x0e,
40*4882a593Smuzhiyun 	0x03, 0x02, 0x1a, 0x05, 0x00, 0x04, 0x14
41*4882a593Smuzhiyun };
42*4882a593Smuzhiyun 
43*4882a593Smuzhiyun /*
44*4882a593Smuzhiyun  * 32-bit integer manipulation macros (big endian)
45*4882a593Smuzhiyun  */
46*4882a593Smuzhiyun #ifndef GET_UINT32_BE
47*4882a593Smuzhiyun #define GET_UINT32_BE(n,b,i) {				\
48*4882a593Smuzhiyun 	(n) = ( (unsigned long) (b)[(i)    ] << 24 )	\
49*4882a593Smuzhiyun 	    | ( (unsigned long) (b)[(i) + 1] << 16 )	\
50*4882a593Smuzhiyun 	    | ( (unsigned long) (b)[(i) + 2] <<  8 )	\
51*4882a593Smuzhiyun 	    | ( (unsigned long) (b)[(i) + 3]       );	\
52*4882a593Smuzhiyun }
53*4882a593Smuzhiyun #endif
54*4882a593Smuzhiyun #ifndef PUT_UINT32_BE
55*4882a593Smuzhiyun #define PUT_UINT32_BE(n,b,i) {				\
56*4882a593Smuzhiyun 	(b)[(i)    ] = (unsigned char) ( (n) >> 24 );	\
57*4882a593Smuzhiyun 	(b)[(i) + 1] = (unsigned char) ( (n) >> 16 );	\
58*4882a593Smuzhiyun 	(b)[(i) + 2] = (unsigned char) ( (n) >>  8 );	\
59*4882a593Smuzhiyun 	(b)[(i) + 3] = (unsigned char) ( (n)       );	\
60*4882a593Smuzhiyun }
61*4882a593Smuzhiyun #endif
62*4882a593Smuzhiyun 
63*4882a593Smuzhiyun /*
64*4882a593Smuzhiyun  * SHA-1 context setup
65*4882a593Smuzhiyun  */
sha1_starts(sha1_context * ctx)66*4882a593Smuzhiyun void sha1_starts (sha1_context * ctx)
67*4882a593Smuzhiyun {
68*4882a593Smuzhiyun 	ctx->total[0] = 0;
69*4882a593Smuzhiyun 	ctx->total[1] = 0;
70*4882a593Smuzhiyun 
71*4882a593Smuzhiyun 	ctx->state[0] = 0x67452301;
72*4882a593Smuzhiyun 	ctx->state[1] = 0xEFCDAB89;
73*4882a593Smuzhiyun 	ctx->state[2] = 0x98BADCFE;
74*4882a593Smuzhiyun 	ctx->state[3] = 0x10325476;
75*4882a593Smuzhiyun 	ctx->state[4] = 0xC3D2E1F0;
76*4882a593Smuzhiyun }
77*4882a593Smuzhiyun 
sha1_process_one(sha1_context * ctx,const unsigned char data[64])78*4882a593Smuzhiyun static void __maybe_unused sha1_process_one(sha1_context *ctx, const unsigned char data[64])
79*4882a593Smuzhiyun {
80*4882a593Smuzhiyun 	unsigned long temp, W[16], A, B, C, D, E;
81*4882a593Smuzhiyun 
82*4882a593Smuzhiyun 	GET_UINT32_BE (W[0], data, 0);
83*4882a593Smuzhiyun 	GET_UINT32_BE (W[1], data, 4);
84*4882a593Smuzhiyun 	GET_UINT32_BE (W[2], data, 8);
85*4882a593Smuzhiyun 	GET_UINT32_BE (W[3], data, 12);
86*4882a593Smuzhiyun 	GET_UINT32_BE (W[4], data, 16);
87*4882a593Smuzhiyun 	GET_UINT32_BE (W[5], data, 20);
88*4882a593Smuzhiyun 	GET_UINT32_BE (W[6], data, 24);
89*4882a593Smuzhiyun 	GET_UINT32_BE (W[7], data, 28);
90*4882a593Smuzhiyun 	GET_UINT32_BE (W[8], data, 32);
91*4882a593Smuzhiyun 	GET_UINT32_BE (W[9], data, 36);
92*4882a593Smuzhiyun 	GET_UINT32_BE (W[10], data, 40);
93*4882a593Smuzhiyun 	GET_UINT32_BE (W[11], data, 44);
94*4882a593Smuzhiyun 	GET_UINT32_BE (W[12], data, 48);
95*4882a593Smuzhiyun 	GET_UINT32_BE (W[13], data, 52);
96*4882a593Smuzhiyun 	GET_UINT32_BE (W[14], data, 56);
97*4882a593Smuzhiyun 	GET_UINT32_BE (W[15], data, 60);
98*4882a593Smuzhiyun 
99*4882a593Smuzhiyun #define S(x,n)	((x << n) | ((x & 0xFFFFFFFF) >> (32 - n)))
100*4882a593Smuzhiyun 
101*4882a593Smuzhiyun #define R(t) (						\
102*4882a593Smuzhiyun 	temp = W[(t -  3) & 0x0F] ^ W[(t - 8) & 0x0F] ^	\
103*4882a593Smuzhiyun 	       W[(t - 14) & 0x0F] ^ W[ t      & 0x0F],	\
104*4882a593Smuzhiyun 	( W[t & 0x0F] = S(temp,1) )			\
105*4882a593Smuzhiyun )
106*4882a593Smuzhiyun 
107*4882a593Smuzhiyun #define P(a,b,c,d,e,x)	{				\
108*4882a593Smuzhiyun 	e += S(a,5) + F(b,c,d) + K + x; b = S(b,30);	\
109*4882a593Smuzhiyun }
110*4882a593Smuzhiyun 
111*4882a593Smuzhiyun 	A = ctx->state[0];
112*4882a593Smuzhiyun 	B = ctx->state[1];
113*4882a593Smuzhiyun 	C = ctx->state[2];
114*4882a593Smuzhiyun 	D = ctx->state[3];
115*4882a593Smuzhiyun 	E = ctx->state[4];
116*4882a593Smuzhiyun 
117*4882a593Smuzhiyun #define F(x,y,z) (z ^ (x & (y ^ z)))
118*4882a593Smuzhiyun #define K 0x5A827999
119*4882a593Smuzhiyun 
120*4882a593Smuzhiyun 	P (A, B, C, D, E, W[0]);
121*4882a593Smuzhiyun 	P (E, A, B, C, D, W[1]);
122*4882a593Smuzhiyun 	P (D, E, A, B, C, W[2]);
123*4882a593Smuzhiyun 	P (C, D, E, A, B, W[3]);
124*4882a593Smuzhiyun 	P (B, C, D, E, A, W[4]);
125*4882a593Smuzhiyun 	P (A, B, C, D, E, W[5]);
126*4882a593Smuzhiyun 	P (E, A, B, C, D, W[6]);
127*4882a593Smuzhiyun 	P (D, E, A, B, C, W[7]);
128*4882a593Smuzhiyun 	P (C, D, E, A, B, W[8]);
129*4882a593Smuzhiyun 	P (B, C, D, E, A, W[9]);
130*4882a593Smuzhiyun 	P (A, B, C, D, E, W[10]);
131*4882a593Smuzhiyun 	P (E, A, B, C, D, W[11]);
132*4882a593Smuzhiyun 	P (D, E, A, B, C, W[12]);
133*4882a593Smuzhiyun 	P (C, D, E, A, B, W[13]);
134*4882a593Smuzhiyun 	P (B, C, D, E, A, W[14]);
135*4882a593Smuzhiyun 	P (A, B, C, D, E, W[15]);
136*4882a593Smuzhiyun 	P (E, A, B, C, D, R (16));
137*4882a593Smuzhiyun 	P (D, E, A, B, C, R (17));
138*4882a593Smuzhiyun 	P (C, D, E, A, B, R (18));
139*4882a593Smuzhiyun 	P (B, C, D, E, A, R (19));
140*4882a593Smuzhiyun 
141*4882a593Smuzhiyun #undef K
142*4882a593Smuzhiyun #undef F
143*4882a593Smuzhiyun 
144*4882a593Smuzhiyun #define F(x,y,z) (x ^ y ^ z)
145*4882a593Smuzhiyun #define K 0x6ED9EBA1
146*4882a593Smuzhiyun 
147*4882a593Smuzhiyun 	P (A, B, C, D, E, R (20));
148*4882a593Smuzhiyun 	P (E, A, B, C, D, R (21));
149*4882a593Smuzhiyun 	P (D, E, A, B, C, R (22));
150*4882a593Smuzhiyun 	P (C, D, E, A, B, R (23));
151*4882a593Smuzhiyun 	P (B, C, D, E, A, R (24));
152*4882a593Smuzhiyun 	P (A, B, C, D, E, R (25));
153*4882a593Smuzhiyun 	P (E, A, B, C, D, R (26));
154*4882a593Smuzhiyun 	P (D, E, A, B, C, R (27));
155*4882a593Smuzhiyun 	P (C, D, E, A, B, R (28));
156*4882a593Smuzhiyun 	P (B, C, D, E, A, R (29));
157*4882a593Smuzhiyun 	P (A, B, C, D, E, R (30));
158*4882a593Smuzhiyun 	P (E, A, B, C, D, R (31));
159*4882a593Smuzhiyun 	P (D, E, A, B, C, R (32));
160*4882a593Smuzhiyun 	P (C, D, E, A, B, R (33));
161*4882a593Smuzhiyun 	P (B, C, D, E, A, R (34));
162*4882a593Smuzhiyun 	P (A, B, C, D, E, R (35));
163*4882a593Smuzhiyun 	P (E, A, B, C, D, R (36));
164*4882a593Smuzhiyun 	P (D, E, A, B, C, R (37));
165*4882a593Smuzhiyun 	P (C, D, E, A, B, R (38));
166*4882a593Smuzhiyun 	P (B, C, D, E, A, R (39));
167*4882a593Smuzhiyun 
168*4882a593Smuzhiyun #undef K
169*4882a593Smuzhiyun #undef F
170*4882a593Smuzhiyun 
171*4882a593Smuzhiyun #define F(x,y,z) ((x & y) | (z & (x | y)))
172*4882a593Smuzhiyun #define K 0x8F1BBCDC
173*4882a593Smuzhiyun 
174*4882a593Smuzhiyun 	P (A, B, C, D, E, R (40));
175*4882a593Smuzhiyun 	P (E, A, B, C, D, R (41));
176*4882a593Smuzhiyun 	P (D, E, A, B, C, R (42));
177*4882a593Smuzhiyun 	P (C, D, E, A, B, R (43));
178*4882a593Smuzhiyun 	P (B, C, D, E, A, R (44));
179*4882a593Smuzhiyun 	P (A, B, C, D, E, R (45));
180*4882a593Smuzhiyun 	P (E, A, B, C, D, R (46));
181*4882a593Smuzhiyun 	P (D, E, A, B, C, R (47));
182*4882a593Smuzhiyun 	P (C, D, E, A, B, R (48));
183*4882a593Smuzhiyun 	P (B, C, D, E, A, R (49));
184*4882a593Smuzhiyun 	P (A, B, C, D, E, R (50));
185*4882a593Smuzhiyun 	P (E, A, B, C, D, R (51));
186*4882a593Smuzhiyun 	P (D, E, A, B, C, R (52));
187*4882a593Smuzhiyun 	P (C, D, E, A, B, R (53));
188*4882a593Smuzhiyun 	P (B, C, D, E, A, R (54));
189*4882a593Smuzhiyun 	P (A, B, C, D, E, R (55));
190*4882a593Smuzhiyun 	P (E, A, B, C, D, R (56));
191*4882a593Smuzhiyun 	P (D, E, A, B, C, R (57));
192*4882a593Smuzhiyun 	P (C, D, E, A, B, R (58));
193*4882a593Smuzhiyun 	P (B, C, D, E, A, R (59));
194*4882a593Smuzhiyun 
195*4882a593Smuzhiyun #undef K
196*4882a593Smuzhiyun #undef F
197*4882a593Smuzhiyun 
198*4882a593Smuzhiyun #define F(x,y,z) (x ^ y ^ z)
199*4882a593Smuzhiyun #define K 0xCA62C1D6
200*4882a593Smuzhiyun 
201*4882a593Smuzhiyun 	P (A, B, C, D, E, R (60));
202*4882a593Smuzhiyun 	P (E, A, B, C, D, R (61));
203*4882a593Smuzhiyun 	P (D, E, A, B, C, R (62));
204*4882a593Smuzhiyun 	P (C, D, E, A, B, R (63));
205*4882a593Smuzhiyun 	P (B, C, D, E, A, R (64));
206*4882a593Smuzhiyun 	P (A, B, C, D, E, R (65));
207*4882a593Smuzhiyun 	P (E, A, B, C, D, R (66));
208*4882a593Smuzhiyun 	P (D, E, A, B, C, R (67));
209*4882a593Smuzhiyun 	P (C, D, E, A, B, R (68));
210*4882a593Smuzhiyun 	P (B, C, D, E, A, R (69));
211*4882a593Smuzhiyun 	P (A, B, C, D, E, R (70));
212*4882a593Smuzhiyun 	P (E, A, B, C, D, R (71));
213*4882a593Smuzhiyun 	P (D, E, A, B, C, R (72));
214*4882a593Smuzhiyun 	P (C, D, E, A, B, R (73));
215*4882a593Smuzhiyun 	P (B, C, D, E, A, R (74));
216*4882a593Smuzhiyun 	P (A, B, C, D, E, R (75));
217*4882a593Smuzhiyun 	P (E, A, B, C, D, R (76));
218*4882a593Smuzhiyun 	P (D, E, A, B, C, R (77));
219*4882a593Smuzhiyun 	P (C, D, E, A, B, R (78));
220*4882a593Smuzhiyun 	P (B, C, D, E, A, R (79));
221*4882a593Smuzhiyun 
222*4882a593Smuzhiyun #undef K
223*4882a593Smuzhiyun #undef F
224*4882a593Smuzhiyun 
225*4882a593Smuzhiyun 	ctx->state[0] += A;
226*4882a593Smuzhiyun 	ctx->state[1] += B;
227*4882a593Smuzhiyun 	ctx->state[2] += C;
228*4882a593Smuzhiyun 	ctx->state[3] += D;
229*4882a593Smuzhiyun 	ctx->state[4] += E;
230*4882a593Smuzhiyun }
231*4882a593Smuzhiyun 
sha1_process(sha1_context * ctx,const unsigned char * data,unsigned int blocks)232*4882a593Smuzhiyun __weak void sha1_process(sha1_context *ctx, const unsigned char *data,
233*4882a593Smuzhiyun 			 unsigned int blocks)
234*4882a593Smuzhiyun {
235*4882a593Smuzhiyun 	if (!blocks)
236*4882a593Smuzhiyun 		return;
237*4882a593Smuzhiyun 
238*4882a593Smuzhiyun 	while (blocks--) {
239*4882a593Smuzhiyun 		sha1_process_one(ctx, data);
240*4882a593Smuzhiyun 		data += 64;
241*4882a593Smuzhiyun 	}
242*4882a593Smuzhiyun }
243*4882a593Smuzhiyun 
244*4882a593Smuzhiyun /*
245*4882a593Smuzhiyun  * SHA-1 process buffer
246*4882a593Smuzhiyun  */
sha1_update(sha1_context * ctx,const unsigned char * input,unsigned int ilen)247*4882a593Smuzhiyun void sha1_update(sha1_context *ctx, const unsigned char *input,
248*4882a593Smuzhiyun 		 unsigned int ilen)
249*4882a593Smuzhiyun {
250*4882a593Smuzhiyun 	int fill;
251*4882a593Smuzhiyun 	unsigned long left;
252*4882a593Smuzhiyun 
253*4882a593Smuzhiyun 	if (ilen <= 0)
254*4882a593Smuzhiyun 		return;
255*4882a593Smuzhiyun 
256*4882a593Smuzhiyun 	left = ctx->total[0] & 0x3F;
257*4882a593Smuzhiyun 	fill = 64 - left;
258*4882a593Smuzhiyun 
259*4882a593Smuzhiyun 	ctx->total[0] += ilen;
260*4882a593Smuzhiyun 	ctx->total[0] &= 0xFFFFFFFF;
261*4882a593Smuzhiyun 
262*4882a593Smuzhiyun 	if (ctx->total[0] < (unsigned long) ilen)
263*4882a593Smuzhiyun 		ctx->total[1]++;
264*4882a593Smuzhiyun 
265*4882a593Smuzhiyun 	if (left && ilen >= fill) {
266*4882a593Smuzhiyun 		memcpy ((void *) (ctx->buffer + left), (void *) input, fill);
267*4882a593Smuzhiyun 		sha1_process(ctx, ctx->buffer, 1);
268*4882a593Smuzhiyun 		input += fill;
269*4882a593Smuzhiyun 		ilen -= fill;
270*4882a593Smuzhiyun 		left = 0;
271*4882a593Smuzhiyun 	}
272*4882a593Smuzhiyun 
273*4882a593Smuzhiyun 	sha1_process(ctx, input, ilen / 64);
274*4882a593Smuzhiyun 	input += ilen / 64 * 64;
275*4882a593Smuzhiyun 	ilen = ilen % 64;
276*4882a593Smuzhiyun 
277*4882a593Smuzhiyun 	if (ilen > 0) {
278*4882a593Smuzhiyun 		memcpy ((void *) (ctx->buffer + left), (void *) input, ilen);
279*4882a593Smuzhiyun 	}
280*4882a593Smuzhiyun }
281*4882a593Smuzhiyun 
282*4882a593Smuzhiyun static const unsigned char sha1_padding[64] = {
283*4882a593Smuzhiyun 	0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
284*4882a593Smuzhiyun 	   0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
285*4882a593Smuzhiyun 	   0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
286*4882a593Smuzhiyun 	   0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
287*4882a593Smuzhiyun };
288*4882a593Smuzhiyun 
289*4882a593Smuzhiyun /*
290*4882a593Smuzhiyun  * SHA-1 final digest
291*4882a593Smuzhiyun  */
sha1_finish(sha1_context * ctx,unsigned char output[20])292*4882a593Smuzhiyun void sha1_finish (sha1_context * ctx, unsigned char output[20])
293*4882a593Smuzhiyun {
294*4882a593Smuzhiyun 	unsigned long last, padn;
295*4882a593Smuzhiyun 	unsigned long high, low;
296*4882a593Smuzhiyun 	unsigned char msglen[8];
297*4882a593Smuzhiyun 
298*4882a593Smuzhiyun 	high = (ctx->total[0] >> 29)
299*4882a593Smuzhiyun 		| (ctx->total[1] << 3);
300*4882a593Smuzhiyun 	low = (ctx->total[0] << 3);
301*4882a593Smuzhiyun 
302*4882a593Smuzhiyun 	PUT_UINT32_BE (high, msglen, 0);
303*4882a593Smuzhiyun 	PUT_UINT32_BE (low, msglen, 4);
304*4882a593Smuzhiyun 
305*4882a593Smuzhiyun 	last = ctx->total[0] & 0x3F;
306*4882a593Smuzhiyun 	padn = (last < 56) ? (56 - last) : (120 - last);
307*4882a593Smuzhiyun 
308*4882a593Smuzhiyun 	sha1_update (ctx, (unsigned char *) sha1_padding, padn);
309*4882a593Smuzhiyun 	sha1_update (ctx, msglen, 8);
310*4882a593Smuzhiyun 
311*4882a593Smuzhiyun 	PUT_UINT32_BE (ctx->state[0], output, 0);
312*4882a593Smuzhiyun 	PUT_UINT32_BE (ctx->state[1], output, 4);
313*4882a593Smuzhiyun 	PUT_UINT32_BE (ctx->state[2], output, 8);
314*4882a593Smuzhiyun 	PUT_UINT32_BE (ctx->state[3], output, 12);
315*4882a593Smuzhiyun 	PUT_UINT32_BE (ctx->state[4], output, 16);
316*4882a593Smuzhiyun }
317*4882a593Smuzhiyun 
318*4882a593Smuzhiyun /*
319*4882a593Smuzhiyun  * Output = SHA-1( input buffer )
320*4882a593Smuzhiyun  */
sha1_csum(const unsigned char * input,unsigned int ilen,unsigned char * output)321*4882a593Smuzhiyun void sha1_csum(const unsigned char *input, unsigned int ilen,
322*4882a593Smuzhiyun 	       unsigned char *output)
323*4882a593Smuzhiyun {
324*4882a593Smuzhiyun 	sha1_context ctx;
325*4882a593Smuzhiyun 
326*4882a593Smuzhiyun 	sha1_starts (&ctx);
327*4882a593Smuzhiyun 	sha1_update (&ctx, input, ilen);
328*4882a593Smuzhiyun 	sha1_finish (&ctx, output);
329*4882a593Smuzhiyun }
330*4882a593Smuzhiyun 
331*4882a593Smuzhiyun /*
332*4882a593Smuzhiyun  * Output = SHA-1( input buffer ). Trigger the watchdog every 'chunk_sz'
333*4882a593Smuzhiyun  * bytes of input processed.
334*4882a593Smuzhiyun  */
sha1_csum_wd(const unsigned char * input,unsigned int ilen,unsigned char * output,unsigned int chunk_sz)335*4882a593Smuzhiyun void sha1_csum_wd(const unsigned char *input, unsigned int ilen,
336*4882a593Smuzhiyun 		  unsigned char *output, unsigned int chunk_sz)
337*4882a593Smuzhiyun {
338*4882a593Smuzhiyun 	sha1_context ctx;
339*4882a593Smuzhiyun #if defined(CONFIG_HW_WATCHDOG) || defined(CONFIG_WATCHDOG)
340*4882a593Smuzhiyun 	const unsigned char *end, *curr;
341*4882a593Smuzhiyun 	int chunk;
342*4882a593Smuzhiyun #endif
343*4882a593Smuzhiyun 
344*4882a593Smuzhiyun 	sha1_starts (&ctx);
345*4882a593Smuzhiyun 
346*4882a593Smuzhiyun #if defined(CONFIG_HW_WATCHDOG) || defined(CONFIG_WATCHDOG)
347*4882a593Smuzhiyun 	curr = input;
348*4882a593Smuzhiyun 	end = input + ilen;
349*4882a593Smuzhiyun 	while (curr < end) {
350*4882a593Smuzhiyun 		chunk = end - curr;
351*4882a593Smuzhiyun 		if (chunk > chunk_sz)
352*4882a593Smuzhiyun 			chunk = chunk_sz;
353*4882a593Smuzhiyun 		sha1_update (&ctx, curr, chunk);
354*4882a593Smuzhiyun 		curr += chunk;
355*4882a593Smuzhiyun 		WATCHDOG_RESET ();
356*4882a593Smuzhiyun 	}
357*4882a593Smuzhiyun #else
358*4882a593Smuzhiyun 	sha1_update (&ctx, input, ilen);
359*4882a593Smuzhiyun #endif
360*4882a593Smuzhiyun 
361*4882a593Smuzhiyun 	sha1_finish (&ctx, output);
362*4882a593Smuzhiyun }
363*4882a593Smuzhiyun 
364*4882a593Smuzhiyun /*
365*4882a593Smuzhiyun  * Output = HMAC-SHA-1( input buffer, hmac key )
366*4882a593Smuzhiyun  */
sha1_hmac(const unsigned char * key,int keylen,const unsigned char * input,unsigned int ilen,unsigned char * output)367*4882a593Smuzhiyun void sha1_hmac(const unsigned char *key, int keylen,
368*4882a593Smuzhiyun 	       const unsigned char *input, unsigned int ilen,
369*4882a593Smuzhiyun 	       unsigned char *output)
370*4882a593Smuzhiyun {
371*4882a593Smuzhiyun 	int i;
372*4882a593Smuzhiyun 	sha1_context ctx;
373*4882a593Smuzhiyun 	unsigned char k_ipad[64];
374*4882a593Smuzhiyun 	unsigned char k_opad[64];
375*4882a593Smuzhiyun 	unsigned char tmpbuf[20];
376*4882a593Smuzhiyun 
377*4882a593Smuzhiyun 	memset (k_ipad, 0x36, 64);
378*4882a593Smuzhiyun 	memset (k_opad, 0x5C, 64);
379*4882a593Smuzhiyun 
380*4882a593Smuzhiyun 	for (i = 0; i < keylen; i++) {
381*4882a593Smuzhiyun 		if (i >= 64)
382*4882a593Smuzhiyun 			break;
383*4882a593Smuzhiyun 
384*4882a593Smuzhiyun 		k_ipad[i] ^= key[i];
385*4882a593Smuzhiyun 		k_opad[i] ^= key[i];
386*4882a593Smuzhiyun 	}
387*4882a593Smuzhiyun 
388*4882a593Smuzhiyun 	sha1_starts (&ctx);
389*4882a593Smuzhiyun 	sha1_update (&ctx, k_ipad, 64);
390*4882a593Smuzhiyun 	sha1_update (&ctx, input, ilen);
391*4882a593Smuzhiyun 	sha1_finish (&ctx, tmpbuf);
392*4882a593Smuzhiyun 
393*4882a593Smuzhiyun 	sha1_starts (&ctx);
394*4882a593Smuzhiyun 	sha1_update (&ctx, k_opad, 64);
395*4882a593Smuzhiyun 	sha1_update (&ctx, tmpbuf, 20);
396*4882a593Smuzhiyun 	sha1_finish (&ctx, output);
397*4882a593Smuzhiyun 
398*4882a593Smuzhiyun 	memset (k_ipad, 0, 64);
399*4882a593Smuzhiyun 	memset (k_opad, 0, 64);
400*4882a593Smuzhiyun 	memset (tmpbuf, 0, 20);
401*4882a593Smuzhiyun 	memset (&ctx, 0, sizeof (sha1_context));
402*4882a593Smuzhiyun }
403*4882a593Smuzhiyun 
404*4882a593Smuzhiyun #ifdef SELF_TEST
405*4882a593Smuzhiyun /*
406*4882a593Smuzhiyun  * FIPS-180-1 test vectors
407*4882a593Smuzhiyun  */
408*4882a593Smuzhiyun static const char sha1_test_str[3][57] = {
409*4882a593Smuzhiyun 	{"abc"},
410*4882a593Smuzhiyun 	{"abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq"},
411*4882a593Smuzhiyun 	{""}
412*4882a593Smuzhiyun };
413*4882a593Smuzhiyun 
414*4882a593Smuzhiyun static const unsigned char sha1_test_sum[3][20] = {
415*4882a593Smuzhiyun 	{0xA9, 0x99, 0x3E, 0x36, 0x47, 0x06, 0x81, 0x6A, 0xBA, 0x3E,
416*4882a593Smuzhiyun 	 0x25, 0x71, 0x78, 0x50, 0xC2, 0x6C, 0x9C, 0xD0, 0xD8, 0x9D},
417*4882a593Smuzhiyun 	{0x84, 0x98, 0x3E, 0x44, 0x1C, 0x3B, 0xD2, 0x6E, 0xBA, 0xAE,
418*4882a593Smuzhiyun 	 0x4A, 0xA1, 0xF9, 0x51, 0x29, 0xE5, 0xE5, 0x46, 0x70, 0xF1},
419*4882a593Smuzhiyun 	{0x34, 0xAA, 0x97, 0x3C, 0xD4, 0xC4, 0xDA, 0xA4, 0xF6, 0x1E,
420*4882a593Smuzhiyun 	 0xEB, 0x2B, 0xDB, 0xAD, 0x27, 0x31, 0x65, 0x34, 0x01, 0x6F}
421*4882a593Smuzhiyun };
422*4882a593Smuzhiyun 
423*4882a593Smuzhiyun /*
424*4882a593Smuzhiyun  * Checkup routine
425*4882a593Smuzhiyun  */
sha1_self_test(void)426*4882a593Smuzhiyun int sha1_self_test (void)
427*4882a593Smuzhiyun {
428*4882a593Smuzhiyun 	int i, j;
429*4882a593Smuzhiyun 	unsigned char buf[1000];
430*4882a593Smuzhiyun 	unsigned char sha1sum[20];
431*4882a593Smuzhiyun 	sha1_context ctx;
432*4882a593Smuzhiyun 
433*4882a593Smuzhiyun 	for (i = 0; i < 3; i++) {
434*4882a593Smuzhiyun 		printf ("  SHA-1 test #%d: ", i + 1);
435*4882a593Smuzhiyun 
436*4882a593Smuzhiyun 		sha1_starts (&ctx);
437*4882a593Smuzhiyun 
438*4882a593Smuzhiyun 		if (i < 2)
439*4882a593Smuzhiyun 			sha1_update (&ctx, (unsigned char *) sha1_test_str[i],
440*4882a593Smuzhiyun 				     strlen (sha1_test_str[i]));
441*4882a593Smuzhiyun 		else {
442*4882a593Smuzhiyun 			memset (buf, 'a', 1000);
443*4882a593Smuzhiyun 			for (j = 0; j < 1000; j++)
444*4882a593Smuzhiyun 				sha1_update (&ctx, buf, 1000);
445*4882a593Smuzhiyun 		}
446*4882a593Smuzhiyun 
447*4882a593Smuzhiyun 		sha1_finish (&ctx, sha1sum);
448*4882a593Smuzhiyun 
449*4882a593Smuzhiyun 		if (memcmp (sha1sum, sha1_test_sum[i], 20) != 0) {
450*4882a593Smuzhiyun 			printf ("failed\n");
451*4882a593Smuzhiyun 			return (1);
452*4882a593Smuzhiyun 		}
453*4882a593Smuzhiyun 
454*4882a593Smuzhiyun 		printf ("passed\n");
455*4882a593Smuzhiyun 	}
456*4882a593Smuzhiyun 
457*4882a593Smuzhiyun 	printf ("\n");
458*4882a593Smuzhiyun 	return (0);
459*4882a593Smuzhiyun }
460*4882a593Smuzhiyun #else
sha1_self_test(void)461*4882a593Smuzhiyun int sha1_self_test (void)
462*4882a593Smuzhiyun {
463*4882a593Smuzhiyun 	return (0);
464*4882a593Smuzhiyun }
465*4882a593Smuzhiyun #endif
466