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