1 /* 2 * CDDL HEADER START 3 * 4 * The contents of this file are subject to the terms of the 5 * Common Development and Distribution License (the "License"). 6 * You may not use this file except in compliance with the License. 7 * 8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9 * or http://www.opensolaris.org/os/licensing. 10 * See the License for the specific language governing permissions 11 * and limitations under the License. 12 * 13 * When distributing Covered Code, include this CDDL HEADER in each 14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15 * If applicable, add the following below this CDDL HEADER, with the 16 * fields enclosed by brackets "[]" replaced with your own identifying 17 * information: Portions Copyright [yyyy] [name of copyright owner] 18 * 19 * CDDL HEADER END 20 */ 21 /* 22 * Copyright 2006 Sun Microsystems, Inc. All rights reserved. 23 * Use is subject to license terms. 24 */ 25 26 #pragma ident "%Z%%M% %I% %E% SMI" 27 28 /* 29 * The ioctl interface for cryptographic commands. 30 */ 31 32 #include <sys/types.h> 33 #include <sys/modctl.h> 34 #include <sys/conf.h> 35 #include <sys/stat.h> 36 #include <sys/ddi.h> 37 #include <sys/sunddi.h> 38 #include <sys/kmem.h> 39 #include <sys/errno.h> 40 #include <sys/ksynch.h> 41 #include <sys/file.h> 42 #include <sys/open.h> 43 #include <sys/cred.h> 44 #include <sys/proc.h> 45 #include <sys/task.h> 46 #include <sys/mkdev.h> 47 #include <sys/model.h> 48 #include <sys/sysmacros.h> 49 #include <sys/crypto/common.h> 50 #include <sys/crypto/api.h> 51 #include <sys/crypto/impl.h> 52 #include <sys/crypto/sched_impl.h> 53 #include <sys/crypto/ioctl.h> 54 55 /* 56 * Locking notes: 57 * 58 * crypto_lock protects the global array of minor structures. It 59 * also protects the cm_refcnt member of each of these structures. 60 * The crypto_cv is used to signal decrements in the cm_refcnt, 61 * and is used with the global crypto_lock. 62 * 63 * Other fields in the minor structure are protected by the 64 * cm_lock member of the minor structure. 65 */ 66 67 /* 68 * DDI entry points. 69 */ 70 static int crypto_attach(dev_info_t *, ddi_attach_cmd_t); 71 static int crypto_detach(dev_info_t *, ddi_detach_cmd_t); 72 static int crypto_getinfo(dev_info_t *, ddi_info_cmd_t, void *, void **); 73 static int crypto_open(dev_t *, int, int, cred_t *); 74 static int crypto_close(dev_t, int, int, cred_t *); 75 static int crypto_ioctl(dev_t, int, intptr_t, int, cred_t *, int *); 76 77 static int cipher_init(dev_t, caddr_t, int, int (*)(crypto_provider_t, 78 crypto_session_id_t, crypto_mechanism_t *, crypto_key_t *, 79 crypto_ctx_template_t, crypto_context_t *, crypto_call_req_t *)); 80 81 static int common_digest(dev_t, caddr_t, int, int (*)(crypto_context_t, 82 crypto_data_t *, crypto_data_t *, crypto_call_req_t *)); 83 84 static int cipher(dev_t, caddr_t, int, int (*)(crypto_context_t, 85 crypto_data_t *, crypto_data_t *, crypto_call_req_t *)); 86 87 static int cipher_update(dev_t, caddr_t, int, int (*)(crypto_context_t, 88 crypto_data_t *, crypto_data_t *, crypto_call_req_t *)); 89 90 static int common_final(dev_t, caddr_t, int, int (*)(crypto_context_t, 91 crypto_data_t *, crypto_call_req_t *)); 92 93 static int sign_verify_init(dev_t, caddr_t, int, int (*)(crypto_provider_t, 94 crypto_session_id_t, crypto_mechanism_t *, crypto_key_t *, 95 crypto_ctx_template_t, crypto_context_t *, crypto_call_req_t *)); 96 97 static int sign_verify_update(dev_t dev, caddr_t arg, int mode, 98 int (*)(crypto_context_t, crypto_data_t *, crypto_call_req_t *)); 99 100 static void crypto_initialize_rctl(void); 101 static void crypto_release_provider_session(crypto_minor_t *, 102 crypto_provider_session_t *); 103 static int crypto_buffer_check(size_t, kproject_t **); 104 static int crypto_free_find_ctx(crypto_session_data_t *); 105 static int crypto_get_provider_list(crypto_minor_t *, uint_t *, 106 crypto_provider_entry_t **, boolean_t); 107 108 /* number of minor numbers to allocate at a time */ 109 #define CRYPTO_MINOR_CHUNK 16 110 111 /* 112 * There are two limits associated with kernel memory. The first, 113 * CRYPTO_MAX_BUFFER_LEN, is the maximum number of bytes that can be 114 * allocated for a single copyin/copyout buffer. The second limit is 115 * the total number of bytes that can be allocated by a process 116 * for copyin/copyout buffers. The latter is enforced by the 117 * project.max-crypto-memory resource control. 118 */ 119 120 #define CRYPTO_MAX_BUFFER_LEN (2 * 1024 * 1024) 121 #define CRYPTO_MAX_FIND_COUNT 512 122 123 /* 124 * When a mechanism parameter length is less than CRYPTO_DEFERRED_LIMIT 125 * bytes, then the length is added to the next resource control check. 126 */ 127 #define CRYPTO_DEFERRED_LIMIT 100 128 129 /* The session table grows by CRYPTO_SESSION_CHUNK increments */ 130 #define CRYPTO_SESSION_CHUNK 100 131 132 size_t crypto_max_buffer_len = CRYPTO_MAX_BUFFER_LEN; 133 134 #define INIT_RAW_CRYPTO_DATA(data, len) \ 135 (data).cd_format = CRYPTO_DATA_RAW; \ 136 (data).cd_raw.iov_base = kmem_alloc(len, KM_SLEEP); \ 137 (data).cd_raw.iov_len = len; \ 138 (data).cd_offset = 0; \ 139 (data).cd_length = len; 140 141 static struct kmem_cache *crypto_session_cache; 142 static crypto_minor_t **crypto_minors = NULL; 143 static dev_info_t *crypto_dip = NULL; 144 static minor_t crypto_minor_chunk = CRYPTO_MINOR_CHUNK; 145 static minor_t crypto_minors_table_count = 0; 146 147 /* 148 * Minors are started from 1 because vmem_alloc() 149 * returns 0 in case of failure. 150 */ 151 static vmem_t *crypto_arena = NULL; /* Arena for device minors */ 152 static minor_t crypto_minors_count = 0; 153 static kmutex_t crypto_lock; 154 static kmutex_t crypto_rctl_lock; 155 static kcondvar_t crypto_cv; 156 157 #define RETURN_LIST B_TRUE 158 #define DONT_RETURN_LIST B_FALSE 159 160 #define CRYPTO_OPS_OFFSET(f) offsetof(crypto_ops_t, co_##f) 161 #define CRYPTO_RANDOM_OFFSET(f) offsetof(crypto_random_number_ops_t, f) 162 #define CRYPTO_SESSION_OFFSET(f) offsetof(crypto_session_ops_t, f) 163 #define CRYPTO_OBJECT_OFFSET(f) offsetof(crypto_object_ops_t, f) 164 #define CRYPTO_PROVIDER_OFFSET(f) \ 165 offsetof(crypto_provider_management_ops_t, f) 166 167 #define CRYPTO_CANCEL_CTX(spp) { \ 168 crypto_cancel_ctx(*(spp)); \ 169 *(spp) = NULL; \ 170 } 171 172 #define CRYPTO_CANCEL_ALL_CTX(sp) { \ 173 if ((sp)->sd_digest_ctx != NULL) { \ 174 crypto_cancel_ctx((sp)->sd_digest_ctx); \ 175 (sp)->sd_digest_ctx = NULL; \ 176 } \ 177 if ((sp)->sd_encr_ctx != NULL) { \ 178 crypto_cancel_ctx((sp)->sd_encr_ctx); \ 179 (sp)->sd_encr_ctx = NULL; \ 180 } \ 181 if ((sp)->sd_decr_ctx != NULL) { \ 182 crypto_cancel_ctx((sp)->sd_decr_ctx); \ 183 (sp)->sd_decr_ctx = NULL; \ 184 } \ 185 if ((sp)->sd_sign_ctx != NULL) { \ 186 crypto_cancel_ctx((sp)->sd_sign_ctx); \ 187 (sp)->sd_sign_ctx = NULL; \ 188 } \ 189 if ((sp)->sd_verify_ctx != NULL) { \ 190 crypto_cancel_ctx((sp)->sd_verify_ctx); \ 191 (sp)->sd_verify_ctx = NULL; \ 192 } \ 193 if ((sp)->sd_sign_recover_ctx != NULL) { \ 194 crypto_cancel_ctx((sp)->sd_sign_recover_ctx); \ 195 (sp)->sd_sign_recover_ctx = NULL; \ 196 } \ 197 if ((sp)->sd_verify_recover_ctx != NULL) { \ 198 crypto_cancel_ctx((sp)->sd_verify_recover_ctx); \ 199 (sp)->sd_verify_recover_ctx = NULL; \ 200 } \ 201 } 202 203 #define CRYPTO_DECREMENT_RCTL(val, projp) { \ 204 ASSERT(projp != NULL); \ 205 (projp)->kpj_data.kpd_crypto_mem -= (val); \ 206 project_rele(projp); \ 207 } 208 209 /* 210 * Module linkage. 211 */ 212 static struct cb_ops cbops = { 213 crypto_open, /* cb_open */ 214 crypto_close, /* cb_close */ 215 nodev, /* cb_strategy */ 216 nodev, /* cb_print */ 217 nodev, /* cb_dump */ 218 nodev, /* cb_read */ 219 nodev, /* cb_write */ 220 crypto_ioctl, /* cb_ioctl */ 221 nodev, /* cb_devmap */ 222 nodev, /* cb_mmap */ 223 nodev, /* cb_segmap */ 224 nochpoll, /* cb_chpoll */ 225 ddi_prop_op, /* cb_prop_op */ 226 NULL, /* cb_streamtab */ 227 D_MP, /* cb_flag */ 228 CB_REV, /* cb_rev */ 229 nodev, /* cb_aread */ 230 nodev, /* cb_awrite */ 231 }; 232 233 static struct dev_ops devops = { 234 DEVO_REV, /* devo_rev */ 235 0, /* devo_refcnt */ 236 crypto_getinfo, /* devo_getinfo */ 237 nulldev, /* devo_identify */ 238 nulldev, /* devo_probe */ 239 crypto_attach, /* devo_attach */ 240 crypto_detach, /* devo_detach */ 241 nodev, /* devo_reset */ 242 &cbops, /* devo_cb_ops */ 243 NULL, /* devo_bus_ops */ 244 NULL, /* devo_power */ 245 }; 246 247 static struct modldrv modldrv = { 248 &mod_driverops, /* drv_modops */ 249 "Cryptographic Library Interface v%I%", /* drv_linkinfo */ 250 &devops, 251 }; 252 253 static struct modlinkage modlinkage = { 254 MODREV_1, /* ml_rev */ 255 &modldrv, /* ml_linkage */ 256 NULL 257 }; 258 259 /* 260 * DDI entry points. 261 */ 262 int 263 _init(void) 264 { 265 return (mod_install(&modlinkage)); 266 } 267 268 int 269 _fini(void) 270 { 271 return (mod_remove(&modlinkage)); 272 } 273 274 int 275 _info(struct modinfo *modinfop) 276 { 277 return (mod_info(&modlinkage, modinfop)); 278 } 279 280 /* ARGSUSED */ 281 static int 282 crypto_getinfo(dev_info_t *dip, ddi_info_cmd_t cmd, void *arg, void **result) 283 { 284 switch (cmd) { 285 case DDI_INFO_DEVT2DEVINFO: 286 *result = crypto_dip; 287 return (DDI_SUCCESS); 288 289 case DDI_INFO_DEVT2INSTANCE: 290 *result = (void *)0; 291 return (DDI_SUCCESS); 292 } 293 return (DDI_FAILURE); 294 } 295 296 static int 297 crypto_attach(dev_info_t *dip, ddi_attach_cmd_t cmd) 298 { 299 if (cmd != DDI_ATTACH) { 300 return (DDI_FAILURE); 301 } 302 303 if (ddi_get_instance(dip) != 0) { 304 /* we only allow instance 0 to attach */ 305 return (DDI_FAILURE); 306 } 307 308 crypto_session_cache = kmem_cache_create("crypto_session_cache", 309 sizeof (crypto_session_data_t), 0, NULL, NULL, NULL, NULL, NULL, 0); 310 311 if (crypto_session_cache == NULL) 312 return (DDI_FAILURE); 313 314 /* create the minor node */ 315 if (ddi_create_minor_node(dip, "crypto", S_IFCHR, 0, 316 DDI_PSEUDO, 0) != DDI_SUCCESS) { 317 kmem_cache_destroy(crypto_session_cache); 318 crypto_session_cache = NULL; 319 cmn_err(CE_WARN, "crypto_attach: failed creating minor node"); 320 ddi_remove_minor_node(dip, NULL); 321 return (DDI_FAILURE); 322 } 323 324 mutex_init(&crypto_lock, NULL, MUTEX_DRIVER, NULL); 325 mutex_init(&crypto_rctl_lock, NULL, MUTEX_DRIVER, NULL); 326 cv_init(&crypto_cv, NULL, CV_DRIVER, NULL); 327 crypto_dip = dip; 328 329 /* allocate integer space for minor numbers */ 330 crypto_arena = vmem_create("crypto", (void *)1, 331 CRYPTO_MINOR_CHUNK, 1, NULL, NULL, NULL, 0, 332 VM_SLEEP | VMC_IDENTIFIER); 333 334 return (DDI_SUCCESS); 335 } 336 337 static int 338 crypto_detach(dev_info_t *dip, ddi_detach_cmd_t cmd) 339 { 340 minor_t i; 341 342 if (cmd != DDI_DETACH) 343 return (DDI_FAILURE); 344 345 /* check if device is open */ 346 mutex_enter(&crypto_lock); 347 for (i = 0; i < crypto_minors_table_count; i++) { 348 if (crypto_minors[i] != NULL) { 349 mutex_exit(&crypto_lock); 350 return (DDI_FAILURE); 351 } 352 } 353 mutex_exit(&crypto_lock); 354 355 crypto_dip = NULL; 356 ddi_remove_minor_node(dip, NULL); 357 358 kmem_cache_destroy(crypto_session_cache); 359 crypto_session_cache = NULL; 360 361 kmem_free(crypto_minors, 362 sizeof (crypto_minor_t *) * crypto_minors_table_count); 363 crypto_minors = NULL; 364 crypto_minors_table_count = 0; 365 mutex_destroy(&crypto_lock); 366 mutex_destroy(&crypto_rctl_lock); 367 cv_destroy(&crypto_cv); 368 vmem_destroy(crypto_arena); 369 crypto_arena = NULL; 370 371 return (DDI_SUCCESS); 372 } 373 374 /* ARGSUSED */ 375 static int 376 crypto_open(dev_t *devp, int flag, int otyp, cred_t *credp) 377 { 378 crypto_minor_t *cm = NULL; 379 minor_t mn; 380 381 if (otyp != OTYP_CHR) 382 return (ENXIO); 383 384 if (crypto_dip == NULL) 385 return (ENXIO); 386 387 /* exclusive opens are not supported */ 388 if (flag & FEXCL) 389 return (ENOTSUP); 390 391 mutex_enter(&crypto_lock); 392 again: 393 /* grow the minors table if needed */ 394 if (crypto_minors_count >= crypto_minors_table_count) { 395 crypto_minor_t **newtable; 396 minor_t chunk = crypto_minor_chunk; 397 minor_t saved_count; 398 size_t new_size; 399 ulong_t big_count; 400 401 big_count = crypto_minors_count + chunk; 402 if (big_count > MAXMIN) { 403 mutex_exit(&crypto_lock); 404 return (ENOMEM); 405 } 406 407 saved_count = crypto_minors_table_count; 408 new_size = sizeof (crypto_minor_t *) * 409 (crypto_minors_table_count + chunk); 410 411 mutex_exit(&crypto_lock); 412 newtable = kmem_zalloc(new_size, KM_SLEEP); 413 mutex_enter(&crypto_lock); 414 415 /* 416 * Check if table grew while we were sleeping. 417 * The minors table never shrinks. 418 */ 419 if (crypto_minors_table_count > saved_count) { 420 kmem_free(newtable, new_size); 421 goto again; 422 } 423 424 /* we assume that bcopy() will return if count is 0 */ 425 bcopy(crypto_minors, newtable, 426 sizeof (crypto_minor_t *) * crypto_minors_table_count); 427 428 kmem_free(crypto_minors, 429 sizeof (crypto_minor_t *) * crypto_minors_table_count); 430 431 /* grow the minors number space */ 432 if (crypto_minors_table_count != 0) { 433 (void) vmem_add(crypto_arena, 434 (void *)(uintptr_t)(crypto_minors_table_count + 1), 435 crypto_minor_chunk, VM_SLEEP); 436 } 437 438 crypto_minors = newtable; 439 crypto_minors_table_count += chunk; 440 } 441 mutex_exit(&crypto_lock); 442 443 /* allocate a new minor number starting with 1 */ 444 mn = (minor_t)(uintptr_t)vmem_alloc(crypto_arena, 1, VM_SLEEP); 445 446 cm = kmem_zalloc(sizeof (crypto_minor_t), KM_SLEEP); 447 mutex_init(&cm->cm_lock, NULL, MUTEX_DRIVER, NULL); 448 cv_init(&cm->cm_cv, NULL, CV_DRIVER, NULL); 449 450 mutex_enter(&crypto_lock); 451 crypto_minors[mn - 1] = cm; 452 crypto_minors_count++; 453 mutex_exit(&crypto_lock); 454 455 *devp = makedevice(getmajor(*devp), mn); 456 457 return (0); 458 } 459 460 /* ARGSUSED */ 461 static int 462 crypto_close(dev_t dev, int flag, int otyp, cred_t *credp) 463 { 464 crypto_minor_t *cm = NULL; 465 crypto_session_data_t *sp; 466 minor_t mn = getminor(dev); 467 uint_t i; 468 469 mutex_enter(&crypto_lock); 470 if (mn > crypto_minors_table_count) { 471 mutex_exit(&crypto_lock); 472 cmn_err(CE_WARN, "crypto_close: bad minor (too big) %d", mn); 473 return (ENODEV); 474 } 475 476 while (((cm = crypto_minors[mn - 1]) != NULL) && (cm->cm_refcnt > 0)) { 477 cv_wait(&crypto_cv, &crypto_lock); 478 } 479 480 if (cm == NULL) { 481 mutex_exit(&crypto_lock); 482 cmn_err(CE_WARN, "crypto_close: duplicate close of minor %d", 483 getminor(dev)); 484 return (ENODEV); 485 } 486 487 /* take it out of the global table */ 488 crypto_minors[mn - 1] = NULL; 489 crypto_minors_count--; 490 491 vmem_free(crypto_arena, (void *)(uintptr_t)mn, 1); 492 493 mutex_enter(&cm->cm_lock); 494 mutex_exit(&crypto_lock); 495 496 /* free all session table entries starting with 1 */ 497 for (i = 1; i < cm->cm_session_table_count; i++) { 498 if (cm->cm_session_table[i] == NULL) 499 continue; 500 501 sp = cm->cm_session_table[i]; 502 ASSERT((sp->sd_flags & CRYPTO_SESSION_IS_BUSY) == 0); 503 if (sp->sd_find_init_cookie != NULL) { 504 (void) crypto_free_find_ctx(sp); 505 } 506 crypto_release_provider_session(cm, sp->sd_provider_session); 507 KCF_PROV_REFRELE(sp->sd_provider); 508 CRYPTO_CANCEL_ALL_CTX(sp); 509 mutex_destroy(&sp->sd_lock); 510 cv_destroy(&sp->sd_cv); 511 kmem_cache_free(crypto_session_cache, sp); 512 cm->cm_session_table[i] = NULL; 513 } 514 515 /* free the session table */ 516 if (cm->cm_session_table != NULL && cm->cm_session_table_count > 0) 517 kmem_free(cm->cm_session_table, cm->cm_session_table_count * 518 sizeof (void *)); 519 520 if (cm->cm_session_table_count != 0) { 521 mutex_enter(&crypto_rctl_lock); 522 CRYPTO_DECREMENT_RCTL(cm->cm_session_table_count * 523 sizeof (void *), cm->cm_projp); 524 mutex_exit(&crypto_rctl_lock); 525 } 526 527 kcf_free_provider_tab(cm->cm_provider_count, 528 cm->cm_provider_array); 529 530 mutex_destroy(&cm->cm_lock); 531 cv_destroy(&cm->cm_cv); 532 kmem_free(cm, sizeof (crypto_minor_t)); 533 534 return (0); 535 } 536 537 static crypto_minor_t * 538 crypto_hold_minor(minor_t minor) 539 { 540 crypto_minor_t *cm = NULL; 541 542 mutex_enter(&crypto_lock); 543 if ((minor <= crypto_minors_table_count) && 544 ((cm = crypto_minors[minor - 1]) != NULL)) { 545 cm->cm_refcnt++; 546 } 547 mutex_exit(&crypto_lock); 548 return (cm); 549 } 550 551 static void 552 crypto_release_minor(crypto_minor_t *cm) 553 { 554 mutex_enter(&crypto_lock); 555 cm->cm_refcnt--; 556 if (cm->cm_refcnt == 0) { 557 cv_broadcast(&crypto_cv); 558 } 559 mutex_exit(&crypto_lock); 560 } 561 562 /* 563 * 564 */ 565 static void 566 crypto_build_function_list(crypto_function_list_t *fl, kcf_provider_desc_t *pd) 567 { 568 crypto_ops_t *ops; 569 crypto_digest_ops_t *digest_ops; 570 crypto_cipher_ops_t *cipher_ops; 571 crypto_mac_ops_t *mac_ops; 572 crypto_sign_ops_t *sign_ops; 573 crypto_verify_ops_t *verify_ops; 574 crypto_dual_ops_t *dual_ops; 575 crypto_random_number_ops_t *random_number_ops; 576 crypto_session_ops_t *session_ops; 577 crypto_object_ops_t *object_ops; 578 crypto_key_ops_t *key_ops; 579 crypto_provider_management_ops_t *provider_ops; 580 581 if ((ops = pd->pd_ops_vector) == NULL) 582 return; 583 584 if ((digest_ops = ops->co_digest_ops) != NULL) { 585 if (digest_ops->digest_init != NULL) 586 fl->fl_digest_init = B_TRUE; 587 if (digest_ops->digest != NULL) 588 fl->fl_digest = B_TRUE; 589 if (digest_ops->digest_update != NULL) 590 fl->fl_digest_update = B_TRUE; 591 if (digest_ops->digest_key != NULL) 592 fl->fl_digest_key = B_TRUE; 593 if (digest_ops->digest_final != NULL) 594 fl->fl_digest_final = B_TRUE; 595 } 596 if ((cipher_ops = ops->co_cipher_ops) != NULL) { 597 if (cipher_ops->encrypt_init != NULL) 598 fl->fl_encrypt_init = B_TRUE; 599 if (cipher_ops->encrypt != NULL) 600 fl->fl_encrypt = B_TRUE; 601 if (cipher_ops->encrypt_update != NULL) 602 fl->fl_encrypt_update = B_TRUE; 603 if (cipher_ops->encrypt_final != NULL) 604 fl->fl_encrypt_final = B_TRUE; 605 if (cipher_ops->decrypt_init != NULL) 606 fl->fl_decrypt_init = B_TRUE; 607 if (cipher_ops->decrypt != NULL) 608 fl->fl_decrypt = B_TRUE; 609 if (cipher_ops->decrypt_update != NULL) 610 fl->fl_decrypt_update = B_TRUE; 611 if (cipher_ops->decrypt_final != NULL) 612 fl->fl_decrypt_final = B_TRUE; 613 } 614 if ((mac_ops = ops->co_mac_ops) != NULL) { 615 if (mac_ops->mac_init != NULL) 616 fl->fl_mac_init = B_TRUE; 617 if (mac_ops->mac != NULL) 618 fl->fl_mac = B_TRUE; 619 if (mac_ops->mac_update != NULL) 620 fl->fl_mac_update = B_TRUE; 621 if (mac_ops->mac_final != NULL) 622 fl->fl_mac_final = B_TRUE; 623 } 624 if ((sign_ops = ops->co_sign_ops) != NULL) { 625 if (sign_ops->sign_init != NULL) 626 fl->fl_sign_init = B_TRUE; 627 if (sign_ops->sign != NULL) 628 fl->fl_sign = B_TRUE; 629 if (sign_ops->sign_update != NULL) 630 fl->fl_sign_update = B_TRUE; 631 if (sign_ops->sign_final != NULL) 632 fl->fl_sign_final = B_TRUE; 633 if (sign_ops->sign_recover_init != NULL) 634 fl->fl_sign_recover_init = B_TRUE; 635 if (sign_ops->sign_recover != NULL) 636 fl->fl_sign_recover = B_TRUE; 637 } 638 if ((verify_ops = ops->co_verify_ops) != NULL) { 639 if (verify_ops->verify_init != NULL) 640 fl->fl_verify_init = B_TRUE; 641 if (verify_ops->verify != NULL) 642 fl->fl_verify = B_TRUE; 643 if (verify_ops->verify_update != NULL) 644 fl->fl_verify_update = B_TRUE; 645 if (verify_ops->verify_final != NULL) 646 fl->fl_verify_final = B_TRUE; 647 if (verify_ops->verify_recover_init != NULL) 648 fl->fl_verify_recover_init = B_TRUE; 649 if (verify_ops->verify_recover != NULL) 650 fl->fl_verify_recover = B_TRUE; 651 } 652 if ((dual_ops = ops->co_dual_ops) != NULL) { 653 if (dual_ops->digest_encrypt_update != NULL) 654 fl->fl_digest_encrypt_update = B_TRUE; 655 if (dual_ops->decrypt_digest_update != NULL) 656 fl->fl_decrypt_digest_update = B_TRUE; 657 if (dual_ops->sign_encrypt_update != NULL) 658 fl->fl_sign_encrypt_update = B_TRUE; 659 if (dual_ops->decrypt_verify_update != NULL) 660 fl->fl_decrypt_verify_update = B_TRUE; 661 } 662 if ((random_number_ops = ops->co_random_ops) != NULL) { 663 if (random_number_ops->seed_random != NULL) 664 fl->fl_seed_random = B_TRUE; 665 if (random_number_ops->generate_random != NULL) 666 fl->fl_generate_random = B_TRUE; 667 } 668 if ((session_ops = ops->co_session_ops) != NULL) { 669 if (session_ops->session_open != NULL) 670 fl->fl_session_open = B_TRUE; 671 if (session_ops->session_close != NULL) 672 fl->fl_session_close = B_TRUE; 673 if (session_ops->session_login != NULL) 674 fl->fl_session_login = B_TRUE; 675 if (session_ops->session_logout != NULL) 676 fl->fl_session_logout = B_TRUE; 677 } 678 if ((object_ops = ops->co_object_ops) != NULL) { 679 if (object_ops->object_create != NULL) 680 fl->fl_object_create = B_TRUE; 681 if (object_ops->object_copy != NULL) 682 fl->fl_object_copy = B_TRUE; 683 if (object_ops->object_destroy != NULL) 684 fl->fl_object_destroy = B_TRUE; 685 if (object_ops->object_get_size != NULL) 686 fl->fl_object_get_size = B_TRUE; 687 if (object_ops->object_get_attribute_value != NULL) 688 fl->fl_object_get_attribute_value = B_TRUE; 689 if (object_ops->object_set_attribute_value != NULL) 690 fl->fl_object_set_attribute_value = B_TRUE; 691 if (object_ops->object_find_init != NULL) 692 fl->fl_object_find_init = B_TRUE; 693 if (object_ops->object_find != NULL) 694 fl->fl_object_find = B_TRUE; 695 if (object_ops->object_find_final != NULL) 696 fl->fl_object_find_final = B_TRUE; 697 } 698 if ((key_ops = ops->co_key_ops) != NULL) { 699 if (key_ops->key_generate != NULL) 700 fl->fl_key_generate = B_TRUE; 701 if (key_ops->key_generate_pair != NULL) 702 fl->fl_key_generate_pair = B_TRUE; 703 if (key_ops->key_wrap != NULL) 704 fl->fl_key_wrap = B_TRUE; 705 if (key_ops->key_unwrap != NULL) 706 fl->fl_key_unwrap = B_TRUE; 707 if (key_ops->key_derive != NULL) 708 fl->fl_key_derive = B_TRUE; 709 } 710 if ((provider_ops = ops->co_provider_ops) != NULL) { 711 if (provider_ops->init_token != NULL) 712 fl->fl_init_token = B_TRUE; 713 if (provider_ops->init_pin != NULL) 714 fl->fl_init_pin = B_TRUE; 715 if (provider_ops->set_pin != NULL) 716 fl->fl_set_pin = B_TRUE; 717 } 718 } 719 720 /* ARGSUSED */ 721 static int 722 get_function_list(dev_t dev, caddr_t arg, int mode, int *rval) 723 { 724 crypto_get_function_list_t get_function_list; 725 crypto_minor_t *cm; 726 crypto_provider_id_t provider_id; 727 crypto_function_list_t *fl; 728 kcf_provider_desc_t *provider; 729 int rv; 730 731 if ((cm = crypto_hold_minor(getminor(dev))) == NULL) { 732 cmn_err(CE_WARN, "get_function_list: failed holding minor"); 733 return (ENXIO); 734 } 735 736 if (copyin(arg, &get_function_list, sizeof (get_function_list)) != 0) { 737 crypto_release_minor(cm); 738 return (EFAULT); 739 } 740 741 /* initialize provider_array */ 742 if (cm->cm_provider_array == NULL) { 743 rv = crypto_get_provider_list(cm, NULL, NULL, DONT_RETURN_LIST); 744 if (rv != CRYPTO_SUCCESS) { 745 goto release_minor; 746 } 747 } 748 749 provider_id = get_function_list.fl_provider_id; 750 mutex_enter(&cm->cm_lock); 751 /* index must be less than count of providers */ 752 if (provider_id >= cm->cm_provider_count) { 753 mutex_exit(&cm->cm_lock); 754 rv = CRYPTO_ARGUMENTS_BAD; 755 goto release_minor; 756 } 757 758 ASSERT(cm->cm_provider_array != NULL); 759 provider = cm->cm_provider_array[provider_id]; 760 mutex_exit(&cm->cm_lock); 761 762 fl = &get_function_list.fl_list; 763 bzero(fl, sizeof (crypto_function_list_t)); 764 765 if (provider->pd_prov_type != CRYPTO_LOGICAL_PROVIDER) { 766 crypto_build_function_list(fl, provider); 767 } else { 768 kcf_provider_desc_t *prev = NULL, *pd; 769 770 mutex_enter(&provider->pd_lock); 771 while (kcf_get_next_logical_provider_member(provider, 772 prev, &pd)) { 773 prev = pd; 774 crypto_build_function_list(fl, pd); 775 KCF_PROV_REFRELE(pd); 776 } 777 mutex_exit(&provider->pd_lock); 778 } 779 780 rv = CRYPTO_SUCCESS; 781 782 release_minor: 783 crypto_release_minor(cm); 784 785 get_function_list.fl_return_value = rv; 786 787 if (copyout(&get_function_list, arg, sizeof (get_function_list)) != 0) { 788 return (EFAULT); 789 } 790 return (0); 791 } 792 793 /* 794 * This ioctl maps a PKCS#11 mechanism string into an internal number 795 * that is used by the kernel. pn_internal_number is set to the 796 * internal number. 797 */ 798 /* ARGSUSED */ 799 static int 800 get_mechanism_number(dev_t dev, caddr_t arg, int mode, int *rval) 801 { 802 STRUCT_DECL(crypto_get_mechanism_number, get_number); 803 crypto_mech_type_t number; 804 size_t len; 805 char *mechanism_name; 806 int rv; 807 808 STRUCT_INIT(get_number, mode); 809 810 if (copyin(arg, STRUCT_BUF(get_number), STRUCT_SIZE(get_number)) != 0) 811 return (EFAULT); 812 813 len = STRUCT_FGET(get_number, pn_mechanism_len); 814 if (len == 0 || len > CRYPTO_MAX_MECH_NAME) { 815 rv = CRYPTO_ARGUMENTS_BAD; 816 goto out; 817 } 818 mechanism_name = kmem_alloc(len, KM_SLEEP); 819 820 if (copyin(STRUCT_FGETP(get_number, pn_mechanism_string), 821 mechanism_name, len) != 0) { 822 kmem_free(mechanism_name, len); 823 return (EFAULT); 824 } 825 826 /* get mechanism number from the core module */ 827 number = crypto_mech2id_common(mechanism_name, B_TRUE); 828 kmem_free(mechanism_name, len); 829 if (number == CRYPTO_MECH_INVALID) { 830 rv = CRYPTO_ARGUMENTS_BAD; 831 goto out; 832 } 833 834 bcopy((char *)&number, (char *)STRUCT_FADDR(get_number, 835 pn_internal_number), sizeof (number)); 836 837 rv = CRYPTO_SUCCESS; 838 out: 839 STRUCT_FSET(get_number, pn_return_value, rv); 840 841 if (copyout(STRUCT_BUF(get_number), arg, 842 STRUCT_SIZE(get_number)) != 0) { 843 return (EFAULT); 844 } 845 return (0); 846 } 847 848 /* 849 * Side-effects: 850 * 1. This routine stores provider descriptor pointers in an array 851 * and increments each descriptor's reference count. The array 852 * is stored in per-minor number storage. 853 * 2. Destroys the old array and creates a new one every time 854 * this routine is called. 855 */ 856 int 857 crypto_get_provider_list(crypto_minor_t *cm, uint_t *count, 858 crypto_provider_entry_t **array, boolean_t return_slot_list) 859 { 860 kcf_provider_desc_t **provider_array; 861 crypto_provider_entry_t *p = NULL; 862 uint_t provider_count; 863 int rval; 864 int i; 865 866 /* 867 * Take snapshot of provider table returning only HW entries 868 * that are in a usable state. Also returns logical provider entries. 869 */ 870 rval = kcf_get_slot_list(&provider_count, &provider_array, B_FALSE); 871 if (rval != CRYPTO_SUCCESS) 872 return (rval); 873 874 /* allocate memory before taking cm->cm_lock */ 875 if (return_slot_list) { 876 if (provider_count != 0) { 877 p = kmem_alloc(provider_count * 878 sizeof (crypto_provider_entry_t), KM_SLEEP); 879 for (i = 0; i < provider_count; i++) { 880 p[i].pe_provider_id = i; 881 p[i].pe_mechanism_count = 882 provider_array[i]->pd_mech_list_count; 883 } 884 } 885 *array = p; 886 *count = provider_count; 887 } 888 889 /* 890 * Free existing array of providers and replace with new list. 891 */ 892 mutex_enter(&cm->cm_lock); 893 if (cm->cm_provider_array != NULL) { 894 ASSERT(cm->cm_provider_count > 0); 895 kcf_free_provider_tab(cm->cm_provider_count, 896 cm->cm_provider_array); 897 } 898 899 cm->cm_provider_array = provider_array; 900 cm->cm_provider_count = provider_count; 901 mutex_exit(&cm->cm_lock); 902 903 return (CRYPTO_SUCCESS); 904 } 905 906 /* 907 * This ioctl returns an array of crypto_provider_entry_t entries. 908 * This is how consumers learn which hardware providers are available. 909 */ 910 /* ARGSUSED */ 911 static int 912 get_provider_list(dev_t dev, caddr_t arg, int mode, int *rval) 913 { 914 STRUCT_DECL(crypto_get_provider_list, get_list); 915 crypto_provider_entry_t *entries; 916 crypto_minor_t *cm; 917 size_t copyout_size; 918 uint_t req_count; 919 uint_t count; 920 ulong_t offset; 921 int rv; 922 923 STRUCT_INIT(get_list, mode); 924 925 if ((cm = crypto_hold_minor(getminor(dev))) == NULL) { 926 cmn_err(CE_WARN, "get_provider_list: failed holding minor"); 927 return (ENXIO); 928 } 929 930 if (copyin(arg, STRUCT_BUF(get_list), STRUCT_SIZE(get_list)) != 0) { 931 crypto_release_minor(cm); 932 return (EFAULT); 933 } 934 935 rv = crypto_get_provider_list(cm, &count, &entries, RETURN_LIST); 936 if (rv != CRYPTO_SUCCESS) { 937 crypto_release_minor(cm); 938 STRUCT_FSET(get_list, pl_return_value, rv); 939 if (copyout(STRUCT_BUF(get_list), arg, 940 STRUCT_SIZE(get_list)) != 0) { 941 return (EFAULT); 942 } 943 return (0); 944 } 945 crypto_release_minor(cm); 946 947 /* Number of slots caller thinks we have */ 948 req_count = STRUCT_FGET(get_list, pl_count); 949 950 /* Check if only requesting number of slots */ 951 if (req_count == 0) { 952 953 STRUCT_FSET(get_list, pl_count, count); 954 STRUCT_FSET(get_list, pl_return_value, CRYPTO_SUCCESS); 955 956 crypto_free_provider_list(entries, count); 957 if (copyout(STRUCT_BUF(get_list), arg, 958 STRUCT_SIZE(get_list)) != 0) { 959 return (EFAULT); 960 } 961 return (0); 962 } 963 964 /* check if buffer is too small */ 965 req_count = STRUCT_FGET(get_list, pl_count); 966 if (count > req_count) { 967 STRUCT_FSET(get_list, pl_count, count); 968 STRUCT_FSET(get_list, pl_return_value, CRYPTO_BUFFER_TOO_SMALL); 969 crypto_free_provider_list(entries, count); 970 if (copyout(STRUCT_BUF(get_list), arg, 971 STRUCT_SIZE(get_list)) != 0) { 972 return (EFAULT); 973 } 974 return (0); 975 } 976 977 STRUCT_FSET(get_list, pl_count, count); 978 STRUCT_FSET(get_list, pl_return_value, CRYPTO_SUCCESS); 979 980 copyout_size = count * sizeof (crypto_provider_entry_t); 981 982 /* copyout the first stuff */ 983 if (copyout(STRUCT_BUF(get_list), arg, STRUCT_SIZE(get_list)) != 0) { 984 crypto_free_provider_list(entries, count); 985 return (EFAULT); 986 } 987 988 if (count == 0) { 989 crypto_free_provider_list(entries, count); 990 return (0); 991 } 992 993 /* copyout entries */ 994 offset = (ulong_t)STRUCT_FADDR(get_list, pl_list); 995 offset -= (ulong_t)STRUCT_BUF(get_list); 996 if (copyout(entries, arg + offset, copyout_size) != 0) { 997 crypto_free_provider_list(entries, count); 998 return (EFAULT); 999 } 1000 1001 crypto_free_provider_list(entries, count); 1002 return (0); 1003 } 1004 1005 static void 1006 ext_to_provider_data(int mode, kcf_provider_desc_t *provider, 1007 crypto_provider_ext_info_t *ei, void *out) 1008 { 1009 STRUCT_DECL(crypto_provider_data, pd); 1010 STRUCT_DECL(crypto_version, version); 1011 1012 STRUCT_INIT(pd, mode); 1013 STRUCT_INIT(version, mode); 1014 1015 bcopy(provider->pd_description, STRUCT_FGET(pd, pd_prov_desc), 1016 CRYPTO_PROVIDER_DESCR_MAX_LEN); 1017 1018 bcopy(ei->ei_label, STRUCT_FGET(pd, pd_label), CRYPTO_EXT_SIZE_LABEL); 1019 bcopy(ei->ei_manufacturerID, STRUCT_FGET(pd, pd_manufacturerID), 1020 CRYPTO_EXT_SIZE_MANUF); 1021 bcopy(ei->ei_model, STRUCT_FGET(pd, pd_model), CRYPTO_EXT_SIZE_MODEL); 1022 bcopy(ei->ei_serial_number, STRUCT_FGET(pd, pd_serial_number), 1023 CRYPTO_EXT_SIZE_SERIAL); 1024 /* 1025 * We do not support ioctls for dual-function crypto operations yet. 1026 * So, we clear this flag as it might have been set by a provider. 1027 */ 1028 ei->ei_flags &= ~CRYPTO_EXTF_DUAL_CRYPTO_OPERATIONS; 1029 1030 STRUCT_FSET(pd, pd_flags, ei->ei_flags); 1031 STRUCT_FSET(pd, pd_max_session_count, ei->ei_max_session_count); 1032 STRUCT_FSET(pd, pd_session_count, (int)CRYPTO_UNAVAILABLE_INFO); 1033 STRUCT_FSET(pd, pd_max_rw_session_count, ei->ei_max_session_count); 1034 STRUCT_FSET(pd, pd_rw_session_count, (int)CRYPTO_UNAVAILABLE_INFO); 1035 STRUCT_FSET(pd, pd_max_pin_len, ei->ei_max_pin_len); 1036 STRUCT_FSET(pd, pd_min_pin_len, ei->ei_min_pin_len); 1037 STRUCT_FSET(pd, pd_total_public_memory, ei->ei_total_public_memory); 1038 STRUCT_FSET(pd, pd_free_public_memory, ei->ei_free_public_memory); 1039 STRUCT_FSET(pd, pd_total_private_memory, ei->ei_total_private_memory); 1040 STRUCT_FSET(pd, pd_free_private_memory, ei->ei_free_private_memory); 1041 STRUCT_FSET(version, cv_major, ei->ei_hardware_version.cv_major); 1042 STRUCT_FSET(version, cv_minor, ei->ei_hardware_version.cv_minor); 1043 bcopy(STRUCT_BUF(version), STRUCT_FADDR(pd, pd_hardware_version), 1044 STRUCT_SIZE(version)); 1045 bcopy(STRUCT_BUF(version), STRUCT_FADDR(pd, pd_firmware_version), 1046 STRUCT_SIZE(version)); 1047 bcopy(ei->ei_time, STRUCT_FGET(pd, pd_time), CRYPTO_EXT_SIZE_TIME); 1048 bcopy(STRUCT_BUF(pd), out, STRUCT_SIZE(pd)); 1049 } 1050 1051 /* 1052 * Utility routine to construct a crypto_provider_ext_info structure. Some 1053 * of the fields are constructed from information in the provider structure. 1054 * The rest of the fields have default values. We need to do this for 1055 * providers which do not support crypto_provider_management_ops routines. 1056 */ 1057 static void 1058 fabricate_ext_info(kcf_provider_desc_t *provider, 1059 crypto_provider_ext_info_t *ei) 1060 { 1061 /* empty label */ 1062 (void) memset(ei->ei_label, ' ', CRYPTO_EXT_SIZE_LABEL); 1063 1064 (void) memset(ei->ei_manufacturerID, ' ', CRYPTO_EXT_SIZE_MANUF); 1065 (void) strncpy((char *)ei->ei_manufacturerID, "Unknown", 7); 1066 1067 (void) memset(ei->ei_model, ' ', CRYPTO_EXT_SIZE_MODEL); 1068 (void) strncpy((char *)ei->ei_model, "Unknown", 7); 1069 1070 (void) memset(ei->ei_serial_number, ' ', CRYPTO_EXT_SIZE_SERIAL); 1071 (void) strncpy((char *)ei->ei_serial_number, "Unknown", 7); 1072 1073 if (KCF_PROV_RANDOM_OPS(provider) != NULL) 1074 ei->ei_flags |= CRYPTO_EXTF_RNG; 1075 if (KCF_PROV_DUAL_OPS(provider) != NULL) 1076 ei->ei_flags |= CRYPTO_EXTF_DUAL_CRYPTO_OPERATIONS; 1077 1078 ei->ei_max_session_count = CRYPTO_UNAVAILABLE_INFO; 1079 ei->ei_max_pin_len = 0; 1080 ei->ei_min_pin_len = 0; 1081 ei->ei_total_public_memory = CRYPTO_UNAVAILABLE_INFO; 1082 ei->ei_free_public_memory = CRYPTO_UNAVAILABLE_INFO; 1083 ei->ei_total_private_memory = CRYPTO_UNAVAILABLE_INFO; 1084 ei->ei_free_private_memory = CRYPTO_UNAVAILABLE_INFO; 1085 ei->ei_hardware_version.cv_major = 1; 1086 ei->ei_hardware_version.cv_minor = 0; 1087 ei->ei_firmware_version.cv_major = 1; 1088 ei->ei_firmware_version.cv_minor = 0; 1089 } 1090 1091 /* ARGSUSED */ 1092 static int 1093 get_provider_info(dev_t dev, caddr_t arg, int mode, int *rval) 1094 { 1095 STRUCT_DECL(crypto_get_provider_info, get_info); 1096 kproject_t *projp; 1097 crypto_minor_t *cm; 1098 crypto_provider_id_t provider_id; 1099 kcf_provider_desc_t *provider, *real_provider; 1100 crypto_provider_ext_info_t *ext_info = NULL; 1101 size_t need; 1102 int error = 0; 1103 int rv; 1104 kcf_req_params_t params; 1105 1106 STRUCT_INIT(get_info, mode); 1107 1108 if ((cm = crypto_hold_minor(getminor(dev))) == NULL) { 1109 cmn_err(CE_WARN, "get_provider_info: failed holding minor"); 1110 return (ENXIO); 1111 } 1112 1113 if (copyin(arg, STRUCT_BUF(get_info), STRUCT_SIZE(get_info)) != 0) { 1114 crypto_release_minor(cm); 1115 return (EFAULT); 1116 } 1117 1118 need = sizeof (crypto_provider_ext_info_t); 1119 if ((rv = crypto_buffer_check(need, &projp)) != CRYPTO_SUCCESS) { 1120 need = 0; 1121 goto release_minor; 1122 } 1123 1124 /* initialize provider_array */ 1125 if (cm->cm_provider_array == NULL) { 1126 rv = crypto_get_provider_list(cm, NULL, NULL, DONT_RETURN_LIST); 1127 if (rv != CRYPTO_SUCCESS) { 1128 goto release_minor; 1129 } 1130 } 1131 1132 ext_info = kmem_zalloc(need, KM_SLEEP); 1133 1134 provider_id = STRUCT_FGET(get_info, gi_provider_id); 1135 mutex_enter(&cm->cm_lock); 1136 /* index must be less than count of providers */ 1137 if (provider_id >= cm->cm_provider_count) { 1138 mutex_exit(&cm->cm_lock); 1139 rv = CRYPTO_ARGUMENTS_BAD; 1140 goto release_minor; 1141 } 1142 1143 ASSERT(cm->cm_provider_array != NULL); 1144 provider = cm->cm_provider_array[provider_id]; 1145 KCF_PROV_REFHOLD(provider); 1146 mutex_exit(&cm->cm_lock); 1147 1148 (void) kcf_get_hardware_provider_nomech( 1149 CRYPTO_OPS_OFFSET(provider_ops), CRYPTO_PROVIDER_OFFSET(ext_info), 1150 CHECK_RESTRICT_FALSE, provider, &real_provider); 1151 1152 if (real_provider != NULL) { 1153 ASSERT(real_provider == provider || 1154 provider->pd_prov_type == CRYPTO_LOGICAL_PROVIDER); 1155 KCF_WRAP_PROVMGMT_OPS_PARAMS(¶ms, KCF_OP_MGMT_EXTINFO, 1156 0, NULL, 0, NULL, 0, NULL, ext_info, provider); 1157 rv = kcf_submit_request(real_provider, NULL, NULL, ¶ms, 1158 B_FALSE); 1159 ASSERT(rv != CRYPTO_NOT_SUPPORTED); 1160 KCF_PROV_REFRELE(real_provider); 1161 } else { 1162 /* do the best we can */ 1163 fabricate_ext_info(provider, ext_info); 1164 rv = CRYPTO_SUCCESS; 1165 } 1166 KCF_PROV_REFRELE(provider); 1167 1168 if (rv == CRYPTO_SUCCESS) { 1169 ext_to_provider_data(mode, provider, ext_info, 1170 STRUCT_FADDR(get_info, gi_provider_data)); 1171 } 1172 1173 release_minor: 1174 if (need != 0) { 1175 mutex_enter(&crypto_rctl_lock); 1176 CRYPTO_DECREMENT_RCTL(need, projp); 1177 mutex_exit(&crypto_rctl_lock); 1178 } 1179 crypto_release_minor(cm); 1180 1181 if (ext_info != NULL) 1182 kmem_free(ext_info, sizeof (crypto_provider_ext_info_t)); 1183 1184 if (error != 0) 1185 return (error); 1186 1187 STRUCT_FSET(get_info, gi_return_value, rv); 1188 if (copyout(STRUCT_BUF(get_info), arg, STRUCT_SIZE(get_info)) != 0) { 1189 return (EFAULT); 1190 } 1191 return (0); 1192 } 1193 1194 /* 1195 * This ioctl returns an array of crypto_mech_name_t entries. 1196 * This is how consumers learn which mechanisms are permitted 1197 * by a provider. 1198 */ 1199 /* ARGSUSED */ 1200 static int 1201 get_provider_mechanisms(dev_t dev, caddr_t arg, int mode, int *rval) 1202 { 1203 STRUCT_DECL(crypto_get_provider_mechanisms, get_mechanisms); 1204 crypto_mech_name_t *entries; 1205 crypto_minor_t *cm; 1206 size_t copyout_size; 1207 uint_t req_count; 1208 uint_t count; 1209 ulong_t offset; 1210 int err; 1211 1212 STRUCT_INIT(get_mechanisms, mode); 1213 1214 if ((cm = crypto_hold_minor(getminor(dev))) == NULL) { 1215 cmn_err(CE_WARN, 1216 "get_provider_mechanisms: failed holding minor"); 1217 return (ENXIO); 1218 } 1219 1220 if (copyin(arg, STRUCT_BUF(get_mechanisms), 1221 STRUCT_SIZE(get_mechanisms)) != 0) { 1222 crypto_release_minor(cm); 1223 return (EFAULT); 1224 } 1225 1226 /* get array of mechanisms from the core module */ 1227 if ((err = crypto_get_provider_mechanisms(cm, 1228 STRUCT_FGET(get_mechanisms, pm_provider_id), 1229 &count, &entries)) != 0) { 1230 crypto_release_minor(cm); 1231 STRUCT_FSET(get_mechanisms, pm_return_value, err); 1232 if (copyout(STRUCT_BUF(get_mechanisms), arg, 1233 STRUCT_SIZE(get_mechanisms)) != 0) { 1234 return (EFAULT); 1235 } 1236 return (0); 1237 } 1238 crypto_release_minor(cm); 1239 /* Number of mechs caller thinks we have */ 1240 req_count = STRUCT_FGET(get_mechanisms, pm_count); 1241 1242 /* Check if caller is just requesting a count of mechanisms */ 1243 if (req_count == 0) { 1244 STRUCT_FSET(get_mechanisms, pm_count, count); 1245 STRUCT_FSET(get_mechanisms, pm_return_value, CRYPTO_SUCCESS); 1246 1247 crypto_free_mech_list(entries, count); 1248 if (copyout(STRUCT_BUF(get_mechanisms), arg, 1249 STRUCT_SIZE(get_mechanisms)) != 0) { 1250 return (EFAULT); 1251 } 1252 return (0); 1253 } 1254 1255 /* check if buffer is too small */ 1256 if (count > req_count) { 1257 STRUCT_FSET(get_mechanisms, pm_count, count); 1258 STRUCT_FSET(get_mechanisms, pm_return_value, 1259 CRYPTO_BUFFER_TOO_SMALL); 1260 crypto_free_mech_list(entries, count); 1261 if (copyout(STRUCT_BUF(get_mechanisms), arg, 1262 STRUCT_SIZE(get_mechanisms)) != 0) { 1263 return (EFAULT); 1264 } 1265 return (0); 1266 } 1267 1268 STRUCT_FSET(get_mechanisms, pm_count, count); 1269 STRUCT_FSET(get_mechanisms, pm_return_value, CRYPTO_SUCCESS); 1270 1271 copyout_size = count * sizeof (crypto_mech_name_t); 1272 1273 /* copyout the first stuff */ 1274 if (copyout(STRUCT_BUF(get_mechanisms), arg, 1275 STRUCT_SIZE(get_mechanisms)) != 0) { 1276 crypto_free_mech_list(entries, count); 1277 return (EFAULT); 1278 } 1279 1280 if (count == 0) { 1281 return (0); 1282 } 1283 1284 /* copyout entries */ 1285 offset = (ulong_t)STRUCT_FADDR(get_mechanisms, pm_list); 1286 offset -= (ulong_t)STRUCT_BUF(get_mechanisms); 1287 if (copyout(entries, arg + offset, copyout_size) != 0) { 1288 crypto_free_mech_list(entries, count); 1289 return (EFAULT); 1290 } 1291 1292 crypto_free_mech_list(entries, count); 1293 return (0); 1294 } 1295 1296 /* 1297 * This ioctl returns information about a provider's mechanism. 1298 */ 1299 /* ARGSUSED */ 1300 static int 1301 get_provider_mechanism_info(dev_t dev, caddr_t arg, int mode, int *rval) 1302 { 1303 crypto_get_provider_mechanism_info_t mechanism_info; 1304 crypto_minor_t *cm; 1305 kcf_provider_desc_t *pd; 1306 crypto_mech_info_t *mi = NULL; 1307 int rv = CRYPTO_SUCCESS; 1308 int i; 1309 1310 if ((cm = crypto_hold_minor(getminor(dev))) == NULL) { 1311 cmn_err(CE_WARN, 1312 "get_provider_mechanism_info: failed holding minor"); 1313 return (ENXIO); 1314 } 1315 1316 if (copyin(arg, &mechanism_info, sizeof (mechanism_info)) != 0) { 1317 crypto_release_minor(cm); 1318 return (EFAULT); 1319 } 1320 1321 /* initialize provider table */ 1322 if (cm->cm_provider_array == NULL) { 1323 rv = crypto_get_provider_list(cm, NULL, NULL, DONT_RETURN_LIST); 1324 if (rv != CRYPTO_SUCCESS) { 1325 mutex_enter(&cm->cm_lock); 1326 goto fail; 1327 } 1328 } 1329 1330 /* 1331 * Provider ID must be less than the count of providers 1332 * obtained by calling get_provider_list(). 1333 */ 1334 mutex_enter(&cm->cm_lock); 1335 if (mechanism_info.mi_provider_id >= cm->cm_provider_count) { 1336 rv = CRYPTO_ARGUMENTS_BAD; 1337 goto fail; 1338 } 1339 1340 pd = cm->cm_provider_array[mechanism_info.mi_provider_id]; 1341 1342 for (i = 0; i < pd->pd_mech_list_count; i++) { 1343 if (strncmp(pd->pd_mechanisms[i].cm_mech_name, 1344 mechanism_info.mi_mechanism_name, 1345 CRYPTO_MAX_MECH_NAME) == 0) { 1346 mi = &pd->pd_mechanisms[i]; 1347 } 1348 } 1349 1350 if (mi == NULL) { 1351 rv = CRYPTO_ARGUMENTS_BAD; 1352 goto fail; 1353 } 1354 1355 mechanism_info.mi_min_key_size = mi->cm_min_key_length; 1356 mechanism_info.mi_max_key_size = mi->cm_max_key_length; 1357 mechanism_info.mi_flags = mi->cm_func_group_mask; 1358 1359 fail: 1360 mutex_exit(&cm->cm_lock); 1361 crypto_release_minor(cm); 1362 mechanism_info.mi_return_value = rv; 1363 if (copyout(&mechanism_info, arg, sizeof (mechanism_info)) != 0) { 1364 return (EFAULT); 1365 } 1366 1367 return (0); 1368 } 1369 1370 /* 1371 * Every open of /dev/crypto multiplexes all PKCS#11 sessions across 1372 * a single session to each provider. Calls to open and close session 1373 * are not made to providers that do not support sessions. For these 1374 * providers, a session number of 0 is passed during subsequent operations, 1375 * and it is ignored by the provider. 1376 */ 1377 static int 1378 crypto_get_provider_session(crypto_minor_t *cm, 1379 crypto_provider_id_t provider_index, crypto_provider_session_t **output_ps) 1380 { 1381 kcf_provider_desc_t *pd, *real_provider; 1382 kcf_req_params_t params; 1383 crypto_provider_session_t *ps, *new_ps; 1384 crypto_session_id_t provider_session_id = 0; 1385 int rv; 1386 1387 ASSERT(MUTEX_HELD(&cm->cm_lock)); 1388 1389 /* pd may be a logical provider */ 1390 pd = cm->cm_provider_array[provider_index]; 1391 1392 again: 1393 /* 1394 * Check if there is already a session to the provider. 1395 * Sessions may be to a logical provider or a real provider. 1396 */ 1397 for (ps = cm->cm_provider_session; ps != NULL; ps = ps->ps_next) { 1398 if (ps->ps_provider == pd) 1399 break; 1400 } 1401 1402 /* found existing session */ 1403 if (ps != NULL) { 1404 ps->ps_refcnt++; 1405 *output_ps = ps; 1406 return (CRYPTO_SUCCESS); 1407 } 1408 mutex_exit(&cm->cm_lock); 1409 1410 /* find a hardware provider that supports session ops */ 1411 (void) kcf_get_hardware_provider_nomech(CRYPTO_OPS_OFFSET(session_ops), 1412 CRYPTO_SESSION_OFFSET(session_open), CHECK_RESTRICT_FALSE, 1413 pd, &real_provider); 1414 1415 if (real_provider != NULL) { 1416 ASSERT(real_provider == pd || 1417 pd->pd_prov_type == CRYPTO_LOGICAL_PROVIDER); 1418 /* open session to provider */ 1419 KCF_WRAP_SESSION_OPS_PARAMS(¶ms, KCF_OP_SESSION_OPEN, 1420 &provider_session_id, 0, CRYPTO_USER, NULL, 0, pd); 1421 rv = kcf_submit_request(real_provider, NULL, NULL, ¶ms, 1422 B_FALSE); 1423 if (rv != CRYPTO_SUCCESS) { 1424 mutex_enter(&cm->cm_lock); 1425 KCF_PROV_REFRELE(real_provider); 1426 return (rv); 1427 } 1428 } 1429 1430 /* allocate crypto_provider_session structure */ 1431 new_ps = kmem_zalloc(sizeof (crypto_provider_session_t), KM_SLEEP); 1432 1433 /* 1434 * Check if someone opened a session to the provider 1435 * while we dropped the lock. 1436 */ 1437 mutex_enter(&cm->cm_lock); 1438 for (ps = cm->cm_provider_session; ps != NULL; ps = ps->ps_next) { 1439 if (ps->ps_provider == pd) { 1440 mutex_exit(&cm->cm_lock); 1441 kmem_free(new_ps, sizeof (crypto_provider_session_t)); 1442 if (real_provider != NULL) { 1443 KCF_WRAP_SESSION_OPS_PARAMS(¶ms, 1444 KCF_OP_SESSION_CLOSE, NULL, 1445 provider_session_id, CRYPTO_USER, NULL, 0, 1446 pd); 1447 (void) kcf_submit_request(real_provider, NULL, 1448 NULL, ¶ms, B_FALSE); 1449 KCF_PROV_REFRELE(real_provider); 1450 } 1451 mutex_enter(&cm->cm_lock); 1452 goto again; 1453 1454 } 1455 } 1456 1457 /* increment refcnt and attach to crypto_minor structure */ 1458 new_ps->ps_session = provider_session_id; 1459 new_ps->ps_refcnt = 1; 1460 KCF_PROV_REFHOLD(pd); 1461 new_ps->ps_provider = pd; 1462 if (real_provider != NULL) { 1463 new_ps->ps_real_provider = real_provider; 1464 } 1465 new_ps->ps_next = cm->cm_provider_session; 1466 cm->cm_provider_session = new_ps; 1467 1468 *output_ps = new_ps; 1469 return (CRYPTO_SUCCESS); 1470 } 1471 1472 /* 1473 * Release a provider session. 1474 * If the reference count goes to zero, then close the session 1475 * to the provider. 1476 */ 1477 static void 1478 crypto_release_provider_session(crypto_minor_t *cm, 1479 crypto_provider_session_t *provider_session) 1480 { 1481 kcf_req_params_t params; 1482 crypto_provider_session_t *ps = NULL, **prev; 1483 1484 ASSERT(MUTEX_HELD(&cm->cm_lock)); 1485 1486 /* verify that provider_session is valid */ 1487 for (ps = cm->cm_provider_session, prev = &cm->cm_provider_session; 1488 ps != NULL; prev = &ps->ps_next, ps = ps->ps_next) { 1489 if (ps == provider_session) { 1490 break; 1491 } 1492 } 1493 1494 if (ps == NULL) 1495 return; 1496 1497 ps->ps_refcnt--; 1498 1499 if (ps->ps_refcnt > 0) 1500 return; 1501 1502 if (ps->ps_real_provider != NULL) { 1503 /* close session with provider */ 1504 KCF_WRAP_SESSION_OPS_PARAMS(¶ms, KCF_OP_SESSION_CLOSE, NULL, 1505 ps->ps_session, CRYPTO_USER, NULL, 0, ps->ps_provider); 1506 (void) kcf_submit_request(ps->ps_real_provider, 1507 NULL, NULL, ¶ms, B_FALSE); 1508 KCF_PROV_REFRELE(ps->ps_real_provider); 1509 } 1510 KCF_PROV_REFRELE(ps->ps_provider); 1511 *prev = ps->ps_next; 1512 kmem_free(ps, sizeof (*ps)); 1513 } 1514 1515 static int 1516 grow_session_table(crypto_minor_t *cm) 1517 { 1518 crypto_session_data_t **session_table; 1519 crypto_session_data_t **new; 1520 uint_t session_table_count; 1521 uint_t need; 1522 size_t current_allocation; 1523 size_t new_allocation; 1524 1525 ASSERT(MUTEX_HELD(&cm->cm_lock)); 1526 1527 session_table_count = cm->cm_session_table_count; 1528 session_table = cm->cm_session_table; 1529 need = session_table_count + CRYPTO_SESSION_CHUNK; 1530 1531 current_allocation = session_table_count * sizeof (void *); 1532 new_allocation = need * sizeof (void *); 1533 1534 mutex_enter(&curproc->p_lock); 1535 mutex_enter(&crypto_rctl_lock); 1536 1537 /* give back the current allocation */ 1538 if (cm->cm_projp != NULL) { 1539 cm->cm_projp->kpj_data.kpd_crypto_mem -= current_allocation; 1540 } 1541 1542 /* 1543 * Memory needed to grow the session table is checked 1544 * against the project.max-crypto-memory resource control. 1545 */ 1546 if (rctl_test(rc_project_crypto_mem, 1547 curproc->p_task->tk_proj->kpj_rctls, curproc, 1548 new_allocation, 0) & RCT_DENY) { 1549 /* restore the current allocation */ 1550 if (cm->cm_projp != NULL) { 1551 cm->cm_projp->kpj_data.kpd_crypto_mem += 1552 current_allocation; 1553 } 1554 mutex_exit(&crypto_rctl_lock); 1555 mutex_exit(&curproc->p_lock); 1556 return (CRYPTO_HOST_MEMORY); 1557 } 1558 curproc->p_task->tk_proj->kpj_data.kpd_crypto_mem += new_allocation; 1559 1560 /* the process changed projects */ 1561 if (curproc->p_task->tk_proj != cm->cm_projp) { 1562 if (cm->cm_projp != 0) 1563 project_rele(cm->cm_projp); 1564 (void) project_hold(curproc->p_task->tk_proj); 1565 cm->cm_projp = curproc->p_task->tk_proj; 1566 } 1567 mutex_exit(&crypto_rctl_lock); 1568 mutex_exit(&curproc->p_lock); 1569 1570 /* drop lock while we allocate memory */ 1571 mutex_exit(&cm->cm_lock); 1572 new = kmem_zalloc(new_allocation, KM_SLEEP); 1573 mutex_enter(&cm->cm_lock); 1574 1575 /* check if another thread increased the table size */ 1576 if (session_table_count != cm->cm_session_table_count) { 1577 kmem_free(new, new_allocation); 1578 return (CRYPTO_SUCCESS); 1579 } 1580 1581 bcopy(session_table, new, current_allocation); 1582 kmem_free(session_table, current_allocation); 1583 cm->cm_session_table = new; 1584 cm->cm_session_table_count += CRYPTO_SESSION_CHUNK; 1585 1586 return (CRYPTO_SUCCESS); 1587 } 1588 1589 /* 1590 * Find unused entry in session table and return it's index. 1591 * Initialize session table entry. 1592 */ 1593 /* ARGSUSED */ 1594 static int 1595 crypto_open_session(dev_t dev, uint_t flags, crypto_session_id_t *session_index, 1596 crypto_provider_id_t provider_id) 1597 { 1598 crypto_session_data_t **session_table; 1599 crypto_session_data_t *sp; 1600 crypto_minor_t *cm; 1601 uint_t session_table_count; 1602 uint_t i; 1603 int rv; 1604 crypto_provider_session_t *ps; 1605 kcf_provider_desc_t *provider; 1606 1607 if ((cm = crypto_hold_minor(getminor(dev))) == NULL) { 1608 cmn_err(CE_WARN, "crypto_open_session: failed holding minor"); 1609 return (CRYPTO_FAILED); 1610 } 1611 1612 /* initialize provider_array */ 1613 if (cm->cm_provider_array == NULL) { 1614 rv = crypto_get_provider_list(cm, NULL, NULL, DONT_RETURN_LIST); 1615 if (rv != 0) { 1616 crypto_release_minor(cm); 1617 return (rv); 1618 } 1619 } 1620 1621 mutex_enter(&cm->cm_lock); 1622 /* index must be less than count of providers */ 1623 if (provider_id >= cm->cm_provider_count) { 1624 mutex_exit(&cm->cm_lock); 1625 crypto_release_minor(cm); 1626 return (CRYPTO_INVALID_PROVIDER_ID); 1627 } 1628 ASSERT(cm->cm_provider_array != NULL); 1629 1630 rv = crypto_get_provider_session(cm, provider_id, &ps); 1631 if (rv != CRYPTO_SUCCESS) { 1632 mutex_exit(&cm->cm_lock); 1633 crypto_release_minor(cm); 1634 return (rv); 1635 } 1636 provider = cm->cm_provider_array[provider_id]; 1637 1638 again: 1639 session_table_count = cm->cm_session_table_count; 1640 session_table = cm->cm_session_table; 1641 1642 /* session handles start with 1 */ 1643 for (i = 1; i < session_table_count; i++) { 1644 if (session_table[i] == NULL) 1645 break; 1646 } 1647 1648 if (i == session_table_count || session_table_count == 0) { 1649 if ((rv = grow_session_table(cm)) != CRYPTO_SUCCESS) { 1650 crypto_release_provider_session(cm, ps); 1651 mutex_exit(&cm->cm_lock); 1652 crypto_release_minor(cm); 1653 return (rv); 1654 } 1655 goto again; 1656 } 1657 1658 sp = kmem_cache_alloc(crypto_session_cache, KM_SLEEP); 1659 sp->sd_flags = 0; 1660 sp->sd_find_init_cookie = NULL; 1661 sp->sd_digest_ctx = NULL; 1662 sp->sd_encr_ctx = NULL; 1663 sp->sd_decr_ctx = NULL; 1664 sp->sd_sign_ctx = NULL; 1665 sp->sd_verify_ctx = NULL; 1666 sp->sd_sign_recover_ctx = NULL; 1667 sp->sd_verify_recover_ctx = NULL; 1668 mutex_init(&sp->sd_lock, NULL, MUTEX_DRIVER, NULL); 1669 cv_init(&sp->sd_cv, NULL, CV_DRIVER, NULL); 1670 KCF_PROV_REFHOLD(provider); 1671 sp->sd_provider = provider; 1672 sp->sd_provider_session = ps; 1673 cm->cm_session_table[i] = sp; 1674 mutex_exit(&cm->cm_lock); 1675 crypto_release_minor(cm); 1676 *session_index = i; 1677 1678 return (CRYPTO_SUCCESS); 1679 } 1680 1681 /* 1682 * Close a session. 1683 */ 1684 static int 1685 crypto_close_session(dev_t dev, crypto_session_id_t session_index) 1686 { 1687 crypto_session_data_t **session_table; 1688 crypto_session_data_t *sp; 1689 crypto_minor_t *cm; 1690 1691 if ((cm = crypto_hold_minor(getminor(dev))) == NULL) { 1692 cmn_err(CE_WARN, "crypto_close_session: failed holding minor"); 1693 return (CRYPTO_FAILED); 1694 } 1695 1696 mutex_enter(&cm->cm_lock); 1697 session_table = cm->cm_session_table; 1698 1699 if ((session_index) == 0 || 1700 (session_index >= cm->cm_session_table_count)) { 1701 mutex_exit(&cm->cm_lock); 1702 crypto_release_minor(cm); 1703 return (CRYPTO_SESSION_HANDLE_INVALID); 1704 } 1705 1706 sp = session_table[session_index]; 1707 if (sp == NULL) { 1708 mutex_exit(&cm->cm_lock); 1709 crypto_release_minor(cm); 1710 return (CRYPTO_SESSION_HANDLE_INVALID); 1711 } 1712 /* 1713 * If session is in use, free it when the thread 1714 * finishes with the session. 1715 */ 1716 mutex_enter(&sp->sd_lock); 1717 if (sp->sd_flags & CRYPTO_SESSION_IS_BUSY) { 1718 sp->sd_flags |= CRYPTO_SESSION_IS_CLOSED; 1719 mutex_exit(&sp->sd_lock); 1720 } else { 1721 if (sp->sd_find_init_cookie != NULL) { 1722 (void) crypto_free_find_ctx(sp); 1723 } 1724 1725 crypto_release_provider_session(cm, sp->sd_provider_session); 1726 KCF_PROV_REFRELE(sp->sd_provider); 1727 CRYPTO_CANCEL_ALL_CTX(sp); 1728 mutex_destroy(&sp->sd_lock); 1729 cv_destroy(&sp->sd_cv); 1730 kmem_cache_free(crypto_session_cache, sp); 1731 session_table[session_index] = NULL; 1732 } 1733 1734 mutex_exit(&cm->cm_lock); 1735 crypto_release_minor(cm); 1736 1737 return (CRYPTO_SUCCESS); 1738 } 1739 1740 /* 1741 * This ioctl opens a session and returns the session ID in os_session. 1742 */ 1743 /* ARGSUSED */ 1744 static int 1745 open_session(dev_t dev, caddr_t arg, int mode, int *rval) 1746 { 1747 crypto_open_session_t open_session; 1748 crypto_session_id_t session; 1749 int rv; 1750 1751 if (copyin(arg, &open_session, sizeof (open_session)) != 0) 1752 return (EFAULT); 1753 1754 rv = crypto_open_session(dev, open_session.os_flags, 1755 &session, open_session.os_provider_id); 1756 if (rv != CRYPTO_SUCCESS) { 1757 open_session.os_return_value = rv; 1758 if (copyout(&open_session, arg, sizeof (open_session)) != 0) { 1759 return (EFAULT); 1760 } 1761 return (0); 1762 } 1763 1764 open_session.os_session = session; 1765 open_session.os_return_value = CRYPTO_SUCCESS; 1766 1767 if (copyout(&open_session, arg, sizeof (open_session)) != 0) { 1768 return (EFAULT); 1769 } 1770 return (0); 1771 } 1772 1773 /* 1774 * This ioctl closes a session. 1775 */ 1776 /* ARGSUSED */ 1777 static int 1778 close_session(dev_t dev, caddr_t arg, int mode, int *rval) 1779 { 1780 crypto_close_session_t close_session; 1781 int rv; 1782 1783 if (copyin(arg, &close_session, sizeof (close_session)) != 0) 1784 return (EFAULT); 1785 1786 rv = crypto_close_session(dev, close_session.cs_session); 1787 close_session.cs_return_value = rv; 1788 if (copyout(&close_session, arg, sizeof (close_session)) != 0) { 1789 return (EFAULT); 1790 } 1791 return (0); 1792 } 1793 1794 /* 1795 * Copy data model dependent mechanism structure into a kernel mechanism 1796 * structure. Allocate param storage if necessary. 1797 */ 1798 static boolean_t 1799 copyin_mech(int mode, crypto_mechanism_t *in_mech, 1800 crypto_mechanism_t *out_mech, size_t *out_rctl_bytes, size_t *out_carry, 1801 int *out_rv, int *out_error, kproject_t **projp) 1802 { 1803 STRUCT_DECL(crypto_mechanism, mech); 1804 caddr_t param; 1805 size_t param_len; 1806 size_t rctl_bytes = 0, carry = 0; 1807 int error = 0; 1808 int rv = 0; 1809 1810 STRUCT_INIT(mech, mode); 1811 bcopy(in_mech, STRUCT_BUF(mech), STRUCT_SIZE(mech)); 1812 param = STRUCT_FGETP(mech, cm_param); 1813 param_len = STRUCT_FGET(mech, cm_param_len); 1814 out_mech->cm_type = STRUCT_FGET(mech, cm_type); 1815 out_mech->cm_param = NULL; 1816 out_mech->cm_param_len = 0; 1817 if (param != NULL && param_len != 0) { 1818 if (param_len > crypto_max_buffer_len) { 1819 cmn_err(CE_NOTE, "copyin_mech: buffer greater than " 1820 "%ld bytes, pid = %d", crypto_max_buffer_len, 1821 curproc->p_pid); 1822 rv = CRYPTO_ARGUMENTS_BAD; 1823 goto out; 1824 } 1825 1826 /* 1827 * Most calls to copyin_mech() are followed by a call to 1828 * copyin_key(), resulting in two resource control checks. 1829 * As an optimization, the resource control check is not 1830 * made in this function if the check is for less than 1831 * CRYPTO_DEFERRED_LIMIT bytes. The number of bytes that 1832 * would be checked is passed as an argument to copyin_key() 1833 * where the check is made, and the bytes are charged against 1834 * the project.max-crypto-memory resource control. 1835 */ 1836 if ((param_len > CRYPTO_DEFERRED_LIMIT) || out_carry == NULL) { 1837 rv = crypto_buffer_check(param_len, projp); 1838 if (rv != CRYPTO_SUCCESS) { 1839 goto out; 1840 } 1841 rctl_bytes = param_len; 1842 } else { 1843 carry = param_len; 1844 } 1845 out_mech->cm_param = kmem_alloc(param_len, KM_SLEEP); 1846 if (copyin((char *)param, out_mech->cm_param, param_len) != 0) { 1847 kmem_free(out_mech->cm_param, param_len); 1848 out_mech->cm_param = NULL; 1849 error = EFAULT; 1850 goto out; 1851 } 1852 out_mech->cm_param_len = param_len; 1853 } 1854 out: 1855 *out_rctl_bytes = rctl_bytes; 1856 *out_rv = rv; 1857 *out_error = error; 1858 if (out_carry != NULL) 1859 *out_carry = carry; 1860 return ((rv | error) ? B_FALSE : B_TRUE); 1861 } 1862 1863 /* 1864 * Free key attributes when key type is CRYPTO_KEY_ATTR_LIST. 1865 * The crypto_key structure is not freed. 1866 */ 1867 static void 1868 crypto_free_key_attributes(crypto_key_t *key) 1869 { 1870 crypto_object_attribute_t *attrs; 1871 size_t len = 0; 1872 int i; 1873 1874 ASSERT(key->ck_format == CRYPTO_KEY_ATTR_LIST); 1875 if (key->ck_count == 0 || key->ck_attrs == NULL) 1876 return; 1877 1878 /* compute the size of the container */ 1879 len = key->ck_count * sizeof (crypto_object_attribute_t); 1880 1881 /* total up the size of all attributes in the container */ 1882 for (i = 0; i < key->ck_count; i++) { 1883 attrs = &key->ck_attrs[i]; 1884 if (attrs->oa_value_len != 0 && 1885 attrs->oa_value != NULL) { 1886 len += roundup(attrs->oa_value_len, sizeof (caddr_t)); 1887 } 1888 } 1889 1890 bzero(key->ck_attrs, len); 1891 kmem_free(key->ck_attrs, len); 1892 } 1893 1894 /* 1895 * Frees allocated storage in the key structure, but doesn't free 1896 * the key structure. 1897 */ 1898 static void 1899 free_crypto_key(crypto_key_t *key) 1900 { 1901 switch (key->ck_format) { 1902 case CRYPTO_KEY_RAW: { 1903 size_t len; 1904 1905 if (key->ck_length == 0 || key->ck_data == NULL) 1906 break; 1907 1908 len = CRYPTO_BITS2BYTES(key->ck_length); 1909 bzero(key->ck_data, len); 1910 kmem_free(key->ck_data, len); 1911 break; 1912 } 1913 1914 case CRYPTO_KEY_ATTR_LIST: 1915 crypto_free_key_attributes(key); 1916 break; 1917 1918 default: 1919 break; 1920 } 1921 } 1922 1923 /* 1924 * Copy in an array of crypto_object_attribute structures from user-space. 1925 * Kernel memory is allocated for the array and the value of each attribute 1926 * in the array. Since unprivileged users can specify the size of attributes, 1927 * the amount of memory needed is charged against the 1928 * project.max-crypto-memory resource control. 1929 * 1930 * Attribute values are copied in from user-space if copyin_value is set to 1931 * B_TRUE. This routine returns B_TRUE if the copyin was successful. 1932 */ 1933 static boolean_t 1934 copyin_attributes(int mode, uint_t count, caddr_t oc_attributes, 1935 crypto_object_attribute_t **k_attrs_out, size_t *k_attrs_size_out, 1936 caddr_t *u_attrs_out, int *out_rv, int *out_error, size_t *out_rctl_bytes, 1937 size_t carry, boolean_t copyin_value, kproject_t **projp) 1938 { 1939 STRUCT_DECL(crypto_object_attribute, oa); 1940 crypto_object_attribute_t *k_attrs = NULL; 1941 caddr_t attrs = NULL, ap, p, value; 1942 caddr_t k_attrs_buf; 1943 size_t k_attrs_len; 1944 size_t k_attrs_buf_len = 0; 1945 size_t k_attrs_total_len = 0; 1946 size_t tmp_len; 1947 size_t rctl_bytes = 0; 1948 size_t len = 0; 1949 size_t value_len; 1950 int error = 0; 1951 int rv = 0; 1952 int i; 1953 1954 STRUCT_INIT(oa, mode); 1955 1956 if (count == 0) { 1957 rv = CRYPTO_SUCCESS; 1958 goto out; 1959 } 1960 1961 if (count > CRYPTO_MAX_ATTRIBUTE_COUNT) { 1962 rv = CRYPTO_ARGUMENTS_BAD; 1963 goto out; 1964 } 1965 1966 /* compute size of crypto_object_attribute array */ 1967 len = count * STRUCT_SIZE(oa); 1968 1969 /* this allocation is not charged against the user's resource limit */ 1970 attrs = kmem_alloc(len, KM_SLEEP); 1971 if (copyin(oc_attributes, attrs, len) != 0) { 1972 error = EFAULT; 1973 goto out; 1974 } 1975 1976 /* figure out how much memory to allocate for all of the attributes */ 1977 ap = attrs; 1978 for (i = 0; i < count; i++) { 1979 bcopy(ap, STRUCT_BUF(oa), STRUCT_SIZE(oa)); 1980 tmp_len = roundup(STRUCT_FGET(oa, oa_value_len), 1981 sizeof (caddr_t)); 1982 if (tmp_len > crypto_max_buffer_len) { 1983 cmn_err(CE_NOTE, "copyin_attributes: buffer greater " 1984 "than %ld bytes, pid = %d", crypto_max_buffer_len, 1985 curproc->p_pid); 1986 rv = CRYPTO_ARGUMENTS_BAD; 1987 goto out; 1988 } 1989 if (STRUCT_FGETP(oa, oa_value) != NULL) 1990 k_attrs_buf_len += tmp_len; 1991 ap += STRUCT_SIZE(oa); 1992 } 1993 1994 k_attrs_len = count * sizeof (crypto_object_attribute_t); 1995 k_attrs_total_len = k_attrs_buf_len + k_attrs_len; 1996 if ((k_attrs_total_len + carry) != 0) { 1997 rv = crypto_buffer_check(k_attrs_total_len + carry, projp); 1998 if (rv != CRYPTO_SUCCESS) { 1999 goto out; 2000 } 2001 } 2002 rctl_bytes = k_attrs_total_len + carry; 2003 2004 /* one big allocation for everything */ 2005 k_attrs = kmem_alloc(k_attrs_total_len, KM_SLEEP); 2006 k_attrs_buf = (char *)k_attrs + k_attrs_len; 2007 2008 ap = attrs; 2009 p = k_attrs_buf; 2010 for (i = 0; i < count; i++) { 2011 bcopy(ap, STRUCT_BUF(oa), STRUCT_SIZE(oa)); 2012 k_attrs[i].oa_type = STRUCT_FGET(oa, oa_type); 2013 value = STRUCT_FGETP(oa, oa_value); 2014 value_len = STRUCT_FGET(oa, oa_value_len); 2015 if (value != NULL && value_len != 0 && copyin_value) { 2016 if (copyin(value, p, value_len) != 0) { 2017 kmem_free(k_attrs, k_attrs_total_len); 2018 k_attrs = NULL; 2019 error = EFAULT; 2020 goto out; 2021 } 2022 } 2023 2024 if (value != NULL) { 2025 k_attrs[i].oa_value = p; 2026 p += roundup(value_len, sizeof (caddr_t)); 2027 } else { 2028 k_attrs[i].oa_value = NULL; 2029 } 2030 k_attrs[i].oa_value_len = value_len; 2031 ap += STRUCT_SIZE(oa); 2032 } 2033 out: 2034 if (attrs != NULL) { 2035 /* 2036 * Free the array if there is a failure or the caller 2037 * doesn't want the array to be returned. 2038 */ 2039 if (error != 0 || rv != CRYPTO_SUCCESS || u_attrs_out == NULL) { 2040 kmem_free(attrs, len); 2041 attrs = NULL; 2042 } 2043 } 2044 2045 if (u_attrs_out != NULL) 2046 *u_attrs_out = attrs; 2047 if (k_attrs_size_out != NULL) 2048 *k_attrs_size_out = k_attrs_total_len; 2049 *k_attrs_out = k_attrs; 2050 *out_rctl_bytes = rctl_bytes; 2051 *out_rv = rv; 2052 *out_error = error; 2053 return ((rv | error) ? B_FALSE : B_TRUE); 2054 } 2055 2056 /* 2057 * Copy data model dependent raw key into a kernel key 2058 * structure. Checks key length or attribute lengths against 2059 * resource controls before allocating memory. Returns B_TRUE 2060 * if both error and rv are set to 0. 2061 */ 2062 static boolean_t 2063 copyin_key(int mode, crypto_key_t *in_key, crypto_key_t *out_key, 2064 size_t *out_rctl_bytes, int *out_rv, int *out_error, size_t carry, 2065 kproject_t **projp) 2066 { 2067 STRUCT_DECL(crypto_key, key); 2068 crypto_object_attribute_t *k_attrs = NULL; 2069 size_t key_bits; 2070 size_t key_bytes = 0; 2071 size_t rctl_bytes = 0; 2072 int count; 2073 int error = 0; 2074 int rv = CRYPTO_SUCCESS; 2075 2076 STRUCT_INIT(key, mode); 2077 bcopy(in_key, STRUCT_BUF(key), STRUCT_SIZE(key)); 2078 out_key->ck_format = STRUCT_FGET(key, ck_format); 2079 switch (out_key->ck_format) { 2080 case CRYPTO_KEY_RAW: 2081 key_bits = STRUCT_FGET(key, ck_length); 2082 if (key_bits != 0) { 2083 key_bytes = CRYPTO_BITS2BYTES(key_bits); 2084 if (key_bytes > crypto_max_buffer_len) { 2085 cmn_err(CE_NOTE, "copyin_key: buffer greater " 2086 "than %ld bytes, pid = %d", 2087 crypto_max_buffer_len, curproc->p_pid); 2088 rv = CRYPTO_ARGUMENTS_BAD; 2089 goto out; 2090 } 2091 2092 rv = crypto_buffer_check(key_bytes + carry, projp); 2093 if (rv != CRYPTO_SUCCESS) { 2094 goto out; 2095 } 2096 rctl_bytes = key_bytes + carry; 2097 2098 out_key->ck_data = kmem_alloc(key_bytes, KM_SLEEP); 2099 2100 if (copyin((char *)STRUCT_FGETP(key, ck_data), 2101 out_key->ck_data, key_bytes) != 0) { 2102 kmem_free(out_key->ck_data, key_bytes); 2103 out_key->ck_data = NULL; 2104 out_key->ck_length = 0; 2105 error = EFAULT; 2106 goto out; 2107 } 2108 } 2109 out_key->ck_length = key_bits; 2110 break; 2111 2112 case CRYPTO_KEY_ATTR_LIST: 2113 count = STRUCT_FGET(key, ck_count); 2114 2115 if (copyin_attributes(mode, count, 2116 (caddr_t)STRUCT_FGETP(key, ck_attrs), &k_attrs, NULL, NULL, 2117 &rv, &error, &rctl_bytes, carry, B_TRUE, projp)) { 2118 out_key->ck_count = count; 2119 out_key->ck_attrs = k_attrs; 2120 k_attrs = NULL; 2121 } else { 2122 out_key->ck_count = 0; 2123 out_key->ck_attrs = NULL; 2124 } 2125 break; 2126 2127 case CRYPTO_KEY_REFERENCE: 2128 out_key->ck_obj_id = STRUCT_FGET(key, ck_obj_id); 2129 break; 2130 2131 default: 2132 rv = CRYPTO_ARGUMENTS_BAD; 2133 } 2134 2135 out: 2136 *out_rctl_bytes = rctl_bytes; 2137 *out_rv = rv; 2138 *out_error = error; 2139 return ((rv | error) ? B_FALSE : B_TRUE); 2140 } 2141 2142 /* 2143 * This routine does two things: 2144 * 1. Given a crypto_minor structure and a session ID, it returns 2145 * a valid session pointer. 2146 * 2. It checks that the provider, to which the session has been opened, 2147 * has not been removed. 2148 */ 2149 static boolean_t 2150 get_session_ptr(crypto_session_id_t i, crypto_minor_t *cm, 2151 crypto_session_data_t **session_ptr, int *out_error, int *out_rv) 2152 { 2153 crypto_session_data_t *sp = NULL; 2154 int rv = CRYPTO_SESSION_HANDLE_INVALID; 2155 int error = 0; 2156 2157 mutex_enter(&cm->cm_lock); 2158 if ((i < cm->cm_session_table_count) && 2159 (cm->cm_session_table[i] != NULL)) { 2160 sp = cm->cm_session_table[i]; 2161 mutex_enter(&sp->sd_lock); 2162 mutex_exit(&cm->cm_lock); 2163 while (sp->sd_flags & CRYPTO_SESSION_IS_BUSY) { 2164 if (cv_wait_sig(&sp->sd_cv, &sp->sd_lock) == 0) { 2165 mutex_exit(&sp->sd_lock); 2166 sp = NULL; 2167 error = EINTR; 2168 goto out; 2169 } 2170 } 2171 2172 if (sp->sd_flags & CRYPTO_SESSION_IS_CLOSED) { 2173 mutex_exit(&sp->sd_lock); 2174 sp = NULL; 2175 goto out; 2176 } 2177 2178 if (KCF_IS_PROV_REMOVED(sp->sd_provider)) { 2179 mutex_exit(&sp->sd_lock); 2180 sp = NULL; 2181 rv = CRYPTO_DEVICE_ERROR; 2182 goto out; 2183 } 2184 2185 rv = CRYPTO_SUCCESS; 2186 sp->sd_flags |= CRYPTO_SESSION_IS_BUSY; 2187 mutex_exit(&sp->sd_lock); 2188 } else { 2189 mutex_exit(&cm->cm_lock); 2190 } 2191 out: 2192 *session_ptr = sp; 2193 *out_error = error; 2194 *out_rv = rv; 2195 return ((rv == CRYPTO_SUCCESS && error == 0) ? B_TRUE : B_FALSE); 2196 } 2197 2198 #define CRYPTO_SESSION_RELE(s) { \ 2199 mutex_enter(&((s)->sd_lock)); \ 2200 (s)->sd_flags &= ~CRYPTO_SESSION_IS_BUSY; \ 2201 cv_broadcast(&(s)->sd_cv); \ 2202 mutex_exit(&((s)->sd_lock)); \ 2203 } 2204 2205 /* ARGSUSED */ 2206 static int 2207 encrypt_init(dev_t dev, caddr_t arg, int mode, int *rval) 2208 { 2209 return (cipher_init(dev, arg, mode, crypto_encrypt_init_prov)); 2210 } 2211 2212 /* ARGSUSED */ 2213 static int 2214 decrypt_init(dev_t dev, caddr_t arg, int mode, int *rval) 2215 { 2216 return (cipher_init(dev, arg, mode, crypto_decrypt_init_prov)); 2217 } 2218 2219 /* 2220 * umech is a mechanism structure that has been copied from user address 2221 * space into kernel address space. Only one copyin has been done. 2222 * The mechanism parameter, if non-null, still points to user address space. 2223 * If the mechanism parameter contains pointers, they are pointers into 2224 * user address space. 2225 * 2226 * kmech is a umech with all pointers and structures in kernel address space. 2227 * 2228 * This routine calls the provider's entry point to copy a umech parameter 2229 * into kernel address space. Kernel memory is allocated by the provider. 2230 */ 2231 static int 2232 crypto_provider_copyin_mech_param(kcf_provider_desc_t *pd, 2233 crypto_mechanism_t *umech, crypto_mechanism_t *kmech, int mode, int *error) 2234 { 2235 crypto_mech_type_t provider_mech_type; 2236 kcf_ops_class_t class; 2237 int index; 2238 int rv; 2239 2240 /* get the provider's mech number */ 2241 class = KCF_MECH2CLASS(umech->cm_type); 2242 index = KCF_MECH2INDEX(umech->cm_type); 2243 provider_mech_type = pd->pd_map_mechnums[class][index]; 2244 2245 kmech->cm_param = NULL; 2246 kmech->cm_param_len = 0; 2247 kmech->cm_type = provider_mech_type; 2248 rv = KCF_PROV_COPYIN_MECH(pd, umech, kmech, error, mode); 2249 kmech->cm_type = umech->cm_type; 2250 2251 return (rv); 2252 } 2253 2254 /* 2255 * umech is a mechanism structure that has been copied from user address 2256 * space into kernel address space. Only one copyin has been done. 2257 * The mechanism parameter, if non-null, still points to user address space. 2258 * If the mechanism parameter contains pointers, they are pointers into 2259 * user address space. 2260 * 2261 * kmech is a umech with all pointers and structures in kernel address space. 2262 * 2263 * This routine calls the provider's entry point to copy a kmech parameter 2264 * into user address space using umech as a template containing 2265 * user address pointers. 2266 */ 2267 static int 2268 crypto_provider_copyout_mech_param(kcf_provider_desc_t *pd, 2269 crypto_mechanism_t *kmech, crypto_mechanism_t *umech, int mode, int *error) 2270 { 2271 crypto_mech_type_t provider_mech_type; 2272 kcf_ops_class_t class; 2273 int index; 2274 int rv; 2275 2276 /* get the provider's mech number */ 2277 class = KCF_MECH2CLASS(umech->cm_type); 2278 index = KCF_MECH2INDEX(umech->cm_type); 2279 provider_mech_type = pd->pd_map_mechnums[class][index]; 2280 2281 kmech->cm_type = provider_mech_type; 2282 rv = KCF_PROV_COPYOUT_MECH(pd, kmech, umech, error, mode); 2283 kmech->cm_type = umech->cm_type; 2284 2285 return (rv); 2286 } 2287 2288 /* 2289 * Call the provider's entry point to free kernel memory that has been 2290 * allocated for the mechanism's parameter. 2291 */ 2292 static void 2293 crypto_free_mech(kcf_provider_desc_t *pd, boolean_t allocated_by_crypto_module, 2294 crypto_mechanism_t *mech) 2295 { 2296 crypto_mech_type_t provider_mech_type; 2297 kcf_ops_class_t class; 2298 int index; 2299 2300 if (allocated_by_crypto_module) { 2301 if (mech->cm_param != NULL) 2302 kmem_free(mech->cm_param, mech->cm_param_len); 2303 } else { 2304 /* get the provider's mech number */ 2305 class = KCF_MECH2CLASS(mech->cm_type); 2306 index = KCF_MECH2INDEX(mech->cm_type); 2307 provider_mech_type = pd->pd_map_mechnums[class][index]; 2308 2309 if (mech->cm_param != NULL && mech->cm_param_len != 0) { 2310 mech->cm_type = provider_mech_type; 2311 (void) KCF_PROV_FREE_MECH(pd, mech); 2312 } 2313 } 2314 } 2315 2316 /* 2317 * ASSUMPTION: crypto_encrypt_init and crypto_decrypt_init 2318 * structures are identical except for field names. 2319 */ 2320 static int 2321 cipher_init(dev_t dev, caddr_t arg, int mode, int (*init)(crypto_provider_t, 2322 crypto_session_id_t, crypto_mechanism_t *, crypto_key_t *, 2323 crypto_ctx_template_t, crypto_context_t *, crypto_call_req_t *)) 2324 { 2325 STRUCT_DECL(crypto_encrypt_init, encrypt_init); 2326 kproject_t *mech_projp, *key_projp; 2327 kcf_provider_desc_t *real_provider = NULL; 2328 crypto_session_id_t session_id; 2329 crypto_mechanism_t mech; 2330 crypto_key_t key; 2331 crypto_minor_t *cm; 2332 crypto_session_data_t *sp; 2333 crypto_context_t cc; 2334 crypto_ctx_t **ctxpp; 2335 size_t mech_rctl_bytes = 0; 2336 size_t key_rctl_bytes = 0; 2337 size_t carry; 2338 int error = 0; 2339 int rv; 2340 boolean_t allocated_by_crypto_module = B_FALSE; 2341 crypto_func_group_t fg; 2342 2343 STRUCT_INIT(encrypt_init, mode); 2344 2345 if ((cm = crypto_hold_minor(getminor(dev))) == NULL) { 2346 cmn_err(CE_WARN, "cipher_init: failed holding minor"); 2347 return (ENXIO); 2348 } 2349 2350 if (copyin(arg, STRUCT_BUF(encrypt_init), 2351 STRUCT_SIZE(encrypt_init)) != 0) { 2352 crypto_release_minor(cm); 2353 return (EFAULT); 2354 } 2355 2356 mech.cm_param = NULL; 2357 bzero(&key, sizeof (crypto_key_t)); 2358 2359 session_id = STRUCT_FGET(encrypt_init, ei_session); 2360 2361 if (!get_session_ptr(session_id, cm, &sp, &error, &rv)) { 2362 goto release_minor; 2363 } 2364 2365 bcopy(STRUCT_FADDR(encrypt_init, ei_mech), &mech.cm_type, 2366 sizeof (crypto_mech_type_t)); 2367 2368 if (init == crypto_encrypt_init_prov) { 2369 fg = CRYPTO_FG_ENCRYPT; 2370 } else { 2371 fg = CRYPTO_FG_DECRYPT; 2372 } 2373 2374 if ((rv = kcf_get_hardware_provider(mech.cm_type, CRYPTO_MECH_INVALID, 2375 CHECK_RESTRICT_FALSE, sp->sd_provider, &real_provider, fg)) 2376 != CRYPTO_SUCCESS) { 2377 goto out; 2378 } 2379 2380 carry = 0; 2381 rv = crypto_provider_copyin_mech_param(real_provider, 2382 STRUCT_FADDR(encrypt_init, ei_mech), &mech, mode, &error); 2383 2384 if (rv == CRYPTO_NOT_SUPPORTED) { 2385 allocated_by_crypto_module = B_TRUE; 2386 if (!copyin_mech(mode, STRUCT_FADDR(encrypt_init, ei_mech), 2387 &mech, &mech_rctl_bytes, &carry, &rv, &error, 2388 &mech_projp)) { 2389 goto out; 2390 } 2391 } else { 2392 if (rv != CRYPTO_SUCCESS) 2393 goto out; 2394 } 2395 2396 if (!copyin_key(mode, STRUCT_FADDR(encrypt_init, ei_key), &key, 2397 &key_rctl_bytes, &rv, &error, carry, &key_projp)) { 2398 goto out; 2399 } 2400 2401 rv = (init)(real_provider, sp->sd_provider_session->ps_session, 2402 &mech, &key, NULL, &cc, NULL); 2403 2404 /* 2405 * Check if a context already exists. If so, it means it is being 2406 * abandoned. So, cancel it to avoid leaking it. 2407 */ 2408 ctxpp = (init == crypto_encrypt_init_prov) ? 2409 &sp->sd_encr_ctx : &sp->sd_decr_ctx; 2410 2411 if (*ctxpp != NULL) 2412 CRYPTO_CANCEL_CTX(ctxpp); 2413 *ctxpp = (rv == CRYPTO_SUCCESS) ? cc : NULL; 2414 2415 out: 2416 CRYPTO_SESSION_RELE(sp); 2417 2418 release_minor: 2419 mutex_enter(&crypto_rctl_lock); 2420 if (mech_rctl_bytes != 0) 2421 CRYPTO_DECREMENT_RCTL(mech_rctl_bytes, mech_projp); 2422 if (key_rctl_bytes != 0) 2423 CRYPTO_DECREMENT_RCTL(key_rctl_bytes, key_projp); 2424 mutex_exit(&crypto_rctl_lock); 2425 crypto_release_minor(cm); 2426 2427 if (real_provider != NULL) { 2428 crypto_free_mech(real_provider, 2429 allocated_by_crypto_module, &mech); 2430 KCF_PROV_REFRELE(real_provider); 2431 } 2432 2433 free_crypto_key(&key); 2434 2435 if (error != 0) 2436 /* XXX free context */ 2437 return (error); 2438 2439 STRUCT_FSET(encrypt_init, ei_return_value, rv); 2440 if (copyout(STRUCT_BUF(encrypt_init), arg, 2441 STRUCT_SIZE(encrypt_init)) != 0) { 2442 /* XXX free context */ 2443 return (EFAULT); 2444 } 2445 return (0); 2446 } 2447 2448 /* ARGSUSED */ 2449 static int 2450 encrypt(dev_t dev, caddr_t arg, int mode, int *rval) 2451 { 2452 return (cipher(dev, arg, mode, crypto_encrypt_single)); 2453 } 2454 2455 /* ARGSUSED */ 2456 static int 2457 decrypt(dev_t dev, caddr_t arg, int mode, int *rval) 2458 { 2459 return (cipher(dev, arg, mode, crypto_decrypt_single)); 2460 } 2461 2462 /* 2463 * ASSUMPTION: crypto_encrypt and crypto_decrypt structures 2464 * are identical except for field names. 2465 */ 2466 static int 2467 cipher(dev_t dev, caddr_t arg, int mode, 2468 int (*single)(crypto_context_t, crypto_data_t *, crypto_data_t *, 2469 crypto_call_req_t *)) 2470 { 2471 STRUCT_DECL(crypto_encrypt, encrypt); 2472 kproject_t *projp; 2473 crypto_session_id_t session_id; 2474 crypto_minor_t *cm; 2475 crypto_session_data_t *sp; 2476 crypto_ctx_t **ctxpp; 2477 crypto_data_t data, encr; 2478 size_t datalen, encrlen, need = 0; 2479 char *encrbuf; 2480 int error = 0; 2481 int rv; 2482 2483 STRUCT_INIT(encrypt, mode); 2484 2485 if ((cm = crypto_hold_minor(getminor(dev))) == NULL) { 2486 cmn_err(CE_WARN, "cipher: failed holding minor"); 2487 return (ENXIO); 2488 } 2489 2490 if (copyin(arg, STRUCT_BUF(encrypt), STRUCT_SIZE(encrypt)) != 0) { 2491 crypto_release_minor(cm); 2492 return (EFAULT); 2493 } 2494 2495 data.cd_raw.iov_base = NULL; 2496 encr.cd_raw.iov_base = NULL; 2497 2498 datalen = STRUCT_FGET(encrypt, ce_datalen); 2499 encrlen = STRUCT_FGET(encrypt, ce_encrlen); 2500 2501 /* 2502 * Don't allocate output buffer unless both buffer pointer and 2503 * buffer length are not NULL or 0 (length). 2504 */ 2505 encrbuf = STRUCT_FGETP(encrypt, ce_encrbuf); 2506 if (encrbuf == NULL || encrlen == 0) { 2507 encrlen = 0; 2508 } 2509 2510 if (datalen > crypto_max_buffer_len || 2511 encrlen > crypto_max_buffer_len) { 2512 cmn_err(CE_NOTE, "cipher: buffer greater than %ld bytes, " 2513 "pid = %d", crypto_max_buffer_len, curproc->p_pid); 2514 rv = CRYPTO_ARGUMENTS_BAD; 2515 goto release_minor; 2516 } 2517 2518 need = datalen + encrlen; 2519 if ((rv = crypto_buffer_check(need, &projp)) != CRYPTO_SUCCESS) { 2520 need = 0; 2521 goto release_minor; 2522 } 2523 2524 INIT_RAW_CRYPTO_DATA(data, datalen); 2525 data.cd_miscdata = NULL; 2526 2527 if (datalen != 0 && copyin(STRUCT_FGETP(encrypt, ce_databuf), 2528 data.cd_raw.iov_base, datalen) != 0) { 2529 error = EFAULT; 2530 goto release_minor; 2531 } 2532 2533 INIT_RAW_CRYPTO_DATA(encr, encrlen); 2534 2535 session_id = STRUCT_FGET(encrypt, ce_session); 2536 2537 if (!get_session_ptr(session_id, cm, &sp, &error, &rv)) { 2538 goto release_minor; 2539 } 2540 2541 ctxpp = (single == crypto_encrypt_single) ? 2542 &sp->sd_encr_ctx : &sp->sd_decr_ctx; 2543 2544 rv = (single)(*ctxpp, &data, &encr, NULL); 2545 if (KCF_CONTEXT_DONE(rv)) 2546 *ctxpp = NULL; 2547 2548 CRYPTO_SESSION_RELE(sp); 2549 2550 if (rv == CRYPTO_SUCCESS) { 2551 ASSERT(encr.cd_length <= encrlen); 2552 if (encr.cd_length != 0 && copyout(encr.cd_raw.iov_base, 2553 encrbuf, encr.cd_length) != 0) { 2554 error = EFAULT; 2555 goto release_minor; 2556 } 2557 STRUCT_FSET(encrypt, ce_encrlen, encr.cd_length); 2558 } 2559 2560 if (rv == CRYPTO_BUFFER_TOO_SMALL) { 2561 /* 2562 * The providers return CRYPTO_BUFFER_TOO_SMALL even for case 1 2563 * of section 11.2 of the pkcs11 spec. We catch it here and 2564 * provide the correct pkcs11 return value. 2565 */ 2566 if (STRUCT_FGETP(encrypt, ce_encrbuf) == NULL) 2567 rv = CRYPTO_SUCCESS; 2568 STRUCT_FSET(encrypt, ce_encrlen, encr.cd_length); 2569 } 2570 2571 release_minor: 2572 if (need != 0) { 2573 mutex_enter(&crypto_rctl_lock); 2574 CRYPTO_DECREMENT_RCTL(need, projp); 2575 mutex_exit(&crypto_rctl_lock); 2576 } 2577 crypto_release_minor(cm); 2578 2579 if (data.cd_raw.iov_base != NULL) 2580 kmem_free(data.cd_raw.iov_base, datalen); 2581 2582 if (encr.cd_raw.iov_base != NULL) 2583 kmem_free(encr.cd_raw.iov_base, encrlen); 2584 2585 if (error != 0) 2586 return (error); 2587 2588 STRUCT_FSET(encrypt, ce_return_value, rv); 2589 if (copyout(STRUCT_BUF(encrypt), arg, STRUCT_SIZE(encrypt)) != 0) { 2590 return (EFAULT); 2591 } 2592 return (0); 2593 } 2594 2595 /* ARGSUSED */ 2596 static int 2597 encrypt_update(dev_t dev, caddr_t arg, int mode, int *rval) 2598 { 2599 return (cipher_update(dev, arg, mode, crypto_encrypt_update)); 2600 } 2601 2602 /* ARGSUSED */ 2603 static int 2604 decrypt_update(dev_t dev, caddr_t arg, int mode, int *rval) 2605 { 2606 return (cipher_update(dev, arg, mode, crypto_decrypt_update)); 2607 } 2608 2609 /* 2610 * ASSUMPTION: crypto_encrypt_update and crypto_decrypt_update 2611 * structures are identical except for field names. 2612 */ 2613 static int 2614 cipher_update(dev_t dev, caddr_t arg, int mode, 2615 int (*update)(crypto_context_t, crypto_data_t *, crypto_data_t *, 2616 crypto_call_req_t *)) 2617 { 2618 STRUCT_DECL(crypto_encrypt_update, encrypt_update); 2619 kproject_t *projp; 2620 crypto_session_id_t session_id; 2621 crypto_minor_t *cm; 2622 crypto_session_data_t *sp; 2623 crypto_ctx_t **ctxpp; 2624 crypto_data_t data, encr; 2625 size_t datalen, encrlen, need = 0; 2626 char *encrbuf; 2627 int error = 0; 2628 int rv; 2629 2630 STRUCT_INIT(encrypt_update, mode); 2631 2632 if ((cm = crypto_hold_minor(getminor(dev))) == NULL) { 2633 cmn_err(CE_WARN, "cipher_update: failed holding minor"); 2634 return (ENXIO); 2635 } 2636 2637 if (copyin(arg, STRUCT_BUF(encrypt_update), 2638 STRUCT_SIZE(encrypt_update)) != 0) { 2639 crypto_release_minor(cm); 2640 return (EFAULT); 2641 } 2642 2643 data.cd_raw.iov_base = NULL; 2644 encr.cd_raw.iov_base = NULL; 2645 2646 datalen = STRUCT_FGET(encrypt_update, eu_datalen); 2647 encrlen = STRUCT_FGET(encrypt_update, eu_encrlen); 2648 2649 /* 2650 * Don't allocate output buffer unless both buffer pointer and 2651 * buffer length are not NULL or 0 (length). 2652 */ 2653 encrbuf = STRUCT_FGETP(encrypt_update, eu_encrbuf); 2654 if (encrbuf == NULL || encrlen == 0) { 2655 encrlen = 0; 2656 } 2657 2658 if (datalen > crypto_max_buffer_len || 2659 encrlen > crypto_max_buffer_len) { 2660 cmn_err(CE_NOTE, "cipher_update: buffer greater than %ld " 2661 "bytes, pid = %d", crypto_max_buffer_len, curproc->p_pid); 2662 rv = CRYPTO_ARGUMENTS_BAD; 2663 goto release_minor; 2664 } 2665 2666 need = datalen + encrlen; 2667 if ((rv = crypto_buffer_check(need, &projp)) != CRYPTO_SUCCESS) { 2668 need = 0; 2669 goto release_minor; 2670 } 2671 2672 INIT_RAW_CRYPTO_DATA(data, datalen); 2673 data.cd_miscdata = NULL; 2674 2675 if (datalen != 0 && copyin(STRUCT_FGETP(encrypt_update, eu_databuf), 2676 data.cd_raw.iov_base, datalen) != 0) { 2677 error = EFAULT; 2678 goto release_minor; 2679 } 2680 2681 INIT_RAW_CRYPTO_DATA(encr, encrlen); 2682 2683 session_id = STRUCT_FGET(encrypt_update, eu_session); 2684 2685 if (!get_session_ptr(session_id, cm, &sp, &error, &rv)) { 2686 goto release_minor; 2687 } 2688 2689 ctxpp = (update == crypto_encrypt_update) ? 2690 &sp->sd_encr_ctx : &sp->sd_decr_ctx; 2691 2692 rv = (update)(*ctxpp, &data, &encr, NULL); 2693 2694 if (rv == CRYPTO_SUCCESS || rv == CRYPTO_BUFFER_TOO_SMALL) { 2695 if (rv == CRYPTO_SUCCESS) { 2696 ASSERT(encr.cd_length <= encrlen); 2697 if (encr.cd_length != 0 && copyout(encr.cd_raw.iov_base, 2698 encrbuf, encr.cd_length) != 0) { 2699 error = EFAULT; 2700 goto out; 2701 } 2702 } else { 2703 /* 2704 * The providers return CRYPTO_BUFFER_TOO_SMALL even 2705 * for case 1 of section 11.2 of the pkcs11 spec. 2706 * We catch it here and provide the correct pkcs11 2707 * return value. 2708 */ 2709 if (STRUCT_FGETP(encrypt_update, eu_encrbuf) == NULL) 2710 rv = CRYPTO_SUCCESS; 2711 } 2712 STRUCT_FSET(encrypt_update, eu_encrlen, encr.cd_length); 2713 } else { 2714 CRYPTO_CANCEL_CTX(ctxpp); 2715 } 2716 out: 2717 CRYPTO_SESSION_RELE(sp); 2718 2719 release_minor: 2720 if (need != 0) { 2721 mutex_enter(&crypto_rctl_lock); 2722 CRYPTO_DECREMENT_RCTL(need, projp); 2723 mutex_exit(&crypto_rctl_lock); 2724 } 2725 crypto_release_minor(cm); 2726 2727 if (data.cd_raw.iov_base != NULL) 2728 kmem_free(data.cd_raw.iov_base, datalen); 2729 2730 if (encr.cd_raw.iov_base != NULL) 2731 kmem_free(encr.cd_raw.iov_base, encrlen); 2732 2733 if (error != 0) 2734 return (error); 2735 2736 STRUCT_FSET(encrypt_update, eu_return_value, rv); 2737 if (copyout(STRUCT_BUF(encrypt_update), arg, 2738 STRUCT_SIZE(encrypt_update)) != 0) { 2739 return (EFAULT); 2740 } 2741 return (0); 2742 } 2743 2744 /* ARGSUSED */ 2745 static int 2746 encrypt_final(dev_t dev, caddr_t arg, int mode, int *rval) 2747 { 2748 return (common_final(dev, arg, mode, crypto_encrypt_final)); 2749 } 2750 2751 /* ARGSUSED */ 2752 static int 2753 decrypt_final(dev_t dev, caddr_t arg, int mode, int *rval) 2754 { 2755 return (common_final(dev, arg, mode, crypto_decrypt_final)); 2756 } 2757 2758 /* 2759 * ASSUMPTION: crypto_encrypt_final, crypto_decrypt_final, crypto_sign_final, 2760 * and crypto_digest_final structures are identical except for field names. 2761 */ 2762 static int 2763 common_final(dev_t dev, caddr_t arg, int mode, 2764 int (*final)(crypto_context_t, crypto_data_t *, crypto_call_req_t *)) 2765 { 2766 STRUCT_DECL(crypto_encrypt_final, encrypt_final); 2767 kproject_t *projp; 2768 crypto_session_id_t session_id; 2769 crypto_minor_t *cm; 2770 crypto_session_data_t *sp; 2771 crypto_ctx_t **ctxpp; 2772 crypto_data_t encr; 2773 size_t encrlen, need = 0; 2774 char *encrbuf; 2775 int error = 0; 2776 int rv; 2777 2778 STRUCT_INIT(encrypt_final, mode); 2779 2780 if ((cm = crypto_hold_minor(getminor(dev))) == NULL) { 2781 cmn_err(CE_WARN, "common_final: failed holding minor"); 2782 return (ENXIO); 2783 } 2784 2785 if (copyin(arg, STRUCT_BUF(encrypt_final), 2786 STRUCT_SIZE(encrypt_final)) != 0) { 2787 crypto_release_minor(cm); 2788 return (EFAULT); 2789 } 2790 2791 encr.cd_format = CRYPTO_DATA_RAW; 2792 encr.cd_raw.iov_base = NULL; 2793 2794 encrlen = STRUCT_FGET(encrypt_final, ef_encrlen); 2795 2796 /* 2797 * Don't allocate output buffer unless both buffer pointer and 2798 * buffer length are not NULL or 0 (length). 2799 */ 2800 encrbuf = STRUCT_FGETP(encrypt_final, ef_encrbuf); 2801 if (encrbuf == NULL || encrlen == 0) { 2802 encrlen = 0; 2803 } 2804 2805 if (encrlen > crypto_max_buffer_len) { 2806 cmn_err(CE_NOTE, "common_final: buffer greater than %ld " 2807 "bytes, pid = %d", crypto_max_buffer_len, curproc->p_pid); 2808 rv = CRYPTO_ARGUMENTS_BAD; 2809 goto release_minor; 2810 } 2811 2812 if ((rv = crypto_buffer_check(encrlen, &projp)) != CRYPTO_SUCCESS) { 2813 goto release_minor; 2814 } 2815 need = encrlen; 2816 encr.cd_raw.iov_base = kmem_alloc(encrlen, KM_SLEEP); 2817 encr.cd_raw.iov_len = encrlen; 2818 2819 encr.cd_offset = 0; 2820 encr.cd_length = encrlen; 2821 2822 session_id = STRUCT_FGET(encrypt_final, ef_session); 2823 2824 if (!get_session_ptr(session_id, cm, &sp, &error, &rv)) { 2825 goto release_minor; 2826 } 2827 2828 ASSERT(final == crypto_encrypt_final || 2829 final == crypto_decrypt_final || final == crypto_sign_final || 2830 final == crypto_digest_final); 2831 2832 if (final == crypto_encrypt_final) { 2833 ctxpp = &sp->sd_encr_ctx; 2834 } else if (final == crypto_decrypt_final) { 2835 ctxpp = &sp->sd_decr_ctx; 2836 } else if (final == crypto_sign_final) { 2837 ctxpp = &sp->sd_sign_ctx; 2838 } else { 2839 ctxpp = &sp->sd_digest_ctx; 2840 } 2841 2842 rv = (final)(*ctxpp, &encr, NULL); 2843 if (KCF_CONTEXT_DONE(rv)) 2844 *ctxpp = NULL; 2845 2846 CRYPTO_SESSION_RELE(sp); 2847 2848 if (rv == CRYPTO_SUCCESS) { 2849 ASSERT(encr.cd_length <= encrlen); 2850 if (encr.cd_length != 0 && copyout(encr.cd_raw.iov_base, 2851 encrbuf, encr.cd_length) != 0) { 2852 error = EFAULT; 2853 goto release_minor; 2854 } 2855 STRUCT_FSET(encrypt_final, ef_encrlen, encr.cd_length); 2856 } 2857 2858 if (rv == CRYPTO_BUFFER_TOO_SMALL) { 2859 /* 2860 * The providers return CRYPTO_BUFFER_TOO_SMALL even for case 1 2861 * of section 11.2 of the pkcs11 spec. We catch it here and 2862 * provide the correct pkcs11 return value. 2863 */ 2864 if (STRUCT_FGETP(encrypt_final, ef_encrbuf) == NULL) 2865 rv = CRYPTO_SUCCESS; 2866 STRUCT_FSET(encrypt_final, ef_encrlen, encr.cd_length); 2867 } 2868 2869 release_minor: 2870 if (need != 0) { 2871 mutex_enter(&crypto_rctl_lock); 2872 CRYPTO_DECREMENT_RCTL(need, projp); 2873 mutex_exit(&crypto_rctl_lock); 2874 } 2875 crypto_release_minor(cm); 2876 2877 if (encr.cd_raw.iov_base != NULL) 2878 kmem_free(encr.cd_raw.iov_base, encrlen); 2879 2880 if (error != 0) 2881 return (error); 2882 2883 STRUCT_FSET(encrypt_final, ef_return_value, rv); 2884 if (copyout(STRUCT_BUF(encrypt_final), arg, 2885 STRUCT_SIZE(encrypt_final)) != 0) { 2886 return (EFAULT); 2887 } 2888 return (0); 2889 } 2890 2891 /* ARGSUSED */ 2892 static int 2893 digest_init(dev_t dev, caddr_t arg, int mode, int *rval) 2894 { 2895 STRUCT_DECL(crypto_digest_init, digest_init); 2896 kproject_t *mech_projp; 2897 kcf_provider_desc_t *real_provider = NULL; 2898 crypto_session_id_t session_id; 2899 crypto_mechanism_t mech; 2900 crypto_minor_t *cm; 2901 crypto_session_data_t *sp; 2902 crypto_context_t cc; 2903 size_t rctl_bytes = 0; 2904 int error = 0; 2905 int rv; 2906 2907 STRUCT_INIT(digest_init, mode); 2908 2909 if ((cm = crypto_hold_minor(getminor(dev))) == NULL) { 2910 cmn_err(CE_WARN, "digest_init: failed holding minor"); 2911 return (ENXIO); 2912 } 2913 2914 if (copyin(arg, STRUCT_BUF(digest_init), 2915 STRUCT_SIZE(digest_init)) != 0) { 2916 crypto_release_minor(cm); 2917 return (EFAULT); 2918 } 2919 2920 mech.cm_param = NULL; 2921 2922 session_id = STRUCT_FGET(digest_init, di_session); 2923 2924 if (!get_session_ptr(session_id, cm, &sp, &error, &rv)) { 2925 goto release_minor; 2926 } 2927 2928 if (!copyin_mech(mode, STRUCT_FADDR(digest_init, di_mech), &mech, 2929 &rctl_bytes, NULL, &rv, &error, &mech_projp)) { 2930 goto out; 2931 } 2932 2933 if ((rv = kcf_get_hardware_provider(mech.cm_type, CRYPTO_MECH_INVALID, 2934 CHECK_RESTRICT_FALSE, sp->sd_provider, &real_provider, 2935 CRYPTO_FG_DIGEST)) != CRYPTO_SUCCESS) { 2936 goto out; 2937 } 2938 2939 rv = crypto_digest_init_prov(real_provider, 2940 sp->sd_provider_session->ps_session, &mech, &cc, NULL); 2941 2942 /* 2943 * Check if a context already exists. If so, it means it is being 2944 * abandoned. So, cancel it to avoid leaking it. 2945 */ 2946 if (sp->sd_digest_ctx != NULL) 2947 CRYPTO_CANCEL_CTX(&sp->sd_digest_ctx); 2948 sp->sd_digest_ctx = (rv == CRYPTO_SUCCESS) ? cc : NULL; 2949 out: 2950 CRYPTO_SESSION_RELE(sp); 2951 2952 release_minor: 2953 if (rctl_bytes != 0) { 2954 mutex_enter(&crypto_rctl_lock); 2955 CRYPTO_DECREMENT_RCTL(rctl_bytes, mech_projp); 2956 mutex_exit(&crypto_rctl_lock); 2957 } 2958 crypto_release_minor(cm); 2959 2960 if (real_provider != NULL) 2961 KCF_PROV_REFRELE(real_provider); 2962 2963 if (mech.cm_param != NULL) 2964 kmem_free(mech.cm_param, mech.cm_param_len); 2965 2966 if (error != 0) 2967 return (error); 2968 2969 STRUCT_FSET(digest_init, di_return_value, rv); 2970 if (copyout(STRUCT_BUF(digest_init), arg, 2971 STRUCT_SIZE(digest_init)) != 0) { 2972 return (EFAULT); 2973 } 2974 return (0); 2975 } 2976 2977 /* ARGSUSED */ 2978 static int 2979 digest_update(dev_t dev, caddr_t arg, int mode, int *rval) 2980 { 2981 STRUCT_DECL(crypto_digest_update, digest_update); 2982 kproject_t *projp; 2983 crypto_session_id_t session_id; 2984 crypto_minor_t *cm; 2985 crypto_session_data_t *sp; 2986 crypto_data_t data; 2987 size_t datalen, need = 0; 2988 int error = 0; 2989 int rv; 2990 2991 STRUCT_INIT(digest_update, mode); 2992 2993 if ((cm = crypto_hold_minor(getminor(dev))) == NULL) { 2994 cmn_err(CE_WARN, "digest_update: failed holding minor"); 2995 return (ENXIO); 2996 } 2997 2998 if (copyin(arg, STRUCT_BUF(digest_update), 2999 STRUCT_SIZE(digest_update)) != 0) { 3000 crypto_release_minor(cm); 3001 return (EFAULT); 3002 } 3003 3004 data.cd_format = CRYPTO_DATA_RAW; 3005 data.cd_raw.iov_base = NULL; 3006 3007 datalen = STRUCT_FGET(digest_update, du_datalen); 3008 if (datalen > crypto_max_buffer_len) { 3009 cmn_err(CE_NOTE, "digest_update: buffer greater than %ld " 3010 "bytes, pid = %d", crypto_max_buffer_len, curproc->p_pid); 3011 rv = CRYPTO_ARGUMENTS_BAD; 3012 goto release_minor; 3013 } 3014 3015 if ((rv = crypto_buffer_check(datalen, &projp)) != CRYPTO_SUCCESS) { 3016 goto release_minor; 3017 } 3018 need = datalen; 3019 data.cd_raw.iov_base = kmem_alloc(datalen, KM_SLEEP); 3020 data.cd_raw.iov_len = datalen; 3021 3022 if (datalen != 0 && copyin(STRUCT_FGETP(digest_update, du_databuf), 3023 data.cd_raw.iov_base, datalen) != 0) { 3024 error = EFAULT; 3025 goto release_minor; 3026 } 3027 3028 data.cd_offset = 0; 3029 data.cd_length = datalen; 3030 3031 session_id = STRUCT_FGET(digest_update, du_session); 3032 3033 if (!get_session_ptr(session_id, cm, &sp, &error, &rv)) { 3034 goto release_minor; 3035 } 3036 3037 rv = crypto_digest_update(sp->sd_digest_ctx, &data, NULL); 3038 if (rv != CRYPTO_SUCCESS) 3039 CRYPTO_CANCEL_CTX(&sp->sd_digest_ctx); 3040 CRYPTO_SESSION_RELE(sp); 3041 3042 release_minor: 3043 if (need != 0) { 3044 mutex_enter(&crypto_rctl_lock); 3045 CRYPTO_DECREMENT_RCTL(need, projp); 3046 mutex_exit(&crypto_rctl_lock); 3047 } 3048 crypto_release_minor(cm); 3049 3050 if (data.cd_raw.iov_base != NULL) 3051 kmem_free(data.cd_raw.iov_base, datalen); 3052 3053 if (error != 0) 3054 return (error); 3055 3056 STRUCT_FSET(digest_update, du_return_value, rv); 3057 if (copyout(STRUCT_BUF(digest_update), arg, 3058 STRUCT_SIZE(digest_update)) != 0) { 3059 return (EFAULT); 3060 } 3061 return (0); 3062 } 3063 3064 /* ARGSUSED */ 3065 static int 3066 digest_key(dev_t dev, caddr_t arg, int mode, int *rval) 3067 { 3068 STRUCT_DECL(crypto_digest_key, digest_key); 3069 kproject_t *projp; 3070 crypto_session_id_t session_id; 3071 crypto_key_t key; 3072 crypto_minor_t *cm; 3073 crypto_session_data_t *sp; 3074 size_t rctl_bytes = 0; 3075 int error = 0; 3076 int rv; 3077 3078 STRUCT_INIT(digest_key, mode); 3079 3080 if ((cm = crypto_hold_minor(getminor(dev))) == NULL) { 3081 cmn_err(CE_WARN, "digest_key: failed holding minor"); 3082 return (ENXIO); 3083 } 3084 3085 if (copyin(arg, STRUCT_BUF(digest_key), STRUCT_SIZE(digest_key)) != 0) { 3086 crypto_release_minor(cm); 3087 return (EFAULT); 3088 } 3089 3090 bzero(&key, sizeof (crypto_key_t)); 3091 3092 session_id = STRUCT_FGET(digest_key, dk_session); 3093 3094 if (!get_session_ptr(session_id, cm, &sp, &error, &rv)) { 3095 goto release_minor; 3096 } 3097 3098 if (!copyin_key(mode, STRUCT_FADDR(digest_key, dk_key), &key, 3099 &rctl_bytes, &rv, &error, 0, &projp)) { 3100 goto out; 3101 } 3102 3103 rv = crypto_digest_key_prov(sp->sd_digest_ctx, &key, NULL); 3104 if (rv != CRYPTO_SUCCESS) 3105 CRYPTO_CANCEL_CTX(&sp->sd_digest_ctx); 3106 out: 3107 CRYPTO_SESSION_RELE(sp); 3108 3109 release_minor: 3110 if (rctl_bytes != 0) { 3111 mutex_enter(&crypto_rctl_lock); 3112 CRYPTO_DECREMENT_RCTL(rctl_bytes, projp); 3113 mutex_exit(&crypto_rctl_lock); 3114 } 3115 crypto_release_minor(cm); 3116 3117 free_crypto_key(&key); 3118 3119 if (error != 0) 3120 return (error); 3121 3122 STRUCT_FSET(digest_key, dk_return_value, rv); 3123 if (copyout(STRUCT_BUF(digest_key), arg, 3124 STRUCT_SIZE(digest_key)) != 0) { 3125 return (EFAULT); 3126 } 3127 return (0); 3128 } 3129 3130 /* ARGSUSED */ 3131 static int 3132 digest_final(dev_t dev, caddr_t arg, int mode, int *rval) 3133 { 3134 return (common_final(dev, arg, mode, crypto_digest_final)); 3135 } 3136 3137 /* ARGSUSED */ 3138 static int 3139 digest(dev_t dev, caddr_t arg, int mode, int *rval) 3140 { 3141 return (common_digest(dev, arg, mode, crypto_digest_single)); 3142 } 3143 3144 /* 3145 * ASSUMPTION: crypto_digest, crypto_sign, crypto_sign_recover, 3146 * and crypto_verify_recover are identical except for field names. 3147 */ 3148 static int 3149 common_digest(dev_t dev, caddr_t arg, int mode, 3150 int (*single)(crypto_context_t, crypto_data_t *, crypto_data_t *, 3151 crypto_call_req_t *)) 3152 { 3153 STRUCT_DECL(crypto_digest, crypto_digest); 3154 kproject_t *projp; 3155 crypto_session_id_t session_id; 3156 crypto_minor_t *cm; 3157 crypto_session_data_t *sp; 3158 crypto_data_t data, digest; 3159 crypto_ctx_t **ctxpp; 3160 size_t datalen, digestlen, need = 0; 3161 char *digestbuf; 3162 int error = 0; 3163 int rv; 3164 3165 STRUCT_INIT(crypto_digest, mode); 3166 3167 if ((cm = crypto_hold_minor(getminor(dev))) == NULL) { 3168 cmn_err(CE_WARN, "common_digest: failed holding minor"); 3169 return (ENXIO); 3170 } 3171 3172 if (copyin(arg, STRUCT_BUF(crypto_digest), 3173 STRUCT_SIZE(crypto_digest)) != 0) { 3174 crypto_release_minor(cm); 3175 return (EFAULT); 3176 } 3177 3178 data.cd_raw.iov_base = NULL; 3179 digest.cd_raw.iov_base = NULL; 3180 3181 datalen = STRUCT_FGET(crypto_digest, cd_datalen); 3182 digestlen = STRUCT_FGET(crypto_digest, cd_digestlen); 3183 3184 /* 3185 * Don't allocate output buffer unless both buffer pointer and 3186 * buffer length are not NULL or 0 (length). 3187 */ 3188 digestbuf = STRUCT_FGETP(crypto_digest, cd_digestbuf); 3189 if (digestbuf == NULL || digestlen == 0) { 3190 digestlen = 0; 3191 } 3192 3193 if (datalen > crypto_max_buffer_len || 3194 digestlen > crypto_max_buffer_len) { 3195 cmn_err(CE_NOTE, "common_digest: buffer greater than %ld " 3196 "bytes, pid = %d", crypto_max_buffer_len, curproc->p_pid); 3197 rv = CRYPTO_ARGUMENTS_BAD; 3198 goto release_minor; 3199 } 3200 3201 need = datalen + digestlen; 3202 if ((rv = crypto_buffer_check(need, &projp)) != CRYPTO_SUCCESS) { 3203 need = 0; 3204 goto release_minor; 3205 } 3206 3207 INIT_RAW_CRYPTO_DATA(data, datalen); 3208 3209 if (datalen != 0 && copyin(STRUCT_FGETP(crypto_digest, cd_databuf), 3210 data.cd_raw.iov_base, datalen) != 0) { 3211 error = EFAULT; 3212 goto release_minor; 3213 } 3214 3215 INIT_RAW_CRYPTO_DATA(digest, digestlen); 3216 3217 session_id = STRUCT_FGET(crypto_digest, cd_session); 3218 3219 if (!get_session_ptr(session_id, cm, &sp, &error, &rv)) { 3220 goto release_minor; 3221 } 3222 3223 ASSERT(single == crypto_digest_single || 3224 single == crypto_sign_single || 3225 single == crypto_verify_recover_single || 3226 single == crypto_sign_recover_single); 3227 3228 if (single == crypto_digest_single) { 3229 ctxpp = &sp->sd_digest_ctx; 3230 } else if (single == crypto_sign_single) { 3231 ctxpp = &sp->sd_sign_ctx; 3232 } else if (single == crypto_verify_recover_single) { 3233 ctxpp = &sp->sd_verify_recover_ctx; 3234 } else { 3235 ctxpp = &sp->sd_sign_recover_ctx; 3236 } 3237 rv = (single)(*ctxpp, &data, &digest, NULL); 3238 if (KCF_CONTEXT_DONE(rv)) 3239 *ctxpp = NULL; 3240 3241 CRYPTO_SESSION_RELE(sp); 3242 3243 if (rv == CRYPTO_SUCCESS) { 3244 ASSERT(digest.cd_length <= digestlen); 3245 if (digest.cd_length != 0 && copyout(digest.cd_raw.iov_base, 3246 digestbuf, digest.cd_length) != 0) { 3247 error = EFAULT; 3248 goto release_minor; 3249 } 3250 STRUCT_FSET(crypto_digest, cd_digestlen, digest.cd_length); 3251 } 3252 3253 if (rv == CRYPTO_BUFFER_TOO_SMALL) { 3254 /* 3255 * The providers return CRYPTO_BUFFER_TOO_SMALL even for case 1 3256 * of section 11.2 of the pkcs11 spec. We catch it here and 3257 * provide the correct pkcs11 return value. 3258 */ 3259 if (STRUCT_FGETP(crypto_digest, cd_digestbuf) == NULL) 3260 rv = CRYPTO_SUCCESS; 3261 STRUCT_FSET(crypto_digest, cd_digestlen, digest.cd_length); 3262 } 3263 3264 release_minor: 3265 if (need != 0) { 3266 mutex_enter(&crypto_rctl_lock); 3267 CRYPTO_DECREMENT_RCTL(need, projp); 3268 mutex_exit(&crypto_rctl_lock); 3269 } 3270 crypto_release_minor(cm); 3271 3272 if (data.cd_raw.iov_base != NULL) 3273 kmem_free(data.cd_raw.iov_base, datalen); 3274 3275 if (digest.cd_raw.iov_base != NULL) 3276 kmem_free(digest.cd_raw.iov_base, digestlen); 3277 3278 if (error != 0) 3279 return (error); 3280 3281 STRUCT_FSET(crypto_digest, cd_return_value, rv); 3282 if (copyout(STRUCT_BUF(crypto_digest), arg, 3283 STRUCT_SIZE(crypto_digest)) != 0) { 3284 return (EFAULT); 3285 } 3286 return (0); 3287 } 3288 3289 /* 3290 * A helper function that does what the name suggests. 3291 * Returns 0 on success and non-zero otherwise. 3292 * On failure, out_pin is set to 0. 3293 */ 3294 int 3295 get_pin_and_session_ptr(char *in_pin, char **out_pin, size_t pin_len, 3296 crypto_minor_t *cm, crypto_session_id_t sid, crypto_session_data_t **sp, 3297 int *rv, int *error) 3298 { 3299 char *tmp_pin = NULL; 3300 int tmp_error = 0, tmp_rv = 0; 3301 3302 if (pin_len > KCF_MAX_PIN_LEN) { 3303 tmp_rv = CRYPTO_PIN_LEN_RANGE; 3304 goto out; 3305 } 3306 tmp_pin = kmem_alloc(pin_len, KM_SLEEP); 3307 3308 if (pin_len != 0 && copyin(in_pin, tmp_pin, pin_len) != 0) { 3309 tmp_error = EFAULT; 3310 goto out; 3311 } 3312 3313 (void) get_session_ptr(sid, cm, sp, &tmp_error, &tmp_rv); 3314 out: 3315 *out_pin = tmp_pin; 3316 *rv = tmp_rv; 3317 *error = tmp_error; 3318 return (tmp_rv | tmp_error); 3319 } 3320 3321 /* ARGSUSED */ 3322 static int 3323 set_pin(dev_t dev, caddr_t arg, int mode, int *rval) 3324 { 3325 STRUCT_DECL(crypto_set_pin, set_pin); 3326 kcf_provider_desc_t *real_provider; 3327 kcf_req_params_t params; 3328 crypto_minor_t *cm; 3329 crypto_session_data_t *sp; 3330 char *old_pin = NULL; 3331 char *new_pin = NULL; 3332 size_t old_pin_len; 3333 size_t new_pin_len; 3334 int error = 0; 3335 int rv; 3336 3337 STRUCT_INIT(set_pin, mode); 3338 3339 if ((cm = crypto_hold_minor(getminor(dev))) == NULL) { 3340 cmn_err(CE_WARN, "set_pin: failed holding minor"); 3341 return (ENXIO); 3342 } 3343 3344 if (copyin(arg, STRUCT_BUF(set_pin), 3345 STRUCT_SIZE(set_pin)) != 0) { 3346 crypto_release_minor(cm); 3347 return (EFAULT); 3348 } 3349 3350 old_pin_len = STRUCT_FGET(set_pin, sp_old_len); 3351 3352 if (get_pin_and_session_ptr(STRUCT_FGETP(set_pin, sp_old_pin), 3353 &old_pin, old_pin_len, cm, STRUCT_FGET(set_pin, sp_session), 3354 &sp, &rv, &error) != 0) 3355 goto release_minor; 3356 3357 new_pin_len = STRUCT_FGET(set_pin, sp_new_len); 3358 if (new_pin_len > KCF_MAX_PIN_LEN) { 3359 rv = CRYPTO_PIN_LEN_RANGE; 3360 goto out; 3361 } 3362 new_pin = kmem_alloc(new_pin_len, KM_SLEEP); 3363 3364 if (new_pin_len != 0 && copyin(STRUCT_FGETP(set_pin, sp_new_pin), 3365 new_pin, new_pin_len) != 0) { 3366 error = EFAULT; 3367 goto out; 3368 } 3369 3370 if ((rv = kcf_get_hardware_provider_nomech( 3371 CRYPTO_OPS_OFFSET(provider_ops), CRYPTO_PROVIDER_OFFSET(set_pin), 3372 CHECK_RESTRICT_FALSE, sp->sd_provider, &real_provider)) 3373 != CRYPTO_SUCCESS) { 3374 goto out; 3375 } 3376 3377 KCF_WRAP_PROVMGMT_OPS_PARAMS(¶ms, KCF_OP_MGMT_SETPIN, 3378 sp->sd_provider_session->ps_session, old_pin, old_pin_len, 3379 new_pin, new_pin_len, NULL, NULL, real_provider); 3380 3381 rv = kcf_submit_request(real_provider, NULL, NULL, ¶ms, B_FALSE); 3382 KCF_PROV_REFRELE(real_provider); 3383 3384 out: 3385 CRYPTO_SESSION_RELE(sp); 3386 3387 release_minor: 3388 crypto_release_minor(cm); 3389 3390 if (old_pin != NULL) { 3391 bzero(old_pin, old_pin_len); 3392 kmem_free(old_pin, old_pin_len); 3393 } 3394 3395 if (new_pin != NULL) { 3396 bzero(new_pin, new_pin_len); 3397 kmem_free(new_pin, new_pin_len); 3398 } 3399 3400 if (error != 0) 3401 return (error); 3402 3403 STRUCT_FSET(set_pin, sp_return_value, rv); 3404 if (copyout(STRUCT_BUF(set_pin), arg, STRUCT_SIZE(set_pin)) != 0) { 3405 return (EFAULT); 3406 } 3407 return (0); 3408 } 3409 3410 /* ARGSUSED */ 3411 static int 3412 login(dev_t dev, caddr_t arg, int mode, int *rval) 3413 { 3414 STRUCT_DECL(crypto_login, login); 3415 kcf_provider_desc_t *real_provider; 3416 kcf_req_params_t params; 3417 crypto_minor_t *cm; 3418 crypto_session_data_t *sp; 3419 size_t pin_len; 3420 char *pin; 3421 uint_t user_type; 3422 int error = 0; 3423 int rv; 3424 3425 STRUCT_INIT(login, mode); 3426 3427 if ((cm = crypto_hold_minor(getminor(dev))) == NULL) { 3428 cmn_err(CE_WARN, "login: failed holding minor"); 3429 return (ENXIO); 3430 } 3431 3432 if (copyin(arg, STRUCT_BUF(login), STRUCT_SIZE(login)) != 0) { 3433 crypto_release_minor(cm); 3434 return (EFAULT); 3435 } 3436 3437 user_type = STRUCT_FGET(login, co_user_type); 3438 3439 pin_len = STRUCT_FGET(login, co_pin_len); 3440 3441 if (get_pin_and_session_ptr(STRUCT_FGETP(login, co_pin), 3442 &pin, pin_len, cm, STRUCT_FGET(login, co_session), 3443 &sp, &rv, &error) != 0) { 3444 if (rv == CRYPTO_PIN_LEN_RANGE) 3445 rv = CRYPTO_PIN_INCORRECT; 3446 goto release_minor; 3447 } 3448 3449 if ((rv = kcf_get_hardware_provider_nomech( 3450 CRYPTO_OPS_OFFSET(session_ops), 3451 CRYPTO_SESSION_OFFSET(session_login), 3452 CHECK_RESTRICT_FALSE, sp->sd_provider, &real_provider)) 3453 != CRYPTO_SUCCESS) { 3454 goto out; 3455 } 3456 3457 KCF_WRAP_SESSION_OPS_PARAMS(¶ms, KCF_OP_SESSION_LOGIN, NULL, 3458 sp->sd_provider_session->ps_session, user_type, pin, pin_len, 3459 real_provider); 3460 3461 rv = kcf_submit_request(real_provider, NULL, NULL, ¶ms, B_FALSE); 3462 KCF_PROV_REFRELE(real_provider); 3463 3464 out: 3465 CRYPTO_SESSION_RELE(sp); 3466 3467 release_minor: 3468 crypto_release_minor(cm); 3469 3470 if (pin != NULL) { 3471 bzero(pin, pin_len); 3472 kmem_free(pin, pin_len); 3473 } 3474 3475 if (error != 0) 3476 return (error); 3477 3478 STRUCT_FSET(login, co_return_value, rv); 3479 if (copyout(STRUCT_BUF(login), arg, STRUCT_SIZE(login)) != 0) { 3480 return (EFAULT); 3481 } 3482 return (0); 3483 } 3484 3485 /* ARGSUSED */ 3486 static int 3487 logout(dev_t dev, caddr_t arg, int mode, int *rval) 3488 { 3489 crypto_logout_t logout; 3490 kcf_provider_desc_t *real_provider; 3491 kcf_req_params_t params; 3492 crypto_minor_t *cm; 3493 crypto_session_data_t *sp; 3494 int error = 0; 3495 int rv; 3496 3497 if ((cm = crypto_hold_minor(getminor(dev))) == NULL) { 3498 cmn_err(CE_WARN, "logout: failed holding minor"); 3499 return (ENXIO); 3500 } 3501 3502 if (copyin(arg, &logout, sizeof (logout)) != 0) { 3503 crypto_release_minor(cm); 3504 return (EFAULT); 3505 } 3506 3507 if (!get_session_ptr(logout.cl_session, cm, &sp, &error, &rv)) { 3508 goto release_minor; 3509 } 3510 3511 if ((rv = kcf_get_hardware_provider_nomech( 3512 CRYPTO_OPS_OFFSET(session_ops), 3513 CRYPTO_SESSION_OFFSET(session_logout), CHECK_RESTRICT_FALSE, 3514 sp->sd_provider, &real_provider)) != CRYPTO_SUCCESS) { 3515 goto out; 3516 } 3517 3518 KCF_WRAP_SESSION_OPS_PARAMS(¶ms, KCF_OP_SESSION_LOGOUT, NULL, 3519 sp->sd_provider_session->ps_session, 0, NULL, 0, real_provider); 3520 rv = kcf_submit_request(real_provider, NULL, NULL, ¶ms, B_FALSE); 3521 KCF_PROV_REFRELE(real_provider); 3522 3523 out: 3524 CRYPTO_SESSION_RELE(sp); 3525 3526 release_minor: 3527 crypto_release_minor(cm); 3528 3529 if (error != 0) 3530 return (error); 3531 3532 logout.cl_return_value = rv; 3533 if (copyout(&logout, arg, sizeof (logout)) != 0) { 3534 return (EFAULT); 3535 } 3536 return (0); 3537 } 3538 3539 /* ARGSUSED */ 3540 static int 3541 sign_init(dev_t dev, caddr_t arg, int mode, int *rval) 3542 { 3543 return (sign_verify_init(dev, arg, mode, crypto_sign_init_prov)); 3544 } 3545 3546 /* ARGSUSED */ 3547 static int 3548 sign_recover_init(dev_t dev, caddr_t arg, int mode, int *rval) 3549 { 3550 return (sign_verify_init(dev, arg, mode, 3551 crypto_sign_recover_init_prov)); 3552 } 3553 3554 /* ARGSUSED */ 3555 static int 3556 verify_init(dev_t dev, caddr_t arg, int mode, int *rval) 3557 { 3558 return (sign_verify_init(dev, arg, mode, crypto_verify_init_prov)); 3559 } 3560 3561 /* ARGSUSED */ 3562 static int 3563 verify_recover_init(dev_t dev, caddr_t arg, int mode, int *rval) 3564 { 3565 return (sign_verify_init(dev, arg, mode, 3566 crypto_verify_recover_init_prov)); 3567 } 3568 3569 /* 3570 * ASSUMPTION: crypto_sign_init, crypto_verify_init, crypto_sign_recover_init, 3571 * and crypto_verify_recover_init structures are identical 3572 * except for field names. 3573 */ 3574 static int 3575 sign_verify_init(dev_t dev, caddr_t arg, int mode, 3576 int (*init)(crypto_provider_t, crypto_session_id_t, 3577 crypto_mechanism_t *, crypto_key_t *, crypto_ctx_template_t, 3578 crypto_context_t *, crypto_call_req_t *)) 3579 { 3580 STRUCT_DECL(crypto_sign_init, sign_init); 3581 kproject_t *mech_projp, *key_projp; 3582 kcf_provider_desc_t *real_provider = NULL; 3583 crypto_session_id_t session_id; 3584 crypto_mechanism_t mech; 3585 crypto_key_t key; 3586 crypto_minor_t *cm; 3587 crypto_session_data_t *sp; 3588 crypto_context_t cc; 3589 crypto_ctx_t **ctxpp; 3590 size_t mech_rctl_bytes = 0; 3591 size_t key_rctl_bytes = 0; 3592 size_t carry; 3593 int error = 0; 3594 int rv; 3595 boolean_t allocated_by_crypto_module = B_FALSE; 3596 crypto_func_group_t fg; 3597 3598 STRUCT_INIT(sign_init, mode); 3599 3600 if ((cm = crypto_hold_minor(getminor(dev))) == NULL) { 3601 cmn_err(CE_WARN, "sign_verify_init: failed holding minor"); 3602 return (ENXIO); 3603 } 3604 3605 if (copyin(arg, STRUCT_BUF(sign_init), STRUCT_SIZE(sign_init)) != 0) { 3606 crypto_release_minor(cm); 3607 return (EFAULT); 3608 } 3609 3610 mech.cm_param = NULL; 3611 bzero(&key, sizeof (key)); 3612 3613 session_id = STRUCT_FGET(sign_init, si_session); 3614 3615 if (!get_session_ptr(session_id, cm, &sp, &error, &rv)) { 3616 goto release_minor; 3617 } 3618 3619 bcopy(STRUCT_FADDR(sign_init, si_mech), &mech.cm_type, 3620 sizeof (crypto_mech_type_t)); 3621 3622 ASSERT(init == crypto_sign_init_prov || 3623 init == crypto_verify_init_prov || 3624 init == crypto_sign_recover_init_prov || 3625 init == crypto_verify_recover_init_prov); 3626 3627 if (init == crypto_sign_init_prov) { 3628 fg = CRYPTO_FG_SIGN; 3629 ctxpp = &sp->sd_sign_ctx; 3630 } else if (init == crypto_verify_init_prov) { 3631 fg = CRYPTO_FG_VERIFY; 3632 ctxpp = &sp->sd_verify_ctx; 3633 } else if (init == crypto_sign_recover_init_prov) { 3634 fg = CRYPTO_FG_SIGN_RECOVER; 3635 ctxpp = &sp->sd_sign_recover_ctx; 3636 } else { 3637 fg = CRYPTO_FG_VERIFY_RECOVER; 3638 ctxpp = &sp->sd_verify_recover_ctx; 3639 } 3640 3641 if ((rv = kcf_get_hardware_provider(mech.cm_type, CRYPTO_MECH_INVALID, 3642 CHECK_RESTRICT_FALSE, sp->sd_provider, &real_provider, fg)) 3643 != CRYPTO_SUCCESS) { 3644 goto out; 3645 } 3646 3647 carry = 0; 3648 rv = crypto_provider_copyin_mech_param(real_provider, 3649 STRUCT_FADDR(sign_init, si_mech), &mech, mode, &error); 3650 3651 if (rv == CRYPTO_NOT_SUPPORTED) { 3652 allocated_by_crypto_module = B_TRUE; 3653 if (!copyin_mech(mode, STRUCT_FADDR(sign_init, si_mech), 3654 &mech, &mech_rctl_bytes, &carry, &rv, &error, 3655 &mech_projp)) { 3656 goto out; 3657 } 3658 } else { 3659 if (rv != CRYPTO_SUCCESS) 3660 goto out; 3661 } 3662 3663 if (!copyin_key(mode, STRUCT_FADDR(sign_init, si_key), &key, 3664 &key_rctl_bytes, &rv, &error, carry, &key_projp)) { 3665 goto out; 3666 } 3667 3668 rv = (init)(real_provider, sp->sd_provider_session->ps_session, 3669 &mech, &key, NULL, &cc, NULL); 3670 3671 /* 3672 * Check if a context already exists. If so, it means it is being 3673 * abandoned. So, cancel it to avoid leaking it. 3674 */ 3675 if (*ctxpp != NULL) 3676 CRYPTO_CANCEL_CTX(ctxpp); 3677 *ctxpp = (rv == CRYPTO_SUCCESS) ? cc : NULL; 3678 3679 out: 3680 CRYPTO_SESSION_RELE(sp); 3681 3682 release_minor: 3683 mutex_enter(&crypto_rctl_lock); 3684 if (mech_rctl_bytes != 0) 3685 CRYPTO_DECREMENT_RCTL(mech_rctl_bytes, mech_projp); 3686 if (key_rctl_bytes != 0) 3687 CRYPTO_DECREMENT_RCTL(key_rctl_bytes, key_projp); 3688 mutex_exit(&crypto_rctl_lock); 3689 crypto_release_minor(cm); 3690 3691 if (real_provider != NULL) { 3692 crypto_free_mech(real_provider, 3693 allocated_by_crypto_module, &mech); 3694 KCF_PROV_REFRELE(real_provider); 3695 } 3696 3697 free_crypto_key(&key); 3698 3699 if (error != 0) 3700 return (error); 3701 3702 STRUCT_FSET(sign_init, si_return_value, rv); 3703 if (copyout(STRUCT_BUF(sign_init), arg, STRUCT_SIZE(sign_init)) != 0) { 3704 return (EFAULT); 3705 } 3706 return (0); 3707 } 3708 3709 /* ARGSUSED */ 3710 static int 3711 sign(dev_t dev, caddr_t arg, int mode, int *rval) 3712 { 3713 return (common_digest(dev, arg, mode, crypto_sign_single)); 3714 } 3715 3716 /* ARGSUSED */ 3717 static int 3718 sign_recover(dev_t dev, caddr_t arg, int mode, int *rval) 3719 { 3720 return (common_digest(dev, arg, mode, crypto_sign_recover_single)); 3721 } 3722 3723 /* ARGSUSED */ 3724 static int 3725 verify(dev_t dev, caddr_t arg, int mode, int *rval) 3726 { 3727 STRUCT_DECL(crypto_verify, verify); 3728 kproject_t *projp; 3729 crypto_session_id_t session_id; 3730 crypto_minor_t *cm; 3731 crypto_session_data_t *sp; 3732 crypto_data_t data, sign; 3733 size_t datalen, signlen, need = 0; 3734 int error = 0; 3735 int rv; 3736 3737 STRUCT_INIT(verify, mode); 3738 3739 if ((cm = crypto_hold_minor(getminor(dev))) == NULL) { 3740 cmn_err(CE_WARN, "verify: failed holding minor"); 3741 return (ENXIO); 3742 } 3743 3744 if (copyin(arg, STRUCT_BUF(verify), STRUCT_SIZE(verify)) != 0) { 3745 crypto_release_minor(cm); 3746 return (EFAULT); 3747 } 3748 3749 data.cd_raw.iov_base = NULL; 3750 sign.cd_raw.iov_base = NULL; 3751 3752 datalen = STRUCT_FGET(verify, cv_datalen); 3753 signlen = STRUCT_FGET(verify, cv_signlen); 3754 if (datalen > crypto_max_buffer_len || 3755 signlen > crypto_max_buffer_len) { 3756 cmn_err(CE_NOTE, "verify: buffer greater than %ld bytes, " 3757 "pid = %d", crypto_max_buffer_len, curproc->p_pid); 3758 rv = CRYPTO_ARGUMENTS_BAD; 3759 goto release_minor; 3760 } 3761 3762 need = datalen + signlen; 3763 if ((rv = crypto_buffer_check(need, &projp)) != CRYPTO_SUCCESS) { 3764 need = 0; 3765 goto release_minor; 3766 } 3767 3768 INIT_RAW_CRYPTO_DATA(data, datalen); 3769 INIT_RAW_CRYPTO_DATA(sign, signlen); 3770 3771 if (datalen != 0 && copyin(STRUCT_FGETP(verify, cv_databuf), 3772 data.cd_raw.iov_base, datalen) != 0) { 3773 error = EFAULT; 3774 goto release_minor; 3775 } 3776 3777 if (signlen != 0 && copyin(STRUCT_FGETP(verify, cv_signbuf), 3778 sign.cd_raw.iov_base, signlen) != 0) { 3779 error = EFAULT; 3780 goto release_minor; 3781 } 3782 session_id = STRUCT_FGET(verify, cv_session); 3783 3784 if (!get_session_ptr(session_id, cm, &sp, &error, &rv)) { 3785 goto release_minor; 3786 } 3787 3788 rv = crypto_verify_single(sp->sd_verify_ctx, &data, &sign, NULL); 3789 if (KCF_CONTEXT_DONE(rv)) 3790 sp->sd_verify_ctx = NULL; 3791 3792 CRYPTO_SESSION_RELE(sp); 3793 3794 release_minor: 3795 if (need != 0) { 3796 mutex_enter(&crypto_rctl_lock); 3797 CRYPTO_DECREMENT_RCTL(need, projp); 3798 mutex_exit(&crypto_rctl_lock); 3799 } 3800 crypto_release_minor(cm); 3801 3802 if (data.cd_raw.iov_base != NULL) 3803 kmem_free(data.cd_raw.iov_base, datalen); 3804 3805 if (sign.cd_raw.iov_base != NULL) 3806 kmem_free(sign.cd_raw.iov_base, signlen); 3807 3808 if (error != 0) 3809 return (error); 3810 3811 STRUCT_FSET(verify, cv_return_value, rv); 3812 if (copyout(STRUCT_BUF(verify), arg, STRUCT_SIZE(verify)) != 0) { 3813 return (EFAULT); 3814 } 3815 return (0); 3816 } 3817 3818 /* ARGSUSED */ 3819 static int 3820 verify_recover(dev_t dev, caddr_t arg, int mode, int *rval) 3821 { 3822 return (common_digest(dev, arg, mode, crypto_verify_recover_single)); 3823 } 3824 3825 /* ARGSUSED */ 3826 static int 3827 sign_update(dev_t dev, caddr_t arg, int mode, int *rval) 3828 { 3829 return (sign_verify_update(dev, arg, mode, crypto_sign_update)); 3830 } 3831 3832 /* ARGSUSED */ 3833 static int 3834 verify_update(dev_t dev, caddr_t arg, int mode, int *rval) 3835 { 3836 return (sign_verify_update(dev, arg, mode, crypto_verify_update)); 3837 } 3838 3839 /* 3840 * ASSUMPTION: crypto_sign_update and crypto_verify_update structures 3841 * are identical except for field names. 3842 */ 3843 static int 3844 sign_verify_update(dev_t dev, caddr_t arg, int mode, 3845 int (*update)(crypto_context_t, crypto_data_t *, crypto_call_req_t *)) 3846 { 3847 STRUCT_DECL(crypto_sign_update, sign_update); 3848 kproject_t *projp; 3849 crypto_session_id_t session_id; 3850 crypto_minor_t *cm; 3851 crypto_session_data_t *sp; 3852 crypto_ctx_t **ctxpp; 3853 crypto_data_t data; 3854 size_t datalen, need = 0; 3855 int error = 0; 3856 int rv; 3857 3858 STRUCT_INIT(sign_update, mode); 3859 3860 if ((cm = crypto_hold_minor(getminor(dev))) == NULL) { 3861 cmn_err(CE_WARN, "sign_verify_update: failed holding minor"); 3862 return (ENXIO); 3863 } 3864 3865 if (copyin(arg, STRUCT_BUF(sign_update), 3866 STRUCT_SIZE(sign_update)) != 0) { 3867 crypto_release_minor(cm); 3868 return (EFAULT); 3869 } 3870 3871 data.cd_raw.iov_base = NULL; 3872 3873 datalen = STRUCT_FGET(sign_update, su_datalen); 3874 if (datalen > crypto_max_buffer_len) { 3875 cmn_err(CE_NOTE, "sign_verify_update: buffer greater than %ld " 3876 "bytes, pid = %d", crypto_max_buffer_len, curproc->p_pid); 3877 rv = CRYPTO_ARGUMENTS_BAD; 3878 goto release_minor; 3879 } 3880 3881 if ((rv = crypto_buffer_check(datalen, &projp)) != CRYPTO_SUCCESS) { 3882 goto release_minor; 3883 } 3884 need = datalen; 3885 3886 INIT_RAW_CRYPTO_DATA(data, datalen); 3887 3888 if (datalen != 0 && copyin(STRUCT_FGETP(sign_update, su_databuf), 3889 data.cd_raw.iov_base, datalen) != 0) { 3890 error = EFAULT; 3891 goto release_minor; 3892 } 3893 3894 session_id = STRUCT_FGET(sign_update, su_session); 3895 3896 if (!get_session_ptr(session_id, cm, &sp, &error, &rv)) { 3897 goto release_minor; 3898 } 3899 3900 ctxpp = (update == crypto_sign_update) ? 3901 &sp->sd_sign_ctx : &sp->sd_verify_ctx; 3902 3903 rv = (update)(*ctxpp, &data, NULL); 3904 if (rv != CRYPTO_SUCCESS) 3905 CRYPTO_CANCEL_CTX(ctxpp); 3906 CRYPTO_SESSION_RELE(sp); 3907 3908 release_minor: 3909 if (need != 0) { 3910 mutex_enter(&crypto_rctl_lock); 3911 CRYPTO_DECREMENT_RCTL(need, projp); 3912 mutex_exit(&crypto_rctl_lock); 3913 } 3914 crypto_release_minor(cm); 3915 3916 if (data.cd_raw.iov_base != NULL) 3917 kmem_free(data.cd_raw.iov_base, datalen); 3918 3919 if (error != 0) 3920 return (error); 3921 3922 STRUCT_FSET(sign_update, su_return_value, rv); 3923 if (copyout(STRUCT_BUF(sign_update), arg, 3924 STRUCT_SIZE(sign_update)) != 0) { 3925 return (EFAULT); 3926 } 3927 return (0); 3928 } 3929 3930 /* ARGSUSED */ 3931 static int 3932 sign_final(dev_t dev, caddr_t arg, int mode, int *rval) 3933 { 3934 return (common_final(dev, arg, mode, crypto_sign_final)); 3935 } 3936 3937 /* 3938 * Can't use the common final because it does a copyout of 3939 * the final part. 3940 */ 3941 /* ARGSUSED */ 3942 static int 3943 verify_final(dev_t dev, caddr_t arg, int mode, int *rval) 3944 { 3945 STRUCT_DECL(crypto_verify_final, verify_final); 3946 kproject_t *projp; 3947 crypto_session_id_t session_id; 3948 crypto_minor_t *cm; 3949 crypto_session_data_t *sp; 3950 crypto_data_t sign; 3951 size_t signlen, need = 0; 3952 int error = 0; 3953 int rv; 3954 3955 STRUCT_INIT(verify_final, mode); 3956 3957 if ((cm = crypto_hold_minor(getminor(dev))) == NULL) { 3958 cmn_err(CE_WARN, "verify_final: failed holding minor"); 3959 return (ENXIO); 3960 } 3961 3962 if (copyin(arg, STRUCT_BUF(verify_final), 3963 STRUCT_SIZE(verify_final)) != 0) { 3964 crypto_release_minor(cm); 3965 return (EFAULT); 3966 } 3967 3968 sign.cd_raw.iov_base = NULL; 3969 3970 signlen = STRUCT_FGET(verify_final, vf_signlen); 3971 if (signlen > crypto_max_buffer_len) { 3972 cmn_err(CE_NOTE, "verify_final: buffer greater than %ld " 3973 "bytes, pid = %d", crypto_max_buffer_len, curproc->p_pid); 3974 rv = CRYPTO_ARGUMENTS_BAD; 3975 goto release_minor; 3976 } 3977 3978 if ((rv = crypto_buffer_check(signlen, &projp)) != CRYPTO_SUCCESS) { 3979 goto release_minor; 3980 } 3981 need = signlen; 3982 3983 INIT_RAW_CRYPTO_DATA(sign, signlen); 3984 3985 if (signlen != 0 && copyin(STRUCT_FGETP(verify_final, vf_signbuf), 3986 sign.cd_raw.iov_base, signlen) != 0) { 3987 error = EFAULT; 3988 goto release_minor; 3989 } 3990 3991 session_id = STRUCT_FGET(verify_final, vf_session); 3992 3993 if (!get_session_ptr(session_id, cm, &sp, &error, &rv)) { 3994 goto release_minor; 3995 } 3996 3997 rv = crypto_verify_final(sp->sd_verify_ctx, &sign, NULL); 3998 if (KCF_CONTEXT_DONE(rv)) 3999 sp->sd_verify_ctx = NULL; 4000 4001 CRYPTO_SESSION_RELE(sp); 4002 4003 release_minor: 4004 if (need != 0) { 4005 mutex_enter(&crypto_rctl_lock); 4006 CRYPTO_DECREMENT_RCTL(need, projp); 4007 mutex_exit(&crypto_rctl_lock); 4008 } 4009 crypto_release_minor(cm); 4010 4011 if (sign.cd_raw.iov_base != NULL) 4012 kmem_free(sign.cd_raw.iov_base, signlen); 4013 4014 if (error != 0) 4015 return (error); 4016 4017 STRUCT_FSET(verify_final, vf_return_value, rv); 4018 if (copyout(STRUCT_BUF(verify_final), arg, 4019 STRUCT_SIZE(verify_final)) != 0) { 4020 return (EFAULT); 4021 } 4022 return (0); 4023 } 4024 4025 /* ARGSUSED */ 4026 static int 4027 seed_random(dev_t dev, caddr_t arg, int mode, int *rval) 4028 { 4029 STRUCT_DECL(crypto_seed_random, seed_random); 4030 kproject_t *projp; 4031 kcf_provider_desc_t *real_provider = NULL; 4032 kcf_req_params_t params; 4033 crypto_session_id_t session_id; 4034 crypto_minor_t *cm; 4035 crypto_session_data_t *sp; 4036 uchar_t *seed_buffer = NULL; 4037 size_t seed_len; 4038 size_t need = 0; 4039 int error = 0; 4040 int rv; 4041 4042 STRUCT_INIT(seed_random, mode); 4043 4044 if ((cm = crypto_hold_minor(getminor(dev))) == NULL) { 4045 cmn_err(CE_WARN, "seed_random: failed holding minor"); 4046 return (ENXIO); 4047 } 4048 4049 if (copyin(arg, STRUCT_BUF(seed_random), 4050 STRUCT_SIZE(seed_random)) != 0) { 4051 crypto_release_minor(cm); 4052 return (EFAULT); 4053 } 4054 4055 seed_len = STRUCT_FGET(seed_random, sr_seedlen); 4056 if (seed_len > crypto_max_buffer_len) { 4057 cmn_err(CE_NOTE, "seed_random: buffer greater than %ld " 4058 "bytes, pid = %d", crypto_max_buffer_len, curproc->p_pid); 4059 rv = CRYPTO_ARGUMENTS_BAD; 4060 goto release_minor; 4061 } 4062 4063 if ((rv = crypto_buffer_check(seed_len, &projp)) != CRYPTO_SUCCESS) { 4064 goto release_minor; 4065 } 4066 need = seed_len; 4067 seed_buffer = kmem_alloc(seed_len, KM_SLEEP); 4068 4069 if (seed_len != 0 && copyin(STRUCT_FGETP(seed_random, sr_seedbuf), 4070 seed_buffer, seed_len) != 0) { 4071 error = EFAULT; 4072 goto release_minor; 4073 } 4074 4075 session_id = STRUCT_FGET(seed_random, sr_session); 4076 4077 if (!get_session_ptr(session_id, cm, &sp, &error, &rv)) { 4078 goto release_minor; 4079 } 4080 4081 if ((rv = kcf_get_hardware_provider_nomech( 4082 CRYPTO_OPS_OFFSET(random_ops), CRYPTO_RANDOM_OFFSET(seed_random), 4083 CHECK_RESTRICT_FALSE, sp->sd_provider, &real_provider)) 4084 != CRYPTO_SUCCESS) { 4085 goto out; 4086 } 4087 4088 KCF_WRAP_RANDOM_OPS_PARAMS(¶ms, KCF_OP_RANDOM_SEED, 4089 sp->sd_provider_session->ps_session, seed_buffer, seed_len, 0, 4090 CRYPTO_SEED_NOW); 4091 4092 rv = kcf_submit_request(real_provider, NULL, NULL, ¶ms, B_FALSE); 4093 4094 out: 4095 CRYPTO_SESSION_RELE(sp); 4096 4097 release_minor: 4098 if (need != 0) { 4099 mutex_enter(&crypto_rctl_lock); 4100 CRYPTO_DECREMENT_RCTL(need, projp); 4101 mutex_exit(&crypto_rctl_lock); 4102 } 4103 crypto_release_minor(cm); 4104 4105 if (real_provider != NULL) 4106 KCF_PROV_REFRELE(real_provider); 4107 4108 if (seed_buffer != NULL) 4109 kmem_free(seed_buffer, seed_len); 4110 4111 if (error != 0) 4112 return (error); 4113 4114 STRUCT_FSET(seed_random, sr_return_value, rv); 4115 if (copyout(STRUCT_BUF(seed_random), arg, 4116 STRUCT_SIZE(seed_random)) != 0) { 4117 return (EFAULT); 4118 } 4119 return (0); 4120 } 4121 4122 /* ARGSUSED */ 4123 static int 4124 generate_random(dev_t dev, caddr_t arg, int mode, int *rval) 4125 { 4126 STRUCT_DECL(crypto_generate_random, generate_random); 4127 kproject_t *projp; 4128 kcf_provider_desc_t *real_provider = NULL; 4129 kcf_req_params_t params; 4130 crypto_session_id_t session_id; 4131 crypto_minor_t *cm; 4132 crypto_session_data_t *sp; 4133 uchar_t *buffer = NULL; 4134 size_t len; 4135 size_t need = 0; 4136 int error = 0; 4137 int rv; 4138 4139 STRUCT_INIT(generate_random, mode); 4140 4141 if ((cm = crypto_hold_minor(getminor(dev))) == NULL) { 4142 cmn_err(CE_WARN, "generate_random: failed holding minor"); 4143 return (ENXIO); 4144 } 4145 4146 if (copyin(arg, STRUCT_BUF(generate_random), 4147 STRUCT_SIZE(generate_random)) != 0) { 4148 crypto_release_minor(cm); 4149 return (EFAULT); 4150 } 4151 4152 len = STRUCT_FGET(generate_random, gr_buflen); 4153 if (len > crypto_max_buffer_len) { 4154 cmn_err(CE_NOTE, "generate_random: buffer greater than %ld " 4155 "bytes, pid = %d", crypto_max_buffer_len, curproc->p_pid); 4156 rv = CRYPTO_ARGUMENTS_BAD; 4157 goto release_minor; 4158 } 4159 4160 if ((rv = crypto_buffer_check(len, &projp)) != CRYPTO_SUCCESS) { 4161 goto release_minor; 4162 } 4163 need = len; 4164 buffer = kmem_alloc(len, KM_SLEEP); 4165 4166 session_id = STRUCT_FGET(generate_random, gr_session); 4167 4168 if (!get_session_ptr(session_id, cm, &sp, &error, &rv)) { 4169 goto release_minor; 4170 } 4171 4172 if ((rv = kcf_get_hardware_provider_nomech( 4173 CRYPTO_OPS_OFFSET(random_ops), 4174 CRYPTO_RANDOM_OFFSET(generate_random), CHECK_RESTRICT_FALSE, 4175 sp->sd_provider, &real_provider)) != CRYPTO_SUCCESS) { 4176 goto out; 4177 } 4178 4179 KCF_WRAP_RANDOM_OPS_PARAMS(¶ms, KCF_OP_RANDOM_GENERATE, 4180 sp->sd_provider_session->ps_session, buffer, len, 0, 0); 4181 4182 rv = kcf_submit_request(real_provider, NULL, NULL, ¶ms, B_FALSE); 4183 4184 out: 4185 CRYPTO_SESSION_RELE(sp); 4186 4187 if (rv == CRYPTO_SUCCESS) { 4188 if (len != 0 && copyout(buffer, 4189 STRUCT_FGETP(generate_random, gr_buf), len) != 0) { 4190 error = EFAULT; 4191 } 4192 } 4193 4194 release_minor: 4195 if (need != 0) { 4196 mutex_enter(&crypto_rctl_lock); 4197 CRYPTO_DECREMENT_RCTL(need, projp); 4198 mutex_exit(&crypto_rctl_lock); 4199 } 4200 crypto_release_minor(cm); 4201 4202 if (real_provider != NULL) 4203 KCF_PROV_REFRELE(real_provider); 4204 4205 if (buffer != NULL) { 4206 /* random numbers are often used to create keys */ 4207 bzero(buffer, len); 4208 kmem_free(buffer, len); 4209 } 4210 4211 if (error != 0) 4212 return (error); 4213 4214 STRUCT_FSET(generate_random, gr_return_value, rv); 4215 if (copyout(STRUCT_BUF(generate_random), arg, 4216 STRUCT_SIZE(generate_random)) != 0) { 4217 return (EFAULT); 4218 } 4219 return (0); 4220 } 4221 4222 /* 4223 * Copyout a kernel array of attributes to user space. 4224 * u_attrs is the corresponding user space array containing 4225 * user space pointers necessary for the copyout. 4226 */ 4227 /* ARGSUSED */ 4228 static int 4229 copyout_attributes(int mode, caddr_t out, uint_t count, 4230 crypto_object_attribute_t *k_attrs, caddr_t u_attrs) 4231 { 4232 STRUCT_DECL(crypto_object_attribute, oa); 4233 caddr_t p, valuep; 4234 size_t value_len; 4235 size_t len; 4236 int i; 4237 int error = 0; 4238 4239 if (count == 0) 4240 return (0); 4241 4242 STRUCT_INIT(oa, mode); 4243 4244 len = count * STRUCT_SIZE(oa); 4245 4246 ASSERT(u_attrs != NULL); 4247 p = u_attrs; 4248 for (i = 0; i < count; i++) { 4249 /* can this bcopy be eliminated? */ 4250 bcopy(p, STRUCT_BUF(oa), STRUCT_SIZE(oa)); 4251 value_len = k_attrs[i].oa_value_len; 4252 STRUCT_FSET(oa, oa_type, k_attrs[i].oa_type); 4253 STRUCT_FSET(oa, oa_value_len, value_len); 4254 valuep = STRUCT_FGETP(oa, oa_value); 4255 if (valuep != NULL && value_len != -1) { 4256 if (copyout(k_attrs[i].oa_value, 4257 valuep, value_len) != 0) { 4258 error = EFAULT; 4259 goto out; 4260 } 4261 } 4262 bcopy(STRUCT_BUF(oa), p, STRUCT_SIZE(oa)); 4263 p += STRUCT_SIZE(oa); 4264 } 4265 if (copyout(u_attrs, out, len)) { 4266 error = EFAULT; 4267 } 4268 out: 4269 return (error); 4270 } 4271 4272 4273 /* ARGSUSED */ 4274 static int 4275 object_create(dev_t dev, caddr_t arg, int mode, int *rval) 4276 { 4277 STRUCT_DECL(crypto_object_create, object_create); 4278 kproject_t *projp; 4279 kcf_provider_desc_t *real_provider = NULL; 4280 kcf_req_params_t params; 4281 crypto_object_attribute_t *k_attrs = NULL; 4282 crypto_session_id_t session_id; 4283 crypto_minor_t *cm; 4284 crypto_session_data_t *sp = NULL; 4285 crypto_object_id_t object_handle; 4286 caddr_t oc_attributes; 4287 size_t k_attrs_size; 4288 size_t rctl_bytes = 0; 4289 int error = 0; 4290 int rv; 4291 uint_t count; 4292 4293 STRUCT_INIT(object_create, mode); 4294 4295 if ((cm = crypto_hold_minor(getminor(dev))) == NULL) { 4296 cmn_err(CE_WARN, "object_create: failed holding minor"); 4297 return (ENXIO); 4298 } 4299 4300 if (copyin(arg, STRUCT_BUF(object_create), 4301 STRUCT_SIZE(object_create)) != 0) { 4302 crypto_release_minor(cm); 4303 return (EFAULT); 4304 } 4305 4306 count = STRUCT_FGET(object_create, oc_count); 4307 oc_attributes = STRUCT_FGETP(object_create, oc_attributes); 4308 if (!copyin_attributes(mode, count, oc_attributes, &k_attrs, 4309 &k_attrs_size, NULL, &rv, &error, &rctl_bytes, 0, B_TRUE, &projp)) { 4310 goto release_minor; 4311 } 4312 4313 session_id = STRUCT_FGET(object_create, oc_session); 4314 4315 if (!get_session_ptr(session_id, cm, &sp, &error, &rv)) { 4316 goto release_minor; 4317 } 4318 4319 if ((rv = kcf_get_hardware_provider_nomech( 4320 CRYPTO_OPS_OFFSET(object_ops), 4321 CRYPTO_OBJECT_OFFSET(object_create), 4322 CHECK_RESTRICT_FALSE, sp->sd_provider, &real_provider)) 4323 != CRYPTO_SUCCESS) { 4324 goto release_minor; 4325 } 4326 4327 KCF_WRAP_OBJECT_OPS_PARAMS(¶ms, KCF_OP_OBJECT_CREATE, 4328 sp->sd_provider_session->ps_session, 0, k_attrs, count, 4329 &object_handle, 0, NULL, NULL, 0, NULL); 4330 4331 rv = kcf_submit_request(real_provider, NULL, NULL, ¶ms, B_FALSE); 4332 4333 if (rv == CRYPTO_SUCCESS) 4334 STRUCT_FSET(object_create, oc_handle, object_handle); 4335 4336 release_minor: 4337 if (rctl_bytes != 0) { 4338 mutex_enter(&crypto_rctl_lock); 4339 CRYPTO_DECREMENT_RCTL(rctl_bytes, projp); 4340 mutex_exit(&crypto_rctl_lock); 4341 } 4342 4343 if (k_attrs != NULL) 4344 kmem_free(k_attrs, k_attrs_size); 4345 4346 if (error != 0) 4347 goto out; 4348 4349 STRUCT_FSET(object_create, oc_return_value, rv); 4350 if (copyout(STRUCT_BUF(object_create), arg, 4351 STRUCT_SIZE(object_create)) != 0) { 4352 if (rv == CRYPTO_SUCCESS) { 4353 KCF_WRAP_OBJECT_OPS_PARAMS(¶ms, 4354 KCF_OP_OBJECT_DESTROY, 4355 sp->sd_provider_session->ps_session, object_handle, 4356 NULL, 0, NULL, 0, NULL, NULL, 0, NULL); 4357 4358 (void) kcf_submit_request(real_provider, NULL, 4359 NULL, ¶ms, B_FALSE); 4360 4361 error = EFAULT; 4362 } 4363 } 4364 out: 4365 if (sp != NULL) 4366 CRYPTO_SESSION_RELE(sp); 4367 crypto_release_minor(cm); 4368 if (real_provider != NULL) 4369 KCF_PROV_REFRELE(real_provider); 4370 return (error); 4371 } 4372 4373 /* ARGSUSED */ 4374 static int 4375 object_copy(dev_t dev, caddr_t arg, int mode, int *rval) 4376 { 4377 STRUCT_DECL(crypto_object_copy, object_copy); 4378 kproject_t *projp; 4379 kcf_provider_desc_t *real_provider = NULL; 4380 kcf_req_params_t params; 4381 crypto_object_attribute_t *k_attrs = NULL; 4382 crypto_session_id_t session_id; 4383 crypto_minor_t *cm; 4384 crypto_session_data_t *sp = NULL; 4385 crypto_object_id_t handle, new_handle; 4386 caddr_t oc_new_attributes; 4387 size_t k_attrs_size; 4388 size_t rctl_bytes = 0; 4389 int error = 0; 4390 int rv; 4391 uint_t count; 4392 4393 STRUCT_INIT(object_copy, mode); 4394 4395 if ((cm = crypto_hold_minor(getminor(dev))) == NULL) { 4396 cmn_err(CE_WARN, "object_copy: failed holding minor"); 4397 return (ENXIO); 4398 } 4399 4400 if (copyin(arg, STRUCT_BUF(object_copy), 4401 STRUCT_SIZE(object_copy)) != 0) { 4402 crypto_release_minor(cm); 4403 return (EFAULT); 4404 } 4405 4406 count = STRUCT_FGET(object_copy, oc_count); 4407 oc_new_attributes = STRUCT_FGETP(object_copy, oc_new_attributes); 4408 if (!copyin_attributes(mode, count, oc_new_attributes, &k_attrs, 4409 &k_attrs_size, NULL, &rv, &error, &rctl_bytes, 0, B_TRUE, &projp)) { 4410 goto release_minor; 4411 } 4412 4413 session_id = STRUCT_FGET(object_copy, oc_session); 4414 4415 if (!get_session_ptr(session_id, cm, &sp, &error, &rv)) { 4416 goto release_minor; 4417 } 4418 4419 if ((rv = kcf_get_hardware_provider_nomech( 4420 CRYPTO_OPS_OFFSET(object_ops), 4421 CRYPTO_OBJECT_OFFSET(object_copy), CHECK_RESTRICT_FALSE, 4422 sp->sd_provider, &real_provider)) != CRYPTO_SUCCESS) { 4423 goto release_minor; 4424 } 4425 4426 handle = STRUCT_FGET(object_copy, oc_handle); 4427 KCF_WRAP_OBJECT_OPS_PARAMS(¶ms, KCF_OP_OBJECT_COPY, 4428 sp->sd_provider_session->ps_session, handle, k_attrs, count, 4429 &new_handle, 0, NULL, NULL, 0, NULL); 4430 4431 rv = kcf_submit_request(real_provider, NULL, NULL, ¶ms, B_FALSE); 4432 4433 if (rv == CRYPTO_SUCCESS) 4434 STRUCT_FSET(object_copy, oc_new_handle, new_handle); 4435 4436 release_minor: 4437 if (rctl_bytes != 0) { 4438 mutex_enter(&crypto_rctl_lock); 4439 CRYPTO_DECREMENT_RCTL(rctl_bytes, projp); 4440 mutex_exit(&crypto_rctl_lock); 4441 } 4442 4443 if (k_attrs != NULL) 4444 kmem_free(k_attrs, k_attrs_size); 4445 4446 if (error != 0) 4447 goto out; 4448 4449 STRUCT_FSET(object_copy, oc_return_value, rv); 4450 if (copyout(STRUCT_BUF(object_copy), arg, 4451 STRUCT_SIZE(object_copy)) != 0) { 4452 if (rv == CRYPTO_SUCCESS) { 4453 KCF_WRAP_OBJECT_OPS_PARAMS(¶ms, 4454 KCF_OP_OBJECT_DESTROY, 4455 sp->sd_provider_session->ps_session, new_handle, 4456 NULL, 0, NULL, 0, NULL, NULL, 0, NULL); 4457 4458 (void) kcf_submit_request(real_provider, NULL, 4459 NULL, ¶ms, B_FALSE); 4460 4461 error = EFAULT; 4462 } 4463 } 4464 out: 4465 if (sp != NULL) 4466 CRYPTO_SESSION_RELE(sp); 4467 crypto_release_minor(cm); 4468 if (real_provider != NULL) 4469 KCF_PROV_REFRELE(real_provider); 4470 return (error); 4471 } 4472 4473 /* ARGSUSED */ 4474 static int 4475 object_destroy(dev_t dev, caddr_t arg, int mode, int *rval) 4476 { 4477 STRUCT_DECL(crypto_object_destroy, object_destroy); 4478 kcf_provider_desc_t *real_provider; 4479 kcf_req_params_t params; 4480 crypto_session_id_t session_id; 4481 crypto_minor_t *cm; 4482 crypto_session_data_t *sp; 4483 crypto_object_id_t handle; 4484 int error = 0; 4485 int rv; 4486 4487 STRUCT_INIT(object_destroy, mode); 4488 4489 if ((cm = crypto_hold_minor(getminor(dev))) == NULL) { 4490 cmn_err(CE_WARN, "object_destroy: failed holding minor"); 4491 return (ENXIO); 4492 } 4493 4494 if (copyin(arg, STRUCT_BUF(object_destroy), 4495 STRUCT_SIZE(object_destroy)) != 0) { 4496 crypto_release_minor(cm); 4497 return (EFAULT); 4498 } 4499 4500 session_id = STRUCT_FGET(object_destroy, od_session); 4501 4502 if (!get_session_ptr(session_id, cm, &sp, &error, &rv)) { 4503 goto release_minor; 4504 } 4505 4506 if ((rv = kcf_get_hardware_provider_nomech( 4507 CRYPTO_OPS_OFFSET(object_ops), 4508 CRYPTO_OBJECT_OFFSET(object_destroy), CHECK_RESTRICT_FALSE, 4509 sp->sd_provider, &real_provider)) != CRYPTO_SUCCESS) { 4510 goto out; 4511 } 4512 4513 handle = STRUCT_FGET(object_destroy, od_handle); 4514 KCF_WRAP_OBJECT_OPS_PARAMS(¶ms, KCF_OP_OBJECT_DESTROY, 4515 sp->sd_provider_session->ps_session, handle, NULL, 0, NULL, 0, 4516 NULL, NULL, 0, NULL); 4517 4518 rv = kcf_submit_request(real_provider, NULL, NULL, ¶ms, B_FALSE); 4519 KCF_PROV_REFRELE(real_provider); 4520 4521 out: 4522 CRYPTO_SESSION_RELE(sp); 4523 4524 release_minor: 4525 crypto_release_minor(cm); 4526 4527 if (error != 0) 4528 return (error); 4529 4530 STRUCT_FSET(object_destroy, od_return_value, rv); 4531 4532 if (copyout(STRUCT_BUF(object_destroy), arg, 4533 STRUCT_SIZE(object_destroy)) != 0) { 4534 return (EFAULT); 4535 } 4536 return (0); 4537 } 4538 4539 /* ARGSUSED */ 4540 static int 4541 object_get_attribute_value(dev_t dev, caddr_t arg, int mode, int *rval) 4542 { 4543 STRUCT_DECL(crypto_object_get_attribute_value, get_attribute_value); 4544 /* LINTED E_FUNC_SET_NOT_USED */ 4545 STRUCT_DECL(crypto_object_attribute, oa); 4546 kproject_t *projp; 4547 kcf_provider_desc_t *real_provider; 4548 kcf_req_params_t params; 4549 crypto_object_attribute_t *k_attrs = NULL; 4550 crypto_session_id_t session_id; 4551 crypto_minor_t *cm; 4552 crypto_session_data_t *sp; 4553 crypto_object_id_t handle; 4554 caddr_t og_attributes; 4555 caddr_t u_attrs; 4556 size_t k_attrs_size; 4557 size_t rctl_bytes = 0; 4558 int error = 0; 4559 int rv; 4560 uint_t count; 4561 4562 STRUCT_INIT(get_attribute_value, mode); 4563 STRUCT_INIT(oa, mode); 4564 4565 if ((cm = crypto_hold_minor(getminor(dev))) == NULL) { 4566 cmn_err(CE_WARN, 4567 "object_get_attribute_value: failed holding minor"); 4568 return (ENXIO); 4569 } 4570 4571 if (copyin(arg, STRUCT_BUF(get_attribute_value), 4572 STRUCT_SIZE(get_attribute_value)) != 0) { 4573 crypto_release_minor(cm); 4574 return (EFAULT); 4575 } 4576 4577 count = STRUCT_FGET(get_attribute_value, og_count); 4578 og_attributes = STRUCT_FGETP(get_attribute_value, og_attributes); 4579 if (!copyin_attributes(mode, count, og_attributes, &k_attrs, 4580 &k_attrs_size, &u_attrs, &rv, &error, &rctl_bytes, 0, B_FALSE, 4581 &projp)) { 4582 goto release_minor; 4583 } 4584 4585 session_id = STRUCT_FGET(get_attribute_value, og_session); 4586 4587 if (!get_session_ptr(session_id, cm, &sp, &error, &rv)) { 4588 goto release_minor; 4589 } 4590 4591 if ((rv = kcf_get_hardware_provider_nomech( 4592 CRYPTO_OPS_OFFSET(object_ops), 4593 CRYPTO_OBJECT_OFFSET(object_get_attribute_value), 4594 CHECK_RESTRICT_FALSE, sp->sd_provider, &real_provider)) 4595 != CRYPTO_SUCCESS) { 4596 goto out; 4597 } 4598 4599 handle = STRUCT_FGET(get_attribute_value, og_handle); 4600 KCF_WRAP_OBJECT_OPS_PARAMS(¶ms, KCF_OP_OBJECT_GET_ATTRIBUTE_VALUE, 4601 sp->sd_provider_session->ps_session, handle, k_attrs, count, NULL, 4602 0, NULL, NULL, 0, NULL); 4603 4604 rv = kcf_submit_request(real_provider, NULL, NULL, ¶ms, B_FALSE); 4605 KCF_PROV_REFRELE(real_provider); 4606 4607 out: 4608 CRYPTO_SESSION_RELE(sp); 4609 4610 if (rv == CRYPTO_SUCCESS || rv == CRYPTO_ATTRIBUTE_SENSITIVE || 4611 rv == CRYPTO_ATTRIBUTE_TYPE_INVALID || 4612 rv == CRYPTO_BUFFER_TOO_SMALL) { 4613 error = copyout_attributes(mode, 4614 STRUCT_FGETP(get_attribute_value, og_attributes), 4615 count, k_attrs, u_attrs); 4616 } 4617 4618 release_minor: 4619 if (rctl_bytes != 0) { 4620 mutex_enter(&crypto_rctl_lock); 4621 CRYPTO_DECREMENT_RCTL(rctl_bytes, projp); 4622 mutex_exit(&crypto_rctl_lock); 4623 } 4624 crypto_release_minor(cm); 4625 4626 if (k_attrs != NULL) 4627 kmem_free(k_attrs, k_attrs_size); 4628 4629 if (u_attrs != NULL) 4630 kmem_free(u_attrs, count * STRUCT_SIZE(oa)); 4631 4632 if (error != 0) 4633 return (error); 4634 4635 STRUCT_FSET(get_attribute_value, og_return_value, rv); 4636 if (copyout(STRUCT_BUF(get_attribute_value), arg, 4637 STRUCT_SIZE(get_attribute_value)) != 0) { 4638 return (EFAULT); 4639 } 4640 return (0); 4641 } 4642 4643 /* ARGSUSED */ 4644 static int 4645 object_get_size(dev_t dev, caddr_t arg, int mode, int *rval) 4646 { 4647 STRUCT_DECL(crypto_object_get_size, object_get_size); 4648 kcf_provider_desc_t *real_provider; 4649 kcf_req_params_t params; 4650 crypto_session_id_t session_id; 4651 crypto_minor_t *cm; 4652 crypto_session_data_t *sp; 4653 crypto_object_id_t handle; 4654 size_t size; 4655 int error = 0; 4656 int rv; 4657 4658 STRUCT_INIT(object_get_size, mode); 4659 4660 if ((cm = crypto_hold_minor(getminor(dev))) == NULL) { 4661 cmn_err(CE_WARN, "object_get_size: failed holding minor"); 4662 return (ENXIO); 4663 } 4664 4665 if (copyin(arg, STRUCT_BUF(object_get_size), 4666 STRUCT_SIZE(object_get_size)) != 0) { 4667 crypto_release_minor(cm); 4668 return (EFAULT); 4669 } 4670 4671 session_id = STRUCT_FGET(object_get_size, gs_session); 4672 4673 if (!get_session_ptr(session_id, cm, &sp, &error, &rv)) { 4674 goto release_minor; 4675 } 4676 4677 if ((rv = kcf_get_hardware_provider_nomech( 4678 CRYPTO_OPS_OFFSET(object_ops), 4679 CRYPTO_OBJECT_OFFSET(object_get_size), CHECK_RESTRICT_FALSE, 4680 sp->sd_provider, &real_provider)) != CRYPTO_SUCCESS) { 4681 goto out; 4682 } 4683 4684 handle = STRUCT_FGET(object_get_size, gs_handle); 4685 KCF_WRAP_OBJECT_OPS_PARAMS(¶ms, KCF_OP_OBJECT_GET_SIZE, 4686 sp->sd_provider_session->ps_session, handle, NULL, 0, NULL, &size, 4687 NULL, NULL, 0, NULL); 4688 4689 rv = kcf_submit_request(real_provider, NULL, NULL, ¶ms, B_FALSE); 4690 KCF_PROV_REFRELE(real_provider); 4691 4692 out: 4693 CRYPTO_SESSION_RELE(sp); 4694 4695 if (rv == CRYPTO_SUCCESS) { 4696 STRUCT_FSET(object_get_size, gs_size, size); 4697 } 4698 release_minor: 4699 crypto_release_minor(cm); 4700 4701 if (error != 0) 4702 return (error); 4703 4704 STRUCT_FSET(object_get_size, gs_return_value, rv); 4705 if (copyout(STRUCT_BUF(object_get_size), arg, 4706 STRUCT_SIZE(object_get_size)) != 0) { 4707 return (EFAULT); 4708 } 4709 return (0); 4710 } 4711 4712 /* ARGSUSED */ 4713 static int 4714 object_set_attribute_value(dev_t dev, caddr_t arg, int mode, int *rval) 4715 { 4716 STRUCT_DECL(crypto_object_set_attribute_value, set_attribute_value); 4717 kproject_t *projp; 4718 kcf_provider_desc_t *real_provider; 4719 kcf_req_params_t params; 4720 crypto_object_attribute_t *k_attrs = NULL; 4721 crypto_session_id_t session_id; 4722 crypto_minor_t *cm; 4723 crypto_session_data_t *sp; 4724 crypto_object_id_t object_handle; 4725 caddr_t sa_attributes; 4726 size_t k_attrs_size; 4727 size_t rctl_bytes = 0; 4728 int error = 0; 4729 int rv; 4730 uint_t count; 4731 4732 STRUCT_INIT(set_attribute_value, mode); 4733 4734 if ((cm = crypto_hold_minor(getminor(dev))) == NULL) { 4735 cmn_err(CE_WARN, 4736 "object_set_attribute_value: failed holding minor"); 4737 return (ENXIO); 4738 } 4739 4740 if (copyin(arg, STRUCT_BUF(set_attribute_value), 4741 STRUCT_SIZE(set_attribute_value)) != 0) { 4742 crypto_release_minor(cm); 4743 return (EFAULT); 4744 } 4745 4746 count = STRUCT_FGET(set_attribute_value, sa_count); 4747 sa_attributes = STRUCT_FGETP(set_attribute_value, sa_attributes); 4748 if (!copyin_attributes(mode, count, sa_attributes, &k_attrs, 4749 &k_attrs_size, NULL, &rv, &error, &rctl_bytes, 0, B_TRUE, &projp)) { 4750 goto release_minor; 4751 } 4752 4753 session_id = STRUCT_FGET(set_attribute_value, sa_session); 4754 4755 if (!get_session_ptr(session_id, cm, &sp, &error, &rv)) { 4756 goto release_minor; 4757 } 4758 4759 if ((rv = kcf_get_hardware_provider_nomech( 4760 CRYPTO_OPS_OFFSET(object_ops), 4761 CRYPTO_OBJECT_OFFSET(object_set_attribute_value), 4762 CHECK_RESTRICT_FALSE, sp->sd_provider, &real_provider)) 4763 != CRYPTO_SUCCESS) { 4764 goto out; 4765 } 4766 4767 object_handle = STRUCT_FGET(set_attribute_value, sa_handle); 4768 KCF_WRAP_OBJECT_OPS_PARAMS(¶ms, KCF_OP_OBJECT_SET_ATTRIBUTE_VALUE, 4769 sp->sd_provider_session->ps_session, object_handle, k_attrs, count, 4770 NULL, 0, NULL, NULL, 0, NULL); 4771 4772 rv = kcf_submit_request(real_provider, NULL, NULL, ¶ms, B_FALSE); 4773 KCF_PROV_REFRELE(real_provider); 4774 4775 out: 4776 CRYPTO_SESSION_RELE(sp); 4777 4778 release_minor: 4779 if (rctl_bytes != 0) { 4780 mutex_enter(&crypto_rctl_lock); 4781 CRYPTO_DECREMENT_RCTL(rctl_bytes, projp); 4782 mutex_exit(&crypto_rctl_lock); 4783 } 4784 crypto_release_minor(cm); 4785 4786 if (k_attrs != NULL) 4787 kmem_free(k_attrs, k_attrs_size); 4788 4789 if (error != 0) 4790 return (error); 4791 4792 STRUCT_FSET(set_attribute_value, sa_return_value, rv); 4793 if (copyout(STRUCT_BUF(set_attribute_value), arg, 4794 STRUCT_SIZE(set_attribute_value)) != 0) { 4795 return (EFAULT); 4796 } 4797 return (0); 4798 } 4799 4800 /* ARGSUSED */ 4801 static int 4802 object_find_init(dev_t dev, caddr_t arg, int mode, int *rval) 4803 { 4804 STRUCT_DECL(crypto_object_find_init, find_init); 4805 kproject_t *projp; 4806 kcf_provider_desc_t *real_provider = NULL; 4807 kcf_req_params_t params; 4808 crypto_object_attribute_t *k_attrs = NULL; 4809 crypto_session_id_t session_id; 4810 crypto_minor_t *cm; 4811 crypto_session_data_t *sp; 4812 caddr_t attributes; 4813 size_t k_attrs_size; 4814 size_t rctl_bytes = 0; 4815 int error = 0; 4816 int rv; 4817 uint_t count; 4818 void *cookie; 4819 4820 STRUCT_INIT(find_init, mode); 4821 4822 if ((cm = crypto_hold_minor(getminor(dev))) == NULL) { 4823 cmn_err(CE_WARN, "object_find_init: failed holding minor"); 4824 return (ENXIO); 4825 } 4826 4827 if (copyin(arg, STRUCT_BUF(find_init), STRUCT_SIZE(find_init)) != 0) { 4828 crypto_release_minor(cm); 4829 return (EFAULT); 4830 } 4831 4832 count = STRUCT_FGET(find_init, fi_count); 4833 attributes = STRUCT_FGETP(find_init, fi_attributes); 4834 if (!copyin_attributes(mode, count, attributes, &k_attrs, 4835 &k_attrs_size, NULL, &rv, &error, &rctl_bytes, 0, B_TRUE, &projp)) { 4836 goto release_minor; 4837 } 4838 4839 session_id = STRUCT_FGET(find_init, fi_session); 4840 4841 if (!get_session_ptr(session_id, cm, &sp, &error, &rv)) { 4842 goto release_minor; 4843 } 4844 4845 if ((rv = kcf_get_hardware_provider_nomech( 4846 CRYPTO_OPS_OFFSET(object_ops), 4847 CRYPTO_OBJECT_OFFSET(object_find_init), CHECK_RESTRICT_FALSE, 4848 sp->sd_provider, &real_provider)) != CRYPTO_SUCCESS) { 4849 goto out; 4850 } 4851 4852 /* check for an active find */ 4853 if (sp->sd_find_init_cookie != NULL) { 4854 rv = CRYPTO_OPERATION_IS_ACTIVE; 4855 CRYPTO_SESSION_RELE(sp); 4856 goto release_minor; 4857 } 4858 4859 KCF_WRAP_OBJECT_OPS_PARAMS(¶ms, KCF_OP_OBJECT_FIND_INIT, 4860 sp->sd_provider_session->ps_session, 0, k_attrs, count, NULL, 0, 4861 &cookie, NULL, 0, NULL); 4862 4863 rv = kcf_submit_request(real_provider, NULL, NULL, ¶ms, B_FALSE); 4864 4865 if (rv == CRYPTO_SUCCESS) { 4866 /* 4867 * The cookie is allocated by a provider at the start of an 4868 * object search. It is freed when the search is terminated 4869 * by a final operation, or when the session is closed. 4870 * It contains state information about which object handles 4871 * have been returned to the caller. 4872 */ 4873 sp->sd_find_init_cookie = cookie; 4874 } 4875 4876 out: 4877 CRYPTO_SESSION_RELE(sp); 4878 4879 release_minor: 4880 if (rctl_bytes != 0) { 4881 mutex_enter(&crypto_rctl_lock); 4882 CRYPTO_DECREMENT_RCTL(rctl_bytes, projp); 4883 mutex_exit(&crypto_rctl_lock); 4884 } 4885 crypto_release_minor(cm); 4886 4887 if (real_provider != NULL) 4888 KCF_PROV_REFRELE(real_provider); 4889 4890 if (k_attrs != NULL) 4891 kmem_free(k_attrs, k_attrs_size); 4892 4893 if (error != 0) 4894 return (error); 4895 4896 STRUCT_FSET(find_init, fi_return_value, rv); 4897 if (copyout(STRUCT_BUF(find_init), arg, STRUCT_SIZE(find_init)) != 0) { 4898 return (EFAULT); 4899 } 4900 return (0); 4901 } 4902 4903 /* ARGSUSED */ 4904 static int 4905 object_find_update(dev_t dev, caddr_t arg, int mode, int *rval) 4906 { 4907 STRUCT_DECL(crypto_object_find_update, find_update); 4908 kproject_t *projp; 4909 kcf_provider_desc_t *real_provider; 4910 kcf_req_params_t params; 4911 crypto_minor_t *cm; 4912 crypto_session_data_t *sp; 4913 crypto_object_id_t *buffer = NULL; 4914 crypto_session_id_t session_id; 4915 size_t len, rctl_bytes = 0; 4916 uint_t count, max_count; 4917 int rv, error = 0; 4918 4919 STRUCT_INIT(find_update, mode); 4920 4921 if ((cm = crypto_hold_minor(getminor(dev))) == NULL) { 4922 cmn_err(CE_WARN, "object_find_update: failed holding minor"); 4923 return (ENXIO); 4924 } 4925 4926 if (copyin(arg, STRUCT_BUF(find_update), 4927 STRUCT_SIZE(find_update)) != 0) { 4928 crypto_release_minor(cm); 4929 return (EFAULT); 4930 } 4931 4932 max_count = STRUCT_FGET(find_update, fu_max_count); 4933 if (max_count > CRYPTO_MAX_FIND_COUNT) { 4934 cmn_err(CE_NOTE, "object_find_update: count greater than %d, " 4935 "pid = %d", CRYPTO_MAX_FIND_COUNT, curproc->p_pid); 4936 rv = CRYPTO_ARGUMENTS_BAD; 4937 goto release_minor; 4938 } 4939 len = max_count * sizeof (crypto_object_id_t); 4940 if ((rv = crypto_buffer_check(len, &projp)) != CRYPTO_SUCCESS) { 4941 goto release_minor; 4942 } 4943 rctl_bytes = len; 4944 buffer = kmem_alloc(len, KM_SLEEP); 4945 4946 session_id = STRUCT_FGET(find_update, fu_session); 4947 4948 if (!get_session_ptr(session_id, cm, &sp, &error, &rv)) { 4949 goto release_minor; 4950 } 4951 4952 if ((rv = kcf_get_hardware_provider_nomech( 4953 CRYPTO_OPS_OFFSET(object_ops), 4954 CRYPTO_OBJECT_OFFSET(object_find), CHECK_RESTRICT_FALSE, 4955 sp->sd_provider, &real_provider)) != CRYPTO_SUCCESS) { 4956 goto out; 4957 } 4958 4959 KCF_WRAP_OBJECT_OPS_PARAMS(¶ms, KCF_OP_OBJECT_FIND, 4960 sp->sd_provider_session->ps_session, 0, NULL, 0, buffer, 0, 4961 NULL, sp->sd_find_init_cookie, max_count, &count); 4962 4963 rv = kcf_submit_request(real_provider, NULL, NULL, ¶ms, B_FALSE); 4964 KCF_PROV_REFRELE(real_provider); 4965 4966 out: 4967 CRYPTO_SESSION_RELE(sp); 4968 if (rv == CRYPTO_SUCCESS) { 4969 if (count > max_count) { 4970 /* bad bad provider */ 4971 rv = CRYPTO_FAILED; 4972 goto release_minor; 4973 } 4974 if (count != 0) { 4975 /* copyout handles */ 4976 if (copyout(buffer, 4977 STRUCT_FGETP(find_update, fu_handles), 4978 count * sizeof (crypto_object_id_t)) != 0) { 4979 error = EFAULT; 4980 } 4981 } 4982 STRUCT_FSET(find_update, fu_count, count); 4983 } 4984 4985 release_minor: 4986 if (rctl_bytes != 0) { 4987 mutex_enter(&crypto_rctl_lock); 4988 CRYPTO_DECREMENT_RCTL(rctl_bytes, projp); 4989 mutex_exit(&crypto_rctl_lock); 4990 } 4991 crypto_release_minor(cm); 4992 4993 if (buffer != NULL) 4994 kmem_free(buffer, len); 4995 4996 if (error != 0) 4997 return (error); 4998 4999 STRUCT_FSET(find_update, fu_return_value, rv); 5000 if (copyout(STRUCT_BUF(find_update), arg, 5001 STRUCT_SIZE(find_update)) != 0) { 5002 return (EFAULT); 5003 } 5004 5005 return (0); 5006 } 5007 5008 /* 5009 * Free provider-allocated storage used for find object searches. 5010 */ 5011 static int 5012 crypto_free_find_ctx(crypto_session_data_t *sp) 5013 { 5014 kcf_provider_desc_t *real_provider; 5015 kcf_req_params_t params; 5016 int rv; 5017 5018 if ((rv = kcf_get_hardware_provider_nomech( 5019 CRYPTO_OPS_OFFSET(object_ops), 5020 CRYPTO_OBJECT_OFFSET(object_find_final), CHECK_RESTRICT_FALSE, 5021 sp->sd_provider, &real_provider)) != CRYPTO_SUCCESS) { 5022 return (rv); 5023 } 5024 5025 KCF_WRAP_OBJECT_OPS_PARAMS(¶ms, KCF_OP_OBJECT_FIND_FINAL, 5026 sp->sd_provider_session->ps_session, 0, NULL, 0, NULL, 0, 5027 NULL, sp->sd_find_init_cookie, 0, NULL); 5028 5029 rv = kcf_submit_request(real_provider, NULL, NULL, ¶ms, B_FALSE); 5030 KCF_PROV_REFRELE(real_provider); 5031 return (rv); 5032 } 5033 5034 /* ARGSUSED */ 5035 static int 5036 object_find_final(dev_t dev, caddr_t arg, int mode, int *rval) 5037 { 5038 STRUCT_DECL(crypto_object_find_final, object_find_final); 5039 crypto_session_id_t session_id; 5040 crypto_minor_t *cm; 5041 crypto_session_data_t *sp; 5042 int error = 0; 5043 int rv; 5044 5045 STRUCT_INIT(object_find_final, mode); 5046 5047 if ((cm = crypto_hold_minor(getminor(dev))) == NULL) { 5048 cmn_err(CE_WARN, "object_find_final: failed holding minor"); 5049 return (ENXIO); 5050 } 5051 5052 if (copyin(arg, STRUCT_BUF(object_find_final), 5053 STRUCT_SIZE(object_find_final)) != 0) { 5054 crypto_release_minor(cm); 5055 return (EFAULT); 5056 } 5057 5058 session_id = STRUCT_FGET(object_find_final, ff_session); 5059 5060 if (!get_session_ptr(session_id, cm, &sp, &error, &rv)) { 5061 goto release_minor; 5062 } 5063 5064 if ((rv = crypto_free_find_ctx(sp)) == CRYPTO_SUCCESS) { 5065 sp->sd_find_init_cookie = NULL; 5066 } 5067 5068 CRYPTO_SESSION_RELE(sp); 5069 5070 release_minor: 5071 crypto_release_minor(cm); 5072 5073 if (error != 0) 5074 return (error); 5075 5076 STRUCT_FSET(object_find_final, ff_return_value, rv); 5077 5078 if (copyout(STRUCT_BUF(object_find_final), arg, 5079 STRUCT_SIZE(object_find_final)) != 0) { 5080 return (EFAULT); 5081 } 5082 return (0); 5083 } 5084 5085 /* ARGSUSED */ 5086 static int 5087 object_generate_key(dev_t dev, caddr_t arg, int mode, int *rval) 5088 { 5089 STRUCT_DECL(crypto_object_generate_key, generate_key); 5090 kproject_t *mech_projp, *key_projp; 5091 kcf_provider_desc_t *real_provider = NULL; 5092 kcf_req_params_t params; 5093 crypto_mechanism_t mech; 5094 crypto_object_attribute_t *k_attrs = NULL; 5095 crypto_session_id_t session_id; 5096 crypto_minor_t *cm; 5097 crypto_session_data_t *sp = NULL; 5098 crypto_object_id_t key_handle; 5099 caddr_t attributes; 5100 size_t k_attrs_size; 5101 size_t mech_rctl_bytes = 0, key_rctl_bytes = 0; 5102 size_t carry; 5103 uint_t count; 5104 int error = 0; 5105 int rv; 5106 boolean_t allocated_by_crypto_module = B_FALSE; 5107 5108 STRUCT_INIT(generate_key, mode); 5109 5110 if ((cm = crypto_hold_minor(getminor(dev))) == NULL) { 5111 cmn_err(CE_WARN, "object_generate_key: failed holding minor"); 5112 return (ENXIO); 5113 } 5114 5115 if (copyin(arg, STRUCT_BUF(generate_key), 5116 STRUCT_SIZE(generate_key)) != 0) { 5117 crypto_release_minor(cm); 5118 return (EFAULT); 5119 } 5120 5121 session_id = STRUCT_FGET(generate_key, gk_session); 5122 5123 if (!get_session_ptr(session_id, cm, &sp, &error, &rv)) { 5124 goto release_minor; 5125 } 5126 5127 bcopy(STRUCT_FADDR(generate_key, gk_mechanism), &mech.cm_type, 5128 sizeof (crypto_mech_type_t)); 5129 5130 if ((rv = kcf_get_hardware_provider(mech.cm_type, CRYPTO_MECH_INVALID, 5131 CHECK_RESTRICT_FALSE, sp->sd_provider, &real_provider, 5132 CRYPTO_FG_GENERATE)) != CRYPTO_SUCCESS) { 5133 goto release_minor; 5134 } 5135 5136 carry = 0; 5137 rv = crypto_provider_copyin_mech_param(real_provider, 5138 STRUCT_FADDR(generate_key, gk_mechanism), &mech, mode, &error); 5139 5140 if (rv == CRYPTO_NOT_SUPPORTED) { 5141 allocated_by_crypto_module = B_TRUE; 5142 if (!copyin_mech(mode, STRUCT_FADDR(generate_key, gk_mechanism), 5143 &mech, &mech_rctl_bytes, &carry, &rv, &error, 5144 &mech_projp)) { 5145 goto release_minor; 5146 } 5147 } else { 5148 if (rv != CRYPTO_SUCCESS) 5149 goto release_minor; 5150 } 5151 5152 count = STRUCT_FGET(generate_key, gk_count); 5153 attributes = STRUCT_FGETP(generate_key, gk_attributes); 5154 if (!copyin_attributes(mode, count, attributes, &k_attrs, 5155 &k_attrs_size, NULL, &rv, &error, &key_rctl_bytes, carry, B_TRUE, 5156 &key_projp)) { 5157 goto release_minor; 5158 } 5159 5160 KCF_WRAP_KEY_OPS_PARAMS(¶ms, KCF_OP_KEY_GENERATE, 5161 sp->sd_provider_session->ps_session, &mech, k_attrs, count, 5162 &key_handle, NULL, 0, NULL, NULL, NULL, 0); 5163 5164 rv = kcf_submit_request(real_provider, NULL, NULL, ¶ms, B_FALSE); 5165 5166 if (rv == CRYPTO_SUCCESS) 5167 STRUCT_FSET(generate_key, gk_handle, key_handle); 5168 5169 release_minor: 5170 mutex_enter(&crypto_rctl_lock); 5171 if (mech_rctl_bytes != 0) 5172 CRYPTO_DECREMENT_RCTL(mech_rctl_bytes, mech_projp); 5173 if (key_rctl_bytes != 0) 5174 CRYPTO_DECREMENT_RCTL(key_rctl_bytes, key_projp); 5175 mutex_exit(&crypto_rctl_lock); 5176 5177 if (k_attrs != NULL) 5178 kmem_free(k_attrs, k_attrs_size); 5179 5180 if (error != 0) 5181 goto out; 5182 5183 STRUCT_FSET(generate_key, gk_return_value, rv); 5184 if (copyout(STRUCT_BUF(generate_key), arg, 5185 STRUCT_SIZE(generate_key)) != 0) { 5186 if (rv == CRYPTO_SUCCESS) { 5187 KCF_WRAP_OBJECT_OPS_PARAMS(¶ms, 5188 KCF_OP_OBJECT_DESTROY, 5189 sp->sd_provider_session->ps_session, key_handle, 5190 NULL, 0, NULL, 0, NULL, NULL, 0, NULL); 5191 5192 (void) kcf_submit_request(real_provider, NULL, 5193 NULL, ¶ms, B_FALSE); 5194 5195 error = EFAULT; 5196 } 5197 } 5198 out: 5199 if (sp != NULL) 5200 CRYPTO_SESSION_RELE(sp); 5201 crypto_release_minor(cm); 5202 5203 if (real_provider != NULL) { 5204 crypto_free_mech(real_provider, 5205 allocated_by_crypto_module, &mech); 5206 KCF_PROV_REFRELE(real_provider); 5207 } 5208 return (error); 5209 } 5210 5211 /* ARGSUSED */ 5212 static int 5213 object_generate_key_pair(dev_t dev, caddr_t arg, int mode, int *rval) 5214 { 5215 STRUCT_DECL(crypto_object_generate_key_pair, generate_key_pair); 5216 kproject_t *pub_projp, *pri_projp, *mech_projp; 5217 kcf_provider_desc_t *real_provider = NULL; 5218 kcf_req_params_t params; 5219 crypto_mechanism_t mech; 5220 crypto_object_attribute_t *k_pub_attrs = NULL; 5221 crypto_object_attribute_t *k_pri_attrs = NULL; 5222 crypto_session_id_t session_id; 5223 crypto_minor_t *cm; 5224 crypto_session_data_t *sp = NULL; 5225 crypto_object_id_t pub_handle; 5226 crypto_object_id_t pri_handle; 5227 caddr_t pri_attributes; 5228 caddr_t pub_attributes; 5229 size_t k_pub_attrs_size, k_pri_attrs_size; 5230 size_t mech_rctl_bytes = 0; 5231 size_t pub_rctl_bytes = 0; 5232 size_t pri_rctl_bytes = 0; 5233 size_t carry; 5234 uint_t pub_count; 5235 uint_t pri_count; 5236 int error = 0; 5237 int rv; 5238 boolean_t allocated_by_crypto_module = B_FALSE; 5239 5240 STRUCT_INIT(generate_key_pair, mode); 5241 5242 if ((cm = crypto_hold_minor(getminor(dev))) == NULL) { 5243 cmn_err(CE_WARN, 5244 "object_generate_key_pair: failed holding minor"); 5245 return (ENXIO); 5246 } 5247 5248 if (copyin(arg, STRUCT_BUF(generate_key_pair), 5249 STRUCT_SIZE(generate_key_pair)) != 0) { 5250 crypto_release_minor(cm); 5251 return (EFAULT); 5252 } 5253 5254 session_id = STRUCT_FGET(generate_key_pair, kp_session); 5255 5256 if (!get_session_ptr(session_id, cm, &sp, &error, &rv)) { 5257 goto release_minor; 5258 } 5259 5260 bcopy(STRUCT_FADDR(generate_key_pair, kp_mechanism), &mech.cm_type, 5261 sizeof (crypto_mech_type_t)); 5262 5263 if ((rv = kcf_get_hardware_provider(mech.cm_type, CRYPTO_MECH_INVALID, 5264 CHECK_RESTRICT_FALSE, sp->sd_provider, &real_provider, 5265 CRYPTO_FG_GENERATE_KEY_PAIR)) != CRYPTO_SUCCESS) { 5266 goto release_minor; 5267 } 5268 5269 carry = 0; 5270 rv = crypto_provider_copyin_mech_param(real_provider, 5271 STRUCT_FADDR(generate_key_pair, kp_mechanism), &mech, mode, &error); 5272 5273 if (rv == CRYPTO_NOT_SUPPORTED) { 5274 allocated_by_crypto_module = B_TRUE; 5275 if (!copyin_mech(mode, STRUCT_FADDR(generate_key_pair, 5276 kp_mechanism), &mech, &mech_rctl_bytes, &carry, &rv, 5277 &error, &mech_projp)) { 5278 goto release_minor; 5279 } 5280 } else { 5281 if (rv != CRYPTO_SUCCESS) 5282 goto release_minor; 5283 } 5284 5285 pub_count = STRUCT_FGET(generate_key_pair, kp_public_count); 5286 pri_count = STRUCT_FGET(generate_key_pair, kp_private_count); 5287 5288 pub_attributes = STRUCT_FGETP(generate_key_pair, kp_public_attributes); 5289 if (!copyin_attributes(mode, pub_count, pub_attributes, &k_pub_attrs, 5290 &k_pub_attrs_size, NULL, &rv, &error, &pub_rctl_bytes, carry, 5291 B_TRUE, &pub_projp)) { 5292 goto release_minor; 5293 } 5294 5295 pri_attributes = STRUCT_FGETP(generate_key_pair, kp_private_attributes); 5296 if (!copyin_attributes(mode, pri_count, pri_attributes, &k_pri_attrs, 5297 &k_pri_attrs_size, NULL, &rv, &error, &pri_rctl_bytes, 0, 5298 B_TRUE, &pri_projp)) { 5299 goto release_minor; 5300 } 5301 5302 KCF_WRAP_KEY_OPS_PARAMS(¶ms, KCF_OP_KEY_GENERATE_PAIR, 5303 sp->sd_provider_session->ps_session, &mech, k_pub_attrs, 5304 pub_count, &pub_handle, k_pri_attrs, pri_count, &pri_handle, 5305 NULL, NULL, 0); 5306 5307 rv = kcf_submit_request(real_provider, NULL, NULL, ¶ms, B_FALSE); 5308 5309 if (rv == CRYPTO_SUCCESS) { 5310 STRUCT_FSET(generate_key_pair, kp_public_handle, pub_handle); 5311 STRUCT_FSET(generate_key_pair, kp_private_handle, pri_handle); 5312 } 5313 5314 release_minor: 5315 mutex_enter(&crypto_rctl_lock); 5316 if (mech_rctl_bytes != 0) 5317 CRYPTO_DECREMENT_RCTL(mech_rctl_bytes, mech_projp); 5318 if (pub_rctl_bytes != 0) 5319 CRYPTO_DECREMENT_RCTL(pub_rctl_bytes, pub_projp); 5320 if (pri_rctl_bytes != 0) 5321 CRYPTO_DECREMENT_RCTL(pri_rctl_bytes, pri_projp); 5322 mutex_exit(&crypto_rctl_lock); 5323 5324 if (k_pub_attrs != NULL) 5325 kmem_free(k_pub_attrs, k_pub_attrs_size); 5326 5327 if (k_pri_attrs != NULL) 5328 kmem_free(k_pri_attrs, k_pri_attrs_size); 5329 5330 if (error != 0) 5331 goto out; 5332 5333 STRUCT_FSET(generate_key_pair, kp_return_value, rv); 5334 if (copyout(STRUCT_BUF(generate_key_pair), arg, 5335 STRUCT_SIZE(generate_key_pair)) != 0) { 5336 if (rv == CRYPTO_SUCCESS) { 5337 KCF_WRAP_OBJECT_OPS_PARAMS(¶ms, 5338 KCF_OP_OBJECT_DESTROY, 5339 sp->sd_provider_session->ps_session, pub_handle, 5340 NULL, 0, NULL, 0, NULL, NULL, 0, NULL); 5341 5342 (void) kcf_submit_request(real_provider, NULL, 5343 NULL, ¶ms, B_FALSE); 5344 5345 KCF_WRAP_OBJECT_OPS_PARAMS(¶ms, 5346 KCF_OP_OBJECT_DESTROY, 5347 sp->sd_provider_session->ps_session, pri_handle, 5348 NULL, 0, NULL, 0, NULL, NULL, 0, NULL); 5349 5350 (void) kcf_submit_request(real_provider, NULL, 5351 NULL, ¶ms, B_FALSE); 5352 5353 error = EFAULT; 5354 } 5355 } 5356 out: 5357 if (sp != NULL) 5358 CRYPTO_SESSION_RELE(sp); 5359 crypto_release_minor(cm); 5360 5361 if (real_provider != NULL) { 5362 crypto_free_mech(real_provider, 5363 allocated_by_crypto_module, &mech); 5364 KCF_PROV_REFRELE(real_provider); 5365 } 5366 return (error); 5367 } 5368 5369 /* ARGSUSED */ 5370 static int 5371 object_wrap_key(dev_t dev, caddr_t arg, int mode, int *rval) 5372 { 5373 STRUCT_DECL(crypto_object_wrap_key, wrap_key); 5374 kproject_t *mech_projp, *key_projp, *wrapped_key_projp; 5375 kcf_provider_desc_t *real_provider = NULL; 5376 kcf_req_params_t params; 5377 crypto_mechanism_t mech; 5378 crypto_key_t key; 5379 crypto_session_id_t session_id; 5380 crypto_minor_t *cm; 5381 crypto_session_data_t *sp; 5382 crypto_object_id_t handle; 5383 size_t mech_rctl_bytes = 0, key_rctl_bytes = 0; 5384 size_t wrapped_key_rctl_bytes = 0; 5385 size_t carry; 5386 size_t wrapped_key_len, new_wrapped_key_len; 5387 uchar_t *wrapped_key = NULL; 5388 char *wrapped_key_buffer; 5389 int error = 0; 5390 int rv; 5391 boolean_t allocated_by_crypto_module = B_FALSE; 5392 5393 STRUCT_INIT(wrap_key, mode); 5394 5395 if ((cm = crypto_hold_minor(getminor(dev))) == NULL) { 5396 cmn_err(CE_WARN, "object_wrap_key: failed holding minor"); 5397 return (ENXIO); 5398 } 5399 5400 if (copyin(arg, STRUCT_BUF(wrap_key), STRUCT_SIZE(wrap_key)) != 0) { 5401 crypto_release_minor(cm); 5402 return (EFAULT); 5403 } 5404 5405 bzero(&key, sizeof (crypto_key_t)); 5406 5407 session_id = STRUCT_FGET(wrap_key, wk_session); 5408 5409 if (!get_session_ptr(session_id, cm, &sp, &error, &rv)) { 5410 goto release_minor; 5411 } 5412 5413 bcopy(STRUCT_FADDR(wrap_key, wk_mechanism), &mech.cm_type, 5414 sizeof (crypto_mech_type_t)); 5415 5416 if ((rv = kcf_get_hardware_provider(mech.cm_type, CRYPTO_MECH_INVALID, 5417 CHECK_RESTRICT_FALSE, sp->sd_provider, &real_provider, 5418 CRYPTO_FG_WRAP)) != CRYPTO_SUCCESS) { 5419 goto out; 5420 } 5421 5422 carry = 0; 5423 rv = crypto_provider_copyin_mech_param(real_provider, 5424 STRUCT_FADDR(wrap_key, wk_mechanism), &mech, mode, &error); 5425 5426 if (rv == CRYPTO_NOT_SUPPORTED) { 5427 allocated_by_crypto_module = B_TRUE; 5428 if (!copyin_mech(mode, STRUCT_FADDR(wrap_key, wk_mechanism), 5429 &mech, &mech_rctl_bytes, &carry, &rv, &error, 5430 &mech_projp)) { 5431 goto out; 5432 } 5433 } else { 5434 if (rv != CRYPTO_SUCCESS) 5435 goto out; 5436 } 5437 5438 if (!copyin_key(mode, STRUCT_FADDR(wrap_key, wk_wrapping_key), &key, 5439 &key_rctl_bytes, &rv, &error, carry, &key_projp)) { 5440 goto out; 5441 } 5442 5443 wrapped_key_len = STRUCT_FGET(wrap_key, wk_wrapped_key_len); 5444 5445 /* 5446 * Don't allocate output buffer unless both buffer pointer and 5447 * buffer length are not NULL or 0 (length). 5448 */ 5449 wrapped_key_buffer = STRUCT_FGETP(wrap_key, wk_wrapped_key); 5450 if (wrapped_key_buffer == NULL || wrapped_key_len == 0) { 5451 wrapped_key_len = 0; 5452 } 5453 5454 if (wrapped_key_len > crypto_max_buffer_len) { 5455 cmn_err(CE_NOTE, "object_wrap_key: buffer greater than %ld " 5456 "bytes, pid = %d", crypto_max_buffer_len, curproc->p_pid); 5457 rv = CRYPTO_ARGUMENTS_BAD; 5458 goto out; 5459 } 5460 5461 if ((rv = crypto_buffer_check(wrapped_key_len, 5462 &wrapped_key_projp)) != CRYPTO_SUCCESS) { 5463 goto out; 5464 } 5465 5466 /* new_wrapped_key_len can be modified by the provider */ 5467 wrapped_key_rctl_bytes = new_wrapped_key_len = wrapped_key_len; 5468 wrapped_key = kmem_alloc(wrapped_key_len, KM_SLEEP); 5469 5470 handle = STRUCT_FGET(wrap_key, wk_object_handle); 5471 KCF_WRAP_KEY_OPS_PARAMS(¶ms, KCF_OP_KEY_WRAP, 5472 sp->sd_provider_session->ps_session, &mech, NULL, 0, &handle, 5473 NULL, 0, NULL, &key, wrapped_key, &new_wrapped_key_len); 5474 5475 rv = kcf_submit_request(real_provider, NULL, NULL, ¶ms, B_FALSE); 5476 5477 if (rv == CRYPTO_SUCCESS) { 5478 if (wrapped_key_len != 0 && copyout(wrapped_key, 5479 wrapped_key_buffer, new_wrapped_key_len) != 0) { 5480 error = EFAULT; 5481 } 5482 STRUCT_FSET(wrap_key, wk_wrapped_key_len, new_wrapped_key_len); 5483 } 5484 5485 if (rv == CRYPTO_BUFFER_TOO_SMALL) { 5486 /* 5487 * The providers return CRYPTO_BUFFER_TOO_SMALL even for case 1 5488 * of section 11.2 of the pkcs11 spec. We catch it here and 5489 * provide the correct pkcs11 return value. 5490 */ 5491 if (STRUCT_FGETP(wrap_key, wk_wrapped_key) == NULL) 5492 rv = CRYPTO_SUCCESS; 5493 STRUCT_FSET(wrap_key, wk_wrapped_key_len, new_wrapped_key_len); 5494 } 5495 out: 5496 CRYPTO_SESSION_RELE(sp); 5497 5498 release_minor: 5499 mutex_enter(&crypto_rctl_lock); 5500 if (mech_rctl_bytes != 0) 5501 CRYPTO_DECREMENT_RCTL(mech_rctl_bytes, mech_projp); 5502 if (key_rctl_bytes != 0) 5503 CRYPTO_DECREMENT_RCTL(key_rctl_bytes, key_projp); 5504 if (wrapped_key_rctl_bytes != 0) 5505 CRYPTO_DECREMENT_RCTL(wrapped_key_rctl_bytes, 5506 wrapped_key_projp); 5507 mutex_exit(&crypto_rctl_lock); 5508 crypto_release_minor(cm); 5509 5510 if (real_provider != NULL) { 5511 crypto_free_mech(real_provider, 5512 allocated_by_crypto_module, &mech); 5513 KCF_PROV_REFRELE(real_provider); 5514 } 5515 5516 if (wrapped_key != NULL) 5517 kmem_free(wrapped_key, wrapped_key_len); 5518 5519 free_crypto_key(&key); 5520 5521 if (error != 0) 5522 return (error); 5523 5524 STRUCT_FSET(wrap_key, wk_return_value, rv); 5525 if (copyout(STRUCT_BUF(wrap_key), arg, STRUCT_SIZE(wrap_key)) != 0) { 5526 return (EFAULT); 5527 } 5528 return (0); 5529 } 5530 5531 /* ARGSUSED */ 5532 static int 5533 object_unwrap_key(dev_t dev, caddr_t arg, int mode, int *rval) 5534 { 5535 STRUCT_DECL(crypto_object_unwrap_key, unwrap_key); 5536 kproject_t *mech_projp, *unwrapping_key_projp, *wrapped_key_projp, 5537 *k_attrs_projp; 5538 kcf_provider_desc_t *real_provider = NULL; 5539 kcf_req_params_t params; 5540 crypto_mechanism_t mech; 5541 crypto_key_t unwrapping_key; 5542 crypto_session_id_t session_id; 5543 crypto_minor_t *cm; 5544 crypto_session_data_t *sp = NULL; 5545 crypto_object_id_t handle; 5546 crypto_object_attribute_t *k_attrs = NULL; 5547 size_t k_attrs_size; 5548 size_t mech_rctl_bytes = 0, unwrapping_key_rctl_bytes = 0; 5549 size_t wrapped_key_rctl_bytes = 0, k_attrs_rctl_bytes = 0; 5550 size_t carry; 5551 size_t wrapped_key_len; 5552 uchar_t *wrapped_key = NULL; 5553 int error = 0; 5554 int rv; 5555 uint_t count; 5556 caddr_t uk_attributes; 5557 boolean_t allocated_by_crypto_module = B_FALSE; 5558 5559 STRUCT_INIT(unwrap_key, mode); 5560 5561 if ((cm = crypto_hold_minor(getminor(dev))) == NULL) { 5562 cmn_err(CE_WARN, "object_unwrap_key: failed holding minor"); 5563 return (ENXIO); 5564 } 5565 5566 if (copyin(arg, STRUCT_BUF(unwrap_key), STRUCT_SIZE(unwrap_key)) != 0) { 5567 crypto_release_minor(cm); 5568 return (EFAULT); 5569 } 5570 5571 bzero(&unwrapping_key, sizeof (unwrapping_key)); 5572 5573 session_id = STRUCT_FGET(unwrap_key, uk_session); 5574 5575 if (!get_session_ptr(session_id, cm, &sp, &error, &rv)) { 5576 goto release_minor; 5577 } 5578 5579 bcopy(STRUCT_FADDR(unwrap_key, uk_mechanism), &mech.cm_type, 5580 sizeof (crypto_mech_type_t)); 5581 5582 if ((rv = kcf_get_hardware_provider(mech.cm_type, CRYPTO_MECH_INVALID, 5583 CHECK_RESTRICT_FALSE, sp->sd_provider, &real_provider, 5584 CRYPTO_FG_UNWRAP)) != CRYPTO_SUCCESS) { 5585 goto release_minor; 5586 } 5587 5588 carry = 0; 5589 rv = crypto_provider_copyin_mech_param(real_provider, 5590 STRUCT_FADDR(unwrap_key, uk_mechanism), &mech, mode, &error); 5591 5592 if (rv == CRYPTO_NOT_SUPPORTED) { 5593 allocated_by_crypto_module = B_TRUE; 5594 if (!copyin_mech(mode, STRUCT_FADDR(unwrap_key, uk_mechanism), 5595 &mech, &mech_rctl_bytes, &carry, &rv, &error, 5596 &mech_projp)) { 5597 goto release_minor; 5598 } 5599 } else { 5600 if (rv != CRYPTO_SUCCESS) 5601 goto release_minor; 5602 } 5603 5604 if (!copyin_key(mode, STRUCT_FADDR(unwrap_key, uk_unwrapping_key), 5605 &unwrapping_key, &unwrapping_key_rctl_bytes, &rv, &error, carry, 5606 &unwrapping_key_projp)) { 5607 goto release_minor; 5608 } 5609 5610 count = STRUCT_FGET(unwrap_key, uk_count); 5611 uk_attributes = STRUCT_FGETP(unwrap_key, uk_attributes); 5612 if (!copyin_attributes(mode, count, uk_attributes, &k_attrs, 5613 &k_attrs_size, NULL, &rv, &error, &k_attrs_rctl_bytes, 0, B_TRUE, 5614 &k_attrs_projp)) { 5615 goto release_minor; 5616 } 5617 5618 wrapped_key_len = STRUCT_FGET(unwrap_key, uk_wrapped_key_len); 5619 if (wrapped_key_len > crypto_max_buffer_len) { 5620 cmn_err(CE_NOTE, "object_unwrap_key: buffer greater than %ld " 5621 "bytes, pid = %d", crypto_max_buffer_len, curproc->p_pid); 5622 rv = CRYPTO_ARGUMENTS_BAD; 5623 goto release_minor; 5624 } 5625 5626 if ((rv = crypto_buffer_check(wrapped_key_len, &wrapped_key_projp)) 5627 != CRYPTO_SUCCESS) { 5628 goto release_minor; 5629 } 5630 wrapped_key_rctl_bytes = wrapped_key_len; 5631 wrapped_key = kmem_alloc(wrapped_key_len, KM_SLEEP); 5632 5633 if (wrapped_key_len != 0 && copyin(STRUCT_FGETP(unwrap_key, 5634 uk_wrapped_key), wrapped_key, wrapped_key_len) != 0) { 5635 error = EFAULT; 5636 goto release_minor; 5637 } 5638 5639 /* wrapped_key_len is not modified by the unwrap operation */ 5640 KCF_WRAP_KEY_OPS_PARAMS(¶ms, KCF_OP_KEY_UNWRAP, 5641 sp->sd_provider_session->ps_session, &mech, k_attrs, count, &handle, 5642 NULL, 0, NULL, &unwrapping_key, wrapped_key, &wrapped_key_len); 5643 5644 rv = kcf_submit_request(real_provider, NULL, NULL, ¶ms, B_FALSE); 5645 5646 if (rv == CRYPTO_SUCCESS) 5647 STRUCT_FSET(unwrap_key, uk_object_handle, handle); 5648 5649 release_minor: 5650 mutex_enter(&crypto_rctl_lock); 5651 if (mech_rctl_bytes != 0) 5652 CRYPTO_DECREMENT_RCTL(mech_rctl_bytes, mech_projp); 5653 if (unwrapping_key_rctl_bytes != 0) 5654 CRYPTO_DECREMENT_RCTL(unwrapping_key_rctl_bytes, 5655 unwrapping_key_projp); 5656 if (wrapped_key_rctl_bytes != 0) 5657 CRYPTO_DECREMENT_RCTL(wrapped_key_rctl_bytes, 5658 wrapped_key_projp); 5659 if (k_attrs_rctl_bytes != 0) 5660 CRYPTO_DECREMENT_RCTL(k_attrs_rctl_bytes, k_attrs_projp); 5661 mutex_exit(&crypto_rctl_lock); 5662 5663 if (k_attrs != NULL) 5664 kmem_free(k_attrs, k_attrs_size); 5665 5666 if (wrapped_key != NULL) 5667 kmem_free(wrapped_key, wrapped_key_len); 5668 5669 free_crypto_key(&unwrapping_key); 5670 5671 if (error != 0) 5672 goto out; 5673 5674 STRUCT_FSET(unwrap_key, uk_return_value, rv); 5675 if (copyout(STRUCT_BUF(unwrap_key), arg, 5676 STRUCT_SIZE(unwrap_key)) != 0) { 5677 if (rv == CRYPTO_SUCCESS) { 5678 KCF_WRAP_OBJECT_OPS_PARAMS(¶ms, 5679 KCF_OP_OBJECT_DESTROY, 5680 sp->sd_provider_session->ps_session, handle, 5681 NULL, 0, NULL, 0, NULL, NULL, 0, NULL); 5682 5683 (void) kcf_submit_request(real_provider, NULL, 5684 NULL, ¶ms, B_FALSE); 5685 5686 error = EFAULT; 5687 } 5688 } 5689 out: 5690 if (sp != NULL) 5691 CRYPTO_SESSION_RELE(sp); 5692 crypto_release_minor(cm); 5693 5694 if (real_provider != NULL) { 5695 crypto_free_mech(real_provider, 5696 allocated_by_crypto_module, &mech); 5697 KCF_PROV_REFRELE(real_provider); 5698 } 5699 5700 return (error); 5701 } 5702 5703 /* ARGSUSED */ 5704 static int 5705 object_derive_key(dev_t dev, caddr_t arg, int mode, int *rval) 5706 { 5707 STRUCT_DECL(crypto_derive_key, derive_key); 5708 kproject_t *key_projp, *mech_projp, *attributes_projp; 5709 kcf_provider_desc_t *real_provider = NULL; 5710 kcf_req_params_t params; 5711 crypto_object_attribute_t *k_attrs = NULL; 5712 crypto_mechanism_t mech; 5713 crypto_key_t base_key; 5714 crypto_session_id_t session_id; 5715 crypto_minor_t *cm; 5716 crypto_session_data_t *sp = NULL; 5717 crypto_object_id_t handle; 5718 size_t k_attrs_size; 5719 size_t key_rctl_bytes = 0, mech_rctl_bytes = 0; 5720 size_t attributes_rctl_bytes = 0; 5721 size_t carry; 5722 caddr_t attributes; 5723 uint_t count; 5724 int error = 0; 5725 int rv; 5726 boolean_t allocated_by_crypto_module = B_FALSE; 5727 boolean_t please_destroy_object = B_FALSE; 5728 5729 STRUCT_INIT(derive_key, mode); 5730 5731 if ((cm = crypto_hold_minor(getminor(dev))) == NULL) { 5732 cmn_err(CE_WARN, "object_derive_key: failed holding minor"); 5733 return (ENXIO); 5734 } 5735 5736 if (copyin(arg, STRUCT_BUF(derive_key), STRUCT_SIZE(derive_key)) != 0) { 5737 crypto_release_minor(cm); 5738 return (EFAULT); 5739 } 5740 5741 bzero(&base_key, sizeof (base_key)); 5742 5743 session_id = STRUCT_FGET(derive_key, dk_session); 5744 5745 if (!get_session_ptr(session_id, cm, &sp, &error, &rv)) { 5746 goto release_minor; 5747 } 5748 5749 bcopy(STRUCT_FADDR(derive_key, dk_mechanism), &mech.cm_type, 5750 sizeof (crypto_mech_type_t)); 5751 5752 if ((rv = kcf_get_hardware_provider(mech.cm_type, CRYPTO_MECH_INVALID, 5753 CHECK_RESTRICT_FALSE, sp->sd_provider, &real_provider, 5754 CRYPTO_FG_DERIVE)) != CRYPTO_SUCCESS) { 5755 goto release_minor; 5756 } 5757 5758 carry = 0; 5759 rv = crypto_provider_copyin_mech_param(real_provider, 5760 STRUCT_FADDR(derive_key, dk_mechanism), &mech, mode, &error); 5761 5762 if (rv == CRYPTO_NOT_SUPPORTED) { 5763 allocated_by_crypto_module = B_TRUE; 5764 if (!copyin_mech(mode, STRUCT_FADDR(derive_key, dk_mechanism), 5765 &mech, &mech_rctl_bytes, &carry, &rv, &error, 5766 &mech_projp)) { 5767 goto release_minor; 5768 } 5769 } else { 5770 if (rv != CRYPTO_SUCCESS) 5771 goto release_minor; 5772 } 5773 5774 if (!copyin_key(mode, STRUCT_FADDR(derive_key, dk_base_key), 5775 &base_key, &key_rctl_bytes, &rv, &error, carry, &key_projp)) { 5776 goto release_minor; 5777 } 5778 5779 count = STRUCT_FGET(derive_key, dk_count); 5780 5781 attributes = STRUCT_FGETP(derive_key, dk_attributes); 5782 if (!copyin_attributes(mode, count, attributes, &k_attrs, 5783 &k_attrs_size, NULL, &rv, &error, &attributes_rctl_bytes, 0, B_TRUE, 5784 &attributes_projp)) { 5785 goto release_minor; 5786 } 5787 5788 KCF_WRAP_KEY_OPS_PARAMS(¶ms, KCF_OP_KEY_DERIVE, 5789 sp->sd_provider_session->ps_session, &mech, k_attrs, count, 5790 &handle, NULL, 0, NULL, &base_key, NULL, NULL); 5791 5792 rv = kcf_submit_request(real_provider, NULL, NULL, ¶ms, B_FALSE); 5793 5794 if (rv == CRYPTO_SUCCESS) { 5795 STRUCT_FSET(derive_key, dk_object_handle, handle); 5796 5797 rv = crypto_provider_copyout_mech_param(real_provider, 5798 &mech, STRUCT_FADDR(derive_key, dk_mechanism), 5799 mode, &error); 5800 5801 if (rv == CRYPTO_NOT_SUPPORTED) { 5802 rv = CRYPTO_SUCCESS; 5803 goto release_minor; 5804 } 5805 5806 if (rv != CRYPTO_SUCCESS) 5807 please_destroy_object = B_TRUE; 5808 } 5809 5810 release_minor: 5811 mutex_enter(&crypto_rctl_lock); 5812 if (mech_rctl_bytes != 0) 5813 CRYPTO_DECREMENT_RCTL(mech_rctl_bytes, mech_projp); 5814 if (key_rctl_bytes != 0) 5815 CRYPTO_DECREMENT_RCTL(key_rctl_bytes, key_projp); 5816 if (attributes_rctl_bytes != 0) 5817 CRYPTO_DECREMENT_RCTL(attributes_rctl_bytes, attributes_projp); 5818 mutex_exit(&crypto_rctl_lock); 5819 5820 if (k_attrs != NULL) 5821 kmem_free(k_attrs, k_attrs_size); 5822 5823 free_crypto_key(&base_key); 5824 5825 if (error != 0) 5826 goto out; 5827 5828 STRUCT_FSET(derive_key, dk_return_value, rv); 5829 if (copyout(STRUCT_BUF(derive_key), arg, 5830 STRUCT_SIZE(derive_key)) != 0) { 5831 if (rv == CRYPTO_SUCCESS) { 5832 please_destroy_object = B_TRUE; 5833 error = EFAULT; 5834 } 5835 } 5836 out: 5837 if (please_destroy_object) { 5838 KCF_WRAP_OBJECT_OPS_PARAMS(¶ms, KCF_OP_OBJECT_DESTROY, 5839 sp->sd_provider_session->ps_session, handle, 5840 NULL, 0, NULL, 0, NULL, NULL, 0, NULL); 5841 5842 (void) kcf_submit_request(real_provider, NULL, 5843 NULL, ¶ms, B_FALSE); 5844 } 5845 5846 if (sp != NULL) 5847 CRYPTO_SESSION_RELE(sp); 5848 crypto_release_minor(cm); 5849 5850 if (real_provider != NULL) { 5851 crypto_free_mech(real_provider, 5852 allocated_by_crypto_module, &mech); 5853 KCF_PROV_REFRELE(real_provider); 5854 } 5855 return (error); 5856 } 5857 5858 /* ARGSUSED */ 5859 static int 5860 crypto_ioctl(dev_t dev, int cmd, intptr_t arg, int mode, cred_t *c, 5861 int *rval) 5862 { 5863 #define ARG ((caddr_t)arg) 5864 5865 switch (cmd) { 5866 case CRYPTO_GET_FUNCTION_LIST: 5867 return (get_function_list(dev, ARG, mode, rval)); 5868 5869 case CRYPTO_GET_MECHANISM_NUMBER: 5870 return (get_mechanism_number(dev, ARG, mode, rval)); 5871 5872 case CRYPTO_GET_PROVIDER_LIST: 5873 return (get_provider_list(dev, ARG, mode, rval)); 5874 5875 case CRYPTO_GET_PROVIDER_INFO: 5876 return (get_provider_info(dev, ARG, mode, rval)); 5877 5878 case CRYPTO_GET_PROVIDER_MECHANISMS: 5879 return (get_provider_mechanisms(dev, ARG, mode, rval)); 5880 5881 case CRYPTO_GET_PROVIDER_MECHANISM_INFO: 5882 return (get_provider_mechanism_info(dev, ARG, mode, rval)); 5883 5884 case CRYPTO_OPEN_SESSION: 5885 return (open_session(dev, ARG, mode, rval)); 5886 5887 case CRYPTO_CLOSE_SESSION: 5888 return (close_session(dev, ARG, mode, rval)); 5889 5890 case CRYPTO_ENCRYPT_INIT: 5891 return (encrypt_init(dev, ARG, mode, rval)); 5892 5893 case CRYPTO_DECRYPT_INIT: 5894 return (decrypt_init(dev, ARG, mode, rval)); 5895 5896 case CRYPTO_ENCRYPT: 5897 return (encrypt(dev, ARG, mode, rval)); 5898 5899 case CRYPTO_DECRYPT: 5900 return (decrypt(dev, ARG, mode, rval)); 5901 5902 case CRYPTO_ENCRYPT_UPDATE: 5903 return (encrypt_update(dev, ARG, mode, rval)); 5904 5905 case CRYPTO_DECRYPT_UPDATE: 5906 return (decrypt_update(dev, ARG, mode, rval)); 5907 5908 case CRYPTO_ENCRYPT_FINAL: 5909 return (encrypt_final(dev, ARG, mode, rval)); 5910 5911 case CRYPTO_DECRYPT_FINAL: 5912 return (decrypt_final(dev, ARG, mode, rval)); 5913 5914 case CRYPTO_DIGEST_INIT: 5915 return (digest_init(dev, ARG, mode, rval)); 5916 5917 case CRYPTO_DIGEST: 5918 return (digest(dev, ARG, mode, rval)); 5919 5920 case CRYPTO_DIGEST_UPDATE: 5921 return (digest_update(dev, ARG, mode, rval)); 5922 5923 case CRYPTO_DIGEST_KEY: 5924 return (digest_key(dev, ARG, mode, rval)); 5925 5926 case CRYPTO_DIGEST_FINAL: 5927 return (digest_final(dev, ARG, mode, rval)); 5928 5929 case CRYPTO_SIGN_INIT: 5930 return (sign_init(dev, ARG, mode, rval)); 5931 5932 case CRYPTO_SIGN: 5933 return (sign(dev, ARG, mode, rval)); 5934 5935 case CRYPTO_SIGN_UPDATE: 5936 return (sign_update(dev, ARG, mode, rval)); 5937 5938 case CRYPTO_SIGN_FINAL: 5939 return (sign_final(dev, ARG, mode, rval)); 5940 5941 case CRYPTO_SIGN_RECOVER_INIT: 5942 return (sign_recover_init(dev, ARG, mode, rval)); 5943 5944 case CRYPTO_SIGN_RECOVER: 5945 return (sign_recover(dev, ARG, mode, rval)); 5946 5947 case CRYPTO_VERIFY_INIT: 5948 return (verify_init(dev, ARG, mode, rval)); 5949 5950 case CRYPTO_VERIFY: 5951 return (verify(dev, ARG, mode, rval)); 5952 5953 case CRYPTO_VERIFY_UPDATE: 5954 return (verify_update(dev, ARG, mode, rval)); 5955 5956 case CRYPTO_VERIFY_FINAL: 5957 return (verify_final(dev, ARG, mode, rval)); 5958 5959 case CRYPTO_VERIFY_RECOVER_INIT: 5960 return (verify_recover_init(dev, ARG, mode, rval)); 5961 5962 case CRYPTO_VERIFY_RECOVER: 5963 return (verify_recover(dev, ARG, mode, rval)); 5964 5965 case CRYPTO_SET_PIN: 5966 return (set_pin(dev, ARG, mode, rval)); 5967 5968 case CRYPTO_LOGIN: 5969 return (login(dev, ARG, mode, rval)); 5970 5971 case CRYPTO_LOGOUT: 5972 return (logout(dev, ARG, mode, rval)); 5973 5974 case CRYPTO_SEED_RANDOM: 5975 return (seed_random(dev, ARG, mode, rval)); 5976 5977 case CRYPTO_GENERATE_RANDOM: 5978 return (generate_random(dev, ARG, mode, rval)); 5979 5980 case CRYPTO_OBJECT_CREATE: 5981 return (object_create(dev, ARG, mode, rval)); 5982 5983 case CRYPTO_OBJECT_COPY: 5984 return (object_copy(dev, ARG, mode, rval)); 5985 5986 case CRYPTO_OBJECT_DESTROY: 5987 return (object_destroy(dev, ARG, mode, rval)); 5988 5989 case CRYPTO_OBJECT_GET_ATTRIBUTE_VALUE: 5990 return (object_get_attribute_value(dev, ARG, mode, rval)); 5991 5992 case CRYPTO_OBJECT_GET_SIZE: 5993 return (object_get_size(dev, ARG, mode, rval)); 5994 5995 case CRYPTO_OBJECT_SET_ATTRIBUTE_VALUE: 5996 return (object_set_attribute_value(dev, ARG, mode, rval)); 5997 5998 case CRYPTO_OBJECT_FIND_INIT: 5999 return (object_find_init(dev, ARG, mode, rval)); 6000 6001 case CRYPTO_OBJECT_FIND_UPDATE: 6002 return (object_find_update(dev, ARG, mode, rval)); 6003 6004 case CRYPTO_OBJECT_FIND_FINAL: 6005 return (object_find_final(dev, ARG, mode, rval)); 6006 6007 case CRYPTO_GENERATE_KEY: 6008 return (object_generate_key(dev, ARG, mode, rval)); 6009 6010 case CRYPTO_GENERATE_KEY_PAIR: 6011 return (object_generate_key_pair(dev, ARG, mode, rval)); 6012 6013 case CRYPTO_WRAP_KEY: 6014 return (object_wrap_key(dev, ARG, mode, rval)); 6015 6016 case CRYPTO_UNWRAP_KEY: 6017 return (object_unwrap_key(dev, ARG, mode, rval)); 6018 6019 case CRYPTO_DERIVE_KEY: 6020 return (object_derive_key(dev, ARG, mode, rval)); 6021 } 6022 return (EINVAL); 6023 } 6024 6025 /* 6026 * Check for the project.max-crypto-memory resource control. 6027 */ 6028 static int 6029 crypto_buffer_check(size_t need, kproject_t **projp) 6030 { 6031 ASSERT(projp != NULL); 6032 6033 if (need == 0) 6034 return (CRYPTO_SUCCESS); 6035 6036 mutex_enter(&curproc->p_lock); 6037 mutex_enter(&crypto_rctl_lock); 6038 if (rctl_test(rc_project_crypto_mem, 6039 curproc->p_task->tk_proj->kpj_rctls, curproc, need, 0) & RCT_DENY) { 6040 mutex_exit(&crypto_rctl_lock); 6041 mutex_exit(&curproc->p_lock); 6042 return (CRYPTO_HOST_MEMORY); 6043 } 6044 6045 curproc->p_task->tk_proj->kpj_data.kpd_crypto_mem += need; 6046 mutex_exit(&crypto_rctl_lock); 6047 6048 (void) project_hold(curproc->p_task->tk_proj); 6049 *projp = curproc->p_task->tk_proj; 6050 mutex_exit(&curproc->p_lock); 6051 return (CRYPTO_SUCCESS); 6052 } 6053