Blame view

lib/sha1.c 9.76 KB
83d290c56   Tom Rini   SPDX: Convert all...
1
  // SPDX-License-Identifier: LGPL-2.1
566a494f5   Heiko Schocher   [PCS440EP] u...
2
3
4
5
6
7
  /*
   *  Heiko Schocher, DENX Software Engineering, hs@denx.de.
   *  based on:
   *  FIPS-180-1 compliant SHA-1 implementation
   *
   *  Copyright (C) 2003-2006  Christophe Devine
566a494f5   Heiko Schocher   [PCS440EP] u...
8
9
10
11
12
13
14
15
16
17
   */
  /*
   *  The SHA-1 standard was published by NIST in 1993.
   *
   *  http://www.itl.nist.gov/fipspubs/fip180-1.htm
   */
  
  #ifndef _CRT_SECURE_NO_DEPRECATE
  #define _CRT_SECURE_NO_DEPRECATE 1
  #endif
7590378fb   Bartlomiej Sieka   Use watchdog-awar...
18
19
  #ifndef USE_HOSTCC
  #include <common.h>
a94f22f08   Andy Fleming   Fix build issue w...
20
  #include <linux/string.h>
338cc0384   Wolfgang Denk   tools/mkimage: fi...
21
22
  #else
  #include <string.h>
7590378fb   Bartlomiej Sieka   Use watchdog-awar...
23
24
  #endif /* USE_HOSTCC */
  #include <watchdog.h>
2b9912e6a   Jeroen Hofstee   includes: move op...
25
  #include <u-boot/sha1.h>
566a494f5   Heiko Schocher   [PCS440EP] u...
26

da29f2991   Andrew Duda   rsa: Verify RSA p...
27
28
29
30
  const uint8_t sha1_der_prefix[SHA1_DER_LEN] = {
  	0x30, 0x21, 0x30, 0x09, 0x06, 0x05, 0x2b, 0x0e,
  	0x03, 0x02, 0x1a, 0x05, 0x00, 0x04, 0x14
  };
566a494f5   Heiko Schocher   [PCS440EP] u...
31
32
33
34
  /*
   * 32-bit integer manipulation macros (big endian)
   */
  #ifndef GET_UINT32_BE
4ef218f6f   Wolfgang Denk   Coding style clea...
35
36
37
38
39
  #define GET_UINT32_BE(n,b,i) {				\
  	(n) = ( (unsigned long) (b)[(i)    ] << 24 )	\
  	    | ( (unsigned long) (b)[(i) + 1] << 16 )	\
  	    | ( (unsigned long) (b)[(i) + 2] <<  8 )	\
  	    | ( (unsigned long) (b)[(i) + 3]       );	\
566a494f5   Heiko Schocher   [PCS440EP] u...
40
41
42
  }
  #endif
  #ifndef PUT_UINT32_BE
4ef218f6f   Wolfgang Denk   Coding style clea...
43
44
45
46
47
  #define PUT_UINT32_BE(n,b,i) {				\
  	(b)[(i)    ] = (unsigned char) ( (n) >> 24 );	\
  	(b)[(i) + 1] = (unsigned char) ( (n) >> 16 );	\
  	(b)[(i) + 2] = (unsigned char) ( (n) >>  8 );	\
  	(b)[(i) + 3] = (unsigned char) ( (n)       );	\
566a494f5   Heiko Schocher   [PCS440EP] u...
48
49
50
51
52
53
  }
  #endif
  
  /*
   * SHA-1 context setup
   */
4ef218f6f   Wolfgang Denk   Coding style clea...
54
  void sha1_starts (sha1_context * ctx)
566a494f5   Heiko Schocher   [PCS440EP] u...
55
  {
4ef218f6f   Wolfgang Denk   Coding style clea...
56
57
58
59
60
61
62
63
  	ctx->total[0] = 0;
  	ctx->total[1] = 0;
  
  	ctx->state[0] = 0x67452301;
  	ctx->state[1] = 0xEFCDAB89;
  	ctx->state[2] = 0x98BADCFE;
  	ctx->state[3] = 0x10325476;
  	ctx->state[4] = 0xC3D2E1F0;
566a494f5   Heiko Schocher   [PCS440EP] u...
64
  }
a7d1d7657   Simon Glass   sha1: Use const w...
65
  static void sha1_process(sha1_context *ctx, const unsigned char data[64])
