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 <linux/iov_iter.h> 25 #include <crypto/aead.h> 26 #include <crypto/arc4.h> 27 #include <crypto/md5.h> 28 #include <crypto/sha2.h> 29 30 static int cifs_sig_update(struct cifs_calc_sig_ctx *ctx, 31 const u8 *data, size_t len) 32 { 33 if (ctx->md5) { 34 md5_update(ctx->md5, data, len); 35 return 0; 36 } 37 if (ctx->hmac) { 38 hmac_sha256_update(ctx->hmac, data, len); 39 return 0; 40 } 41 return crypto_shash_update(ctx->shash, data, len); 42 } 43 44 static int cifs_sig_final(struct cifs_calc_sig_ctx *ctx, u8 *out) 45 { 46 if (ctx->md5) { 47 md5_final(ctx->md5, out); 48 return 0; 49 } 50 if (ctx->hmac) { 51 hmac_sha256_final(ctx->hmac, out); 52 return 0; 53 } 54 return crypto_shash_final(ctx->shash, out); 55 } 56 57 static size_t cifs_sig_step(void *iter_base, size_t progress, size_t len, 58 void *priv, void *priv2) 59 { 60 struct cifs_calc_sig_ctx *ctx = priv; 61 int ret, *pret = priv2; 62 63 ret = cifs_sig_update(ctx, iter_base, len); 64 if (ret < 0) { 65 *pret = ret; 66 return len; 67 } 68 return 0; 69 } 70 71 /* 72 * Pass the data from an iterator into a hash. 73 */ 74 static int cifs_sig_iter(const struct iov_iter *iter, size_t maxsize, 75 struct cifs_calc_sig_ctx *ctx) 76 { 77 struct iov_iter tmp_iter = *iter; 78 int err = -EIO; 79 80 if (iterate_and_advance_kernel(&tmp_iter, maxsize, ctx, &err, 81 cifs_sig_step) != maxsize) 82 return err; 83 return 0; 84 } 85 86 int __cifs_calc_signature(struct smb_rqst *rqst, struct TCP_Server_Info *server, 87 char *signature, struct cifs_calc_sig_ctx *ctx) 88 { 89 int i; 90 ssize_t rc; 91 struct kvec *iov = rqst->rq_iov; 92 int n_vec = rqst->rq_nvec; 93 94 /* iov[0] is actual data and not the rfc1002 length for SMB2+ */ 95 if (!is_smb1(server)) { 96 if (iov[0].iov_len <= 4) 97 return -EIO; 98 i = 0; 99 } else { 100 if (n_vec < 2 || iov[0].iov_len != 4) 101 return -EIO; 102 i = 1; /* skip rfc1002 length */ 103 } 104 105 for (; i < n_vec; i++) { 106 if (iov[i].iov_len == 0) 107 continue; 108 if (iov[i].iov_base == NULL) { 109 cifs_dbg(VFS, "null iovec entry\n"); 110 return -EIO; 111 } 112 113 rc = cifs_sig_update(ctx, iov[i].iov_base, iov[i].iov_len); 114 if (rc) { 115 cifs_dbg(VFS, "%s: Could not update with payload\n", 116 __func__); 117 return rc; 118 } 119 } 120 121 rc = cifs_sig_iter(&rqst->rq_iter, iov_iter_count(&rqst->rq_iter), ctx); 122 if (rc < 0) 123 return rc; 124 125 rc = cifs_sig_final(ctx, signature); 126 if (rc) 127 cifs_dbg(VFS, "%s: Could not generate hash\n", __func__); 128 129 return rc; 130 } 131 132 /* 133 * Calculate and return the CIFS signature based on the mac key and SMB PDU. 134 * The 16 byte signature must be allocated by the caller. Note we only use the 135 * 1st eight bytes and that the smb header signature field on input contains 136 * the sequence number before this function is called. Also, this function 137 * should be called with the server->srv_mutex held. 138 */ 139 static int cifs_calc_signature(struct smb_rqst *rqst, 140 struct TCP_Server_Info *server, char *signature) 141 { 142 struct md5_ctx ctx; 143 144 if (!rqst->rq_iov || !signature || !server) 145 return -EINVAL; 146 if (fips_enabled) { 147 cifs_dbg(VFS, 148 "MD5 signature support is disabled due to FIPS\n"); 149 return -EOPNOTSUPP; 150 } 151 152 md5_init(&ctx); 153 md5_update(&ctx, server->session_key.response, server->session_key.len); 154 155 return __cifs_calc_signature( 156 rqst, server, signature, 157 &(struct cifs_calc_sig_ctx){ .md5 = &ctx }); 158 } 159 160 /* must be called with server->srv_mutex held */ 161 int cifs_sign_rqst(struct smb_rqst *rqst, struct TCP_Server_Info *server, 162 __u32 *pexpected_response_sequence_number) 163 { 164 int rc = 0; 165 char smb_signature[20]; 166 struct smb_hdr *cifs_pdu = (struct smb_hdr *)rqst->rq_iov[0].iov_base; 167 168 if (rqst->rq_iov[0].iov_len != 4 || 169 rqst->rq_iov[0].iov_base + 4 != rqst->rq_iov[1].iov_base) 170 return -EIO; 171 172 if ((cifs_pdu == NULL) || (server == NULL)) 173 return -EINVAL; 174 175 spin_lock(&server->srv_lock); 176 if (!(cifs_pdu->Flags2 & SMBFLG2_SECURITY_SIGNATURE) || 177 server->tcpStatus == CifsNeedNegotiate) { 178 spin_unlock(&server->srv_lock); 179 return rc; 180 } 181 spin_unlock(&server->srv_lock); 182 183 if (!server->session_estab) { 184 memcpy(cifs_pdu->Signature.SecuritySignature, "BSRSPYL", 8); 185 return rc; 186 } 187 188 cifs_pdu->Signature.Sequence.SequenceNumber = 189 cpu_to_le32(server->sequence_number); 190 cifs_pdu->Signature.Sequence.Reserved = 0; 191 192 *pexpected_response_sequence_number = ++server->sequence_number; 193 ++server->sequence_number; 194 195 rc = cifs_calc_signature(rqst, server, smb_signature); 196 if (rc) 197 memset(cifs_pdu->Signature.SecuritySignature, 0, 8); 198 else 199 memcpy(cifs_pdu->Signature.SecuritySignature, smb_signature, 8); 200 201 return rc; 202 } 203 204 int cifs_sign_smbv(struct kvec *iov, int n_vec, struct TCP_Server_Info *server, 205 __u32 *pexpected_response_sequence) 206 { 207 struct smb_rqst rqst = { .rq_iov = iov, 208 .rq_nvec = n_vec }; 209 210 return cifs_sign_rqst(&rqst, server, pexpected_response_sequence); 211 } 212 213 /* must be called with server->srv_mutex held */ 214 int cifs_sign_smb(struct smb_hdr *cifs_pdu, struct TCP_Server_Info *server, 215 __u32 *pexpected_response_sequence_number) 216 { 217 struct kvec iov[2]; 218 219 iov[0].iov_base = cifs_pdu; 220 iov[0].iov_len = 4; 221 iov[1].iov_base = (char *)cifs_pdu + 4; 222 iov[1].iov_len = be32_to_cpu(cifs_pdu->smb_buf_length); 223 224 return cifs_sign_smbv(iov, 2, server, 225 pexpected_response_sequence_number); 226 } 227 228 int cifs_verify_signature(struct smb_rqst *rqst, 229 struct TCP_Server_Info *server, 230 __u32 expected_sequence_number) 231 { 232 unsigned int rc; 233 char server_response_sig[8]; 234 char what_we_think_sig_should_be[20]; 235 struct smb_hdr *cifs_pdu = (struct smb_hdr *)rqst->rq_iov[0].iov_base; 236 237 if (rqst->rq_iov[0].iov_len != 4 || 238 rqst->rq_iov[0].iov_base + 4 != rqst->rq_iov[1].iov_base) 239 return -EIO; 240 241 if (cifs_pdu == NULL || server == NULL) 242 return -EINVAL; 243 244 if (!server->session_estab) 245 return 0; 246 247 if (cifs_pdu->Command == SMB_COM_LOCKING_ANDX) { 248 struct smb_com_lock_req *pSMB = 249 (struct smb_com_lock_req *)cifs_pdu; 250 if (pSMB->LockType & LOCKING_ANDX_OPLOCK_RELEASE) 251 return 0; 252 } 253 254 /* BB what if signatures are supposed to be on for session but 255 server does not send one? BB */ 256 257 /* Do not need to verify session setups with signature "BSRSPYL " */ 258 if (memcmp(cifs_pdu->Signature.SecuritySignature, "BSRSPYL ", 8) == 0) 259 cifs_dbg(FYI, "dummy signature received for smb command 0x%x\n", 260 cifs_pdu->Command); 261 262 /* save off the original signature so we can modify the smb and check 263 its signature against what the server sent */ 264 memcpy(server_response_sig, cifs_pdu->Signature.SecuritySignature, 8); 265 266 cifs_pdu->Signature.Sequence.SequenceNumber = 267 cpu_to_le32(expected_sequence_number); 268 cifs_pdu->Signature.Sequence.Reserved = 0; 269 270 cifs_server_lock(server); 271 rc = cifs_calc_signature(rqst, server, what_we_think_sig_should_be); 272 cifs_server_unlock(server); 273 274 if (rc) 275 return rc; 276 277 /* cifs_dump_mem("what we think it should be: ", 278 what_we_think_sig_should_be, 16); */ 279 280 if (memcmp(server_response_sig, what_we_think_sig_should_be, 8)) 281 return -EACCES; 282 else 283 return 0; 284 285 } 286 287 /* Build a proper attribute value/target info pairs blob. 288 * Fill in netbios and dns domain name and workstation name 289 * and client time (total five av pairs and + one end of fields indicator. 290 * Allocate domain name which gets freed when session struct is deallocated. 291 */ 292 static int 293 build_avpair_blob(struct cifs_ses *ses, const struct nls_table *nls_cp) 294 { 295 unsigned int dlen; 296 unsigned int size = 2 * sizeof(struct ntlmssp2_name); 297 char *defdmname = "WORKGROUP"; 298 unsigned char *blobptr; 299 struct ntlmssp2_name *attrptr; 300 301 if (!ses->domainName) { 302 ses->domainName = kstrdup(defdmname, GFP_KERNEL); 303 if (!ses->domainName) 304 return -ENOMEM; 305 } 306 307 dlen = strlen(ses->domainName); 308 309 /* 310 * The length of this blob is two times the size of a 311 * structure (av pair) which holds name/size 312 * ( for NTLMSSP_AV_NB_DOMAIN_NAME followed by NTLMSSP_AV_EOL ) + 313 * unicode length of a netbios domain name 314 */ 315 kfree_sensitive(ses->auth_key.response); 316 ses->auth_key.len = size + 2 * dlen; 317 ses->auth_key.response = kzalloc(ses->auth_key.len, GFP_KERNEL); 318 if (!ses->auth_key.response) { 319 ses->auth_key.len = 0; 320 return -ENOMEM; 321 } 322 323 blobptr = ses->auth_key.response; 324 attrptr = (struct ntlmssp2_name *) blobptr; 325 326 /* 327 * As defined in MS-NTLM 3.3.2, just this av pair field 328 * is sufficient as part of the temp 329 */ 330 attrptr->type = cpu_to_le16(NTLMSSP_AV_NB_DOMAIN_NAME); 331 attrptr->length = cpu_to_le16(2 * dlen); 332 blobptr = (unsigned char *)attrptr + sizeof(struct ntlmssp2_name); 333 cifs_strtoUTF16((__le16 *)blobptr, ses->domainName, dlen, nls_cp); 334 335 return 0; 336 } 337 338 #define AV_TYPE(av) (le16_to_cpu(av->type)) 339 #define AV_LEN(av) (le16_to_cpu(av->length)) 340 #define AV_DATA_PTR(av) ((void *)av->data) 341 342 #define av_for_each_entry(ses, av) \ 343 for (av = NULL; (av = find_next_av(ses, av));) 344 345 static struct ntlmssp2_name *find_next_av(struct cifs_ses *ses, 346 struct ntlmssp2_name *av) 347 { 348 u16 len; 349 u8 *end; 350 351 end = (u8 *)ses->auth_key.response + ses->auth_key.len; 352 if (!av) { 353 if (unlikely(!ses->auth_key.response || !ses->auth_key.len)) 354 return NULL; 355 av = (void *)ses->auth_key.response; 356 } else { 357 av = (void *)((u8 *)av + sizeof(*av) + AV_LEN(av)); 358 } 359 360 if ((u8 *)av + sizeof(*av) > end) 361 return NULL; 362 363 len = AV_LEN(av); 364 if (AV_TYPE(av) == NTLMSSP_AV_EOL) 365 return NULL; 366 if ((u8 *)av + sizeof(*av) + len > end) 367 return NULL; 368 return av; 369 } 370 371 /* 372 * Check if server has provided av pair of @type in the NTLMSSP 373 * CHALLENGE_MESSAGE blob. 374 */ 375 static int find_av_name(struct cifs_ses *ses, u16 type, char **name, u16 maxlen) 376 { 377 const struct nls_table *nlsc = ses->local_nls; 378 struct ntlmssp2_name *av; 379 u16 len, nlen; 380 381 if (*name) 382 return 0; 383 384 av_for_each_entry(ses, av) { 385 len = AV_LEN(av); 386 if (AV_TYPE(av) != type || !len) 387 continue; 388 if (!IS_ALIGNED(len, sizeof(__le16))) { 389 cifs_dbg(VFS | ONCE, "%s: bad length(%u) for type %u\n", 390 __func__, len, type); 391 continue; 392 } 393 nlen = len / sizeof(__le16); 394 if (nlen <= maxlen) { 395 ++nlen; 396 *name = kmalloc(nlen, GFP_KERNEL); 397 if (!*name) 398 return -ENOMEM; 399 cifs_from_utf16(*name, AV_DATA_PTR(av), nlen, 400 len, nlsc, NO_MAP_UNI_RSVD); 401 break; 402 } 403 } 404 return 0; 405 } 406 407 /* Server has provided av pairs/target info in the type 2 challenge 408 * packet and we have plucked it and stored within smb session. 409 * We parse that blob here to find the server given timestamp 410 * as part of ntlmv2 authentication (or local current time as 411 * default in case of failure) 412 */ 413 static __le64 find_timestamp(struct cifs_ses *ses) 414 { 415 struct ntlmssp2_name *av; 416 struct timespec64 ts; 417 418 av_for_each_entry(ses, av) { 419 if (AV_TYPE(av) == NTLMSSP_AV_TIMESTAMP && 420 AV_LEN(av) == sizeof(u64)) 421 return *((__le64 *)AV_DATA_PTR(av)); 422 } 423 ktime_get_real_ts64(&ts); 424 return cpu_to_le64(cifs_UnixTimeToNT(ts)); 425 } 426 427 static int calc_ntlmv2_hash(struct cifs_ses *ses, char *ntlmv2_hash, 428 const struct nls_table *nls_cp) 429 { 430 int len; 431 char nt_hash[CIFS_NTHASH_SIZE]; 432 struct hmac_md5_ctx hmac_ctx; 433 __le16 *user; 434 wchar_t *domain; 435 wchar_t *server; 436 437 /* calculate md4 hash of password */ 438 E_md4hash(ses->password, nt_hash, nls_cp); 439 440 hmac_md5_init_usingrawkey(&hmac_ctx, nt_hash, CIFS_NTHASH_SIZE); 441 442 /* convert ses->user_name to unicode */ 443 len = ses->user_name ? strlen(ses->user_name) : 0; 444 user = kmalloc(2 + (len * 2), GFP_KERNEL); 445 if (user == NULL) 446 return -ENOMEM; 447 448 if (len) { 449 len = cifs_strtoUTF16(user, ses->user_name, len, nls_cp); 450 UniStrupr(user); 451 } else { 452 *(u16 *)user = 0; 453 } 454 455 hmac_md5_update(&hmac_ctx, (const u8 *)user, 2 * len); 456 kfree(user); 457 458 /* convert ses->domainName to unicode and uppercase */ 459 if (ses->domainName) { 460 len = strlen(ses->domainName); 461 462 domain = kmalloc(2 + (len * 2), GFP_KERNEL); 463 if (domain == NULL) 464 return -ENOMEM; 465 466 len = cifs_strtoUTF16((__le16 *)domain, ses->domainName, len, 467 nls_cp); 468 hmac_md5_update(&hmac_ctx, (const u8 *)domain, 2 * len); 469 kfree(domain); 470 } else { 471 /* We use ses->ip_addr if no domain name available */ 472 len = strlen(ses->ip_addr); 473 474 server = kmalloc(2 + (len * 2), GFP_KERNEL); 475 if (server == NULL) 476 return -ENOMEM; 477 478 len = cifs_strtoUTF16((__le16 *)server, ses->ip_addr, len, nls_cp); 479 hmac_md5_update(&hmac_ctx, (const u8 *)server, 2 * len); 480 kfree(server); 481 } 482 483 hmac_md5_final(&hmac_ctx, ntlmv2_hash); 484 return 0; 485 } 486 487 static void CalcNTLMv2_response(const struct cifs_ses *ses, char *ntlmv2_hash) 488 { 489 struct ntlmv2_resp *ntlmv2 = (struct ntlmv2_resp *) 490 (ses->auth_key.response + CIFS_SESS_KEY_SIZE); 491 unsigned int hash_len; 492 493 /* The MD5 hash starts at challenge_key.key */ 494 hash_len = ses->auth_key.len - (CIFS_SESS_KEY_SIZE + 495 offsetof(struct ntlmv2_resp, challenge.key[0])); 496 497 if (ses->server->negflavor == CIFS_NEGFLAVOR_EXTENDED) 498 memcpy(ntlmv2->challenge.key, ses->ntlmssp->cryptkey, CIFS_SERVER_CHALLENGE_SIZE); 499 else 500 memcpy(ntlmv2->challenge.key, ses->server->cryptkey, CIFS_SERVER_CHALLENGE_SIZE); 501 502 /* Note that the HMAC-MD5 value overwrites ntlmv2->challenge.key */ 503 hmac_md5_usingrawkey(ntlmv2_hash, CIFS_HMAC_MD5_HASH_SIZE, 504 ntlmv2->challenge.key, hash_len, 505 ntlmv2->ntlmv2_hash); 506 } 507 508 /* 509 * Set up NTLMv2 response blob with SPN (cifs/<hostname>) appended to the 510 * existing list of AV pairs. 511 */ 512 static int set_auth_key_response(struct cifs_ses *ses) 513 { 514 size_t baselen = CIFS_SESS_KEY_SIZE + sizeof(struct ntlmv2_resp); 515 size_t len, spnlen, tilen = 0, num_avs = 2 /* SPN + EOL */; 516 struct TCP_Server_Info *server = ses->server; 517 char *spn __free(kfree) = NULL; 518 struct ntlmssp2_name *av; 519 char *rsp = NULL; 520 int rc; 521 522 spnlen = strlen(server->hostname); 523 len = sizeof("cifs/") + spnlen; 524 spn = kmalloc(len, GFP_KERNEL); 525 if (!spn) { 526 rc = -ENOMEM; 527 goto out; 528 } 529 530 spnlen = scnprintf(spn, len, "cifs/%.*s", 531 (int)spnlen, server->hostname); 532 533 av_for_each_entry(ses, av) 534 tilen += sizeof(*av) + AV_LEN(av); 535 536 len = baselen + tilen + spnlen * sizeof(__le16) + num_avs * sizeof(*av); 537 rsp = kmalloc(len, GFP_KERNEL); 538 if (!rsp) { 539 rc = -ENOMEM; 540 goto out; 541 } 542 543 memcpy(rsp + baselen, ses->auth_key.response, tilen); 544 av = (void *)(rsp + baselen + tilen); 545 av->type = cpu_to_le16(NTLMSSP_AV_TARGET_NAME); 546 av->length = cpu_to_le16(spnlen * sizeof(__le16)); 547 cifs_strtoUTF16((__le16 *)av->data, spn, spnlen, ses->local_nls); 548 av = (void *)((__u8 *)av + sizeof(*av) + AV_LEN(av)); 549 av->type = cpu_to_le16(NTLMSSP_AV_EOL); 550 av->length = 0; 551 552 rc = 0; 553 ses->auth_key.len = len; 554 out: 555 ses->auth_key.response = rsp; 556 return rc; 557 } 558 559 int 560 setup_ntlmv2_rsp(struct cifs_ses *ses, const struct nls_table *nls_cp) 561 { 562 unsigned char *tiblob = NULL; /* target info blob */ 563 struct ntlmv2_resp *ntlmv2; 564 char ntlmv2_hash[16]; 565 __le64 rsp_timestamp; 566 __u64 cc; 567 int rc; 568 569 if (nls_cp == NULL) { 570 cifs_dbg(VFS, "%s called with nls_cp==NULL\n", __func__); 571 return -EINVAL; 572 } 573 574 if (ses->server->negflavor == CIFS_NEGFLAVOR_EXTENDED) { 575 if (!ses->domainName) { 576 if (ses->domainAuto) { 577 /* 578 * Domain (workgroup) hasn't been specified in 579 * mount options, so try to find it in 580 * CHALLENGE_MESSAGE message and then use it as 581 * part of NTLMv2 authentication. 582 */ 583 rc = find_av_name(ses, NTLMSSP_AV_NB_DOMAIN_NAME, 584 &ses->domainName, 585 CIFS_MAX_DOMAINNAME_LEN); 586 if (rc) 587 goto setup_ntlmv2_rsp_ret; 588 } else { 589 ses->domainName = kstrdup("", GFP_KERNEL); 590 if (!ses->domainName) { 591 rc = -ENOMEM; 592 goto setup_ntlmv2_rsp_ret; 593 } 594 } 595 } 596 rc = find_av_name(ses, NTLMSSP_AV_DNS_DOMAIN_NAME, 597 &ses->dns_dom, CIFS_MAX_DOMAINNAME_LEN); 598 if (rc) 599 goto setup_ntlmv2_rsp_ret; 600 } else { 601 rc = build_avpair_blob(ses, nls_cp); 602 if (rc) { 603 cifs_dbg(VFS, "error %d building av pair blob\n", rc); 604 goto setup_ntlmv2_rsp_ret; 605 } 606 } 607 608 /* Must be within 5 minutes of the server (or in range +/-2h 609 * in case of Mac OS X), so simply carry over server timestamp 610 * (as Windows 7 does) 611 */ 612 rsp_timestamp = find_timestamp(ses); 613 get_random_bytes(&cc, sizeof(cc)); 614 615 cifs_server_lock(ses->server); 616 617 tiblob = ses->auth_key.response; 618 rc = set_auth_key_response(ses); 619 if (rc) { 620 ses->auth_key.len = 0; 621 goto unlock; 622 } 623 624 ntlmv2 = (struct ntlmv2_resp *) 625 (ses->auth_key.response + CIFS_SESS_KEY_SIZE); 626 ntlmv2->blob_signature = cpu_to_le32(0x00000101); 627 ntlmv2->reserved = 0; 628 ntlmv2->time = rsp_timestamp; 629 ntlmv2->client_chal = cc; 630 ntlmv2->reserved2 = 0; 631 632 if (fips_enabled) { 633 cifs_dbg(VFS, "NTLMv2 support is disabled due to FIPS\n"); 634 rc = -EOPNOTSUPP; 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 NTLMv2 hash, rc=%d\n", rc); 642 goto unlock; 643 } 644 645 /* calculate first part of the client response (CR1) */ 646 CalcNTLMv2_response(ses, ntlmv2_hash); 647 648 /* now calculate the session key for NTLMv2 */ 649 hmac_md5_usingrawkey(ntlmv2_hash, CIFS_HMAC_MD5_HASH_SIZE, 650 ntlmv2->ntlmv2_hash, CIFS_HMAC_MD5_HASH_SIZE, 651 ses->auth_key.response); 652 rc = 0; 653 unlock: 654 cifs_server_unlock(ses->server); 655 setup_ntlmv2_rsp_ret: 656 kfree_sensitive(tiblob); 657 658 return rc; 659 } 660 661 int 662 calc_seckey(struct cifs_ses *ses) 663 { 664 unsigned char sec_key[CIFS_SESS_KEY_SIZE]; /* a nonce */ 665 struct arc4_ctx *ctx_arc4; 666 667 if (fips_enabled) 668 return -ENODEV; 669 670 get_random_bytes(sec_key, CIFS_SESS_KEY_SIZE); 671 672 ctx_arc4 = kmalloc(sizeof(*ctx_arc4), GFP_KERNEL); 673 if (!ctx_arc4) { 674 cifs_dbg(VFS, "Could not allocate arc4 context\n"); 675 return -ENOMEM; 676 } 677 678 arc4_setkey(ctx_arc4, ses->auth_key.response, CIFS_SESS_KEY_SIZE); 679 arc4_crypt(ctx_arc4, ses->ntlmssp->ciphertext, sec_key, 680 CIFS_CPHTXT_SIZE); 681 682 /* make secondary_key/nonce as session key */ 683 memcpy(ses->auth_key.response, sec_key, CIFS_SESS_KEY_SIZE); 684 /* and make len as that of session key only */ 685 ses->auth_key.len = CIFS_SESS_KEY_SIZE; 686 687 memzero_explicit(sec_key, CIFS_SESS_KEY_SIZE); 688 kfree_sensitive(ctx_arc4); 689 return 0; 690 } 691 692 void 693 cifs_crypto_secmech_release(struct TCP_Server_Info *server) 694 { 695 cifs_free_hash(&server->secmech.aes_cmac); 696 697 if (server->secmech.enc) { 698 crypto_free_aead(server->secmech.enc); 699 server->secmech.enc = NULL; 700 } 701 if (server->secmech.dec) { 702 crypto_free_aead(server->secmech.dec); 703 server->secmech.dec = NULL; 704 } 705 } 706