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