0001
0002
0003
0004
0005
0006
0007
0008
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
0108
0109
0110
0111 memcpy(key, ses->smb3signingkey, SMB3_SIGN_KEY_SIZE);
0112 spin_unlock(&ses->chan_lock);
0113 goto out;
0114 }
0115
0116
0117
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
0184
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
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
0266
0267
0268
0269
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
0409 spin_unlock(&ses->chan_lock);
0410
0411
0412
0413
0414
0415
0416
0417
0418
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
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
0461
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
0585
0586
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
0596
0597
0598
0599
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
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
0677
0678
0679
0680
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
0687
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
0708
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
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;
0741 temp->when_alloc = jiffies;
0742 temp->server = server;
0743
0744
0745
0746
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
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
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
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 }