Skip to content

Commit fb249ce

Browse files
holger-denglerhcahca
authored andcommitted
s390/pkey: fix PKEY_TYPE_EP11_AES handling in PKEY_GENSECK2 IOCTL
Commit 'fa6999e326fe ("s390/pkey: support CCA and EP11 secure ECC private keys")' introduced PKEY_TYPE_EP11_AES for the PKEY_GENSECK2 IOCTL, to enable userspace to generate securekey blobs of this type. Unfortunately, all PKEY_GENSECK2 IOCTL requests for PKEY_TYPE_EP11_AES return with an error (-EINVAL). Fix the handling for PKEY_TYPE_EP11_AES in PKEY_GENSECK2 IOCTL, so that userspace can generate securekey blobs of this type. The start of the header and the keyblob, as well as the length need special handling, depending on the internal keyversion. Add a helper function that splits an uninitialized buffer into start and size of the header as well as start and size of the payload, depending on the requested keyversion. Do the header-related calculations and the raw genkey request handling in separate functions. Use the raw genkey request function for internal purposes. 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 37a08f0 commit fb249ce

File tree

3 files changed

+102
-21
lines changed

3 files changed

+102
-21
lines changed

drivers/s390/crypto/pkey_api.c

Lines changed: 13 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -713,6 +713,11 @@ static int pkey_genseckey2(const struct pkey_apqn *apqns, size_t nr_apqns,
713713
if (*keybufsize < MINEP11AESKEYBLOBSIZE)
714714
return -EINVAL;
715715
break;
716+
case PKEY_TYPE_EP11_AES:
717+
if (*keybufsize < (sizeof(struct ep11kblob_header) +
718+
MINEP11AESKEYBLOBSIZE))
719+
return -EINVAL;
720+
break;
716721
default:
717722
return -EINVAL;
718723
}
@@ -729,9 +734,10 @@ static int pkey_genseckey2(const struct pkey_apqn *apqns, size_t nr_apqns,
729734
for (i = 0, rc = -ENODEV; i < nr_apqns; i++) {
730735
card = apqns[i].card;
731736
dom = apqns[i].domain;
732-
if (ktype == PKEY_TYPE_EP11) {
737+
if (ktype == PKEY_TYPE_EP11 ||
738+
ktype == PKEY_TYPE_EP11_AES) {
733739
rc = ep11_genaeskey(card, dom, ksize, kflags,
734-
keybuf, keybufsize);
740+
keybuf, keybufsize, ktype);
735741
} else if (ktype == PKEY_TYPE_CCA_DATA) {
736742
rc = cca_genseckey(card, dom, ksize, keybuf);
737743
*keybufsize = (rc ? 0 : SECKEYBLOBSIZE);
@@ -1466,7 +1472,7 @@ static long pkey_unlocked_ioctl(struct file *filp, unsigned int cmd,
14661472
apqns = _copy_apqns_from_user(kgs.apqns, kgs.apqn_entries);
14671473
if (IS_ERR(apqns))
14681474
return PTR_ERR(apqns);
1469-
kkey = kmalloc(klen, GFP_KERNEL);
1475+
kkey = kzalloc(klen, GFP_KERNEL);
14701476
if (!kkey) {
14711477
kfree(apqns);
14721478
return -ENOMEM;
@@ -2130,7 +2136,8 @@ static ssize_t pkey_ep11_aes_attr_read(enum pkey_key_size keybits,
21302136
for (i = 0, rc = -ENODEV; i < nr_apqns; i++) {
21312137
card = apqns[i] >> 16;
21322138
dom = apqns[i] & 0xFFFF;
2133-
rc = ep11_genaeskey(card, dom, keybits, 0, buf, &keysize);
2139+
rc = ep11_genaeskey(card, dom, keybits, 0, buf, &keysize,
2140+
PKEY_TYPE_EP11);
21342141
if (rc == 0)
21352142
break;
21362143
}
@@ -2140,7 +2147,8 @@ static ssize_t pkey_ep11_aes_attr_read(enum pkey_key_size keybits,
21402147
if (is_xts) {
21412148
keysize = MAXEP11AESKEYBLOBSIZE;
21422149
buf += MAXEP11AESKEYBLOBSIZE;
2143-
rc = ep11_genaeskey(card, dom, keybits, 0, buf, &keysize);
2150+
rc = ep11_genaeskey(card, dom, keybits, 0, buf, &keysize,
2151+
PKEY_TYPE_EP11);
21442152
if (rc == 0)
21452153
return 2 * MAXEP11AESKEYBLOBSIZE;
21462154
}

drivers/s390/crypto/zcrypt_ep11misc.c

Lines changed: 88 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -113,6 +113,50 @@ static void __exit card_cache_free(void)
113113
spin_unlock_bh(&card_list_lock);
114114
}
115115

116+
static int ep11_kb_split(const u8 *kb, size_t kblen, u32 kbver,
117+
struct ep11kblob_header **kbhdr, size_t *kbhdrsize,
118+
u8 **kbpl, size_t *kbplsize)
119+
{
120+
struct ep11kblob_header *hdr = NULL;
121+
size_t hdrsize, plsize = 0;
122+
int rc = -EINVAL;
123+
u8 *pl = NULL;
124+
125+
if (kblen < sizeof(struct ep11kblob_header))
126+
goto out;
127+
hdr = (struct ep11kblob_header *)kb;
128+
129+
switch (kbver) {
130+
case TOKVER_EP11_AES:
131+
/* header overlays the payload */
132+
hdrsize = 0;
133+
break;
134+
case TOKVER_EP11_ECC_WITH_HEADER:
135+
case TOKVER_EP11_AES_WITH_HEADER:
136+
/* payload starts after the header */
137+
hdrsize = sizeof(struct ep11kblob_header);
138+
break;
139+
default:
140+
goto out;
141+
}
142+
143+
plsize = kblen - hdrsize;
144+
pl = (u8 *)kb + hdrsize;
145+
146+
if (kbhdr)
147+
*kbhdr = hdr;
148+
if (kbhdrsize)
149+
*kbhdrsize = hdrsize;
150+
if (kbpl)
151+
*kbpl = pl;
152+
if (kbplsize)
153+
*kbplsize = plsize;
154+
155+
rc = 0;
156+
out:
157+
return rc;
158+
}
159+
116160
/*
117161
* Simple check if the key blob is a valid EP11 AES key blob with header.
118162
*/
@@ -664,8 +708,9 @@ EXPORT_SYMBOL(ep11_get_domain_info);
664708
*/
665709
#define KEY_ATTR_DEFAULTS 0x00200c00
666710

667-
int ep11_genaeskey(u16 card, u16 domain, u32 keybitsize, u32 keygenflags,
668-
u8 *keybuf, size_t *keybufsize)
711+
static int _ep11_genaeskey(u16 card, u16 domain,
712+
u32 keybitsize, u32 keygenflags,
713+
u8 *keybuf, size_t *keybufsize)
669714
{
670715
struct keygen_req_pl {
671716
struct pl_head head;
@@ -701,7 +746,6 @@ int ep11_genaeskey(u16 card, u16 domain, u32 keybitsize, u32 keygenflags,
701746
struct ep11_cprb *req = NULL, *rep = NULL;
702747
struct ep11_target_dev target;
703748
struct ep11_urb *urb = NULL;
704-
struct ep11keyblob *kb;
705749
int api, rc = -ENOMEM;
706750

707751
switch (keybitsize) {
@@ -780,21 +824,53 @@ int ep11_genaeskey(u16 card, u16 domain, u32 keybitsize, u32 keygenflags,
780824
goto out;
781825
}
782826

783-
/* copy key blob and set header values */
827+
/* copy key blob */
784828
memcpy(keybuf, rep_pl->data, rep_pl->data_len);
785829
*keybufsize = rep_pl->data_len;
786-
kb = (struct ep11keyblob *)keybuf;
787-
kb->head.type = TOKTYPE_NON_CCA;
788-
kb->head.len = rep_pl->data_len;
789-
kb->head.version = TOKVER_EP11_AES;
790-
kb->head.bitlen = keybitsize;
791830

792831
out:
793832
kfree(req);
794833
kfree(rep);
795834
kfree(urb);
796835
return rc;
797836
}
837+
838+
int ep11_genaeskey(u16 card, u16 domain, u32 keybitsize, u32 keygenflags,
839+
u8 *keybuf, size_t *keybufsize, u32 keybufver)
840+
{
841+
struct ep11kblob_header *hdr;
842+
size_t hdr_size, pl_size;
843+
u8 *pl;
844+
int rc;
845+
846+
switch (keybufver) {
847+
case TOKVER_EP11_AES:
848+
case TOKVER_EP11_AES_WITH_HEADER:
849+
break;
850+
default:
851+
return -EINVAL;
852+
}
853+
854+
rc = ep11_kb_split(keybuf, *keybufsize, keybufver,
855+
&hdr, &hdr_size, &pl, &pl_size);
856+
if (rc)
857+
return rc;
858+
859+
rc = _ep11_genaeskey(card, domain, keybitsize, keygenflags,
860+
pl, &pl_size);
861+
if (rc)
862+
return rc;
863+
864+
*keybufsize = hdr_size + pl_size;
865+
866+
/* update header information */
867+
hdr->type = TOKTYPE_NON_CCA;
868+
hdr->len = *keybufsize;
869+
hdr->version = keybufver;
870+
hdr->bitlen = keybitsize;
871+
872+
return 0;
873+
}
798874
EXPORT_SYMBOL(ep11_genaeskey);
799875

800876
static int ep11_cryptsingle(u16 card, u16 domain,
@@ -1201,7 +1277,6 @@ int ep11_clr2keyblob(u16 card, u16 domain, u32 keybitsize, u32 keygenflags,
12011277
const u8 *clrkey, u8 *keybuf, size_t *keybufsize)
12021278
{
12031279
int rc;
1204-
struct ep11keyblob *kb;
12051280
u8 encbuf[64], *kek = NULL;
12061281
size_t clrkeylen, keklen, encbuflen = sizeof(encbuf);
12071282

@@ -1223,17 +1298,15 @@ int ep11_clr2keyblob(u16 card, u16 domain, u32 keybitsize, u32 keygenflags,
12231298
}
12241299

12251300
/* Step 1: generate AES 256 bit random kek key */
1226-
rc = ep11_genaeskey(card, domain, 256,
1227-
0x00006c00, /* EN/DECRYPT, WRAP/UNWRAP */
1228-
kek, &keklen);
1301+
rc = _ep11_genaeskey(card, domain, 256,
1302+
0x00006c00, /* EN/DECRYPT, WRAP/UNWRAP */
1303+
kek, &keklen);
12291304
if (rc) {
12301305
DEBUG_ERR(
12311306
"%s generate kek key failed, rc=%d\n",
12321307
__func__, rc);
12331308
goto out;
12341309
}
1235-
kb = (struct ep11keyblob *)kek;
1236-
memset(&kb->head, 0, sizeof(kb->head));
12371310

12381311
/* Step 2: encrypt clear key value with the kek key */
12391312
rc = ep11_cryptsingle(card, domain, 0, 0, def_iv, kek, keklen,

drivers/s390/crypto/zcrypt_ep11misc.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -107,7 +107,7 @@ int ep11_get_domain_info(u16 card, u16 domain, struct ep11_domain_info *info);
107107
* Generate (random) EP11 AES secure key.
108108
*/
109109
int ep11_genaeskey(u16 card, u16 domain, u32 keybitsize, u32 keygenflags,
110-
u8 *keybuf, size_t *keybufsize);
110+
u8 *keybuf, size_t *keybufsize, u32 keybufver);
111111

112112
/*
113113
* Generate EP11 AES secure key with given clear key value.

0 commit comments

Comments
 (0)