Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

Merge tag '6.12rc-more-smb3-client-fixes' of git://git.samba.org/sfrench/cifs-2.6

Pull xmb client fixes from Steve French:

- Noisy log message cleanup

- Important netfs fix for cifs crash in generic/074

- Three minor improvements to use of hashing (multichannel and mount
improvements)

- Fix decryption crash for large read with small esize

* tag '6.12rc-more-smb3-client-fixes' of git://git.samba.org/sfrench/cifs-2.6:
smb: client: make SHA-512 TFM ephemeral
smb: client: make HMAC-MD5 TFM ephemeral
smb: client: stop flooding dmesg in smb2_calc_signature()
smb: client: allocate crypto only for primary server
smb: client: fix UAF in async decryption
netfs: Fix write oops in generic/346 (9p) and generic/074 (cifs)

+182 -179
+1
fs/netfs/internal.h
··· 58 58 /* 59 59 * misc.c 60 60 */ 61 + struct folio_queue *netfs_buffer_make_space(struct netfs_io_request *rreq); 61 62 int netfs_buffer_append_folio(struct netfs_io_request *rreq, struct folio *folio, 62 63 bool needs_put); 63 64 struct folio_queue *netfs_delete_buffer_head(struct netfs_io_request *wreq);
+53 -21
fs/netfs/misc.c
··· 9 9 #include "internal.h" 10 10 11 11 /* 12 + * Make sure there's space in the rolling queue. 13 + */ 14 + struct folio_queue *netfs_buffer_make_space(struct netfs_io_request *rreq) 15 + { 16 + struct folio_queue *tail = rreq->buffer_tail, *prev; 17 + unsigned int prev_nr_slots = 0; 18 + 19 + if (WARN_ON_ONCE(!rreq->buffer && tail) || 20 + WARN_ON_ONCE(rreq->buffer && !tail)) 21 + return ERR_PTR(-EIO); 22 + 23 + prev = tail; 24 + if (prev) { 25 + if (!folioq_full(tail)) 26 + return tail; 27 + prev_nr_slots = folioq_nr_slots(tail); 28 + } 29 + 30 + tail = kmalloc(sizeof(*tail), GFP_NOFS); 31 + if (!tail) 32 + return ERR_PTR(-ENOMEM); 33 + netfs_stat(&netfs_n_folioq); 34 + folioq_init(tail); 35 + tail->prev = prev; 36 + if (prev) 37 + /* [!] NOTE: After we set prev->next, the consumer is entirely 38 + * at liberty to delete prev. 39 + */ 40 + WRITE_ONCE(prev->next, tail); 41 + 42 + rreq->buffer_tail = tail; 43 + if (!rreq->buffer) { 44 + rreq->buffer = tail; 45 + iov_iter_folio_queue(&rreq->io_iter, ITER_SOURCE, tail, 0, 0, 0); 46 + } else { 47 + /* Make sure we don't leave the master iterator pointing to a 48 + * block that might get immediately consumed. 49 + */ 50 + if (rreq->io_iter.folioq == prev && 51 + rreq->io_iter.folioq_slot == prev_nr_slots) { 52 + rreq->io_iter.folioq = tail; 53 + rreq->io_iter.folioq_slot = 0; 54 + } 55 + } 56 + rreq->buffer_tail_slot = 0; 57 + return tail; 58 + } 59 + 60 + /* 12 61 * Append a folio to the rolling queue. 13 62 */ 14 63 int netfs_buffer_append_folio(struct netfs_io_request *rreq, struct folio *folio, 15 64 bool needs_put) 16 65 { 17 - struct folio_queue *tail = rreq->buffer_tail; 66 + struct folio_queue *tail; 18 67 unsigned int slot, order = folio_order(folio); 19 68 20 - if (WARN_ON_ONCE(!rreq->buffer && tail) || 21 - WARN_ON_ONCE(rreq->buffer && !tail)) 22 - return -EIO; 23 - 24 - if (!tail || folioq_full(tail)) { 25 - tail = kmalloc(sizeof(*tail), GFP_NOFS); 26 - if (!tail) 27 - return -ENOMEM; 28 - netfs_stat(&netfs_n_folioq); 29 - folioq_init(tail); 30 - tail->prev = rreq->buffer_tail; 31 - if (tail->prev) 32 - tail->prev->next = tail; 33 - rreq->buffer_tail = tail; 34 - if (!rreq->buffer) { 35 - rreq->buffer = tail; 36 - iov_iter_folio_queue(&rreq->io_iter, ITER_SOURCE, tail, 0, 0, 0); 37 - } 38 - rreq->buffer_tail_slot = 0; 39 - } 69 + tail = netfs_buffer_make_space(rreq); 70 + if (IS_ERR(tail)) 71 + return PTR_ERR(tail); 40 72 41 73 rreq->io_iter.count += PAGE_SIZE << order; 42 74
+11 -1
fs/netfs/write_issue.c
··· 153 153 loff_t start) 154 154 { 155 155 struct netfs_io_subrequest *subreq; 156 + struct iov_iter *wreq_iter = &wreq->io_iter; 157 + 158 + /* Make sure we don't point the iterator at a used-up folio_queue 159 + * struct being used as a placeholder to prevent the queue from 160 + * collapsing. In such a case, extend the queue. 161 + */ 162 + if (iov_iter_is_folioq(wreq_iter) && 163 + wreq_iter->folioq_slot >= folioq_nr_slots(wreq_iter->folioq)) { 164 + netfs_buffer_make_space(wreq); 165 + } 156 166 157 167 subreq = netfs_alloc_subrequest(wreq); 158 168 subreq->source = stream->source; 159 169 subreq->start = start; 160 170 subreq->stream_nr = stream->stream_nr; 161 - subreq->io_iter = wreq->io_iter; 171 + subreq->io_iter = *wreq_iter; 162 172 163 173 _enter("R=%x[%x]", wreq->debug_id, subreq->debug_index); 164 174
+61 -90
fs/smb/client/cifsencrypt.c
··· 416 416 } 417 417 418 418 static int calc_ntlmv2_hash(struct cifs_ses *ses, char *ntlmv2_hash, 419 - const struct nls_table *nls_cp) 419 + const struct nls_table *nls_cp, struct shash_desc *hmacmd5) 420 420 { 421 421 int rc = 0; 422 422 int len; ··· 425 425 wchar_t *domain; 426 426 wchar_t *server; 427 427 428 - if (!ses->server->secmech.hmacmd5) { 429 - cifs_dbg(VFS, "%s: can't generate ntlmv2 hash\n", __func__); 430 - return -1; 431 - } 432 - 433 428 /* calculate md4 hash of password */ 434 429 E_md4hash(ses->password, nt_hash, nls_cp); 435 430 436 - rc = crypto_shash_setkey(ses->server->secmech.hmacmd5->tfm, nt_hash, 437 - CIFS_NTHASH_SIZE); 431 + rc = crypto_shash_setkey(hmacmd5->tfm, nt_hash, CIFS_NTHASH_SIZE); 438 432 if (rc) { 439 - cifs_dbg(VFS, "%s: Could not set NT Hash as a key\n", __func__); 433 + cifs_dbg(VFS, "%s: Could not set NT hash as a key, rc=%d\n", __func__, rc); 440 434 return rc; 441 435 } 442 436 443 - rc = crypto_shash_init(ses->server->secmech.hmacmd5); 437 + rc = crypto_shash_init(hmacmd5); 444 438 if (rc) { 445 - cifs_dbg(VFS, "%s: Could not init hmacmd5\n", __func__); 439 + cifs_dbg(VFS, "%s: Could not init HMAC-MD5, rc=%d\n", __func__, rc); 446 440 return rc; 447 441 } 448 442 449 443 /* convert ses->user_name to unicode */ 450 444 len = ses->user_name ? strlen(ses->user_name) : 0; 451 445 user = kmalloc(2 + (len * 2), GFP_KERNEL); 452 - if (user == NULL) { 453 - rc = -ENOMEM; 454 - return rc; 455 - } 446 + if (user == NULL) 447 + return -ENOMEM; 456 448 457 449 if (len) { 458 450 len = cifs_strtoUTF16(user, ses->user_name, len, nls_cp); ··· 453 461 *(u16 *)user = 0; 454 462 } 455 463 456 - rc = crypto_shash_update(ses->server->secmech.hmacmd5, 457 - (char *)user, 2 * len); 464 + rc = crypto_shash_update(hmacmd5, (char *)user, 2 * len); 458 465 kfree(user); 459 466 if (rc) { 460 - cifs_dbg(VFS, "%s: Could not update with user\n", __func__); 467 + cifs_dbg(VFS, "%s: Could not update with user, rc=%d\n", __func__, rc); 461 468 return rc; 462 469 } 463 470 ··· 465 474 len = strlen(ses->domainName); 466 475 467 476 domain = kmalloc(2 + (len * 2), GFP_KERNEL); 468 - if (domain == NULL) { 469 - rc = -ENOMEM; 470 - return rc; 471 - } 477 + if (domain == NULL) 478 + return -ENOMEM; 479 + 472 480 len = cifs_strtoUTF16((__le16 *)domain, ses->domainName, len, 473 481 nls_cp); 474 - rc = 475 - crypto_shash_update(ses->server->secmech.hmacmd5, 476 - (char *)domain, 2 * len); 482 + rc = crypto_shash_update(hmacmd5, (char *)domain, 2 * len); 477 483 kfree(domain); 478 484 if (rc) { 479 - cifs_dbg(VFS, "%s: Could not update with domain\n", 480 - __func__); 485 + cifs_dbg(VFS, "%s: Could not update with domain, rc=%d\n", __func__, rc); 481 486 return rc; 482 487 } 483 488 } else { ··· 481 494 len = strlen(ses->ip_addr); 482 495 483 496 server = kmalloc(2 + (len * 2), GFP_KERNEL); 484 - if (server == NULL) { 485 - rc = -ENOMEM; 486 - return rc; 487 - } 488 - len = cifs_strtoUTF16((__le16 *)server, ses->ip_addr, len, 489 - nls_cp); 490 - rc = 491 - crypto_shash_update(ses->server->secmech.hmacmd5, 492 - (char *)server, 2 * len); 497 + if (server == NULL) 498 + return -ENOMEM; 499 + 500 + len = cifs_strtoUTF16((__le16 *)server, ses->ip_addr, len, nls_cp); 501 + rc = crypto_shash_update(hmacmd5, (char *)server, 2 * len); 493 502 kfree(server); 494 503 if (rc) { 495 - cifs_dbg(VFS, "%s: Could not update with server\n", 496 - __func__); 504 + cifs_dbg(VFS, "%s: Could not update with server, rc=%d\n", __func__, rc); 497 505 return rc; 498 506 } 499 507 } 500 508 501 - rc = crypto_shash_final(ses->server->secmech.hmacmd5, 502 - ntlmv2_hash); 509 + rc = crypto_shash_final(hmacmd5, ntlmv2_hash); 503 510 if (rc) 504 - cifs_dbg(VFS, "%s: Could not generate md5 hash\n", __func__); 511 + cifs_dbg(VFS, "%s: Could not generate MD5 hash, rc=%d\n", __func__, rc); 505 512 506 513 return rc; 507 514 } 508 515 509 516 static int 510 - CalcNTLMv2_response(const struct cifs_ses *ses, char *ntlmv2_hash) 517 + CalcNTLMv2_response(const struct cifs_ses *ses, char *ntlmv2_hash, struct shash_desc *hmacmd5) 511 518 { 512 519 int rc; 513 520 struct ntlmv2_resp *ntlmv2 = (struct ntlmv2_resp *) ··· 512 531 hash_len = ses->auth_key.len - (CIFS_SESS_KEY_SIZE + 513 532 offsetof(struct ntlmv2_resp, challenge.key[0])); 514 533 515 - if (!ses->server->secmech.hmacmd5) { 516 - cifs_dbg(VFS, "%s: can't generate ntlmv2 hash\n", __func__); 517 - return -1; 518 - } 519 - 520 - rc = crypto_shash_setkey(ses->server->secmech.hmacmd5->tfm, 521 - ntlmv2_hash, CIFS_HMAC_MD5_HASH_SIZE); 534 + rc = crypto_shash_setkey(hmacmd5->tfm, ntlmv2_hash, CIFS_HMAC_MD5_HASH_SIZE); 522 535 if (rc) { 523 - cifs_dbg(VFS, "%s: Could not set NTLMV2 Hash as a key\n", 524 - __func__); 536 + cifs_dbg(VFS, "%s: Could not set NTLMv2 hash as a key, rc=%d\n", __func__, rc); 525 537 return rc; 526 538 } 527 539 528 - rc = crypto_shash_init(ses->server->secmech.hmacmd5); 540 + rc = crypto_shash_init(hmacmd5); 529 541 if (rc) { 530 - cifs_dbg(VFS, "%s: Could not init hmacmd5\n", __func__); 542 + cifs_dbg(VFS, "%s: Could not init HMAC-MD5, rc=%d\n", __func__, rc); 531 543 return rc; 532 544 } 533 545 534 546 if (ses->server->negflavor == CIFS_NEGFLAVOR_EXTENDED) 535 - memcpy(ntlmv2->challenge.key, 536 - ses->ntlmssp->cryptkey, CIFS_SERVER_CHALLENGE_SIZE); 547 + memcpy(ntlmv2->challenge.key, ses->ntlmssp->cryptkey, CIFS_SERVER_CHALLENGE_SIZE); 537 548 else 538 - memcpy(ntlmv2->challenge.key, 539 - ses->server->cryptkey, CIFS_SERVER_CHALLENGE_SIZE); 540 - rc = crypto_shash_update(ses->server->secmech.hmacmd5, 541 - ntlmv2->challenge.key, hash_len); 549 + memcpy(ntlmv2->challenge.key, ses->server->cryptkey, CIFS_SERVER_CHALLENGE_SIZE); 550 + 551 + rc = crypto_shash_update(hmacmd5, ntlmv2->challenge.key, hash_len); 542 552 if (rc) { 543 - cifs_dbg(VFS, "%s: Could not update with response\n", __func__); 553 + cifs_dbg(VFS, "%s: Could not update with response, rc=%d\n", __func__, rc); 544 554 return rc; 545 555 } 546 556 547 557 /* Note that the MD5 digest over writes anon.challenge_key.key */ 548 - rc = crypto_shash_final(ses->server->secmech.hmacmd5, 549 - ntlmv2->ntlmv2_hash); 558 + rc = crypto_shash_final(hmacmd5, ntlmv2->ntlmv2_hash); 550 559 if (rc) 551 - cifs_dbg(VFS, "%s: Could not generate md5 hash\n", __func__); 560 + cifs_dbg(VFS, "%s: Could not generate MD5 hash, rc=%d\n", __func__, rc); 552 561 553 562 return rc; 554 563 } ··· 546 575 int 547 576 setup_ntlmv2_rsp(struct cifs_ses *ses, const struct nls_table *nls_cp) 548 577 { 578 + struct shash_desc *hmacmd5 = NULL; 549 579 int rc; 550 580 int baselen; 551 581 unsigned int tilen; ··· 612 640 613 641 cifs_server_lock(ses->server); 614 642 615 - rc = cifs_alloc_hash("hmac(md5)", &ses->server->secmech.hmacmd5); 643 + rc = cifs_alloc_hash("hmac(md5)", &hmacmd5); 616 644 if (rc) { 645 + cifs_dbg(VFS, "Could not allocate HMAC-MD5, rc=%d\n", rc); 617 646 goto unlock; 618 647 } 619 648 620 649 /* calculate ntlmv2_hash */ 621 - rc = calc_ntlmv2_hash(ses, ntlmv2_hash, nls_cp); 650 + rc = calc_ntlmv2_hash(ses, ntlmv2_hash, nls_cp, hmacmd5); 622 651 if (rc) { 623 - cifs_dbg(VFS, "Could not get v2 hash rc %d\n", rc); 652 + cifs_dbg(VFS, "Could not get NTLMv2 hash, rc=%d\n", rc); 624 653 goto unlock; 625 654 } 626 655 627 656 /* calculate first part of the client response (CR1) */ 628 - rc = CalcNTLMv2_response(ses, ntlmv2_hash); 657 + rc = CalcNTLMv2_response(ses, ntlmv2_hash, hmacmd5); 629 658 if (rc) { 630 - cifs_dbg(VFS, "Could not calculate CR1 rc: %d\n", rc); 659 + cifs_dbg(VFS, "Could not calculate CR1, rc=%d\n", rc); 631 660 goto unlock; 632 661 } 633 662 634 663 /* now calculate the session key for NTLMv2 */ 635 - rc = crypto_shash_setkey(ses->server->secmech.hmacmd5->tfm, 636 - ntlmv2_hash, CIFS_HMAC_MD5_HASH_SIZE); 664 + rc = crypto_shash_setkey(hmacmd5->tfm, ntlmv2_hash, CIFS_HMAC_MD5_HASH_SIZE); 637 665 if (rc) { 638 - cifs_dbg(VFS, "%s: Could not set NTLMV2 Hash as a key\n", 639 - __func__); 666 + cifs_dbg(VFS, "%s: Could not set NTLMv2 hash as a key, rc=%d\n", __func__, rc); 640 667 goto unlock; 641 668 } 642 669 643 - rc = crypto_shash_init(ses->server->secmech.hmacmd5); 670 + rc = crypto_shash_init(hmacmd5); 644 671 if (rc) { 645 - cifs_dbg(VFS, "%s: Could not init hmacmd5\n", __func__); 672 + cifs_dbg(VFS, "%s: Could not init HMAC-MD5, rc=%d\n", __func__, rc); 646 673 goto unlock; 647 674 } 648 675 649 - rc = crypto_shash_update(ses->server->secmech.hmacmd5, 650 - ntlmv2->ntlmv2_hash, 651 - CIFS_HMAC_MD5_HASH_SIZE); 676 + rc = crypto_shash_update(hmacmd5, ntlmv2->ntlmv2_hash, CIFS_HMAC_MD5_HASH_SIZE); 652 677 if (rc) { 653 - cifs_dbg(VFS, "%s: Could not update with response\n", __func__); 678 + cifs_dbg(VFS, "%s: Could not update with response, rc=%d\n", __func__, rc); 654 679 goto unlock; 655 680 } 656 681 657 - rc = crypto_shash_final(ses->server->secmech.hmacmd5, 658 - ses->auth_key.response); 682 + rc = crypto_shash_final(hmacmd5, ses->auth_key.response); 659 683 if (rc) 660 - cifs_dbg(VFS, "%s: Could not generate md5 hash\n", __func__); 661 - 684 + cifs_dbg(VFS, "%s: Could not generate MD5 hash, rc=%d\n", __func__, rc); 662 685 unlock: 663 686 cifs_server_unlock(ses->server); 687 + cifs_free_hash(&hmacmd5); 664 688 setup_ntlmv2_rsp_ret: 665 689 kfree_sensitive(tiblob); 666 690 ··· 700 732 cifs_free_hash(&server->secmech.aes_cmac); 701 733 cifs_free_hash(&server->secmech.hmacsha256); 702 734 cifs_free_hash(&server->secmech.md5); 703 - cifs_free_hash(&server->secmech.sha512); 704 - cifs_free_hash(&server->secmech.hmacmd5); 705 735 706 - if (server->secmech.enc) { 707 - crypto_free_aead(server->secmech.enc); 736 + if (!SERVER_IS_CHAN(server)) { 737 + if (server->secmech.enc) { 738 + crypto_free_aead(server->secmech.enc); 739 + server->secmech.enc = NULL; 740 + } 741 + 742 + if (server->secmech.dec) { 743 + crypto_free_aead(server->secmech.dec); 744 + server->secmech.dec = NULL; 745 + } 746 + } else { 708 747 server->secmech.enc = NULL; 709 - } 710 - 711 - if (server->secmech.dec) { 712 - crypto_free_aead(server->secmech.dec); 713 748 server->secmech.dec = NULL; 714 749 } 715 750 }
-2
fs/smb/client/cifsglob.h
··· 178 178 179 179 /* crypto hashing related structure/fields, not specific to a sec mech */ 180 180 struct cifs_secmech { 181 - struct shash_desc *hmacmd5; /* hmacmd5 hash function, for NTLMv2/CR1 hashes */ 182 181 struct shash_desc *md5; /* md5 hash function, for CIFS/SMB1 signatures */ 183 182 struct shash_desc *hmacsha256; /* hmac-sha256 hash function, for SMB2 signatures */ 184 - struct shash_desc *sha512; /* sha512 hash function, for SMB3.1.1 preauth hash */ 185 183 struct shash_desc *aes_cmac; /* block-cipher based MAC function, for SMB3 signatures */ 186 184 187 185 struct crypto_aead *enc; /* smb3 encryption AEAD TFM (AES-CCM and AES-GCM) */
+1 -1
fs/smb/client/sess.c
··· 624 624 * to sign packets before we generate the channel signing key 625 625 * (we sign with the session key) 626 626 */ 627 - rc = smb311_crypto_shash_allocate(chan->server); 627 + rc = smb3_crypto_shash_allocate(chan->server); 628 628 if (rc) { 629 629 cifs_dbg(VFS, "%s: crypto alloc failed\n", __func__); 630 630 mutex_unlock(&ses->session_mutex);
+14 -14
fs/smb/client/smb2misc.c
··· 906 906 || (hdr->Status != 907 907 cpu_to_le32(NT_STATUS_MORE_PROCESSING_REQUIRED)))) 908 908 return 0; 909 - 910 909 ok: 911 - rc = smb311_crypto_shash_allocate(server); 912 - if (rc) 910 + rc = cifs_alloc_hash("sha512", &sha512); 911 + if (rc) { 912 + cifs_dbg(VFS, "%s: Could not allocate SHA512 shash, rc=%d\n", __func__, rc); 913 913 return rc; 914 + } 914 915 915 - sha512 = server->secmech.sha512; 916 916 rc = crypto_shash_init(sha512); 917 917 if (rc) { 918 - cifs_dbg(VFS, "%s: Could not init sha512 shash\n", __func__); 919 - return rc; 918 + cifs_dbg(VFS, "%s: Could not init SHA512 shash, rc=%d\n", __func__, rc); 919 + goto err_free; 920 920 } 921 921 922 922 rc = crypto_shash_update(sha512, ses->preauth_sha_hash, 923 923 SMB2_PREAUTH_HASH_SIZE); 924 924 if (rc) { 925 - cifs_dbg(VFS, "%s: Could not update sha512 shash\n", __func__); 926 - return rc; 925 + cifs_dbg(VFS, "%s: Could not update SHA512 shash, rc=%d\n", __func__, rc); 926 + goto err_free; 927 927 } 928 928 929 929 for (i = 0; i < nvec; i++) { 930 930 rc = crypto_shash_update(sha512, iov[i].iov_base, iov[i].iov_len); 931 931 if (rc) { 932 - cifs_dbg(VFS, "%s: Could not update sha512 shash\n", 933 - __func__); 934 - return rc; 932 + cifs_dbg(VFS, "%s: Could not update SHA512 shash, rc=%d\n", __func__, rc); 933 + goto err_free; 935 934 } 936 935 } 937 936 938 937 rc = crypto_shash_final(sha512, ses->preauth_sha_hash); 939 938 if (rc) { 940 - cifs_dbg(VFS, "%s: Could not finalize sha512 shash\n", 941 - __func__); 942 - return rc; 939 + cifs_dbg(VFS, "%s: Could not finalize SHA12 shash, rc=%d\n", __func__, rc); 940 + goto err_free; 943 941 } 942 + err_free: 943 + cifs_free_hash(&sha512); 944 944 945 945 return 0; 946 946 }
+28 -19
fs/smb/client/smb2ops.c
··· 4309 4309 */ 4310 4310 static int 4311 4311 crypt_message(struct TCP_Server_Info *server, int num_rqst, 4312 - struct smb_rqst *rqst, int enc) 4312 + struct smb_rqst *rqst, int enc, struct crypto_aead *tfm) 4313 4313 { 4314 4314 struct smb2_transform_hdr *tr_hdr = 4315 4315 (struct smb2_transform_hdr *)rqst[0].rq_iov[0].iov_base; ··· 4320 4320 u8 key[SMB3_ENC_DEC_KEY_SIZE]; 4321 4321 struct aead_request *req; 4322 4322 u8 *iv; 4323 - DECLARE_CRYPTO_WAIT(wait); 4324 - struct crypto_aead *tfm; 4325 4323 unsigned int crypt_len = le32_to_cpu(tr_hdr->OriginalMessageSize); 4326 4324 void *creq; 4327 4325 size_t sensitive_size; ··· 4330 4332 enc ? "en" : "de", le64_to_cpu(tr_hdr->SessionId)); 4331 4333 return rc; 4332 4334 } 4333 - 4334 - rc = smb3_crypto_aead_allocate(server); 4335 - if (rc) { 4336 - cifs_server_dbg(VFS, "%s: crypto alloc failed\n", __func__); 4337 - return rc; 4338 - } 4339 - 4340 - tfm = enc ? server->secmech.enc : server->secmech.dec; 4341 4335 4342 4336 if ((server->cipher_type == SMB2_ENCRYPTION_AES256_CCM) || 4343 4337 (server->cipher_type == SMB2_ENCRYPTION_AES256_GCM)) ··· 4370 4380 aead_request_set_crypt(req, sg, sg, crypt_len, iv); 4371 4381 aead_request_set_ad(req, assoc_data_len); 4372 4382 4373 - aead_request_set_callback(req, CRYPTO_TFM_REQ_MAY_BACKLOG, 4374 - crypto_req_done, &wait); 4375 - 4376 - rc = crypto_wait_req(enc ? crypto_aead_encrypt(req) 4377 - : crypto_aead_decrypt(req), &wait); 4383 + rc = enc ? crypto_aead_encrypt(req) : crypto_aead_decrypt(req); 4378 4384 4379 4385 if (!rc && enc) 4380 4386 memcpy(&tr_hdr->Signature, sign, SMB2_SIGNATURE_SIZE); ··· 4512 4526 /* fill the 1st iov with a transform header */ 4513 4527 fill_transform_hdr(tr_hdr, orig_len, old_rq, server->cipher_type); 4514 4528 4515 - rc = crypt_message(server, num_rqst, new_rq, 1); 4529 + rc = crypt_message(server, num_rqst, new_rq, 1, server->secmech.enc); 4516 4530 cifs_dbg(FYI, "Encrypt message returned %d\n", rc); 4517 4531 if (rc) 4518 4532 goto err_free; ··· 4537 4551 unsigned int buf_data_size, struct iov_iter *iter, 4538 4552 bool is_offloaded) 4539 4553 { 4540 - struct kvec iov[2]; 4554 + struct crypto_aead *tfm; 4541 4555 struct smb_rqst rqst = {NULL}; 4556 + struct kvec iov[2]; 4542 4557 size_t iter_size = 0; 4543 4558 int rc; 4544 4559 ··· 4555 4568 iter_size = iov_iter_count(iter); 4556 4569 } 4557 4570 4558 - rc = crypt_message(server, 1, &rqst, 0); 4571 + if (is_offloaded) { 4572 + if ((server->cipher_type == SMB2_ENCRYPTION_AES128_GCM) || 4573 + (server->cipher_type == SMB2_ENCRYPTION_AES256_GCM)) 4574 + tfm = crypto_alloc_aead("gcm(aes)", 0, 0); 4575 + else 4576 + tfm = crypto_alloc_aead("ccm(aes)", 0, 0); 4577 + if (IS_ERR(tfm)) { 4578 + rc = PTR_ERR(tfm); 4579 + cifs_server_dbg(VFS, "%s: Failed alloc decrypt TFM, rc=%d\n", __func__, rc); 4580 + 4581 + return rc; 4582 + } 4583 + } else { 4584 + if (unlikely(!server->secmech.dec)) 4585 + return -EIO; 4586 + 4587 + tfm = server->secmech.dec; 4588 + } 4589 + 4590 + rc = crypt_message(server, 1, &rqst, 0, tfm); 4559 4591 cifs_dbg(FYI, "Decrypt message returned %d\n", rc); 4592 + 4593 + if (is_offloaded) 4594 + crypto_free_aead(tfm); 4560 4595 4561 4596 if (rc) 4562 4597 return rc;
+10
fs/smb/client/smb2pdu.c
··· 1266 1266 else 1267 1267 cifs_server_dbg(VFS, "Missing expected negotiate contexts\n"); 1268 1268 } 1269 + 1270 + if (server->cipher_type && !rc) { 1271 + if (!SERVER_IS_CHAN(server)) { 1272 + rc = smb3_crypto_aead_allocate(server); 1273 + } else { 1274 + /* For channels, just reuse the primary server crypto secmech. */ 1275 + server->secmech.enc = server->primary_server->secmech.enc; 1276 + server->secmech.dec = server->primary_server->secmech.dec; 1277 + } 1278 + } 1269 1279 neg_exit: 1270 1280 free_rsp_buf(resp_buftype, rsp); 1271 1281 return rc;
+1 -1
fs/smb/client/smb2proto.h
··· 291 291 extern void smb2_copy_fs_info_to_kstatfs( 292 292 struct smb2_fs_full_size_info *pfs_inf, 293 293 struct kstatfs *kst); 294 - extern int smb311_crypto_shash_allocate(struct TCP_Server_Info *server); 294 + extern int smb3_crypto_shash_allocate(struct TCP_Server_Info *server); 295 295 extern int smb311_update_preauth_hash(struct cifs_ses *ses, 296 296 struct TCP_Server_Info *server, 297 297 struct kvec *iov, int nvec);
+2 -30
fs/smb/client/smb2transport.c
··· 26 26 #include "../common/smb2status.h" 27 27 #include "smb2glob.h" 28 28 29 - static int 30 - smb3_crypto_shash_allocate(struct TCP_Server_Info *server) 29 + int smb3_crypto_shash_allocate(struct TCP_Server_Info *server) 31 30 { 32 31 struct cifs_secmech *p = &server->secmech; 33 32 int rc; ··· 44 45 cifs_free_hash(&p->hmacsha256); 45 46 return rc; 46 47 } 47 - 48 - int 49 - smb311_crypto_shash_allocate(struct TCP_Server_Info *server) 50 - { 51 - struct cifs_secmech *p = &server->secmech; 52 - int rc = 0; 53 - 54 - rc = cifs_alloc_hash("hmac(sha256)", &p->hmacsha256); 55 - if (rc) 56 - return rc; 57 - 58 - rc = cifs_alloc_hash("cmac(aes)", &p->aes_cmac); 59 - if (rc) 60 - goto err; 61 - 62 - rc = cifs_alloc_hash("sha512", &p->sha512); 63 - if (rc) 64 - goto err; 65 - 66 - return 0; 67 - 68 - err: 69 - cifs_free_hash(&p->aes_cmac); 70 - cifs_free_hash(&p->hmacsha256); 71 - return rc; 72 - } 73 - 74 48 75 49 static 76 50 int smb2_get_sign_key(__u64 ses_id, struct TCP_Server_Info *server, u8 *key) ··· 214 242 215 243 ses = smb2_find_smb_ses(server, le64_to_cpu(shdr->SessionId)); 216 244 if (unlikely(!ses)) { 217 - cifs_server_dbg(VFS, "%s: Could not find session\n", __func__); 245 + cifs_server_dbg(FYI, "%s: Could not find session\n", __func__); 218 246 return -ENOENT; 219 247 } 220 248