#include <plib.h>
#include "md4.h"

#if (defined(__MSDOS__) || defined(MPU8086) || defined(MPU8080) \
 || defined(vax) || defined (MIPSEL))
#define	LITTLE_ENDIAN	/* Low order bytes are first in memory */
#endif			/* Almost all other machines are big-endian */

/* Crunch a key:
 * concatenate the seed and the password, run through MD4 and
 * collapse to 64 bits. This is defined as the user's starting key.
 */
int keycrunch( char * result, char * seed, char * passwd )
{	char *buf;
	MDstruct md;
	unsigned int buflen;
#ifndef	LITTLE_ENDIAN
	int i;
	register long tmp;
#endif
	
	buflen = p_slen(seed) + p_slen(passwd);
	if((buf = (char *)p_alloc(buflen+1)) == NULL)
		return -1;
	p_scpy(buf,seed);
	p_scat(buf,passwd);

	/* Crunch the key through MD4 */
	MDbegin(&md);
	MDupdate(&md,(unsigned char *)buf,8*buflen);

	p_free(buf);

	/* Fold result from 128 to 64 bits */
	md.buffer[0] ^= md.buffer[2];
	md.buffer[1] ^= md.buffer[3];

#ifdef	LITTLE_ENDIAN
	/* Only works on byte-addressed little-endian machines!! */
	p_bcpy(result,(char *)md.buffer,8);
#else
	/* Default (but slow) code that will convert to
	 * little-endian byte ordering on any machine
	 */
	for(i=0;i<2;i++){
		tmp = md.buffer[i];
		*result++ = tmp;
		tmp >>= 8;
		*result++ = tmp;
		tmp >>= 8;
		*result++ = tmp;
		tmp >>= 8;
		*result++ = tmp;
	}
#endif

	return 0;
}

/* The one-way function f(). Takes 8 bytes and returns 8 bytes in place */
void
f(x)
char *x;
{
	MDstruct md;
#ifndef	LITTLE_ENDIAN
	register long tmp;
#endif

	MDbegin(&md);
	MDupdate(&md,(unsigned char *)x,64);

	/* Fold 128 to 64 bits */
	md.buffer[0] ^= md.buffer[2];
	md.buffer[1] ^= md.buffer[3];

#ifdef	LITTLE_ENDIAN
	/* Only works on byte-addressed little-endian machines!! */
	p_bcpy(x,(char *)md.buffer,8);

#else
	/* Default (but slow) code that will convert to
	 * little-endian byte ordering on any machine
	 */
	tmp = md.buffer[0];
	*x++ = tmp;
	tmp >>= 8;
	*x++ = tmp;
	tmp >>= 8;
	*x++ = tmp;
	tmp >>= 8;
	*x++ = tmp;

	tmp = md.buffer[1];
	*x++ = tmp;
	tmp >>= 8;
	*x++ = tmp;
	tmp >>= 8;
	*x++ = tmp;
	tmp >>= 8;
	*x = tmp;
#endif
}

/* Strip trailing cr/lf from a line of text */
void rip( char * buf )
{	
	int i;

	if ((i = p_sloc(buf,'\r')) != -1)
		buf[i]= '\0';

	if ((i = p_sloc(buf,'\n')) != -1)
		buf[i]= '\0';

}
