]> bbs.cooldavid.org Git - net-next-2.6.git/blob - fs/cifs/cifsencrypt.c
[CIFS] Fix ntlmv2 auth with ntlmssp
[net-next-2.6.git] / fs / cifs / cifsencrypt.c
1 /*
2  *   fs/cifs/cifsencrypt.c
3  *
4  *   Copyright (C) International Business Machines  Corp., 2005,2006
5  *   Author(s): Steve French (sfrench@us.ibm.com)
6  *
7  *   This library is free software; you can redistribute it and/or modify
8  *   it under the terms of the GNU Lesser General Public License as published
9  *   by the Free Software Foundation; either version 2.1 of the License, or
10  *   (at your option) any later version.
11  *
12  *   This library is distributed in the hope that it will be useful,
13  *   but WITHOUT ANY WARRANTY; without even the implied warranty of
14  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
15  *   the GNU Lesser General Public License for more details.
16  *
17  *   You should have received a copy of the GNU Lesser General Public License
18  *   along with this library; if not, write to the Free Software
19  *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20  */
21
22 #include <linux/fs.h>
23 #include <linux/slab.h>
24 #include "cifspdu.h"
25 #include "cifsglob.h"
26 #include "cifs_debug.h"
27 #include "md5.h"
28 #include "cifs_unicode.h"
29 #include "cifsproto.h"
30 #include "ntlmssp.h"
31 #include <linux/ctype.h>
32 #include <linux/random.h>
33
34 /* Calculate and return the CIFS signature based on the mac key and SMB PDU */
35 /* the 16 byte signature must be allocated by the caller  */
36 /* Note we only use the 1st eight bytes */
37 /* Note that the smb header signature field on input contains the
38         sequence number before this function is called */
39
40 extern void mdfour(unsigned char *out, unsigned char *in, int n);
41 extern void E_md4hash(const unsigned char *passwd, unsigned char *p16);
42 extern void SMBencrypt(unsigned char *passwd, const unsigned char *c8,
43                        unsigned char *p24);
44
45 static int cifs_calculate_signature(const struct smb_hdr *cifs_pdu,
46                         struct TCP_Server_Info *server, char *signature)
47 {
48         int rc = 0;
49         struct {
50                 struct shash_desc shash;
51                 char ctx[crypto_shash_descsize(server->ntlmssp.md5)];
52         } sdesc;
53
54         if (cifs_pdu == NULL || server == NULL || signature == NULL)
55                 return -EINVAL;
56
57         sdesc.shash.tfm = server->ntlmssp.md5;
58         sdesc.shash.flags = 0x0;
59
60         rc = crypto_shash_init(&sdesc.shash);
61         if (rc) {
62                 cERROR(1, "could not initialize master crypto API hmacmd5\n");
63                 return rc;
64         }
65
66         if (server->secType == RawNTLMSSP)
67                 crypto_shash_update(&sdesc.shash,
68                         server->session_key.data.ntlmv2.key,
69                         CIFS_NTLMV2_SESSKEY_SIZE);
70         else
71                 crypto_shash_update(&sdesc.shash,
72                         (char *)&server->session_key.data,
73                         server->session_key.len);
74
75         crypto_shash_update(&sdesc.shash,
76                         cifs_pdu->Protocol, cifs_pdu->smb_buf_length);
77
78         rc = crypto_shash_final(&sdesc.shash, signature);
79
80         return 0;
81 }
82
83
84 int cifs_sign_smb(struct smb_hdr *cifs_pdu, struct TCP_Server_Info *server,
85                   __u32 *pexpected_response_sequence_number)
86 {
87         int rc = 0;
88         char smb_signature[20];
89
90         if ((cifs_pdu == NULL) || (server == NULL))
91                 return -EINVAL;
92
93         if ((cifs_pdu->Flags2 & SMBFLG2_SECURITY_SIGNATURE) == 0)
94                 return rc;
95
96         spin_lock(&GlobalMid_Lock);
97         cifs_pdu->Signature.Sequence.SequenceNumber =
98                         cpu_to_le32(server->sequence_number);
99         cifs_pdu->Signature.Sequence.Reserved = 0;
100
101         *pexpected_response_sequence_number = server->sequence_number++;
102         server->sequence_number++;
103         spin_unlock(&GlobalMid_Lock);
104
105         rc = cifs_calculate_signature(cifs_pdu, server, smb_signature);
106         if (rc)
107                 memset(cifs_pdu->Signature.SecuritySignature, 0, 8);
108         else
109                 memcpy(cifs_pdu->Signature.SecuritySignature, smb_signature, 8);
110
111         return rc;
112 }
113
114 static int cifs_calc_signature2(const struct kvec *iov, int n_vec,
115                         struct TCP_Server_Info *server, char *signature)
116 {
117         int i;
118         int rc = 0;
119         struct {
120                 struct shash_desc shash;
121                 char ctx[crypto_shash_descsize(server->ntlmssp.md5)];
122         } sdesc;
123
124         if (iov == NULL || server == NULL || signature == NULL)
125                 return -EINVAL;
126
127         sdesc.shash.tfm = server->ntlmssp.md5;
128         sdesc.shash.flags = 0x0;
129
130         rc = crypto_shash_init(&sdesc.shash);
131         if (rc) {
132                 cERROR(1, "could not initialize master crypto API hmacmd5\n");
133                 return rc;
134         }
135
136         if (server->secType == RawNTLMSSP)
137                 crypto_shash_update(&sdesc.shash,
138                         server->session_key.data.ntlmv2.key,
139                         CIFS_NTLMV2_SESSKEY_SIZE);
140         else
141                 crypto_shash_update(&sdesc.shash,
142                         (char *)&server->session_key.data,
143                         server->session_key.len);
144
145         for (i = 0; i < n_vec; i++) {
146                 if (iov[i].iov_len == 0)
147                         continue;
148                 if (iov[i].iov_base == NULL) {
149                         cERROR(1, "null iovec entry");
150                         return -EIO;
151                 }
152                 /* The first entry includes a length field (which does not get
153                    signed that occupies the first 4 bytes before the header */
154                 if (i == 0) {
155                         if (iov[0].iov_len <= 8) /* cmd field at offset 9 */
156                                 break; /* nothing to sign or corrupt header */
157                         crypto_shash_update(&sdesc.shash,
158                                 iov[i].iov_base + 4, iov[i].iov_len - 4);
159                 } else
160                         crypto_shash_update(&sdesc.shash,
161                                 iov[i].iov_base, iov[i].iov_len);
162         }
163
164         rc = crypto_shash_final(&sdesc.shash, signature);
165
166         return 0;
167 }
168
169 int cifs_sign_smb2(struct kvec *iov, int n_vec, struct TCP_Server_Info *server,
170                    __u32 *pexpected_response_sequence_number)
171 {
172         int rc = 0;
173         char smb_signature[20];
174         struct smb_hdr *cifs_pdu = iov[0].iov_base;
175
176         if ((cifs_pdu == NULL) || (server == NULL))
177                 return -EINVAL;
178
179         if ((cifs_pdu->Flags2 & SMBFLG2_SECURITY_SIGNATURE) == 0)
180                 return rc;
181
182         spin_lock(&GlobalMid_Lock);
183         cifs_pdu->Signature.Sequence.SequenceNumber =
184                                 cpu_to_le32(server->sequence_number);
185         cifs_pdu->Signature.Sequence.Reserved = 0;
186
187         *pexpected_response_sequence_number = server->sequence_number++;
188         server->sequence_number++;
189         spin_unlock(&GlobalMid_Lock);
190
191         rc = cifs_calc_signature2(iov, n_vec, server, smb_signature);
192         if (rc)
193                 memset(cifs_pdu->Signature.SecuritySignature, 0, 8);
194         else
195                 memcpy(cifs_pdu->Signature.SecuritySignature, smb_signature, 8);
196
197         return rc;
198 }
199
200 int cifs_verify_signature(struct smb_hdr *cifs_pdu,
201                           struct TCP_Server_Info *server,
202                           __u32 expected_sequence_number)
203 {
204         int rc;
205         char server_response_sig[8];
206         char what_we_think_sig_should_be[20];
207
208         if (cifs_pdu == NULL || server == NULL)
209                 return -EINVAL;
210
211         if (cifs_pdu->Command == SMB_COM_NEGOTIATE)
212                 return 0;
213
214         if (cifs_pdu->Command == SMB_COM_LOCKING_ANDX) {
215                 struct smb_com_lock_req *pSMB =
216                         (struct smb_com_lock_req *)cifs_pdu;
217             if (pSMB->LockType & LOCKING_ANDX_OPLOCK_RELEASE)
218                         return 0;
219         }
220
221         /* BB what if signatures are supposed to be on for session but
222            server does not send one? BB */
223
224         /* Do not need to verify session setups with signature "BSRSPYL "  */
225         if (memcmp(cifs_pdu->Signature.SecuritySignature, "BSRSPYL ", 8) == 0)
226                 cFYI(1, "dummy signature received for smb command 0x%x",
227                         cifs_pdu->Command);
228
229         /* save off the origiginal signature so we can modify the smb and check
230                 its signature against what the server sent */
231         memcpy(server_response_sig, cifs_pdu->Signature.SecuritySignature, 8);
232
233         cifs_pdu->Signature.Sequence.SequenceNumber =
234                                         cpu_to_le32(expected_sequence_number);
235         cifs_pdu->Signature.Sequence.Reserved = 0;
236
237         rc = cifs_calculate_signature(cifs_pdu, server,
238                 what_we_think_sig_should_be);
239
240         if (rc)
241                 return rc;
242
243 /*      cifs_dump_mem("what we think it should be: ",
244                       what_we_think_sig_should_be, 16); */
245
246         if (memcmp(server_response_sig, what_we_think_sig_should_be, 8))
247                 return -EACCES;
248         else
249                 return 0;
250
251 }
252
253 /* We fill in key by putting in 40 byte array which was allocated by caller */
254 int cifs_calculate_session_key(struct session_key *key, const char *rn,
255                            const char *password)
256 {
257         char temp_key[16];
258         if ((key == NULL) || (rn == NULL))
259                 return -EINVAL;
260
261         E_md4hash(password, temp_key);
262         mdfour(key->data.ntlm, temp_key, 16);
263         memcpy(key->data.ntlm+16, rn, CIFS_SESS_KEY_SIZE);
264         key->len = 40;
265         return 0;
266 }
267
268 #ifdef CONFIG_CIFS_WEAK_PW_HASH
269 void calc_lanman_hash(const char *password, const char *cryptkey, bool encrypt,
270                         char *lnm_session_key)
271 {
272         int i;
273         char password_with_pad[CIFS_ENCPWD_SIZE];
274
275         memset(password_with_pad, 0, CIFS_ENCPWD_SIZE);
276         if (password)
277                 strncpy(password_with_pad, password, CIFS_ENCPWD_SIZE);
278
279         if (!encrypt && global_secflags & CIFSSEC_MAY_PLNTXT) {
280                 memset(lnm_session_key, 0, CIFS_SESS_KEY_SIZE);
281                 memcpy(lnm_session_key, password_with_pad,
282                         CIFS_ENCPWD_SIZE);
283                 return;
284         }
285
286         /* calculate old style session key */
287         /* calling toupper is less broken than repeatedly
288         calling nls_toupper would be since that will never
289         work for UTF8, but neither handles multibyte code pages
290         but the only alternative would be converting to UCS-16 (Unicode)
291         (using a routine something like UniStrupr) then
292         uppercasing and then converting back from Unicode - which
293         would only worth doing it if we knew it were utf8. Basically
294         utf8 and other multibyte codepages each need their own strupper
295         function since a byte at a time will ont work. */
296
297         for (i = 0; i < CIFS_ENCPWD_SIZE; i++)
298                 password_with_pad[i] = toupper(password_with_pad[i]);
299
300         SMBencrypt(password_with_pad, cryptkey, lnm_session_key);
301
302         /* clear password before we return/free memory */
303         memset(password_with_pad, 0, CIFS_ENCPWD_SIZE);
304 }
305 #endif /* CIFS_WEAK_PW_HASH */
306
307 static int calc_ntlmv2_hash(struct cifsSesInfo *ses,
308                             const struct nls_table *nls_cp)
309 {
310         int rc = 0;
311         int len;
312         char nt_hash[CIFS_NTHASH_SIZE];
313         wchar_t *user;
314         wchar_t *domain;
315         wchar_t *server;
316         struct {
317                 struct shash_desc shash;
318                 char ctx[crypto_shash_descsize(ses->server->ntlmssp.hmacmd5)];
319         } sdesc;
320
321         /* calculate md4 hash of password */
322         E_md4hash(ses->password, nt_hash);
323
324         sdesc.shash.tfm = ses->server->ntlmssp.hmacmd5;
325         sdesc.shash.flags = 0x0;
326
327         crypto_shash_setkey(ses->server->ntlmssp.hmacmd5, nt_hash,
328                                 CIFS_NTHASH_SIZE);
329
330         rc = crypto_shash_init(&sdesc.shash);
331         if (rc) {
332                 cERROR(1, "could not initialize master crypto API hmacmd5\n");
333                 return rc;
334         }
335
336         /* convert ses->userName to unicode and uppercase */
337         len = strlen(ses->userName);
338         user = kmalloc(2 + (len * 2), GFP_KERNEL);
339         if (user == NULL)
340                 goto calc_exit_2;
341         len = cifs_strtoUCS((__le16 *)user, ses->userName, len, nls_cp);
342         UniStrupr(user);
343
344         crypto_shash_update(&sdesc.shash, (char *)user, 2 * len);
345
346         /* convert ses->domainName to unicode and uppercase */
347         if (ses->domainName) {
348                 len = strlen(ses->domainName);
349
350                 domain = kmalloc(2 + (len * 2), GFP_KERNEL);
351                 if (domain == NULL)
352                         goto calc_exit_1;
353                 len = cifs_strtoUCS((__le16 *)domain, ses->domainName, len,
354                                         nls_cp);
355                 /* the following line was removed since it didn't work well
356                    with lower cased domain name that passed as an option.
357                    Maybe converting the domain name earlier makes sense */
358                 /* UniStrupr(domain); */
359
360                 crypto_shash_update(&sdesc.shash, (char *)domain, 2 * len);
361
362                 kfree(domain);
363         } else if (ses->serverName) {
364                 len = strlen(ses->serverName);
365
366                 server = kmalloc(2 + (len * 2), GFP_KERNEL);
367                 if (server == NULL)
368                         goto calc_exit_1;
369                 len = cifs_strtoUCS((__le16 *)server, ses->serverName, len,
370                                         nls_cp);
371                 /* the following line was removed since it didn't work well
372                    with lower cased domain name that passed as an option.
373                    Maybe converting the domain name earlier makes sense */
374                 /* UniStrupr(domain); */
375
376                 crypto_shash_update(&sdesc.shash, (char *)server, 2 * len);
377
378                 kfree(server);
379         }
380 calc_exit_1:
381         kfree(user);
382 calc_exit_2:
383         /* BB FIXME what about bytes 24 through 40 of the signing key?
384            compare with the NTLM example */
385         rc = crypto_shash_final(&sdesc.shash, ses->server->ntlmv2_hash);
386
387         return rc;
388 }
389
390 static int
391 find_domain_name(struct cifsSesInfo *ses)
392 {
393         int rc = 0;
394         unsigned int attrsize;
395         unsigned int type;
396         unsigned char *blobptr;
397         struct ntlmssp2_name *attrptr;
398
399         if (ses->server->tiblob) {
400                 blobptr = ses->server->tiblob;
401                 attrptr = (struct ntlmssp2_name *) blobptr;
402
403                 while ((type = attrptr->type) != 0) {
404                         blobptr += 2; /* advance attr type */
405                         attrsize = attrptr->length;
406                         blobptr += 2; /* advance attr size */
407                         if (type == NTLMSSP_AV_NB_DOMAIN_NAME) {
408                                 if (!ses->domainName) {
409                                         ses->domainName =
410                                                 kmalloc(attrptr->length + 1,
411                                                                 GFP_KERNEL);
412                                         if (!ses->domainName)
413                                                         return -ENOMEM;
414                                         cifs_from_ucs2(ses->domainName,
415                                                 (__le16 *)blobptr,
416                                                 attrptr->length,
417                                                 attrptr->length,
418                                                 load_nls_default(), false);
419                                 }
420                         }
421                         blobptr += attrsize; /* advance attr  value */
422                         attrptr = (struct ntlmssp2_name *) blobptr;
423                 }
424         } else {
425                 ses->server->tilen = 2 * sizeof(struct ntlmssp2_name);
426                 ses->server->tiblob = kmalloc(ses->server->tilen, GFP_KERNEL);
427                 if (!ses->server->tiblob) {
428                         ses->server->tilen = 0;
429                         cERROR(1, "Challenge target info allocation failure");
430                         return -ENOMEM;
431                 }
432                 memset(ses->server->tiblob, 0x0, ses->server->tilen);
433                 attrptr = (struct ntlmssp2_name *) ses->server->tiblob;
434                 attrptr->type = cpu_to_le16(NTLMSSP_DOMAIN_TYPE);
435         }
436
437         return rc;
438 }
439
440 static int
441 CalcNTLMv2_response(const struct TCP_Server_Info *server,
442                          char *v2_session_response)
443 {
444         int rc;
445         struct {
446                 struct shash_desc shash;
447                 char ctx[crypto_shash_descsize(server->ntlmssp.hmacmd5)];
448         } sdesc;
449
450         sdesc.shash.tfm = server->ntlmssp.hmacmd5;
451         sdesc.shash.flags = 0x0;
452
453         crypto_shash_setkey(server->ntlmssp.hmacmd5, server->ntlmv2_hash,
454                 CIFS_HMAC_MD5_HASH_SIZE);
455
456         rc = crypto_shash_init(&sdesc.shash);
457         if (rc) {
458                 cERROR(1, "could not initialize master crypto API hmacmd5\n");
459                 return rc;
460         }
461
462         memcpy(v2_session_response + CIFS_SERVER_CHALLENGE_SIZE,
463                 server->cryptKey, CIFS_SERVER_CHALLENGE_SIZE);
464         crypto_shash_update(&sdesc.shash,
465                 v2_session_response + CIFS_SERVER_CHALLENGE_SIZE,
466                 sizeof(struct ntlmv2_resp) - CIFS_SERVER_CHALLENGE_SIZE);
467
468         if (server->tilen)
469                 crypto_shash_update(&sdesc.shash,
470                                         server->tiblob, server->tilen);
471
472         rc = crypto_shash_final(&sdesc.shash, v2_session_response);
473
474         return rc;
475 }
476
477 int
478 setup_ntlmv2_rsp(struct cifsSesInfo *ses, char *resp_buf,
479                       const struct nls_table *nls_cp)
480 {
481         int rc = 0;
482         struct ntlmv2_resp *buf = (struct ntlmv2_resp *)resp_buf;
483         struct {
484                 struct shash_desc shash;
485                 char ctx[crypto_shash_descsize(ses->server->ntlmssp.hmacmd5)];
486         } sdesc;
487
488         buf->blob_signature = cpu_to_le32(0x00000101);
489         buf->reserved = 0;
490         buf->time = cpu_to_le64(cifs_UnixTimeToNT(CURRENT_TIME));
491         get_random_bytes(&buf->client_chal, sizeof(buf->client_chal));
492         buf->reserved2 = 0;
493
494         if (!ses->domainName) {
495                 rc = find_domain_name(ses);
496                 if (rc) {
497                         cERROR(1, "could not get domain/server name rc %d", rc);
498                         return rc;
499                 }
500         }
501
502         /* calculate buf->ntlmv2_hash */
503         rc = calc_ntlmv2_hash(ses, nls_cp);
504         if (rc) {
505                 cERROR(1, "could not get v2 hash rc %d", rc);
506                 return rc;
507         }
508         rc = CalcNTLMv2_response(ses->server, resp_buf);
509         if (rc) {
510                 cERROR(1, "could not get v2 hash rc %d", rc);
511                 return rc;
512         }
513
514         crypto_shash_setkey(ses->server->ntlmssp.hmacmd5,
515                         ses->server->ntlmv2_hash, CIFS_HMAC_MD5_HASH_SIZE);
516
517         sdesc.shash.tfm = ses->server->ntlmssp.hmacmd5;
518         sdesc.shash.flags = 0x0;
519
520         rc = crypto_shash_init(&sdesc.shash);
521         if (rc) {
522                 cERROR(1, "could not initialize master crypto API hmacmd5\n");
523                 return rc;
524         }
525
526         crypto_shash_update(&sdesc.shash, resp_buf, CIFS_HMAC_MD5_HASH_SIZE);
527
528         rc = crypto_shash_final(&sdesc.shash,
529                 ses->server->session_key.data.ntlmv2.key);
530
531         memcpy(&ses->server->session_key.data.ntlmv2.resp, resp_buf,
532                         sizeof(struct ntlmv2_resp));
533         ses->server->session_key.len = 16 + sizeof(struct ntlmv2_resp);
534
535         return rc;
536 }
537
538 int
539 calc_seckey(struct TCP_Server_Info *server)
540 {
541         int rc;
542         unsigned char sec_key[CIFS_NTLMV2_SESSKEY_SIZE];
543         struct crypto_blkcipher *tfm_arc4;
544         struct scatterlist sgin, sgout;
545         struct blkcipher_desc desc;
546
547         get_random_bytes(sec_key, CIFS_NTLMV2_SESSKEY_SIZE);
548
549         tfm_arc4 = crypto_alloc_blkcipher("ecb(arc4)",
550                                                 0, CRYPTO_ALG_ASYNC);
551         if (!tfm_arc4 || IS_ERR(tfm_arc4)) {
552                 cERROR(1, "could not allocate " "master crypto API arc4\n");
553                 return 1;
554         }
555
556         crypto_blkcipher_setkey(tfm_arc4,
557                 server->session_key.data.ntlmv2.key, CIFS_CPHTXT_SIZE);
558         sg_init_one(&sgin, sec_key, CIFS_CPHTXT_SIZE);
559         sg_init_one(&sgout, server->ntlmssp.ciphertext, CIFS_CPHTXT_SIZE);
560         rc = crypto_blkcipher_encrypt(&desc, &sgout, &sgin, CIFS_CPHTXT_SIZE);
561
562         if (!rc)
563                 memcpy(server->session_key.data.ntlmv2.key,
564                                 sec_key, CIFS_NTLMV2_SESSKEY_SIZE);
565
566         crypto_free_blkcipher(tfm_arc4);
567
568         return 0;
569 }
570
571 void
572 cifs_crypto_shash_release(struct TCP_Server_Info *server)
573 {
574         if (server->ntlmssp.md5)
575                 crypto_free_shash(server->ntlmssp.md5);
576
577         if (server->ntlmssp.hmacmd5)
578                 crypto_free_shash(server->ntlmssp.hmacmd5);
579 }
580
581 int
582 cifs_crypto_shash_allocate(struct TCP_Server_Info *server)
583 {
584         server->ntlmssp.hmacmd5 = crypto_alloc_shash("hmac(md5)", 0, 0);
585         if (!server->ntlmssp.hmacmd5 ||
586                         IS_ERR(server->ntlmssp.hmacmd5)) {
587                 cERROR(1, "could not allocate master crypto API hmacmd5\n");
588                 return 1;
589         }
590
591         server->ntlmssp.md5 = crypto_alloc_shash("md5", 0, 0);
592         if (!server->ntlmssp.md5 || IS_ERR(server->ntlmssp.md5)) {
593                 crypto_free_shash(server->ntlmssp.hmacmd5);
594                 cERROR(1, "could not allocate master crypto API md5\n");
595                 return 1;
596         }
597
598         return 0;
599 }