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