diff options
Diffstat (limited to 'lib/libmd')
-rw-r--r-- | lib/libmd/Makefile | 91 | ||||
-rw-r--r-- | lib/libmd/md2.copyright | 17 | ||||
-rw-r--r-- | lib/libmd/md2.h | 45 | ||||
-rw-r--r-- | lib/libmd/md2c.c | 208 | ||||
-rw-r--r-- | lib/libmd/md4.copyright | 20 | ||||
-rw-r--r-- | lib/libmd/md4.h | 47 | ||||
-rw-r--r-- | lib/libmd/md4c.c | 288 | ||||
-rw-r--r-- | lib/libmd/md5.copyright | 21 | ||||
-rw-r--r-- | lib/libmd/md5.h | 4 | ||||
-rw-r--r-- | lib/libmd/md5c.c | 342 | ||||
-rw-r--r-- | lib/libmd/mdX.3 | 146 | ||||
-rw-r--r-- | lib/libmd/mdXhl.c | 71 | ||||
-rw-r--r-- | lib/libmd/mddriver.c | 69 |
13 files changed, 1369 insertions, 0 deletions
diff --git a/lib/libmd/Makefile b/lib/libmd/Makefile new file mode 100644 index 0000000..96c2d0a --- /dev/null +++ b/lib/libmd/Makefile @@ -0,0 +1,91 @@ +# $Id: Makefile,v 1.24 1997/09/05 11:49:43 peter Exp $ + +LIB= md +.if ${BINFORMAT} != elf +NOPIC= true +.endif +SRCS= md2c.c md4c.c md5c.c md2hl.c md4hl.c md5hl.c +MAN3+= md2.3 md4.3 md5.3 +MLINKS+=md2.3 MD2Init.3 md2.3 MD2Update.3 md2.3 MD2Final.3 +MLINKS+=md2.3 MD2End.3 md2.3 MD2File.3 md2.3 MD2Data.3 +MLINKS+=md4.3 MD4Init.3 md4.3 MD4Update.3 md4.3 MD4Final.3 +MLINKS+=md4.3 MD4End.3 md4.3 MD4File.3 md4.3 MD4Data.3 +MLINKS+=md5.3 MD5Init.3 md5.3 MD5Update.3 md5.3 MD5Final.3 +MLINKS+=md5.3 MD5End.3 md5.3 MD5File.3 md5.3 MD5Data.3 +CLEANFILES+= md[245]hl.c md[245].ref md[245].3 mddriver +CFLAGS+= -I${.CURDIR} + +all: md2.3 md4.3 md5.3 + +md2hl.c: mdXhl.c + sed -e 's/mdX/md2/g' -e 's/MDX/MD2/g' $> > $@ + +md4hl.c: mdXhl.c + sed -e 's/mdX/md4/g' -e 's/MDX/MD4/g' $> > $@ + +md5hl.c: mdXhl.c + sed -e 's/mdX/md5/g' -e 's/MDX/MD5/g' $> > $@ + +md2.3: ${.CURDIR}/mdX.3 + sed -e 's/mdX/md2/g' -e 's/MDX/MD2/g' $> > $@ + cat ${.CURDIR}/md2.copyright >> $@ + +md4.3: ${.CURDIR}/mdX.3 + sed -e 's/mdX/md4/g' -e 's/MDX/MD4/g' $> > $@ + cat ${.CURDIR}/md4.copyright >> $@ + +md5.3: ${.CURDIR}/mdX.3 + sed -e 's/mdX/md5/g' -e 's/MDX/MD5/g' $> > $@ + cat ${.CURDIR}/md5.copyright >> $@ + +md2.ref: + echo 'MD2 test suite:' > $@ + @echo 'MD2 ("") = 8350e5a3e24c153df2275c9f80692773' >> $@ + @echo 'MD2 ("a") = 32ec01ec4a6dac72c0ab96fb34c0b5d1' >> $@ + @echo 'MD2 ("abc") = da853b0d3f88d99b30283a69e6ded6bb' >> $@ + @echo 'MD2 ("message digest") = ab4f496bfb2a530b219ff33031fe06b0' >> $@ + @echo 'MD2 ("abcdefghijklmnopqrstuvwxyz") = 4e8ddff3650292ab5a4108c3aa47940b' >> $@ + @echo 'MD2 ("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789") = da33def2a42df13975352846c30338cd' >> $@ + @echo 'MD2 ("12345678901234567890123456789012345678901234567890123456789012345678901234567890") = d5976f79d83d3a0dc9806c3c66f3efd8' >> $@ + +md4.ref: + echo 'MD4 test suite:' > $@ + @echo 'MD4 ("") = 31d6cfe0d16ae931b73c59d7e0c089c0' >> $@ + @echo 'MD4 ("a") = bde52cb31de33e46245e05fbdbd6fb24' >> $@ + @echo 'MD4 ("abc") = a448017aaf21d8525fc10ae87aa6729d' >> $@ + @echo 'MD4 ("message digest") = d9130a8164549fe818874806e1c7014b' >> $@ + @echo 'MD4 ("abcdefghijklmnopqrstuvwxyz") = d79e1c308aa5bbcdeea8ed63df412da9' >> $@ + @echo 'MD4 ("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789") = 043f8582f241db351ce627e153e7f0e4' >> $@ + @echo 'MD4 ("12345678901234567890123456789012345678901234567890123456789012345678901234567890") = e33b4ddc9c38f2199c3e7b164fcc0536' >> $@ + +md5.ref: + echo 'MD5 test suite:' > $@ + @echo 'MD5 ("") = d41d8cd98f00b204e9800998ecf8427e' >> $@ + @echo 'MD5 ("a") = 0cc175b9c0f1b6a831c399e269772661' >> $@ + @echo 'MD5 ("abc") = 900150983cd24fb0d6963f7d28e17f72' >> $@ + @echo 'MD5 ("message digest") = f96b697d7cb7938d525a2f31aaf161d0' >> $@ + @echo 'MD5 ("abcdefghijklmnopqrstuvwxyz") = c3fcd3d76192e4007dfb496cca67e13b' >> $@ + @echo 'MD5 ("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789") = d174ab98d277d9f5a5611c2c9f419d9f' >> $@ + @echo 'MD5 ("12345678901234567890123456789012345678901234567890123456789012345678901234567890") = 57edf4a22be3c955ac49da2e2107b67a' >> $@ + +test: md2.ref md4.ref md5.ref + @${ECHO} if any of these test fail, the code produces wrong results + @${ECHO} and should NOT be used. + ${CC} -static ${CFLAGS} ${LDFLAGS} -DMD=2 -o mddriver ${.CURDIR}/mddriver.c -L. -lmd + ./mddriver | cmp md2.ref - + @${ECHO} MD2 passed test + ${CC} -static ${CFLAGS} ${LDFLAGS} -DMD=4 -o mddriver ${.CURDIR}/mddriver.c -L. -lmd + ./mddriver | cmp md4.ref - + @${ECHO} MD4 passed test + ${CC} -static ${CFLAGS} ${LDFLAGS} -DMD=5 -o mddriver ${.CURDIR}/mddriver.c -L. -lmd + ./mddriver | cmp md5.ref - + @${ECHO} MD5 passed test + -rm -f mddriver + +beforeinstall: +.for i in md2.h md4.h md5.h + ${INSTALL} -C -o ${BINOWN} -g ${BINGRP} -m 444 ${.CURDIR}/$i \ + ${DESTDIR}/usr/include +.endfor + +.include <bsd.lib.mk> diff --git a/lib/libmd/md2.copyright b/lib/libmd/md2.copyright new file mode 100644 index 0000000..5f04560 --- /dev/null +++ b/lib/libmd/md2.copyright @@ -0,0 +1,17 @@ +.\" $Id$ +Copyright (C) 1990-2, RSA Data Security, Inc. Created 1990. All +rights reserved. +.Pp +License to copy and use this software is granted for +non-commercial Internet Privacy-Enhanced Mail provided that it is +identified as the "RSA Data Security, Inc. MD2 Message Digest +Algorithm" in all material mentioning or referencing this software +or this function. +.Pp +RSA Data Security, Inc. makes no representations concerning either +the merchantability of this software or the suitability of this +software for any particular purpose. It is provided "as is" +without express or implied warranty of any kind. +.Pp +These notices must be retained in any copies of any part of this +documentation and/or software. diff --git a/lib/libmd/md2.h b/lib/libmd/md2.h new file mode 100644 index 0000000..9c1ac5d --- /dev/null +++ b/lib/libmd/md2.h @@ -0,0 +1,45 @@ +/* MD2.H - header file for MD2C.C + * $Id: md2.h,v 1.6 1997/08/25 05:24:24 joerg Exp $ + */ + +/* Copyright (C) 1990-2, RSA Data Security, Inc. Created 1990. All + rights reserved. + + License to copy and use this software is granted for + non-commercial Internet Privacy-Enhanced Mail provided that it is + identified as the "RSA Data Security, Inc. MD2 Message Digest + Algorithm" in all material mentioning or referencing this software + or this function. + + RSA Data Security, Inc. makes no representations concerning either + the merchantability of this software or the suitability of this + software for any particular purpose. It is provided "as is" + without express or implied warranty of any kind. + + These notices must be retained in any copies of any part of this + documentation and/or software. + */ + +#ifndef _MD2_H_ +#define _MD2_H_ + +typedef struct MD2Context { + unsigned char state[16]; /* state */ + unsigned char checksum[16]; /* checksum */ + unsigned int count; /* number of bytes, modulo 16 */ + unsigned char buffer[16]; /* input buffer */ +} MD2_CTX; + +#include <sys/cdefs.h> + +__BEGIN_DECLS +void MD2Init(MD2_CTX *); +void MD2Update(MD2_CTX *, const unsigned char *, unsigned int); +void MD2Pad(MD2_CTX *); +void MD2Final(unsigned char [16], MD2_CTX *); +char * MD2End(MD2_CTX *, char *); +char * MD2File(const char *, char *); +char * MD2Data(const unsigned char *, unsigned int, char *); +__END_DECLS + +#endif /* _MD2_H_ */ diff --git a/lib/libmd/md2c.c b/lib/libmd/md2c.c new file mode 100644 index 0000000..561337a --- /dev/null +++ b/lib/libmd/md2c.c @@ -0,0 +1,208 @@ +/* MD2C.C - RSA Data Security, Inc., MD2 message-digest algorithm + * $Id: md2c.c,v 1.5 1997/02/22 15:07:15 peter Exp $ + */ + +/* Copyright (C) 1990-2, RSA Data Security, Inc. Created 1990. All + rights reserved. + + License to copy and use this software is granted for + non-commercial Internet Privacy-Enhanced Mail provided that it is + identified as the "RSA Data Security, Inc. MD2 Message Digest + Algorithm" in all material mentioning or referencing this software + or this function. + + RSA Data Security, Inc. makes no representations concerning either + the merchantability of this software or the suitability of this + software for any particular purpose. It is provided "as is" + without express or implied warranty of any kind. + + These notices must be retained in any copies of any part of this + documentation and/or software. + */ + +#include "md2.h" +#include <string.h> +#include <sys/types.h> + + +typedef unsigned char *POINTER; +typedef u_int16_t UINT2; +typedef u_int32_t UINT4; + +#define PROTO_LIST(list) list + +static void MD2Transform PROTO_LIST + ((unsigned char [16], unsigned char [16], const unsigned char [16])); + +/* Permutation of 0..255 constructed from the digits of pi. It gives a + "random" nonlinear byte substitution operation. + */ +static unsigned char PI_SUBST[256] = { + 41, 46, 67, 201, 162, 216, 124, 1, 61, 54, 84, 161, 236, 240, 6, + 19, 98, 167, 5, 243, 192, 199, 115, 140, 152, 147, 43, 217, 188, + 76, 130, 202, 30, 155, 87, 60, 253, 212, 224, 22, 103, 66, 111, 24, + 138, 23, 229, 18, 190, 78, 196, 214, 218, 158, 222, 73, 160, 251, + 245, 142, 187, 47, 238, 122, 169, 104, 121, 145, 21, 178, 7, 63, + 148, 194, 16, 137, 11, 34, 95, 33, 128, 127, 93, 154, 90, 144, 50, + 39, 53, 62, 204, 231, 191, 247, 151, 3, 255, 25, 48, 179, 72, 165, + 181, 209, 215, 94, 146, 42, 172, 86, 170, 198, 79, 184, 56, 210, + 150, 164, 125, 182, 118, 252, 107, 226, 156, 116, 4, 241, 69, 157, + 112, 89, 100, 113, 135, 32, 134, 91, 207, 101, 230, 45, 168, 2, 27, + 96, 37, 173, 174, 176, 185, 246, 28, 70, 97, 105, 52, 64, 126, 15, + 85, 71, 163, 35, 221, 81, 175, 58, 195, 92, 249, 206, 186, 197, + 234, 38, 44, 83, 13, 110, 133, 40, 132, 9, 211, 223, 205, 244, 65, + 129, 77, 82, 106, 220, 55, 200, 108, 193, 171, 250, 36, 225, 123, + 8, 12, 189, 177, 74, 120, 136, 149, 139, 227, 99, 232, 109, 233, + 203, 213, 254, 59, 0, 29, 57, 242, 239, 183, 14, 102, 88, 208, 228, + 166, 119, 114, 248, 235, 117, 75, 10, 49, 68, 80, 180, 143, 237, + 31, 26, 219, 153, 141, 51, 159, 17, 131, 20 +}; + +static unsigned char *PADDING[] = { + (unsigned char *)"", + (unsigned char *)"\001", + (unsigned char *)"\002\002", + (unsigned char *)"\003\003\003", + (unsigned char *)"\004\004\004\004", + (unsigned char *)"\005\005\005\005\005", + (unsigned char *)"\006\006\006\006\006\006", + (unsigned char *)"\007\007\007\007\007\007\007", + (unsigned char *)"\010\010\010\010\010\010\010\010", + (unsigned char *)"\011\011\011\011\011\011\011\011\011", + (unsigned char *)"\012\012\012\012\012\012\012\012\012\012", + (unsigned char *)"\013\013\013\013\013\013\013\013\013\013\013", + (unsigned char *)"\014\014\014\014\014\014\014\014\014\014\014\014", + (unsigned char *) + "\015\015\015\015\015\015\015\015\015\015\015\015\015", + (unsigned char *) + "\016\016\016\016\016\016\016\016\016\016\016\016\016\016", + (unsigned char *) + "\017\017\017\017\017\017\017\017\017\017\017\017\017\017\017", + (unsigned char *) + "\020\020\020\020\020\020\020\020\020\020\020\020\020\020\020\020" +}; + +/* MD2 initialization. Begins an MD2 operation, writing a new context. + */ +void MD2Init (context) +MD2_CTX *context; /* context */ +{ + context->count = 0; + memset ((POINTER)context->state, 0, sizeof (context->state)); + memset + ((POINTER)context->checksum, 0, sizeof (context->checksum)); +} + +/* MD2 block update operation. Continues an MD2 message-digest + operation, processing another message block, and updating the + context. + */ +void MD2Update (context, input, inputLen) +MD2_CTX *context; /* context */ +const unsigned char *input; /* input block */ +unsigned int inputLen; /* length of input block */ +{ + unsigned int i, index, partLen; + + /* Update number of bytes mod 16 */ + index = context->count; + context->count = (index + inputLen) & 0xf; + + partLen = 16 - index; + + /* Transform as many times as possible. + */ + if (inputLen >= partLen) { + memcpy + ((POINTER)&context->buffer[index], (POINTER)input, partLen); + MD2Transform (context->state, context->checksum, context->buffer); + + for (i = partLen; i + 15 < inputLen; i += 16) + MD2Transform (context->state, context->checksum, &input[i]); + + index = 0; + } + else + i = 0; + + /* Buffer remaining input */ + memcpy + ((POINTER)&context->buffer[index], (POINTER)&input[i], + inputLen-i); +} + +/* MD2 padding. + */ +void MD2Pad (context) +MD2_CTX *context; /* context */ +{ + unsigned int index, padLen; + + /* Pad out to multiple of 16. + */ + index = context->count; + padLen = 16 - index; + MD2Update (context, PADDING[padLen], padLen); + + /* Extend with checksum */ + MD2Update (context, context->checksum, 16); +} + +/* MD2 finalization. Ends an MD2 message-digest operation, writing the + message digest and zeroizing the context. + */ +void MD2Final (digest, context) +unsigned char digest[16]; /* message digest */ +MD2_CTX *context; /* context */ +{ + /* Do padding */ + MD2Pad (context); + + /* Store state in digest */ + memcpy ((POINTER)digest, (POINTER)context->state, 16); + + /* Zeroize sensitive information. + */ + memset ((POINTER)context, 0, sizeof (*context)); +} + +/* MD2 basic transformation. Transforms state and updates checksum + based on block. + */ +static void MD2Transform (state, checksum, block) +unsigned char state[16]; +unsigned char checksum[16]; +const unsigned char block[16]; +{ + unsigned int i, j, t; + unsigned char x[48]; + + /* Form encryption block from state, block, state ^ block. + */ + memcpy ((POINTER)x, (POINTER)state, 16); + memcpy ((POINTER)x+16, (POINTER)block, 16); + for (i = 0; i < 16; i++) + x[i+32] = state[i] ^ block[i]; + + /* Encrypt block (18 rounds). + */ + t = 0; + for (i = 0; i < 18; i++) { + for (j = 0; j < 48; j++) + t = x[j] ^= PI_SUBST[t]; + t = (t + i) & 0xff; + } + + /* Save new state */ + memcpy ((POINTER)state, (POINTER)x, 16); + + /* Update checksum. + */ + t = checksum[15]; + for (i = 0; i < 16; i++) + t = checksum[i] ^= PI_SUBST[block[i] ^ t]; + + /* Zeroize sensitive information. + */ + memset ((POINTER)x, 0, sizeof (x)); +} diff --git a/lib/libmd/md4.copyright b/lib/libmd/md4.copyright new file mode 100644 index 0000000..df93ad0 --- /dev/null +++ b/lib/libmd/md4.copyright @@ -0,0 +1,20 @@ +.\" $Id$ +Copyright (C) 1991-2, RSA Data Security, Inc. Created 1991. All +rights reserved. +.Pp +License to copy and use this software is granted provided that it +is identified as the "RSA Data Security, Inc. MD4 Message-Digest +Algorithm" in all material mentioning or referencing this software +or this function. +License is also granted to make and use derivative works provided +that such works are identified as "derived from the RSA Data +Security, Inc. MD4 Message-Digest Algorithm" in all material +mentioning or referencing the derived work. +.Pp +RSA Data Security, Inc. makes no representations concerning either +the merchantability of this software or the suitability of this +software for any particular purpose. It is provided "as is" +without express or implied warranty of any kind. +.Pp +These notices must be retained in any copies of any part of this +documentation and/or software. diff --git a/lib/libmd/md4.h b/lib/libmd/md4.h new file mode 100644 index 0000000..cee0e4a --- /dev/null +++ b/lib/libmd/md4.h @@ -0,0 +1,47 @@ +/* MD4.H - header file for MD4C.C + * $Id: md4.h,v 1.7 1997/08/25 05:24:24 joerg Exp $ + */ + +/* Copyright (C) 1991-2, RSA Data Security, Inc. Created 1991. All + rights reserved. + + License to copy and use this software is granted provided that it + is identified as the "RSA Data Security, Inc. MD4 Message-Digest + Algorithm" in all material mentioning or referencing this software + or this function. + License is also granted to make and use derivative works provided + that such works are identified as "derived from the RSA Data + Security, Inc. MD4 Message-Digest Algorithm" in all material + mentioning or referencing the derived work. + + RSA Data Security, Inc. makes no representations concerning either + the merchantability of this software or the suitability of this + software for any particular purpose. It is provided "as is" + without express or implied warranty of any kind. + + These notices must be retained in any copies of any part of this + documentation and/or software. + */ + +#ifndef _MD4_H_ +#define _MD4_H_ +/* MD4 context. */ +typedef struct MD4Context { + u_int32_t state[4]; /* state (ABCD) */ + u_int32_t count[2]; /* number of bits, modulo 2^64 (lsb first) */ + unsigned char buffer[64]; /* input buffer */ +} MD4_CTX; + +#include <sys/cdefs.h> + +__BEGIN_DECLS +void MD4Init(MD4_CTX *); +void MD4Update(MD4_CTX *, const unsigned char *, unsigned int); +void MD4Pad(MD4_CTX *); +void MD4Final(unsigned char [16], MD4_CTX *); +char * MD4End(MD4_CTX *, char *); +char * MD4File(const char *, char *); +char * MD4Data(const unsigned char *, unsigned int, char *); +__END_DECLS + +#endif /* _MD4_H_ */ diff --git a/lib/libmd/md4c.c b/lib/libmd/md4c.c new file mode 100644 index 0000000..71c3af7 --- /dev/null +++ b/lib/libmd/md4c.c @@ -0,0 +1,288 @@ +/* MD4C.C - RSA Data Security, Inc., MD4 message-digest algorithm + * $Id: md4c.c,v 1.5 1997/02/22 15:07:19 peter Exp $ + */ + +/* Copyright (C) 1990-2, RSA Data Security, Inc. All rights reserved. + + License to copy and use this software is granted provided that it + is identified as the "RSA Data Security, Inc. MD4 Message-Digest + Algorithm" in all material mentioning or referencing this software + or this function. + + License is also granted to make and use derivative works provided + that such works are identified as "derived from the RSA Data + Security, Inc. MD4 Message-Digest Algorithm" in all material + mentioning or referencing the derived work. + + RSA Data Security, Inc. makes no representations concerning either + the merchantability of this software or the suitability of this + software for any particular purpose. It is provided "as is" + without express or implied warranty of any kind. + + These notices must be retained in any copies of any part of this + documentation and/or software. + */ + +#include <sys/types.h> +#include <string.h> +#include "md4.h" + +typedef unsigned char *POINTER; +typedef u_int16_t UINT2; +typedef u_int32_t UINT4; + +#define PROTO_LIST(list) list + +/* Constants for MD4Transform routine. + */ +#define S11 3 +#define S12 7 +#define S13 11 +#define S14 19 +#define S21 3 +#define S22 5 +#define S23 9 +#define S24 13 +#define S31 3 +#define S32 9 +#define S33 11 +#define S34 15 + +static void MD4Transform PROTO_LIST ((UINT4 [4], const unsigned char [64])); +static void Encode PROTO_LIST + ((unsigned char *, UINT4 *, unsigned int)); +static void Decode PROTO_LIST + ((UINT4 *, const unsigned char *, unsigned int)); + +static unsigned char PADDING[64] = { + 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 +}; + +/* F, G and H are basic MD4 functions. + */ +#define F(x, y, z) (((x) & (y)) | ((~x) & (z))) +#define G(x, y, z) (((x) & (y)) | ((x) & (z)) | ((y) & (z))) +#define H(x, y, z) ((x) ^ (y) ^ (z)) + +/* ROTATE_LEFT rotates x left n bits. + */ +#define ROTATE_LEFT(x, n) (((x) << (n)) | ((x) >> (32-(n)))) + +/* FF, GG and HH are transformations for rounds 1, 2 and 3 */ +/* Rotation is separate from addition to prevent recomputation */ +#define FF(a, b, c, d, x, s) { \ + (a) += F ((b), (c), (d)) + (x); \ + (a) = ROTATE_LEFT ((a), (s)); \ + } +#define GG(a, b, c, d, x, s) { \ + (a) += G ((b), (c), (d)) + (x) + (UINT4)0x5a827999; \ + (a) = ROTATE_LEFT ((a), (s)); \ + } +#define HH(a, b, c, d, x, s) { \ + (a) += H ((b), (c), (d)) + (x) + (UINT4)0x6ed9eba1; \ + (a) = ROTATE_LEFT ((a), (s)); \ + } + +/* MD4 initialization. Begins an MD4 operation, writing a new context. + */ +void MD4Init (context) +MD4_CTX *context; /* context */ +{ + context->count[0] = context->count[1] = 0; + + /* Load magic initialization constants. + */ + context->state[0] = 0x67452301; + context->state[1] = 0xefcdab89; + context->state[2] = 0x98badcfe; + context->state[3] = 0x10325476; +} + +/* MD4 block update operation. Continues an MD4 message-digest + operation, processing another message block, and updating the + context. + */ +void MD4Update (context, input, inputLen) +MD4_CTX *context; /* context */ +const unsigned char *input; /* input block */ +unsigned int inputLen; /* length of input block */ +{ + unsigned int i, index, partLen; + + /* Compute number of bytes mod 64 */ + index = (unsigned int)((context->count[0] >> 3) & 0x3F); + /* Update number of bits */ + if ((context->count[0] += ((UINT4)inputLen << 3)) + < ((UINT4)inputLen << 3)) + context->count[1]++; + context->count[1] += ((UINT4)inputLen >> 29); + + partLen = 64 - index; + /* Transform as many times as possible. + */ + if (inputLen >= partLen) { + memcpy + ((POINTER)&context->buffer[index], (POINTER)input, partLen); + MD4Transform (context->state, context->buffer); + + for (i = partLen; i + 63 < inputLen; i += 64) + MD4Transform (context->state, &input[i]); + + index = 0; + } + else + i = 0; + + /* Buffer remaining input */ + memcpy + ((POINTER)&context->buffer[index], (POINTER)&input[i], + inputLen-i); +} + +/* MD4 padding. */ +void MD4Pad (context) +MD4_CTX *context; /* context */ +{ + unsigned char bits[8]; + unsigned int index, padLen; + + /* Save number of bits */ + Encode (bits, context->count, 8); + + /* Pad out to 56 mod 64. + */ + index = (unsigned int)((context->count[0] >> 3) & 0x3f); + padLen = (index < 56) ? (56 - index) : (120 - index); + MD4Update (context, PADDING, padLen); + + /* Append length (before padding) */ + MD4Update (context, bits, 8); +} + +/* MD4 finalization. Ends an MD4 message-digest operation, writing the + the message digest and zeroizing the context. + */ +void MD4Final (digest, context) +unsigned char digest[16]; /* message digest */ +MD4_CTX *context; /* context */ +{ + /* Do padding */ + MD4Pad (context); + + /* Store state in digest */ + Encode (digest, context->state, 16); + + /* Zeroize sensitive information. + */ + memset ((POINTER)context, 0, sizeof (*context)); +} + +/* MD4 basic transformation. Transforms state based on block. + */ +static void MD4Transform (state, block) +UINT4 state[4]; +const unsigned char block[64]; +{ + UINT4 a = state[0], b = state[1], c = state[2], d = state[3], x[16]; + + Decode (x, block, 64); + + /* Round 1 */ + FF (a, b, c, d, x[ 0], S11); /* 1 */ + FF (d, a, b, c, x[ 1], S12); /* 2 */ + FF (c, d, a, b, x[ 2], S13); /* 3 */ + FF (b, c, d, a, x[ 3], S14); /* 4 */ + FF (a, b, c, d, x[ 4], S11); /* 5 */ + FF (d, a, b, c, x[ 5], S12); /* 6 */ + FF (c, d, a, b, x[ 6], S13); /* 7 */ + FF (b, c, d, a, x[ 7], S14); /* 8 */ + FF (a, b, c, d, x[ 8], S11); /* 9 */ + FF (d, a, b, c, x[ 9], S12); /* 10 */ + FF (c, d, a, b, x[10], S13); /* 11 */ + FF (b, c, d, a, x[11], S14); /* 12 */ + FF (a, b, c, d, x[12], S11); /* 13 */ + FF (d, a, b, c, x[13], S12); /* 14 */ + FF (c, d, a, b, x[14], S13); /* 15 */ + FF (b, c, d, a, x[15], S14); /* 16 */ + + /* Round 2 */ + GG (a, b, c, d, x[ 0], S21); /* 17 */ + GG (d, a, b, c, x[ 4], S22); /* 18 */ + GG (c, d, a, b, x[ 8], S23); /* 19 */ + GG (b, c, d, a, x[12], S24); /* 20 */ + GG (a, b, c, d, x[ 1], S21); /* 21 */ + GG (d, a, b, c, x[ 5], S22); /* 22 */ + GG (c, d, a, b, x[ 9], S23); /* 23 */ + GG (b, c, d, a, x[13], S24); /* 24 */ + GG (a, b, c, d, x[ 2], S21); /* 25 */ + GG (d, a, b, c, x[ 6], S22); /* 26 */ + GG (c, d, a, b, x[10], S23); /* 27 */ + GG (b, c, d, a, x[14], S24); /* 28 */ + GG (a, b, c, d, x[ 3], S21); /* 29 */ + GG (d, a, b, c, x[ 7], S22); /* 30 */ + GG (c, d, a, b, x[11], S23); /* 31 */ + GG (b, c, d, a, x[15], S24); /* 32 */ + + /* Round 3 */ + HH (a, b, c, d, x[ 0], S31); /* 33 */ + HH (d, a, b, c, x[ 8], S32); /* 34 */ + HH (c, d, a, b, x[ 4], S33); /* 35 */ + HH (b, c, d, a, x[12], S34); /* 36 */ + HH (a, b, c, d, x[ 2], S31); /* 37 */ + HH (d, a, b, c, x[10], S32); /* 38 */ + HH (c, d, a, b, x[ 6], S33); /* 39 */ + HH (b, c, d, a, x[14], S34); /* 40 */ + HH (a, b, c, d, x[ 1], S31); /* 41 */ + HH (d, a, b, c, x[ 9], S32); /* 42 */ + HH (c, d, a, b, x[ 5], S33); /* 43 */ + HH (b, c, d, a, x[13], S34); /* 44 */ + HH (a, b, c, d, x[ 3], S31); /* 45 */ + HH (d, a, b, c, x[11], S32); /* 46 */ + HH (c, d, a, b, x[ 7], S33); /* 47 */ + HH (b, c, d, a, x[15], S34); /* 48 */ + + state[0] += a; + state[1] += b; + state[2] += c; + state[3] += d; + + /* Zeroize sensitive information. + */ + memset ((POINTER)x, 0, sizeof (x)); +} + +/* Encodes input (UINT4) into output (unsigned char). Assumes len is + a multiple of 4. + */ +static void Encode (output, input, len) +unsigned char *output; +UINT4 *input; +unsigned int len; +{ + unsigned int i, j; + + for (i = 0, j = 0; j < len; i++, j += 4) { + output[j] = (unsigned char)(input[i] & 0xff); + output[j+1] = (unsigned char)((input[i] >> 8) & 0xff); + output[j+2] = (unsigned char)((input[i] >> 16) & 0xff); + output[j+3] = (unsigned char)((input[i] >> 24) & 0xff); + } +} + +/* Decodes input (unsigned char) into output (UINT4). Assumes len is + a multiple of 4. + */ +static void Decode (output, input, len) + +UINT4 *output; +const unsigned char *input; +unsigned int len; +{ + unsigned int i, j; + + for (i = 0, j = 0; j < len; i++, j += 4) + output[i] = ((UINT4)input[j]) | (((UINT4)input[j+1]) << 8) | + (((UINT4)input[j+2]) << 16) | (((UINT4)input[j+3]) << 24); +} diff --git a/lib/libmd/md5.copyright b/lib/libmd/md5.copyright new file mode 100644 index 0000000..c37746f --- /dev/null +++ b/lib/libmd/md5.copyright @@ -0,0 +1,21 @@ +.\" $Id$ +Copyright (C) 1991-2, RSA Data Security, Inc. Created 1991. All +rights reserved. +.Pp +License to copy and use this software is granted provided that it +is identified as the "RSA Data Security, Inc. MD5 Message-Digest +Algorithm" in all material mentioning or referencing this software +or this function. +.Pp +License is also granted to make and use derivative works provided +that such works are identified as "derived from the RSA Data +Security, Inc. MD5 Message-Digest Algorithm" in all material +mentioning or referencing the derived work. +.Pp +RSA Data Security, Inc. makes no representations concerning either +the merchantability of this software or the suitability of this +software for any particular purpose. It is provided "as is" +without express or implied warranty of any kind. +.Pp +These notices must be retained in any copies of any part of this +documentation and/or software. diff --git a/lib/libmd/md5.h b/lib/libmd/md5.h new file mode 100644 index 0000000..803a88f --- /dev/null +++ b/lib/libmd/md5.h @@ -0,0 +1,4 @@ +#ifndef _MD5_H_ +#define _MD5_H_ +#include <sys/md5.h> +#endif /* _MD5_H_ */ diff --git a/lib/libmd/md5c.c b/lib/libmd/md5c.c new file mode 100644 index 0000000..c1fdc6d --- /dev/null +++ b/lib/libmd/md5c.c @@ -0,0 +1,342 @@ +/* + * MD5C.C - RSA Data Security, Inc., MD5 message-digest algorithm + * + * Copyright (C) 1991-2, RSA Data Security, Inc. Created 1991. All + * rights reserved. + * + * License to copy and use this software is granted provided that it + * is identified as the "RSA Data Security, Inc. MD5 Message-Digest + * Algorithm" in all material mentioning or referencing this software + * or this function. + * + * License is also granted to make and use derivative works provided + * that such works are identified as "derived from the RSA Data + * Security, Inc. MD5 Message-Digest Algorithm" in all material + * mentioning or referencing the derived work. + * + * RSA Data Security, Inc. makes no representations concerning either + * the merchantability of this software or the suitability of this + * software for any particular purpose. It is provided "as is" + * without express or implied warranty of any kind. + * + * These notices must be retained in any copies of any part of this + * documentation and/or software. + * + * $Id: md5c.c,v 1.10 1997/10/21 13:28:36 phk Exp $ + * + * This code is the same as the code published by RSA Inc. It has been + * edited for clarity and style only. + */ + +#include <sys/types.h> + +#ifdef KERNEL +#include <sys/systm.h> +#else +#include <string.h> +#endif + +#include <sys/md5.h> + +static void MD5Transform __P((u_int32_t [4], const unsigned char [64])); + +#ifdef KERNEL +#define memset(x,y,z) bzero(x,z); +#define memcpy(x,y,z) bcopy(y, x, z) +#endif + +#ifdef i386 +#define Encode memcpy +#define Decode memcpy +#else /* i386 */ + +/* + * Encodes input (u_int32_t) into output (unsigned char). Assumes len is + * a multiple of 4. + */ + +static void +Encode (output, input, len) + unsigned char *output; + u_int32_t *input; + unsigned int len; +{ + unsigned int i, j; + + for (i = 0, j = 0; j < len; i++, j += 4) { + output[j] = (unsigned char)(input[i] & 0xff); + output[j+1] = (unsigned char)((input[i] >> 8) & 0xff); + output[j+2] = (unsigned char)((input[i] >> 16) & 0xff); + output[j+3] = (unsigned char)((input[i] >> 24) & 0xff); + } +} + +/* + * Decodes input (unsigned char) into output (u_int32_t). Assumes len is + * a multiple of 4. + */ + +static void +Decode (output, input, len) + u_int32_t *output; + const unsigned char *input; + unsigned int len; +{ + unsigned int i, j; + + for (i = 0, j = 0; j < len; i++, j += 4) + output[i] = ((u_int32_t)input[j]) | (((u_int32_t)input[j+1]) << 8) | + (((u_int32_t)input[j+2]) << 16) | (((u_int32_t)input[j+3]) << 24); +} +#endif /* i386 */ + +static unsigned char PADDING[64] = { + 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 +}; + +/* F, G, H and I are basic MD5 functions. */ +#define F(x, y, z) (((x) & (y)) | ((~x) & (z))) +#define G(x, y, z) (((x) & (z)) | ((y) & (~z))) +#define H(x, y, z) ((x) ^ (y) ^ (z)) +#define I(x, y, z) ((y) ^ ((x) | (~z))) + +/* ROTATE_LEFT rotates x left n bits. */ +#define ROTATE_LEFT(x, n) (((x) << (n)) | ((x) >> (32-(n)))) + +/* + * FF, GG, HH, and II transformations for rounds 1, 2, 3, and 4. + * Rotation is separate from addition to prevent recomputation. + */ +#define FF(a, b, c, d, x, s, ac) { \ + (a) += F ((b), (c), (d)) + (x) + (u_int32_t)(ac); \ + (a) = ROTATE_LEFT ((a), (s)); \ + (a) += (b); \ + } +#define GG(a, b, c, d, x, s, ac) { \ + (a) += G ((b), (c), (d)) + (x) + (u_int32_t)(ac); \ + (a) = ROTATE_LEFT ((a), (s)); \ + (a) += (b); \ + } +#define HH(a, b, c, d, x, s, ac) { \ + (a) += H ((b), (c), (d)) + (x) + (u_int32_t)(ac); \ + (a) = ROTATE_LEFT ((a), (s)); \ + (a) += (b); \ + } +#define II(a, b, c, d, x, s, ac) { \ + (a) += I ((b), (c), (d)) + (x) + (u_int32_t)(ac); \ + (a) = ROTATE_LEFT ((a), (s)); \ + (a) += (b); \ + } + +/* MD5 initialization. Begins an MD5 operation, writing a new context. */ + +void +MD5Init (context) + MD5_CTX *context; +{ + + context->count[0] = context->count[1] = 0; + + /* Load magic initialization constants. */ + context->state[0] = 0x67452301; + context->state[1] = 0xefcdab89; + context->state[2] = 0x98badcfe; + context->state[3] = 0x10325476; +} + +/* + * MD5 block update operation. Continues an MD5 message-digest + * operation, processing another message block, and updating the + * context. + */ + +void +MD5Update (context, input, inputLen) + MD5_CTX *context; + const unsigned char *input; + unsigned int inputLen; +{ + unsigned int i, index, partLen; + + /* Compute number of bytes mod 64 */ + index = (unsigned int)((context->count[0] >> 3) & 0x3F); + + /* Update number of bits */ + if ((context->count[0] += ((u_int32_t)inputLen << 3)) + < ((u_int32_t)inputLen << 3)) + context->count[1]++; + context->count[1] += ((u_int32_t)inputLen >> 29); + + partLen = 64 - index; + + /* Transform as many times as possible. */ + if (inputLen >= partLen) { + memcpy((void *)&context->buffer[index], (const void *)input, + partLen); + MD5Transform (context->state, context->buffer); + + for (i = partLen; i + 63 < inputLen; i += 64) + MD5Transform (context->state, &input[i]); + + index = 0; + } + else + i = 0; + + /* Buffer remaining input */ + memcpy ((void *)&context->buffer[index], (const void *)&input[i], + inputLen-i); +} + +/* + * MD5 padding. Adds padding followed by original length. + */ + +void +MD5Pad (context) + MD5_CTX *context; +{ + unsigned char bits[8]; + unsigned int index, padLen; + + /* Save number of bits */ + Encode (bits, context->count, 8); + + /* Pad out to 56 mod 64. */ + index = (unsigned int)((context->count[0] >> 3) & 0x3f); + padLen = (index < 56) ? (56 - index) : (120 - index); + MD5Update (context, PADDING, padLen); + + /* Append length (before padding) */ + MD5Update (context, bits, 8); +} + +/* + * MD5 finalization. Ends an MD5 message-digest operation, writing the + * the message digest and zeroizing the context. + */ + +void +MD5Final (digest, context) + unsigned char digest[16]; + MD5_CTX *context; +{ + /* Do padding. */ + MD5Pad (context); + + /* Store state in digest */ + Encode (digest, context->state, 16); + + /* Zeroize sensitive information. */ + memset ((void *)context, 0, sizeof (*context)); +} + +/* MD5 basic transformation. Transforms state based on block. */ + +static void +MD5Transform (state, block) + u_int32_t state[4]; + const unsigned char block[64]; +{ + u_int32_t a = state[0], b = state[1], c = state[2], d = state[3], x[16]; + + Decode (x, block, 64); + + /* Round 1 */ +#define S11 7 +#define S12 12 +#define S13 17 +#define S14 22 + FF (a, b, c, d, x[ 0], S11, 0xd76aa478); /* 1 */ + FF (d, a, b, c, x[ 1], S12, 0xe8c7b756); /* 2 */ + FF (c, d, a, b, x[ 2], S13, 0x242070db); /* 3 */ + FF (b, c, d, a, x[ 3], S14, 0xc1bdceee); /* 4 */ + FF (a, b, c, d, x[ 4], S11, 0xf57c0faf); /* 5 */ + FF (d, a, b, c, x[ 5], S12, 0x4787c62a); /* 6 */ + FF (c, d, a, b, x[ 6], S13, 0xa8304613); /* 7 */ + FF (b, c, d, a, x[ 7], S14, 0xfd469501); /* 8 */ + FF (a, b, c, d, x[ 8], S11, 0x698098d8); /* 9 */ + FF (d, a, b, c, x[ 9], S12, 0x8b44f7af); /* 10 */ + FF (c, d, a, b, x[10], S13, 0xffff5bb1); /* 11 */ + FF (b, c, d, a, x[11], S14, 0x895cd7be); /* 12 */ + FF (a, b, c, d, x[12], S11, 0x6b901122); /* 13 */ + FF (d, a, b, c, x[13], S12, 0xfd987193); /* 14 */ + FF (c, d, a, b, x[14], S13, 0xa679438e); /* 15 */ + FF (b, c, d, a, x[15], S14, 0x49b40821); /* 16 */ + + /* Round 2 */ +#define S21 5 +#define S22 9 +#define S23 14 +#define S24 20 + GG (a, b, c, d, x[ 1], S21, 0xf61e2562); /* 17 */ + GG (d, a, b, c, x[ 6], S22, 0xc040b340); /* 18 */ + GG (c, d, a, b, x[11], S23, 0x265e5a51); /* 19 */ + GG (b, c, d, a, x[ 0], S24, 0xe9b6c7aa); /* 20 */ + GG (a, b, c, d, x[ 5], S21, 0xd62f105d); /* 21 */ + GG (d, a, b, c, x[10], S22, 0x2441453); /* 22 */ + GG (c, d, a, b, x[15], S23, 0xd8a1e681); /* 23 */ + GG (b, c, d, a, x[ 4], S24, 0xe7d3fbc8); /* 24 */ + GG (a, b, c, d, x[ 9], S21, 0x21e1cde6); /* 25 */ + GG (d, a, b, c, x[14], S22, 0xc33707d6); /* 26 */ + GG (c, d, a, b, x[ 3], S23, 0xf4d50d87); /* 27 */ + GG (b, c, d, a, x[ 8], S24, 0x455a14ed); /* 28 */ + GG (a, b, c, d, x[13], S21, 0xa9e3e905); /* 29 */ + GG (d, a, b, c, x[ 2], S22, 0xfcefa3f8); /* 30 */ + GG (c, d, a, b, x[ 7], S23, 0x676f02d9); /* 31 */ + GG (b, c, d, a, x[12], S24, 0x8d2a4c8a); /* 32 */ + + /* Round 3 */ +#define S31 4 +#define S32 11 +#define S33 16 +#define S34 23 + HH (a, b, c, d, x[ 5], S31, 0xfffa3942); /* 33 */ + HH (d, a, b, c, x[ 8], S32, 0x8771f681); /* 34 */ + HH (c, d, a, b, x[11], S33, 0x6d9d6122); /* 35 */ + HH (b, c, d, a, x[14], S34, 0xfde5380c); /* 36 */ + HH (a, b, c, d, x[ 1], S31, 0xa4beea44); /* 37 */ + HH (d, a, b, c, x[ 4], S32, 0x4bdecfa9); /* 38 */ + HH (c, d, a, b, x[ 7], S33, 0xf6bb4b60); /* 39 */ + HH (b, c, d, a, x[10], S34, 0xbebfbc70); /* 40 */ + HH (a, b, c, d, x[13], S31, 0x289b7ec6); /* 41 */ + HH (d, a, b, c, x[ 0], S32, 0xeaa127fa); /* 42 */ + HH (c, d, a, b, x[ 3], S33, 0xd4ef3085); /* 43 */ + HH (b, c, d, a, x[ 6], S34, 0x4881d05); /* 44 */ + HH (a, b, c, d, x[ 9], S31, 0xd9d4d039); /* 45 */ + HH (d, a, b, c, x[12], S32, 0xe6db99e5); /* 46 */ + HH (c, d, a, b, x[15], S33, 0x1fa27cf8); /* 47 */ + HH (b, c, d, a, x[ 2], S34, 0xc4ac5665); /* 48 */ + + /* Round 4 */ +#define S41 6 +#define S42 10 +#define S43 15 +#define S44 21 + II (a, b, c, d, x[ 0], S41, 0xf4292244); /* 49 */ + II (d, a, b, c, x[ 7], S42, 0x432aff97); /* 50 */ + II (c, d, a, b, x[14], S43, 0xab9423a7); /* 51 */ + II (b, c, d, a, x[ 5], S44, 0xfc93a039); /* 52 */ + II (a, b, c, d, x[12], S41, 0x655b59c3); /* 53 */ + II (d, a, b, c, x[ 3], S42, 0x8f0ccc92); /* 54 */ + II (c, d, a, b, x[10], S43, 0xffeff47d); /* 55 */ + II (b, c, d, a, x[ 1], S44, 0x85845dd1); /* 56 */ + II (a, b, c, d, x[ 8], S41, 0x6fa87e4f); /* 57 */ + II (d, a, b, c, x[15], S42, 0xfe2ce6e0); /* 58 */ + II (c, d, a, b, x[ 6], S43, 0xa3014314); /* 59 */ + II (b, c, d, a, x[13], S44, 0x4e0811a1); /* 60 */ + II (a, b, c, d, x[ 4], S41, 0xf7537e82); /* 61 */ + II (d, a, b, c, x[11], S42, 0xbd3af235); /* 62 */ + II (c, d, a, b, x[ 2], S43, 0x2ad7d2bb); /* 63 */ + II (b, c, d, a, x[ 9], S44, 0xeb86d391); /* 64 */ + + state[0] += a; + state[1] += b; + state[2] += c; + state[3] += d; + + /* Zeroize sensitive information. */ + memset ((void *)x, 0, sizeof (x)); +} diff --git a/lib/libmd/mdX.3 b/lib/libmd/mdX.3 new file mode 100644 index 0000000..21e4d45 --- /dev/null +++ b/lib/libmd/mdX.3 @@ -0,0 +1,146 @@ +.\" +.\" ---------------------------------------------------------------------------- +.\" "THE BEER-WARE LICENSE" (Revision 42): +.\" <phk@login.dkuug.dk> wrote this file. As long as you retain this notice you +.\" can do whatever you want with this stuff. If we meet some day, and you think +.\" this stuff is worth it, you can buy me a beer in return. Poul-Henning Kamp +.\" ---------------------------------------------------------------------------- +.\" +.\" $Id: mdX.3,v 1.12 1998/03/19 07:34:12 charnier Exp $ +.\" +.Dd October 9, 1996 +.Dt MDX 3 +.Os FreeBSD 2 +.Sh NAME +.Nm MDXInit , +.Nm MDXUpdate , +.Nm MDXPad , +.Nm MDXFinal , +.Nm MDXEnd , +.Nm MDXFile , +.Nm MDXData +.Nd calculate the RSA Data Security, Inc., ``MDX'' message digest +.Sh SYNOPSIS +.Fd #include <sys/types.h> +.Fd #include <mdX.h> +.Ft void +.Fn MDXInit "MDX_CTX *context" +.Ft void +.Fn MDXUpdate "MDX_CTX *context" "const unsigned char *data" "unsigned int len" +.Ft void +.Fn MDXPad "MDX_CTX *context" +.Ft void +.Fn MDXFinal "unsigned char digest[16]" "MDX_CTX *context" +.Ft "char *" +.Fn MDXEnd "MDX_CTX *context" "char *buf" +.Ft "char *" +.Fn MDXFile "const char *filename" "char *buf" +.Ft "char *" +.Fn MDXData "const unsigned char *data" "unsigned int len" "char *buf" +.Sh DESCRIPTION +The MDX functions calculate a 128-bit cryptographic checksum (digest) +for any number of input bytes. A cryptographic checksum is a one-way +hash-function, that is, you cannot find (except by exhaustive search) +the input corresponding to a particular output. This net result is +a ``fingerprint'' of the input-data, which doesn't disclose the actual +input. +.Pp +MD2 is the slowest, MD4 is the fastest and MD5 is somewhere in the middle. +MD2 can only be used for Privacy-Enhanced Mail. +MD4 has been criticized for being too weak, so MD5 was developed in +response as ``MD4 with safety-belts''. When in doubt, use MD5. +.Pp +The +.Fn MDXInit , +.Fn MDXUpdate , +and +.Fn MDXFinal +functions are the core functions. Allocate an MDX_CTX, initialize it with +.Fn MDXInit , +run over the data with +.Fn MDXUpdate , +and finally extract the result using +.Fn MDXFinal . +.Pp +.Fn MDXPad +can be used to pad message data in same way +as done by +.Fn MDXFinal +without terminating calculation. +.Pp +.Fn MDXEnd +is a wrapper for +.Fn MDXFinal +which converts the return value to a 33-character +(including the terminating '\e0') +.Tn ASCII +string which represents the 128 bits in hexadecimal. +.Pp +.Fn MDXFile +calculates the digest of a file, and uses +.Fn MDXEnd +to return the result. +If the file cannot be opened, a null pointer is returned. +.Fn MDXData +calculates the digest of a chunk of data in memory, and uses +.Fn MDXEnd +to return the result. +.Pp +When using +.Fn MDXEnd , +.Fn MDXFile , +or +.Fn MDXData , +the +.Ar buf +argument can be a null pointer, in which case the returned string +is allocated with +.Xr malloc 3 +and subsequently must be explicitly deallocated using +.Xr free 3 +after use. +If the +.Ar buf +argument is non-null it must point to at least 33 characters of buffer space. +.Sh SEE ALSO +.Xr md2 3 , +.Xr md4 3 , +.Xr md5 3 +.Rs +.%A B. Kaliski +.%T The MD2 Message-Digest Algorithm +.%O RFC 1319 +.Re +.Rs +.%A R. Rivest +.%T The MD4 Message-Digest Algorithm +.%O RFC 1186 +.Re +.Rs +.%A R. Rivest +.%T The MD5 Message-Digest Algorithm +.%O RFC 1321 +.Re +.Rs +.%A RSA Laboratories +.%T Frequently Asked Questions About today's Cryptography +.Re +.Sh AUTHORS +The original MDX routines were developed by +.Tn RSA +Data Security, Inc., and published in the above references. +This code is derived directly from these implementations by +.An Poul-Henning Kamp Aq phk@login.dkuug.dk +.Pp +Phk ristede runen. +.Sh HISTORY +These functions appeared in +.Fx 2.0 . +.Sh BUGS +No method is known to exist which finds two files having the same hash value, +nor to find a file with a specific hash value. +There is on the other hand no guarantee that such a method doesn't exist. +.Pp +MD2 has only been licensed for use in Privacy Enhanced Mail. +Use MD4 or MD5 if that isn't what you're doing. +.Sh COPYRIGHT diff --git a/lib/libmd/mdXhl.c b/lib/libmd/mdXhl.c new file mode 100644 index 0000000..460d27e --- /dev/null +++ b/lib/libmd/mdXhl.c @@ -0,0 +1,71 @@ +/* mdXhl.c + * ---------------------------------------------------------------------------- + * "THE BEER-WARE LICENSE" (Revision 42): + * <phk@login.dkuug.dk> wrote this file. As long as you retain this notice you + * can do whatever you want with this stuff. If we meet some day, and you think + * this stuff is worth it, you can buy me a beer in return. Poul-Henning Kamp + * ---------------------------------------------------------------------------- + * + * $Id: mdXhl.c,v 1.10 1997/02/22 15:07:23 peter Exp $ + * + */ + +#include <sys/types.h> +#include <fcntl.h> +#include <unistd.h> + +#include <errno.h> +#include <stdio.h> +#include <stdlib.h> + +#include "mdX.h" + +char * +MDXEnd(MDX_CTX *ctx, char *buf) +{ + int i; + unsigned char digest[16]; + static const char hex[]="0123456789abcdef"; + + if (!buf) + buf = malloc(33); + if (!buf) + return 0; + MDXFinal(digest,ctx); + for (i=0;i<16;i++) { + buf[i+i] = hex[digest[i] >> 4]; + buf[i+i+1] = hex[digest[i] & 0x0f]; + } + buf[i+i] = '\0'; + return buf; +} + +char * +MDXFile (const char *filename, char *buf) +{ + unsigned char buffer[BUFSIZ]; + MDX_CTX ctx; + int f,i,j; + + MDXInit(&ctx); + f = open(filename,O_RDONLY); + if (f < 0) return 0; + while ((i = read(f,buffer,sizeof buffer)) > 0) { + MDXUpdate(&ctx,buffer,i); + } + j = errno; + close(f); + errno = j; + if (i < 0) return 0; + return MDXEnd(&ctx, buf); +} + +char * +MDXData (const unsigned char *data, unsigned int len, char *buf) +{ + MDX_CTX ctx; + + MDXInit(&ctx); + MDXUpdate(&ctx,data,len); + return MDXEnd(&ctx, buf); +} diff --git a/lib/libmd/mddriver.c b/lib/libmd/mddriver.c new file mode 100644 index 0000000..82a4757 --- /dev/null +++ b/lib/libmd/mddriver.c @@ -0,0 +1,69 @@ +/* MDDRIVER.C - test driver for MD2, MD4 and MD5 + * $Id: mddriver.c,v 1.3 1997/02/22 15:07:24 peter Exp $ + */ + +/* Copyright (C) 1990-2, RSA Data Security, Inc. Created 1990. All + rights reserved. + + RSA Data Security, Inc. makes no representations concerning either + the merchantability of this software or the suitability of this + software for any particular purpose. It is provided "as is" + without express or implied warranty of any kind. + + These notices must be retained in any copies of any part of this + documentation and/or software. + */ + +/* The following makes MD default to MD5 if it has not already been + defined with C compiler flags. + */ +#ifndef MD +#define MD 5 +#endif + +#include <sys/types.h> + +#include <stdio.h> +#include <time.h> +#include <string.h> +#if MD == 2 +#include "md2.h" +#define MDData MD2Data +#endif +#if MD == 4 +#include "md4.h" +#define MDData MD4Data +#endif +#if MD == 5 +#include "md5.h" +#define MDData MD5Data +#endif + +/* Digests a string and prints the result. + */ +static void MDString (string) +char *string; +{ + char buf[33]; + + printf ("MD%d (\"%s\") = %s\n", + MD, string, MDData(string,strlen(string),buf)); +} + +/* Digests a reference suite of strings and prints the results. + */ +main() +{ + printf ("MD%d test suite:\n", MD); + + MDString (""); + MDString ("a"); + MDString ("abc"); + MDString ("message digest"); + MDString ("abcdefghijklmnopqrstuvwxyz"); + MDString + ("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"); + MDString + ("1234567890123456789012345678901234567890\ +1234567890123456789012345678901234567890"); +} |