aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/s390/crypto/pkey_api.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/s390/crypto/pkey_api.c')
-rw-r--r--drivers/s390/crypto/pkey_api.c53
1 files changed, 34 insertions, 19 deletions
diff --git a/drivers/s390/crypto/pkey_api.c b/drivers/s390/crypto/pkey_api.c
index 40f1136f5568..058db724b5a2 100644
--- a/drivers/s390/crypto/pkey_api.c
+++ b/drivers/s390/crypto/pkey_api.c
@@ -572,6 +572,12 @@ int pkey_sec2protkey(u16 cardnr, u16 domain,
572 rc = -EIO; 572 rc = -EIO;
573 goto out; 573 goto out;
574 } 574 }
575 if (prepcblk->ccp_rscode != 0) {
576 DEBUG_WARN(
577 "pkey_sec2protkey unwrap secure key warning, card response %d/%d\n",
578 (int) prepcblk->ccp_rtcode,
579 (int) prepcblk->ccp_rscode);
580 }
575 581
576 /* process response cprb param block */ 582 /* process response cprb param block */
577 prepcblk->rpl_parmb = ((u8 *) prepcblk) + sizeof(struct CPRBX); 583 prepcblk->rpl_parmb = ((u8 *) prepcblk) + sizeof(struct CPRBX);
@@ -761,9 +767,10 @@ out:
761} 767}
762 768
763/* 769/*
764 * Fetch just the mkvp value via query_crypto_facility from adapter. 770 * Fetch the current and old mkvp values via
771 * query_crypto_facility from adapter.
765 */ 772 */
766static int fetch_mkvp(u16 cardnr, u16 domain, u64 *mkvp) 773static int fetch_mkvp(u16 cardnr, u16 domain, u64 mkvp[2])
767{ 774{
768 int rc, found = 0; 775 int rc, found = 0;
769 size_t rlen, vlen; 776 size_t rlen, vlen;
@@ -779,9 +786,10 @@ static int fetch_mkvp(u16 cardnr, u16 domain, u64 *mkvp)
779 rc = query_crypto_facility(cardnr, domain, "STATICSA", 786 rc = query_crypto_facility(cardnr, domain, "STATICSA",
780 rarray, &rlen, varray, &vlen); 787 rarray, &rlen, varray, &vlen);
781 if (rc == 0 && rlen > 8*8 && vlen > 184+8) { 788 if (rc == 0 && rlen > 8*8 && vlen > 184+8) {
782 if (rarray[64] == '2') { 789 if (rarray[8*8] == '2') {
783 /* current master key state is valid */ 790 /* current master key state is valid */
784 *mkvp = *((u64 *)(varray + 184)); 791 mkvp[0] = *((u64 *)(varray + 184));
792 mkvp[1] = *((u64 *)(varray + 172));
785 found = 1; 793 found = 1;
786 } 794 }
787 } 795 }
@@ -796,14 +804,14 @@ struct mkvp_info {
796 struct list_head list; 804 struct list_head list;
797 u16 cardnr; 805 u16 cardnr;
798 u16 domain; 806 u16 domain;
799 u64 mkvp; 807 u64 mkvp[2];
800}; 808};
801 809
802/* a list with mkvp_info entries */ 810/* a list with mkvp_info entries */
803static LIST_HEAD(mkvp_list); 811static LIST_HEAD(mkvp_list);
804static DEFINE_SPINLOCK(mkvp_list_lock); 812static DEFINE_SPINLOCK(mkvp_list_lock);
805 813
806static int mkvp_cache_fetch(u16 cardnr, u16 domain, u64 *mkvp) 814static int mkvp_cache_fetch(u16 cardnr, u16 domain, u64 mkvp[2])
807{ 815{
808 int rc = -ENOENT; 816 int rc = -ENOENT;
809 struct mkvp_info *ptr; 817 struct mkvp_info *ptr;
@@ -812,7 +820,7 @@ static int mkvp_cache_fetch(u16 cardnr, u16 domain, u64 *mkvp)
812 list_for_each_entry(ptr, &mkvp_list, list) { 820 list_for_each_entry(ptr, &mkvp_list, list) {
813 if (ptr->cardnr == cardnr && 821 if (ptr->cardnr == cardnr &&
814 ptr->domain == domain) { 822 ptr->domain == domain) {
815 *mkvp = ptr->mkvp; 823 memcpy(mkvp, ptr->mkvp, 2 * sizeof(u64));
816 rc = 0; 824 rc = 0;
817 break; 825 break;
818 } 826 }
@@ -822,7 +830,7 @@ static int mkvp_cache_fetch(u16 cardnr, u16 domain, u64 *mkvp)
822 return rc; 830 return rc;
823} 831}
824 832
825static void mkvp_cache_update(u16 cardnr, u16 domain, u64 mkvp) 833static void mkvp_cache_update(u16 cardnr, u16 domain, u64 mkvp[2])
826{ 834{
827 int found = 0; 835 int found = 0;
828 struct mkvp_info *ptr; 836 struct mkvp_info *ptr;
@@ -831,7 +839,7 @@ static void mkvp_cache_update(u16 cardnr, u16 domain, u64 mkvp)
831 list_for_each_entry(ptr, &mkvp_list, list) { 839 list_for_each_entry(ptr, &mkvp_list, list) {
832 if (ptr->cardnr == cardnr && 840 if (ptr->cardnr == cardnr &&
833 ptr->domain == domain) { 841 ptr->domain == domain) {
834 ptr->mkvp = mkvp; 842 memcpy(ptr->mkvp, mkvp, 2 * sizeof(u64));
835 found = 1; 843 found = 1;
836 break; 844 break;
837 } 845 }
@@ -844,7 +852,7 @@ static void mkvp_cache_update(u16 cardnr, u16 domain, u64 mkvp)
844 } 852 }
845 ptr->cardnr = cardnr; 853 ptr->cardnr = cardnr;
846 ptr->domain = domain; 854 ptr->domain = domain;
847 ptr->mkvp = mkvp; 855 memcpy(ptr->mkvp, mkvp, 2 * sizeof(u64));
848 list_add(&ptr->list, &mkvp_list); 856 list_add(&ptr->list, &mkvp_list);
849 } 857 }
850 spin_unlock_bh(&mkvp_list_lock); 858 spin_unlock_bh(&mkvp_list_lock);
@@ -888,8 +896,8 @@ int pkey_findcard(const struct pkey_seckey *seckey,
888 struct secaeskeytoken *t = (struct secaeskeytoken *) seckey; 896 struct secaeskeytoken *t = (struct secaeskeytoken *) seckey;
889 struct zcrypt_device_matrix *device_matrix; 897 struct zcrypt_device_matrix *device_matrix;
890 u16 card, dom; 898 u16 card, dom;
891 u64 mkvp; 899 u64 mkvp[2];
892 int i, rc; 900 int i, rc, oi = -1;
893 901
894 /* mkvp must not be zero */ 902 /* mkvp must not be zero */
895 if (t->mkvp == 0) 903 if (t->mkvp == 0)
@@ -910,14 +918,14 @@ int pkey_findcard(const struct pkey_seckey *seckey,
910 device_matrix->device[i].functions & 0x04) { 918 device_matrix->device[i].functions & 0x04) {
911 /* an enabled CCA Coprocessor card */ 919 /* an enabled CCA Coprocessor card */
912 /* try cached mkvp */ 920 /* try cached mkvp */
913 if (mkvp_cache_fetch(card, dom, &mkvp) == 0 && 921 if (mkvp_cache_fetch(card, dom, mkvp) == 0 &&
914 t->mkvp == mkvp) { 922 t->mkvp == mkvp[0]) {
915 if (!verify) 923 if (!verify)
916 break; 924 break;
917 /* verify: fetch mkvp from adapter */ 925 /* verify: fetch mkvp from adapter */
918 if (fetch_mkvp(card, dom, &mkvp) == 0) { 926 if (fetch_mkvp(card, dom, mkvp) == 0) {
919 mkvp_cache_update(card, dom, mkvp); 927 mkvp_cache_update(card, dom, mkvp);
920 if (t->mkvp == mkvp) 928 if (t->mkvp == mkvp[0])
921 break; 929 break;
922 } 930 }
923 } 931 }
@@ -936,14 +944,21 @@ int pkey_findcard(const struct pkey_seckey *seckey,
936 card = AP_QID_CARD(device_matrix->device[i].qid); 944 card = AP_QID_CARD(device_matrix->device[i].qid);
937 dom = AP_QID_QUEUE(device_matrix->device[i].qid); 945 dom = AP_QID_QUEUE(device_matrix->device[i].qid);
938 /* fresh fetch mkvp from adapter */ 946 /* fresh fetch mkvp from adapter */
939 if (fetch_mkvp(card, dom, &mkvp) == 0) { 947 if (fetch_mkvp(card, dom, mkvp) == 0) {
940 mkvp_cache_update(card, dom, mkvp); 948 mkvp_cache_update(card, dom, mkvp);
941 if (t->mkvp == mkvp) 949 if (t->mkvp == mkvp[0])
942 break; 950 break;
951 if (t->mkvp == mkvp[1] && oi < 0)
952 oi = i;
943 } 953 }
944 } 954 }
955 if (i >= MAX_ZDEV_ENTRIES && oi >= 0) {
956 /* old mkvp matched, use this card then */
957 card = AP_QID_CARD(device_matrix->device[oi].qid);
958 dom = AP_QID_QUEUE(device_matrix->device[oi].qid);
959 }
945 } 960 }
946 if (i < MAX_ZDEV_ENTRIES) { 961 if (i < MAX_ZDEV_ENTRIES || oi >= 0) {
947 if (pcardnr) 962 if (pcardnr)
948 *pcardnr = card; 963 *pcardnr = card;
949 if (pdomain) 964 if (pdomain)