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