1e1645093SPaul Traina /* MDDRIVER.C - test driver for MD2, MD4 and MD5 2e1645093SPaul Traina */ 3e1645093SPaul Traina 4e1645093SPaul Traina /* Copyright (C) 1990-2, RSA Data Security, Inc. Created 1990. All 5e1645093SPaul Traina rights reserved. 6e1645093SPaul Traina 7e1645093SPaul Traina RSA Data Security, Inc. makes no representations concerning either 8e1645093SPaul Traina the merchantability of this software or the suitability of this 9e1645093SPaul Traina software for any particular purpose. It is provided "as is" 10e1645093SPaul Traina without express or implied warranty of any kind. 11e1645093SPaul Traina 12e1645093SPaul Traina These notices must be retained in any copies of any part of this 13e1645093SPaul Traina documentation and/or software. 14e1645093SPaul Traina */ 15e1645093SPaul Traina 16e1645093SPaul Traina /* The following makes MD default to MD5 if it has not already been 17e1645093SPaul Traina defined with C compiler flags. 18e1645093SPaul Traina */ 19e1645093SPaul Traina #ifndef MD 20e1645093SPaul Traina #define MD 5 21e1645093SPaul Traina #endif 22e1645093SPaul Traina 23e1645093SPaul Traina #include <stdio.h> 24e1645093SPaul Traina #include <time.h> 25e1645093SPaul Traina #include <string.h> 26e1645093SPaul Traina #include "global.h" 27e1645093SPaul Traina #if MD == 2 28e1645093SPaul Traina #include <md2.h> 29e1645093SPaul Traina #endif 30e1645093SPaul Traina #if MD == 4 31e1645093SPaul Traina #include <md4.h> 32e1645093SPaul Traina #endif 33e1645093SPaul Traina #if MD == 5 34e1645093SPaul Traina #include <md5.h> 35e1645093SPaul Traina #endif 36e1645093SPaul Traina 37e1645093SPaul Traina /* Length of test block, number of test blocks. 38e1645093SPaul Traina */ 39e1645093SPaul Traina #define TEST_BLOCK_LEN 1000 40e1645093SPaul Traina #define TEST_BLOCK_COUNT 1000 41e1645093SPaul Traina 42e1645093SPaul Traina static void MDString PROTO_LIST ((char *)); 43e1645093SPaul Traina static void MDTimeTrial PROTO_LIST ((void)); 44e1645093SPaul Traina static void MDTestSuite PROTO_LIST ((void)); 45e1645093SPaul Traina static void MDFile PROTO_LIST ((char *)); 46e1645093SPaul Traina static void MDFilter PROTO_LIST ((void)); 47e1645093SPaul Traina static void MDPrint PROTO_LIST ((unsigned char [16])); 48e1645093SPaul Traina 49e1645093SPaul Traina #if MD == 2 50e1645093SPaul Traina #define MD_CTX MD2_CTX 51e1645093SPaul Traina #define MDInit MD2Init 52e1645093SPaul Traina #define MDUpdate MD2Update 53e1645093SPaul Traina #define MDFinal MD2Final 54e1645093SPaul Traina #endif 55e1645093SPaul Traina #if MD == 4 56e1645093SPaul Traina #define MD_CTX MD4_CTX 57e1645093SPaul Traina #define MDInit MD4Init 58e1645093SPaul Traina #define MDUpdate MD4Update 59e1645093SPaul Traina #define MDFinal MD4Final 60e1645093SPaul Traina #endif 61e1645093SPaul Traina #if MD == 5 62e1645093SPaul Traina #define MD_CTX MD5_CTX 63e1645093SPaul Traina #define MDInit MD5Init 64e1645093SPaul Traina #define MDUpdate MD5Update 65e1645093SPaul Traina #define MDFinal MD5Final 66e1645093SPaul Traina #endif 67e1645093SPaul Traina 68e1645093SPaul Traina /* Main driver. 69e1645093SPaul Traina 70e1645093SPaul Traina Arguments (may be any combination): 71e1645093SPaul Traina -sstring - digests string 72e1645093SPaul Traina -t - runs time trial 73e1645093SPaul Traina -x - runs test script 74e1645093SPaul Traina filename - digests file 75e1645093SPaul Traina (none) - digests standard input 76e1645093SPaul Traina */ 77e1645093SPaul Traina int main (argc, argv) 78e1645093SPaul Traina int argc; 79e1645093SPaul Traina char *argv[]; 80e1645093SPaul Traina { 81e1645093SPaul Traina int i; 82e1645093SPaul Traina 83e1645093SPaul Traina if (argc > 1) 84e1645093SPaul Traina for (i = 1; i < argc; i++) 85e1645093SPaul Traina if (argv[i][0] == '-' && argv[i][1] == 's') 86e1645093SPaul Traina MDString (argv[i] + 2); 87e1645093SPaul Traina else if (strcmp (argv[i], "-t") == 0) 88e1645093SPaul Traina MDTimeTrial (); 89e1645093SPaul Traina else if (strcmp (argv[i], "-x") == 0) 90e1645093SPaul Traina MDTestSuite (); 91e1645093SPaul Traina else 92e1645093SPaul Traina MDFile (argv[i]); 93e1645093SPaul Traina else 94e1645093SPaul Traina MDFilter (); 95e1645093SPaul Traina 96e1645093SPaul Traina return (0); 97e1645093SPaul Traina } 98e1645093SPaul Traina 99e1645093SPaul Traina /* Digests a string and prints the result. 100e1645093SPaul Traina */ 101e1645093SPaul Traina static void MDString (string) 102e1645093SPaul Traina char *string; 103e1645093SPaul Traina { 104e1645093SPaul Traina MD_CTX context; 105e1645093SPaul Traina unsigned char digest[16]; 106e1645093SPaul Traina unsigned int len = strlen (string); 107e1645093SPaul Traina 108e1645093SPaul Traina MDInit (&context); 109e1645093SPaul Traina MDUpdate (&context, string, len); 110e1645093SPaul Traina MDFinal (digest, &context); 111e1645093SPaul Traina 112e1645093SPaul Traina printf ("MD%d (\"%s\") = ", MD, string); 113e1645093SPaul Traina MDPrint (digest); 114e1645093SPaul Traina printf ("\n"); 115e1645093SPaul Traina } 116e1645093SPaul Traina 117e1645093SPaul Traina /* Measures the time to digest TEST_BLOCK_COUNT TEST_BLOCK_LEN-byte 118e1645093SPaul Traina blocks. 119e1645093SPaul Traina */ 120e1645093SPaul Traina static void MDTimeTrial () 121e1645093SPaul Traina { 122e1645093SPaul Traina MD_CTX context; 123e1645093SPaul Traina time_t endTime, startTime; 124e1645093SPaul Traina unsigned char block[TEST_BLOCK_LEN], digest[16]; 125e1645093SPaul Traina unsigned int i; 126e1645093SPaul Traina 127e1645093SPaul Traina printf 128e1645093SPaul Traina ("MD%d time trial. Digesting %d %d-byte blocks ...", MD, 129e1645093SPaul Traina TEST_BLOCK_LEN, TEST_BLOCK_COUNT); 130e1645093SPaul Traina 131e1645093SPaul Traina /* Initialize block */ 132e1645093SPaul Traina for (i = 0; i < TEST_BLOCK_LEN; i++) 133e1645093SPaul Traina block[i] = (unsigned char)(i & 0xff); 134e1645093SPaul Traina 135e1645093SPaul Traina /* Start timer */ 136e1645093SPaul Traina time (&startTime); 137e1645093SPaul Traina 138e1645093SPaul Traina /* Digest blocks */ 139e1645093SPaul Traina MDInit (&context); 140e1645093SPaul Traina for (i = 0; i < TEST_BLOCK_COUNT; i++) 141e1645093SPaul Traina MDUpdate (&context, block, TEST_BLOCK_LEN); 142e1645093SPaul Traina MDFinal (digest, &context); 143e1645093SPaul Traina 144e1645093SPaul Traina /* Stop timer */ 145e1645093SPaul Traina time (&endTime); 146e1645093SPaul Traina 147e1645093SPaul Traina printf (" done\n"); 148e1645093SPaul Traina printf ("Digest = "); 149e1645093SPaul Traina MDPrint (digest); 150e1645093SPaul Traina printf ("\nTime = %ld seconds\n", (long)(endTime-startTime)); 151e1645093SPaul Traina /* 152e1645093SPaul Traina * Be careful that endTime-startTime is not zero. 153e1645093SPaul Traina * (Bug fix from Ric Anderson, ric@Artisoft.COM.) 154e1645093SPaul Traina */ 155e1645093SPaul Traina printf 156e1645093SPaul Traina ("Speed = %ld bytes/second\n", 157e1645093SPaul Traina (long)TEST_BLOCK_LEN * (long)TEST_BLOCK_COUNT/((endTime-startTime) != 0 ? (endTime-startTime):1)); 158e1645093SPaul Traina } 159e1645093SPaul Traina 160e1645093SPaul Traina /* Digests a reference suite of strings and prints the results. 161e1645093SPaul Traina */ 162e1645093SPaul Traina static void MDTestSuite () 163e1645093SPaul Traina { 164e1645093SPaul Traina printf ("MD%d test suite:\n", MD); 165e1645093SPaul Traina 166e1645093SPaul Traina MDString (""); 167e1645093SPaul Traina MDString ("a"); 168e1645093SPaul Traina MDString ("abc"); 169e1645093SPaul Traina MDString ("message digest"); 170e1645093SPaul Traina MDString ("abcdefghijklmnopqrstuvwxyz"); 171e1645093SPaul Traina MDString 172e1645093SPaul Traina ("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"); 173e1645093SPaul Traina MDString 174e1645093SPaul Traina ("1234567890123456789012345678901234567890\ 175e1645093SPaul Traina 1234567890123456789012345678901234567890"); 176e1645093SPaul Traina } 177e1645093SPaul Traina 178e1645093SPaul Traina /* Digests a file and prints the result. 179e1645093SPaul Traina */ 180e1645093SPaul Traina static void MDFile (filename) 181e1645093SPaul Traina char *filename; 182e1645093SPaul Traina { 183e1645093SPaul Traina FILE *file; 184e1645093SPaul Traina MD_CTX context; 185e1645093SPaul Traina int len; 186e1645093SPaul Traina unsigned char buffer[1024], digest[16]; 187e1645093SPaul Traina 188e1645093SPaul Traina if ((file = fopen (filename, "rb")) == NULL) 189e1645093SPaul Traina printf ("%s can't be opened\n", filename); 190e1645093SPaul Traina 191e1645093SPaul Traina else { 192e1645093SPaul Traina MDInit (&context); 193e1645093SPaul Traina while (len = fread (buffer, 1, 1024, file)) 194e1645093SPaul Traina MDUpdate (&context, buffer, len); 195e1645093SPaul Traina MDFinal (digest, &context); 196e1645093SPaul Traina 197e1645093SPaul Traina fclose (file); 198e1645093SPaul Traina 199e1645093SPaul Traina printf ("MD%d (%s) = ", MD, filename); 200e1645093SPaul Traina MDPrint (digest); 201e1645093SPaul Traina printf ("\n"); 202e1645093SPaul Traina } 203e1645093SPaul Traina } 204e1645093SPaul Traina 205e1645093SPaul Traina /* Digests the standard input and prints the result. 206e1645093SPaul Traina */ 207e1645093SPaul Traina static void MDFilter () 208e1645093SPaul Traina { 209e1645093SPaul Traina MD_CTX context; 210e1645093SPaul Traina int len; 211e1645093SPaul Traina unsigned char buffer[16], digest[16]; 212e1645093SPaul Traina 213e1645093SPaul Traina MDInit (&context); 214e1645093SPaul Traina while (len = fread (buffer, 1, 16, stdin)) 215e1645093SPaul Traina MDUpdate (&context, buffer, len); 216e1645093SPaul Traina MDFinal (digest, &context); 217e1645093SPaul Traina 218e1645093SPaul Traina MDPrint (digest); 219e1645093SPaul Traina printf ("\n"); 220e1645093SPaul Traina } 221e1645093SPaul Traina 222e1645093SPaul Traina /* Prints a message digest in hexadecimal. 223e1645093SPaul Traina */ 224e1645093SPaul Traina static void MDPrint (digest) 225e1645093SPaul Traina unsigned char digest[16]; 226e1645093SPaul Traina { 227e1645093SPaul Traina unsigned int i; 228e1645093SPaul Traina 229e1645093SPaul Traina for (i = 0; i < 16; i++) 230e1645093SPaul Traina printf ("%02x", digest[i]); 231e1645093SPaul Traina } 232