Linux Audio

Check our new training course

Loading...
Note: File does not exist in v3.5.6.
  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
 43static int
 44smb2_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
 51static int
 52smb3_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;
 68err:
 69	cifs_free_hash(&p->hmacsha256, &p->sdeschmacsha256);
 70	return rc;
 71}
 72
 73int
 74smb311_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
 95err:
 96	cifs_free_hash(&p->cmacaes, &p->sdesccmacaes);
 97	cifs_free_hash(&p->hmacsha256, &p->sdeschmacsha256);
 98	return rc;
 99}
100
101static struct cifs_ses *
102smb2_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
115struct cifs_ses *
116smb2_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
127static struct cifs_tcon *
128smb2_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
147struct cifs_tcon *
148smb2_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
165int
166smb2_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
233static 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
310smb3signkey_ret:
311	return rc;
312}
313
314struct derivation {
315	struct kvec label;
316	struct kvec context;
317};
318
319struct derivation_triplet {
320	struct derivation signing;
321	struct derivation encryption;
322	struct derivation decryption;
323};
324
325static int
326generate_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
370int
371generate_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
398int
399generate_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
426int
427smb3_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 */
493static int
494smb2_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
514int
515smb2_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 */
564static inline void
565smb2_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
576static struct mid_q_entry *
577smb2_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	temp->callback = cifs_wake_up_task;
603	temp->callback_data = current;
604
605	atomic_inc(&midCount);
606	temp->mid_state = MID_REQUEST_ALLOCATED;
607	trace_smb3_cmd_enter(shdr->TreeId, shdr->SessionId,
608		le16_to_cpu(shdr->Command), temp->mid);
609	return temp;
610}
611
612static int
613smb2_get_mid_entry(struct cifs_ses *ses, struct smb2_sync_hdr *shdr,
614		   struct mid_q_entry **mid)
615{
616	if (ses->server->tcpStatus == CifsExiting)
617		return -ENOENT;
618
619	if (ses->server->tcpStatus == CifsNeedReconnect) {
620		cifs_dbg(FYI, "tcp session dead - return to caller to retry\n");
621		return -EAGAIN;
622	}
623
624	if (ses->server->tcpStatus == CifsNeedNegotiate &&
625	   shdr->Command != SMB2_NEGOTIATE)
626		return -EAGAIN;
627
628	if (ses->status == CifsNew) {
629		if ((shdr->Command != SMB2_SESSION_SETUP) &&
630		    (shdr->Command != SMB2_NEGOTIATE))
631			return -EAGAIN;
632		/* else ok - we are setting up session */
633	}
634
635	if (ses->status == CifsExiting) {
636		if (shdr->Command != SMB2_LOGOFF)
637			return -EAGAIN;
638		/* else ok - we are shutting down the session */
639	}
640
641	*mid = smb2_mid_entry_alloc(shdr, ses->server);
642	if (*mid == NULL)
643		return -ENOMEM;
644	spin_lock(&GlobalMid_Lock);
645	list_add_tail(&(*mid)->qhead, &ses->server->pending_mid_q);
646	spin_unlock(&GlobalMid_Lock);
647
648	return 0;
649}
650
651int
652smb2_check_receive(struct mid_q_entry *mid, struct TCP_Server_Info *server,
653		   bool log_error)
654{
655	unsigned int len = mid->resp_buf_size;
656	struct kvec iov[1];
657	struct smb_rqst rqst = { .rq_iov = iov,
658				 .rq_nvec = 1 };
659
660	iov[0].iov_base = (char *)mid->resp_buf;
661	iov[0].iov_len = len;
662
663	dump_smb(mid->resp_buf, min_t(u32, 80, len));
664	/* convert the length into a more usable form */
665	if (len > 24 && server->sign && !mid->decrypted) {
666		int rc;
667
668		rc = smb2_verify_signature(&rqst, server);
669		if (rc)
670			cifs_server_dbg(VFS, "SMB signature verification returned error = %d\n",
671				 rc);
672	}
673
674	return map_smb2_to_linux_error(mid->resp_buf, log_error);
675}
676
677struct mid_q_entry *
678smb2_setup_request(struct cifs_ses *ses, struct smb_rqst *rqst)
679{
680	int rc;
681	struct smb2_sync_hdr *shdr =
682			(struct smb2_sync_hdr *)rqst->rq_iov[0].iov_base;
683	struct mid_q_entry *mid;
684
685	smb2_seq_num_into_buf(ses->server, shdr);
686
687	rc = smb2_get_mid_entry(ses, shdr, &mid);
688	if (rc) {
689		revert_current_mid_from_hdr(ses->server, shdr);
690		return ERR_PTR(rc);
691	}
692
693	rc = smb2_sign_rqst(rqst, ses->server);
694	if (rc) {
695		revert_current_mid_from_hdr(ses->server, shdr);
696		cifs_delete_mid(mid);
697		return ERR_PTR(rc);
698	}
699
700	return mid;
701}
702
703struct mid_q_entry *
704smb2_setup_async_request(struct TCP_Server_Info *server, struct smb_rqst *rqst)
705{
706	int rc;
707	struct smb2_sync_hdr *shdr =
708			(struct smb2_sync_hdr *)rqst->rq_iov[0].iov_base;
709	struct mid_q_entry *mid;
710
711	if (server->tcpStatus == CifsNeedNegotiate &&
712	   shdr->Command != SMB2_NEGOTIATE)
713		return ERR_PTR(-EAGAIN);
714
715	smb2_seq_num_into_buf(server, shdr);
716
717	mid = smb2_mid_entry_alloc(shdr, server);
718	if (mid == NULL) {
719		revert_current_mid_from_hdr(server, shdr);
720		return ERR_PTR(-ENOMEM);
721	}
722
723	rc = smb2_sign_rqst(rqst, server);
724	if (rc) {
725		revert_current_mid_from_hdr(server, shdr);
726		DeleteMidQEntry(mid);
727		return ERR_PTR(rc);
728	}
729
730	return mid;
731}
732
733int
734smb3_crypto_aead_allocate(struct TCP_Server_Info *server)
735{
736	struct crypto_aead *tfm;
737
738	if (!server->secmech.ccmaesencrypt) {
739		if (server->cipher_type == SMB2_ENCRYPTION_AES128_GCM)
740			tfm = crypto_alloc_aead("gcm(aes)", 0, 0);
741		else
742			tfm = crypto_alloc_aead("ccm(aes)", 0, 0);
743		if (IS_ERR(tfm)) {
744			cifs_server_dbg(VFS, "%s: Failed to alloc encrypt aead\n",
745				 __func__);
746			return PTR_ERR(tfm);
747		}
748		server->secmech.ccmaesencrypt = tfm;
749	}
750
751	if (!server->secmech.ccmaesdecrypt) {
752		if (server->cipher_type == SMB2_ENCRYPTION_AES128_GCM)
753			tfm = crypto_alloc_aead("gcm(aes)", 0, 0);
754		else
755			tfm = crypto_alloc_aead("ccm(aes)", 0, 0);
756		if (IS_ERR(tfm)) {
757			crypto_free_aead(server->secmech.ccmaesencrypt);
758			server->secmech.ccmaesencrypt = NULL;
759			cifs_server_dbg(VFS, "%s: Failed to alloc decrypt aead\n",
760				 __func__);
761			return PTR_ERR(tfm);
762		}
763		server->secmech.ccmaesdecrypt = tfm;
764	}
765
766	return 0;
767}