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