md5.c revision 3995
13995Spst/* MDDRIVER.C - test driver for MD2, MD4 and MD5 23995Spst */ 33995Spst 43995Spst/* Copyright (C) 1990-2, RSA Data Security, Inc. Created 1990. All 53995Spstrights reserved. 63995Spst 73995SpstRSA Data Security, Inc. makes no representations concerning either 83995Spstthe merchantability of this software or the suitability of this 93995Spstsoftware for any particular purpose. It is provided "as is" 103995Spstwithout express or implied warranty of any kind. 113995Spst 123995SpstThese notices must be retained in any copies of any part of this 133995Spstdocumentation and/or software. 143995Spst */ 153995Spst 163995Spst/* The following makes MD default to MD5 if it has not already been 173995Spst defined with C compiler flags. 183995Spst */ 193995Spst#ifndef MD 203995Spst#define MD 5 213995Spst#endif 223995Spst 233995Spst#include <stdio.h> 243995Spst#include <time.h> 253995Spst#include <string.h> 263995Spst#include "global.h" 273995Spst#if MD == 2 283995Spst#include <md2.h> 293995Spst#endif 303995Spst#if MD == 4 313995Spst#include <md4.h> 323995Spst#endif 333995Spst#if MD == 5 343995Spst#include <md5.h> 353995Spst#endif 363995Spst 373995Spst/* Length of test block, number of test blocks. 383995Spst */ 393995Spst#define TEST_BLOCK_LEN 1000 403995Spst#define TEST_BLOCK_COUNT 1000 413995Spst 423995Spststatic void MDString PROTO_LIST ((char *)); 433995Spststatic void MDTimeTrial PROTO_LIST ((void)); 443995Spststatic void MDTestSuite PROTO_LIST ((void)); 453995Spststatic void MDFile PROTO_LIST ((char *)); 463995Spststatic void MDFilter PROTO_LIST ((void)); 473995Spststatic void MDPrint PROTO_LIST ((unsigned char [16])); 483995Spst 493995Spst#if MD == 2 503995Spst#define MD_CTX MD2_CTX 513995Spst#define MDInit MD2Init 523995Spst#define MDUpdate MD2Update 533995Spst#define MDFinal MD2Final 543995Spst#endif 553995Spst#if MD == 4 563995Spst#define MD_CTX MD4_CTX 573995Spst#define MDInit MD4Init 583995Spst#define MDUpdate MD4Update 593995Spst#define MDFinal MD4Final 603995Spst#endif 613995Spst#if MD == 5 623995Spst#define MD_CTX MD5_CTX 633995Spst#define MDInit MD5Init 643995Spst#define MDUpdate MD5Update 653995Spst#define MDFinal MD5Final 663995Spst#endif 673995Spst 683995Spst/* Main driver. 693995Spst 703995SpstArguments (may be any combination): 713995Spst -sstring - digests string 723995Spst -t - runs time trial 733995Spst -x - runs test script 743995Spst filename - digests file 753995Spst (none) - digests standard input 763995Spst */ 773995Spstint main (argc, argv) 783995Spstint argc; 793995Spstchar *argv[]; 803995Spst{ 813995Spst int i; 823995Spst 833995Spst if (argc > 1) 843995Spst for (i = 1; i < argc; i++) 853995Spst if (argv[i][0] == '-' && argv[i][1] == 's') 863995Spst MDString (argv[i] + 2); 873995Spst else if (strcmp (argv[i], "-t") == 0) 883995Spst MDTimeTrial (); 893995Spst else if (strcmp (argv[i], "-x") == 0) 903995Spst MDTestSuite (); 913995Spst else 923995Spst MDFile (argv[i]); 933995Spst else 943995Spst MDFilter (); 953995Spst 963995Spst return (0); 973995Spst} 983995Spst 993995Spst/* Digests a string and prints the result. 1003995Spst */ 1013995Spststatic void MDString (string) 1023995Spstchar *string; 1033995Spst{ 1043995Spst MD_CTX context; 1053995Spst unsigned char digest[16]; 1063995Spst unsigned int len = strlen (string); 1073995Spst 1083995Spst MDInit (&context); 1093995Spst MDUpdate (&context, string, len); 1103995Spst MDFinal (digest, &context); 1113995Spst 1123995Spst printf ("MD%d (\"%s\") = ", MD, string); 1133995Spst MDPrint (digest); 1143995Spst printf ("\n"); 1153995Spst} 1163995Spst 1173995Spst/* Measures the time to digest TEST_BLOCK_COUNT TEST_BLOCK_LEN-byte 1183995Spst blocks. 1193995Spst */ 1203995Spststatic void MDTimeTrial () 1213995Spst{ 1223995Spst MD_CTX context; 1233995Spst time_t endTime, startTime; 1243995Spst unsigned char block[TEST_BLOCK_LEN], digest[16]; 1253995Spst unsigned int i; 1263995Spst 1273995Spst printf 1283995Spst ("MD%d time trial. Digesting %d %d-byte blocks ...", MD, 1293995Spst TEST_BLOCK_LEN, TEST_BLOCK_COUNT); 1303995Spst 1313995Spst /* Initialize block */ 1323995Spst for (i = 0; i < TEST_BLOCK_LEN; i++) 1333995Spst block[i] = (unsigned char)(i & 0xff); 1343995Spst 1353995Spst /* Start timer */ 1363995Spst time (&startTime); 1373995Spst 1383995Spst /* Digest blocks */ 1393995Spst MDInit (&context); 1403995Spst for (i = 0; i < TEST_BLOCK_COUNT; i++) 1413995Spst MDUpdate (&context, block, TEST_BLOCK_LEN); 1423995Spst MDFinal (digest, &context); 1433995Spst 1443995Spst /* Stop timer */ 1453995Spst time (&endTime); 1463995Spst 1473995Spst printf (" done\n"); 1483995Spst printf ("Digest = "); 1493995Spst MDPrint (digest); 1503995Spst printf ("\nTime = %ld seconds\n", (long)(endTime-startTime)); 1513995Spst /* 1523995Spst * Be careful that endTime-startTime is not zero. 1533995Spst * (Bug fix from Ric Anderson, ric@Artisoft.COM.) 1543995Spst */ 1553995Spst printf 1563995Spst ("Speed = %ld bytes/second\n", 1573995Spst (long)TEST_BLOCK_LEN * (long)TEST_BLOCK_COUNT/((endTime-startTime) != 0 ? (endTime-startTime):1)); 1583995Spst} 1593995Spst 1603995Spst/* Digests a reference suite of strings and prints the results. 1613995Spst */ 1623995Spststatic void MDTestSuite () 1633995Spst{ 1643995Spst printf ("MD%d test suite:\n", MD); 1653995Spst 1663995Spst MDString (""); 1673995Spst MDString ("a"); 1683995Spst MDString ("abc"); 1693995Spst MDString ("message digest"); 1703995Spst MDString ("abcdefghijklmnopqrstuvwxyz"); 1713995Spst MDString 1723995Spst ("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"); 1733995Spst MDString 1743995Spst ("1234567890123456789012345678901234567890\ 1753995Spst1234567890123456789012345678901234567890"); 1763995Spst} 1773995Spst 1783995Spst/* Digests a file and prints the result. 1793995Spst */ 1803995Spststatic void MDFile (filename) 1813995Spstchar *filename; 1823995Spst{ 1833995Spst FILE *file; 1843995Spst MD_CTX context; 1853995Spst int len; 1863995Spst unsigned char buffer[1024], digest[16]; 1873995Spst 1883995Spst if ((file = fopen (filename, "rb")) == NULL) 1893995Spst printf ("%s can't be opened\n", filename); 1903995Spst 1913995Spst else { 1923995Spst MDInit (&context); 1933995Spst while (len = fread (buffer, 1, 1024, file)) 1943995Spst MDUpdate (&context, buffer, len); 1953995Spst MDFinal (digest, &context); 1963995Spst 1973995Spst fclose (file); 1983995Spst 1993995Spst printf ("MD%d (%s) = ", MD, filename); 2003995Spst MDPrint (digest); 2013995Spst printf ("\n"); 2023995Spst } 2033995Spst} 2043995Spst 2053995Spst/* Digests the standard input and prints the result. 2063995Spst */ 2073995Spststatic void MDFilter () 2083995Spst{ 2093995Spst MD_CTX context; 2103995Spst int len; 2113995Spst unsigned char buffer[16], digest[16]; 2123995Spst 2133995Spst MDInit (&context); 2143995Spst while (len = fread (buffer, 1, 16, stdin)) 2153995Spst MDUpdate (&context, buffer, len); 2163995Spst MDFinal (digest, &context); 2173995Spst 2183995Spst MDPrint (digest); 2193995Spst printf ("\n"); 2203995Spst} 2213995Spst 2223995Spst/* Prints a message digest in hexadecimal. 2233995Spst */ 2243995Spststatic void MDPrint (digest) 2253995Spstunsigned char digest[16]; 2263995Spst{ 2273995Spst unsigned int i; 2283995Spst 2293995Spst for (i = 0; i < 16; i++) 2303995Spst printf ("%02x", digest[i]); 2313995Spst} 232