1 /* $NetBSD: md5.c,v 1.10 2008/12/29 00:51:29 christos Exp $ */ 2 3 /* 4 * MDDRIVER.C - test driver for MD2, MD4 and MD5 5 */ 6 7 /* 8 * Copyright (C) 1990-2, RSA Data Security, Inc. Created 1990. All 9 * rights reserved. 10 * 11 * RSA Data Security, Inc. makes no representations concerning either 12 * the merchantability of this software or the suitability of this 13 * software for any particular purpose. It is provided "as is" 14 * without express or implied warranty of any kind. 15 * 16 * These notices must be retained in any copies of any part of this 17 * documentation and/or software. 18 */ 19 20 #if HAVE_NBTOOL_CONFIG_H 21 #include "nbtool_config.h" 22 #endif 23 24 #include <sys/cdefs.h> 25 #if defined(__RCSID) && !defined(lint) 26 __RCSID("$NetBSD: md5.c,v 1.10 2008/12/29 00:51:29 christos Exp $"); 27 #endif /* not lint */ 28 29 #include <sys/types.h> 30 31 #include <err.h> 32 #include <md5.h> 33 #include <stdio.h> 34 #include <string.h> 35 #include <time.h> 36 37 void MD5Filter(int); 38 void MD5String(const char *); 39 void MD5TestSuite(void); 40 void MD5TimeTrial(void); 41 42 #ifndef HASHTYPE 43 #define HASHTYPE "MD5" 44 #endif 45 46 #ifndef HASHLEN 47 #define HASHLEN 32 48 #endif 49 50 /* 51 * Length of test block, number of test blocks. 52 */ 53 #define TEST_BLOCK_LEN 1000 54 #define TEST_BLOCK_COUNT 1000 55 56 /* 57 * Digests a string and prints the result. 58 */ 59 void 60 MD5String(const char *string) 61 { 62 unsigned int len = strlen(string); 63 char buf[HASHLEN + 1]; 64 65 printf("%s (\"%s\") = %s\n", HASHTYPE, string, 66 MD5Data((const unsigned char *)string, len, buf)); 67 } 68 69 /* 70 * Measures the time to digest TEST_BLOCK_COUNT TEST_BLOCK_LEN-byte blocks. 71 */ 72 void 73 MD5TimeTrial(void) 74 { 75 MD5_CTX context; 76 time_t endTime, startTime; 77 unsigned char block[TEST_BLOCK_LEN]; 78 unsigned int i; 79 char *p, buf[HASHLEN + 1]; 80 81 printf("%s time trial. Digesting %d %d-byte blocks ...", HASHTYPE, 82 TEST_BLOCK_LEN, TEST_BLOCK_COUNT); 83 fflush(stdout); 84 85 /* Initialize block */ 86 for (i = 0; i < TEST_BLOCK_LEN; i++) 87 block[i] = (unsigned char) (i & 0xff); 88 89 /* Start timer */ 90 time(&startTime); 91 92 /* Digest blocks */ 93 MD5Init(&context); 94 for (i = 0; i < TEST_BLOCK_COUNT; i++) 95 MD5Update(&context, block, TEST_BLOCK_LEN); 96 p = MD5End(&context,buf); 97 98 /* Stop timer */ 99 time(&endTime); 100 101 printf(" done\n"); 102 printf("Digest = %s\n", p); 103 printf("Time = %ld seconds\n", (long) (endTime - startTime)); 104 105 /* 106 * Be careful that endTime-startTime is not zero. 107 * (Bug fix from Ric * Anderson, ric@Artisoft.COM.) 108 */ 109 printf("Speed = %lld bytes/second\n", 110 (long long) TEST_BLOCK_LEN * TEST_BLOCK_COUNT / 111 ((endTime - startTime) != 0 ? (endTime - startTime) : 1)); 112 } 113 114 /* 115 * Digests a reference suite of strings and prints the results. 116 */ 117 void 118 MD5TestSuite(void) 119 { 120 printf("%s test suite:\n", HASHTYPE); 121 122 MD5String(""); 123 MD5String("a"); 124 MD5String("abc"); 125 MD5String("message digest"); 126 MD5String("abcdefghijklmnopqrstuvwxyz"); 127 MD5String("abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq"); 128 MD5String 129 ("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"); 130 MD5String 131 ("1234567890123456789012345678901234567890\ 132 1234567890123456789012345678901234567890"); 133 } 134 135 /* 136 * Digests the standard input and prints the result. 137 */ 138 void 139 MD5Filter(int pipe) 140 { 141 MD5_CTX context; 142 size_t len; 143 unsigned char buffer[BUFSIZ]; 144 char buf[HASHLEN + 1]; 145 146 MD5Init(&context); 147 while ((len = fread(buffer, (size_t)1, (size_t)BUFSIZ, stdin)) > 0) { 148 if (pipe && (len != fwrite(buffer, (size_t)1, len, stdout))) 149 err(1, "stdout"); 150 MD5Update(&context, buffer, (unsigned int)len); 151 } 152 printf("%s\n", MD5End(&context,buf)); 153 } 154