2 * FIPS-180-1 compliant SHA-1 implementation
\r
4 * Copyright (C) 2006-2007 Christophe Devine
\r
6 * This library is free software; you can redistribute it and/or
\r
7 * modify it under the terms of the GNU Lesser General Public
\r
8 * License, version 2.1 as published by the Free Software Foundation.
\r
10 * This library is distributed in the hope that it will be useful,
\r
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
\r
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
\r
13 * Lesser General Public License for more details.
\r
15 * You should have received a copy of the GNU Lesser General Public
\r
16 * License along with this library; if not, write to the Free Software
\r
17 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
\r
21 * The SHA-1 standard was published by NIST in 1993.
\r
23 * http://www.itl.nist.gov/fipspubs/fip180-1.htm
\r
26 #include "../../include/xyssl/config.h"
\r
28 #if defined(XYSSL_SHA1_C)
\r
30 #include "../../include/xyssl/sha1.h"
\r
36 * 32-bit integer manipulation macros (big endian)
\r
38 #ifndef GET_ULONG_BE
\r
39 #define GET_ULONG_BE(n,b,i) \
\r
41 (n) = ( (unsigned long) (b)[(i) ] << 24 ) \
\r
42 | ( (unsigned long) (b)[(i) + 1] << 16 ) \
\r
43 | ( (unsigned long) (b)[(i) + 2] << 8 ) \
\r
44 | ( (unsigned long) (b)[(i) + 3] ); \
\r
48 #ifndef PUT_ULONG_BE
\r
49 #define PUT_ULONG_BE(n,b,i) \
\r
51 (b)[(i) ] = (unsigned char) ( (n) >> 24 ); \
\r
52 (b)[(i) + 1] = (unsigned char) ( (n) >> 16 ); \
\r
53 (b)[(i) + 2] = (unsigned char) ( (n) >> 8 ); \
\r
54 (b)[(i) + 3] = (unsigned char) ( (n) ); \
\r
59 * SHA-1 context setup
\r
61 void sha1_starts( sha1_context *ctx )
\r
66 ctx->state[0] = 0x67452301;
\r
67 ctx->state[1] = 0xEFCDAB89;
\r
68 ctx->state[2] = 0x98BADCFE;
\r
69 ctx->state[3] = 0x10325476;
\r
70 ctx->state[4] = 0xC3D2E1F0;
\r
73 static void sha1_process( sha1_context *ctx, unsigned char data[64] )
\r
75 unsigned long temp, W[16], A, B, C, D, E;
\r
77 GET_ULONG_BE( W[ 0], data, 0 );
\r
78 GET_ULONG_BE( W[ 1], data, 4 );
\r
79 GET_ULONG_BE( W[ 2], data, 8 );
\r
80 GET_ULONG_BE( W[ 3], data, 12 );
\r
81 GET_ULONG_BE( W[ 4], data, 16 );
\r
82 GET_ULONG_BE( W[ 5], data, 20 );
\r
83 GET_ULONG_BE( W[ 6], data, 24 );
\r
84 GET_ULONG_BE( W[ 7], data, 28 );
\r
85 GET_ULONG_BE( W[ 8], data, 32 );
\r
86 GET_ULONG_BE( W[ 9], data, 36 );
\r
87 GET_ULONG_BE( W[10], data, 40 );
\r
88 GET_ULONG_BE( W[11], data, 44 );
\r
89 GET_ULONG_BE( W[12], data, 48 );
\r
90 GET_ULONG_BE( W[13], data, 52 );
\r
91 GET_ULONG_BE( W[14], data, 56 );
\r
92 GET_ULONG_BE( W[15], data, 60 );
\r
94 #define S(x,n) ((x << n) | ((x & 0xFFFFFFFF) >> (32 - n)))
\r
98 temp = W[(t - 3) & 0x0F] ^ W[(t - 8) & 0x0F] ^ \
\r
99 W[(t - 14) & 0x0F] ^ W[ t & 0x0F], \
\r
100 ( W[t & 0x0F] = S(temp,1) ) \
\r
103 #define P(a,b,c,d,e,x) \
\r
105 e += S(a,5) + F(b,c,d) + K + x; b = S(b,30); \
\r
114 #define F(x,y,z) (z ^ (x & (y ^ z)))
\r
115 #define K 0x5A827999
\r
117 P( A, B, C, D, E, W[0] );
\r
118 P( E, A, B, C, D, W[1] );
\r
119 P( D, E, A, B, C, W[2] );
\r
120 P( C, D, E, A, B, W[3] );
\r
121 P( B, C, D, E, A, W[4] );
\r
122 P( A, B, C, D, E, W[5] );
\r
123 P( E, A, B, C, D, W[6] );
\r
124 P( D, E, A, B, C, W[7] );
\r
125 P( C, D, E, A, B, W[8] );
\r
126 P( B, C, D, E, A, W[9] );
\r
127 P( A, B, C, D, E, W[10] );
\r
128 P( E, A, B, C, D, W[11] );
\r
129 P( D, E, A, B, C, W[12] );
\r
130 P( C, D, E, A, B, W[13] );
\r
131 P( B, C, D, E, A, W[14] );
\r
132 P( A, B, C, D, E, W[15] );
\r
133 P( E, A, B, C, D, R(16) );
\r
134 P( D, E, A, B, C, R(17) );
\r
135 P( C, D, E, A, B, R(18) );
\r
136 P( B, C, D, E, A, R(19) );
\r
141 #define F(x,y,z) (x ^ y ^ z)
\r
142 #define K 0x6ED9EBA1
\r
144 P( A, B, C, D, E, R(20) );
\r
145 P( E, A, B, C, D, R(21) );
\r
146 P( D, E, A, B, C, R(22) );
\r
147 P( C, D, E, A, B, R(23) );
\r
148 P( B, C, D, E, A, R(24) );
\r
149 P( A, B, C, D, E, R(25) );
\r
150 P( E, A, B, C, D, R(26) );
\r
151 P( D, E, A, B, C, R(27) );
\r
152 P( C, D, E, A, B, R(28) );
\r
153 P( B, C, D, E, A, R(29) );
\r
154 P( A, B, C, D, E, R(30) );
\r
155 P( E, A, B, C, D, R(31) );
\r
156 P( D, E, A, B, C, R(32) );
\r
157 P( C, D, E, A, B, R(33) );
\r
158 P( B, C, D, E, A, R(34) );
\r
159 P( A, B, C, D, E, R(35) );
\r
160 P( E, A, B, C, D, R(36) );
\r
161 P( D, E, A, B, C, R(37) );
\r
162 P( C, D, E, A, B, R(38) );
\r
163 P( B, C, D, E, A, R(39) );
\r
168 #define F(x,y,z) ((x & y) | (z & (x | y)))
\r
169 #define K 0x8F1BBCDC
\r
171 P( A, B, C, D, E, R(40) );
\r
172 P( E, A, B, C, D, R(41) );
\r
173 P( D, E, A, B, C, R(42) );
\r
174 P( C, D, E, A, B, R(43) );
\r
175 P( B, C, D, E, A, R(44) );
\r
176 P( A, B, C, D, E, R(45) );
\r
177 P( E, A, B, C, D, R(46) );
\r
178 P( D, E, A, B, C, R(47) );
\r
179 P( C, D, E, A, B, R(48) );
\r
180 P( B, C, D, E, A, R(49) );
\r
181 P( A, B, C, D, E, R(50) );
\r
182 P( E, A, B, C, D, R(51) );
\r
183 P( D, E, A, B, C, R(52) );
\r
184 P( C, D, E, A, B, R(53) );
\r
185 P( B, C, D, E, A, R(54) );
\r
186 P( A, B, C, D, E, R(55) );
\r
187 P( E, A, B, C, D, R(56) );
\r
188 P( D, E, A, B, C, R(57) );
\r
189 P( C, D, E, A, B, R(58) );
\r
190 P( B, C, D, E, A, R(59) );
\r
195 #define F(x,y,z) (x ^ y ^ z)
\r
196 #define K 0xCA62C1D6
\r
198 P( A, B, C, D, E, R(60) );
\r
199 P( E, A, B, C, D, R(61) );
\r
200 P( D, E, A, B, C, R(62) );
\r
201 P( C, D, E, A, B, R(63) );
\r
202 P( B, C, D, E, A, R(64) );
\r
203 P( A, B, C, D, E, R(65) );
\r
204 P( E, A, B, C, D, R(66) );
\r
205 P( D, E, A, B, C, R(67) );
\r
206 P( C, D, E, A, B, R(68) );
\r
207 P( B, C, D, E, A, R(69) );
\r
208 P( A, B, C, D, E, R(70) );
\r
209 P( E, A, B, C, D, R(71) );
\r
210 P( D, E, A, B, C, R(72) );
\r
211 P( C, D, E, A, B, R(73) );
\r
212 P( B, C, D, E, A, R(74) );
\r
213 P( A, B, C, D, E, R(75) );
\r
214 P( E, A, B, C, D, R(76) );
\r
215 P( D, E, A, B, C, R(77) );
\r
216 P( C, D, E, A, B, R(78) );
\r
217 P( B, C, D, E, A, R(79) );
\r
222 ctx->state[0] += A;
\r
223 ctx->state[1] += B;
\r
224 ctx->state[2] += C;
\r
225 ctx->state[3] += D;
\r
226 ctx->state[4] += E;
\r
230 * SHA-1 process buffer
\r
232 void sha1_update( sha1_context *ctx, unsigned char *input, int ilen )
\r
235 unsigned long left;
\r
240 left = ctx->total[0] & 0x3F;
\r
243 ctx->total[0] += ilen;
\r
244 ctx->total[0] &= 0xFFFFFFFF;
\r
246 if( ctx->total[0] < (unsigned long) ilen )
\r
249 if( left && ilen >= fill )
\r
251 memcpy( (void *) (ctx->buffer + left),
\r
252 (void *) input, fill );
\r
253 sha1_process( ctx, ctx->buffer );
\r
259 while( ilen >= 64 )
\r
261 sha1_process( ctx, input );
\r
268 memcpy( (void *) (ctx->buffer + left),
\r
269 (void *) input, ilen );
\r
273 static const unsigned char sha1_padding[64] =
\r
275 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
\r
276 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
\r
277 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
\r
278 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
\r
282 * SHA-1 final digest
\r
284 void sha1_finish( sha1_context *ctx, unsigned char output[20] )
\r
286 unsigned long last, padn;
\r
287 unsigned long high, low;
\r
288 unsigned char msglen[8];
\r
290 high = ( ctx->total[0] >> 29 )
\r
291 | ( ctx->total[1] << 3 );
\r
292 low = ( ctx->total[0] << 3 );
\r
294 PUT_ULONG_BE( high, msglen, 0 );
\r
295 PUT_ULONG_BE( low, msglen, 4 );
\r
297 last = ctx->total[0] & 0x3F;
\r
298 padn = ( last < 56 ) ? ( 56 - last ) : ( 120 - last );
\r
300 sha1_update( ctx, (unsigned char *) sha1_padding, padn );
\r
301 sha1_update( ctx, msglen, 8 );
\r
303 PUT_ULONG_BE( ctx->state[0], output, 0 );
\r
304 PUT_ULONG_BE( ctx->state[1], output, 4 );
\r
305 PUT_ULONG_BE( ctx->state[2], output, 8 );
\r
306 PUT_ULONG_BE( ctx->state[3], output, 12 );
\r
307 PUT_ULONG_BE( ctx->state[4], output, 16 );
\r
311 * output = SHA-1( input buffer )
\r
313 void sha1( unsigned char *input, int ilen, unsigned char output[20] )
\r
317 sha1_starts( &ctx );
\r
318 sha1_update( &ctx, input, ilen );
\r
319 sha1_finish( &ctx, output );
\r
321 memset( &ctx, 0, sizeof( sha1_context ) );
\r
325 * output = SHA-1( file contents )
\r
327 int sha1_file( char *path, unsigned char output[20] )
\r
332 unsigned char buf[1024];
\r
334 if( ( f = fopen( path, "rb" ) ) == NULL )
\r
337 sha1_starts( &ctx );
\r
339 while( ( n = fread( buf, 1, sizeof( buf ), f ) ) > 0 )
\r
340 sha1_update( &ctx, buf, (int) n );
\r
342 sha1_finish( &ctx, output );
\r
344 memset( &ctx, 0, sizeof( sha1_context ) );
\r
346 if( ferror( f ) != 0 )
\r
357 * SHA-1 HMAC context setup
\r
359 void sha1_hmac_starts( sha1_context *ctx, unsigned char *key, int keylen )
\r
362 unsigned char sum[20];
\r
366 sha1( key, keylen, sum );
\r
371 memset( ctx->ipad, 0x36, 64 );
\r
372 memset( ctx->opad, 0x5C, 64 );
\r
374 for( i = 0; i < keylen; i++ )
\r
376 ctx->ipad[i] = (unsigned char)( ctx->ipad[i] ^ key[i] );
\r
377 ctx->opad[i] = (unsigned char)( ctx->opad[i] ^ key[i] );
\r
380 sha1_starts( ctx );
\r
381 sha1_update( ctx, ctx->ipad, 64 );
\r
383 memset( sum, 0, sizeof( sum ) );
\r
387 * SHA-1 HMAC process buffer
\r
389 void sha1_hmac_update( sha1_context *ctx, unsigned char *input, int ilen )
\r
391 sha1_update( ctx, input, ilen );
\r
395 * SHA-1 HMAC final digest
\r
397 void sha1_hmac_finish( sha1_context *ctx, unsigned char output[20] )
\r
399 unsigned char tmpbuf[20];
\r
401 sha1_finish( ctx, tmpbuf );
\r
402 sha1_starts( ctx );
\r
403 sha1_update( ctx, ctx->opad, 64 );
\r
404 sha1_update( ctx, tmpbuf, 20 );
\r
405 sha1_finish( ctx, output );
\r
407 memset( tmpbuf, 0, sizeof( tmpbuf ) );
\r
411 * output = HMAC-SHA-1( hmac key, input buffer )
\r
413 void sha1_hmac( unsigned char *key, int keylen, unsigned char *input, int ilen,
\r
414 unsigned char output[20] )
\r
418 sha1_hmac_starts( &ctx, key, keylen );
\r
419 sha1_hmac_update( &ctx, input, ilen );
\r
420 sha1_hmac_finish( &ctx, output );
\r
422 memset( &ctx, 0, sizeof( sha1_context ) );
\r
425 #if defined(XYSSL_SELF_TEST)
\r
428 * FIPS-180-1 test vectors
\r
430 static const char sha1_test_str[3][57] =
\r
433 { "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq" },
\r
437 static const unsigned char sha1_test_sum[3][20] =
\r
439 { 0xA9, 0x99, 0x3E, 0x36, 0x47, 0x06, 0x81, 0x6A, 0xBA, 0x3E,
\r
440 0x25, 0x71, 0x78, 0x50, 0xC2, 0x6C, 0x9C, 0xD0, 0xD8, 0x9D },
\r
441 { 0x84, 0x98, 0x3E, 0x44, 0x1C, 0x3B, 0xD2, 0x6E, 0xBA, 0xAE,
\r
442 0x4A, 0xA1, 0xF9, 0x51, 0x29, 0xE5, 0xE5, 0x46, 0x70, 0xF1 },
\r
443 { 0x34, 0xAA, 0x97, 0x3C, 0xD4, 0xC4, 0xDA, 0xA4, 0xF6, 0x1E,
\r
444 0xEB, 0x2B, 0xDB, 0xAD, 0x27, 0x31, 0x65, 0x34, 0x01, 0x6F }
\r
450 int sha1_self_test( int verbose )
\r
453 unsigned char buf[1000];
\r
454 unsigned char sha1sum[20];
\r
457 for( i = 0; i < 3; i++ )
\r
460 printf( " SHA-1 test #%d: ", i + 1 );
\r
462 sha1_starts( &ctx );
\r
465 sha1_update( &ctx, (unsigned char *) sha1_test_str[i],
\r
466 strlen( sha1_test_str[i] ) );
\r
469 memset( buf, 'a', 1000 );
\r
470 for( j = 0; j < 1000; j++ )
\r
471 sha1_update( &ctx, buf, 1000 );
\r
474 sha1_finish( &ctx, sha1sum );
\r
476 if( memcmp( sha1sum, sha1_test_sum[i], 20 ) != 0 )
\r
479 printf( "failed\n" );
\r
485 printf( "passed\n" );
\r