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>
