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[] = 22b76bf6fcSBill Fumerola "$Id: md5.c,v 1.14 1999/05/01 14:54:21 kris 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> 31b76bf6fcSBill Fumerola #include <string.h> 321ab6205cSBruce Evans 331ab6205cSBruce Evans #include "global.h" 341ab6205cSBruce Evans 359b1fd0e5SPoul-Henning Kamp /* 369b1fd0e5SPoul-Henning Kamp * Length of test block, number of test blocks. 37e1645093SPaul Traina */ 3893606d6eSKris Kennaway #define TEST_BLOCK_LEN 10000 3993606d6eSKris Kennaway #define TEST_BLOCK_COUNT 100000 40e1645093SPaul Traina 41e1645093SPaul Traina static void MDString PROTO_LIST((char *)); 42e1645093SPaul Traina static void MDTimeTrial PROTO_LIST((void)); 43e1645093SPaul Traina static void MDTestSuite PROTO_LIST((void)); 4423b406e1SPoul-Henning Kamp static void MDFilter PROTO_LIST((int)); 45716847a6SSteve Price static void usage PROTO_LIST((void)); 46e1645093SPaul Traina 47e1645093SPaul Traina /* Main driver. 48e1645093SPaul Traina 49e1645093SPaul Traina Arguments (may be any combination): 50e1645093SPaul Traina -sstring - digests string 51e1645093SPaul Traina -t - runs time trial 52e1645093SPaul Traina -x - runs test script 53e1645093SPaul Traina filename - digests file 54e1645093SPaul Traina (none) - digests standard input 55e1645093SPaul Traina */ 569b1fd0e5SPoul-Henning Kamp int 579b1fd0e5SPoul-Henning Kamp main(argc, argv) 58e1645093SPaul Traina int argc; 59e1645093SPaul Traina char *argv[]; 60e1645093SPaul Traina { 619a9791afSSteve Price int ch; 629b1fd0e5SPoul-Henning Kamp char *p; 63116805fdSPoul-Henning Kamp char buf[33]; 64e1645093SPaul Traina 65716847a6SSteve Price if (argc > 1) { 669a9791afSSteve Price while ((ch = getopt(argc, argv, "ps:tx")) != -1) { 679a9791afSSteve Price switch (ch) { 68716847a6SSteve Price case 'p': 6923b406e1SPoul-Henning Kamp MDFilter(1); 70716847a6SSteve Price break; 71716847a6SSteve Price case 's': 72716847a6SSteve Price MDString(optarg); 73716847a6SSteve Price break; 74716847a6SSteve Price case 't': 75716847a6SSteve Price MDTimeTrial(); 76716847a6SSteve Price break; 77716847a6SSteve Price case 'x': 78e1645093SPaul Traina MDTestSuite(); 79716847a6SSteve Price break; 80716847a6SSteve Price default: 81716847a6SSteve Price usage(); 829b1fd0e5SPoul-Henning Kamp } 83716847a6SSteve Price } 84716847a6SSteve Price while (optind < argc) { 85716847a6SSteve Price p = MD5File(argv[optind], buf); 86716847a6SSteve Price if (!p) 8723b5892fSPhilippe Charnier warn("%s", argv[optind]); 88e1645093SPaul Traina else 89716847a6SSteve Price printf("MD5 (%s) = %s\n", argv[optind], p); 90716847a6SSteve Price optind++; 91716847a6SSteve Price } 92716847a6SSteve Price } else 9323b406e1SPoul-Henning Kamp MDFilter(0); 94e1645093SPaul Traina 95e1645093SPaul Traina return (0); 96e1645093SPaul Traina } 979b1fd0e5SPoul-Henning Kamp /* 989b1fd0e5SPoul-Henning Kamp * Digests a string and prints the result. 99e1645093SPaul Traina */ 1009b1fd0e5SPoul-Henning Kamp static void 1019b1fd0e5SPoul-Henning Kamp MDString(string) 102e1645093SPaul Traina char *string; 103e1645093SPaul Traina { 104b76bf6fcSBill Fumerola size_t len = strlen(string); 105116805fdSPoul-Henning Kamp char buf[33]; 106e1645093SPaul Traina 107116805fdSPoul-Henning Kamp printf("MD5 (\"%s\") = %s\n", string, MD5Data(string, len, buf)); 108e1645093SPaul Traina } 1099b1fd0e5SPoul-Henning Kamp /* 1109b1fd0e5SPoul-Henning Kamp * Measures the time to digest TEST_BLOCK_COUNT TEST_BLOCK_LEN-byte blocks. 111e1645093SPaul Traina */ 1129b1fd0e5SPoul-Henning Kamp static void 1139b1fd0e5SPoul-Henning Kamp MDTimeTrial() 114e1645093SPaul Traina { 1159b1fd0e5SPoul-Henning Kamp MD5_CTX context; 116e1645093SPaul Traina time_t endTime, startTime; 11723b406e1SPoul-Henning Kamp unsigned char block[TEST_BLOCK_LEN]; 118e1645093SPaul Traina unsigned int i; 119116805fdSPoul-Henning Kamp char *p, buf[33]; 120e1645093SPaul Traina 121e1645093SPaul Traina printf 1229b1fd0e5SPoul-Henning Kamp ("MD5 time trial. Digesting %d %d-byte blocks ...", 1231d0847d3SPoul-Henning Kamp TEST_BLOCK_COUNT, TEST_BLOCK_LEN); 12493606d6eSKris Kennaway fflush(stdout); 125e1645093SPaul Traina 126e1645093SPaul Traina /* Initialize block */ 127e1645093SPaul Traina for (i = 0; i < TEST_BLOCK_LEN; i++) 128e1645093SPaul Traina block[i] = (unsigned char) (i & 0xff); 129e1645093SPaul Traina 130e1645093SPaul Traina /* Start timer */ 131e1645093SPaul Traina time(&startTime); 132e1645093SPaul Traina 133e1645093SPaul Traina /* Digest blocks */ 1349b1fd0e5SPoul-Henning Kamp MD5Init(&context); 135e1645093SPaul Traina for (i = 0; i < TEST_BLOCK_COUNT; i++) 1369b1fd0e5SPoul-Henning Kamp MD5Update(&context, block, TEST_BLOCK_LEN); 137116805fdSPoul-Henning Kamp p = MD5End(&context,buf); 138e1645093SPaul Traina 139e1645093SPaul Traina /* Stop timer */ 140e1645093SPaul Traina time(&endTime); 141e1645093SPaul Traina 142e1645093SPaul Traina printf(" done\n"); 1439b1fd0e5SPoul-Henning Kamp printf("Digest = %s", p); 144e1645093SPaul Traina printf("\nTime = %ld seconds\n", (long) (endTime - startTime)); 1459b1fd0e5SPoul-Henning Kamp /* Be careful that endTime-startTime is not zero. (Bug fix from Ric 1469b1fd0e5SPoul-Henning Kamp * Anderson, ric@Artisoft.COM.) */ 147e1645093SPaul Traina printf 148e1645093SPaul Traina ("Speed = %ld bytes/second\n", 149e1645093SPaul Traina (long) TEST_BLOCK_LEN * (long) TEST_BLOCK_COUNT / ((endTime - startTime) != 0 ? (endTime - startTime) : 1)); 150e1645093SPaul Traina } 1519b1fd0e5SPoul-Henning Kamp /* 1529b1fd0e5SPoul-Henning Kamp * Digests a reference suite of strings and prints the results. 153e1645093SPaul Traina */ 1549b1fd0e5SPoul-Henning Kamp static void 1559b1fd0e5SPoul-Henning Kamp MDTestSuite() 156e1645093SPaul Traina { 1579a9791afSSteve Price 1589b1fd0e5SPoul-Henning Kamp printf("MD5 test suite:\n"); 159e1645093SPaul Traina 160e1645093SPaul Traina MDString(""); 161e1645093SPaul Traina MDString("a"); 162e1645093SPaul Traina MDString("abc"); 163e1645093SPaul Traina MDString("message digest"); 164e1645093SPaul Traina MDString("abcdefghijklmnopqrstuvwxyz"); 165e1645093SPaul Traina MDString 166e1645093SPaul Traina ("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"); 167e1645093SPaul Traina MDString 168e1645093SPaul Traina ("1234567890123456789012345678901234567890\ 169e1645093SPaul Traina 1234567890123456789012345678901234567890"); 170e1645093SPaul Traina } 171e1645093SPaul Traina 1729b1fd0e5SPoul-Henning Kamp /* 1739b1fd0e5SPoul-Henning Kamp * Digests the standard input and prints the result. 174e1645093SPaul Traina */ 1759b1fd0e5SPoul-Henning Kamp static void 1769a9791afSSteve Price MDFilter(pipe) 1779a9791afSSteve Price int pipe; 178e1645093SPaul Traina { 1799b1fd0e5SPoul-Henning Kamp MD5_CTX context; 180e1645093SPaul Traina int len; 181716847a6SSteve Price unsigned char buffer[BUFSIZ]; 182116805fdSPoul-Henning Kamp char buf[33]; 183e1645093SPaul Traina 1849b1fd0e5SPoul-Henning Kamp MD5Init(&context); 185716847a6SSteve Price while ((len = fread(buffer, 1, BUFSIZ, stdin))) { 18623b5892fSPhilippe Charnier if(pipe && (len != fwrite(buffer, 1, len, stdout))) 18723b5892fSPhilippe Charnier err(1, "stdout"); 1889b1fd0e5SPoul-Henning Kamp MD5Update(&context, buffer, len); 18923b406e1SPoul-Henning Kamp } 190116805fdSPoul-Henning Kamp printf("%s\n", MD5End(&context,buf)); 191e1645093SPaul Traina } 192716847a6SSteve Price 193716847a6SSteve Price static void 1949a9791afSSteve Price usage() 195716847a6SSteve Price { 1969a9791afSSteve Price 1979a9791afSSteve Price fprintf(stderr, "usage: md5 [-ptx] [-s string] [files ...]\n"); 198716847a6SSteve Price exit(1); 199716847a6SSteve Price } 200