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 * This file is part of the core Kernel Cryptographic Framework. 30 * It implements the SPI functions exported to cryptographic 31 * providers. 32 */ 33 34 #include <sys/ksynch.h> 35 #include <sys/cmn_err.h> 36 #include <sys/ddi.h> 37 #include <sys/sunddi.h> 38 #include <sys/modctl.h> 39 #include <sys/crypto/common.h> 40 #include <sys/crypto/impl.h> 41 #include <sys/crypto/sched_impl.h> 42 #include <sys/crypto/spi.h> 43 #include <sys/taskq.h> 44 #include <sys/disp.h> 45 #include <sys/kstat.h> 46 #include <sys/policy.h> 47 48 /* 49 * minalloc and maxalloc values to be used for taskq_create(). 50 */ 51 int crypto_taskq_minalloc = CYRPTO_TASKQ_MIN; 52 int crypto_taskq_maxalloc = CRYPTO_TASKQ_MAX; 53 54 static void free_provider_list(kcf_provider_list_t *); 55 static void remove_provider(kcf_provider_desc_t *); 56 static void process_logical_providers(crypto_provider_info_t *, 57 kcf_provider_desc_t *); 58 static void copy_ops_vector_v1(crypto_ops_t *, crypto_ops_t *); 59 static void copy_ops_vector_v2(crypto_ops_t *, crypto_ops_t *); 60 static int init_prov_mechs(crypto_provider_info_t *, kcf_provider_desc_t *); 61 static int kcf_prov_kstat_update(kstat_t *, int); 62 63 static kcf_prov_stats_t kcf_stats_ks_data_template = { 64 { "kcf_ops_total", KSTAT_DATA_UINT64 }, 65 { "kcf_ops_passed", KSTAT_DATA_UINT64 }, 66 { "kcf_ops_failed", KSTAT_DATA_UINT64 }, 67 { "kcf_ops_returned_busy", KSTAT_DATA_UINT64 } 68 }; 69 70 #define KCF_SPI_COPY_OPS(src, dst, ops) if ((src)->ops != NULL) \ 71 *((dst)->ops) = *((src)->ops); 72 73 /* 74 * This routine is used to add cryptographic providers to the KEF framework. 75 * Providers pass a crypto_provider_info structure to crypto_register_provider() 76 * and get back a handle. The crypto_provider_info structure contains a 77 * list of mechanisms supported by the provider and an ops vector containing 78 * provider entry points. Hardware providers call this routine in their attach 79 * routines. Software providers call this routine in their _init() routine. 80 */ 81 int 82 crypto_register_provider(crypto_provider_info_t *info, 83 crypto_kcf_provider_handle_t *handle) 84 { 85 int i; 86 int vstatus = 0; 87 struct modctl *mcp; 88 char *name; 89 char ks_name[KSTAT_STRLEN]; 90 crypto_notify_event_change_t ec; 91 92 kcf_provider_desc_t *prov_desc = NULL; 93 int ret = CRYPTO_ARGUMENTS_BAD; 94 95 if (info->pi_interface_version > CRYPTO_SPI_VERSION_2) 96 return (CRYPTO_VERSION_MISMATCH); 97 98 /* 99 * Check provider type, must be software, hardware, or logical. 100 */ 101 if (info->pi_provider_type != CRYPTO_HW_PROVIDER && 102 info->pi_provider_type != CRYPTO_SW_PROVIDER && 103 info->pi_provider_type != CRYPTO_LOGICAL_PROVIDER) 104 return (CRYPTO_ARGUMENTS_BAD); 105 106 /* 107 * Allocate and initialize a new provider descriptor. We also 108 * hold it and release it when done. 109 */ 110 prov_desc = kcf_alloc_provider_desc(info); 111 KCF_PROV_REFHOLD(prov_desc); 112 113 prov_desc->pd_prov_type = info->pi_provider_type; 114 115 /* provider-private handle, opaque to KCF */ 116 prov_desc->pd_prov_handle = info->pi_provider_handle; 117 118 /* copy provider description string */ 119 if (info->pi_provider_description != NULL) { 120 /* 121 * pi_provider_descriptor is a string that can contain 122 * up to CRYPTO_PROVIDER_DESCR_MAX_LEN + 1 characters 123 * INCLUDING the terminating null character. A bcopy() 124 * is necessary here as pd_description should not have 125 * a null character. See comments in kcf_alloc_provider_desc() 126 * for details on pd_description field. 127 */ 128 bcopy(info->pi_provider_description, prov_desc->pd_description, 129 min(strlen(info->pi_provider_description), 130 CRYPTO_PROVIDER_DESCR_MAX_LEN)); 131 } 132 133 if (info->pi_provider_type != CRYPTO_LOGICAL_PROVIDER) { 134 if (info->pi_ops_vector == NULL) { 135 return (CRYPTO_ARGUMENTS_BAD); 136 } 137 copy_ops_vector_v1(info->pi_ops_vector, 138 prov_desc->pd_ops_vector); 139 if (info->pi_interface_version == CRYPTO_SPI_VERSION_2) { 140 copy_ops_vector_v2(info->pi_ops_vector, 141 prov_desc->pd_ops_vector); 142 prov_desc->pd_flags = info->pi_flags; 143 } 144 } 145 146 /* 147 * For software providers, copy the module name and module ID. 148 * For hardware providers, copy the driver name and instance. 149 */ 150 switch (info->pi_provider_type) { 151 case CRYPTO_SW_PROVIDER: 152 if (info->pi_provider_dev.pd_sw == NULL) 153 goto bail; 154 155 if ((mcp = mod_getctl(info->pi_provider_dev.pd_sw)) == NULL) 156 goto bail; 157 158 prov_desc->pd_module_id = mcp->mod_id; 159 name = mcp->mod_modname; 160 break; 161 162 case CRYPTO_HW_PROVIDER: 163 case CRYPTO_LOGICAL_PROVIDER: 164 if (info->pi_provider_dev.pd_hw == NULL) 165 goto bail; 166 167 prov_desc->pd_instance = 168 ddi_get_instance(info->pi_provider_dev.pd_hw); 169 name = (char *)ddi_driver_name(info->pi_provider_dev.pd_hw); 170 break; 171 } 172 if (name == NULL) 173 goto bail; 174 175 prov_desc->pd_name = kmem_alloc(strlen(name) + 1, KM_SLEEP); 176 (void) strcpy(prov_desc->pd_name, name); 177 178 if ((prov_desc->pd_mctlp = kcf_get_modctl(info)) == NULL) 179 goto bail; 180 181 /* process the mechanisms supported by the provider */ 182 if ((ret = init_prov_mechs(info, prov_desc)) != CRYPTO_SUCCESS) 183 goto bail; 184 185 /* 186 * Add provider to providers tables, also sets the descriptor 187 * pd_prov_id field. 188 */ 189 if ((ret = kcf_prov_tab_add_provider(prov_desc)) != CRYPTO_SUCCESS) { 190 undo_register_provider(prov_desc, B_FALSE); 191 goto bail; 192 } 193 194 if (info->pi_provider_type != CRYPTO_LOGICAL_PROVIDER) { 195 if ((vstatus = kcf_verify_signature(prov_desc)) == 196 CRYPTO_MODVERIFICATION_FAILED) { 197 undo_register_provider(prov_desc, B_TRUE); 198 ret = CRYPTO_MODVERIFICATION_FAILED; 199 goto bail; 200 } 201 } 202 203 /* 204 * We create a taskq only for a hardware provider. The global 205 * software queue is used for software providers. The taskq 206 * is limited to one thread since tasks are guaranteed to be 207 * executed in the order they are scheduled, if nthreads == 1. We 208 * pass TASKQ_PREPOPULATE flag to keep some entries cached to 209 * improve performance. 210 */ 211 if (prov_desc->pd_prov_type == CRYPTO_HW_PROVIDER) 212 prov_desc->pd_sched_info.ks_taskq = taskq_create("kcf_taskq", 213 1, minclsyspri, crypto_taskq_minalloc, 214 crypto_taskq_maxalloc, TASKQ_PREPOPULATE); 215 else 216 prov_desc->pd_sched_info.ks_taskq = NULL; 217 218 /* no kernel session to logical providers */ 219 if (prov_desc->pd_prov_type != CRYPTO_LOGICAL_PROVIDER) { 220 /* 221 * Open a session for session-oriented providers. This session 222 * is used for all kernel consumers. This is fine as a provider 223 * is required to support multiple thread access to a session. 224 * We can do this only after the taskq has been created as we 225 * do a kcf_submit_request() to open the session. 226 */ 227 if (KCF_PROV_SESSION_OPS(prov_desc) != NULL) { 228 kcf_req_params_t params; 229 230 KCF_WRAP_SESSION_OPS_PARAMS(¶ms, 231 KCF_OP_SESSION_OPEN, &prov_desc->pd_sid, 0, 232 CRYPTO_USER, NULL, 0, prov_desc); 233 ret = kcf_submit_request(prov_desc, NULL, NULL, ¶ms, 234 B_FALSE); 235 236 if (ret != CRYPTO_SUCCESS) { 237 undo_register_provider(prov_desc, B_TRUE); 238 ret = CRYPTO_FAILED; 239 goto bail; 240 } 241 } 242 } 243 244 if (prov_desc->pd_prov_type != CRYPTO_LOGICAL_PROVIDER) { 245 /* 246 * Create the kstat for this provider. There is a kstat 247 * installed for each successfully registered provider. 248 * This kstat is deleted, when the provider unregisters. 249 */ 250 if (prov_desc->pd_prov_type == CRYPTO_SW_PROVIDER) { 251 (void) snprintf(ks_name, KSTAT_STRLEN, "%s_%s", 252 prov_desc->pd_name, "provider_stats"); 253 } else { 254 (void) snprintf(ks_name, KSTAT_STRLEN, "%s_%d_%u_%s", 255 prov_desc->pd_name, prov_desc->pd_instance, 256 prov_desc->pd_prov_id, "provider_stats"); 257 } 258 259 prov_desc->pd_kstat = kstat_create("kcf", 0, ks_name, "crypto", 260 KSTAT_TYPE_NAMED, sizeof (kcf_prov_stats_t) / 261 sizeof (kstat_named_t), KSTAT_FLAG_VIRTUAL); 262 263 if (prov_desc->pd_kstat != NULL) { 264 bcopy(&kcf_stats_ks_data_template, 265 &prov_desc->pd_ks_data, 266 sizeof (kcf_stats_ks_data_template)); 267 prov_desc->pd_kstat->ks_data = &prov_desc->pd_ks_data; 268 KCF_PROV_REFHOLD(prov_desc); 269 KCF_PROV_IREFHOLD(prov_desc); 270 prov_desc->pd_kstat->ks_private = prov_desc; 271 prov_desc->pd_kstat->ks_update = kcf_prov_kstat_update; 272 kstat_install(prov_desc->pd_kstat); 273 } 274 } 275 276 if (prov_desc->pd_prov_type == CRYPTO_HW_PROVIDER) 277 process_logical_providers(info, prov_desc); 278 279 /* 280 * Inform interested clients of the mechanisms becoming 281 * available. We skip this for logical providers as they 282 * do not affect mechanisms. 283 */ 284 if (prov_desc->pd_prov_type != CRYPTO_LOGICAL_PROVIDER) { 285 ec.ec_provider_type = prov_desc->pd_prov_type; 286 ec.ec_change = CRYPTO_MECH_ADDED; 287 for (i = 0; i < prov_desc->pd_mech_list_count; i++) { 288 /* Skip any mechanisms not allowed by the policy */ 289 if (is_mech_disabled(prov_desc, 290 prov_desc->pd_mechanisms[i].cm_mech_name)) 291 continue; 292 293 (void) strncpy(ec.ec_mech_name, 294 prov_desc->pd_mechanisms[i].cm_mech_name, 295 CRYPTO_MAX_MECH_NAME); 296 kcf_walk_ntfylist(CRYPTO_EVENT_MECHS_CHANGED, &ec); 297 } 298 299 } 300 301 /* 302 * Inform interested clients of the new provider. In case of a 303 * logical provider, we need to notify the event only 304 * for the logical provider and not for the underlying 305 * providers which are known by pi_logical_provider_count > 0. 306 */ 307 if (prov_desc->pd_prov_type == CRYPTO_LOGICAL_PROVIDER || 308 info->pi_logical_provider_count == 0) 309 kcf_walk_ntfylist(CRYPTO_EVENT_PROVIDER_REGISTERED, prov_desc); 310 311 mutex_enter(&prov_desc->pd_lock); 312 prov_desc->pd_state = (vstatus == 0) ? KCF_PROV_READY : 313 KCF_PROV_UNVERIFIED; 314 mutex_exit(&prov_desc->pd_lock); 315 316 *handle = prov_desc->pd_kcf_prov_handle; 317 KCF_PROV_REFRELE(prov_desc); 318 return (CRYPTO_SUCCESS); 319 320 bail: 321 KCF_PROV_REFRELE(prov_desc); 322 return (ret); 323 } 324 325 /* 326 * This routine is used to notify the framework when a provider is being 327 * removed. Hardware providers call this routine in their detach routines. 328 * Software providers call this routine in their _fini() routine. 329 */ 330 int 331 crypto_unregister_provider(crypto_kcf_provider_handle_t handle) 332 { 333 int i; 334 uint_t mech_idx; 335 kcf_provider_desc_t *desc; 336 crypto_notify_event_change_t ec; 337 kcf_prov_state_t saved_state; 338 339 /* lookup provider descriptor */ 340 if ((desc = kcf_prov_tab_lookup((crypto_provider_id_t)handle)) == NULL) 341 return (CRYPTO_UNKNOWN_PROVIDER); 342 343 mutex_enter(&desc->pd_lock); 344 /* 345 * Check if any other thread is disabling or removing 346 * this provider. We return if this is the case. 347 */ 348 if (desc->pd_state >= KCF_PROV_DISABLED) { 349 mutex_exit(&desc->pd_lock); 350 /* Release reference held by kcf_prov_tab_lookup(). */ 351 KCF_PROV_REFRELE(desc); 352 return (CRYPTO_BUSY); 353 } 354 355 saved_state = desc->pd_state; 356 desc->pd_state = KCF_PROV_REMOVED; 357 358 if (saved_state == KCF_PROV_BUSY) { 359 /* 360 * The per-provider taskq thread may be waiting. We 361 * signal it so that it can start failing requests. 362 * Note that we do not need a cv_broadcast() as we keep 363 * only a single thread per taskq. 364 */ 365 cv_signal(&desc->pd_resume_cv); 366 } 367 368 if (desc->pd_prov_type == CRYPTO_SW_PROVIDER) { 369 /* 370 * Check if this provider is currently being used. 371 * pd_irefcnt is the number of holds from the internal 372 * structures. We add one to account for the above lookup. 373 */ 374 if (desc->pd_refcnt > desc->pd_irefcnt + 1) { 375 desc->pd_state = saved_state; 376 mutex_exit(&desc->pd_lock); 377 /* Release reference held by kcf_prov_tab_lookup(). */ 378 KCF_PROV_REFRELE(desc); 379 /* 380 * The administrator presumably will stop the clients 381 * thus removing the holds, when they get the busy 382 * return value. Any retry will succeed then. 383 */ 384 return (CRYPTO_BUSY); 385 } 386 } 387 mutex_exit(&desc->pd_lock); 388 389 if (desc->pd_prov_type != CRYPTO_SW_PROVIDER) { 390 remove_provider(desc); 391 } 392 393 if (desc->pd_prov_type != CRYPTO_LOGICAL_PROVIDER) { 394 /* remove the provider from the mechanisms tables */ 395 for (mech_idx = 0; mech_idx < desc->pd_mech_list_count; 396 mech_idx++) { 397 kcf_remove_mech_provider( 398 desc->pd_mechanisms[mech_idx].cm_mech_name, desc); 399 } 400 } 401 402 /* remove provider from providers table */ 403 if (kcf_prov_tab_rem_provider((crypto_provider_id_t)handle) != 404 CRYPTO_SUCCESS) { 405 /* Release reference held by kcf_prov_tab_lookup(). */ 406 KCF_PROV_REFRELE(desc); 407 return (CRYPTO_UNKNOWN_PROVIDER); 408 } 409 410 /* destroy the kstat created for this provider */ 411 if (desc->pd_kstat != NULL) { 412 kcf_provider_desc_t *kspd = desc->pd_kstat->ks_private; 413 414 /* release reference held by desc->pd_kstat->ks_private */ 415 ASSERT(desc == kspd); 416 kstat_delete(kspd->pd_kstat); 417 KCF_PROV_REFRELE(kspd); 418 KCF_PROV_IREFRELE(kspd); 419 } 420 421 if (desc->pd_prov_type == CRYPTO_SW_PROVIDER) { 422 /* Release reference held by kcf_prov_tab_lookup(). */ 423 KCF_PROV_REFRELE(desc); 424 425 /* 426 * Wait till the existing requests complete. 427 */ 428 mutex_enter(&desc->pd_lock); 429 while (desc->pd_state != KCF_PROV_FREED) 430 cv_wait(&desc->pd_remove_cv, &desc->pd_lock); 431 mutex_exit(&desc->pd_lock); 432 } else { 433 /* 434 * Wait until requests that have been sent to the provider 435 * complete. 436 */ 437 mutex_enter(&desc->pd_lock); 438 while (desc->pd_irefcnt > 0) 439 cv_wait(&desc->pd_remove_cv, &desc->pd_lock); 440 mutex_exit(&desc->pd_lock); 441 } 442 443 /* 444 * Inform interested clients of the mechanisms becoming 445 * unavailable. We skip this for logical providers as they 446 * do not affect mechanisms. 447 */ 448 if (desc->pd_prov_type != CRYPTO_LOGICAL_PROVIDER) { 449 ec.ec_provider_type = desc->pd_prov_type; 450 ec.ec_change = CRYPTO_MECH_REMOVED; 451 for (i = 0; i < desc->pd_mech_list_count; i++) { 452 /* Skip any mechanisms not allowed by the policy */ 453 if (is_mech_disabled(desc, 454 desc->pd_mechanisms[i].cm_mech_name)) 455 continue; 456 457 (void) strncpy(ec.ec_mech_name, 458 desc->pd_mechanisms[i].cm_mech_name, 459 CRYPTO_MAX_MECH_NAME); 460 kcf_walk_ntfylist(CRYPTO_EVENT_MECHS_CHANGED, &ec); 461 } 462 463 } 464 465 /* 466 * Inform interested clients about the departing provider. 467 * In case of a logical provider, we need to notify the event only 468 * for the logical provider and not for the underlying 469 * providers which are known by the KCF_LPROV_MEMBER bit. 470 */ 471 if (desc->pd_prov_type == CRYPTO_LOGICAL_PROVIDER || 472 (desc->pd_flags & KCF_LPROV_MEMBER) == 0) 473 kcf_walk_ntfylist(CRYPTO_EVENT_PROVIDER_UNREGISTERED, desc); 474 475 if (desc->pd_prov_type == CRYPTO_SW_PROVIDER) { 476 /* 477 * This is the only place where kcf_free_provider_desc() 478 * is called directly. KCF_PROV_REFRELE() should free the 479 * structure in all other places. 480 */ 481 ASSERT(desc->pd_state == KCF_PROV_FREED && 482 desc->pd_refcnt == 0); 483 kcf_free_provider_desc(desc); 484 } else { 485 KCF_PROV_REFRELE(desc); 486 } 487 488 return (CRYPTO_SUCCESS); 489 } 490 491 /* 492 * This routine is used to notify the framework that the state of 493 * a cryptographic provider has changed. Valid state codes are: 494 * 495 * CRYPTO_PROVIDER_READY 496 * The provider indicates that it can process more requests. A provider 497 * will notify with this event if it previously has notified us with a 498 * CRYPTO_PROVIDER_BUSY. 499 * 500 * CRYPTO_PROVIDER_BUSY 501 * The provider can not take more requests. 502 * 503 * CRYPTO_PROVIDER_FAILED 504 * The provider encountered an internal error. The framework will not 505 * be sending any more requests to the provider. The provider may notify 506 * with a CRYPTO_PROVIDER_READY, if it is able to recover from the error. 507 * 508 * This routine can be called from user or interrupt context. 509 */ 510 void 511 crypto_provider_notification(crypto_kcf_provider_handle_t handle, uint_t state) 512 { 513 kcf_provider_desc_t *pd; 514 515 /* lookup the provider from the given handle */ 516 if ((pd = kcf_prov_tab_lookup((crypto_provider_id_t)handle)) == NULL) 517 return; 518 519 mutex_enter(&pd->pd_lock); 520 521 if (pd->pd_prov_type == CRYPTO_LOGICAL_PROVIDER) { 522 cmn_err(CE_WARN, "crypto_provider_notification: " 523 "logical provider (%x) ignored\n", handle); 524 goto out; 525 } 526 switch (state) { 527 case CRYPTO_PROVIDER_READY: 528 switch (pd->pd_state) { 529 case KCF_PROV_BUSY: 530 pd->pd_state = KCF_PROV_READY; 531 /* 532 * Signal the per-provider taskq thread that it 533 * can start submitting requests. Note that we do 534 * not need a cv_broadcast() as we keep only a 535 * single thread per taskq. 536 */ 537 cv_signal(&pd->pd_resume_cv); 538 break; 539 540 case KCF_PROV_FAILED: 541 /* 542 * The provider recovered from the error. Let us 543 * use it now. 544 */ 545 pd->pd_state = KCF_PROV_READY; 546 break; 547 } 548 break; 549 550 case CRYPTO_PROVIDER_BUSY: 551 switch (pd->pd_state) { 552 case KCF_PROV_READY: 553 pd->pd_state = KCF_PROV_BUSY; 554 break; 555 } 556 break; 557 558 case CRYPTO_PROVIDER_FAILED: 559 /* 560 * We note the failure and return. The per-provider taskq 561 * thread checks this flag and starts failing the 562 * requests, if it is set. See process_req_hwp() for details. 563 */ 564 switch (pd->pd_state) { 565 case KCF_PROV_READY: 566 pd->pd_state = KCF_PROV_FAILED; 567 break; 568 569 case KCF_PROV_BUSY: 570 pd->pd_state = KCF_PROV_FAILED; 571 /* 572 * The per-provider taskq thread may be waiting. We 573 * signal it so that it can start failing requests. 574 */ 575 cv_signal(&pd->pd_resume_cv); 576 break; 577 } 578 break; 579 } 580 out: 581 mutex_exit(&pd->pd_lock); 582 KCF_PROV_REFRELE(pd); 583 } 584 585 /* 586 * This routine is used to notify the framework the result of 587 * an asynchronous request handled by a provider. Valid error 588 * codes are the same as the CRYPTO_* errors defined in common.h. 589 * 590 * This routine can be called from user or interrupt context. 591 */ 592 void 593 crypto_op_notification(crypto_req_handle_t handle, int error) 594 { 595 kcf_call_type_t ctype; 596 597 if ((ctype = GET_REQ_TYPE(handle)) == CRYPTO_SYNCH) { 598 kcf_sreq_node_t *sreq = (kcf_sreq_node_t *)handle; 599 600 if (error != CRYPTO_SUCCESS) 601 sreq->sn_provider->pd_sched_info.ks_nfails++; 602 KCF_PROV_IREFRELE(sreq->sn_provider); 603 kcf_sop_done(sreq, error); 604 } else { 605 kcf_areq_node_t *areq = (kcf_areq_node_t *)handle; 606 607 ASSERT(ctype == CRYPTO_ASYNCH); 608 if (error != CRYPTO_SUCCESS) 609 areq->an_provider->pd_sched_info.ks_nfails++; 610 KCF_PROV_IREFRELE(areq->an_provider); 611 kcf_aop_done(areq, error); 612 } 613 } 614 615 /* 616 * This routine is used by software providers to determine 617 * whether to use KM_SLEEP or KM_NOSLEEP during memory allocation. 618 * Note that hardware providers can always use KM_SLEEP. So, 619 * they do not need to call this routine. 620 * 621 * This routine can be called from user or interrupt context. 622 */ 623 int 624 crypto_kmflag(crypto_req_handle_t handle) 625 { 626 return (REQHNDL2_KMFLAG(handle)); 627 } 628 629 630 /* 631 * Copy an ops vector from src to dst. Used during provider registration 632 * to copy the ops vector from the provider info structure to the 633 * provider descriptor maintained by KCF. 634 * Copying the ops vector specified by the provider is needed since the 635 * framework does not require the provider info structure to be 636 * persistent. 637 */ 638 static void 639 copy_ops_vector_v1(crypto_ops_t *src_ops, crypto_ops_t *dst_ops) 640 { 641 KCF_SPI_COPY_OPS(src_ops, dst_ops, co_control_ops); 642 KCF_SPI_COPY_OPS(src_ops, dst_ops, co_digest_ops); 643 KCF_SPI_COPY_OPS(src_ops, dst_ops, co_cipher_ops); 644 KCF_SPI_COPY_OPS(src_ops, dst_ops, co_mac_ops); 645 KCF_SPI_COPY_OPS(src_ops, dst_ops, co_sign_ops); 646 KCF_SPI_COPY_OPS(src_ops, dst_ops, co_verify_ops); 647 KCF_SPI_COPY_OPS(src_ops, dst_ops, co_dual_ops); 648 KCF_SPI_COPY_OPS(src_ops, dst_ops, co_dual_cipher_mac_ops); 649 KCF_SPI_COPY_OPS(src_ops, dst_ops, co_random_ops); 650 KCF_SPI_COPY_OPS(src_ops, dst_ops, co_session_ops); 651 KCF_SPI_COPY_OPS(src_ops, dst_ops, co_object_ops); 652 KCF_SPI_COPY_OPS(src_ops, dst_ops, co_key_ops); 653 KCF_SPI_COPY_OPS(src_ops, dst_ops, co_provider_ops); 654 KCF_SPI_COPY_OPS(src_ops, dst_ops, co_ctx_ops); 655 } 656 657 static void 658 copy_ops_vector_v2(crypto_ops_t *src_ops, crypto_ops_t *dst_ops) 659 { 660 KCF_SPI_COPY_OPS(src_ops, dst_ops, co_mech_ops); 661 } 662 663 /* 664 * Process the mechanism info structures specified by the provider 665 * during registration. A NULL crypto_provider_info_t indicates 666 * an already initialized provider descriptor. 667 * 668 * Mechanisms are not added to the kernel's mechanism table if the 669 * provider is a logical provider. 670 * 671 * Returns CRYPTO_SUCCESS on success, CRYPTO_ARGUMENTS if one 672 * of the specified mechanisms was malformed, or CRYPTO_HOST_MEMORY 673 * if the table of mechanisms is full. 674 */ 675 static int 676 init_prov_mechs(crypto_provider_info_t *info, kcf_provider_desc_t *desc) 677 { 678 uint_t mech_idx; 679 uint_t cleanup_idx; 680 int err = CRYPTO_SUCCESS; 681 kcf_prov_mech_desc_t *pmd; 682 int desc_use_count = 0; 683 int mcount = desc->pd_mech_list_count; 684 685 if (desc->pd_prov_type == CRYPTO_LOGICAL_PROVIDER) { 686 if (info != NULL) { 687 ASSERT(info->pi_mechanisms != NULL); 688 bcopy(info->pi_mechanisms, desc->pd_mechanisms, 689 sizeof (crypto_mech_info_t) * mcount); 690 } 691 return (CRYPTO_SUCCESS); 692 } 693 694 /* 695 * Copy the mechanism list from the provider info to the provider 696 * descriptor. desc->pd_mechanisms has an extra crypto_mech_info_t 697 * element if the provider has random_ops since we keep an internal 698 * mechanism, SUN_RANDOM, in this case. 699 */ 700 if (info != NULL) { 701 if (info->pi_ops_vector->co_random_ops != NULL) { 702 crypto_mech_info_t *rand_mi; 703 704 /* 705 * Need the following check as it is possible to have 706 * a provider that implements just random_ops and has 707 * pi_mechanisms == NULL. 708 */ 709 if (info->pi_mechanisms != NULL) { 710 bcopy(info->pi_mechanisms, desc->pd_mechanisms, 711 sizeof (crypto_mech_info_t) * (mcount - 1)); 712 } 713 rand_mi = &desc->pd_mechanisms[mcount - 1]; 714 715 bzero(rand_mi, sizeof (crypto_mech_info_t)); 716 (void) strncpy(rand_mi->cm_mech_name, SUN_RANDOM, 717 CRYPTO_MAX_MECH_NAME); 718 rand_mi->cm_func_group_mask = CRYPTO_FG_RANDOM; 719 } else { 720 ASSERT(info->pi_mechanisms != NULL); 721 bcopy(info->pi_mechanisms, desc->pd_mechanisms, 722 sizeof (crypto_mech_info_t) * mcount); 723 } 724 } 725 726 /* 727 * For each mechanism support by the provider, add the provider 728 * to the corresponding KCF mechanism mech_entry chain. 729 */ 730 for (mech_idx = 0; mech_idx < desc->pd_mech_list_count; mech_idx++) { 731 crypto_mech_info_t *mi = &desc->pd_mechanisms[mech_idx]; 732 733 if ((mi->cm_mech_flags & CRYPTO_KEYSIZE_UNIT_IN_BITS) && 734 (mi->cm_mech_flags & CRYPTO_KEYSIZE_UNIT_IN_BYTES)) { 735 err = CRYPTO_ARGUMENTS_BAD; 736 break; 737 } 738 739 if (kcf_add_mech_provider(mech_idx, desc, &pmd) != KCF_SUCCESS) 740 break; 741 742 if (pmd == NULL) 743 continue; 744 745 /* The provider will be used for this mechanism */ 746 desc_use_count++; 747 } 748 749 /* 750 * Don't allow multiple software providers with disabled mechanisms 751 * to register. Subsequent enabling of mechanisms will result in 752 * an unsupported configuration, i.e. multiple software providers 753 * per mechanism. 754 */ 755 if (desc_use_count == 0 && desc->pd_prov_type == CRYPTO_SW_PROVIDER) 756 return (CRYPTO_ARGUMENTS_BAD); 757 758 if (err == KCF_SUCCESS) 759 return (CRYPTO_SUCCESS); 760 761 /* 762 * An error occurred while adding the mechanism, cleanup 763 * and bail. 764 */ 765 for (cleanup_idx = 0; cleanup_idx < mech_idx; cleanup_idx++) { 766 kcf_remove_mech_provider( 767 desc->pd_mechanisms[cleanup_idx].cm_mech_name, desc); 768 } 769 770 if (err == KCF_MECH_TAB_FULL) 771 return (CRYPTO_HOST_MEMORY); 772 773 return (CRYPTO_ARGUMENTS_BAD); 774 } 775 776 /* 777 * Update routine for kstat. Only privileged users are allowed to 778 * access this information, since this information is sensitive. 779 * There are some cryptographic attacks (e.g. traffic analysis) 780 * which can use this information. 781 */ 782 static int 783 kcf_prov_kstat_update(kstat_t *ksp, int rw) 784 { 785 kcf_prov_stats_t *ks_data; 786 kcf_provider_desc_t *pd = (kcf_provider_desc_t *)ksp->ks_private; 787 788 if (rw == KSTAT_WRITE) 789 return (EACCES); 790 791 ks_data = ksp->ks_data; 792 793 if (secpolicy_sys_config(CRED(), B_TRUE) != 0) { 794 ks_data->ps_ops_total.value.ui64 = 0; 795 ks_data->ps_ops_passed.value.ui64 = 0; 796 ks_data->ps_ops_failed.value.ui64 = 0; 797 ks_data->ps_ops_busy_rval.value.ui64 = 0; 798 } else { 799 ks_data->ps_ops_total.value.ui64 = 800 pd->pd_sched_info.ks_ndispatches; 801 ks_data->ps_ops_failed.value.ui64 = 802 pd->pd_sched_info.ks_nfails; 803 ks_data->ps_ops_busy_rval.value.ui64 = 804 pd->pd_sched_info.ks_nbusy_rval; 805 ks_data->ps_ops_passed.value.ui64 = 806 pd->pd_sched_info.ks_ndispatches - 807 pd->pd_sched_info.ks_nfails - 808 pd->pd_sched_info.ks_nbusy_rval; 809 } 810 811 return (0); 812 } 813 814 815 /* 816 * Utility routine called from failure paths in crypto_register_provider() 817 * and from crypto_load_soft_disabled(). 818 */ 819 void 820 undo_register_provider(kcf_provider_desc_t *desc, boolean_t remove_prov) 821 { 822 uint_t mech_idx; 823 824 /* remove the provider from the mechanisms tables */ 825 for (mech_idx = 0; mech_idx < desc->pd_mech_list_count; 826 mech_idx++) { 827 kcf_remove_mech_provider( 828 desc->pd_mechanisms[mech_idx].cm_mech_name, desc); 829 } 830 831 /* remove provider from providers table */ 832 if (remove_prov) 833 (void) kcf_prov_tab_rem_provider(desc->pd_prov_id); 834 } 835 836 /* 837 * Utility routine called from crypto_load_soft_disabled(). Callers 838 * should have done a prior undo_register_provider(). 839 */ 840 void 841 redo_register_provider(kcf_provider_desc_t *pd) 842 { 843 /* process the mechanisms supported by the provider */ 844 (void) init_prov_mechs(NULL, pd); 845 846 /* 847 * Hold provider in providers table. We should not call 848 * kcf_prov_tab_add_provider() here as the provider descriptor 849 * is still valid which means it has an entry in the provider 850 * table. 851 */ 852 KCF_PROV_REFHOLD(pd); 853 KCF_PROV_IREFHOLD(pd); 854 } 855 856 /* 857 * Add provider (p1) to another provider's array of providers (p2). 858 * Hardware and logical providers use this array to cross-reference 859 * each other. 860 */ 861 static void 862 add_provider_to_array(kcf_provider_desc_t *p1, kcf_provider_desc_t *p2) 863 { 864 kcf_provider_list_t *new; 865 866 new = kmem_alloc(sizeof (kcf_provider_list_t), KM_SLEEP); 867 mutex_enter(&p2->pd_lock); 868 new->pl_next = p2->pd_provider_list; 869 p2->pd_provider_list = new; 870 KCF_PROV_IREFHOLD(p1); 871 new->pl_provider = p1; 872 mutex_exit(&p2->pd_lock); 873 } 874 875 /* 876 * Remove provider (p1) from another provider's array of providers (p2). 877 * Hardware and logical providers use this array to cross-reference 878 * each other. 879 */ 880 static void 881 remove_provider_from_array(kcf_provider_desc_t *p1, kcf_provider_desc_t *p2) 882 { 883 884 kcf_provider_list_t *pl = NULL, **prev; 885 886 mutex_enter(&p2->pd_lock); 887 for (pl = p2->pd_provider_list, prev = &p2->pd_provider_list; 888 pl != NULL; prev = &pl->pl_next, pl = pl->pl_next) { 889 if (pl->pl_provider == p1) { 890 break; 891 } 892 } 893 894 if (p1 == NULL) { 895 mutex_exit(&p2->pd_lock); 896 return; 897 } 898 899 /* detach and free kcf_provider_list structure */ 900 KCF_PROV_IREFRELE(p1); 901 *prev = pl->pl_next; 902 kmem_free(pl, sizeof (*pl)); 903 mutex_exit(&p2->pd_lock); 904 } 905 906 /* 907 * Convert an array of logical provider handles (crypto_provider_id) 908 * stored in a crypto_provider_info structure into an array of provider 909 * descriptors (kcf_provider_desc_t) attached to a logical provider. 910 */ 911 static void 912 process_logical_providers(crypto_provider_info_t *info, kcf_provider_desc_t *hp) 913 { 914 kcf_provider_desc_t *lp; 915 crypto_provider_id_t handle; 916 int count = info->pi_logical_provider_count; 917 int i; 918 919 /* add hardware provider to each logical provider */ 920 for (i = 0; i < count; i++) { 921 handle = info->pi_logical_providers[i]; 922 lp = kcf_prov_tab_lookup((crypto_provider_id_t)handle); 923 if (lp == NULL) { 924 continue; 925 } 926 add_provider_to_array(hp, lp); 927 hp->pd_flags |= KCF_LPROV_MEMBER; 928 929 /* 930 * A hardware provider has to have the provider descriptor of 931 * every logical provider it belongs to, so it can be removed 932 * from the logical provider if the hardware provider 933 * unregisters from the framework. 934 */ 935 add_provider_to_array(lp, hp); 936 KCF_PROV_REFRELE(lp); 937 } 938 } 939 940 /* 941 * This routine removes a provider from all of the logical or 942 * hardware providers it belongs to, and frees the provider's 943 * array of pointers to providers. 944 */ 945 static void 946 remove_provider(kcf_provider_desc_t *pp) 947 { 948 kcf_provider_desc_t *p; 949 kcf_provider_list_t *e, *next; 950 951 mutex_enter(&pp->pd_lock); 952 for (e = pp->pd_provider_list; e != NULL; e = next) { 953 p = e->pl_provider; 954 remove_provider_from_array(pp, p); 955 if (p->pd_prov_type == CRYPTO_HW_PROVIDER && 956 p->pd_provider_list == NULL) 957 p->pd_flags &= ~KCF_LPROV_MEMBER; 958 KCF_PROV_IREFRELE(p); 959 next = e->pl_next; 960 kmem_free(e, sizeof (*e)); 961 } 962 pp->pd_provider_list = NULL; 963 mutex_exit(&pp->pd_lock); 964 } 965