diff options
Diffstat (limited to 'source/libsmb/smbencrypt.c')
-rw-r--r-- | source/libsmb/smbencrypt.c | 95 |
1 files changed, 90 insertions, 5 deletions
diff --git a/source/libsmb/smbencrypt.c b/source/libsmb/smbencrypt.c index 27172fd4136..8bb21cfed20 100644 --- a/source/libsmb/smbencrypt.c +++ b/source/libsmb/smbencrypt.c @@ -1,3 +1,4 @@ +#ifdef SMB_PASSWD /* Unix SMB/Netbios implementation. Version 1.9. @@ -21,11 +22,84 @@ */ #include "includes.h" +#include "des.h" +#include "md4.h" extern int DEBUGLEVEL; #include "byteorder.h" +void str_to_key(uchar *str,uchar *key) +{ + void des_set_odd_parity(des_cblock *); + int i; + + key[0] = str[0]>>1; + key[1] = ((str[0]&0x01)<<6) | (str[1]>>2); + key[2] = ((str[1]&0x03)<<5) | (str[2]>>3); + key[3] = ((str[2]&0x07)<<4) | (str[3]>>4); + key[4] = ((str[3]&0x0F)<<3) | (str[4]>>5); + key[5] = ((str[4]&0x1F)<<2) | (str[5]>>6); + key[6] = ((str[5]&0x3F)<<1) | (str[6]>>7); + key[7] = str[6]&0x7F; + for (i=0;i<8;i++) { + key[i] = (key[i]<<1); + } + des_set_odd_parity((des_cblock *)key); +} + +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 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); +} + + /* This implements the X/Open SMB password encryption It takes a password, a 8 byte "crypt key" and puts 24 bytes of @@ -81,20 +155,28 @@ static int _my_mbstowcs(int16 *dst, uchar *src, int len) void E_md4hash(uchar *passwd, uchar *p16) { - int len; + int i, len; int16 wpwd[129]; - + MDstruct MD; + /* Password cannot be longer than 128 characters */ len = strlen((char *)passwd); if(len > 128) len = 128; /* Password must be converted to NT unicode */ - _my_mbstowcs(wpwd, passwd, len); + _my_mbstowcs( wpwd, passwd, len); wpwd[len] = 0; /* Ensure string is null terminated */ /* Calculate length in bytes */ len = _my_wcslen(wpwd) * sizeof(int16); - - mdfour(p16, (unsigned char *)wpwd, len); + + MDbegin(&MD); + for(i = 0; i + 64 <= len; i += 64) + MDupdate(&MD,wpwd + (i/2), 512); + MDupdate(&MD,wpwd + (i/2),(len-i)*8); + SIVAL(p16,0,MD.buffer[0]); + SIVAL(p16,4,MD.buffer[1]); + SIVAL(p16,8,MD.buffer[2]); + SIVAL(p16,12,MD.buffer[3]); } /* Does the NT MD4 hash then des encryption. */ @@ -109,3 +191,6 @@ void SMBNTencrypt(uchar *passwd, uchar *c8, uchar *p24) E_P24(p21, c8, p24); } +#else + void smbencrypt_dummy(void){} +#endif |