566a494f5   Heiko Schocher   [PCS440EP] u...
66
  {
4ef218f6f   Wolfgang Denk   Coding style clea...
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
  	unsigned long temp, W[16], A, B, C, D, E;
  
  	GET_UINT32_BE (W[0], data, 0);
  	GET_UINT32_BE (W[1], data, 4);
  	GET_UINT32_BE (W[2], data, 8);
  	GET_UINT32_BE (W[3], data, 12);
  	GET_UINT32_BE (W[4], data, 16);
  	GET_UINT32_BE (W[5], data, 20);
  	GET_UINT32_BE (W[6], data, 24);
  	GET_UINT32_BE (W[7], data, 28);
  	GET_UINT32_BE (W[8], data, 32);
  	GET_UINT32_BE (W[9], data, 36);
  	GET_UINT32_BE (W[10], data, 40);
  	GET_UINT32_BE (W[11], data, 44);
  	GET_UINT32_BE (W[12], data, 48);
  	GET_UINT32_BE (W[13], data, 52);
  	GET_UINT32_BE (W[14], data, 56);
  	GET_UINT32_BE (W[15], data, 60);
  
  #define S(x,n)	((x << n) | ((x & 0xFFFFFFFF) >> (32 - n)))
  
  #define R(t) (						\
  	temp = W[(t -  3) & 0x0F] ^ W[(t - 8) & 0x0F] ^	\
  	       W[(t - 14) & 0x0F] ^ W[ t      & 0x0F],	\
  	( W[t & 0x0F] = S(temp,1) )			\
566a494f5   Heiko Schocher   [PCS440EP] u...
92
  )
4ef218f6f   Wolfgang Denk   Coding style clea...
93
94
  #define P(a,b,c,d,e,x)	{				\
  	e += S(a,5) + F(b,c,d) + K + x; b = S(b,30);	\
566a494f5   Heiko Schocher   [PCS440EP] u...
95
  }
4ef218f6f   Wolfgang Denk   Coding style clea...
96
97
98
99
100
  	A = ctx->state[0];
  	B = ctx->state[1];
  	C = ctx->state[2];
  	D = ctx->state[3];
  	E = ctx->state[4];
566a494f5   Heiko Schocher   [PCS440EP] u...
101
102
103
  
  #define F(x,y,z) (z ^ (x & (y ^ z)))
  #define K 0x5A827999
4ef218f6f   Wolfgang Denk   Coding style clea...
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
  	P (A, B, C, D, E, W[0]);
  	P (E, A, B, C, D, W[1]);
  	P (D, E, A, B, C, W[2]);
  	P (C, D, E, A, B, W[3]);
  	P (B, C, D, E, A, W[4]);
  	P (A, B, C, D, E, W[5]);
  	P (E, A, B, C, D, W[6]);
  	P (D, E, A, B, C, W[7]);
  	P (C, D, E, A, B, W[8]);
  	P (B, C, D, E, A, W[9]);
  	P (A, B, C, D, E, W[10]);
  	P (E, A, B, C, D, W[11]);
  	P (D, E, A, B, C, W[12]);
  	P (C, D, E, A, B, W[13]);
  	P (B, C, D, E, A, W[14]);
  	P (A, B, C, D, E, W[15]);
  	P (E, A, B, C, D, R (16));
  	P (D, E, A, B, C, R (17));
  	P (C, D, E, A, B, R (18));
  	P (B, C, D, E, A, R (19));
566a494f5   Heiko Schocher   [PCS440EP] u...
124
125
126
127
128
129
  
  #undef K
  #undef F
  
  #define F(x,y,z) (x ^ y ^ z)
  #define K 0x6ED9EBA1
4ef218f6f   Wolfgang Denk   Coding style clea...
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
  	P (A, B, C, D, E, R (20));
  	P (E, A, B, C, D, R (21));
  	P (D, E, A, B, C, R (22));
  	P (C, D, E, A, B, R (23));
  	P (B, C, D, E, A, R (24));
  	P (A, B, C, D, E, R (25));
  	P (E, A, B, C, D, R (26));
  	P (D, E, A, B, C, R (27));
  	P (C, D, E, A, B, R (28));
  	P (B, C, D, E, A, R (29));
  	P (A, B, C, D, E, R (30));
  	P (E, A, B, C, D, R (31));
  	P (D, E, A, B, C, R (32));
  	P (C, D, E, A, B, R (33));
  	P (B, C, D, E, A, R (34));
  	P (A, B, C, D, E, R (35));
  	P (E, A, B, C, D, R (36));
  	P (D, E, A, B, C, R (37));
  	P (C, D, E, A, B, R (38));
  	P (B, C, D, E, A, R (39));
566a494f5   Heiko Schocher   [PCS440EP] u...
150
151
152
153
154
155
  
  #undef K
  #undef F
  
  #define F(x,y,z) ((x & y) | (z & (x | y)))
  #define K 0x8F1BBCDC
