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

s390/zcrypt_ep11misc: support API ordinal 6 with empty pin-blob

Secure execution guest environments require an empty pinblob in all
key generation and unwrap requests. Empty pinblobs are only available
in EP11 API ordinal 6 or higher.

Add an empty pinblob to key generation and unwrap requests, if the AP
secure binding facility is available. In all other cases, stay with
the empty pin tag (no pinblob) and the current API ordinals.

The EP11 API ordinal also needs to be considered when the pkey module
tries to figure out the list of eligible cards for key operations
with protected keys in secure execution environment.

These changes are transparent to userspace but required for running
an secure execution guest with handling key generate and key derive
(e.g. secure key to protected key) correct. Especially using EP11
secure keys with the kernel dm-crypt layer requires this patch.

Co-developed-by: Harald Freudenberger <freude@linux.ibm.com>
Signed-off-by: Harald Freudenberger <freude@linux.ibm.com>
Signed-off-by: Holger Dengler <dengler@linux.ibm.com>
Reviewed-by: Ingo Franzki <ifranzki@linux.ibm.com>
Signed-off-by: Heiko Carstens <hca@linux.ibm.com>

authored by

Holger Dengler and committed by
Heiko Carstens
386cb81e cba33db3

+76 -25
+9
drivers/s390/crypto/ap_bus.c
··· 219 219 } 220 220 221 221 /* 222 + * ap_is_se_guest(): Check for SE guest with AP pass-through support. 223 + */ 224 + bool ap_is_se_guest(void) 225 + { 226 + return is_prot_virt_guest() && ap_sb_available(); 227 + } 228 + EXPORT_SYMBOL(ap_is_se_guest); 229 + 230 + /* 222 231 * ap_fetch_qci_info(): Fetch cryptographic config info 223 232 * 224 233 * Returns the ap configuration info fetched via PQAP(QCI).
+1
drivers/s390/crypto/ap_bus.h
··· 274 274 275 275 void *ap_airq_ptr(void); 276 276 int ap_sb_available(void); 277 + bool ap_is_se_guest(void); 277 278 void ap_wait(enum ap_sm_wait wait); 278 279 void ap_request_timeout(struct timer_list *t); 279 280 void ap_bus_force_rescan(void);
+19 -8
drivers/s390/crypto/pkey_api.c
··· 263 263 264 264 /* build a list of apqns suitable for ep11 keys with cpacf support */ 265 265 rc = ep11_findcard2(&apqns, &nr_apqns, 0xFFFF, 0xFFFF, 266 - ZCRYPT_CEX7, EP11_API_V, NULL); 266 + ZCRYPT_CEX7, 267 + ap_is_se_guest() ? EP11_API_V6 : EP11_API_V4, 268 + NULL); 267 269 if (rc) 268 270 goto out; 269 271 ··· 301 299 302 300 /* build a list of apqns suitable for this key */ 303 301 rc = ep11_findcard2(&apqns, &nr_apqns, 0xFFFF, 0xFFFF, 304 - ZCRYPT_CEX7, EP11_API_V, 302 + ZCRYPT_CEX7, 303 + ap_is_se_guest() ? EP11_API_V6 : EP11_API_V4, 305 304 ep11_kb_wkvp(key, keylen)); 306 305 if (rc) 307 306 goto out; ··· 905 902 } else if (hdr->type == TOKTYPE_NON_CCA && 906 903 hdr->version == TOKVER_EP11_AES) { 907 904 struct ep11keyblob *kb = (struct ep11keyblob *)key; 905 + int api; 908 906 909 907 rc = ep11_check_aes_key(debug_info, 3, key, keylen, 1); 910 908 if (rc) ··· 915 911 if (ksize) 916 912 *ksize = kb->head.bitlen; 917 913 914 + api = ap_is_se_guest() ? EP11_API_V6 : EP11_API_V4; 918 915 rc = ep11_findcard2(&_apqns, &_nr_apqns, *cardnr, *domain, 919 - ZCRYPT_CEX7, EP11_API_V, 916 + ZCRYPT_CEX7, api, 920 917 ep11_kb_wkvp(key, keylen)); 921 918 if (rc) 922 919 goto out; ··· 931 926 } else if (hdr->type == TOKTYPE_NON_CCA && 932 927 hdr->version == TOKVER_EP11_AES_WITH_HEADER) { 933 928 struct ep11kblob_header *kh = (struct ep11kblob_header *)key; 929 + int api; 934 930 935 931 rc = ep11_check_aes_key_with_hdr(debug_info, 3, 936 932 key, keylen, 1); ··· 942 936 if (ksize) 943 937 *ksize = kh->bitlen; 944 938 939 + api = ap_is_se_guest() ? EP11_API_V6 : EP11_API_V4; 945 940 rc = ep11_findcard2(&_apqns, &_nr_apqns, *cardnr, *domain, 946 - ZCRYPT_CEX7, EP11_API_V, 941 + ZCRYPT_CEX7, api, 947 942 ep11_kb_wkvp(key, keylen)); 948 943 if (rc) 949 944 goto out; ··· 1063 1056 return -EINVAL; 1064 1057 if (kb->attr & EP11_BLOB_PKEY_EXTRACTABLE) { 1065 1058 minhwtype = ZCRYPT_CEX7; 1066 - api = EP11_API_V; 1059 + api = ap_is_se_guest() ? EP11_API_V6 : EP11_API_V4; 1067 1060 } 1068 1061 rc = ep11_findcard2(&_apqns, &_nr_apqns, 0xFFFF, 0xFFFF, 1069 1062 minhwtype, api, kb->wkvp); ··· 1079 1072 return -EINVAL; 1080 1073 if (kb->attr & EP11_BLOB_PKEY_EXTRACTABLE) { 1081 1074 minhwtype = ZCRYPT_CEX7; 1082 - api = EP11_API_V; 1075 + api = ap_is_se_guest() ? EP11_API_V6 : EP11_API_V4; 1083 1076 } 1084 1077 rc = ep11_findcard2(&_apqns, &_nr_apqns, 0xFFFF, 0xFFFF, 1085 1078 minhwtype, api, kb->wkvp); ··· 1189 1182 ktype == PKEY_TYPE_EP11_AES || 1190 1183 ktype == PKEY_TYPE_EP11_ECC) { 1191 1184 u8 *wkvp = NULL; 1185 + int api; 1192 1186 1193 1187 if (flags & PKEY_FLAGS_MATCH_CUR_MKVP) 1194 1188 wkvp = cur_mkvp; 1189 + api = ap_is_se_guest() ? EP11_API_V6 : EP11_API_V4; 1195 1190 rc = ep11_findcard2(&_apqns, &_nr_apqns, 0xFFFF, 0xFFFF, 1196 - ZCRYPT_CEX7, EP11_API_V, wkvp); 1191 + ZCRYPT_CEX7, api, wkvp); 1197 1192 if (rc) 1198 1193 goto out; 1199 1194 ··· 2169 2160 2170 2161 /* build a list of apqns able to generate an cipher key */ 2171 2162 rc = ep11_findcard2(&apqns, &nr_apqns, 0xFFFF, 0xFFFF, 2172 - ZCRYPT_CEX7, EP11_API_V, NULL); 2163 + ZCRYPT_CEX7, 2164 + ap_is_se_guest() ? EP11_API_V6 : EP11_API_V4, 2165 + NULL); 2173 2166 if (rc) 2174 2167 return rc; 2175 2168
+44 -16
drivers/s390/crypto/zcrypt_ep11misc.c
··· 29 29 #define DEBUG_WARN(...) ZCRYPT_DBF(DBF_WARN, ##__VA_ARGS__) 30 30 #define DEBUG_ERR(...) ZCRYPT_DBF(DBF_ERR, ##__VA_ARGS__) 31 31 32 + #define EP11_PINBLOB_V1_BYTES 56 33 + 32 34 /* default iv used here */ 33 35 static const u8 def_iv[16] = { 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 34 36 0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff }; ··· 594 592 struct ep11_cprb *req = NULL, *rep = NULL; 595 593 struct ep11_target_dev target; 596 594 struct ep11_urb *urb = NULL; 597 - int api = 1, rc = -ENOMEM; 595 + int api = EP11_API_V1, rc = -ENOMEM; 598 596 599 597 /* request cprb and payload */ 600 598 req = alloc_cprb(sizeof(struct ep11_info_req_pl)); ··· 791 789 u32 attr_bool_bits; 792 790 u32 attr_val_len_type; 793 791 u32 attr_val_len_value; 794 - u8 pin_tag; 795 - u8 pin_len; 792 + /* followed by empty pin tag or empty pinblob tag */ 796 793 } __packed * req_pl; 797 794 struct keygen_rep_pl { 798 795 struct pl_head head; ··· 804 803 u8 data[512]; 805 804 } __packed * rep_pl; 806 805 struct ep11_cprb *req = NULL, *rep = NULL; 806 + size_t req_pl_size, pinblob_size = 0; 807 807 struct ep11_target_dev target; 808 808 struct ep11_urb *urb = NULL; 809 809 int api, rc = -ENOMEM; 810 + u8 *p; 810 811 811 812 switch (keybitsize) { 812 813 case 128: ··· 824 821 } 825 822 826 823 /* request cprb and payload */ 827 - req = alloc_cprb(sizeof(struct keygen_req_pl)); 824 + api = (!keygenflags || keygenflags & 0x00200000) ? 825 + EP11_API_V4 : EP11_API_V1; 826 + if (ap_is_se_guest()) { 827 + /* 828 + * genkey within SE environment requires API ordinal 6 829 + * with empty pinblob 830 + */ 831 + api = EP11_API_V6; 832 + pinblob_size = EP11_PINBLOB_V1_BYTES; 833 + } 834 + req_pl_size = sizeof(struct keygen_req_pl) + ASN1TAGLEN(pinblob_size); 835 + req = alloc_cprb(req_pl_size); 828 836 if (!req) 829 837 goto out; 830 838 req_pl = (struct keygen_req_pl *)(((u8 *)req) + sizeof(*req)); 831 - api = (!keygenflags || keygenflags & 0x00200000) ? 4 : 1; 832 - prep_head(&req_pl->head, sizeof(*req_pl), api, 21); /* GenerateKey */ 839 + prep_head(&req_pl->head, req_pl_size, api, 21); /* GenerateKey */ 833 840 req_pl->var_tag = 0x04; 834 841 req_pl->var_len = sizeof(u32); 835 842 req_pl->keybytes_tag = 0x04; ··· 855 842 req_pl->attr_bool_bits = keygenflags ? keygenflags : KEY_ATTR_DEFAULTS; 856 843 req_pl->attr_val_len_type = 0x00000161; /* CKA_VALUE_LEN */ 857 844 req_pl->attr_val_len_value = keybitsize / 8; 858 - req_pl->pin_tag = 0x04; 845 + p = ((u8 *)req_pl) + sizeof(*req_pl); 846 + /* pin tag */ 847 + *p++ = 0x04; 848 + *p++ = pinblob_size; 859 849 860 850 /* reply cprb and payload */ 861 851 rep = alloc_cprb(sizeof(struct keygen_rep_pl)); ··· 873 857 target.ap_id = card; 874 858 target.dom_id = domain; 875 859 prep_urb(urb, &target, 1, 876 - req, sizeof(*req) + sizeof(*req_pl), 860 + req, sizeof(*req) + req_pl_size, 877 861 rep, sizeof(*rep) + sizeof(*rep_pl)); 878 862 879 863 rc = zcrypt_send_ep11_cprb(urb); ··· 981 965 struct ep11_target_dev target; 982 966 struct ep11_urb *urb = NULL; 983 967 size_t req_pl_size, rep_pl_size; 984 - int n, api = 1, rc = -ENOMEM; 968 + int n, api = EP11_API_V1, rc = -ENOMEM; 985 969 u8 *p; 986 970 987 971 /* the simple asn1 coding used has length limits */ ··· 1100 1084 * maybe followed by iv data 1101 1085 * followed by kek tag + kek blob 1102 1086 * followed by empty mac tag 1103 - * followed by empty pin tag 1087 + * followed by empty pin tag or empty pinblob tag 1104 1088 * followed by encryted key tag + bytes 1105 1089 */ 1106 1090 } __packed * req_pl; ··· 1115 1099 u8 data[512]; 1116 1100 } __packed * rep_pl; 1117 1101 struct ep11_cprb *req = NULL, *rep = NULL; 1102 + size_t req_pl_size, pinblob_size = 0; 1118 1103 struct ep11_target_dev target; 1119 1104 struct ep11_urb *urb = NULL; 1120 - size_t req_pl_size; 1121 1105 int api, rc = -ENOMEM; 1122 1106 u8 *p; 1123 1107 1124 1108 /* request cprb and payload */ 1109 + api = (!keygenflags || keygenflags & 0x00200000) ? 1110 + EP11_API_V4 : EP11_API_V1; 1111 + if (ap_is_se_guest()) { 1112 + /* 1113 + * unwrap within SE environment requires API ordinal 6 1114 + * with empty pinblob 1115 + */ 1116 + api = EP11_API_V6; 1117 + pinblob_size = EP11_PINBLOB_V1_BYTES; 1118 + } 1125 1119 req_pl_size = sizeof(struct uw_req_pl) + (iv ? 16 : 0) 1126 - + ASN1TAGLEN(keksize) + 4 + ASN1TAGLEN(enckeysize); 1120 + + ASN1TAGLEN(keksize) + ASN1TAGLEN(0) 1121 + + ASN1TAGLEN(pinblob_size) + ASN1TAGLEN(enckeysize); 1127 1122 req = alloc_cprb(req_pl_size); 1128 1123 if (!req) 1129 1124 goto out; 1130 1125 req_pl = (struct uw_req_pl *)(((u8 *)req) + sizeof(*req)); 1131 - api = (!keygenflags || keygenflags & 0x00200000) ? 4 : 1; 1132 1126 prep_head(&req_pl->head, req_pl_size, api, 34); /* UnwrapKey */ 1133 1127 req_pl->attr_tag = 0x04; 1134 1128 req_pl->attr_len = 7 * sizeof(u32); ··· 1163 1137 /* empty mac key tag */ 1164 1138 *p++ = 0x04; 1165 1139 *p++ = 0; 1166 - /* empty pin tag */ 1140 + /* pin tag */ 1167 1141 *p++ = 0x04; 1168 - *p++ = 0; 1142 + *p++ = pinblob_size; 1143 + p += pinblob_size; 1169 1144 /* encrypted key value tag and bytes */ 1170 1145 p += asn1tag_write(p, 0x04, enckey, enckeysize); 1171 1146 ··· 1302 1275 if (!mech || mech == 0x80060001) 1303 1276 req->flags |= 0x20; /* CPACF_WRAP needs special bit */ 1304 1277 req_pl = (struct wk_req_pl *)(((u8 *)req) + sizeof(*req)); 1305 - api = (!mech || mech == 0x80060001) ? 4 : 1; /* CKM_IBM_CPACF_WRAP */ 1278 + api = (!mech || mech == 0x80060001) ? /* CKM_IBM_CPACF_WRAP */ 1279 + EP11_API_V4 : EP11_API_V1; 1306 1280 prep_head(&req_pl->head, req_pl_size, api, 33); /* WrapKey */ 1307 1281 req_pl->var_tag = 0x04; 1308 1282 req_pl->var_len = sizeof(u32);
+3 -1
drivers/s390/crypto/zcrypt_ep11misc.h
··· 12 12 #include <asm/zcrypt.h> 13 13 #include <asm/pkey.h> 14 14 15 - #define EP11_API_V 4 /* highest known and supported EP11 API version */ 15 + #define EP11_API_V1 1 /* min EP11 API, default if no higher api required */ 16 + #define EP11_API_V4 4 /* supported EP11 API for the ep11misc cprbs */ 17 + #define EP11_API_V6 6 /* min EP11 API for some cprbs in SE environment */ 16 18 #define EP11_STRUCT_MAGIC 0x1234 17 19 #define EP11_BLOB_PKEY_EXTRACTABLE 0x00200000 18 20