MINI2440: Auto probe for SDRAM size
[u-boot-openmoko/mini2440.git] / lib_generic / sha1.c
blob08ffa6b9bacb43382535b664e08334c0c84ae005
1 /*
2 * Heiko Schocher, DENX Software Engineering, hs@denx.de.
3 * based on:
4 * FIPS-180-1 compliant SHA-1 implementation
6 * Copyright (C) 2003-2006 Christophe Devine
8 * This library is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Lesser General Public
10 * License, version 2.1 as published by the Free Software Foundation.
12 * This library is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Lesser General Public License for more details.
17 * You should have received a copy of the GNU Lesser General Public
18 * License along with this library; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
20 * MA 02110-1301 USA
23 * The SHA-1 standard was published by NIST in 1993.
25 * http://www.itl.nist.gov/fipspubs/fip180-1.htm
28 #ifndef _CRT_SECURE_NO_DEPRECATE
29 #define _CRT_SECURE_NO_DEPRECATE 1
30 #endif
32 #include <linux/string.h>
33 #include "sha1.h"
36 * 32-bit integer manipulation macros (big endian)
38 #ifndef GET_UINT32_BE
39 #define GET_UINT32_BE(n,b,i) { \
40 (n) = ( (unsigned long) (b)[(i) ] << 24 ) \
41 | ( (unsigned long) (b)[(i) + 1] << 16 ) \
42 | ( (unsigned long) (b)[(i) + 2] << 8 ) \
43 | ( (unsigned long) (b)[(i) + 3] ); \
45 #endif
46 #ifndef PUT_UINT32_BE
47 #define PUT_UINT32_BE(n,b,i) { \
48 (b)[(i) ] = (unsigned char) ( (n) >> 24 ); \
49 (b)[(i) + 1] = (unsigned char) ( (n) >> 16 ); \
50 (b)[(i) + 2] = (unsigned char) ( (n) >> 8 ); \
51 (b)[(i) + 3] = (unsigned char) ( (n) ); \
53 #endif
56 * SHA-1 context setup
58 void sha1_starts (sha1_context * ctx)
60 ctx->total[0] = 0;
61 ctx->total[1] = 0;
63 ctx->state[0] = 0x67452301;
64 ctx->state[1] = 0xEFCDAB89;
65 ctx->state[2] = 0x98BADCFE;
66 ctx->state[3] = 0x10325476;
67 ctx->state[4] = 0xC3D2E1F0;
70 static void sha1_process (sha1_context * ctx, unsigned char data[64])
72 unsigned long temp, W[16], A, B, C, D, E;
74 GET_UINT32_BE (W[0], data, 0);
75 GET_UINT32_BE (W[1], data, 4);
76 GET_UINT32_BE (W[2], data, 8);
77 GET_UINT32_BE (W[3], data, 12);
78 GET_UINT32_BE (W[4], data, 16);
79 GET_UINT32_BE (W[5], data, 20);
80 GET_UINT32_BE (W[6], data, 24);
81 GET_UINT32_BE (W[7], data, 28);
82 GET_UINT32_BE (W[8], data, 32);
83 GET_UINT32_BE (W[9], data, 36);
84 GET_UINT32_BE (W[10], data, 40);
85 GET_UINT32_BE (W[11], data, 44);
86 GET_UINT32_BE (W[12], data, 48);
87 GET_UINT32_BE (W[13], data, 52);
88 GET_UINT32_BE (W[14], data, 56);
89 GET_UINT32_BE (W[15], data, 60);
91 #define S(x,n) ((x << n) | ((x & 0xFFFFFFFF) >> (32 - n)))
93 #define R(t) ( \
94 temp = W[(t - 3) & 0x0F] ^ W[(t - 8) & 0x0F] ^ \
95 W[(t - 14) & 0x0F] ^ W[ t & 0x0F], \
96 ( W[t & 0x0F] = S(temp,1) ) \
99 #define P(a,b,c,d,e,x) { \
100 e += S(a,5) + F(b,c,d) + K + x; b = S(b,30); \
103 A = ctx->state[0];
104 B = ctx->state[1];
105 C = ctx->state[2];
106 D = ctx->state[3];
107 E = ctx->state[4];
109 #define F(x,y,z) (z ^ (x & (y ^ z)))
110 #define K 0x5A827999
112 P (A, B, C, D, E, W[0]);
113 P (E, A, B, C, D, W[1]);
114 P (D, E, A, B, C, W[2]);
115 P (C, D, E, A, B, W[3]);
116 P (B, C, D, E, A, W[4]);
117 P (A, B, C, D, E, W[5]);
118 P (E, A, B, C, D, W[6]);
119 P (D, E, A, B, C, W[7]);
120 P (C, D, E, A, B, W[8]);
121 P (B, C, D, E, A, W[9]);
122 P (A, B, C, D, E, W[10]);
123 P (E, A, B, C, D, W[11]);
124 P (D, E, A, B, C, W[12]);
125 P (C, D, E, A, B, W[13]);
126 P (B, C, D, E, A, W[14]);
127 P (A, B, C, D, E, W[15]);
128 P (E, A, B, C, D, R (16));
129 P (D, E, A, B, C, R (17));
130 P (C, D, E, A, B, R (18));
131 P (B, C, D, E, A, R (19));
133 #undef K
134 #undef F
136 #define F(x,y,z) (x ^ y ^ z)
137 #define K 0x6ED9EBA1
139 P (A, B, C, D, E, R (20));
140 P (E, A, B, C, D, R (21));
141 P (D, E, A, B, C, R (22));
142 P (C, D, E, A, B, R (23));
143 P (B, C, D, E, A, R (24));
144 P (A, B, C, D, E, R (25));
145 P (E, A, B, C, D, R (26));
146 P (D, E, A, B, C, R (27));
147 P (C, D, E, A, B, R (28));
148 P (B, C, D, E, A, R (29));
149 P (A, B, C, D, E, R (30));
150 P (E, A, B, C, D, R (31));
151 P (D, E, A, B, C, R (32));
152 P (C, D, E, A, B, R (33));
153 P (B, C, D, E, A, R (34));
154 P (A, B, C, D, E, R (35));
155 P (E, A, B, C, D, R (36));
156 P (D, E, A, B, C, R (37));
157 P (C, D, E, A, B, R (38));
158 P (B, C, D, E, A, R (39));
160 #undef K
161 #undef F
163 #define F(x,y,z) ((x & y) | (z & (x | y)))
164 #define K 0x8F1BBCDC
166 P (A, B, C, D, E, R (40));
167 P (E, A, B, C, D, R (41));
168 P (D, E, A, B, C, R (42));
169 P (C, D, E, A, B, R (43));
170 P (B, C, D, E, A, R (44));
171 P (A, B, C, D, E, R (45));
172 P (E, A, B, C, D, R (46));
173 P (D, E, A, B, C, R (47));
174 P (C, D, E, A, B, R (48));
175 P (B, C, D, E, A, R (49));
176 P (A, B, C, D, E, R (50));
177 P (E, A, B, C, D, R (51));
178 P (D, E, A, B, C, R (52));
179 P (C, D, E, A, B, R (53));
180 P (B, C, D, E, A, R (54));
181 P (A, B, C, D, E, R (55));
182 P (E, A, B, C, D, R (56));
183 P (D, E, A, B, C, R (57));
184 P (C, D, E, A, B, R (58));
185 P (B, C, D, E, A, R (59));
187 #undef K
188 #undef F
190 #define F(x,y,z) (x ^ y ^ z)
191 #define K 0xCA62C1D6
193 P (A, B, C, D, E, R (60));
194 P (E, A, B, C, D, R (61));
195 P (D, E, A, B, C, R (62));
196 P (C, D, E, A, B, R (63));
197 P (B, C, D, E, A, R (64));
198 P (A, B, C, D, E, R (65));
199 P (E, A, B, C, D, R (66));
200 P (D, E, A, B, C, R (67));
201 P (C, D, E, A, B, R (68));
202 P (B, C, D, E, A, R (69));
203 P (A, B, C, D, E, R (70));
204 P (E, A, B, C, D, R (71));
205 P (D, E, A, B, C, R (72));
206 P (C, D, E, A, B, R (73));
207 P (B, C, D, E, A, R (74));
208 P (A, B, C, D, E, R (75));
209 P (E, A, B, C, D, R (76));
210 P (D, E, A, B, C, R (77));
211 P (C, D, E, A, B, R (78));
212 P (B, C, D, E, A, R (79));
214 #undef K
215 #undef F
217 ctx->state[0] += A;
218 ctx->state[1] += B;
219 ctx->state[2] += C;
220 ctx->state[3] += D;
221 ctx->state[4] += E;
225 * SHA-1 process buffer
227 void sha1_update (sha1_context * ctx, unsigned char *input, int ilen)
229 int fill;
230 unsigned long left;
232 if (ilen <= 0)
233 return;
235 left = ctx->total[0] & 0x3F;
236 fill = 64 - left;
238 ctx->total[0] += ilen;
239 ctx->total[0] &= 0xFFFFFFFF;
241 if (ctx->total[0] < (unsigned long) ilen)
242 ctx->total[1]++;
244 if (left && ilen >= fill) {
245 memcpy ((void *) (ctx->buffer + left), (void *) input, fill);
246 sha1_process (ctx, ctx->buffer);
247 input += fill;
248 ilen -= fill;
249 left = 0;
252 while (ilen >= 64) {
253 sha1_process (ctx, input);
254 input += 64;
255 ilen -= 64;
258 if (ilen > 0) {
259 memcpy ((void *) (ctx->buffer + left), (void *) input, ilen);
263 static const unsigned char sha1_padding[64] = {
264 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
265 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
266 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
267 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
271 * SHA-1 final digest
273 void sha1_finish (sha1_context * ctx, unsigned char output[20])
275 unsigned long last, padn;
276 unsigned long high, low;
277 unsigned char msglen[8];
279 high = (ctx->total[0] >> 29)
280 | (ctx->total[1] << 3);
281 low = (ctx->total[0] << 3);
283 PUT_UINT32_BE (high, msglen, 0);
284 PUT_UINT32_BE (low, msglen, 4);
286 last = ctx->total[0] & 0x3F;
287 padn = (last < 56) ? (56 - last) : (120 - last);
289 sha1_update (ctx, (unsigned char *) sha1_padding, padn);
290 sha1_update (ctx, msglen, 8);
292 PUT_UINT32_BE (ctx->state[0], output, 0);
293 PUT_UINT32_BE (ctx->state[1], output, 4);
294 PUT_UINT32_BE (ctx->state[2], output, 8);
295 PUT_UINT32_BE (ctx->state[3], output, 12);
296 PUT_UINT32_BE (ctx->state[4], output, 16);
300 * Output = SHA-1( input buffer )
302 void sha1_csum (unsigned char *input, int ilen, unsigned char output[20])
304 sha1_context ctx;
306 sha1_starts (&ctx);
307 sha1_update (&ctx, input, ilen);
308 sha1_finish (&ctx, output);
312 * Output = HMAC-SHA-1( input buffer, hmac key )
314 void sha1_hmac (unsigned char *key, int keylen,
315 unsigned char *input, int ilen, unsigned char output[20])
317 int i;
318 sha1_context ctx;
319 unsigned char k_ipad[64];
320 unsigned char k_opad[64];
321 unsigned char tmpbuf[20];
323 memset (k_ipad, 0x36, 64);
324 memset (k_opad, 0x5C, 64);
326 for (i = 0; i < keylen; i++) {
327 if (i >= 64)
328 break;
330 k_ipad[i] ^= key[i];
331 k_opad[i] ^= key[i];
334 sha1_starts (&ctx);
335 sha1_update (&ctx, k_ipad, 64);
336 sha1_update (&ctx, input, ilen);
337 sha1_finish (&ctx, tmpbuf);
339 sha1_starts (&ctx);
340 sha1_update (&ctx, k_opad, 64);
341 sha1_update (&ctx, tmpbuf, 20);
342 sha1_finish (&ctx, output);
344 memset (k_ipad, 0, 64);
345 memset (k_opad, 0, 64);
346 memset (tmpbuf, 0, 20);
347 memset (&ctx, 0, sizeof (sha1_context));
350 static const char _sha1_src[] = "_sha1_src";
352 #ifdef SELF_TEST
354 * FIPS-180-1 test vectors
356 static const char sha1_test_str[3][57] = {
357 {"abc"},
358 {"abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq"},
359 {""}
362 static const unsigned char sha1_test_sum[3][20] = {
363 {0xA9, 0x99, 0x3E, 0x36, 0x47, 0x06, 0x81, 0x6A, 0xBA, 0x3E,
364 0x25, 0x71, 0x78, 0x50, 0xC2, 0x6C, 0x9C, 0xD0, 0xD8, 0x9D},
365 {0x84, 0x98, 0x3E, 0x44, 0x1C, 0x3B, 0xD2, 0x6E, 0xBA, 0xAE,
366 0x4A, 0xA1, 0xF9, 0x51, 0x29, 0xE5, 0xE5, 0x46, 0x70, 0xF1},
367 {0x34, 0xAA, 0x97, 0x3C, 0xD4, 0xC4, 0xDA, 0xA4, 0xF6, 0x1E,
368 0xEB, 0x2B, 0xDB, 0xAD, 0x27, 0x31, 0x65, 0x34, 0x01, 0x6F}
372 * Checkup routine
374 int sha1_self_test (void)
376 int i, j;
377 unsigned char buf[1000];
378 unsigned char sha1sum[20];
379 sha1_context ctx;
381 for (i = 0; i < 3; i++) {
382 printf (" SHA-1 test #%d: ", i + 1);
384 sha1_starts (&ctx);
386 if (i < 2)
387 sha1_update (&ctx, (unsigned char *) sha1_test_str[i],
388 strlen (sha1_test_str[i]));
389 else {
390 memset (buf, 'a', 1000);
391 for (j = 0; j < 1000; j++)
392 sha1_update (&ctx, buf, 1000);
395 sha1_finish (&ctx, sha1sum);
397 if (memcmp (sha1sum, sha1_test_sum[i], 20) != 0) {
398 printf ("failed\n");
399 return (1);
402 printf ("passed\n");
405 printf ("\n");
406 return (0);
408 #else
409 int sha1_self_test (void)
411 return (0);
413 #endif