xref: /freebsd/sbin/md5/md5.c (revision a1a4f1a0d87b594d3f17a97dc0127eec1417e6f6)
1 /*
2  * Derived from:
3  *
4  * MDDRIVER.C - test driver for MD2, MD4 and MD5
5  */
6 
7 /*
8  *  Copyright (C) 1990-2, RSA Data Security, Inc. Created 1990. All
9  *  rights reserved.
10  *
11  *  RSA Data Security, Inc. makes no representations concerning either
12  *  the merchantability of this software or the suitability of this
13  *  software for any particular purpose. It is provided "as is"
14  *  without express or implied warranty of any kind.
15  *
16  *  These notices must be retained in any copies of any part of this
17  *  documentation and/or software.
18  */
19 
20 #ifndef lint
21 static const char rcsid[] =
22   "$FreeBSD$";
23 #endif /* not lint */
24 
25 #include <sys/types.h>
26 #include <err.h>
27 #include <md5.h>
28 #include <stdio.h>
29 #include <time.h>
30 #include <unistd.h>
31 #include <string.h>
32 
33 #include "global.h"
34 
35 /*
36  * Length of test block, number of test blocks.
37  */
38 #define TEST_BLOCK_LEN 10000
39 #define TEST_BLOCK_COUNT 100000
40 
41 static void MDString PROTO_LIST((char *));
42 static void MDTimeTrial PROTO_LIST((void));
43 static void MDTestSuite PROTO_LIST((void));
44 static void MDFilter PROTO_LIST((int));
45 static void usage PROTO_LIST((void));
46 
47 /* Main driver.
48 
49 Arguments (may be any combination):
50   -sstring - digests string
51   -t       - runs time trial
52   -x       - runs test script
53   filename - digests file
54   (none)   - digests standard input
55  */
56 int
57 main(argc, argv)
58 	int     argc;
59 	char   *argv[];
60 {
61 	int     ch;
62 	char   *p;
63 	char	buf[33];
64 
65 	if (argc > 1) {
66 		while ((ch = getopt(argc, argv, "ps:tx")) != -1) {
67 			switch (ch) {
68 			case 'p':
69 				MDFilter(1);
70 				break;
71 			case 's':
72 				MDString(optarg);
73 				break;
74 			case 't':
75 				MDTimeTrial();
76 				break;
77 			case 'x':
78 				MDTestSuite();
79 				break;
80 			default:
81 				usage();
82 			}
83 		}
84 		while (optind < argc) {
85 			p = MD5File(argv[optind], buf);
86 			if (!p)
87 				warn("%s", argv[optind]);
88 			else
89 				printf("MD5 (%s) = %s\n", argv[optind], p);
90 			optind++;
91 		}
92 	} else
93 		MDFilter(0);
94 
95 	return (0);
96 }
97 /*
98  * Digests a string and prints the result.
99  */
100 static void
101 MDString(string)
102 	char   *string;
103 {
104 	size_t len = strlen(string);
105 	char buf[33];
106 
107 	printf("MD5 (\"%s\") = %s\n", string, MD5Data(string, len, buf));
108 }
109 /*
110  * Measures the time to digest TEST_BLOCK_COUNT TEST_BLOCK_LEN-byte blocks.
111  */
112 static void
113 MDTimeTrial()
114 {
115 	MD5_CTX context;
116 	time_t  endTime, startTime;
117 	unsigned char block[TEST_BLOCK_LEN];
118 	unsigned int i;
119 	char   *p, buf[33];
120 
121 	printf
122 	    ("MD5 time trial. Digesting %d %d-byte blocks ...",
123 	    TEST_BLOCK_COUNT, TEST_BLOCK_LEN);
124 	fflush(stdout);
125 
126 	/* Initialize block */
127 	for (i = 0; i < TEST_BLOCK_LEN; i++)
128 		block[i] = (unsigned char) (i & 0xff);
129 
130 	/* Start timer */
131 	time(&startTime);
132 
133 	/* Digest blocks */
134 	MD5Init(&context);
135 	for (i = 0; i < TEST_BLOCK_COUNT; i++)
136 		MD5Update(&context, block, TEST_BLOCK_LEN);
137 	p = MD5End(&context,buf);
138 
139 	/* Stop timer */
140 	time(&endTime);
141 
142 	printf(" done\n");
143 	printf("Digest = %s", p);
144 	printf("\nTime = %ld seconds\n", (long) (endTime - startTime));
145 	/* Be careful that endTime-startTime is not zero. (Bug fix from Ric
146 	 * Anderson, ric@Artisoft.COM.) */
147 	printf
148 	    ("Speed = %ld bytes/second\n",
149 	    (long) TEST_BLOCK_LEN * (long) TEST_BLOCK_COUNT / ((endTime - startTime) != 0 ? (endTime - startTime) : 1));
150 }
151 /*
152  * Digests a reference suite of strings and prints the results.
153  */
154 static void
155 MDTestSuite()
156 {
157 
158 	printf("MD5 test suite:\n");
159 
160 	MDString("");
161 	MDString("a");
162 	MDString("abc");
163 	MDString("message digest");
164 	MDString("abcdefghijklmnopqrstuvwxyz");
165 	MDString
166 	    ("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789");
167 	MDString
168 	    ("1234567890123456789012345678901234567890\
169 1234567890123456789012345678901234567890");
170 }
171 
172 /*
173  * Digests the standard input and prints the result.
174  */
175 static void
176 MDFilter(pipe)
177 	int pipe;
178 {
179 	MD5_CTX context;
180 	int     len;
181 	unsigned char buffer[BUFSIZ];
182 	char buf[33];
183 
184 	MD5Init(&context);
185 	while ((len = fread(buffer, 1, BUFSIZ, stdin))) {
186 		if(pipe && (len != fwrite(buffer, 1, len, stdout)))
187 			err(1, "stdout");
188 		MD5Update(&context, buffer, len);
189 	}
190 	printf("%s\n", MD5End(&context,buf));
191 }
192 
193 static void
194 usage()
195 {
196 
197 	fprintf(stderr, "usage: md5 [-ptx] [-s string] [files ...]\n");
198 	exit(1);
199 }
200