md5.c revision 37421
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[] =
2237421Scharnier	"$Id$";
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 */
373995Spst#define TEST_BLOCK_LEN 1000
383995Spst#define TEST_BLOCK_COUNT 1000
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);
1233995Spst
1246562Sphk	/* Initialize block */
1256562Sphk	for (i = 0; i < TEST_BLOCK_LEN; i++)
1266562Sphk		block[i] = (unsigned char) (i & 0xff);
1273995Spst
1286562Sphk	/* Start timer */
1296562Sphk	time(&startTime);
1303995Spst
1316562Sphk	/* Digest blocks */
1326562Sphk	MD5Init(&context);
1336562Sphk	for (i = 0; i < TEST_BLOCK_COUNT; i++)
1346562Sphk		MD5Update(&context, block, TEST_BLOCK_LEN);
1359489Sphk	p = MD5End(&context,buf);
1363995Spst
1376562Sphk	/* Stop timer */
1386562Sphk	time(&endTime);
1393995Spst
1406562Sphk	printf(" done\n");
1416562Sphk	printf("Digest = %s", p);
1426562Sphk	printf("\nTime = %ld seconds\n", (long) (endTime - startTime));
1436562Sphk	/* Be careful that endTime-startTime is not zero. (Bug fix from Ric
1446562Sphk	 * Anderson, ric@Artisoft.COM.) */
1456562Sphk	printf
1466562Sphk	    ("Speed = %ld bytes/second\n",
1476562Sphk	    (long) TEST_BLOCK_LEN * (long) TEST_BLOCK_COUNT / ((endTime - startTime) != 0 ? (endTime - startTime) : 1));
1483995Spst}
1496562Sphk/*
1506562Sphk * Digests a reference suite of strings and prints the results.
1513995Spst */
1526562Sphkstatic void
1536562SphkMDTestSuite()
1543995Spst{
15532086Ssteve
1566562Sphk	printf("MD5 test suite:\n");
1573995Spst
1586562Sphk	MDString("");
1596562Sphk	MDString("a");
1606562Sphk	MDString("abc");
1616562Sphk	MDString("message digest");
1626562Sphk	MDString("abcdefghijklmnopqrstuvwxyz");
1636562Sphk	MDString
1646562Sphk	    ("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789");
1656562Sphk	MDString
1666562Sphk	    ("1234567890123456789012345678901234567890\
1673995Spst1234567890123456789012345678901234567890");
1683995Spst}
1693995Spst
1706562Sphk/*
1716562Sphk * Digests the standard input and prints the result.
1723995Spst */
1736562Sphkstatic void
17432086SsteveMDFilter(pipe)
17532086Ssteve	int pipe;
1763995Spst{
1776562Sphk	MD5_CTX context;
1786562Sphk	int     len;
17932074Ssteve	unsigned char buffer[BUFSIZ];
1809489Sphk	char buf[33];
1813995Spst
1826562Sphk	MD5Init(&context);
18332074Ssteve	while ((len = fread(buffer, 1, BUFSIZ, stdin))) {
18437421Scharnier		if(pipe && (len != fwrite(buffer, 1, len, stdout)))
18537421Scharnier			err(1, "stdout");
1866562Sphk		MD5Update(&context, buffer, len);
1876725Sphk	}
1889489Sphk	printf("%s\n", MD5End(&context,buf));
1893995Spst}
19032074Ssteve
19132074Sstevestatic void
19232086Ssteveusage()
19332074Ssteve{
19432086Ssteve
19532086Ssteve	fprintf(stderr, "usage: md5 [-ptx] [-s string] [files ...]\n");
19632074Ssteve	exit(1);
19732074Ssteve}
198