4ef218f6f   Wolfgang Denk   Coding style clea...
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
  	P (A, B, C, D, E, R (40));
  	P (E, A, B, C, D, R (41));
  	P (D, E, A, B, C, R (42));
  	P (C, D, E, A, B, R (43));
  	P (B, C, D, E, A, R (44));
  	P (A, B, C, D, E, R (45));
  	P (E, A, B, C, D, R (46));
  	P (D, E, A, B, C, R (47));
  	P (C, D, E, A, B, R (48));
  	P (B, C, D, E, A, R (49));
  	P (A, B, C, D, E, R (50));
  	P (E, A, B, C, D, R (51));
  	P (D, E, A, B, C, R (52));
  	P (C, D, E, A, B, R (53));
  	P (B, C, D, E, A, R (54));
  	P (A, B, C, D, E, R (55));
  	P (E, A, B, C, D, R (56));
  	P (D, E, A, B, C, R (57));
  	P (C, D, E, A, B, R (58));
  	P (B, C, D, E, A, R (59));
566a494f5   Heiko Schocher   [PCS440EP] u...
176
177
178
179
180
181
  
  #undef K
  #undef F
  
  #define F(x,y,z) (x ^ y ^ z)
  #define K 0xCA62C1D6
4ef218f6f   Wolfgang Denk   Coding style clea...
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
  	P (A, B, C, D, E, R (60));
  	P (E, A, B, C, D, R (61));
  	P (D, E, A, B, C, R (62));
  	P (C, D, E, A, B, R (63));
  	P (B, C, D, E, A, R (64));
  	P (A, B, C, D, E, R (65));
  	P (E, A, B, C, D, R (66));
  	P (D, E, A, B, C, R (67));
  	P (C, D, E, A, B, R (68));
  	P (B, C, D, E, A, R (69));
  	P (A, B, C, D, E, R (70));
  	P (E, A, B, C, D, R (71));
  	P (D, E, A, B, C, R (72));
  	P (C, D, E, A, B, R (73));
  	P (B, C, D, E, A, R (74));
  	P (A, B, C, D, E, R (75));
  	P (E, A, B, C, D, R (76));
  	P (D, E, A, B, C, R (77));
  	P (C, D, E, A, B, R (78));
  	P (B, C, D, E, A, R (79));
566a494f5   Heiko Schocher   [PCS440EP] u...
202
203
204
  
  #undef K
  #undef F
4ef218f6f   Wolfgang Denk   Coding style clea...
205
206
207
208
209
  	ctx->state[0] += A;
  	ctx->state[1] += B;
  	ctx->state[2] += C;
  	ctx->state[3] += D;
  	ctx->state[4] += E;
566a494f5   Heiko Schocher   [PCS440EP] u...
210
211
212
213
214
  }
  
  /*
   * SHA-1 process buffer
   */
a7d1d7657   Simon Glass   sha1: Use const w...
215
216
  void sha1_update(sha1_context *ctx, const unsigned char *input,
  		 unsigned int ilen)
566a494f5   Heiko Schocher   [PCS440EP] u...
217
  {
4ef218f6f   Wolfgang Denk   Coding style clea...
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
  	int fill;
  	unsigned long left;
  
  	if (ilen <= 0)
  		return;
  
  	left = ctx->total[0] & 0x3F;
  	fill = 64 - left;
  
  	ctx->total[0] += ilen;
  	ctx->total[0] &= 0xFFFFFFFF;
  
  	if (ctx->total[0] < (unsigned long) ilen)
  		ctx->total[1]++;
  
  	if (left && ilen >= fill) {
  		memcpy ((void *) (ctx->buffer + left), (void *) input, fill);
  		sha1_process (ctx, ctx->buffer);
  		input += fill;
  		ilen -= fill;
  		left = 0;
  	}
  
  	while (ilen >= 64) {
  		sha1_process (ctx, input);
  		input += 64;
  		ilen -= 64;
  	}
  
  	if (ilen > 0) {
  		memcpy ((void *) (ctx->buffer + left), (void *) input, ilen);
  	}
566a494f5   Heiko Schocher   [PCS440EP] u...
250
  }
4ef218f6f   Wolfgang Denk   Coding style clea...
251
252
253
254
255
  static const unsigned char sha1_padding[64] = {
  	0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
  	   0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
  	   0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
  	   0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
566a494f5   Heiko Schocher   [PCS440EP] u...
256
257
258
259
260
  };
  
  /*
   * SHA-1 final digest
   */
4ef218f6f   Wolfgang Denk   Coding style clea...
261
  void sha1_finish (sha1_context * ctx, unsigned char output[20])
