1 /* 2 * Derived from: 3 * 4 * MDDRIVER.C - test driver for MD2, MD4 and MD5 5 */ 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 #ifndef lint 21 static const char rcsid[] = 22 "$FreeBSD$"; 23 #endif /* not lint */ 24 25 #include <sys/types.h> 26 #include <err.h> 27 #include <md5.h> 28 #include <stdio.h> 29 #include <time.h> 30 #include <unistd.h> 31 #include <string.h> 32 33 #include "global.h" 34 35 /* 36 * Length of test block, number of test blocks. 37 */ 38 #define TEST_BLOCK_LEN 10000 39 #define TEST_BLOCK_COUNT 100000 40 41 static void MDString PROTO_LIST((char *)); 42 static void MDTimeTrial PROTO_LIST((void)); 43 static void MDTestSuite PROTO_LIST((void)); 44 static void MDFilter PROTO_LIST((int)); 45 static void usage PROTO_LIST((void)); 46 47 /* Main driver. 48 49 Arguments (may be any combination): 50 -sstring - digests string 51 -t - runs time trial 52 -x - runs test script 53 filename - digests file 54 (none) - digests standard input 55 */ 56 int 57 main(argc, argv) 58 int argc; 59 char *argv[]; 60 { 61 int ch; 62 char *p; 63 char buf[33]; 64 65 if (argc > 1) { 66 while ((ch = getopt(argc, argv, "ps:tx")) != -1) { 67 switch (ch) { 68 case 'p': 69 MDFilter(1); 70 break; 71 case 's': 72 MDString(optarg); 73 break; 74 case 't': 75 MDTimeTrial(); 76 break; 77 case 'x': 78 MDTestSuite(); 79 break; 80 default: 81 usage(); 82 } 83 } 84 while (optind < argc) { 85 p = MD5File(argv[optind], buf); 86 if (!p) 87 warn("%s", argv[optind]); 88 else 89 printf("MD5 (%s) = %s\n", argv[optind], p); 90 optind++; 91 } 92 } else 93 MDFilter(0); 94 95 return (0); 96 } 97 /* 98 * Digests a string and prints the result. 99 */ 100 static void 101 MDString(string) 102 char *string; 103 { 104 size_t len = strlen(string); 105 char buf[33]; 106 107 printf("MD5 (\"%s\") = %s\n", string, MD5Data(string, len, buf)); 108 } 109 /* 110 * Measures the time to digest TEST_BLOCK_COUNT TEST_BLOCK_LEN-byte blocks. 111 */ 112 static void 113 MDTimeTrial() 114 { 115 MD5_CTX context; 116 time_t endTime, startTime; 117 unsigned char block[TEST_BLOCK_LEN]; 118 unsigned int i; 119 char *p, buf[33]; 120 121 printf 122 ("MD5 time trial. Digesting %d %d-byte blocks ...", 123 TEST_BLOCK_COUNT, TEST_BLOCK_LEN); 124 fflush(stdout); 125 126 /* Initialize block */ 127 for (i = 0; i < TEST_BLOCK_LEN; i++) 128 block[i] = (unsigned char) (i & 0xff); 129 130 /* Start timer */ 131 time(&startTime); 132 133 /* Digest blocks */ 134 MD5Init(&context); 135 for (i = 0; i < TEST_BLOCK_COUNT; i++) 136 MD5Update(&context, block, TEST_BLOCK_LEN); 137 p = MD5End(&context,buf); 138 139 /* Stop timer */ 140 time(&endTime); 141 142 printf(" done\n"); 143 printf("Digest = %s", p); 144 printf("\nTime = %ld seconds\n", (long) (endTime - startTime)); 145 /* Be careful that endTime-startTime is not zero. (Bug fix from Ric 146 * Anderson, ric@Artisoft.COM.) */ 147 printf 148 ("Speed = %ld bytes/second\n", 149 (long) TEST_BLOCK_LEN * (long) TEST_BLOCK_COUNT / ((endTime - startTime) != 0 ? (endTime - startTime) : 1)); 150 } 151 /* 152 * Digests a reference suite of strings and prints the results. 153 */ 154 static void 155 MDTestSuite() 156 { 157 158 printf("MD5 test suite:\n"); 159 160 MDString(""); 161 MDString("a"); 162 MDString("abc"); 163 MDString("message digest"); 164 MDString("abcdefghijklmnopqrstuvwxyz"); 165 MDString 166 ("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"); 167 MDString 168 ("1234567890123456789012345678901234567890\ 169 1234567890123456789012345678901234567890"); 170 } 171 172 /* 173 * Digests the standard input and prints the result. 174 */ 175 static void 176 MDFilter(pipe) 177 int pipe; 178 { 179 MD5_CTX context; 180 int len; 181 unsigned char buffer[BUFSIZ]; 182 char buf[33]; 183 184 MD5Init(&context); 185 while ((len = fread(buffer, 1, BUFSIZ, stdin))) { 186 if(pipe && (len != fwrite(buffer, 1, len, stdout))) 187 err(1, "stdout"); 188 MD5Update(&context, buffer, len); 189 } 190 printf("%s\n", MD5End(&context,buf)); 191 } 192 193 static void 194 usage() 195 { 196 197 fprintf(stderr, "usage: md5 [-ptx] [-s string] [files ...]\n"); 198 exit(1); 199 } 200