md5.c revision 3995
1189251Ssam/* MDDRIVER.C - test driver for MD2, MD4 and MD5 2189251Ssam */ 3189251Ssam 4189251Ssam/* Copyright (C) 1990-2, RSA Data Security, Inc. Created 1990. All 5189251Ssamrights reserved. 6189251Ssam 7189251SsamRSA Data Security, Inc. makes no representations concerning either 8189251Ssamthe merchantability of this software or the suitability of this 9189251Ssamsoftware for any particular purpose. It is provided "as is" 10189251Ssamwithout express or implied warranty of any kind. 11189251Ssam 12189251SsamThese notices must be retained in any copies of any part of this 13189251Ssamdocumentation and/or software. 14189251Ssam */ 15189251Ssam 16189251Ssam/* The following makes MD default to MD5 if it has not already been 17189251Ssam defined with C compiler flags. 18189251Ssam */ 19189251Ssam#ifndef MD 20189251Ssam#define MD 5 21189251Ssam#endif 22189251Ssam 23189251Ssam#include <stdio.h> 24189251Ssam#include <time.h> 25189251Ssam#include <string.h> 26189251Ssam#include "global.h" 27189251Ssam#if MD == 2 28189251Ssam#include <md2.h> 29189251Ssam#endif 30189251Ssam#if MD == 4 31189251Ssam#include <md4.h> 32189251Ssam#endif 33189251Ssam#if MD == 5 34189251Ssam#include <md5.h> 35189251Ssam#endif 36189251Ssam 37189251Ssam/* Length of test block, number of test blocks. 38189251Ssam */ 39189251Ssam#define TEST_BLOCK_LEN 1000 40189251Ssam#define TEST_BLOCK_COUNT 1000 41189251Ssam 42189251Ssamstatic void MDString PROTO_LIST ((char *)); 43189251Ssamstatic void MDTimeTrial PROTO_LIST ((void)); 44189251Ssamstatic void MDTestSuite PROTO_LIST ((void)); 45189251Ssamstatic void MDFile PROTO_LIST ((char *)); 46189251Ssamstatic void MDFilter PROTO_LIST ((void)); 47189251Ssamstatic void MDPrint PROTO_LIST ((unsigned char [16])); 48189251Ssam 49189251Ssam#if MD == 2 50189251Ssam#define MD_CTX MD2_CTX 51189251Ssam#define MDInit MD2Init 52189251Ssam#define MDUpdate MD2Update 53189251Ssam#define MDFinal MD2Final 54189251Ssam#endif 55189251Ssam#if MD == 4 56189251Ssam#define MD_CTX MD4_CTX 57189251Ssam#define MDInit MD4Init 58189251Ssam#define MDUpdate MD4Update 59189251Ssam#define MDFinal MD4Final 60189251Ssam#endif 61189251Ssam#if MD == 5 62189251Ssam#define MD_CTX MD5_CTX 63189251Ssam#define MDInit MD5Init 64189251Ssam#define MDUpdate MD5Update 65189251Ssam#define MDFinal MD5Final 66189251Ssam#endif 67189251Ssam 68189251Ssam/* Main driver. 69189251Ssam 70189251SsamArguments (may be any combination): 71189251Ssam -sstring - digests string 72189251Ssam -t - runs time trial 73189251Ssam -x - runs test script 74189251Ssam filename - digests file 75189251Ssam (none) - digests standard input 76189251Ssam */ 77189251Ssamint main (argc, argv) 78189251Ssamint argc; 79189251Ssamchar *argv[]; 80189251Ssam{ 81189251Ssam int i; 82189251Ssam 83189251Ssam if (argc > 1) 84189251Ssam for (i = 1; i < argc; i++) 85189251Ssam if (argv[i][0] == '-' && argv[i][1] == 's') 86189251Ssam MDString (argv[i] + 2); 87189251Ssam else if (strcmp (argv[i], "-t") == 0) 88189251Ssam MDTimeTrial (); 89189251Ssam else if (strcmp (argv[i], "-x") == 0) 90189251Ssam MDTestSuite (); 91189251Ssam else 92189251Ssam MDFile (argv[i]); 93189251Ssam else 94189251Ssam MDFilter (); 95189251Ssam 96189251Ssam return (0); 97189251Ssam} 98189251Ssam 99189251Ssam/* Digests a string and prints the result. 100189251Ssam */ 101189251Ssamstatic void MDString (string) 102189251Ssamchar *string; 103189251Ssam{ 104189251Ssam MD_CTX context; 105189251Ssam unsigned char digest[16]; 106189251Ssam unsigned int len = strlen (string); 107189251Ssam 108189251Ssam MDInit (&context); 109189251Ssam MDUpdate (&context, string, len); 110189251Ssam MDFinal (digest, &context); 111189251Ssam 112189251Ssam printf ("MD%d (\"%s\") = ", MD, string); 113189251Ssam MDPrint (digest); 114189251Ssam printf ("\n"); 115189251Ssam} 116189251Ssam 117189251Ssam/* Measures the time to digest TEST_BLOCK_COUNT TEST_BLOCK_LEN-byte 118189251Ssam blocks. 119189251Ssam */ 120189251Ssamstatic void MDTimeTrial () 121189251Ssam{ 122189251Ssam MD_CTX context; 123189251Ssam time_t endTime, startTime; 124189251Ssam unsigned char block[TEST_BLOCK_LEN], digest[16]; 125189251Ssam unsigned int i; 126189251Ssam 127189251Ssam printf 128189251Ssam ("MD%d time trial. Digesting %d %d-byte blocks ...", MD, 129189251Ssam TEST_BLOCK_LEN, TEST_BLOCK_COUNT); 130189251Ssam 131189251Ssam /* Initialize block */ 132189251Ssam for (i = 0; i < TEST_BLOCK_LEN; i++) 133189251Ssam block[i] = (unsigned char)(i & 0xff); 134189251Ssam 135189251Ssam /* Start timer */ 136189251Ssam time (&startTime); 137189251Ssam 138189251Ssam /* Digest blocks */ 139189251Ssam MDInit (&context); 140189251Ssam for (i = 0; i < TEST_BLOCK_COUNT; i++) 141189251Ssam MDUpdate (&context, block, TEST_BLOCK_LEN); 142189251Ssam MDFinal (digest, &context); 143189251Ssam 144189251Ssam /* Stop timer */ 145189251Ssam time (&endTime); 146189251Ssam 147189251Ssam printf (" done\n"); 148189251Ssam printf ("Digest = "); 149189251Ssam MDPrint (digest); 150189251Ssam printf ("\nTime = %ld seconds\n", (long)(endTime-startTime)); 151189251Ssam /* 152189251Ssam * Be careful that endTime-startTime is not zero. 153189251Ssam * (Bug fix from Ric Anderson, ric@Artisoft.COM.) 154189251Ssam */ 155189251Ssam printf 156189251Ssam ("Speed = %ld bytes/second\n", 157189251Ssam (long)TEST_BLOCK_LEN * (long)TEST_BLOCK_COUNT/((endTime-startTime) != 0 ? (endTime-startTime):1)); 158189251Ssam} 159189251Ssam 160189251Ssam/* Digests a reference suite of strings and prints the results. 161189251Ssam */ 162189251Ssamstatic void MDTestSuite () 163189251Ssam{ 164189251Ssam printf ("MD%d test suite:\n", MD); 165189251Ssam 166189251Ssam MDString (""); 167189251Ssam MDString ("a"); 168189251Ssam MDString ("abc"); 169189251Ssam MDString ("message digest"); 170189251Ssam MDString ("abcdefghijklmnopqrstuvwxyz"); 171189251Ssam MDString 172189251Ssam ("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"); 173189251Ssam MDString 174189251Ssam ("1234567890123456789012345678901234567890\ 175189251Ssam1234567890123456789012345678901234567890"); 176189251Ssam} 177189251Ssam 178189251Ssam/* Digests a file and prints the result. 179189251Ssam */ 180189251Ssamstatic void MDFile (filename) 181189251Ssamchar *filename; 182189251Ssam{ 183189251Ssam FILE *file; 184189251Ssam MD_CTX context; 185189251Ssam int len; 186189251Ssam unsigned char buffer[1024], digest[16]; 187189251Ssam 188189251Ssam if ((file = fopen (filename, "rb")) == NULL) 189189251Ssam printf ("%s can't be opened\n", filename); 190189251Ssam 191189251Ssam else { 192189251Ssam MDInit (&context); 193189251Ssam while (len = fread (buffer, 1, 1024, file)) 194189251Ssam MDUpdate (&context, buffer, len); 195189251Ssam MDFinal (digest, &context); 196189251Ssam 197189251Ssam fclose (file); 198189251Ssam 199189251Ssam printf ("MD%d (%s) = ", MD, filename); 200189251Ssam MDPrint (digest); 201189251Ssam printf ("\n"); 202189251Ssam } 203189251Ssam} 204189251Ssam 205189251Ssam/* Digests the standard input and prints the result. 206189251Ssam */ 207189251Ssamstatic void MDFilter () 208189251Ssam{ 209214734Srpaulo MD_CTX context; 210214734Srpaulo int len; 211214734Srpaulo unsigned char buffer[16], digest[16]; 212214734Srpaulo 213214734Srpaulo MDInit (&context); 214214734Srpaulo while (len = fread (buffer, 1, 16, stdin)) 215189251Ssam MDUpdate (&context, buffer, len); 216189251Ssam MDFinal (digest, &context); 217189251Ssam 218189251Ssam MDPrint (digest); 219189251Ssam printf ("\n"); 220189251Ssam} 221189251Ssam 222189251Ssam/* Prints a message digest in hexadecimal. 223189251Ssam */ 224189251Ssamstatic void MDPrint (digest) 225189251Ssamunsigned char digest[16]; 226189251Ssam{ 227189251Ssam unsigned int i; 228189251Ssam 229189251Ssam for (i = 0; i < 16; i++) 230189251Ssam printf ("%02x", digest[i]); 231189251Ssam} 232189251Ssam