Annotation of OpenXM_contrib2/asir2000/builtin/sha1.c, Revision 1.4
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.4 ! noro 48: * $OpenXM: OpenXM_contrib2/asir2000/builtin/sha1.c,v 1.3 2000/08/22 05:04:00 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);
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 ONT_WRAP
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 */
1.4 ! noro 338: if ((int)(lo_length += nbits) < nbits)
1.1 noro 339: hi_length++; /* 64-bit integer */
340:
341: if (nread < 64 && ! padded) /* Append a single bit */
342: {
1.4 ! noro 343: d.B[nread++] = (char)0x80; /* Using up next byte */
1.1 noro 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>