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