r14380: Reduce the size of structs.h
[sfrench/samba-autobuild/.git] / source4 / libcli / auth / smbencrypt.c
1 /* 
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.
8    Copyright (C) Andrew Bartlett <abartlet@samba.org> 2002-2003
9    
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.
14    
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.
19    
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.
23 */
24
25 #include "includes.h"
26 #include "system/time.h"
27 #include "smb.h"
28 #include "auth/ntlmssp/ntlmssp.h"
29 #include "auth/ntlmssp/msrpc_parse.h"
30 #include "lib/crypto/crypto.h"
31 #include "libcli/auth/libcli_auth.h"
32 #include "pstring.h"
33
34 /*
35    This implements the X/Open SMB password encryption
36    It takes a password ('unix' string), a 8 byte "crypt key" 
37    and puts 24 bytes of encrypted password into p24 
38
39    Returns False if password must have been truncated to create LM hash
40 */
41 BOOL SMBencrypt(const char *passwd, const uint8_t *c8, uint8_t p24[24])
42 {
43         BOOL ret;
44         uint8_t p21[21];
45
46         memset(p21,'\0',21);
47         ret = E_deshash(passwd, p21); 
48
49         SMBOWFencrypt(p21, c8, p24);
50
51 #ifdef DEBUG_PASSWORD
52         DEBUG(100,("SMBencrypt: lm#, challenge, response\n"));
53         dump_data(100, p21, 16);
54         dump_data(100, c8, 8);
55         dump_data(100, p24, 24);
56 #endif
57
58         return ret;
59 }
60
61 /**
62  * Creates the MD4 Hash of the users password in NT UNICODE.
63  * @param passwd password in 'unix' charset.
64  * @param p16 return password hashed with md4, caller allocated 16 byte buffer
65  */
66  
67 void E_md4hash(const char *passwd, uint8_t p16[16])
68 {
69         int len;
70         void *wpwd;
71
72         len = push_ucs2_talloc(NULL, &wpwd, passwd);
73         SMB_ASSERT(len >= 2);
74         
75         len -= 2;
76         mdfour(p16, wpwd, len);
77
78         talloc_free(wpwd);
79 }
80
81 /**
82  * Creates the DES forward-only Hash of the users password in DOS ASCII charset
83  * @param passwd password in 'unix' charset.
84  * @param p16 return password hashed with DES, caller allocated 16 byte buffer
85  * @return False if password was > 14 characters, and therefore may be incorrect, otherwise True
86  * @note p16 is filled in regardless
87  */
88  
89 BOOL E_deshash(const char *passwd, uint8_t p16[16])
90 {
91         BOOL ret = True;
92         fstring dospwd; 
93         ZERO_STRUCT(dospwd);
94         
95         /* Password must be converted to DOS charset - null terminated, uppercase. */
96         push_ascii(dospwd, passwd, sizeof(dospwd), STR_UPPER|STR_TERMINATE);
97        
98         /* Only the fisrt 14 chars are considered, password need not be null terminated. */
99         E_P16((const uint8_t *)dospwd, p16);
100
101         if (strlen(dospwd) > 14) {
102                 ret = False;
103         }
104
105         ZERO_STRUCT(dospwd);    
106
107         return ret;
108 }
109
110 /* Does both the NTLMv2 owfs of a user's password */
111 BOOL ntv2_owf_gen(const uint8_t owf[16],
112                   const char *user_in, const char *domain_in,
113                   BOOL upper_case_domain, /* Transform the domain into UPPER case */
114                   uint8_t kr_buf[16])
115 {
116         void *user;
117         void *domain;   
118         size_t user_byte_len;
119         size_t domain_byte_len;
120
121         HMACMD5Context ctx;
122         TALLOC_CTX *mem_ctx = talloc_init("ntv2_owf_gen for %s\\%s", domain_in, user_in); 
123         if (!mem_ctx) {
124                 return False;
125         }
126
127         if (!user_in) {
128                 user_in = "";
129         }
130
131         if (!domain_in) {
132                 domain_in = "";
133         }
134
135         user_in = strupper_talloc(mem_ctx, user_in);
136         if (user_in == NULL) {
137                 talloc_free(mem_ctx);
138                 return False;
139         }
140
141         if (upper_case_domain) {
142                 domain_in = strupper_talloc(mem_ctx, domain_in);
143                 if (domain_in == NULL) {
144                         talloc_free(mem_ctx);
145                         return False;
146                 }
147         }
148
149         user_byte_len = push_ucs2_talloc(mem_ctx, &user, user_in);
150         if (user_byte_len == (ssize_t)-1) {
151                 DEBUG(0, ("push_uss2_talloc() for user returned -1 (probably talloc() failure)\n"));
152                 talloc_free(mem_ctx);
153                 return False;
154         }
155
156         domain_byte_len = push_ucs2_talloc(mem_ctx, &domain, domain_in);
157         if (domain_byte_len == (ssize_t)-1) {
158                 DEBUG(0, ("push_ucs2_talloc() for domain returned -1 (probably talloc() failure)\n"));
159                 talloc_free(mem_ctx);
160                 return False;
161         }
162
163         SMB_ASSERT(user_byte_len >= 2);
164         SMB_ASSERT(domain_byte_len >= 2);
165
166         /* We don't want null termination */
167         user_byte_len = user_byte_len - 2;
168         domain_byte_len = domain_byte_len - 2;
169         
170         hmac_md5_init_limK_to_64(owf, 16, &ctx);
171         hmac_md5_update(user, user_byte_len, &ctx);
172         hmac_md5_update(domain, domain_byte_len, &ctx);
173         hmac_md5_final(kr_buf, &ctx);
174
175 #ifdef DEBUG_PASSWORD
176         DEBUG(100, ("ntv2_owf_gen: user, domain, owfkey, kr\n"));
177         dump_data(100, user, user_byte_len);
178         dump_data(100, domain, domain_byte_len);
179         dump_data(100, owf, 16);
180         dump_data(100, kr_buf, 16);
181 #endif
182
183         talloc_free(mem_ctx);
184         return True;
185 }
186
187 /* Does the des encryption from the NT or LM MD4 hash. */
188 void SMBOWFencrypt(const uint8_t passwd[16], const uint8_t *c8, uint8_t p24[24])
189 {
190         uint8_t p21[21];
191
192         ZERO_STRUCT(p21);
193  
194         memcpy(p21, passwd, 16);    
195         E_P24(p21, c8, p24);
196 }
197
198 /* Does the NT MD4 hash then des encryption. */
199  
200 void SMBNTencrypt(const char *passwd, uint8_t *c8, uint8_t *p24)
201 {
202         uint8_t p21[21];
203  
204         memset(p21,'\0',21);
205  
206         E_md4hash(passwd, p21);    
207         SMBOWFencrypt(p21, c8, p24);
208
209 #ifdef DEBUG_PASSWORD
210         DEBUG(100,("SMBNTencrypt: nt#, challenge, response\n"));
211         dump_data(100, p21, 16);
212         dump_data(100, c8, 8);
213         dump_data(100, p24, 24);
214 #endif
215 }
216
217 /* Does the md5 encryption from the Key Response for NTLMv2. */
218 void SMBOWFencrypt_ntv2(const uint8_t kr[16],
219                         const DATA_BLOB *srv_chal,
220                         const DATA_BLOB *smbcli_chal,
221                         uint8_t resp_buf[16])
222 {
223         HMACMD5Context ctx;
224
225         hmac_md5_init_limK_to_64(kr, 16, &ctx);
226         hmac_md5_update(srv_chal->data, srv_chal->length, &ctx);
227         hmac_md5_update(smbcli_chal->data, smbcli_chal->length, &ctx);
228         hmac_md5_final(resp_buf, &ctx);
229
230 #ifdef DEBUG_PASSWORD
231         DEBUG(100, ("SMBOWFencrypt_ntv2: srv_chal, smbcli_chal, resp_buf\n"));
232         dump_data(100, srv_chal->data, srv_chal->length);
233         dump_data(100, smbcli_chal->data, smbcli_chal->length);
234         dump_data(100, resp_buf, 16);
235 #endif
236 }
237
238 void SMBsesskeygen_ntv2(const uint8_t kr[16],
239                         const uint8_t * nt_resp, uint8_t sess_key[16])
240 {
241         /* a very nice, 128 bit, variable session key */
242         
243         HMACMD5Context ctx;
244
245         hmac_md5_init_limK_to_64(kr, 16, &ctx);
246         hmac_md5_update(nt_resp, 16, &ctx);
247         hmac_md5_final((uint8_t *)sess_key, &ctx);
248
249 #ifdef DEBUG_PASSWORD
250         DEBUG(100, ("SMBsesskeygen_ntv2:\n"));
251         dump_data(100, sess_key, 16);
252 #endif
253 }
254
255 void SMBsesskeygen_ntv1(const uint8_t kr[16], uint8_t sess_key[16])
256 {
257         /* yes, this session key does not change - yes, this 
258            is a problem - but it is 128 bits */
259         
260         mdfour((uint8_t *)sess_key, kr, 16);
261
262 #ifdef DEBUG_PASSWORD
263         DEBUG(100, ("SMBsesskeygen_ntv1:\n"));
264         dump_data(100, sess_key, 16);
265 #endif
266 }
267
268 void SMBsesskeygen_lm_sess_key(const uint8_t lm_hash[16],
269                                const uint8_t lm_resp[24], /* only uses 8 */ 
270                                uint8_t sess_key[16])
271 {
272         /* Calculate the LM session key (effective length 40 bits,
273            but changes with each session) */
274         uint8_t p24[24];
275         uint8_t partial_lm_hash[14];
276  
277         memcpy(partial_lm_hash, lm_hash, 8);    
278         memset(partial_lm_hash + 8, 0xbd, 6);
279
280         des_crypt56(p24,   lm_resp, partial_lm_hash,     1);
281         des_crypt56(p24+8, lm_resp, partial_lm_hash + 7, 1);
282
283         memcpy(sess_key, p24, 16);
284
285 #ifdef DEBUG_PASSWORD
286         DEBUG(100, ("SMBsesskeygen_lm_sess_key: \n"));
287         dump_data(100, sess_key, 16);
288 #endif
289 }
290
291 DATA_BLOB NTLMv2_generate_names_blob(TALLOC_CTX *mem_ctx, 
292                                      const char *hostname, 
293                                      const char *domain)
294 {
295         DATA_BLOB names_blob = data_blob_talloc(mem_ctx, NULL, 0);
296         
297         msrpc_gen(mem_ctx, &names_blob, "aaa", 
298                   NTLMSSP_NAME_TYPE_DOMAIN, domain,
299                   NTLMSSP_NAME_TYPE_SERVER, hostname,
300                   0, "");
301         return names_blob;
302 }
303
304 static DATA_BLOB NTLMv2_generate_client_data(TALLOC_CTX *mem_ctx, const DATA_BLOB *names_blob) 
305 {
306         uint8_t client_chal[8];
307         DATA_BLOB response = data_blob(NULL, 0);
308         uint8_t long_date[8];
309         NTTIME nttime;
310
311         unix_to_nt_time(&nttime, time(NULL));
312
313         generate_random_buffer(client_chal, sizeof(client_chal));
314
315         push_nttime(long_date, 0, nttime);
316
317         /* See http://www.ubiqx.org/cifs/SMB.html#SMB.8.5 */
318
319         msrpc_gen(mem_ctx, &response, "ddbbdb", 
320                   0x00000101,     /* Header  */
321                   0,              /* 'Reserved'  */
322                   long_date, 8,   /* Timestamp */
323                   client_chal, 8, /* client challenge */
324                   0,              /* Unknown */
325                   names_blob->data, names_blob->length);        /* End of name list */
326
327         return response;
328 }
329
330 static DATA_BLOB NTLMv2_generate_response(TALLOC_CTX *out_mem_ctx, 
331                                           const uint8_t ntlm_v2_hash[16],
332                                           const DATA_BLOB *server_chal,
333                                           const DATA_BLOB *names_blob)
334 {
335         uint8_t ntlmv2_response[16];
336         DATA_BLOB ntlmv2_client_data;
337         DATA_BLOB final_response;
338         
339         TALLOC_CTX *mem_ctx = talloc_named(out_mem_ctx, 0, 
340                                            "NTLMv2_generate_response internal context");
341
342         if (!mem_ctx) {
343                 return data_blob(NULL, 0);
344         }
345         
346         /* NTLMv2 */
347         /* generate some data to pass into the response function - including
348            the hostname and domain name of the server */
349         ntlmv2_client_data = NTLMv2_generate_client_data(mem_ctx, names_blob);
350
351         /* Given that data, and the challenge from the server, generate a response */
352         SMBOWFencrypt_ntv2(ntlm_v2_hash, server_chal, &ntlmv2_client_data, ntlmv2_response);
353         
354         final_response = data_blob_talloc(out_mem_ctx, NULL, sizeof(ntlmv2_response) + ntlmv2_client_data.length);
355
356         memcpy(final_response.data, ntlmv2_response, sizeof(ntlmv2_response));
357
358         memcpy(final_response.data+sizeof(ntlmv2_response), 
359                ntlmv2_client_data.data, ntlmv2_client_data.length);
360
361         talloc_free(mem_ctx);
362
363         return final_response;
364 }
365
366 static DATA_BLOB LMv2_generate_response(TALLOC_CTX *mem_ctx, 
367                                         const uint8_t ntlm_v2_hash[16],
368                                         const DATA_BLOB *server_chal)
369 {
370         uint8_t lmv2_response[16];
371         DATA_BLOB lmv2_client_data = data_blob_talloc(mem_ctx, NULL, 8);
372         DATA_BLOB final_response = data_blob_talloc(mem_ctx, NULL,24);
373         
374         /* LMv2 */
375         /* client-supplied random data */
376         generate_random_buffer(lmv2_client_data.data, lmv2_client_data.length); 
377
378         /* Given that data, and the challenge from the server, generate a response */
379         SMBOWFencrypt_ntv2(ntlm_v2_hash, server_chal, &lmv2_client_data, lmv2_response);
380         memcpy(final_response.data, lmv2_response, sizeof(lmv2_response));
381
382         /* after the first 16 bytes is the random data we generated above, 
383            so the server can verify us with it */
384         memcpy(final_response.data+sizeof(lmv2_response), 
385                lmv2_client_data.data, lmv2_client_data.length);
386
387         data_blob_free(&lmv2_client_data);
388
389         return final_response;
390 }
391
392 BOOL SMBNTLMv2encrypt_hash(TALLOC_CTX *mem_ctx, 
393                            const char *user, const char *domain, const uint8_t nt_hash[16],
394                            const DATA_BLOB *server_chal, 
395                            const DATA_BLOB *names_blob,
396                            DATA_BLOB *lm_response, DATA_BLOB *nt_response, 
397                            DATA_BLOB *lm_session_key, DATA_BLOB *user_session_key) 
398 {
399         uint8_t ntlm_v2_hash[16];
400
401         /* We don't use the NT# directly.  Instead we use it mashed up with
402            the username and domain.
403            This prevents username swapping during the auth exchange
404         */
405         if (!ntv2_owf_gen(nt_hash, user, domain, True, ntlm_v2_hash)) {
406                 return False;
407         }
408         
409         if (nt_response) {
410                 *nt_response = NTLMv2_generate_response(mem_ctx, 
411                                                         ntlm_v2_hash, server_chal,
412                                                         names_blob); 
413                 if (user_session_key) {
414                         *user_session_key = data_blob_talloc(mem_ctx, NULL, 16);
415                         
416                         /* The NTLMv2 calculations also provide a session key, for signing etc later */
417                         /* use only the first 16 bytes of nt_response for session key */
418                         SMBsesskeygen_ntv2(ntlm_v2_hash, nt_response->data, user_session_key->data);
419                 }
420         }
421         
422         /* LMv2 */
423         
424         if (lm_response) {
425                 *lm_response = LMv2_generate_response(mem_ctx, 
426                                                       ntlm_v2_hash, server_chal);
427                 if (lm_session_key) {
428                         *lm_session_key = data_blob_talloc(mem_ctx, NULL, 16);
429                         
430                         /* The NTLMv2 calculations also provide a session key, for signing etc later */
431                         /* use only the first 16 bytes of lm_response for session key */
432                         SMBsesskeygen_ntv2(ntlm_v2_hash, lm_response->data, lm_session_key->data);
433                 }
434         }
435         
436         return True;
437 }
438
439 BOOL SMBNTLMv2encrypt(TALLOC_CTX *mem_ctx, 
440                       const char *user, const char *domain, 
441                       const char *password, 
442                       const DATA_BLOB *server_chal, 
443                       const DATA_BLOB *names_blob,
444                       DATA_BLOB *lm_response, DATA_BLOB *nt_response, 
445                       DATA_BLOB *lm_session_key, DATA_BLOB *user_session_key) 
446 {
447         uint8_t nt_hash[16];
448         E_md4hash(password, nt_hash);
449
450         return SMBNTLMv2encrypt_hash(mem_ctx, 
451                                      user, domain, nt_hash, server_chal, names_blob,
452                                      lm_response, nt_response, lm_session_key, user_session_key);
453 }
454
455 /***********************************************************
456  encode a password buffer with a unicode password.  The buffer
457  is filled with random data to make it harder to attack.
458 ************************************************************/
459 BOOL encode_pw_buffer(uint8_t buffer[516], const char *password, int string_flags)
460 {
461         uint8_t new_pw[512];
462         size_t new_pw_len;
463
464         new_pw_len = push_string(new_pw,
465                                  password, 
466                                  sizeof(new_pw), string_flags);
467         
468         memcpy(&buffer[512 - new_pw_len], new_pw, new_pw_len);
469
470         generate_random_buffer(buffer, 512 - new_pw_len);
471
472         /* 
473          * The length of the new password is in the last 4 bytes of
474          * the data buffer.
475          */
476         SIVAL(buffer, 512, new_pw_len);
477         ZERO_STRUCT(new_pw);
478         return True;
479 }
480
481
482 /***********************************************************
483  decode a password buffer
484  *new_pw_len is the length in bytes of the possibly mulitbyte
485  returned password including termination.
486 ************************************************************/
487 BOOL decode_pw_buffer(uint8_t in_buffer[516], char *new_pwrd,
488                       int new_pwrd_size, uint32_t *new_pw_len,
489                       int string_flags)
490 {
491         int byte_len=0;
492
493         /*
494           Warning !!! : This function is called from some rpc call.
495           The password IN the buffer may be a UNICODE string.
496           The password IN new_pwrd is an ASCII string
497           If you reuse that code somewhere else check first.
498         */
499
500         /* The length of the new password is in the last 4 bytes of the data buffer. */
501
502         byte_len = IVAL(in_buffer, 512);
503
504 #ifdef DEBUG_PASSWORD
505         dump_data(100, in_buffer, 516);
506 #endif
507
508         /* Password cannot be longer than the size of the password buffer */
509         if ( (byte_len < 0) || (byte_len > 512)) {
510                 return False;
511         }
512
513         /* decode into the return buffer.  Buffer length supplied */
514         *new_pw_len = pull_string(new_pwrd, &in_buffer[512 - byte_len], new_pwrd_size, 
515                                   byte_len, string_flags);
516
517 #ifdef DEBUG_PASSWORD
518         DEBUG(100,("decode_pw_buffer: new_pwrd: "));
519         dump_data(100, (const uint8_t *)new_pwrd, *new_pw_len);
520         DEBUG(100,("multibyte len:%d\n", *new_pw_len));
521         DEBUG(100,("original char len:%d\n", byte_len/2));
522 #endif
523         
524         return True;
525 }