Source code of Windows XP (NT5)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

314 lines
7.4 KiB

  1. /* MDDRIVER.C - test driver for MD2, MD4 and MD5
  2. */
  3. /* Copyright (C) 1990-2, RSA Data Security, Inc. Created 1990. All
  4. rights reserved.
  5. RSA Data Security, Inc. makes no representations concerning either
  6. the merchantability of this software or the suitability of this
  7. software for any particular purpose. It is provided "as is"
  8. without express or implied warranty of any kind.
  9. These notices must be retained in any copies of any part of this
  10. documentation and/or software.
  11. */
  12. /* The following makes MD default to MD5 if it has not already been
  13. defined with C compiler flags.
  14. */
  15. #ifndef MD
  16. #define MD MD5
  17. #endif
  18. #include <stdio.h>
  19. #include <string.h>
  20. #include <sys/time.h>
  21. #include <sys/resource.h>
  22. #include "global.h"
  23. #if MD == 2
  24. #include "md2.h"
  25. #endif
  26. #if MD == 4
  27. #include "md4.h"
  28. #endif
  29. #if MD == 5
  30. #include "md5.h"
  31. #endif
  32. /* Length of test block, number of test blocks.
  33. */
  34. #define TEST_BLOCK_LEN 1000
  35. #define TEST_BLOCK_COUNT 1000
  36. extern char *calloc();
  37. long test_block_len = TEST_BLOCK_LEN;
  38. long test_block_count = TEST_BLOCK_COUNT;
  39. int skip_init = 0;
  40. int random_init = 0;
  41. int double_block = 0;
  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. #if MD == 2
  49. #define MD_CTX MD2_CTX
  50. #define MDInit MD2Init
  51. #define MDUpdate MD2Update
  52. #define MDFinal MD2Final
  53. #endif
  54. #if MD == 4
  55. #define MD_CTX MD4_CTX
  56. #define MDInit MD4Init
  57. #define MDUpdate MD4Update
  58. #define MDFinal MD4Final
  59. #endif
  60. #if MD == 5
  61. #define MD_CTX MD5_CTX
  62. #define MDInit MD5Init
  63. #define MDUpdate MD5Update
  64. #define MDFinal MD5Final
  65. #endif
  66. /* Main driver.
  67. Arguments (may be any combination):
  68. -sstring - digests string
  69. -t - runs time trial
  70. -x - runs test script
  71. filename - digests file
  72. (none) - digests standard input
  73. Used with -t:
  74. -l - test block length
  75. -c - test block count
  76. -s - skip test init
  77. -r - randomized (pseudo) test initialization
  78. -d - double-buffer the block
  79. (split in half - OK to use with -c; doesn't have cache effects)
  80. */
  81. int main (argc, argv)
  82. int argc;
  83. char *argv[];
  84. {
  85. int i;
  86. if (argc > 1)
  87. for (i = 1; i < argc; i++)
  88. if (argv[i][0] == '-' && argv[i][1] == 's')
  89. MDString (argv[i] + 2);
  90. else if (strcmp (argv[i], "-c") == 0)
  91. test_block_count = atol(argv[++i]);
  92. else if (strcmp (argv[i], "-l") == 0)
  93. test_block_len = atol(argv[++i]);
  94. else if (strcmp (argv[i], "-s") == 0)
  95. skip_init = 1;
  96. else if (strcmp (argv[i], "-r") == 0)
  97. random_init = 1;
  98. else if (strcmp (argv[i], "-d") == 0)
  99. double_block = 1;
  100. else if (strcmp (argv[i], "-t") == 0)
  101. MDTimeTrial ();
  102. else if (strcmp (argv[i], "-x") == 0)
  103. MDTestSuite ();
  104. else
  105. MDFile (argv[i]);
  106. else
  107. MDFilter ();
  108. return (0);
  109. }
  110. /* Digests a string and prints the result.
  111. */
  112. static void MDString (string)
  113. char *string;
  114. {
  115. MD_CTX context;
  116. unsigned char digest[16];
  117. unsigned int len = strlen (string);
  118. MDInit (&context);
  119. MDUpdate (&context, string, len);
  120. MDFinal (digest, &context);
  121. printf ("MD%d (\"%s\") = ", MD, string);
  122. MDPrint (digest);
  123. printf ("\n");
  124. }
  125. /* Measures the time to digest TEST_BLOCK_COUNT TEST_BLOCK_LEN-byte
  126. blocks.
  127. */
  128. static void MDTimeTrial ()
  129. {
  130. MD_CTX context;
  131. unsigned char *block, digest[16];
  132. unsigned char *block2;
  133. unsigned int count;
  134. unsigned int i;
  135. struct timeval randtime;
  136. #if (defined(hpux))
  137. struct timeval starttime;
  138. struct timeval stoptime;
  139. #else
  140. struct rusage starttime;
  141. struct rusage stoptime;
  142. #endif
  143. double usecs,ssecs,tsecs;
  144. block = (unsigned char *)malloc(test_block_len);
  145. block2 = (unsigned char *)malloc(test_block_len);
  146. printf
  147. ("MD%d time trial. Digesting %d %d-byte blocks ...", MD,
  148. test_block_count, test_block_len);
  149. /* Initialize block */
  150. if (!skip_init) {
  151. if (random_init) {
  152. gettimeofday(&randtime,(char *)0);
  153. count = (unsigned int)(randtime.tv_usec);
  154. } else
  155. count = 0;
  156. for (i = 0; i < test_block_len; i++,count++)
  157. block[i] = block2[i] = (unsigned char)(count & 0xff);
  158. }
  159. /* Start timer */
  160. #if (defined(hpux))
  161. gettimeofday(&starttime,(char *)0);
  162. #else
  163. getrusage(RUSAGE_SELF,&starttime);
  164. #endif
  165. /* Digest blocks */
  166. MDInit (&context);
  167. if (double_block)
  168. for (i = 0; i < test_block_count/2; i++) {
  169. MDUpdate (&context, block, test_block_len);
  170. MDUpdate (&context, block2, test_block_len);
  171. }
  172. else {
  173. for (i = 0; i < test_block_count; i++)
  174. MDUpdate (&context, block, test_block_len);
  175. }
  176. MDFinal (digest, &context);
  177. /* Stop timer */
  178. #if (defined(hpux))
  179. gettimeofday(&stoptime,(char *)0);
  180. tsecs = stoptime.tv_sec - starttime.tv_sec;
  181. tsecs += (stoptime.tv_usec - starttime.tv_usec) * 1e-6;
  182. usecs = 0;
  183. ssecs = 0;
  184. #else
  185. getrusage(RUSAGE_SELF,&stoptime);
  186. usecs = stoptime.ru_utime.tv_sec - starttime.ru_utime.tv_sec;
  187. usecs += (stoptime.ru_utime.tv_usec - starttime.ru_utime.tv_usec) * 1e-6;
  188. ssecs = stoptime.ru_stime.tv_sec - starttime.ru_stime.tv_sec;
  189. ssecs += (stoptime.ru_stime.tv_usec - starttime.ru_stime.tv_usec) * 1e-6;
  190. tsecs = usecs + ssecs;
  191. #endif
  192. printf (" done\n");
  193. printf ("Digest = ");
  194. MDPrint (digest);
  195. printf ("\nTime = %g U : %g S :: %g seconds\n", usecs,ssecs,tsecs);
  196. /*
  197. * Be careful that endTime-startTime is not zero.
  198. * (Bug fix from Ric Anderson, ric@Artisoft.COM.)
  199. */
  200. printf
  201. ("Speed = %g bytes/second, %g bits/sec\n",
  202. (long)test_block_len * (long)test_block_count/((tsecs != 0) ? tsecs : 1),
  203. 8 * (long)test_block_len * (long)test_block_count/((tsecs != 0) ? tsecs : 1));
  204. printf("minflt %d majflt %d nswap %d nvcsw %d nivcsw %d\n",
  205. #if (!defined(hpux))
  206. stoptime.ru_minflt - starttime.ru_minflt,
  207. stoptime.ru_majflt - starttime.ru_majflt,
  208. stoptime.ru_nswap - starttime.ru_nswap,
  209. stoptime.ru_nvcsw - starttime.ru_nvcsw,
  210. stoptime.ru_nivcsw - starttime.ru_nivcsw
  211. #else
  212. -1,-1,-1,-1,-1
  213. #endif
  214. );
  215. }
  216. /* Digests a reference suite of strings and prints the results.
  217. */
  218. static void MDTestSuite ()
  219. {
  220. printf ("MD%d test suite:\n", MD);
  221. MDString ("");
  222. MDString ("a");
  223. MDString ("abc");
  224. MDString ("message digest");
  225. MDString ("abcdefghijklmnopqrstuvwxyz");
  226. MDString
  227. ("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789");
  228. MDString
  229. ("1234567890123456789012345678901234567890\
  230. 1234567890123456789012345678901234567890");
  231. }
  232. /* Digests a file and prints the result.
  233. */
  234. static void MDFile (filename)
  235. char *filename;
  236. {
  237. FILE *file;
  238. MD_CTX context;
  239. int len;
  240. unsigned char buffer[1024], digest[16];
  241. if ((file = fopen (filename, "rb")) == NULL)
  242. printf ("%s can't be opened\n", filename);
  243. else {
  244. MDInit (&context);
  245. while (len = fread (buffer, 1, 1024, file))
  246. MDUpdate (&context, buffer, len);
  247. MDFinal (digest, &context);
  248. fclose (file);
  249. printf ("MD%d (%s) = ", MD, filename);
  250. MDPrint (digest);
  251. printf ("\n");
  252. }
  253. }
  254. /* Digests the standard input and prints the result.
  255. */
  256. static void MDFilter ()
  257. {
  258. MD_CTX context;
  259. int len;
  260. unsigned char buffer[16], digest[16];
  261. MDInit (&context);
  262. while (len = fread (buffer, 1, 16, stdin))
  263. MDUpdate (&context, buffer, len);
  264. MDFinal (digest, &context);
  265. MDPrint (digest);
  266. printf ("\n");
  267. }
  268. /* Prints a message digest in hexadecimal.
  269. */
  270. static void MDPrint (digest)
  271. unsigned char digest[16];
  272. {
  273. unsigned int i;
  274. for (i = 0; i < 16; i++)
  275. printf ("%02x", digest[i]);
  276. }