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