2 Unix SMB/Netbios implementation.
4 SMB parameters and setup
5 Copyright (C) Andrew Tridgell 1992-1998
6 Modified by Jeremy Allison 1995.
8 This program is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 2 of the License, or
11 (at your option) any later version.
13 This program is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
18 You should have received a copy of the GNU General Public License
19 along with this program; if not, write to the Free Software
20 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
25 extern int DEBUGLEVEL
;
27 #include "byteorder.h"
30 This implements the X/Open SMB password encryption
31 It takes a password, a 8 byte "crypt key" and puts 24 bytes of
32 encrypted password into p24 */
33 void SMBencrypt(uchar
*passwd
, uchar
*c8
, uchar
*p24
)
35 uchar p14
[15], p21
[21];
39 StrnCpy((char *)p14
,(char *)passwd
,14);
41 strupper((char *)p14
);
44 SMBOWFencrypt(p21
, c8
, p24
);
47 DEBUG(100,("SMBencrypt: lm#, challenge, response\n"));
48 dump_data(100, (char *)p21
, 16);
49 dump_data(100, (char *)c8
, 8);
50 dump_data(100, (char *)p24
, 24);
54 /* Routines for Windows NT MD4 Hash functions. */
55 static int _my_wcslen(int16
*str
)
64 * Convert a string into an NT UNICODE string.
65 * Note that regardless of processor type
66 * this must be in intel (little-endian)
70 static int _my_mbstowcs(int16
*dst
, uchar
*src
, int len
)
75 for(i
= 0; i
< len
; i
++) {
87 * Creates the MD4 Hash of the users password in NT UNICODE.
90 void E_md4hash(uchar
*passwd
, uchar
*p16
)
95 /* Password cannot be longer than 128 characters */
96 len
= strlen((char *)passwd
);
99 /* Password must be converted to NT unicode */
100 _my_mbstowcs(wpwd
, passwd
, len
);
101 wpwd
[len
] = 0; /* Ensure string is null terminated */
102 /* Calculate length in bytes */
103 len
= _my_wcslen(wpwd
) * sizeof(int16
);
105 mdfour(p16
, (unsigned char *)wpwd
, len
);
108 /* Does both the NT and LM owfs of a user's password */
109 void nt_lm_owf_gen(char *pwd
, uchar nt_p16
[16], uchar p16
[16])
113 memset(passwd
,'\0',130);
114 safe_strcpy( passwd
, pwd
, sizeof(passwd
)-1);
116 /* Calculate the MD4 hash (NT compatible) of the password */
117 memset(nt_p16
, '\0', 16);
118 E_md4hash((uchar
*)passwd
, nt_p16
);
120 #ifdef DEBUG_PASSWORD
121 DEBUG(100,("nt_lm_owf_gen: pwd, nt#\n"));
122 dump_data(120, passwd
, strlen(passwd
));
123 dump_data(100, (char *)nt_p16
, 16);
126 /* Mangle the passwords into Lanman format */
130 /* Calculate the SMB (lanman) hash functions of the password */
132 memset(p16
, '\0', 16);
133 E_P16((uchar
*) passwd
, (uchar
*)p16
);
135 #ifdef DEBUG_PASSWORD
136 DEBUG(100,("nt_lm_owf_gen: pwd, lm#\n"));
137 dump_data(120, passwd
, strlen(passwd
));
138 dump_data(100, (char *)p16
, 16);
140 /* clear out local copy of user's password (just being paranoid). */
141 memset(passwd
, '\0', sizeof(passwd
));
144 /* Does the des encryption from the NT or LM MD4 hash. */
145 void SMBOWFencrypt(uchar passwd
[16], uchar
*c8
, uchar p24
[24])
151 memcpy(p21
, passwd
, 16);
155 /* Does the des encryption from the FIRST 8 BYTES of the NT or LM MD4 hash. */
156 void NTLMSSPOWFencrypt(uchar passwd
[8], uchar
*ntlmchalresp
, uchar p24
[24])
161 memcpy(p21
, passwd
, 8);
162 memset(p21
+ 8, 0xbd, 8);
164 E_P24(p21
, ntlmchalresp
, p24
);
165 #ifdef DEBUG_PASSWORD
166 DEBUG(100,("NTLMSSPOWFencrypt: p21, c8, p24\n"));
167 dump_data(100, (char *)p21
, 21);
168 dump_data(100, (char *)ntlmchalresp
, 8);
169 dump_data(100, (char *)p24
, 24);
174 /* Does the NT MD4 hash then des encryption. */
176 void SMBNTencrypt(uchar
*passwd
, uchar
*c8
, uchar
*p24
)
182 E_md4hash(passwd
, p21
);
183 SMBOWFencrypt(p21
, c8
, p24
);
185 #ifdef DEBUG_PASSWORD
186 DEBUG(100,("SMBNTencrypt: nt#, challenge, response\n"));
187 dump_data(100, (char *)p21
, 16);
188 dump_data(100, (char *)c8
, 8);
189 dump_data(100, (char *)p24
, 24);
193 BOOL
make_oem_passwd_hash(char data
[516], const char *passwd
, uchar old_pw_hash
[16], BOOL unicode
)
195 int new_pw_len
= strlen(passwd
) * (unicode
? 2 : 1);
197 if (new_pw_len
> 512)
199 DEBUG(0,("make_oem_passwd_hash: new password is too long.\n"));
204 * Now setup the data area.
205 * We need to generate a random fill
206 * for this area to make it harder to
209 generate_random_buffer((unsigned char *)data
, 516, False
);
212 /* Note that passwd should be in DOS oem character set. */
213 dos_struni2( &data
[512 - new_pw_len
], passwd
, 512);
217 /* Note that passwd should be in DOS oem character set. */
218 fstrcpy( &data
[512 - new_pw_len
], passwd
);
220 SIVAL(data
, 512, new_pw_len
);
222 #ifdef DEBUG_PASSWORD
223 DEBUG(100,("make_oem_passwd_hash\n"));
224 dump_data(100, data
, 516);
226 SamOEMhash( (unsigned char *)data
, (unsigned char *)old_pw_hash
, True
);