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 u8 *tmpbuf = NULL; 173 u32 keylen; 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 rc = -EINVAL; 185 goto out; 186 } 187 tmpbuf = kzalloc(sizeof(*t) + keylen, GFP_KERNEL); 188 if (!tmpbuf) { 189 rc = -ENOMEM; 190 goto out; 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 if (rc) 206 goto out; 207 208 if (copy_to_user(ucp, &kcp, sizeof(kcp))) 209 rc = -EFAULT; 210 211 out: 212 memzero_explicit(&kcp, sizeof(kcp)); 213 kfree_sensitive(tmpbuf); 214 return rc; 215 } 216 217 static int pkey_ioctl_findcard(struct pkey_findcard __user *ufc) 218 { 219 struct pkey_apqn *apqns = NULL; 220 struct pkey_findcard kfc; 221 size_t nr_apqns; 222 int rc; 223 224 if (copy_from_user(&kfc, ufc, sizeof(kfc))) 225 return -EFAULT; 226 227 nr_apqns = MAXAPQNSINLIST; 228 apqns = kmalloc_objs(struct pkey_apqn, nr_apqns); 229 if (!apqns) { 230 rc = -ENOMEM; 231 goto out; 232 } 233 234 rc = pkey_handler_apqns_for_key(kfc.seckey.seckey, 235 sizeof(kfc.seckey.seckey), 236 PKEY_FLAGS_MATCH_CUR_MKVP, 237 apqns, &nr_apqns, 0); 238 if (rc == -ENODEV) 239 rc = pkey_handler_apqns_for_key(kfc.seckey.seckey, 240 sizeof(kfc.seckey.seckey), 241 PKEY_FLAGS_MATCH_ALT_MKVP, 242 apqns, &nr_apqns, 0); 243 pr_debug("apqns_for_key()=%d\n", rc); 244 if (rc) 245 goto out; 246 247 kfc.cardnr = apqns[0].card; 248 kfc.domain = apqns[0].domain; 249 250 if (copy_to_user(ufc, &kfc, sizeof(kfc))) 251 rc = -EFAULT; 252 253 out: 254 kfree(apqns); 255 return rc; 256 } 257 258 static int pkey_ioctl_skey2pkey(struct pkey_skey2pkey __user *usp) 259 { 260 struct pkey_skey2pkey ksp; 261 int rc; 262 263 if (copy_from_user(&ksp, usp, sizeof(ksp))) 264 return -EFAULT; 265 266 ksp.protkey.len = sizeof(ksp.protkey.protkey); 267 rc = pkey_handler_key_to_protkey(NULL, 0, 268 ksp.seckey.seckey, 269 sizeof(ksp.seckey.seckey), 270 ksp.protkey.protkey, 271 &ksp.protkey.len, 272 &ksp.protkey.type, 0); 273 pr_debug("key_to_protkey()=%d\n", rc); 274 if (!rc && copy_to_user(usp, &ksp, sizeof(ksp))) 275 rc = -EFAULT; 276 memzero_explicit(&ksp, sizeof(ksp)); 277 278 return rc; 279 } 280 281 static int pkey_ioctl_verifykey(struct pkey_verifykey __user *uvk) 282 { 283 u32 keytype, keybitsize, flags; 284 struct pkey_verifykey kvk; 285 int rc; 286 287 if (copy_from_user(&kvk, uvk, sizeof(kvk))) 288 return -EFAULT; 289 290 kvk.cardnr = 0xFFFF; 291 kvk.domain = 0xFFFF; 292 rc = pkey_handler_verify_key(kvk.seckey.seckey, 293 sizeof(kvk.seckey.seckey), 294 &kvk.cardnr, &kvk.domain, 295 &keytype, &keybitsize, &flags, 0); 296 pr_debug("verify_key()=%d\n", rc); 297 if (!rc && keytype != PKEY_TYPE_CCA_DATA) 298 rc = -EINVAL; 299 kvk.attributes = PKEY_VERIFY_ATTR_AES; 300 kvk.keysize = (u16)keybitsize; 301 if (flags & PKEY_FLAGS_MATCH_ALT_MKVP) 302 kvk.attributes |= PKEY_VERIFY_ATTR_OLD_MKVP; 303 if (!rc && copy_to_user(uvk, &kvk, sizeof(kvk))) 304 rc = -EFAULT; 305 memzero_explicit(&kvk, sizeof(kvk)); 306 307 return rc; 308 } 309 310 static int pkey_ioctl_genprotk(struct pkey_genprotk __user *ugp) 311 { 312 struct pkey_genprotk kgp; 313 int rc; 314 315 if (copy_from_user(&kgp, ugp, sizeof(kgp))) 316 return -EFAULT; 317 318 kgp.protkey.len = sizeof(kgp.protkey.protkey); 319 rc = pkey_handler_gen_key(NULL, 0, kgp.keytype, 320 PKEY_TYPE_PROTKEY, 0, 0, 321 kgp.protkey.protkey, &kgp.protkey.len, 322 &kgp.protkey.type, 0); 323 pr_debug("gen_key()=%d\n", rc); 324 if (!rc && copy_to_user(ugp, &kgp, sizeof(kgp))) 325 rc = -EFAULT; 326 memzero_explicit(&kgp, sizeof(kgp)); 327 328 return rc; 329 } 330 331 static int pkey_ioctl_verifyprotk(struct pkey_verifyprotk __user *uvp) 332 { 333 struct pkey_verifyprotk kvp; 334 struct protaeskeytoken *t; 335 u8 *tmpbuf = NULL; 336 int rc; 337 338 if (copy_from_user(&kvp, uvp, sizeof(kvp))) 339 return -EFAULT; 340 341 if (kvp.protkey.len > sizeof(kvp.protkey.protkey)) { 342 PKEY_DBF_ERR("%s protkey length %u exceeds protkey buffer size\n", 343 __func__, kvp.protkey.len); 344 rc = -EINVAL; 345 goto out; 346 } 347 348 /* build a 'protected key token' from the raw protected key */ 349 tmpbuf = kzalloc(sizeof(*t), GFP_KERNEL); 350 if (!tmpbuf) { 351 rc = -ENOMEM; 352 goto out; 353 } 354 t = (struct protaeskeytoken *)tmpbuf; 355 t->type = TOKTYPE_NON_CCA; 356 t->version = TOKVER_PROTECTED_KEY; 357 t->keytype = kvp.protkey.type; 358 t->len = kvp.protkey.len; 359 memcpy(t->protkey, kvp.protkey.protkey, kvp.protkey.len); 360 361 rc = pkey_handler_verify_key(tmpbuf, sizeof(*t), 362 NULL, NULL, NULL, NULL, NULL, 0); 363 pr_debug("verify_key()=%d\n", rc); 364 365 out: 366 memzero_explicit(&kvp, sizeof(kvp)); 367 kfree_sensitive(tmpbuf); 368 return rc; 369 } 370 371 static int pkey_ioctl_kblob2protk(struct pkey_kblob2pkey __user *utp) 372 { 373 struct pkey_kblob2pkey ktp; 374 u8 *kkey = NULL; 375 int rc; 376 377 if (copy_from_user(&ktp, utp, sizeof(ktp))) 378 return -EFAULT; 379 kkey = _copy_key_from_user(ktp.key, ktp.keylen); 380 if (IS_ERR(kkey)) { 381 rc = PTR_ERR(kkey); 382 kkey = NULL; 383 goto out; 384 } 385 ktp.protkey.len = sizeof(ktp.protkey.protkey); 386 rc = key2protkey(NULL, 0, kkey, ktp.keylen, 387 ktp.protkey.protkey, &ktp.protkey.len, 388 &ktp.protkey.type, 0); 389 pr_debug("key2protkey()=%d\n", rc); 390 if (rc) 391 goto out; 392 if (copy_to_user(utp, &ktp, sizeof(ktp))) 393 rc = -EFAULT; 394 395 out: 396 memzero_explicit(&ktp, sizeof(ktp)); 397 kfree_sensitive(kkey); 398 return rc; 399 } 400 401 static int pkey_ioctl_genseck2(struct pkey_genseck2 __user *ugs) 402 { 403 struct pkey_apqn *apqns = NULL; 404 u32 klen = KEYBLOBBUFSIZE; 405 struct pkey_genseck2 kgs; 406 u8 *kkey = NULL; 407 int rc; 408 u32 u; 409 410 if (copy_from_user(&kgs, ugs, sizeof(kgs))) 411 return -EFAULT; 412 u = pkey_aes_bitsize_to_keytype(kgs.size); 413 if (!u) { 414 PKEY_DBF_ERR("%s unknown/unsupported keybitsize %d\n", 415 __func__, kgs.size); 416 return -EINVAL; 417 } 418 apqns = _copy_apqns_from_user(kgs.apqns, kgs.apqn_entries); 419 if (IS_ERR(apqns)) { 420 rc = PTR_ERR(apqns); 421 apqns = NULL; 422 goto out; 423 } 424 kkey = kzalloc(klen, GFP_KERNEL); 425 if (!kkey) { 426 rc = -ENOMEM; 427 goto out; 428 } 429 rc = pkey_handler_gen_key(apqns, kgs.apqn_entries, 430 u, kgs.type, kgs.size, kgs.keygenflags, 431 kkey, &klen, NULL, 0); 432 pr_debug("gen_key()=%d\n", rc); 433 if (rc) 434 goto out; 435 if (kgs.key) { 436 if (kgs.keylen < klen) { 437 rc = -EINVAL; 438 goto out; 439 } 440 if (copy_to_user(kgs.key, kkey, klen)) { 441 rc = -EFAULT; 442 goto out; 443 } 444 } 445 kgs.keylen = klen; 446 if (copy_to_user(ugs, &kgs, sizeof(kgs))) 447 rc = -EFAULT; 448 449 out: 450 kfree_sensitive(kkey); 451 kfree(apqns); 452 return rc; 453 } 454 455 static int pkey_ioctl_clr2seck2(struct pkey_clr2seck2 __user *ucs) 456 { 457 struct pkey_apqn *apqns = NULL; 458 u32 klen = KEYBLOBBUFSIZE; 459 struct pkey_clr2seck2 kcs; 460 u8 *kkey = NULL; 461 int rc; 462 u32 u; 463 464 if (copy_from_user(&kcs, ucs, sizeof(kcs))) 465 return -EFAULT; 466 u = pkey_aes_bitsize_to_keytype(kcs.size); 467 if (!u) { 468 PKEY_DBF_ERR("%s unknown/unsupported keybitsize %d\n", 469 __func__, kcs.size); 470 rc = -EINVAL; 471 goto out; 472 } 473 apqns = _copy_apqns_from_user(kcs.apqns, kcs.apqn_entries); 474 if (IS_ERR(apqns)) { 475 rc = PTR_ERR(apqns); 476 apqns = NULL; 477 goto out; 478 } 479 kkey = kzalloc(klen, GFP_KERNEL); 480 if (!kkey) { 481 rc = -ENOMEM; 482 goto out; 483 } 484 rc = pkey_handler_clr_to_key(apqns, kcs.apqn_entries, 485 u, kcs.type, kcs.size, kcs.keygenflags, 486 kcs.clrkey.clrkey, kcs.size / 8, 487 kkey, &klen, NULL, 0); 488 pr_debug("clr_to_key()=%d\n", rc); 489 if (rc) 490 goto out; 491 if (kcs.key) { 492 if (kcs.keylen < klen) { 493 rc = -EINVAL; 494 goto out; 495 } 496 if (copy_to_user(kcs.key, kkey, klen)) { 497 rc = -EFAULT; 498 goto out; 499 } 500 } 501 kcs.keylen = klen; 502 if (copy_to_user(ucs, &kcs, sizeof(kcs))) 503 rc = -EFAULT; 504 505 out: 506 memzero_explicit(&kcs, sizeof(kcs)); 507 kfree_sensitive(kkey); 508 kfree(apqns); 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 rc = PTR_ERR(kkey); 523 kkey = NULL; 524 goto out; 525 } 526 527 rc = pkey_handler_verify_key(kkey, kvk.keylen, 528 &kvk.cardnr, &kvk.domain, 529 &kvk.type, &kvk.size, &kvk.flags, 0); 530 pr_debug("verify_key()=%d\n", rc); 531 if (rc) 532 goto out; 533 if (copy_to_user(uvk, &kvk, sizeof(kvk))) 534 rc = -EFAULT; 535 536 out: 537 kfree_sensitive(kkey); 538 return rc; 539 } 540 541 static int pkey_ioctl_kblob2protk2(struct pkey_kblob2pkey2 __user *utp) 542 { 543 struct pkey_apqn *apqns = NULL; 544 struct pkey_kblob2pkey2 ktp; 545 u8 *kkey = NULL; 546 int rc; 547 548 if (copy_from_user(&ktp, utp, sizeof(ktp))) 549 return -EFAULT; 550 apqns = _copy_apqns_from_user(ktp.apqns, ktp.apqn_entries); 551 if (IS_ERR(apqns)) { 552 rc = PTR_ERR(apqns); 553 apqns = NULL; 554 goto out; 555 } 556 kkey = _copy_key_from_user(ktp.key, ktp.keylen); 557 if (IS_ERR(kkey)) { 558 rc = PTR_ERR(kkey); 559 kkey = NULL; 560 goto out; 561 } 562 ktp.protkey.len = sizeof(ktp.protkey.protkey); 563 rc = key2protkey(apqns, ktp.apqn_entries, kkey, ktp.keylen, 564 ktp.protkey.protkey, &ktp.protkey.len, 565 &ktp.protkey.type, 0); 566 pr_debug("key2protkey()=%d\n", rc); 567 if (rc) 568 goto out; 569 if (copy_to_user(utp, &ktp, sizeof(ktp))) 570 rc = -EFAULT; 571 572 out: 573 memzero_explicit(&ktp, sizeof(ktp)); 574 kfree_sensitive(kkey); 575 kfree(apqns); 576 return rc; 577 } 578 579 static int pkey_ioctl_apqns4k(struct pkey_apqns4key __user *uak) 580 { 581 struct pkey_apqn *apqns = NULL; 582 struct pkey_apqns4key kak; 583 size_t nr_apqns, len; 584 u8 *kkey = NULL; 585 int rc; 586 587 if (copy_from_user(&kak, uak, sizeof(kak))) 588 return -EFAULT; 589 nr_apqns = kak.apqn_entries; 590 if (nr_apqns) { 591 apqns = kmalloc_objs(struct pkey_apqn, nr_apqns); 592 if (!apqns) { 593 rc = -ENOMEM; 594 goto out; 595 } 596 } 597 kkey = _copy_key_from_user(kak.key, kak.keylen); 598 if (IS_ERR(kkey)) { 599 rc = PTR_ERR(kkey); 600 kkey = NULL; 601 goto out; 602 } 603 rc = pkey_handler_apqns_for_key(kkey, kak.keylen, kak.flags, 604 apqns, &nr_apqns, 0); 605 pr_debug("apqns_for_key()=%d\n", rc); 606 if (rc && rc != -ENOSPC) 607 goto out; 608 if (!rc && kak.apqns) { 609 if (nr_apqns > kak.apqn_entries) { 610 rc = -EINVAL; 611 goto out; 612 } 613 len = nr_apqns * sizeof(struct pkey_apqn); 614 if (len) { 615 if (copy_to_user(kak.apqns, apqns, len)) { 616 rc = -EFAULT; 617 goto out; 618 } 619 } 620 } 621 kak.apqn_entries = nr_apqns; 622 if (copy_to_user(uak, &kak, sizeof(kak))) 623 rc = -EFAULT; 624 625 out: 626 kfree_sensitive(kkey); 627 kfree(apqns); 628 return rc; 629 } 630 631 static int pkey_ioctl_apqns4kt(struct pkey_apqns4keytype __user *uat) 632 { 633 struct pkey_apqn *apqns = NULL; 634 struct pkey_apqns4keytype kat; 635 size_t nr_apqns, len; 636 int rc; 637 638 if (copy_from_user(&kat, uat, sizeof(kat))) 639 return -EFAULT; 640 nr_apqns = kat.apqn_entries; 641 if (nr_apqns) { 642 apqns = kmalloc_objs(struct pkey_apqn, nr_apqns); 643 if (!apqns) { 644 rc = -ENOMEM; 645 goto out; 646 } 647 } 648 rc = pkey_handler_apqns_for_keytype(kat.type, 649 kat.cur_mkvp, kat.alt_mkvp, 650 kat.flags, apqns, &nr_apqns, 0); 651 pr_debug("apqns_for_keytype()=%d\n", rc); 652 if (rc && rc != -ENOSPC) 653 goto out; 654 if (!rc && kat.apqns) { 655 if (nr_apqns > kat.apqn_entries) { 656 rc = -EINVAL; 657 goto out; 658 } 659 len = nr_apqns * sizeof(struct pkey_apqn); 660 if (len) { 661 if (copy_to_user(kat.apqns, apqns, len)) { 662 rc = -EFAULT; 663 goto out; 664 } 665 } 666 } 667 kat.apqn_entries = nr_apqns; 668 if (copy_to_user(uat, &kat, sizeof(kat))) 669 rc = -EFAULT; 670 671 out: 672 kfree(apqns); 673 return rc; 674 } 675 676 static int pkey_ioctl_kblob2protk3(struct pkey_kblob2pkey3 __user *utp) 677 { 678 u32 protkeylen = PROTKEYBLOBBUFSIZE; 679 u8 *kkey = NULL, *protkey = NULL; 680 struct pkey_apqn *apqns = NULL; 681 struct pkey_kblob2pkey3 ktp; 682 int rc; 683 684 if (copy_from_user(&ktp, utp, sizeof(ktp))) 685 return -EFAULT; 686 apqns = _copy_apqns_from_user(ktp.apqns, ktp.apqn_entries); 687 if (IS_ERR(apqns)) { 688 rc = PTR_ERR(apqns); 689 apqns = NULL; 690 goto out; 691 } 692 kkey = _copy_key_from_user(ktp.key, ktp.keylen); 693 if (IS_ERR(kkey)) { 694 rc = PTR_ERR(kkey); 695 kkey = NULL; 696 goto out; 697 } 698 protkey = kmalloc(protkeylen, GFP_KERNEL); 699 if (!protkey) { 700 rc = -ENOMEM; 701 goto out; 702 } 703 rc = key2protkey(apqns, ktp.apqn_entries, kkey, ktp.keylen, 704 protkey, &protkeylen, &ktp.pkeytype, 0); 705 pr_debug("key2protkey()=%d\n", rc); 706 if (rc) 707 goto out; 708 if (ktp.pkey && ktp.pkeylen) { 709 if (protkeylen > ktp.pkeylen) { 710 rc = -EINVAL; 711 goto out; 712 } 713 if (copy_to_user(ktp.pkey, protkey, protkeylen)) { 714 rc = -EFAULT; 715 goto out; 716 } 717 } 718 ktp.pkeylen = protkeylen; 719 if (copy_to_user(utp, &ktp, sizeof(ktp))) 720 rc = -EFAULT; 721 722 out: 723 kfree_sensitive(protkey); 724 kfree_sensitive(kkey); 725 kfree(apqns); 726 return rc; 727 } 728 729 static long pkey_unlocked_ioctl(struct file *filp, unsigned int cmd, 730 unsigned long arg) 731 { 732 int rc; 733 734 switch (cmd) { 735 case PKEY_GENSECK: 736 rc = pkey_ioctl_genseck((struct pkey_genseck __user *)arg); 737 break; 738 case PKEY_CLR2SECK: 739 rc = pkey_ioctl_clr2seck((struct pkey_clr2seck __user *)arg); 740 break; 741 case PKEY_SEC2PROTK: 742 rc = pkey_ioctl_sec2protk((struct pkey_sec2protk __user *)arg); 743 break; 744 case PKEY_CLR2PROTK: 745 rc = pkey_ioctl_clr2protk((struct pkey_clr2protk __user *)arg); 746 break; 747 case PKEY_FINDCARD: 748 rc = pkey_ioctl_findcard((struct pkey_findcard __user *)arg); 749 break; 750 case PKEY_SKEY2PKEY: 751 rc = pkey_ioctl_skey2pkey((struct pkey_skey2pkey __user *)arg); 752 break; 753 case PKEY_VERIFYKEY: 754 rc = pkey_ioctl_verifykey((struct pkey_verifykey __user *)arg); 755 break; 756 case PKEY_GENPROTK: 757 rc = pkey_ioctl_genprotk((struct pkey_genprotk __user *)arg); 758 break; 759 case PKEY_VERIFYPROTK: 760 rc = pkey_ioctl_verifyprotk((struct pkey_verifyprotk __user *)arg); 761 break; 762 case PKEY_KBLOB2PROTK: 763 rc = pkey_ioctl_kblob2protk((struct pkey_kblob2pkey __user *)arg); 764 break; 765 case PKEY_GENSECK2: 766 rc = pkey_ioctl_genseck2((struct pkey_genseck2 __user *)arg); 767 break; 768 case PKEY_CLR2SECK2: 769 rc = pkey_ioctl_clr2seck2((struct pkey_clr2seck2 __user *)arg); 770 break; 771 case PKEY_VERIFYKEY2: 772 rc = pkey_ioctl_verifykey2((struct pkey_verifykey2 __user *)arg); 773 break; 774 case PKEY_KBLOB2PROTK2: 775 rc = pkey_ioctl_kblob2protk2((struct pkey_kblob2pkey2 __user *)arg); 776 break; 777 case PKEY_APQNS4K: 778 rc = pkey_ioctl_apqns4k((struct pkey_apqns4key __user *)arg); 779 break; 780 case PKEY_APQNS4KT: 781 rc = pkey_ioctl_apqns4kt((struct pkey_apqns4keytype __user *)arg); 782 break; 783 case PKEY_KBLOB2PROTK3: 784 rc = pkey_ioctl_kblob2protk3((struct pkey_kblob2pkey3 __user *)arg); 785 break; 786 default: 787 /* unknown/unsupported ioctl cmd */ 788 return -ENOTTY; 789 } 790 791 return rc; 792 } 793 794 /* 795 * File io operations 796 */ 797 798 static const struct file_operations pkey_fops = { 799 .owner = THIS_MODULE, 800 .open = nonseekable_open, 801 .unlocked_ioctl = pkey_unlocked_ioctl, 802 }; 803 804 static struct miscdevice pkey_dev = { 805 .name = "pkey", 806 .minor = MISC_DYNAMIC_MINOR, 807 .mode = 0666, 808 .fops = &pkey_fops, 809 .groups = pkey_attr_groups, 810 }; 811 812 int __init pkey_api_init(void) 813 { 814 /* register as a misc device */ 815 return misc_register(&pkey_dev); 816 } 817 818 void __exit pkey_api_exit(void) 819 { 820 misc_deregister(&pkey_dev); 821 } 822