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