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 /* Password must be converted to NT unicode - null terminated. */
63 dos_struni2((char *)wpwd
, (const char *)passwd
, sizeof(wpwd
));
64 /* Calculate length in bytes */
65 len
= strlen_w((const smb_ucs2_t
*)wpwd
) * sizeof(smb_ucs2_t
);
67 mdfour(p16
, (unsigned char *)wpwd
, len
);
70 /* Does both the NT and LM owfs of a user's password */
71 void nt_lm_owf_gen(char *pwd
, uchar nt_p16
[16], uchar p16
[16])
75 memset(passwd
,'\0',514);
76 safe_strcpy( passwd
, pwd
, sizeof(passwd
)-1);
78 /* Calculate the MD4 hash (NT compatible) of the password */
79 memset(nt_p16
, '\0', 16);
80 E_md4hash((uchar
*)passwd
, nt_p16
);
83 DEBUG(100,("nt_lm_owf_gen: pwd, nt#\n"));
84 dump_data(120, passwd
, strlen(passwd
));
85 dump_data(100, (char *)nt_p16
, 16);
88 /* Mangle the passwords into Lanman format */
92 /* Calculate the SMB (lanman) hash functions of the password */
94 memset(p16
, '\0', 16);
95 E_P16((uchar
*) passwd
, (uchar
*)p16
);
98 DEBUG(100,("nt_lm_owf_gen: pwd, lm#\n"));
99 dump_data(120, passwd
, strlen(passwd
));
100 dump_data(100, (char *)p16
, 16);
102 /* clear out local copy of user's password (just being paranoid). */
103 memset(passwd
, '\0', sizeof(passwd
));
106 /* Does the des encryption from the NT or LM MD4 hash. */
107 void SMBOWFencrypt(uchar passwd
[16], uchar
*c8
, uchar p24
[24])
113 memcpy(p21
, passwd
, 16);
117 /* Does the des encryption from the FIRST 8 BYTES of the NT or LM MD4 hash. */
118 void NTLMSSPOWFencrypt(uchar passwd
[8], uchar
*ntlmchalresp
, uchar p24
[24])
123 memcpy(p21
, passwd
, 8);
124 memset(p21
+ 8, 0xbd, 8);
126 E_P24(p21
, ntlmchalresp
, p24
);
127 #ifdef DEBUG_PASSWORD
128 DEBUG(100,("NTLMSSPOWFencrypt: p21, c8, p24\n"));
129 dump_data(100, (char *)p21
, 21);
130 dump_data(100, (char *)ntlmchalresp
, 8);
131 dump_data(100, (char *)p24
, 24);
136 /* Does the NT MD4 hash then des encryption. */
138 void SMBNTencrypt(const uchar
*passwd
, uchar
*c8
, uchar
*p24
)
144 E_md4hash(passwd
, p21
);
145 SMBOWFencrypt(p21
, c8
, p24
);
147 #ifdef DEBUG_PASSWORD
148 DEBUG(100,("SMBNTencrypt: nt#, challenge, response\n"));
149 dump_data(100, (char *)p21
, 16);
150 dump_data(100, (char *)c8
, 8);
151 dump_data(100, (char *)p24
, 24);
155 BOOL
make_oem_passwd_hash(char data
[516], const char *passwd
, uchar old_pw_hash
[16], BOOL unicode
)
157 int new_pw_len
= strlen(passwd
) * (unicode
? 2 : 1);
159 if (new_pw_len
> 512)
161 DEBUG(0,("make_oem_passwd_hash: new password is too long.\n"));
166 * Now setup the data area.
167 * We need to generate a random fill
168 * for this area to make it harder to
171 generate_random_buffer((unsigned char *)data
, 516, False
);
174 /* Note that passwd should be in DOS oem character set. */
175 dos_struni2( &data
[512 - new_pw_len
], passwd
, 512);
179 /* Note that passwd should be in DOS oem character set. */
180 fstrcpy( &data
[512 - new_pw_len
], passwd
);
182 SIVAL(data
, 512, new_pw_len
);
184 #ifdef DEBUG_PASSWORD
185 DEBUG(100,("make_oem_passwd_hash\n"));
186 dump_data(100, data
, 516);
188 SamOEMhash( (unsigned char *)data
, (unsigned char *)old_pw_hash
, 516);
193 /***********************************************************
194 Encode a password buffer.
195 ************************************************************/
197 BOOL
encode_pw_buffer(char buffer
[516], const char *new_pass
,
198 int new_pw_len
, BOOL nt_pass_set
)
200 generate_random_buffer((unsigned char *)buffer
, 516, True
);
202 if (new_pw_len
< 0 || new_pw_len
> 512)
207 dos_struni2(&buffer
[512 - new_pw_len
], new_pass
, 256);
209 memcpy(&buffer
[512 - new_pw_len
], new_pass
, new_pw_len
);
213 * The length of the new password is in the last 4 bytes of
216 SIVAL(buffer
, 512, new_pw_len
);
221 /***********************************************************
222 decode a password buffer
223 ************************************************************/
224 BOOL
decode_pw_buffer(char in_buffer
[516], char *new_pwrd
,
225 int new_pwrd_size
, uint32
*new_pw_len
,
226 uchar nt_p16
[16], uchar p16
[16])
232 char unicode_passwd
[514];
233 char lm_ascii_passwd
[514];
237 Warning !!! : This function is called from some rpc call.
238 The password IN the buffer is a UNICODE string.
239 The password IN new_pwrd is an ASCII string
240 If you reuse that code somewhere else check first.
243 ZERO_STRUCT(unicode_passwd
);
244 ZERO_STRUCT(lm_ascii_passwd
);
247 memset(nt_p16
, '\0', 16);
248 memset(p16
, '\0', 16);
250 /* The length of the new password is in the last 4 bytes of the data buffer. */
252 byte_len
= IVAL(in_buffer
, 512);
254 #ifdef DEBUG_PASSWORD
255 dump_data(100, in_buffer
, 516);
258 /* Password cannot be longer than 128 characters */
259 if ( (byte_len
< 0) || (byte_len
> new_pwrd_size
- 1)) {
260 DEBUG(0, ("decode_pw_buffer: incorrect password length (%d).\n", byte_len
));
264 uni_pw_len
= byte_len
/2;
265 pw
= dos_unistrn2((uint16
*)(&in_buffer
[512 - byte_len
]), uni_pw_len
);
266 memcpy(passwd
, pw
, uni_pw_len
);
268 #ifdef DEBUG_PASSWORD
269 DEBUG(100,("nt_lm_owf_gen: passwd: "));
270 dump_data(100, (char *)passwd
, uni_pw_len
);
271 DEBUG(100,("len:%d\n", uni_pw_len
));
273 memcpy(unicode_passwd
, &in_buffer
[512 - byte_len
], byte_len
);
275 mdfour(nt_p16
, (unsigned char *)unicode_passwd
, byte_len
);
277 #ifdef DEBUG_PASSWORD
278 DEBUG(100,("nt_lm_owf_gen: nt#:"));
279 dump_data(100, (char *)nt_p16
, 16);
283 /* Mangle the passwords into Lanman format */
284 memcpy(lm_ascii_passwd
, passwd
, uni_pw_len
);
285 lm_ascii_passwd
[14] = '\0';
286 strupper(lm_ascii_passwd
);
288 /* Calculate the SMB (lanman) hash functions of the password */
289 E_P16((uchar
*) lm_ascii_passwd
, (uchar
*)p16
);
291 #ifdef DEBUG_PASSWORD
292 DEBUG(100,("nt_lm_owf_gen: lm#:"));
293 dump_data(100, (char *)p16
, 16);
297 /* copy the password and it's length to the return buffer */
298 *new_pw_len
=uni_pw_len
;
299 memcpy(new_pwrd
, passwd
, uni_pw_len
);
300 new_pwrd
[uni_pw_len
]='\0';
303 /* clear out local copy of user's password (just being paranoid). */
304 ZERO_STRUCT(unicode_passwd
);
305 ZERO_STRUCT(lm_ascii_passwd
);
312 /* Calculate the NT owfs of a user's password */
313 void nt_owf_genW(const UNISTR2
*pwd
, uchar nt_p16
[16])
318 for (i
= 0; i
< MIN(pwd
->uni_str_len
, sizeof(buf
) / 2); i
++)
319 SIVAL(buf
, i
* 2, pwd
->buffer
[i
]);
321 /* Calculate the MD4 hash (NT compatible) of the password */
322 mdfour(nt_p16
, (unsigned char *)buf
, pwd
->uni_str_len
* 2);
324 /* clear out local copy of user's password (just being paranoid). */