xref: /linux/drivers/s390/crypto/pkey_api.c (revision b3d4ab2d7df9426f7f1d3671d7e2108f2ca6e970)
1 // SPDX-License-Identifier: GPL-2.0
2 /*
3  *  pkey device driver
4  *
5  *  Copyright IBM Corp. 2017, 2023
6  *
7  *  Author(s): Harald Freudenberger
8  */
9 
10 #define pr_fmt(fmt) "pkey: " fmt
11 
12 #include <linux/init.h>
13 #include <linux/miscdevice.h>
14 #include <linux/export.h>
15 #include <linux/slab.h>
16 
17 #include "zcrypt_api.h"
18 #include "zcrypt_ccamisc.h"
19 
20 #include "pkey_base.h"
21 
22 /*
23  * Helper functions
24  */
25 static int key2protkey(const struct pkey_apqn *apqns, size_t nr_apqns,
26 		       const u8 *key, size_t keylen,
27 		       u8 *protkey, u32 *protkeylen, u32 *protkeytype,
28 		       u32 xflags)
29 {
30 	int rc;
31 
32 	/* try the direct way */
33 	rc = pkey_handler_key_to_protkey(apqns, nr_apqns,
34 					 key, keylen,
35 					 protkey, protkeylen,
36 					 protkeytype, xflags);
37 
38 	/* if this did not work, try the slowpath way */
39 	if (rc == -ENODEV) {
40 		rc = pkey_handler_slowpath_key_to_protkey(apqns, nr_apqns,
41 							  key, keylen,
42 							  protkey, protkeylen,
43 							  protkeytype, xflags);
44 		if (rc)
45 			rc = -ENODEV;
46 	}
47 
48 	pr_debug("rc=%d\n", rc);
49 	return rc;
50 }
51 
52 /*
53  * In-Kernel function: Transform a key blob (of any type) into a protected key
54  */
55 int pkey_key2protkey(const u8 *key, u32 keylen,
56 		     u8 *protkey, u32 *protkeylen, u32 *protkeytype, u32 xflags)
57 {
58 	int rc;
59 
60 	rc = key2protkey(NULL, 0, key, keylen,
61 			 protkey, protkeylen, protkeytype, xflags);
62 	if (rc == -ENODEV) {
63 		pkey_handler_request_modules();
64 		rc = key2protkey(NULL, 0, key, keylen,
65 				 protkey, protkeylen, protkeytype, xflags);
66 	}
67 
68 	return rc;
69 }
70 EXPORT_SYMBOL(pkey_key2protkey);
71 
72 /*
73  * Ioctl functions
74  */
75 
76 static void *_copy_key_from_user(void __user *ukey, size_t keylen)
77 {
78 	if (!ukey || keylen < MINKEYBLOBBUFSIZE || keylen > KEYBLOBBUFSIZE)
79 		return ERR_PTR(-EINVAL);
80 
81 	return memdup_user(ukey, keylen);
82 }
83 
84 static void *_copy_apqns_from_user(void __user *uapqns, size_t nr_apqns)
85 {
86 	if (!uapqns || nr_apqns == 0)
87 		return NULL;
88 
89 	return memdup_array_user(uapqns, nr_apqns, sizeof(struct pkey_apqn));
90 }
91 
92 static int pkey_ioctl_genseck(struct pkey_genseck __user *ugs)
93 {
94 	struct pkey_genseck kgs;
95 	struct pkey_apqn apqn;
96 	u32 keybuflen;
97 	int rc;
98 
99 	if (copy_from_user(&kgs, ugs, sizeof(kgs)))
100 		return -EFAULT;
101 
102 	apqn.card = kgs.cardnr;
103 	apqn.domain = kgs.domain;
104 	keybuflen = sizeof(kgs.seckey.seckey);
105 	rc = pkey_handler_gen_key(&apqn, 1,
106 				  kgs.keytype, PKEY_TYPE_CCA_DATA, 0, 0,
107 				  kgs.seckey.seckey, &keybuflen, NULL, 0);
108 	pr_debug("gen_key()=%d\n", rc);
109 	if (!rc && copy_to_user(ugs, &kgs, sizeof(kgs)))
110 		rc = -EFAULT;
111 	memzero_explicit(&kgs, sizeof(kgs));
112 
113 	return rc;
114 }
115 
116 static int pkey_ioctl_clr2seck(struct pkey_clr2seck __user *ucs)
117 {
118 	struct pkey_clr2seck kcs;
119 	struct pkey_apqn apqn;
120 	u32 keybuflen;
121 	int rc;
122 
123 	if (copy_from_user(&kcs, ucs, sizeof(kcs)))
124 		return -EFAULT;
125 
126 	apqn.card = kcs.cardnr;
127 	apqn.domain = kcs.domain;
128 	keybuflen = sizeof(kcs.seckey.seckey);
129 	rc = pkey_handler_clr_to_key(&apqn, 1,
130 				     kcs.keytype, PKEY_TYPE_CCA_DATA, 0, 0,
131 				     kcs.clrkey.clrkey,
132 				     pkey_keytype_aes_to_size(kcs.keytype),
133 				     kcs.seckey.seckey, &keybuflen, NULL, 0);
134 	pr_debug("clr_to_key()=%d\n", rc);
135 	if (!rc && copy_to_user(ucs, &kcs, sizeof(kcs)))
136 		rc = -EFAULT;
137 	memzero_explicit(&kcs, sizeof(kcs));
138 
139 	return rc;
140 }
141 
142 static int pkey_ioctl_sec2protk(struct pkey_sec2protk __user *usp)
143 {
144 	struct pkey_sec2protk ksp;
145 	struct pkey_apqn apqn;
146 	int rc;
147 
148 	if (copy_from_user(&ksp, usp, sizeof(ksp)))
149 		return -EFAULT;
150 
151 	apqn.card = ksp.cardnr;
152 	apqn.domain = ksp.domain;
153 	ksp.protkey.len = sizeof(ksp.protkey.protkey);
154 	rc = pkey_handler_key_to_protkey(&apqn, 1,
155 					 ksp.seckey.seckey,
156 					 sizeof(ksp.seckey.seckey),
157 					 ksp.protkey.protkey,
158 					 &ksp.protkey.len, &ksp.protkey.type,
159 					 0);
160 	pr_debug("key_to_protkey()=%d\n", rc);
161 	if (!rc && copy_to_user(usp, &ksp, sizeof(ksp)))
162 		rc = -EFAULT;
163 	memzero_explicit(&ksp, sizeof(ksp));
164 
165 	return rc;
166 }
167 
168 static int pkey_ioctl_clr2protk(struct pkey_clr2protk __user *ucp)
169 {
170 	struct pkey_clr2protk kcp;
171 	struct clearkeytoken *t;
172 	u32 keylen;
173 	u8 *tmpbuf;
174 	int rc;
175 
176 	if (copy_from_user(&kcp, ucp, sizeof(kcp)))
177 		return -EFAULT;
178 
179 	/* build a 'clear key token' from the clear key value */
180 	keylen = pkey_keytype_aes_to_size(kcp.keytype);
181 	if (!keylen) {
182 		PKEY_DBF_ERR("%s unknown/unsupported keytype %u\n",
183 			     __func__, kcp.keytype);
184 		memzero_explicit(&kcp, sizeof(kcp));
185 		return -EINVAL;
186 	}
187 	tmpbuf = kzalloc(sizeof(*t) + keylen, GFP_KERNEL);
188 	if (!tmpbuf) {
189 		memzero_explicit(&kcp, sizeof(kcp));
190 		return -ENOMEM;
191 	}
192 	t = (struct clearkeytoken *)tmpbuf;
193 	t->type = TOKTYPE_NON_CCA;
194 	t->version = TOKVER_CLEAR_KEY;
195 	t->keytype = (keylen - 8) >> 3;
196 	t->len = keylen;
197 	memcpy(t->clearkey, kcp.clrkey.clrkey, keylen);
198 	kcp.protkey.len = sizeof(kcp.protkey.protkey);
199 
200 	rc = key2protkey(NULL, 0,
201 			 tmpbuf, sizeof(*t) + keylen,
202 			 kcp.protkey.protkey,
203 			 &kcp.protkey.len, &kcp.protkey.type, 0);
204 	pr_debug("key2protkey()=%d\n", rc);
205 
206 	kfree_sensitive(tmpbuf);
207 
208 	if (!rc && copy_to_user(ucp, &kcp, sizeof(kcp)))
209 		rc = -EFAULT;
210 	memzero_explicit(&kcp, sizeof(kcp));
211 
212 	return rc;
213 }
214 
215 static int pkey_ioctl_findcard(struct pkey_findcard __user *ufc)
216 {
217 	struct pkey_findcard kfc;
218 	struct pkey_apqn *apqns;
219 	size_t nr_apqns;
220 	int rc;
221 
222 	if (copy_from_user(&kfc, ufc, sizeof(kfc)))
223 		return -EFAULT;
224 
225 	nr_apqns = MAXAPQNSINLIST;
226 	apqns = kmalloc_objs(struct pkey_apqn, nr_apqns);
227 	if (!apqns)
228 		return -ENOMEM;
229 
230 	rc = pkey_handler_apqns_for_key(kfc.seckey.seckey,
231 					sizeof(kfc.seckey.seckey),
232 					PKEY_FLAGS_MATCH_CUR_MKVP,
233 					apqns, &nr_apqns, 0);
234 	if (rc == -ENODEV)
235 		rc = pkey_handler_apqns_for_key(kfc.seckey.seckey,
236 						sizeof(kfc.seckey.seckey),
237 						PKEY_FLAGS_MATCH_ALT_MKVP,
238 						apqns, &nr_apqns, 0);
239 	pr_debug("apqns_for_key()=%d\n", rc);
240 	if (rc) {
241 		kfree(apqns);
242 		return rc;
243 	}
244 	kfc.cardnr = apqns[0].card;
245 	kfc.domain = apqns[0].domain;
246 	kfree(apqns);
247 	if (copy_to_user(ufc, &kfc, sizeof(kfc)))
248 		return -EFAULT;
249 
250 	return 0;
251 }
252 
253 static int pkey_ioctl_skey2pkey(struct pkey_skey2pkey __user *usp)
254 {
255 	struct pkey_skey2pkey ksp;
256 	int rc;
257 
258 	if (copy_from_user(&ksp, usp, sizeof(ksp)))
259 		return -EFAULT;
260 
261 	ksp.protkey.len = sizeof(ksp.protkey.protkey);
262 	rc = pkey_handler_key_to_protkey(NULL, 0,
263 					 ksp.seckey.seckey,
264 					 sizeof(ksp.seckey.seckey),
265 					 ksp.protkey.protkey,
266 					 &ksp.protkey.len,
267 					 &ksp.protkey.type, 0);
268 	pr_debug("key_to_protkey()=%d\n", rc);
269 	if (!rc && copy_to_user(usp, &ksp, sizeof(ksp)))
270 		rc = -EFAULT;
271 	memzero_explicit(&ksp, sizeof(ksp));
272 
273 	return rc;
274 }
275 
276 static int pkey_ioctl_verifykey(struct pkey_verifykey __user *uvk)
277 {
278 	u32 keytype, keybitsize, flags;
279 	struct pkey_verifykey kvk;
280 	int rc;
281 
282 	if (copy_from_user(&kvk, uvk, sizeof(kvk)))
283 		return -EFAULT;
284 
285 	kvk.cardnr = 0xFFFF;
286 	kvk.domain = 0xFFFF;
287 	rc = pkey_handler_verify_key(kvk.seckey.seckey,
288 				     sizeof(kvk.seckey.seckey),
289 				     &kvk.cardnr, &kvk.domain,
290 				     &keytype, &keybitsize, &flags, 0);
291 	pr_debug("verify_key()=%d\n", rc);
292 	if (!rc && keytype != PKEY_TYPE_CCA_DATA)
293 		rc = -EINVAL;
294 	kvk.attributes = PKEY_VERIFY_ATTR_AES;
295 	kvk.keysize = (u16)keybitsize;
296 	if (flags & PKEY_FLAGS_MATCH_ALT_MKVP)
297 		kvk.attributes |= PKEY_VERIFY_ATTR_OLD_MKVP;
298 	if (!rc && copy_to_user(uvk, &kvk, sizeof(kvk)))
299 		rc = -EFAULT;
300 	memzero_explicit(&kvk, sizeof(kvk));
301 
302 	return rc;
303 }
304 
305 static int pkey_ioctl_genprotk(struct pkey_genprotk __user *ugp)
306 {
307 	struct pkey_genprotk kgp;
308 	int rc;
309 
310 	if (copy_from_user(&kgp, ugp, sizeof(kgp)))
311 		return -EFAULT;
312 
313 	kgp.protkey.len = sizeof(kgp.protkey.protkey);
314 	rc = pkey_handler_gen_key(NULL, 0, kgp.keytype,
315 				  PKEY_TYPE_PROTKEY, 0, 0,
316 				  kgp.protkey.protkey, &kgp.protkey.len,
317 				  &kgp.protkey.type, 0);
318 	pr_debug("gen_key()=%d\n", rc);
319 	if (!rc && copy_to_user(ugp, &kgp, sizeof(kgp)))
320 		rc = -EFAULT;
321 	memzero_explicit(&kgp, sizeof(kgp));
322 
323 	return rc;
324 }
325 
326 static int pkey_ioctl_verifyprotk(struct pkey_verifyprotk __user *uvp)
327 {
328 	struct pkey_verifyprotk kvp;
329 	struct protaeskeytoken *t;
330 	u32 keytype;
331 	u8 *tmpbuf;
332 	int rc;
333 
334 	if (copy_from_user(&kvp, uvp, sizeof(kvp)))
335 		return -EFAULT;
336 
337 	if (kvp.protkey.len > sizeof(kvp.protkey.protkey)) {
338 		PKEY_DBF_ERR("%s protkey length %u exceeds protkey buffer size\n",
339 			     __func__, kvp.protkey.len);
340 		memzero_explicit(&kvp, sizeof(kvp));
341 		return -EINVAL;
342 	}
343 
344 	keytype = pkey_aes_bitsize_to_keytype(8 * kvp.protkey.len);
345 	if (!keytype) {
346 		PKEY_DBF_ERR("%s unknown/unsupported protkey length %u\n",
347 			     __func__, kvp.protkey.len);
348 		memzero_explicit(&kvp, sizeof(kvp));
349 		return -EINVAL;
350 	}
351 
352 	/* build a 'protected key token' from the raw protected key */
353 	tmpbuf = kzalloc(sizeof(*t), GFP_KERNEL);
354 	if (!tmpbuf) {
355 		memzero_explicit(&kvp, sizeof(kvp));
356 		return -ENOMEM;
357 	}
358 	t = (struct protaeskeytoken *)tmpbuf;
359 	t->type = TOKTYPE_NON_CCA;
360 	t->version = TOKVER_PROTECTED_KEY;
361 	t->keytype = keytype;
362 	t->len = kvp.protkey.len;
363 	memcpy(t->protkey, kvp.protkey.protkey, kvp.protkey.len);
364 
365 	rc = pkey_handler_verify_key(tmpbuf, sizeof(*t),
366 				     NULL, NULL, NULL, NULL, NULL, 0);
367 	pr_debug("verify_key()=%d\n", rc);
368 
369 	kfree_sensitive(tmpbuf);
370 	memzero_explicit(&kvp, sizeof(kvp));
371 
372 	return rc;
373 }
374 
375 static int pkey_ioctl_kblob2protk(struct pkey_kblob2pkey __user *utp)
376 {
377 	struct pkey_kblob2pkey ktp;
378 	u8 *kkey;
379 	int rc;
380 
381 	if (copy_from_user(&ktp, utp, sizeof(ktp)))
382 		return -EFAULT;
383 	kkey = _copy_key_from_user(ktp.key, ktp.keylen);
384 	if (IS_ERR(kkey))
385 		return PTR_ERR(kkey);
386 	ktp.protkey.len = sizeof(ktp.protkey.protkey);
387 	rc = key2protkey(NULL, 0, kkey, ktp.keylen,
388 			 ktp.protkey.protkey, &ktp.protkey.len,
389 			 &ktp.protkey.type, 0);
390 	pr_debug("key2protkey()=%d\n", rc);
391 	kfree_sensitive(kkey);
392 	if (!rc && copy_to_user(utp, &ktp, sizeof(ktp)))
393 		rc = -EFAULT;
394 	memzero_explicit(&ktp, sizeof(ktp));
395 
396 	return rc;
397 }
398 
399 static int pkey_ioctl_genseck2(struct pkey_genseck2 __user *ugs)
400 {
401 	u32 klen = KEYBLOBBUFSIZE;
402 	struct pkey_genseck2 kgs;
403 	struct pkey_apqn *apqns;
404 	u8 *kkey;
405 	int rc;
406 	u32 u;
407 
408 	if (copy_from_user(&kgs, ugs, sizeof(kgs)))
409 		return -EFAULT;
410 	u = pkey_aes_bitsize_to_keytype(kgs.size);
411 	if (!u) {
412 		PKEY_DBF_ERR("%s unknown/unsupported keybitsize %d\n",
413 			     __func__, kgs.size);
414 		return -EINVAL;
415 	}
416 	apqns = _copy_apqns_from_user(kgs.apqns, kgs.apqn_entries);
417 	if (IS_ERR(apqns))
418 		return PTR_ERR(apqns);
419 	kkey = kzalloc(klen, GFP_KERNEL);
420 	if (!kkey) {
421 		kfree(apqns);
422 		return -ENOMEM;
423 	}
424 	rc = pkey_handler_gen_key(apqns, kgs.apqn_entries,
425 				  u, kgs.type, kgs.size, kgs.keygenflags,
426 				  kkey, &klen, NULL, 0);
427 	pr_debug("gen_key()=%d\n", rc);
428 	kfree(apqns);
429 	if (rc) {
430 		kfree_sensitive(kkey);
431 		return rc;
432 	}
433 	if (kgs.key) {
434 		if (kgs.keylen < klen) {
435 			kfree_sensitive(kkey);
436 			return -EINVAL;
437 		}
438 		if (copy_to_user(kgs.key, kkey, klen)) {
439 			kfree_sensitive(kkey);
440 			return -EFAULT;
441 		}
442 	}
443 	kgs.keylen = klen;
444 	if (copy_to_user(ugs, &kgs, sizeof(kgs)))
445 		rc = -EFAULT;
446 	kfree_sensitive(kkey);
447 
448 	return rc;
449 }
450 
451 static int pkey_ioctl_clr2seck2(struct pkey_clr2seck2 __user *ucs)
452 {
453 	u32 klen = KEYBLOBBUFSIZE;
454 	struct pkey_clr2seck2 kcs;
455 	struct pkey_apqn *apqns;
456 	u8 *kkey;
457 	int rc;
458 	u32 u;
459 
460 	if (copy_from_user(&kcs, ucs, sizeof(kcs)))
461 		return -EFAULT;
462 	u = pkey_aes_bitsize_to_keytype(kcs.size);
463 	if (!u) {
464 		PKEY_DBF_ERR("%s unknown/unsupported keybitsize %d\n",
465 			     __func__, kcs.size);
466 		memzero_explicit(&kcs, sizeof(kcs));
467 		return -EINVAL;
468 	}
469 	apqns = _copy_apqns_from_user(kcs.apqns, kcs.apqn_entries);
470 	if (IS_ERR(apqns)) {
471 		memzero_explicit(&kcs, sizeof(kcs));
472 		return PTR_ERR(apqns);
473 	}
474 	kkey = kzalloc(klen, GFP_KERNEL);
475 	if (!kkey) {
476 		kfree(apqns);
477 		memzero_explicit(&kcs, sizeof(kcs));
478 		return -ENOMEM;
479 	}
480 	rc = pkey_handler_clr_to_key(apqns, kcs.apqn_entries,
481 				     u, kcs.type, kcs.size, kcs.keygenflags,
482 				     kcs.clrkey.clrkey, kcs.size / 8,
483 				     kkey, &klen, NULL, 0);
484 	pr_debug("clr_to_key()=%d\n", rc);
485 	kfree(apqns);
486 	if (rc) {
487 		kfree_sensitive(kkey);
488 		memzero_explicit(&kcs, sizeof(kcs));
489 		return rc;
490 	}
491 	if (kcs.key) {
492 		if (kcs.keylen < klen) {
493 			kfree_sensitive(kkey);
494 			memzero_explicit(&kcs, sizeof(kcs));
495 			return -EINVAL;
496 		}
497 		if (copy_to_user(kcs.key, kkey, klen)) {
498 			kfree_sensitive(kkey);
499 			memzero_explicit(&kcs, sizeof(kcs));
500 			return -EFAULT;
501 		}
502 	}
503 	kcs.keylen = klen;
504 	if (copy_to_user(ucs, &kcs, sizeof(kcs)))
505 		rc = -EFAULT;
506 	memzero_explicit(&kcs, sizeof(kcs));
507 	kfree_sensitive(kkey);
508 
509 	return rc;
510 }
511 
512 static int pkey_ioctl_verifykey2(struct pkey_verifykey2 __user *uvk)
513 {
514 	struct pkey_verifykey2 kvk;
515 	u8 *kkey;
516 	int rc;
517 
518 	if (copy_from_user(&kvk, uvk, sizeof(kvk)))
519 		return -EFAULT;
520 	kkey = _copy_key_from_user(kvk.key, kvk.keylen);
521 	if (IS_ERR(kkey))
522 		return PTR_ERR(kkey);
523 
524 	rc = pkey_handler_verify_key(kkey, kvk.keylen,
525 				     &kvk.cardnr, &kvk.domain,
526 				     &kvk.type, &kvk.size, &kvk.flags, 0);
527 	pr_debug("verify_key()=%d\n", rc);
528 
529 	kfree_sensitive(kkey);
530 	if (!rc && copy_to_user(uvk, &kvk, sizeof(kvk)))
531 		return -EFAULT;
532 
533 	return rc;
534 }
535 
536 static int pkey_ioctl_kblob2protk2(struct pkey_kblob2pkey2 __user *utp)
537 {
538 	struct pkey_apqn *apqns = NULL;
539 	struct pkey_kblob2pkey2 ktp;
540 	u8 *kkey;
541 	int rc;
542 
543 	if (copy_from_user(&ktp, utp, sizeof(ktp)))
544 		return -EFAULT;
545 	apqns = _copy_apqns_from_user(ktp.apqns, ktp.apqn_entries);
546 	if (IS_ERR(apqns))
547 		return PTR_ERR(apqns);
548 	kkey = _copy_key_from_user(ktp.key, ktp.keylen);
549 	if (IS_ERR(kkey)) {
550 		kfree(apqns);
551 		return PTR_ERR(kkey);
552 	}
553 	ktp.protkey.len = sizeof(ktp.protkey.protkey);
554 	rc = key2protkey(apqns, ktp.apqn_entries, kkey, ktp.keylen,
555 			 ktp.protkey.protkey, &ktp.protkey.len,
556 			 &ktp.protkey.type, 0);
557 	pr_debug("key2protkey()=%d\n", rc);
558 	kfree(apqns);
559 	kfree_sensitive(kkey);
560 	if (!rc && copy_to_user(utp, &ktp, sizeof(ktp)))
561 		rc = -EFAULT;
562 	memzero_explicit(&ktp, sizeof(ktp));
563 
564 	return rc;
565 }
566 
567 static int pkey_ioctl_apqns4k(struct pkey_apqns4key __user *uak)
568 {
569 	struct pkey_apqn *apqns = NULL;
570 	struct pkey_apqns4key kak;
571 	size_t nr_apqns, len;
572 	u8 *kkey;
573 	int rc;
574 
575 	if (copy_from_user(&kak, uak, sizeof(kak)))
576 		return -EFAULT;
577 	nr_apqns = kak.apqn_entries;
578 	if (nr_apqns) {
579 		apqns = kmalloc_objs(struct pkey_apqn, nr_apqns);
580 		if (!apqns)
581 			return -ENOMEM;
582 	}
583 	kkey = _copy_key_from_user(kak.key, kak.keylen);
584 	if (IS_ERR(kkey)) {
585 		kfree(apqns);
586 		return PTR_ERR(kkey);
587 	}
588 	rc = pkey_handler_apqns_for_key(kkey, kak.keylen, kak.flags,
589 					apqns, &nr_apqns, 0);
590 	pr_debug("apqns_for_key()=%d\n", rc);
591 	kfree_sensitive(kkey);
592 	if (rc && rc != -ENOSPC) {
593 		kfree(apqns);
594 		return rc;
595 	}
596 	if (!rc && kak.apqns) {
597 		if (nr_apqns > kak.apqn_entries) {
598 			kfree(apqns);
599 			return -EINVAL;
600 		}
601 		len = nr_apqns * sizeof(struct pkey_apqn);
602 		if (len) {
603 			if (copy_to_user(kak.apqns, apqns, len)) {
604 				kfree(apqns);
605 				return -EFAULT;
606 			}
607 		}
608 	}
609 	kak.apqn_entries = nr_apqns;
610 	if (copy_to_user(uak, &kak, sizeof(kak)))
611 		rc = -EFAULT;
612 	kfree(apqns);
613 
614 	return rc;
615 }
616 
617 static int pkey_ioctl_apqns4kt(struct pkey_apqns4keytype __user *uat)
618 {
619 	struct pkey_apqn *apqns = NULL;
620 	struct pkey_apqns4keytype kat;
621 	size_t nr_apqns, len;
622 	int rc;
623 
624 	if (copy_from_user(&kat, uat, sizeof(kat)))
625 		return -EFAULT;
626 	nr_apqns = kat.apqn_entries;
627 	if (nr_apqns) {
628 		apqns = kmalloc_objs(struct pkey_apqn, nr_apqns);
629 		if (!apqns)
630 			return -ENOMEM;
631 	}
632 	rc = pkey_handler_apqns_for_keytype(kat.type,
633 					    kat.cur_mkvp, kat.alt_mkvp,
634 					    kat.flags, apqns, &nr_apqns, 0);
635 	pr_debug("apqns_for_keytype()=%d\n", rc);
636 	if (rc && rc != -ENOSPC) {
637 		kfree(apqns);
638 		return rc;
639 	}
640 	if (!rc && kat.apqns) {
641 		if (nr_apqns > kat.apqn_entries) {
642 			kfree(apqns);
643 			return -EINVAL;
644 		}
645 		len = nr_apqns * sizeof(struct pkey_apqn);
646 		if (len) {
647 			if (copy_to_user(kat.apqns, apqns, len)) {
648 				kfree(apqns);
649 				return -EFAULT;
650 			}
651 		}
652 	}
653 	kat.apqn_entries = nr_apqns;
654 	if (copy_to_user(uat, &kat, sizeof(kat)))
655 		rc = -EFAULT;
656 	kfree(apqns);
657 
658 	return rc;
659 }
660 
661 static int pkey_ioctl_kblob2protk3(struct pkey_kblob2pkey3 __user *utp)
662 {
663 	u32 protkeylen = PROTKEYBLOBBUFSIZE;
664 	struct pkey_apqn *apqns = NULL;
665 	struct pkey_kblob2pkey3 ktp;
666 	u8 *kkey, *protkey;
667 	int rc;
668 
669 	if (copy_from_user(&ktp, utp, sizeof(ktp)))
670 		return -EFAULT;
671 	apqns = _copy_apqns_from_user(ktp.apqns, ktp.apqn_entries);
672 	if (IS_ERR(apqns))
673 		return PTR_ERR(apqns);
674 	kkey = _copy_key_from_user(ktp.key, ktp.keylen);
675 	if (IS_ERR(kkey)) {
676 		kfree(apqns);
677 		return PTR_ERR(kkey);
678 	}
679 	protkey = kmalloc(protkeylen, GFP_KERNEL);
680 	if (!protkey) {
681 		kfree(apqns);
682 		kfree_sensitive(kkey);
683 		return -ENOMEM;
684 	}
685 	rc = key2protkey(apqns, ktp.apqn_entries, kkey, ktp.keylen,
686 			 protkey, &protkeylen, &ktp.pkeytype, 0);
687 	pr_debug("key2protkey()=%d\n", rc);
688 	kfree(apqns);
689 	kfree_sensitive(kkey);
690 	if (rc) {
691 		kfree_sensitive(protkey);
692 		return rc;
693 	}
694 	if (ktp.pkey && ktp.pkeylen) {
695 		if (protkeylen > ktp.pkeylen) {
696 			kfree_sensitive(protkey);
697 			return -EINVAL;
698 		}
699 		if (copy_to_user(ktp.pkey, protkey, protkeylen)) {
700 			kfree_sensitive(protkey);
701 			return -EFAULT;
702 		}
703 	}
704 	kfree_sensitive(protkey);
705 	ktp.pkeylen = protkeylen;
706 	if (copy_to_user(utp, &ktp, sizeof(ktp)))
707 		return -EFAULT;
708 
709 	return 0;
710 }
711 
712 static long pkey_unlocked_ioctl(struct file *filp, unsigned int cmd,
713 				unsigned long arg)
714 {
715 	int rc;
716 
717 	switch (cmd) {
718 	case PKEY_GENSECK:
719 		rc = pkey_ioctl_genseck((struct pkey_genseck __user *)arg);
720 		break;
721 	case PKEY_CLR2SECK:
722 		rc = pkey_ioctl_clr2seck((struct pkey_clr2seck __user *)arg);
723 		break;
724 	case PKEY_SEC2PROTK:
725 		rc = pkey_ioctl_sec2protk((struct pkey_sec2protk __user *)arg);
726 		break;
727 	case PKEY_CLR2PROTK:
728 		rc = pkey_ioctl_clr2protk((struct pkey_clr2protk __user *)arg);
729 		break;
730 	case PKEY_FINDCARD:
731 		rc = pkey_ioctl_findcard((struct pkey_findcard __user *)arg);
732 		break;
733 	case PKEY_SKEY2PKEY:
734 		rc = pkey_ioctl_skey2pkey((struct pkey_skey2pkey __user *)arg);
735 		break;
736 	case PKEY_VERIFYKEY:
737 		rc = pkey_ioctl_verifykey((struct pkey_verifykey __user *)arg);
738 		break;
739 	case PKEY_GENPROTK:
740 		rc = pkey_ioctl_genprotk((struct pkey_genprotk __user *)arg);
741 		break;
742 	case PKEY_VERIFYPROTK:
743 		rc = pkey_ioctl_verifyprotk((struct pkey_verifyprotk __user *)arg);
744 		break;
745 	case PKEY_KBLOB2PROTK:
746 		rc = pkey_ioctl_kblob2protk((struct pkey_kblob2pkey __user *)arg);
747 		break;
748 	case PKEY_GENSECK2:
749 		rc = pkey_ioctl_genseck2((struct pkey_genseck2 __user *)arg);
750 		break;
751 	case PKEY_CLR2SECK2:
752 		rc = pkey_ioctl_clr2seck2((struct pkey_clr2seck2 __user *)arg);
753 		break;
754 	case PKEY_VERIFYKEY2:
755 		rc = pkey_ioctl_verifykey2((struct pkey_verifykey2 __user *)arg);
756 		break;
757 	case PKEY_KBLOB2PROTK2:
758 		rc = pkey_ioctl_kblob2protk2((struct pkey_kblob2pkey2 __user *)arg);
759 		break;
760 	case PKEY_APQNS4K:
761 		rc = pkey_ioctl_apqns4k((struct pkey_apqns4key __user *)arg);
762 		break;
763 	case PKEY_APQNS4KT:
764 		rc = pkey_ioctl_apqns4kt((struct pkey_apqns4keytype __user *)arg);
765 		break;
766 	case PKEY_KBLOB2PROTK3:
767 		rc = pkey_ioctl_kblob2protk3((struct pkey_kblob2pkey3 __user *)arg);
768 		break;
769 	default:
770 		/* unknown/unsupported ioctl cmd */
771 		return -ENOTTY;
772 	}
773 
774 	return rc;
775 }
776 
777 /*
778  * File io operations
779  */
780 
781 static const struct file_operations pkey_fops = {
782 	.owner		= THIS_MODULE,
783 	.open		= nonseekable_open,
784 	.unlocked_ioctl = pkey_unlocked_ioctl,
785 };
786 
787 static struct miscdevice pkey_dev = {
788 	.name	= "pkey",
789 	.minor	= MISC_DYNAMIC_MINOR,
790 	.mode	= 0666,
791 	.fops	= &pkey_fops,
792 	.groups = pkey_attr_groups,
793 };
794 
795 int __init pkey_api_init(void)
796 {
797 	/* register as a misc device */
798 	return misc_register(&pkey_dev);
799 }
800 
801 void __exit pkey_api_exit(void)
802 {
803 	misc_deregister(&pkey_dev);
804 }
805