md5.c revision 48953
16562Sphk/* 237421Scharnier * Derived from: 36562Sphk * 46562Sphk * MDDRIVER.C - test driver for MD2, MD4 and MD5 53995Spst */ 63995Spst 76562Sphk/* 86562Sphk * Copyright (C) 1990-2, RSA Data Security, Inc. Created 1990. All 96562Sphk * rights reserved. 106562Sphk * 116562Sphk * RSA Data Security, Inc. makes no representations concerning either 126562Sphk * the merchantability of this software or the suitability of this 136562Sphk * software for any particular purpose. It is provided "as is" 146562Sphk * without express or implied warranty of any kind. 156562Sphk * 166562Sphk * These notices must be retained in any copies of any part of this 176562Sphk * documentation and/or software. 183995Spst */ 193995Spst 2037421Scharnier#ifndef lint 2137421Scharnierstatic const char rcsid[] = 2248953Sbillf "$Id: md5.c,v 1.14 1999/05/01 14:54:21 kris Exp $"; 2337421Scharnier#endif /* not lint */ 2437421Scharnier 2519168Sbde#include <sys/types.h> 2637421Scharnier#include <err.h> 2719168Sbde#include <md5.h> 283995Spst#include <stdio.h> 293995Spst#include <time.h> 3032074Ssteve#include <unistd.h> 3148953Sbillf#include <string.h> 3219168Sbde 333995Spst#include "global.h" 343995Spst 356562Sphk/* 366562Sphk * Length of test block, number of test blocks. 373995Spst */ 3846226Skris#define TEST_BLOCK_LEN 10000 3946226Skris#define TEST_BLOCK_COUNT 100000 403995Spst 416562Sphkstatic void MDString PROTO_LIST((char *)); 426562Sphkstatic void MDTimeTrial PROTO_LIST((void)); 436562Sphkstatic void MDTestSuite PROTO_LIST((void)); 446725Sphkstatic void MDFilter PROTO_LIST((int)); 4532074Sstevestatic void usage PROTO_LIST((void)); 463995Spst 473995Spst/* Main driver. 483995Spst 493995SpstArguments (may be any combination): 503995Spst -sstring - digests string 513995Spst -t - runs time trial 523995Spst -x - runs test script 533995Spst filename - digests file 543995Spst (none) - digests standard input 553995Spst */ 566562Sphkint 576562Sphkmain(argc, argv) 586562Sphk int argc; 596562Sphk char *argv[]; 603995Spst{ 6132086Ssteve int ch; 626562Sphk char *p; 639489Sphk char buf[33]; 643995Spst 6532074Ssteve if (argc > 1) { 6632086Ssteve while ((ch = getopt(argc, argv, "ps:tx")) != -1) { 6732086Ssteve switch (ch) { 6832074Ssteve case 'p': 6932074Ssteve MDFilter(1); 7032074Ssteve break; 7132074Ssteve case 's': 7232074Ssteve MDString(optarg); 7332074Ssteve break; 7432074Ssteve case 't': 756562Sphk MDTimeTrial(); 7632074Ssteve break; 7732074Ssteve case 'x': 786562Sphk MDTestSuite(); 7932074Ssteve break; 8032074Ssteve default: 8132074Ssteve usage(); 826562Sphk } 8332074Ssteve } 8432074Ssteve while (optind < argc) { 8532074Ssteve p = MD5File(argv[optind], buf); 8632074Ssteve if (!p) 8737421Scharnier warn("%s", argv[optind]); 8832074Ssteve else 8932074Ssteve printf("MD5 (%s) = %s\n", argv[optind], p); 9032074Ssteve optind++; 9132074Ssteve } 9232074Ssteve } else 936725Sphk MDFilter(0); 943995Spst 956562Sphk return (0); 963995Spst} 976562Sphk/* 986562Sphk * Digests a string and prints the result. 993995Spst */ 1006562Sphkstatic void 1016562SphkMDString(string) 1026562Sphk char *string; 1033995Spst{ 10448953Sbillf size_t len = strlen(string); 1059489Sphk char buf[33]; 1063995Spst 1079489Sphk printf("MD5 (\"%s\") = %s\n", string, MD5Data(string, len, buf)); 1083995Spst} 1096562Sphk/* 1106562Sphk * Measures the time to digest TEST_BLOCK_COUNT TEST_BLOCK_LEN-byte blocks. 1113995Spst */ 1126562Sphkstatic void 1136562SphkMDTimeTrial() 1143995Spst{ 1156562Sphk MD5_CTX context; 1166562Sphk time_t endTime, startTime; 1176725Sphk unsigned char block[TEST_BLOCK_LEN]; 1186562Sphk unsigned int i; 1199489Sphk char *p, buf[33]; 1203995Spst 1216562Sphk printf 1226562Sphk ("MD5 time trial. Digesting %d %d-byte blocks ...", 12321763Sphk TEST_BLOCK_COUNT, TEST_BLOCK_LEN); 12446226Skris fflush(stdout); 1253995Spst 1266562Sphk /* Initialize block */ 1276562Sphk for (i = 0; i < TEST_BLOCK_LEN; i++) 1286562Sphk block[i] = (unsigned char) (i & 0xff); 1293995Spst 1306562Sphk /* Start timer */ 1316562Sphk time(&startTime); 1323995Spst 1336562Sphk /* Digest blocks */ 1346562Sphk MD5Init(&context); 1356562Sphk for (i = 0; i < TEST_BLOCK_COUNT; i++) 1366562Sphk MD5Update(&context, block, TEST_BLOCK_LEN); 1379489Sphk p = MD5End(&context,buf); 1383995Spst 1396562Sphk /* Stop timer */ 1406562Sphk time(&endTime); 1413995Spst 1426562Sphk printf(" done\n"); 1436562Sphk printf("Digest = %s", p); 1446562Sphk printf("\nTime = %ld seconds\n", (long) (endTime - startTime)); 1456562Sphk /* Be careful that endTime-startTime is not zero. (Bug fix from Ric 1466562Sphk * Anderson, ric@Artisoft.COM.) */ 1476562Sphk printf 1486562Sphk ("Speed = %ld bytes/second\n", 1496562Sphk (long) TEST_BLOCK_LEN * (long) TEST_BLOCK_COUNT / ((endTime - startTime) != 0 ? (endTime - startTime) : 1)); 1503995Spst} 1516562Sphk/* 1526562Sphk * Digests a reference suite of strings and prints the results. 1533995Spst */ 1546562Sphkstatic void 1556562SphkMDTestSuite() 1563995Spst{ 15732086Ssteve 1586562Sphk printf("MD5 test suite:\n"); 1593995Spst 1606562Sphk MDString(""); 1616562Sphk MDString("a"); 1626562Sphk MDString("abc"); 1636562Sphk MDString("message digest"); 1646562Sphk MDString("abcdefghijklmnopqrstuvwxyz"); 1656562Sphk MDString 1666562Sphk ("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"); 1676562Sphk MDString 1686562Sphk ("1234567890123456789012345678901234567890\ 1693995Spst1234567890123456789012345678901234567890"); 1703995Spst} 1713995Spst 1726562Sphk/* 1736562Sphk * Digests the standard input and prints the result. 1743995Spst */ 1756562Sphkstatic void 17632086SsteveMDFilter(pipe) 17732086Ssteve int pipe; 1783995Spst{ 1796562Sphk MD5_CTX context; 1806562Sphk int len; 18132074Ssteve unsigned char buffer[BUFSIZ]; 1829489Sphk char buf[33]; 1833995Spst 1846562Sphk MD5Init(&context); 18532074Ssteve while ((len = fread(buffer, 1, BUFSIZ, stdin))) { 18637421Scharnier if(pipe && (len != fwrite(buffer, 1, len, stdout))) 18737421Scharnier err(1, "stdout"); 1886562Sphk MD5Update(&context, buffer, len); 1896725Sphk } 1909489Sphk printf("%s\n", MD5End(&context,buf)); 1913995Spst} 19232074Ssteve 19332074Sstevestatic void 19432086Ssteveusage() 19532074Ssteve{ 19632086Ssteve 19732086Ssteve fprintf(stderr, "usage: md5 [-ptx] [-s string] [files ...]\n"); 19832074Ssteve exit(1); 19932074Ssteve} 200