md5.c revision 78949
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 78949 2001-06-29 06:21:57Z des $"; 2337421Scharnier#endif /* not lint */ 2437421Scharnier 2519168Sbde#include <sys/types.h> 2637421Scharnier#include <err.h> 2719168Sbde#include <md5.h> 283995Spst#include <stdio.h> 2978949Sdes#include <stdlib.h> 3078949Sdes#include <string.h> 313995Spst#include <time.h> 3232074Ssteve#include <unistd.h> 3319168Sbde 346562Sphk/* 356562Sphk * Length of test block, number of test blocks. 363995Spst */ 3746226Skris#define TEST_BLOCK_LEN 10000 3846226Skris#define TEST_BLOCK_COUNT 100000 393995Spst 4054109Sobrienint qflag; 4152949Sobrienint rflag; 4252949Sobrien 4376988Srustatic void MDString(const char *); 4476988Srustatic void MDTimeTrial(void); 4576988Srustatic void MDTestSuite(void); 4676988Srustatic void MDFilter(int); 4776988Srustatic void usage(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 5976988Srumain(int argc, char *argv[]) 603995Spst{ 6132086Ssteve int ch; 626562Sphk char *p; 639489Sphk char buf[33]; 643995Spst 6578756Sru while ((ch = getopt(argc, argv, "pqrs:tx")) != -1) 6676988Sru switch (ch) { 6776988Sru case 'p': 6876988Sru MDFilter(1); 6976988Sru break; 7076988Sru case 'q': 7176988Sru qflag = 1; 7276988Sru break; 7376988Sru case 'r': 7476988Sru rflag = 1; 7576988Sru break; 7676988Sru case 's': 7776988Sru MDString(optarg); 7876988Sru break; 7976988Sru case 't': 8076988Sru MDTimeTrial(); 8176988Sru break; 8276988Sru case 'x': 8376988Sru MDTestSuite(); 8476988Sru break; 8576988Sru default: 8676988Sru usage(); 8732074Ssteve } 8876988Sru argc -= optind; 8976988Sru argv += optind; 9076988Sru 9176988Sru if (*argv) { 9276988Sru do { 9376988Sru p = MD5File(*argv, buf); 9432074Ssteve if (!p) 9576988Sru warn("%s", *argv); 9632074Ssteve else 9754109Sobrien if (qflag) 9854109Sobrien printf("%s\n", p); 9954109Sobrien else if (rflag) 10076988Sru printf("%s %s\n", p, *argv); 10152949Sobrien else 10276988Sru printf("MD5 (%s) = %s\n", *argv, p); 10376988Sru } while (*++argv); 10478756Sru } else if (optind == 1 || qflag || rflag) 1056725Sphk MDFilter(0); 1063995Spst 1076562Sphk return (0); 1083995Spst} 1096562Sphk/* 1106562Sphk * Digests a string and prints the result. 1113995Spst */ 1126562Sphkstatic void 11376988SruMDString(const char *string) 1143995Spst{ 11548953Sbillf size_t len = strlen(string); 1169489Sphk char buf[33]; 1173995Spst 11854109Sobrien if (qflag) 11954109Sobrien printf("%s\n", MD5Data(string, len, buf)); 12054109Sobrien else if (rflag) 12153092Sobrien printf("%s \"%s\"\n", MD5Data(string, len, buf), string); 12252949Sobrien else 12352949Sobrien printf("MD5 (\"%s\") = %s\n", string, MD5Data(string, len, buf)); 1243995Spst} 1256562Sphk/* 1266562Sphk * Measures the time to digest TEST_BLOCK_COUNT TEST_BLOCK_LEN-byte blocks. 1273995Spst */ 1286562Sphkstatic void 12976988SruMDTimeTrial(void) 1303995Spst{ 1316562Sphk MD5_CTX context; 1326562Sphk time_t endTime, startTime; 1336725Sphk unsigned char block[TEST_BLOCK_LEN]; 1346562Sphk unsigned int i; 1359489Sphk char *p, buf[33]; 1363995Spst 1376562Sphk printf 1386562Sphk ("MD5 time trial. Digesting %d %d-byte blocks ...", 13921763Sphk TEST_BLOCK_COUNT, TEST_BLOCK_LEN); 14046226Skris fflush(stdout); 1413995Spst 1426562Sphk /* Initialize block */ 1436562Sphk for (i = 0; i < TEST_BLOCK_LEN; i++) 1446562Sphk block[i] = (unsigned char) (i & 0xff); 1453995Spst 1466562Sphk /* Start timer */ 1476562Sphk time(&startTime); 1483995Spst 1496562Sphk /* Digest blocks */ 1506562Sphk MD5Init(&context); 1516562Sphk for (i = 0; i < TEST_BLOCK_COUNT; i++) 1526562Sphk MD5Update(&context, block, TEST_BLOCK_LEN); 1539489Sphk p = MD5End(&context,buf); 1543995Spst 1556562Sphk /* Stop timer */ 1566562Sphk time(&endTime); 1573995Spst 1586562Sphk printf(" done\n"); 1596562Sphk printf("Digest = %s", p); 1606562Sphk printf("\nTime = %ld seconds\n", (long) (endTime - startTime)); 1616562Sphk /* Be careful that endTime-startTime is not zero. (Bug fix from Ric 1626562Sphk * Anderson, ric@Artisoft.COM.) */ 1636562Sphk printf 1646562Sphk ("Speed = %ld bytes/second\n", 1656562Sphk (long) TEST_BLOCK_LEN * (long) TEST_BLOCK_COUNT / ((endTime - startTime) != 0 ? (endTime - startTime) : 1)); 1663995Spst} 1676562Sphk/* 1686562Sphk * Digests a reference suite of strings and prints the results. 1693995Spst */ 1706562Sphkstatic void 17176988SruMDTestSuite(void) 1723995Spst{ 17332086Ssteve 1746562Sphk printf("MD5 test suite:\n"); 1753995Spst 1766562Sphk MDString(""); 1776562Sphk MDString("a"); 1786562Sphk MDString("abc"); 1796562Sphk MDString("message digest"); 1806562Sphk MDString("abcdefghijklmnopqrstuvwxyz"); 1816562Sphk MDString 1826562Sphk ("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"); 1836562Sphk MDString 1846562Sphk ("1234567890123456789012345678901234567890\ 1853995Spst1234567890123456789012345678901234567890"); 1863995Spst} 1873995Spst 1886562Sphk/* 1896562Sphk * Digests the standard input and prints the result. 1903995Spst */ 1916562Sphkstatic void 19276988SruMDFilter(int tee) 1933995Spst{ 1946562Sphk MD5_CTX context; 19576988Sru unsigned int len; 19632074Ssteve unsigned char buffer[BUFSIZ]; 1979489Sphk char buf[33]; 1983995Spst 1996562Sphk MD5Init(&context); 20032074Ssteve while ((len = fread(buffer, 1, BUFSIZ, stdin))) { 20176988Sru if (tee && len != fwrite(buffer, 1, len, stdout)) 20237421Scharnier err(1, "stdout"); 2036562Sphk MD5Update(&context, buffer, len); 2046725Sphk } 2059489Sphk printf("%s\n", MD5End(&context,buf)); 2063995Spst} 20732074Ssteve 20832074Sstevestatic void 20976988Sruusage(void) 21032074Ssteve{ 21132086Ssteve 21268503Sobrien fprintf(stderr, "usage: md5 [-pqrtx] [-s string] [files ...]\n"); 21332074Ssteve exit(1); 21432074Ssteve} 215