md5.c revision 53060
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[] = 2250476Speter "$FreeBSD: head/sbin/md5/md5.c 53060 1999-11-09 17:28:47Z obrien $"; 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 4152949Sobrienint rflag; 4252949Sobrien 436562Sphkstatic void MDString PROTO_LIST((char *)); 446562Sphkstatic void MDTimeTrial PROTO_LIST((void)); 456562Sphkstatic void MDTestSuite PROTO_LIST((void)); 466725Sphkstatic void MDFilter PROTO_LIST((int)); 4732074Sstevestatic void usage PROTO_LIST((void)); 483995Spst 493995Spst/* Main driver. 503995Spst 513995SpstArguments (may be any combination): 523995Spst -sstring - digests string 533995Spst -t - runs time trial 543995Spst -x - runs test script 553995Spst filename - digests file 563995Spst (none) - digests standard input 573995Spst */ 586562Sphkint 596562Sphkmain(argc, argv) 606562Sphk int argc; 616562Sphk char *argv[]; 623995Spst{ 6332086Ssteve int ch; 646562Sphk char *p; 659489Sphk char buf[33]; 663995Spst 6732074Ssteve if (argc > 1) { 6852949Sobrien while ((ch = getopt(argc, argv, "ps:rtx")) != -1) { 6932086Ssteve switch (ch) { 7032074Ssteve case 'p': 7132074Ssteve MDFilter(1); 7232074Ssteve break; 7352949Sobrien case 'r': 7452949Sobrien rflag = 1; 7552949Sobrien break; 7632074Ssteve case 's': 7732074Ssteve MDString(optarg); 7832074Ssteve break; 7932074Ssteve case 't': 806562Sphk MDTimeTrial(); 8132074Ssteve break; 8232074Ssteve case 'x': 836562Sphk MDTestSuite(); 8432074Ssteve break; 8532074Ssteve default: 8632074Ssteve usage(); 876562Sphk } 8832074Ssteve } 8932074Ssteve while (optind < argc) { 9032074Ssteve p = MD5File(argv[optind], buf); 9132074Ssteve if (!p) 9237421Scharnier warn("%s", argv[optind]); 9332074Ssteve else 9452949Sobrien if (rflag) 9553060Sobrien printf("%s %s\n", p, argv[optind]); 9652949Sobrien else 9752949Sobrien printf("MD5 (%s) = %s\n", argv[optind], 9852949Sobrien p); 9932074Ssteve optind++; 10032074Ssteve } 10132074Ssteve } else 1026725Sphk MDFilter(0); 1033995Spst 1046562Sphk return (0); 1053995Spst} 1066562Sphk/* 1076562Sphk * Digests a string and prints the result. 1083995Spst */ 1096562Sphkstatic void 1106562SphkMDString(string) 1116562Sphk char *string; 1123995Spst{ 11348953Sbillf size_t len = strlen(string); 1149489Sphk char buf[33]; 1153995Spst 11652949Sobrien if (rflag) 11753060Sobrien printf("%s (\"%s\")\n", MD5Data(string, len, buf), string); 11852949Sobrien else 11952949Sobrien printf("MD5 (\"%s\") = %s\n", string, MD5Data(string, len, buf)); 1203995Spst} 1216562Sphk/* 1226562Sphk * Measures the time to digest TEST_BLOCK_COUNT TEST_BLOCK_LEN-byte blocks. 1233995Spst */ 1246562Sphkstatic void 1256562SphkMDTimeTrial() 1263995Spst{ 1276562Sphk MD5_CTX context; 1286562Sphk time_t endTime, startTime; 1296725Sphk unsigned char block[TEST_BLOCK_LEN]; 1306562Sphk unsigned int i; 1319489Sphk char *p, buf[33]; 1323995Spst 1336562Sphk printf 1346562Sphk ("MD5 time trial. Digesting %d %d-byte blocks ...", 13521763Sphk TEST_BLOCK_COUNT, TEST_BLOCK_LEN); 13646226Skris fflush(stdout); 1373995Spst 1386562Sphk /* Initialize block */ 1396562Sphk for (i = 0; i < TEST_BLOCK_LEN; i++) 1406562Sphk block[i] = (unsigned char) (i & 0xff); 1413995Spst 1426562Sphk /* Start timer */ 1436562Sphk time(&startTime); 1443995Spst 1456562Sphk /* Digest blocks */ 1466562Sphk MD5Init(&context); 1476562Sphk for (i = 0; i < TEST_BLOCK_COUNT; i++) 1486562Sphk MD5Update(&context, block, TEST_BLOCK_LEN); 1499489Sphk p = MD5End(&context,buf); 1503995Spst 1516562Sphk /* Stop timer */ 1526562Sphk time(&endTime); 1533995Spst 1546562Sphk printf(" done\n"); 1556562Sphk printf("Digest = %s", p); 1566562Sphk printf("\nTime = %ld seconds\n", (long) (endTime - startTime)); 1576562Sphk /* Be careful that endTime-startTime is not zero. (Bug fix from Ric 1586562Sphk * Anderson, ric@Artisoft.COM.) */ 1596562Sphk printf 1606562Sphk ("Speed = %ld bytes/second\n", 1616562Sphk (long) TEST_BLOCK_LEN * (long) TEST_BLOCK_COUNT / ((endTime - startTime) != 0 ? (endTime - startTime) : 1)); 1623995Spst} 1636562Sphk/* 1646562Sphk * Digests a reference suite of strings and prints the results. 1653995Spst */ 1666562Sphkstatic void 1676562SphkMDTestSuite() 1683995Spst{ 16932086Ssteve 1706562Sphk printf("MD5 test suite:\n"); 1713995Spst 1726562Sphk MDString(""); 1736562Sphk MDString("a"); 1746562Sphk MDString("abc"); 1756562Sphk MDString("message digest"); 1766562Sphk MDString("abcdefghijklmnopqrstuvwxyz"); 1776562Sphk MDString 1786562Sphk ("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"); 1796562Sphk MDString 1806562Sphk ("1234567890123456789012345678901234567890\ 1813995Spst1234567890123456789012345678901234567890"); 1823995Spst} 1833995Spst 1846562Sphk/* 1856562Sphk * Digests the standard input and prints the result. 1863995Spst */ 1876562Sphkstatic void 18832086SsteveMDFilter(pipe) 18932086Ssteve int pipe; 1903995Spst{ 1916562Sphk MD5_CTX context; 1926562Sphk int len; 19332074Ssteve unsigned char buffer[BUFSIZ]; 1949489Sphk char buf[33]; 1953995Spst 1966562Sphk MD5Init(&context); 19732074Ssteve while ((len = fread(buffer, 1, BUFSIZ, stdin))) { 19837421Scharnier if(pipe && (len != fwrite(buffer, 1, len, stdout))) 19937421Scharnier err(1, "stdout"); 2006562Sphk MD5Update(&context, buffer, len); 2016725Sphk } 2029489Sphk printf("%s\n", MD5End(&context,buf)); 2033995Spst} 20432074Ssteve 20532074Sstevestatic void 20632086Ssteveusage() 20732074Ssteve{ 20832086Ssteve 20932086Ssteve fprintf(stderr, "usage: md5 [-ptx] [-s string] [files ...]\n"); 21032074Ssteve exit(1); 21132074Ssteve} 212