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