1 /* MDDRIVER.C - test driver for MD2, MD4 and MD5
2 */
3
4 /*
5 $Id$
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 /* The following makes MD default to MD5 if it has not already been
21 defined with C compiler flags.
22 */
23 #ifndef MD
24 #define MD 5
25 #endif
26
27 #include <stdio.h>
28 #include <time.h>
29 #include <string.h>
30 #include "mdglobal.h"
31 #if MD == 2
32 #include "md2.h"
33 #endif
34 #if MD == 4
35 #include "md4.h"
36 #endif
37 #if MD == 5
38 #include "md5.h"
39 #endif
40
41 /* Length of test block, number of test blocks.
42 */
43 #define TEST_BLOCK_LEN 1000
44 #define TEST_BLOCK_COUNT 1000
45
46 static void MDString PROTO_LIST ((char *));
47 static void MDTimeTrial PROTO_LIST ((void));
48 static void MDTestSuite PROTO_LIST ((void));
49 static void MDFile PROTO_LIST ((char *));
50 static void MDFilter PROTO_LIST ((void));
51 static void MDPrint PROTO_LIST ((unsigned char [16]));
52
53 #if MD == 2
54 #define MD_CTX MD2_CTX
55 #define MDInit MD2Init
56 #define MDUpdate MD2Update
57 #define MDFinal MD2Final
58 #endif
59 #if MD == 4
60 #define MD_CTX MD4_CTX
61 #define MDInit MD4Init
62 #define MDUpdate MD4Update
63 #define MDFinal MD4Final
64 #endif
65 #if MD == 5
66 #define MD_CTX MD5_CTX
67 #define MDInit MD5Init
68 #define MDUpdate MD5Update
69 #define MDFinal MD5Final
70 #endif
71
72 /* Main driver.
73
74 Arguments (may be any combination):
75 -sstring - digests string
76 -t - runs time trial
77 -x - runs test script
78 filename - digests file
79 (none) - digests standard input
80 */
main(argc,argv)81 int main (argc, argv)
82 int argc;
83
84 char *argv[];
85 {
86 int i;
87
88 if (argc > 1)
89 for (i = 1; i < argc; i++)
90 if (argv[i][0] == '-' && argv[i][1] == 's')
91 MDString (argv[i] + 2);
92 else if (strcmp (argv[i], "-t") == 0)
93 MDTimeTrial ();
94 else if (strcmp (argv[i], "-x") == 0)
95 MDTestSuite ();
96 else
97 MDFile (argv[i]);
98 else
99 MDFilter ();
100
101 return (0);
102 }
103
104 /* Digests a string and prints the result.
105 */
MDStringOrig(string)106 static void MDStringOrig (string)
107 char *string;
108 {
109 MD_CTX context;
110 unsigned char digest[16];
111 unsigned int len = strlen (string);
112
113 MDInit (&context);
114 MDUpdate (&context, string, len);
115 MDFinal (digest, &context);
116
117 printf ("MD%d (\"%s\") = ", MD, string);
118 MDPrint (digest);
119 printf ("\n");
120 }
121
MDString(string)122 static void MDString(string)
123 char *string;
124 {
125 char sum[33];
126 checksum_simple(strlen(string), string, sum);
127 printf ("MD%d (\"%s\") = %s\n", MD, string, sum);
128 }
129
130 /* Measures the time to digest TEST_BLOCK_COUNT TEST_BLOCK_LEN-byte
131 blocks.
132 */
MDTimeTrial()133 static void MDTimeTrial ()
134 {
135 MD_CTX context;
136 time_t endTime, startTime;
137 unsigned char block[TEST_BLOCK_LEN], digest[16];
138 unsigned int i;
139
140 printf
141 ("MD%d time trial. Digesting %d %d-byte blocks ...", MD,
142 TEST_BLOCK_LEN, TEST_BLOCK_COUNT);
143
144 /* Initialize block */
145 for (i = 0; i < TEST_BLOCK_LEN; i++)
146 block[i] = (unsigned char)(i & 0xff);
147
148 /* Start timer */
149 time (&startTime);
150
151 /* Digest blocks */
152 MDInit (&context);
153 for (i = 0; i < TEST_BLOCK_COUNT; i++)
154 MDUpdate (&context, block, TEST_BLOCK_LEN);
155 MDFinal (digest, &context);
156
157 /* Stop timer */
158 time (&endTime);
159
160 printf (" done\n");
161 printf ("Digest = ");
162 MDPrint (digest);
163 printf ("\nTime = %ld seconds\n", (long)(endTime-startTime));
164 printf
165 ("Speed = %ld bytes/second\n",
166 (long)TEST_BLOCK_LEN * (long)TEST_BLOCK_COUNT/(endTime-startTime));
167 }
168
169 /* Digests a reference suite of strings and prints the results.
170 */
MDTestSuite()171 static void MDTestSuite ()
172 {
173 printf ("MD%d test suite:\n", MD);
174
175 MDString ("");
176 MDString ("a");
177 MDString ("abc");
178 MDString ("message digest");
179 MDString ("abcdefghijklmnopqrstuvwxyz");
180 MDString
181 ("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789");
182 MDString
183 ("1234567890123456789012345678901234567890\
184 1234567890123456789012345678901234567890");
185 }
186
187 /* Digests a file and prints the result.
188 */
MDFile(filename)189 static void MDFile (filename)
190 char *filename;
191 {
192 FILE *file;
193 MD_CTX context;
194 int len;
195 unsigned char buffer[1024], digest[16];
196
197 if ((file = fopen (filename, "rb")) == NULL)
198 printf ("%s can't be opened\n", filename);
199
200 else {
201 MDInit (&context);
202 while (len = fread (buffer, 1, 1024, file))
203 MDUpdate (&context, buffer, len);
204 MDFinal (digest, &context);
205
206 fclose (file);
207
208 printf ("MD%d (%s) = ", MD, filename);
209 MDPrint (digest);
210 printf ("\n");
211 }
212 }
213
214 /* Digests the standard input and prints the result.
215 */
MDFilter()216 static void MDFilter ()
217 {
218 MD_CTX context;
219 int len;
220 unsigned char buffer[16], digest[16];
221
222 MDInit (&context);
223 while (len = fread (buffer, 1, 16, stdin))
224 MDUpdate (&context, buffer, len);
225 MDFinal (digest, &context);
226
227 MDPrint (digest);
228 printf ("\n");
229 }
230
231 /* Prints a message digest in hexadecimal.
232 */
MDPrint(digest)233 static void MDPrint (digest)
234 unsigned char digest[16];
235 {
236 unsigned int i;
237
238 for (i = 0; i < 16; i++)
239 printf ("%02x", digest[i]);
240 }
241