]> Git Repo - J-linux.git/blob - drivers/s390/crypto/pkey_api.c
Merge tag 'vfs-6.13-rc7.fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/vfs/vfs
[J-linux.git] / drivers / s390 / crypto / pkey_api.c
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 }
This page took 0.070931 seconds and 4 git commands to generate.