diff options
| author | Sam Varshavchik | 2013-08-19 16:39:41 -0400 |
|---|---|---|
| committer | Sam Varshavchik | 2013-08-25 14:43:51 -0400 |
| commit | 9c45d9ad13fdf439d44d7443ae75da15ea0223ed (patch) | |
| tree | 7a81a04cb51efb078ee350859a64be2ebc6b8813 /md5 | |
| parent | a9520698b770168d1f33d6301463bb70a19655ec (diff) | |
| download | courier-libs-9c45d9ad13fdf439d44d7443ae75da15ea0223ed.tar.bz2 | |
Initial checkin
Imported from subversion report, converted to git. Updated all paths in
scripts and makefiles, reflecting the new directory hierarchy.
Diffstat (limited to 'md5')
| -rw-r--r-- | md5/.gitignore | 1 | ||||
| -rw-r--r-- | md5/Makefile.am | 28 | ||||
| -rw-r--r-- | md5/configure.in | 99 | ||||
| -rw-r--r-- | md5/hmac.c | 35 | ||||
| -rw-r--r-- | md5/md5.c | 278 | ||||
| -rw-r--r-- | md5/md5.h | 65 | ||||
| -rw-r--r-- | md5/md5_hash.c | 67 | ||||
| -rw-r--r-- | md5/md5test.c | 46 | ||||
| -rw-r--r-- | md5/md5test.txt | 24 | ||||
| -rw-r--r-- | md5/redhat-crypt-md5.c | 125 |
10 files changed, 768 insertions, 0 deletions
diff --git a/md5/.gitignore b/md5/.gitignore new file mode 100644 index 0000000..b81ee39 --- /dev/null +++ b/md5/.gitignore @@ -0,0 +1 @@ +/md5test diff --git a/md5/Makefile.am b/md5/Makefile.am new file mode 100644 index 0000000..2e2c8e9 --- /dev/null +++ b/md5/Makefile.am @@ -0,0 +1,28 @@ +# +# Copyright 1998 - 2005 Double Precision, Inc. See COPYING for +# distribution information. + + +if HMACC +HMAC=hmac.c +else +HMAC= +endif + +libmd5_la_SOURCES=md5.c md5.h md5_hash.c redhat-crypt-md5.c $(HMAC) + +CLEANFILES=$(noinst_DATA) + +noinst_LTLIBRARIES=libmd5.la + +noinst_PROGRAMS=md5test + +md5test_SOURCES=md5test.c +md5test_DEPENDENCIES=libmd5.la +md5test_LDADD=libmd5.la +md5test_LDFLAGS=-static + +EXTRA_DIST=md5test.txt hmac.c + +check-am: + ./md5test | cmp -s - $(srcdir)/md5test.txt diff --git a/md5/configure.in b/md5/configure.in new file mode 100644 index 0000000..7808f06 --- /dev/null +++ b/md5/configure.in @@ -0,0 +1,99 @@ +dnl Process this file with autoconf to produce a configure script. +dnl +dnl Copyright 1998 - 2004 Double Precision, Inc. See COPYING for +dnl distribution information. + +AC_PREREQ(2.59) +AC_INIT(libmd5, 1.21, courier-users@lists.sourceforge.net) + +>confdefs.h # Kill PACKAGE_ macros + +AC_CONFIG_SRCDIR([hmac.c]) +AC_CONFIG_AUX_DIR(../..) +AM_CONFIG_HEADER([config.h]) +AM_INIT_AUTOMAKE([foreign no-define]) + +AM_CONDITIONAL(HMACC, test -d ${srcdir}/../libhmac) + +dnl Checks for programs. +AC_PROG_AWK +AC_PROG_INSTALL +AC_PROG_LN_S +AC_PROG_CC +AC_PROG_LIBTOOL + +if test "$GCC" = yes +then + CFLAGS="-Wall $CFLAGS" +fi + +CFLAGS="$CFLAGS -I$srcdir/.. -I.." + +dnl Checks for libraries. + +dnl Checks for header files. +AC_HEADER_STDC + +AC_CHECK_HEADERS(sys/types.h) + + +AC_ARG_WITH(int32, +[ --with-int32='type' use 'type' for an unsigned 32 bit integer type + ( default is 'unsigned')], + int32="$withval", [ + + AC_MSG_CHECKING(for uint32_t) + + AC_TRY_COMPILE([ +#if HAVE_SYS_TYPES_H +#include <sys/types.h> +#endif + ],[ + uint32_t i=0; + ], [ AC_MSG_RESULT(yes) ; int32="uint32_t"], [ + + AC_MSG_RESULT(no) + AC_MSG_CHECKING(for u_int_32_t) + + AC_TRY_COMPILE([ +#if HAVE_SYS_TYPES_H +#include <sys/types.h> +#endif + ],[ + u_int32_t i=0; + ], [AC_MSG_RESULT(yes); int32="u_int32_t"],[ + + AC_MSG_RESULT(no) + + AC_CHECK_SIZEOF(unsigned, 0) + if test "$ac_cv_sizeof_unsigned" != 4 + then + AC_CHECK_SIZEOF(unsigned long, 0) + if test "$ac_cv_sizeof_unsigned_long" != 4 + then + AC_CHECK_SIZEOF(unsigned short, 0) + if test "$ac_cv_sizeof_unsigned_short" != 4 + then + AC_ERROR(--with-int32 option is required) + fi + int32="unsigned short" + fi + int32="unsigned long" + else + int32="unsigned" + fi + ]) + ]) + ] +) +UINT32="$int32" + +AC_DEFINE_UNQUOTED(MD5_WORD, $UINT32, [ 32 bit data type ]) + +dnl Checks for typedefs, structures, and compiler characteristics. +AC_C_CONST +AC_SYS_LARGEFILE + +dnl Checks for library functions. + +AC_OUTPUT(Makefile) diff --git a/md5/hmac.c b/md5/hmac.c new file mode 100644 index 0000000..26589ab --- /dev/null +++ b/md5/hmac.c @@ -0,0 +1,35 @@ +/* +** Copyright 1998 - 1999 Double Precision, Inc. +** See COPYING for distribution information. +*/ + +#define MD5_INTERNAL +#include "md5.h" +#include "../libhmac/hmac.h" + +static void alloc_context( void (*func)(void *, void *), void *arg) +{ +struct MD5_CONTEXT c; + + (*func)((void *)&c, arg); +} + +static void alloc_hash( void (*func)(unsigned char *, void *), void *arg) +{ +unsigned char c[MD5_DIGEST_SIZE]; + + (*func)(c, arg); +} + +struct hmac_hashinfo hmac_md5 = { + "md5", + MD5_BLOCK_SIZE, + MD5_DIGEST_SIZE, + sizeof(struct MD5_CONTEXT), + (void (*)(void *))md5_context_init, + (void (*)(void *, const void *, unsigned))md5_context_hashstream, + (void (*)(void *, unsigned long))md5_context_endstream, + (void (*)(void *, unsigned char *))md5_context_digest, + (void (*)(void *, const unsigned char *))md5_context_restore, + alloc_context, + alloc_hash}; diff --git a/md5/md5.c b/md5/md5.c new file mode 100644 index 0000000..f718389 --- /dev/null +++ b/md5/md5.c @@ -0,0 +1,278 @@ +/* +** Copyright 1998 - 2000 Double Precision, Inc. +** See COPYING for distribution information. +*/ + +#define MD5_INTERNAL +#include "md5.h" +#include <string.h> +#include <stdlib.h> + + +#define MD5_BYTE unsigned char + +#define MD5_ROL(w,n) \ + ( (w) << (n) | ( (w) >> (32-(n)) ) ) + +static MD5_WORD T[64]={ +0xd76aa478, 0xe8c7b756, 0x242070db, 0xc1bdceee, +0xf57c0faf, 0x4787c62a, 0xa8304613, 0xfd469501, +0x698098d8, 0x8b44f7af, 0xffff5bb1, 0x895cd7be, +0x6b901122, 0xfd987193, 0xa679438e, 0x49b40821, +0xf61e2562, 0xc040b340, 0x265e5a51, 0xe9b6c7aa, +0xd62f105d, 0x2441453, 0xd8a1e681, 0xe7d3fbc8, +0x21e1cde6, 0xc33707d6, 0xf4d50d87, 0x455a14ed, +0xa9e3e905, 0xfcefa3f8, 0x676f02d9, 0x8d2a4c8a, +0xfffa3942, 0x8771f681, 0x6d9d6122, 0xfde5380c, +0xa4beea44, 0x4bdecfa9, 0xf6bb4b60, 0xbebfbc70, +0x289b7ec6, 0xeaa127fa, 0xd4ef3085, 0x4881d05, +0xd9d4d039, 0xe6db99e5, 0x1fa27cf8, 0xc4ac5665, +0xf4292244, 0x432aff97, 0xab9423a7, 0xfc93a039, +0x655b59c3, 0x8f0ccc92, 0xffeff47d, 0x85845dd1, +0x6fa87e4f, 0xfe2ce6e0, 0xa3014314, 0x4e0811a1, +0xf7537e82, 0xbd3af235, 0x2ad7d2bb, 0xeb86d391}; + +void md5_context_init(struct MD5_CONTEXT *c) +{ + if (sizeof(MD5_WORD) != 4) abort(); + + c->A=0x67452301; + c->B=0xefcdab89; + c->C=0x98badcfe; + c->D=0x10325476; + + c->blk_ptr=0; +} + +void md5_context_hash(struct MD5_CONTEXT *c, + const unsigned char blk[MD5_BLOCK_SIZE]) +{ +MD5_WORD x[16]; +unsigned i, j; +MD5_WORD A, B, C, D; +MD5_WORD zz; + + for (i=j=0; i<16; i++) + { + MD5_WORD w=(MD5_WORD)blk[j++]; + + w |= (MD5_WORD)blk[j++] << 8; + w |= (MD5_WORD)blk[j++] << 16; + w |= (MD5_WORD)blk[j++] << 24; + x[i]= w; + } + +#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)))) + + A=c->A; + B=c->B; + C=c->C; + D=c->D; + +#define ROUND1(a,b,c,d,k,s,i) \ + { zz=(a + F(b,c,d) + x[k] + T[i]); a=b+MD5_ROL(zz,s); } + + ROUND1(A,B,C,D,0,7,0); + ROUND1(D,A,B,C,1,12,1); + ROUND1(C,D,A,B,2,17,2); + ROUND1(B,C,D,A,3,22,3); + ROUND1(A,B,C,D,4,7,4); + ROUND1(D,A,B,C,5,12,5); + ROUND1(C,D,A,B,6,17,6); + ROUND1(B,C,D,A,7,22,7); + ROUND1(A,B,C,D,8,7,8); + ROUND1(D,A,B,C,9,12,9); + ROUND1(C,D,A,B,10,17,10); + ROUND1(B,C,D,A,11,22,11); + ROUND1(A,B,C,D,12,7,12); + ROUND1(D,A,B,C,13,12,13); + ROUND1(C,D,A,B,14,17,14); + ROUND1(B,C,D,A,15,22,15); + +#define ROUND2(a,b,c,d,k,s,i) \ + { zz=(a + G(b,c,d) + x[k] + T[i]); a = b + MD5_ROL(zz,s); } + + ROUND2(A,B,C,D,1,5,16); + ROUND2(D,A,B,C,6,9,17); + ROUND2(C,D,A,B,11,14,18); + ROUND2(B,C,D,A,0,20,19); + ROUND2(A,B,C,D,5,5,20); + ROUND2(D,A,B,C,10,9,21); + ROUND2(C,D,A,B,15,14,22); + ROUND2(B,C,D,A,4,20,23); + ROUND2(A,B,C,D,9,5,24); + ROUND2(D,A,B,C,14,9,25); + ROUND2(C,D,A,B,3,14,26); + ROUND2(B,C,D,A,8,20,27); + ROUND2(A,B,C,D,13,5,28); + ROUND2(D,A,B,C,2,9,29); + ROUND2(C,D,A,B,7,14,30); + ROUND2(B,C,D,A,12,20,31); + +#define ROUND3(a,b,c,d,k,s,i) \ + { zz=(a + H(b,c,d) + x[k] + T[i]); a = b + MD5_ROL(zz,s); } + + ROUND3(A,B,C,D,5,4,32); + ROUND3(D,A,B,C,8,11,33); + ROUND3(C,D,A,B,11,16,34); + ROUND3(B,C,D,A,14,23,35); + ROUND3(A,B,C,D,1,4,36); + ROUND3(D,A,B,C,4,11,37); + ROUND3(C,D,A,B,7,16,38); + ROUND3(B,C,D,A,10,23,39); + ROUND3(A,B,C,D,13,4,40); + ROUND3(D,A,B,C,0,11,41); + ROUND3(C,D,A,B,3,16,42); + ROUND3(B,C,D,A,6,23,43); + ROUND3(A,B,C,D,9,4,44); + ROUND3(D,A,B,C,12,11,45); + ROUND3(C,D,A,B,15,16,46); + ROUND3(B,C,D,A,2,23,47); + +#define ROUND4(a,b,c,d,k,s,i) \ + { zz=(a + I(b,c,d) + x[k] + T[i]); a = b + MD5_ROL(zz,s); } + + ROUND4(A,B,C,D,0,6,48); + ROUND4(D,A,B,C,7,10,49); + ROUND4(C,D,A,B,14,15,50); + ROUND4(B,C,D,A,5,21,51); + ROUND4(A,B,C,D,12,6,52); + ROUND4(D,A,B,C,3,10,53); + ROUND4(C,D,A,B,10,15,54); + ROUND4(B,C,D,A,1,21,55); + ROUND4(A,B,C,D,8,6,56); + ROUND4(D,A,B,C,15,10,57); + ROUND4(C,D,A,B,6,15,58); + ROUND4(B,C,D,A,13,21,59); + ROUND4(A,B,C,D,4,6,60); + ROUND4(D,A,B,C,11,10,61); + ROUND4(C,D,A,B,2,15,62); + ROUND4(B,C,D,A,9,21,63); + + c->A += A; + c->B += B; + c->C += C; + c->D += D; +} + +void md5_context_hashstream(struct MD5_CONTEXT *c, const void *p, unsigned l) +{ +const unsigned char *cp=(const unsigned char *)p; +unsigned ll; + + while (l) + { + if (c->blk_ptr == 0 && l >= MD5_BLOCK_SIZE) + { + md5_context_hash(c, cp); + cp += MD5_BLOCK_SIZE; + l -= MD5_BLOCK_SIZE; + continue; + } + + ll=l; + if (ll > MD5_BLOCK_SIZE - c->blk_ptr) + ll=MD5_BLOCK_SIZE - c->blk_ptr; + memcpy(c->blk + c->blk_ptr, cp, ll); + c->blk_ptr += ll; + cp += ll; + l -= ll; + if (c->blk_ptr >= MD5_BLOCK_SIZE) + { + md5_context_hash(c, c->blk); + c->blk_ptr=0; + } + } +} + +void md5_context_endstream(struct MD5_CONTEXT *c, unsigned long ll) +{ +unsigned char buf[8]; + +static unsigned char zero[MD5_BLOCK_SIZE-8]; +MD5_WORD l; + + buf[0]=0x80; + md5_context_hashstream(c, buf, 1); + while (c->blk_ptr != MD5_BLOCK_SIZE - 8) + { + if (c->blk_ptr > MD5_BLOCK_SIZE - 8) + { + md5_context_hashstream(c, zero, + MD5_BLOCK_SIZE - c->blk_ptr); + continue; + } + md5_context_hashstream(c, zero, + MD5_BLOCK_SIZE - 8 - c->blk_ptr); + } + + l= ll; + + l <<= 3; + + buf[0]=l; + l >>= 8; + buf[1]=l; + l >>= 8; + buf[2]=l; + l >>= 8; + buf[3]=l; + + l= ll; + l >>= 29; + buf[4]=l; + l >>= 8; + buf[5]=l; + l >>= 8; + buf[6]=l; + l >>= 8; + buf[7]=l; + + md5_context_hashstream(c, buf, 8); +} + +void md5_context_digest(struct MD5_CONTEXT *c, MD5_DIGEST d) +{ +unsigned char *dp=d; +MD5_WORD w; + +#define PUT(c) (w=(c), *dp++ = w, w >>= 8, *dp++ = w, w >>= 8, *dp++ = w, w >>= 8, *dp++ = w) + + PUT(c->A); + PUT(c->B); + PUT(c->C); + PUT(c->D); +#undef PUT +} + +void md5_context_restore(struct MD5_CONTEXT *c, const MD5_DIGEST d) +{ +const unsigned char *dp=(unsigned char *)d+MD5_DIGEST_SIZE; +MD5_WORD w; + +#define GET \ + w=*--dp; w=(w << 8) | *--dp; w=(w << 8) | *--dp; w=(w << 8) | *--dp; + + GET + c->D=w; + GET + c->C=w; + GET + c->B=w; + GET + c->A=w; + c->blk_ptr=0; +} + +void md5_digest(const void *msg, unsigned int len, MD5_DIGEST d) +{ +struct MD5_CONTEXT c; + + md5_context_init(&c); + md5_context_hashstream(&c, msg, len); + md5_context_endstream(&c, len); + md5_context_digest(&c, d); +} diff --git a/md5/md5.h b/md5/md5.h new file mode 100644 index 0000000..2124879 --- /dev/null +++ b/md5/md5.h @@ -0,0 +1,65 @@ +#ifndef md5_h +#define md5_h + +/* +** Copyright 1998 - 2001 Double Precision, Inc. +** See COPYING for distribution information. +*/ + +/* +** RFC 1321 MD5 Message digest calculation. +** +** Returns a pointer to a sixteen-byte message digest. +*/ + +#ifdef __cplusplus +extern "C" { +#endif + +#if HAVE_CONFIG_H +#include "md5/config.h" +#endif + +#if HAVE_SYS_TYPES_H +#include <sys/types.h> +#endif + +#define MD5_DIGEST_SIZE 16 +#define MD5_BLOCK_SIZE 64 + +typedef unsigned char MD5_DIGEST[MD5_DIGEST_SIZE]; + +#ifdef MD5_INTERNAL + +struct MD5_CONTEXT { + + MD5_WORD A, B, C, D; + + unsigned char blk[MD5_BLOCK_SIZE]; + unsigned blk_ptr; + } ; + +void md5_context_init(struct MD5_CONTEXT *); +void md5_context_hash(struct MD5_CONTEXT *, + const unsigned char[MD5_BLOCK_SIZE]); +void md5_context_hashstream(struct MD5_CONTEXT *, const void *, unsigned); +void md5_context_endstream(struct MD5_CONTEXT *, unsigned long); +void md5_context_digest(struct MD5_CONTEXT *, MD5_DIGEST); + +void md5_context_restore(struct MD5_CONTEXT *, const MD5_DIGEST); + +#endif + +void md5_digest(const void *msg, unsigned int len, MD5_DIGEST); + +char *md5_crypt_redhat(const char *, const char *); +#define md5_crypt md5_crypt_redhat + +const char *md5_hash_courier(const char *); +const char *md5_hash_raw(const char *); + +#ifdef __cplusplus +} ; +#endif + +#endif diff --git a/md5/md5_hash.c b/md5/md5_hash.c new file mode 100644 index 0000000..fd16538 --- /dev/null +++ b/md5/md5_hash.c @@ -0,0 +1,67 @@ +/* +** Copyright 2007 Double Precision, Inc. +** See COPYING for distribution information. +*/ + +#include "md5.h" +#include <string.h> +#include <stdio.h> + + +static const char base64tab[]= +"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; + +const char *md5_hash_courier(const char *passw) +{ +MD5_DIGEST md5buf; +static char hash_buffer[1+(sizeof(md5buf)+2)/3*4]; +int a=0,b=0,c=0; +int i, j; +int d, e, f, g; + + md5_digest(passw, strlen(passw), md5buf); + + j=0; + + for (i=0; i<sizeof(md5buf); i += 3) + { + a=md5buf[i]; + b= i+1 < sizeof(md5buf) ? md5buf[i+1]:0; + c= i+2 < sizeof(md5buf) ? md5buf[i+2]:0; + + d=base64tab[ a >> 2 ]; + e=base64tab[ ((a & 3 ) << 4) | (b >> 4)]; + f=base64tab[ ((b & 15) << 2) | (c >> 6)]; + g=base64tab[ c & 63 ]; + if (i + 1 >= sizeof(md5buf)) f='='; + if (i + 2 >= sizeof(md5buf)) g='='; + hash_buffer[j++]=d; + hash_buffer[j++]=e; + hash_buffer[j++]=f; + hash_buffer[j++]=g; + } + + hash_buffer[j]=0; + return (hash_buffer); +} + +const char *md5_hash_raw(const char *passw) +{ + MD5_DIGEST digest; + static char hash_buffer[sizeof(digest)*2+1]; + size_t j=0,i=0; + + char + tmp_buf[3]; + + md5_digest(passw, strlen(passw), digest); + for (j=0; j<sizeof(digest); j++) + { + sprintf(tmp_buf,"%02x",digest[j]); + hash_buffer[i++]=tmp_buf[0]; + hash_buffer[i++]=tmp_buf[1]; + } + hash_buffer[i]=0; + + return(hash_buffer); +} diff --git a/md5/md5test.c b/md5/md5test.c new file mode 100644 index 0000000..c5c4554 --- /dev/null +++ b/md5/md5test.c @@ -0,0 +1,46 @@ +/* +** Copyright 1998 - 2000 Double Precision, Inc. +** See COPYING for distribution information. +*/ + +#include "md5.h" +#include <stdio.h> +#include <string.h> + +int main() +{ +static const char * const teststr[]={ +"", +"a", +"abc", +"message digest", +"abcdefghijklmnopqrstuvwxyz", +"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789", +"12345678901234567890123456789012345678901234567890123456789012345678901234567890"}; + +char *salts[4]={"abcdef","01234567","76543210","QWERTY"}; +char *passwds[4]={ "rosebud", + "trust noone", + "trust, but verify", + "for the world is hollow, and I have touched the sky"}; + +int i,j; + + printf("MD5 test suite:\n"); + for (i=0; i<(int)sizeof(teststr)/sizeof(teststr[0]); i++) + { + MD5_DIGEST digest; + + md5_digest(teststr[i], strlen(teststr[i]), digest); + + printf("MD5 (\"%s\") = ", teststr[i]); + for (j=0; j<sizeof(digest); j++) + printf("%02x", digest[j]); + printf("\n"); + } + for (i=0; i<sizeof(salts)/sizeof(salts[0]); i++) + printf("Salt: %s\nPassword: %s\nHash:%s\n\n", + salts[i], passwds[i], + md5_crypt_redhat(passwds[i], salts[i])); + return (0); +} diff --git a/md5/md5test.txt b/md5/md5test.txt new file mode 100644 index 0000000..55efb05 --- /dev/null +++ b/md5/md5test.txt @@ -0,0 +1,24 @@ +MD5 test suite: +MD5 ("") = d41d8cd98f00b204e9800998ecf8427e +MD5 ("a") = 0cc175b9c0f1b6a831c399e269772661 +MD5 ("abc") = 900150983cd24fb0d6963f7d28e17f72 +MD5 ("message digest") = f96b697d7cb7938d525a2f31aaf161d0 +MD5 ("abcdefghijklmnopqrstuvwxyz") = c3fcd3d76192e4007dfb496cca67e13b +MD5 ("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789") = d174ab98d277d9f5a5611c2c9f419d9f +MD5 ("12345678901234567890123456789012345678901234567890123456789012345678901234567890") = 57edf4a22be3c955ac49da2e2107b67a +Salt: abcdef +Password: rosebud +Hash:$1$abcdef$2XiyKFam4XUU0UKeisSUw. + +Salt: 01234567 +Password: trust noone +Hash:$1$01234567$UOH93AP.QnI8/c8miDJjz/ + +Salt: 76543210 +Password: trust, but verify +Hash:$1$76543210$w5fc8I64uQ1gulWoDQ4vw0 + +Salt: QWERTY +Password: for the world is hollow, and I have touched the sky +Hash:$1$QWERTY$DGJfam2.wuUFO90L/I9Ty. + diff --git a/md5/redhat-crypt-md5.c b/md5/redhat-crypt-md5.c new file mode 100644 index 0000000..a8a37fd --- /dev/null +++ b/md5/redhat-crypt-md5.c @@ -0,0 +1,125 @@ +/* +** Copyright 1998 - 1999 Double Precision, Inc. +** See COPYING for distribution information. +*/ + +#define MD5_INTERNAL +#include "md5.h" +#include <string.h> + + +static char base64[]= + "./0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"; + +char *md5_crypt_redhat(const char *pw, const char *salt) +{ +struct MD5_CONTEXT outer_context, inner_context; +MD5_DIGEST digest; +unsigned pwl=strlen(pw); +unsigned l; +unsigned i, j; +char *p; +static char buffer[100]; + + if (*salt == '$' && salt[1] == '1' && salt[2] == '$') + salt += 3; + + for (l=0; l<8 && salt[l] && salt[l] != '$'; l++) + ; + + md5_context_init(&inner_context); + md5_context_hashstream(&inner_context, pw, pwl); + md5_context_hashstream(&inner_context, salt, l); + md5_context_hashstream(&inner_context, pw, pwl); + md5_context_endstream(&inner_context, pwl*2+l); + md5_context_digest(&inner_context, digest); + + md5_context_init(&outer_context); + md5_context_hashstream(&outer_context, pw, pwl); + md5_context_hashstream(&outer_context, "$1$", 3); + md5_context_hashstream(&outer_context, salt, l); + + for (i=pwl; i; ) + { + j=i; + if (j > 16) j=16; + md5_context_hashstream(&outer_context, digest, j); + i -= j; + } + + j=pwl*2+l+3; + + for (i=pwl; i; i >>= 1) + { + md5_context_hashstream(&outer_context, (i & 1) ? "": pw, 1); + ++j; + } + + + md5_context_endstream(&outer_context, j); + md5_context_digest(&outer_context, digest); + + for (i=0; i<1000; i++) + { + j=0; + + md5_context_init(&outer_context); + if (i & 1) + { + md5_context_hashstream(&outer_context, pw, pwl); + j += pwl; + } + else + { + md5_context_hashstream(&outer_context, digest, 16); + j += 16; + } + + if (i % 3) + { + md5_context_hashstream(&outer_context, salt, l); + j += l; + } + + if (i % 7) + { + md5_context_hashstream(&outer_context, pw, pwl); + j += pwl; + } + + if (i & 1) + { + md5_context_hashstream(&outer_context, digest, 16); + j += 16; + } + else + { + md5_context_hashstream(&outer_context, pw, pwl); + j += pwl; + } + + md5_context_endstream(&outer_context, j); + md5_context_digest(&outer_context, digest); + } + + strcpy(buffer, "$1$"); + strncat(buffer, salt, l); + strcat(buffer, "$"); + + p=buffer+strlen(buffer); + for (i=0; i<5; i++) + { + unsigned char *d=digest; + + j= (d[i] << 16) | (d[i+6] << 8) | d[i == 4 ? 5:12+i]; + *p++= base64[j & 63] ; j=j >> 6; + *p++= base64[j & 63] ; j=j >> 6; + *p++= base64[j & 63] ; j=j >> 6; + *p++= base64[j & 63]; + } + j=digest[11]; + *p++ = base64[j & 63]; j=j >> 6; + *p++ = base64[j & 63]; + *p=0; + return (buffer); +} |
