| 1 |
|
| 2 |
/* MDDRIVER.C - test driver for MD2, MD4 and MD5 |
| 3 |
*/ |
| 4 |
|
| 5 |
/* Copyright (C) 1990-2, RSA Data Security, Inc. Created 1990. All |
| 6 |
rights reserved. |
| 7 |
|
| 8 |
RSA Data Security, Inc. makes no representations concerning either |
| 9 |
the merchantability of this software or the suitability of this |
| 10 |
software for any particular purpose. It is provided "as is" |
| 11 |
without express or implied warranty of any kind. |
| 12 |
|
| 13 |
These notices must be retained in any copies of any part of this |
| 14 |
documentation and/or software. |
| 15 |
|
| 16 |
Additional main() function ©2024 mrw <plus@m0001a.org> |
| 17 |
*/ |
| 18 |
|
| 19 |
/* The following makes MD default to MD5 if it has not already been |
| 20 |
defined with C compiler flags. |
| 21 |
*/ |
| 22 |
#ifndef MD |
| 23 |
#define MD 5 |
| 24 |
#endif |
| 25 |
|
| 26 |
#include <stdio.h> |
| 27 |
#include <time.h> |
| 28 |
#include <string.h> |
| 29 |
#include "global.h" |
| 30 |
#if MD == 2 |
| 31 |
#include "md2.h" |
| 32 |
#endif |
| 33 |
#if MD == 4 |
| 34 |
#include "md4.h" |
| 35 |
#endif |
| 36 |
#if MD == 5 |
| 37 |
#include "md5.h" |
| 38 |
#endif |
| 39 |
|
| 40 |
/* for ccommand - mrw */ |
| 41 |
#include <console.h> |
| 42 |
|
| 43 |
/* Length of test block, number of test blocks. |
| 44 |
*/ |
| 45 |
#define TEST_BLOCK_LEN 1000 |
| 46 |
#define TEST_BLOCK_COUNT 1000 |
| 47 |
|
| 48 |
static void MDString PROTO_LIST ((char *, unsigned char [16])); |
| 49 |
static void MDTimeTrial PROTO_LIST ((void)); |
| 50 |
static void MDTestSuite PROTO_LIST ((void)); |
| 51 |
static void MDFile PROTO_LIST ((char *)); |
| 52 |
static void MDFilter PROTO_LIST ((void)); |
| 53 |
static void MDPrint PROTO_LIST ((unsigned char [16])); |
| 54 |
|
| 55 |
#if MD == 2 |
| 56 |
#define MD_CTX MD2_CTX |
| 57 |
#define MDInit MD2Init |
| 58 |
#define MDUpdate MD2Update |
| 59 |
#define MDFinal MD2Final |
| 60 |
#endif |
| 61 |
#if MD == 4 |
| 62 |
#define MD_CTX MD4_CTX |
| 63 |
#define MDInit MD4Init |
| 64 |
#define MDUpdate MD4Update |
| 65 |
#define MDFinal MD4Final |
| 66 |
#endif |
| 67 |
#if MD == 5 |
| 68 |
#define MD_CTX MD5_CTX |
| 69 |
#define MDInit MD5Init |
| 70 |
#define MDUpdate MD5Update |
| 71 |
#define MDFinal MD5Final |
| 72 |
#endif |
| 73 |
|
| 74 |
|
| 75 |
/* Main driver. |
| 76 |
|
| 77 |
Arguments (may be any combination): |
| 78 |
-sstring - digests string |
| 79 |
-t - runs time trial |
| 80 |
-x - runs test script |
| 81 |
filename - digests file |
| 82 |
(none) - digests standard input |
| 83 |
*/ |
| 84 |
int main (argc, argv) |
| 85 |
int argc; |
| 86 |
char *argv[]; |
| 87 |
{ |
| 88 |
int i; |
| 89 |
|
| 90 |
argc = ccommand(&argv); |
| 91 |
|
| 92 |
if (argc > 1) |
| 93 |
for (i = 1; i < argc; i++) |
| 94 |
if (argv[i][0] == '-' && argv[i][1] == 's') |
| 95 |
MDString (argv[i] + 2, NULL); |
| 96 |
else if (strcmp (argv[i], "-t") == 0) |
| 97 |
MDTimeTrial (); |
| 98 |
else if (strcmp (argv[i], "-x") == 0) |
| 99 |
MDTestSuite (); |
| 100 |
else |
| 101 |
MDFile (argv[i]); |
| 102 |
else |
| 103 |
MDFilter (); |
| 104 |
|
| 105 |
return (0); |
| 106 |
} |
| 107 |
/* Added so MDTestSuite can check output - mrw |
| 108 |
*/ |
| 109 |
static int MDEqual(unsigned char a[16], unsigned char b[16]) |
| 110 |
{ |
| 111 |
int i; |
| 112 |
for (i = 0; i < sizeof(a); i++) { |
| 113 |
if (a[i] != b[i]) |
| 114 |
return 0; |
| 115 |
} |
| 116 |
|
| 117 |
return 1; |
| 118 |
} |
| 119 |
|
| 120 |
/* Digests a string and prints the result. |
| 121 |
* |
| 122 |
* Extended to check expected digest. |
| 123 |
*/ |
| 124 |
static void MDString (string, expected) |
| 125 |
char *string; |
| 126 |
unsigned char expected[16]; |
| 127 |
{ |
| 128 |
MD_CTX context; |
| 129 |
unsigned char digest[16]; |
| 130 |
unsigned int len = strlen (string); |
| 131 |
|
| 132 |
MDInit (&context); |
| 133 |
MDUpdate (&context, (unsigned char *)string, len); |
| 134 |
MDFinal (digest, &context); |
| 135 |
|
| 136 |
printf ("MD%d (\"%s\") = ", MD, string); |
| 137 |
MDPrint (digest); |
| 138 |
|
| 139 |
if (expected && !MDEqual(digest, expected)) { |
| 140 |
printf(" ** FAIL **"); |
| 141 |
} |
| 142 |
|
| 143 |
printf ("\n"); |
| 144 |
} |
| 145 |
|
| 146 |
/* Measures the time to digest TEST_BLOCK_COUNT TEST_BLOCK_LEN-byte |
| 147 |
blocks. |
| 148 |
*/ |
| 149 |
static void MDTimeTrial () |
| 150 |
{ |
| 151 |
MD_CTX context; |
| 152 |
time_t endTime, startTime; |
| 153 |
unsigned char block[TEST_BLOCK_LEN], digest[16]; |
| 154 |
unsigned int i; |
| 155 |
|
| 156 |
printf |
| 157 |
("MD%d time trial. Digesting %d %d-byte blocks ...", MD, |
| 158 |
TEST_BLOCK_LEN, TEST_BLOCK_COUNT); |
| 159 |
|
| 160 |
/* Initialize block */ |
| 161 |
for (i = 0; i < TEST_BLOCK_LEN; i++) |
| 162 |
block[i] = (unsigned char)(i & 0xff); |
| 163 |
|
| 164 |
/* Start timer */ |
| 165 |
time (&startTime); |
| 166 |
|
| 167 |
/* Digest blocks */ |
| 168 |
MDInit (&context); |
| 169 |
for (i = 0; i < TEST_BLOCK_COUNT; i++) |
| 170 |
MDUpdate (&context, block, TEST_BLOCK_LEN); |
| 171 |
MDFinal (digest, &context); |
| 172 |
|
| 173 |
/* Stop timer */ |
| 174 |
time (&endTime); |
| 175 |
|
| 176 |
printf (" done\n"); |
| 177 |
printf ("Digest = "); |
| 178 |
MDPrint (digest); |
| 179 |
printf ("\nTime = %ld seconds\n", (long)(endTime-startTime)); |
| 180 |
printf |
| 181 |
("Speed = %ld bytes/second\n", |
| 182 |
(long)TEST_BLOCK_LEN * (long)TEST_BLOCK_COUNT/(endTime-startTime)); |
| 183 |
} |
| 184 |
|
| 185 |
/* Digests a reference suite of strings and prints the results. |
| 186 |
*/ |
| 187 |
static void MDTestSuite () |
| 188 |
{ |
| 189 |
unsigned char digests[7][16] = { |
| 190 |
{ 0xD4, 0x1D, 0x8C, 0xD9, 0x8F, 0x00, 0xB2, 0x04, 0xE9, 0x80, 0x09, 0x98, 0xEC, 0xF8, 0x42, 0x7E }, |
| 191 |
{ 0x0C, 0xC1, 0x75, 0xB9, 0xC0, 0xF1, 0xB6, 0xA8, 0x31, 0xC3, 0x99, 0xE2, 0x69, 0x77, 0x26, 0x61 }, |
| 192 |
{ 0x90, 0x01, 0x50, 0x98, 0x3C, 0xD2, 0x4F, 0xB0, 0xD6, 0x96, 0x3F, 0x7D, 0x28, 0xE1, 0x7F, 0x72 }, |
| 193 |
{ 0xF9, 0x6B, 0x69, 0x7D, 0x7C, 0xB7, 0x93, 0x8D, 0x52, 0x5A, 0x2F, 0x31, 0xAA, 0xF1, 0x61, 0xD0 }, |
| 194 |
{ 0xC3, 0xFC, 0xD3, 0xD7, 0x61, 0x92, 0xE4, 0x00, 0x7D, 0xFB, 0x49, 0x6C, 0xCA, 0x67, 0xE1, 0x3B }, |
| 195 |
{ 0xD1, 0x74, 0xAB, 0x98, 0xD2, 0x77, 0xD9, 0xF5, 0xA5, 0x61, 0x1C, 0x2C, 0x9F, 0x41, 0x9D, 0x9F }, |
| 196 |
{ 0x57, 0xED, 0xF4, 0xA2, 0x2B, 0xE3, 0xC9, 0x55, 0xAC, 0x49, 0xDA, 0x2E, 0x21, 0x07, 0xB6, 0x7A }, |
| 197 |
}; |
| 198 |
|
| 199 |
printf ("MD%d test suite:\n", MD); |
| 200 |
|
| 201 |
|
| 202 |
MDString ("", digests[0]); |
| 203 |
MDString ("a", digests[1]); |
| 204 |
MDString ("abc", digests[2]); |
| 205 |
MDString ("message digest", digests[3]); |
| 206 |
MDString ("abcdefghijklmnopqrstuvwxyz", digests[4]); |
| 207 |
MDString |
| 208 |
("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789", |
| 209 |
digests[5]); |
| 210 |
MDString |
| 211 |
("1234567890123456789012345678901234567890\ |
| 212 |
1234567890123456789012345678901234567890", |
| 213 |
digests[6]); |
| 214 |
} |
| 215 |
|
| 216 |
/* Digests a file and prints the result. |
| 217 |
*/ |
| 218 |
static void MDFile (filename) |
| 219 |
char *filename; |
| 220 |
{ |
| 221 |
FILE *file; |
| 222 |
MD_CTX context; |
| 223 |
int len; |
| 224 |
unsigned char buffer[1024], digest[16]; |
| 225 |
|
| 226 |
if ((file = fopen (filename, "rb")) == NULL) |
| 227 |
printf ("%s can't be opened\n", filename); |
| 228 |
|
| 229 |
else { |
| 230 |
MDInit (&context); |
| 231 |
while (len = fread (buffer, 1, 1024, file)) |
| 232 |
MDUpdate (&context, buffer, len); |
| 233 |
MDFinal (digest, &context); |
| 234 |
|
| 235 |
fclose (file); |
| 236 |
|
| 237 |
printf ("MD%d (%s) = ", MD, filename); |
| 238 |
MDPrint (digest); |
| 239 |
printf ("\n"); |
| 240 |
} |
| 241 |
} |
| 242 |
|
| 243 |
/* Digests the standard input and prints the result. |
| 244 |
*/ |
| 245 |
static void MDFilter () |
| 246 |
{ |
| 247 |
MD_CTX context; |
| 248 |
int len; |
| 249 |
unsigned char buffer[16], digest[16]; |
| 250 |
|
| 251 |
MDInit (&context); |
| 252 |
while (len = fread (buffer, 1, 16, stdin)) |
| 253 |
MDUpdate (&context, buffer, len); |
| 254 |
MDFinal (digest, &context); |
| 255 |
|
| 256 |
MDPrint (digest); |
| 257 |
printf ("\n"); |
| 258 |
} |
| 259 |
|
| 260 |
/* Prints a message digest in hexadecimal. |
| 261 |
*/ |
| 262 |
static void MDPrint (digest) |
| 263 |
unsigned char digest[16]; |
| 264 |
{ |
| 265 |
unsigned int i; |
| 266 |
|
| 267 |
for (i = 0; i < 16; i++) |
| 268 |
printf ("%02x", digest[i]); |
| 269 |
} |