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