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 "smb2pdu.h"
  35#include "cifsglob.h"
  36#include "cifsproto.h"
  37#include "smb2proto.h"
  38#include "cifs_debug.h"
  39#include "smb2status.h"
  40#include "smb2glob.h"
  41
  42static int
  43smb2_crypto_shash_allocate(struct TCP_Server_Info *server)
  44{
  45        int rc;
  46        unsigned int size;
  47
  48        if (server->secmech.sdeschmacsha256 != NULL)
  49                return 0; /* already allocated */
  50
  51        server->secmech.hmacsha256 = crypto_alloc_shash("hmac(sha256)", 0, 0);
  52        if (IS_ERR(server->secmech.hmacsha256)) {
  53                cifs_dbg(VFS, "could not allocate crypto hmacsha256\n");
  54                rc = PTR_ERR(server->secmech.hmacsha256);
  55                server->secmech.hmacsha256 = NULL;
  56                return rc;
  57        }
  58
  59        size = sizeof(struct shash_desc) +
  60                        crypto_shash_descsize(server->secmech.hmacsha256);
  61        server->secmech.sdeschmacsha256 = kmalloc(size, GFP_KERNEL);
  62        if (!server->secmech.sdeschmacsha256) {
  63                crypto_free_shash(server->secmech.hmacsha256);
  64                server->secmech.hmacsha256 = NULL;
  65                return -ENOMEM;
  66        }
  67        server->secmech.sdeschmacsha256->shash.tfm = server->secmech.hmacsha256;
  68        server->secmech.sdeschmacsha256->shash.flags = 0x0;
  69
  70        return 0;
  71}
  72
  73static int
  74smb3_crypto_shash_allocate(struct TCP_Server_Info *server)
  75{
  76        unsigned int size;
  77        int rc;
  78
  79        if (server->secmech.sdesccmacaes != NULL)
  80                return 0;  /* already allocated */
  81
  82        rc = smb2_crypto_shash_allocate(server);
  83        if (rc)
  84                return rc;
  85
  86        server->secmech.cmacaes = crypto_alloc_shash("cmac(aes)", 0, 0);
  87        if (IS_ERR(server->secmech.cmacaes)) {
  88                cifs_dbg(VFS, "could not allocate crypto cmac-aes");
  89                kfree(server->secmech.sdeschmacsha256);
  90                server->secmech.sdeschmacsha256 = NULL;
  91                crypto_free_shash(server->secmech.hmacsha256);
  92                server->secmech.hmacsha256 = NULL;
  93                rc = PTR_ERR(server->secmech.cmacaes);
  94                server->secmech.cmacaes = NULL;
  95                return rc;
  96        }
  97
  98        size = sizeof(struct shash_desc) +
  99                        crypto_shash_descsize(server->secmech.cmacaes);
 100        server->secmech.sdesccmacaes = kmalloc(size, GFP_KERNEL);
 101        if (!server->secmech.sdesccmacaes) {
 102                cifs_dbg(VFS, "%s: Can't alloc cmacaes\n", __func__);
 103                kfree(server->secmech.sdeschmacsha256);
 104                server->secmech.sdeschmacsha256 = NULL;
 105                crypto_free_shash(server->secmech.hmacsha256);
 106                crypto_free_shash(server->secmech.cmacaes);
 107                server->secmech.hmacsha256 = NULL;
 108                server->secmech.cmacaes = NULL;
 109                return -ENOMEM;
 110        }
 111        server->secmech.sdesccmacaes->shash.tfm = server->secmech.cmacaes;
 112        server->secmech.sdesccmacaes->shash.flags = 0x0;
 113
 114        return 0;
 115}
 116
 117static struct cifs_ses *
 118smb2_find_smb_ses(struct smb2_hdr *smb2hdr, struct TCP_Server_Info *server)
 119{
 120        struct cifs_ses *ses;
 121
 122        spin_lock(&cifs_tcp_ses_lock);
 123        list_for_each_entry(ses, &server->smb_ses_list, smb_ses_list) {
 124                if (ses->Suid != smb2hdr->SessionId)
 125                        continue;
 126                spin_unlock(&cifs_tcp_ses_lock);
 127                return ses;
 128        }
 129        spin_unlock(&cifs_tcp_ses_lock);
 130
 131        return NULL;
 132}
 133
 134
 135int
 136smb2_calc_signature(struct smb_rqst *rqst, struct TCP_Server_Info *server)
 137{
 138        int i, rc;
 139        unsigned char smb2_signature[SMB2_HMACSHA256_SIZE];
 140        unsigned char *sigptr = smb2_signature;
 141        struct kvec *iov = rqst->rq_iov;
 142        int n_vec = rqst->rq_nvec;
 143        struct smb2_hdr *smb2_pdu = (struct smb2_hdr *)iov[0].iov_base;
 144        struct cifs_ses *ses;
 145
 146        ses = smb2_find_smb_ses(smb2_pdu, server);
 147        if (!ses) {
 148                cifs_dbg(VFS, "%s: Could not find session\n", __func__);
 149                return 0;
 150        }
 151
 152        memset(smb2_signature, 0x0, SMB2_HMACSHA256_SIZE);
 153        memset(smb2_pdu->Signature, 0x0, SMB2_SIGNATURE_SIZE);
 154
 155        rc = smb2_crypto_shash_allocate(server);
 156        if (rc) {
 157                cifs_dbg(VFS, "%s: shah256 alloc failed\n", __func__);
 158                return rc;
 159        }
 160
 161        rc = crypto_shash_setkey(server->secmech.hmacsha256,
 162                ses->auth_key.response, SMB2_NTLMV2_SESSKEY_SIZE);
 163        if (rc) {
 164                cifs_dbg(VFS, "%s: Could not update with response\n", __func__);
 165                return rc;
 166        }
 167
 168        rc = crypto_shash_init(&server->secmech.sdeschmacsha256->shash);
 169        if (rc) {
 170                cifs_dbg(VFS, "%s: Could not init sha256", __func__);
 171                return rc;
 172        }
 173
 174        for (i = 0; i < n_vec; i++) {
 175                if (iov[i].iov_len == 0)
 176                        continue;
 177                if (iov[i].iov_base == NULL) {
 178                        cifs_dbg(VFS, "null iovec entry\n");
 179                        return -EIO;
 180                }
 181                /*
 182                 * The first entry includes a length field (which does not get
 183                 * signed that occupies the first 4 bytes before the header).
 184                 */
 185                if (i == 0) {
 186                        if (iov[0].iov_len <= 8) /* cmd field at offset 9 */
 187                                break; /* nothing to sign or corrupt header */
 188                        rc =
 189                        crypto_shash_update(
 190                                &server->secmech.sdeschmacsha256->shash,
 191                                iov[i].iov_base + 4, iov[i].iov_len - 4);
 192                } else {
 193                        rc =
 194                        crypto_shash_update(
 195                                &server->secmech.sdeschmacsha256->shash,
 196                                iov[i].iov_base, iov[i].iov_len);
 197                }
 198                if (rc) {
 199                        cifs_dbg(VFS, "%s: Could not update with payload\n",
 200                                 __func__);
 201                        return rc;
 202                }
 203        }
 204
 205        /* now hash over the rq_pages array */
 206        for (i = 0; i < rqst->rq_npages; i++) {
 207                struct kvec p_iov;
 208
 209                cifs_rqst_page_to_kvec(rqst, i, &p_iov);
 210                crypto_shash_update(&server->secmech.sdeschmacsha256->shash,
 211                                        p_iov.iov_base, p_iov.iov_len);
 212                kunmap(rqst->rq_pages[i]);
 213        }
 214
 215        rc = crypto_shash_final(&server->secmech.sdeschmacsha256->shash,
 216                                sigptr);
 217        if (rc)
 218                cifs_dbg(VFS, "%s: Could not generate sha256 hash\n", __func__);
 219
 220        memcpy(smb2_pdu->Signature, sigptr, SMB2_SIGNATURE_SIZE);
 221
 222        return rc;
 223}
 224
 225int
 226generate_smb3signingkey(struct cifs_ses *ses)
 227{
 228        unsigned char zero = 0x0;
 229        __u8 i[4] = {0, 0, 0, 1};
 230        __u8 L[4] = {0, 0, 0, 128};
 231        int rc = 0;
 232        unsigned char prfhash[SMB2_HMACSHA256_SIZE];
 233        unsigned char *hashptr = prfhash;
 234
 235        memset(prfhash, 0x0, SMB2_HMACSHA256_SIZE);
 236        memset(ses->smb3signingkey, 0x0, SMB3_SIGNKEY_SIZE);
 237
 238        rc = smb3_crypto_shash_allocate(ses->server);
 239        if (rc) {
 240                cifs_dbg(VFS, "%s: crypto alloc failed\n", __func__);
 241                goto smb3signkey_ret;
 242        }
 243
 244        rc = crypto_shash_setkey(ses->server->secmech.hmacsha256,
 245                ses->auth_key.response, SMB2_NTLMV2_SESSKEY_SIZE);
 246        if (rc) {
 247                cifs_dbg(VFS, "%s: Could not set with session key\n", __func__);
 248                goto smb3signkey_ret;
 249        }
 250
 251        rc = crypto_shash_init(&ses->server->secmech.sdeschmacsha256->shash);
 252        if (rc) {
 253                cifs_dbg(VFS, "%s: Could not init sign hmac\n", __func__);
 254                goto smb3signkey_ret;
 255        }
 256
 257        rc = crypto_shash_update(&ses->server->secmech.sdeschmacsha256->shash,
 258                                i, 4);
 259        if (rc) {
 260                cifs_dbg(VFS, "%s: Could not update with n\n", __func__);
 261                goto smb3signkey_ret;
 262        }
 263
 264        rc = crypto_shash_update(&ses->server->secmech.sdeschmacsha256->shash,
 265                                "SMB2AESCMAC", 12);
 266        if (rc) {
 267                cifs_dbg(VFS, "%s: Could not update with label\n", __func__);
 268                goto smb3signkey_ret;
 269        }
 270
 271        rc = crypto_shash_update(&ses->server->secmech.sdeschmacsha256->shash,
 272                                &zero, 1);
 273        if (rc) {
 274                cifs_dbg(VFS, "%s: Could not update with zero\n", __func__);
 275                goto smb3signkey_ret;
 276        }
 277
 278        rc = crypto_shash_update(&ses->server->secmech.sdeschmacsha256->shash,
 279                                "SmbSign", 8);
 280        if (rc) {
 281                cifs_dbg(VFS, "%s: Could not update with context\n", __func__);
 282                goto smb3signkey_ret;
 283        }
 284
 285        rc = crypto_shash_update(&ses->server->secmech.sdeschmacsha256->shash,
 286                                L, 4);
 287        if (rc) {
 288                cifs_dbg(VFS, "%s: Could not update with L\n", __func__);
 289                goto smb3signkey_ret;
 290        }
 291
 292        rc = crypto_shash_final(&ses->server->secmech.sdeschmacsha256->shash,
 293                                hashptr);
 294        if (rc) {
 295                cifs_dbg(VFS, "%s: Could not generate sha256 hash\n", __func__);
 296                goto smb3signkey_ret;
 297        }
 298
 299        memcpy(ses->smb3signingkey, hashptr, SMB3_SIGNKEY_SIZE);
 300
 301smb3signkey_ret:
 302        return rc;
 303}
 304
 305int
 306smb3_calc_signature(struct smb_rqst *rqst, struct TCP_Server_Info *server)
 307{
 308        int i;
 309        int rc = 0;
 310        unsigned char smb3_signature[SMB2_CMACAES_SIZE];
 311        unsigned char *sigptr = smb3_signature;
 312        struct kvec *iov = rqst->rq_iov;
 313        int n_vec = rqst->rq_nvec;
 314        struct smb2_hdr *smb2_pdu = (struct smb2_hdr *)iov[0].iov_base;
 315        struct cifs_ses *ses;
 316
 317        ses = smb2_find_smb_ses(smb2_pdu, server);
 318        if (!ses) {
 319                cifs_dbg(VFS, "%s: Could not find session\n", __func__);
 320                return 0;
 321        }
 322
 323        memset(smb3_signature, 0x0, SMB2_CMACAES_SIZE);
 324        memset(smb2_pdu->Signature, 0x0, SMB2_SIGNATURE_SIZE);
 325
 326        rc = crypto_shash_setkey(server->secmech.cmacaes,
 327                ses->smb3signingkey, SMB2_CMACAES_SIZE);
 328
 329        if (rc) {
 330                cifs_dbg(VFS, "%s: Could not set key for cmac aes\n", __func__);
 331                return rc;
 332        }
 333
 334        /*
 335         * we already allocate sdesccmacaes when we init smb3 signing key,
 336         * so unlike smb2 case we do not have to check here if secmech are
 337         * initialized
 338         */
 339        rc = crypto_shash_init(&server->secmech.sdesccmacaes->shash);
 340        if (rc) {
 341                cifs_dbg(VFS, "%s: Could not init cmac aes\n", __func__);
 342                return rc;
 343        }
 344
 345        for (i = 0; i < n_vec; i++) {
 346                if (iov[i].iov_len == 0)
 347                        continue;
 348                if (iov[i].iov_base == NULL) {
 349                        cifs_dbg(VFS, "null iovec entry");
 350                        return -EIO;
 351                }
 352                /*
 353                 * The first entry includes a length field (which does not get
 354                 * signed that occupies the first 4 bytes before the header).
 355                 */
 356                if (i == 0) {
 357                        if (iov[0].iov_len <= 8) /* cmd field at offset 9 */
 358                                break; /* nothing to sign or corrupt header */
 359                        rc =
 360                        crypto_shash_update(
 361                                &server->secmech.sdesccmacaes->shash,
 362                                iov[i].iov_base + 4, iov[i].iov_len - 4);
 363                } else {
 364                        rc =
 365                        crypto_shash_update(
 366                                &server->secmech.sdesccmacaes->shash,
 367                                iov[i].iov_base, iov[i].iov_len);
 368                }
 369                if (rc) {
 370                        cifs_dbg(VFS, "%s: Couldn't update cmac aes with payload\n",
 371                                                        __func__);
 372                        return rc;
 373                }
 374        }
 375
 376        /* now hash over the rq_pages array */
 377        for (i = 0; i < rqst->rq_npages; i++) {
 378                struct kvec p_iov;
 379
 380                cifs_rqst_page_to_kvec(rqst, i, &p_iov);
 381                crypto_shash_update(&server->secmech.sdesccmacaes->shash,
 382                                        p_iov.iov_base, p_iov.iov_len);
 383                kunmap(rqst->rq_pages[i]);
 384        }
 385
 386        rc = crypto_shash_final(&server->secmech.sdesccmacaes->shash,
 387                                                sigptr);
 388        if (rc)
 389                cifs_dbg(VFS, "%s: Could not generate cmac aes\n", __func__);
 390
 391        memcpy(smb2_pdu->Signature, sigptr, SMB2_SIGNATURE_SIZE);
 392
 393        return rc;
 394}
 395
 396/* must be called with server->srv_mutex held */
 397static int
 398smb2_sign_rqst(struct smb_rqst *rqst, struct TCP_Server_Info *server)
 399{
 400        int rc = 0;
 401        struct smb2_hdr *smb2_pdu = rqst->rq_iov[0].iov_base;
 402
 403        if (!(smb2_pdu->Flags & SMB2_FLAGS_SIGNED) ||
 404            server->tcpStatus == CifsNeedNegotiate)
 405                return rc;
 406
 407        if (!server->session_estab) {
 408                strncpy(smb2_pdu->Signature, "BSRSPYL", 8);
 409                return rc;
 410        }
 411
 412        rc = server->ops->calc_signature(rqst, server);
 413
 414        return rc;
 415}
 416
 417int
 418smb2_verify_signature(struct smb_rqst *rqst, struct TCP_Server_Info *server)
 419{
 420        unsigned int rc;
 421        char server_response_sig[16];
 422        struct smb2_hdr *smb2_pdu = (struct smb2_hdr *)rqst->rq_iov[0].iov_base;
 423
 424        if ((smb2_pdu->Command == SMB2_NEGOTIATE) ||
 425            (smb2_pdu->Command == SMB2_SESSION_SETUP) ||
 426            (smb2_pdu->Command == SMB2_OPLOCK_BREAK) ||
 427            (!server->session_estab))
 428                return 0;
 429
 430        /*
 431         * BB what if signatures are supposed to be on for session but
 432         * server does not send one? BB
 433         */
 434
 435        /* Do not need to verify session setups with signature "BSRSPYL " */
 436        if (memcmp(smb2_pdu->Signature, "BSRSPYL ", 8) == 0)
 437                cifs_dbg(FYI, "dummy signature received for smb command 0x%x\n",
 438                         smb2_pdu->Command);
 439
 440        /*
 441         * Save off the origiginal signature so we can modify the smb and check
 442         * our calculated signature against what the server sent.
 443         */
 444        memcpy(server_response_sig, smb2_pdu->Signature, SMB2_SIGNATURE_SIZE);
 445
 446        memset(smb2_pdu->Signature, 0, SMB2_SIGNATURE_SIZE);
 447
 448        mutex_lock(&server->srv_mutex);
 449        rc = server->ops->calc_signature(rqst, server);
 450        mutex_unlock(&server->srv_mutex);
 451
 452        if (rc)
 453                return rc;
 454
 455        if (memcmp(server_response_sig, smb2_pdu->Signature,
 456                   SMB2_SIGNATURE_SIZE))
 457                return -EACCES;
 458        else
 459                return 0;
 460}
 461
 462/*
 463 * Set message id for the request. Should be called after wait_for_free_request
 464 * and when srv_mutex is held.
 465 */
 466static inline void
 467smb2_seq_num_into_buf(struct TCP_Server_Info *server, struct smb2_hdr *hdr)
 468{
 469        hdr->MessageId = get_next_mid64(server);
 470}
 471
 472static struct mid_q_entry *
 473smb2_mid_entry_alloc(const struct smb2_hdr *smb_buffer,
 474                     struct TCP_Server_Info *server)
 475{
 476        struct mid_q_entry *temp;
 477
 478        if (server == NULL) {
 479                cifs_dbg(VFS, "Null TCP session in smb2_mid_entry_alloc\n");
 480                return NULL;
 481        }
 482
 483        temp = mempool_alloc(cifs_mid_poolp, GFP_NOFS);
 484        if (temp == NULL)
 485                return temp;
 486        else {
 487                memset(temp, 0, sizeof(struct mid_q_entry));
 488                temp->mid = smb_buffer->MessageId;      /* always LE */
 489                temp->pid = current->pid;
 490                temp->command = smb_buffer->Command;    /* Always LE */
 491                temp->when_alloc = jiffies;
 492                temp->server = server;
 493
 494                /*
 495                 * The default is for the mid to be synchronous, so the
 496                 * default callback just wakes up the current task.
 497                 */
 498                temp->callback = cifs_wake_up_task;
 499                temp->callback_data = current;
 500        }
 501
 502        atomic_inc(&midCount);
 503        temp->mid_state = MID_REQUEST_ALLOCATED;
 504        return temp;
 505}
 506
 507static int
 508smb2_get_mid_entry(struct cifs_ses *ses, struct smb2_hdr *buf,
 509                   struct mid_q_entry **mid)
 510{
 511        if (ses->server->tcpStatus == CifsExiting)
 512                return -ENOENT;
 513
 514        if (ses->server->tcpStatus == CifsNeedReconnect) {
 515                cifs_dbg(FYI, "tcp session dead - return to caller to retry\n");
 516                return -EAGAIN;
 517        }
 518
 519        if (ses->status == CifsNew) {
 520                if ((buf->Command != SMB2_SESSION_SETUP) &&
 521                    (buf->Command != SMB2_NEGOTIATE))
 522                        return -EAGAIN;
 523                /* else ok - we are setting up session */
 524        }
 525
 526        if (ses->status == CifsExiting) {
 527                if (buf->Command != SMB2_LOGOFF)
 528                        return -EAGAIN;
 529                /* else ok - we are shutting down the session */
 530        }
 531
 532        *mid = smb2_mid_entry_alloc(buf, ses->server);
 533        if (*mid == NULL)
 534                return -ENOMEM;
 535        spin_lock(&GlobalMid_Lock);
 536        list_add_tail(&(*mid)->qhead, &ses->server->pending_mid_q);
 537        spin_unlock(&GlobalMid_Lock);
 538        return 0;
 539}
 540
 541int
 542smb2_check_receive(struct mid_q_entry *mid, struct TCP_Server_Info *server,
 543                   bool log_error)
 544{
 545        unsigned int len = get_rfc1002_length(mid->resp_buf);
 546        struct kvec iov;
 547        struct smb_rqst rqst = { .rq_iov = &iov,
 548                                 .rq_nvec = 1 };
 549
 550        iov.iov_base = (char *)mid->resp_buf;
 551        iov.iov_len = get_rfc1002_length(mid->resp_buf) + 4;
 552
 553        dump_smb(mid->resp_buf, min_t(u32, 80, len));
 554        /* convert the length into a more usable form */
 555        if (len > 24 && server->sign) {
 556                int rc;
 557
 558                rc = smb2_verify_signature(&rqst, server);
 559                if (rc)
 560                        cifs_dbg(VFS, "SMB signature verification returned error = %d\n",
 561                                 rc);
 562        }
 563
 564        return map_smb2_to_linux_error(mid->resp_buf, log_error);
 565}
 566
 567struct mid_q_entry *
 568smb2_setup_request(struct cifs_ses *ses, struct smb_rqst *rqst)
 569{
 570        int rc;
 571        struct smb2_hdr *hdr = (struct smb2_hdr *)rqst->rq_iov[0].iov_base;
 572        struct mid_q_entry *mid;
 573
 574        smb2_seq_num_into_buf(ses->server, hdr);
 575
 576        rc = smb2_get_mid_entry(ses, hdr, &mid);
 577        if (rc)
 578                return ERR_PTR(rc);
 579        rc = smb2_sign_rqst(rqst, ses->server);
 580        if (rc) {
 581                cifs_delete_mid(mid);
 582                return ERR_PTR(rc);
 583        }
 584        return mid;
 585}
 586
 587struct mid_q_entry *
 588smb2_setup_async_request(struct TCP_Server_Info *server, struct smb_rqst *rqst)
 589{
 590        int rc;
 591        struct smb2_hdr *hdr = (struct smb2_hdr *)rqst->rq_iov[0].iov_base;
 592        struct mid_q_entry *mid;
 593
 594        smb2_seq_num_into_buf(server, hdr);
 595
 596        mid = smb2_mid_entry_alloc(hdr, server);
 597        if (mid == NULL)
 598                return ERR_PTR(-ENOMEM);
 599
 600        rc = smb2_sign_rqst(rqst, server);
 601        if (rc) {
 602                DeleteMidQEntry(mid);
 603                return ERR_PTR(rc);
 604        }
 605
 606        return mid;
 607}
 608