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