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