19b1fd0e5SPoul-Henning Kamp /* 29b1fd0e5SPoul-Henning Kamp * Derived from: 323b5892fSPhilippe Charnier * 49b1fd0e5SPoul-Henning Kamp * MDDRIVER.C - test driver for MD2, MD4 and MD5 5e1645093SPaul Traina */ 6e1645093SPaul Traina 79b1fd0e5SPoul-Henning Kamp /* 89b1fd0e5SPoul-Henning Kamp * Copyright (C) 1990-2, RSA Data Security, Inc. Created 1990. All 99b1fd0e5SPoul-Henning Kamp * rights reserved. 109b1fd0e5SPoul-Henning Kamp * 119b1fd0e5SPoul-Henning Kamp * RSA Data Security, Inc. makes no representations concerning either 129b1fd0e5SPoul-Henning Kamp * the merchantability of this software or the suitability of this 139b1fd0e5SPoul-Henning Kamp * software for any particular purpose. It is provided "as is" 149b1fd0e5SPoul-Henning Kamp * without express or implied warranty of any kind. 159b1fd0e5SPoul-Henning Kamp * 169b1fd0e5SPoul-Henning Kamp * These notices must be retained in any copies of any part of this 179b1fd0e5SPoul-Henning Kamp * documentation and/or software. 18e1645093SPaul Traina */ 19e1645093SPaul Traina 2023b5892fSPhilippe Charnier #ifndef lint 2123b5892fSPhilippe Charnier static const char rcsid[] = 2293606d6eSKris Kennaway "$Id: md5.c,v 1.13 1998/07/06 07:04:50 charnier Exp $"; 2323b5892fSPhilippe Charnier #endif /* not lint */ 24e1645093SPaul Traina 2523b5892fSPhilippe Charnier #include <sys/types.h> 2623b5892fSPhilippe Charnier #include <err.h> 2723b5892fSPhilippe Charnier #include <md5.h> 281ab6205cSBruce Evans #include <stdio.h> 291ab6205cSBruce Evans #include <time.h> 30716847a6SSteve Price #include <unistd.h> 311ab6205cSBruce Evans 321ab6205cSBruce Evans #include "global.h" 331ab6205cSBruce Evans 349b1fd0e5SPoul-Henning Kamp /* 359b1fd0e5SPoul-Henning Kamp * Length of test block, number of test blocks. 36e1645093SPaul Traina */ 3793606d6eSKris Kennaway #define TEST_BLOCK_LEN 10000 3893606d6eSKris Kennaway #define TEST_BLOCK_COUNT 100000 39e1645093SPaul Traina 40e1645093SPaul Traina static void MDString PROTO_LIST((char *)); 41e1645093SPaul Traina static void MDTimeTrial PROTO_LIST((void)); 42e1645093SPaul Traina static void MDTestSuite PROTO_LIST((void)); 4323b406e1SPoul-Henning Kamp static void MDFilter PROTO_LIST((int)); 44716847a6SSteve Price static void usage PROTO_LIST((void)); 45e1645093SPaul Traina 46e1645093SPaul Traina /* Main driver. 47e1645093SPaul Traina 48e1645093SPaul Traina Arguments (may be any combination): 49e1645093SPaul Traina -sstring - digests string 50e1645093SPaul Traina -t - runs time trial 51e1645093SPaul Traina -x - runs test script 52e1645093SPaul Traina filename - digests file 53e1645093SPaul Traina (none) - digests standard input 54e1645093SPaul Traina */ 559b1fd0e5SPoul-Henning Kamp int 569b1fd0e5SPoul-Henning Kamp main(argc, argv) 57e1645093SPaul Traina int argc; 58e1645093SPaul Traina char *argv[]; 59e1645093SPaul Traina { 609a9791afSSteve Price int ch; 619b1fd0e5SPoul-Henning Kamp char *p; 62116805fdSPoul-Henning Kamp char buf[33]; 63e1645093SPaul Traina 64716847a6SSteve Price if (argc > 1) { 659a9791afSSteve Price while ((ch = getopt(argc, argv, "ps:tx")) != -1) { 669a9791afSSteve Price switch (ch) { 67716847a6SSteve Price case 'p': 6823b406e1SPoul-Henning Kamp MDFilter(1); 69716847a6SSteve Price break; 70716847a6SSteve Price case 's': 71716847a6SSteve Price MDString(optarg); 72716847a6SSteve Price break; 73716847a6SSteve Price case 't': 74716847a6SSteve Price MDTimeTrial(); 75716847a6SSteve Price break; 76716847a6SSteve Price case 'x': 77e1645093SPaul Traina MDTestSuite(); 78716847a6SSteve Price break; 79716847a6SSteve Price default: 80716847a6SSteve Price usage(); 819b1fd0e5SPoul-Henning Kamp } 82716847a6SSteve Price } 83716847a6SSteve Price while (optind < argc) { 84716847a6SSteve Price p = MD5File(argv[optind], buf); 85716847a6SSteve Price if (!p) 8623b5892fSPhilippe Charnier warn("%s", argv[optind]); 87e1645093SPaul Traina else 88716847a6SSteve Price printf("MD5 (%s) = %s\n", argv[optind], p); 89716847a6SSteve Price optind++; 90716847a6SSteve Price } 91716847a6SSteve Price } else 9223b406e1SPoul-Henning Kamp MDFilter(0); 93e1645093SPaul Traina 94e1645093SPaul Traina return (0); 95e1645093SPaul Traina } 969b1fd0e5SPoul-Henning Kamp /* 979b1fd0e5SPoul-Henning Kamp * Digests a string and prints the result. 98e1645093SPaul Traina */ 999b1fd0e5SPoul-Henning Kamp static void 1009b1fd0e5SPoul-Henning Kamp MDString(string) 101e1645093SPaul Traina char *string; 102e1645093SPaul Traina { 103e1645093SPaul Traina unsigned int len = strlen(string); 104116805fdSPoul-Henning Kamp char buf[33]; 105e1645093SPaul Traina 106116805fdSPoul-Henning Kamp printf("MD5 (\"%s\") = %s\n", string, MD5Data(string, len, buf)); 107e1645093SPaul Traina } 1089b1fd0e5SPoul-Henning Kamp /* 1099b1fd0e5SPoul-Henning Kamp * Measures the time to digest TEST_BLOCK_COUNT TEST_BLOCK_LEN-byte blocks. 110e1645093SPaul Traina */ 1119b1fd0e5SPoul-Henning Kamp static void 1129b1fd0e5SPoul-Henning Kamp MDTimeTrial() 113e1645093SPaul Traina { 1149b1fd0e5SPoul-Henning Kamp MD5_CTX context; 115e1645093SPaul Traina time_t endTime, startTime; 11623b406e1SPoul-Henning Kamp unsigned char block[TEST_BLOCK_LEN]; 117e1645093SPaul Traina unsigned int i; 118116805fdSPoul-Henning Kamp char *p, buf[33]; 119e1645093SPaul Traina 120e1645093SPaul Traina printf 1219b1fd0e5SPoul-Henning Kamp ("MD5 time trial. Digesting %d %d-byte blocks ...", 1221d0847d3SPoul-Henning Kamp TEST_BLOCK_COUNT, TEST_BLOCK_LEN); 12393606d6eSKris Kennaway fflush(stdout); 124e1645093SPaul Traina 125e1645093SPaul Traina /* Initialize block */ 126e1645093SPaul Traina for (i = 0; i < TEST_BLOCK_LEN; i++) 127e1645093SPaul Traina block[i] = (unsigned char) (i & 0xff); 128e1645093SPaul Traina 129e1645093SPaul Traina /* Start timer */ 130e1645093SPaul Traina time(&startTime); 131e1645093SPaul Traina 132e1645093SPaul Traina /* Digest blocks */ 1339b1fd0e5SPoul-Henning Kamp MD5Init(&context); 134e1645093SPaul Traina for (i = 0; i < TEST_BLOCK_COUNT; i++) 1359b1fd0e5SPoul-Henning Kamp MD5Update(&context, block, TEST_BLOCK_LEN); 136116805fdSPoul-Henning Kamp p = MD5End(&context,buf); 137e1645093SPaul Traina 138e1645093SPaul Traina /* Stop timer */ 139e1645093SPaul Traina time(&endTime); 140e1645093SPaul Traina 141e1645093SPaul Traina printf(" done\n"); 1429b1fd0e5SPoul-Henning Kamp printf("Digest = %s", p); 143e1645093SPaul Traina printf("\nTime = %ld seconds\n", (long) (endTime - startTime)); 1449b1fd0e5SPoul-Henning Kamp /* Be careful that endTime-startTime is not zero. (Bug fix from Ric 1459b1fd0e5SPoul-Henning Kamp * Anderson, ric@Artisoft.COM.) */ 146e1645093SPaul Traina printf 147e1645093SPaul Traina ("Speed = %ld bytes/second\n", 148e1645093SPaul Traina (long) TEST_BLOCK_LEN * (long) TEST_BLOCK_COUNT / ((endTime - startTime) != 0 ? (endTime - startTime) : 1)); 149e1645093SPaul Traina } 1509b1fd0e5SPoul-Henning Kamp /* 1519b1fd0e5SPoul-Henning Kamp * Digests a reference suite of strings and prints the results. 152e1645093SPaul Traina */ 1539b1fd0e5SPoul-Henning Kamp static void 1549b1fd0e5SPoul-Henning Kamp MDTestSuite() 155e1645093SPaul Traina { 1569a9791afSSteve Price 1579b1fd0e5SPoul-Henning Kamp printf("MD5 test suite:\n"); 158e1645093SPaul Traina 159e1645093SPaul Traina MDString(""); 160e1645093SPaul Traina MDString("a"); 161e1645093SPaul Traina MDString("abc"); 162e1645093SPaul Traina MDString("message digest"); 163e1645093SPaul Traina MDString("abcdefghijklmnopqrstuvwxyz"); 164e1645093SPaul Traina MDString 165e1645093SPaul Traina ("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"); 166e1645093SPaul Traina MDString 167e1645093SPaul Traina ("1234567890123456789012345678901234567890\ 168e1645093SPaul Traina 1234567890123456789012345678901234567890"); 169e1645093SPaul Traina } 170e1645093SPaul Traina 1719b1fd0e5SPoul-Henning Kamp /* 1729b1fd0e5SPoul-Henning Kamp * Digests the standard input and prints the result. 173e1645093SPaul Traina */ 1749b1fd0e5SPoul-Henning Kamp static void 1759a9791afSSteve Price MDFilter(pipe) 1769a9791afSSteve Price int pipe; 177e1645093SPaul Traina { 1789b1fd0e5SPoul-Henning Kamp MD5_CTX context; 179e1645093SPaul Traina int len; 180716847a6SSteve Price unsigned char buffer[BUFSIZ]; 181116805fdSPoul-Henning Kamp char buf[33]; 182e1645093SPaul Traina 1839b1fd0e5SPoul-Henning Kamp MD5Init(&context); 184716847a6SSteve Price while ((len = fread(buffer, 1, BUFSIZ, stdin))) { 18523b5892fSPhilippe Charnier if(pipe && (len != fwrite(buffer, 1, len, stdout))) 18623b5892fSPhilippe Charnier err(1, "stdout"); 1879b1fd0e5SPoul-Henning Kamp MD5Update(&context, buffer, len); 18823b406e1SPoul-Henning Kamp } 189116805fdSPoul-Henning Kamp printf("%s\n", MD5End(&context,buf)); 190e1645093SPaul Traina } 191716847a6SSteve Price 192716847a6SSteve Price static void 1939a9791afSSteve Price usage() 194716847a6SSteve Price { 1959a9791afSSteve Price 1969a9791afSSteve Price fprintf(stderr, "usage: md5 [-ptx] [-s string] [files ...]\n"); 197716847a6SSteve Price exit(1); 198716847a6SSteve Price } 199