Blame view

lib/sha1.c 9.76 KB
566a494f5   Heiko Schocher   [PCS440EP] u...
1
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
   *
5b8031ccb   Tom Rini   Add more SPDX-Lic...
8
   * SPDX-License-Identifier:	LGPL-2.1
566a494f5   Heiko Schocher   [PCS440EP] u...
9
10
11
12
13
14
15
16
17
18
   */
  /*
   *  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...
19
20
  #ifndef USE_HOSTCC
  #include <common.h>
a94f22f08   Andy Fleming   Fix build issue w...
21
  #include <linux/string.h>
338cc0384   Wolfgang Denk   tools/mkimage: fi...
22
23
  #else
  #include <string.h>
7590378fb   Bartlomiej Sieka   Use watchdog-awar...
24
25
  #endif /* USE_HOSTCC */
  #include <watchdog.h>
2b9912e6a   Jeroen Hofstee   includes: move op...
26
  #include <u-boot/sha1.h>
566a494f5   Heiko Schocher   [PCS440EP] u...
27

da29f2991   Andrew Duda   rsa: Verify RSA p...
28
29
30
31
  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...
32
33
34
35
  /*
   * 32-bit integer manipulation macros (big endian)
   */
  #ifndef GET_UINT32_BE
4ef218f6f   Wolfgang Denk   Coding style clea...
36
37
38
39
40
  #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...
41
42
43
  }
  #endif
  #ifndef PUT_UINT32_BE
4ef218f6f   Wolfgang Denk   Coding style clea...
44
45
46
47
48
  #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...
49
50
51
52
53
54
  }
  #endif
  
  /*
   * SHA-1 context setup
   */
4ef218f6f   Wolfgang Denk   Coding style clea...
55
  void sha1_starts (sha1_context * ctx)
566a494f5   Heiko Schocher   [PCS440EP] u...
56
  {
4ef218f6f   Wolfgang Denk   Coding style clea...
57
58
59
60
61
62
63
64
  	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...
65
  }
a7d1d7657   Simon Glass   sha1: Use const w...
66
  static void sha1_process(sha1_context *ctx, const unsigned char data[64])
566a494f5   Heiko Schocher   [PCS440EP] u...
67
  {
4ef218f6f   Wolfgang Denk   Coding style clea...
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
  	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...
93
  )
4ef218f6f   Wolfgang Denk   Coding style clea...
94
95
  #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...
96
  }
4ef218f6f   Wolfgang Denk   Coding style clea...
97
98
99
100
101
  	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...
102
103
104
  
  #define F(x,y,z) (z ^ (x & (y ^ z)))
  #define K 0x5A827999
4ef218f6f   Wolfgang Denk   Coding style clea...
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
  	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...
125
126
127
128
129
130
  
  #undef K
  #undef F
  
  #define F(x,y,z) (x ^ y ^ z)
  #define K 0x6ED9EBA1
4ef218f6f   Wolfgang Denk   Coding style clea...
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
  	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...
151
152
153
154
155
156
  
  #undef K
  #undef F
  
  #define F(x,y,z) ((x & y) | (z & (x | y)))
  #define K 0x8F1BBCDC
4ef218f6f   Wolfgang Denk   Coding style clea...
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
  	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...
177
178
179
180
181
182
  
  #undef K
  #undef F
  
  #define F(x,y,z) (x ^ y ^ z)
  #define K 0xCA62C1D6
4ef218f6f   Wolfgang Denk   Coding style clea...
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
  	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...
203
204
205
  
  #undef K
  #undef F
4ef218f6f   Wolfgang Denk   Coding style clea...
206
207
208
209
210
  	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...
211
212
213
214
215
  }
  
  /*
   * SHA-1 process buffer
   */
a7d1d7657   Simon Glass   sha1: Use const w...
216
217
  void sha1_update(sha1_context *ctx, const unsigned char *input,
  		 unsigned int ilen)
566a494f5   Heiko Schocher   [PCS440EP] u...
218
  {
4ef218f6f   Wolfgang Denk   Coding style clea...
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
250
  	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...
251
  }
