md5.c revision 46226
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[] =
2246226Skris	"$Id: md5.c,v 1.13 1998/07/06 07:04:50 charnier 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>
3119168Sbde
323995Spst#include "global.h"
333995Spst
346562Sphk/*
356562Sphk * Length of test block, number of test blocks.
363995Spst */
3746226Skris#define TEST_BLOCK_LEN 10000
3846226Skris#define TEST_BLOCK_COUNT 100000
393995Spst
406562Sphkstatic void MDString PROTO_LIST((char *));
416562Sphkstatic void MDTimeTrial PROTO_LIST((void));
426562Sphkstatic void MDTestSuite PROTO_LIST((void));
436725Sphkstatic void MDFilter PROTO_LIST((int));
4432074Sstevestatic void usage PROTO_LIST((void));
453995Spst
463995Spst/* Main driver.
473995Spst
483995SpstArguments (may be any combination):
493995Spst  -sstring - digests string
503995Spst  -t       - runs time trial
513995Spst  -x       - runs test script
523995Spst  filename - digests file
533995Spst  (none)   - digests standard input
543995Spst */
556562Sphkint
566562Sphkmain(argc, argv)
576562Sphk	int     argc;
586562Sphk	char   *argv[];
593995Spst{
6032086Ssteve	int     ch;
616562Sphk	char   *p;
629489Sphk	char	buf[33];
633995Spst
6432074Ssteve	if (argc > 1) {
6532086Ssteve		while ((ch = getopt(argc, argv, "ps:tx")) != -1) {
6632086Ssteve			switch (ch) {
6732074Ssteve			case 'p':
6832074Ssteve				MDFilter(1);
6932074Ssteve				break;
7032074Ssteve			case 's':
7132074Ssteve				MDString(optarg);
7232074Ssteve				break;
7332074Ssteve			case 't':
746562Sphk				MDTimeTrial();
7532074Ssteve				break;
7632074Ssteve			case 'x':
776562Sphk				MDTestSuite();
7832074Ssteve				break;
7932074Ssteve			default:
8032074Ssteve				usage();
816562Sphk			}
8232074Ssteve		}
8332074Ssteve		while (optind < argc) {
8432074Ssteve			p = MD5File(argv[optind], buf);
8532074Ssteve			if (!p)
8637421Scharnier				warn("%s", argv[optind]);
8732074Ssteve			else
8832074Ssteve				printf("MD5 (%s) = %s\n", argv[optind], p);
8932074Ssteve			optind++;
9032074Ssteve		}
9132074Ssteve	} else
926725Sphk		MDFilter(0);
933995Spst
946562Sphk	return (0);
953995Spst}
966562Sphk/*
976562Sphk * Digests a string and prints the result.
983995Spst */
996562Sphkstatic void
1006562SphkMDString(string)
1016562Sphk	char   *string;
1023995Spst{
1036562Sphk	unsigned int len = strlen(string);
1049489Sphk	char buf[33];
1053995Spst
1069489Sphk	printf("MD5 (\"%s\") = %s\n", string, MD5Data(string, len, buf));
1073995Spst}
1086562Sphk/*
1096562Sphk * Measures the time to digest TEST_BLOCK_COUNT TEST_BLOCK_LEN-byte blocks.
1103995Spst */
1116562Sphkstatic void
1126562SphkMDTimeTrial()
1133995Spst{
1146562Sphk	MD5_CTX context;
1156562Sphk	time_t  endTime, startTime;
1166725Sphk	unsigned char block[TEST_BLOCK_LEN];
1176562Sphk	unsigned int i;
1189489Sphk	char   *p, buf[33];
1193995Spst
1206562Sphk	printf
1216562Sphk	    ("MD5 time trial. Digesting %d %d-byte blocks ...",
12221763Sphk	    TEST_BLOCK_COUNT, TEST_BLOCK_LEN);
12346226Skris	fflush(stdout);
1243995Spst
1256562Sphk	/* Initialize block */
1266562Sphk	for (i = 0; i < TEST_BLOCK_LEN; i++)
1276562Sphk		block[i] = (unsigned char) (i & 0xff);
1283995Spst
1296562Sphk	/* Start timer */
1306562Sphk	time(&startTime);
1313995Spst
1326562Sphk	/* Digest blocks */
1336562Sphk	MD5Init(&context);
1346562Sphk	for (i = 0; i < TEST_BLOCK_COUNT; i++)
1356562Sphk		MD5Update(&context, block, TEST_BLOCK_LEN);
1369489Sphk	p = MD5End(&context,buf);
1373995Spst
1386562Sphk	/* Stop timer */
1396562Sphk	time(&endTime);
1403995Spst
1416562Sphk	printf(" done\n");
1426562Sphk	printf("Digest = %s", p);
1436562Sphk	printf("\nTime = %ld seconds\n", (long) (endTime - startTime));
1446562Sphk	/* Be careful that endTime-startTime is not zero. (Bug fix from Ric
1456562Sphk	 * Anderson, ric@Artisoft.COM.) */
1466562Sphk	printf
1476562Sphk	    ("Speed = %ld bytes/second\n",
1486562Sphk	    (long) TEST_BLOCK_LEN * (long) TEST_BLOCK_COUNT / ((endTime - startTime) != 0 ? (endTime - startTime) : 1));
1493995Spst}
1506562Sphk/*
1516562Sphk * Digests a reference suite of strings and prints the results.
1523995Spst */
1536562Sphkstatic void
1546562SphkMDTestSuite()
1553995Spst{
15632086Ssteve
1576562Sphk	printf("MD5 test suite:\n");
1583995Spst
1596562Sphk	MDString("");
1606562Sphk	MDString("a");
1616562Sphk	MDString("abc");
1626562Sphk	MDString("message digest");
1636562Sphk	MDString("abcdefghijklmnopqrstuvwxyz");
1646562Sphk	MDString
1656562Sphk	    ("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789");
1666562Sphk	MDString
1676562Sphk	    ("1234567890123456789012345678901234567890\
1683995Spst1234567890123456789012345678901234567890");
1693995Spst}
1703995Spst
1716562Sphk/*
1726562Sphk * Digests the standard input and prints the result.
1733995Spst */
1746562Sphkstatic void
17532086SsteveMDFilter(pipe)
17632086Ssteve	int pipe;
1773995Spst{
1786562Sphk	MD5_CTX context;
1796562Sphk	int     len;
18032074Ssteve	unsigned char buffer[BUFSIZ];
1819489Sphk	char buf[33];
1823995Spst
1836562Sphk	MD5Init(&context);
18432074Ssteve	while ((len = fread(buffer, 1, BUFSIZ, stdin))) {
18537421Scharnier		if(pipe && (len != fwrite(buffer, 1, len, stdout)))
18637421Scharnier			err(1, "stdout");
1876562Sphk		MD5Update(&context, buffer, len);
1886725Sphk	}
1899489Sphk	printf("%s\n", MD5End(&context,buf));
1903995Spst}
19132074Ssteve
19232074Sstevestatic void
19332086Ssteveusage()
19432074Ssteve{
19532086Ssteve
19632086Ssteve	fprintf(stderr, "usage: md5 [-ptx] [-s string] [files ...]\n");
19732074Ssteve	exit(1);
19832074Ssteve}
199