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