/*
	This code is based on work from
	L0phtcrack 1.5 06.02.97 mudge@l0pht.com

	The code also contains sources from:
                . routines from the samba code source
		  md4.c smbdes.c

	Anton Roeckseisen (anton@genua.de)

*/

/*
 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 * SUCH DAMAGE.
 */

#include "mkntpwd.h"

void mdfour(unsigned char *out, unsigned char *in, int n);
void E_P16(unsigned char *p14,unsigned char *p16);

static int PutUniCode(char *dst,char *src);
/*void mklmhash(const char *passwd, char lmhash[17]);
void mknthash(const char *passwd, char lmhash[17]);
void to_hexstr(const char *src, char hexstr[33]);
*/

void mklmhash(const char *passwd, char lmhash[17])
{
  char lanpwd[LMPASSWDLEN+1];
  int i;

  for (i = 0; (i < LMPASSWDLEN) && (passwd[i] != '\0'); ++i)
  {
    lanpwd[i] = toupper(passwd[i]);
  }
  for (; i < (LMPASSWDLEN + 1); ++i)
  {
    lanpwd[i] = '\0';
  }

  E_P16((uchar *) lanpwd, lmhash);
}

void mknthash(const char *passwd, char nthash[17])
{
  char ntpasswd[NTPASSWDLEN + 1]; 
  char hold[2*NTPASSWDLEN + 2];
  int uni_len;

  strncpy(ntpasswd, passwd, NTPASSWDLEN);
  ntpasswd[NTPASSWDLEN] = '\0';
  uni_len = PutUniCode(hold, ntpasswd);

  mdfour(nthash, hold, uni_len);
}

/*****************************************************************************/
/*****************************************************************************/
/*****************************************************************************/


/*******************************************************************
write a string in unicoode format
********************************************************************/
int PutUniCode(char *dst,char *src) 
{                       
  int ret = 0;  
  while (*src) {
    dst[ret++] = src[0];
    dst[ret++] = 0;
    src++;
  }
  dst[ret++]=0; 
  dst[ret++]=0; 
  return(ret-2); /* the way they do the md4 hash they don't represent
                    the last null. ie 'A' becomes just 0x41 0x00 - not
                    0x41 0x00 0x00 0x00 */
}

/*
  print binary buffer as hex-string
*/
void to_hexstr(const char *src, char hexstr[33])
{
  int i;
  unsigned char c;


  /* build string from binary hash */
  for (i = 0; i < 16; ++i)
  {
    c = src[i];
    sprintf(hexstr + 2*i, "%x", (c >> 4) & 0x0f);
    sprintf(hexstr + 2*i + 1, "%x", c & 0x0f);
  }

  /* convert to uppercase */
  for (i = 0; i < 32; ++i)
  {
    hexstr[i] = toupper(hexstr[i]);
  }

  hexstr[32] = '\0';
}


syntax highlighted by Code2HTML, v. 0.9.1