• 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 "smb2pdu.h"
35 #include "cifsglob.h"
36 #include "cifsproto.h"
37 #include "smb2proto.h"
38 #include "cifs_debug.h"
39 #include "smb2status.h"
40 #include "smb2glob.h"
41 
42 static int
smb2_crypto_shash_allocate(struct TCP_Server_Info * server)43 smb2_crypto_shash_allocate(struct TCP_Server_Info *server)
44 {
45 	int rc;
46 	unsigned int size;
47 
48 	if (server->secmech.sdeschmacsha256 != NULL)
49 		return 0; /* already allocated */
50 
51 	server->secmech.hmacsha256 = crypto_alloc_shash("hmac(sha256)", 0, 0);
52 	if (IS_ERR(server->secmech.hmacsha256)) {
53 		cifs_dbg(VFS, "could not allocate crypto hmacsha256\n");
54 		rc = PTR_ERR(server->secmech.hmacsha256);
55 		server->secmech.hmacsha256 = NULL;
56 		return rc;
57 	}
58 
59 	size = sizeof(struct shash_desc) +
60 			crypto_shash_descsize(server->secmech.hmacsha256);
61 	server->secmech.sdeschmacsha256 = kmalloc(size, GFP_KERNEL);
62 	if (!server->secmech.sdeschmacsha256) {
63 		crypto_free_shash(server->secmech.hmacsha256);
64 		server->secmech.hmacsha256 = NULL;
65 		return -ENOMEM;
66 	}
67 	server->secmech.sdeschmacsha256->shash.tfm = server->secmech.hmacsha256;
68 	server->secmech.sdeschmacsha256->shash.flags = 0x0;
69 
70 	return 0;
71 }
72 
73 static int
smb3_crypto_shash_allocate(struct TCP_Server_Info * server)74 smb3_crypto_shash_allocate(struct TCP_Server_Info *server)
75 {
76 	unsigned int size;
77 	int rc;
78 
79 	if (server->secmech.sdesccmacaes != NULL)
80 		return 0;  /* already allocated */
81 
82 	rc = smb2_crypto_shash_allocate(server);
83 	if (rc)
84 		return rc;
85 
86 	server->secmech.cmacaes = crypto_alloc_shash("cmac(aes)", 0, 0);
87 	if (IS_ERR(server->secmech.cmacaes)) {
88 		cifs_dbg(VFS, "could not allocate crypto cmac-aes");
89 		kfree(server->secmech.sdeschmacsha256);
90 		server->secmech.sdeschmacsha256 = NULL;
91 		crypto_free_shash(server->secmech.hmacsha256);
92 		server->secmech.hmacsha256 = NULL;
93 		rc = PTR_ERR(server->secmech.cmacaes);
94 		server->secmech.cmacaes = NULL;
95 		return rc;
96 	}
97 
98 	size = sizeof(struct shash_desc) +
99 			crypto_shash_descsize(server->secmech.cmacaes);
100 	server->secmech.sdesccmacaes = kmalloc(size, GFP_KERNEL);
101 	if (!server->secmech.sdesccmacaes) {
102 		cifs_dbg(VFS, "%s: Can't alloc cmacaes\n", __func__);
103 		kfree(server->secmech.sdeschmacsha256);
104 		server->secmech.sdeschmacsha256 = NULL;
105 		crypto_free_shash(server->secmech.hmacsha256);
106 		crypto_free_shash(server->secmech.cmacaes);
107 		server->secmech.hmacsha256 = NULL;
108 		server->secmech.cmacaes = NULL;
109 		return -ENOMEM;
110 	}
111 	server->secmech.sdesccmacaes->shash.tfm = server->secmech.cmacaes;
112 	server->secmech.sdesccmacaes->shash.flags = 0x0;
113 
114 	return 0;
115 }
116 
117 static struct cifs_ses *
smb2_find_smb_ses_unlocked(struct TCP_Server_Info * server,__u64 ses_id)118 smb2_find_smb_ses_unlocked(struct TCP_Server_Info *server, __u64 ses_id)
119 {
120 	struct cifs_ses *ses;
121 
122 	list_for_each_entry(ses, &server->smb_ses_list, smb_ses_list) {
123 		if (ses->Suid != ses_id)
124 			continue;
125 		return ses;
126 	}
127 
128 	return NULL;
129 }
130 
131 struct cifs_ses *
smb2_find_smb_ses(struct TCP_Server_Info * server,__u64 ses_id)132 smb2_find_smb_ses(struct TCP_Server_Info *server, __u64 ses_id)
133 {
134 	struct cifs_ses *ses;
135 
136 	spin_lock(&cifs_tcp_ses_lock);
137 	ses = smb2_find_smb_ses_unlocked(server, ses_id);
138 	spin_unlock(&cifs_tcp_ses_lock);
139 
140 	return ses;
141 }
142 
143 static struct cifs_tcon *
smb2_find_smb_sess_tcon_unlocked(struct cifs_ses * ses,__u32 tid)144 smb2_find_smb_sess_tcon_unlocked(struct cifs_ses *ses, __u32  tid)
145 {
146 	struct cifs_tcon *tcon;
147 
148 	list_for_each_entry(tcon, &ses->tcon_list, tcon_list) {
149 		if (tcon->tid != tid)
150 			continue;
151 		++tcon->tc_count;
152 		return tcon;
153 	}
154 
155 	return NULL;
156 }
157 
158 /*
159  * Obtain tcon corresponding to the tid in the given
160  * cifs_ses
161  */
162 
163 struct cifs_tcon *
smb2_find_smb_tcon(struct TCP_Server_Info * server,__u64 ses_id,__u32 tid)164 smb2_find_smb_tcon(struct TCP_Server_Info *server, __u64 ses_id, __u32 tid)
165 {
166 	struct cifs_ses *ses;
167 	struct cifs_tcon *tcon;
168 
169 	spin_lock(&cifs_tcp_ses_lock);
170 	ses = smb2_find_smb_ses_unlocked(server, ses_id);
171 	if (!ses) {
172 		spin_unlock(&cifs_tcp_ses_lock);
173 		return NULL;
174 	}
175 	tcon = smb2_find_smb_sess_tcon_unlocked(ses, tid);
176 	spin_unlock(&cifs_tcp_ses_lock);
177 
178 	return tcon;
179 }
180 
181 int
smb2_calc_signature(struct smb_rqst * rqst,struct TCP_Server_Info * server)182 smb2_calc_signature(struct smb_rqst *rqst, struct TCP_Server_Info *server)
183 {
184 	int i, rc;
185 	unsigned char smb2_signature[SMB2_HMACSHA256_SIZE];
186 	unsigned char *sigptr = smb2_signature;
187 	struct kvec *iov = rqst->rq_iov;
188 	int n_vec = rqst->rq_nvec;
189 	struct smb2_hdr *smb2_pdu = (struct smb2_hdr *)iov[0].iov_base;
190 	struct cifs_ses *ses;
191 
192 	ses = smb2_find_smb_ses(server, smb2_pdu->SessionId);
193 	if (!ses) {
194 		cifs_dbg(VFS, "%s: Could not find session\n", __func__);
195 		return 0;
196 	}
197 
198 	memset(smb2_signature, 0x0, SMB2_HMACSHA256_SIZE);
199 	memset(smb2_pdu->Signature, 0x0, SMB2_SIGNATURE_SIZE);
200 
201 	rc = smb2_crypto_shash_allocate(server);
202 	if (rc) {
203 		cifs_dbg(VFS, "%s: shah256 alloc failed\n", __func__);
204 		return rc;
205 	}
206 
207 	rc = crypto_shash_setkey(server->secmech.hmacsha256,
208 		ses->auth_key.response, SMB2_NTLMV2_SESSKEY_SIZE);
209 	if (rc) {
210 		cifs_dbg(VFS, "%s: Could not update with response\n", __func__);
211 		return rc;
212 	}
213 
214 	rc = crypto_shash_init(&server->secmech.sdeschmacsha256->shash);
215 	if (rc) {
216 		cifs_dbg(VFS, "%s: Could not init sha256", __func__);
217 		return rc;
218 	}
219 
220 	for (i = 0; i < n_vec; i++) {
221 		if (iov[i].iov_len == 0)
222 			continue;
223 		if (iov[i].iov_base == NULL) {
224 			cifs_dbg(VFS, "null iovec entry\n");
225 			return -EIO;
226 		}
227 		/*
228 		 * The first entry includes a length field (which does not get
229 		 * signed that occupies the first 4 bytes before the header).
230 		 */
231 		if (i == 0) {
232 			if (iov[0].iov_len <= 8) /* cmd field at offset 9 */
233 				break; /* nothing to sign or corrupt header */
234 			rc =
235 			crypto_shash_update(
236 				&server->secmech.sdeschmacsha256->shash,
237 				iov[i].iov_base + 4, iov[i].iov_len - 4);
238 		} else {
239 			rc =
240 			crypto_shash_update(
241 				&server->secmech.sdeschmacsha256->shash,
242 				iov[i].iov_base, iov[i].iov_len);
243 		}
244 		if (rc) {
245 			cifs_dbg(VFS, "%s: Could not update with payload\n",
246 				 __func__);
247 			return rc;
248 		}
249 	}
250 
251 	/* now hash over the rq_pages array */
252 	for (i = 0; i < rqst->rq_npages; i++) {
253 		struct kvec p_iov;
254 
255 		cifs_rqst_page_to_kvec(rqst, i, &p_iov);
256 		crypto_shash_update(&server->secmech.sdeschmacsha256->shash,
257 					p_iov.iov_base, p_iov.iov_len);
258 		kunmap(rqst->rq_pages[i]);
259 	}
260 
261 	rc = crypto_shash_final(&server->secmech.sdeschmacsha256->shash,
262 				sigptr);
263 	if (rc)
264 		cifs_dbg(VFS, "%s: Could not generate sha256 hash\n", __func__);
265 
266 	memcpy(smb2_pdu->Signature, sigptr, SMB2_SIGNATURE_SIZE);
267 
268 	return rc;
269 }
270 
271 int
generate_smb3signingkey(struct cifs_ses * ses)272 generate_smb3signingkey(struct cifs_ses *ses)
273 {
274 	unsigned char zero = 0x0;
275 	__u8 i[4] = {0, 0, 0, 1};
276 	__u8 L[4] = {0, 0, 0, 128};
277 	int rc = 0;
278 	unsigned char prfhash[SMB2_HMACSHA256_SIZE];
279 	unsigned char *hashptr = prfhash;
280 
281 	memset(prfhash, 0x0, SMB2_HMACSHA256_SIZE);
282 	memset(ses->smb3signingkey, 0x0, SMB3_SIGNKEY_SIZE);
283 
284 	rc = smb3_crypto_shash_allocate(ses->server);
285 	if (rc) {
286 		cifs_dbg(VFS, "%s: crypto alloc failed\n", __func__);
287 		goto smb3signkey_ret;
288 	}
289 
290 	rc = crypto_shash_setkey(ses->server->secmech.hmacsha256,
291 		ses->auth_key.response, SMB2_NTLMV2_SESSKEY_SIZE);
292 	if (rc) {
293 		cifs_dbg(VFS, "%s: Could not set with session key\n", __func__);
294 		goto smb3signkey_ret;
295 	}
296 
297 	rc = crypto_shash_init(&ses->server->secmech.sdeschmacsha256->shash);
298 	if (rc) {
299 		cifs_dbg(VFS, "%s: Could not init sign hmac\n", __func__);
300 		goto smb3signkey_ret;
301 	}
302 
303 	rc = crypto_shash_update(&ses->server->secmech.sdeschmacsha256->shash,
304 				i, 4);
305 	if (rc) {
306 		cifs_dbg(VFS, "%s: Could not update with n\n", __func__);
307 		goto smb3signkey_ret;
308 	}
309 
310 	rc = crypto_shash_update(&ses->server->secmech.sdeschmacsha256->shash,
311 				"SMB2AESCMAC", 12);
312 	if (rc) {
313 		cifs_dbg(VFS, "%s: Could not update with label\n", __func__);
314 		goto smb3signkey_ret;
315 	}
316 
317 	rc = crypto_shash_update(&ses->server->secmech.sdeschmacsha256->shash,
318 				&zero, 1);
319 	if (rc) {
320 		cifs_dbg(VFS, "%s: Could not update with zero\n", __func__);
321 		goto smb3signkey_ret;
322 	}
323 
324 	rc = crypto_shash_update(&ses->server->secmech.sdeschmacsha256->shash,
325 				"SmbSign", 8);
326 	if (rc) {
327 		cifs_dbg(VFS, "%s: Could not update with context\n", __func__);
328 		goto smb3signkey_ret;
329 	}
330 
331 	rc = crypto_shash_update(&ses->server->secmech.sdeschmacsha256->shash,
332 				L, 4);
333 	if (rc) {
334 		cifs_dbg(VFS, "%s: Could not update with L\n", __func__);
335 		goto smb3signkey_ret;
336 	}
337 
338 	rc = crypto_shash_final(&ses->server->secmech.sdeschmacsha256->shash,
339 				hashptr);
340 	if (rc) {
341 		cifs_dbg(VFS, "%s: Could not generate sha256 hash\n", __func__);
342 		goto smb3signkey_ret;
343 	}
344 
345 	memcpy(ses->smb3signingkey, hashptr, SMB3_SIGNKEY_SIZE);
346 
347 smb3signkey_ret:
348 	return rc;
349 }
350 
351 int
smb3_calc_signature(struct smb_rqst * rqst,struct TCP_Server_Info * server)352 smb3_calc_signature(struct smb_rqst *rqst, struct TCP_Server_Info *server)
353 {
354 	int i;
355 	int rc = 0;
356 	unsigned char smb3_signature[SMB2_CMACAES_SIZE];
357 	unsigned char *sigptr = smb3_signature;
358 	struct kvec *iov = rqst->rq_iov;
359 	int n_vec = rqst->rq_nvec;
360 	struct smb2_hdr *smb2_pdu = (struct smb2_hdr *)iov[0].iov_base;
361 	struct cifs_ses *ses;
362 
363 	ses = smb2_find_smb_ses(server, smb2_pdu->SessionId);
364 	if (!ses) {
365 		cifs_dbg(VFS, "%s: Could not find session\n", __func__);
366 		return 0;
367 	}
368 
369 	memset(smb3_signature, 0x0, SMB2_CMACAES_SIZE);
370 	memset(smb2_pdu->Signature, 0x0, SMB2_SIGNATURE_SIZE);
371 
372 	rc = crypto_shash_setkey(server->secmech.cmacaes,
373 		ses->smb3signingkey, SMB2_CMACAES_SIZE);
374 
375 	if (rc) {
376 		cifs_dbg(VFS, "%s: Could not set key for cmac aes\n", __func__);
377 		return rc;
378 	}
379 
380 	/*
381 	 * we already allocate sdesccmacaes when we init smb3 signing key,
382 	 * so unlike smb2 case we do not have to check here if secmech are
383 	 * initialized
384 	 */
385 	rc = crypto_shash_init(&server->secmech.sdesccmacaes->shash);
386 	if (rc) {
387 		cifs_dbg(VFS, "%s: Could not init cmac aes\n", __func__);
388 		return rc;
389 	}
390 
391 	for (i = 0; i < n_vec; i++) {
392 		if (iov[i].iov_len == 0)
393 			continue;
394 		if (iov[i].iov_base == NULL) {
395 			cifs_dbg(VFS, "null iovec entry");
396 			return -EIO;
397 		}
398 		/*
399 		 * The first entry includes a length field (which does not get
400 		 * signed that occupies the first 4 bytes before the header).
401 		 */
402 		if (i == 0) {
403 			if (iov[0].iov_len <= 8) /* cmd field at offset 9 */
404 				break; /* nothing to sign or corrupt header */
405 			rc =
406 			crypto_shash_update(
407 				&server->secmech.sdesccmacaes->shash,
408 				iov[i].iov_base + 4, iov[i].iov_len - 4);
409 		} else {
410 			rc =
411 			crypto_shash_update(
412 				&server->secmech.sdesccmacaes->shash,
413 				iov[i].iov_base, iov[i].iov_len);
414 		}
415 		if (rc) {
416 			cifs_dbg(VFS, "%s: Couldn't update cmac aes with payload\n",
417 							__func__);
418 			return rc;
419 		}
420 	}
421 
422 	/* now hash over the rq_pages array */
423 	for (i = 0; i < rqst->rq_npages; i++) {
424 		struct kvec p_iov;
425 
426 		cifs_rqst_page_to_kvec(rqst, i, &p_iov);
427 		crypto_shash_update(&server->secmech.sdesccmacaes->shash,
428 					p_iov.iov_base, p_iov.iov_len);
429 		kunmap(rqst->rq_pages[i]);
430 	}
431 
432 	rc = crypto_shash_final(&server->secmech.sdesccmacaes->shash,
433 						sigptr);
434 	if (rc)
435 		cifs_dbg(VFS, "%s: Could not generate cmac aes\n", __func__);
436 
437 	memcpy(smb2_pdu->Signature, sigptr, SMB2_SIGNATURE_SIZE);
438 
439 	return rc;
440 }
441 
442 /* must be called with server->srv_mutex held */
443 static int
smb2_sign_rqst(struct smb_rqst * rqst,struct TCP_Server_Info * server)444 smb2_sign_rqst(struct smb_rqst *rqst, struct TCP_Server_Info *server)
445 {
446 	int rc = 0;
447 	struct smb2_hdr *smb2_pdu = rqst->rq_iov[0].iov_base;
448 
449 	if (!(smb2_pdu->Flags & SMB2_FLAGS_SIGNED) ||
450 	    server->tcpStatus == CifsNeedNegotiate)
451 		return rc;
452 
453 	if (!server->session_estab) {
454 		strncpy(smb2_pdu->Signature, "BSRSPYL", 8);
455 		return rc;
456 	}
457 
458 	rc = server->ops->calc_signature(rqst, server);
459 
460 	return rc;
461 }
462 
463 int
smb2_verify_signature(struct smb_rqst * rqst,struct TCP_Server_Info * server)464 smb2_verify_signature(struct smb_rqst *rqst, struct TCP_Server_Info *server)
465 {
466 	unsigned int rc;
467 	char server_response_sig[16];
468 	struct smb2_hdr *smb2_pdu = (struct smb2_hdr *)rqst->rq_iov[0].iov_base;
469 
470 	if ((smb2_pdu->Command == SMB2_NEGOTIATE) ||
471 	    (smb2_pdu->Command == SMB2_SESSION_SETUP) ||
472 	    (smb2_pdu->Command == SMB2_OPLOCK_BREAK) ||
473 	    (!server->session_estab))
474 		return 0;
475 
476 	/*
477 	 * BB what if signatures are supposed to be on for session but
478 	 * server does not send one? BB
479 	 */
480 
481 	/* Do not need to verify session setups with signature "BSRSPYL " */
482 	if (memcmp(smb2_pdu->Signature, "BSRSPYL ", 8) == 0)
483 		cifs_dbg(FYI, "dummy signature received for smb command 0x%x\n",
484 			 smb2_pdu->Command);
485 
486 	/*
487 	 * Save off the origiginal signature so we can modify the smb and check
488 	 * our calculated signature against what the server sent.
489 	 */
490 	memcpy(server_response_sig, smb2_pdu->Signature, SMB2_SIGNATURE_SIZE);
491 
492 	memset(smb2_pdu->Signature, 0, SMB2_SIGNATURE_SIZE);
493 
494 	mutex_lock(&server->srv_mutex);
495 	rc = server->ops->calc_signature(rqst, server);
496 	mutex_unlock(&server->srv_mutex);
497 
498 	if (rc)
499 		return rc;
500 
501 	if (memcmp(server_response_sig, smb2_pdu->Signature,
502 		   SMB2_SIGNATURE_SIZE))
503 		return -EACCES;
504 	else
505 		return 0;
506 }
507 
508 /*
509  * Set message id for the request. Should be called after wait_for_free_request
510  * and when srv_mutex is held.
511  */
512 static inline void
smb2_seq_num_into_buf(struct TCP_Server_Info * server,struct smb2_hdr * hdr)513 smb2_seq_num_into_buf(struct TCP_Server_Info *server, struct smb2_hdr *hdr)
514 {
515 	unsigned int i, num = le16_to_cpu(hdr->CreditCharge);
516 
517 	hdr->MessageId = get_next_mid64(server);
518 	/* skip message numbers according to CreditCharge field */
519 	for (i = 1; i < num; i++)
520 		get_next_mid(server);
521 }
522 
523 static struct mid_q_entry *
smb2_mid_entry_alloc(const struct smb2_hdr * smb_buffer,struct TCP_Server_Info * server)524 smb2_mid_entry_alloc(const struct smb2_hdr *smb_buffer,
525 		     struct TCP_Server_Info *server)
526 {
527 	struct mid_q_entry *temp;
528 
529 	if (server == NULL) {
530 		cifs_dbg(VFS, "Null TCP session in smb2_mid_entry_alloc\n");
531 		return NULL;
532 	}
533 
534 	temp = mempool_alloc(cifs_mid_poolp, GFP_NOFS);
535 	if (temp == NULL)
536 		return temp;
537 	else {
538 		memset(temp, 0, sizeof(struct mid_q_entry));
539 		temp->mid = le64_to_cpu(smb_buffer->MessageId);
540 		temp->pid = current->pid;
541 		temp->command = smb_buffer->Command;	/* Always LE */
542 		temp->when_alloc = jiffies;
543 		temp->server = server;
544 
545 		/*
546 		 * The default is for the mid to be synchronous, so the
547 		 * default callback just wakes up the current task.
548 		 */
549 		temp->callback = cifs_wake_up_task;
550 		temp->callback_data = current;
551 	}
552 
553 	atomic_inc(&midCount);
554 	temp->mid_state = MID_REQUEST_ALLOCATED;
555 	return temp;
556 }
557 
558 static int
smb2_get_mid_entry(struct cifs_ses * ses,struct smb2_hdr * buf,struct mid_q_entry ** mid)559 smb2_get_mid_entry(struct cifs_ses *ses, struct smb2_hdr *buf,
560 		   struct mid_q_entry **mid)
561 {
562 	if (ses->server->tcpStatus == CifsExiting)
563 		return -ENOENT;
564 
565 	if (ses->server->tcpStatus == CifsNeedReconnect) {
566 		cifs_dbg(FYI, "tcp session dead - return to caller to retry\n");
567 		return -EAGAIN;
568 	}
569 
570 	if (ses->status == CifsNew) {
571 		if ((buf->Command != SMB2_SESSION_SETUP) &&
572 		    (buf->Command != SMB2_NEGOTIATE))
573 			return -EAGAIN;
574 		/* else ok - we are setting up session */
575 	}
576 
577 	if (ses->status == CifsExiting) {
578 		if (buf->Command != SMB2_LOGOFF)
579 			return -EAGAIN;
580 		/* else ok - we are shutting down the session */
581 	}
582 
583 	*mid = smb2_mid_entry_alloc(buf, ses->server);
584 	if (*mid == NULL)
585 		return -ENOMEM;
586 	spin_lock(&GlobalMid_Lock);
587 	list_add_tail(&(*mid)->qhead, &ses->server->pending_mid_q);
588 	spin_unlock(&GlobalMid_Lock);
589 	return 0;
590 }
591 
592 int
smb2_check_receive(struct mid_q_entry * mid,struct TCP_Server_Info * server,bool log_error)593 smb2_check_receive(struct mid_q_entry *mid, struct TCP_Server_Info *server,
594 		   bool log_error)
595 {
596 	unsigned int len = get_rfc1002_length(mid->resp_buf);
597 	struct kvec iov;
598 	struct smb_rqst rqst = { .rq_iov = &iov,
599 				 .rq_nvec = 1 };
600 
601 	iov.iov_base = (char *)mid->resp_buf;
602 	iov.iov_len = get_rfc1002_length(mid->resp_buf) + 4;
603 
604 	dump_smb(mid->resp_buf, min_t(u32, 80, len));
605 	/* convert the length into a more usable form */
606 	if (len > 24 && server->sign) {
607 		int rc;
608 
609 		rc = smb2_verify_signature(&rqst, server);
610 		if (rc)
611 			cifs_dbg(VFS, "SMB signature verification returned error = %d\n",
612 				 rc);
613 	}
614 
615 	return map_smb2_to_linux_error(mid->resp_buf, log_error);
616 }
617 
618 struct mid_q_entry *
smb2_setup_request(struct cifs_ses * ses,struct smb_rqst * rqst)619 smb2_setup_request(struct cifs_ses *ses, struct smb_rqst *rqst)
620 {
621 	int rc;
622 	struct smb2_hdr *hdr = (struct smb2_hdr *)rqst->rq_iov[0].iov_base;
623 	struct mid_q_entry *mid;
624 
625 	smb2_seq_num_into_buf(ses->server, hdr);
626 
627 	rc = smb2_get_mid_entry(ses, hdr, &mid);
628 	if (rc)
629 		return ERR_PTR(rc);
630 	rc = smb2_sign_rqst(rqst, ses->server);
631 	if (rc) {
632 		cifs_delete_mid(mid);
633 		return ERR_PTR(rc);
634 	}
635 	return mid;
636 }
637 
638 struct mid_q_entry *
smb2_setup_async_request(struct TCP_Server_Info * server,struct smb_rqst * rqst)639 smb2_setup_async_request(struct TCP_Server_Info *server, struct smb_rqst *rqst)
640 {
641 	int rc;
642 	struct smb2_hdr *hdr = (struct smb2_hdr *)rqst->rq_iov[0].iov_base;
643 	struct mid_q_entry *mid;
644 
645 	smb2_seq_num_into_buf(server, hdr);
646 
647 	mid = smb2_mid_entry_alloc(hdr, server);
648 	if (mid == NULL)
649 		return ERR_PTR(-ENOMEM);
650 
651 	rc = smb2_sign_rqst(rqst, server);
652 	if (rc) {
653 		DeleteMidQEntry(mid);
654 		return ERR_PTR(rc);
655 	}
656 
657 	return mid;
658 }
659