mddriver.c 5.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258
  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 <time.h>
  20. #include <string.h>
  21. #include <sys/types.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. static void MDString PROTO_LIST ((char *));
  37. static void MDTimeTrial PROTO_LIST ((void));
  38. static void MDTestSuite PROTO_LIST ((void));
  39. static void MDFile PROTO_LIST ((char *));
  40. static void MDFilter PROTO_LIST ((void));
  41. static void MDPrint PROTO_LIST ((unsigned char[16]));
  42. #if MD == 2
  43. #define MD_CTX MD2_CTX
  44. #define MDInit MD2Init
  45. #define MDUpdate MD2Update
  46. #define MDFinal MD2Final
  47. #endif
  48. #if MD == 4
  49. #define MD_CTX MD4_CTX
  50. #define MDInit MD4Init
  51. #define MDUpdate MD4Update
  52. #define MDFinal MD4Final
  53. #endif
  54. #if MD == 5
  55. #define MD_CTX MD5_CTX
  56. #define MDInit MD5Init
  57. #define MDUpdate MD5Update
  58. #define MDFinal MD5Final
  59. #endif
  60. /* Main driver.
  61. Arguments (may be any combination):
  62. -sstring - digests string
  63. -t - runs time trial
  64. -x - runs test script
  65. -b - print MD5 sum in binary on stdout
  66. filename - digests file
  67. (none) - digests standard input
  68. */
  69. short bflag = 0; /* 1 == print sums in binary */
  70. int
  71. main (argc, argv)
  72. int argc;
  73. char *argv[];
  74. {
  75. int i;
  76. if (argc > 1)
  77. for (i = 1; i < argc; i++)
  78. if (argv[i][0] == '-' && argv[i][1] == 's')
  79. MDString (argv[i] + 2);
  80. else if (strcmp (argv[i], "-t") == 0)
  81. MDTimeTrial ();
  82. else if (strcmp (argv[i], "-x") == 0)
  83. MDTestSuite ();
  84. else if (strcmp (argv[i], "-b") == 0)
  85. bflag = 1;
  86. else
  87. MDFile (argv[i]);
  88. else
  89. MDFilter ();
  90. return (0);
  91. }
  92. /* Digests a string and prints the result.
  93. */
  94. static void
  95. MDString (string)
  96. char *string;
  97. {
  98. MD_CTX context;
  99. unsigned char digest[16];
  100. unsigned int len = strlen (string);
  101. MDInit (&context);
  102. MDUpdate (&context, string, len);
  103. MDFinal (digest, &context);
  104. // if (!bflag) printf ("%s",string);
  105. MDPrint (digest);
  106. if (!bflag)
  107. printf ("\n");
  108. }
  109. /* Measures the time to digest TEST_BLOCK_COUNT TEST_BLOCK_LEN-byte
  110. blocks.
  111. */
  112. static void
  113. MDTimeTrial ()
  114. {
  115. MD_CTX context;
  116. time_t endTime, startTime;
  117. unsigned char block[TEST_BLOCK_LEN], digest[16];
  118. unsigned int i;
  119. printf
  120. ("MD%d time trial. Digesting %d %d-byte blocks ...", MD,
  121. TEST_BLOCK_LEN, TEST_BLOCK_COUNT);
  122. /* Initialize block */
  123. for (i = 0; i < TEST_BLOCK_LEN; i++)
  124. block[i] = (unsigned char) (i & 0xff);
  125. /* Start timer */
  126. time (&startTime);
  127. /* Digest blocks */
  128. MDInit (&context);
  129. for (i = 0; i < TEST_BLOCK_COUNT; i++)
  130. MDUpdate (&context, block, TEST_BLOCK_LEN);
  131. MDFinal (digest, &context);
  132. /* Stop timer */
  133. time (&endTime);
  134. printf (" done\n");
  135. printf ("Digest = ");
  136. MDPrint (digest);
  137. printf ("\nTime = %d seconds\n", (time_t) (endTime - startTime));
  138. /*
  139. * Be careful that endTime-startTime is not zero.
  140. * (Bug fix from Ric Anderson, ric@Artisoft.COM.)
  141. */
  142. printf
  143. ("Speed = %d bytes/second\n",
  144. (time_t) TEST_BLOCK_LEN * (time_t) TEST_BLOCK_COUNT /
  145. ((endTime - startTime) != 0 ? (endTime - startTime) : 1));
  146. }
  147. /* Digests a reference suite of strings and prints the results.
  148. */
  149. static void
  150. MDTestSuite ()
  151. {
  152. printf ("MD%d test suite:\n", MD);
  153. MDString ("");
  154. MDString ("a");
  155. MDString ("abc");
  156. MDString ("message digest");
  157. MDString ("abcdefghijklmnopqrstuvwxyz");
  158. MDString ("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789");
  159. MDString ("1234567890123456789012345678901234567890\
  160. 1234567890123456789012345678901234567890");
  161. }
  162. /* Digests a file and prints the result.
  163. */
  164. static void
  165. MDFile (filename)
  166. char *filename;
  167. {
  168. FILE *file;
  169. MD_CTX context;
  170. int len;
  171. unsigned char buffer[1024], digest[16];
  172. if ((file = fopen (filename, "rb")) == NULL)
  173. printf ("%s can't be opened\n", filename);
  174. else
  175. {
  176. MDInit (&context);
  177. while (len = fread (buffer, 1, 1024, file))
  178. MDUpdate (&context, buffer, len);
  179. MDFinal (digest, &context);
  180. fclose (file);
  181. if (!bflag)
  182. printf ("MD%d (%s) = ", MD, filename);
  183. MDPrint (digest);
  184. if (!bflag)
  185. printf ("\n");
  186. }
  187. }
  188. /* Digests the standard input and prints the result.
  189. */
  190. static void
  191. MDFilter ()
  192. {
  193. MD_CTX context;
  194. int len;
  195. unsigned char buffer[16], digest[16];
  196. MDInit (&context);
  197. while (len = fread (buffer, 1, 16, stdin))
  198. MDUpdate (&context, buffer, len);
  199. MDFinal (digest, &context);
  200. MDPrint (digest);
  201. if (!bflag)
  202. printf ("\n");
  203. }
  204. /* Prints a message digest in hexadecimal or binary.
  205. */
  206. static void
  207. MDPrint (digest)
  208. unsigned char digest[16];
  209. {
  210. unsigned int i;
  211. if (bflag)
  212. {
  213. /* print in binary */
  214. write (1, &digest[0], 16);
  215. }
  216. else
  217. {
  218. /* print in hex */
  219. for (i = 0; i < 16; i++)
  220. printf ("%02x", digest[i]);
  221. }
  222. }