Linux Audio

Check our new training course

Loading...
Note: File does not exist in v3.1.
  1// SPDX-License-Identifier: GPL-2.0
  2/*
  3 *  pkey ep11 specific code
  4 *
  5 *  Copyright IBM Corp. 2024
  6 */
  7
  8#define KMSG_COMPONENT "pkey"
  9#define pr_fmt(fmt) KMSG_COMPONENT ": " fmt
 10
 11#include <linux/init.h>
 12#include <linux/module.h>
 13#include <linux/cpufeature.h>
 14
 15#include "zcrypt_ccamisc.h"
 16#include "zcrypt_ep11misc.h"
 17#include "pkey_base.h"
 18
 19MODULE_LICENSE("GPL");
 20MODULE_AUTHOR("IBM Corporation");
 21MODULE_DESCRIPTION("s390 protected key EP11 handler");
 22
 23#if IS_MODULE(CONFIG_PKEY_EP11)
 24static struct ap_device_id pkey_ep11_card_ids[] = {
 25	{ .dev_type = AP_DEVICE_TYPE_CEX4 },
 26	{ .dev_type = AP_DEVICE_TYPE_CEX5 },
 27	{ .dev_type = AP_DEVICE_TYPE_CEX6 },
 28	{ .dev_type = AP_DEVICE_TYPE_CEX7 },
 29	{ .dev_type = AP_DEVICE_TYPE_CEX8 },
 30	{ /* end of list */ },
 31};
 32MODULE_DEVICE_TABLE(ap, pkey_ep11_card_ids);
 33#endif
 34
 35/*
 36 * Check key blob for known and supported EP11 key.
 37 */
 38static bool is_ep11_key(const u8 *key, u32 keylen)
 39{
 40	struct keytoken_header *hdr = (struct keytoken_header *)key;
 41
 42	if (keylen < sizeof(*hdr))
 43		return false;
 44
 45	switch (hdr->type) {
 46	case TOKTYPE_NON_CCA:
 47		switch (hdr->version) {
 48		case TOKVER_EP11_AES:
 49		case TOKVER_EP11_AES_WITH_HEADER:
 50		case TOKVER_EP11_ECC_WITH_HEADER:
 51			return true;
 52		default:
 53			return false;
 54		}
 55	default:
 56		return false;
 57	}
 58}
 59
 60static bool is_ep11_keytype(enum pkey_key_type key_type)
 61{
 62	switch (key_type) {
 63	case PKEY_TYPE_EP11:
 64	case PKEY_TYPE_EP11_AES:
 65	case PKEY_TYPE_EP11_ECC:
 66		return true;
 67	default:
 68		return false;
 69	}
 70}
 71
 72static int ep11_apqns4key(const u8 *key, u32 keylen, u32 flags,
 73			  struct pkey_apqn *apqns, size_t *nr_apqns)
 74{
 75	struct keytoken_header *hdr = (struct keytoken_header *)key;
 76	u32 _nr_apqns, *_apqns = NULL;
 77	int rc;
 78
 79	if (!flags)
 80		flags = PKEY_FLAGS_MATCH_CUR_MKVP;
 81
 82	if (keylen < sizeof(struct keytoken_header) || flags == 0)
 83		return -EINVAL;
 84
 85	zcrypt_wait_api_operational();
 86
 87	if (hdr->type == TOKTYPE_NON_CCA &&
 88	    (hdr->version == TOKVER_EP11_AES_WITH_HEADER ||
 89	     hdr->version == TOKVER_EP11_ECC_WITH_HEADER) &&
 90	    is_ep11_keyblob(key + sizeof(struct ep11kblob_header))) {
 91		struct ep11keyblob *kb = (struct ep11keyblob *)
 92			(key + sizeof(struct ep11kblob_header));
 93		int minhwtype = 0, api = 0;
 94
 95		if (flags != PKEY_FLAGS_MATCH_CUR_MKVP)
 96			return -EINVAL;
 97		if (kb->attr & EP11_BLOB_PKEY_EXTRACTABLE) {
 98			minhwtype = ZCRYPT_CEX7;
 99			api = ap_is_se_guest() ? EP11_API_V6 : EP11_API_V4;
100		}
101		rc = ep11_findcard2(&_apqns, &_nr_apqns, 0xFFFF, 0xFFFF,
102				    minhwtype, api, kb->wkvp);
103		if (rc)
104			goto out;
105
106	} else if (hdr->type == TOKTYPE_NON_CCA &&
107		   hdr->version == TOKVER_EP11_AES &&
108		   is_ep11_keyblob(key)) {
109		struct ep11keyblob *kb = (struct ep11keyblob *)key;
110		int minhwtype = 0, api = 0;
111
112		if (flags != PKEY_FLAGS_MATCH_CUR_MKVP)
113			return -EINVAL;
114		if (kb->attr & EP11_BLOB_PKEY_EXTRACTABLE) {
115			minhwtype = ZCRYPT_CEX7;
116			api = ap_is_se_guest() ? EP11_API_V6 : EP11_API_V4;
117		}
118		rc = ep11_findcard2(&_apqns, &_nr_apqns, 0xFFFF, 0xFFFF,
119				    minhwtype, api, kb->wkvp);
120		if (rc)
121			goto out;
122
123	} else {
124		PKEY_DBF_ERR("%s unknown/unsupported blob type %d version %d\n",
125			     __func__, hdr->type, hdr->version);
126		return -EINVAL;
127	}
128
129	if (apqns) {
130		if (*nr_apqns < _nr_apqns)
131			rc = -ENOSPC;
132		else
133			memcpy(apqns, _apqns, _nr_apqns * sizeof(u32));
134	}
135	*nr_apqns = _nr_apqns;
136
137out:
138	kfree(_apqns);
139	pr_debug("rc=%d\n", rc);
140	return rc;
141}
142
143static int ep11_apqns4type(enum pkey_key_type ktype,
144			   u8 cur_mkvp[32], u8 alt_mkvp[32], u32 flags,
145			   struct pkey_apqn *apqns, size_t *nr_apqns)
146{
147	u32 _nr_apqns, *_apqns = NULL;
148	int rc;
149
150	zcrypt_wait_api_operational();
151
152	if (ktype == PKEY_TYPE_EP11 ||
153	    ktype == PKEY_TYPE_EP11_AES ||
154	    ktype == PKEY_TYPE_EP11_ECC) {
155		u8 *wkvp = NULL;
156		int api;
157
158		if (flags & PKEY_FLAGS_MATCH_CUR_MKVP)
159			wkvp = cur_mkvp;
160		api = ap_is_se_guest() ? EP11_API_V6 : EP11_API_V4;
161		rc = ep11_findcard2(&_apqns, &_nr_apqns, 0xFFFF, 0xFFFF,
162				    ZCRYPT_CEX7, api, wkvp);
163		if (rc)
164			goto out;
165
166	} else {
167		PKEY_DBF_ERR("%s unknown/unsupported key type %d\n",
168			     __func__, (int)ktype);
169		return -EINVAL;
170	}
171
172	if (apqns) {
173		if (*nr_apqns < _nr_apqns)
174			rc = -ENOSPC;
175		else
176			memcpy(apqns, _apqns, _nr_apqns * sizeof(u32));
177	}
178	*nr_apqns = _nr_apqns;
179
180out:
181	kfree(_apqns);
182	pr_debug("rc=%d\n", rc);
183	return rc;
184}
185
186static int ep11_key2protkey(const struct pkey_apqn *apqns, size_t nr_apqns,
187			    const u8 *key, u32 keylen,
188			    u8 *protkey, u32 *protkeylen, u32 *protkeytype)
189{
190	struct keytoken_header *hdr = (struct keytoken_header *)key;
191	struct pkey_apqn *local_apqns = NULL;
192	int i, rc;
193
194	if (keylen < sizeof(*hdr))
195		return -EINVAL;
196
197	if (hdr->type == TOKTYPE_NON_CCA &&
198	    hdr->version == TOKVER_EP11_AES_WITH_HEADER &&
199	    is_ep11_keyblob(key + sizeof(struct ep11kblob_header))) {
200		/* EP11 AES key blob with header */
201		if (ep11_check_aes_key_with_hdr(pkey_dbf_info,
202						3, key, keylen, 1))
203			return -EINVAL;
204	} else if (hdr->type == TOKTYPE_NON_CCA &&
205		   hdr->version == TOKVER_EP11_ECC_WITH_HEADER &&
206		   is_ep11_keyblob(key + sizeof(struct ep11kblob_header))) {
207		/* EP11 ECC key blob with header */
208		if (ep11_check_ecc_key_with_hdr(pkey_dbf_info,
209						3, key, keylen, 1))
210			return -EINVAL;
211	} else if (hdr->type == TOKTYPE_NON_CCA &&
212		   hdr->version == TOKVER_EP11_AES &&
213		   is_ep11_keyblob(key)) {
214		/* EP11 AES key blob with header in session field */
215		if (ep11_check_aes_key(pkey_dbf_info, 3, key, keylen, 1))
216			return -EINVAL;
217	} else {
218		PKEY_DBF_ERR("%s unknown/unsupported blob type %d version %d\n",
219			     __func__, hdr->type, hdr->version);
220		return -EINVAL;
221	}
222
223	zcrypt_wait_api_operational();
224
225	if (!apqns || (nr_apqns == 1 &&
226		       apqns[0].card == 0xFFFF && apqns[0].domain == 0xFFFF)) {
227		nr_apqns = MAXAPQNSINLIST;
228		local_apqns = kmalloc_array(nr_apqns, sizeof(struct pkey_apqn),
229					    GFP_KERNEL);
230		if (!local_apqns)
231			return -ENOMEM;
232		rc = ep11_apqns4key(key, keylen, 0, local_apqns, &nr_apqns);
233		if (rc)
234			goto out;
235		apqns = local_apqns;
236	}
237
238	for (rc = -ENODEV, i = 0; rc && i < nr_apqns; i++) {
239		if (hdr->type == TOKTYPE_NON_CCA &&
240		    hdr->version == TOKVER_EP11_AES_WITH_HEADER &&
241		    is_ep11_keyblob(key + sizeof(struct ep11kblob_header))) {
242			rc = ep11_kblob2protkey(apqns[i].card, apqns[i].domain,
243						key, hdr->len, protkey,
244						protkeylen, protkeytype);
245		} else if (hdr->type == TOKTYPE_NON_CCA &&
246			   hdr->version == TOKVER_EP11_ECC_WITH_HEADER &&
247			   is_ep11_keyblob(key + sizeof(struct ep11kblob_header))) {
248			rc = ep11_kblob2protkey(apqns[i].card, apqns[i].domain,
249						key, hdr->len, protkey,
250						protkeylen, protkeytype);
251		} else if (hdr->type == TOKTYPE_NON_CCA &&
252			   hdr->version == TOKVER_EP11_AES &&
253			   is_ep11_keyblob(key)) {
254			rc = ep11_kblob2protkey(apqns[i].card, apqns[i].domain,
255						key, hdr->len, protkey,
256						protkeylen, protkeytype);
257		} else {
258			rc = -EINVAL;
259			break;
260		}
261	}
262
263out:
264	kfree(local_apqns);
265	pr_debug("rc=%d\n", rc);
266	return rc;
267}
268
269/*
270 * Generate EP11 secure key.
271 * As of now only EP11 AES secure keys are supported.
272 * keytype is one of the PKEY_KEYTYPE_* constants,
273 * subtype may be PKEY_TYPE_EP11 or PKEY_TYPE_EP11_AES
274 * or 0 (results in subtype PKEY_TYPE_EP11_AES),
275 * keybitsize is the bit size of the key (may be 0 for
276 * keytype PKEY_KEYTYPE_AES_*).
277 */
278static int ep11_gen_key(const struct pkey_apqn *apqns, size_t nr_apqns,
279			u32 keytype, u32 subtype,
280			u32 keybitsize, u32 flags,
281			u8 *keybuf, u32 *keybuflen, u32 *_keyinfo)
282{
283	struct pkey_apqn *local_apqns = NULL;
284	int i, len, rc;
285
286	/* check keytype, subtype, keybitsize */
287	switch (keytype) {
288	case PKEY_KEYTYPE_AES_128:
289	case PKEY_KEYTYPE_AES_192:
290	case PKEY_KEYTYPE_AES_256:
291		len = pkey_keytype_aes_to_size(keytype);
292		if (keybitsize && keybitsize != 8 * len) {
293			PKEY_DBF_ERR("%s unknown/unsupported keybitsize %d\n",
294				     __func__, keybitsize);
295			return -EINVAL;
296		}
297		keybitsize = 8 * len;
298		switch (subtype) {
299		case PKEY_TYPE_EP11:
300		case PKEY_TYPE_EP11_AES:
301			break;
302		default:
303			PKEY_DBF_ERR("%s unknown/unsupported subtype %d\n",
304				     __func__, subtype);
305			return -EINVAL;
306		}
307		break;
308	default:
309		PKEY_DBF_ERR("%s unknown/unsupported keytype %d\n",
310			     __func__, keytype);
311		return -EINVAL;
312	}
313
314	zcrypt_wait_api_operational();
315
316	if (!apqns || (nr_apqns == 1 &&
317		       apqns[0].card == 0xFFFF && apqns[0].domain == 0xFFFF)) {
318		nr_apqns = MAXAPQNSINLIST;
319		local_apqns = kmalloc_array(nr_apqns, sizeof(struct pkey_apqn),
320					    GFP_KERNEL);
321		if (!local_apqns)
322			return -ENOMEM;
323		rc = ep11_apqns4type(subtype, NULL, NULL, 0,
324				     local_apqns, &nr_apqns);
325		if (rc)
326			goto out;
327		apqns = local_apqns;
328	}
329
330	for (rc = -ENODEV, i = 0; rc && i < nr_apqns; i++) {
331		rc = ep11_genaeskey(apqns[i].card, apqns[i].domain,
332				    keybitsize, flags,
333				    keybuf, keybuflen, subtype);
334	}
335
336out:
337	kfree(local_apqns);
338	pr_debug("rc=%d\n", rc);
339	return rc;
340}
341
342/*
343 * Generate EP11 secure key with given clear key value.
344 * As of now only EP11 AES secure keys are supported.
345 * keytype is one of the PKEY_KEYTYPE_* constants,
346 * subtype may be PKEY_TYPE_EP11 or PKEY_TYPE_EP11_AES
347 * or 0 (assumes PKEY_TYPE_EP11_AES then).
348 * keybitsize is the bit size of the key (may be 0 for
349 * keytype PKEY_KEYTYPE_AES_*).
350 */
351static int ep11_clr2key(const struct pkey_apqn *apqns, size_t nr_apqns,
352			u32 keytype, u32 subtype,
353			u32 keybitsize, u32 flags,
354			const u8 *clrkey, u32 clrkeylen,
355			u8 *keybuf, u32 *keybuflen, u32 *_keyinfo)
356{
357	struct pkey_apqn *local_apqns = NULL;
358	int i, len, rc;
359
360	/* check keytype, subtype, clrkeylen, keybitsize */
361	switch (keytype) {
362	case PKEY_KEYTYPE_AES_128:
363	case PKEY_KEYTYPE_AES_192:
364	case PKEY_KEYTYPE_AES_256:
365		len = pkey_keytype_aes_to_size(keytype);
366		if (keybitsize && keybitsize != 8 * len) {
367			PKEY_DBF_ERR("%s unknown/unsupported keybitsize %d\n",
368				     __func__, keybitsize);
369			return -EINVAL;
370		}
371		keybitsize = 8 * len;
372		if (clrkeylen != len) {
373			PKEY_DBF_ERR("%s invalid clear key len %d != %d\n",
374				     __func__, clrkeylen, len);
375			return -EINVAL;
376		}
377		switch (subtype) {
378		case PKEY_TYPE_EP11:
379		case PKEY_TYPE_EP11_AES:
380			break;
381		default:
382			PKEY_DBF_ERR("%s unknown/unsupported subtype %d\n",
383				     __func__, subtype);
384			return -EINVAL;
385		}
386		break;
387	default:
388		PKEY_DBF_ERR("%s unknown/unsupported keytype %d\n",
389			     __func__, keytype);
390		return -EINVAL;
391	}
392
393	zcrypt_wait_api_operational();
394
395	if (!apqns || (nr_apqns == 1 &&
396		       apqns[0].card == 0xFFFF && apqns[0].domain == 0xFFFF)) {
397		nr_apqns = MAXAPQNSINLIST;
398		local_apqns = kmalloc_array(nr_apqns, sizeof(struct pkey_apqn),
399					    GFP_KERNEL);
400		if (!local_apqns)
401			return -ENOMEM;
402		rc = ep11_apqns4type(subtype, NULL, NULL, 0,
403				     local_apqns, &nr_apqns);
404		if (rc)
405			goto out;
406		apqns = local_apqns;
407	}
408
409	for (rc = -ENODEV, i = 0; rc && i < nr_apqns; i++) {
410		rc = ep11_clr2keyblob(apqns[i].card, apqns[i].domain,
411				      keybitsize, flags, clrkey,
412				      keybuf, keybuflen, subtype);
413	}
414
415out:
416	kfree(local_apqns);
417	pr_debug("rc=%d\n", rc);
418	return rc;
419}
420
421static int ep11_verifykey(const u8 *key, u32 keylen,
422			  u16 *card, u16 *dom,
423			  u32 *keytype, u32 *keybitsize, u32 *flags)
424{
425	struct keytoken_header *hdr = (struct keytoken_header *)key;
426	u32 nr_apqns, *apqns = NULL;
427	int rc;
428
429	if (keylen < sizeof(*hdr))
430		return -EINVAL;
431
432	zcrypt_wait_api_operational();
433
434	if (hdr->type == TOKTYPE_NON_CCA &&
435	    hdr->version == TOKVER_EP11_AES) {
436		struct ep11keyblob *kb = (struct ep11keyblob *)key;
437		int api;
438
439		rc = ep11_check_aes_key(pkey_dbf_info, 3, key, keylen, 1);
440		if (rc)
441			goto out;
442		*keytype = PKEY_TYPE_EP11;
443		*keybitsize = kb->head.bitlen;
444
445		api = ap_is_se_guest() ? EP11_API_V6 : EP11_API_V4;
446		rc = ep11_findcard2(&apqns, &nr_apqns, *card, *dom,
447				    ZCRYPT_CEX7, api,
448				    ep11_kb_wkvp(key, keylen));
449		if (rc)
450			goto out;
451
452		*flags = PKEY_FLAGS_MATCH_CUR_MKVP;
453
454		*card = ((struct pkey_apqn *)apqns)->card;
455		*dom = ((struct pkey_apqn *)apqns)->domain;
456
457	} else if (hdr->type == TOKTYPE_NON_CCA &&
458		   hdr->version == TOKVER_EP11_AES_WITH_HEADER) {
459		struct ep11kblob_header *kh = (struct ep11kblob_header *)key;
460		int api;
461
462		rc = ep11_check_aes_key_with_hdr(pkey_dbf_info,
463						 3, key, keylen, 1);
464		if (rc)
465			goto out;
466		*keytype = PKEY_TYPE_EP11_AES;
467		*keybitsize = kh->bitlen;
468
469		api = ap_is_se_guest() ? EP11_API_V6 : EP11_API_V4;
470		rc = ep11_findcard2(&apqns, &nr_apqns, *card, *dom,
471				    ZCRYPT_CEX7, api,
472				    ep11_kb_wkvp(key, keylen));
473		if (rc)
474			goto out;
475
476		*flags = PKEY_FLAGS_MATCH_CUR_MKVP;
477
478		*card = ((struct pkey_apqn *)apqns)->card;
479		*dom = ((struct pkey_apqn *)apqns)->domain;
480
481	} else {
482		/* unknown/unsupported key blob */
483		rc = -EINVAL;
484	}
485
486out:
487	kfree(apqns);
488	pr_debug("rc=%d\n", rc);
489	return rc;
490}
491
492/*
493 * This function provides an alternate but usually slow way
494 * to convert a 'clear key token' with AES key material into
495 * a protected key. That is done via an intermediate step
496 * which creates an EP11 AES secure key first and then derives
497 * the protected key from this secure key.
498 */
499static int ep11_slowpath_key2protkey(const struct pkey_apqn *apqns,
500				     size_t nr_apqns,
501				     const u8 *key, u32 keylen,
502				     u8 *protkey, u32 *protkeylen,
503				     u32 *protkeytype)
504{
505	const struct keytoken_header *hdr = (const struct keytoken_header *)key;
506	const struct clearkeytoken *t = (const struct clearkeytoken *)key;
507	u32 tmplen, keysize = 0;
508	u8 *tmpbuf;
509	int i, rc;
510
511	if (keylen < sizeof(*hdr))
512		return -EINVAL;
513
514	if (hdr->type == TOKTYPE_NON_CCA &&
515	    hdr->version == TOKVER_CLEAR_KEY)
516		keysize = pkey_keytype_aes_to_size(t->keytype);
517	if (!keysize || t->len != keysize)
518		return -EINVAL;
519
520	/* alloc tmp key buffer */
521	tmpbuf = kmalloc(MAXEP11AESKEYBLOBSIZE, GFP_ATOMIC);
522	if (!tmpbuf)
523		return -ENOMEM;
524
525	/* try two times in case of failure */
526	for (i = 0, rc = -ENODEV; i < 2 && rc; i++) {
527		tmplen = MAXEP11AESKEYBLOBSIZE;
528		rc = ep11_clr2key(NULL, 0, t->keytype, PKEY_TYPE_EP11,
529				  8 * keysize, 0, t->clearkey, t->len,
530				  tmpbuf, &tmplen, NULL);
531		pr_debug("ep11_clr2key()=%d\n", rc);
532		if (rc)
533			continue;
534		rc = ep11_key2protkey(NULL, 0, tmpbuf, tmplen,
535				      protkey, protkeylen, protkeytype);
536		pr_debug("ep11_key2protkey()=%d\n", rc);
537	}
538
539	kfree(tmpbuf);
540	pr_debug("rc=%d\n", rc);
541	return rc;
542}
543
544static struct pkey_handler ep11_handler = {
545	.module			 = THIS_MODULE,
546	.name			 = "PKEY EP11 handler",
547	.is_supported_key	 = is_ep11_key,
548	.is_supported_keytype	 = is_ep11_keytype,
549	.key_to_protkey		 = ep11_key2protkey,
550	.slowpath_key_to_protkey = ep11_slowpath_key2protkey,
551	.gen_key		 = ep11_gen_key,
552	.clr_to_key		 = ep11_clr2key,
553	.verify_key		 = ep11_verifykey,
554	.apqns_for_key		 = ep11_apqns4key,
555	.apqns_for_keytype	 = ep11_apqns4type,
556};
557
558/*
559 * Module init
560 */
561static int __init pkey_ep11_init(void)
562{
563	/* register this module as pkey handler for all the ep11 stuff */
564	return pkey_handler_register(&ep11_handler);
565}
566
567/*
568 * Module exit
569 */
570static void __exit pkey_ep11_exit(void)
571{
572	/* unregister this module as pkey handler */
573	pkey_handler_unregister(&ep11_handler);
574}
575
576module_init(pkey_ep11_init);
577module_exit(pkey_ep11_exit);