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