1/*
2 *  FIPS-180-1 compliant SHA-1 implementation
3 *
4 *  Copyright (C) 2003-2006  Christophe Devine
5 *
6 *  This library is free software; you can redistribute it and/or
7 *  modify it under the terms of the GNU Lesser General Public
8 *  License, version 2.1 as published by the Free Software Foundation.
9 *
10 *  This library is distributed in the hope that it will be useful,
11 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
12 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13 *  Lesser General Public License for more details.
14 *
15 *  You should have received a copy of the GNU Lesser General Public
16 *  License along with this library; if not, write to the Free Software
17 *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
18 *  MA  02110-1301  USA
19 */
20/*
21 *  The SHA-1 standard was published by NIST in 1993.
22 *
23 *  http://www.itl.nist.gov/fipspubs/fip180-1.htm
24 */
25
26#ifndef _CRT_SECURE_NO_DEPRECATE
27#define _CRT_SECURE_NO_DEPRECATE 1
28#endif
29
30#include <string.h>
31#include <stdio.h>
32
33#include "sha1.h"
34
35/*
36 * 32-bit integer manipulation macros (big endian)
37 */
38#ifndef GET_UINT32_BE
39#define GET_UINT32_BE(n,b,i)                    \
40{                                               \
41    (n) = ( (ulong) (b)[(i)    ] << 24 )        \
42        | ( (ulong) (b)[(i) + 1] << 16 )        \
43        | ( (ulong) (b)[(i) + 2] <<  8 )        \
44        | ( (ulong) (b)[(i) + 3]       );       \
45}
46#endif
47#ifndef PUT_UINT32_BE
48#define PUT_UINT32_BE(n,b,i)                    \
49{                                               \
50    (b)[(i)    ] = (uchar) ( (n) >> 24 );       \
51    (b)[(i) + 1] = (uchar) ( (n) >> 16 );       \
52    (b)[(i) + 2] = (uchar) ( (n) >>  8 );       \
53    (b)[(i) + 3] = (uchar) ( (n)       );       \
54}
55#endif
56
57/*
58 * Core SHA-1 functions
59 */
60void sha1_starts( sha1_context *ctx )
61{
62    ctx->total[0] = 0;
63    ctx->total[1] = 0;
64
65    ctx->state[0] = 0x67452301;
66    ctx->state[1] = 0xEFCDAB89;
67    ctx->state[2] = 0x98BADCFE;
68    ctx->state[3] = 0x10325476;
69    ctx->state[4] = 0xC3D2E1F0;
70}
71
72void sha1_process( sha1_context *ctx, uchar data[64] )
73{
74    ulong temp, W[16], A, B, C, D, E;
75
76    GET_UINT32_BE( W[0],  data,  0 );
77    GET_UINT32_BE( W[1],  data,  4 );
78    GET_UINT32_BE( W[2],  data,  8 );
79    GET_UINT32_BE( W[3],  data, 12 );
80    GET_UINT32_BE( W[4],  data, 16 );
81    GET_UINT32_BE( W[5],  data, 20 );
82    GET_UINT32_BE( W[6],  data, 24 );
83    GET_UINT32_BE( W[7],  data, 28 );
84    GET_UINT32_BE( W[8],  data, 32 );
85    GET_UINT32_BE( W[9],  data, 36 );
86    GET_UINT32_BE( W[10], data, 40 );
87    GET_UINT32_BE( W[11], data, 44 );
88    GET_UINT32_BE( W[12], data, 48 );
89    GET_UINT32_BE( W[13], data, 52 );
90    GET_UINT32_BE( W[14], data, 56 );
91    GET_UINT32_BE( W[15], data, 60 );
92
93#define S(x,n) ((x << n) | ((x & 0xFFFFFFFF) >> (32 - n)))
94
95#define R(t)                                            \
96(                                                       \
97    temp = W[(t -  3) & 0x0F] ^ W[(t - 8) & 0x0F] ^     \
98           W[(t - 14) & 0x0F] ^ W[ t      & 0x0F],      \
99    ( W[t & 0x0F] = S(temp,1) )                         \
100)
101
102#define P(a,b,c,d,e,x)                                  \
103{                                                       \
104    e += S(a,5) + F(b,c,d) + K + x; b = S(b,30);        \
105}
106
107    A = ctx->state[0];
108    B = ctx->state[1];
109    C = ctx->state[2];
110    D = ctx->state[3];
111    E = ctx->state[4];
112
113#define F(x,y,z) (z ^ (x & (y ^ z)))
114#define K 0x5A827999
115
116    P( A, B, C, D, E, W[0]  );
117    P( E, A, B, C, D, W[1]  );
118    P( D, E, A, B, C, W[2]  );
119    P( C, D, E, A, B, W[3]  );
120    P( B, C, D, E, A, W[4]  );
121    P( A, B, C, D, E, W[5]  );
122    P( E, A, B, C, D, W[6]  );
123    P( D, E, A, B, C, W[7]  );
124    P( C, D, E, A, B, W[8]  );
125    P( B, C, D, E, A, W[9]  );
126    P( A, B, C, D, E, W[10] );
127    P( E, A, B, C, D, W[11] );
128    P( D, E, A, B, C, W[12] );
129    P( C, D, E, A, B, W[13] );
130    P( B, C, D, E, A, W[14] );
131    P( A, B, C, D, E, W[15] );
132    P( E, A, B, C, D, R(16) );
133    P( D, E, A, B, C, R(17) );
134    P( C, D, E, A, B, R(18) );
135    P( B, C, D, E, A, R(19) );
136
137#undef K
138#undef F
139
140#define F(x,y,z) (x ^ y ^ z)
141#define K 0x6ED9EBA1
142
143    P( A, B, C, D, E, R(20) );
144    P( E, A, B, C, D, R(21) );
145    P( D, E, A, B, C, R(22) );
146    P( C, D, E, A, B, R(23) );
147    P( B, C, D, E, A, R(24) );
148    P( A, B, C, D, E, R(25) );
149    P( E, A, B, C, D, R(26) );
150    P( D, E, A, B, C, R(27) );
151    P( C, D, E, A, B, R(28) );
152    P( B, C, D, E, A, R(29) );
153    P( A, B, C, D, E, R(30) );
154    P( E, A, B, C, D, R(31) );
155    P( D, E, A, B, C, R(32) );
156    P( C, D, E, A, B, R(33) );
157    P( B, C, D, E, A, R(34) );
158    P( A, B, C, D, E, R(35) );
159    P( E, A, B, C, D, R(36) );
160    P( D, E, A, B, C, R(37) );
161    P( C, D, E, A, B, R(38) );
162    P( B, C, D, E, A, R(39) );
163
164#undef K
165#undef F
166
167#define F(x,y,z) ((x & y) | (z & (x | y)))
168#define K 0x8F1BBCDC
169
170    P( A, B, C, D, E, R(40) );
171    P( E, A, B, C, D, R(41) );
172    P( D, E, A, B, C, R(42) );
173    P( C, D, E, A, B, R(43) );
174    P( B, C, D, E, A, R(44) );
175    P( A, B, C, D, E, R(45) );
176    P( E, A, B, C, D, R(46) );
177    P( D, E, A, B, C, R(47) );
178    P( C, D, E, A, B, R(48) );
179    P( B, C, D, E, A, R(49) );
180    P( A, B, C, D, E, R(50) );
181    P( E, A, B, C, D, R(51) );
182    P( D, E, A, B, C, R(52) );
183    P( C, D, E, A, B, R(53) );
184    P( B, C, D, E, A, R(54) );
185    P( A, B, C, D, E, R(55) );
186    P( E, A, B, C, D, R(56) );
187    P( D, E, A, B, C, R(57) );
188    P( C, D, E, A, B, R(58) );
189    P( B, C, D, E, A, R(59) );
190
191#undef K
192#undef F
193
194#define F(x,y,z) (x ^ y ^ z)
195#define K 0xCA62C1D6
196
197    P( A, B, C, D, E, R(60) );
198    P( E, A, B, C, D, R(61) );
199    P( D, E, A, B, C, R(62) );
200    P( C, D, E, A, B, R(63) );
201    P( B, C, D, E, A, R(64) );
202    P( A, B, C, D, E, R(65) );
203    P( E, A, B, C, D, R(66) );
204    P( D, E, A, B, C, R(67) );
205    P( C, D, E, A, B, R(68) );
206    P( B, C, D, E, A, R(69) );
207    P( A, B, C, D, E, R(70) );
208    P( E, A, B, C, D, R(71) );
209    P( D, E, A, B, C, R(72) );
210    P( C, D, E, A, B, R(73) );
211    P( B, C, D, E, A, R(74) );
212    P( A, B, C, D, E, R(75) );
213    P( E, A, B, C, D, R(76) );
214    P( D, E, A, B, C, R(77) );
215    P( C, D, E, A, B, R(78) );
216    P( B, C, D, E, A, R(79) );
217
218#undef K
219#undef F
220
221    ctx->state[0] += A;
222    ctx->state[1] += B;
223    ctx->state[2] += C;
224    ctx->state[3] += D;
225    ctx->state[4] += E;
226}
227
228void sha1_update( sha1_context *ctx, uchar *input, uint length )
229{
230    ulong left, fill;
231
232    if( ! length ) return;
233
234    left = ctx->total[0] & 0x3F;
235    fill = 64 - left;
236
237    ctx->total[0] += length;
238    ctx->total[0] &= 0xFFFFFFFF;
239
240    if( ctx->total[0] < length )
241        ctx->total[1]++;
242
243    if( left && length >= fill )
244    {
245        memcpy( (void *) (ctx->buffer + left),
246                (void *) input, fill );
247        sha1_process( ctx, ctx->buffer );
248        length -= fill;
249        input  += fill;
250        left = 0;
251    }
252
253    while( length >= 64 )
254    {
255        sha1_process( ctx, input );
256        length -= 64;
257        input  += 64;
258    }
259
260    if( length )
261    {
262        memcpy( (void *) (ctx->buffer + left),
263                (void *) input, length );
264    }
265}
266
267static uchar sha1_padding[64] =
268{
269 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
270    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
271    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
272    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
273};
274
275void sha1_finish( sha1_context *ctx, uchar digest[20] )
276{
277    ulong last, padn;
278    ulong high, low;
279    uchar msglen[8];
280
281    high = ( ctx->total[0] >> 29 )
282         | ( ctx->total[1] <<  3 );
283    low  = ( ctx->total[0] <<  3 );
284
285    PUT_UINT32_BE( high, msglen, 0 );
286    PUT_UINT32_BE( low,  msglen, 4 );
287
288    last = ctx->total[0] & 0x3F;
289    padn = ( last < 56 ) ? ( 56 - last ) : ( 120 - last );
290
291    sha1_update( ctx, sha1_padding, padn );
292    sha1_update( ctx, msglen, 8 );
293
294    PUT_UINT32_BE( ctx->state[0], digest,  0 );
295    PUT_UINT32_BE( ctx->state[1], digest,  4 );
296    PUT_UINT32_BE( ctx->state[2], digest,  8 );
297    PUT_UINT32_BE( ctx->state[3], digest, 12 );
298    PUT_UINT32_BE( ctx->state[4], digest, 16 );
299}
300
301/*
302 * Output SHA-1(file contents), returns 0 if successful.
303 */
304int sha1_file( char *filename, uchar digest[20] )
305{
306    FILE *f;
307    size_t n;
308    sha1_context ctx;
309    uchar buf[1024];
310
311    if( ( f = fopen( filename, "rb" ) ) == NULL )
312        return( 1 );
313
314    sha1_starts( &ctx );
315
316    while( ( n = fread( buf, 1, sizeof( buf ), f ) ) > 0 )
317        sha1_update( &ctx, buf, (uint) n );
318
319    sha1_finish( &ctx, digest );
320
321    fclose( f );
322    return( 0 );
323}
324
325/*
326 * Output SHA-1(buf)
327 */
328void sha1_csum( uchar *buf, uint buflen, uchar digest[20] )
329{
330    sha1_context ctx;
331
332    sha1_starts( &ctx );
333    sha1_update( &ctx, buf, buflen );
334    sha1_finish( &ctx, digest );
335}
336
337/*
338 * Output HMAC-SHA-1(key,buf)
339 */
340void sha1_hmac( uchar *key, uint keylen, uchar *buf, uint buflen,
341                uchar digest[20] )
342{
343    uint i;
344    sha1_context ctx;
345    uchar k_ipad[64];
346    uchar k_opad[64];
347    uchar tmpbuf[20];
348
349    memset( k_ipad, 0x36, 64 );
350    memset( k_opad, 0x5C, 64 );
351
352    for( i = 0; i < keylen; i++ )
353    {
354        if( i >= 64 ) break;
355
356        k_ipad[i] ^= key[i];
357        k_opad[i] ^= key[i];
358    }
359
360    sha1_starts( &ctx );
361    sha1_update( &ctx, k_ipad, 64 );
362    sha1_update( &ctx, buf, buflen );
363    sha1_finish( &ctx, tmpbuf );
364
365    sha1_starts( &ctx );
366    sha1_update( &ctx, k_opad, 64 );
367    sha1_update( &ctx, tmpbuf, 20 );
368    sha1_finish( &ctx, digest );
369
370    memset( k_ipad, 0, 64 );
371    memset( k_opad, 0, 64 );
372    memset( tmpbuf, 0, 20 );
373    memset( &ctx, 0, sizeof( sha1_context ) );
374}
375
376#ifdef SELF_TEST
377/*
378 * FIPS-180-1 test vectors
379 */
380static char *sha1_test_str[3] =
381{
382    "abc",
383    "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq",
384    NULL
385};
386
387static uchar sha1_test_sum[3][20] =
388{
389    { 0xA9, 0x99, 0x3E, 0x36, 0x47, 0x06, 0x81, 0x6A, 0xBA, 0x3E,
390      0x25, 0x71, 0x78, 0x50, 0xC2, 0x6C, 0x9C, 0xD0, 0xD8, 0x9D },
391    { 0x84, 0x98, 0x3E, 0x44, 0x1C, 0x3B, 0xD2, 0x6E, 0xBA, 0xAE,
392      0x4A, 0xA1, 0xF9, 0x51, 0x29, 0xE5, 0xE5, 0x46, 0x70, 0xF1 },
393    { 0x34, 0xAA, 0x97, 0x3C, 0xD4, 0xC4, 0xDA, 0xA4, 0xF6, 0x1E,
394      0xEB, 0x2B, 0xDB, 0xAD, 0x27, 0x31, 0x65, 0x34, 0x01, 0x6F }
395};
396
397/*
398 * Checkup routine
399 */
400int sha1_self_test( void )
401{
402    int i, j;
403    uchar buf[1000];
404    uchar sha1sum[20];
405    sha1_context ctx;
406
407    for( i = 0; i < 3; i++ )
408    {
409        printf( "  SHA-1 test #%d: ", i + 1 );
410
411        sha1_starts( &ctx );
412
413        if( i < 2 )
414            sha1_update( &ctx, (uchar *) sha1_test_str[i],
415                         strlen( sha1_test_str[i] ) );
416        else
417        {
418            memset( buf, 'a', 1000 );
419            for( j = 0; j < 1000; j++ )
420                sha1_update( &ctx, (uchar *) buf, 1000 );
421        }
422
423        sha1_finish( &ctx, sha1sum );
424
425        if( memcmp( sha1sum, sha1_test_sum[i], 20 ) != 0 )
426        {
427            printf( "failed\n" );
428            return( 1 );
429        }
430
431        printf( "passed\n" );
432    }
433
434    printf( "\n" );
435    return( 0 );
436}
437#else
438int sha1_self_test( void )
439{
440    printf( "SHA-1 self-test not available\n\n" );
441    return( 1 );
442}
443#endif
444