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