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