Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: LGPL-2.1
0002 /*
0003  *
0004  *   Copyright (C) International Business Machines  Corp., 2002, 2011
0005  *                 Etersoft, 2012
0006  *   Author(s): Steve French (sfrench@us.ibm.com)
0007  *              Jeremy Allison (jra@samba.org) 2006
0008  *              Pavel Shilovsky (pshilovsky@samba.org) 2012
0009  *
0010  */
0011 
0012 #include <linux/fs.h>
0013 #include <linux/list.h>
0014 #include <linux/wait.h>
0015 #include <linux/net.h>
0016 #include <linux/delay.h>
0017 #include <linux/uaccess.h>
0018 #include <asm/processor.h>
0019 #include <linux/mempool.h>
0020 #include <linux/highmem.h>
0021 #include <crypto/aead.h>
0022 #include "cifsglob.h"
0023 #include "cifsproto.h"
0024 #include "smb2proto.h"
0025 #include "cifs_debug.h"
0026 #include "smb2status.h"
0027 #include "smb2glob.h"
0028 
0029 static int
0030 smb3_crypto_shash_allocate(struct TCP_Server_Info *server)
0031 {
0032     struct cifs_secmech *p = &server->secmech;
0033     int rc;
0034 
0035     rc = cifs_alloc_hash("hmac(sha256)",
0036                  &p->hmacsha256,
0037                  &p->sdeschmacsha256);
0038     if (rc)
0039         goto err;
0040 
0041     rc = cifs_alloc_hash("cmac(aes)", &p->cmacaes, &p->sdesccmacaes);
0042     if (rc)
0043         goto err;
0044 
0045     return 0;
0046 err:
0047     cifs_free_hash(&p->hmacsha256, &p->sdeschmacsha256);
0048     return rc;
0049 }
0050 
0051 int
0052 smb311_crypto_shash_allocate(struct TCP_Server_Info *server)
0053 {
0054     struct cifs_secmech *p = &server->secmech;
0055     int rc = 0;
0056 
0057     rc = cifs_alloc_hash("hmac(sha256)",
0058                  &p->hmacsha256,
0059                  &p->sdeschmacsha256);
0060     if (rc)
0061         return rc;
0062 
0063     rc = cifs_alloc_hash("cmac(aes)", &p->cmacaes, &p->sdesccmacaes);
0064     if (rc)
0065         goto err;
0066 
0067     rc = cifs_alloc_hash("sha512", &p->sha512, &p->sdescsha512);
0068     if (rc)
0069         goto err;
0070 
0071     return 0;
0072 
0073 err:
0074     cifs_free_hash(&p->cmacaes, &p->sdesccmacaes);
0075     cifs_free_hash(&p->hmacsha256, &p->sdeschmacsha256);
0076     return rc;
0077 }
0078 
0079 
0080 static
0081 int smb2_get_sign_key(__u64 ses_id, struct TCP_Server_Info *server, u8 *key)
0082 {
0083     struct cifs_chan *chan;
0084     struct cifs_ses *ses = NULL;
0085     struct TCP_Server_Info *it = NULL;
0086     int i;
0087     int rc = 0;
0088 
0089     spin_lock(&cifs_tcp_ses_lock);
0090 
0091     list_for_each_entry(it, &cifs_tcp_ses_list, tcp_ses_list) {
0092         list_for_each_entry(ses, &it->smb_ses_list, smb_ses_list) {
0093             if (ses->Suid == ses_id)
0094                 goto found;
0095         }
0096     }
0097     cifs_server_dbg(VFS, "%s: Could not find session 0x%llx\n",
0098             __func__, ses_id);
0099     rc = -ENOENT;
0100     goto out;
0101 
0102 found:
0103     spin_lock(&ses->chan_lock);
0104     if (cifs_chan_needs_reconnect(ses, server) &&
0105         !CIFS_ALL_CHANS_NEED_RECONNECT(ses)) {
0106         /*
0107          * If we are in the process of binding a new channel
0108          * to an existing session, use the master connection
0109          * session key
0110          */
0111         memcpy(key, ses->smb3signingkey, SMB3_SIGN_KEY_SIZE);
0112         spin_unlock(&ses->chan_lock);
0113         goto out;
0114     }
0115 
0116     /*
0117      * Otherwise, use the channel key.
0118      */
0119 
0120     for (i = 0; i < ses->chan_count; i++) {
0121         chan = ses->chans + i;
0122         if (chan->server == server) {
0123             memcpy(key, chan->signkey, SMB3_SIGN_KEY_SIZE);
0124             spin_unlock(&ses->chan_lock);
0125             goto out;
0126         }
0127     }
0128     spin_unlock(&ses->chan_lock);
0129 
0130     cifs_dbg(VFS,
0131          "%s: Could not find channel signing key for session 0x%llx\n",
0132          __func__, ses_id);
0133     rc = -ENOENT;
0134 
0135 out:
0136     spin_unlock(&cifs_tcp_ses_lock);
0137     return rc;
0138 }
0139 
0140 static struct cifs_ses *
0141 smb2_find_smb_ses_unlocked(struct TCP_Server_Info *server, __u64 ses_id)
0142 {
0143     struct cifs_ses *ses;
0144 
0145     list_for_each_entry(ses, &server->smb_ses_list, smb_ses_list) {
0146         if (ses->Suid != ses_id)
0147             continue;
0148         ++ses->ses_count;
0149         return ses;
0150     }
0151 
0152     return NULL;
0153 }
0154 
0155 struct cifs_ses *
0156 smb2_find_smb_ses(struct TCP_Server_Info *server, __u64 ses_id)
0157 {
0158     struct cifs_ses *ses;
0159 
0160     spin_lock(&cifs_tcp_ses_lock);
0161     ses = smb2_find_smb_ses_unlocked(server, ses_id);
0162     spin_unlock(&cifs_tcp_ses_lock);
0163 
0164     return ses;
0165 }
0166 
0167 static struct cifs_tcon *
0168 smb2_find_smb_sess_tcon_unlocked(struct cifs_ses *ses, __u32  tid)
0169 {
0170     struct cifs_tcon *tcon;
0171 
0172     list_for_each_entry(tcon, &ses->tcon_list, tcon_list) {
0173         if (tcon->tid != tid)
0174             continue;
0175         ++tcon->tc_count;
0176         return tcon;
0177     }
0178 
0179     return NULL;
0180 }
0181 
0182 /*
0183  * Obtain tcon corresponding to the tid in the given
0184  * cifs_ses
0185  */
0186 
0187 struct cifs_tcon *
0188 smb2_find_smb_tcon(struct TCP_Server_Info *server, __u64 ses_id, __u32  tid)
0189 {
0190     struct cifs_ses *ses;
0191     struct cifs_tcon *tcon;
0192 
0193     spin_lock(&cifs_tcp_ses_lock);
0194     ses = smb2_find_smb_ses_unlocked(server, ses_id);
0195     if (!ses) {
0196         spin_unlock(&cifs_tcp_ses_lock);
0197         return NULL;
0198     }
0199     tcon = smb2_find_smb_sess_tcon_unlocked(ses, tid);
0200     if (!tcon) {
0201         cifs_put_smb_ses(ses);
0202         spin_unlock(&cifs_tcp_ses_lock);
0203         return NULL;
0204     }
0205     spin_unlock(&cifs_tcp_ses_lock);
0206     /* tcon already has a ref to ses, so we don't need ses anymore */
0207     cifs_put_smb_ses(ses);
0208 
0209     return tcon;
0210 }
0211 
0212 int
0213 smb2_calc_signature(struct smb_rqst *rqst, struct TCP_Server_Info *server,
0214             bool allocate_crypto)
0215 {
0216     int rc;
0217     unsigned char smb2_signature[SMB2_HMACSHA256_SIZE];
0218     unsigned char *sigptr = smb2_signature;
0219     struct kvec *iov = rqst->rq_iov;
0220     struct smb2_hdr *shdr = (struct smb2_hdr *)iov[0].iov_base;
0221     struct cifs_ses *ses;
0222     struct shash_desc *shash;
0223     struct crypto_shash *hash;
0224     struct sdesc *sdesc = NULL;
0225     struct smb_rqst drqst;
0226 
0227     ses = smb2_find_smb_ses(server, le64_to_cpu(shdr->SessionId));
0228     if (!ses) {
0229         cifs_server_dbg(VFS, "%s: Could not find session\n", __func__);
0230         return 0;
0231     }
0232 
0233     memset(smb2_signature, 0x0, SMB2_HMACSHA256_SIZE);
0234     memset(shdr->Signature, 0x0, SMB2_SIGNATURE_SIZE);
0235 
0236     if (allocate_crypto) {
0237         rc = cifs_alloc_hash("hmac(sha256)", &hash, &sdesc);
0238         if (rc) {
0239             cifs_server_dbg(VFS,
0240                     "%s: sha256 alloc failed\n", __func__);
0241             goto out;
0242         }
0243         shash = &sdesc->shash;
0244     } else {
0245         hash = server->secmech.hmacsha256;
0246         shash = &server->secmech.sdeschmacsha256->shash;
0247     }
0248 
0249     rc = crypto_shash_setkey(hash, ses->auth_key.response,
0250             SMB2_NTLMV2_SESSKEY_SIZE);
0251     if (rc) {
0252         cifs_server_dbg(VFS,
0253                 "%s: Could not update with response\n",
0254                 __func__);
0255         goto out;
0256     }
0257 
0258     rc = crypto_shash_init(shash);
0259     if (rc) {
0260         cifs_server_dbg(VFS, "%s: Could not init sha256", __func__);
0261         goto out;
0262     }
0263 
0264     /*
0265      * For SMB2+, __cifs_calc_signature() expects to sign only the actual
0266      * data, that is, iov[0] should not contain a rfc1002 length.
0267      *
0268      * Sign the rfc1002 length prior to passing the data (iov[1-N]) down to
0269      * __cifs_calc_signature().
0270      */
0271     drqst = *rqst;
0272     if (drqst.rq_nvec >= 2 && iov[0].iov_len == 4) {
0273         rc = crypto_shash_update(shash, iov[0].iov_base,
0274                      iov[0].iov_len);
0275         if (rc) {
0276             cifs_server_dbg(VFS,
0277                     "%s: Could not update with payload\n",
0278                     __func__);
0279             goto out;
0280         }
0281         drqst.rq_iov++;
0282         drqst.rq_nvec--;
0283     }
0284 
0285     rc = __cifs_calc_signature(&drqst, server, sigptr, shash);
0286     if (!rc)
0287         memcpy(shdr->Signature, sigptr, SMB2_SIGNATURE_SIZE);
0288 
0289 out:
0290     if (allocate_crypto)
0291         cifs_free_hash(&hash, &sdesc);
0292     if (ses)
0293         cifs_put_smb_ses(ses);
0294     return rc;
0295 }
0296 
0297 static int generate_key(struct cifs_ses *ses, struct kvec label,
0298             struct kvec context, __u8 *key, unsigned int key_size)
0299 {
0300     unsigned char zero = 0x0;
0301     __u8 i[4] = {0, 0, 0, 1};
0302     __u8 L128[4] = {0, 0, 0, 128};
0303     __u8 L256[4] = {0, 0, 1, 0};
0304     int rc = 0;
0305     unsigned char prfhash[SMB2_HMACSHA256_SIZE];
0306     unsigned char *hashptr = prfhash;
0307     struct TCP_Server_Info *server = ses->server;
0308 
0309     memset(prfhash, 0x0, SMB2_HMACSHA256_SIZE);
0310     memset(key, 0x0, key_size);
0311 
0312     rc = smb3_crypto_shash_allocate(server);
0313     if (rc) {
0314         cifs_server_dbg(VFS, "%s: crypto alloc failed\n", __func__);
0315         goto smb3signkey_ret;
0316     }
0317 
0318     rc = crypto_shash_setkey(server->secmech.hmacsha256,
0319         ses->auth_key.response, SMB2_NTLMV2_SESSKEY_SIZE);
0320     if (rc) {
0321         cifs_server_dbg(VFS, "%s: Could not set with session key\n", __func__);
0322         goto smb3signkey_ret;
0323     }
0324 
0325     rc = crypto_shash_init(&server->secmech.sdeschmacsha256->shash);
0326     if (rc) {
0327         cifs_server_dbg(VFS, "%s: Could not init sign hmac\n", __func__);
0328         goto smb3signkey_ret;
0329     }
0330 
0331     rc = crypto_shash_update(&server->secmech.sdeschmacsha256->shash,
0332                 i, 4);
0333     if (rc) {
0334         cifs_server_dbg(VFS, "%s: Could not update with n\n", __func__);
0335         goto smb3signkey_ret;
0336     }
0337 
0338     rc = crypto_shash_update(&server->secmech.sdeschmacsha256->shash,
0339                 label.iov_base, label.iov_len);
0340     if (rc) {
0341         cifs_server_dbg(VFS, "%s: Could not update with label\n", __func__);
0342         goto smb3signkey_ret;
0343     }
0344 
0345     rc = crypto_shash_update(&server->secmech.sdeschmacsha256->shash,
0346                 &zero, 1);
0347     if (rc) {
0348         cifs_server_dbg(VFS, "%s: Could not update with zero\n", __func__);
0349         goto smb3signkey_ret;
0350     }
0351 
0352     rc = crypto_shash_update(&server->secmech.sdeschmacsha256->shash,
0353                 context.iov_base, context.iov_len);
0354     if (rc) {
0355         cifs_server_dbg(VFS, "%s: Could not update with context\n", __func__);
0356         goto smb3signkey_ret;
0357     }
0358 
0359     if ((server->cipher_type == SMB2_ENCRYPTION_AES256_CCM) ||
0360         (server->cipher_type == SMB2_ENCRYPTION_AES256_GCM)) {
0361         rc = crypto_shash_update(&server->secmech.sdeschmacsha256->shash,
0362                 L256, 4);
0363     } else {
0364         rc = crypto_shash_update(&server->secmech.sdeschmacsha256->shash,
0365                 L128, 4);
0366     }
0367     if (rc) {
0368         cifs_server_dbg(VFS, "%s: Could not update with L\n", __func__);
0369         goto smb3signkey_ret;
0370     }
0371 
0372     rc = crypto_shash_final(&server->secmech.sdeschmacsha256->shash,
0373                 hashptr);
0374     if (rc) {
0375         cifs_server_dbg(VFS, "%s: Could not generate sha256 hash\n", __func__);
0376         goto smb3signkey_ret;
0377     }
0378 
0379     memcpy(key, hashptr, key_size);
0380 
0381 smb3signkey_ret:
0382     return rc;
0383 }
0384 
0385 struct derivation {
0386     struct kvec label;
0387     struct kvec context;
0388 };
0389 
0390 struct derivation_triplet {
0391     struct derivation signing;
0392     struct derivation encryption;
0393     struct derivation decryption;
0394 };
0395 
0396 static int
0397 generate_smb3signingkey(struct cifs_ses *ses,
0398             struct TCP_Server_Info *server,
0399             const struct derivation_triplet *ptriplet)
0400 {
0401     int rc;
0402     bool is_binding = false;
0403     int chan_index = 0;
0404 
0405     spin_lock(&ses->chan_lock);
0406     is_binding = !CIFS_ALL_CHANS_NEED_RECONNECT(ses);
0407     chan_index = cifs_ses_get_chan_index(ses, server);
0408     /* TODO: introduce ref counting for channels when the can be freed */
0409     spin_unlock(&ses->chan_lock);
0410 
0411     /*
0412      * All channels use the same encryption/decryption keys but
0413      * they have their own signing key.
0414      *
0415      * When we generate the keys, check if it is for a new channel
0416      * (binding) in which case we only need to generate a signing
0417      * key and store it in the channel as to not overwrite the
0418      * master connection signing key stored in the session
0419      */
0420 
0421     if (is_binding) {
0422         rc = generate_key(ses, ptriplet->signing.label,
0423                   ptriplet->signing.context,
0424                   ses->chans[chan_index].signkey,
0425                   SMB3_SIGN_KEY_SIZE);
0426         if (rc)
0427             return rc;
0428     } else {
0429         rc = generate_key(ses, ptriplet->signing.label,
0430                   ptriplet->signing.context,
0431                   ses->smb3signingkey,
0432                   SMB3_SIGN_KEY_SIZE);
0433         if (rc)
0434             return rc;
0435 
0436         /* safe to access primary channel, since it will never go away */
0437         spin_lock(&ses->chan_lock);
0438         memcpy(ses->chans[0].signkey, ses->smb3signingkey,
0439                SMB3_SIGN_KEY_SIZE);
0440         spin_unlock(&ses->chan_lock);
0441 
0442         rc = generate_key(ses, ptriplet->encryption.label,
0443                   ptriplet->encryption.context,
0444                   ses->smb3encryptionkey,
0445                   SMB3_ENC_DEC_KEY_SIZE);
0446         rc = generate_key(ses, ptriplet->decryption.label,
0447                   ptriplet->decryption.context,
0448                   ses->smb3decryptionkey,
0449                   SMB3_ENC_DEC_KEY_SIZE);
0450         if (rc)
0451             return rc;
0452     }
0453 
0454     if (rc)
0455         return rc;
0456 
0457 #ifdef CONFIG_CIFS_DEBUG_DUMP_KEYS
0458     cifs_dbg(VFS, "%s: dumping generated AES session keys\n", __func__);
0459     /*
0460      * The session id is opaque in terms of endianness, so we can't
0461      * print it as a long long. we dump it as we got it on the wire
0462      */
0463     cifs_dbg(VFS, "Session Id    %*ph\n", (int)sizeof(ses->Suid),
0464             &ses->Suid);
0465     cifs_dbg(VFS, "Cipher type   %d\n", server->cipher_type);
0466     cifs_dbg(VFS, "Session Key   %*ph\n",
0467          SMB2_NTLMV2_SESSKEY_SIZE, ses->auth_key.response);
0468     cifs_dbg(VFS, "Signing Key   %*ph\n",
0469          SMB3_SIGN_KEY_SIZE, ses->smb3signingkey);
0470     if ((server->cipher_type == SMB2_ENCRYPTION_AES256_CCM) ||
0471         (server->cipher_type == SMB2_ENCRYPTION_AES256_GCM)) {
0472         cifs_dbg(VFS, "ServerIn Key  %*ph\n",
0473                 SMB3_GCM256_CRYPTKEY_SIZE, ses->smb3encryptionkey);
0474         cifs_dbg(VFS, "ServerOut Key %*ph\n",
0475                 SMB3_GCM256_CRYPTKEY_SIZE, ses->smb3decryptionkey);
0476     } else {
0477         cifs_dbg(VFS, "ServerIn Key  %*ph\n",
0478                 SMB3_GCM128_CRYPTKEY_SIZE, ses->smb3encryptionkey);
0479         cifs_dbg(VFS, "ServerOut Key %*ph\n",
0480                 SMB3_GCM128_CRYPTKEY_SIZE, ses->smb3decryptionkey);
0481     }
0482 #endif
0483     return rc;
0484 }
0485 
0486 int
0487 generate_smb30signingkey(struct cifs_ses *ses,
0488              struct TCP_Server_Info *server)
0489 
0490 {
0491     struct derivation_triplet triplet;
0492     struct derivation *d;
0493 
0494     d = &triplet.signing;
0495     d->label.iov_base = "SMB2AESCMAC";
0496     d->label.iov_len = 12;
0497     d->context.iov_base = "SmbSign";
0498     d->context.iov_len = 8;
0499 
0500     d = &triplet.encryption;
0501     d->label.iov_base = "SMB2AESCCM";
0502     d->label.iov_len = 11;
0503     d->context.iov_base = "ServerIn ";
0504     d->context.iov_len = 10;
0505 
0506     d = &triplet.decryption;
0507     d->label.iov_base = "SMB2AESCCM";
0508     d->label.iov_len = 11;
0509     d->context.iov_base = "ServerOut";
0510     d->context.iov_len = 10;
0511 
0512     return generate_smb3signingkey(ses, server, &triplet);
0513 }
0514 
0515 int
0516 generate_smb311signingkey(struct cifs_ses *ses,
0517               struct TCP_Server_Info *server)
0518 
0519 {
0520     struct derivation_triplet triplet;
0521     struct derivation *d;
0522 
0523     d = &triplet.signing;
0524     d->label.iov_base = "SMBSigningKey";
0525     d->label.iov_len = 14;
0526     d->context.iov_base = ses->preauth_sha_hash;
0527     d->context.iov_len = 64;
0528 
0529     d = &triplet.encryption;
0530     d->label.iov_base = "SMBC2SCipherKey";
0531     d->label.iov_len = 16;
0532     d->context.iov_base = ses->preauth_sha_hash;
0533     d->context.iov_len = 64;
0534 
0535     d = &triplet.decryption;
0536     d->label.iov_base = "SMBS2CCipherKey";
0537     d->label.iov_len = 16;
0538     d->context.iov_base = ses->preauth_sha_hash;
0539     d->context.iov_len = 64;
0540 
0541     return generate_smb3signingkey(ses, server, &triplet);
0542 }
0543 
0544 int
0545 smb3_calc_signature(struct smb_rqst *rqst, struct TCP_Server_Info *server,
0546             bool allocate_crypto)
0547 {
0548     int rc;
0549     unsigned char smb3_signature[SMB2_CMACAES_SIZE];
0550     unsigned char *sigptr = smb3_signature;
0551     struct kvec *iov = rqst->rq_iov;
0552     struct smb2_hdr *shdr = (struct smb2_hdr *)iov[0].iov_base;
0553     struct shash_desc *shash;
0554     struct crypto_shash *hash;
0555     struct sdesc *sdesc = NULL;
0556     struct smb_rqst drqst;
0557     u8 key[SMB3_SIGN_KEY_SIZE];
0558 
0559     rc = smb2_get_sign_key(le64_to_cpu(shdr->SessionId), server, key);
0560     if (rc)
0561         return 0;
0562 
0563     if (allocate_crypto) {
0564         rc = cifs_alloc_hash("cmac(aes)", &hash, &sdesc);
0565         if (rc)
0566             return rc;
0567 
0568         shash = &sdesc->shash;
0569     } else {
0570         hash = server->secmech.cmacaes;
0571         shash = &server->secmech.sdesccmacaes->shash;
0572     }
0573 
0574     memset(smb3_signature, 0x0, SMB2_CMACAES_SIZE);
0575     memset(shdr->Signature, 0x0, SMB2_SIGNATURE_SIZE);
0576 
0577     rc = crypto_shash_setkey(hash, key, SMB2_CMACAES_SIZE);
0578     if (rc) {
0579         cifs_server_dbg(VFS, "%s: Could not set key for cmac aes\n", __func__);
0580         goto out;
0581     }
0582 
0583     /*
0584      * we already allocate sdesccmacaes when we init smb3 signing key,
0585      * so unlike smb2 case we do not have to check here if secmech are
0586      * initialized
0587      */
0588     rc = crypto_shash_init(shash);
0589     if (rc) {
0590         cifs_server_dbg(VFS, "%s: Could not init cmac aes\n", __func__);
0591         goto out;
0592     }
0593 
0594     /*
0595      * For SMB2+, __cifs_calc_signature() expects to sign only the actual
0596      * data, that is, iov[0] should not contain a rfc1002 length.
0597      *
0598      * Sign the rfc1002 length prior to passing the data (iov[1-N]) down to
0599      * __cifs_calc_signature().
0600      */
0601     drqst = *rqst;
0602     if (drqst.rq_nvec >= 2 && iov[0].iov_len == 4) {
0603         rc = crypto_shash_update(shash, iov[0].iov_base,
0604                      iov[0].iov_len);
0605         if (rc) {
0606             cifs_server_dbg(VFS, "%s: Could not update with payload\n",
0607                  __func__);
0608             goto out;
0609         }
0610         drqst.rq_iov++;
0611         drqst.rq_nvec--;
0612     }
0613 
0614     rc = __cifs_calc_signature(&drqst, server, sigptr, shash);
0615     if (!rc)
0616         memcpy(shdr->Signature, sigptr, SMB2_SIGNATURE_SIZE);
0617 
0618 out:
0619     if (allocate_crypto)
0620         cifs_free_hash(&hash, &sdesc);
0621     return rc;
0622 }
0623 
0624 /* must be called with server->srv_mutex held */
0625 static int
0626 smb2_sign_rqst(struct smb_rqst *rqst, struct TCP_Server_Info *server)
0627 {
0628     int rc = 0;
0629     struct smb2_hdr *shdr;
0630     struct smb2_sess_setup_req *ssr;
0631     bool is_binding;
0632     bool is_signed;
0633 
0634     shdr = (struct smb2_hdr *)rqst->rq_iov[0].iov_base;
0635     ssr = (struct smb2_sess_setup_req *)shdr;
0636 
0637     is_binding = shdr->Command == SMB2_SESSION_SETUP &&
0638         (ssr->Flags & SMB2_SESSION_REQ_FLAG_BINDING);
0639     is_signed = shdr->Flags & SMB2_FLAGS_SIGNED;
0640 
0641     if (!is_signed)
0642         return 0;
0643     spin_lock(&server->srv_lock);
0644     if (server->ops->need_neg &&
0645         server->ops->need_neg(server)) {
0646         spin_unlock(&server->srv_lock);
0647         return 0;
0648     }
0649     spin_unlock(&server->srv_lock);
0650     if (!is_binding && !server->session_estab) {
0651         strncpy(shdr->Signature, "BSRSPYL", 8);
0652         return 0;
0653     }
0654 
0655     rc = server->ops->calc_signature(rqst, server, false);
0656 
0657     return rc;
0658 }
0659 
0660 int
0661 smb2_verify_signature(struct smb_rqst *rqst, struct TCP_Server_Info *server)
0662 {
0663     unsigned int rc;
0664     char server_response_sig[SMB2_SIGNATURE_SIZE];
0665     struct smb2_hdr *shdr =
0666             (struct smb2_hdr *)rqst->rq_iov[0].iov_base;
0667 
0668     if ((shdr->Command == SMB2_NEGOTIATE) ||
0669         (shdr->Command == SMB2_SESSION_SETUP) ||
0670         (shdr->Command == SMB2_OPLOCK_BREAK) ||
0671         server->ignore_signature ||
0672         (!server->session_estab))
0673         return 0;
0674 
0675     /*
0676      * BB what if signatures are supposed to be on for session but
0677      * server does not send one? BB
0678      */
0679 
0680     /* Do not need to verify session setups with signature "BSRSPYL " */
0681     if (memcmp(shdr->Signature, "BSRSPYL ", 8) == 0)
0682         cifs_dbg(FYI, "dummy signature received for smb command 0x%x\n",
0683              shdr->Command);
0684 
0685     /*
0686      * Save off the origiginal signature so we can modify the smb and check
0687      * our calculated signature against what the server sent.
0688      */
0689     memcpy(server_response_sig, shdr->Signature, SMB2_SIGNATURE_SIZE);
0690 
0691     memset(shdr->Signature, 0, SMB2_SIGNATURE_SIZE);
0692 
0693     rc = server->ops->calc_signature(rqst, server, true);
0694 
0695     if (rc)
0696         return rc;
0697 
0698     if (memcmp(server_response_sig, shdr->Signature, SMB2_SIGNATURE_SIZE)) {
0699         cifs_dbg(VFS, "sign fail cmd 0x%x message id 0x%llx\n",
0700             shdr->Command, shdr->MessageId);
0701         return -EACCES;
0702     } else
0703         return 0;
0704 }
0705 
0706 /*
0707  * Set message id for the request. Should be called after wait_for_free_request
0708  * and when srv_mutex is held.
0709  */
0710 static inline void
0711 smb2_seq_num_into_buf(struct TCP_Server_Info *server,
0712               struct smb2_hdr *shdr)
0713 {
0714     unsigned int i, num = le16_to_cpu(shdr->CreditCharge);
0715 
0716     shdr->MessageId = get_next_mid64(server);
0717     /* skip message numbers according to CreditCharge field */
0718     for (i = 1; i < num; i++)
0719         get_next_mid(server);
0720 }
0721 
0722 static struct mid_q_entry *
0723 smb2_mid_entry_alloc(const struct smb2_hdr *shdr,
0724              struct TCP_Server_Info *server)
0725 {
0726     struct mid_q_entry *temp;
0727     unsigned int credits = le16_to_cpu(shdr->CreditCharge);
0728 
0729     if (server == NULL) {
0730         cifs_dbg(VFS, "Null TCP session in smb2_mid_entry_alloc\n");
0731         return NULL;
0732     }
0733 
0734     temp = mempool_alloc(cifs_mid_poolp, GFP_NOFS);
0735     memset(temp, 0, sizeof(struct mid_q_entry));
0736     kref_init(&temp->refcount);
0737     temp->mid = le64_to_cpu(shdr->MessageId);
0738     temp->credits = credits > 0 ? credits : 1;
0739     temp->pid = current->pid;
0740     temp->command = shdr->Command; /* Always LE */
0741     temp->when_alloc = jiffies;
0742     temp->server = server;
0743 
0744     /*
0745      * The default is for the mid to be synchronous, so the
0746      * default callback just wakes up the current task.
0747      */
0748     get_task_struct(current);
0749     temp->creator = current;
0750     temp->callback = cifs_wake_up_task;
0751     temp->callback_data = current;
0752 
0753     atomic_inc(&mid_count);
0754     temp->mid_state = MID_REQUEST_ALLOCATED;
0755     trace_smb3_cmd_enter(le32_to_cpu(shdr->Id.SyncId.TreeId),
0756                  le64_to_cpu(shdr->SessionId),
0757                  le16_to_cpu(shdr->Command), temp->mid);
0758     return temp;
0759 }
0760 
0761 static int
0762 smb2_get_mid_entry(struct cifs_ses *ses, struct TCP_Server_Info *server,
0763            struct smb2_hdr *shdr, struct mid_q_entry **mid)
0764 {
0765     spin_lock(&server->srv_lock);
0766     if (server->tcpStatus == CifsExiting) {
0767         spin_unlock(&server->srv_lock);
0768         return -ENOENT;
0769     }
0770 
0771     if (server->tcpStatus == CifsNeedReconnect) {
0772         spin_unlock(&server->srv_lock);
0773         cifs_dbg(FYI, "tcp session dead - return to caller to retry\n");
0774         return -EAGAIN;
0775     }
0776 
0777     if (server->tcpStatus == CifsNeedNegotiate &&
0778        shdr->Command != SMB2_NEGOTIATE) {
0779         spin_unlock(&server->srv_lock);
0780         return -EAGAIN;
0781     }
0782     spin_unlock(&server->srv_lock);
0783 
0784     spin_lock(&ses->ses_lock);
0785     if (ses->ses_status == SES_NEW) {
0786         if ((shdr->Command != SMB2_SESSION_SETUP) &&
0787             (shdr->Command != SMB2_NEGOTIATE)) {
0788             spin_unlock(&ses->ses_lock);
0789             return -EAGAIN;
0790         }
0791         /* else ok - we are setting up session */
0792     }
0793 
0794     if (ses->ses_status == SES_EXITING) {
0795         if (shdr->Command != SMB2_LOGOFF) {
0796             spin_unlock(&ses->ses_lock);
0797             return -EAGAIN;
0798         }
0799         /* else ok - we are shutting down the session */
0800     }
0801     spin_unlock(&ses->ses_lock);
0802 
0803     *mid = smb2_mid_entry_alloc(shdr, server);
0804     if (*mid == NULL)
0805         return -ENOMEM;
0806     spin_lock(&server->mid_lock);
0807     list_add_tail(&(*mid)->qhead, &server->pending_mid_q);
0808     spin_unlock(&server->mid_lock);
0809 
0810     return 0;
0811 }
0812 
0813 int
0814 smb2_check_receive(struct mid_q_entry *mid, struct TCP_Server_Info *server,
0815            bool log_error)
0816 {
0817     unsigned int len = mid->resp_buf_size;
0818     struct kvec iov[1];
0819     struct smb_rqst rqst = { .rq_iov = iov,
0820                  .rq_nvec = 1 };
0821 
0822     iov[0].iov_base = (char *)mid->resp_buf;
0823     iov[0].iov_len = len;
0824 
0825     dump_smb(mid->resp_buf, min_t(u32, 80, len));
0826     /* convert the length into a more usable form */
0827     if (len > 24 && server->sign && !mid->decrypted) {
0828         int rc;
0829 
0830         rc = smb2_verify_signature(&rqst, server);
0831         if (rc)
0832             cifs_server_dbg(VFS, "SMB signature verification returned error = %d\n",
0833                  rc);
0834     }
0835 
0836     return map_smb2_to_linux_error(mid->resp_buf, log_error);
0837 }
0838 
0839 struct mid_q_entry *
0840 smb2_setup_request(struct cifs_ses *ses, struct TCP_Server_Info *server,
0841            struct smb_rqst *rqst)
0842 {
0843     int rc;
0844     struct smb2_hdr *shdr =
0845             (struct smb2_hdr *)rqst->rq_iov[0].iov_base;
0846     struct mid_q_entry *mid;
0847 
0848     smb2_seq_num_into_buf(server, shdr);
0849 
0850     rc = smb2_get_mid_entry(ses, server, shdr, &mid);
0851     if (rc) {
0852         revert_current_mid_from_hdr(server, shdr);
0853         return ERR_PTR(rc);
0854     }
0855 
0856     rc = smb2_sign_rqst(rqst, server);
0857     if (rc) {
0858         revert_current_mid_from_hdr(server, shdr);
0859         delete_mid(mid);
0860         return ERR_PTR(rc);
0861     }
0862 
0863     return mid;
0864 }
0865 
0866 struct mid_q_entry *
0867 smb2_setup_async_request(struct TCP_Server_Info *server, struct smb_rqst *rqst)
0868 {
0869     int rc;
0870     struct smb2_hdr *shdr =
0871             (struct smb2_hdr *)rqst->rq_iov[0].iov_base;
0872     struct mid_q_entry *mid;
0873 
0874     spin_lock(&server->srv_lock);
0875     if (server->tcpStatus == CifsNeedNegotiate &&
0876        shdr->Command != SMB2_NEGOTIATE) {
0877         spin_unlock(&server->srv_lock);
0878         return ERR_PTR(-EAGAIN);
0879     }
0880     spin_unlock(&server->srv_lock);
0881 
0882     smb2_seq_num_into_buf(server, shdr);
0883 
0884     mid = smb2_mid_entry_alloc(shdr, server);
0885     if (mid == NULL) {
0886         revert_current_mid_from_hdr(server, shdr);
0887         return ERR_PTR(-ENOMEM);
0888     }
0889 
0890     rc = smb2_sign_rqst(rqst, server);
0891     if (rc) {
0892         revert_current_mid_from_hdr(server, shdr);
0893         release_mid(mid);
0894         return ERR_PTR(rc);
0895     }
0896 
0897     return mid;
0898 }
0899 
0900 int
0901 smb3_crypto_aead_allocate(struct TCP_Server_Info *server)
0902 {
0903     struct crypto_aead *tfm;
0904 
0905     if (!server->secmech.ccmaesencrypt) {
0906         if ((server->cipher_type == SMB2_ENCRYPTION_AES128_GCM) ||
0907             (server->cipher_type == SMB2_ENCRYPTION_AES256_GCM))
0908             tfm = crypto_alloc_aead("gcm(aes)", 0, 0);
0909         else
0910             tfm = crypto_alloc_aead("ccm(aes)", 0, 0);
0911         if (IS_ERR(tfm)) {
0912             cifs_server_dbg(VFS, "%s: Failed alloc encrypt aead\n",
0913                  __func__);
0914             return PTR_ERR(tfm);
0915         }
0916         server->secmech.ccmaesencrypt = tfm;
0917     }
0918 
0919     if (!server->secmech.ccmaesdecrypt) {
0920         if ((server->cipher_type == SMB2_ENCRYPTION_AES128_GCM) ||
0921             (server->cipher_type == SMB2_ENCRYPTION_AES256_GCM))
0922             tfm = crypto_alloc_aead("gcm(aes)", 0, 0);
0923         else
0924             tfm = crypto_alloc_aead("ccm(aes)", 0, 0);
0925         if (IS_ERR(tfm)) {
0926             crypto_free_aead(server->secmech.ccmaesencrypt);
0927             server->secmech.ccmaesencrypt = NULL;
0928             cifs_server_dbg(VFS, "%s: Failed to alloc decrypt aead\n",
0929                  __func__);
0930             return PTR_ERR(tfm);
0931         }
0932         server->secmech.ccmaesdecrypt = tfm;
0933     }
0934 
0935     return 0;
0936 }