#include <stdio.h>
#include "includes.h"
#include "des.h"

/*
  8byte challenge for LM from server : 5766e2e275b97554 [offset 0x77]
  our 24byte response: 107893f3f45cf777158b782c6ef0077ad1dccdfeff2be459 [0x71]
  username:ADMINISTRATOR [0x89]

  threea:1001:1C3A2B6D939A1021AAD3B435B51404EE:E24106942BF38BCF57A6A4B29016EFF6:::
  password should be "aaa"
*/

void SMBencrypt(uchar *passwd, uchar *c8, uchar *p24);
char *StrnCpy(char *, char *, int);
void E_P16(uchar *, uchar *);
void E_P24(uchar *, uchar *, uchar *);
void E1(uchar *, uchar *, uchar *);
void D1(uchar *, uchar *, uchar *);
void strupper(char *);
extern void str_to_key (uchar *, uchar *);

/*
void main(){
  char chal[8]="\x57\x66\xe2\xe2\x75\xb9\x75\x54"; 
  char lmhash[21]="\x1C\x3A\x2B\x6D\x93\x9A\x10\x21\xAA\xD3\xB4\x35\xB5\x14\x04\xEE\x00\x00\x00\x00\x00";
  char nthash[21]="\xE2\x41\x06\x94\x2B\xF3\x8B\xCF\x57\xA6\xA4\xB2\x90\x16\xEF\xF6\x00\x00\x00\x00\x00";
  char holder[24];
  char pwd[]="aaa";
*/

/*  SMBencrypt(pwd, chal, holder); */
/*
  E_P24(lmhash, chal, holder);

  printf("foof!\n");
}
*/
/*
   This implements the X/Open SMB password encryption 
   It takes a password, a 8 byte "crypt key" and puts 24 bytes of
   encrypted password into p24 */

void SMBencrypt(uchar *passwd, uchar *c8, uchar *p24)
{ 
  uchar p14[15], p21[21];
  
  memset(p21,'\0',21);
  memset(p14,'\0',14);
  StrnCpy((char *)p14,(char *)passwd,14);
  
  strupper((char *)p14);
  E_P16(p14, p21);
  E_P24(p21, c8, p24);
} 


char *StrnCpy(char *dest,char *src,int n)
{  
  char *d = dest;
  if (!dest) return(NULL);
  if (!src) { 
    *dest = 0; 
    return(dest);
  }
  while (n-- && (*d++ = *src++)) ;
  *d = 0;
  return(dest);
}    

void E_P16(uchar *p14,uchar *p16)
{
  uchar sp7[7]; 
  /* the following constant makes us compatible with other
  implementations. Note that publishing this constant does not reduce the
  security of the encryption mechanism */
  uchar sp8[] = {0xAA,0xD3,0xB4,0x35,0xB5,0x14,0x4,0xEE};
  uchar x[8]; 
   
  memset(sp7,'\0',7);
  
  D1(sp7, sp8, x);
  E1(p14, x, p16);
  E1(p14+7, x, p16+8);
}    

void E_P24(uchar *p21, uchar *c8, uchar *p24)
{    
  E1(p21, c8, p24);
  E1(p21+7, c8, p24+8);
  E1(p21+14, c8, p24+16);
}    

void D1(uchar *k, uchar *d, uchar *out)
{ 
  des_key_schedule ks;
  des_cblock deskey;

  str_to_key(k,(uchar *)deskey);
#ifdef __FreeBSD__
  des_set_key(&deskey,ks);
#else /* __FreeBSD__ */
  des_set_key((des_cblock *)deskey,ks);
#endif /* __FreeBsd */
  des_ecb_encrypt((des_cblock *)d,(des_cblock *)out, ks, DES_DECRYPT);
}    

void E1(uchar *k, uchar *d, uchar *out)
{    
  des_key_schedule ks;
  des_cblock deskey;
     
  str_to_key(k,(uchar *)deskey);
#ifdef __FreeBSD__
  des_set_key(&deskey,ks);
#else /* __FreeBsd__ */
  des_set_key((des_cblock *)deskey,ks);
#endif /* __FreeBsd__ */
  des_ecb_encrypt((des_cblock *)d,(des_cblock *)out, ks, DES_ENCRYPT);
}    

void strupper(char *s)
{  
  while (*s)
    {
#ifdef KANJI
        if (is_shift_jis (*s)) {
            s += 2;
        } else if (is_kana (*s)) { 
            s++;
        } else {
            if (islower(*s))
                *s = toupper(*s);
            s++;
        }
#else
      if (islower(*s))
        *s = toupper(*s);
      s++;
#endif
    }
}   

