File Index
Files and directories
Sign in
FILE

smb2transport.c

File preview with syntax highlighting.

linux-6.19.14/fs/smb/client/smb2transport.c C
  1// SPDX-License-Identifier: LGPL-2.1
  2/*
  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 */
 11
 12#include <linux/fs.h>
 13#include <linux/list.h>
 14#include <linux/wait.h>
 15#include <linux/net.h>
 16#include <linux/delay.h>
 17#include <linux/uaccess.h>
 18#include <asm/processor.h>
 19#include <linux/mempool.h>
 20#include <linux/highmem.h>
 21#include <crypto/aead.h>
 22#include <crypto/sha2.h>
 23#include "cifsglob.h"
 24#include "cifsproto.h"
 25#include "smb2proto.h"
 26#include "cifs_debug.h"
 27#include "../common/smb2status.h"
 28#include "smb2glob.h"
 29
 30int
 31smb3_crypto_shash_allocate(struct TCP_Server_Info *server)
 32{
 33	struct cifs_secmech *p = &server->secmech;
 34
 35	return cifs_alloc_hash("cmac(aes)", &p->aes_cmac);
 36}
 37
 38static
 39int smb3_get_sign_key(__u64 ses_id, struct TCP_Server_Info *server, u8 *key)
 40{
 41	struct cifs_chan *chan;
 42	struct TCP_Server_Info *pserver;
 43	struct cifs_ses *ses = NULL;
 44	int i;
 45	int rc = 0;
 46	bool is_binding = false;
 47
 48	spin_lock(&cifs_tcp_ses_lock);
 49
 50	/* If server is a channel, select the primary channel */
 51	pserver = SERVER_IS_CHAN(server) ? server->primary_server : server;
 52
 53	list_for_each_entry(ses, &pserver->smb_ses_list, smb_ses_list) {
 54		if (ses->Suid == ses_id)
 55			goto found;
 56	}
 57	trace_smb3_ses_not_found(ses_id);
 58	cifs_server_dbg(FYI, "%s: Could not find session 0x%llx\n",
 59			__func__, ses_id);
 60	rc = -ENOENT;
 61	goto out;
 62
 63found:
 64	spin_lock(&ses->ses_lock);
 65	spin_lock(&ses->chan_lock);
 66
 67	is_binding = (cifs_chan_needs_reconnect(ses, server) &&
 68		      ses->ses_status == SES_GOOD);
 69	if (is_binding) {
 70		/*
 71		 * If we are in the process of binding a new channel
 72		 * to an existing session, use the master connection
 73		 * session key
 74		 */
 75		memcpy(key, ses->smb3signingkey, SMB3_SIGN_KEY_SIZE);
 76		spin_unlock(&ses->chan_lock);
 77		spin_unlock(&ses->ses_lock);
 78		goto out;
 79	}
 80
 81	/*
 82	 * Otherwise, use the channel key.
 83	 */
 84
 85	for (i = 0; i < ses->chan_count; i++) {
 86		chan = ses->chans + i;
 87		if (chan->server == server) {
 88			memcpy(key, chan->signkey, SMB3_SIGN_KEY_SIZE);
 89			spin_unlock(&ses->chan_lock);
 90			spin_unlock(&ses->ses_lock);
 91			goto out;
 92		}
 93	}
 94	spin_unlock(&ses->chan_lock);
 95	spin_unlock(&ses->ses_lock);
 96
 97	cifs_dbg(VFS,
 98		 "%s: Could not find channel signing key for session 0x%llx\n",
 99		 __func__, ses_id);
100	rc = -ENOENT;
101
102out:
103	spin_unlock(&cifs_tcp_ses_lock);
104	return rc;
105}
106
107static struct cifs_ses *
108smb2_find_smb_ses_unlocked(struct TCP_Server_Info *server, __u64 ses_id)
109{
110	struct TCP_Server_Info *pserver;
111	struct cifs_ses *ses;
112
113	/* If server is a channel, select the primary channel */
114	pserver = SERVER_IS_CHAN(server) ? server->primary_server : server;
115
116	list_for_each_entry(ses, &pserver->smb_ses_list, smb_ses_list) {
117		if (ses->Suid != ses_id)
118			continue;
119
120		spin_lock(&ses->ses_lock);
121		if (ses->ses_status == SES_EXITING) {
122			spin_unlock(&ses->ses_lock);
123			continue;
124		}
125		cifs_smb_ses_inc_refcount(ses);
126		spin_unlock(&ses->ses_lock);
127		return ses;
128	}
129
130	return NULL;
131}
132
133static int smb2_get_sign_key(struct TCP_Server_Info *server,
134			     __u64 ses_id, u8 *key)
135{
136	struct cifs_ses *ses;
137	int rc = -ENOENT;
138
139	if (SERVER_IS_CHAN(server))
140		server = server->primary_server;
141
142	spin_lock(&cifs_tcp_ses_lock);
143	list_for_each_entry(ses, &server->smb_ses_list, smb_ses_list) {
144		if (ses->Suid != ses_id)
145			continue;
146
147		rc = 0;
148		spin_lock(&ses->ses_lock);
149		switch (ses->ses_status) {
150		case SES_EXITING: /* SMB2_LOGOFF */
151		case SES_GOOD:
152			if (likely(ses->auth_key.response)) {
153				memcpy(key, ses->auth_key.response,
154				       SMB2_NTLMV2_SESSKEY_SIZE);
155			} else {
156				rc = smb_EIO(smb_eio_trace_no_auth_key);
157			}
158			break;
159		default:
160			rc = -EAGAIN;
161			break;
162		}
163		spin_unlock(&ses->ses_lock);
164		break;
165	}
166	spin_unlock(&cifs_tcp_ses_lock);
167	return rc;
168}
169
170static struct cifs_tcon *
171smb2_find_smb_sess_tcon_unlocked(struct cifs_ses *ses, __u32  tid)
172{
173	struct cifs_tcon *tcon;
174
175	list_for_each_entry(tcon, &ses->tcon_list, tcon_list) {
176		if (tcon->tid != tid)
177			continue;
178		++tcon->tc_count;
179		trace_smb3_tcon_ref(tcon->debug_id, tcon->tc_count,
180				    netfs_trace_tcon_ref_get_find_sess_tcon);
181		return tcon;
182	}
183
184	return NULL;
185}
186
187/*
188 * Obtain tcon corresponding to the tid in the given
189 * cifs_ses
190 */
191
192struct cifs_tcon *
193smb2_find_smb_tcon(struct TCP_Server_Info *server, __u64 ses_id, __u32  tid)
194{
195	struct cifs_ses *ses;
196	struct cifs_tcon *tcon;
197
198	spin_lock(&cifs_tcp_ses_lock);
199	ses = smb2_find_smb_ses_unlocked(server, ses_id);
200	if (!ses) {
201		spin_unlock(&cifs_tcp_ses_lock);
202		return NULL;
203	}
204	tcon = smb2_find_smb_sess_tcon_unlocked(ses, tid);
205	spin_unlock(&cifs_tcp_ses_lock);
206	/* tcon already has a ref to ses, so we don't need ses anymore */
207	cifs_put_smb_ses(ses);
208
209	return tcon;
210}
211
212static int
213smb2_calc_signature(struct smb_rqst *rqst, struct TCP_Server_Info *server,
214		    bool allocate_crypto)
215{
216	int rc;
217	unsigned char smb2_signature[SMB2_HMACSHA256_SIZE];
218	struct kvec *iov = rqst->rq_iov;
219	struct smb2_hdr *shdr = (struct smb2_hdr *)iov[0].iov_base;
220	struct hmac_sha256_ctx hmac_ctx;
221	struct smb_rqst drqst;
222	__u64 sid = le64_to_cpu(shdr->SessionId);
223	u8 key[SMB2_NTLMV2_SESSKEY_SIZE];
224
225	rc = smb2_get_sign_key(server, sid, key);
226	if (unlikely(rc)) {
227		cifs_server_dbg(FYI, "%s: [sesid=0x%llx] couldn't find signing key: %d\n",
228				__func__, sid, rc);
229		return rc;
230	}
231
232	memset(smb2_signature, 0x0, SMB2_HMACSHA256_SIZE);
233	memset(shdr->Signature, 0x0, SMB2_SIGNATURE_SIZE);
234
235	hmac_sha256_init_usingrawkey(&hmac_ctx, key, sizeof(key));
236
237	/*
238	 * For SMB2+, __cifs_calc_signature() expects to sign only the actual
239	 * data, that is, iov[0] should not contain a rfc1002 length.
240	 *
241	 * Sign the rfc1002 length prior to passing the data (iov[1-N]) down to
242	 * __cifs_calc_signature().
243	 */
244	drqst = *rqst;
245	if (drqst.rq_nvec >= 2 && iov[0].iov_len == 4) {
246		hmac_sha256_update(&hmac_ctx, iov[0].iov_base, iov[0].iov_len);
247		drqst.rq_iov++;
248		drqst.rq_nvec--;
249	}
250
251	rc = __cifs_calc_signature(
252		&drqst, server, smb2_signature,
253		&(struct cifs_calc_sig_ctx){ .hmac = &hmac_ctx });
254	if (!rc)
255		memcpy(shdr->Signature, smb2_signature, SMB2_SIGNATURE_SIZE);
256
257	return rc;
258}
259
260static int generate_key(struct cifs_ses *ses, struct kvec label,
261			struct kvec context, __u8 *key, unsigned int key_size)
262{
263	unsigned char zero = 0x0;
264	__u8 i[4] = {0, 0, 0, 1};
265	__u8 L128[4] = {0, 0, 0, 128};
266	__u8 L256[4] = {0, 0, 1, 0};
267	int rc = 0;
268	unsigned char prfhash[SMB2_HMACSHA256_SIZE];
269	struct TCP_Server_Info *server = ses->server;
270	struct hmac_sha256_ctx hmac_ctx;
271
272	memset(prfhash, 0x0, SMB2_HMACSHA256_SIZE);
273	memset(key, 0x0, key_size);
274
275	rc = smb3_crypto_shash_allocate(server);
276	if (rc) {
277		cifs_server_dbg(VFS, "%s: crypto alloc failed\n", __func__);
278		return rc;
279	}
280
281	hmac_sha256_init_usingrawkey(&hmac_ctx, ses->auth_key.response,
282				     SMB2_NTLMV2_SESSKEY_SIZE);
283	hmac_sha256_update(&hmac_ctx, i, 4);
284	hmac_sha256_update(&hmac_ctx, label.iov_base, label.iov_len);
285	hmac_sha256_update(&hmac_ctx, &zero, 1);
286	hmac_sha256_update(&hmac_ctx, context.iov_base, context.iov_len);
287
288	if ((server->cipher_type == SMB2_ENCRYPTION_AES256_CCM) ||
289		(server->cipher_type == SMB2_ENCRYPTION_AES256_GCM)) {
290		hmac_sha256_update(&hmac_ctx, L256, 4);
291	} else {
292		hmac_sha256_update(&hmac_ctx, L128, 4);
293	}
294	hmac_sha256_final(&hmac_ctx, prfhash);
295
296	memcpy(key, prfhash, key_size);
297	return 0;
298}
299
300struct derivation {
301	struct kvec label;
302	struct kvec context;
303};
304
305struct derivation_triplet {
306	struct derivation signing;
307	struct derivation encryption;
308	struct derivation decryption;
309};
310
311static int
312generate_smb3signingkey(struct cifs_ses *ses,
313			struct TCP_Server_Info *server,
314			const struct derivation_triplet *ptriplet)
315{
316	int rc;
317	bool is_binding = false;
318	int chan_index = 0;
319
320	spin_lock(&ses->ses_lock);
321	spin_lock(&ses->chan_lock);
322	is_binding = (cifs_chan_needs_reconnect(ses, server) &&
323		      ses->ses_status == SES_GOOD);
324
325	chan_index = cifs_ses_get_chan_index(ses, server);
326	if (chan_index == CIFS_INVAL_CHAN_INDEX) {
327		spin_unlock(&ses->chan_lock);
328		spin_unlock(&ses->ses_lock);
329
330		return -EINVAL;
331	}
332
333	spin_unlock(&ses->chan_lock);
334	spin_unlock(&ses->ses_lock);
335
336	/*
337	 * All channels use the same encryption/decryption keys but
338	 * they have their own signing key.
339	 *
340	 * When we generate the keys, check if it is for a new channel
341	 * (binding) in which case we only need to generate a signing
342	 * key and store it in the channel as to not overwrite the
343	 * master connection signing key stored in the session
344	 */
345
346	if (is_binding) {
347		rc = generate_key(ses, ptriplet->signing.label,
348				  ptriplet->signing.context,
349				  ses->chans[chan_index].signkey,
350				  SMB3_SIGN_KEY_SIZE);
351		if (rc)
352			return rc;
353	} else {
354		rc = generate_key(ses, ptriplet->signing.label,
355				  ptriplet->signing.context,
356				  ses->smb3signingkey,
357				  SMB3_SIGN_KEY_SIZE);
358		if (rc)
359			return rc;
360
361		/* safe to access primary channel, since it will never go away */
362		spin_lock(&ses->chan_lock);
363		memcpy(ses->chans[chan_index].signkey, ses->smb3signingkey,
364		       SMB3_SIGN_KEY_SIZE);
365		spin_unlock(&ses->chan_lock);
366
367		rc = generate_key(ses, ptriplet->encryption.label,
368				  ptriplet->encryption.context,
369				  ses->smb3encryptionkey,
370				  SMB3_ENC_DEC_KEY_SIZE);
371		if (rc)
372			return rc;
373		rc = generate_key(ses, ptriplet->decryption.label,
374				  ptriplet->decryption.context,
375				  ses->smb3decryptionkey,
376				  SMB3_ENC_DEC_KEY_SIZE);
377		if (rc)
378			return rc;
379	}
380
381#ifdef CONFIG_CIFS_DEBUG_DUMP_KEYS
382	cifs_dbg(VFS, "%s: dumping generated AES session keys\n", __func__);
383	/*
384	 * The session id is opaque in terms of endianness, so we can't
385	 * print it as a long long. we dump it as we got it on the wire
386	 */
387	cifs_dbg(VFS, "Session Id    %*ph\n", (int)sizeof(ses->Suid),
388			&ses->Suid);
389	cifs_dbg(VFS, "Cipher type   %d\n", server->cipher_type);
390	cifs_dbg(VFS, "Session Key   %*ph\n",
391		 SMB2_NTLMV2_SESSKEY_SIZE, ses->auth_key.response);
392	cifs_dbg(VFS, "Signing Key   %*ph\n",
393		 SMB3_SIGN_KEY_SIZE, ses->smb3signingkey);
394	if ((server->cipher_type == SMB2_ENCRYPTION_AES256_CCM) ||
395		(server->cipher_type == SMB2_ENCRYPTION_AES256_GCM)) {
396		cifs_dbg(VFS, "ServerIn Key  %*ph\n",
397				SMB3_GCM256_CRYPTKEY_SIZE, ses->smb3encryptionkey);
398		cifs_dbg(VFS, "ServerOut Key %*ph\n",
399				SMB3_GCM256_CRYPTKEY_SIZE, ses->smb3decryptionkey);
400	} else {
401		cifs_dbg(VFS, "ServerIn Key  %*ph\n",
402				SMB3_GCM128_CRYPTKEY_SIZE, ses->smb3encryptionkey);
403		cifs_dbg(VFS, "ServerOut Key %*ph\n",
404				SMB3_GCM128_CRYPTKEY_SIZE, ses->smb3decryptionkey);
405	}
406#endif
407	return rc;
408}
409
410int
411generate_smb30signingkey(struct cifs_ses *ses,
412			 struct TCP_Server_Info *server)
413
414{
415	struct derivation_triplet triplet;
416	struct derivation *d;
417
418	d = &triplet.signing;
419	d->label.iov_base = "SMB2AESCMAC";
420	d->label.iov_len = 12;
421	d->context.iov_base = "SmbSign";
422	d->context.iov_len = 8;
423
424	d = &triplet.encryption;
425	d->label.iov_base = "SMB2AESCCM";
426	d->label.iov_len = 11;
427	d->context.iov_base = "ServerIn ";
428	d->context.iov_len = 10;
429
430	d = &triplet.decryption;
431	d->label.iov_base = "SMB2AESCCM";
432	d->label.iov_len = 11;
433	d->context.iov_base = "ServerOut";
434	d->context.iov_len = 10;
435
436	return generate_smb3signingkey(ses, server, &triplet);
437}
438
439int
440generate_smb311signingkey(struct cifs_ses *ses,
441			  struct TCP_Server_Info *server)
442
443{
444	struct derivation_triplet triplet;
445	struct derivation *d;
446
447	d = &triplet.signing;
448	d->label.iov_base = "SMBSigningKey";
449	d->label.iov_len = 14;
450	d->context.iov_base = ses->preauth_sha_hash;
451	d->context.iov_len = 64;
452
453	d = &triplet.encryption;
454	d->label.iov_base = "SMBC2SCipherKey";
455	d->label.iov_len = 16;
456	d->context.iov_base = ses->preauth_sha_hash;
457	d->context.iov_len = 64;
458
459	d = &triplet.decryption;
460	d->label.iov_base = "SMBS2CCipherKey";
461	d->label.iov_len = 16;
462	d->context.iov_base = ses->preauth_sha_hash;
463	d->context.iov_len = 64;
464
465	return generate_smb3signingkey(ses, server, &triplet);
466}
467
468static int
469smb3_calc_signature(struct smb_rqst *rqst, struct TCP_Server_Info *server,
470		    bool allocate_crypto)
471{
472	int rc;
473	unsigned char smb3_signature[SMB2_CMACAES_SIZE];
474	struct kvec *iov = rqst->rq_iov;
475	struct smb2_hdr *shdr = (struct smb2_hdr *)iov[0].iov_base;
476	struct shash_desc *shash = NULL;
477	struct smb_rqst drqst;
478	u8 key[SMB3_SIGN_KEY_SIZE];
479
480	if (server->vals->protocol_id <= SMB21_PROT_ID)
481		return smb2_calc_signature(rqst, server, allocate_crypto);
482
483	rc = smb3_get_sign_key(le64_to_cpu(shdr->SessionId), server, key);
484	if (unlikely(rc)) {
485		cifs_server_dbg(FYI, "%s: Could not get signing key\n", __func__);
486		return rc;
487	}
488
489	if (allocate_crypto) {
490		rc = cifs_alloc_hash("cmac(aes)", &shash);
491		if (rc)
492			return rc;
493	} else {
494		shash = server->secmech.aes_cmac;
495	}
496
497	memset(smb3_signature, 0x0, SMB2_CMACAES_SIZE);
498	memset(shdr->Signature, 0x0, SMB2_SIGNATURE_SIZE);
499
500	rc = crypto_shash_setkey(shash->tfm, key, SMB2_CMACAES_SIZE);
501	if (rc) {
502		cifs_server_dbg(VFS, "%s: Could not set key for cmac aes\n", __func__);
503		goto out;
504	}
505
506	/*
507	 * we already allocate aes_cmac when we init smb3 signing key,
508	 * so unlike smb2 case we do not have to check here if secmech are
509	 * initialized
510	 */
511	rc = crypto_shash_init(shash);
512	if (rc) {
513		cifs_server_dbg(VFS, "%s: Could not init cmac aes\n", __func__);
514		goto out;
515	}
516
517	/*
518	 * For SMB2+, __cifs_calc_signature() expects to sign only the actual
519	 * data, that is, iov[0] should not contain a rfc1002 length.
520	 *
521	 * Sign the rfc1002 length prior to passing the data (iov[1-N]) down to
522	 * __cifs_calc_signature().
523	 */
524	drqst = *rqst;
525	if (drqst.rq_nvec >= 2 && iov[0].iov_len == 4) {
526		rc = crypto_shash_update(shash, iov[0].iov_base,
527					 iov[0].iov_len);
528		if (rc) {
529			cifs_server_dbg(VFS, "%s: Could not update with payload\n",
530				 __func__);
531			goto out;
532		}
533		drqst.rq_iov++;
534		drqst.rq_nvec--;
535	}
536
537	rc = __cifs_calc_signature(
538		&drqst, server, smb3_signature,
539		&(struct cifs_calc_sig_ctx){ .shash = shash });
540	if (!rc)
541		memcpy(shdr->Signature, smb3_signature, SMB2_SIGNATURE_SIZE);
542
543out:
544	if (allocate_crypto)
545		cifs_free_hash(&shash);
546	return rc;
547}
548
549/* must be called with server->srv_mutex held */
550static int
551smb2_sign_rqst(struct smb_rqst *rqst, struct TCP_Server_Info *server)
552{
553	struct smb2_hdr *shdr;
554	struct smb2_sess_setup_req *ssr;
555	bool is_binding;
556	bool is_signed;
557
558	shdr = (struct smb2_hdr *)rqst->rq_iov[0].iov_base;
559	ssr = (struct smb2_sess_setup_req *)shdr;
560
561	is_binding = shdr->Command == SMB2_SESSION_SETUP &&
562		(ssr->Flags & SMB2_SESSION_REQ_FLAG_BINDING);
563	is_signed = shdr->Flags & SMB2_FLAGS_SIGNED;
564
565	if (!is_signed)
566		return 0;
567	spin_lock(&server->srv_lock);
568	if (server->ops->need_neg &&
569	    server->ops->need_neg(server)) {
570		spin_unlock(&server->srv_lock);
571		return 0;
572	}
573	spin_unlock(&server->srv_lock);
574	if (!is_binding && !server->session_estab) {
575		strscpy(shdr->Signature, "BSRSPYL");
576		return 0;
577	}
578
579	return smb3_calc_signature(rqst, server, false);
580}
581
582int
583smb2_verify_signature(struct smb_rqst *rqst, struct TCP_Server_Info *server)
584{
585	unsigned int rc;
586	char server_response_sig[SMB2_SIGNATURE_SIZE];
587	struct smb2_hdr *shdr =
588			(struct smb2_hdr *)rqst->rq_iov[0].iov_base;
589
590	if ((shdr->Command == SMB2_NEGOTIATE) ||
591	    (shdr->Command == SMB2_SESSION_SETUP) ||
592	    (shdr->Command == SMB2_OPLOCK_BREAK) ||
593	    server->ignore_signature ||
594	    (!server->session_estab))
595		return 0;
596
597	/*
598	 * BB what if signatures are supposed to be on for session but
599	 * server does not send one? BB
600	 */
601
602	/* Do not need to verify session setups with signature "BSRSPYL " */
603	if (memcmp(shdr->Signature, "BSRSPYL ", 8) == 0)
604		cifs_dbg(FYI, "dummy signature received for smb command 0x%x\n",
605			 shdr->Command);
606
607	/*
608	 * Save off the original signature so we can modify the smb and check
609	 * our calculated signature against what the server sent.
610	 */
611	memcpy(server_response_sig, shdr->Signature, SMB2_SIGNATURE_SIZE);
612
613	memset(shdr->Signature, 0, SMB2_SIGNATURE_SIZE);
614
615	rc = smb3_calc_signature(rqst, server, true);
616
617	if (rc)
618		return rc;
619
620	if (memcmp(server_response_sig, shdr->Signature, SMB2_SIGNATURE_SIZE)) {
621		cifs_dbg(VFS, "sign fail cmd 0x%x message id 0x%llx\n",
622			shdr->Command, shdr->MessageId);
623		return -EACCES;
624	} else
625		return 0;
626}
627
628/*
629 * Set message id for the request. Should be called after wait_for_free_request
630 * and when srv_mutex is held.
631 */
632static inline void
633smb2_seq_num_into_buf(struct TCP_Server_Info *server,
634		      struct smb2_hdr *shdr)
635{
636	unsigned int i, num = le16_to_cpu(shdr->CreditCharge);
637
638	shdr->MessageId = get_next_mid64(server);
639	/* skip message numbers according to CreditCharge field */
640	for (i = 1; i < num; i++)
641		get_next_mid(server);
642}
643
644static struct mid_q_entry *
645smb2_mid_entry_alloc(const struct smb2_hdr *shdr,
646		     struct TCP_Server_Info *server)
647{
648	struct mid_q_entry *temp;
649	unsigned int credits = le16_to_cpu(shdr->CreditCharge);
650
651	if (server == NULL) {
652		cifs_dbg(VFS, "Null TCP session in smb2_mid_entry_alloc\n");
653		return NULL;
654	}
655
656	temp = mempool_alloc(&cifs_mid_pool, GFP_NOFS);
657	memset(temp, 0, sizeof(struct mid_q_entry));
658	refcount_set(&temp->refcount, 1);
659	spin_lock_init(&temp->mid_lock);
660	temp->mid = le64_to_cpu(shdr->MessageId);
661	temp->credits = credits > 0 ? credits : 1;
662	temp->pid = current->pid;
663	temp->command = shdr->Command; /* Always LE */
664	temp->when_alloc = jiffies;
665
666	/*
667	 * The default is for the mid to be synchronous, so the
668	 * default callback just wakes up the current task.
669	 */
670	get_task_struct(current);
671	temp->creator = current;
672	temp->callback = cifs_wake_up_task;
673	temp->callback_data = current;
674
675	atomic_inc(&mid_count);
676	temp->mid_state = MID_REQUEST_ALLOCATED;
677	trace_smb3_cmd_enter(le32_to_cpu(shdr->Id.SyncId.TreeId),
678			     le64_to_cpu(shdr->SessionId),
679			     le16_to_cpu(shdr->Command), temp->mid);
680	return temp;
681}
682
683static int
684smb2_get_mid_entry(struct cifs_ses *ses, struct TCP_Server_Info *server,
685		   struct smb2_hdr *shdr, struct mid_q_entry **mid)
686{
687	switch (READ_ONCE(server->tcpStatus)) {
688	case CifsExiting:
689		return -ENOENT;
690	case CifsNeedReconnect:
691		cifs_dbg(FYI, "tcp session dead - return to caller to retry\n");
692		return -EAGAIN;
693	case CifsNeedNegotiate:
694		if (shdr->Command != SMB2_NEGOTIATE)
695			return -EAGAIN;
696		break;
697	default:
698		break;
699	}
700
701	switch (READ_ONCE(ses->ses_status)) {
702	case SES_NEW:
703		if (shdr->Command != SMB2_SESSION_SETUP &&
704		    shdr->Command != SMB2_NEGOTIATE)
705			return -EAGAIN;
706			/* else ok - we are setting up session */
707		break;
708	case SES_EXITING:
709		if (shdr->Command != SMB2_LOGOFF)
710			return -EAGAIN;
711		/* else ok - we are shutting down the session */
712		break;
713	default:
714		break;
715	}
716
717	*mid = smb2_mid_entry_alloc(shdr, server);
718	if (*mid == NULL)
719		return -ENOMEM;
720	spin_lock(&server->mid_queue_lock);
721	list_add_tail(&(*mid)->qhead, &server->pending_mid_q);
722	spin_unlock(&server->mid_queue_lock);
723
724	return 0;
725}
726
727int
728smb2_check_receive(struct mid_q_entry *mid, struct TCP_Server_Info *server,
729		   bool log_error)
730{
731	unsigned int len = mid->resp_buf_size;
732	struct kvec iov[1];
733	struct smb_rqst rqst = { .rq_iov = iov,
734				 .rq_nvec = 1 };
735
736	iov[0].iov_base = (char *)mid->resp_buf;
737	iov[0].iov_len = len;
738
739	dump_smb(mid->resp_buf, min_t(u32, 80, len));
740	/* convert the length into a more usable form */
741	if (len > 24 && server->sign && !mid->decrypted) {
742		int rc;
743
744		rc = smb2_verify_signature(&rqst, server);
745		if (rc)
746			cifs_server_dbg(VFS, "SMB signature verification returned error = %d\n",
747				 rc);
748	}
749
750	return map_smb2_to_linux_error(mid->resp_buf, log_error);
751}
752
753struct mid_q_entry *
754smb2_setup_request(struct cifs_ses *ses, struct TCP_Server_Info *server,
755		   struct smb_rqst *rqst)
756{
757	int rc;
758	struct smb2_hdr *shdr =
759			(struct smb2_hdr *)rqst->rq_iov[0].iov_base;
760	struct mid_q_entry *mid;
761
762	smb2_seq_num_into_buf(server, shdr);
763
764	rc = smb2_get_mid_entry(ses, server, shdr, &mid);
765	if (rc) {
766		revert_current_mid_from_hdr(server, shdr);
767		return ERR_PTR(rc);
768	}
769
770	rc = smb2_sign_rqst(rqst, server);
771	if (rc) {
772		revert_current_mid_from_hdr(server, shdr);
773		delete_mid(server, mid);
774		return ERR_PTR(rc);
775	}
776
777	return mid;
778}
779
780struct mid_q_entry *
781smb2_setup_async_request(struct TCP_Server_Info *server, struct smb_rqst *rqst)
782{
783	int rc;
784	struct smb2_hdr *shdr =
785			(struct smb2_hdr *)rqst->rq_iov[0].iov_base;
786	struct mid_q_entry *mid;
787
788	spin_lock(&server->srv_lock);
789	if (server->tcpStatus == CifsNeedNegotiate &&
790	   shdr->Command != SMB2_NEGOTIATE) {
791		spin_unlock(&server->srv_lock);
792		return ERR_PTR(-EAGAIN);
793	}
794	spin_unlock(&server->srv_lock);
795
796	smb2_seq_num_into_buf(server, shdr);
797
798	mid = smb2_mid_entry_alloc(shdr, server);
799	if (mid == NULL) {
800		revert_current_mid_from_hdr(server, shdr);
801		return ERR_PTR(-ENOMEM);
802	}
803
804	rc = smb2_sign_rqst(rqst, server);
805	if (rc) {
806		revert_current_mid_from_hdr(server, shdr);
807		release_mid(server, mid);
808		return ERR_PTR(rc);
809	}
810
811	return mid;
812}
813
814int
815smb3_crypto_aead_allocate(struct TCP_Server_Info *server)
816{
817	struct crypto_aead *tfm;
818
819	if (!server->secmech.enc) {
820		if ((server->cipher_type == SMB2_ENCRYPTION_AES128_GCM) ||
821		    (server->cipher_type == SMB2_ENCRYPTION_AES256_GCM))
822			tfm = crypto_alloc_aead("gcm(aes)", 0, 0);
823		else
824			tfm = crypto_alloc_aead("ccm(aes)", 0, 0);
825		if (IS_ERR(tfm)) {
826			cifs_server_dbg(VFS, "%s: Failed alloc encrypt aead\n",
827				 __func__);
828			return PTR_ERR(tfm);
829		}
830		server->secmech.enc = tfm;
831	}
832
833	if (!server->secmech.dec) {
834		if ((server->cipher_type == SMB2_ENCRYPTION_AES128_GCM) ||
835		    (server->cipher_type == SMB2_ENCRYPTION_AES256_GCM))
836			tfm = crypto_alloc_aead("gcm(aes)", 0, 0);
837		else
838			tfm = crypto_alloc_aead("ccm(aes)", 0, 0);
839		if (IS_ERR(tfm)) {
840			crypto_free_aead(server->secmech.enc);
841			server->secmech.enc = NULL;
842			cifs_server_dbg(VFS, "%s: Failed to alloc decrypt aead\n",
843				 __func__);
844			return PTR_ERR(tfm);
845		}
846		server->secmech.dec = tfm;
847	}
848
849	return 0;
850}
~/ Read-only file preview.