]> git.kernelconcepts.de Git - karo-tx-linux.git/blob - fs/cifs/cifsencrypt.c
pwm: imx: indentation cleanup
[karo-tx-linux.git] / fs / cifs / cifsencrypt.c
1 /*
2  *   fs/cifs/cifsencrypt.c
3  *
4  *   Copyright (C) International Business Machines  Corp., 2005,2013
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 "cifs_unicode.h"
28 #include "cifsproto.h"
29 #include "ntlmssp.h"
30 #include <linux/ctype.h>
31 #include <linux/random.h>
32 #include <linux/highmem.h>
33
34 static int
35 cifs_crypto_shash_md5_allocate(struct TCP_Server_Info *server)
36 {
37         int rc;
38         unsigned int size;
39
40         if (server->secmech.sdescmd5 != NULL)
41                 return 0; /* already allocated */
42
43         server->secmech.md5 = crypto_alloc_shash("md5", 0, 0);
44         if (IS_ERR(server->secmech.md5)) {
45                 cifs_dbg(VFS, "could not allocate crypto md5\n");
46                 rc = PTR_ERR(server->secmech.md5);
47                 server->secmech.md5 = NULL;
48                 return rc;
49         }
50
51         size = sizeof(struct shash_desc) +
52                         crypto_shash_descsize(server->secmech.md5);
53         server->secmech.sdescmd5 = kmalloc(size, GFP_KERNEL);
54         if (!server->secmech.sdescmd5) {
55                 crypto_free_shash(server->secmech.md5);
56                 server->secmech.md5 = NULL;
57                 return -ENOMEM;
58         }
59         server->secmech.sdescmd5->shash.tfm = server->secmech.md5;
60         server->secmech.sdescmd5->shash.flags = 0x0;
61
62         return 0;
63 }
64
65 /*
66  * Calculate and return the CIFS signature based on the mac key and SMB PDU.
67  * The 16 byte signature must be allocated by the caller. Note we only use the
68  * 1st eight bytes and that the smb header signature field on input contains
69  * the sequence number before this function is called. Also, this function
70  * should be called with the server->srv_mutex held.
71  */
72 static int cifs_calc_signature(struct smb_rqst *rqst,
73                         struct TCP_Server_Info *server, char *signature)
74 {
75         int i;
76         int rc;
77         struct kvec *iov = rqst->rq_iov;
78         int n_vec = rqst->rq_nvec;
79
80         if (iov == NULL || signature == NULL || server == NULL)
81                 return -EINVAL;
82
83         if (!server->secmech.sdescmd5) {
84                 rc = cifs_crypto_shash_md5_allocate(server);
85                 if (rc) {
86                         cifs_dbg(VFS, "%s: Can't alloc md5 crypto\n", __func__);
87                         return -1;
88                 }
89         }
90
91         rc = crypto_shash_init(&server->secmech.sdescmd5->shash);
92         if (rc) {
93                 cifs_dbg(VFS, "%s: Could not init md5\n", __func__);
94                 return rc;
95         }
96
97         rc = crypto_shash_update(&server->secmech.sdescmd5->shash,
98                 server->session_key.response, server->session_key.len);
99         if (rc) {
100                 cifs_dbg(VFS, "%s: Could not update with response\n", __func__);
101                 return rc;
102         }
103
104         for (i = 0; i < n_vec; i++) {
105                 if (iov[i].iov_len == 0)
106                         continue;
107                 if (iov[i].iov_base == NULL) {
108                         cifs_dbg(VFS, "null iovec entry\n");
109                         return -EIO;
110                 }
111                 /* The first entry includes a length field (which does not get
112                    signed that occupies the first 4 bytes before the header */
113                 if (i == 0) {
114                         if (iov[0].iov_len <= 8) /* cmd field at offset 9 */
115                                 break; /* nothing to sign or corrupt header */
116                         rc =
117                         crypto_shash_update(&server->secmech.sdescmd5->shash,
118                                 iov[i].iov_base + 4, iov[i].iov_len - 4);
119                 } else {
120                         rc =
121                         crypto_shash_update(&server->secmech.sdescmd5->shash,
122                                 iov[i].iov_base, iov[i].iov_len);
123                 }
124                 if (rc) {
125                         cifs_dbg(VFS, "%s: Could not update with payload\n",
126                                  __func__);
127                         return rc;
128                 }
129         }
130
131         /* now hash over the rq_pages array */
132         for (i = 0; i < rqst->rq_npages; i++) {
133                 struct kvec p_iov;
134
135                 cifs_rqst_page_to_kvec(rqst, i, &p_iov);
136                 crypto_shash_update(&server->secmech.sdescmd5->shash,
137                                         p_iov.iov_base, p_iov.iov_len);
138                 kunmap(rqst->rq_pages[i]);
139         }
140
141         rc = crypto_shash_final(&server->secmech.sdescmd5->shash, signature);
142         if (rc)
143                 cifs_dbg(VFS, "%s: Could not generate md5 hash\n", __func__);
144
145         return rc;
146 }
147
148 /* must be called with server->srv_mutex held */
149 int cifs_sign_rqst(struct smb_rqst *rqst, struct TCP_Server_Info *server,
150                    __u32 *pexpected_response_sequence_number)
151 {
152         int rc = 0;
153         char smb_signature[20];
154         struct smb_hdr *cifs_pdu = (struct smb_hdr *)rqst->rq_iov[0].iov_base;
155
156         if ((cifs_pdu == NULL) || (server == NULL))
157                 return -EINVAL;
158
159         if (!(cifs_pdu->Flags2 & SMBFLG2_SECURITY_SIGNATURE) ||
160             server->tcpStatus == CifsNeedNegotiate)
161                 return rc;
162
163         if (!server->session_estab) {
164                 memcpy(cifs_pdu->Signature.SecuritySignature, "BSRSPYL", 8);
165                 return rc;
166         }
167
168         cifs_pdu->Signature.Sequence.SequenceNumber =
169                                 cpu_to_le32(server->sequence_number);
170         cifs_pdu->Signature.Sequence.Reserved = 0;
171
172         *pexpected_response_sequence_number = ++server->sequence_number;
173         ++server->sequence_number;
174
175         rc = cifs_calc_signature(rqst, server, smb_signature);
176         if (rc)
177                 memset(cifs_pdu->Signature.SecuritySignature, 0, 8);
178         else
179                 memcpy(cifs_pdu->Signature.SecuritySignature, smb_signature, 8);
180
181         return rc;
182 }
183
184 int cifs_sign_smbv(struct kvec *iov, int n_vec, struct TCP_Server_Info *server,
185                    __u32 *pexpected_response_sequence)
186 {
187         struct smb_rqst rqst = { .rq_iov = iov,
188                                  .rq_nvec = n_vec };
189
190         return cifs_sign_rqst(&rqst, server, pexpected_response_sequence);
191 }
192
193 /* must be called with server->srv_mutex held */
194 int cifs_sign_smb(struct smb_hdr *cifs_pdu, struct TCP_Server_Info *server,
195                   __u32 *pexpected_response_sequence_number)
196 {
197         struct kvec iov;
198
199         iov.iov_base = cifs_pdu;
200         iov.iov_len = be32_to_cpu(cifs_pdu->smb_buf_length) + 4;
201
202         return cifs_sign_smbv(&iov, 1, server,
203                               pexpected_response_sequence_number);
204 }
205
206 int cifs_verify_signature(struct smb_rqst *rqst,
207                           struct TCP_Server_Info *server,
208                           __u32 expected_sequence_number)
209 {
210         unsigned int rc;
211         char server_response_sig[8];
212         char what_we_think_sig_should_be[20];
213         struct smb_hdr *cifs_pdu = (struct smb_hdr *)rqst->rq_iov[0].iov_base;
214
215         if (cifs_pdu == NULL || server == NULL)
216                 return -EINVAL;
217
218         if (!server->session_estab)
219                 return 0;
220
221         if (cifs_pdu->Command == SMB_COM_LOCKING_ANDX) {
222                 struct smb_com_lock_req *pSMB =
223                         (struct smb_com_lock_req *)cifs_pdu;
224             if (pSMB->LockType & LOCKING_ANDX_OPLOCK_RELEASE)
225                         return 0;
226         }
227
228         /* BB what if signatures are supposed to be on for session but
229            server does not send one? BB */
230
231         /* Do not need to verify session setups with signature "BSRSPYL "  */
232         if (memcmp(cifs_pdu->Signature.SecuritySignature, "BSRSPYL ", 8) == 0)
233                 cifs_dbg(FYI, "dummy signature received for smb command 0x%x\n",
234                          cifs_pdu->Command);
235
236         /* save off the origiginal signature so we can modify the smb and check
237                 its signature against what the server sent */
238         memcpy(server_response_sig, cifs_pdu->Signature.SecuritySignature, 8);
239
240         cifs_pdu->Signature.Sequence.SequenceNumber =
241                                         cpu_to_le32(expected_sequence_number);
242         cifs_pdu->Signature.Sequence.Reserved = 0;
243
244         mutex_lock(&server->srv_mutex);
245         rc = cifs_calc_signature(rqst, server, what_we_think_sig_should_be);
246         mutex_unlock(&server->srv_mutex);
247
248         if (rc)
249                 return rc;
250
251 /*      cifs_dump_mem("what we think it should be: ",
252                       what_we_think_sig_should_be, 16); */
253
254         if (memcmp(server_response_sig, what_we_think_sig_should_be, 8))
255                 return -EACCES;
256         else
257                 return 0;
258
259 }
260
261 /* first calculate 24 bytes ntlm response and then 16 byte session key */
262 int setup_ntlm_response(struct cifs_ses *ses, const struct nls_table *nls_cp)
263 {
264         int rc = 0;
265         unsigned int temp_len = CIFS_SESS_KEY_SIZE + CIFS_AUTH_RESP_SIZE;
266         char temp_key[CIFS_SESS_KEY_SIZE];
267
268         if (!ses)
269                 return -EINVAL;
270
271         ses->auth_key.response = kmalloc(temp_len, GFP_KERNEL);
272         if (!ses->auth_key.response)
273                 return -ENOMEM;
274
275         ses->auth_key.len = temp_len;
276
277         rc = SMBNTencrypt(ses->password, ses->server->cryptkey,
278                         ses->auth_key.response + CIFS_SESS_KEY_SIZE, nls_cp);
279         if (rc) {
280                 cifs_dbg(FYI, "%s Can't generate NTLM response, error: %d\n",
281                          __func__, rc);
282                 return rc;
283         }
284
285         rc = E_md4hash(ses->password, temp_key, nls_cp);
286         if (rc) {
287                 cifs_dbg(FYI, "%s Can't generate NT hash, error: %d\n",
288                          __func__, rc);
289                 return rc;
290         }
291
292         rc = mdfour(ses->auth_key.response, temp_key, CIFS_SESS_KEY_SIZE);
293         if (rc)
294                 cifs_dbg(FYI, "%s Can't generate NTLM session key, error: %d\n",
295                          __func__, rc);
296
297         return rc;
298 }
299
300 #ifdef CONFIG_CIFS_WEAK_PW_HASH
301 int calc_lanman_hash(const char *password, const char *cryptkey, bool encrypt,
302                         char *lnm_session_key)
303 {
304         int i;
305         int rc;
306         char password_with_pad[CIFS_ENCPWD_SIZE];
307
308         memset(password_with_pad, 0, CIFS_ENCPWD_SIZE);
309         if (password)
310                 strncpy(password_with_pad, password, CIFS_ENCPWD_SIZE);
311
312         if (!encrypt && global_secflags & CIFSSEC_MAY_PLNTXT) {
313                 memcpy(lnm_session_key, password_with_pad,
314                         CIFS_ENCPWD_SIZE);
315                 return 0;
316         }
317
318         /* calculate old style session key */
319         /* calling toupper is less broken than repeatedly
320         calling nls_toupper would be since that will never
321         work for UTF8, but neither handles multibyte code pages
322         but the only alternative would be converting to UCS-16 (Unicode)
323         (using a routine something like UniStrupr) then
324         uppercasing and then converting back from Unicode - which
325         would only worth doing it if we knew it were utf8. Basically
326         utf8 and other multibyte codepages each need their own strupper
327         function since a byte at a time will ont work. */
328
329         for (i = 0; i < CIFS_ENCPWD_SIZE; i++)
330                 password_with_pad[i] = toupper(password_with_pad[i]);
331
332         rc = SMBencrypt(password_with_pad, cryptkey, lnm_session_key);
333
334         return rc;
335 }
336 #endif /* CIFS_WEAK_PW_HASH */
337
338 /* Build a proper attribute value/target info pairs blob.
339  * Fill in netbios and dns domain name and workstation name
340  * and client time (total five av pairs and + one end of fields indicator.
341  * Allocate domain name which gets freed when session struct is deallocated.
342  */
343 static int
344 build_avpair_blob(struct cifs_ses *ses, const struct nls_table *nls_cp)
345 {
346         unsigned int dlen;
347         unsigned int size = 2 * sizeof(struct ntlmssp2_name);
348         char *defdmname = "WORKGROUP";
349         unsigned char *blobptr;
350         struct ntlmssp2_name *attrptr;
351
352         if (!ses->domainName) {
353                 ses->domainName = kstrdup(defdmname, GFP_KERNEL);
354                 if (!ses->domainName)
355                         return -ENOMEM;
356         }
357
358         dlen = strlen(ses->domainName);
359
360         /*
361          * The length of this blob is two times the size of a
362          * structure (av pair) which holds name/size
363          * ( for NTLMSSP_AV_NB_DOMAIN_NAME followed by NTLMSSP_AV_EOL ) +
364          * unicode length of a netbios domain name
365          */
366         ses->auth_key.len = size + 2 * dlen;
367         ses->auth_key.response = kzalloc(ses->auth_key.len, GFP_KERNEL);
368         if (!ses->auth_key.response) {
369                 ses->auth_key.len = 0;
370                 return -ENOMEM;
371         }
372
373         blobptr = ses->auth_key.response;
374         attrptr = (struct ntlmssp2_name *) blobptr;
375
376         /*
377          * As defined in MS-NTLM 3.3.2, just this av pair field
378          * is sufficient as part of the temp
379          */
380         attrptr->type = cpu_to_le16(NTLMSSP_AV_NB_DOMAIN_NAME);
381         attrptr->length = cpu_to_le16(2 * dlen);
382         blobptr = (unsigned char *)attrptr + sizeof(struct ntlmssp2_name);
383         cifs_strtoUTF16((__le16 *)blobptr, ses->domainName, dlen, nls_cp);
384
385         return 0;
386 }
387
388 /* Server has provided av pairs/target info in the type 2 challenge
389  * packet and we have plucked it and stored within smb session.
390  * We parse that blob here to find netbios domain name to be used
391  * as part of ntlmv2 authentication (in Target String), if not already
392  * specified on the command line.
393  * If this function returns without any error but without fetching
394  * domain name, authentication may fail against some server but
395  * may not fail against other (those who are not very particular
396  * about target string i.e. for some, just user name might suffice.
397  */
398 static int
399 find_domain_name(struct cifs_ses *ses, const struct nls_table *nls_cp)
400 {
401         unsigned int attrsize;
402         unsigned int type;
403         unsigned int onesize = sizeof(struct ntlmssp2_name);
404         unsigned char *blobptr;
405         unsigned char *blobend;
406         struct ntlmssp2_name *attrptr;
407
408         if (!ses->auth_key.len || !ses->auth_key.response)
409                 return 0;
410
411         blobptr = ses->auth_key.response;
412         blobend = blobptr + ses->auth_key.len;
413
414         while (blobptr + onesize < blobend) {
415                 attrptr = (struct ntlmssp2_name *) blobptr;
416                 type = le16_to_cpu(attrptr->type);
417                 if (type == NTLMSSP_AV_EOL)
418                         break;
419                 blobptr += 2; /* advance attr type */
420                 attrsize = le16_to_cpu(attrptr->length);
421                 blobptr += 2; /* advance attr size */
422                 if (blobptr + attrsize > blobend)
423                         break;
424                 if (type == NTLMSSP_AV_NB_DOMAIN_NAME) {
425                         if (!attrsize || attrsize >= CIFS_MAX_DOMAINNAME_LEN)
426                                 break;
427                         if (!ses->domainName) {
428                                 ses->domainName =
429                                         kmalloc(attrsize + 1, GFP_KERNEL);
430                                 if (!ses->domainName)
431                                                 return -ENOMEM;
432                                 cifs_from_utf16(ses->domainName,
433                                         (__le16 *)blobptr, attrsize, attrsize,
434                                         nls_cp, false);
435                                 break;
436                         }
437                 }
438                 blobptr += attrsize; /* advance attr  value */
439         }
440
441         return 0;
442 }
443
444 static int calc_ntlmv2_hash(struct cifs_ses *ses, char *ntlmv2_hash,
445                             const struct nls_table *nls_cp)
446 {
447         int rc = 0;
448         int len;
449         char nt_hash[CIFS_NTHASH_SIZE];
450         __le16 *user;
451         wchar_t *domain;
452         wchar_t *server;
453
454         if (!ses->server->secmech.sdeschmacmd5) {
455                 cifs_dbg(VFS, "%s: can't generate ntlmv2 hash\n", __func__);
456                 return -1;
457         }
458
459         /* calculate md4 hash of password */
460         E_md4hash(ses->password, nt_hash, nls_cp);
461
462         rc = crypto_shash_setkey(ses->server->secmech.hmacmd5, nt_hash,
463                                 CIFS_NTHASH_SIZE);
464         if (rc) {
465                 cifs_dbg(VFS, "%s: Could not set NT Hash as a key\n", __func__);
466                 return rc;
467         }
468
469         rc = crypto_shash_init(&ses->server->secmech.sdeschmacmd5->shash);
470         if (rc) {
471                 cifs_dbg(VFS, "%s: could not init hmacmd5\n", __func__);
472                 return rc;
473         }
474
475         /* convert ses->user_name to unicode */
476         len = ses->user_name ? strlen(ses->user_name) : 0;
477         user = kmalloc(2 + (len * 2), GFP_KERNEL);
478         if (user == NULL) {
479                 rc = -ENOMEM;
480                 return rc;
481         }
482
483         if (len) {
484                 len = cifs_strtoUTF16(user, ses->user_name, len, nls_cp);
485                 UniStrupr(user);
486         } else {
487                 memset(user, '\0', 2);
488         }
489
490         rc = crypto_shash_update(&ses->server->secmech.sdeschmacmd5->shash,
491                                 (char *)user, 2 * len);
492         kfree(user);
493         if (rc) {
494                 cifs_dbg(VFS, "%s: Could not update with user\n", __func__);
495                 return rc;
496         }
497
498         /* convert ses->domainName to unicode and uppercase */
499         if (ses->domainName) {
500                 len = strlen(ses->domainName);
501
502                 domain = kmalloc(2 + (len * 2), GFP_KERNEL);
503                 if (domain == NULL) {
504                         rc = -ENOMEM;
505                         return rc;
506                 }
507                 len = cifs_strtoUTF16((__le16 *)domain, ses->domainName, len,
508                                       nls_cp);
509                 rc =
510                 crypto_shash_update(&ses->server->secmech.sdeschmacmd5->shash,
511                                         (char *)domain, 2 * len);
512                 kfree(domain);
513                 if (rc) {
514                         cifs_dbg(VFS, "%s: Could not update with domain\n",
515                                  __func__);
516                         return rc;
517                 }
518         } else if (ses->serverName) {
519                 len = strlen(ses->serverName);
520
521                 server = kmalloc(2 + (len * 2), GFP_KERNEL);
522                 if (server == NULL) {
523                         rc = -ENOMEM;
524                         return rc;
525                 }
526                 len = cifs_strtoUTF16((__le16 *)server, ses->serverName, len,
527                                         nls_cp);
528                 rc =
529                 crypto_shash_update(&ses->server->secmech.sdeschmacmd5->shash,
530                                         (char *)server, 2 * len);
531                 kfree(server);
532                 if (rc) {
533                         cifs_dbg(VFS, "%s: Could not update with server\n",
534                                  __func__);
535                         return rc;
536                 }
537         }
538
539         rc = crypto_shash_final(&ses->server->secmech.sdeschmacmd5->shash,
540                                         ntlmv2_hash);
541         if (rc)
542                 cifs_dbg(VFS, "%s: Could not generate md5 hash\n", __func__);
543
544         return rc;
545 }
546
547 static int
548 CalcNTLMv2_response(const struct cifs_ses *ses, char *ntlmv2_hash)
549 {
550         int rc;
551         unsigned int offset = CIFS_SESS_KEY_SIZE + 8;
552
553         if (!ses->server->secmech.sdeschmacmd5) {
554                 cifs_dbg(VFS, "%s: can't generate ntlmv2 hash\n", __func__);
555                 return -1;
556         }
557
558         rc = crypto_shash_setkey(ses->server->secmech.hmacmd5,
559                                 ntlmv2_hash, CIFS_HMAC_MD5_HASH_SIZE);
560         if (rc) {
561                 cifs_dbg(VFS, "%s: Could not set NTLMV2 Hash as a key\n",
562                          __func__);
563                 return rc;
564         }
565
566         rc = crypto_shash_init(&ses->server->secmech.sdeschmacmd5->shash);
567         if (rc) {
568                 cifs_dbg(VFS, "%s: could not init hmacmd5\n", __func__);
569                 return rc;
570         }
571
572         if (ses->server->negflavor == CIFS_NEGFLAVOR_EXTENDED)
573                 memcpy(ses->auth_key.response + offset,
574                         ses->ntlmssp->cryptkey, CIFS_SERVER_CHALLENGE_SIZE);
575         else
576                 memcpy(ses->auth_key.response + offset,
577                         ses->server->cryptkey, CIFS_SERVER_CHALLENGE_SIZE);
578         rc = crypto_shash_update(&ses->server->secmech.sdeschmacmd5->shash,
579                 ses->auth_key.response + offset, ses->auth_key.len - offset);
580         if (rc) {
581                 cifs_dbg(VFS, "%s: Could not update with response\n", __func__);
582                 return rc;
583         }
584
585         rc = crypto_shash_final(&ses->server->secmech.sdeschmacmd5->shash,
586                 ses->auth_key.response + CIFS_SESS_KEY_SIZE);
587         if (rc)
588                 cifs_dbg(VFS, "%s: Could not generate md5 hash\n", __func__);
589
590         return rc;
591 }
592
593 static int crypto_hmacmd5_alloc(struct TCP_Server_Info *server)
594 {
595         int rc;
596         unsigned int size;
597
598         /* check if already allocated */
599         if (server->secmech.sdeschmacmd5)
600                 return 0;
601
602         server->secmech.hmacmd5 = crypto_alloc_shash("hmac(md5)", 0, 0);
603         if (IS_ERR(server->secmech.hmacmd5)) {
604                 cifs_dbg(VFS, "could not allocate crypto hmacmd5\n");
605                 rc = PTR_ERR(server->secmech.hmacmd5);
606                 server->secmech.hmacmd5 = NULL;
607                 return rc;
608         }
609
610         size = sizeof(struct shash_desc) +
611                         crypto_shash_descsize(server->secmech.hmacmd5);
612         server->secmech.sdeschmacmd5 = kmalloc(size, GFP_KERNEL);
613         if (!server->secmech.sdeschmacmd5) {
614                 crypto_free_shash(server->secmech.hmacmd5);
615                 server->secmech.hmacmd5 = NULL;
616                 return -ENOMEM;
617         }
618         server->secmech.sdeschmacmd5->shash.tfm = server->secmech.hmacmd5;
619         server->secmech.sdeschmacmd5->shash.flags = 0x0;
620
621         return 0;
622 }
623
624 int
625 setup_ntlmv2_rsp(struct cifs_ses *ses, const struct nls_table *nls_cp)
626 {
627         int rc;
628         int baselen;
629         unsigned int tilen;
630         struct ntlmv2_resp *buf;
631         char ntlmv2_hash[16];
632         unsigned char *tiblob = NULL; /* target info blob */
633
634         if (ses->server->negflavor == CIFS_NEGFLAVOR_EXTENDED) {
635                 if (!ses->domainName) {
636                         rc = find_domain_name(ses, nls_cp);
637                         if (rc) {
638                                 cifs_dbg(VFS, "error %d finding domain name\n",
639                                          rc);
640                                 goto setup_ntlmv2_rsp_ret;
641                         }
642                 }
643         } else {
644                 rc = build_avpair_blob(ses, nls_cp);
645                 if (rc) {
646                         cifs_dbg(VFS, "error %d building av pair blob\n", rc);
647                         goto setup_ntlmv2_rsp_ret;
648                 }
649         }
650
651         baselen = CIFS_SESS_KEY_SIZE + sizeof(struct ntlmv2_resp);
652         tilen = ses->auth_key.len;
653         tiblob = ses->auth_key.response;
654
655         ses->auth_key.response = kmalloc(baselen + tilen, GFP_KERNEL);
656         if (!ses->auth_key.response) {
657                 rc = ENOMEM;
658                 ses->auth_key.len = 0;
659                 goto setup_ntlmv2_rsp_ret;
660         }
661         ses->auth_key.len += baselen;
662
663         buf = (struct ntlmv2_resp *)
664                         (ses->auth_key.response + CIFS_SESS_KEY_SIZE);
665         buf->blob_signature = cpu_to_le32(0x00000101);
666         buf->reserved = 0;
667         buf->time = cpu_to_le64(cifs_UnixTimeToNT(CURRENT_TIME));
668         get_random_bytes(&buf->client_chal, sizeof(buf->client_chal));
669         buf->reserved2 = 0;
670
671         memcpy(ses->auth_key.response + baselen, tiblob, tilen);
672
673         rc = crypto_hmacmd5_alloc(ses->server);
674         if (rc) {
675                 cifs_dbg(VFS, "could not crypto alloc hmacmd5 rc %d\n", rc);
676                 goto setup_ntlmv2_rsp_ret;
677         }
678
679         /* calculate ntlmv2_hash */
680         rc = calc_ntlmv2_hash(ses, ntlmv2_hash, nls_cp);
681         if (rc) {
682                 cifs_dbg(VFS, "could not get v2 hash rc %d\n", rc);
683                 goto setup_ntlmv2_rsp_ret;
684         }
685
686         /* calculate first part of the client response (CR1) */
687         rc = CalcNTLMv2_response(ses, ntlmv2_hash);
688         if (rc) {
689                 cifs_dbg(VFS, "Could not calculate CR1 rc: %d\n", rc);
690                 goto setup_ntlmv2_rsp_ret;
691         }
692
693         /* now calculate the session key for NTLMv2 */
694         rc = crypto_shash_setkey(ses->server->secmech.hmacmd5,
695                 ntlmv2_hash, CIFS_HMAC_MD5_HASH_SIZE);
696         if (rc) {
697                 cifs_dbg(VFS, "%s: Could not set NTLMV2 Hash as a key\n",
698                          __func__);
699                 goto setup_ntlmv2_rsp_ret;
700         }
701
702         rc = crypto_shash_init(&ses->server->secmech.sdeschmacmd5->shash);
703         if (rc) {
704                 cifs_dbg(VFS, "%s: Could not init hmacmd5\n", __func__);
705                 goto setup_ntlmv2_rsp_ret;
706         }
707
708         rc = crypto_shash_update(&ses->server->secmech.sdeschmacmd5->shash,
709                 ses->auth_key.response + CIFS_SESS_KEY_SIZE,
710                 CIFS_HMAC_MD5_HASH_SIZE);
711         if (rc) {
712                 cifs_dbg(VFS, "%s: Could not update with response\n", __func__);
713                 goto setup_ntlmv2_rsp_ret;
714         }
715
716         rc = crypto_shash_final(&ses->server->secmech.sdeschmacmd5->shash,
717                 ses->auth_key.response);
718         if (rc)
719                 cifs_dbg(VFS, "%s: Could not generate md5 hash\n", __func__);
720
721 setup_ntlmv2_rsp_ret:
722         kfree(tiblob);
723
724         return rc;
725 }
726
727 int
728 calc_seckey(struct cifs_ses *ses)
729 {
730         int rc;
731         struct crypto_blkcipher *tfm_arc4;
732         struct scatterlist sgin, sgout;
733         struct blkcipher_desc desc;
734         unsigned char sec_key[CIFS_SESS_KEY_SIZE]; /* a nonce */
735
736         get_random_bytes(sec_key, CIFS_SESS_KEY_SIZE);
737
738         tfm_arc4 = crypto_alloc_blkcipher("ecb(arc4)", 0, CRYPTO_ALG_ASYNC);
739         if (IS_ERR(tfm_arc4)) {
740                 rc = PTR_ERR(tfm_arc4);
741                 cifs_dbg(VFS, "could not allocate crypto API arc4\n");
742                 return rc;
743         }
744
745         desc.tfm = tfm_arc4;
746
747         rc = crypto_blkcipher_setkey(tfm_arc4, ses->auth_key.response,
748                                         CIFS_SESS_KEY_SIZE);
749         if (rc) {
750                 cifs_dbg(VFS, "%s: Could not set response as a key\n",
751                          __func__);
752                 return rc;
753         }
754
755         sg_init_one(&sgin, sec_key, CIFS_SESS_KEY_SIZE);
756         sg_init_one(&sgout, ses->ntlmssp->ciphertext, CIFS_CPHTXT_SIZE);
757
758         rc = crypto_blkcipher_encrypt(&desc, &sgout, &sgin, CIFS_CPHTXT_SIZE);
759         if (rc) {
760                 cifs_dbg(VFS, "could not encrypt session key rc: %d\n", rc);
761                 crypto_free_blkcipher(tfm_arc4);
762                 return rc;
763         }
764
765         /* make secondary_key/nonce as session key */
766         memcpy(ses->auth_key.response, sec_key, CIFS_SESS_KEY_SIZE);
767         /* and make len as that of session key only */
768         ses->auth_key.len = CIFS_SESS_KEY_SIZE;
769
770         crypto_free_blkcipher(tfm_arc4);
771
772         return rc;
773 }
774
775 void
776 cifs_crypto_shash_release(struct TCP_Server_Info *server)
777 {
778         if (server->secmech.cmacaes) {
779                 crypto_free_shash(server->secmech.cmacaes);
780                 server->secmech.cmacaes = NULL;
781         }
782
783         if (server->secmech.hmacsha256) {
784                 crypto_free_shash(server->secmech.hmacsha256);
785                 server->secmech.hmacsha256 = NULL;
786         }
787
788         if (server->secmech.md5) {
789                 crypto_free_shash(server->secmech.md5);
790                 server->secmech.md5 = NULL;
791         }
792
793         if (server->secmech.hmacmd5) {
794                 crypto_free_shash(server->secmech.hmacmd5);
795                 server->secmech.hmacmd5 = NULL;
796         }
797
798         kfree(server->secmech.sdesccmacaes);
799         server->secmech.sdesccmacaes = NULL;
800         kfree(server->secmech.sdeschmacsha256);
801         server->secmech.sdeschmacsha256 = NULL;
802         kfree(server->secmech.sdeschmacmd5);
803         server->secmech.sdeschmacmd5 = NULL;
804         kfree(server->secmech.sdescmd5);
805         server->secmech.sdescmd5 = NULL;
806 }