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