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 (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved. 23 */ 24 25 #include <sys/types.h> 26 #include <sys/sunddi.h> 27 #include <sys/disp.h> 28 #include <sys/modctl.h> 29 #include <sys/sysmacros.h> 30 #include <sys/crypto/common.h> 31 #include <sys/crypto/api.h> 32 #include <sys/crypto/impl.h> 33 #include <sys/crypto/sched_impl.h> 34 35 #define isspace(ch) (((ch) == ' ') || ((ch) == '\r') || ((ch) == '\n') || \ 36 ((ch) == '\t') || ((ch) == '\f')) 37 38 #define CRYPTO_OPS_OFFSET(f) offsetof(crypto_ops_t, co_##f) 39 #define CRYPTO_KEY_OFFSET(f) offsetof(crypto_key_ops_t, f) 40 #define CRYPTO_PROVIDER_OFFSET(f) \ 41 offsetof(crypto_provider_management_ops_t, f) 42 43 /* Miscellaneous exported entry points */ 44 45 /* 46 * All event subscribers are put on a list. kcf_notify_list_lock 47 * protects changes to this list. 48 * 49 * The following locking order is maintained in the code - The 50 * global kcf_notify_list_lock followed by the individual lock 51 * in a kcf_ntfy_elem structure (kn_lock). 52 */ 53 kmutex_t ntfy_list_lock; 54 kcondvar_t ntfy_list_cv; /* cv the service thread waits on */ 55 static kcf_ntfy_elem_t *ntfy_list_head; 56 static kcf_ntfy_elem_t *ntfy_list_tail; 57 58 /* count all the hardware and software providers */ 59 #define PROV_COUNT(me) \ 60 (((me)->me_sw_prov != NULL ? 1 : 0) + (me)->me_num_hwprov) 61 62 /* 63 * crypto_mech2id() 64 * 65 * Arguments: 66 * . mechname: A null-terminated string identifying the mechanism name. 67 * 68 * Description: 69 * Walks the mechanisms tables, looking for an entry that matches the 70 * mechname. Once it find it, it builds the 64-bit mech_type and returns 71 * it. If there are no hardware or software providers for the mechanism, 72 * but there is an unloaded software provider, this routine will attempt 73 * to load it. 74 * 75 * Context: 76 * Process and interruption. 77 * 78 * Returns: 79 * The unique mechanism identified by 'mechname', if found. 80 * CRYPTO_MECH_INVALID otherwise. 81 */ 82 crypto_mech_type_t 83 crypto_mech2id(const char *mechname) 84 { 85 return (crypto_mech2id_common((char *)mechname, B_TRUE)); 86 } 87 88 /* 89 * crypto_get_mech_list() 90 * 91 * Arguments: 92 * . countp: pointer to contain the number of mech names returned 93 * . kmflag: memory allocation flag. 94 * 95 * Description: 96 * Allocates an array of crypto_mech_name_t containing all the mechanisms 97 * currently available on the system. Sets *countp with the number of 98 * mechanism names returned. 99 * 100 * We get a list of mech names which have a hardware provider by walking 101 * all the mechanism tables. We merge them with mech names obtained from 102 * the hint list. A mech name in the hint list is considered only if it 103 * is not disabled for the provider. Note that the hint list contains only 104 * software providers and the mech names supported by them. 105 * 106 * Context: 107 * Process and interruption. kmflag should be KM_NOSLEEP when called 108 * from an interruption context. 109 * 110 * Returns: 111 * The array of the crypto_mech_t allocated. 112 * NULL otherwise. 113 */ 114 crypto_mech_name_t * 115 crypto_get_mech_list(uint_t *countp, int kmflag) 116 { 117 uint_t count = 0, me_tab_size, i, j; 118 kcf_ops_class_t cl; 119 kcf_mech_entry_t *me, *me_tab; 120 crypto_mech_name_t *mech_name_tab, *tmp_mech_name_tab; 121 char *mech_name, *hint_mech, *end; 122 kcf_soft_conf_entry_t *p; 123 size_t n; 124 kcf_lock_withpad_t *mp; 125 126 /* 127 * Count the maximum possible mechanisms that can come from the 128 * hint list. 129 */ 130 mutex_enter(&soft_config_mutex); 131 p = soft_config_list; 132 while (p != NULL) { 133 count += p->ce_count; 134 p = p->ce_next; 135 } 136 mutex_exit(&soft_config_mutex); 137 138 /* First let's count'em, for mem allocation */ 139 for (cl = KCF_FIRST_OPSCLASS; cl <= KCF_LAST_OPSCLASS; cl++) { 140 me_tab_size = kcf_mech_tabs_tab[cl].met_size; 141 me_tab = kcf_mech_tabs_tab[cl].met_tab; 142 for (i = 0; i < me_tab_size; i++) { 143 me = &me_tab[i]; 144 mp = &me_mutexes[CPU_SEQID]; 145 mutex_enter(&mp->kl_lock); 146 if ((me->me_name[0] != 0) && (me->me_num_hwprov >= 1)) { 147 ASSERT(me->me_hw_prov_chain != NULL); 148 count++; 149 } 150 mutex_exit(&mp->kl_lock); 151 } 152 } 153 154 /* 155 * Allocate a buffer to hold the mechanisms from 156 * mech tabs and mechanisms from the hint list. 157 */ 158 n = count * CRYPTO_MAX_MECH_NAME; 159 160 again: 161 count = 0; 162 tmp_mech_name_tab = kmem_zalloc(n, kmflag); 163 if (tmp_mech_name_tab == NULL) { 164 *countp = 0; 165 return (NULL); 166 } 167 168 /* 169 * Second round, fill in the table 170 */ 171 172 mech_name = (char *)tmp_mech_name_tab; 173 end = mech_name + n; 174 175 for (cl = KCF_FIRST_OPSCLASS; cl <= KCF_LAST_OPSCLASS; cl++) { 176 me_tab_size = kcf_mech_tabs_tab[cl].met_size; 177 me_tab = kcf_mech_tabs_tab[cl].met_tab; 178 for (i = 0; i < me_tab_size; i++) { 179 me = &me_tab[i]; 180 mp = &me_mutexes[CPU_SEQID]; 181 mutex_enter(&mp->kl_lock); 182 if ((me->me_name[0] != 0) && (me->me_num_hwprov >= 1)) { 183 ASSERT(me->me_hw_prov_chain != NULL); 184 if ((mech_name + CRYPTO_MAX_MECH_NAME) > end) { 185 mutex_exit(&mp->kl_lock); 186 kmem_free(tmp_mech_name_tab, n); 187 n = n << 1; 188 goto again; 189 } 190 (void) strncpy(mech_name, me->me_name, 191 CRYPTO_MAX_MECH_NAME); 192 193 mech_name += CRYPTO_MAX_MECH_NAME; 194 count++; 195 } 196 mutex_exit(&mp->kl_lock); 197 } 198 } 199 200 /* 201 * Search tmp_mech_name_tab for each mechanism in the hint list. We 202 * have to add any new mechanisms found in the hint list. Note that we 203 * should not modload the providers here as it will be too early. It 204 * may be the case that the caller never uses a provider. 205 */ 206 mutex_enter(&soft_config_mutex); 207 p = soft_config_list; 208 while (p != NULL) { 209 for (i = 0; i < p->ce_count; i++) { 210 hint_mech = p->ce_mechs[i]; 211 212 /* Do not consider the mechanism if it is disabled. */ 213 if (is_mech_disabled_byname(CRYPTO_SW_PROVIDER, 214 p->ce_name, 0, hint_mech)) 215 continue; 216 217 /* 218 * There may be duplicate mechanisms in the hint list. 219 * So, we need to search all the entries that have been 220 * added so far. That number would be count. 221 */ 222 for (j = 0; j < count; j++) { 223 if (strcmp(hint_mech, 224 tmp_mech_name_tab[j]) == 0) 225 break; 226 } 227 228 if (j == count) { /* This is a new one. Add it. */ 229 ASSERT((char *)&tmp_mech_name_tab[count] == 230 mech_name); 231 if ((mech_name + CRYPTO_MAX_MECH_NAME) > end) { 232 mutex_exit(&soft_config_mutex); 233 kmem_free(tmp_mech_name_tab, n); 234 n = n << 1; 235 goto again; 236 } 237 (void) strncpy(tmp_mech_name_tab[count], 238 hint_mech, CRYPTO_MAX_MECH_NAME); 239 mech_name += CRYPTO_MAX_MECH_NAME; 240 count++; 241 } 242 } 243 p = p->ce_next; 244 } 245 mutex_exit(&soft_config_mutex); 246 247 /* 248 * Check if we have consumed all of the space. We are done if 249 * this is the case. 250 */ 251 ASSERT(mech_name <= end); 252 if (mech_name == end) { 253 mech_name_tab = tmp_mech_name_tab; 254 goto done; 255 } 256 257 /* 258 * Allocate a buffer of the right size now that we have the 259 * correct count. 260 */ 261 mech_name_tab = kmem_zalloc(count * CRYPTO_MAX_MECH_NAME, kmflag); 262 if (mech_name_tab == NULL) { 263 kmem_free(tmp_mech_name_tab, n); 264 *countp = 0; 265 return (NULL); 266 } 267 268 bcopy(tmp_mech_name_tab, mech_name_tab, count * CRYPTO_MAX_MECH_NAME); 269 kmem_free(tmp_mech_name_tab, n); 270 271 done: 272 *countp = count; 273 return (mech_name_tab); 274 } 275 276 /* 277 * crypto_free_mech_list() 278 * 279 * Arguments: 280 * . mech_names: An array of crypto_mech_name_t previously allocated by 281 * crypto_get_mech_list. 282 * . count: the number of mech names in mech_names 283 * 284 * Description: 285 * Frees the the mech_names array. 286 * 287 * Context: 288 * Process and interruption. 289 */ 290 void 291 crypto_free_mech_list(crypto_mech_name_t *mech_names, uint_t count) 292 { 293 if ((mech_names != NULL) && (count > 0)) 294 kmem_free(mech_names, count * CRYPTO_MAX_MECH_NAME); 295 } 296 297 /* 298 * crypto_notify_events() 299 * 300 * Arguments: 301 * . nf: Callback function to invoke when event occurs. 302 * . event_mask: Mask of events. 303 * 304 * Description: 305 * Allocates a new element and inserts it in to the notification 306 * list. 307 * 308 * Context: 309 * Process context. 310 * 311 * Returns: 312 * A handle is returned if the client is put on the notification list. 313 * NULL is returned otherwise. 314 */ 315 crypto_notify_handle_t 316 crypto_notify_events(crypto_notify_callback_t nf, uint32_t event_mask) 317 { 318 kcf_ntfy_elem_t *nep; 319 crypto_notify_handle_t hndl; 320 321 /* Check the input */ 322 if (nf == NULL || !(event_mask & (CRYPTO_EVENT_MECHS_CHANGED | 323 CRYPTO_EVENT_PROVIDER_REGISTERED | 324 CRYPTO_EVENT_PROVIDER_UNREGISTERED))) { 325 return (NULL); 326 } 327 328 nep = kmem_zalloc(sizeof (kcf_ntfy_elem_t), KM_SLEEP); 329 mutex_init(&nep->kn_lock, NULL, MUTEX_DEFAULT, NULL); 330 cv_init(&nep->kn_cv, NULL, CV_DEFAULT, NULL); 331 nep->kn_state = NTFY_WAITING; 332 nep->kn_func = nf; 333 nep->kn_event_mask = event_mask; 334 335 mutex_enter(&ntfy_list_lock); 336 if (ntfy_list_head == NULL) { 337 ntfy_list_head = ntfy_list_tail = nep; 338 } else { 339 ntfy_list_tail->kn_next = nep; 340 nep->kn_prev = ntfy_list_tail; 341 ntfy_list_tail = nep; 342 } 343 344 hndl = (crypto_notify_handle_t)nep; 345 mutex_exit(&ntfy_list_lock); 346 347 return (hndl); 348 } 349 350 /* 351 * crypto_unnotify_events() 352 * 353 * Arguments: 354 * . hndl - Handle returned from an earlier crypto_notify_events(). 355 * 356 * Description: 357 * Removes the element specified by hndl from the notification list. 358 * We wait for the notification routine to complete, if the routine 359 * is currently being called. We also free the element. 360 * 361 * Context: 362 * Process context. 363 */ 364 void 365 crypto_unnotify_events(crypto_notify_handle_t hndl) 366 { 367 kcf_ntfy_elem_t *nep = (kcf_ntfy_elem_t *)hndl; 368 369 if (hndl == NULL) 370 return; 371 372 retry: 373 mutex_enter(&ntfy_list_lock); 374 mutex_enter(&nep->kn_lock); 375 376 if (nep->kn_state == NTFY_WAITING) { 377 kcf_ntfy_elem_t *nextp = nep->kn_next; 378 kcf_ntfy_elem_t *prevp = nep->kn_prev; 379 380 if (nextp != NULL) 381 nextp->kn_prev = prevp; 382 else 383 ntfy_list_tail = prevp; 384 385 if (prevp != NULL) 386 prevp->kn_next = nextp; 387 else 388 ntfy_list_head = nextp; 389 } else { 390 ASSERT(nep->kn_state == NTFY_RUNNING); 391 392 /* 393 * We have to drop this lock as the client might call 394 * crypto_notify_events() in the callback routine resulting 395 * in a deadlock. 396 */ 397 mutex_exit(&ntfy_list_lock); 398 399 /* 400 * Another thread is working on this element. We will wait 401 * for that thread to signal us when done. No other thread 402 * will free this element. So, we can be sure it stays valid 403 * after the wait. 404 */ 405 while (nep->kn_state == NTFY_RUNNING) 406 cv_wait(&nep->kn_cv, &nep->kn_lock); 407 mutex_exit(&nep->kn_lock); 408 409 /* 410 * We have to remove the element from the notification list. 411 * So, start over and do the work (acquire locks etc.). This is 412 * safe (i.e. We won't be in this routine forever) as the 413 * events do not happen frequently. We have to revisit this 414 * code if we add a new event that happens often. 415 */ 416 goto retry; 417 } 418 419 mutex_exit(&nep->kn_lock); 420 421 /* Free the element */ 422 mutex_destroy(&nep->kn_lock); 423 cv_destroy(&nep->kn_cv); 424 kmem_free(nep, sizeof (kcf_ntfy_elem_t)); 425 426 mutex_exit(&ntfy_list_lock); 427 } 428 429 /* 430 * We walk the notification list and do the callbacks. 431 */ 432 void 433 kcf_walk_ntfylist(uint32_t event, void *event_arg) 434 { 435 kcf_ntfy_elem_t *nep; 436 int nelem = 0; 437 438 mutex_enter(&ntfy_list_lock); 439 440 /* 441 * Count how many clients are on the notification list. We need 442 * this count to ensure that clients which joined the list after we 443 * have started this walk, are not wrongly notified. 444 */ 445 for (nep = ntfy_list_head; nep != NULL; nep = nep->kn_next) 446 nelem++; 447 448 for (nep = ntfy_list_head; (nep != NULL && nelem); nep = nep->kn_next) { 449 nelem--; 450 451 /* 452 * Check if this client is interested in the 453 * event. 454 */ 455 if (!(nep->kn_event_mask & event)) 456 continue; 457 458 mutex_enter(&nep->kn_lock); 459 nep->kn_state = NTFY_RUNNING; 460 mutex_exit(&nep->kn_lock); 461 mutex_exit(&ntfy_list_lock); 462 463 /* 464 * We invoke the callback routine with no locks held. Another 465 * client could have joined the list meanwhile. This is fine 466 * as we maintain nelem as stated above. The NULL check in the 467 * for loop guards against shrinkage. Also, any callers of 468 * crypto_unnotify_events() at this point cv_wait till kn_state 469 * changes to NTFY_WAITING. Hence, nep is assured to be valid. 470 */ 471 (*nep->kn_func)(event, event_arg); 472 473 mutex_enter(&nep->kn_lock); 474 nep->kn_state = NTFY_WAITING; 475 cv_broadcast(&nep->kn_cv); 476 mutex_exit(&nep->kn_lock); 477 478 mutex_enter(&ntfy_list_lock); 479 } 480 481 mutex_exit(&ntfy_list_lock); 482 } 483 484 /* 485 * crypto_key_check() 486 * 487 * Arguments: 488 * . mech: the mechanism to check the key with. 489 * . key: the key to check for validity and weakness. 490 * 491 * Description: 492 * Checks the validity and strength of the key for the mechanism. 493 * CRYPTO_KEY_REFERENCE is not supported for this routine. 494 * If more than one provider is capable of key checking for the mechanism, 495 * then run the key through them all. 496 * A conservative approach is adopted here: New weak keys may be 497 * discovered with more recent providers. If at least one provider is 498 * not happy with a key, then it is no good. 499 * 500 * Context: 501 * Process and interruption. 502 */ 503 int 504 crypto_key_check(crypto_mechanism_t *mech, crypto_key_t *key) 505 { 506 int error; 507 kcf_mech_entry_t *me; 508 kcf_provider_desc_t *pd; 509 kcf_prov_mech_desc_t *prov_chain; 510 kcf_lock_withpad_t *mp; 511 512 /* when mech is a valid mechanism, me will be its mech_entry */ 513 if ((mech == NULL) || (key == NULL) || 514 (key->ck_format == CRYPTO_KEY_REFERENCE)) 515 return (CRYPTO_ARGUMENTS_BAD); 516 517 if ((error = kcf_get_mech_entry(mech->cm_type, &me)) != KCF_SUCCESS) { 518 /* error is one of the KCF_INVALID_MECH_XXX's */ 519 return (CRYPTO_MECHANISM_INVALID); 520 } 521 522 mp = &me_mutexes[CPU_SEQID]; 523 mutex_enter(&mp->kl_lock); 524 525 /* First let the software provider check this key */ 526 if (me->me_sw_prov != NULL) { 527 pd = me->me_sw_prov->pm_prov_desc; 528 KCF_PROV_REFHOLD(pd); 529 530 if ((KCF_PROV_KEY_OPS(pd) != NULL) && 531 (KCF_PROV_KEY_OPS(pd)->key_check != NULL)) { 532 crypto_mechanism_t lmech; 533 534 mutex_exit(&mp->kl_lock); 535 lmech = *mech; 536 KCF_SET_PROVIDER_MECHNUM(mech->cm_type, pd, &lmech); 537 error = KCF_PROV_KEY_CHECK(pd, &lmech, key); 538 539 if (error != CRYPTO_SUCCESS) { 540 KCF_PROV_REFRELE(pd); 541 return (error); 542 } 543 544 mutex_enter(&mp->kl_lock); 545 } 546 KCF_PROV_REFRELE(pd); 547 } 548 549 prov_chain = me->me_hw_prov_chain; 550 while (prov_chain != NULL) { 551 pd = prov_chain->pm_prov_desc; 552 KCF_PROV_REFHOLD(pd); 553 554 if ((KCF_PROV_KEY_OPS(pd) != NULL) && 555 (KCF_PROV_KEY_OPS(pd)->key_check != NULL)) { 556 crypto_mechanism_t lmech; 557 558 mutex_exit(&mp->kl_lock); 559 lmech = *mech; 560 KCF_SET_PROVIDER_MECHNUM(mech->cm_type, pd, 561 &lmech); 562 error = KCF_PROV_KEY_CHECK(pd, &lmech, key); 563 564 if (error != CRYPTO_SUCCESS) { 565 KCF_PROV_REFRELE(pd); 566 return (error); 567 } 568 mutex_enter(&mp->kl_lock); 569 } 570 KCF_PROV_REFRELE(pd); 571 prov_chain = prov_chain->pm_next; 572 } 573 574 mutex_exit(&mp->kl_lock); 575 576 /* All are happy with this key */ 577 return (CRYPTO_SUCCESS); 578 } 579 580 int 581 crypto_key_check_prov(crypto_provider_t provider, crypto_mechanism_t *mech, 582 crypto_key_t *key) 583 { 584 kcf_provider_desc_t *pd = provider; 585 kcf_provider_desc_t *real_provider = pd; 586 crypto_mechanism_t lmech; 587 int rv; 588 589 ASSERT(KCF_PROV_REFHELD(pd)); 590 591 if ((mech == NULL) || (key == NULL) || 592 (key->ck_format == CRYPTO_KEY_REFERENCE)) 593 return (CRYPTO_ARGUMENTS_BAD); 594 595 /* no logical providers currently support the key check */ 596 if (pd->pd_prov_type == CRYPTO_LOGICAL_PROVIDER) { 597 return (CRYPTO_NOT_SUPPORTED); 598 } 599 600 lmech = *mech; 601 KCF_SET_PROVIDER_MECHNUM(mech->cm_type, real_provider, &lmech); 602 rv = KCF_PROV_KEY_CHECK(real_provider, &lmech, key); 603 if (pd->pd_prov_type == CRYPTO_LOGICAL_PROVIDER) 604 KCF_PROV_REFRELE(real_provider); 605 606 return (rv); 607 } 608 609 /* 610 * Initialize the specified crypto_mechanism_info_t structure for 611 * the specified mechanism provider descriptor. Used by 612 * crypto_get_all_mech_info(). 613 */ 614 static void 615 init_mechanism_info(crypto_mechanism_info_t *mech_info, 616 kcf_prov_mech_desc_t *pmd) 617 { 618 crypto_func_group_t fg = pmd->pm_mech_info.cm_func_group_mask; 619 620 /* min/max key sizes */ 621 mech_info->mi_keysize_unit = pmd->pm_mech_info.cm_mech_flags & 622 (CRYPTO_KEYSIZE_UNIT_IN_BITS | CRYPTO_KEYSIZE_UNIT_IN_BYTES); 623 mech_info->mi_min_key_size = 624 (size_t)pmd->pm_mech_info.cm_min_key_length; 625 mech_info->mi_max_key_size = 626 (size_t)pmd->pm_mech_info.cm_max_key_length; 627 628 /* usage flag */ 629 mech_info->mi_usage = 0; 630 if (fg & (CRYPTO_FG_ENCRYPT | CRYPTO_FG_ENCRYPT_ATOMIC)) 631 mech_info->mi_usage |= CRYPTO_MECH_USAGE_ENCRYPT; 632 if (fg & (CRYPTO_FG_DECRYPT | CRYPTO_FG_DECRYPT_ATOMIC)) 633 mech_info->mi_usage |= CRYPTO_MECH_USAGE_DECRYPT; 634 if (fg & (CRYPTO_FG_MAC | CRYPTO_FG_MAC_ATOMIC)) 635 mech_info->mi_usage |= CRYPTO_MECH_USAGE_MAC; 636 } 637 638 /* 639 * Return the mechanism info for the specified mechanism. 640 */ 641 int 642 crypto_get_all_mech_info(crypto_mech_type_t mech_type, 643 crypto_mechanism_info_t **mech_infos, uint_t *num_mech_infos, 644 int km_flag) 645 { 646 uint_t ninfos, cur_info; 647 kcf_mech_entry_t *me; 648 int rv; 649 kcf_prov_mech_desc_t *hwp; 650 crypto_mechanism_info_t *infos; 651 size_t infos_size; 652 kcf_lock_withpad_t *mp; 653 654 /* get to the mech entry corresponding to the specified mech type */ 655 if ((rv = kcf_get_mech_entry(mech_type, &me)) != CRYPTO_SUCCESS) { 656 return (rv); 657 } 658 659 /* compute the number of key size ranges to return */ 660 mp = &me_mutexes[CPU_SEQID]; 661 mutex_enter(&mp->kl_lock); 662 again: 663 ninfos = PROV_COUNT(me); 664 mutex_exit(&mp->kl_lock); 665 666 if (ninfos == 0) { 667 infos = NULL; 668 rv = CRYPTO_SUCCESS; 669 goto bail; 670 } 671 infos_size = ninfos * sizeof (crypto_mechanism_info_t); 672 infos = kmem_alloc(infos_size, km_flag); 673 if (infos == NULL) { 674 rv = CRYPTO_HOST_MEMORY; 675 goto bail; 676 } 677 678 mutex_enter(&mp->kl_lock); 679 if (ninfos != PROV_COUNT(me)) { 680 kmem_free(infos, infos_size); 681 goto again; 682 } 683 684 /* populate array of crypto mechanism infos */ 685 cur_info = 0; 686 687 /* software provider, if present */ 688 if (me->me_sw_prov != NULL) 689 init_mechanism_info(&infos[cur_info++], me->me_sw_prov); 690 691 /* hardware providers */ 692 for (hwp = me->me_hw_prov_chain; hwp != NULL; hwp = hwp->pm_next) 693 init_mechanism_info(&infos[cur_info++], hwp); 694 695 mutex_exit(&mp->kl_lock); 696 ASSERT(cur_info == ninfos); 697 bail: 698 *mech_infos = infos; 699 *num_mech_infos = ninfos; 700 return (rv); 701 } 702 703 /* 704 * Frees the array of mechanism infos previously allocated by 705 * crypto_get_all_mech_info(). 706 */ 707 void 708 crypto_free_all_mech_info(crypto_mechanism_info_t *mech_infos, uint_t count) 709 { 710 if ((mech_infos != NULL) && (count > 0)) 711 kmem_free(mech_infos, count * sizeof (crypto_mechanism_info_t)); 712 } 713 714 /* 715 * memcmp_pad_max() is a specialized version of memcmp() which 716 * compares two pieces of data up to a maximum length. If the 717 * the two data match up the maximum length, they are considered 718 * matching. Trailing blanks do not cause the match to fail if 719 * one of the data is shorter. 720 * 721 * Examples of matches: 722 * "one" | 723 * "one " | 724 * ^maximum length 725 * 726 * "Number One | X" (X is beyond maximum length) 727 * "Number One " | 728 * ^maximum length 729 * 730 * Examples of mismatches: 731 * " one" 732 * "one" 733 * 734 * "Number One X|" 735 * "Number One |" 736 * ^maximum length 737 */ 738 static int 739 memcmp_pad_max(void *d1, uint_t d1_len, void *d2, uint_t d2_len, uint_t max_sz) 740 { 741 uint_t len, extra_len; 742 char *marker; 743 744 /* No point in comparing anything beyond max_sz */ 745 if (d1_len > max_sz) 746 d1_len = max_sz; 747 if (d2_len > max_sz) 748 d2_len = max_sz; 749 750 /* Find shorter of the two data. */ 751 if (d1_len <= d2_len) { 752 len = d1_len; 753 extra_len = d2_len; 754 marker = d2; 755 } else { /* d1_len > d2_len */ 756 len = d2_len; 757 extra_len = d1_len; 758 marker = d1; 759 } 760 761 /* Have a match in the shortest length of data? */ 762 if (memcmp(d1, d2, len) != 0) 763 /* CONSTCOND */ 764 return (!0); 765 766 /* If the rest of longer data is nulls or blanks, call it a match. */ 767 while (len < extra_len) 768 if (!isspace(marker[len++])) 769 /* CONSTCOND */ 770 return (!0); 771 return (0); 772 } 773 774 /* 775 * Obtain ext info for specified provider and see if it matches. 776 */ 777 static boolean_t 778 match_ext_info(kcf_provider_desc_t *pd, char *label, char *manuf, char *serial, 779 crypto_provider_ext_info_t *ext_info) 780 { 781 int rv; 782 783 rv = crypto_get_provinfo(pd, ext_info); 784 ASSERT(rv != CRYPTO_NOT_SUPPORTED); 785 if (rv != CRYPTO_SUCCESS) 786 return (B_FALSE); 787 788 if (memcmp_pad_max(ext_info->ei_label, CRYPTO_EXT_SIZE_LABEL, 789 label, strlen(label), CRYPTO_EXT_SIZE_LABEL)) 790 return (B_FALSE); 791 792 if (manuf != NULL) { 793 if (memcmp_pad_max(ext_info->ei_manufacturerID, 794 CRYPTO_EXT_SIZE_MANUF, manuf, strlen(manuf), 795 CRYPTO_EXT_SIZE_MANUF)) 796 return (B_FALSE); 797 } 798 799 if (serial != NULL) { 800 if (memcmp_pad_max(ext_info->ei_serial_number, 801 CRYPTO_EXT_SIZE_SERIAL, serial, strlen(serial), 802 CRYPTO_EXT_SIZE_SERIAL)) 803 return (B_FALSE); 804 } 805 return (B_TRUE); 806 } 807 808 /* 809 * Find a provider based on its label, manufacturer ID, and serial number. 810 */ 811 crypto_provider_t 812 crypto_get_provider(char *label, char *manuf, char *serial) 813 { 814 kcf_provider_desc_t **provider_array, *pd; 815 crypto_provider_ext_info_t *ext_info; 816 uint_t count; 817 int i; 818 819 /* manuf and serial are optional */ 820 if (label == NULL) 821 return (NULL); 822 823 if (kcf_get_slot_list(&count, &provider_array, B_FALSE) 824 != CRYPTO_SUCCESS) 825 return (NULL); 826 827 if (count == 0) 828 return (NULL); 829 830 ext_info = kmem_zalloc(sizeof (crypto_provider_ext_info_t), KM_SLEEP); 831 832 for (i = 0; i < count; i++) { 833 pd = provider_array[i]; 834 if (match_ext_info(pd, label, manuf, serial, ext_info)) { 835 KCF_PROV_REFHOLD(pd); 836 break; 837 } 838 } 839 if (i == count) 840 pd = NULL; 841 842 kcf_free_provider_tab(count, provider_array); 843 kmem_free(ext_info, sizeof (crypto_provider_ext_info_t)); 844 return (pd); 845 } 846 847 /* 848 * Get the provider information given a provider handle. The caller 849 * needs to allocate the space for the argument, info. 850 */ 851 int 852 crypto_get_provinfo(crypto_provider_t hndl, crypto_provider_ext_info_t *info) 853 { 854 int rv; 855 kcf_req_params_t params; 856 kcf_provider_desc_t *pd; 857 kcf_provider_desc_t *real_provider; 858 859 pd = (kcf_provider_desc_t *)hndl; 860 rv = kcf_get_hardware_provider_nomech( 861 CRYPTO_OPS_OFFSET(provider_ops), CRYPTO_PROVIDER_OFFSET(ext_info), 862 pd, &real_provider); 863 864 if (rv == CRYPTO_SUCCESS && real_provider != NULL) { 865 ASSERT(real_provider == pd || 866 pd->pd_prov_type == CRYPTO_LOGICAL_PROVIDER); 867 KCF_WRAP_PROVMGMT_OPS_PARAMS(¶ms, KCF_OP_MGMT_EXTINFO, 868 0, NULL, 0, NULL, 0, NULL, info, pd); 869 rv = kcf_submit_request(real_provider, NULL, NULL, ¶ms, 870 B_FALSE); 871 KCF_PROV_REFRELE(real_provider); 872 } 873 874 return (rv); 875 } 876 877 void 878 crypto_release_provider(crypto_provider_t provider) 879 { 880 KCF_PROV_REFRELE((kcf_provider_desc_t *)provider); 881 } 882