566a494f5   Heiko Schocher   [PCS440EP] u...
262
  {
4ef218f6f   Wolfgang Denk   Coding style clea...
263
264
265
  	unsigned long last, padn;
  	unsigned long high, low;
  	unsigned char msglen[8];
566a494f5   Heiko Schocher   [PCS440EP] u...
266

4ef218f6f   Wolfgang Denk   Coding style clea...
267
268
269
  	high = (ctx->total[0] >> 29)
  		| (ctx->total[1] << 3);
  	low = (ctx->total[0] << 3);
566a494f5   Heiko Schocher   [PCS440EP] u...
270

4ef218f6f   Wolfgang Denk   Coding style clea...
271
272
  	PUT_UINT32_BE (high, msglen, 0);
  	PUT_UINT32_BE (low, msglen, 4);
566a494f5   Heiko Schocher   [PCS440EP] u...
273

4ef218f6f   Wolfgang Denk   Coding style clea...
274
275
  	last = ctx->total[0] & 0x3F;
  	padn = (last < 56) ? (56 - last) : (120 - last);
566a494f5   Heiko Schocher   [PCS440EP] u...
276

4ef218f6f   Wolfgang Denk   Coding style clea...
277
278
  	sha1_update (ctx, (unsigned char *) sha1_padding, padn);
  	sha1_update (ctx, msglen, 8);
566a494f5   Heiko Schocher   [PCS440EP] u...
279

4ef218f6f   Wolfgang Denk   Coding style clea...
280
281
282
283
284
  	PUT_UINT32_BE (ctx->state[0], output, 0);
  	PUT_UINT32_BE (ctx->state[1], output, 4);
  	PUT_UINT32_BE (ctx->state[2], output, 8);
  	PUT_UINT32_BE (ctx->state[3], output, 12);
  	PUT_UINT32_BE (ctx->state[4], output, 16);
566a494f5   Heiko Schocher   [PCS440EP] u...
285
286
287
288
289
  }
  
  /*
   * Output = SHA-1( input buffer )
   */
a7d1d7657   Simon Glass   sha1: Use const w...
290
291
  void sha1_csum(const unsigned char *input, unsigned int ilen,
  	       unsigned char *output)
566a494f5   Heiko Schocher   [PCS440EP] u...
292
  {
4ef218f6f   Wolfgang Denk   Coding style clea...
293
  	sha1_context ctx;
566a494f5   Heiko Schocher   [PCS440EP] u...
294

4ef218f6f   Wolfgang Denk   Coding style clea...
295
296
297
  	sha1_starts (&ctx);
  	sha1_update (&ctx, input, ilen);
  	sha1_finish (&ctx, output);
566a494f5   Heiko Schocher   [PCS440EP] u...
298
299
300
  }
  
  /*
215b01bba   Bartlomiej Sieka   Add support for c...
301
302
303
   * Output = SHA-1( input buffer ). Trigger the watchdog every 'chunk_sz'
   * bytes of input processed.
   */
a7d1d7657   Simon Glass   sha1: Use const w...
304
305
  void sha1_csum_wd(const unsigned char *input, unsigned int ilen,
  		  unsigned char *output, unsigned int chunk_sz)
215b01bba   Bartlomiej Sieka   Add support for c...
306
307
308
  {
  	sha1_context ctx;
  #if defined(CONFIG_HW_WATCHDOG) || defined(CONFIG_WATCHDOG)
a7d1d7657   Simon Glass   sha1: Use const w...
309
  	const unsigned char *end, *curr;
215b01bba   Bartlomiej Sieka   Add support for c...
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
  	int chunk;
  #endif
  
  	sha1_starts (&ctx);
  
  #if defined(CONFIG_HW_WATCHDOG) || defined(CONFIG_WATCHDOG)
  	curr = input;
  	end = input + ilen;
  	while (curr < end) {
  		chunk = end - curr;
  		if (chunk > chunk_sz)
  			chunk = chunk_sz;
  		sha1_update (&ctx, curr, chunk);
  		curr += chunk;
  		WATCHDOG_RESET ();
  	}
  #else
  	sha1_update (&ctx, input, ilen);
  #endif
  
  	sha1_finish (&ctx, output);
  }
  
  /*
566a494f5   Heiko Schocher   [PCS440EP] u...
334
335
   * Output = HMAC-SHA-1( input buffer, hmac key )
   */
a7d1d7657   Simon Glass   sha1: Use const w...
336
337
338
  void sha1_hmac(const unsigned char *key, int keylen,
  	       const unsigned char *input, unsigned int ilen,
  	       unsigned char *output)