4ef218f6f   Wolfgang Denk   Coding style clea...
252
253
254
255
256
  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...
257
258
259
260
261
  };
  
  /*
   * SHA-1 final digest
   */
4ef218f6f   Wolfgang Denk   Coding style clea...
262
  void sha1_finish (sha1_context * ctx, unsigned char output[20])
566a494f5   Heiko Schocher   [PCS440EP] u...
263
  {
4ef218f6f   Wolfgang Denk   Coding style clea...
264
265
266
  	unsigned long last, padn;
  	unsigned long high, low;
  	unsigned char msglen[8];
566a494f5   Heiko Schocher   [PCS440EP] u...
267

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

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

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

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

4ef218f6f   Wolfgang Denk   Coding style clea...
281
282
283
284
285
  	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...
286
287
288
289
290
  }
  
  /*
   * Output = SHA-1( input buffer )
   */
a7d1d7657   Simon Glass   sha1: Use const w...
291
292
  void sha1_csum(const unsigned char *input, unsigned int ilen,
  	       unsigned char *output)
566a494f5   Heiko Schocher   [PCS440EP] u...
293
  {
4ef218f6f   Wolfgang Denk   Coding style clea...
294
  	sha1_context ctx;
566a494f5   Heiko Schocher   [PCS440EP] u...
295

4ef218f6f   Wolfgang Denk   Coding style clea...
296
297
298
  	sha1_starts (&ctx);
  	sha1_update (&ctx, input, ilen);
  	sha1_finish (&ctx, output);
566a494f5   Heiko Schocher   [PCS440EP] u...
299
300
301
  }
  
  /*
215b01bba   Bartlomiej Sieka   Add support for c...
302
303
304
   * Output = SHA-1( input buffer ). Trigger the watchdog every 'chunk_sz'
   * bytes of input processed.
   */
a7d1d7657   Simon Glass   sha1: Use const w...
305
306
  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...
307
308
309
  {
  	sha1_context ctx;
  #if defined(CONFIG_HW_WATCHDOG) || defined(CONFIG_WATCHDOG)
a7d1d7657   Simon Glass   sha1: Use const w...
310
  	const unsigned char *end, *curr;
215b01bba   Bartlomiej Sieka   Add support for c...
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
  	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...
335
336
   * Output = HMAC-SHA-1( input buffer, hmac key )
   */
a7d1d7657   Simon Glass   sha1: Use const w...
337
338
339
  void sha1_hmac(const unsigned char *key, int keylen,
  	       const unsigned char *input, unsigned int ilen,
  	       unsigned char *output)
566a494f5   Heiko Schocher   [PCS440EP] u...
340
  {
4ef218f6f   Wolfgang Denk   Coding style clea...
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
371
  	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...
372
  }
566a494f5   Heiko Schocher   [PCS440EP] u...
373
374
375
376
  #ifdef SELF_TEST
  /*
   * FIPS-180-1 test vectors
   */
4ef218f6f   Wolfgang Denk   Coding style clea...
377
378
379
380
  static const char sha1_test_str[3][57] = {
  	{"abc"},
  	{"abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq"},
  	{""}
566a494f5   Heiko Schocher   [PCS440EP] u...
381
  };
4ef218f6f   Wolfgang Denk   Coding style clea...
382
383
384
385
386
387
388
  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...
389
390
391
392
393
  };
  
  /*
   * Checkup routine
   */
4ef218f6f   Wolfgang Denk   Coding style clea...
394
  int sha1_self_test (void)
566a494f5   Heiko Schocher   [PCS440EP] u...
395
  {
4ef218f6f   Wolfgang Denk   Coding style clea...
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
429
  	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...
430
431
  }
  #else
4ef218f6f   Wolfgang Denk   Coding style clea...
432
  int sha1_self_test (void)
566a494f5   Heiko Schocher   [PCS440EP] u...
433
  {
4ef218f6f   Wolfgang Denk   Coding style clea...
434
  	return (0);
566a494f5   Heiko Schocher   [PCS440EP] u...
435
436
  }
  #endif