summaryrefslogtreecommitdiff
path: root/source/libsmb/smbencrypt.c
diff options
context:
space:
mode:
Diffstat (limited to 'source/libsmb/smbencrypt.c')
-rw-r--r--source/libsmb/smbencrypt.c95
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