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 contains routines which call into a provider's 30 * entry points and do other related work. 31 */ 32 33 #include <sys/types.h> 34 #include <sys/systm.h> 35 #include <sys/taskq_impl.h> 36 #include <sys/cmn_err.h> 37 38 #include <sys/crypto/common.h> 39 #include <sys/crypto/impl.h> 40 #include <sys/crypto/sched_impl.h> 41 42 /* 43 * Return B_TRUE if the specified entry point is NULL. We rely on the 44 * caller to provide, with offset_1 and offset_2, information to calculate 45 * the location of the entry point. The ops argument is a temporary local 46 * variable defined as caddr_t *. 47 */ 48 #define KCF_PROV_NULL_ENTRY_POINT(pd, o1, o2, ops) \ 49 (ops = (caddr_t *)((caddr_t)(pd)->pd_ops_vector + (o1)), \ 50 (*ops == NULL || *(caddr_t *)((caddr_t)(*ops) + (o2)) == NULL)) 51 52 53 static int kcf_emulate_dual(kcf_provider_desc_t *, crypto_ctx_t *, 54 kcf_req_params_t *); 55 void 56 kcf_free_triedlist(kcf_prov_tried_t *list) 57 { 58 kcf_prov_tried_t *l; 59 60 while ((l = list) != NULL) { 61 list = list->pt_next; 62 KCF_PROV_REFRELE(l->pt_pd); 63 kmem_free(l, sizeof (kcf_prov_tried_t)); 64 } 65 } 66 67 kcf_prov_tried_t * 68 kcf_insert_triedlist(kcf_prov_tried_t **list, kcf_provider_desc_t *pd, 69 int kmflag) 70 { 71 kcf_prov_tried_t *l; 72 73 l = kmem_alloc(sizeof (kcf_prov_tried_t), kmflag); 74 if (l == NULL) 75 return (NULL); 76 77 l->pt_pd = pd; 78 l->pt_next = *list; 79 *list = l; 80 81 return (l); 82 } 83 84 static boolean_t 85 is_in_triedlist(kcf_provider_desc_t *pd, kcf_prov_tried_t *triedl) 86 { 87 while (triedl != NULL) { 88 if (triedl->pt_pd == pd) 89 return (B_TRUE); 90 triedl = triedl->pt_next; 91 }; 92 93 return (B_FALSE); 94 } 95 96 /* 97 * Search a mech entry's hardware provider list for the specified 98 * provider. Return true if found. 99 */ 100 static boolean_t 101 is_valid_provider_for_mech(kcf_provider_desc_t *pd, kcf_mech_entry_t *me, 102 crypto_func_group_t fg) 103 { 104 kcf_prov_mech_desc_t *prov_chain; 105 106 prov_chain = me->me_hw_prov_chain; 107 if (prov_chain != NULL) { 108 ASSERT(me->me_num_hwprov > 0); 109 for (; prov_chain != NULL; prov_chain = prov_chain->pm_next) { 110 if (prov_chain->pm_prov_desc == pd && 111 IS_FG_SUPPORTED(prov_chain, fg)) { 112 return (B_TRUE); 113 } 114 } 115 } 116 return (B_FALSE); 117 } 118 119 /* 120 * This routine, given a logical provider, returns the least loaded 121 * provider belonging to the logical provider. The provider must be 122 * able to do the specified mechanism, i.e. check that the mechanism 123 * hasn't been disabled. In addition, just in case providers are not 124 * entirely equivalent, the provider's entry point is checked for 125 * non-nullness. This is accomplished by having the caller pass, as 126 * arguments, the offset of the function group (offset_1), and the 127 * offset of the function within the function group (offset_2). 128 * Returns NULL if no provider can be found. 129 */ 130 int 131 kcf_get_hardware_provider(crypto_mech_type_t mech_type_1, 132 crypto_mech_type_t mech_type_2, boolean_t call_restrict, 133 kcf_provider_desc_t *old, kcf_provider_desc_t **new, crypto_func_group_t fg) 134 { 135 kcf_provider_desc_t *provider, *real_pd = old; 136 kcf_provider_desc_t *gpd = NULL; /* good provider */ 137 kcf_provider_desc_t *bpd = NULL; /* busy provider */ 138 kcf_provider_list_t *p; 139 kcf_ops_class_t class; 140 kcf_mech_entry_t *me; 141 kcf_mech_entry_tab_t *me_tab; 142 int index, len, gqlen = INT_MAX, rv = CRYPTO_SUCCESS; 143 144 /* get the mech entry for the specified mechanism */ 145 class = KCF_MECH2CLASS(mech_type_1); 146 if ((class < KCF_FIRST_OPSCLASS) || (class > KCF_LAST_OPSCLASS)) { 147 return (CRYPTO_MECHANISM_INVALID); 148 } 149 150 me_tab = &kcf_mech_tabs_tab[class]; 151 index = KCF_MECH2INDEX(mech_type_1); 152 if ((index < 0) || (index >= me_tab->met_size)) { 153 return (CRYPTO_MECHANISM_INVALID); 154 } 155 156 me = &((me_tab->met_tab)[index]); 157 mutex_enter(&me->me_mutex); 158 159 /* 160 * We assume the provider descriptor will not go away because 161 * it is being held somewhere, i.e. its reference count has been 162 * incremented. In the case of the crypto module, the provider 163 * descriptor is held by the session structure. 164 */ 165 if (old->pd_prov_type == CRYPTO_LOGICAL_PROVIDER) { 166 if (old->pd_provider_list == NULL) { 167 real_pd = NULL; 168 rv = CRYPTO_DEVICE_ERROR; 169 goto out; 170 } 171 /* 172 * Find the least loaded real provider. tq_nalloc gives 173 * the number of task entries in the task queue. We do 174 * not acquire tq_lock here as it is not critical to 175 * get the exact number and the lock contention may be 176 * too costly for this code path. 177 */ 178 mutex_enter(&old->pd_lock); 179 p = old->pd_provider_list; 180 while (p != NULL) { 181 provider = p->pl_provider; 182 183 ASSERT(provider->pd_prov_type != 184 CRYPTO_LOGICAL_PROVIDER); 185 186 if (call_restrict && 187 (provider->pd_flags & KCF_PROV_RESTRICTED)) { 188 p = p->pl_next; 189 continue; 190 } 191 192 if (!is_valid_provider_for_mech(provider, me, fg)) { 193 p = p->pl_next; 194 continue; 195 } 196 197 /* provider does second mech */ 198 if (mech_type_2 != CRYPTO_MECH_INVALID) { 199 int i; 200 201 i = KCF_TO_PROV_MECH_INDX(provider, 202 mech_type_2); 203 if (i == KCF_INVALID_INDX) { 204 p = p->pl_next; 205 continue; 206 } 207 } 208 209 if (provider->pd_state != KCF_PROV_READY) { 210 /* choose BUSY if no READY providers */ 211 if (provider->pd_state == KCF_PROV_BUSY) 212 bpd = provider; 213 p = p->pl_next; 214 continue; 215 } 216 217 len = provider->pd_sched_info.ks_taskq->tq_nalloc; 218 if (len < gqlen) { 219 gqlen = len; 220 gpd = provider; 221 } 222 223 p = p->pl_next; 224 } 225 226 if (gpd != NULL) { 227 real_pd = gpd; 228 KCF_PROV_REFHOLD(real_pd); 229 } else if (bpd != NULL) { 230 real_pd = bpd; 231 KCF_PROV_REFHOLD(real_pd); 232 } else { 233 /* can't find provider */ 234 real_pd = NULL; 235 rv = CRYPTO_MECHANISM_INVALID; 236 } 237 mutex_exit(&old->pd_lock); 238 239 } else { 240 if (!KCF_IS_PROV_USABLE(old) || 241 (call_restrict && (old->pd_flags & KCF_PROV_RESTRICTED))) { 242 real_pd = NULL; 243 rv = CRYPTO_DEVICE_ERROR; 244 goto out; 245 } 246 247 if (!is_valid_provider_for_mech(old, me, fg)) { 248 real_pd = NULL; 249 rv = CRYPTO_MECHANISM_INVALID; 250 goto out; 251 } 252 253 KCF_PROV_REFHOLD(real_pd); 254 } 255 out: 256 mutex_exit(&me->me_mutex); 257 *new = real_pd; 258 return (rv); 259 } 260 261 /* 262 * This routine, given a logical provider, returns the least loaded 263 * provider belonging to the logical provider. Just in case providers 264 * are not entirely equivalent, the provider's entry point is checked 265 * for non-nullness. This is accomplished by having the caller pass, as 266 * arguments, the offset of the function group (offset_1), and the 267 * offset of the function within the function group (offset_2). 268 * Returns NULL if no provider can be found. 269 */ 270 int 271 kcf_get_hardware_provider_nomech(offset_t offset_1, offset_t offset_2, 272 boolean_t call_restrict, kcf_provider_desc_t *old, 273 kcf_provider_desc_t **new) 274 { 275 kcf_provider_desc_t *provider, *real_pd = old; 276 kcf_provider_desc_t *gpd = NULL; /* good provider */ 277 kcf_provider_desc_t *bpd = NULL; /* busy provider */ 278 kcf_provider_list_t *p; 279 caddr_t *ops; 280 int len, gqlen = INT_MAX, rv = CRYPTO_SUCCESS; 281 282 /* 283 * We assume the provider descriptor will not go away because 284 * it is being held somewhere, i.e. its reference count has been 285 * incremented. In the case of the crypto module, the provider 286 * descriptor is held by the session structure. 287 */ 288 if (old->pd_prov_type == CRYPTO_LOGICAL_PROVIDER) { 289 if (old->pd_provider_list == NULL) { 290 real_pd = NULL; 291 rv = CRYPTO_DEVICE_ERROR; 292 goto out; 293 } 294 /* 295 * Find the least loaded real provider. tq_nalloc gives 296 * the number of task entries in the task queue. We do 297 * not acquire tq_lock here as it is not critical to 298 * get the exact number and the lock contention may be 299 * too costly for this code path. 300 */ 301 mutex_enter(&old->pd_lock); 302 p = old->pd_provider_list; 303 while (p != NULL) { 304 provider = p->pl_provider; 305 306 ASSERT(provider->pd_prov_type != 307 CRYPTO_LOGICAL_PROVIDER); 308 309 if (call_restrict && 310 (provider->pd_flags & KCF_PROV_RESTRICTED)) { 311 p = p->pl_next; 312 continue; 313 } 314 if (KCF_PROV_NULL_ENTRY_POINT(provider, offset_1, 315 offset_2, ops)) { 316 p = p->pl_next; 317 continue; 318 } 319 320 if (provider->pd_state != KCF_PROV_READY) { 321 /* choose BUSY if no READY providers */ 322 if (provider->pd_state == KCF_PROV_BUSY) 323 bpd = provider; 324 p = p->pl_next; 325 continue; 326 } 327 328 len = provider->pd_sched_info.ks_taskq->tq_nalloc; 329 if (len < gqlen) { 330 gqlen = len; 331 gpd = provider; 332 } 333 334 p = p->pl_next; 335 } 336 mutex_exit(&old->pd_lock); 337 338 if (gpd != NULL) { 339 real_pd = gpd; 340 KCF_PROV_REFHOLD(real_pd); 341 } else if (bpd != NULL) { 342 real_pd = bpd; 343 KCF_PROV_REFHOLD(real_pd); 344 } else { 345 /* can't find provider */ 346 real_pd = NULL; 347 rv = CRYPTO_DEVICE_ERROR; 348 } 349 350 } else { 351 if (!KCF_IS_PROV_USABLE(old) || 352 (call_restrict && (old->pd_flags & KCF_PROV_RESTRICTED))) { 353 real_pd = NULL; 354 rv = CRYPTO_DEVICE_ERROR; 355 goto out; 356 } 357 358 if (KCF_PROV_NULL_ENTRY_POINT(old, offset_1, offset_2, ops)) { 359 real_pd = NULL; 360 rv = CRYPTO_NOT_SUPPORTED; 361 goto out; 362 } 363 KCF_PROV_REFHOLD(real_pd); 364 } 365 out: 366 *new = real_pd; 367 return (rv); 368 } 369 370 /* 371 * Return the next member of a logical provider, given the previous 372 * member. The function returns true if the next member is found and 373 * bumps its refcnt before returning. 374 */ 375 boolean_t 376 kcf_get_next_logical_provider_member(kcf_provider_desc_t *logical_provider, 377 kcf_provider_desc_t *prev, kcf_provider_desc_t **pd) 378 { 379 kcf_provider_list_t *p; 380 kcf_provider_desc_t *next; 381 382 ASSERT(MUTEX_HELD(&logical_provider->pd_lock)); 383 p = logical_provider->pd_provider_list; 384 while (p != NULL) { 385 /* start the search */ 386 if (prev == NULL) { 387 next = p->pl_provider; 388 goto found; 389 } else { 390 /* find where we were before */ 391 if (p->pl_provider == prev) { 392 if (p->pl_next != NULL) { 393 next = p->pl_next->pl_provider; 394 goto found; 395 } 396 } 397 } 398 p = p->pl_next; 399 } 400 return (B_FALSE); 401 402 found: 403 KCF_PROV_REFHOLD(next); 404 *pd = next; 405 return (B_TRUE); 406 } 407 408 /* 409 * Return the best provider for the specified mechanism. The provider 410 * is held and it is the caller's responsibility to release it when done. 411 * The fg input argument is used as a search criterion to pick a provider. 412 * A provider has to support this function group to be picked. 413 * 414 * Find the least loaded provider in the list of providers. We do a linear 415 * search to find one. This is fine as we assume there are only a few 416 * number of providers in this list. If this assumption ever changes, 417 * we should revisit this. 418 * 419 * call_restrict represents if the caller should not be allowed to 420 * use restricted providers. 421 */ 422 kcf_provider_desc_t * 423 kcf_get_mech_provider(crypto_mech_type_t mech_type, kcf_mech_entry_t **mepp, 424 int *error, kcf_prov_tried_t *triedl, crypto_func_group_t fg, 425 boolean_t call_restrict, size_t data_size) 426 { 427 kcf_provider_desc_t *pd = NULL, *gpd = NULL; 428 kcf_prov_mech_desc_t *prov_chain, *mdesc; 429 int len, gqlen = INT_MAX; 430 kcf_ops_class_t class; 431 int index; 432 kcf_mech_entry_t *me; 433 kcf_mech_entry_tab_t *me_tab; 434 435 class = KCF_MECH2CLASS(mech_type); 436 if ((class < KCF_FIRST_OPSCLASS) || (class > KCF_LAST_OPSCLASS)) { 437 *error = CRYPTO_MECHANISM_INVALID; 438 return (NULL); 439 } 440 441 me_tab = &kcf_mech_tabs_tab[class]; 442 index = KCF_MECH2INDEX(mech_type); 443 if ((index < 0) || (index >= me_tab->met_size)) { 444 *error = CRYPTO_MECHANISM_INVALID; 445 return (NULL); 446 } 447 448 me = &((me_tab->met_tab)[index]); 449 if (mepp != NULL) 450 *mepp = me; 451 452 mutex_enter(&me->me_mutex); 453 454 prov_chain = me->me_hw_prov_chain; 455 456 /* 457 * We check for the threshhold for using a hardware provider for 458 * this amount of data. If there is no software provider available 459 * for the mechanism, then the threshold is ignored. 460 */ 461 if ((prov_chain != NULL) && 462 ((data_size == 0) || (me->me_threshold == 0) || 463 (data_size >= me->me_threshold) || 464 ((mdesc = me->me_sw_prov) == NULL) || 465 (!IS_FG_SUPPORTED(mdesc, fg)) || 466 (!KCF_IS_PROV_USABLE(mdesc->pm_prov_desc)))) { 467 ASSERT(me->me_num_hwprov > 0); 468 /* there is at least one provider */ 469 470 /* 471 * Find the least loaded provider. tq_nalloc gives 472 * the number of task entries in the task queue. We do 473 * not acquire tq_lock here as it is not critical to 474 * get the exact number and the lock contention may be 475 * too costly for this code path. 476 */ 477 while (prov_chain != NULL) { 478 pd = prov_chain->pm_prov_desc; 479 480 if (!IS_FG_SUPPORTED(prov_chain, fg) || 481 !KCF_IS_PROV_USABLE(pd) || 482 IS_PROVIDER_TRIED(pd, triedl) || 483 (call_restrict && 484 (pd->pd_flags & KCF_PROV_RESTRICTED))) { 485 prov_chain = prov_chain->pm_next; 486 continue; 487 } 488 489 if ((len = pd->pd_sched_info.ks_taskq->tq_nalloc) 490 < gqlen) { 491 gqlen = len; 492 gpd = pd; 493 } 494 495 prov_chain = prov_chain->pm_next; 496 } 497 498 pd = gpd; 499 } 500 501 /* No HW provider for this mech, is there a SW provider? */ 502 if (pd == NULL && (mdesc = me->me_sw_prov) != NULL) { 503 pd = mdesc->pm_prov_desc; 504 if (!IS_FG_SUPPORTED(mdesc, fg) || 505 !KCF_IS_PROV_USABLE(pd) || 506 IS_PROVIDER_TRIED(pd, triedl) || 507 (call_restrict && (pd->pd_flags & KCF_PROV_RESTRICTED))) 508 pd = NULL; 509 } 510 511 if (pd == NULL) { 512 /* 513 * We do not want to report CRYPTO_MECH_NOT_SUPPORTED, when 514 * we are in the "fallback to the next provider" case. Rather 515 * we preserve the error, so that the client gets the right 516 * error code. 517 */ 518 if (triedl == NULL) 519 *error = CRYPTO_MECH_NOT_SUPPORTED; 520 } else 521 KCF_PROV_REFHOLD(pd); 522 523 mutex_exit(&me->me_mutex); 524 return (pd); 525 } 526 527 /* 528 * Very similar to kcf_get_mech_provider(). Finds the best provider capable of 529 * a dual operation with both me1 and me2. 530 * When no dual-ops capable providers are available, return the best provider 531 * for me1 only, and sets *prov_mt2 to CRYPTO_INVALID_MECHID; 532 * We assume/expect that a slower HW capable of the dual is still 533 * faster than the 2 fastest providers capable of the individual ops 534 * separately. 535 */ 536 kcf_provider_desc_t * 537 kcf_get_dual_provider(crypto_mechanism_t *mech1, crypto_mechanism_t *mech2, 538 kcf_mech_entry_t **mepp, crypto_mech_type_t *prov_mt1, 539 crypto_mech_type_t *prov_mt2, int *error, kcf_prov_tried_t *triedl, 540 crypto_func_group_t fg1, crypto_func_group_t fg2, boolean_t call_restrict, 541 size_t data_size) 542 { 543 kcf_provider_desc_t *pd = NULL, *pdm1 = NULL, *pdm1m2 = NULL; 544 kcf_prov_mech_desc_t *prov_chain, *mdesc; 545 int len, gqlen = INT_MAX, dgqlen = INT_MAX; 546 crypto_mech_info_list_t *mil; 547 crypto_mech_type_t m2id = mech2->cm_type; 548 kcf_mech_entry_t *me; 549 550 /* when mech is a valid mechanism, me will be its mech_entry */ 551 if (kcf_get_mech_entry(mech1->cm_type, &me) != KCF_SUCCESS) { 552 *error = CRYPTO_MECHANISM_INVALID; 553 return (NULL); 554 } 555 556 *prov_mt2 = CRYPTO_MECH_INVALID; 557 558 if (mepp != NULL) 559 *mepp = me; 560 mutex_enter(&me->me_mutex); 561 562 prov_chain = me->me_hw_prov_chain; 563 /* 564 * We check the threshold for using a hardware provider for 565 * this amount of data. If there is no software provider available 566 * for the first mechanism, then the threshold is ignored. 567 */ 568 if ((prov_chain != NULL) && 569 ((data_size == 0) || (me->me_threshold == 0) || 570 (data_size >= me->me_threshold) || 571 ((mdesc = me->me_sw_prov) == NULL) || 572 (!IS_FG_SUPPORTED(mdesc, fg1)) || 573 (!KCF_IS_PROV_USABLE(mdesc->pm_prov_desc)))) { 574 /* there is at least one provider */ 575 ASSERT(me->me_num_hwprov > 0); 576 577 /* 578 * Find the least loaded provider capable of the combo 579 * me1 + me2, and save a pointer to the least loaded 580 * provider capable of me1 only. 581 */ 582 while (prov_chain != NULL) { 583 pd = prov_chain->pm_prov_desc; 584 len = pd->pd_sched_info.ks_taskq->tq_nalloc; 585 586 if (!IS_FG_SUPPORTED(prov_chain, fg1) || 587 !KCF_IS_PROV_USABLE(pd) || 588 IS_PROVIDER_TRIED(pd, triedl) || 589 (call_restrict && 590 (pd->pd_flags & KCF_PROV_RESTRICTED))) { 591 prov_chain = prov_chain->pm_next; 592 continue; 593 } 594 595 /* Save the best provider capable of m1 */ 596 if (len < gqlen) { 597 *prov_mt1 = 598 prov_chain->pm_mech_info.cm_mech_number; 599 gqlen = len; 600 pdm1 = pd; 601 } 602 603 /* See if pd can do me2 too */ 604 for (mil = prov_chain->pm_mi_list; 605 mil != NULL; mil = mil->ml_next) { 606 if ((mil->ml_mech_info.cm_func_group_mask & 607 fg2) == 0) 608 continue; 609 610 if ((mil->ml_kcf_mechid == m2id) && 611 (len < dgqlen)) { 612 /* Bingo! */ 613 dgqlen = len; 614 pdm1m2 = pd; 615 *prov_mt2 = 616 mil->ml_mech_info.cm_mech_number; 617 *prov_mt1 = prov_chain-> 618 pm_mech_info.cm_mech_number; 619 break; 620 } 621 } 622 623 prov_chain = prov_chain->pm_next; 624 } 625 626 pd = (pdm1m2 != NULL) ? pdm1m2 : pdm1; 627 } 628 629 /* no HW provider for this mech, is there a SW provider? */ 630 if (pd == NULL && (mdesc = me->me_sw_prov) != NULL) { 631 pd = mdesc->pm_prov_desc; 632 if (!IS_FG_SUPPORTED(mdesc, fg1) || 633 !KCF_IS_PROV_USABLE(pd) || 634 IS_PROVIDER_TRIED(pd, triedl) || 635 (call_restrict && (pd->pd_flags & KCF_PROV_RESTRICTED))) 636 pd = NULL; 637 else { 638 /* See if pd can do me2 too */ 639 for (mil = me->me_sw_prov->pm_mi_list; 640 mil != NULL; mil = mil->ml_next) { 641 if ((mil->ml_mech_info.cm_func_group_mask & 642 fg2) == 0) 643 continue; 644 645 if (mil->ml_kcf_mechid == m2id) { 646 /* Bingo! */ 647 *prov_mt2 = 648 mil->ml_mech_info.cm_mech_number; 649 break; 650 } 651 } 652 *prov_mt1 = me->me_sw_prov->pm_mech_info.cm_mech_number; 653 } 654 } 655 656 if (pd == NULL) 657 *error = CRYPTO_MECH_NOT_SUPPORTED; 658 else 659 KCF_PROV_REFHOLD(pd); 660 661 mutex_exit(&me->me_mutex); 662 return (pd); 663 } 664 665 /* 666 * Do the actual work of calling the provider routines. 667 * 668 * pd - Provider structure 669 * ctx - Context for this operation 670 * params - Parameters for this operation 671 * rhndl - Request handle to use for notification 672 * 673 * The return values are the same as that of the respective SPI. 674 */ 675 int 676 common_submit_request(kcf_provider_desc_t *pd, crypto_ctx_t *ctx, 677 kcf_req_params_t *params, crypto_req_handle_t rhndl) 678 { 679 int err = CRYPTO_ARGUMENTS_BAD; 680 kcf_op_type_t optype; 681 682 optype = params->rp_optype; 683 684 switch (params->rp_opgrp) { 685 case KCF_OG_DIGEST: { 686 kcf_digest_ops_params_t *dops = ¶ms->rp_u.digest_params; 687 688 switch (optype) { 689 case KCF_OP_INIT: 690 /* 691 * We should do this only here and not in KCF_WRAP_* 692 * macros. This is because we may want to try other 693 * providers, in case we recover from a failure. 694 */ 695 KCF_SET_PROVIDER_MECHNUM(dops->do_framework_mechtype, 696 pd, &dops->do_mech); 697 698 err = KCF_PROV_DIGEST_INIT(pd, ctx, &dops->do_mech, 699 rhndl); 700 break; 701 702 case KCF_OP_SINGLE: 703 err = KCF_PROV_DIGEST(pd, ctx, dops->do_data, 704 dops->do_digest, rhndl); 705 break; 706 707 case KCF_OP_UPDATE: 708 err = KCF_PROV_DIGEST_UPDATE(pd, ctx, 709 dops->do_data, rhndl); 710 break; 711 712 case KCF_OP_FINAL: 713 err = KCF_PROV_DIGEST_FINAL(pd, ctx, 714 dops->do_digest, rhndl); 715 break; 716 717 case KCF_OP_ATOMIC: 718 ASSERT(ctx == NULL); 719 KCF_SET_PROVIDER_MECHNUM(dops->do_framework_mechtype, 720 pd, &dops->do_mech); 721 err = KCF_PROV_DIGEST_ATOMIC(pd, dops->do_sid, 722 &dops->do_mech, dops->do_data, dops->do_digest, 723 rhndl); 724 break; 725 726 case KCF_OP_DIGEST_KEY: 727 err = KCF_PROV_DIGEST_KEY(pd, ctx, dops->do_digest_key, 728 rhndl); 729 break; 730 731 default: 732 break; 733 } 734 break; 735 } 736 737 case KCF_OG_MAC: { 738 kcf_mac_ops_params_t *mops = ¶ms->rp_u.mac_params; 739 740 switch (optype) { 741 case KCF_OP_INIT: 742 KCF_SET_PROVIDER_MECHNUM(mops->mo_framework_mechtype, 743 pd, &mops->mo_mech); 744 745 err = KCF_PROV_MAC_INIT(pd, ctx, &mops->mo_mech, 746 mops->mo_key, mops->mo_templ, rhndl); 747 break; 748 749 case KCF_OP_SINGLE: 750 err = KCF_PROV_MAC(pd, ctx, mops->mo_data, 751 mops->mo_mac, rhndl); 752 break; 753 754 case KCF_OP_UPDATE: 755 err = KCF_PROV_MAC_UPDATE(pd, ctx, mops->mo_data, 756 rhndl); 757 break; 758 759 case KCF_OP_FINAL: 760 err = KCF_PROV_MAC_FINAL(pd, ctx, mops->mo_mac, rhndl); 761 break; 762 763 case KCF_OP_ATOMIC: 764 ASSERT(ctx == NULL); 765 KCF_SET_PROVIDER_MECHNUM(mops->mo_framework_mechtype, 766 pd, &mops->mo_mech); 767 768 err = KCF_PROV_MAC_ATOMIC(pd, mops->mo_sid, 769 &mops->mo_mech, mops->mo_key, mops->mo_data, 770 mops->mo_mac, mops->mo_templ, rhndl); 771 break; 772 773 case KCF_OP_MAC_VERIFY_ATOMIC: 774 ASSERT(ctx == NULL); 775 KCF_SET_PROVIDER_MECHNUM(mops->mo_framework_mechtype, 776 pd, &mops->mo_mech); 777 778 err = KCF_PROV_MAC_VERIFY_ATOMIC(pd, mops->mo_sid, 779 &mops->mo_mech, mops->mo_key, mops->mo_data, 780 mops->mo_mac, mops->mo_templ, rhndl); 781 break; 782 783 default: 784 break; 785 } 786 break; 787 } 788 789 case KCF_OG_ENCRYPT: { 790 kcf_encrypt_ops_params_t *eops = ¶ms->rp_u.encrypt_params; 791 792 switch (optype) { 793 case KCF_OP_INIT: 794 KCF_SET_PROVIDER_MECHNUM(eops->eo_framework_mechtype, 795 pd, &eops->eo_mech); 796 797 err = KCF_PROV_ENCRYPT_INIT(pd, ctx, &eops->eo_mech, 798 eops->eo_key, eops->eo_templ, rhndl); 799 break; 800 801 case KCF_OP_SINGLE: 802 err = KCF_PROV_ENCRYPT(pd, ctx, eops->eo_plaintext, 803 eops->eo_ciphertext, rhndl); 804 break; 805 806 case KCF_OP_UPDATE: 807 err = KCF_PROV_ENCRYPT_UPDATE(pd, ctx, 808 eops->eo_plaintext, eops->eo_ciphertext, rhndl); 809 break; 810 811 case KCF_OP_FINAL: 812 err = KCF_PROV_ENCRYPT_FINAL(pd, ctx, 813 eops->eo_ciphertext, rhndl); 814 break; 815 816 case KCF_OP_ATOMIC: 817 ASSERT(ctx == NULL); 818 KCF_SET_PROVIDER_MECHNUM(eops->eo_framework_mechtype, 819 pd, &eops->eo_mech); 820 821 err = KCF_PROV_ENCRYPT_ATOMIC(pd, eops->eo_sid, 822 &eops->eo_mech, eops->eo_key, eops->eo_plaintext, 823 eops->eo_ciphertext, eops->eo_templ, rhndl); 824 break; 825 826 default: 827 break; 828 } 829 break; 830 } 831 832 case KCF_OG_DECRYPT: { 833 kcf_decrypt_ops_params_t *dcrops = ¶ms->rp_u.decrypt_params; 834 835 switch (optype) { 836 case KCF_OP_INIT: 837 KCF_SET_PROVIDER_MECHNUM(dcrops->dop_framework_mechtype, 838 pd, &dcrops->dop_mech); 839 840 err = KCF_PROV_DECRYPT_INIT(pd, ctx, &dcrops->dop_mech, 841 dcrops->dop_key, dcrops->dop_templ, rhndl); 842 break; 843 844 case KCF_OP_SINGLE: 845 err = KCF_PROV_DECRYPT(pd, ctx, dcrops->dop_ciphertext, 846 dcrops->dop_plaintext, rhndl); 847 break; 848 849 case KCF_OP_UPDATE: 850 err = KCF_PROV_DECRYPT_UPDATE(pd, ctx, 851 dcrops->dop_ciphertext, dcrops->dop_plaintext, 852 rhndl); 853 break; 854 855 case KCF_OP_FINAL: 856 err = KCF_PROV_DECRYPT_FINAL(pd, ctx, 857 dcrops->dop_plaintext, rhndl); 858 break; 859 860 case KCF_OP_ATOMIC: 861 ASSERT(ctx == NULL); 862 KCF_SET_PROVIDER_MECHNUM(dcrops->dop_framework_mechtype, 863 pd, &dcrops->dop_mech); 864 865 err = KCF_PROV_DECRYPT_ATOMIC(pd, dcrops->dop_sid, 866 &dcrops->dop_mech, dcrops->dop_key, 867 dcrops->dop_ciphertext, dcrops->dop_plaintext, 868 dcrops->dop_templ, rhndl); 869 break; 870 871 default: 872 break; 873 } 874 break; 875 } 876 877 case KCF_OG_SIGN: { 878 kcf_sign_ops_params_t *sops = ¶ms->rp_u.sign_params; 879 880 switch (optype) { 881 case KCF_OP_INIT: 882 KCF_SET_PROVIDER_MECHNUM(sops->so_framework_mechtype, 883 pd, &sops->so_mech); 884 885 err = KCF_PROV_SIGN_INIT(pd, ctx, &sops->so_mech, 886 sops->so_key, sops->so_templ, rhndl); 887 break; 888 889 case KCF_OP_SIGN_RECOVER_INIT: 890 KCF_SET_PROVIDER_MECHNUM(sops->so_framework_mechtype, 891 pd, &sops->so_mech); 892 893 err = KCF_PROV_SIGN_RECOVER_INIT(pd, ctx, 894 &sops->so_mech, sops->so_key, sops->so_templ, 895 rhndl); 896 break; 897 898 case KCF_OP_SINGLE: 899 err = KCF_PROV_SIGN(pd, ctx, sops->so_data, 900 sops->so_signature, rhndl); 901 break; 902 903 case KCF_OP_SIGN_RECOVER: 904 err = KCF_PROV_SIGN_RECOVER(pd, ctx, 905 sops->so_data, sops->so_signature, rhndl); 906 break; 907 908 case KCF_OP_UPDATE: 909 err = KCF_PROV_SIGN_UPDATE(pd, ctx, sops->so_data, 910 rhndl); 911 break; 912 913 case KCF_OP_FINAL: 914 err = KCF_PROV_SIGN_FINAL(pd, ctx, sops->so_signature, 915 rhndl); 916 break; 917 918 case KCF_OP_ATOMIC: 919 ASSERT(ctx == NULL); 920 KCF_SET_PROVIDER_MECHNUM(sops->so_framework_mechtype, 921 pd, &sops->so_mech); 922 923 err = KCF_PROV_SIGN_ATOMIC(pd, sops->so_sid, 924 &sops->so_mech, sops->so_key, sops->so_data, 925 sops->so_templ, sops->so_signature, rhndl); 926 break; 927 928 case KCF_OP_SIGN_RECOVER_ATOMIC: 929 ASSERT(ctx == NULL); 930 KCF_SET_PROVIDER_MECHNUM(sops->so_framework_mechtype, 931 pd, &sops->so_mech); 932 933 err = KCF_PROV_SIGN_RECOVER_ATOMIC(pd, sops->so_sid, 934 &sops->so_mech, sops->so_key, sops->so_data, 935 sops->so_templ, sops->so_signature, rhndl); 936 break; 937 938 default: 939 break; 940 } 941 break; 942 } 943 944 case KCF_OG_VERIFY: { 945 kcf_verify_ops_params_t *vops = ¶ms->rp_u.verify_params; 946 947 switch (optype) { 948 case KCF_OP_INIT: 949 KCF_SET_PROVIDER_MECHNUM(vops->vo_framework_mechtype, 950 pd, &vops->vo_mech); 951 952 err = KCF_PROV_VERIFY_INIT(pd, ctx, &vops->vo_mech, 953 vops->vo_key, vops->vo_templ, rhndl); 954 break; 955 956 case KCF_OP_VERIFY_RECOVER_INIT: 957 KCF_SET_PROVIDER_MECHNUM(vops->vo_framework_mechtype, 958 pd, &vops->vo_mech); 959 960 err = KCF_PROV_VERIFY_RECOVER_INIT(pd, ctx, 961 &vops->vo_mech, vops->vo_key, vops->vo_templ, 962 rhndl); 963 break; 964 965 case KCF_OP_SINGLE: 966 err = KCF_PROV_VERIFY(pd, ctx, vops->vo_data, 967 vops->vo_signature, rhndl); 968 break; 969 970 case KCF_OP_VERIFY_RECOVER: 971 err = KCF_PROV_VERIFY_RECOVER(pd, ctx, 972 vops->vo_signature, vops->vo_data, rhndl); 973 break; 974 975 case KCF_OP_UPDATE: 976 err = KCF_PROV_VERIFY_UPDATE(pd, ctx, vops->vo_data, 977 rhndl); 978 break; 979 980 case KCF_OP_FINAL: 981 err = KCF_PROV_VERIFY_FINAL(pd, ctx, vops->vo_signature, 982 rhndl); 983 break; 984 985 case KCF_OP_ATOMIC: 986 ASSERT(ctx == NULL); 987 KCF_SET_PROVIDER_MECHNUM(vops->vo_framework_mechtype, 988 pd, &vops->vo_mech); 989 990 err = KCF_PROV_VERIFY_ATOMIC(pd, vops->vo_sid, 991 &vops->vo_mech, vops->vo_key, vops->vo_data, 992 vops->vo_templ, vops->vo_signature, rhndl); 993 break; 994 995 case KCF_OP_VERIFY_RECOVER_ATOMIC: 996 ASSERT(ctx == NULL); 997 KCF_SET_PROVIDER_MECHNUM(vops->vo_framework_mechtype, 998 pd, &vops->vo_mech); 999 1000 err = KCF_PROV_VERIFY_RECOVER_ATOMIC(pd, vops->vo_sid, 1001 &vops->vo_mech, vops->vo_key, vops->vo_signature, 1002 vops->vo_templ, vops->vo_data, rhndl); 1003 break; 1004 1005 default: 1006 break; 1007 } 1008 break; 1009 } 1010 1011 case KCF_OG_ENCRYPT_MAC: { 1012 kcf_encrypt_mac_ops_params_t *eops = 1013 ¶ms->rp_u.encrypt_mac_params; 1014 kcf_context_t *kcf_secondctx; 1015 1016 switch (optype) { 1017 case KCF_OP_INIT: 1018 kcf_secondctx = ((kcf_context_t *) 1019 (ctx->cc_framework_private))->kc_secondctx; 1020 1021 if (kcf_secondctx != NULL) { 1022 err = kcf_emulate_dual(pd, ctx, params); 1023 break; 1024 } 1025 KCF_SET_PROVIDER_MECHNUM( 1026 eops->em_framework_encr_mechtype, 1027 pd, &eops->em_encr_mech); 1028 1029 KCF_SET_PROVIDER_MECHNUM( 1030 eops->em_framework_mac_mechtype, 1031 pd, &eops->em_mac_mech); 1032 1033 err = KCF_PROV_ENCRYPT_MAC_INIT(pd, ctx, 1034 &eops->em_encr_mech, eops->em_encr_key, 1035 &eops->em_mac_mech, eops->em_mac_key, 1036 eops->em_encr_templ, eops->em_mac_templ, 1037 rhndl); 1038 1039 break; 1040 1041 case KCF_OP_SINGLE: 1042 err = KCF_PROV_ENCRYPT_MAC(pd, ctx, 1043 eops->em_plaintext, eops->em_ciphertext, 1044 eops->em_mac, rhndl); 1045 break; 1046 1047 case KCF_OP_UPDATE: 1048 kcf_secondctx = ((kcf_context_t *) 1049 (ctx->cc_framework_private))->kc_secondctx; 1050 if (kcf_secondctx != NULL) { 1051 err = kcf_emulate_dual(pd, ctx, params); 1052 break; 1053 } 1054 err = KCF_PROV_ENCRYPT_MAC_UPDATE(pd, ctx, 1055 eops->em_plaintext, eops->em_ciphertext, rhndl); 1056 break; 1057 1058 case KCF_OP_FINAL: 1059 kcf_secondctx = ((kcf_context_t *) 1060 (ctx->cc_framework_private))->kc_secondctx; 1061 if (kcf_secondctx != NULL) { 1062 err = kcf_emulate_dual(pd, ctx, params); 1063 break; 1064 } 1065 err = KCF_PROV_ENCRYPT_MAC_FINAL(pd, ctx, 1066 eops->em_ciphertext, eops->em_mac, rhndl); 1067 break; 1068 1069 case KCF_OP_ATOMIC: 1070 ASSERT(ctx == NULL); 1071 1072 KCF_SET_PROVIDER_MECHNUM( 1073 eops->em_framework_encr_mechtype, 1074 pd, &eops->em_encr_mech); 1075 1076 KCF_SET_PROVIDER_MECHNUM( 1077 eops->em_framework_mac_mechtype, 1078 pd, &eops->em_mac_mech); 1079 1080 err = KCF_PROV_ENCRYPT_MAC_ATOMIC(pd, eops->em_sid, 1081 &eops->em_encr_mech, eops->em_encr_key, 1082 &eops->em_mac_mech, eops->em_mac_key, 1083 eops->em_plaintext, eops->em_ciphertext, 1084 eops->em_mac, 1085 eops->em_encr_templ, eops->em_mac_templ, 1086 rhndl); 1087 1088 break; 1089 1090 default: 1091 break; 1092 } 1093 break; 1094 } 1095 1096 case KCF_OG_MAC_DECRYPT: { 1097 kcf_mac_decrypt_ops_params_t *dops = 1098 ¶ms->rp_u.mac_decrypt_params; 1099 kcf_context_t *kcf_secondctx; 1100 1101 switch (optype) { 1102 case KCF_OP_INIT: 1103 kcf_secondctx = ((kcf_context_t *) 1104 (ctx->cc_framework_private))->kc_secondctx; 1105 1106 if (kcf_secondctx != NULL) { 1107 err = kcf_emulate_dual(pd, ctx, params); 1108 break; 1109 } 1110 KCF_SET_PROVIDER_MECHNUM( 1111 dops->md_framework_mac_mechtype, 1112 pd, &dops->md_mac_mech); 1113 1114 KCF_SET_PROVIDER_MECHNUM( 1115 dops->md_framework_decr_mechtype, 1116 pd, &dops->md_decr_mech); 1117 1118 err = KCF_PROV_MAC_DECRYPT_INIT(pd, ctx, 1119 &dops->md_mac_mech, dops->md_mac_key, 1120 &dops->md_decr_mech, dops->md_decr_key, 1121 dops->md_mac_templ, dops->md_decr_templ, 1122 rhndl); 1123 1124 break; 1125 1126 case KCF_OP_SINGLE: 1127 err = KCF_PROV_MAC_DECRYPT(pd, ctx, 1128 dops->md_ciphertext, dops->md_mac, 1129 dops->md_plaintext, rhndl); 1130 break; 1131 1132 case KCF_OP_UPDATE: 1133 kcf_secondctx = ((kcf_context_t *) 1134 (ctx->cc_framework_private))->kc_secondctx; 1135 if (kcf_secondctx != NULL) { 1136 err = kcf_emulate_dual(pd, ctx, params); 1137 break; 1138 } 1139 err = KCF_PROV_MAC_DECRYPT_UPDATE(pd, ctx, 1140 dops->md_ciphertext, dops->md_plaintext, rhndl); 1141 break; 1142 1143 case KCF_OP_FINAL: 1144 kcf_secondctx = ((kcf_context_t *) 1145 (ctx->cc_framework_private))->kc_secondctx; 1146 if (kcf_secondctx != NULL) { 1147 err = kcf_emulate_dual(pd, ctx, params); 1148 break; 1149 } 1150 err = KCF_PROV_MAC_DECRYPT_FINAL(pd, ctx, 1151 dops->md_mac, dops->md_plaintext, rhndl); 1152 break; 1153 1154 case KCF_OP_ATOMIC: 1155 ASSERT(ctx == NULL); 1156 1157 KCF_SET_PROVIDER_MECHNUM( 1158 dops->md_framework_mac_mechtype, 1159 pd, &dops->md_mac_mech); 1160 1161 KCF_SET_PROVIDER_MECHNUM( 1162 dops->md_framework_decr_mechtype, 1163 pd, &dops->md_decr_mech); 1164 1165 err = KCF_PROV_MAC_DECRYPT_ATOMIC(pd, dops->md_sid, 1166 &dops->md_mac_mech, dops->md_mac_key, 1167 &dops->md_decr_mech, dops->md_decr_key, 1168 dops->md_ciphertext, dops->md_mac, 1169 dops->md_plaintext, 1170 dops->md_mac_templ, dops->md_decr_templ, 1171 rhndl); 1172 1173 break; 1174 1175 case KCF_OP_MAC_VERIFY_DECRYPT_ATOMIC: 1176 ASSERT(ctx == NULL); 1177 1178 KCF_SET_PROVIDER_MECHNUM( 1179 dops->md_framework_mac_mechtype, 1180 pd, &dops->md_mac_mech); 1181 1182 KCF_SET_PROVIDER_MECHNUM( 1183 dops->md_framework_decr_mechtype, 1184 pd, &dops->md_decr_mech); 1185 1186 err = KCF_PROV_MAC_VERIFY_DECRYPT_ATOMIC(pd, 1187 dops->md_sid, &dops->md_mac_mech, dops->md_mac_key, 1188 &dops->md_decr_mech, dops->md_decr_key, 1189 dops->md_ciphertext, dops->md_mac, 1190 dops->md_plaintext, 1191 dops->md_mac_templ, dops->md_decr_templ, 1192 rhndl); 1193 1194 break; 1195 1196 default: 1197 break; 1198 } 1199 break; 1200 } 1201 1202 case KCF_OG_KEY: { 1203 kcf_key_ops_params_t *kops = ¶ms->rp_u.key_params; 1204 1205 ASSERT(ctx == NULL); 1206 KCF_SET_PROVIDER_MECHNUM(kops->ko_framework_mechtype, pd, 1207 &kops->ko_mech); 1208 1209 switch (optype) { 1210 case KCF_OP_KEY_GENERATE: 1211 err = KCF_PROV_KEY_GENERATE(pd, kops->ko_sid, 1212 &kops->ko_mech, 1213 kops->ko_key_template, kops->ko_key_attribute_count, 1214 kops->ko_key_object_id_ptr, rhndl); 1215 break; 1216 1217 case KCF_OP_KEY_GENERATE_PAIR: 1218 err = KCF_PROV_KEY_GENERATE_PAIR(pd, kops->ko_sid, 1219 &kops->ko_mech, 1220 kops->ko_key_template, kops->ko_key_attribute_count, 1221 kops->ko_private_key_template, 1222 kops->ko_private_key_attribute_count, 1223 kops->ko_key_object_id_ptr, 1224 kops->ko_private_key_object_id_ptr, rhndl); 1225 break; 1226 1227 case KCF_OP_KEY_WRAP: 1228 err = KCF_PROV_KEY_WRAP(pd, kops->ko_sid, 1229 &kops->ko_mech, 1230 kops->ko_key, kops->ko_key_object_id_ptr, 1231 kops->ko_wrapped_key, kops->ko_wrapped_key_len_ptr, 1232 rhndl); 1233 break; 1234 1235 case KCF_OP_KEY_UNWRAP: 1236 err = KCF_PROV_KEY_UNWRAP(pd, kops->ko_sid, 1237 &kops->ko_mech, 1238 kops->ko_key, kops->ko_wrapped_key, 1239 kops->ko_wrapped_key_len_ptr, 1240 kops->ko_key_template, kops->ko_key_attribute_count, 1241 kops->ko_key_object_id_ptr, rhndl); 1242 break; 1243 1244 case KCF_OP_KEY_DERIVE: 1245 err = KCF_PROV_KEY_DERIVE(pd, kops->ko_sid, 1246 &kops->ko_mech, 1247 kops->ko_key, kops->ko_key_template, 1248 kops->ko_key_attribute_count, 1249 kops->ko_key_object_id_ptr, rhndl); 1250 break; 1251 1252 default: 1253 break; 1254 } 1255 break; 1256 } 1257 1258 case KCF_OG_RANDOM: { 1259 kcf_random_number_ops_params_t *rops = 1260 ¶ms->rp_u.random_number_params; 1261 1262 ASSERT(ctx == NULL); 1263 1264 switch (optype) { 1265 case KCF_OP_RANDOM_SEED: 1266 err = KCF_PROV_SEED_RANDOM(pd, rops->rn_sid, 1267 rops->rn_buf, rops->rn_buflen, rops->rn_entropy_est, 1268 rops->rn_flags, rhndl); 1269 break; 1270 1271 case KCF_OP_RANDOM_GENERATE: 1272 err = KCF_PROV_GENERATE_RANDOM(pd, rops->rn_sid, 1273 rops->rn_buf, rops->rn_buflen, rhndl); 1274 break; 1275 1276 default: 1277 break; 1278 } 1279 break; 1280 } 1281 1282 case KCF_OG_SESSION: { 1283 kcf_session_ops_params_t *sops = ¶ms->rp_u.session_params; 1284 1285 ASSERT(ctx == NULL); 1286 switch (optype) { 1287 case KCF_OP_SESSION_OPEN: 1288 /* 1289 * so_pd may be a logical provider, in which case 1290 * we need to check whether it has been removed. 1291 */ 1292 if (KCF_IS_PROV_REMOVED(sops->so_pd)) { 1293 err = CRYPTO_DEVICE_ERROR; 1294 break; 1295 } 1296 err = KCF_PROV_SESSION_OPEN(pd, sops->so_sid_ptr, 1297 rhndl, sops->so_pd); 1298 break; 1299 1300 case KCF_OP_SESSION_CLOSE: 1301 /* 1302 * so_pd may be a logical provider, in which case 1303 * we need to check whether it has been removed. 1304 */ 1305 if (KCF_IS_PROV_REMOVED(sops->so_pd)) { 1306 err = CRYPTO_DEVICE_ERROR; 1307 break; 1308 } 1309 err = KCF_PROV_SESSION_CLOSE(pd, sops->so_sid, 1310 rhndl, sops->so_pd); 1311 break; 1312 1313 case KCF_OP_SESSION_LOGIN: 1314 err = KCF_PROV_SESSION_LOGIN(pd, sops->so_sid, 1315 sops->so_user_type, sops->so_pin, 1316 sops->so_pin_len, rhndl); 1317 break; 1318 1319 case KCF_OP_SESSION_LOGOUT: 1320 err = KCF_PROV_SESSION_LOGOUT(pd, sops->so_sid, rhndl); 1321 break; 1322 1323 default: 1324 break; 1325 } 1326 break; 1327 } 1328 1329 case KCF_OG_OBJECT: { 1330 kcf_object_ops_params_t *jops = ¶ms->rp_u.object_params; 1331 1332 ASSERT(ctx == NULL); 1333 switch (optype) { 1334 case KCF_OP_OBJECT_CREATE: 1335 err = KCF_PROV_OBJECT_CREATE(pd, jops->oo_sid, 1336 jops->oo_template, jops->oo_attribute_count, 1337 jops->oo_object_id_ptr, rhndl); 1338 break; 1339 1340 case KCF_OP_OBJECT_COPY: 1341 err = KCF_PROV_OBJECT_COPY(pd, jops->oo_sid, 1342 jops->oo_object_id, 1343 jops->oo_template, jops->oo_attribute_count, 1344 jops->oo_object_id_ptr, rhndl); 1345 break; 1346 1347 case KCF_OP_OBJECT_DESTROY: 1348 err = KCF_PROV_OBJECT_DESTROY(pd, jops->oo_sid, 1349 jops->oo_object_id, rhndl); 1350 break; 1351 1352 case KCF_OP_OBJECT_GET_SIZE: 1353 err = KCF_PROV_OBJECT_GET_SIZE(pd, jops->oo_sid, 1354 jops->oo_object_id, jops->oo_object_size, rhndl); 1355 break; 1356 1357 case KCF_OP_OBJECT_GET_ATTRIBUTE_VALUE: 1358 err = KCF_PROV_OBJECT_GET_ATTRIBUTE_VALUE(pd, 1359 jops->oo_sid, jops->oo_object_id, 1360 jops->oo_template, jops->oo_attribute_count, rhndl); 1361 break; 1362 1363 case KCF_OP_OBJECT_SET_ATTRIBUTE_VALUE: 1364 err = KCF_PROV_OBJECT_SET_ATTRIBUTE_VALUE(pd, 1365 jops->oo_sid, jops->oo_object_id, 1366 jops->oo_template, jops->oo_attribute_count, rhndl); 1367 break; 1368 1369 case KCF_OP_OBJECT_FIND_INIT: 1370 err = KCF_PROV_OBJECT_FIND_INIT(pd, jops->oo_sid, 1371 jops->oo_template, jops->oo_attribute_count, 1372 jops->oo_find_init_pp_ptr, rhndl); 1373 break; 1374 1375 case KCF_OP_OBJECT_FIND: 1376 err = KCF_PROV_OBJECT_FIND(pd, jops->oo_find_pp, 1377 jops->oo_object_id_ptr, jops->oo_max_object_count, 1378 jops->oo_object_count_ptr, rhndl); 1379 break; 1380 1381 case KCF_OP_OBJECT_FIND_FINAL: 1382 err = KCF_PROV_OBJECT_FIND_FINAL(pd, jops->oo_find_pp, 1383 rhndl); 1384 break; 1385 1386 default: 1387 break; 1388 } 1389 break; 1390 } 1391 1392 case KCF_OG_PROVMGMT: { 1393 kcf_provmgmt_ops_params_t *pops = ¶ms->rp_u.provmgmt_params; 1394 1395 ASSERT(ctx == NULL); 1396 switch (optype) { 1397 case KCF_OP_MGMT_EXTINFO: 1398 /* 1399 * po_pd may be a logical provider, in which case 1400 * we need to check whether it has been removed. 1401 */ 1402 if (KCF_IS_PROV_REMOVED(pops->po_pd)) { 1403 err = CRYPTO_DEVICE_ERROR; 1404 break; 1405 } 1406 err = KCF_PROV_EXT_INFO(pd, pops->po_ext_info, rhndl, 1407 pops->po_pd); 1408 break; 1409 1410 case KCF_OP_MGMT_INITTOKEN: 1411 err = KCF_PROV_INIT_TOKEN(pd, pops->po_pin, 1412 pops->po_pin_len, pops->po_label, rhndl); 1413 break; 1414 1415 case KCF_OP_MGMT_INITPIN: 1416 err = KCF_PROV_INIT_PIN(pd, pops->po_sid, pops->po_pin, 1417 pops->po_pin_len, rhndl); 1418 break; 1419 1420 case KCF_OP_MGMT_SETPIN: 1421 err = KCF_PROV_SET_PIN(pd, pops->po_sid, 1422 pops->po_old_pin, pops->po_old_pin_len, 1423 pops->po_pin, pops->po_pin_len, rhndl); 1424 break; 1425 1426 default: 1427 break; 1428 } 1429 break; 1430 } 1431 1432 case KCF_OG_NOSTORE_KEY: { 1433 kcf_key_ops_params_t *kops = ¶ms->rp_u.key_params; 1434 1435 ASSERT(ctx == NULL); 1436 KCF_SET_PROVIDER_MECHNUM(kops->ko_framework_mechtype, pd, 1437 &kops->ko_mech); 1438 1439 switch (optype) { 1440 case KCF_OP_KEY_GENERATE: 1441 err = KCF_PROV_NOSTORE_KEY_GENERATE(pd, kops->ko_sid, 1442 &kops->ko_mech, kops->ko_key_template, 1443 kops->ko_key_attribute_count, 1444 kops->ko_out_template1, 1445 kops->ko_out_attribute_count1, rhndl); 1446 break; 1447 1448 case KCF_OP_KEY_GENERATE_PAIR: 1449 err = KCF_PROV_NOSTORE_KEY_GENERATE_PAIR(pd, 1450 kops->ko_sid, &kops->ko_mech, 1451 kops->ko_key_template, kops->ko_key_attribute_count, 1452 kops->ko_private_key_template, 1453 kops->ko_private_key_attribute_count, 1454 kops->ko_out_template1, 1455 kops->ko_out_attribute_count1, 1456 kops->ko_out_template2, 1457 kops->ko_out_attribute_count2, 1458 rhndl); 1459 break; 1460 1461 case KCF_OP_KEY_DERIVE: 1462 err = KCF_PROV_NOSTORE_KEY_DERIVE(pd, kops->ko_sid, 1463 &kops->ko_mech, kops->ko_key, 1464 kops->ko_key_template, 1465 kops->ko_key_attribute_count, 1466 kops->ko_out_template1, 1467 kops->ko_out_attribute_count1, rhndl); 1468 break; 1469 1470 default: 1471 break; 1472 } 1473 break; 1474 } 1475 default: 1476 break; 1477 } /* end of switch(params->rp_opgrp) */ 1478 1479 KCF_PROV_INCRSTATS(pd, err); 1480 return (err); 1481 } 1482 1483 /* 1484 * Emulate the call for a multipart dual ops with 2 single steps. 1485 * This routine is always called in the context of a working thread 1486 * running kcf_svc_do_run(). 1487 * The single steps are submitted in a pure synchronous way (blocking). 1488 * When this routine returns, kcf_svc_do_run() will call kcf_aop_done() 1489 * so the originating consumer's callback gets invoked. kcf_aop_done() 1490 * takes care of freeing the operation context. So, this routine does 1491 * not free the operation context. 1492 * 1493 * The provider descriptor is assumed held by the callers. 1494 */ 1495 static int 1496 kcf_emulate_dual(kcf_provider_desc_t *pd, crypto_ctx_t *ctx, 1497 kcf_req_params_t *params) 1498 { 1499 int err = CRYPTO_ARGUMENTS_BAD; 1500 kcf_op_type_t optype; 1501 size_t save_len; 1502 off_t save_offset; 1503 1504 optype = params->rp_optype; 1505 1506 switch (params->rp_opgrp) { 1507 case KCF_OG_ENCRYPT_MAC: { 1508 kcf_encrypt_mac_ops_params_t *cmops = 1509 ¶ms->rp_u.encrypt_mac_params; 1510 kcf_context_t *encr_kcf_ctx; 1511 crypto_ctx_t *mac_ctx; 1512 kcf_req_params_t encr_params; 1513 1514 encr_kcf_ctx = (kcf_context_t *)(ctx->cc_framework_private); 1515 1516 switch (optype) { 1517 case KCF_OP_INIT: { 1518 encr_kcf_ctx->kc_secondctx = NULL; 1519 1520 KCF_WRAP_ENCRYPT_OPS_PARAMS(&encr_params, KCF_OP_INIT, 1521 pd->pd_sid, &cmops->em_encr_mech, 1522 cmops->em_encr_key, NULL, NULL, 1523 cmops->em_encr_templ); 1524 1525 err = kcf_submit_request(pd, ctx, NULL, &encr_params, 1526 B_FALSE); 1527 1528 /* It can't be CRYPTO_QUEUED */ 1529 if (err != CRYPTO_SUCCESS) { 1530 break; 1531 } 1532 1533 err = crypto_mac_init(&cmops->em_mac_mech, 1534 cmops->em_mac_key, cmops->em_mac_templ, 1535 (crypto_context_t *)&mac_ctx, NULL); 1536 1537 if (err == CRYPTO_SUCCESS) { 1538 encr_kcf_ctx->kc_secondctx = (kcf_context_t *) 1539 mac_ctx->cc_framework_private; 1540 KCF_CONTEXT_REFHOLD((kcf_context_t *) 1541 mac_ctx->cc_framework_private); 1542 } 1543 1544 break; 1545 1546 } 1547 case KCF_OP_UPDATE: { 1548 crypto_dual_data_t *ct = cmops->em_ciphertext; 1549 crypto_data_t *pt = cmops->em_plaintext; 1550 kcf_context_t *mac_kcf_ctx = encr_kcf_ctx->kc_secondctx; 1551 crypto_ctx_t *mac_ctx = &mac_kcf_ctx->kc_glbl_ctx; 1552 1553 KCF_WRAP_ENCRYPT_OPS_PARAMS(&encr_params, KCF_OP_UPDATE, 1554 pd->pd_sid, NULL, NULL, pt, (crypto_data_t *)ct, 1555 NULL); 1556 1557 err = kcf_submit_request(pd, ctx, NULL, &encr_params, 1558 B_FALSE); 1559 1560 /* It can't be CRYPTO_QUEUED */ 1561 if (err != CRYPTO_SUCCESS) { 1562 break; 1563 } 1564 1565 save_offset = ct->dd_offset1; 1566 save_len = ct->dd_len1; 1567 if (ct->dd_len2 == 0) { 1568 /* 1569 * The previous encrypt step was an 1570 * accumulation only and didn't produce any 1571 * partial output 1572 */ 1573 if (ct->dd_len1 == 0) 1574 break; 1575 1576 } else { 1577 ct->dd_offset1 = ct->dd_offset2; 1578 ct->dd_len1 = ct->dd_len2; 1579 } 1580 err = crypto_mac_update((crypto_context_t)mac_ctx, 1581 (crypto_data_t *)ct, NULL); 1582 1583 ct->dd_offset1 = save_offset; 1584 ct->dd_len1 = save_len; 1585 1586 break; 1587 } 1588 case KCF_OP_FINAL: { 1589 crypto_dual_data_t *ct = cmops->em_ciphertext; 1590 crypto_data_t *mac = cmops->em_mac; 1591 kcf_context_t *mac_kcf_ctx = encr_kcf_ctx->kc_secondctx; 1592 crypto_ctx_t *mac_ctx = &mac_kcf_ctx->kc_glbl_ctx; 1593 crypto_context_t mac_context = mac_ctx; 1594 1595 KCF_WRAP_ENCRYPT_OPS_PARAMS(&encr_params, KCF_OP_FINAL, 1596 pd->pd_sid, NULL, NULL, NULL, (crypto_data_t *)ct, 1597 NULL); 1598 1599 err = kcf_submit_request(pd, ctx, NULL, &encr_params, 1600 B_FALSE); 1601 1602 /* It can't be CRYPTO_QUEUED */ 1603 if (err != CRYPTO_SUCCESS) { 1604 crypto_cancel_ctx(mac_context); 1605 break; 1606 } 1607 1608 if (ct->dd_len2 > 0) { 1609 save_offset = ct->dd_offset1; 1610 save_len = ct->dd_len1; 1611 ct->dd_offset1 = ct->dd_offset2; 1612 ct->dd_len1 = ct->dd_len2; 1613 1614 err = crypto_mac_update(mac_context, 1615 (crypto_data_t *)ct, NULL); 1616 1617 ct->dd_offset1 = save_offset; 1618 ct->dd_len1 = save_len; 1619 1620 if (err != CRYPTO_SUCCESS) { 1621 crypto_cancel_ctx(mac_context); 1622 return (err); 1623 } 1624 } 1625 1626 /* and finally, collect the MAC */ 1627 err = crypto_mac_final(mac_context, mac, NULL); 1628 break; 1629 } 1630 1631 default: 1632 break; 1633 } 1634 KCF_PROV_INCRSTATS(pd, err); 1635 break; 1636 } 1637 case KCF_OG_MAC_DECRYPT: { 1638 kcf_mac_decrypt_ops_params_t *mdops = 1639 ¶ms->rp_u.mac_decrypt_params; 1640 kcf_context_t *decr_kcf_ctx; 1641 crypto_ctx_t *mac_ctx; 1642 kcf_req_params_t decr_params; 1643 1644 decr_kcf_ctx = (kcf_context_t *)(ctx->cc_framework_private); 1645 1646 switch (optype) { 1647 case KCF_OP_INIT: { 1648 decr_kcf_ctx->kc_secondctx = NULL; 1649 1650 err = crypto_mac_init(&mdops->md_mac_mech, 1651 mdops->md_mac_key, mdops->md_mac_templ, 1652 (crypto_context_t *)&mac_ctx, NULL); 1653 1654 /* It can't be CRYPTO_QUEUED */ 1655 if (err != CRYPTO_SUCCESS) { 1656 break; 1657 } 1658 1659 KCF_WRAP_DECRYPT_OPS_PARAMS(&decr_params, KCF_OP_INIT, 1660 pd->pd_sid, &mdops->md_decr_mech, 1661 mdops->md_decr_key, NULL, NULL, 1662 mdops->md_decr_templ); 1663 1664 err = kcf_submit_request(pd, ctx, NULL, &decr_params, 1665 B_FALSE); 1666 1667 /* It can't be CRYPTO_QUEUED */ 1668 if (err != CRYPTO_SUCCESS) { 1669 crypto_cancel_ctx((crypto_context_t)mac_ctx); 1670 break; 1671 } 1672 1673 decr_kcf_ctx->kc_secondctx = (kcf_context_t *) 1674 mac_ctx->cc_framework_private; 1675 KCF_CONTEXT_REFHOLD((kcf_context_t *) 1676 mac_ctx->cc_framework_private); 1677 1678 break; 1679 1680 } 1681 case KCF_OP_UPDATE: { 1682 crypto_dual_data_t *ct = mdops->md_ciphertext; 1683 crypto_data_t *pt = mdops->md_plaintext; 1684 kcf_context_t *mac_kcf_ctx = decr_kcf_ctx->kc_secondctx; 1685 crypto_ctx_t *mac_ctx = &mac_kcf_ctx->kc_glbl_ctx; 1686 1687 err = crypto_mac_update((crypto_context_t)mac_ctx, 1688 (crypto_data_t *)ct, NULL); 1689 1690 if (err != CRYPTO_SUCCESS) 1691 break; 1692 1693 save_offset = ct->dd_offset1; 1694 save_len = ct->dd_len1; 1695 1696 /* zero ct->dd_len2 means decrypt everything */ 1697 if (ct->dd_len2 > 0) { 1698 ct->dd_offset1 = ct->dd_offset2; 1699 ct->dd_len1 = ct->dd_len2; 1700 } 1701 1702 err = crypto_decrypt_update((crypto_context_t)ctx, 1703 (crypto_data_t *)ct, pt, NULL); 1704 1705 ct->dd_offset1 = save_offset; 1706 ct->dd_len1 = save_len; 1707 1708 break; 1709 } 1710 case KCF_OP_FINAL: { 1711 crypto_data_t *pt = mdops->md_plaintext; 1712 crypto_data_t *mac = mdops->md_mac; 1713 kcf_context_t *mac_kcf_ctx = decr_kcf_ctx->kc_secondctx; 1714 crypto_ctx_t *mac_ctx = &mac_kcf_ctx->kc_glbl_ctx; 1715 1716 err = crypto_mac_final((crypto_context_t)mac_ctx, 1717 mac, NULL); 1718 1719 if (err != CRYPTO_SUCCESS) { 1720 crypto_cancel_ctx(ctx); 1721 break; 1722 } 1723 1724 /* Get the last chunk of plaintext */ 1725 KCF_CONTEXT_REFHOLD(decr_kcf_ctx); 1726 err = crypto_decrypt_final((crypto_context_t)ctx, pt, 1727 NULL); 1728 1729 break; 1730 } 1731 } 1732 break; 1733 } 1734 default: 1735 1736 break; 1737 } /* end of switch(params->rp_opgrp) */ 1738 1739 return (err); 1740 } 1741