md5.c revision 54109
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 54109 1999-12-04 01:29:43Z 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 4154109Sobrienint qflag; 4252949Sobrienint rflag; 4352949Sobrien 446562Sphkstatic void MDString PROTO_LIST((char *)); 456562Sphkstatic void MDTimeTrial PROTO_LIST((void)); 466562Sphkstatic void MDTestSuite PROTO_LIST((void)); 476725Sphkstatic void MDFilter PROTO_LIST((int)); 4832074Sstevestatic void usage PROTO_LIST((void)); 493995Spst 503995Spst/* Main driver. 513995Spst 523995SpstArguments (may be any combination): 533995Spst -sstring - digests string 543995Spst -t - runs time trial 553995Spst -x - runs test script 563995Spst filename - digests file 573995Spst (none) - digests standard input 583995Spst */ 596562Sphkint 606562Sphkmain(argc, argv) 616562Sphk int argc; 626562Sphk char *argv[]; 633995Spst{ 6432086Ssteve int ch; 656562Sphk char *p; 669489Sphk char buf[33]; 673995Spst 6832074Ssteve if (argc > 1) { 6954109Sobrien while ((ch = getopt(argc, argv, "ps:qrtx")) != -1) { 7032086Ssteve switch (ch) { 7132074Ssteve case 'p': 7232074Ssteve MDFilter(1); 7332074Ssteve break; 7454109Sobrien case 'q': 7554109Sobrien qflag = 1; 7654109Sobrien break; 7752949Sobrien case 'r': 7852949Sobrien rflag = 1; 7952949Sobrien break; 8032074Ssteve case 's': 8132074Ssteve MDString(optarg); 8232074Ssteve break; 8332074Ssteve case 't': 846562Sphk MDTimeTrial(); 8532074Ssteve break; 8632074Ssteve case 'x': 876562Sphk MDTestSuite(); 8832074Ssteve break; 8932074Ssteve default: 9032074Ssteve usage(); 916562Sphk } 9232074Ssteve } 9332074Ssteve while (optind < argc) { 9432074Ssteve p = MD5File(argv[optind], buf); 9532074Ssteve if (!p) 9637421Scharnier warn("%s", argv[optind]); 9732074Ssteve else 9854109Sobrien if (qflag) 9954109Sobrien printf("%s\n", p); 10054109Sobrien else if (rflag) 10153060Sobrien printf("%s %s\n", p, argv[optind]); 10252949Sobrien else 10352949Sobrien printf("MD5 (%s) = %s\n", argv[optind], 10452949Sobrien p); 10532074Ssteve optind++; 10632074Ssteve } 10732074Ssteve } else 1086725Sphk MDFilter(0); 1093995Spst 1106562Sphk return (0); 1113995Spst} 1126562Sphk/* 1136562Sphk * Digests a string and prints the result. 1143995Spst */ 1156562Sphkstatic void 1166562SphkMDString(string) 1176562Sphk char *string; 1183995Spst{ 11948953Sbillf size_t len = strlen(string); 1209489Sphk char buf[33]; 1213995Spst 12254109Sobrien if (qflag) 12354109Sobrien printf("%s\n", MD5Data(string, len, buf)); 12454109Sobrien else if (rflag) 12553092Sobrien printf("%s \"%s\"\n", MD5Data(string, len, buf), string); 12652949Sobrien else 12752949Sobrien printf("MD5 (\"%s\") = %s\n", string, MD5Data(string, len, buf)); 1283995Spst} 1296562Sphk/* 1306562Sphk * Measures the time to digest TEST_BLOCK_COUNT TEST_BLOCK_LEN-byte blocks. 1313995Spst */ 1326562Sphkstatic void 1336562SphkMDTimeTrial() 1343995Spst{ 1356562Sphk MD5_CTX context; 1366562Sphk time_t endTime, startTime; 1376725Sphk unsigned char block[TEST_BLOCK_LEN]; 1386562Sphk unsigned int i; 1399489Sphk char *p, buf[33]; 1403995Spst 1416562Sphk printf 1426562Sphk ("MD5 time trial. Digesting %d %d-byte blocks ...", 14321763Sphk TEST_BLOCK_COUNT, TEST_BLOCK_LEN); 14446226Skris fflush(stdout); 1453995Spst 1466562Sphk /* Initialize block */ 1476562Sphk for (i = 0; i < TEST_BLOCK_LEN; i++) 1486562Sphk block[i] = (unsigned char) (i & 0xff); 1493995Spst 1506562Sphk /* Start timer */ 1516562Sphk time(&startTime); 1523995Spst 1536562Sphk /* Digest blocks */ 1546562Sphk MD5Init(&context); 1556562Sphk for (i = 0; i < TEST_BLOCK_COUNT; i++) 1566562Sphk MD5Update(&context, block, TEST_BLOCK_LEN); 1579489Sphk p = MD5End(&context,buf); 1583995Spst 1596562Sphk /* Stop timer */ 1606562Sphk time(&endTime); 1613995Spst 1626562Sphk printf(" done\n"); 1636562Sphk printf("Digest = %s", p); 1646562Sphk printf("\nTime = %ld seconds\n", (long) (endTime - startTime)); 1656562Sphk /* Be careful that endTime-startTime is not zero. (Bug fix from Ric 1666562Sphk * Anderson, ric@Artisoft.COM.) */ 1676562Sphk printf 1686562Sphk ("Speed = %ld bytes/second\n", 1696562Sphk (long) TEST_BLOCK_LEN * (long) TEST_BLOCK_COUNT / ((endTime - startTime) != 0 ? (endTime - startTime) : 1)); 1703995Spst} 1716562Sphk/* 1726562Sphk * Digests a reference suite of strings and prints the results. 1733995Spst */ 1746562Sphkstatic void 1756562SphkMDTestSuite() 1763995Spst{ 17732086Ssteve 1786562Sphk printf("MD5 test suite:\n"); 1793995Spst 1806562Sphk MDString(""); 1816562Sphk MDString("a"); 1826562Sphk MDString("abc"); 1836562Sphk MDString("message digest"); 1846562Sphk MDString("abcdefghijklmnopqrstuvwxyz"); 1856562Sphk MDString 1866562Sphk ("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"); 1876562Sphk MDString 1886562Sphk ("1234567890123456789012345678901234567890\ 1893995Spst1234567890123456789012345678901234567890"); 1903995Spst} 1913995Spst 1926562Sphk/* 1936562Sphk * Digests the standard input and prints the result. 1943995Spst */ 1956562Sphkstatic void 19632086SsteveMDFilter(pipe) 19732086Ssteve int pipe; 1983995Spst{ 1996562Sphk MD5_CTX context; 2006562Sphk int len; 20132074Ssteve unsigned char buffer[BUFSIZ]; 2029489Sphk char buf[33]; 2033995Spst 2046562Sphk MD5Init(&context); 20532074Ssteve while ((len = fread(buffer, 1, BUFSIZ, stdin))) { 20637421Scharnier if(pipe && (len != fwrite(buffer, 1, len, stdout))) 20737421Scharnier err(1, "stdout"); 2086562Sphk MD5Update(&context, buffer, len); 2096725Sphk } 2109489Sphk printf("%s\n", MD5End(&context,buf)); 2113995Spst} 21232074Ssteve 21332074Sstevestatic void 21432086Ssteveusage() 21532074Ssteve{ 21632086Ssteve 21732086Ssteve fprintf(stderr, "usage: md5 [-ptx] [-s string] [files ...]\n"); 21832074Ssteve exit(1); 21932074Ssteve} 220