tree: https://git.kernel.org/pub/scm/linux/kernel/git/hare/scsi-devel.git auth.v2 head: 9107ea4a3526c6801b38b7a2345b7372278a35ba commit: 9ca30b761b5f46cc6293abdd7fb89cc1732381e9 [9/12] nvme-auth: augmented challenge support config: x86_64-allyesconfig (attached as .config) compiler: gcc-9 (Debian 9.3.0-22) 9.3.0 reproduce (this is a W=1 build): # https://git.kernel.org/pub/scm/linux/kernel/git/hare/scsi-devel.git/commit/?id=9ca30b761b5f46cc6293abdd7fb89cc1732381e9 git remote add hare-scsi-devel https://git.kernel.org/pub/scm/linux/kernel/git/hare/scsi-devel.git git fetch --no-tags hare-scsi-devel auth.v2 git checkout 9ca30b761b5f46cc6293abdd7fb89cc1732381e9 # save the attached .config to linux build tree make W=1 ARCH=x86_64 If you fix the issue, kindly add following tag as appropriate Reported-by: kernel test robot All warnings (new ones prefixed by >>): drivers/nvme/host/auth.c:43:5: warning: no previous prototype for 'nvme_auth_send' [-Wmissing-prototypes] 43 | int nvme_auth_send(struct nvme_ctrl *ctrl, int qid, void *data, size_t tl) | ^~~~~~~~~~~~~~ drivers/nvme/host/auth.c:67:5: warning: no previous prototype for 'nvme_auth_receive' [-Wmissing-prototypes] 67 | int nvme_auth_receive(struct nvme_ctrl *ctrl, int qid, void *buf, size_t al, | ^~~~~~~~~~~~~~~~~ drivers/nvme/host/auth.c:120:5: warning: no previous prototype for 'nvme_auth_dhchap_negotiate' [-Wmissing-prototypes] 120 | int nvme_auth_dhchap_negotiate(struct nvme_ctrl *ctrl, | ^~~~~~~~~~~~~~~~~~~~~~~~~~ drivers/nvme/host/auth.c:149:5: warning: no previous prototype for 'nvme_auth_dhchap_challenge' [-Wmissing-prototypes] 149 | int nvme_auth_dhchap_challenge(struct nvme_ctrl *ctrl, | ^~~~~~~~~~~~~~~~~~~~~~~~~~ drivers/nvme/host/auth.c:264:5: warning: no previous prototype for 'nvme_auth_dhchap_reply' [-Wmissing-prototypes] 264 | int nvme_auth_dhchap_reply(struct nvme_ctrl *ctrl, | ^~~~~~~~~~~~~~~~~~~~~~ drivers/nvme/host/auth.c:310:5: warning: no previous prototype for 'nvme_auth_dhchap_success1' [-Wmissing-prototypes] 310 | int nvme_auth_dhchap_success1(struct nvme_ctrl *ctrl, | ^~~~~~~~~~~~~~~~~~~~~~~~~ drivers/nvme/host/auth.c:355:5: warning: no previous prototype for 'nvme_auth_dhchap_success2' [-Wmissing-prototypes] 355 | int nvme_auth_dhchap_success2(struct nvme_ctrl *ctrl, | ^~~~~~~~~~~~~~~~~~~~~~~~~ drivers/nvme/host/auth.c:370:5: warning: no previous prototype for 'nvme_auth_dhchap_failure2' [-Wmissing-prototypes] 370 | int nvme_auth_dhchap_failure2(struct nvme_ctrl *ctrl, | ^~~~~~~~~~~~~~~~~~~~~~~~~ drivers/nvme/host/auth.c:387:5: warning: no previous prototype for 'nvme_auth_select_hash' [-Wmissing-prototypes] 387 | int nvme_auth_select_hash(struct nvme_ctrl *ctrl, | ^~~~~~~~~~~~~~~~~~~~~ drivers/nvme/host/auth.c:531:5: warning: no previous prototype for 'nvme_auth_dhchap_host_response' [-Wmissing-prototypes] 531 | int nvme_auth_dhchap_host_response(struct nvme_ctrl *ctrl, | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ drivers/nvme/host/auth.c:590:5: warning: no previous prototype for 'nvme_auth_dhchap_controller_response' [-Wmissing-prototypes] 590 | int nvme_auth_dhchap_controller_response(struct nvme_ctrl *ctrl, | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ drivers/nvme/host/auth.c:656:5: warning: no previous prototype for 'nvme_auth_generate_key' [-Wmissing-prototypes] 656 | int nvme_auth_generate_key(struct nvme_ctrl *ctrl, | ^~~~~~~~~~~~~~~~~~~~~~ >> drivers/nvme/host/auth.c:691:5: warning: no previous prototype for 'nvme_auth_dhchap_exponential' [-Wmissing-prototypes] 691 | int nvme_auth_dhchap_exponential(struct nvme_ctrl *ctrl, | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~ vim +/nvme_auth_dhchap_exponential +691 drivers/nvme/host/auth.c 530 > 531 int nvme_auth_dhchap_host_response(struct nvme_ctrl *ctrl, 532 struct nvme_dhchap_context *chap) 533 { 534 SHASH_DESC_ON_STACK(shash, chap->shash_tfm); 535 u8 buf[4], *challenge = chap->c1; 536 int ret; 537 538 dev_dbg(ctrl->device, "%s: qid %d host response seq %d transaction %d\n", 539 __func__, chap->qid, chap->s1, chap->transaction); 540 if (chap->dh_tfm) { 541 challenge = kmalloc(chap->hash_len, GFP_KERNEL); 542 if (!challenge) { 543 ret = -ENOMEM; 544 goto out; 545 } 546 ret = nvme_auth_augmented_challenge(chap, chap->c1, challenge); 547 if (ret) 548 goto out; 549 } 550 shash->tfm = chap->shash_tfm; 551 ret = crypto_shash_init(shash); 552 if (ret) 553 goto out; 554 ret = crypto_shash_update(shash, challenge, chap->hash_len); 555 if (ret) 556 goto out; 557 put_unaligned_le32(chap->s1, buf); 558 ret = crypto_shash_update(shash, buf, 4); 559 if (ret) 560 goto out; 561 put_unaligned_le16(chap->transaction, buf); 562 ret = crypto_shash_update(shash, buf, 2); 563 if (ret) 564 goto out; 565 memset(buf, 0, sizeof(buf)); 566 ret = crypto_shash_update(shash, buf, 1); 567 if (ret) 568 goto out; 569 ret = crypto_shash_update(shash, "HostHost", 8); 570 if (ret) 571 goto out; 572 ret = crypto_shash_update(shash, ctrl->opts->host->nqn, 573 strlen(ctrl->opts->host->nqn)); 574 if (ret) 575 goto out; 576 ret = crypto_shash_update(shash, buf, 1); 577 if (ret) 578 goto out; 579 ret = crypto_shash_update(shash, ctrl->opts->subsysnqn, 580 strlen(ctrl->opts->subsysnqn)); 581 if (ret) 582 goto out; 583 ret = crypto_shash_final(shash, chap->response); 584 out: 585 if (challenge != chap->c1) 586 kfree(challenge); 587 return ret; 588 } 589 590 int nvme_auth_dhchap_controller_response(struct nvme_ctrl *ctrl, 591 struct nvme_dhchap_context *chap) 592 { 593 SHASH_DESC_ON_STACK(shash, chap->shash_tfm); 594 u8 buf[4], *challenge = chap->c2; 595 int ret; 596 597 if (chap->dh_tfm) { 598 challenge = kmalloc(chap->hash_len, GFP_KERNEL); 599 if (!challenge) { 600 ret = -ENOMEM; 601 goto out; 602 } 603 ret = nvme_auth_augmented_challenge(chap, chap->c2, 604 challenge); 605 if (ret) 606 goto out; 607 } 608 dev_dbg(ctrl->device, "%s: qid %d host response seq %d transaction %d\n", 609 __func__, chap->qid, chap->s2, chap->transaction); 610 dev_dbg(ctrl->device, "%s: qid %d challenge %*ph\n", 611 __func__, chap->qid, chap->hash_len, challenge); 612 dev_dbg(ctrl->device, "%s: qid %d subsysnqn %s\n", 613 __func__, chap->qid, ctrl->opts->subsysnqn); 614 dev_dbg(ctrl->device, "%s: qid %d hostnqn %s\n", 615 __func__, chap->qid, ctrl->opts->host->nqn); 616 shash->tfm = chap->shash_tfm; 617 ret = crypto_shash_init(shash); 618 if (ret) 619 goto out; 620 ret = crypto_shash_update(shash, challenge, chap->hash_len); 621 if (ret) 622 goto out; 623 put_unaligned_le32(chap->s2, buf); 624 ret = crypto_shash_update(shash, buf, 4); 625 if (ret) 626 goto out; 627 put_unaligned_le16(chap->transaction, buf); 628 ret = crypto_shash_update(shash, buf, 2); 629 if (ret) 630 goto out; 631 memset(buf, 0, 4); 632 ret = crypto_shash_update(shash, buf, 1); 633 if (ret) 634 goto out; 635 ret = crypto_shash_update(shash, "Controller", 10); 636 if (ret) 637 goto out; 638 ret = crypto_shash_update(shash, ctrl->opts->subsysnqn, 639 strlen(ctrl->opts->subsysnqn)); 640 if (ret) 641 goto out; 642 ret = crypto_shash_update(shash, buf, 1); 643 if (ret) 644 goto out; 645 ret = crypto_shash_update(shash, ctrl->opts->host->nqn, 646 strlen(ctrl->opts->host->nqn)); 647 if (ret) 648 goto out; 649 ret = crypto_shash_final(shash, chap->response); 650 out: 651 if (challenge != chap->c2) 652 kfree(challenge); 653 return ret; 654 } 655 656 int nvme_auth_generate_key(struct nvme_ctrl *ctrl, 657 struct nvme_dhchap_context *chap) 658 { 659 size_t dhchap_len = strlen(ctrl->opts->dhchap_secret) - 11; 660 u8 *decoded_key; 661 size_t decoded_len; 662 u32 crc; 663 664 if (memcmp(ctrl->opts->dhchap_secret, "DHHC-1:00:", 10)) 665 return -EINVAL; 666 667 decoded_key = kzalloc(dhchap_len, GFP_KERNEL); 668 if (!decoded_key) 669 return -ENOMEM; 670 decoded_len = base64_decode(ctrl->opts->dhchap_secret + 10, 671 dhchap_len, decoded_key); 672 if (decoded_len != 36 && decoded_len != 52 && decoded_len != 68) { 673 dev_warn(ctrl->dev, 674 "DH-HMAC-CHAP: unsupported key length %zu\n", dhchap_len); 675 return -EKEYREJECTED; 676 } 677 /* The last four bytes is the CRC in little-endian format */ 678 decoded_len -= 4; 679 crc = ~crc32(~0, decoded_key, decoded_len); 680 681 if (get_unaligned_le32(decoded_key + decoded_len) != crc) { 682 dev_warn(ctrl->dev, 683 "DH-HMAC-CHAP: key crc mismatch! (%u != %u)\n", 684 get_unaligned_le32(decoded_key + decoded_len), crc); 685 } 686 memcpy(chap->key, decoded_key, decoded_len); 687 kfree(decoded_key); 688 return 0; 689 } 690 > 691 int nvme_auth_dhchap_exponential(struct nvme_ctrl *ctrl, 692 struct nvme_dhchap_context *chap) 693 { 694 struct kpp_request *req; 695 struct crypto_wait wait; 696 struct scatterlist src, dst; 697 u8 *pkey; 698 int ret, pkey_len; 699 700 if (chap->dhgroup_id == NVME_AUTH_DHCHAP_DHGROUP_ECDH) { 701 struct ecdh p = {0}; 702 703 pkey_len = crypto_ecdh_key_len(&p); 704 pkey = kzalloc(pkey_len, GFP_KERNEL); 705 if (!pkey) 706 return -ENOMEM; 707 708 get_random_bytes(pkey, pkey_len); 709 ret = crypto_ecdh_encode_key(pkey, pkey_len, &p); 710 if (ret) { 711 dev_dbg(ctrl->device, 712 "failed to encode pkey, error %d\n", ret); 713 kfree(pkey); 714 return ret; 715 } 716 chap->host_key_len = 64; 717 chap->sess_key_len = 32; 718 } else if (chap->dhgroup_id == NVME_AUTH_DHCHAP_DHGROUP_25519) { 719 pkey_len = CURVE25519_KEY_SIZE; 720 pkey = kzalloc(pkey_len, GFP_KERNEL); 721 if (!pkey) 722 return -ENOMEM; 723 get_random_bytes(pkey, pkey_len); 724 chap->host_key_len = chap->sess_key_len = CURVE25519_KEY_SIZE; 725 } else { 726 dev_warn(ctrl->device, "Invalid DH group id %d\n", 727 chap->dhgroup_id); 728 chap->status = NVME_AUTH_DHCHAP_FAILURE_INVALID_PAYLOAD; 729 return -EINVAL; 730 } 731 732 ret = crypto_kpp_set_secret(chap->dh_tfm, pkey, pkey_len); 733 if (ret) { 734 dev_dbg(ctrl->dev, "failed to set secret, error %d\n", ret); 735 kfree(pkey); 736 return ret; 737 } 738 req = kpp_request_alloc(chap->dh_tfm, GFP_KERNEL); 739 if (!req) { 740 ret = -ENOMEM; 741 goto out_free_exp; 742 } 743 744 chap->host_key = kzalloc(chap->host_key_len, GFP_KERNEL); 745 if (!chap->host_key) { 746 ret = -ENOMEM; 747 goto out_free_req; 748 } 749 crypto_init_wait(&wait); 750 kpp_request_set_input(req, NULL, 0); 751 sg_init_one(&dst, chap->host_key, chap->host_key_len); 752 kpp_request_set_output(req, &dst, chap->host_key_len); 753 kpp_request_set_callback(req, CRYPTO_TFM_REQ_MAY_BACKLOG, 754 crypto_req_done, &wait); 755 756 ret = crypto_wait_req(crypto_kpp_generate_public_key(req), &wait); 757 if (ret) { 758 dev_dbg(ctrl->dev, 759 "failed to generate public key, error %d\n", ret); 760 goto out_free_host; 761 } 762 763 chap->sess_key = kmalloc(chap->sess_key_len, GFP_KERNEL); 764 if (!chap->sess_key) 765 goto out_free_host; 766 767 crypto_init_wait(&wait); 768 sg_init_one(&src, chap->ctrl_key, chap->ctrl_key_len); 769 kpp_request_set_input(req, &src, chap->ctrl_key_len); 770 sg_init_one(&dst, chap->sess_key, chap->sess_key_len); 771 kpp_request_set_output(req, &dst, chap->sess_key_len); 772 kpp_request_set_callback(req, CRYPTO_TFM_REQ_MAY_BACKLOG, 773 crypto_req_done, &wait); 774 775 ret = crypto_wait_req(crypto_kpp_compute_shared_secret(req), &wait); 776 if (ret) { 777 dev_dbg(ctrl->dev, 778 "failed to generate shared secret, error %d\n", ret); 779 kfree_sensitive(chap->sess_key); 780 chap->sess_key = NULL; 781 chap->sess_key_len = 0; 782 } else 783 dev_dbg(ctrl->dev, "shared secret %*ph\n", 784 (int)chap->sess_key_len, chap->sess_key); 785 out_free_host: 786 if (ret) { 787 kfree(chap->host_key); 788 chap->host_key = NULL; 789 chap->host_key_len = 0; 790 } 791 out_free_req: 792 kpp_request_free(req); 793 out_free_exp: 794 kfree_sensitive(pkey); 795 if (ret) 796 chap->status = NVME_AUTH_DHCHAP_FAILURE_INVALID_PAYLOAD; 797 return ret; 798 } 799 --- 0-DAY CI Kernel Test Service, Intel Corporation https://lists.01.org/hyperkitty/list/kbuild-all@lists.01.org