md5.c revision 3995
11844Swollman/* MDDRIVER.C - test driver for MD2, MD4 and MD5 250476Speter */ 31844Swollman 41638Srgrimes/* Copyright (C) 1990-2, RSA Data Security, Inc. Created 1990. All 594940Srurights reserved. 61638Srgrimes 742915SjdpRSA Data Security, Inc. makes no representations concerning either 842915Sjdpthe merchantability of this software or the suitability of this 942915Sjdpsoftware for any particular purpose. It is provided "as is" 1042915Sjdpwithout express or implied warranty of any kind. 11139106Sru 1242915SjdpThese notices must be retained in any copies of any part of this 1342915Sjdpdocumentation and/or software. 1442915Sjdp */ 15129024Sdes 16129024Sdes/* The following makes MD default to MD5 if it has not already been 1729141Speter defined with C compiler flags. 18129024Sdes */ 19129024Sdes#ifndef MD 20129024Sdes#define MD 5 21125119Sru#endif 22100332Sru 23100332Sru#include <stdio.h> 2442915Sjdp#include <time.h> 2542915Sjdp#include <string.h> 2629141Speter#include "global.h" 27119607Sru#if MD == 2 28117034Sgordon#include <md2.h> 29119607Sru#endif 30117034Sgordon#if MD == 4 312827Sjkh#include <md4.h> 322827Sjkh#endif 332827Sjkh#if MD == 5 342827Sjkh#include <md5.h> 352827Sjkh#endif 361638Srgrimes 372827Sjkh/* Length of test block, number of test blocks. 381638Srgrimes */ 3918529Sbde#define TEST_BLOCK_LEN 1000 4018529Sbde#define TEST_BLOCK_COUNT 1000 411638Srgrimes 4242450Sjdpstatic void MDString PROTO_LIST ((char *)); 431638Srgrimesstatic void MDTimeTrial PROTO_LIST ((void)); 44117173Srustatic void MDTestSuite PROTO_LIST ((void)); 451638Srgrimesstatic void MDFile PROTO_LIST ((char *)); 4696512Srustatic void MDFilter PROTO_LIST ((void)); 4796512Srustatic void MDPrint PROTO_LIST ((unsigned char [16])); 4896512Sru 4996512Sru#if MD == 2 5096512Sru#define MD_CTX MD2_CTX 5196512Sru#define MDInit MD2Init 5296512Sru#define MDUpdate MD2Update 5396512Sru#define MDFinal MD2Final 54126890Strhodes#endif 55126890Strhodes#if MD == 4 56126890Strhodes#define MD_CTX MD4_CTX 57126890Strhodes#define MDInit MD4Init 58126890Strhodes#define MDUpdate MD4Update 59126890Strhodes#define MDFinal MD4Final 601638Srgrimes#endif 61126890Strhodes#if MD == 5 621638Srgrimes#define MD_CTX MD5_CTX 6342450Sjdp#define MDInit MD5Init 641844Swollman#define MDUpdate MD5Update 651844Swollman#define MDFinal MD5Final 6636673Sdt#endif 67126890Strhodes 681844Swollman/* Main driver. 6942450Sjdp 701844SwollmanArguments (may be any combination): 711844Swollman -sstring - digests string 721844Swollman -t - runs time trial 73127027Strhodes -x - runs test script 741844Swollman filename - digests file 7542450Sjdp (none) - digests standard input 761844Swollman */ 771844Swollmanint main (argc, argv) 7836054Sbdeint argc; 7936054Sbdechar *argv[]; 8036054Sbde{ 8142450Sjdp int i; 8236054Sbde 8336054Sbde if (argc > 1) 84117173Sru for (i = 1; i < argc; i++) 85117159Sru if (argv[i][0] == '-' && argv[i][1] == 's') 861638Srgrimes MDString (argv[i] + 2); 87117173Sru else if (strcmp (argv[i], "-t") == 0) 88117173Sru MDTimeTrial (); 89117173Sru else if (strcmp (argv[i], "-x") == 0) 90117173Sru MDTestSuite (); 91117173Sru else 92117173Sru MDFile (argv[i]); 93117173Sru else 941844Swollman MDFilter (); 95117122Sru 961844Swollman return (0); 9742450Sjdp} 98117122Sru 991844Swollman/* Digests a string and prints the result. 10096512Sru */ 1011638Srgrimesstatic void MDString (string) 102156772Sdeischenchar *string; 103156772Sdeischen{ 104156772Sdeischen MD_CTX context; 105156772Sdeischen unsigned char digest[16]; 106156772Sdeischen unsigned int len = strlen (string); 107156772Sdeischen 108156772Sdeischen MDInit (&context); 109156772Sdeischen MDUpdate (&context, string, len); 110156772Sdeischen MDFinal (digest, &context); 111156772Sdeischen 112156772Sdeischen printf ("MD%d (\"%s\") = ", MD, string); 113156772Sdeischen MDPrint (digest); 114156772Sdeischen printf ("\n"); 115156772Sdeischen} 116156772Sdeischen 117156772Sdeischen/* Measures the time to digest TEST_BLOCK_COUNT TEST_BLOCK_LEN-byte 118156772Sdeischen blocks. 119156772Sdeischen */ 120156772Sdeischenstatic void MDTimeTrial () 121156772Sdeischen{ 122156772Sdeischen MD_CTX context; 123156772Sdeischen time_t endTime, startTime; 124156772Sdeischen unsigned char block[TEST_BLOCK_LEN], digest[16]; 125156772Sdeischen unsigned int i; 126156772Sdeischen 127156772Sdeischen printf 128156772Sdeischen ("MD%d time trial. Digesting %d %d-byte blocks ...", MD, 129156772Sdeischen TEST_BLOCK_LEN, TEST_BLOCK_COUNT); 130156772Sdeischen 131156772Sdeischen /* Initialize block */ 132156772Sdeischen for (i = 0; i < TEST_BLOCK_LEN; i++) 133156772Sdeischen block[i] = (unsigned char)(i & 0xff); 134156772Sdeischen 135156772Sdeischen /* Start timer */ 136156772Sdeischen time (&startTime); 137156772Sdeischen 138156772Sdeischen /* Digest blocks */ 139156772Sdeischen MDInit (&context); 140156772Sdeischen for (i = 0; i < TEST_BLOCK_COUNT; i++) 141156772Sdeischen MDUpdate (&context, block, TEST_BLOCK_LEN); 14299362Sru MDFinal (digest, &context); 14399362Sru 14499362Sru /* Stop timer */ 14599362Sru time (&endTime); 14696512Sru 14796512Sru printf (" done\n"); 1481638Srgrimes printf ("Digest = "); 14996512Sru MDPrint (digest); 15096512Sru printf ("\nTime = %ld seconds\n", (long)(endTime-startTime)); 15196512Sru /* 15296512Sru * Be careful that endTime-startTime is not zero. 15396512Sru * (Bug fix from Ric Anderson, ric@Artisoft.COM.) 15499362Sru */ 1551638Srgrimes printf 15696512Sru ("Speed = %ld bytes/second\n", 15795114Sobrien (long)TEST_BLOCK_LEN * (long)TEST_BLOCK_COUNT/((endTime-startTime) != 0 ? (endTime-startTime):1)); 158139106Sru} 15996512Sru 16096512Sru/* Digests a reference suite of strings and prints the results. 16195306Sru */ 16296512Srustatic void MDTestSuite () 16396512Sru{ 16496512Sru printf ("MD%d test suite:\n", MD); 16596512Sru 16696512Sru MDString (""); 16774805Sru MDString ("a"); 1681844Swollman MDString ("abc"); 16999362Sru MDString ("message digest"); 17099362Sru MDString ("abcdefghijklmnopqrstuvwxyz"); 17196512Sru MDString 17299362Sru ("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"); 1731844Swollman MDString 17496512Sru ("1234567890123456789012345678901234567890\ 17596512Sru1234567890123456789012345678901234567890"); 1761638Srgrimes} 17742915Sjdp 17842915Sjdp/* Digests a file and prints the result. 17996512Sru */ 18042915Sjdpstatic void MDFile (filename) 18196512Sruchar *filename; 18242915Sjdp{ 18396343Sobrien FILE *file; 18496512Sru MD_CTX context; 18591011Sru int len; 18628945Speter unsigned char buffer[1024], digest[16]; 1871844Swollman 188148725Sphk if ((file = fopen (filename, "rb")) == NULL) 18996512Sru printf ("%s can't be opened\n", filename); 19096512Sru 19196512Sru else { 1922353Sbde MDInit (&context); 19396512Sru while (len = fread (buffer, 1, 1024, file)) 19496512Sru MDUpdate (&context, buffer, len); 19596512Sru MDFinal (digest, &context); 1963859Sbde 1971844Swollman fclose (file); 198139106Sru 19996512Sru printf ("MD%d (%s) = ", MD, filename); 20096512Sru MDPrint (digest); 20196512Sru printf ("\n"); 20296512Sru } 20392491Smarkm} 20496512Sru 20596512Sru/* Digests the standard input and prints the result. 20692491Smarkm */ 20792491Smarkmstatic void MDFilter () 2081638Srgrimes{ 209144893Sharti MD_CTX context; 21096512Sru int len; 21196512Sru unsigned char buffer[16], digest[16]; 21296512Sru 213139103Sru MDInit (&context); 21496512Sru while (len = fread (buffer, 1, 16, stdin)) 2151638Srgrimes MDUpdate (&context, buffer, len); 2161638Srgrimes MDFinal (digest, &context); 21734179Sbde 21824750Sbde MDPrint (digest); 21942450Sjdp printf ("\n"); 22024750Sbde} 22124750Sbde 222139107Sru/* Prints a message digest in hexadecimal. 22331809Sbde */ 22442915Sjdpstatic void MDPrint (digest) 22527910Sasamiunsigned char digest[16]; 22628945Speter{ 2271638Srgrimes unsigned int i; 2281638Srgrimes 2291638Srgrimes for (i = 0; i < 16; i++) 230136019Sru printf ("%02x", digest[i]); 231139111Sru} 2322298Swollman