root/fs/cifs/smb2transport.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. smb2_crypto_shash_allocate
  2. smb3_crypto_shash_allocate
  3. smb311_crypto_shash_allocate
  4. smb2_find_smb_ses_unlocked
  5. smb2_find_smb_ses
  6. smb2_find_smb_sess_tcon_unlocked
  7. smb2_find_smb_tcon
  8. smb2_calc_signature
  9. generate_key
  10. generate_smb3signingkey
  11. generate_smb30signingkey
  12. generate_smb311signingkey
  13. smb3_calc_signature
  14. smb2_sign_rqst
  15. smb2_verify_signature
  16. smb2_seq_num_into_buf
  17. smb2_mid_entry_alloc
  18. smb2_get_mid_entry
  19. smb2_check_receive
  20. smb2_setup_request
  21. smb2_setup_async_request
  22. smb3_crypto_aead_allocate

   1 /*
   2  *   fs/cifs/smb2transport.c
   3  *
   4  *   Copyright (C) International Business Machines  Corp., 2002, 2011
   5  *                 Etersoft, 2012
   6  *   Author(s): Steve French (sfrench@us.ibm.com)
   7  *              Jeremy Allison (jra@samba.org) 2006
   8  *              Pavel Shilovsky (pshilovsky@samba.org) 2012
   9  *
  10  *   This library is free software; you can redistribute it and/or modify
  11  *   it under the terms of the GNU Lesser General Public License as published
  12  *   by the Free Software Foundation; either version 2.1 of the License, or
  13  *   (at your option) any later version.
  14  *
  15  *   This library is distributed in the hope that it will be useful,
  16  *   but WITHOUT ANY WARRANTY; without even the implied warranty of
  17  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
  18  *   the GNU Lesser General Public License for more details.
  19  *
  20  *   You should have received a copy of the GNU Lesser General Public License
  21  *   along with this library; if not, write to the Free Software
  22  *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
  23  */
  24 
  25 #include <linux/fs.h>
  26 #include <linux/list.h>
  27 #include <linux/wait.h>
  28 #include <linux/net.h>
  29 #include <linux/delay.h>
  30 #include <linux/uaccess.h>
  31 #include <asm/processor.h>
  32 #include <linux/mempool.h>
  33 #include <linux/highmem.h>
  34 #include <crypto/aead.h>
  35 #include "smb2pdu.h"
  36 #include "cifsglob.h"
  37 #include "cifsproto.h"
  38 #include "smb2proto.h"
  39 #include "cifs_debug.h"
  40 #include "smb2status.h"
  41 #include "smb2glob.h"
  42 
  43 static int
  44 smb2_crypto_shash_allocate(struct TCP_Server_Info *server)
  45 {
  46         return cifs_alloc_hash("hmac(sha256)",
  47                                &server->secmech.hmacsha256,
  48                                &server->secmech.sdeschmacsha256);
  49 }
  50 
  51 static int
  52 smb3_crypto_shash_allocate(struct TCP_Server_Info *server)
  53 {
  54         struct cifs_secmech *p = &server->secmech;
  55         int rc;
  56 
  57         rc = cifs_alloc_hash("hmac(sha256)",
  58                              &p->hmacsha256,
  59                              &p->sdeschmacsha256);
  60         if (rc)
  61                 goto err;
  62 
  63         rc = cifs_alloc_hash("cmac(aes)", &p->cmacaes, &p->sdesccmacaes);
  64         if (rc)
  65                 goto err;
  66 
  67         return 0;
  68 err:
  69         cifs_free_hash(&p->hmacsha256, &p->sdeschmacsha256);
  70         return rc;
  71 }
  72 
  73 int
  74 smb311_crypto_shash_allocate(struct TCP_Server_Info *server)
  75 {
  76         struct cifs_secmech *p = &server->secmech;
  77         int rc = 0;
  78 
  79         rc = cifs_alloc_hash("hmac(sha256)",
  80                              &p->hmacsha256,
  81                              &p->sdeschmacsha256);
  82         if (rc)
  83                 return rc;
  84 
  85         rc = cifs_alloc_hash("cmac(aes)", &p->cmacaes, &p->sdesccmacaes);
  86         if (rc)
  87                 goto err;
  88 
  89         rc = cifs_alloc_hash("sha512", &p->sha512, &p->sdescsha512);
  90         if (rc)
  91                 goto err;
  92 
  93         return 0;
  94 
  95 err:
  96         cifs_free_hash(&p->cmacaes, &p->sdesccmacaes);
  97         cifs_free_hash(&p->hmacsha256, &p->sdeschmacsha256);
  98         return rc;
  99 }
 100 
 101 static struct cifs_ses *
 102 smb2_find_smb_ses_unlocked(struct TCP_Server_Info *server, __u64 ses_id)
 103 {
 104         struct cifs_ses *ses;
 105 
 106         list_for_each_entry(ses, &server->smb_ses_list, smb_ses_list) {
 107                 if (ses->Suid != ses_id)
 108                         continue;
 109                 return ses;
 110         }
 111 
 112         return NULL;
 113 }
 114 
 115 struct cifs_ses *
 116 smb2_find_smb_ses(struct TCP_Server_Info *server, __u64 ses_id)
 117 {
 118         struct cifs_ses *ses;
 119 
 120         spin_lock(&cifs_tcp_ses_lock);
 121         ses = smb2_find_smb_ses_unlocked(server, ses_id);
 122         spin_unlock(&cifs_tcp_ses_lock);
 123 
 124         return ses;
 125 }
 126 
 127 static struct cifs_tcon *
 128 smb2_find_smb_sess_tcon_unlocked(struct cifs_ses *ses, __u32  tid)
 129 {
 130         struct cifs_tcon *tcon;
 131 
 132         list_for_each_entry(tcon, &ses->tcon_list, tcon_list) {
 133                 if (tcon->tid != tid)
 134                         continue;
 135                 ++tcon->tc_count;
 136                 return tcon;
 137         }
 138 
 139         return NULL;
 140 }
 141 
 142 /*
 143  * Obtain tcon corresponding to the tid in the given
 144  * cifs_ses
 145  */
 146 
 147 struct cifs_tcon *
 148 smb2_find_smb_tcon(struct TCP_Server_Info *server, __u64 ses_id, __u32  tid)
 149 {
 150         struct cifs_ses *ses;
 151         struct cifs_tcon *tcon;
 152 
 153         spin_lock(&cifs_tcp_ses_lock);
 154         ses = smb2_find_smb_ses_unlocked(server, ses_id);
 155         if (!ses) {
 156                 spin_unlock(&cifs_tcp_ses_lock);
 157                 return NULL;
 158         }
 159         tcon = smb2_find_smb_sess_tcon_unlocked(ses, tid);
 160         spin_unlock(&cifs_tcp_ses_lock);
 161 
 162         return tcon;
 163 }
 164 
 165 int
 166 smb2_calc_signature(struct smb_rqst *rqst, struct TCP_Server_Info *server)
 167 {
 168         int rc;
 169         unsigned char smb2_signature[SMB2_HMACSHA256_SIZE];
 170         unsigned char *sigptr = smb2_signature;
 171         struct kvec *iov = rqst->rq_iov;
 172         struct smb2_sync_hdr *shdr = (struct smb2_sync_hdr *)iov[0].iov_base;
 173         struct cifs_ses *ses;
 174         struct shash_desc *shash;
 175         struct smb_rqst drqst;
 176 
 177         ses = smb2_find_smb_ses(server, shdr->SessionId);
 178         if (!ses) {
 179                 cifs_server_dbg(VFS, "%s: Could not find session\n", __func__);
 180                 return 0;
 181         }
 182 
 183         memset(smb2_signature, 0x0, SMB2_HMACSHA256_SIZE);
 184         memset(shdr->Signature, 0x0, SMB2_SIGNATURE_SIZE);
 185 
 186         rc = smb2_crypto_shash_allocate(server);
 187         if (rc) {
 188                 cifs_server_dbg(VFS, "%s: sha256 alloc failed\n", __func__);
 189                 return rc;
 190         }
 191 
 192         rc = crypto_shash_setkey(server->secmech.hmacsha256,
 193                                  ses->auth_key.response, SMB2_NTLMV2_SESSKEY_SIZE);
 194         if (rc) {
 195                 cifs_server_dbg(VFS, "%s: Could not update with response\n", __func__);
 196                 return rc;
 197         }
 198 
 199         shash = &server->secmech.sdeschmacsha256->shash;
 200         rc = crypto_shash_init(shash);
 201         if (rc) {
 202                 cifs_server_dbg(VFS, "%s: Could not init sha256", __func__);
 203                 return rc;
 204         }
 205 
 206         /*
 207          * For SMB2+, __cifs_calc_signature() expects to sign only the actual
 208          * data, that is, iov[0] should not contain a rfc1002 length.
 209          *
 210          * Sign the rfc1002 length prior to passing the data (iov[1-N]) down to
 211          * __cifs_calc_signature().
 212          */
 213         drqst = *rqst;
 214         if (drqst.rq_nvec >= 2 && iov[0].iov_len == 4) {
 215                 rc = crypto_shash_update(shash, iov[0].iov_base,
 216                                          iov[0].iov_len);
 217                 if (rc) {
 218                         cifs_server_dbg(VFS, "%s: Could not update with payload\n",
 219                                  __func__);
 220                         return rc;
 221                 }
 222                 drqst.rq_iov++;
 223                 drqst.rq_nvec--;
 224         }
 225 
 226         rc = __cifs_calc_signature(&drqst, server, sigptr, shash);
 227         if (!rc)
 228                 memcpy(shdr->Signature, sigptr, SMB2_SIGNATURE_SIZE);
 229 
 230         return rc;
 231 }
 232 
 233 static int generate_key(struct cifs_ses *ses, struct kvec label,
 234                         struct kvec context, __u8 *key, unsigned int key_size)
 235 {
 236         unsigned char zero = 0x0;
 237         __u8 i[4] = {0, 0, 0, 1};
 238         __u8 L[4] = {0, 0, 0, 128};
 239         int rc = 0;
 240         unsigned char prfhash[SMB2_HMACSHA256_SIZE];
 241         unsigned char *hashptr = prfhash;
 242         struct TCP_Server_Info *server = ses->server;
 243 
 244         memset(prfhash, 0x0, SMB2_HMACSHA256_SIZE);
 245         memset(key, 0x0, key_size);
 246 
 247         rc = smb3_crypto_shash_allocate(server);
 248         if (rc) {
 249                 cifs_server_dbg(VFS, "%s: crypto alloc failed\n", __func__);
 250                 goto smb3signkey_ret;
 251         }
 252 
 253         rc = crypto_shash_setkey(server->secmech.hmacsha256,
 254                 ses->auth_key.response, SMB2_NTLMV2_SESSKEY_SIZE);
 255         if (rc) {
 256                 cifs_server_dbg(VFS, "%s: Could not set with session key\n", __func__);
 257                 goto smb3signkey_ret;
 258         }
 259 
 260         rc = crypto_shash_init(&server->secmech.sdeschmacsha256->shash);
 261         if (rc) {
 262                 cifs_server_dbg(VFS, "%s: Could not init sign hmac\n", __func__);
 263                 goto smb3signkey_ret;
 264         }
 265 
 266         rc = crypto_shash_update(&server->secmech.sdeschmacsha256->shash,
 267                                 i, 4);
 268         if (rc) {
 269                 cifs_server_dbg(VFS, "%s: Could not update with n\n", __func__);
 270                 goto smb3signkey_ret;
 271         }
 272 
 273         rc = crypto_shash_update(&server->secmech.sdeschmacsha256->shash,
 274                                 label.iov_base, label.iov_len);
 275         if (rc) {
 276                 cifs_server_dbg(VFS, "%s: Could not update with label\n", __func__);
 277                 goto smb3signkey_ret;
 278         }
 279 
 280         rc = crypto_shash_update(&server->secmech.sdeschmacsha256->shash,
 281                                 &zero, 1);
 282         if (rc) {
 283                 cifs_server_dbg(VFS, "%s: Could not update with zero\n", __func__);
 284                 goto smb3signkey_ret;
 285         }
 286 
 287         rc = crypto_shash_update(&server->secmech.sdeschmacsha256->shash,
 288                                 context.iov_base, context.iov_len);
 289         if (rc) {
 290                 cifs_server_dbg(VFS, "%s: Could not update with context\n", __func__);
 291                 goto smb3signkey_ret;
 292         }
 293 
 294         rc = crypto_shash_update(&server->secmech.sdeschmacsha256->shash,
 295                                 L, 4);
 296         if (rc) {
 297                 cifs_server_dbg(VFS, "%s: Could not update with L\n", __func__);
 298                 goto smb3signkey_ret;
 299         }
 300 
 301         rc = crypto_shash_final(&server->secmech.sdeschmacsha256->shash,
 302                                 hashptr);
 303         if (rc) {
 304                 cifs_server_dbg(VFS, "%s: Could not generate sha256 hash\n", __func__);
 305                 goto smb3signkey_ret;
 306         }
 307 
 308         memcpy(key, hashptr, key_size);
 309 
 310 smb3signkey_ret:
 311         return rc;
 312 }
 313 
 314 struct derivation {
 315         struct kvec label;
 316         struct kvec context;
 317 };
 318 
 319 struct derivation_triplet {
 320         struct derivation signing;
 321         struct derivation encryption;
 322         struct derivation decryption;
 323 };
 324 
 325 static int
 326 generate_smb3signingkey(struct cifs_ses *ses,
 327                         const struct derivation_triplet *ptriplet)
 328 {
 329         int rc;
 330 
 331         rc = generate_key(ses, ptriplet->signing.label,
 332                           ptriplet->signing.context, ses->smb3signingkey,
 333                           SMB3_SIGN_KEY_SIZE);
 334         if (rc)
 335                 return rc;
 336 
 337         rc = generate_key(ses, ptriplet->encryption.label,
 338                           ptriplet->encryption.context, ses->smb3encryptionkey,
 339                           SMB3_SIGN_KEY_SIZE);
 340         if (rc)
 341                 return rc;
 342 
 343         rc = generate_key(ses, ptriplet->decryption.label,
 344                           ptriplet->decryption.context,
 345                           ses->smb3decryptionkey, SMB3_SIGN_KEY_SIZE);
 346 
 347         if (rc)
 348                 return rc;
 349 
 350 #ifdef CONFIG_CIFS_DEBUG_DUMP_KEYS
 351         cifs_dbg(VFS, "%s: dumping generated AES session keys\n", __func__);
 352         /*
 353          * The session id is opaque in terms of endianness, so we can't
 354          * print it as a long long. we dump it as we got it on the wire
 355          */
 356         cifs_dbg(VFS, "Session Id    %*ph\n", (int)sizeof(ses->Suid),
 357                         &ses->Suid);
 358         cifs_dbg(VFS, "Session Key   %*ph\n",
 359                  SMB2_NTLMV2_SESSKEY_SIZE, ses->auth_key.response);
 360         cifs_dbg(VFS, "Signing Key   %*ph\n",
 361                  SMB3_SIGN_KEY_SIZE, ses->smb3signingkey);
 362         cifs_dbg(VFS, "ServerIn Key  %*ph\n",
 363                  SMB3_SIGN_KEY_SIZE, ses->smb3encryptionkey);
 364         cifs_dbg(VFS, "ServerOut Key %*ph\n",
 365                  SMB3_SIGN_KEY_SIZE, ses->smb3decryptionkey);
 366 #endif
 367         return rc;
 368 }
 369 
 370 int
 371 generate_smb30signingkey(struct cifs_ses *ses)
 372 
 373 {
 374         struct derivation_triplet triplet;
 375         struct derivation *d;
 376 
 377         d = &triplet.signing;
 378         d->label.iov_base = "SMB2AESCMAC";
 379         d->label.iov_len = 12;
 380         d->context.iov_base = "SmbSign";
 381         d->context.iov_len = 8;
 382 
 383         d = &triplet.encryption;
 384         d->label.iov_base = "SMB2AESCCM";
 385         d->label.iov_len = 11;
 386         d->context.iov_base = "ServerIn ";
 387         d->context.iov_len = 10;
 388 
 389         d = &triplet.decryption;
 390         d->label.iov_base = "SMB2AESCCM";
 391         d->label.iov_len = 11;
 392         d->context.iov_base = "ServerOut";
 393         d->context.iov_len = 10;
 394 
 395         return generate_smb3signingkey(ses, &triplet);
 396 }
 397 
 398 int
 399 generate_smb311signingkey(struct cifs_ses *ses)
 400 
 401 {
 402         struct derivation_triplet triplet;
 403         struct derivation *d;
 404 
 405         d = &triplet.signing;
 406         d->label.iov_base = "SMBSigningKey";
 407         d->label.iov_len = 14;
 408         d->context.iov_base = ses->preauth_sha_hash;
 409         d->context.iov_len = 64;
 410 
 411         d = &triplet.encryption;
 412         d->label.iov_base = "SMBC2SCipherKey";
 413         d->label.iov_len = 16;
 414         d->context.iov_base = ses->preauth_sha_hash;
 415         d->context.iov_len = 64;
 416 
 417         d = &triplet.decryption;
 418         d->label.iov_base = "SMBS2CCipherKey";
 419         d->label.iov_len = 16;
 420         d->context.iov_base = ses->preauth_sha_hash;
 421         d->context.iov_len = 64;
 422 
 423         return generate_smb3signingkey(ses, &triplet);
 424 }
 425 
 426 int
 427 smb3_calc_signature(struct smb_rqst *rqst, struct TCP_Server_Info *server)
 428 {
 429         int rc;
 430         unsigned char smb3_signature[SMB2_CMACAES_SIZE];
 431         unsigned char *sigptr = smb3_signature;
 432         struct kvec *iov = rqst->rq_iov;
 433         struct smb2_sync_hdr *shdr = (struct smb2_sync_hdr *)iov[0].iov_base;
 434         struct cifs_ses *ses;
 435         struct shash_desc *shash = &server->secmech.sdesccmacaes->shash;
 436         struct smb_rqst drqst;
 437 
 438         ses = smb2_find_smb_ses(server, shdr->SessionId);
 439         if (!ses) {
 440                 cifs_server_dbg(VFS, "%s: Could not find session\n", __func__);
 441                 return 0;
 442         }
 443 
 444         memset(smb3_signature, 0x0, SMB2_CMACAES_SIZE);
 445         memset(shdr->Signature, 0x0, SMB2_SIGNATURE_SIZE);
 446 
 447         rc = crypto_shash_setkey(server->secmech.cmacaes,
 448                                  ses->smb3signingkey, SMB2_CMACAES_SIZE);
 449         if (rc) {
 450                 cifs_server_dbg(VFS, "%s: Could not set key for cmac aes\n", __func__);
 451                 return rc;
 452         }
 453 
 454         /*
 455          * we already allocate sdesccmacaes when we init smb3 signing key,
 456          * so unlike smb2 case we do not have to check here if secmech are
 457          * initialized
 458          */
 459         rc = crypto_shash_init(shash);
 460         if (rc) {
 461                 cifs_server_dbg(VFS, "%s: Could not init cmac aes\n", __func__);
 462                 return rc;
 463         }
 464 
 465         /*
 466          * For SMB2+, __cifs_calc_signature() expects to sign only the actual
 467          * data, that is, iov[0] should not contain a rfc1002 length.
 468          *
 469          * Sign the rfc1002 length prior to passing the data (iov[1-N]) down to
 470          * __cifs_calc_signature().
 471          */
 472         drqst = *rqst;
 473         if (drqst.rq_nvec >= 2 && iov[0].iov_len == 4) {
 474                 rc = crypto_shash_update(shash, iov[0].iov_base,
 475                                          iov[0].iov_len);
 476                 if (rc) {
 477                         cifs_server_dbg(VFS, "%s: Could not update with payload\n",
 478                                  __func__);
 479                         return rc;
 480                 }
 481                 drqst.rq_iov++;
 482                 drqst.rq_nvec--;
 483         }
 484 
 485         rc = __cifs_calc_signature(&drqst, server, sigptr, shash);
 486         if (!rc)
 487                 memcpy(shdr->Signature, sigptr, SMB2_SIGNATURE_SIZE);
 488 
 489         return rc;
 490 }
 491 
 492 /* must be called with server->srv_mutex held */
 493 static int
 494 smb2_sign_rqst(struct smb_rqst *rqst, struct TCP_Server_Info *server)
 495 {
 496         int rc = 0;
 497         struct smb2_sync_hdr *shdr =
 498                         (struct smb2_sync_hdr *)rqst->rq_iov[0].iov_base;
 499 
 500         if (!(shdr->Flags & SMB2_FLAGS_SIGNED) ||
 501             server->tcpStatus == CifsNeedNegotiate)
 502                 return rc;
 503 
 504         if (!server->session_estab) {
 505                 strncpy(shdr->Signature, "BSRSPYL", 8);
 506                 return rc;
 507         }
 508 
 509         rc = server->ops->calc_signature(rqst, server);
 510 
 511         return rc;
 512 }
 513 
 514 int
 515 smb2_verify_signature(struct smb_rqst *rqst, struct TCP_Server_Info *server)
 516 {
 517         unsigned int rc;
 518         char server_response_sig[16];
 519         struct smb2_sync_hdr *shdr =
 520                         (struct smb2_sync_hdr *)rqst->rq_iov[0].iov_base;
 521 
 522         if ((shdr->Command == SMB2_NEGOTIATE) ||
 523             (shdr->Command == SMB2_SESSION_SETUP) ||
 524             (shdr->Command == SMB2_OPLOCK_BREAK) ||
 525             server->ignore_signature ||
 526             (!server->session_estab))
 527                 return 0;
 528 
 529         /*
 530          * BB what if signatures are supposed to be on for session but
 531          * server does not send one? BB
 532          */
 533 
 534         /* Do not need to verify session setups with signature "BSRSPYL " */
 535         if (memcmp(shdr->Signature, "BSRSPYL ", 8) == 0)
 536                 cifs_dbg(FYI, "dummy signature received for smb command 0x%x\n",
 537                          shdr->Command);
 538 
 539         /*
 540          * Save off the origiginal signature so we can modify the smb and check
 541          * our calculated signature against what the server sent.
 542          */
 543         memcpy(server_response_sig, shdr->Signature, SMB2_SIGNATURE_SIZE);
 544 
 545         memset(shdr->Signature, 0, SMB2_SIGNATURE_SIZE);
 546 
 547         mutex_lock(&server->srv_mutex);
 548         rc = server->ops->calc_signature(rqst, server);
 549         mutex_unlock(&server->srv_mutex);
 550 
 551         if (rc)
 552                 return rc;
 553 
 554         if (memcmp(server_response_sig, shdr->Signature, SMB2_SIGNATURE_SIZE))
 555                 return -EACCES;
 556         else
 557                 return 0;
 558 }
 559 
 560 /*
 561  * Set message id for the request. Should be called after wait_for_free_request
 562  * and when srv_mutex is held.
 563  */
 564 static inline void
 565 smb2_seq_num_into_buf(struct TCP_Server_Info *server,
 566                       struct smb2_sync_hdr *shdr)
 567 {
 568         unsigned int i, num = le16_to_cpu(shdr->CreditCharge);
 569 
 570         shdr->MessageId = get_next_mid64(server);
 571         /* skip message numbers according to CreditCharge field */
 572         for (i = 1; i < num; i++)
 573                 get_next_mid(server);
 574 }
 575 
 576 static struct mid_q_entry *
 577 smb2_mid_entry_alloc(const struct smb2_sync_hdr *shdr,
 578                      struct TCP_Server_Info *server)
 579 {
 580         struct mid_q_entry *temp;
 581         unsigned int credits = le16_to_cpu(shdr->CreditCharge);
 582 
 583         if (server == NULL) {
 584                 cifs_dbg(VFS, "Null TCP session in smb2_mid_entry_alloc\n");
 585                 return NULL;
 586         }
 587 
 588         temp = mempool_alloc(cifs_mid_poolp, GFP_NOFS);
 589         memset(temp, 0, sizeof(struct mid_q_entry));
 590         kref_init(&temp->refcount);
 591         temp->mid = le64_to_cpu(shdr->MessageId);
 592         temp->credits = credits > 0 ? credits : 1;
 593         temp->pid = current->pid;
 594         temp->command = shdr->Command; /* Always LE */
 595         temp->when_alloc = jiffies;
 596         temp->server = server;
 597 
 598         /*
 599          * The default is for the mid to be synchronous, so the
 600          * default callback just wakes up the current task.
 601          */
 602         get_task_struct(current);
 603         temp->creator = current;
 604         temp->callback = cifs_wake_up_task;
 605         temp->callback_data = current;
 606 
 607         atomic_inc(&midCount);
 608         temp->mid_state = MID_REQUEST_ALLOCATED;
 609         trace_smb3_cmd_enter(shdr->TreeId, shdr->SessionId,
 610                 le16_to_cpu(shdr->Command), temp->mid);
 611         return temp;
 612 }
 613 
 614 static int
 615 smb2_get_mid_entry(struct cifs_ses *ses, struct smb2_sync_hdr *shdr,
 616                    struct mid_q_entry **mid)
 617 {
 618         if (ses->server->tcpStatus == CifsExiting)
 619                 return -ENOENT;
 620 
 621         if (ses->server->tcpStatus == CifsNeedReconnect) {
 622                 cifs_dbg(FYI, "tcp session dead - return to caller to retry\n");
 623                 return -EAGAIN;
 624         }
 625 
 626         if (ses->server->tcpStatus == CifsNeedNegotiate &&
 627            shdr->Command != SMB2_NEGOTIATE)
 628                 return -EAGAIN;
 629 
 630         if (ses->status == CifsNew) {
 631                 if ((shdr->Command != SMB2_SESSION_SETUP) &&
 632                     (shdr->Command != SMB2_NEGOTIATE))
 633                         return -EAGAIN;
 634                 /* else ok - we are setting up session */
 635         }
 636 
 637         if (ses->status == CifsExiting) {
 638                 if (shdr->Command != SMB2_LOGOFF)
 639                         return -EAGAIN;
 640                 /* else ok - we are shutting down the session */
 641         }
 642 
 643         *mid = smb2_mid_entry_alloc(shdr, ses->server);
 644         if (*mid == NULL)
 645                 return -ENOMEM;
 646         spin_lock(&GlobalMid_Lock);
 647         list_add_tail(&(*mid)->qhead, &ses->server->pending_mid_q);
 648         spin_unlock(&GlobalMid_Lock);
 649 
 650         return 0;
 651 }
 652 
 653 int
 654 smb2_check_receive(struct mid_q_entry *mid, struct TCP_Server_Info *server,
 655                    bool log_error)
 656 {
 657         unsigned int len = mid->resp_buf_size;
 658         struct kvec iov[1];
 659         struct smb_rqst rqst = { .rq_iov = iov,
 660                                  .rq_nvec = 1 };
 661 
 662         iov[0].iov_base = (char *)mid->resp_buf;
 663         iov[0].iov_len = len;
 664 
 665         dump_smb(mid->resp_buf, min_t(u32, 80, len));
 666         /* convert the length into a more usable form */
 667         if (len > 24 && server->sign && !mid->decrypted) {
 668                 int rc;
 669 
 670                 rc = smb2_verify_signature(&rqst, server);
 671                 if (rc)
 672                         cifs_server_dbg(VFS, "SMB signature verification returned error = %d\n",
 673                                  rc);
 674         }
 675 
 676         return map_smb2_to_linux_error(mid->resp_buf, log_error);
 677 }
 678 
 679 struct mid_q_entry *
 680 smb2_setup_request(struct cifs_ses *ses, struct smb_rqst *rqst)
 681 {
 682         int rc;
 683         struct smb2_sync_hdr *shdr =
 684                         (struct smb2_sync_hdr *)rqst->rq_iov[0].iov_base;
 685         struct mid_q_entry *mid;
 686 
 687         smb2_seq_num_into_buf(ses->server, shdr);
 688 
 689         rc = smb2_get_mid_entry(ses, shdr, &mid);
 690         if (rc) {
 691                 revert_current_mid_from_hdr(ses->server, shdr);
 692                 return ERR_PTR(rc);
 693         }
 694 
 695         rc = smb2_sign_rqst(rqst, ses->server);
 696         if (rc) {
 697                 revert_current_mid_from_hdr(ses->server, shdr);
 698                 cifs_delete_mid(mid);
 699                 return ERR_PTR(rc);
 700         }
 701 
 702         return mid;
 703 }
 704 
 705 struct mid_q_entry *
 706 smb2_setup_async_request(struct TCP_Server_Info *server, struct smb_rqst *rqst)
 707 {
 708         int rc;
 709         struct smb2_sync_hdr *shdr =
 710                         (struct smb2_sync_hdr *)rqst->rq_iov[0].iov_base;
 711         struct mid_q_entry *mid;
 712 
 713         if (server->tcpStatus == CifsNeedNegotiate &&
 714            shdr->Command != SMB2_NEGOTIATE)
 715                 return ERR_PTR(-EAGAIN);
 716 
 717         smb2_seq_num_into_buf(server, shdr);
 718 
 719         mid = smb2_mid_entry_alloc(shdr, server);
 720         if (mid == NULL) {
 721                 revert_current_mid_from_hdr(server, shdr);
 722                 return ERR_PTR(-ENOMEM);
 723         }
 724 
 725         rc = smb2_sign_rqst(rqst, server);
 726         if (rc) {
 727                 revert_current_mid_from_hdr(server, shdr);
 728                 DeleteMidQEntry(mid);
 729                 return ERR_PTR(rc);
 730         }
 731 
 732         return mid;
 733 }
 734 
 735 int
 736 smb3_crypto_aead_allocate(struct TCP_Server_Info *server)
 737 {
 738         struct crypto_aead *tfm;
 739 
 740         if (!server->secmech.ccmaesencrypt) {
 741                 if (server->cipher_type == SMB2_ENCRYPTION_AES128_GCM)
 742                         tfm = crypto_alloc_aead("gcm(aes)", 0, 0);
 743                 else
 744                         tfm = crypto_alloc_aead("ccm(aes)", 0, 0);
 745                 if (IS_ERR(tfm)) {
 746                         cifs_server_dbg(VFS, "%s: Failed to alloc encrypt aead\n",
 747                                  __func__);
 748                         return PTR_ERR(tfm);
 749                 }
 750                 server->secmech.ccmaesencrypt = tfm;
 751         }
 752 
 753         if (!server->secmech.ccmaesdecrypt) {
 754                 if (server->cipher_type == SMB2_ENCRYPTION_AES128_GCM)
 755                         tfm = crypto_alloc_aead("gcm(aes)", 0, 0);
 756                 else
 757                         tfm = crypto_alloc_aead("ccm(aes)", 0, 0);
 758                 if (IS_ERR(tfm)) {
 759                         crypto_free_aead(server->secmech.ccmaesencrypt);
 760                         server->secmech.ccmaesencrypt = NULL;
 761                         cifs_server_dbg(VFS, "%s: Failed to alloc decrypt aead\n",
 762                                  __func__);
 763                         return PTR_ERR(tfm);
 764                 }
 765                 server->secmech.ccmaesdecrypt = tfm;
 766         }
 767 
 768         return 0;
 769 }

/* [<][>][^][v][top][bottom][index][help] */