xref: /linux/drivers/s390/crypto/pkey_ep11.c (revision 3fd6c59042dbba50391e30862beac979491145fe)
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 
19 MODULE_LICENSE("GPL");
20 MODULE_AUTHOR("IBM Corporation");
21 MODULE_DESCRIPTION("s390 protected key EP11 handler");
22 
23 #if IS_MODULE(CONFIG_PKEY_EP11)
24 static 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 };
32 MODULE_DEVICE_TABLE(ap, pkey_ep11_card_ids);
33 #endif
34 
35 /*
36  * Check key blob for known and supported EP11 key.
37  */
is_ep11_key(const u8 * key,u32 keylen)38 static 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 
is_ep11_keytype(enum pkey_key_type key_type)60 static 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 
ep11_apqns4key(const u8 * key,u32 keylen,u32 flags,struct pkey_apqn * apqns,size_t * nr_apqns)72 static 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 
137 out:
138 	kfree(_apqns);
139 	pr_debug("rc=%d\n", rc);
140 	return rc;
141 }
142 
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)143 static 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 
180 out:
181 	kfree(_apqns);
182 	pr_debug("rc=%d\n", rc);
183 	return rc;
184 }
185 
ep11_key2protkey(const struct pkey_apqn * apqns,size_t nr_apqns,const u8 * key,u32 keylen,u8 * protkey,u32 * protkeylen,u32 * protkeytype)186 static 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 
263 out:
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  */
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)278 static 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 
336 out:
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  */
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)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)
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 
415 out:
416 	kfree(local_apqns);
417 	pr_debug("rc=%d\n", rc);
418 	return rc;
419 }
420 
ep11_verifykey(const u8 * key,u32 keylen,u16 * card,u16 * dom,u32 * keytype,u32 * keybitsize,u32 * flags)421 static 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 
486 out:
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  */
ep11_slowpath_key2protkey(const struct pkey_apqn * apqns,size_t nr_apqns,const u8 * key,u32 keylen,u8 * protkey,u32 * protkeylen,u32 * protkeytype)499 static 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 
544 static 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  */
pkey_ep11_init(void)561 static 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  */
pkey_ep11_exit(void)570 static void __exit pkey_ep11_exit(void)
571 {
572 	/* unregister this module as pkey handler */
573 	pkey_handler_unregister(&ep11_handler);
574 }
575 
576 module_init(pkey_ep11_init);
577 module_exit(pkey_ep11_exit);
578