source: project/release/4/sha1/trunk/sha1-base.c @ 15609

Last change on this file since 15609 was 15609, checked in by Kon Lovett, 11 years ago

Initial save.

  • Property svn:executable set to *
File size: 9.5 KB
Line 
1/*
2 *  FIPS-180-1 compliant SHA-1 implementation
3 *
4 *  Copyright (C) 2001-2003  Christophe Devine
5 *
6 *  This program is free software; you can redistribute it and/or modify
7 *  it under the terms of the GNU General Public License as published by
8 *  the Free Software Foundation; either version 2 of the License, or
9 *  (at your option) any later version.
10 *
11 *  This program is distributed in the hope that it will be useful,
12 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
13 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14 *  GNU General Public License for more details.
15 *
16 *  You should have received a copy of the GNU General Public License
17 *  along with this program; if not, write to the Free Software
18 *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
19 */
20
21#include <string.h>
22
23#include "sha1.h"
24
25#define GET_UINT32(n,b,i)                       \
26{                                               \
27    (n) = ( (uint32) (b)[(i)    ] << 24 )       \
28        | ( (uint32) (b)[(i) + 1] << 16 )       \
29        | ( (uint32) (b)[(i) + 2] <<  8 )       \
30        | ( (uint32) (b)[(i) + 3]       );      \
31}
32
33#define PUT_UINT32(n,b,i)                       \
34{                                               \
35    (b)[(i)    ] = (uint8) ( (n) >> 24 );       \
36    (b)[(i) + 1] = (uint8) ( (n) >> 16 );       \
37    (b)[(i) + 2] = (uint8) ( (n) >>  8 );       \
38    (b)[(i) + 3] = (uint8) ( (n)       );       \
39}
40
41static
42void sha1_starts( sha1_context *ctx )
43{
44    ctx->total[0] = 0;
45    ctx->total[1] = 0;
46
47    ctx->state[0] = 0x67452301;
48    ctx->state[1] = 0xEFCDAB89;
49    ctx->state[2] = 0x98BADCFE;
50    ctx->state[3] = 0x10325476;
51    ctx->state[4] = 0xC3D2E1F0;
52}
53
54static
55void sha1_process( sha1_context *ctx, uint8 data[64] )
56{
57    uint32 temp, W[16], A, B, C, D, E;
58
59    GET_UINT32( W[0],  data,  0 );
60    GET_UINT32( W[1],  data,  4 );
61    GET_UINT32( W[2],  data,  8 );
62    GET_UINT32( W[3],  data, 12 );
63    GET_UINT32( W[4],  data, 16 );
64    GET_UINT32( W[5],  data, 20 );
65    GET_UINT32( W[6],  data, 24 );
66    GET_UINT32( W[7],  data, 28 );
67    GET_UINT32( W[8],  data, 32 );
68    GET_UINT32( W[9],  data, 36 );
69    GET_UINT32( W[10], data, 40 );
70    GET_UINT32( W[11], data, 44 );
71    GET_UINT32( W[12], data, 48 );
72    GET_UINT32( W[13], data, 52 );
73    GET_UINT32( W[14], data, 56 );
74    GET_UINT32( W[15], data, 60 );
75
76#define S(x,n) ((x << n) | ((x & 0xFFFFFFFF) >> (32 - n)))
77
78#define R(t)                                            \
79(                                                       \
80    temp = W[(t -  3) & 0x0F] ^ W[(t - 8) & 0x0F] ^     \
81           W[(t - 14) & 0x0F] ^ W[ t      & 0x0F],      \
82    ( W[t & 0x0F] = S(temp,1) )                         \
83)
84
85#define P(a,b,c,d,e,x)                                  \
86{                                                       \
87    e += S(a,5) + F(b,c,d) + K + x; b = S(b,30);        \
88}
89
90    A = ctx->state[0];
91    B = ctx->state[1];
92    C = ctx->state[2];
93    D = ctx->state[3];
94    E = ctx->state[4];
95
96#define F(x,y,z) (z ^ (x & (y ^ z)))
97#define K 0x5A827999
98
99    P( A, B, C, D, E, W[0]  );
100    P( E, A, B, C, D, W[1]  );
101    P( D, E, A, B, C, W[2]  );
102    P( C, D, E, A, B, W[3]  );
103    P( B, C, D, E, A, W[4]  );
104    P( A, B, C, D, E, W[5]  );
105    P( E, A, B, C, D, W[6]  );
106    P( D, E, A, B, C, W[7]  );
107    P( C, D, E, A, B, W[8]  );
108    P( B, C, D, E, A, W[9]  );
109    P( A, B, C, D, E, W[10] );
110    P( E, A, B, C, D, W[11] );
111    P( D, E, A, B, C, W[12] );
112    P( C, D, E, A, B, W[13] );
113    P( B, C, D, E, A, W[14] );
114    P( A, B, C, D, E, W[15] );
115    P( E, A, B, C, D, R(16) );
116    P( D, E, A, B, C, R(17) );
117    P( C, D, E, A, B, R(18) );
118    P( B, C, D, E, A, R(19) );
119
120#undef K
121#undef F
122
123#define F(x,y,z) (x ^ y ^ z)
124#define K 0x6ED9EBA1
125
126    P( A, B, C, D, E, R(20) );
127    P( E, A, B, C, D, R(21) );
128    P( D, E, A, B, C, R(22) );
129    P( C, D, E, A, B, R(23) );
130    P( B, C, D, E, A, R(24) );
131    P( A, B, C, D, E, R(25) );
132    P( E, A, B, C, D, R(26) );
133    P( D, E, A, B, C, R(27) );
134    P( C, D, E, A, B, R(28) );
135    P( B, C, D, E, A, R(29) );
136    P( A, B, C, D, E, R(30) );
137    P( E, A, B, C, D, R(31) );
138    P( D, E, A, B, C, R(32) );
139    P( C, D, E, A, B, R(33) );
140    P( B, C, D, E, A, R(34) );
141    P( A, B, C, D, E, R(35) );
142    P( E, A, B, C, D, R(36) );
143    P( D, E, A, B, C, R(37) );
144    P( C, D, E, A, B, R(38) );
145    P( B, C, D, E, A, R(39) );
146
147#undef K
148#undef F
149
150#define F(x,y,z) ((x & y) | (z & (x | y)))
151#define K 0x8F1BBCDC
152
153    P( A, B, C, D, E, R(40) );
154    P( E, A, B, C, D, R(41) );
155    P( D, E, A, B, C, R(42) );
156    P( C, D, E, A, B, R(43) );
157    P( B, C, D, E, A, R(44) );
158    P( A, B, C, D, E, R(45) );
159    P( E, A, B, C, D, R(46) );
160    P( D, E, A, B, C, R(47) );
161    P( C, D, E, A, B, R(48) );
162    P( B, C, D, E, A, R(49) );
163    P( A, B, C, D, E, R(50) );
164    P( E, A, B, C, D, R(51) );
165    P( D, E, A, B, C, R(52) );
166    P( C, D, E, A, B, R(53) );
167    P( B, C, D, E, A, R(54) );
168    P( A, B, C, D, E, R(55) );
169    P( E, A, B, C, D, R(56) );
170    P( D, E, A, B, C, R(57) );
171    P( C, D, E, A, B, R(58) );
172    P( B, C, D, E, A, R(59) );
173
174#undef K
175#undef F
176
177#define F(x,y,z) (x ^ y ^ z)
178#define K 0xCA62C1D6
179
180    P( A, B, C, D, E, R(60) );
181    P( E, A, B, C, D, R(61) );
182    P( D, E, A, B, C, R(62) );
183    P( C, D, E, A, B, R(63) );
184    P( B, C, D, E, A, R(64) );
185    P( A, B, C, D, E, R(65) );
186    P( E, A, B, C, D, R(66) );
187    P( D, E, A, B, C, R(67) );
188    P( C, D, E, A, B, R(68) );
189    P( B, C, D, E, A, R(69) );
190    P( A, B, C, D, E, R(70) );
191    P( E, A, B, C, D, R(71) );
192    P( D, E, A, B, C, R(72) );
193    P( C, D, E, A, B, R(73) );
194    P( B, C, D, E, A, R(74) );
195    P( A, B, C, D, E, R(75) );
196    P( E, A, B, C, D, R(76) );
197    P( D, E, A, B, C, R(77) );
198    P( C, D, E, A, B, R(78) );
199    P( B, C, D, E, A, R(79) );
200
201#undef K
202#undef F
203
204    ctx->state[0] += A;
205    ctx->state[1] += B;
206    ctx->state[2] += C;
207    ctx->state[3] += D;
208    ctx->state[4] += E;
209}
210
211static
212void sha1_update( sha1_context *ctx, uint8 *input, uint32 length )
213{
214    uint32 left, fill;
215
216    if( ! length ) return;
217
218    left = ctx->total[0] & 0x3F;
219    fill = 64 - left;
220
221    ctx->total[0] += length;
222    ctx->total[0] &= 0xFFFFFFFF;
223
224    if( ctx->total[0] < length )
225        ctx->total[1]++;
226
227    if( left && length >= fill )
228    {
229        memcpy( (void *) (ctx->buffer + left),
230                (void *) input, fill );
231        sha1_process( ctx, ctx->buffer );
232        length -= fill;
233        input  += fill;
234        left = 0;
235    }
236
237    while( length >= 64 )
238    {
239        sha1_process( ctx, input );
240        length -= 64;
241        input  += 64;
242    }
243
244    if( length )
245    {
246        memcpy( (void *) (ctx->buffer + left),
247                (void *) input, length );
248    }
249}
250
251static uint8 sha1_padding[64] =
252{
253 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
254    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
255    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
256    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
257};
258
259static
260void sha1_finish( sha1_context *ctx, uint8 digest[20] )
261{
262    uint32 last, padn;
263    uint32 high, low;
264    uint8 msglen[8];
265
266    high = ( ctx->total[0] >> 29 )
267         | ( ctx->total[1] <<  3 );
268    low  = ( ctx->total[0] <<  3 );
269
270    PUT_UINT32( high, msglen, 0 );
271    PUT_UINT32( low,  msglen, 4 );
272
273    last = ctx->total[0] & 0x3F;
274    padn = ( last < 56 ) ? ( 56 - last ) : ( 120 - last );
275
276    sha1_update( ctx, sha1_padding, padn );
277    sha1_update( ctx, msglen, 8 );
278
279    PUT_UINT32( ctx->state[0], digest,  0 );
280    PUT_UINT32( ctx->state[1], digest,  4 );
281    PUT_UINT32( ctx->state[2], digest,  8 );
282    PUT_UINT32( ctx->state[3], digest, 12 );
283    PUT_UINT32( ctx->state[4], digest, 16 );
284}
285
286#ifdef TEST
287
288#include <stdlib.h>
289#include <stdio.h>
290
291/*
292 * those are the standard FIPS-180-1 test vectors
293 */
294
295static char *msg[] = 
296{
297    "abc",
298    "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq",
299    NULL
300};
301
302static char *val[] =
303{
304    "a9993e364706816aba3e25717850c26c9cd0d89d",
305    "84983e441c3bd26ebaae4aa1f95129e5e54670f1",
306    "34aa973cd4c4daa4f61eeb2bdbad27316534016f"
307};
308
309int main( int argc, char *argv[] )
310{
311    FILE *f;
312    int i, j;
313    char output[41];
314    sha1_context ctx;
315    unsigned char buf[1000];
316    unsigned char sha1sum[20];
317
318    if( argc < 2 )
319    {
320        printf( "\n SHA-1 Validation Tests:\n\n" );
321
322        for( i = 0; i < 3; i++ )
323        {
324            printf( " Test %d ", i + 1 );
325
326            sha1_starts( &ctx );
327
328            if( i < 2 )
329            {
330                sha1_update( &ctx, (uint8 *) msg[i],
331                             strlen( msg[i] ) );
332            }
333            else
334            {
335                memset( buf, 'a', 1000 );
336
337                for( j = 0; j < 1000; j++ )
338                {
339                    sha1_update( &ctx, (uint8 *) buf, 1000 );
340                }
341            }
342
343            sha1_finish( &ctx, sha1sum );
344
345            for( j = 0; j < 20; j++ )
346            {
347                sprintf( output + j * 2, "%02x", sha1sum[j] );
348            }
349
350            if( memcmp( output, val[i], 40 ) )
351            {
352                printf( "failed!\n" );
353                return( 1 );
354            }
355
356            printf( "passed.\n" );
357        }
358
359        printf( "\n" );
360    }
361    else
362    {
363        if( ! ( f = fopen( argv[1], "rb" ) ) )
364        {
365            perror( "fopen" );
366            return( 1 );
367        }
368
369        sha1_starts( &ctx );
370
371        while( ( i = fread( buf, 1, sizeof( buf ), f ) ) > 0 )
372        {
373            sha1_update( &ctx, buf, i );
374        }
375
376        sha1_finish( &ctx, sha1sum );
377
378        for( j = 0; j < 20; j++ )
379        {
380            printf( "%02x", sha1sum[j] );
381        }
382
383        printf( "  %s\n", argv[1] );
384    }
385
386    return( 0 );
387}
388
389#endif
Note: See TracBrowser for help on using the repository browser.