• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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_server_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_server_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_server_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_server_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_server_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 	struct TCP_Server_Info *server = ses->server;
243 
244 	memset(prfhash, 0x0, SMB2_HMACSHA256_SIZE);
245 	memset(key, 0x0, key_size);
246 
247 	rc = smb3_crypto_shash_allocate(server);
248 	if (rc) {
249 		cifs_server_dbg(VFS, "%s: crypto alloc failed\n", __func__);
250 		goto smb3signkey_ret;
251 	}
252 
253 	rc = crypto_shash_setkey(server->secmech.hmacsha256,
254 		ses->auth_key.response, SMB2_NTLMV2_SESSKEY_SIZE);
255 	if (rc) {
256 		cifs_server_dbg(VFS, "%s: Could not set with session key\n", __func__);
257 		goto smb3signkey_ret;
258 	}
259 
260 	rc = crypto_shash_init(&server->secmech.sdeschmacsha256->shash);
261 	if (rc) {
262 		cifs_server_dbg(VFS, "%s: Could not init sign hmac\n", __func__);
263 		goto smb3signkey_ret;
264 	}
265 
266 	rc = crypto_shash_update(&server->secmech.sdeschmacsha256->shash,
267 				i, 4);
268 	if (rc) {
269 		cifs_server_dbg(VFS, "%s: Could not update with n\n", __func__);
270 		goto smb3signkey_ret;
271 	}
272 
273 	rc = crypto_shash_update(&server->secmech.sdeschmacsha256->shash,
274 				label.iov_base, label.iov_len);
275 	if (rc) {
276 		cifs_server_dbg(VFS, "%s: Could not update with label\n", __func__);
277 		goto smb3signkey_ret;
278 	}
279 
280 	rc = crypto_shash_update(&server->secmech.sdeschmacsha256->shash,
281 				&zero, 1);
282 	if (rc) {
283 		cifs_server_dbg(VFS, "%s: Could not update with zero\n", __func__);
284 		goto smb3signkey_ret;
285 	}
286 
287 	rc = crypto_shash_update(&server->secmech.sdeschmacsha256->shash,
288 				context.iov_base, context.iov_len);
289 	if (rc) {
290 		cifs_server_dbg(VFS, "%s: Could not update with context\n", __func__);
291 		goto smb3signkey_ret;
292 	}
293 
294 	rc = crypto_shash_update(&server->secmech.sdeschmacsha256->shash,
295 				L, 4);
296 	if (rc) {
297 		cifs_server_dbg(VFS, "%s: Could not update with L\n", __func__);
298 		goto smb3signkey_ret;
299 	}
300 
301 	rc = crypto_shash_final(&server->secmech.sdeschmacsha256->shash,
302 				hashptr);
303 	if (rc) {
304 		cifs_server_dbg(VFS, "%s: Could not generate sha256 hash\n", __func__);
305 		goto smb3signkey_ret;
306 	}
307 
308 	memcpy(key, hashptr, key_size);
309 
310 smb3signkey_ret:
311 	return rc;
312 }
313 
314 struct derivation {
315 	struct kvec label;
316 	struct kvec context;
317 };
318 
319 struct derivation_triplet {
320 	struct derivation signing;
321 	struct derivation encryption;
322 	struct derivation decryption;
323 };
324 
325 static int
generate_smb3signingkey(struct cifs_ses * ses,const struct derivation_triplet * ptriplet)326 generate_smb3signingkey(struct cifs_ses *ses,
327 			const struct derivation_triplet *ptriplet)
328 {
329 	int rc;
330 
331 	rc = generate_key(ses, ptriplet->signing.label,
332 			  ptriplet->signing.context, ses->smb3signingkey,
333 			  SMB3_SIGN_KEY_SIZE);
334 	if (rc)
335 		return rc;
336 
337 	rc = generate_key(ses, ptriplet->encryption.label,
338 			  ptriplet->encryption.context, ses->smb3encryptionkey,
339 			  SMB3_SIGN_KEY_SIZE);
340 	if (rc)
341 		return rc;
342 
343 	rc = generate_key(ses, ptriplet->decryption.label,
344 			  ptriplet->decryption.context,
345 			  ses->smb3decryptionkey, SMB3_SIGN_KEY_SIZE);
346 
347 	if (rc)
348 		return rc;
349 
350 #ifdef CONFIG_CIFS_DEBUG_DUMP_KEYS
351 	cifs_dbg(VFS, "%s: dumping generated AES session keys\n", __func__);
352 	/*
353 	 * The session id is opaque in terms of endianness, so we can't
354 	 * print it as a long long. we dump it as we got it on the wire
355 	 */
356 	cifs_dbg(VFS, "Session Id    %*ph\n", (int)sizeof(ses->Suid),
357 			&ses->Suid);
358 	cifs_dbg(VFS, "Session Key   %*ph\n",
359 		 SMB2_NTLMV2_SESSKEY_SIZE, ses->auth_key.response);
360 	cifs_dbg(VFS, "Signing Key   %*ph\n",
361 		 SMB3_SIGN_KEY_SIZE, ses->smb3signingkey);
362 	cifs_dbg(VFS, "ServerIn Key  %*ph\n",
363 		 SMB3_SIGN_KEY_SIZE, ses->smb3encryptionkey);
364 	cifs_dbg(VFS, "ServerOut Key %*ph\n",
365 		 SMB3_SIGN_KEY_SIZE, ses->smb3decryptionkey);
366 #endif
367 	return rc;
368 }
369 
370 int
generate_smb30signingkey(struct cifs_ses * ses)371 generate_smb30signingkey(struct cifs_ses *ses)
372 
373 {
374 	struct derivation_triplet triplet;
375 	struct derivation *d;
376 
377 	d = &triplet.signing;
378 	d->label.iov_base = "SMB2AESCMAC";
379 	d->label.iov_len = 12;
380 	d->context.iov_base = "SmbSign";
381 	d->context.iov_len = 8;
382 
383 	d = &triplet.encryption;
384 	d->label.iov_base = "SMB2AESCCM";
385 	d->label.iov_len = 11;
386 	d->context.iov_base = "ServerIn ";
387 	d->context.iov_len = 10;
388 
389 	d = &triplet.decryption;
390 	d->label.iov_base = "SMB2AESCCM";
391 	d->label.iov_len = 11;
392 	d->context.iov_base = "ServerOut";
393 	d->context.iov_len = 10;
394 
395 	return generate_smb3signingkey(ses, &triplet);
396 }
397 
398 int
generate_smb311signingkey(struct cifs_ses * ses)399 generate_smb311signingkey(struct cifs_ses *ses)
400 
401 {
402 	struct derivation_triplet triplet;
403 	struct derivation *d;
404 
405 	d = &triplet.signing;
406 	d->label.iov_base = "SMBSigningKey";
407 	d->label.iov_len = 14;
408 	d->context.iov_base = ses->preauth_sha_hash;
409 	d->context.iov_len = 64;
410 
411 	d = &triplet.encryption;
412 	d->label.iov_base = "SMBC2SCipherKey";
413 	d->label.iov_len = 16;
414 	d->context.iov_base = ses->preauth_sha_hash;
415 	d->context.iov_len = 64;
416 
417 	d = &triplet.decryption;
418 	d->label.iov_base = "SMBS2CCipherKey";
419 	d->label.iov_len = 16;
420 	d->context.iov_base = ses->preauth_sha_hash;
421 	d->context.iov_len = 64;
422 
423 	return generate_smb3signingkey(ses, &triplet);
424 }
425 
426 int
smb3_calc_signature(struct smb_rqst * rqst,struct TCP_Server_Info * server)427 smb3_calc_signature(struct smb_rqst *rqst, struct TCP_Server_Info *server)
428 {
429 	int rc;
430 	unsigned char smb3_signature[SMB2_CMACAES_SIZE];
431 	unsigned char *sigptr = smb3_signature;
432 	struct kvec *iov = rqst->rq_iov;
433 	struct smb2_sync_hdr *shdr = (struct smb2_sync_hdr *)iov[0].iov_base;
434 	struct cifs_ses *ses;
435 	struct shash_desc *shash = &server->secmech.sdesccmacaes->shash;
436 	struct smb_rqst drqst;
437 
438 	ses = smb2_find_smb_ses(server, shdr->SessionId);
439 	if (!ses) {
440 		cifs_server_dbg(VFS, "%s: Could not find session\n", __func__);
441 		return 0;
442 	}
443 
444 	memset(smb3_signature, 0x0, SMB2_CMACAES_SIZE);
445 	memset(shdr->Signature, 0x0, SMB2_SIGNATURE_SIZE);
446 
447 	rc = crypto_shash_setkey(server->secmech.cmacaes,
448 				 ses->smb3signingkey, SMB2_CMACAES_SIZE);
449 	if (rc) {
450 		cifs_server_dbg(VFS, "%s: Could not set key for cmac aes\n", __func__);
451 		return rc;
452 	}
453 
454 	/*
455 	 * we already allocate sdesccmacaes when we init smb3 signing key,
456 	 * so unlike smb2 case we do not have to check here if secmech are
457 	 * initialized
458 	 */
459 	rc = crypto_shash_init(shash);
460 	if (rc) {
461 		cifs_server_dbg(VFS, "%s: Could not init cmac aes\n", __func__);
462 		return rc;
463 	}
464 
465 	/*
466 	 * For SMB2+, __cifs_calc_signature() expects to sign only the actual
467 	 * data, that is, iov[0] should not contain a rfc1002 length.
468 	 *
469 	 * Sign the rfc1002 length prior to passing the data (iov[1-N]) down to
470 	 * __cifs_calc_signature().
471 	 */
472 	drqst = *rqst;
473 	if (drqst.rq_nvec >= 2 && iov[0].iov_len == 4) {
474 		rc = crypto_shash_update(shash, iov[0].iov_base,
475 					 iov[0].iov_len);
476 		if (rc) {
477 			cifs_server_dbg(VFS, "%s: Could not update with payload\n",
478 				 __func__);
479 			return rc;
480 		}
481 		drqst.rq_iov++;
482 		drqst.rq_nvec--;
483 	}
484 
485 	rc = __cifs_calc_signature(&drqst, server, sigptr, shash);
486 	if (!rc)
487 		memcpy(shdr->Signature, sigptr, SMB2_SIGNATURE_SIZE);
488 
489 	return rc;
490 }
491 
492 /* must be called with server->srv_mutex held */
493 static int
smb2_sign_rqst(struct smb_rqst * rqst,struct TCP_Server_Info * server)494 smb2_sign_rqst(struct smb_rqst *rqst, struct TCP_Server_Info *server)
495 {
496 	int rc = 0;
497 	struct smb2_sync_hdr *shdr =
498 			(struct smb2_sync_hdr *)rqst->rq_iov[0].iov_base;
499 
500 	if (!(shdr->Flags & SMB2_FLAGS_SIGNED) ||
501 	    server->tcpStatus == CifsNeedNegotiate)
502 		return rc;
503 
504 	if (!server->session_estab) {
505 		strncpy(shdr->Signature, "BSRSPYL", 8);
506 		return rc;
507 	}
508 
509 	rc = server->ops->calc_signature(rqst, server);
510 
511 	return rc;
512 }
513 
514 int
smb2_verify_signature(struct smb_rqst * rqst,struct TCP_Server_Info * server)515 smb2_verify_signature(struct smb_rqst *rqst, struct TCP_Server_Info *server)
516 {
517 	unsigned int rc;
518 	char server_response_sig[16];
519 	struct smb2_sync_hdr *shdr =
520 			(struct smb2_sync_hdr *)rqst->rq_iov[0].iov_base;
521 
522 	if ((shdr->Command == SMB2_NEGOTIATE) ||
523 	    (shdr->Command == SMB2_SESSION_SETUP) ||
524 	    (shdr->Command == SMB2_OPLOCK_BREAK) ||
525 	    server->ignore_signature ||
526 	    (!server->session_estab))
527 		return 0;
528 
529 	/*
530 	 * BB what if signatures are supposed to be on for session but
531 	 * server does not send one? BB
532 	 */
533 
534 	/* Do not need to verify session setups with signature "BSRSPYL " */
535 	if (memcmp(shdr->Signature, "BSRSPYL ", 8) == 0)
536 		cifs_dbg(FYI, "dummy signature received for smb command 0x%x\n",
537 			 shdr->Command);
538 
539 	/*
540 	 * Save off the origiginal signature so we can modify the smb and check
541 	 * our calculated signature against what the server sent.
542 	 */
543 	memcpy(server_response_sig, shdr->Signature, SMB2_SIGNATURE_SIZE);
544 
545 	memset(shdr->Signature, 0, SMB2_SIGNATURE_SIZE);
546 
547 	mutex_lock(&server->srv_mutex);
548 	rc = server->ops->calc_signature(rqst, server);
549 	mutex_unlock(&server->srv_mutex);
550 
551 	if (rc)
552 		return rc;
553 
554 	if (memcmp(server_response_sig, shdr->Signature, SMB2_SIGNATURE_SIZE))
555 		return -EACCES;
556 	else
557 		return 0;
558 }
559 
560 /*
561  * Set message id for the request. Should be called after wait_for_free_request
562  * and when srv_mutex is held.
563  */
564 static inline void
smb2_seq_num_into_buf(struct TCP_Server_Info * server,struct smb2_sync_hdr * shdr)565 smb2_seq_num_into_buf(struct TCP_Server_Info *server,
566 		      struct smb2_sync_hdr *shdr)
567 {
568 	unsigned int i, num = le16_to_cpu(shdr->CreditCharge);
569 
570 	shdr->MessageId = get_next_mid64(server);
571 	/* skip message numbers according to CreditCharge field */
572 	for (i = 1; i < num; i++)
573 		get_next_mid(server);
574 }
575 
576 static struct mid_q_entry *
smb2_mid_entry_alloc(const struct smb2_sync_hdr * shdr,struct TCP_Server_Info * server)577 smb2_mid_entry_alloc(const struct smb2_sync_hdr *shdr,
578 		     struct TCP_Server_Info *server)
579 {
580 	struct mid_q_entry *temp;
581 	unsigned int credits = le16_to_cpu(shdr->CreditCharge);
582 
583 	if (server == NULL) {
584 		cifs_dbg(VFS, "Null TCP session in smb2_mid_entry_alloc\n");
585 		return NULL;
586 	}
587 
588 	temp = mempool_alloc(cifs_mid_poolp, GFP_NOFS);
589 	memset(temp, 0, sizeof(struct mid_q_entry));
590 	kref_init(&temp->refcount);
591 	temp->mid = le64_to_cpu(shdr->MessageId);
592 	temp->credits = credits > 0 ? credits : 1;
593 	temp->pid = current->pid;
594 	temp->command = shdr->Command; /* Always LE */
595 	temp->when_alloc = jiffies;
596 	temp->server = server;
597 
598 	/*
599 	 * The default is for the mid to be synchronous, so the
600 	 * default callback just wakes up the current task.
601 	 */
602 	get_task_struct(current);
603 	temp->creator = current;
604 	temp->callback = cifs_wake_up_task;
605 	temp->callback_data = current;
606 
607 	atomic_inc(&midCount);
608 	temp->mid_state = MID_REQUEST_ALLOCATED;
609 	trace_smb3_cmd_enter(shdr->TreeId, shdr->SessionId,
610 		le16_to_cpu(shdr->Command), temp->mid);
611 	return temp;
612 }
613 
614 static int
smb2_get_mid_entry(struct cifs_ses * ses,struct smb2_sync_hdr * shdr,struct mid_q_entry ** mid)615 smb2_get_mid_entry(struct cifs_ses *ses, struct smb2_sync_hdr *shdr,
616 		   struct mid_q_entry **mid)
617 {
618 	if (ses->server->tcpStatus == CifsExiting)
619 		return -ENOENT;
620 
621 	if (ses->server->tcpStatus == CifsNeedReconnect) {
622 		cifs_dbg(FYI, "tcp session dead - return to caller to retry\n");
623 		return -EAGAIN;
624 	}
625 
626 	if (ses->server->tcpStatus == CifsNeedNegotiate &&
627 	   shdr->Command != SMB2_NEGOTIATE)
628 		return -EAGAIN;
629 
630 	if (ses->status == CifsNew) {
631 		if ((shdr->Command != SMB2_SESSION_SETUP) &&
632 		    (shdr->Command != SMB2_NEGOTIATE))
633 			return -EAGAIN;
634 		/* else ok - we are setting up session */
635 	}
636 
637 	if (ses->status == CifsExiting) {
638 		if (shdr->Command != SMB2_LOGOFF)
639 			return -EAGAIN;
640 		/* else ok - we are shutting down the session */
641 	}
642 
643 	*mid = smb2_mid_entry_alloc(shdr, ses->server);
644 	if (*mid == NULL)
645 		return -ENOMEM;
646 	spin_lock(&GlobalMid_Lock);
647 	list_add_tail(&(*mid)->qhead, &ses->server->pending_mid_q);
648 	spin_unlock(&GlobalMid_Lock);
649 
650 	return 0;
651 }
652 
653 int
smb2_check_receive(struct mid_q_entry * mid,struct TCP_Server_Info * server,bool log_error)654 smb2_check_receive(struct mid_q_entry *mid, struct TCP_Server_Info *server,
655 		   bool log_error)
656 {
657 	unsigned int len = mid->resp_buf_size;
658 	struct kvec iov[1];
659 	struct smb_rqst rqst = { .rq_iov = iov,
660 				 .rq_nvec = 1 };
661 
662 	iov[0].iov_base = (char *)mid->resp_buf;
663 	iov[0].iov_len = len;
664 
665 	dump_smb(mid->resp_buf, min_t(u32, 80, len));
666 	/* convert the length into a more usable form */
667 	if (len > 24 && server->sign && !mid->decrypted) {
668 		int rc;
669 
670 		rc = smb2_verify_signature(&rqst, server);
671 		if (rc)
672 			cifs_server_dbg(VFS, "SMB signature verification returned error = %d\n",
673 				 rc);
674 	}
675 
676 	return map_smb2_to_linux_error(mid->resp_buf, log_error);
677 }
678 
679 struct mid_q_entry *
smb2_setup_request(struct cifs_ses * ses,struct smb_rqst * rqst)680 smb2_setup_request(struct cifs_ses *ses, struct smb_rqst *rqst)
681 {
682 	int rc;
683 	struct smb2_sync_hdr *shdr =
684 			(struct smb2_sync_hdr *)rqst->rq_iov[0].iov_base;
685 	struct mid_q_entry *mid;
686 
687 	smb2_seq_num_into_buf(ses->server, shdr);
688 
689 	rc = smb2_get_mid_entry(ses, shdr, &mid);
690 	if (rc) {
691 		revert_current_mid_from_hdr(ses->server, shdr);
692 		return ERR_PTR(rc);
693 	}
694 
695 	rc = smb2_sign_rqst(rqst, ses->server);
696 	if (rc) {
697 		revert_current_mid_from_hdr(ses->server, shdr);
698 		cifs_delete_mid(mid);
699 		return ERR_PTR(rc);
700 	}
701 
702 	return mid;
703 }
704 
705 struct mid_q_entry *
smb2_setup_async_request(struct TCP_Server_Info * server,struct smb_rqst * rqst)706 smb2_setup_async_request(struct TCP_Server_Info *server, struct smb_rqst *rqst)
707 {
708 	int rc;
709 	struct smb2_sync_hdr *shdr =
710 			(struct smb2_sync_hdr *)rqst->rq_iov[0].iov_base;
711 	struct mid_q_entry *mid;
712 
713 	if (server->tcpStatus == CifsNeedNegotiate &&
714 	   shdr->Command != SMB2_NEGOTIATE)
715 		return ERR_PTR(-EAGAIN);
716 
717 	smb2_seq_num_into_buf(server, shdr);
718 
719 	mid = smb2_mid_entry_alloc(shdr, server);
720 	if (mid == NULL) {
721 		revert_current_mid_from_hdr(server, shdr);
722 		return ERR_PTR(-ENOMEM);
723 	}
724 
725 	rc = smb2_sign_rqst(rqst, server);
726 	if (rc) {
727 		revert_current_mid_from_hdr(server, shdr);
728 		DeleteMidQEntry(mid);
729 		return ERR_PTR(rc);
730 	}
731 
732 	return mid;
733 }
734 
735 int
smb3_crypto_aead_allocate(struct TCP_Server_Info * server)736 smb3_crypto_aead_allocate(struct TCP_Server_Info *server)
737 {
738 	struct crypto_aead *tfm;
739 
740 	if (!server->secmech.ccmaesencrypt) {
741 		if (server->cipher_type == SMB2_ENCRYPTION_AES128_GCM)
742 			tfm = crypto_alloc_aead("gcm(aes)", 0, 0);
743 		else
744 			tfm = crypto_alloc_aead("ccm(aes)", 0, 0);
745 		if (IS_ERR(tfm)) {
746 			cifs_server_dbg(VFS, "%s: Failed to alloc encrypt aead\n",
747 				 __func__);
748 			return PTR_ERR(tfm);
749 		}
750 		server->secmech.ccmaesencrypt = tfm;
751 	}
752 
753 	if (!server->secmech.ccmaesdecrypt) {
754 		if (server->cipher_type == SMB2_ENCRYPTION_AES128_GCM)
755 			tfm = crypto_alloc_aead("gcm(aes)", 0, 0);
756 		else
757 			tfm = crypto_alloc_aead("ccm(aes)", 0, 0);
758 		if (IS_ERR(tfm)) {
759 			crypto_free_aead(server->secmech.ccmaesencrypt);
760 			server->secmech.ccmaesencrypt = NULL;
761 			cifs_server_dbg(VFS, "%s: Failed to alloc decrypt aead\n",
762 				 __func__);
763 			return PTR_ERR(tfm);
764 		}
765 		server->secmech.ccmaesdecrypt = tfm;
766 	}
767 
768 	return 0;
769 }
770