2 Unix SMB/Netbios implementation.
4 SMB parameters and setup
5 Copyright (C) Andrew Tridgell 1992-2000
6 Modified by Jeremy Allison.
7 Copyright (C) Jeremy Allison 1995-2000.
8 Copyright (C) Luke Kennethc Casson Leighton 1996-2000.
10 This program is free software; you can redistribute it and/or modify
11 it under the terms of the GNU General Public License as published by
12 the Free Software Foundation; either version 2 of the License, or
13 (at your option) any later version.
15 This program is distributed in the hope that it will be useful,
16 but WITHOUT ANY WARRANTY; without even the implied warranty of
17 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 GNU General Public License for more details.
20 You should have received a copy of the GNU General Public License
21 along with this program; if not, write to the Free Software
22 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
27 extern int DEBUGLEVEL
;
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
* pwrd
, uchar
* c8
, uchar
* p24
)
37 lm_owf_gen(pwrd
, p21
);
38 SMBOWFencrypt(p21
, c8
, p24
);
41 DEBUG(100, ("SMBencrypt: lm#, challenge, response\n"));
42 dump_data(100, p21
, 16);
43 dump_data(100, c8
, 8);
44 dump_data(100, p24
, 24);
48 /* Routines for Windows NT MD4 Hash functions. */
49 static int _my_wcslen(int16
* str
)
58 * Convert a string into an NT UNICODE string.
59 * Note that regardless of processor type
60 * this must be in intel (little-endian)
64 static int _my_mbstowcs(int16
* dst
, const uchar
* src
, int len
)
69 for (i
= 0; i
< len
; i
++)
81 static int _my_mbstowcsupper(int16
* dst
, const uchar
* src
, int len
)
86 for (i
= 0; i
< len
; i
++)
99 * Creates the MD4 Hash of the users password in NT UNICODE.
102 void E_md4hash(uchar
* pwrd
, uchar
* p16
)
107 /* Password cannot be longer than 128 characters */
108 len
= strlen((char *)pwrd
);
111 /* Password must be converted to NT unicode */
112 _my_mbstowcs(wpwd
, pwrd
, len
);
113 wpwd
[len
] = 0; /* Ensure string is null terminated */
114 /* Calculate length in bytes */
115 len
= _my_wcslen(wpwd
) * sizeof(int16
);
117 mdfour(p16
, (uchar
*) wpwd
, len
);
120 /* Does the LM owf of a user's password */
121 void lm_owf_gen(const char *pwd
, uchar p16
[16])
129 safe_strcpy(pwrd
, pwd
, sizeof(pwrd
) - 1);
132 /* Mangle the passwords into Lanman format */
136 /* Calculate the SMB (lanman) hash functions of the password */
138 E_P16((uchar
*) pwrd
, (uchar
*) p16
);
140 #ifdef DEBUG_PASSWORD
141 DEBUG(100, ("nt_lm_owf_gen: pwd, lm#\n"));
142 dump_data(120, pwrd
, strlen(pwrd
));
143 dump_data(100, p16
, 16);
145 /* clear out local copy of user's password (just being paranoid). */
149 /* Does both the NT and LM owfs of a user's password */
150 void nt_owf_gen(const char *pwd
, uchar nt_p16
[16])
157 safe_strcpy(pwrd
, pwd
, sizeof(pwrd
) - 1);
160 /* Calculate the MD4 hash (NT compatible) of the password */
161 E_md4hash((uchar
*) pwrd
, nt_p16
);
163 #ifdef DEBUG_PASSWORD
164 DEBUG(100, ("nt_owf_gen: pwd, nt#\n"));
165 dump_data(120, pwrd
, strlen(pwrd
));
166 dump_data(100, nt_p16
, 16);
168 /* clear out local copy of user's password (just being paranoid). */
172 /* Does both the NT and LM owfs of a user's password */
173 void nt_lm_owf_gen(const char *pwd
, uchar nt_p16
[16], uchar lm_p16
[16])
175 nt_owf_gen(pwd
, nt_p16
);
176 lm_owf_gen(pwd
, lm_p16
);
179 /* Does the des encryption from the NT or LM MD4 hash. */
180 void SMBOWFencrypt(const uchar pwrd
[16], const uchar
* c8
, uchar p24
[24])
186 memcpy(p21
, pwrd
, 16);
190 /* Does the des encryption from the FIRST 8 BYTES of the NT or LM MD4 hash. */
191 void NTLMSSPOWFencrypt(const uchar pwrd
[8], const uchar
* ntlmchalresp
,
197 memcpy(p21
, pwrd
, 8);
198 memset(p21
+ 8, 0xbd, 8);
200 E_P24(p21
, ntlmchalresp
, p24
);
201 #ifdef DEBUG_PASSWORD
202 DEBUG(100, ("NTLMSSPOWFencrypt: p21, c8, p24\n"));
203 dump_data(100, p21
, 21);
204 dump_data(100, ntlmchalresp
, 8);
205 dump_data(100, p24
, 24);
210 void SMBNTencrypt(uchar
* pwrd
, uchar
* c8
, uchar
* p24
)
216 nt_owf_gen(pwrd
, p21
);
217 SMBOWFencrypt(p21
, c8
, p24
);
219 #ifdef DEBUG_PASSWORD
220 DEBUG(100, ("SMBNTencrypt: nt#, challenge, response\n"));
221 dump_data(100, p21
, 16);
222 dump_data(100, c8
, 8);
223 dump_data(100, p24
, 24);
227 BOOL
make_oem_passwd_hash(uchar data
[516],
228 const char *pwrd
, int new_pw_len
,
229 const uchar old_pw_hash
[16], BOOL unicode
)
233 new_pw_len
= strlen(pwrd
) * (unicode
? 2 : 1);
236 if (new_pw_len
> 512)
239 ("make_oem_passwd_hash: new password is too long.\n"));
244 * Now setup the data area.
245 * We need to generate a random fill
246 * for this area to make it harder to
249 generate_random_buffer(data
, 516, False
);
252 ascii_to_unibuf(&data
[512 - new_pw_len
], pwrd
, new_pw_len
);
256 fstrcpy(&data
[512 - new_pw_len
], pwrd
);
258 SIVAL(data
, 512, new_pw_len
);
260 #ifdef DEBUG_PASSWORD
261 DEBUG(100, ("make_oem_passwd_hash\n"));
262 dump_data(100, data
, 516);
264 if (old_pw_hash
!= NULL
)
266 SamOEMhash(data
, old_pw_hash
, True
);
272 void SMBOWFencrypt_ntv2(const uchar kr
[16],
273 const uchar
* srv_chal
, int srv_chal_len
,
274 const uchar
* cli_chal
, int cli_chal_len
,
279 hmac_md5_init_limK_to_64(kr
, 16, &ctx
);
280 hmac_md5_update(srv_chal
, srv_chal_len
, &ctx
);
281 hmac_md5_update(cli_chal
, cli_chal_len
, &ctx
);
282 hmac_md5_final(resp_buf
, &ctx
);
284 #ifdef DEBUG_PASSWORD
285 DEBUG(100, ("SMBOWFencrypt_ntv2: srv_chal, cli_chal, resp_buf\n"));
286 dump_data(100, srv_chal
, srv_chal_len
);
287 dump_data(100, cli_chal
, cli_chal_len
);
288 dump_data(100, resp_buf
, 16);
292 void SMBsesskeygen_ntv2(const uchar kr
[16],
293 const uchar
* nt_resp
, char sess_key
[16])
297 hmac_md5_init_limK_to_64(kr
, 16, &ctx
);
298 hmac_md5_update(nt_resp
, 16, &ctx
);
299 hmac_md5_final(sess_key
, &ctx
);
301 #ifdef DEBUG_PASSWORD
302 DEBUG(100, ("SMBsesskeygen_ntv2:\n"));
303 dump_data(100, sess_key
, 16);
307 void SMBsesskeygen_ntv1(const uchar kr
[16],
308 const uchar
* nt_resp
, char sess_key
[16])
310 mdfour(sess_key
, kr
, 16);
312 #ifdef DEBUG_PASSWORD
313 DEBUG(100, ("SMBsesskeygen_ntv1:\n"));
314 dump_data(100, sess_key
, 16);
318 /***************************************************************************
319 tests showed that the nt challenge can be total random-length garbage!
320 ***************************************************************************/
321 void SMBgenclientchals(char *lm_cli_chal
,
322 char *nt_cli_chal
, int *nt_cli_chal_len
,
323 const char *srv
, const char *dom
)
326 int srv_len
= strlen(srv
);
327 int dom_len
= strlen(dom
);
330 fstrcpy(server
, srv
);
331 fstrcpy(domain
, dom
);
335 #ifdef EXPERIMENTATION_THIS_ACTUALLY_WORKS
336 generate_random_buffer(nt_cli_chal
, 64, False
);
337 (*nt_cli_chal_len
) = 64;
338 memcpy(lm_cli_chal
, nt_cli_chal
+ 16, 8);
339 generate_random_buffer(lm_cli_chal
, 8, False
);
344 generate_random_buffer(lm_cli_chal
, 8, False
);
345 unix_to_nt_time(&nt_time
, time(NULL
));
347 CVAL(nt_cli_chal
, 0) = 0x1;
348 CVAL(nt_cli_chal
, 1) = 0x1;
349 SSVAL(nt_cli_chal
, 2, 0x0);
350 SIVAL(nt_cli_chal
, 4, 0x0);
351 SIVAL(nt_cli_chal
, 8, nt_time
.low
);
352 SIVAL(nt_cli_chal
, 12, nt_time
.high
);
353 memcpy(nt_cli_chal
+ 16, lm_cli_chal
, 8);
354 /* fill in offset 24, size of structure, later */
356 *nt_cli_chal_len
= 28;
358 SSVAL(nt_cli_chal
, *nt_cli_chal_len
, 2);
359 *nt_cli_chal_len
+= 2;
360 SSVAL(nt_cli_chal
, *nt_cli_chal_len
, dom_len
* 2);
361 *nt_cli_chal_len
+= 2;
362 ascii_to_unibuf(nt_cli_chal
+ (*nt_cli_chal_len
), domain
,
364 *nt_cli_chal_len
+= dom_len
* 2;
365 *nt_cli_chal_len
+= 4 - ((*nt_cli_chal_len
) % 4);
367 SSVAL(nt_cli_chal
, *nt_cli_chal_len
, 2);
368 *nt_cli_chal_len
+= 2;
369 SSVAL(nt_cli_chal
, 30, srv_len
* 2);
370 *nt_cli_chal_len
+= 2;
371 ascii_to_unibuf(nt_cli_chal
+ (*nt_cli_chal_len
), server
,
373 *nt_cli_chal_len
+= srv_len
* 2;
375 SSVAL(nt_cli_chal
, 24, (*nt_cli_chal_len
) + 16);
376 SSVAL(nt_cli_chal
, 26, (*nt_cli_chal_len
) + 15);
378 DEBUG(100, ("SMBgenclientchals: srv %s, dom %s\n", server
, domain
));
379 dump_data(100, nt_cli_chal
, *nt_cli_chal_len
);
382 void ntv2_owf_gen(const uchar owf
[16],
383 const char *user_n
, const char *domain_n
, uchar kr_buf
[16])
389 int user_l
= strlen(user_n
);
390 int domain_l
= strlen(domain_n
);
392 _my_mbstowcsupper((int16
*) user_u
, user_n
, user_l
* 2);
393 _my_mbstowcsupper((int16
*) dom_u
, domain_n
, domain_l
* 2);
395 hmac_md5_init_limK_to_64(owf
, 16, &ctx
);
396 hmac_md5_update(user_u
, user_l
* 2, &ctx
);
397 hmac_md5_update(dom_u
, domain_l
* 2, &ctx
);
398 hmac_md5_final(kr_buf
, &ctx
);
400 #ifdef DEBUG_PASSWORD
401 DEBUG(100, ("ntv2_owf_gen: user, domain, owfkey, kr\n"));
402 dump_data(100, user_u
, user_l
* 2);
403 dump_data(100, dom_u
, domain_l
* 2);
404 dump_data(100, owf
, 16);
405 dump_data(100, kr_buf
, 16);
409 /* Does the LM owf of a user's password */
410 void lm_owf_genW(const UNISTR2
*pwd
, uchar p16
[16])
417 unistr2_to_ascii(pwrd
, pwd
, sizeof(pwrd
) - 1);
420 /* Mangle the passwords into Lanman format */
424 /* Calculate the SMB (lanman) hash functions of the password */
426 E_P16((uchar
*) pwrd
, (uchar
*) p16
);
428 #ifdef DEBUG_PASSWORD
429 DEBUG(100, ("lm_owf_genW: pwd, lm#\n"));
430 dump_data(120, pwrd
, strlen(pwrd
));
431 dump_data(100, p16
, 16);
433 /* clear out local copy of user's password (just being paranoid). */
437 /* Does both the NT and LM owfs of a user's password */
438 void nt_owf_genW(const UNISTR2
*pwd
, uchar nt_p16
[16])
443 for (i
= 0; i
< MIN(pwd
->uni_str_len
, sizeof(buf
) / 2); i
++)
445 SIVAL(buf
, i
* 2, pwd
->buffer
[i
]);
447 /* Calculate the MD4 hash (NT compatible) of the password */
448 mdfour(nt_p16
, buf
, pwd
->uni_str_len
* 2);
450 dump_data_pw("nt_owf_genW:", buf
, pwd
->uni_str_len
* 2);
451 dump_data_pw("nt#:", nt_p16
, 16);
453 /* clear out local copy of user's password (just being paranoid). */
457 /* Does both the NT and LM owfs of a user's UNICODE password */
458 void nt_lm_owf_genW(const UNISTR2
*pwd
, uchar nt_p16
[16], uchar lm_p16
[16])
460 nt_owf_genW(pwd
, nt_p16
);
461 lm_owf_genW(pwd
, lm_p16
);
464 BOOL
nt_encrypt_string2(STRING2
* out
, const STRING2
* in
, const uchar
* key
)
466 const uchar
*keyptr
= key
;
467 const uchar
*keyend
= key
+ 16;
468 int datalen
= in
->str_str_len
;
470 uchar
*outbuf
= (uchar
*) out
->buffer
;
471 const uchar
*inbuf
= (const uchar
*)in
->buffer
;
472 const uchar
*inbufend
;
474 out
->str_max_len
= in
->str_max_len
;
475 out
->str_str_len
= in
->str_str_len
;
478 inbufend
= inbuf
+ datalen
;
480 dump_data_pw("nt_encrypt_string2\n", inbuf
, datalen
);
482 while (inbuf
< inbufend
)
484 smbhash(outbuf
, inbuf
, keyptr
, 1);
487 if (keyptr
+ 7 > keyend
)
489 keyptr
= (keyend
- keyptr
) + key
;
496 dump_data_pw("nt_encrypt_string2\n", out
->buffer
, datalen
);
501 BOOL
nt_decrypt_string2(STRING2
* out
, const STRING2
* in
, const uchar
* key
)
503 int datalen
= in
->str_str_len
;
505 const uchar
*keyptr
= key
;
506 const uchar
*keyend
= key
+ 16;
508 uchar
*outbuf
= (uchar
*) out
->buffer
;
509 const uchar
*inbuf
= (const uchar
*)in
->buffer
;
510 const uchar
*inbufend
;
512 if (in
->str_str_len
> MAX_STRINGLEN
)
514 DEBUG(0, ("nt_decrypt_string2: failed\n"));
518 out
->str_max_len
= in
->str_max_len
;
519 out
->str_str_len
= in
->str_str_len
;
520 out
->undoc
= in
->undoc
;
522 inbufend
= inbuf
+ datalen
;
524 while (inbuf
< inbufend
)
526 smbhash(outbuf
, inbuf
, keyptr
, 0);
528 if (keyptr
+ 7 > keyend
)
530 keyptr
= (keyend
- keyptr
) + key
;
537 datalen
= IVAL(out
->buffer
, 0);
539 dump_data_pw("nt_decrypt_string2\n", out
->buffer
, out
->str_str_len
);
541 if (datalen
!= in
->str_str_len
- 8)
543 DEBUG(2, ("nt_decrypt_string2: length-match failed\n"));
550 /***********************************************************
551 decode a password buffer
552 ************************************************************/
553 BOOL
decode_pw_buffer(const char buffer
[516], char *new_pwrd
,
554 int new_pwrd_size
, uint32
*new_pw_len
)
557 * The length of the new password is in the last 4 bytes of
561 (*new_pw_len
) = IVAL(buffer
, 512);
563 #ifdef DEBUG_PASSWORD
564 dump_data(100, buffer
, 516);
567 if ((*new_pw_len
) < 0 || (*new_pw_len
) > new_pwrd_size
- 1)
570 ("decode_pw_buffer: incorrect password length (%d).\n",
575 memcpy(new_pwrd
, &buffer
[512 - (*new_pw_len
)], (*new_pw_len
));
576 new_pwrd
[(*new_pw_len
)] = '\0';
578 #ifdef DEBUG_PASSWORD
579 dump_data(100, new_pwrd
, (*new_pw_len
));
585 /***********************************************************
586 encode a password buffer
587 ************************************************************/
588 BOOL
encode_pw_buffer(char buffer
[516], const char *new_pass
,
589 int new_pw_len
, BOOL nt_pass_set
)
591 generate_random_buffer(buffer
, 516, True
);
596 * nt passwords are in unicode. last char overwrites NULL
597 * in ascii_to_unibuf, so use SIVAL *afterwards*.
600 ascii_to_unibuf(&buffer
[512 - new_pw_len
], new_pass
,
605 memcpy(&buffer
[512 - new_pw_len
], new_pass
, new_pw_len
);
609 * The length of the new password is in the last 4 bytes of
613 SIVAL(buffer
, 512, new_pw_len
);
615 #ifdef DEBUG_PASSWORD
616 dump_data(100, buffer
, 516);