linux/fs/cifs/cifsencrypt.c
<<
>>
Prefs
   1/*
   2 *   fs/cifs/cifsencrypt.c
   3 *
   4 *   Encryption and hashing operations relating to NTLM, NTLMv2.  See MS-NLMP
   5 *   for more detailed information
   6 *
   7 *   Copyright (C) International Business Machines  Corp., 2005,2013
   8 *   Author(s): Steve French (sfrench@us.ibm.com)
   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/slab.h>
  27#include "cifspdu.h"
  28#include "cifsglob.h"
  29#include "cifs_debug.h"
  30#include "cifs_unicode.h"
  31#include "cifsproto.h"
  32#include "ntlmssp.h"
  33#include <linux/ctype.h>
  34#include <linux/random.h>
  35#include <linux/highmem.h>
  36#include <crypto/skcipher.h>
  37
  38static int
  39cifs_crypto_shash_md5_allocate(struct TCP_Server_Info *server)
  40{
  41        int rc;
  42        unsigned int size;
  43
  44        if (server->secmech.sdescmd5 != NULL)
  45                return 0; /* already allocated */
  46
  47        server->secmech.md5 = crypto_alloc_shash("md5", 0, 0);
  48        if (IS_ERR(server->secmech.md5)) {
  49                cifs_dbg(VFS, "could not allocate crypto md5\n");
  50                rc = PTR_ERR(server->secmech.md5);
  51                server->secmech.md5 = NULL;
  52                return rc;
  53        }
  54
  55        size = sizeof(struct shash_desc) +
  56                        crypto_shash_descsize(server->secmech.md5);
  57        server->secmech.sdescmd5 = kmalloc(size, GFP_KERNEL);
  58        if (!server->secmech.sdescmd5) {
  59                crypto_free_shash(server->secmech.md5);
  60                server->secmech.md5 = NULL;
  61                return -ENOMEM;
  62        }
  63        server->secmech.sdescmd5->shash.tfm = server->secmech.md5;
  64        server->secmech.sdescmd5->shash.flags = 0x0;
  65
  66        return 0;
  67}
  68
  69int __cifs_calc_signature(struct smb_rqst *rqst,
  70                        struct TCP_Server_Info *server, char *signature,
  71                        struct shash_desc *shash)
  72{
  73        int i;
  74        int rc;
  75        struct kvec *iov = rqst->rq_iov;
  76        int n_vec = rqst->rq_nvec;
  77
  78        for (i = 0; i < n_vec; i++) {
  79                if (iov[i].iov_len == 0)
  80                        continue;
  81                if (iov[i].iov_base == NULL) {
  82                        cifs_dbg(VFS, "null iovec entry\n");
  83                        return -EIO;
  84                }
  85                /* The first entry includes a length field (which does not get
  86                   signed that occupies the first 4 bytes before the header */
  87                if (i == 0) {
  88                        if (iov[0].iov_len <= 8) /* cmd field at offset 9 */
  89                                break; /* nothing to sign or corrupt header */
  90                        rc = crypto_shash_update(shash,
  91                                iov[i].iov_base + 4, iov[i].iov_len - 4);
  92                } else {
  93                        rc = crypto_shash_update(shash,
  94                                iov[i].iov_base, iov[i].iov_len);
  95                }
  96                if (rc) {
  97                        cifs_dbg(VFS, "%s: Could not update with payload\n",
  98                                 __func__);
  99                        return rc;
 100                }
 101        }
 102
 103        /* now hash over the rq_pages array */
 104        for (i = 0; i < rqst->rq_npages; i++) {
 105                void *kaddr = kmap(rqst->rq_pages[i]);
 106                size_t len = rqst->rq_pagesz;
 107
 108                if (i == rqst->rq_npages - 1)
 109                        len = rqst->rq_tailsz;
 110
 111                crypto_shash_update(shash, kaddr, len);
 112
 113                kunmap(rqst->rq_pages[i]);
 114        }
 115
 116        rc = crypto_shash_final(shash, signature);
 117        if (rc)
 118                cifs_dbg(VFS, "%s: Could not generate hash\n", __func__);
 119
 120        return rc;
 121}
 122
 123/*
 124 * Calculate and return the CIFS signature based on the mac key and SMB PDU.
 125 * The 16 byte signature must be allocated by the caller. Note we only use the
 126 * 1st eight bytes and that the smb header signature field on input contains
 127 * the sequence number before this function is called. Also, this function
 128 * should be called with the server->srv_mutex held.
 129 */
 130static int cifs_calc_signature(struct smb_rqst *rqst,
 131                        struct TCP_Server_Info *server, char *signature)
 132{
 133        int rc;
 134
 135        if (!rqst->rq_iov || !signature || !server)
 136                return -EINVAL;
 137
 138        if (!server->secmech.sdescmd5) {
 139                rc = cifs_crypto_shash_md5_allocate(server);
 140                if (rc) {
 141                        cifs_dbg(VFS, "%s: Can't alloc md5 crypto\n", __func__);
 142                        return -1;
 143                }
 144        }
 145
 146        rc = crypto_shash_init(&server->secmech.sdescmd5->shash);
 147        if (rc) {
 148                cifs_dbg(VFS, "%s: Could not init md5\n", __func__);
 149                return rc;
 150        }
 151
 152        rc = crypto_shash_update(&server->secmech.sdescmd5->shash,
 153                server->session_key.response, server->session_key.len);
 154        if (rc) {
 155                cifs_dbg(VFS, "%s: Could not update with response\n", __func__);
 156                return rc;
 157        }
 158
 159        return __cifs_calc_signature(rqst, server, signature,
 160                                     &server->secmech.sdescmd5->shash);
 161}
 162
 163/* must be called with server->srv_mutex held */
 164int cifs_sign_rqst(struct smb_rqst *rqst, struct TCP_Server_Info *server,
 165                   __u32 *pexpected_response_sequence_number)
 166{
 167        int rc = 0;
 168        char smb_signature[20];
 169        struct smb_hdr *cifs_pdu = (struct smb_hdr *)rqst->rq_iov[0].iov_base;
 170
 171        if ((cifs_pdu == NULL) || (server == NULL))
 172                return -EINVAL;
 173
 174        if (!(cifs_pdu->Flags2 & SMBFLG2_SECURITY_SIGNATURE) ||
 175            server->tcpStatus == CifsNeedNegotiate)
 176                return rc;
 177
 178        if (!server->session_estab) {
 179                memcpy(cifs_pdu->Signature.SecuritySignature, "BSRSPYL", 8);
 180                return rc;
 181        }
 182
 183        cifs_pdu->Signature.Sequence.SequenceNumber =
 184                                cpu_to_le32(server->sequence_number);
 185        cifs_pdu->Signature.Sequence.Reserved = 0;
 186
 187        *pexpected_response_sequence_number = ++server->sequence_number;
 188        ++server->sequence_number;
 189
 190        rc = cifs_calc_signature(rqst, server, smb_signature);
 191        if (rc)
 192                memset(cifs_pdu->Signature.SecuritySignature, 0, 8);
 193        else
 194                memcpy(cifs_pdu->Signature.SecuritySignature, smb_signature, 8);
 195
 196        return rc;
 197}
 198
 199int cifs_sign_smbv(struct kvec *iov, int n_vec, struct TCP_Server_Info *server,
 200                   __u32 *pexpected_response_sequence)
 201{
 202        struct smb_rqst rqst = { .rq_iov = iov,
 203                                 .rq_nvec = n_vec };
 204
 205        return cifs_sign_rqst(&rqst, server, pexpected_response_sequence);
 206}
 207
 208/* must be called with server->srv_mutex held */
 209int cifs_sign_smb(struct smb_hdr *cifs_pdu, struct TCP_Server_Info *server,
 210                  __u32 *pexpected_response_sequence_number)
 211{
 212        struct kvec iov;
 213
 214        iov.iov_base = cifs_pdu;
 215        iov.iov_len = be32_to_cpu(cifs_pdu->smb_buf_length) + 4;
 216
 217        return cifs_sign_smbv(&iov, 1, server,
 218                              pexpected_response_sequence_number);
 219}
 220
 221int cifs_verify_signature(struct smb_rqst *rqst,
 222                          struct TCP_Server_Info *server,
 223                          __u32 expected_sequence_number)
 224{
 225        unsigned int rc;
 226        char server_response_sig[8];
 227        char what_we_think_sig_should_be[20];
 228        struct smb_hdr *cifs_pdu = (struct smb_hdr *)rqst->rq_iov[0].iov_base;
 229
 230        if (cifs_pdu == NULL || server == NULL)
 231                return -EINVAL;
 232
 233        if (!server->session_estab)
 234                return 0;
 235
 236        if (cifs_pdu->Command == SMB_COM_LOCKING_ANDX) {
 237                struct smb_com_lock_req *pSMB =
 238                        (struct smb_com_lock_req *)cifs_pdu;
 239            if (pSMB->LockType & LOCKING_ANDX_OPLOCK_RELEASE)
 240                        return 0;
 241        }
 242
 243        /* BB what if signatures are supposed to be on for session but
 244           server does not send one? BB */
 245
 246        /* Do not need to verify session setups with signature "BSRSPYL "  */
 247        if (memcmp(cifs_pdu->Signature.SecuritySignature, "BSRSPYL ", 8) == 0)
 248                cifs_dbg(FYI, "dummy signature received for smb command 0x%x\n",
 249                         cifs_pdu->Command);
 250
 251        /* save off the origiginal signature so we can modify the smb and check
 252                its signature against what the server sent */
 253        memcpy(server_response_sig, cifs_pdu->Signature.SecuritySignature, 8);
 254
 255        cifs_pdu->Signature.Sequence.SequenceNumber =
 256                                        cpu_to_le32(expected_sequence_number);
 257        cifs_pdu->Signature.Sequence.Reserved = 0;
 258
 259        mutex_lock(&server->srv_mutex);
 260        rc = cifs_calc_signature(rqst, server, what_we_think_sig_should_be);
 261        mutex_unlock(&server->srv_mutex);
 262
 263        if (rc)
 264                return rc;
 265
 266/*      cifs_dump_mem("what we think it should be: ",
 267                      what_we_think_sig_should_be, 16); */
 268
 269        if (memcmp(server_response_sig, what_we_think_sig_should_be, 8))
 270                return -EACCES;
 271        else
 272                return 0;
 273
 274}
 275
 276/* first calculate 24 bytes ntlm response and then 16 byte session key */
 277int setup_ntlm_response(struct cifs_ses *ses, const struct nls_table *nls_cp)
 278{
 279        int rc = 0;
 280        unsigned int temp_len = CIFS_SESS_KEY_SIZE + CIFS_AUTH_RESP_SIZE;
 281        char temp_key[CIFS_SESS_KEY_SIZE];
 282
 283        if (!ses)
 284                return -EINVAL;
 285
 286        ses->auth_key.response = kmalloc(temp_len, GFP_KERNEL);
 287        if (!ses->auth_key.response)
 288                return -ENOMEM;
 289
 290        ses->auth_key.len = temp_len;
 291
 292        rc = SMBNTencrypt(ses->password, ses->server->cryptkey,
 293                        ses->auth_key.response + CIFS_SESS_KEY_SIZE, nls_cp);
 294        if (rc) {
 295                cifs_dbg(FYI, "%s Can't generate NTLM response, error: %d\n",
 296                         __func__, rc);
 297                return rc;
 298        }
 299
 300        rc = E_md4hash(ses->password, temp_key, nls_cp);
 301        if (rc) {
 302                cifs_dbg(FYI, "%s Can't generate NT hash, error: %d\n",
 303                         __func__, rc);
 304                return rc;
 305        }
 306
 307        rc = mdfour(ses->auth_key.response, temp_key, CIFS_SESS_KEY_SIZE);
 308        if (rc)
 309                cifs_dbg(FYI, "%s Can't generate NTLM session key, error: %d\n",
 310                         __func__, rc);
 311
 312        return rc;
 313}
 314
 315#ifdef CONFIG_CIFS_WEAK_PW_HASH
 316int calc_lanman_hash(const char *password, const char *cryptkey, bool encrypt,
 317                        char *lnm_session_key)
 318{
 319        int i;
 320        int rc;
 321        char password_with_pad[CIFS_ENCPWD_SIZE];
 322
 323        memset(password_with_pad, 0, CIFS_ENCPWD_SIZE);
 324        if (password)
 325                strncpy(password_with_pad, password, CIFS_ENCPWD_SIZE);
 326
 327        if (!encrypt && global_secflags & CIFSSEC_MAY_PLNTXT) {
 328                memcpy(lnm_session_key, password_with_pad,
 329                        CIFS_ENCPWD_SIZE);
 330                return 0;
 331        }
 332
 333        /* calculate old style session key */
 334        /* calling toupper is less broken than repeatedly
 335        calling nls_toupper would be since that will never
 336        work for UTF8, but neither handles multibyte code pages
 337        but the only alternative would be converting to UCS-16 (Unicode)
 338        (using a routine something like UniStrupr) then
 339        uppercasing and then converting back from Unicode - which
 340        would only worth doing it if we knew it were utf8. Basically
 341        utf8 and other multibyte codepages each need their own strupper
 342        function since a byte at a time will ont work. */
 343
 344        for (i = 0; i < CIFS_ENCPWD_SIZE; i++)
 345                password_with_pad[i] = toupper(password_with_pad[i]);
 346
 347        rc = SMBencrypt(password_with_pad, cryptkey, lnm_session_key);
 348
 349        return rc;
 350}
 351#endif /* CIFS_WEAK_PW_HASH */
 352
 353/* Build a proper attribute value/target info pairs blob.
 354 * Fill in netbios and dns domain name and workstation name
 355 * and client time (total five av pairs and + one end of fields indicator.
 356 * Allocate domain name which gets freed when session struct is deallocated.
 357 */
 358static int
 359build_avpair_blob(struct cifs_ses *ses, const struct nls_table *nls_cp)
 360{
 361        unsigned int dlen;
 362        unsigned int size = 2 * sizeof(struct ntlmssp2_name);
 363        char *defdmname = "WORKGROUP";
 364        unsigned char *blobptr;
 365        struct ntlmssp2_name *attrptr;
 366
 367        if (!ses->domainName) {
 368                ses->domainName = kstrdup(defdmname, GFP_KERNEL);
 369                if (!ses->domainName)
 370                        return -ENOMEM;
 371        }
 372
 373        dlen = strlen(ses->domainName);
 374
 375        /*
 376         * The length of this blob is two times the size of a
 377         * structure (av pair) which holds name/size
 378         * ( for NTLMSSP_AV_NB_DOMAIN_NAME followed by NTLMSSP_AV_EOL ) +
 379         * unicode length of a netbios domain name
 380         */
 381        ses->auth_key.len = size + 2 * dlen;
 382        ses->auth_key.response = kzalloc(ses->auth_key.len, GFP_KERNEL);
 383        if (!ses->auth_key.response) {
 384                ses->auth_key.len = 0;
 385                return -ENOMEM;
 386        }
 387
 388        blobptr = ses->auth_key.response;
 389        attrptr = (struct ntlmssp2_name *) blobptr;
 390
 391        /*
 392         * As defined in MS-NTLM 3.3.2, just this av pair field
 393         * is sufficient as part of the temp
 394         */
 395        attrptr->type = cpu_to_le16(NTLMSSP_AV_NB_DOMAIN_NAME);
 396        attrptr->length = cpu_to_le16(2 * dlen);
 397        blobptr = (unsigned char *)attrptr + sizeof(struct ntlmssp2_name);
 398        cifs_strtoUTF16((__le16 *)blobptr, ses->domainName, dlen, nls_cp);
 399
 400        return 0;
 401}
 402
 403/* Server has provided av pairs/target info in the type 2 challenge
 404 * packet and we have plucked it and stored within smb session.
 405 * We parse that blob here to find netbios domain name to be used
 406 * as part of ntlmv2 authentication (in Target String), if not already
 407 * specified on the command line.
 408 * If this function returns without any error but without fetching
 409 * domain name, authentication may fail against some server but
 410 * may not fail against other (those who are not very particular
 411 * about target string i.e. for some, just user name might suffice.
 412 */
 413static int
 414find_domain_name(struct cifs_ses *ses, const struct nls_table *nls_cp)
 415{
 416        unsigned int attrsize;
 417        unsigned int type;
 418        unsigned int onesize = sizeof(struct ntlmssp2_name);
 419        unsigned char *blobptr;
 420        unsigned char *blobend;
 421        struct ntlmssp2_name *attrptr;
 422
 423        if (!ses->auth_key.len || !ses->auth_key.response)
 424                return 0;
 425
 426        blobptr = ses->auth_key.response;
 427        blobend = blobptr + ses->auth_key.len;
 428
 429        while (blobptr + onesize < blobend) {
 430                attrptr = (struct ntlmssp2_name *) blobptr;
 431                type = le16_to_cpu(attrptr->type);
 432                if (type == NTLMSSP_AV_EOL)
 433                        break;
 434                blobptr += 2; /* advance attr type */
 435                attrsize = le16_to_cpu(attrptr->length);
 436                blobptr += 2; /* advance attr size */
 437                if (blobptr + attrsize > blobend)
 438                        break;
 439                if (type == NTLMSSP_AV_NB_DOMAIN_NAME) {
 440                        if (!attrsize || attrsize >= CIFS_MAX_DOMAINNAME_LEN)
 441                                break;
 442                        if (!ses->domainName) {
 443                                ses->domainName =
 444                                        kmalloc(attrsize + 1, GFP_KERNEL);
 445                                if (!ses->domainName)
 446                                                return -ENOMEM;
 447                                cifs_from_utf16(ses->domainName,
 448                                        (__le16 *)blobptr, attrsize, attrsize,
 449                                        nls_cp, NO_MAP_UNI_RSVD);
 450                                break;
 451                        }
 452                }
 453                blobptr += attrsize; /* advance attr  value */
 454        }
 455
 456        return 0;
 457}
 458
 459/* Server has provided av pairs/target info in the type 2 challenge
 460 * packet and we have plucked it and stored within smb session.
 461 * We parse that blob here to find the server given timestamp
 462 * as part of ntlmv2 authentication (or local current time as
 463 * default in case of failure)
 464 */
 465static __le64
 466find_timestamp(struct cifs_ses *ses)
 467{
 468        unsigned int attrsize;
 469        unsigned int type;
 470        unsigned int onesize = sizeof(struct ntlmssp2_name);
 471        unsigned char *blobptr;
 472        unsigned char *blobend;
 473        struct ntlmssp2_name *attrptr;
 474
 475        if (!ses->auth_key.len || !ses->auth_key.response)
 476                return 0;
 477
 478        blobptr = ses->auth_key.response;
 479        blobend = blobptr + ses->auth_key.len;
 480
 481        while (blobptr + onesize < blobend) {
 482                attrptr = (struct ntlmssp2_name *) blobptr;
 483                type = le16_to_cpu(attrptr->type);
 484                if (type == NTLMSSP_AV_EOL)
 485                        break;
 486                blobptr += 2; /* advance attr type */
 487                attrsize = le16_to_cpu(attrptr->length);
 488                blobptr += 2; /* advance attr size */
 489                if (blobptr + attrsize > blobend)
 490                        break;
 491                if (type == NTLMSSP_AV_TIMESTAMP) {
 492                        if (attrsize == sizeof(u64))
 493                                return *((__le64 *)blobptr);
 494                }
 495                blobptr += attrsize; /* advance attr value */
 496        }
 497
 498        return cpu_to_le64(cifs_UnixTimeToNT(CURRENT_TIME));
 499}
 500
 501static int calc_ntlmv2_hash(struct cifs_ses *ses, char *ntlmv2_hash,
 502                            const struct nls_table *nls_cp)
 503{
 504        int rc = 0;
 505        int len;
 506        char nt_hash[CIFS_NTHASH_SIZE];
 507        __le16 *user;
 508        wchar_t *domain;
 509        wchar_t *server;
 510
 511        if (!ses->server->secmech.sdeschmacmd5) {
 512                cifs_dbg(VFS, "%s: can't generate ntlmv2 hash\n", __func__);
 513                return -1;
 514        }
 515
 516        /* calculate md4 hash of password */
 517        E_md4hash(ses->password, nt_hash, nls_cp);
 518
 519        rc = crypto_shash_setkey(ses->server->secmech.hmacmd5, nt_hash,
 520                                CIFS_NTHASH_SIZE);
 521        if (rc) {
 522                cifs_dbg(VFS, "%s: Could not set NT Hash as a key\n", __func__);
 523                return rc;
 524        }
 525
 526        rc = crypto_shash_init(&ses->server->secmech.sdeschmacmd5->shash);
 527        if (rc) {
 528                cifs_dbg(VFS, "%s: could not init hmacmd5\n", __func__);
 529                return rc;
 530        }
 531
 532        /* convert ses->user_name to unicode */
 533        len = ses->user_name ? strlen(ses->user_name) : 0;
 534        user = kmalloc(2 + (len * 2), GFP_KERNEL);
 535        if (user == NULL) {
 536                rc = -ENOMEM;
 537                return rc;
 538        }
 539
 540        if (len) {
 541                len = cifs_strtoUTF16(user, ses->user_name, len, nls_cp);
 542                UniStrupr(user);
 543        } else {
 544                memset(user, '\0', 2);
 545        }
 546
 547        rc = crypto_shash_update(&ses->server->secmech.sdeschmacmd5->shash,
 548                                (char *)user, 2 * len);
 549        kfree(user);
 550        if (rc) {
 551                cifs_dbg(VFS, "%s: Could not update with user\n", __func__);
 552                return rc;
 553        }
 554
 555        /* convert ses->domainName to unicode and uppercase */
 556        if (ses->domainName) {
 557                len = strlen(ses->domainName);
 558
 559                domain = kmalloc(2 + (len * 2), GFP_KERNEL);
 560                if (domain == NULL) {
 561                        rc = -ENOMEM;
 562                        return rc;
 563                }
 564                len = cifs_strtoUTF16((__le16 *)domain, ses->domainName, len,
 565                                      nls_cp);
 566                rc =
 567                crypto_shash_update(&ses->server->secmech.sdeschmacmd5->shash,
 568                                        (char *)domain, 2 * len);
 569                kfree(domain);
 570                if (rc) {
 571                        cifs_dbg(VFS, "%s: Could not update with domain\n",
 572                                 __func__);
 573                        return rc;
 574                }
 575        } else {
 576                /* We use ses->serverName if no domain name available */
 577                len = strlen(ses->serverName);
 578
 579                server = kmalloc(2 + (len * 2), GFP_KERNEL);
 580                if (server == NULL) {
 581                        rc = -ENOMEM;
 582                        return rc;
 583                }
 584                len = cifs_strtoUTF16((__le16 *)server, ses->serverName, len,
 585                                        nls_cp);
 586                rc =
 587                crypto_shash_update(&ses->server->secmech.sdeschmacmd5->shash,
 588                                        (char *)server, 2 * len);
 589                kfree(server);
 590                if (rc) {
 591                        cifs_dbg(VFS, "%s: Could not update with server\n",
 592                                 __func__);
 593                        return rc;
 594                }
 595        }
 596
 597        rc = crypto_shash_final(&ses->server->secmech.sdeschmacmd5->shash,
 598                                        ntlmv2_hash);
 599        if (rc)
 600                cifs_dbg(VFS, "%s: Could not generate md5 hash\n", __func__);
 601
 602        return rc;
 603}
 604
 605static int
 606CalcNTLMv2_response(const struct cifs_ses *ses, char *ntlmv2_hash)
 607{
 608        int rc;
 609        struct ntlmv2_resp *ntlmv2 = (struct ntlmv2_resp *)
 610            (ses->auth_key.response + CIFS_SESS_KEY_SIZE);
 611        unsigned int hash_len;
 612
 613        /* The MD5 hash starts at challenge_key.key */
 614        hash_len = ses->auth_key.len - (CIFS_SESS_KEY_SIZE +
 615                offsetof(struct ntlmv2_resp, challenge.key[0]));
 616
 617        if (!ses->server->secmech.sdeschmacmd5) {
 618                cifs_dbg(VFS, "%s: can't generate ntlmv2 hash\n", __func__);
 619                return -1;
 620        }
 621
 622        rc = crypto_shash_setkey(ses->server->secmech.hmacmd5,
 623                                 ntlmv2_hash, CIFS_HMAC_MD5_HASH_SIZE);
 624        if (rc) {
 625                cifs_dbg(VFS, "%s: Could not set NTLMV2 Hash as a key\n",
 626                         __func__);
 627                return rc;
 628        }
 629
 630        rc = crypto_shash_init(&ses->server->secmech.sdeschmacmd5->shash);
 631        if (rc) {
 632                cifs_dbg(VFS, "%s: could not init hmacmd5\n", __func__);
 633                return rc;
 634        }
 635
 636        if (ses->server->negflavor == CIFS_NEGFLAVOR_EXTENDED)
 637                memcpy(ntlmv2->challenge.key,
 638                       ses->ntlmssp->cryptkey, CIFS_SERVER_CHALLENGE_SIZE);
 639        else
 640                memcpy(ntlmv2->challenge.key,
 641                       ses->server->cryptkey, CIFS_SERVER_CHALLENGE_SIZE);
 642        rc = crypto_shash_update(&ses->server->secmech.sdeschmacmd5->shash,
 643                                 ntlmv2->challenge.key, hash_len);
 644        if (rc) {
 645                cifs_dbg(VFS, "%s: Could not update with response\n", __func__);
 646                return rc;
 647        }
 648
 649        /* Note that the MD5 digest over writes anon.challenge_key.key */
 650        rc = crypto_shash_final(&ses->server->secmech.sdeschmacmd5->shash,
 651                                ntlmv2->ntlmv2_hash);
 652        if (rc)
 653                cifs_dbg(VFS, "%s: Could not generate md5 hash\n", __func__);
 654
 655        return rc;
 656}
 657
 658static int crypto_hmacmd5_alloc(struct TCP_Server_Info *server)
 659{
 660        int rc;
 661        unsigned int size;
 662
 663        /* check if already allocated */
 664        if (server->secmech.sdeschmacmd5)
 665                return 0;
 666
 667        server->secmech.hmacmd5 = crypto_alloc_shash("hmac(md5)", 0, 0);
 668        if (IS_ERR(server->secmech.hmacmd5)) {
 669                cifs_dbg(VFS, "could not allocate crypto hmacmd5\n");
 670                rc = PTR_ERR(server->secmech.hmacmd5);
 671                server->secmech.hmacmd5 = NULL;
 672                return rc;
 673        }
 674
 675        size = sizeof(struct shash_desc) +
 676                        crypto_shash_descsize(server->secmech.hmacmd5);
 677        server->secmech.sdeschmacmd5 = kmalloc(size, GFP_KERNEL);
 678        if (!server->secmech.sdeschmacmd5) {
 679                crypto_free_shash(server->secmech.hmacmd5);
 680                server->secmech.hmacmd5 = NULL;
 681                return -ENOMEM;
 682        }
 683        server->secmech.sdeschmacmd5->shash.tfm = server->secmech.hmacmd5;
 684        server->secmech.sdeschmacmd5->shash.flags = 0x0;
 685
 686        return 0;
 687}
 688
 689int
 690setup_ntlmv2_rsp(struct cifs_ses *ses, const struct nls_table *nls_cp)
 691{
 692        int rc;
 693        int baselen;
 694        unsigned int tilen;
 695        struct ntlmv2_resp *ntlmv2;
 696        char ntlmv2_hash[16];
 697        unsigned char *tiblob = NULL; /* target info blob */
 698        __le64 rsp_timestamp;
 699
 700        if (ses->server->negflavor == CIFS_NEGFLAVOR_EXTENDED) {
 701                if (!ses->domainName) {
 702                        rc = find_domain_name(ses, nls_cp);
 703                        if (rc) {
 704                                cifs_dbg(VFS, "error %d finding domain name\n",
 705                                         rc);
 706                                goto setup_ntlmv2_rsp_ret;
 707                        }
 708                }
 709        } else {
 710                rc = build_avpair_blob(ses, nls_cp);
 711                if (rc) {
 712                        cifs_dbg(VFS, "error %d building av pair blob\n", rc);
 713                        goto setup_ntlmv2_rsp_ret;
 714                }
 715        }
 716
 717        /* Must be within 5 minutes of the server (or in range +/-2h
 718         * in case of Mac OS X), so simply carry over server timestamp
 719         * (as Windows 7 does)
 720         */
 721        rsp_timestamp = find_timestamp(ses);
 722
 723        baselen = CIFS_SESS_KEY_SIZE + sizeof(struct ntlmv2_resp);
 724        tilen = ses->auth_key.len;
 725        tiblob = ses->auth_key.response;
 726
 727        ses->auth_key.response = kmalloc(baselen + tilen, GFP_KERNEL);
 728        if (!ses->auth_key.response) {
 729                rc = -ENOMEM;
 730                ses->auth_key.len = 0;
 731                goto setup_ntlmv2_rsp_ret;
 732        }
 733        ses->auth_key.len += baselen;
 734
 735        ntlmv2 = (struct ntlmv2_resp *)
 736                        (ses->auth_key.response + CIFS_SESS_KEY_SIZE);
 737        ntlmv2->blob_signature = cpu_to_le32(0x00000101);
 738        ntlmv2->reserved = 0;
 739        ntlmv2->time = rsp_timestamp;
 740
 741        get_random_bytes(&ntlmv2->client_chal, sizeof(ntlmv2->client_chal));
 742        ntlmv2->reserved2 = 0;
 743
 744        memcpy(ses->auth_key.response + baselen, tiblob, tilen);
 745
 746        mutex_lock(&ses->server->srv_mutex);
 747
 748        rc = crypto_hmacmd5_alloc(ses->server);
 749        if (rc) {
 750                cifs_dbg(VFS, "could not crypto alloc hmacmd5 rc %d\n", rc);
 751                goto unlock;
 752        }
 753
 754        /* calculate ntlmv2_hash */
 755        rc = calc_ntlmv2_hash(ses, ntlmv2_hash, nls_cp);
 756        if (rc) {
 757                cifs_dbg(VFS, "could not get v2 hash rc %d\n", rc);
 758                goto unlock;
 759        }
 760
 761        /* calculate first part of the client response (CR1) */
 762        rc = CalcNTLMv2_response(ses, ntlmv2_hash);
 763        if (rc) {
 764                cifs_dbg(VFS, "Could not calculate CR1 rc: %d\n", rc);
 765                goto unlock;
 766        }
 767
 768        /* now calculate the session key for NTLMv2 */
 769        rc = crypto_shash_setkey(ses->server->secmech.hmacmd5,
 770                ntlmv2_hash, CIFS_HMAC_MD5_HASH_SIZE);
 771        if (rc) {
 772                cifs_dbg(VFS, "%s: Could not set NTLMV2 Hash as a key\n",
 773                         __func__);
 774                goto unlock;
 775        }
 776
 777        rc = crypto_shash_init(&ses->server->secmech.sdeschmacmd5->shash);
 778        if (rc) {
 779                cifs_dbg(VFS, "%s: Could not init hmacmd5\n", __func__);
 780                goto unlock;
 781        }
 782
 783        rc = crypto_shash_update(&ses->server->secmech.sdeschmacmd5->shash,
 784                ntlmv2->ntlmv2_hash,
 785                CIFS_HMAC_MD5_HASH_SIZE);
 786        if (rc) {
 787                cifs_dbg(VFS, "%s: Could not update with response\n", __func__);
 788                goto unlock;
 789        }
 790
 791        rc = crypto_shash_final(&ses->server->secmech.sdeschmacmd5->shash,
 792                ses->auth_key.response);
 793        if (rc)
 794                cifs_dbg(VFS, "%s: Could not generate md5 hash\n", __func__);
 795
 796unlock:
 797        mutex_unlock(&ses->server->srv_mutex);
 798setup_ntlmv2_rsp_ret:
 799        kfree(tiblob);
 800
 801        return rc;
 802}
 803
 804int
 805calc_seckey(struct cifs_ses *ses)
 806{
 807        int rc;
 808        struct crypto_skcipher *tfm_arc4;
 809        struct scatterlist sgin, sgout;
 810        struct skcipher_request *req;
 811        unsigned char sec_key[CIFS_SESS_KEY_SIZE]; /* a nonce */
 812
 813        get_random_bytes(sec_key, CIFS_SESS_KEY_SIZE);
 814
 815        tfm_arc4 = crypto_alloc_skcipher("ecb(arc4)", 0, CRYPTO_ALG_ASYNC);
 816        if (IS_ERR(tfm_arc4)) {
 817                rc = PTR_ERR(tfm_arc4);
 818                cifs_dbg(VFS, "could not allocate crypto API arc4\n");
 819                return rc;
 820        }
 821
 822        rc = crypto_skcipher_setkey(tfm_arc4, ses->auth_key.response,
 823                                        CIFS_SESS_KEY_SIZE);
 824        if (rc) {
 825                cifs_dbg(VFS, "%s: Could not set response as a key\n",
 826                         __func__);
 827                goto out_free_cipher;
 828        }
 829
 830        req = skcipher_request_alloc(tfm_arc4, GFP_KERNEL);
 831        if (!req) {
 832                rc = -ENOMEM;
 833                cifs_dbg(VFS, "could not allocate crypto API arc4 request\n");
 834                goto out_free_cipher;
 835        }
 836
 837        sg_init_one(&sgin, sec_key, CIFS_SESS_KEY_SIZE);
 838        sg_init_one(&sgout, ses->ntlmssp->ciphertext, CIFS_CPHTXT_SIZE);
 839
 840        skcipher_request_set_callback(req, 0, NULL, NULL);
 841        skcipher_request_set_crypt(req, &sgin, &sgout, CIFS_CPHTXT_SIZE, NULL);
 842
 843        rc = crypto_skcipher_encrypt(req);
 844        skcipher_request_free(req);
 845        if (rc) {
 846                cifs_dbg(VFS, "could not encrypt session key rc: %d\n", rc);
 847                goto out_free_cipher;
 848        }
 849
 850        /* make secondary_key/nonce as session key */
 851        memcpy(ses->auth_key.response, sec_key, CIFS_SESS_KEY_SIZE);
 852        /* and make len as that of session key only */
 853        ses->auth_key.len = CIFS_SESS_KEY_SIZE;
 854
 855out_free_cipher:
 856        crypto_free_skcipher(tfm_arc4);
 857
 858        return rc;
 859}
 860
 861void
 862cifs_crypto_shash_release(struct TCP_Server_Info *server)
 863{
 864        if (server->secmech.cmacaes) {
 865                crypto_free_shash(server->secmech.cmacaes);
 866                server->secmech.cmacaes = NULL;
 867        }
 868
 869        if (server->secmech.hmacsha256) {
 870                crypto_free_shash(server->secmech.hmacsha256);
 871                server->secmech.hmacsha256 = NULL;
 872        }
 873
 874        if (server->secmech.md5) {
 875                crypto_free_shash(server->secmech.md5);
 876                server->secmech.md5 = NULL;
 877        }
 878
 879        if (server->secmech.hmacmd5) {
 880                crypto_free_shash(server->secmech.hmacmd5);
 881                server->secmech.hmacmd5 = NULL;
 882        }
 883
 884        kfree(server->secmech.sdesccmacaes);
 885        server->secmech.sdesccmacaes = NULL;
 886        kfree(server->secmech.sdeschmacsha256);
 887        server->secmech.sdeschmacsha256 = NULL;
 888        kfree(server->secmech.sdeschmacmd5);
 889        server->secmech.sdeschmacmd5 = NULL;
 890        kfree(server->secmech.sdescmd5);
 891        server->secmech.sdescmd5 = NULL;
 892}
 893