root/fs/cifs/cifsencrypt.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. __cifs_calc_signature
  2. cifs_calc_signature
  3. cifs_sign_rqst
  4. cifs_sign_smbv
  5. cifs_sign_smb
  6. cifs_verify_signature
  7. setup_ntlm_response
  8. calc_lanman_hash
  9. build_avpair_blob
  10. find_domain_name
  11. find_timestamp
  12. calc_ntlmv2_hash
  13. CalcNTLMv2_response
  14. setup_ntlmv2_rsp
  15. calc_seckey
  16. cifs_crypto_secmech_release

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

/* [<][>][^][v][top][bottom][index][help] */