1 /*
2  *   fs/cifs/smb2transport.c
3  *
4  *   Copyright (C) International Business Machines  Corp., 2002, 2011
5  *                 Etersoft, 2012
6  *   Author(s): Steve French (sfrench@us.ibm.com)
7  *              Jeremy Allison (jra@samba.org) 2006
8  *              Pavel Shilovsky (pshilovsky@samba.org) 2012
9  *
10  *   This library is free software; you can redistribute it and/or modify
11  *   it under the terms of the GNU Lesser General Public License as published
12  *   by the Free Software Foundation; either version 2.1 of the License, or
13  *   (at your option) any later version.
14  *
15  *   This library 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
18  *   the GNU Lesser General Public License for more details.
19  *
20  *   You should have received a copy of the GNU Lesser General Public License
21  *   along with this library; if not, write to the Free Software
22  *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
23  */
24 
25 #include <linux/fs.h>
26 #include <linux/list.h>
27 #include <linux/wait.h>
28 #include <linux/net.h>
29 #include <linux/delay.h>
30 #include <linux/uaccess.h>
31 #include <asm/processor.h>
32 #include <linux/mempool.h>
33 #include <linux/highmem.h>
34 #include <crypto/aead.h>
35 #include "smb2pdu.h"
36 #include "cifsglob.h"
37 #include "cifsproto.h"
38 #include "smb2proto.h"
39 #include "cifs_debug.h"
40 #include "smb2status.h"
41 #include "smb2glob.h"
42 
43 static int
smb2_crypto_shash_allocate(struct TCP_Server_Info * server)44 smb2_crypto_shash_allocate(struct TCP_Server_Info *server)
45 {
46 	return cifs_alloc_hash("hmac(sha256)",
47 			       &server->secmech.hmacsha256,
48 			       &server->secmech.sdeschmacsha256);
49 }
50 
51 static int
smb3_crypto_shash_allocate(struct TCP_Server_Info * server)52 smb3_crypto_shash_allocate(struct TCP_Server_Info *server)
53 {
54 	struct cifs_secmech *p = &server->secmech;
55 	int rc;
56 
57 	rc = cifs_alloc_hash("hmac(sha256)",
58 			     &p->hmacsha256,
59 			     &p->sdeschmacsha256);
60 	if (rc)
61 		goto err;
62 
63 	rc = cifs_alloc_hash("cmac(aes)", &p->cmacaes, &p->sdesccmacaes);
64 	if (rc)
65 		goto err;
66 
67 	return 0;
68 err:
69 	cifs_free_hash(&p->hmacsha256, &p->sdeschmacsha256);
70 	return rc;
71 }
72 
73 int
smb311_crypto_shash_allocate(struct TCP_Server_Info * server)74 smb311_crypto_shash_allocate(struct TCP_Server_Info *server)
75 {
76 	struct cifs_secmech *p = &server->secmech;
77 	int rc = 0;
78 
79 	rc = cifs_alloc_hash("hmac(sha256)",
80 			     &p->hmacsha256,
81 			     &p->sdeschmacsha256);
82 	if (rc)
83 		return rc;
84 
85 	rc = cifs_alloc_hash("cmac(aes)", &p->cmacaes, &p->sdesccmacaes);
86 	if (rc)
87 		goto err;
88 
89 	rc = cifs_alloc_hash("sha512", &p->sha512, &p->sdescsha512);
90 	if (rc)
91 		goto err;
92 
93 	return 0;
94 
95 err:
96 	cifs_free_hash(&p->cmacaes, &p->sdesccmacaes);
97 	cifs_free_hash(&p->hmacsha256, &p->sdeschmacsha256);
98 	return rc;
99 }
100 
101 static struct cifs_ses *
smb2_find_smb_ses_unlocked(struct TCP_Server_Info * server,__u64 ses_id)102 smb2_find_smb_ses_unlocked(struct TCP_Server_Info *server, __u64 ses_id)
103 {
104 	struct cifs_ses *ses;
105 
106 	list_for_each_entry(ses, &server->smb_ses_list, smb_ses_list) {
107 		if (ses->Suid != ses_id)
108 			continue;
109 		return ses;
110 	}
111 
112 	return NULL;
113 }
114 
115 struct cifs_ses *
smb2_find_smb_ses(struct TCP_Server_Info * server,__u64 ses_id)116 smb2_find_smb_ses(struct TCP_Server_Info *server, __u64 ses_id)
117 {
118 	struct cifs_ses *ses;
119 
120 	spin_lock(&cifs_tcp_ses_lock);
121 	ses = smb2_find_smb_ses_unlocked(server, ses_id);
122 	spin_unlock(&cifs_tcp_ses_lock);
123 
124 	return ses;
125 }
126 
127 static struct cifs_tcon *
smb2_find_smb_sess_tcon_unlocked(struct cifs_ses * ses,__u32 tid)128 smb2_find_smb_sess_tcon_unlocked(struct cifs_ses *ses, __u32  tid)
129 {
130 	struct cifs_tcon *tcon;
131 
132 	list_for_each_entry(tcon, &ses->tcon_list, tcon_list) {
133 		if (tcon->tid != tid)
134 			continue;
135 		++tcon->tc_count;
136 		return tcon;
137 	}
138 
139 	return NULL;
140 }
141 
142 /*
143  * Obtain tcon corresponding to the tid in the given
144  * cifs_ses
145  */
146 
147 struct cifs_tcon *
smb2_find_smb_tcon(struct TCP_Server_Info * server,__u64 ses_id,__u32 tid)148 smb2_find_smb_tcon(struct TCP_Server_Info *server, __u64 ses_id, __u32  tid)
149 {
150 	struct cifs_ses *ses;
151 	struct cifs_tcon *tcon;
152 
153 	spin_lock(&cifs_tcp_ses_lock);
154 	ses = smb2_find_smb_ses_unlocked(server, ses_id);
155 	if (!ses) {
156 		spin_unlock(&cifs_tcp_ses_lock);
157 		return NULL;
158 	}
159 	tcon = smb2_find_smb_sess_tcon_unlocked(ses, tid);
160 	spin_unlock(&cifs_tcp_ses_lock);
161 
162 	return tcon;
163 }
164 
165 int
smb2_calc_signature(struct smb_rqst * rqst,struct TCP_Server_Info * server)166 smb2_calc_signature(struct smb_rqst *rqst, struct TCP_Server_Info *server)
167 {
168 	int rc;
169 	unsigned char smb2_signature[SMB2_HMACSHA256_SIZE];
170 	unsigned char *sigptr = smb2_signature;
171 	struct kvec *iov = rqst->rq_iov;
172 	struct smb2_sync_hdr *shdr = (struct smb2_sync_hdr *)iov[0].iov_base;
173 	struct cifs_ses *ses;
174 	struct shash_desc *shash;
175 	struct smb_rqst drqst;
176 
177 	ses = smb2_find_smb_ses(server, shdr->SessionId);
178 	if (!ses) {
179 		cifs_dbg(VFS, "%s: Could not find session\n", __func__);
180 		return 0;
181 	}
182 
183 	memset(smb2_signature, 0x0, SMB2_HMACSHA256_SIZE);
184 	memset(shdr->Signature, 0x0, SMB2_SIGNATURE_SIZE);
185 
186 	rc = smb2_crypto_shash_allocate(server);
187 	if (rc) {
188 		cifs_dbg(VFS, "%s: sha256 alloc failed\n", __func__);
189 		return rc;
190 	}
191 
192 	rc = crypto_shash_setkey(server->secmech.hmacsha256,
193 				 ses->auth_key.response, SMB2_NTLMV2_SESSKEY_SIZE);
194 	if (rc) {
195 		cifs_dbg(VFS, "%s: Could not update with response\n", __func__);
196 		return rc;
197 	}
198 
199 	shash = &server->secmech.sdeschmacsha256->shash;
200 	rc = crypto_shash_init(shash);
201 	if (rc) {
202 		cifs_dbg(VFS, "%s: Could not init sha256", __func__);
203 		return rc;
204 	}
205 
206 	/*
207 	 * For SMB2+, __cifs_calc_signature() expects to sign only the actual
208 	 * data, that is, iov[0] should not contain a rfc1002 length.
209 	 *
210 	 * Sign the rfc1002 length prior to passing the data (iov[1-N]) down to
211 	 * __cifs_calc_signature().
212 	 */
213 	drqst = *rqst;
214 	if (drqst.rq_nvec >= 2 && iov[0].iov_len == 4) {
215 		rc = crypto_shash_update(shash, iov[0].iov_base,
216 					 iov[0].iov_len);
217 		if (rc) {
218 			cifs_dbg(VFS, "%s: Could not update with payload\n",
219 				 __func__);
220 			return rc;
221 		}
222 		drqst.rq_iov++;
223 		drqst.rq_nvec--;
224 	}
225 
226 	rc = __cifs_calc_signature(&drqst, server, sigptr, shash);
227 	if (!rc)
228 		memcpy(shdr->Signature, sigptr, SMB2_SIGNATURE_SIZE);
229 
230 	return rc;
231 }
232 
generate_key(struct cifs_ses * ses,struct kvec label,struct kvec context,__u8 * key,unsigned int key_size)233 static int generate_key(struct cifs_ses *ses, struct kvec label,
234 			struct kvec context, __u8 *key, unsigned int key_size)
235 {
236 	unsigned char zero = 0x0;
237 	__u8 i[4] = {0, 0, 0, 1};
238 	__u8 L[4] = {0, 0, 0, 128};
239 	int rc = 0;
240 	unsigned char prfhash[SMB2_HMACSHA256_SIZE];
241 	unsigned char *hashptr = prfhash;
242 
243 	memset(prfhash, 0x0, SMB2_HMACSHA256_SIZE);
244 	memset(key, 0x0, key_size);
245 
246 	rc = smb3_crypto_shash_allocate(ses->server);
247 	if (rc) {
248 		cifs_dbg(VFS, "%s: crypto alloc failed\n", __func__);
249 		goto smb3signkey_ret;
250 	}
251 
252 	rc = crypto_shash_setkey(ses->server->secmech.hmacsha256,
253 		ses->auth_key.response, SMB2_NTLMV2_SESSKEY_SIZE);
254 	if (rc) {
255 		cifs_dbg(VFS, "%s: Could not set with session key\n", __func__);
256 		goto smb3signkey_ret;
257 	}
258 
259 	rc = crypto_shash_init(&ses->server->secmech.sdeschmacsha256->shash);
260 	if (rc) {
261 		cifs_dbg(VFS, "%s: Could not init sign hmac\n", __func__);
262 		goto smb3signkey_ret;
263 	}
264 
265 	rc = crypto_shash_update(&ses->server->secmech.sdeschmacsha256->shash,
266 				i, 4);
267 	if (rc) {
268 		cifs_dbg(VFS, "%s: Could not update with n\n", __func__);
269 		goto smb3signkey_ret;
270 	}
271 
272 	rc = crypto_shash_update(&ses->server->secmech.sdeschmacsha256->shash,
273 				label.iov_base, label.iov_len);
274 	if (rc) {
275 		cifs_dbg(VFS, "%s: Could not update with label\n", __func__);
276 		goto smb3signkey_ret;
277 	}
278 
279 	rc = crypto_shash_update(&ses->server->secmech.sdeschmacsha256->shash,
280 				&zero, 1);
281 	if (rc) {
282 		cifs_dbg(VFS, "%s: Could not update with zero\n", __func__);
283 		goto smb3signkey_ret;
284 	}
285 
286 	rc = crypto_shash_update(&ses->server->secmech.sdeschmacsha256->shash,
287 				context.iov_base, context.iov_len);
288 	if (rc) {
289 		cifs_dbg(VFS, "%s: Could not update with context\n", __func__);
290 		goto smb3signkey_ret;
291 	}
292 
293 	rc = crypto_shash_update(&ses->server->secmech.sdeschmacsha256->shash,
294 				L, 4);
295 	if (rc) {
296 		cifs_dbg(VFS, "%s: Could not update with L\n", __func__);
297 		goto smb3signkey_ret;
298 	}
299 
300 	rc = crypto_shash_final(&ses->server->secmech.sdeschmacsha256->shash,
301 				hashptr);
302 	if (rc) {
303 		cifs_dbg(VFS, "%s: Could not generate sha256 hash\n", __func__);
304 		goto smb3signkey_ret;
305 	}
306 
307 	memcpy(key, hashptr, key_size);
308 
309 smb3signkey_ret:
310 	return rc;
311 }
312 
313 struct derivation {
314 	struct kvec label;
315 	struct kvec context;
316 };
317 
318 struct derivation_triplet {
319 	struct derivation signing;
320 	struct derivation encryption;
321 	struct derivation decryption;
322 };
323 
324 static int
generate_smb3signingkey(struct cifs_ses * ses,const struct derivation_triplet * ptriplet)325 generate_smb3signingkey(struct cifs_ses *ses,
326 			const struct derivation_triplet *ptriplet)
327 {
328 	int rc;
329 
330 	rc = generate_key(ses, ptriplet->signing.label,
331 			  ptriplet->signing.context, ses->smb3signingkey,
332 			  SMB3_SIGN_KEY_SIZE);
333 	if (rc)
334 		return rc;
335 
336 	rc = generate_key(ses, ptriplet->encryption.label,
337 			  ptriplet->encryption.context, ses->smb3encryptionkey,
338 			  SMB3_SIGN_KEY_SIZE);
339 	if (rc)
340 		return rc;
341 
342 	rc = generate_key(ses, ptriplet->decryption.label,
343 			  ptriplet->decryption.context,
344 			  ses->smb3decryptionkey, SMB3_SIGN_KEY_SIZE);
345 
346 	if (rc)
347 		return rc;
348 
349 #ifdef CONFIG_CIFS_DEBUG_DUMP_KEYS
350 	cifs_dbg(VFS, "%s: dumping generated AES session keys\n", __func__);
351 	/*
352 	 * The session id is opaque in terms of endianness, so we can't
353 	 * print it as a long long. we dump it as we got it on the wire
354 	 */
355 	cifs_dbg(VFS, "Session Id    %*ph\n", (int)sizeof(ses->Suid),
356 			&ses->Suid);
357 	cifs_dbg(VFS, "Session Key   %*ph\n",
358 		 SMB2_NTLMV2_SESSKEY_SIZE, ses->auth_key.response);
359 	cifs_dbg(VFS, "Signing Key   %*ph\n",
360 		 SMB3_SIGN_KEY_SIZE, ses->smb3signingkey);
361 	cifs_dbg(VFS, "ServerIn Key  %*ph\n",
362 		 SMB3_SIGN_KEY_SIZE, ses->smb3encryptionkey);
363 	cifs_dbg(VFS, "ServerOut Key %*ph\n",
364 		 SMB3_SIGN_KEY_SIZE, ses->smb3decryptionkey);
365 #endif
366 	return rc;
367 }
368 
369 int
generate_smb30signingkey(struct cifs_ses * ses)370 generate_smb30signingkey(struct cifs_ses *ses)
371 
372 {
373 	struct derivation_triplet triplet;
374 	struct derivation *d;
375 
376 	d = &triplet.signing;
377 	d->label.iov_base = "SMB2AESCMAC";
378 	d->label.iov_len = 12;
379 	d->context.iov_base = "SmbSign";
380 	d->context.iov_len = 8;
381 
382 	d = &triplet.encryption;
383 	d->label.iov_base = "SMB2AESCCM";
384 	d->label.iov_len = 11;
385 	d->context.iov_base = "ServerIn ";
386 	d->context.iov_len = 10;
387 
388 	d = &triplet.decryption;
389 	d->label.iov_base = "SMB2AESCCM";
390 	d->label.iov_len = 11;
391 	d->context.iov_base = "ServerOut";
392 	d->context.iov_len = 10;
393 
394 	return generate_smb3signingkey(ses, &triplet);
395 }
396 
397 int
generate_smb311signingkey(struct cifs_ses * ses)398 generate_smb311signingkey(struct cifs_ses *ses)
399 
400 {
401 	struct derivation_triplet triplet;
402 	struct derivation *d;
403 
404 	d = &triplet.signing;
405 	d->label.iov_base = "SMBSigningKey";
406 	d->label.iov_len = 14;
407 	d->context.iov_base = ses->preauth_sha_hash;
408 	d->context.iov_len = 64;
409 
410 	d = &triplet.encryption;
411 	d->label.iov_base = "SMBC2SCipherKey";
412 	d->label.iov_len = 16;
413 	d->context.iov_base = ses->preauth_sha_hash;
414 	d->context.iov_len = 64;
415 
416 	d = &triplet.decryption;
417 	d->label.iov_base = "SMBS2CCipherKey";
418 	d->label.iov_len = 16;
419 	d->context.iov_base = ses->preauth_sha_hash;
420 	d->context.iov_len = 64;
421 
422 	return generate_smb3signingkey(ses, &triplet);
423 }
424 
425 int
smb3_calc_signature(struct smb_rqst * rqst,struct TCP_Server_Info * server)426 smb3_calc_signature(struct smb_rqst *rqst, struct TCP_Server_Info *server)
427 {
428 	int rc;
429 	unsigned char smb3_signature[SMB2_CMACAES_SIZE];
430 	unsigned char *sigptr = smb3_signature;
431 	struct kvec *iov = rqst->rq_iov;
432 	struct smb2_sync_hdr *shdr = (struct smb2_sync_hdr *)iov[0].iov_base;
433 	struct cifs_ses *ses;
434 	struct shash_desc *shash = &server->secmech.sdesccmacaes->shash;
435 	struct smb_rqst drqst;
436 
437 	ses = smb2_find_smb_ses(server, shdr->SessionId);
438 	if (!ses) {
439 		cifs_dbg(VFS, "%s: Could not find session\n", __func__);
440 		return 0;
441 	}
442 
443 	memset(smb3_signature, 0x0, SMB2_CMACAES_SIZE);
444 	memset(shdr->Signature, 0x0, SMB2_SIGNATURE_SIZE);
445 
446 	rc = crypto_shash_setkey(server->secmech.cmacaes,
447 				 ses->smb3signingkey, SMB2_CMACAES_SIZE);
448 	if (rc) {
449 		cifs_dbg(VFS, "%s: Could not set key for cmac aes\n", __func__);
450 		return rc;
451 	}
452 
453 	/*
454 	 * we already allocate sdesccmacaes when we init smb3 signing key,
455 	 * so unlike smb2 case we do not have to check here if secmech are
456 	 * initialized
457 	 */
458 	rc = crypto_shash_init(shash);
459 	if (rc) {
460 		cifs_dbg(VFS, "%s: Could not init cmac aes\n", __func__);
461 		return rc;
462 	}
463 
464 	/*
465 	 * For SMB2+, __cifs_calc_signature() expects to sign only the actual
466 	 * data, that is, iov[0] should not contain a rfc1002 length.
467 	 *
468 	 * Sign the rfc1002 length prior to passing the data (iov[1-N]) down to
469 	 * __cifs_calc_signature().
470 	 */
471 	drqst = *rqst;
472 	if (drqst.rq_nvec >= 2 && iov[0].iov_len == 4) {
473 		rc = crypto_shash_update(shash, iov[0].iov_base,
474 					 iov[0].iov_len);
475 		if (rc) {
476 			cifs_dbg(VFS, "%s: Could not update with payload\n",
477 				 __func__);
478 			return rc;
479 		}
480 		drqst.rq_iov++;
481 		drqst.rq_nvec--;
482 	}
483 
484 	rc = __cifs_calc_signature(&drqst, server, sigptr, shash);
485 	if (!rc)
486 		memcpy(shdr->Signature, sigptr, SMB2_SIGNATURE_SIZE);
487 
488 	return rc;
489 }
490 
491 /* must be called with server->srv_mutex held */
492 static int
smb2_sign_rqst(struct smb_rqst * rqst,struct TCP_Server_Info * server)493 smb2_sign_rqst(struct smb_rqst *rqst, struct TCP_Server_Info *server)
494 {
495 	int rc = 0;
496 	struct smb2_sync_hdr *shdr =
497 			(struct smb2_sync_hdr *)rqst->rq_iov[0].iov_base;
498 
499 	if (!(shdr->Flags & SMB2_FLAGS_SIGNED) ||
500 	    server->tcpStatus == CifsNeedNegotiate)
501 		return rc;
502 
503 	if (!server->session_estab) {
504 		strncpy(shdr->Signature, "BSRSPYL", 8);
505 		return rc;
506 	}
507 
508 	rc = server->ops->calc_signature(rqst, server);
509 
510 	return rc;
511 }
512 
513 int
smb2_verify_signature(struct smb_rqst * rqst,struct TCP_Server_Info * server)514 smb2_verify_signature(struct smb_rqst *rqst, struct TCP_Server_Info *server)
515 {
516 	unsigned int rc;
517 	char server_response_sig[16];
518 	struct smb2_sync_hdr *shdr =
519 			(struct smb2_sync_hdr *)rqst->rq_iov[0].iov_base;
520 
521 	if ((shdr->Command == SMB2_NEGOTIATE) ||
522 	    (shdr->Command == SMB2_SESSION_SETUP) ||
523 	    (shdr->Command == SMB2_OPLOCK_BREAK) ||
524 	    (!server->session_estab))
525 		return 0;
526 
527 	/*
528 	 * BB what if signatures are supposed to be on for session but
529 	 * server does not send one? BB
530 	 */
531 
532 	/* Do not need to verify session setups with signature "BSRSPYL " */
533 	if (memcmp(shdr->Signature, "BSRSPYL ", 8) == 0)
534 		cifs_dbg(FYI, "dummy signature received for smb command 0x%x\n",
535 			 shdr->Command);
536 
537 	/*
538 	 * Save off the origiginal signature so we can modify the smb and check
539 	 * our calculated signature against what the server sent.
540 	 */
541 	memcpy(server_response_sig, shdr->Signature, SMB2_SIGNATURE_SIZE);
542 
543 	memset(shdr->Signature, 0, SMB2_SIGNATURE_SIZE);
544 
545 	mutex_lock(&server->srv_mutex);
546 	rc = server->ops->calc_signature(rqst, server);
547 	mutex_unlock(&server->srv_mutex);
548 
549 	if (rc)
550 		return rc;
551 
552 	if (memcmp(server_response_sig, shdr->Signature, SMB2_SIGNATURE_SIZE))
553 		return -EACCES;
554 	else
555 		return 0;
556 }
557 
558 /*
559  * Set message id for the request. Should be called after wait_for_free_request
560  * and when srv_mutex is held.
561  */
562 static inline void
smb2_seq_num_into_buf(struct TCP_Server_Info * server,struct smb2_sync_hdr * shdr)563 smb2_seq_num_into_buf(struct TCP_Server_Info *server,
564 		      struct smb2_sync_hdr *shdr)
565 {
566 	unsigned int i, num = le16_to_cpu(shdr->CreditCharge);
567 
568 	shdr->MessageId = get_next_mid64(server);
569 	/* skip message numbers according to CreditCharge field */
570 	for (i = 1; i < num; i++)
571 		get_next_mid(server);
572 }
573 
574 static struct mid_q_entry *
smb2_mid_entry_alloc(const struct smb2_sync_hdr * shdr,struct TCP_Server_Info * server)575 smb2_mid_entry_alloc(const struct smb2_sync_hdr *shdr,
576 		     struct TCP_Server_Info *server)
577 {
578 	struct mid_q_entry *temp;
579 	unsigned int credits = le16_to_cpu(shdr->CreditCharge);
580 
581 	if (server == NULL) {
582 		cifs_dbg(VFS, "Null TCP session in smb2_mid_entry_alloc\n");
583 		return NULL;
584 	}
585 
586 	temp = mempool_alloc(cifs_mid_poolp, GFP_NOFS);
587 	memset(temp, 0, sizeof(struct mid_q_entry));
588 	kref_init(&temp->refcount);
589 	temp->mid = le64_to_cpu(shdr->MessageId);
590 	temp->credits = credits > 0 ? credits : 1;
591 	temp->pid = current->pid;
592 	temp->command = shdr->Command; /* Always LE */
593 	temp->when_alloc = jiffies;
594 	temp->server = server;
595 
596 	/*
597 	 * The default is for the mid to be synchronous, so the
598 	 * default callback just wakes up the current task.
599 	 */
600 	temp->callback = cifs_wake_up_task;
601 	temp->callback_data = current;
602 
603 	atomic_inc(&midCount);
604 	temp->mid_state = MID_REQUEST_ALLOCATED;
605 	return temp;
606 }
607 
608 static int
smb2_get_mid_entry(struct cifs_ses * ses,struct smb2_sync_hdr * shdr,struct mid_q_entry ** mid)609 smb2_get_mid_entry(struct cifs_ses *ses, struct smb2_sync_hdr *shdr,
610 		   struct mid_q_entry **mid)
611 {
612 	if (ses->server->tcpStatus == CifsExiting)
613 		return -ENOENT;
614 
615 	if (ses->server->tcpStatus == CifsNeedReconnect) {
616 		cifs_dbg(FYI, "tcp session dead - return to caller to retry\n");
617 		return -EAGAIN;
618 	}
619 
620 	if (ses->status == CifsNew) {
621 		if ((shdr->Command != SMB2_SESSION_SETUP) &&
622 		    (shdr->Command != SMB2_NEGOTIATE))
623 			return -EAGAIN;
624 		/* else ok - we are setting up session */
625 	}
626 
627 	if (ses->status == CifsExiting) {
628 		if (shdr->Command != SMB2_LOGOFF)
629 			return -EAGAIN;
630 		/* else ok - we are shutting down the session */
631 	}
632 
633 	*mid = smb2_mid_entry_alloc(shdr, ses->server);
634 	if (*mid == NULL)
635 		return -ENOMEM;
636 	spin_lock(&GlobalMid_Lock);
637 	list_add_tail(&(*mid)->qhead, &ses->server->pending_mid_q);
638 	spin_unlock(&GlobalMid_Lock);
639 	return 0;
640 }
641 
642 int
smb2_check_receive(struct mid_q_entry * mid,struct TCP_Server_Info * server,bool log_error)643 smb2_check_receive(struct mid_q_entry *mid, struct TCP_Server_Info *server,
644 		   bool log_error)
645 {
646 	unsigned int len = mid->resp_buf_size;
647 	struct kvec iov[1];
648 	struct smb_rqst rqst = { .rq_iov = iov,
649 				 .rq_nvec = 1 };
650 
651 	iov[0].iov_base = (char *)mid->resp_buf;
652 	iov[0].iov_len = len;
653 
654 	dump_smb(mid->resp_buf, min_t(u32, 80, len));
655 	/* convert the length into a more usable form */
656 	if (len > 24 && server->sign && !mid->decrypted) {
657 		int rc;
658 
659 		rc = smb2_verify_signature(&rqst, server);
660 		if (rc)
661 			cifs_dbg(VFS, "SMB signature verification returned error = %d\n",
662 				 rc);
663 	}
664 
665 	return map_smb2_to_linux_error(mid->resp_buf, log_error);
666 }
667 
668 struct mid_q_entry *
smb2_setup_request(struct cifs_ses * ses,struct smb_rqst * rqst)669 smb2_setup_request(struct cifs_ses *ses, struct smb_rqst *rqst)
670 {
671 	int rc;
672 	struct smb2_sync_hdr *shdr =
673 			(struct smb2_sync_hdr *)rqst->rq_iov[0].iov_base;
674 	struct mid_q_entry *mid;
675 
676 	smb2_seq_num_into_buf(ses->server, shdr);
677 
678 	rc = smb2_get_mid_entry(ses, shdr, &mid);
679 	if (rc) {
680 		revert_current_mid_from_hdr(ses->server, shdr);
681 		return ERR_PTR(rc);
682 	}
683 
684 	rc = smb2_sign_rqst(rqst, ses->server);
685 	if (rc) {
686 		revert_current_mid_from_hdr(ses->server, shdr);
687 		cifs_delete_mid(mid);
688 		return ERR_PTR(rc);
689 	}
690 
691 	return mid;
692 }
693 
694 struct mid_q_entry *
smb2_setup_async_request(struct TCP_Server_Info * server,struct smb_rqst * rqst)695 smb2_setup_async_request(struct TCP_Server_Info *server, struct smb_rqst *rqst)
696 {
697 	int rc;
698 	struct smb2_sync_hdr *shdr =
699 			(struct smb2_sync_hdr *)rqst->rq_iov[0].iov_base;
700 	struct mid_q_entry *mid;
701 
702 	smb2_seq_num_into_buf(server, shdr);
703 
704 	mid = smb2_mid_entry_alloc(shdr, server);
705 	if (mid == NULL) {
706 		revert_current_mid_from_hdr(server, shdr);
707 		return ERR_PTR(-ENOMEM);
708 	}
709 
710 	rc = smb2_sign_rqst(rqst, server);
711 	if (rc) {
712 		revert_current_mid_from_hdr(server, shdr);
713 		DeleteMidQEntry(mid);
714 		return ERR_PTR(rc);
715 	}
716 
717 	return mid;
718 }
719 
720 int
smb3_crypto_aead_allocate(struct TCP_Server_Info * server)721 smb3_crypto_aead_allocate(struct TCP_Server_Info *server)
722 {
723 	struct crypto_aead *tfm;
724 
725 	if (!server->secmech.ccmaesencrypt) {
726 		tfm = crypto_alloc_aead("ccm(aes)", 0, 0);
727 		if (IS_ERR(tfm)) {
728 			cifs_dbg(VFS, "%s: Failed to alloc encrypt aead\n",
729 				 __func__);
730 			return PTR_ERR(tfm);
731 		}
732 		server->secmech.ccmaesencrypt = tfm;
733 	}
734 
735 	if (!server->secmech.ccmaesdecrypt) {
736 		tfm = crypto_alloc_aead("ccm(aes)", 0, 0);
737 		if (IS_ERR(tfm)) {
738 			crypto_free_aead(server->secmech.ccmaesencrypt);
739 			server->secmech.ccmaesencrypt = NULL;
740 			cifs_dbg(VFS, "%s: Failed to alloc decrypt aead\n",
741 				 __func__);
742 			return PTR_ERR(tfm);
743 		}
744 		server->secmech.ccmaesdecrypt = tfm;
745 	}
746 
747 	return 0;
748 }
749