[BACK]Return to sha1.c CVS log [TXT][DIR] Up to [local] / OpenXM_contrib2 / asir2000 / builtin

Annotation of OpenXM_contrib2/asir2000/builtin/sha1.c, Revision 1.5

1.2       noro        1: /*
                      2:  * Copyright (c) 1994-2000 FUJITSU LABORATORIES LIMITED
                      3:  * All rights reserved.
                      4:  *
                      5:  * FUJITSU LABORATORIES LIMITED ("FLL") hereby grants you a limited,
                      6:  * non-exclusive and royalty-free license to use, copy, modify and
                      7:  * redistribute, solely for non-commercial and non-profit purposes, the
                      8:  * computer program, "Risa/Asir" ("SOFTWARE"), subject to the terms and
                      9:  * conditions of this Agreement. For the avoidance of doubt, you acquire
                     10:  * only a limited right to use the SOFTWARE hereunder, and FLL or any
                     11:  * third party developer retains all rights, including but not limited to
                     12:  * copyrights, in and to the SOFTWARE.
                     13:  *
                     14:  * (1) FLL does not grant you a license in any way for commercial
                     15:  * purposes. You may use the SOFTWARE only for non-commercial and
                     16:  * non-profit purposes only, such as academic, research and internal
                     17:  * business use.
                     18:  * (2) The SOFTWARE is protected by the Copyright Law of Japan and
                     19:  * international copyright treaties. If you make copies of the SOFTWARE,
                     20:  * with or without modification, as permitted hereunder, you shall affix
                     21:  * to all such copies of the SOFTWARE the above copyright notice.
                     22:  * (3) An explicit reference to this SOFTWARE and its copyright owner
                     23:  * shall be made on your publication or presentation in any form of the
                     24:  * results obtained by use of the SOFTWARE.
                     25:  * (4) In the event that you modify the SOFTWARE, you shall notify FLL by
1.3       noro       26:  * e-mail at risa-admin@sec.flab.fujitsu.co.jp of the detailed specification
1.2       noro       27:  * for such modification or the source code of the modified part of the
                     28:  * SOFTWARE.
                     29:  *
                     30:  * THE SOFTWARE IS PROVIDED AS IS WITHOUT ANY WARRANTY OF ANY KIND. FLL
                     31:  * MAKES ABSOLUTELY NO WARRANTIES, EXPRESSED, IMPLIED OR STATUTORY, AND
                     32:  * EXPRESSLY DISCLAIMS ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS
                     33:  * FOR A PARTICULAR PURPOSE OR NONINFRINGEMENT OF THIRD PARTIES'
                     34:  * RIGHTS. NO FLL DEALER, AGENT, EMPLOYEES IS AUTHORIZED TO MAKE ANY
                     35:  * MODIFICATIONS, EXTENSIONS, OR ADDITIONS TO THIS WARRANTY.
                     36:  * UNDER NO CIRCUMSTANCES AND UNDER NO LEGAL THEORY, TORT, CONTRACT,
                     37:  * OR OTHERWISE, SHALL FLL BE LIABLE TO YOU OR ANY OTHER PERSON FOR ANY
                     38:  * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, PUNITIVE OR CONSEQUENTIAL
                     39:  * DAMAGES OF ANY CHARACTER, INCLUDING, WITHOUT LIMITATION, DAMAGES
                     40:  * ARISING OUT OF OR RELATING TO THE SOFTWARE OR THIS AGREEMENT, DAMAGES
                     41:  * FOR LOSS OF GOODWILL, WORK STOPPAGE, OR LOSS OF DATA, OR FOR ANY
                     42:  * DAMAGES, EVEN IF FLL SHALL HAVE BEEN INFORMED OF THE POSSIBILITY OF
                     43:  * SUCH DAMAGES, OR FOR ANY CLAIM BY ANY OTHER PARTY. EVEN IF A PART
                     44:  * OF THE SOFTWARE HAS BEEN DEVELOPED BY A THIRD PARTY, THE THIRD PARTY
                     45:  * DEVELOPER SHALL HAVE NO LIABILITY IN CONNECTION WITH THE USE,
                     46:  * PERFORMANCE OR NON-PERFORMANCE OF THE SOFTWARE.
                     47:  *
1.5     ! fujimoto   48:  * $OpenXM: OpenXM_contrib2/asir2000/builtin/sha1.c,v 1.4 2001/10/09 01:36:07 noro Exp $
1.2       noro       49: */
1.1       noro       50: /* Implementation of NIST's Secure Hash Algorithm (FIPS 180)
                     51: * Lightly bummed for execution efficiency.
                     52: *
                     53: * Jim Gillogly 3 May 1993
                     54: *
                     55: * 27 Aug 93: imported LITTLE_ENDIAN mods from Peter Gutmann's implementation
                     56: * 5 Jul 94: Modified for NSA fix
                     57: *
                     58: * Compile: cc -O -o sha sha.c
                     59: *
                     60: * To remove the test wrapper and use just the nist_hash() routine,
                     61: *      compile with -DONT_WRAP
                     62: *
                     63: * To reverse byte order for little-endian machines, use -DLITTLE_ENDIAN
                     64: *
                     65: * To get the original SHA definition before the 1994 fix, use -DVERSION_0
                     66: *
                     67: * Usage: sha [-vt] [filename ...]
                     68: *
                     69: *      -v switch: output the filename as well
                     70: *      -t switch: suppress spaces between 32-bit blocks
                     71: *
                     72: *      If no input files are specified, process standard input.
                     73: *
                     74: * Output: 40-hex-digit digest of each file specified (160 bits)
                     75: *
                     76: * Synopsis of the function calls:
                     77: *
                     78: *   sha_file(char *filename, unsigned int *buffer)
                     79: *      Filename is a file to be opened and processed.
                     80: *      buffer is a user-supplied array of 5 or more ints.
                     81: *      The 5-word buffer is filled with 160 bits of non-terminated hash.
                     82: *      Returns 0 if successful, non-zero if bad file.
                     83: *
                     84: *   void sha_stream(FILE *stream, unsigned int *buffer)
                     85: *      Input is from already-opened stream, not file.
                     86: *
                     87: *   void sha_memory(char *mem, int length, unsigned int *buffer)
                     88: *      Input is a memory block "length" bytes int.
                     89: *
                     90: * Caveat:
                     91: *      Not tested for case that requires the high word of the length,
                     92: *      which would be files larger than 1/2 gig or so.
                     93: *
                     94: * Limitation:
                     95: *      sha_memory (the memory block function) will deal with blocks no inter
                     96: *      than 4 gigabytes; for inter samples, the stream version will
                     97: *      probably be most convenient (e.g. perl moby_data.pl | sha).
                     98: *
                     99: * Bugs:
                    100: *      The standard is defined for bit strings; I assume bytes.
                    101: *
                    102: * Copyright 1993, Dr. James J. Gillogly
                    103: * This code may be freely used in any application.
                    104: */
                    105:
                    106: #define ONT_WRAP    /* Using just the hash routine itself */
                    107:
                    108: /* #define VERSION_0 */  /* Define this to get the original SHA definition */
                    109:
                    110: #include <stdio.h>
                    111: #include <memory.h>
                    112:
                    113: #define VERBOSE
                    114:
                    115: #define TRUE  1
                    116: #define FALSE 0
                    117:
                    118: #define SUCCESS 0
                    119: #define FAILURE -1
                    120:
                    121: int sha_file(char* filename, unsigned int *buffer);
                    122: void sha_stream(FILE *stream, unsigned int *buffer);
                    123: void sha_memory(char *mem, unsigned int length, unsigned int *buffer);
                    124:
                    125: static void nist_guts(int file_flag, /* Input from memory, or from stream? */
                    126:             FILE *stream,
                    127:             char *mem,
                    128:             unsigned int length,
                    129:             unsigned int *buf);
                    130:
                    131: #ifndef ONT_WRAP    /* Using just the hash routine itself */
                    132:
                    133: #define HASH_SIZE 5   /* Produces 160-bit digest of the message */
                    134:
                    135: int main(int argc, char **argv)
                    136: {
                    137:   unsigned int hbuf[HASH_SIZE];
                    138:   char *s;
                    139:   int file_args = FALSE;  /* If no files, take it from stdin */
                    140:   int verbose = FALSE;
                    141:   int terse = FALSE;
                    142:
                    143: #ifdef MEMTEST
                    144:   sha_memory("abc", 3l, hbuf);     /* NIST test value from appendix A */
                    145:   if (verbose) printf("Memory:");
                    146:   if (terse) printf("%08lx%08lx%08lx%08lx%08lx\n",
                    147:     hbuf[0], hbuf[1], hbuf[2], hbuf[3], hbuf[4]);
                    148:   else printf("%08lx %08lx %08lx %08lx %08lx\n",
                    149:     hbuf[0], hbuf[1], hbuf[2], hbuf[3], hbuf[4]);
                    150: #endif
                    151:
                    152:   for (++argv; --argc; ++argv)       /* March down the arg list */
                    153:     {
                    154:       if (**argv == '-')         /* Process one or more flags */
                    155:         for (s = &(*argv)[1]; *s; s++) /* Obfuscated C contest entry */
                    156:           switch(*s)
                    157:             {
                    158:               case 'v': case 'V':
                    159:                 verbose = TRUE;
                    160:                 break;
                    161:               case 't': case 'T':
                    162:                 terse = TRUE;
                    163:                 break;
                    164:               default:
                    165:                 fprintf(stderr, "Unrecognized flag: %c\n", *s);
1.5     ! fujimoto  166: #if defined(__MINGW32__) || defined(__MINGW64__)
        !           167:                fflush(stderr);
        !           168: #endif
1.1       noro      169:                 return FALSE;
                    170:             }
                    171:       else              /* Process a file */
                    172:         {
                    173:           if (verbose) printf("%s:", *argv);
                    174:           file_args = TRUE;       /* Whether or not we could read it */
                    175:
                    176:           if (sha_file(*argv, hbuf) == FAILURE)
                    177:             printf("Can't open file %s.\n", *argv);
                    178:           else
                    179:             if (terse) printf("%08lx%08lx%08lx%08lx%08lx\n",
                    180:               hbuf[0], hbuf[1], hbuf[2], hbuf[3], hbuf[4]);
                    181:             else printf("%08lx %08lx %08lx %08lx %08lx\n",
                    182:               hbuf[0], hbuf[1], hbuf[2], hbuf[3], hbuf[4]);
                    183:         }
                    184:     }
                    185:   if (! file_args)  /* No file specified */
                    186:     {
                    187:       if (verbose) printf("%s:", *argv);
                    188:       sha_stream(stdin, hbuf);
                    189:
                    190:       if (terse) printf("%08lx%08lx%08lx%08lx%08lx\n",
                    191:         hbuf[0], hbuf[1], hbuf[2], hbuf[3], hbuf[4]);
                    192:       else printf("%08lx %08lx %08lx %08lx %08lx\n",
                    193:         hbuf[0], hbuf[1], hbuf[2], hbuf[3], hbuf[4]);
                    194:     }
                    195:   return TRUE;
                    196: }
                    197:
                    198: #endif ONT_WRAP
                    199:
                    200: /* #ifdef LITTLE_ENDIAN */ /* Imported from Peter Gutmann's implementation */
                    201:
                    202: /* When run on a little-endian CPU we need to perform byte reversal on an
                    203:   array of intwords.  It is possible to make the code endianness-
                    204:   independant by fiddling around with data at the byte level, but this
                    205:   makes for very slow code, so we rely on the user to sort out endianness
                    206:   at compile time */
                    207:
                    208: static void byteReverse( unsigned int *buffer, int byteCount )
                    209: {
                    210:   unsigned int value;
                    211:   int count;
                    212:   extern int little_endian;
                    213:
                    214:   if ( !little_endian )
                    215:        return;
                    216:
                    217:   byteCount /= sizeof( unsigned int );
                    218:   for( count = 0; count < byteCount; count++ )
                    219:     {
                    220:       value = ( buffer[ count ] << 16 ) | ( buffer[ count ] >> 16 );
                    221:       buffer[ count ] = ( ( value & 0xFF00FF00L ) >> 8 ) | ( ( value & 0x00FF00FFL ) << 8 );
                    222:     }
                    223: }
                    224: /* #endif */ /* LITTLE_ENDIAN */
                    225:
                    226: union intbyte
                    227: {
                    228:   unsigned int W[80];    /* Process 16 32-bit words at a time */
                    229:   char B[320];        /* But read them as bytes for counting */
                    230: };
                    231:
                    232: int sha_file(char* filename, unsigned int *buffer)    /* Hash a file */
                    233: {
                    234:   FILE *infile;
                    235:
                    236:   if ((infile = fopen(filename, "rb")) == NULL)
                    237:     {
                    238:       int i;
                    239:
                    240:       for (i = 0; i < 5; i++)
                    241:         buffer[i] = 0xdeadbeef;
                    242:       return FAILURE;
                    243:     }
                    244:   (void) sha_stream(infile, buffer);
                    245:   fclose(infile);
                    246:   return SUCCESS;
                    247: }
                    248:
                    249: void sha_memory(char *mem, unsigned int length, unsigned int *buffer)
                    250: {
                    251:   nist_guts(FALSE, (FILE *) NULL, mem, length, buffer);
                    252: }
                    253:
                    254: void sha_stream(FILE *stream, unsigned int *buffer)
                    255: {
                    256:   nist_guts(TRUE, stream, (char *) NULL, 0l, buffer);
                    257: }
                    258:
                    259: #define f0(x,y,z) (z ^ (x & (y ^ z)))       /* Magic functions */
                    260: #define f1(x,y,z) (x ^ y ^ z)
                    261: #define f2(x,y,z) ((x & y) | (z & (x | y)))
                    262: #define f3(x,y,z) (x ^ y ^ z)
                    263:
                    264: #define K0 0x5a827999               /* Magic constants */
                    265: #define K1 0x6ed9eba1
                    266: #define K2 0x8f1bbcdc
                    267: #define K3 0xca62c1d6
                    268:
                    269: #define S(n, X) ((X << n) | (X >> (32 - n)))  /* Barrel roll */
                    270:
                    271: #define r0(f, K) \
                    272:   temp = S(5, A) + f(B, C, D) + E + *p0++ + K; \
                    273:   E = D;  \
                    274:   D = C;  \
                    275:   C = S(30, B); \
                    276:   B = A;  \
                    277:   A = temp
                    278:
                    279: #ifdef VERSION_0
                    280: #define r1(f, K) \
                    281:   temp = S(5, A) + f(B, C, D) + E + \
                    282:       (*p0++ = *p1++ ^ *p2++ ^ *p3++ ^ *p4++) + K; \
                    283:   E = D;  \
                    284:   D = C;  \
                    285:   C = S(30, B); \
                    286:   B = A;  \
                    287:   A = temp
                    288: #else           /* Version 1: Summer '94 update */
                    289: #define r1(f, K) \
                    290:   temp = *p1++ ^ *p2++ ^ *p3++ ^ *p4++; \
                    291:   temp = S(5, A) + f(B, C, D) + E + (*p0++ = S(1,temp)) + K; \
                    292:   E = D;  \
                    293:   D = C;  \
                    294:   C = S(30, B); \
                    295:   B = A;  \
                    296:   A = temp
                    297: #endif
                    298:
                    299: static void nist_guts(int file_flag, /* Input from memory, or from stream? */
                    300:             FILE *stream,
                    301:             char *mem,
                    302:             unsigned int length,
                    303:             unsigned int *buf)
                    304: {
                    305:   int i, nread, nbits;
                    306:   union intbyte d;
                    307:   unsigned int hi_length, lo_length;
                    308:   int padded;
                    309:   char *s;
                    310:
                    311:   register unsigned int *p0, *p1, *p2, *p3, *p4;
                    312:   unsigned int A, B, C, D, E, temp;
                    313:
                    314:   unsigned int h0, h1, h2, h3, h4;
                    315:
                    316:   h0 = 0x67452301;              /* Accumulators */
                    317:   h1 = 0xefcdab89;
                    318:   h2 = 0x98badcfe;
                    319:   h3 = 0x10325476;
                    320:   h4 = 0xc3d2e1f0;
                    321:
                    322:   padded = FALSE;
                    323:   s = mem;
                    324:   for (hi_length = lo_length = 0; ;)  /* Process 16 ints at a time */
                    325:     {
                    326:       if (file_flag)
                    327:         {
                    328:           nread = fread(d.B, 1, 64, stream);  /* Read as 64 bytes */
                    329:         }
                    330:       else
                    331:         {
                    332:           if (length < 64) nread = length;
                    333:           else       nread = 64;
                    334:           length -= nread;
                    335:           memcpy(d.B, s, nread);
                    336:           s += nread;
                    337:         }
                    338:       if (nread < 64)   /* Partial block? */
                    339:         {
                    340:           nbits = nread << 3;         /* Length: bits */
1.4       noro      341:           if ((int)(lo_length += nbits) < nbits)
1.1       noro      342:             hi_length++;        /* 64-bit integer */
                    343:
                    344:           if (nread < 64 && ! padded)  /* Append a single bit */
                    345:             {
1.4       noro      346:               d.B[nread++] = (char)0x80; /* Using up next byte */
1.1       noro      347:               padded = TRUE;     /* Single bit once */
                    348:             }
                    349:           for (i = nread; i < 64; i++) /* Pad with nulls */
                    350:             d.B[i] = 0;
                    351:           if (nread <= 56)   /* Room for length in this block */
                    352:             {
                    353:               d.W[14] = hi_length;
                    354:               d.W[15] = lo_length;
                    355: /* #ifdef LITTLE_ENDIAN */
                    356:               byteReverse(d.W, 56 );
                    357: /* #endif */ /* LITTLE_ENDIAN */
                    358:             }
                    359: /* #ifdef LITTLE_ENDIAN */
                    360:           else
                    361:             byteReverse(d.W, 64 );
                    362: /* #endif */ /* LITTLE_ENDIAN */
                    363:         }
                    364:       else  /* Full block -- get efficient */
                    365:         {
                    366:           if ((lo_length += 512) < 512)
                    367:             hi_length++;  /* 64-bit integer */
                    368: /* #ifdef LITTLE_ENDIAN */
                    369:           byteReverse(d.W, 64 );
                    370: /* #endif */ /* LITTLE_ENDIAN */
                    371:         }
                    372:
                    373:       p0 = d.W;
                    374:       A = h0; B = h1; C = h2; D = h3; E = h4;
                    375:
                    376:       r0(f0,K0); r0(f0,K0); r0(f0,K0); r0(f0,K0); r0(f0,K0);
                    377:       r0(f0,K0); r0(f0,K0); r0(f0,K0); r0(f0,K0); r0(f0,K0);
                    378:       r0(f0,K0); r0(f0,K0); r0(f0,K0); r0(f0,K0); r0(f0,K0);
                    379:       r0(f0,K0);
                    380:
                    381:       p1 = &d.W[13]; p2 = &d.W[8]; p3 = &d.W[2]; p4 = &d.W[0];
                    382:
                    383:       r1(f0,K0); r1(f0,K0); r1(f0,K0); r1(f0,K0);
                    384:       r1(f1,K1); r1(f1,K1); r1(f1,K1); r1(f1,K1); r1(f1,K1);
                    385:       r1(f1,K1); r1(f1,K1); r1(f1,K1); r1(f1,K1); r1(f1,K1);
                    386:       r1(f1,K1); r1(f1,K1); r1(f1,K1); r1(f1,K1); r1(f1,K1);
                    387:       r1(f1,K1); r1(f1,K1); r1(f1,K1); r1(f1,K1); r1(f1,K1);
                    388:       r1(f2,K2); r1(f2,K2); r1(f2,K2); r1(f2,K2); r1(f2,K2);
                    389:       r1(f2,K2); r1(f2,K2); r1(f2,K2); r1(f2,K2); r1(f2,K2);
                    390:       r1(f2,K2); r1(f2,K2); r1(f2,K2); r1(f2,K2); r1(f2,K2);
                    391:       r1(f2,K2); r1(f2,K2); r1(f2,K2); r1(f2,K2); r1(f2,K2);
                    392:       r1(f3,K3); r1(f3,K3); r1(f3,K3); r1(f3,K3); r1(f3,K3);
                    393:       r1(f3,K3); r1(f3,K3); r1(f3,K3); r1(f3,K3); r1(f3,K3);
                    394:       r1(f3,K3); r1(f3,K3); r1(f3,K3); r1(f3,K3); r1(f3,K3);
                    395:       r1(f3,K3); r1(f3,K3); r1(f3,K3); r1(f3,K3); r1(f3,K3);
                    396:
                    397:       h0 += A; h1 += B; h2 += C; h3 += D; h4 += E;
                    398:
                    399:       if (nread <= 56) break; /* If it's greater, length in next block */
                    400:     }
                    401:   buf[0] = h0; buf[1] = h1; buf[2] = h2; buf[3] = h3; buf[4] = h4;
                    402: }

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>