Skip to content

Commit 386cb81

Browse files
holger-denglerhcahca
authored andcommitted
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>
1 parent cba33db commit 386cb81

File tree

5 files changed

+76
-25
lines changed

5 files changed

+76
-25
lines changed

drivers/s390/crypto/ap_bus.c

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -218,6 +218,15 @@ int ap_sb_available(void)
218218
return 0;
219219
}
220220

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+
221230
/*
222231
* ap_fetch_qci_info(): Fetch cryptographic config info
223232
*

drivers/s390/crypto/ap_bus.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -274,6 +274,7 @@ void ap_flush_queue(struct ap_queue *aq);
274274

275275
void *ap_airq_ptr(void);
276276
int ap_sb_available(void);
277+
bool ap_is_se_guest(void);
277278
void ap_wait(enum ap_sm_wait wait);
278279
void ap_request_timeout(struct timer_list *t);
279280
void ap_bus_force_rescan(void);

drivers/s390/crypto/pkey_api.c

Lines changed: 19 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -263,7 +263,9 @@ static int pkey_clr2ep11key(const u8 *clrkey, size_t clrkeylen,
263263

264264
/* build a list of apqns suitable for ep11 keys with cpacf support */
265265
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);
267269
if (rc)
268270
goto out;
269271

@@ -299,7 +301,8 @@ static int pkey_ep11key2pkey(const u8 *key, size_t keylen,
299301

300302
/* build a list of apqns suitable for this key */
301303
rc = ep11_findcard2(&apqns, &nr_apqns, 0xFFFF, 0xFFFF,
302-
ZCRYPT_CEX7, EP11_API_V,
304+
ZCRYPT_CEX7,
305+
ap_is_se_guest() ? EP11_API_V6 : EP11_API_V4,
303306
ep11_kb_wkvp(key, keylen));
304307
if (rc)
305308
goto out;
@@ -902,6 +905,7 @@ static int pkey_verifykey2(const u8 *key, size_t keylen,
902905
} else if (hdr->type == TOKTYPE_NON_CCA &&
903906
hdr->version == TOKVER_EP11_AES) {
904907
struct ep11keyblob *kb = (struct ep11keyblob *)key;
908+
int api;
905909

906910
rc = ep11_check_aes_key(debug_info, 3, key, keylen, 1);
907911
if (rc)
@@ -911,8 +915,9 @@ static int pkey_verifykey2(const u8 *key, size_t keylen,
911915
if (ksize)
912916
*ksize = kb->head.bitlen;
913917

918+
api = ap_is_se_guest() ? EP11_API_V6 : EP11_API_V4;
914919
rc = ep11_findcard2(&_apqns, &_nr_apqns, *cardnr, *domain,
915-
ZCRYPT_CEX7, EP11_API_V,
920+
ZCRYPT_CEX7, api,
916921
ep11_kb_wkvp(key, keylen));
917922
if (rc)
918923
goto out;
@@ -926,6 +931,7 @@ static int pkey_verifykey2(const u8 *key, size_t keylen,
926931
} else if (hdr->type == TOKTYPE_NON_CCA &&
927932
hdr->version == TOKVER_EP11_AES_WITH_HEADER) {
928933
struct ep11kblob_header *kh = (struct ep11kblob_header *)key;
934+
int api;
929935

930936
rc = ep11_check_aes_key_with_hdr(debug_info, 3,
931937
key, keylen, 1);
@@ -936,8 +942,9 @@ static int pkey_verifykey2(const u8 *key, size_t keylen,
936942
if (ksize)
937943
*ksize = kh->bitlen;
938944

945+
api = ap_is_se_guest() ? EP11_API_V6 : EP11_API_V4;
939946
rc = ep11_findcard2(&_apqns, &_nr_apqns, *cardnr, *domain,
940-
ZCRYPT_CEX7, EP11_API_V,
947+
ZCRYPT_CEX7, api,
941948
ep11_kb_wkvp(key, keylen));
942949
if (rc)
943950
goto out;
@@ -1056,7 +1063,7 @@ static int pkey_apqns4key(const u8 *key, size_t keylen, u32 flags,
10561063
return -EINVAL;
10571064
if (kb->attr & EP11_BLOB_PKEY_EXTRACTABLE) {
10581065
minhwtype = ZCRYPT_CEX7;
1059-
api = EP11_API_V;
1066+
api = ap_is_se_guest() ? EP11_API_V6 : EP11_API_V4;
10601067
}
10611068
rc = ep11_findcard2(&_apqns, &_nr_apqns, 0xFFFF, 0xFFFF,
10621069
minhwtype, api, kb->wkvp);
@@ -1072,7 +1079,7 @@ static int pkey_apqns4key(const u8 *key, size_t keylen, u32 flags,
10721079
return -EINVAL;
10731080
if (kb->attr & EP11_BLOB_PKEY_EXTRACTABLE) {
10741081
minhwtype = ZCRYPT_CEX7;
1075-
api = EP11_API_V;
1082+
api = ap_is_se_guest() ? EP11_API_V6 : EP11_API_V4;
10761083
}
10771084
rc = ep11_findcard2(&_apqns, &_nr_apqns, 0xFFFF, 0xFFFF,
10781085
minhwtype, api, kb->wkvp);
@@ -1182,11 +1189,13 @@ static int pkey_apqns4keytype(enum pkey_key_type ktype,
11821189
ktype == PKEY_TYPE_EP11_AES ||
11831190
ktype == PKEY_TYPE_EP11_ECC) {
11841191
u8 *wkvp = NULL;
1192+
int api;
11851193

11861194
if (flags & PKEY_FLAGS_MATCH_CUR_MKVP)
11871195
wkvp = cur_mkvp;
1196+
api = ap_is_se_guest() ? EP11_API_V6 : EP11_API_V4;
11881197
rc = ep11_findcard2(&_apqns, &_nr_apqns, 0xFFFF, 0xFFFF,
1189-
ZCRYPT_CEX7, EP11_API_V, wkvp);
1198+
ZCRYPT_CEX7, api, wkvp);
11901199
if (rc)
11911200
goto out;
11921201

@@ -2160,7 +2169,9 @@ static ssize_t pkey_ep11_aes_attr_read(enum pkey_key_size keybits,
21602169

21612170
/* build a list of apqns able to generate an cipher key */
21622171
rc = ep11_findcard2(&apqns, &nr_apqns, 0xFFFF, 0xFFFF,
2163-
ZCRYPT_CEX7, EP11_API_V, NULL);
2172+
ZCRYPT_CEX7,
2173+
ap_is_se_guest() ? EP11_API_V6 : EP11_API_V4,
2174+
NULL);
21642175
if (rc)
21652176
return rc;
21662177

drivers/s390/crypto/zcrypt_ep11misc.c

Lines changed: 44 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,8 @@
2929
#define DEBUG_WARN(...) ZCRYPT_DBF(DBF_WARN, ##__VA_ARGS__)
3030
#define DEBUG_ERR(...) ZCRYPT_DBF(DBF_ERR, ##__VA_ARGS__)
3131

32+
#define EP11_PINBLOB_V1_BYTES 56
33+
3234
/* default iv used here */
3335
static const u8 def_iv[16] = { 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77,
3436
0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff };
@@ -592,7 +594,7 @@ static int ep11_query_info(u16 cardnr, u16 domain, u32 query_type,
592594
struct ep11_cprb *req = NULL, *rep = NULL;
593595
struct ep11_target_dev target;
594596
struct ep11_urb *urb = NULL;
595-
int api = 1, rc = -ENOMEM;
597+
int api = EP11_API_V1, rc = -ENOMEM;
596598

597599
/* request cprb and payload */
598600
req = alloc_cprb(sizeof(struct ep11_info_req_pl));
@@ -789,8 +791,7 @@ static int _ep11_genaeskey(u16 card, u16 domain,
789791
u32 attr_bool_bits;
790792
u32 attr_val_len_type;
791793
u32 attr_val_len_value;
792-
u8 pin_tag;
793-
u8 pin_len;
794+
/* followed by empty pin tag or empty pinblob tag */
794795
} __packed * req_pl;
795796
struct keygen_rep_pl {
796797
struct pl_head head;
@@ -803,9 +804,11 @@ static int _ep11_genaeskey(u16 card, u16 domain,
803804
u8 data[512];
804805
} __packed * rep_pl;
805806
struct ep11_cprb *req = NULL, *rep = NULL;
807+
size_t req_pl_size, pinblob_size = 0;
806808
struct ep11_target_dev target;
807809
struct ep11_urb *urb = NULL;
808810
int api, rc = -ENOMEM;
811+
u8 *p;
809812

810813
switch (keybitsize) {
811814
case 128:
@@ -821,12 +824,22 @@ static int _ep11_genaeskey(u16 card, u16 domain,
821824
}
822825

823826
/* request cprb and payload */
824-
req = alloc_cprb(sizeof(struct keygen_req_pl));
827+
api = (!keygenflags || keygenflags & 0x00200000) ?
828+
EP11_API_V4 : EP11_API_V1;
829+
if (ap_is_se_guest()) {
830+
/*
831+
* genkey within SE environment requires API ordinal 6
832+
* with empty pinblob
833+
*/
834+
api = EP11_API_V6;
835+
pinblob_size = EP11_PINBLOB_V1_BYTES;
836+
}
837+
req_pl_size = sizeof(struct keygen_req_pl) + ASN1TAGLEN(pinblob_size);
838+
req = alloc_cprb(req_pl_size);
825839
if (!req)
826840
goto out;
827841
req_pl = (struct keygen_req_pl *)(((u8 *)req) + sizeof(*req));
828-
api = (!keygenflags || keygenflags & 0x00200000) ? 4 : 1;
829-
prep_head(&req_pl->head, sizeof(*req_pl), api, 21); /* GenerateKey */
842+
prep_head(&req_pl->head, req_pl_size, api, 21); /* GenerateKey */
830843
req_pl->var_tag = 0x04;
831844
req_pl->var_len = sizeof(u32);
832845
req_pl->keybytes_tag = 0x04;
@@ -842,7 +855,10 @@ static int _ep11_genaeskey(u16 card, u16 domain,
842855
req_pl->attr_bool_bits = keygenflags ? keygenflags : KEY_ATTR_DEFAULTS;
843856
req_pl->attr_val_len_type = 0x00000161; /* CKA_VALUE_LEN */
844857
req_pl->attr_val_len_value = keybitsize / 8;
845-
req_pl->pin_tag = 0x04;
858+
p = ((u8 *)req_pl) + sizeof(*req_pl);
859+
/* pin tag */
860+
*p++ = 0x04;
861+
*p++ = pinblob_size;
846862

847863
/* reply cprb and payload */
848864
rep = alloc_cprb(sizeof(struct keygen_rep_pl));
@@ -857,7 +873,7 @@ static int _ep11_genaeskey(u16 card, u16 domain,
857873
target.ap_id = card;
858874
target.dom_id = domain;
859875
prep_urb(urb, &target, 1,
860-
req, sizeof(*req) + sizeof(*req_pl),
876+
req, sizeof(*req) + req_pl_size,
861877
rep, sizeof(*rep) + sizeof(*rep_pl));
862878

863879
rc = zcrypt_send_ep11_cprb(urb);
@@ -965,7 +981,7 @@ static int ep11_cryptsingle(u16 card, u16 domain,
965981
struct ep11_target_dev target;
966982
struct ep11_urb *urb = NULL;
967983
size_t req_pl_size, rep_pl_size;
968-
int n, api = 1, rc = -ENOMEM;
984+
int n, api = EP11_API_V1, rc = -ENOMEM;
969985
u8 *p;
970986

971987
/* the simple asn1 coding used has length limits */
@@ -1084,7 +1100,7 @@ static int _ep11_unwrapkey(u16 card, u16 domain,
10841100
* maybe followed by iv data
10851101
* followed by kek tag + kek blob
10861102
* followed by empty mac tag
1087-
* followed by empty pin tag
1103+
* followed by empty pin tag or empty pinblob tag
10881104
* followed by encryted key tag + bytes
10891105
*/
10901106
} __packed * req_pl;
@@ -1099,20 +1115,30 @@ static int _ep11_unwrapkey(u16 card, u16 domain,
10991115
u8 data[512];
11001116
} __packed * rep_pl;
11011117
struct ep11_cprb *req = NULL, *rep = NULL;
1118+
size_t req_pl_size, pinblob_size = 0;
11021119
struct ep11_target_dev target;
11031120
struct ep11_urb *urb = NULL;
1104-
size_t req_pl_size;
11051121
int api, rc = -ENOMEM;
11061122
u8 *p;
11071123

11081124
/* request cprb and payload */
1125+
api = (!keygenflags || keygenflags & 0x00200000) ?
1126+
EP11_API_V4 : EP11_API_V1;
1127+
if (ap_is_se_guest()) {
1128+
/*
1129+
* unwrap within SE environment requires API ordinal 6
1130+
* with empty pinblob
1131+
*/
1132+
api = EP11_API_V6;
1133+
pinblob_size = EP11_PINBLOB_V1_BYTES;
1134+
}
11091135
req_pl_size = sizeof(struct uw_req_pl) + (iv ? 16 : 0)
1110-
+ ASN1TAGLEN(keksize) + 4 + ASN1TAGLEN(enckeysize);
1136+
+ ASN1TAGLEN(keksize) + ASN1TAGLEN(0)
1137+
+ ASN1TAGLEN(pinblob_size) + ASN1TAGLEN(enckeysize);
11111138
req = alloc_cprb(req_pl_size);
11121139
if (!req)
11131140
goto out;
11141141
req_pl = (struct uw_req_pl *)(((u8 *)req) + sizeof(*req));
1115-
api = (!keygenflags || keygenflags & 0x00200000) ? 4 : 1;
11161142
prep_head(&req_pl->head, req_pl_size, api, 34); /* UnwrapKey */
11171143
req_pl->attr_tag = 0x04;
11181144
req_pl->attr_len = 7 * sizeof(u32);
@@ -1137,9 +1163,10 @@ static int _ep11_unwrapkey(u16 card, u16 domain,
11371163
/* empty mac key tag */
11381164
*p++ = 0x04;
11391165
*p++ = 0;
1140-
/* empty pin tag */
1166+
/* pin tag */
11411167
*p++ = 0x04;
1142-
*p++ = 0;
1168+
*p++ = pinblob_size;
1169+
p += pinblob_size;
11431170
/* encrypted key value tag and bytes */
11441171
p += asn1tag_write(p, 0x04, enckey, enckeysize);
11451172

@@ -1275,7 +1302,8 @@ static int _ep11_wrapkey(u16 card, u16 domain,
12751302
if (!mech || mech == 0x80060001)
12761303
req->flags |= 0x20; /* CPACF_WRAP needs special bit */
12771304
req_pl = (struct wk_req_pl *)(((u8 *)req) + sizeof(*req));
1278-
api = (!mech || mech == 0x80060001) ? 4 : 1; /* CKM_IBM_CPACF_WRAP */
1305+
api = (!mech || mech == 0x80060001) ? /* CKM_IBM_CPACF_WRAP */
1306+
EP11_API_V4 : EP11_API_V1;
12791307
prep_head(&req_pl->head, req_pl_size, api, 33); /* WrapKey */
12801308
req_pl->var_tag = 0x04;
12811309
req_pl->var_len = sizeof(u32);

drivers/s390/crypto/zcrypt_ep11misc.h

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,9 @@
1212
#include <asm/zcrypt.h>
1313
#include <asm/pkey.h>
1414

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 */
1618
#define EP11_STRUCT_MAGIC 0x1234
1719
#define EP11_BLOB_PKEY_EXTRACTABLE 0x00200000
1820

0 commit comments

Comments
 (0)