Skip site navigation (1)Skip section navigation (2)
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>