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