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>