home *** CD-ROM | disk | FTP | other *** search
/ The Best of Windows 95.com 1996 September / WIN95_09964.iso / encrypt / cryptext.zip / SHA.C < prev   
C/C++ Source or Header  |  1994-07-08  |  10KB  |  356 lines

  1. /* Implementation of NIST's Secure Hash Algorithm (FIPS 180)
  2.  * Lightly bummed for execution efficiency.
  3.  *
  4.  * Jim Gillogly 3 May 1993
  5.  *
  6.  * 27 Aug 93: imported LITTLE_ENDIAN mods from Peter Gutmann's implementation
  7.  * 5 Jul 94: Modified for NSA fix
  8.  *
  9.  * Compile: cc -O -o sha sha.c
  10.  *
  11.  * To remove the test wrapper and use just the nist_hash() routine,
  12.  *      compile with -DONT_WRAP
  13.  *
  14.  * To reverse byte order for little-endian machines, use -DLITTLE_ENDIAN
  15.  *
  16.  * To get the original SHA definition before the 1994 fix, use -DVERSION_0
  17.  *
  18.  * Usage: sha [-vt] [filename ...]
  19.  *
  20.  *      -v switch: output the filename as well
  21.  *      -t switch: suppress spaces between 32-bit blocks
  22.  *
  23.  *      If no input files are specified, process standard input.
  24.  *
  25.  * Output: 40-hex-digit digest of each file specified (160 bits)
  26.  *
  27.  * Synopsis of the function calls:
  28.  *
  29.  *   sha_file(char *filename, unsigned long *buffer)
  30.  *      Filename is a file to be opened and processed.
  31.  *      buffer is a user-supplied array of 5 or more longs.
  32.  *      The 5-word buffer is filled with 160 bits of non-terminated hash.
  33.  *      Returns 0 if successful, non-zero if bad file.
  34.  *
  35.  *   void sha_stream(FILE *stream, unsigned long *buffer)
  36.  *      Input is from already-opened stream, not file.
  37.  *
  38.  *   void sha_memory(char *mem, long length, unsigned long *buffer)
  39.  *      Input is a memory block "length" bytes long.
  40.  *
  41.  * Caveat:
  42.  *      Not tested for case that requires the high word of the length,
  43.  *      which would be files larger than 1/2 gig or so.
  44.  *
  45.  * Limitation:
  46.  *      sha_memory (the memory block function) will deal with blocks no longer
  47.  *      than 4 gigabytes; for longer samples, the stream version will
  48.  *      probably be most convenient (e.g. perl moby_data.pl | sha).
  49.  *
  50.  * Bugs:
  51.  *      The standard is defined for bit strings; I assume bytes.
  52.  *
  53.  * Copyright 1993, Dr. James J. Gillogly
  54.  * This code may be freely used in any application.
  55.  */
  56.  
  57. /* #define LITTLE_ENDIAN */
  58.  
  59. /* #define VERSION_0 */  /* Define this to get the original SHA definition */
  60.  
  61. #include <stdio.h>
  62. #include <memory.h>
  63.  
  64. #define VERBOSE
  65.  
  66. #define TRUE  1
  67. #define FALSE 0
  68.  
  69. #define SUCCESS 0
  70. #define FAILURE -1
  71.  
  72. int sha_file();                         /* External entries */
  73. void sha_stream(), sha_memory();
  74.  
  75. static void nist_guts();
  76.  
  77. #ifndef ONT_WRAP        /* Using just the hash routine itself */
  78.  
  79. #define HASH_SIZE 5     /* Produces 160-bit digest of the message */
  80.  
  81.  
  82.  
  83.  
  84. main(argc, argv)
  85. int argc;
  86. char **argv;
  87. {
  88.     unsigned long hbuf[HASH_SIZE];
  89.     char *s;
  90.     int file_args = FALSE;  /* If no files, take it from stdin */
  91.     int verbose = FALSE;
  92.     int terse = FALSE;
  93.  
  94. #ifdef MEMTEST
  95.     sha_memory("abc", 3l, hbuf);         /* NIST test value from appendix A */
  96.     if (verbose) printf("Memory:");
  97.     if (terse) printf("%08lx%08lx%08lx%08lx%08lx\n",
  98.     hbuf[0], hbuf[1], hbuf[2], hbuf[3], hbuf[4]);
  99.     else printf("%08lx %08lx %08lx %08lx %08lx\n",
  100.     hbuf[0], hbuf[1], hbuf[2], hbuf[3], hbuf[4]);
  101. #endif
  102.  
  103.     for (++argv; --argc; ++argv)           /* March down the arg list */
  104.     {
  105.     if (**argv == '-')                 /* Process one or more flags */
  106.         for (s = &(*argv)[1]; *s; s++) /* Obfuscated C contest entry */
  107.         switch(*s)
  108.         {
  109.             case 'v': case 'V':
  110.             verbose = TRUE;
  111.             break;
  112.             case 't': case 'T':
  113.             terse = TRUE;
  114.             break;
  115.             default:
  116.             fprintf(stderr, "Unrecognized flag: %c\n", *s);
  117.             return FALSE;
  118.         }
  119.     else                            /* Process a file */
  120.     {
  121.         if (verbose) printf("%s:", *argv);
  122.         file_args = TRUE;           /* Whether or not we could read it */
  123.  
  124.         if (sha_file(*argv, hbuf) == FAILURE)
  125.         printf("Can't open file %s.\n", *argv);
  126.         else
  127.         if (terse) printf("%08lx%08lx%08lx%08lx%08lx\n",
  128.             hbuf[0], hbuf[1], hbuf[2], hbuf[3], hbuf[4]);
  129.         else printf("%08lx %08lx %08lx %08lx %08lx\n",
  130.             hbuf[0], hbuf[1], hbuf[2], hbuf[3], hbuf[4]);
  131.     }
  132.     }
  133.     if (! file_args)    /* No file specified */
  134.     {
  135.     if (verbose) printf("%s:", *argv);
  136.     sha_stream(stdin, hbuf);
  137.  
  138.     if (terse) printf("%08lx%08lx%08lx%08lx%08lx\n",
  139.         hbuf[0], hbuf[1], hbuf[2], hbuf[3], hbuf[4]);
  140.     else printf("%08lx %08lx %08lx %08lx %08lx\n",
  141.         hbuf[0], hbuf[1], hbuf[2], hbuf[3], hbuf[4]);
  142.     }
  143.     return TRUE;
  144. }
  145.  
  146. #endif ONT_WRAP
  147.  
  148. #ifdef LITTLE_ENDIAN    /* Imported from Peter Gutmann's implementation */
  149.  
  150. /* When run on a little-endian CPU we need to perform byte reversal on an
  151.    array of longwords.  It is possible to make the code endianness-
  152.    independant by fiddling around with data at the byte level, but this
  153.    makes for very slow code, so we rely on the user to sort out endianness
  154.    at compile time */
  155.  
  156. static void byteReverse( unsigned long *buffer, int byteCount )
  157.     {
  158.     unsigned long value;
  159.     int count;
  160.  
  161.     byteCount /= sizeof( unsigned long );
  162.     for( count = 0; count < byteCount; count++ )
  163.     {
  164.     value = ( buffer[ count ] << 16 ) | ( buffer[ count ] >> 16 );
  165.     buffer[ count ] = ( ( value & 0xFF00FF00L ) >> 8 ) | ( ( value & 0x00FF00FFL ) << 8 );
  166.     }
  167.     }
  168. #endif /* LITTLE_ENDIAN */
  169.  
  170.  
  171.  
  172. union longbyte
  173. {
  174.     unsigned long W[80];        /* Process 16 32-bit words at a time */
  175.     char B[320];                /* But read them as bytes for counting */
  176. };
  177.  
  178. sha_file(filename, buffer)      /* Hash a file */
  179. char *filename;
  180. unsigned long *buffer;
  181. {
  182.     FILE *infile;
  183.  
  184.     if ((infile = fopen(filename, "rb")) == NULL)
  185.     {
  186.     int i;
  187.  
  188.     for (i = 0; i < 5; i++)
  189.         buffer[i] = 0xdeadbeef;
  190.     return FAILURE;
  191.     }
  192.     (void) sha_stream(infile, buffer);
  193.     fclose(infile);
  194.     return SUCCESS;
  195. }
  196.  
  197. void sha_memory(mem, length, buffer)    /* Hash a memory block */
  198. char *mem;
  199. unsigned long length;
  200. unsigned long *buffer;
  201. {
  202.     nist_guts(FALSE, (FILE *) NULL, mem, length, buffer);
  203. }
  204.  
  205. void sha_stream(stream, buffer)
  206. FILE *stream;
  207. unsigned long *buffer;
  208. {
  209.     nist_guts(TRUE, stream, (char *) NULL, 0l, buffer);
  210. }
  211.  
  212. #define f0(x,y,z) (z ^ (x & (y ^ z)))           /* Magic functions */
  213. #define f1(x,y,z) (x ^ y ^ z)
  214. #define f2(x,y,z) ((x & y) | (z & (x | y)))
  215. #define f3(x,y,z) (x ^ y ^ z)
  216.  
  217. #define K0 0x5a827999                           /* Magic constants */
  218. #define K1 0x6ed9eba1
  219. #define K2 0x8f1bbcdc
  220. #define K3 0xca62c1d6
  221.  
  222. #define S(n, X) ((X << n) | (X >> (32 - n)))    /* Barrel roll */
  223.  
  224. #define r0(f, K) \
  225.     temp = S(5, A) + f(B, C, D) + E + *p0++ + K; \
  226.     E = D;  \
  227.     D = C;  \
  228.     C = S(30, B); \
  229.     B = A;  \
  230.     A = temp
  231.  
  232. #ifdef VERSION_0
  233. #define r1(f, K) \
  234.     temp = S(5, A) + f(B, C, D) + E + \
  235.        (*p0++ = *p1++ ^ *p2++ ^ *p3++ ^ *p4++) + K; \
  236.     E = D;  \
  237.     D = C;  \
  238.     C = S(30, B); \
  239.     B = A;  \
  240.     A = temp
  241. #else                   /* Version 1: Summer '94 update */
  242. #define r1(f, K) \
  243.     temp = *p1++ ^ *p2++ ^ *p3++ ^ *p4++; \
  244.     temp = S(5, A) + f(B, C, D) + E + (*p0++ = S(1,temp)) + K; \
  245.     E = D;  \
  246.     D = C;  \
  247.     C = S(30, B); \
  248.     B = A;  \
  249.     A = temp
  250. #endif
  251.  
  252. static void nist_guts(file_flag, stream, mem, length, buf)
  253. int file_flag;                  /* Input from memory, or from stream? */
  254. FILE *stream;
  255. char *mem;
  256. unsigned long length;
  257. unsigned long *buf;
  258. {
  259.     int i, nread, nbits;
  260.     union longbyte d;
  261.     unsigned long hi_length, lo_length;
  262.     int padded;
  263.     char *s;
  264.  
  265.     register unsigned long *p0, *p1, *p2, *p3, *p4;
  266.     unsigned long A, B, C, D, E, temp;
  267.  
  268.     unsigned long h0, h1, h2, h3, h4;
  269.  
  270.     h0 = 0x67452301;                            /* Accumulators */
  271.     h1 = 0xefcdab89;
  272.     h2 = 0x98badcfe;
  273.     h3 = 0x10325476;
  274.     h4 = 0xc3d2e1f0;
  275.  
  276.     padded = FALSE;
  277.     s = mem;
  278.     for (hi_length = lo_length = 0; ;)  /* Process 16 longs at a time */
  279.     {
  280.     if (file_flag)
  281.     {
  282.         nread = fread(d.B, 1, 64, stream);  /* Read as 64 bytes */
  283.     }
  284.     else
  285.     {
  286.         if (length < 64) nread = length;
  287.         else             nread = 64;
  288.         length -= nread;
  289.         memcpy(d.B, s, nread);
  290.         s += nread;
  291.     }
  292.     if (nread < 64)   /* Partial block? */
  293.     {
  294.         nbits = nread << 3;               /* Length: bits */
  295.         if ((lo_length += nbits) < nbits)
  296.             hi_length++;              /* 64-bit integer */
  297.  
  298.         if (nread < 64 && ! padded)  /* Append a single bit */
  299.         {
  300.             d.B[nread++] = 0x80; /* Using up next byte */
  301.             padded = TRUE;       /* Single bit once */
  302.         }
  303.         for (i = nread; i < 64; i++) /* Pad with nulls */
  304.             d.B[i] = 0;
  305.         if (nread <= 56)   /* Room for length in this block */
  306.         {
  307.             d.W[14] = hi_length;
  308.             d.W[15] = lo_length;
  309. #ifdef LITTLE_ENDIAN
  310.           byteReverse(d.W, 56 );
  311. #endif /* LITTLE_ENDIAN */
  312.         }
  313. #ifdef LITTLE_ENDIAN
  314.        else byteReverse(d.W, 64 );
  315. #endif /* LITTLE_ENDIAN */
  316.     }
  317.     else    /* Full block -- get efficient */
  318.     {
  319.         if ((lo_length += 512) < 512)
  320.             hi_length++;    /* 64-bit integer */
  321. #ifdef LITTLE_ENDIAN
  322.        byteReverse(d.W, 64 );
  323. #endif /* LITTLE_ENDIAN */
  324.     }
  325.  
  326.     p0 = d.W;
  327.     A = h0; B = h1; C = h2; D = h3; E = h4;
  328.  
  329.     r0(f0,K0); r0(f0,K0); r0(f0,K0); r0(f0,K0); r0(f0,K0);
  330.     r0(f0,K0); r0(f0,K0); r0(f0,K0); r0(f0,K0); r0(f0,K0);
  331.     r0(f0,K0); r0(f0,K0); r0(f0,K0); r0(f0,K0); r0(f0,K0);
  332.     r0(f0,K0);
  333.  
  334.     p1 = &d.W[13]; p2 = &d.W[8]; p3 = &d.W[2]; p4 = &d.W[0];
  335.  
  336.            r1(f0,K0); r1(f0,K0); r1(f0,K0); r1(f0,K0);
  337.     r1(f1,K1); r1(f1,K1); r1(f1,K1); r1(f1,K1); r1(f1,K1);
  338.     r1(f1,K1); r1(f1,K1); r1(f1,K1); r1(f1,K1); r1(f1,K1);
  339.     r1(f1,K1); r1(f1,K1); r1(f1,K1); r1(f1,K1); r1(f1,K1);
  340.     r1(f1,K1); r1(f1,K1); r1(f1,K1); r1(f1,K1); r1(f1,K1);
  341.     r1(f2,K2); r1(f2,K2); r1(f2,K2); r1(f2,K2); r1(f2,K2);
  342.     r1(f2,K2); r1(f2,K2); r1(f2,K2); r1(f2,K2); r1(f2,K2);
  343.     r1(f2,K2); r1(f2,K2); r1(f2,K2); r1(f2,K2); r1(f2,K2);
  344.     r1(f2,K2); r1(f2,K2); r1(f2,K2); r1(f2,K2); r1(f2,K2);
  345.     r1(f3,K3); r1(f3,K3); r1(f3,K3); r1(f3,K3); r1(f3,K3);
  346.     r1(f3,K3); r1(f3,K3); r1(f3,K3); r1(f3,K3); r1(f3,K3);
  347.     r1(f3,K3); r1(f3,K3); r1(f3,K3); r1(f3,K3); r1(f3,K3);
  348.     r1(f3,K3); r1(f3,K3); r1(f3,K3); r1(f3,K3); r1(f3,K3);
  349.  
  350.     h0 += A; h1 += B; h2 += C; h3 += D; h4 += E;
  351.  
  352.     if (nread <= 56) break; /* If it's greater, length in next block */
  353.     }
  354.     buf[0] = h0; buf[1] = h1; buf[2] = h2; buf[3] = h3; buf[4] = h4;
  355. }
  356.