2 Unix SMB/CIFS implementation.
3 SMB parameters and setup
4 Copyright (C) Andrew Tridgell 1992-1998
5 Modified by Jeremy Allison 1995.
6 Copyright (C) Jeremy Allison 1995-2000.
7 Copyright (C) Luke Kennethc Casson Leighton 1996-2000.
9 This program is free software; you can redistribute it and/or modify
10 it under the terms of the GNU General Public License as published by
11 the Free Software Foundation; either version 2 of the License, or
12 (at your option) any later version.
14 This program is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 GNU General Public License for more details.
19 You should have received a copy of the GNU General Public License
20 along with this program; if not, write to the Free Software
21 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, const 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, (const 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 push_ucs2(NULL, wpwd, (const char *)passwd, 256, STR_UNICODE|STR_NOALIGN|STR_TERMINATE);
67 /* Calculate length in bytes */
68 len = strlen_w(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(const 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 both the NTLMv2 owfs of a user's password */
110 void ntv2_owf_gen(const uchar owf[16],
111 const char *user_n, const char *domain_n, uchar kr_buf[16])
117 int user_l = strlen(user_n);
118 int domain_l = strlen(domain_n);
120 push_ucs2(NULL, user_u, user_n, (user_l+1)*2, STR_UNICODE|STR_NOALIGN|STR_TERMINATE|STR_UPPER);
121 push_ucs2(NULL, dom_u, domain_n, (domain_l+1)*2, STR_UNICODE|STR_NOALIGN|STR_TERMINATE|STR_UPPER);
123 hmac_md5_init_limK_to_64(owf, 16, &ctx);
124 hmac_md5_update((const unsigned char *)user_u, user_l * 2, &ctx);
125 hmac_md5_update((const unsigned char *)dom_u, domain_l * 2, &ctx);
126 hmac_md5_final(kr_buf, &ctx);
128 #ifdef DEBUG_PASSWORD
129 DEBUG(100, ("ntv2_owf_gen: user, domain, owfkey, kr\n"));
130 dump_data(100, user_u, user_l * 2);
131 dump_data(100, dom_u, domain_l * 2);
132 dump_data(100, owf, 16);
133 dump_data(100, kr_buf, 16);
137 /* Does the des encryption from the NT or LM MD4 hash. */
138 void SMBOWFencrypt(const uchar passwd[16], const uchar *c8, uchar p24[24])
144 memcpy(p21, passwd, 16);
148 /* Does the des encryption from the FIRST 8 BYTES of the NT or LM MD4 hash. */
149 void NTLMSSPOWFencrypt(const uchar passwd[8], const uchar *ntlmchalresp, uchar p24[24])
154 memcpy(p21, passwd, 8);
155 memset(p21 + 8, 0xbd, 8);
157 E_P24(p21, ntlmchalresp, p24);
158 #ifdef DEBUG_PASSWORD
159 DEBUG(100,("NTLMSSPOWFencrypt: p21, c8, p24\n"));
160 dump_data(100, (char *)p21, 21);
161 dump_data(100, (const char *)ntlmchalresp, 8);
162 dump_data(100, (char *)p24, 24);
167 /* Does the NT MD4 hash then des encryption. */
169 void SMBNTencrypt(const uchar *passwd, uchar *c8, uchar *p24)
175 E_md4hash(passwd, p21);
176 SMBOWFencrypt(p21, c8, p24);
178 #ifdef DEBUG_PASSWORD
179 DEBUG(100,("SMBNTencrypt: nt#, challenge, response\n"));
180 dump_data(100, (char *)p21, 16);
181 dump_data(100, (char *)c8, 8);
182 dump_data(100, (char *)p24, 24);
186 BOOL make_oem_passwd_hash(char data[516], const char *passwd, uchar old_pw_hash[16], BOOL unicode)
188 int new_pw_len = strlen(passwd) * (unicode ? 2 : 1);
190 if (new_pw_len > 512)
192 DEBUG(0,("make_oem_passwd_hash: new password is too long.\n"));
197 * Now setup the data area.
198 * We need to generate a random fill
199 * for this area to make it harder to
202 generate_random_buffer((unsigned char *)data, 516, False);
203 push_string(NULL, &data[512 - new_pw_len], passwd, new_pw_len,
204 STR_NOALIGN | (unicode?STR_UNICODE:STR_ASCII));
205 SIVAL(data, 512, new_pw_len);
207 #ifdef DEBUG_PASSWORD
208 DEBUG(100,("make_oem_passwd_hash\n"));
209 dump_data(100, data, 516);
211 SamOEMhash( (unsigned char *)data, (unsigned char *)old_pw_hash, 516);
216 /* Does the md5 encryption from the NT hash for NTLMv2. */
217 void SMBOWFencrypt_ntv2(const uchar kr[16],
218 const DATA_BLOB srv_chal,
219 const DATA_BLOB cli_chal,
224 hmac_md5_init_limK_to_64(kr, 16, &ctx);
225 hmac_md5_update(srv_chal.data, srv_chal.length, &ctx);
226 hmac_md5_update(cli_chal.data, cli_chal.length, &ctx);
227 hmac_md5_final((unsigned char *)resp_buf, &ctx);
229 #ifdef DEBUG_PASSWORD
230 DEBUG(100, ("SMBOWFencrypt_ntv2: srv_chal, cli_chal, resp_buf\n"));
231 dump_data(100, srv_chal.data, srv_chal.length);
232 dump_data(100, cli_chal.data, cli_chal.length);
233 dump_data(100, resp_buf, 16);
237 void SMBsesskeygen_ntv2(const uchar kr[16],
238 const uchar * nt_resp, uint8 sess_key[16])
242 hmac_md5_init_limK_to_64(kr, 16, &ctx);
243 hmac_md5_update(nt_resp, 16, &ctx);
244 hmac_md5_final((unsigned char *)sess_key, &ctx);
246 #ifdef DEBUG_PASSWORD
247 DEBUG(100, ("SMBsesskeygen_ntv2:\n"));
248 dump_data(100, sess_key, 16);
252 void SMBsesskeygen_ntv1(const uchar kr[16],
253 const uchar * nt_resp, uint8 sess_key[16])
255 mdfour((unsigned char *)sess_key, kr, 16);
257 #ifdef DEBUG_PASSWORD
258 DEBUG(100, ("SMBsesskeygen_ntv1:\n"));
259 dump_data(100, sess_key, 16);
263 /***********************************************************
264 encode a password buffer. The caller gets to figure out
266 ************************************************************/
267 BOOL encode_pw_buffer(char buffer[516], char *new_pw, int new_pw_length)
269 generate_random_buffer((unsigned char *)buffer, 516, True);
271 memcpy(&buffer[512 - new_pw_length], new_pw, new_pw_length);
274 * The length of the new password is in the last 4 bytes of
277 SIVAL(buffer, 512, new_pw_length);
282 /***********************************************************
283 decode a password buffer
284 *new_pw_len is the length in bytes of the possibly mulitbyte
285 returned password including termination.
286 ************************************************************/
287 BOOL decode_pw_buffer(char in_buffer[516], char *new_pwrd,
288 int new_pwrd_size, uint32 *new_pw_len)
293 Warning !!! : This function is called from some rpc call.
294 The password IN the buffer is a UNICODE string.
295 The password IN new_pwrd is an ASCII string
296 If you reuse that code somewhere else check first.
299 /* The length of the new password is in the last 4 bytes of the data buffer. */
301 byte_len = IVAL(in_buffer, 512);
303 #ifdef DEBUG_PASSWORD
304 dump_data(100, in_buffer, 516);
307 /* Password cannot be longer than 128 characters */
308 if ( (byte_len < 0) || (byte_len > new_pwrd_size - 1)) {
309 DEBUG(0, ("decode_pw_buffer: incorrect password length (%d).\n", byte_len));
310 DEBUG(0, ("decode_pw_buffer: check that 'encrypt passwords = yes'\n"));
314 /* decode into the return buffer. Buffer must be a pstring */
315 *new_pw_len = pull_string(NULL, new_pwrd, &in_buffer[512 - byte_len], new_pwrd_size, byte_len, STR_UNICODE);
317 #ifdef DEBUG_PASSWORD
318 DEBUG(100,("decode_pw_buffer: new_pwrd: "));
319 dump_data(100, (char *)new_pwrd, *new_pw_len);
320 DEBUG(100,("multibyte len:%d\n", *new_pw_len));
321 DEBUG(100,("original char len:%d\n", byte_len/2));
328 /* Calculate the NT owfs of a user's password */
329 void nt_owf_genW(const UNISTR2 *pwd, uchar nt_p16[16])
334 for (i = 0; i < MIN(pwd->uni_str_len, sizeof(buf) / 2); i++)
336 SIVAL(buf, i * 2, pwd->buffer[i]);
338 /* Calculate the MD4 hash (NT compatible) of the password */
339 mdfour(nt_p16, (const unsigned char *)buf, pwd->uni_str_len * 2);
341 /* clear out local copy of user's password (just being paranoid). */