diff options
Diffstat (limited to 'sbin/md5/md5.c')
-rw-r--r-- | sbin/md5/md5.c | 181 |
1 files changed, 134 insertions, 47 deletions
diff --git a/sbin/md5/md5.c b/sbin/md5/md5.c index 9fd0cf8..8672d3f 100644 --- a/sbin/md5/md5.c +++ b/sbin/md5/md5.c @@ -25,6 +25,8 @@ __FBSDID("$FreeBSD$"); #include <sys/resource.h> #include <err.h> #include <md5.h> +#include <ripemd.h> +#include <sha.h> #include <stdio.h> #include <stdlib.h> #include <string.h> @@ -36,16 +38,66 @@ __FBSDID("$FreeBSD$"); */ #define TEST_BLOCK_LEN 10000 #define TEST_BLOCK_COUNT 100000 +#define MDTESTCOUNT 8 int qflag; int rflag; int sflag; -static void MDString(const char *); -static void MDTimeTrial(void); -static void MDTestSuite(void); -static void MDFilter(int); -static void usage(void); +typedef void (DIGEST_Init)(void *); +typedef void (DIGEST_Update)(void *, const unsigned char *, size_t); +typedef char *(DIGEST_End)(void *, char *); + +extern const char *MD5TestOutput[MDTESTCOUNT]; +extern const char *SHA1_TestOutput[MDTESTCOUNT]; +extern const char *RIPEMD160_TestOutput[MDTESTCOUNT]; + +typedef struct Algorithm_t { + const char *progname; + const char *name; + const char *(*TestOutput)[MDTESTCOUNT]; + DIGEST_Init *Init; + DIGEST_Update *Update; + DIGEST_End *End; + char *(*Data)(const unsigned char *, unsigned int, char *); + char *(*File)(const char *, char *); +} Algorithm_t; + +static void MD5_Update(MD5_CTX *, const unsigned char *, size_t); +static void MDString(Algorithm_t *, const char *); +static void MDTimeTrial(Algorithm_t *); +static void MDTestSuite(Algorithm_t *); +static void MDFilter(Algorithm_t *, int); +static void usage(Algorithm_t *); + +typedef union { + MD5_CTX md5; + SHA1_CTX sha1; + RIPEMD160_CTX ripemd160; +} DIGEST_CTX; + +/* max(MD5_DIGEST_LENGTH, SHA_DIGEST_LENGTH, RIPEMD160_DIGEST_LENGTH)*2+1 */ +#define HEX_DIGEST_LENGTH 41 + +/* algorithm function table */ + +struct Algorithm_t Algorithm[] = { + { "md5", "MD5", &MD5TestOutput, (DIGEST_Init*)&MD5Init, + (DIGEST_Update*)&MD5_Update, (DIGEST_End*)&MD5End, + &MD5Data, &MD5File }, + { "sha1", "SHA1", &SHA1_TestOutput, (DIGEST_Init*)&SHA1_Init, + (DIGEST_Update*)&SHA1_Update, (DIGEST_End*)&SHA1_End, + &SHA1_Data, &SHA1_File }, + { "rmd160", "RMD160", &RIPEMD160_TestOutput, + (DIGEST_Init*)&RIPEMD160_Init, (DIGEST_Update*)&RIPEMD160_Update, + (DIGEST_End*)&RIPEMD160_End, &RIPEMD160_Data, &RIPEMD160_File } +}; + +static void +MD5_Update(MD5_CTX *c, const unsigned char *data, size_t len) +{ + MD5Update(c, data, len); +} /* Main driver. @@ -61,14 +113,28 @@ main(int argc, char *argv[]) { int ch; char *p; - char buf[33]; + char buf[HEX_DIGEST_LENGTH]; int failed; + unsigned digest; + const char* progname; + + if ((progname = strrchr(argv[0], '/')) == NULL) + progname = argv[0]; + else + progname++; + + for (digest = 0; digest < sizeof(Algorithm)/sizeof(*Algorithm); digest++) + if (strcasecmp(Algorithm[digest].progname, progname) == 0) + break; + + if (Algorithm[digest].progname == NULL) + digest = 0; failed = 0; while ((ch = getopt(argc, argv, "pqrs:tx")) != -1) switch (ch) { case 'p': - MDFilter(1); + MDFilter(&Algorithm[digest], 1); break; case 'q': qflag = 1; @@ -78,23 +144,23 @@ main(int argc, char *argv[]) break; case 's': sflag = 1; - MDString(optarg); + MDString(&Algorithm[digest], optarg); break; case 't': - MDTimeTrial(); + MDTimeTrial(&Algorithm[digest]); break; case 'x': - MDTestSuite(); + MDTestSuite(&Algorithm[digest]); break; default: - usage(); + usage(&Algorithm[digest]); } argc -= optind; argv += optind; if (*argv) { do { - p = MD5File(*argv, buf); + p = Algorithm[digest].File(*argv, buf); if (!p) { warn("%s", *argv); failed++; @@ -104,11 +170,11 @@ main(int argc, char *argv[]) else if (rflag) printf("%s %s\n", p, *argv); else - printf("MD5 (%s) = %s\n", *argv, p); + printf("%s (%s) = %s\n", Algorithm[digest].name, *argv, p); } } while (*++argv); } else if (!sflag && (optind == 1 || qflag || rflag)) - MDFilter(0); + MDFilter(&Algorithm[digest], 0); if (failed != 0) return (1); @@ -119,35 +185,35 @@ main(int argc, char *argv[]) * Digests a string and prints the result. */ static void -MDString(const char *string) +MDString(Algorithm_t *alg, const char *string) { size_t len = strlen(string); - char buf[33]; + char buf[HEX_DIGEST_LENGTH]; if (qflag) - printf("%s\n", MD5Data(string, len, buf)); + printf("%s\n", alg->Data(string, len, buf)); else if (rflag) - printf("%s \"%s\"\n", MD5Data(string, len, buf), string); + printf("%s \"%s\"\n", alg->Data(string, len, buf), string); else - printf("MD5 (\"%s\") = %s\n", string, MD5Data(string, len, buf)); + printf("%s (\"%s\") = %s\n", alg->name, string, alg->Data(string, len, buf)); } /* * Measures the time to digest TEST_BLOCK_COUNT TEST_BLOCK_LEN-byte blocks. */ static void -MDTimeTrial(void) +MDTimeTrial(Algorithm_t *alg) { - MD5_CTX context; + DIGEST_CTX context; struct rusage before, after; struct timeval total; float seconds; unsigned char block[TEST_BLOCK_LEN]; unsigned int i; - char *p, buf[33]; + char *p, buf[HEX_DIGEST_LENGTH]; printf - ("MD5 time trial. Digesting %d %d-byte blocks ...", - TEST_BLOCK_COUNT, TEST_BLOCK_LEN); + ("%s time trial. Digesting %d %d-byte blocks ...", + alg->name, TEST_BLOCK_COUNT, TEST_BLOCK_LEN); fflush(stdout); /* Initialize block */ @@ -158,10 +224,10 @@ MDTimeTrial(void) getrusage(0, &before); /* Digest blocks */ - MD5Init(&context); + alg->Init(&context); for (i = 0; i < TEST_BLOCK_COUNT; i++) - MD5Update(&context, block, TEST_BLOCK_LEN); - p = MD5End(&context,buf); + alg->Update(&context, block, TEST_BLOCK_LEN); + p = alg->End(&context, buf); /* Stop timer */ getrusage(0, &after); @@ -179,9 +245,7 @@ MDTimeTrial(void) * Digests a reference suite of strings and prints the results. */ -#define MD5TESTCOUNT 8 - -char *MDTestInput[] = { +const char *MDTestInput[MDTESTCOUNT] = { "", "a", "abc", @@ -189,10 +253,11 @@ char *MDTestInput[] = { "abcdefghijklmnopqrstuvwxyz", "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789", "12345678901234567890123456789012345678901234567890123456789012345678901234567890", - "MD5 has not yet (2001-09-03) been broken, but sufficient attacks have been made that its security is in some doubt" + "MD5 has not yet (2001-09-03) been broken, but sufficient attacks have been made \ +that its security is in some doubt" }; -char *MDTestOutput[MD5TESTCOUNT] = { +const char *MD5TestOutput[MDTESTCOUNT] = { "d41d8cd98f00b204e9800998ecf8427e", "0cc175b9c0f1b6a831c399e269772661", "900150983cd24fb0d6963f7d28e17f72", @@ -203,17 +268,39 @@ char *MDTestOutput[MD5TESTCOUNT] = { "b50663f41d44d92171cb9976bc118538" }; +const char *SHA1_TestOutput[MDTESTCOUNT] = { + "da39a3ee5e6b4b0d3255bfef95601890afd80709", + "86f7e437faa5a7fce15d1ddcb9eaeaea377667b8", + "a9993e364706816aba3e25717850c26c9cd0d89d", + "c12252ceda8be8994d5fa0290a47231c1d16aae3", + "32d10c7b8cf96570ca04ce37f2a19d84240d3a89", + "761c457bf73b14d27e9e9265c46f4b4dda11f940", + "50abf5706a150990a08b2c5ea40fa0e585554732", + "18eca4333979c4181199b7b4fab8786d16cf2846" +}; + +const char *RIPEMD160_TestOutput[MDTESTCOUNT] = { + "9c1185a5c5e9fc54612808977ee8f548b2258d31", + "0bdc9d2d256b3ee9daae347be6f4dc835a467ffe", + "8eb208f7e05d987a9b044a8e98c6b087f15a0bfc", + "5d0689ef49d2fae572b881b123a85ffa21595f36", + "f71c27109c692c1b56bbdceb5b9d2865b3708dbc", + "b0e20b6e3116640286ed3a87a5713079b21f5189", + "9b752e45573d4b39f4dbd3323cab82bf63326bfb", + "5feb69c6bf7c29d95715ad55f57d8ac5b2b7dd32" +}; + static void -MDTestSuite(void) +MDTestSuite(Algorithm_t *alg) { int i; - char buffer[33]; + char buffer[HEX_DIGEST_LENGTH]; - printf("MD5 test suite:\n"); - for (i = 0; i < MD5TESTCOUNT; i++) { - MD5Data(MDTestInput[i], strlen(MDTestInput[i]), buffer); - printf("MD5 (\"%s\") = %s", MDTestInput[i], buffer); - if (strcmp(buffer, MDTestOutput[i]) == 0) + printf("%s test suite:\n", alg->name); + for (i = 0; i < MDTESTCOUNT; i++) { + (*alg->Data)(MDTestInput[i], strlen(MDTestInput[i]), buffer); + printf("%s (\"%s\") = %s", alg->name, MDTestInput[i], buffer); + if (strcmp(buffer, (*alg->TestOutput)[i]) == 0) printf(" - verified correct\n"); else printf(" - INCORRECT RESULT!\n"); @@ -224,26 +311,26 @@ MDTestSuite(void) * Digests the standard input and prints the result. */ static void -MDFilter(int tee) +MDFilter(Algorithm_t *alg, int tee) { - MD5_CTX context; + DIGEST_CTX context; unsigned int len; unsigned char buffer[BUFSIZ]; - char buf[33]; + char buf[HEX_DIGEST_LENGTH]; - MD5Init(&context); + alg->Init(&context); while ((len = fread(buffer, 1, BUFSIZ, stdin))) { if (tee && len != fwrite(buffer, 1, len, stdout)) err(1, "stdout"); - MD5Update(&context, buffer, len); + alg->Update(&context, buffer, len); } - printf("%s\n", MD5End(&context,buf)); + printf("%s\n", alg->End(&context, buf)); } static void -usage(void) +usage(Algorithm_t *alg) { - fprintf(stderr, "usage: md5 [-pqrtx] [-s string] [files ...]\n"); + fprintf(stderr, "usage: %s [-pqrtx] [-s string] [files ...]\n", alg->progname); exit(1); } |