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 #include "byteorder.h"
28 This implements the X/Open SMB password encryption
29 It takes a password, a 8 byte "crypt key" and puts 24 bytes of
30 encrypted password into p24 */
31 void SMBencrypt(const uchar
*passwd
, uchar
*c8
, uchar
*p24
)
33 uchar p14
[15], p21
[21];
37 StrnCpy((char *)p14
,(const char *)passwd
,14);
39 strupper((char *)p14
);
42 SMBOWFencrypt(p21
, c8
, p24
);
45 DEBUG(100,("SMBencrypt: lm#, challenge, response\n"));
46 dump_data(100, (char *)p21
, 16);
47 dump_data(100, (char *)c8
, 8);
48 dump_data(100, (char *)p24
, 24);
53 * Creates the MD4 Hash of the users password in NT UNICODE.
56 void E_md4hash(const uchar
*passwd
, uchar
*p16
)
61 /* Password cannot be longer than 128 characters */
62 len
= strlen((const char *)passwd
);
65 /* Password must be converted to NT unicode - null terminated. */
66 dos_struni2((char *)wpwd
, (const char *)passwd
, 256);
67 /* Calculate length in bytes */
68 len
= strlen_w((const smb_ucs2_t
*)wpwd
) * sizeof(int16
);
70 mdfour(p16
, (unsigned char *)wpwd
, len
);
73 /* Does both the NT and LM owfs of a user's password */
74 void nt_lm_owf_gen(char *pwd
, uchar nt_p16
[16], uchar p16
[16])
78 memset(passwd
,'\0',514);
79 safe_strcpy( passwd
, pwd
, sizeof(passwd
)-1);
81 /* Calculate the MD4 hash (NT compatible) of the password */
82 memset(nt_p16
, '\0', 16);
83 E_md4hash((uchar
*)passwd
, nt_p16
);
86 DEBUG(100,("nt_lm_owf_gen: pwd, nt#\n"));
87 dump_data(120, passwd
, strlen(passwd
));
88 dump_data(100, (char *)nt_p16
, 16);
91 /* Mangle the passwords into Lanman format */
95 /* Calculate the SMB (lanman) hash functions of the password */
97 memset(p16
, '\0', 16);
98 E_P16((uchar
*) passwd
, (uchar
*)p16
);
100 #ifdef DEBUG_PASSWORD
101 DEBUG(100,("nt_lm_owf_gen: pwd, lm#\n"));
102 dump_data(120, passwd
, strlen(passwd
));
103 dump_data(100, (char *)p16
, 16);
105 /* clear out local copy of user's password (just being paranoid). */
106 memset(passwd
, '\0', sizeof(passwd
));
109 /* Does the des encryption from the NT or LM MD4 hash. */
110 void SMBOWFencrypt(uchar passwd
[16], uchar
*c8
, uchar p24
[24])
116 memcpy(p21
, passwd
, 16);
120 /* Does the des encryption from the FIRST 8 BYTES of the NT or LM MD4 hash. */
121 void NTLMSSPOWFencrypt(uchar passwd
[8], uchar
*ntlmchalresp
, uchar p24
[24])
126 memcpy(p21
, passwd
, 8);
127 memset(p21
+ 8, 0xbd, 8);
129 E_P24(p21
, ntlmchalresp
, p24
);
130 #ifdef DEBUG_PASSWORD
131 DEBUG(100,("NTLMSSPOWFencrypt: p21, c8, p24\n"));
132 dump_data(100, (char *)p21
, 21);
133 dump_data(100, (char *)ntlmchalresp
, 8);
134 dump_data(100, (char *)p24
, 24);
139 /* Does the NT MD4 hash then des encryption. */
141 void SMBNTencrypt(const uchar
*passwd
, uchar
*c8
, uchar
*p24
)
147 E_md4hash(passwd
, p21
);
148 SMBOWFencrypt(p21
, c8
, p24
);
150 #ifdef DEBUG_PASSWORD
151 DEBUG(100,("SMBNTencrypt: nt#, challenge, response\n"));
152 dump_data(100, (char *)p21
, 16);
153 dump_data(100, (char *)c8
, 8);
154 dump_data(100, (char *)p24
, 24);
158 BOOL
make_oem_passwd_hash(char data
[516], const char *passwd
, uchar old_pw_hash
[16], BOOL unicode
)
160 int new_pw_len
= strlen(passwd
) * (unicode
? 2 : 1);
162 if (new_pw_len
> 512)
164 DEBUG(0,("make_oem_passwd_hash: new password is too long.\n"));
169 * Now setup the data area.
170 * We need to generate a random fill
171 * for this area to make it harder to
174 generate_random_buffer((unsigned char *)data
, 516, False
);
177 /* Note that passwd should be in DOS oem character set. */
178 dos_struni2( &data
[512 - new_pw_len
], passwd
, 512);
182 /* Note that passwd should be in DOS oem character set. */
183 fstrcpy( &data
[512 - new_pw_len
], passwd
);
185 SIVAL(data
, 512, new_pw_len
);
187 #ifdef DEBUG_PASSWORD
188 DEBUG(100,("make_oem_passwd_hash\n"));
189 dump_data(100, data
, 516);
191 SamOEMhash( (unsigned char *)data
, (unsigned char *)old_pw_hash
, 516);
196 /***********************************************************
197 Encode a password buffer.
198 ************************************************************/
200 BOOL
encode_pw_buffer(char buffer
[516], const char *new_pass
,
201 int new_pw_len
, BOOL nt_pass_set
)
203 generate_random_buffer((unsigned char *)buffer
, 516, True
);
205 if (new_pw_len
< 0 || new_pw_len
> 512)
210 dos_struni2(&buffer
[512 - new_pw_len
], new_pass
, 256);
212 memcpy(&buffer
[512 - new_pw_len
], new_pass
, new_pw_len
);
216 * The length of the new password is in the last 4 bytes of
219 SIVAL(buffer
, 512, new_pw_len
);
224 /***********************************************************
225 decode a password buffer
226 ************************************************************/
227 BOOL
decode_pw_buffer(char in_buffer
[516], char *new_pwrd
,
228 int new_pwrd_size
, uint32
*new_pw_len
,
229 uchar nt_p16
[16], uchar p16
[16])
235 char unicode_passwd
[514];
236 char lm_ascii_passwd
[514];
240 Warning !!! : This function is called from some rpc call.
241 The password IN the buffer is a UNICODE string.
242 The password IN new_pwrd is an ASCII string
243 If you reuse that code somewhere else check first.
246 ZERO_STRUCT(unicode_passwd
);
247 ZERO_STRUCT(lm_ascii_passwd
);
250 memset(nt_p16
, '\0', 16);
251 memset(p16
, '\0', 16);
253 /* The length of the new password is in the last 4 bytes of the data buffer. */
255 byte_len
= IVAL(in_buffer
, 512);
257 #ifdef DEBUG_PASSWORD
258 dump_data(100, in_buffer
, 516);
261 /* Password cannot be longer than 128 characters */
262 if ( (byte_len
< 0) || (byte_len
> new_pwrd_size
- 1)) {
263 DEBUG(0, ("decode_pw_buffer: incorrect password length (%d).\n", byte_len
));
267 uni_pw_len
= byte_len
/2;
268 pw
= dos_unistrn2((uint16
*)(&in_buffer
[512 - byte_len
]), byte_len
);
269 memcpy(passwd
, pw
, uni_pw_len
);
271 #ifdef DEBUG_PASSWORD
272 DEBUG(100,("nt_lm_owf_gen: passwd: "));
273 dump_data(100, (char *)passwd
, uni_pw_len
);
274 DEBUG(100,("len:%d\n", uni_pw_len
));
276 memcpy(unicode_passwd
, &in_buffer
[512 - byte_len
], byte_len
);
278 mdfour(nt_p16
, (unsigned char *)unicode_passwd
, byte_len
);
280 #ifdef DEBUG_PASSWORD
281 DEBUG(100,("nt_lm_owf_gen: nt#:"));
282 dump_data(100, (char *)nt_p16
, 16);
286 /* Mangle the passwords into Lanman format */
287 memcpy(lm_ascii_passwd
, passwd
, uni_pw_len
);
288 lm_ascii_passwd
[14] = '\0';
289 strupper(lm_ascii_passwd
);
291 /* Calculate the SMB (lanman) hash functions of the password */
292 E_P16((uchar
*) lm_ascii_passwd
, (uchar
*)p16
);
294 #ifdef DEBUG_PASSWORD
295 DEBUG(100,("nt_lm_owf_gen: lm#:"));
296 dump_data(100, (char *)p16
, 16);
300 /* copy the password and it's length to the return buffer */
301 *new_pw_len
=uni_pw_len
;
302 memcpy(new_pwrd
, passwd
, uni_pw_len
);
303 new_pwrd
[uni_pw_len
]='\0';
306 /* clear out local copy of user's password (just being paranoid). */
307 ZERO_STRUCT(unicode_passwd
);
308 ZERO_STRUCT(lm_ascii_passwd
);
315 /* Calculate the NT owfs of a user's password */
316 void nt_owf_genW(const UNISTR2
*pwd
, uchar nt_p16
[16])
321 for (i
= 0; i
< MIN(pwd
->uni_str_len
, sizeof(buf
) / 2); i
++)
322 SIVAL(buf
, i
* 2, pwd
->buffer
[i
]);
324 /* Calculate the MD4 hash (NT compatible) of the password */
325 mdfour(nt_p16
, (unsigned char *)buf
, pwd
->uni_str_len
* 2);
327 /* clear out local copy of user's password (just being paranoid). */