linux/fs/cifs/smb2transport.c
<<
>>
Prefs
   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
  43static int
  44smb2_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
  51static int
  52smb3_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;
  68err:
  69        cifs_free_hash(&p->hmacsha256, &p->sdeschmacsha256);
  70        return rc;
  71}
  72
  73#ifdef CONFIG_CIFS_SMB311
  74int
  75smb311_crypto_shash_allocate(struct TCP_Server_Info *server)
  76{
  77        struct cifs_secmech *p = &server->secmech;
  78        int rc = 0;
  79
  80        rc = cifs_alloc_hash("hmac(sha256)",
  81                             &p->hmacsha256,
  82                             &p->sdeschmacsha256);
  83        if (rc)
  84                return rc;
  85
  86        rc = cifs_alloc_hash("cmac(aes)", &p->cmacaes, &p->sdesccmacaes);
  87        if (rc)
  88                goto err;
  89
  90        rc = cifs_alloc_hash("sha512", &p->sha512, &p->sdescsha512);
  91        if (rc)
  92                goto err;
  93
  94        return 0;
  95
  96err:
  97        cifs_free_hash(&p->cmacaes, &p->sdesccmacaes);
  98        cifs_free_hash(&p->hmacsha256, &p->sdeschmacsha256);
  99        return rc;
 100}
 101#endif
 102
 103static struct cifs_ses *
 104smb2_find_smb_ses_unlocked(struct TCP_Server_Info *server, __u64 ses_id)
 105{
 106        struct cifs_ses *ses;
 107
 108        list_for_each_entry(ses, &server->smb_ses_list, smb_ses_list) {
 109                if (ses->Suid != ses_id)
 110                        continue;
 111                return ses;
 112        }
 113
 114        return NULL;
 115}
 116
 117struct cifs_ses *
 118smb2_find_smb_ses(struct TCP_Server_Info *server, __u64 ses_id)
 119{
 120        struct cifs_ses *ses;
 121
 122        spin_lock(&cifs_tcp_ses_lock);
 123        ses = smb2_find_smb_ses_unlocked(server, ses_id);
 124        spin_unlock(&cifs_tcp_ses_lock);
 125
 126        return ses;
 127}
 128
 129static struct cifs_tcon *
 130smb2_find_smb_sess_tcon_unlocked(struct cifs_ses *ses, __u32  tid)
 131{
 132        struct cifs_tcon *tcon;
 133
 134        list_for_each_entry(tcon, &ses->tcon_list, tcon_list) {
 135                if (tcon->tid != tid)
 136                        continue;
 137                ++tcon->tc_count;
 138                return tcon;
 139        }
 140
 141        return NULL;
 142}
 143
 144/*
 145 * Obtain tcon corresponding to the tid in the given
 146 * cifs_ses
 147 */
 148
 149struct cifs_tcon *
 150smb2_find_smb_tcon(struct TCP_Server_Info *server, __u64 ses_id, __u32  tid)
 151{
 152        struct cifs_ses *ses;
 153        struct cifs_tcon *tcon;
 154
 155        spin_lock(&cifs_tcp_ses_lock);
 156        ses = smb2_find_smb_ses_unlocked(server, ses_id);
 157        if (!ses) {
 158                spin_unlock(&cifs_tcp_ses_lock);
 159                return NULL;
 160        }
 161        tcon = smb2_find_smb_sess_tcon_unlocked(ses, tid);
 162        spin_unlock(&cifs_tcp_ses_lock);
 163
 164        return tcon;
 165}
 166
 167int
 168smb2_calc_signature(struct smb_rqst *rqst, struct TCP_Server_Info *server)
 169{
 170        int rc;
 171        unsigned char smb2_signature[SMB2_HMACSHA256_SIZE];
 172        unsigned char *sigptr = smb2_signature;
 173        struct kvec *iov = rqst->rq_iov;
 174        struct smb2_sync_hdr *shdr = (struct smb2_sync_hdr *)iov[0].iov_base;
 175        struct cifs_ses *ses;
 176        struct shash_desc *shash = &server->secmech.sdeschmacsha256->shash;
 177        struct smb_rqst drqst;
 178
 179        ses = smb2_find_smb_ses(server, shdr->SessionId);
 180        if (!ses) {
 181                cifs_dbg(VFS, "%s: Could not find session\n", __func__);
 182                return 0;
 183        }
 184
 185        memset(smb2_signature, 0x0, SMB2_HMACSHA256_SIZE);
 186        memset(shdr->Signature, 0x0, SMB2_SIGNATURE_SIZE);
 187
 188        rc = smb2_crypto_shash_allocate(server);
 189        if (rc) {
 190                cifs_dbg(VFS, "%s: shah256 alloc failed\n", __func__);
 191                return rc;
 192        }
 193
 194        rc = crypto_shash_setkey(server->secmech.hmacsha256,
 195                                 ses->auth_key.response, SMB2_NTLMV2_SESSKEY_SIZE);
 196        if (rc) {
 197                cifs_dbg(VFS, "%s: Could not update with response\n", __func__);
 198                return rc;
 199        }
 200
 201        rc = crypto_shash_init(shash);
 202        if (rc) {
 203                cifs_dbg(VFS, "%s: Could not init sha256", __func__);
 204                return rc;
 205        }
 206
 207        /*
 208         * For SMB2+, __cifs_calc_signature() expects to sign only the actual
 209         * data, that is, iov[0] should not contain a rfc1002 length.
 210         *
 211         * Sign the rfc1002 length prior to passing the data (iov[1-N]) down to
 212         * __cifs_calc_signature().
 213         */
 214        drqst = *rqst;
 215        if (drqst.rq_nvec >= 2 && iov[0].iov_len == 4) {
 216                rc = crypto_shash_update(shash, iov[0].iov_base,
 217                                         iov[0].iov_len);
 218                if (rc) {
 219                        cifs_dbg(VFS, "%s: Could not update with payload\n",
 220                                 __func__);
 221                        return rc;
 222                }
 223                drqst.rq_iov++;
 224                drqst.rq_nvec--;
 225        }
 226
 227        rc = __cifs_calc_signature(&drqst, server, sigptr, shash);
 228        if (!rc)
 229                memcpy(shdr->Signature, sigptr, SMB2_SIGNATURE_SIZE);
 230
 231        return rc;
 232}
 233
 234static int generate_key(struct cifs_ses *ses, struct kvec label,
 235                        struct kvec context, __u8 *key, unsigned int key_size)
 236{
 237        unsigned char zero = 0x0;
 238        __u8 i[4] = {0, 0, 0, 1};
 239        __u8 L[4] = {0, 0, 0, 128};
 240        int rc = 0;
 241        unsigned char prfhash[SMB2_HMACSHA256_SIZE];
 242        unsigned char *hashptr = prfhash;
 243
 244        memset(prfhash, 0x0, SMB2_HMACSHA256_SIZE);
 245        memset(key, 0x0, key_size);
 246
 247        rc = smb3_crypto_shash_allocate(ses->server);
 248        if (rc) {
 249                cifs_dbg(VFS, "%s: crypto alloc failed\n", __func__);
 250                goto smb3signkey_ret;
 251        }
 252
 253        rc = crypto_shash_setkey(ses->server->secmech.hmacsha256,
 254                ses->auth_key.response, SMB2_NTLMV2_SESSKEY_SIZE);
 255        if (rc) {
 256                cifs_dbg(VFS, "%s: Could not set with session key\n", __func__);
 257                goto smb3signkey_ret;
 258        }
 259
 260        rc = crypto_shash_init(&ses->server->secmech.sdeschmacsha256->shash);
 261        if (rc) {
 262                cifs_dbg(VFS, "%s: Could not init sign hmac\n", __func__);
 263                goto smb3signkey_ret;
 264        }
 265
 266        rc = crypto_shash_update(&ses->server->secmech.sdeschmacsha256->shash,
 267                                i, 4);
 268        if (rc) {
 269                cifs_dbg(VFS, "%s: Could not update with n\n", __func__);
 270                goto smb3signkey_ret;
 271        }
 272
 273        rc = crypto_shash_update(&ses->server->secmech.sdeschmacsha256->shash,
 274                                label.iov_base, label.iov_len);
 275        if (rc) {
 276                cifs_dbg(VFS, "%s: Could not update with label\n", __func__);
 277                goto smb3signkey_ret;
 278        }
 279
 280        rc = crypto_shash_update(&ses->server->secmech.sdeschmacsha256->shash,
 281                                &zero, 1);
 282        if (rc) {
 283                cifs_dbg(VFS, "%s: Could not update with zero\n", __func__);
 284                goto smb3signkey_ret;
 285        }
 286
 287        rc = crypto_shash_update(&ses->server->secmech.sdeschmacsha256->shash,
 288                                context.iov_base, context.iov_len);
 289        if (rc) {
 290                cifs_dbg(VFS, "%s: Could not update with context\n", __func__);
 291                goto smb3signkey_ret;
 292        }
 293
 294        rc = crypto_shash_update(&ses->server->secmech.sdeschmacsha256->shash,
 295                                L, 4);
 296        if (rc) {
 297                cifs_dbg(VFS, "%s: Could not update with L\n", __func__);
 298                goto smb3signkey_ret;
 299        }
 300
 301        rc = crypto_shash_final(&ses->server->secmech.sdeschmacsha256->shash,
 302                                hashptr);
 303        if (rc) {
 304                cifs_dbg(VFS, "%s: Could not generate sha256 hash\n", __func__);
 305                goto smb3signkey_ret;
 306        }
 307
 308        memcpy(key, hashptr, key_size);
 309
 310smb3signkey_ret:
 311        return rc;
 312}
 313
 314struct derivation {
 315        struct kvec label;
 316        struct kvec context;
 317};
 318
 319struct derivation_triplet {
 320        struct derivation signing;
 321        struct derivation encryption;
 322        struct derivation decryption;
 323};
 324
 325static int
 326generate_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
 370int
 371generate_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#ifdef CONFIG_CIFS_SMB311
 399int
 400generate_smb311signingkey(struct cifs_ses *ses)
 401
 402{
 403        struct derivation_triplet triplet;
 404        struct derivation *d;
 405
 406        d = &triplet.signing;
 407        d->label.iov_base = "SMBSigningKey";
 408        d->label.iov_len = 14;
 409        d->context.iov_base = ses->preauth_sha_hash;
 410        d->context.iov_len = 64;
 411
 412        d = &triplet.encryption;
 413        d->label.iov_base = "SMBC2SCipherKey";
 414        d->label.iov_len = 16;
 415        d->context.iov_base = ses->preauth_sha_hash;
 416        d->context.iov_len = 64;
 417
 418        d = &triplet.decryption;
 419        d->label.iov_base = "SMBS2CCipherKey";
 420        d->label.iov_len = 16;
 421        d->context.iov_base = ses->preauth_sha_hash;
 422        d->context.iov_len = 64;
 423
 424        return generate_smb3signingkey(ses, &triplet);
 425}
 426#endif /* 311 */
 427
 428int
 429smb3_calc_signature(struct smb_rqst *rqst, struct TCP_Server_Info *server)
 430{
 431        int rc;
 432        unsigned char smb3_signature[SMB2_CMACAES_SIZE];
 433        unsigned char *sigptr = smb3_signature;
 434        struct kvec *iov = rqst->rq_iov;
 435        struct smb2_sync_hdr *shdr = (struct smb2_sync_hdr *)iov[0].iov_base;
 436        struct cifs_ses *ses;
 437        struct shash_desc *shash = &server->secmech.sdesccmacaes->shash;
 438        struct smb_rqst drqst;
 439
 440        ses = smb2_find_smb_ses(server, shdr->SessionId);
 441        if (!ses) {
 442                cifs_dbg(VFS, "%s: Could not find session\n", __func__);
 443                return 0;
 444        }
 445
 446        memset(smb3_signature, 0x0, SMB2_CMACAES_SIZE);
 447        memset(shdr->Signature, 0x0, SMB2_SIGNATURE_SIZE);
 448
 449        rc = crypto_shash_setkey(server->secmech.cmacaes,
 450                                 ses->smb3signingkey, SMB2_CMACAES_SIZE);
 451        if (rc) {
 452                cifs_dbg(VFS, "%s: Could not set key for cmac aes\n", __func__);
 453                return rc;
 454        }
 455
 456        /*
 457         * we already allocate sdesccmacaes when we init smb3 signing key,
 458         * so unlike smb2 case we do not have to check here if secmech are
 459         * initialized
 460         */
 461        rc = crypto_shash_init(shash);
 462        if (rc) {
 463                cifs_dbg(VFS, "%s: Could not init cmac aes\n", __func__);
 464                return rc;
 465        }
 466
 467        /*
 468         * For SMB2+, __cifs_calc_signature() expects to sign only the actual
 469         * data, that is, iov[0] should not contain a rfc1002 length.
 470         *
 471         * Sign the rfc1002 length prior to passing the data (iov[1-N]) down to
 472         * __cifs_calc_signature().
 473         */
 474        drqst = *rqst;
 475        if (drqst.rq_nvec >= 2 && iov[0].iov_len == 4) {
 476                rc = crypto_shash_update(shash, iov[0].iov_base,
 477                                         iov[0].iov_len);
 478                if (rc) {
 479                        cifs_dbg(VFS, "%s: Could not update with payload\n",
 480                                 __func__);
 481                        return rc;
 482                }
 483                drqst.rq_iov++;
 484                drqst.rq_nvec--;
 485        }
 486
 487        rc = __cifs_calc_signature(&drqst, server, sigptr, shash);
 488        if (!rc)
 489                memcpy(shdr->Signature, sigptr, SMB2_SIGNATURE_SIZE);
 490
 491        return rc;
 492}
 493
 494/* must be called with server->srv_mutex held */
 495static int
 496smb2_sign_rqst(struct smb_rqst *rqst, struct TCP_Server_Info *server)
 497{
 498        int rc = 0;
 499        struct smb2_sync_hdr *shdr =
 500                        (struct smb2_sync_hdr *)rqst->rq_iov[0].iov_base;
 501
 502        if (!(shdr->Flags & SMB2_FLAGS_SIGNED) ||
 503            server->tcpStatus == CifsNeedNegotiate)
 504                return rc;
 505
 506        if (!server->session_estab) {
 507                strncpy(shdr->Signature, "BSRSPYL", 8);
 508                return rc;
 509        }
 510
 511        rc = server->ops->calc_signature(rqst, server);
 512
 513        return rc;
 514}
 515
 516int
 517smb2_verify_signature(struct smb_rqst *rqst, struct TCP_Server_Info *server)
 518{
 519        unsigned int rc;
 520        char server_response_sig[16];
 521        struct smb2_sync_hdr *shdr =
 522                        (struct smb2_sync_hdr *)rqst->rq_iov[0].iov_base;
 523
 524        if ((shdr->Command == SMB2_NEGOTIATE) ||
 525            (shdr->Command == SMB2_SESSION_SETUP) ||
 526            (shdr->Command == SMB2_OPLOCK_BREAK) ||
 527            (!server->session_estab))
 528                return 0;
 529
 530        /*
 531         * BB what if signatures are supposed to be on for session but
 532         * server does not send one? BB
 533         */
 534
 535        /* Do not need to verify session setups with signature "BSRSPYL " */
 536        if (memcmp(shdr->Signature, "BSRSPYL ", 8) == 0)
 537                cifs_dbg(FYI, "dummy signature received for smb command 0x%x\n",
 538                         shdr->Command);
 539
 540        /*
 541         * Save off the origiginal signature so we can modify the smb and check
 542         * our calculated signature against what the server sent.
 543         */
 544        memcpy(server_response_sig, shdr->Signature, SMB2_SIGNATURE_SIZE);
 545
 546        memset(shdr->Signature, 0, SMB2_SIGNATURE_SIZE);
 547
 548        mutex_lock(&server->srv_mutex);
 549        rc = server->ops->calc_signature(rqst, server);
 550        mutex_unlock(&server->srv_mutex);
 551
 552        if (rc)
 553                return rc;
 554
 555        if (memcmp(server_response_sig, shdr->Signature, SMB2_SIGNATURE_SIZE))
 556                return -EACCES;
 557        else
 558                return 0;
 559}
 560
 561/*
 562 * Set message id for the request. Should be called after wait_for_free_request
 563 * and when srv_mutex is held.
 564 */
 565static inline void
 566smb2_seq_num_into_buf(struct TCP_Server_Info *server,
 567                      struct smb2_sync_hdr *shdr)
 568{
 569        unsigned int i, num = le16_to_cpu(shdr->CreditCharge);
 570
 571        shdr->MessageId = get_next_mid64(server);
 572        /* skip message numbers according to CreditCharge field */
 573        for (i = 1; i < num; i++)
 574                get_next_mid(server);
 575}
 576
 577static struct mid_q_entry *
 578smb2_mid_entry_alloc(const struct smb2_sync_hdr *shdr,
 579                     struct TCP_Server_Info *server)
 580{
 581        struct mid_q_entry *temp;
 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->pid = current->pid;
 593        temp->command = shdr->Command; /* Always LE */
 594        temp->when_alloc = jiffies;
 595        temp->server = server;
 596
 597        /*
 598         * The default is for the mid to be synchronous, so the
 599         * default callback just wakes up the current task.
 600         */
 601        temp->callback = cifs_wake_up_task;
 602        temp->callback_data = current;
 603
 604        atomic_inc(&midCount);
 605        temp->mid_state = MID_REQUEST_ALLOCATED;
 606        return temp;
 607}
 608
 609static int
 610smb2_get_mid_entry(struct cifs_ses *ses, struct smb2_sync_hdr *shdr,
 611                   struct mid_q_entry **mid)
 612{
 613        if (ses->server->tcpStatus == CifsExiting)
 614                return -ENOENT;
 615
 616        if (ses->server->tcpStatus == CifsNeedReconnect) {
 617                cifs_dbg(FYI, "tcp session dead - return to caller to retry\n");
 618                return -EAGAIN;
 619        }
 620
 621        if (ses->status == CifsNew) {
 622                if ((shdr->Command != SMB2_SESSION_SETUP) &&
 623                    (shdr->Command != SMB2_NEGOTIATE))
 624                        return -EAGAIN;
 625                /* else ok - we are setting up session */
 626        }
 627
 628        if (ses->status == CifsExiting) {
 629                if (shdr->Command != SMB2_LOGOFF)
 630                        return -EAGAIN;
 631                /* else ok - we are shutting down the session */
 632        }
 633
 634        *mid = smb2_mid_entry_alloc(shdr, ses->server);
 635        if (*mid == NULL)
 636                return -ENOMEM;
 637        spin_lock(&GlobalMid_Lock);
 638        list_add_tail(&(*mid)->qhead, &ses->server->pending_mid_q);
 639        spin_unlock(&GlobalMid_Lock);
 640        return 0;
 641}
 642
 643int
 644smb2_check_receive(struct mid_q_entry *mid, struct TCP_Server_Info *server,
 645                   bool log_error)
 646{
 647        unsigned int len = mid->resp_buf_size;
 648        struct kvec iov[1];
 649        struct smb_rqst rqst = { .rq_iov = iov,
 650                                 .rq_nvec = 1 };
 651
 652        iov[0].iov_base = (char *)mid->resp_buf;
 653        iov[0].iov_len = len;
 654
 655        dump_smb(mid->resp_buf, min_t(u32, 80, len));
 656        /* convert the length into a more usable form */
 657        if (len > 24 && server->sign && !mid->decrypted) {
 658                int rc;
 659
 660                rc = smb2_verify_signature(&rqst, server);
 661                if (rc)
 662                        cifs_dbg(VFS, "SMB signature verification returned error = %d\n",
 663                                 rc);
 664        }
 665
 666        return map_smb2_to_linux_error(mid->resp_buf, log_error);
 667}
 668
 669struct mid_q_entry *
 670smb2_setup_request(struct cifs_ses *ses, struct smb_rqst *rqst)
 671{
 672        int rc;
 673        struct smb2_sync_hdr *shdr =
 674                        (struct smb2_sync_hdr *)rqst->rq_iov[0].iov_base;
 675        struct mid_q_entry *mid;
 676
 677        smb2_seq_num_into_buf(ses->server, shdr);
 678
 679        rc = smb2_get_mid_entry(ses, shdr, &mid);
 680        if (rc)
 681                return ERR_PTR(rc);
 682        rc = smb2_sign_rqst(rqst, ses->server);
 683        if (rc) {
 684                cifs_delete_mid(mid);
 685                return ERR_PTR(rc);
 686        }
 687        return mid;
 688}
 689
 690struct mid_q_entry *
 691smb2_setup_async_request(struct TCP_Server_Info *server, struct smb_rqst *rqst)
 692{
 693        int rc;
 694        struct smb2_sync_hdr *shdr =
 695                        (struct smb2_sync_hdr *)rqst->rq_iov[0].iov_base;
 696        struct mid_q_entry *mid;
 697
 698        smb2_seq_num_into_buf(server, shdr);
 699
 700        mid = smb2_mid_entry_alloc(shdr, server);
 701        if (mid == NULL)
 702                return ERR_PTR(-ENOMEM);
 703
 704        rc = smb2_sign_rqst(rqst, server);
 705        if (rc) {
 706                DeleteMidQEntry(mid);
 707                return ERR_PTR(rc);
 708        }
 709
 710        return mid;
 711}
 712
 713int
 714smb3_crypto_aead_allocate(struct TCP_Server_Info *server)
 715{
 716        struct crypto_aead *tfm;
 717
 718        if (!server->secmech.ccmaesencrypt) {
 719                tfm = crypto_alloc_aead("ccm(aes)", 0, 0);
 720                if (IS_ERR(tfm)) {
 721                        cifs_dbg(VFS, "%s: Failed to alloc encrypt aead\n",
 722                                 __func__);
 723                        return PTR_ERR(tfm);
 724                }
 725                server->secmech.ccmaesencrypt = tfm;
 726        }
 727
 728        if (!server->secmech.ccmaesdecrypt) {
 729                tfm = crypto_alloc_aead("ccm(aes)", 0, 0);
 730                if (IS_ERR(tfm)) {
 731                        crypto_free_aead(server->secmech.ccmaesencrypt);
 732                        server->secmech.ccmaesencrypt = NULL;
 733                        cifs_dbg(VFS, "%s: Failed to alloc decrypt aead\n",
 734                                 __func__);
 735                        return PTR_ERR(tfm);
 736                }
 737                server->secmech.ccmaesdecrypt = tfm;
 738        }
 739
 740        return 0;
 741}
 742