Z:/root/Project/pwatch/src/sha1sum.c

이 파일의 문서화 페이지로 가기
00001 /* sha1sum.c - print SHA-1 Message-Digest Algorithm 
00002  * Copyright (C) 1998, 1999, 2000, 2001 Free Software Foundation, Inc.
00003  * Copyright (C) 2004 g10 Code GmbH
00004  *
00005  * This program is free software; you can redistribute it and/or modify it
00006  * under the terms of the GNU General Public License as published by the
00007  * Free Software Foundation; either version 2, or (at your option) any
00008  * later version.
00009  *
00010  * This program is distributed in the hope that it will be useful,
00011  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00012  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00013  * GNU General Public License for more details.
00014  *
00015  * You should have received a copy of the GNU General Public License
00016  * along with this program; if not, write to the Free Software Foundation,
00017  * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
00018  */
00019 
00020 /* SHA-1 coden take from gnupg 1.3.92. 
00021 
00022    Note, that this is a simple tool to be used for MS Windows.
00023 */
00024 #include "sha1sum.h"
00025 
00026 void sha1_init(SHA1_CONTEXT *hd)
00027 {
00028         hd->h0 = 0x67452301;
00029         hd->h1 = 0xefcdab89;
00030         hd->h2 = 0x98badcfe;
00031         hd->h3 = 0x10325476;
00032         hd->h4 = 0xc3d2e1f0;
00033         hd->nblocks = 0;
00034         hd->count = 0;
00035 }
00036 
00037 /****************
00038  * Transform the message X which consists of 16 32-bit-words
00039  */
00040 void transform(SHA1_CONTEXT *hd, unsigned char *data)
00041 {
00042         u32 a,b,c,d,e,tm;
00043         u32 x[16];
00044 
00045         /* get values from the chaining vars */
00046         a = hd->h0;
00047         b = hd->h1;
00048         c = hd->h2;
00049         d = hd->h3;
00050         e = hd->h4;
00051 
00052 #ifdef BIG_ENDIAN_HOST
00053         memcpy( x, data, 64 );
00054 #else
00055         {
00056                 int i;
00057                 unsigned char *p2;
00058                 for(i = 0, p2 = (unsigned char *)x; i < 16; i++, p2 += 4) {
00059                         p2[3] = *data++;
00060                         p2[2] = *data++;
00061                         p2[1] = *data++;
00062                         p2[0] = *data++;
00063                 }
00064         }
00065 #endif
00066 
00067         R( a, b, c, d, e, F1, K1, x[ 0] );
00068         R( e, a, b, c, d, F1, K1, x[ 1] );
00069         R( d, e, a, b, c, F1, K1, x[ 2] );
00070         R( c, d, e, a, b, F1, K1, x[ 3] );
00071         R( b, c, d, e, a, F1, K1, x[ 4] );
00072         R( a, b, c, d, e, F1, K1, x[ 5] );
00073         R( e, a, b, c, d, F1, K1, x[ 6] );
00074         R( d, e, a, b, c, F1, K1, x[ 7] );
00075         R( c, d, e, a, b, F1, K1, x[ 8] );
00076         R( b, c, d, e, a, F1, K1, x[ 9] );
00077         R( a, b, c, d, e, F1, K1, x[10] );
00078         R( e, a, b, c, d, F1, K1, x[11] );
00079         R( d, e, a, b, c, F1, K1, x[12] );
00080         R( c, d, e, a, b, F1, K1, x[13] );
00081         R( b, c, d, e, a, F1, K1, x[14] );
00082         R( a, b, c, d, e, F1, K1, x[15] );
00083         R( e, a, b, c, d, F1, K1, M(16) );
00084         R( d, e, a, b, c, F1, K1, M(17) );
00085         R( c, d, e, a, b, F1, K1, M(18) );
00086         R( b, c, d, e, a, F1, K1, M(19) );
00087         R( a, b, c, d, e, F2, K2, M(20) );
00088         R( e, a, b, c, d, F2, K2, M(21) );
00089         R( d, e, a, b, c, F2, K2, M(22) );
00090         R( c, d, e, a, b, F2, K2, M(23) );
00091         R( b, c, d, e, a, F2, K2, M(24) );
00092         R( a, b, c, d, e, F2, K2, M(25) );
00093         R( e, a, b, c, d, F2, K2, M(26) );
00094         R( d, e, a, b, c, F2, K2, M(27) );
00095         R( c, d, e, a, b, F2, K2, M(28) );
00096         R( b, c, d, e, a, F2, K2, M(29) );
00097         R( a, b, c, d, e, F2, K2, M(30) );
00098         R( e, a, b, c, d, F2, K2, M(31) );
00099         R( d, e, a, b, c, F2, K2, M(32) );
00100         R( c, d, e, a, b, F2, K2, M(33) );
00101         R( b, c, d, e, a, F2, K2, M(34) );
00102         R( a, b, c, d, e, F2, K2, M(35) );
00103         R( e, a, b, c, d, F2, K2, M(36) );
00104         R( d, e, a, b, c, F2, K2, M(37) );
00105         R( c, d, e, a, b, F2, K2, M(38) );
00106         R( b, c, d, e, a, F2, K2, M(39) );
00107         R( a, b, c, d, e, F3, K3, M(40) );
00108         R( e, a, b, c, d, F3, K3, M(41) );
00109         R( d, e, a, b, c, F3, K3, M(42) );
00110         R( c, d, e, a, b, F3, K3, M(43) );
00111         R( b, c, d, e, a, F3, K3, M(44) );
00112         R( a, b, c, d, e, F3, K3, M(45) );
00113         R( e, a, b, c, d, F3, K3, M(46) );
00114         R( d, e, a, b, c, F3, K3, M(47) );
00115         R( c, d, e, a, b, F3, K3, M(48) );
00116         R( b, c, d, e, a, F3, K3, M(49) );
00117         R( a, b, c, d, e, F3, K3, M(50) );
00118         R( e, a, b, c, d, F3, K3, M(51) );
00119         R( d, e, a, b, c, F3, K3, M(52) );
00120         R( c, d, e, a, b, F3, K3, M(53) );
00121         R( b, c, d, e, a, F3, K3, M(54) );
00122         R( a, b, c, d, e, F3, K3, M(55) );
00123         R( e, a, b, c, d, F3, K3, M(56) );
00124         R( d, e, a, b, c, F3, K3, M(57) );
00125         R( c, d, e, a, b, F3, K3, M(58) );
00126         R( b, c, d, e, a, F3, K3, M(59) );
00127         R( a, b, c, d, e, F4, K4, M(60) );
00128         R( e, a, b, c, d, F4, K4, M(61) );
00129         R( d, e, a, b, c, F4, K4, M(62) );
00130         R( c, d, e, a, b, F4, K4, M(63) );
00131         R( b, c, d, e, a, F4, K4, M(64) );
00132         R( a, b, c, d, e, F4, K4, M(65) );
00133         R( e, a, b, c, d, F4, K4, M(66) );
00134         R( d, e, a, b, c, F4, K4, M(67) );
00135         R( c, d, e, a, b, F4, K4, M(68) );
00136         R( b, c, d, e, a, F4, K4, M(69) );
00137         R( a, b, c, d, e, F4, K4, M(70) );
00138         R( e, a, b, c, d, F4, K4, M(71) );
00139         R( d, e, a, b, c, F4, K4, M(72) );
00140         R( c, d, e, a, b, F4, K4, M(73) );
00141         R( b, c, d, e, a, F4, K4, M(74) );
00142         R( a, b, c, d, e, F4, K4, M(75) );
00143     R( e, a, b, c, d, F4, K4, M(76) );
00144     R( d, e, a, b, c, F4, K4, M(77) );
00145     R( c, d, e, a, b, F4, K4, M(78) );
00146     R( b, c, d, e, a, F4, K4, M(79) );
00147 
00148     /* Update chaining vars */
00149     hd->h0 += a;
00150     hd->h1 += b;
00151     hd->h2 += c;
00152     hd->h3 += d;
00153     hd->h4 += e;
00154 }
00155 
00156 
00157 /* Update the message digest with the contents
00158  * of INBUF with length INLEN.
00159  */
00160 void sha1_write(SHA1_CONTEXT *hd, unsigned char *inbuf, size_t inlen)
00161 {
00162         if(hd->count == 64) { /* flush the buffer */
00163                 transform( hd, hd->buf );
00164                 hd->count = 0;
00165                 hd->nblocks++;
00166         }
00167     if(!inbuf)
00168         return;
00169     if(hd->count) {
00170         for( ; inlen && hd->count < 64; inlen--)
00171                 hd->buf[hd->count++] = *inbuf++;
00172                 sha1_write(hd, NULL, 0);
00173                 if(!inlen)
00174                         return;
00175     }
00176 
00177     while(inlen >= 64) {
00178                 transform(hd, inbuf);
00179                 hd->count = 0;
00180                 hd->nblocks++;
00181                 inlen -= 64;
00182                 inbuf += 64;
00183     }
00184     for( ; inlen && hd->count < 64; inlen--)
00185         hd->buf[hd->count++] = *inbuf++;
00186 }
00187 
00188 
00189 /* The routine final terminates the computation and
00190  * returns the digest.
00191  * The handle is prepared for a new cycle, but adding bytes to the
00192  * handle will the destroy the returned buffer.
00193  * Returns: 20 bytes representing the digest.
00194  */
00195 
00196 void sha1_final(SHA1_CONTEXT *hd)
00197 {
00198         u32 t, msb, lsb;
00199         unsigned char *p;
00200 
00201         sha1_write(hd, NULL, 0); /* flush */;
00202 
00203         t = hd->nblocks;
00204         /* multiply by 64 to make a byte count */
00205         lsb = t << 6;
00206         msb = t >> 26;
00207         /* add the count */
00208         t = lsb;
00209         if((lsb += hd->count) < t)
00210                 msb++;
00211         /* multiply by 8 to make a bit count */
00212         t = lsb;
00213         lsb <<= 3;
00214         msb <<= 3;
00215         msb |= t >> 29;
00216 
00217         if(hd->count < 56) { /* enough room */
00218                 hd->buf[hd->count++] = 0x80; /* pad */
00219                 while(hd->count < 56)
00220                         hd->buf[hd->count++] = 0;  /* pad */
00221         }
00222         else { /* need one extra block */
00223                 hd->buf[hd->count++] = 0x80; /* pad character */
00224                 while(hd->count < 64)
00225                         hd->buf[hd->count++] = 0;
00226                 sha1_write(hd, NULL, 0);  /* flush */;
00227                 memset(hd->buf, 0, 56 ); /* fill next block with zeroes */
00228         }
00229         /* append the 64 bit count */
00230         hd->buf[56] = msb >> 24;
00231         hd->buf[57] = msb >> 16;
00232         hd->buf[58] = msb >>  8;
00233         hd->buf[59] = msb          ;
00234         hd->buf[60] = lsb >> 24;
00235         hd->buf[61] = lsb >> 16;
00236         hd->buf[62] = lsb >>  8;
00237         hd->buf[63] = lsb          ;
00238         transform(hd, hd->buf);
00239         
00240         p = hd->buf;
00241 #ifdef BIG_ENDIAN_HOST
00242 #define X(a) do { *(u32*)p = hd->h##a ; p += 4; } while(0)
00243 #else /* little endian */
00244 #define X(a) do { *p++ = hd->h##a >> 24; *p++ = hd->h##a >> 16;  \
00245                         *p++ = hd->h##a >> 8; *p++ = hd->h##a; } while(0)
00246 #endif
00247         X(0);
00248         X(1);
00249         X(2);
00250         X(3);
00251         X(4);
00252 #undef X
00253 }
00262 int sha1sum(char *file_name, SHA1_CONTEXT *ctx)
00263 {
00264         FILE *fp;
00265         unsigned char buffer[4096];
00266         size_t n;
00267         int i;
00268         
00269         assert(sizeof (u32) == 4);
00270               
00271         fp = fopen(file_name, "rb");
00272         if(!fp) {
00273                 fprintf (stderr, "can't open `%s': %s\n", file_name, strerror (errno));
00274                 return -1;
00275         }
00276         sha1_init(ctx);
00277         while((n = fread(buffer, 1, sizeof buffer, fp))) {
00278                 sha1_write (ctx, buffer, n);
00279         }
00280         
00281         if(ferror(fp)) {
00282                 fprintf(stderr, "error reading `%s': %s\n", file_name, strerror(errno));
00283                 return -1;
00284         }
00285         sha1_final(ctx);
00286         fclose (fp);
00287           
00288         for(i = 0; i < 20; i++) {
00289                 printf("%02x", ctx->buf[i]);
00290         }       
00291         printf("  %s\n", file_name);
00292 
00293         return 0;
00294 }
00295 
00296 #if 0
00297 int 
00298 main (int argc, char **argv)
00299 {
00300   assert (sizeof (u32) == 4);
00301 
00302   if (argc < 2)
00303     {
00304       fprintf (stderr, "usage: sha1sum filenames\n");
00305       exit (1);
00306     }
00307   for (argc--, argv++; argc; argv++, argc--)
00308     {
00309       FILE *fp;
00310       char buffer[4096];
00311       size_t n;
00312       SHA1_CONTEXT ctx;
00313       int i;
00314       
00315       fp = fopen (*argv, "rb");
00316       if (!fp)
00317         {
00318           fprintf (stderr, "can't open `%s': %s\n", *argv, strerror (errno));
00319           exit (1);
00320         }
00321       sha1_init (&ctx);
00322       while ( (n = fread (buffer, 1, sizeof buffer, fp)))
00323         sha1_write (&ctx, buffer, n);
00324       if (ferror (fp))
00325         {
00326           fprintf (stderr, "error reading `%s': %s\n", *argv,strerror (errno));
00327           exit (1);
00328         }
00329       sha1_final (&ctx);
00330       fclose (fp);
00331       
00332       for (i=0; i < 20; i++)
00333         printf ("%02x", ctx.buf[i]);
00334       printf ("  %s\n", *argv);
00335     }
00336   return 0;
00337 }
00338 #endif
00339 /*
00340 Local Variables:
00341 compile-command: "cc -Wall -g -o sha1sum sha1sum.c"
00342 End:
00343 */

생성시간 : Mon Dec 31 13:10:53 2007, 프로젝트명 : oblog, 생성자 :   doxygen 1.5.4