19b1fd0e5SPoul-Henning Kamp /* 29a9791afSSteve Price * $Id: md5.c,v 1.11 1997/12/29 03:40:37 steve Exp $ 39b1fd0e5SPoul-Henning Kamp * 49b1fd0e5SPoul-Henning Kamp * Derived from: 5e1645093SPaul Traina */ 6e1645093SPaul Traina 79b1fd0e5SPoul-Henning Kamp /* 89b1fd0e5SPoul-Henning Kamp * MDDRIVER.C - test driver for MD2, MD4 and MD5 9e1645093SPaul Traina */ 10e1645093SPaul Traina 119b1fd0e5SPoul-Henning Kamp /* 129b1fd0e5SPoul-Henning Kamp * Copyright (C) 1990-2, RSA Data Security, Inc. Created 1990. All 139b1fd0e5SPoul-Henning Kamp * rights reserved. 149b1fd0e5SPoul-Henning Kamp * 159b1fd0e5SPoul-Henning Kamp * RSA Data Security, Inc. makes no representations concerning either 169b1fd0e5SPoul-Henning Kamp * the merchantability of this software or the suitability of this 179b1fd0e5SPoul-Henning Kamp * software for any particular purpose. It is provided "as is" 189b1fd0e5SPoul-Henning Kamp * without express or implied warranty of any kind. 199b1fd0e5SPoul-Henning Kamp * 209b1fd0e5SPoul-Henning Kamp * These notices must be retained in any copies of any part of this 219b1fd0e5SPoul-Henning Kamp * documentation and/or software. 22e1645093SPaul Traina */ 23e1645093SPaul Traina 241ab6205cSBruce Evans #include <sys/types.h> 25e1645093SPaul Traina #include <md5.h> 26e1645093SPaul Traina 271ab6205cSBruce Evans #include <stdio.h> 281ab6205cSBruce Evans #include <string.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 */ 37e1645093SPaul Traina #define TEST_BLOCK_LEN 1000 38e1645093SPaul Traina #define TEST_BLOCK_COUNT 1000 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) 86716847a6SSteve Price perror(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); 123e1645093SPaul Traina 124e1645093SPaul Traina /* Initialize block */ 125e1645093SPaul Traina for (i = 0; i < TEST_BLOCK_LEN; i++) 126e1645093SPaul Traina block[i] = (unsigned char) (i & 0xff); 127e1645093SPaul Traina 128e1645093SPaul Traina /* Start timer */ 129e1645093SPaul Traina time(&startTime); 130e1645093SPaul Traina 131e1645093SPaul Traina /* Digest blocks */ 1329b1fd0e5SPoul-Henning Kamp MD5Init(&context); 133e1645093SPaul Traina for (i = 0; i < TEST_BLOCK_COUNT; i++) 1349b1fd0e5SPoul-Henning Kamp MD5Update(&context, block, TEST_BLOCK_LEN); 135116805fdSPoul-Henning Kamp p = MD5End(&context,buf); 136e1645093SPaul Traina 137e1645093SPaul Traina /* Stop timer */ 138e1645093SPaul Traina time(&endTime); 139e1645093SPaul Traina 140e1645093SPaul Traina printf(" done\n"); 1419b1fd0e5SPoul-Henning Kamp printf("Digest = %s", p); 142e1645093SPaul Traina printf("\nTime = %ld seconds\n", (long) (endTime - startTime)); 1439b1fd0e5SPoul-Henning Kamp /* Be careful that endTime-startTime is not zero. (Bug fix from Ric 1449b1fd0e5SPoul-Henning Kamp * Anderson, ric@Artisoft.COM.) */ 145e1645093SPaul Traina printf 146e1645093SPaul Traina ("Speed = %ld bytes/second\n", 147e1645093SPaul Traina (long) TEST_BLOCK_LEN * (long) TEST_BLOCK_COUNT / ((endTime - startTime) != 0 ? (endTime - startTime) : 1)); 148e1645093SPaul Traina } 1499b1fd0e5SPoul-Henning Kamp /* 1509b1fd0e5SPoul-Henning Kamp * Digests a reference suite of strings and prints the results. 151e1645093SPaul Traina */ 1529b1fd0e5SPoul-Henning Kamp static void 1539b1fd0e5SPoul-Henning Kamp MDTestSuite() 154e1645093SPaul Traina { 1559a9791afSSteve Price 1569b1fd0e5SPoul-Henning Kamp printf("MD5 test suite:\n"); 157e1645093SPaul Traina 158e1645093SPaul Traina MDString(""); 159e1645093SPaul Traina MDString("a"); 160e1645093SPaul Traina MDString("abc"); 161e1645093SPaul Traina MDString("message digest"); 162e1645093SPaul Traina MDString("abcdefghijklmnopqrstuvwxyz"); 163e1645093SPaul Traina MDString 164e1645093SPaul Traina ("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"); 165e1645093SPaul Traina MDString 166e1645093SPaul Traina ("1234567890123456789012345678901234567890\ 167e1645093SPaul Traina 1234567890123456789012345678901234567890"); 168e1645093SPaul Traina } 169e1645093SPaul Traina 1709b1fd0e5SPoul-Henning Kamp /* 1719b1fd0e5SPoul-Henning Kamp * Digests the standard input and prints the result. 172e1645093SPaul Traina */ 1739b1fd0e5SPoul-Henning Kamp static void 1749a9791afSSteve Price MDFilter(pipe) 1759a9791afSSteve Price int pipe; 176e1645093SPaul Traina { 1779b1fd0e5SPoul-Henning Kamp MD5_CTX context; 178e1645093SPaul Traina int len; 179716847a6SSteve Price unsigned char buffer[BUFSIZ]; 180116805fdSPoul-Henning Kamp char buf[33]; 181e1645093SPaul Traina 1829b1fd0e5SPoul-Henning Kamp MD5Init(&context); 183716847a6SSteve Price while ((len = fread(buffer, 1, BUFSIZ, stdin))) { 184c8006b15SPoul-Henning Kamp if(pipe && (len != fwrite(buffer, 1, len, stdout))) { 185c8006b15SPoul-Henning Kamp perror("stdout"); 186c8006b15SPoul-Henning Kamp exit(1); 187c8006b15SPoul-Henning Kamp } 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