cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

smb2transport.c (23418B)


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