Skip to content

Commit da2863f

Browse files
holger-denglerhcahca
authored andcommitted
s390/pkey: fix PKEY_TYPE_EP11_AES handling in PKEY_CLR2SECK2 IOCTL
Commit 'fa6999e326fe ("s390/pkey: support CCA and EP11 secure ECC private keys")' introduced PKEY_TYPE_EP11_AES for the PKEY_CLR2SECK2 IOCTL to convert an AES clearkey into a securekey of this type. Unfortunately, all PKEY_CLR2SECK2 IOCTL requests with type PKEY_TYPE_EP11_AES return with an error (-EINVAL). Fix the handling for PKEY_TYPE_EP11_AES in PKEY_CLR2SECK2 IOCTL, so that userspace can convert clearkey blobs into PKEY_TYPE_EP11_AES securekey blobs. Cc: [email protected] # v5.10+ Fixes: fa6999e ("s390/pkey: support CCA and EP11 secure ECC private keys") Signed-off-by: Holger Dengler <[email protected]> Reviewed-by: Ingo Franzki <[email protected]> Signed-off-by: Heiko Carstens <[email protected]>
1 parent fb249ce commit da2863f

File tree

3 files changed

+60
-20
lines changed

3 files changed

+60
-20
lines changed

drivers/s390/crypto/pkey_api.c

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -272,7 +272,8 @@ static int pkey_clr2ep11key(const u8 *clrkey, size_t clrkeylen,
272272
card = apqns[i] >> 16;
273273
dom = apqns[i] & 0xFFFF;
274274
rc = ep11_clr2keyblob(card, dom, clrkeylen * 8,
275-
0, clrkey, keybuf, keybuflen);
275+
0, clrkey, keybuf, keybuflen,
276+
PKEY_TYPE_EP11);
276277
if (rc == 0)
277278
break;
278279
}
@@ -775,6 +776,11 @@ static int pkey_clr2seckey2(const struct pkey_apqn *apqns, size_t nr_apqns,
775776
if (*keybufsize < MINEP11AESKEYBLOBSIZE)
776777
return -EINVAL;
777778
break;
779+
case PKEY_TYPE_EP11_AES:
780+
if (*keybufsize < (sizeof(struct ep11kblob_header) +
781+
MINEP11AESKEYBLOBSIZE))
782+
return -EINVAL;
783+
break;
778784
default:
779785
return -EINVAL;
780786
}
@@ -793,9 +799,11 @@ static int pkey_clr2seckey2(const struct pkey_apqn *apqns, size_t nr_apqns,
793799
for (i = 0, rc = -ENODEV; i < nr_apqns; i++) {
794800
card = apqns[i].card;
795801
dom = apqns[i].domain;
796-
if (ktype == PKEY_TYPE_EP11) {
802+
if (ktype == PKEY_TYPE_EP11 ||
803+
ktype == PKEY_TYPE_EP11_AES) {
797804
rc = ep11_clr2keyblob(card, dom, ksize, kflags,
798-
clrkey, keybuf, keybufsize);
805+
clrkey, keybuf, keybufsize,
806+
ktype);
799807
} else if (ktype == PKEY_TYPE_CCA_DATA) {
800808
rc = cca_clr2seckey(card, dom, ksize,
801809
clrkey, keybuf);
@@ -1514,7 +1522,7 @@ static long pkey_unlocked_ioctl(struct file *filp, unsigned int cmd,
15141522
apqns = _copy_apqns_from_user(kcs.apqns, kcs.apqn_entries);
15151523
if (IS_ERR(apqns))
15161524
return PTR_ERR(apqns);
1517-
kkey = kmalloc(klen, GFP_KERNEL);
1525+
kkey = kzalloc(klen, GFP_KERNEL);
15181526
if (!kkey) {
15191527
kfree(apqns);
15201528
return -ENOMEM;

drivers/s390/crypto/zcrypt_ep11misc.c

Lines changed: 46 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1000,12 +1000,12 @@ static int ep11_cryptsingle(u16 card, u16 domain,
10001000
return rc;
10011001
}
10021002

1003-
static int ep11_unwrapkey(u16 card, u16 domain,
1004-
const u8 *kek, size_t keksize,
1005-
const u8 *enckey, size_t enckeysize,
1006-
u32 mech, const u8 *iv,
1007-
u32 keybitsize, u32 keygenflags,
1008-
u8 *keybuf, size_t *keybufsize)
1003+
static int _ep11_unwrapkey(u16 card, u16 domain,
1004+
const u8 *kek, size_t keksize,
1005+
const u8 *enckey, size_t enckeysize,
1006+
u32 mech, const u8 *iv,
1007+
u32 keybitsize, u32 keygenflags,
1008+
u8 *keybuf, size_t *keybufsize)
10091009
{
10101010
struct uw_req_pl {
10111011
struct pl_head head;
@@ -1042,7 +1042,6 @@ static int ep11_unwrapkey(u16 card, u16 domain,
10421042
struct ep11_cprb *req = NULL, *rep = NULL;
10431043
struct ep11_target_dev target;
10441044
struct ep11_urb *urb = NULL;
1045-
struct ep11keyblob *kb;
10461045
size_t req_pl_size;
10471046
int api, rc = -ENOMEM;
10481047
u8 *p;
@@ -1124,14 +1123,9 @@ static int ep11_unwrapkey(u16 card, u16 domain,
11241123
goto out;
11251124
}
11261125

1127-
/* copy key blob and set header values */
1126+
/* copy key blob */
11281127
memcpy(keybuf, rep_pl->data, rep_pl->data_len);
11291128
*keybufsize = rep_pl->data_len;
1130-
kb = (struct ep11keyblob *)keybuf;
1131-
kb->head.type = TOKTYPE_NON_CCA;
1132-
kb->head.len = rep_pl->data_len;
1133-
kb->head.version = TOKVER_EP11_AES;
1134-
kb->head.bitlen = keybitsize;
11351129

11361130
out:
11371131
kfree(req);
@@ -1140,6 +1134,42 @@ static int ep11_unwrapkey(u16 card, u16 domain,
11401134
return rc;
11411135
}
11421136

1137+
static int ep11_unwrapkey(u16 card, u16 domain,
1138+
const u8 *kek, size_t keksize,
1139+
const u8 *enckey, size_t enckeysize,
1140+
u32 mech, const u8 *iv,
1141+
u32 keybitsize, u32 keygenflags,
1142+
u8 *keybuf, size_t *keybufsize,
1143+
u8 keybufver)
1144+
{
1145+
struct ep11kblob_header *hdr;
1146+
size_t hdr_size, pl_size;
1147+
u8 *pl;
1148+
int rc;
1149+
1150+
rc = ep11_kb_split(keybuf, *keybufsize, keybufver,
1151+
&hdr, &hdr_size, &pl, &pl_size);
1152+
if (rc)
1153+
return rc;
1154+
1155+
rc = _ep11_unwrapkey(card, domain, kek, keksize, enckey, enckeysize,
1156+
mech, iv, keybitsize, keygenflags,
1157+
pl, &pl_size);
1158+
if (rc)
1159+
return rc;
1160+
1161+
*keybufsize = hdr_size + pl_size;
1162+
1163+
/* update header information */
1164+
hdr = (struct ep11kblob_header *)keybuf;
1165+
hdr->type = TOKTYPE_NON_CCA;
1166+
hdr->len = *keybufsize;
1167+
hdr->version = keybufver;
1168+
hdr->bitlen = keybitsize;
1169+
1170+
return 0;
1171+
}
1172+
11431173
static int ep11_wrapkey(u16 card, u16 domain,
11441174
const u8 *key, size_t keysize,
11451175
u32 mech, const u8 *iv,
@@ -1274,7 +1304,8 @@ static int ep11_wrapkey(u16 card, u16 domain,
12741304
}
12751305

12761306
int ep11_clr2keyblob(u16 card, u16 domain, u32 keybitsize, u32 keygenflags,
1277-
const u8 *clrkey, u8 *keybuf, size_t *keybufsize)
1307+
const u8 *clrkey, u8 *keybuf, size_t *keybufsize,
1308+
u32 keytype)
12781309
{
12791310
int rc;
12801311
u8 encbuf[64], *kek = NULL;
@@ -1321,7 +1352,7 @@ int ep11_clr2keyblob(u16 card, u16 domain, u32 keybitsize, u32 keygenflags,
13211352
/* Step 3: import the encrypted key value as a new key */
13221353
rc = ep11_unwrapkey(card, domain, kek, keklen,
13231354
encbuf, encbuflen, 0, def_iv,
1324-
keybitsize, 0, keybuf, keybufsize);
1355+
keybitsize, 0, keybuf, keybufsize, keytype);
13251356
if (rc) {
13261357
DEBUG_ERR(
13271358
"%s importing key value as new key failed,, rc=%d\n",

drivers/s390/crypto/zcrypt_ep11misc.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -113,7 +113,8 @@ int ep11_genaeskey(u16 card, u16 domain, u32 keybitsize, u32 keygenflags,
113113
* Generate EP11 AES secure key with given clear key value.
114114
*/
115115
int ep11_clr2keyblob(u16 cardnr, u16 domain, u32 keybitsize, u32 keygenflags,
116-
const u8 *clrkey, u8 *keybuf, size_t *keybufsize);
116+
const u8 *clrkey, u8 *keybuf, size_t *keybufsize,
117+
u32 keytype);
117118

118119
/*
119120
* Build a list of ep11 apqns meeting the following constrains:

0 commit comments

Comments
 (0)