Date: Sun, 15 Jul 2001 13:40:40 +0200 (CEST) From: Anders Nordby <anders@fix.no> To: FreeBSD-gnats-submit@freebsd.org Subject: bin/28988: We need more simple message digesting tools Message-ID: <20010715114040.3C1763C8E@totem.fix.no>
next in thread | raw e-mail | index | archive | help
>Number: 28988 >Category: bin >Synopsis: We need more simple message digesting tools >Confidential: no >Severity: non-critical >Priority: low >Responsible: freebsd-bugs >State: open >Quarter: >Keywords: >Date-Required: >Class: change-request >Submitter-Id: current-users >Arrival-Date: Sun Jul 15 04:50:02 PDT 2001 >Closed-Date: >Last-Modified: >Originator: Anders Nordby >Release: FreeBSD 4.3-STABLE i386 >Organization: Fluxpod Information eXchange >Environment: 5.0-20010618-CURRENT >Description: Add tools for generating 160 bit SHA1 and RMD-160 digests. Obtained from OpenBSD. I'm sorry to break Ruslan's WARNS= 2, but I haven't been able to remove all warnings (yet). Suggestions are very welcome. Patches are relative to 5.0-20010618-CURRENT (snapshot from current.freebsd.org). Files added: sha1.1 and rmd160.1. Yes, I know openssl dgst -whatnot can do this. But the md5 program is heavily used, and thereby I think we should have sha1 and rmd160 too. >How-To-Repeat: <Code/input/activities to reproduce the problem (multiple lines)> >Fix: In src/sbin: diff -Nur md5.old/Makefile md5/Makefile --- md5.old/Makefile Tue May 22 12:33:43 2001 +++ md5/Makefile Sun Jul 15 11:52:52 2001 @@ -6,6 +6,9 @@ LDADD+= -lmd DPADD+= ${LIBMD} -WARNS= 2 +MAN= md5.1 sha1.1 rmd160.1 + +LINKS= ${BINDIR}/md5 ${BINDIR}/sha1 \ + ${BINDIR}/md5 ${BINDIR}/rmd160 .include <bsd.prog.mk> diff -Nur md5.old/md5.1 md5/md5.1 --- md5.old/md5.1 Tue Feb 13 10:52:50 2001 +++ md5/md5.1 Sun Jul 15 12:10:57 2001 @@ -54,6 +54,8 @@ .El .Sh SEE ALSO .Xr cksum 1 +.Xr sha1 1 +.Xr rmd160 1 .Rs .%A R. Rivest .%T The MD5 Message-Digest Algorithm diff -Nur md5.old/md5.c md5/md5.c --- md5.old/md5.c Tue May 22 12:33:43 2001 +++ md5/md5.c Sun Jul 15 12:34:25 2001 @@ -26,9 +26,13 @@ #include <err.h> #include <md5.h> #include <stdio.h> +#include <stdlib.h> #include <time.h> #include <unistd.h> #include <string.h> +#include <md5.h> +#include <sha.h> +#include <ripemd.h> /* * Length of test block, number of test blocks. @@ -39,32 +43,78 @@ int qflag; int rflag; -static void MDString(const char *); -static void MDTimeTrial(void); -static void MDTestSuite(void); -static void MDFilter(int); +extern char *__progname; + +static void MDString __P((const char *)); +static void MDTimeTrial __P((void *)); +static void MDTestSuite __P((void)); +static void MDFilter __P((int, void *)); static void usage(void); -/* Main driver. +int main __P((int, char *[])); + +/* + * Globals for indirection... + */ +void (*MDInit)(); +void (*MDUpdate)(); +char * (*MDEnd)(); +char * (*MDFile)(); +char * (*MDData)(); +char *MDType; -Arguments (may be any combination): - -sstring - digests string - -t - runs time trial - -x - runs test script - filename - digests file - (none) - digests standard input +/* Main driver. + * + * Arguments (may be any combination): + * -sstring - digests string + * -t - runs time trial + * -x - runs test script + * filename - digests file + * (none) - digests standard input */ int main(int argc, char *argv[]) { int ch; char *p; - char buf[33]; + char buf[41]; + void *context; + + /* What were we called as? Default to md5 */ + if (strcmp(__progname, "sha1") == 0) { + MDType = "SHA1"; + MDInit = SHA1_Init; + MDUpdate = SHA1_Update; + MDEnd = SHA1_End; + MDFile = SHA1_File; + MDData = SHA1_Data; + if ((context = malloc(sizeof(SHA1_CTX))) == NULL) + err(1, "malloc"); + } else if (strcmp(__progname, "rmd160") == 0) { + MDType = "RMD160"; + MDInit = RIPEMD160_Init; + MDUpdate = RIPEMD160_Update; + MDEnd = RIPEMD160_End; + MDFile = RIPEMD160_File; + MDData = RIPEMD160_Data; + if ((context = malloc(sizeof(RIPEMD160_CTX))) == NULL) + err(1, "malloc"); + } else { + MDType = "MD5"; + MDInit = MD5Init; + MDUpdate = MD5Update; + MDEnd = MD5End; + MDFile = MD5File; + MDData = MD5Data; + if ((context = malloc(sizeof(MD5_CTX))) == NULL) + err(1, "malloc"); + } + while ((ch = getopt(argc, argv, "ps:qrtx")) != -1) switch (ch) { case 'p': - MDFilter(1); + MDFilter(1, context); break; case 'q': qflag = 1; @@ -76,7 +126,7 @@ MDString(optarg); break; case 't': - MDTimeTrial(); + MDTimeTrial(context); break; case 'x': MDTestSuite(); @@ -89,7 +139,7 @@ if (*argv) { do { - p = MD5File(*argv, buf); + p = MDFile(*argv, buf); if (!p) warn("%s", *argv); else @@ -98,10 +148,11 @@ else if (rflag) printf("%s %s\n", p, *argv); else - printf("MD5 (%s) = %s\n", *argv, p); + (void)printf("%s (%s) = %s\n", MDType, + *argv, p); } while (*++argv); } else - MDFilter(0); + MDFilter(0, context); return (0); } @@ -109,32 +160,33 @@ * Digests a string and prints the result. */ static void -MDString(const char *string) +MDString(string) + const char *string; { size_t len = strlen(string); - char buf[33]; + char buf[41]; if (qflag) - printf("%s\n", MD5Data(string, len, buf)); + (void)printf("%s (\"%s\") = %s\n", MDType, string, + MDData(string, len, buf)); else if (rflag) - printf("%s \"%s\"\n", MD5Data(string, len, buf), string); + printf("%s \"%s\"\n", MDData(string, len, buf), string); else - printf("MD5 (\"%s\") = %s\n", string, MD5Data(string, len, buf)); + printf("MD5 (\"%s\") = %s\n", string, MDData(string, len, buf)); } /* * Measures the time to digest TEST_BLOCK_COUNT TEST_BLOCK_LEN-byte blocks. */ static void -MDTimeTrial(void) +MDTimeTrial(context) + void *context; { - MD5_CTX context; time_t endTime, startTime; unsigned char block[TEST_BLOCK_LEN]; unsigned int i; - char *p, buf[33]; + char *p, buf[41]; - printf - ("MD5 time trial. Digesting %d %d-byte blocks ...", + (void)printf("%s time trial. Digesting %d %d-byte blocks ...", MDType, TEST_BLOCK_COUNT, TEST_BLOCK_LEN); fflush(stdout); @@ -146,22 +198,23 @@ time(&startTime); /* Digest blocks */ - MD5Init(&context); + MDInit(context); for (i = 0; i < TEST_BLOCK_COUNT; i++) - MD5Update(&context, block, TEST_BLOCK_LEN); - p = MD5End(&context,buf); + MDUpdate(context, block, TEST_BLOCK_LEN); + p = MDEnd(context,buf); /* Stop timer */ time(&endTime); - printf(" done\n"); - printf("Digest = %s", p); - printf("\nTime = %ld seconds\n", (long) (endTime - startTime)); - /* Be careful that endTime-startTime is not zero. (Bug fix from Ric - * Anderson, ric@Artisoft.COM.) */ - printf - ("Speed = %ld bytes/second\n", - (long) TEST_BLOCK_LEN * (long) TEST_BLOCK_COUNT / ((endTime - startTime) != 0 ? (endTime - startTime) : 1)); + (void)printf(" done\nDigest = %s", p); + (void)printf("\nTime = %ld seconds\n", (long) (endTime - startTime)); + /* + * Be careful that endTime-startTime is not zero. (Bug fix from Ric + * Anderson, ric@Artisoft.COM.) + */ + (void)printf("Speed = %ld bytes/second\n", + (long) TEST_BLOCK_LEN * (long) TEST_BLOCK_COUNT / + ((endTime - startTime) != 0 ? (endTime - startTime) : 1)); } /* * Digests a reference suite of strings and prints the results. @@ -170,7 +223,7 @@ MDTestSuite(void) { - printf("MD5 test suite:\n"); + (void)printf("%s test suite:\n", MDType); MDString(""); MDString("a"); @@ -182,26 +235,28 @@ MDString ("1234567890123456789012345678901234567890\ 1234567890123456789012345678901234567890"); + MDString("abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq"); } /* * Digests the standard input and prints the result. */ static void -MDFilter(int tee) +MDFilter(tee, context) + int tee; + void *context; { - MD5_CTX context; unsigned int len; unsigned char buffer[BUFSIZ]; - char buf[33]; + char buf[41]; - MD5Init(&context); + MDInit(context); while ((len = fread(buffer, 1, BUFSIZ, stdin))) { if (tee && len != fwrite(buffer, 1, len, stdout)) err(1, "stdout"); - MD5Update(&context, buffer, len); + MDUpdate(context, buffer, len); } - printf("%s\n", MD5End(&context,buf)); + (void)printf("%s\n", MDEnd(context,buf)); } static void diff -Nur md5.old/rmd160.1 md5/rmd160.1 --- md5.old/rmd160.1 Thu Jan 1 01:00:00 1970 +++ md5/rmd160.1 Sun Jul 15 12:10:15 2001 @@ -0,0 +1,66 @@ +.\" $FreeBSD$ +.Dd July 15, 2001 +.Dt RMD160 1 +.Os +.Sh NAME +.Nm rmd160 +.Nd calculate a message-digest fingerprint (checksum) for a file +.Sh SYNOPSIS +.Nm +.Op Fl pqrtx +.Op Fl s Ar string +.Op Ar +.Sh DESCRIPTION +.Nm Rmd160 +takes as input a message of arbitrary length and produces +as output a 160-bit +.Dq fingerprint +or +.Dq message digest +of the input. It is conjectured that it is computationally infeasible to +produce two messages having the same message digest, or to produce any +message having a given prespecified target message digest. +The RMD-160 algorithm is intended for digital signature applications, where a +large file must be +.Dq compressed +in a secure manner before being encrypted with a private +.Pq secret +key under a public-key cryptosystem such as +.Em RSA . +.Pp +The following four options may be used in any combination and must +precede any files named on the command line. The RMD-160 +sum of each file listed on the command line is printed after the options +are processed. +.Bl -tag -width indent +.It Fl s Ar string +Print a checksum of the given +.Ar string . +.It Fl p +Echo stdin to stdout and appends the RMD160 sum to stdout. +.It Fl q +Quiet mode - only the RMD160 sum is printed out. Overrides the +.Fl r +option. +.It Fl r +Reverses the format of the output. This helps with visual diffs. Does nothing +when combined with the +.Fl ptx +options. +.It Fl t +Run a built-in time trial. +.It Fl x +Run a built-in test script. +.El +.Sh SEE ALSO +.Xr cksum 1 +.Xr md5 1 +.Xr sha1 1 +.Rs +.Pp +RMD-160 is part of the ISO draft standard "ISO/IEC DIS 10118-3" on dedicated +hash functions. +.Re +.Sh ACKNOWLEDGMENTS +This program is placed in the public domain for free general use by +RSA Data Security. diff -Nur md5.old/sha1.1 md5/sha1.1 --- md5.old/sha1.1 Thu Jan 1 01:00:00 1970 +++ md5/sha1.1 Sun Jul 15 12:05:09 2001 @@ -0,0 +1,65 @@ +.\" $FreeBSD$ +.Dd July 15, 2001 +.Dt SHA1 1 +.Os +.Sh NAME +.Nm sha1 +.Nd calculate a message-digest fingerprint (checksum) for a file +.Sh SYNOPSIS +.Nm +.Op Fl pqrtx +.Op Fl s Ar string +.Op Ar +.Sh DESCRIPTION +.Nm Sha1 +takes as input a message of arbitrary length and produces +as output a 160-bit +.Dq fingerprint +or +.Dq message digest +of the input. It is conjectured that it is computationally infeasible to +produce two messages having the same message digest, or to produce any +message having a given prespecified target message digest. +The SHA1 algorithm is intended for digital signature applications, where a +large file must be +.Dq compressed +in a secure manner before being encrypted with a private +.Pq secret +key under a public-key cryptosystem such as +.Em RSA . +.Pp +The following four options may be used in any combination and must +precede any files named on the command line. The SHA1 +sum of each file listed on the command line is printed after the options +are processed. +.Bl -tag -width indent +.It Fl s Ar string +Print a checksum of the given +.Ar string . +.It Fl p +Echo stdin to stdout and appends the SHA1 sum to stdout. +.It Fl q +Quiet mode - only the SHA1 sum is printed out. Overrides the +.Fl r +option. +.It Fl r +Reverses the format of the output. This helps with visual diffs. Does nothing +when combined with the +.Fl ptx +options. +.It Fl t +Run a built-in time trial. +.It Fl x +Run a built-in test script. +.El +.Sh SEE ALSO +.Xr cksum 1 +.Xr md5 1 +.Xr rmd160 1 +.Rs +.Re +.Pp +NIST FIPS PUB 180-1 describes the SHA-1 message-digest algorithm in detail. +.Sh ACKNOWLEDGMENTS +This program is placed in the public domain for free general use by +RSA Data Security. >Release-Note: >Audit-Trail: >Unformatted: To Unsubscribe: send mail to majordomo@FreeBSD.org with "unsubscribe freebsd-bugs" in the body of the message
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?20010715114040.3C1763C8E>