566a494f5   Heiko Schocher   [PCS440EP] u...
339
  {
4ef218f6f   Wolfgang Denk   Coding style clea...
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
  	int i;
  	sha1_context ctx;
  	unsigned char k_ipad[64];
  	unsigned char k_opad[64];
  	unsigned char tmpbuf[20];
  
  	memset (k_ipad, 0x36, 64);
  	memset (k_opad, 0x5C, 64);
  
  	for (i = 0; i < keylen; i++) {
  		if (i >= 64)
  			break;
  
  		k_ipad[i] ^= key[i];
  		k_opad[i] ^= key[i];
  	}
  
  	sha1_starts (&ctx);
  	sha1_update (&ctx, k_ipad, 64);
  	sha1_update (&ctx, input, ilen);
  	sha1_finish (&ctx, tmpbuf);
  
  	sha1_starts (&ctx);
  	sha1_update (&ctx, k_opad, 64);
  	sha1_update (&ctx, tmpbuf, 20);
  	sha1_finish (&ctx, output);
  
  	memset (k_ipad, 0, 64);
  	memset (k_opad, 0, 64);
  	memset (tmpbuf, 0, 20);
  	memset (&ctx, 0, sizeof (sha1_context));
566a494f5   Heiko Schocher   [PCS440EP] u...
371
  }
566a494f5   Heiko Schocher   [PCS440EP] u...
372
373
374
375
  #ifdef SELF_TEST
  /*
   * FIPS-180-1 test vectors
   */
4ef218f6f   Wolfgang Denk   Coding style clea...
376
377
378
379
  static const char sha1_test_str[3][57] = {
  	{"abc"},
  	{"abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq"},
  	{""}
566a494f5   Heiko Schocher   [PCS440EP] u...
380
  };
4ef218f6f   Wolfgang Denk   Coding style clea...
381
382
383
384
385
386
387
  static const unsigned char sha1_test_sum[3][20] = {
  	{0xA9, 0x99, 0x3E, 0x36, 0x47, 0x06, 0x81, 0x6A, 0xBA, 0x3E,
  	 0x25, 0x71, 0x78, 0x50, 0xC2, 0x6C, 0x9C, 0xD0, 0xD8, 0x9D},
  	{0x84, 0x98, 0x3E, 0x44, 0x1C, 0x3B, 0xD2, 0x6E, 0xBA, 0xAE,
  	 0x4A, 0xA1, 0xF9, 0x51, 0x29, 0xE5, 0xE5, 0x46, 0x70, 0xF1},
  	{0x34, 0xAA, 0x97, 0x3C, 0xD4, 0xC4, 0xDA, 0xA4, 0xF6, 0x1E,
  	 0xEB, 0x2B, 0xDB, 0xAD, 0x27, 0x31, 0x65, 0x34, 0x01, 0x6F}
566a494f5   Heiko Schocher   [PCS440EP] u...
388
389
390
391
392
  };
  
  /*
   * Checkup routine
   */
4ef218f6f   Wolfgang Denk   Coding style clea...
393
  int sha1_self_test (void)
566a494f5   Heiko Schocher   [PCS440EP] u...
394
  {
4ef218f6f   Wolfgang Denk   Coding style clea...
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
  	int i, j;
  	unsigned char buf[1000];
  	unsigned char sha1sum[20];
  	sha1_context ctx;
  
  	for (i = 0; i < 3; i++) {
  		printf ("  SHA-1 test #%d: ", i + 1);
  
  		sha1_starts (&ctx);
  
  		if (i < 2)
  			sha1_update (&ctx, (unsigned char *) sha1_test_str[i],
  				     strlen (sha1_test_str[i]));
  		else {
  			memset (buf, 'a', 1000);
  			for (j = 0; j < 1000; j++)
  				sha1_update (&ctx, buf, 1000);
  		}
  
  		sha1_finish (&ctx, sha1sum);
  
  		if (memcmp (sha1sum, sha1_test_sum[i], 20) != 0) {
  			printf ("failed
  ");
  			return (1);
  		}
  
  		printf ("passed
  ");
  	}
  
  	printf ("
  ");
  	return (0);
566a494f5   Heiko Schocher   [PCS440EP] u...
429
430
  }
  #else
4ef218f6f   Wolfgang Denk   Coding style clea...
431
  int sha1_self_test (void)
566a494f5   Heiko Schocher   [PCS440EP] u...
432
  {
4ef218f6f   Wolfgang Denk   Coding style clea...
433
  	return (0);
566a494f5   Heiko Schocher   [PCS440EP] u...
434
435
  }
  #endif