Annotation of OpenXM_contrib2/asir2018/builtin/sha1.c, Revision 1.1
1.1 ! 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
! 26: * e-mail at risa-admin@sec.flab.fujitsu.co.jp of the detailed specification
! 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: *
! 48: * $OpenXM$
! 49: */
! 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);
! 166: return FALSE;
! 167: }
! 168: else /* Process a file */
! 169: {
! 170: if (verbose) printf("%s:", *argv);
! 171: file_args = TRUE; /* Whether or not we could read it */
! 172:
! 173: if (sha_file(*argv, hbuf) == FAILURE)
! 174: printf("Can't open file %s.\n", *argv);
! 175: else
! 176: if (terse) printf("%08lx%08lx%08lx%08lx%08lx\n",
! 177: hbuf[0], hbuf[1], hbuf[2], hbuf[3], hbuf[4]);
! 178: else printf("%08lx %08lx %08lx %08lx %08lx\n",
! 179: hbuf[0], hbuf[1], hbuf[2], hbuf[3], hbuf[4]);
! 180: }
! 181: }
! 182: if (! file_args) /* No file specified */
! 183: {
! 184: if (verbose) printf("%s:", *argv);
! 185: sha_stream(stdin, hbuf);
! 186:
! 187: if (terse) printf("%08lx%08lx%08lx%08lx%08lx\n",
! 188: hbuf[0], hbuf[1], hbuf[2], hbuf[3], hbuf[4]);
! 189: else printf("%08lx %08lx %08lx %08lx %08lx\n",
! 190: hbuf[0], hbuf[1], hbuf[2], hbuf[3], hbuf[4]);
! 191: }
! 192: return TRUE;
! 193: }
! 194:
! 195: #endif
! 196:
! 197: /* #ifdef LITTLE_ENDIAN */ /* Imported from Peter Gutmann's implementation */
! 198:
! 199: /* When run on a little-endian CPU we need to perform byte reversal on an
! 200: array of intwords. It is possible to make the code endianness-
! 201: independant by fiddling around with data at the byte level, but this
! 202: makes for very slow code, so we rely on the user to sort out endianness
! 203: at compile time */
! 204:
! 205: static void byteReverse( unsigned int *buffer, int byteCount )
! 206: {
! 207: unsigned int value;
! 208: int count;
! 209: extern int little_endian;
! 210:
! 211: if ( !little_endian )
! 212: return;
! 213:
! 214: byteCount /= sizeof( unsigned int );
! 215: for( count = 0; count < byteCount; count++ )
! 216: {
! 217: value = ( buffer[ count ] << 16 ) | ( buffer[ count ] >> 16 );
! 218: buffer[ count ] = ( ( value & 0xFF00FF00L ) >> 8 ) | ( ( value & 0x00FF00FFL ) << 8 );
! 219: }
! 220: }
! 221: /* #endif */ /* LITTLE_ENDIAN */
! 222:
! 223: union intbyte
! 224: {
! 225: unsigned int W[80]; /* Process 16 32-bit words at a time */
! 226: char B[320]; /* But read them as bytes for counting */
! 227: };
! 228:
! 229: int sha_file(char* filename, unsigned int *buffer) /* Hash a file */
! 230: {
! 231: FILE *infile;
! 232:
! 233: if ((infile = fopen(filename, "rb")) == NULL)
! 234: {
! 235: int i;
! 236:
! 237: for (i = 0; i < 5; i++)
! 238: buffer[i] = 0xdeadbeef;
! 239: return FAILURE;
! 240: }
! 241: (void) sha_stream(infile, buffer);
! 242: fclose(infile);
! 243: return SUCCESS;
! 244: }
! 245:
! 246: void sha_memory(char *mem, unsigned int length, unsigned int *buffer)
! 247: {
! 248: nist_guts(FALSE, (FILE *) NULL, mem, length, buffer);
! 249: }
! 250:
! 251: void sha_stream(FILE *stream, unsigned int *buffer)
! 252: {
! 253: nist_guts(TRUE, stream, (char *) NULL, 0l, buffer);
! 254: }
! 255:
! 256: #define f0(x,y,z) (z ^ (x & (y ^ z))) /* Magic functions */
! 257: #define f1(x,y,z) (x ^ y ^ z)
! 258: #define f2(x,y,z) ((x & y) | (z & (x | y)))
! 259: #define f3(x,y,z) (x ^ y ^ z)
! 260:
! 261: #define K0 0x5a827999 /* Magic constants */
! 262: #define K1 0x6ed9eba1
! 263: #define K2 0x8f1bbcdc
! 264: #define K3 0xca62c1d6
! 265:
! 266: #define S(n, X) ((X << n) | (X >> (32 - n))) /* Barrel roll */
! 267:
! 268: #define r0(f, K) \
! 269: temp = S(5, A) + f(B, C, D) + E + *p0++ + K; \
! 270: E = D; \
! 271: D = C; \
! 272: C = S(30, B); \
! 273: B = A; \
! 274: A = temp
! 275:
! 276: #ifdef VERSION_0
! 277: #define r1(f, K) \
! 278: temp = S(5, A) + f(B, C, D) + E + \
! 279: (*p0++ = *p1++ ^ *p2++ ^ *p3++ ^ *p4++) + K; \
! 280: E = D; \
! 281: D = C; \
! 282: C = S(30, B); \
! 283: B = A; \
! 284: A = temp
! 285: #else /* Version 1: Summer '94 update */
! 286: #define r1(f, K) \
! 287: temp = *p1++ ^ *p2++ ^ *p3++ ^ *p4++; \
! 288: temp = S(5, A) + f(B, C, D) + E + (*p0++ = S(1,temp)) + K; \
! 289: E = D; \
! 290: D = C; \
! 291: C = S(30, B); \
! 292: B = A; \
! 293: A = temp
! 294: #endif
! 295:
! 296: static void nist_guts(int file_flag, /* Input from memory, or from stream? */
! 297: FILE *stream,
! 298: char *mem,
! 299: unsigned int length,
! 300: unsigned int *buf)
! 301: {
! 302: int i, nread, nbits;
! 303: union intbyte d;
! 304: unsigned int hi_length, lo_length;
! 305: int padded;
! 306: char *s;
! 307:
! 308: register unsigned int *p0, *p1, *p2, *p3, *p4;
! 309: unsigned int A, B, C, D, E, temp;
! 310:
! 311: unsigned int h0, h1, h2, h3, h4;
! 312:
! 313: h0 = 0x67452301; /* Accumulators */
! 314: h1 = 0xefcdab89;
! 315: h2 = 0x98badcfe;
! 316: h3 = 0x10325476;
! 317: h4 = 0xc3d2e1f0;
! 318:
! 319: padded = FALSE;
! 320: s = mem;
! 321: for (hi_length = lo_length = 0; ;) /* Process 16 ints at a time */
! 322: {
! 323: if (file_flag)
! 324: {
! 325: nread = fread(d.B, 1, 64, stream); /* Read as 64 bytes */
! 326: }
! 327: else
! 328: {
! 329: if (length < 64) nread = length;
! 330: else nread = 64;
! 331: length -= nread;
! 332: memcpy(d.B, s, nread);
! 333: s += nread;
! 334: }
! 335: if (nread < 64) /* Partial block? */
! 336: {
! 337: nbits = nread << 3; /* Length: bits */
! 338: if ((int)(lo_length += nbits) < nbits)
! 339: hi_length++; /* 64-bit integer */
! 340:
! 341: if (nread < 64 && ! padded) /* Append a single bit */
! 342: {
! 343: d.B[nread++] = (char)0x80; /* Using up next byte */
! 344: padded = TRUE; /* Single bit once */
! 345: }
! 346: for (i = nread; i < 64; i++) /* Pad with nulls */
! 347: d.B[i] = 0;
! 348: if (nread <= 56) /* Room for length in this block */
! 349: {
! 350: d.W[14] = hi_length;
! 351: d.W[15] = lo_length;
! 352: /* #ifdef LITTLE_ENDIAN */
! 353: byteReverse(d.W, 56 );
! 354: /* #endif */ /* LITTLE_ENDIAN */
! 355: }
! 356: /* #ifdef LITTLE_ENDIAN */
! 357: else
! 358: byteReverse(d.W, 64 );
! 359: /* #endif */ /* LITTLE_ENDIAN */
! 360: }
! 361: else /* Full block -- get efficient */
! 362: {
! 363: if ((lo_length += 512) < 512)
! 364: hi_length++; /* 64-bit integer */
! 365: /* #ifdef LITTLE_ENDIAN */
! 366: byteReverse(d.W, 64 );
! 367: /* #endif */ /* LITTLE_ENDIAN */
! 368: }
! 369:
! 370: p0 = d.W;
! 371: A = h0; B = h1; C = h2; D = h3; E = h4;
! 372:
! 373: r0(f0,K0); r0(f0,K0); r0(f0,K0); r0(f0,K0); r0(f0,K0);
! 374: r0(f0,K0); r0(f0,K0); r0(f0,K0); r0(f0,K0); r0(f0,K0);
! 375: r0(f0,K0); r0(f0,K0); r0(f0,K0); r0(f0,K0); r0(f0,K0);
! 376: r0(f0,K0);
! 377:
! 378: p1 = &d.W[13]; p2 = &d.W[8]; p3 = &d.W[2]; p4 = &d.W[0];
! 379:
! 380: r1(f0,K0); r1(f0,K0); r1(f0,K0); r1(f0,K0);
! 381: r1(f1,K1); r1(f1,K1); r1(f1,K1); r1(f1,K1); r1(f1,K1);
! 382: r1(f1,K1); r1(f1,K1); r1(f1,K1); r1(f1,K1); r1(f1,K1);
! 383: r1(f1,K1); r1(f1,K1); r1(f1,K1); r1(f1,K1); r1(f1,K1);
! 384: r1(f1,K1); r1(f1,K1); r1(f1,K1); r1(f1,K1); r1(f1,K1);
! 385: r1(f2,K2); r1(f2,K2); r1(f2,K2); r1(f2,K2); r1(f2,K2);
! 386: r1(f2,K2); r1(f2,K2); r1(f2,K2); r1(f2,K2); r1(f2,K2);
! 387: r1(f2,K2); r1(f2,K2); r1(f2,K2); r1(f2,K2); r1(f2,K2);
! 388: r1(f2,K2); r1(f2,K2); r1(f2,K2); r1(f2,K2); r1(f2,K2);
! 389: r1(f3,K3); r1(f3,K3); r1(f3,K3); r1(f3,K3); r1(f3,K3);
! 390: r1(f3,K3); r1(f3,K3); r1(f3,K3); r1(f3,K3); r1(f3,K3);
! 391: r1(f3,K3); r1(f3,K3); r1(f3,K3); r1(f3,K3); r1(f3,K3);
! 392: r1(f3,K3); r1(f3,K3); r1(f3,K3); r1(f3,K3); r1(f3,K3);
! 393:
! 394: h0 += A; h1 += B; h2 += C; h3 += D; h4 += E;
! 395:
! 396: if (nread <= 56) break; /* If it's greater, length in next block */
! 397: }
! 398: buf[0] = h0; buf[1] = h1; buf[2] = h2; buf[3] = h3; buf[4] = h4;
! 399: }
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>