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