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