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