1 /* 2 * CDDL HEADER START 3 * 4 * The contents of this file are subject to the terms of the 5 * Common Development and Distribution License, Version 1.0 only 6 * (the "License"). You may not use this file except in compliance 7 * with the License. 8 * 9 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 10 * or http://www.opensolaris.org/os/licensing. 11 * See the License for the specific language governing permissions 12 * and limitations under the License. 13 * 14 * When distributing Covered Code, include this CDDL HEADER in each 15 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 16 * If applicable, add the following below this CDDL HEADER, with the 17 * fields enclosed by brackets "[]" replaced with your own identifying 18 * information: Portions Copyright [yyyy] [name of copyright owner] 19 * 20 * CDDL HEADER END 21 */ 22 /* 23 * Copyright 2004 Sun Microsystems, Inc. All rights reserved. 24 * Use is subject to license terms. 25 */ 26 27 #pragma ident "%Z%%M% %I% %E% SMI" 28 29 #include <sys/types.h> 30 #include <sys/sunddi.h> 31 #include <sys/disp.h> 32 #include <sys/modctl.h> 33 #include <sys/crypto/common.h> 34 #include <sys/crypto/api.h> 35 #include <sys/crypto/impl.h> 36 #include <sys/crypto/sched_impl.h> 37 38 /* Miscellaneous exported entry points */ 39 40 /* 41 * All event subscribers are put on a list. kcf_notify_list_lock 42 * protects changes to this list. 43 * 44 * The following locking order is maintained in the code - The 45 * global kcf_notify_list_lock followed by the individual lock 46 * in a kcf_ntfy_elem structure (kn_lock). 47 */ 48 kmutex_t ntfy_list_lock; 49 kcondvar_t ntfy_list_cv; /* cv the service thread waits on */ 50 static kcf_ntfy_elem_t *ntfy_list_head; 51 static kcf_ntfy_elem_t *ntfy_list_tail; 52 53 /* count all the hardware and software providers */ 54 #define PROV_COUNT(me) \ 55 (((me)->me_sw_prov != NULL ? 1 : 0) + (me)->me_num_hwprov) 56 57 /* 58 * crypto_mech2id() 59 * 60 * Arguments: 61 * . mechname: A null-terminated string identifying the mechanism name. 62 * 63 * Description: 64 * Walks the mechanisms tables, looking for an entry that matches the 65 * mechname. Once it find it, it builds the 64-bit mech_type and returns 66 * it. If there are no hardware or software providers for the mechanism, 67 * but there is an unloaded software provider, this routine will attempt 68 * to load it. 69 * 70 * Context: 71 * Process and interruption. 72 * 73 * Returns: 74 * The unique mechanism identified by 'mechname', if found. 75 * CRYPTO_MECH_INVALID otherwise. 76 */ 77 crypto_mech_type_t 78 crypto_mech2id(char *mechname) 79 { 80 return (crypto_mech2id_common(mechname, B_TRUE)); 81 } 82 83 /* 84 * crypto_get_mech_list() 85 * 86 * Arguments: 87 * . countp: pointer to contain the number of mech names returned 88 * . kmflag: memory allocation flag. 89 * 90 * Description: 91 * Allocates an array of crypto_mech_name_t containing all the mechanisms 92 * currently available on the system. Sets *countp with the number of 93 * mechanism names returned. 94 * 95 * We get a list of mech names which have a hardware provider by walking 96 * all the mechanism tables. We merge them with mech names obtained from 97 * the hint list. A mech name in the hint list is considered only if it 98 * is not disabled for the provider. Note that the hint list contains only 99 * software providers and the mech names supported by them. 100 * 101 * Context: 102 * Process and interruption. kmflag should be KM_NOSLEEP when called 103 * from an interruption context. 104 * 105 * Returns: 106 * The array of the crypto_mech_t allocated. 107 * NULL otherwise. 108 */ 109 crypto_mech_name_t * 110 crypto_get_mech_list(uint_t *countp, int kmflag) 111 { 112 uint_t count = 0, me_tab_size, i, j; 113 kcf_ops_class_t cl; 114 kcf_mech_entry_t *me, *me_tab; 115 crypto_mech_name_t *mech_name_tab, *tmp_mech_name_tab; 116 char *mech_name, *hint_mech, *end; 117 kcf_soft_conf_entry_t *p; 118 size_t n; 119 120 /* 121 * Count the maximum possible mechanisms that can come from the 122 * hint list. 123 */ 124 mutex_enter(&soft_config_mutex); 125 p = soft_config_list; 126 while (p != NULL) { 127 count += p->ce_count; 128 p = p->ce_next; 129 } 130 mutex_exit(&soft_config_mutex); 131 132 /* First let's count'em, for mem allocation */ 133 for (cl = KCF_FIRST_OPSCLASS; cl <= KCF_LAST_OPSCLASS; cl++) { 134 me_tab_size = kcf_mech_tabs_tab[cl].met_size; 135 me_tab = kcf_mech_tabs_tab[cl].met_tab; 136 for (i = 0; i < me_tab_size; i++) { 137 me = &me_tab[i]; 138 mutex_enter(&(me->me_mutex)); 139 if ((me->me_name[0] != 0) && (me->me_num_hwprov >= 1)) { 140 ASSERT(me->me_hw_prov_chain != NULL); 141 count++; 142 } 143 mutex_exit(&(me->me_mutex)); 144 } 145 } 146 147 /* 148 * Allocate a buffer to hold the mechanisms from 149 * mech tabs and mechanisms from the hint list. 150 */ 151 n = count * CRYPTO_MAX_MECH_NAME; 152 153 again: 154 count = 0; 155 tmp_mech_name_tab = kmem_zalloc(n, kmflag); 156 if (tmp_mech_name_tab == NULL) { 157 *countp = 0; 158 return (NULL); 159 } 160 161 /* 162 * Second round, fill in the table 163 */ 164 165 mech_name = (char *)tmp_mech_name_tab; 166 end = mech_name + n; 167 168 for (cl = KCF_FIRST_OPSCLASS; cl <= KCF_LAST_OPSCLASS; cl++) { 169 me_tab_size = kcf_mech_tabs_tab[cl].met_size; 170 me_tab = kcf_mech_tabs_tab[cl].met_tab; 171 for (i = 0; i < me_tab_size; i++) { 172 me = &me_tab[i]; 173 mutex_enter(&(me->me_mutex)); 174 if ((me->me_name[0] != 0) && (me->me_num_hwprov >= 1)) { 175 ASSERT(me->me_hw_prov_chain != NULL); 176 if ((mech_name + CRYPTO_MAX_MECH_NAME) > end) { 177 mutex_exit(&(me->me_mutex)); 178 kmem_free(tmp_mech_name_tab, n); 179 n = n << 1; 180 goto again; 181 } 182 (void) strncpy(mech_name, me->me_name, 183 CRYPTO_MAX_MECH_NAME); 184 185 mech_name += CRYPTO_MAX_MECH_NAME; 186 count++; 187 } 188 mutex_exit(&(me->me_mutex)); 189 } 190 } 191 192 /* 193 * Search tmp_mech_name_tab for each mechanism in the hint list. We 194 * have to add any new mechanisms found in the hint list. Note that we 195 * should not modload the providers here as it will be too early. It 196 * may be the case that the caller never uses a provider. 197 */ 198 mutex_enter(&soft_config_mutex); 199 p = soft_config_list; 200 while (p != NULL) { 201 for (i = 0; i < p->ce_count; i++) { 202 hint_mech = p->ce_mechs[i]; 203 204 /* Do not consider the mechanism if it is disabled. */ 205 if (is_mech_disabled_byname(CRYPTO_SW_PROVIDER, 206 p->ce_name, 0, hint_mech)) 207 continue; 208 209 /* 210 * There may be duplicate mechanisms in the hint list. 211 * So, we need to search all the entries that have been 212 * added so far. That number would be count. 213 */ 214 for (j = 0; j < count; j++) { 215 if (strcmp(hint_mech, 216 tmp_mech_name_tab[j]) == 0) 217 break; 218 } 219 220 if (j == count) { /* This is a new one. Add it. */ 221 ASSERT((char *)&tmp_mech_name_tab[count] == 222 mech_name); 223 if ((mech_name + CRYPTO_MAX_MECH_NAME) > end) { 224 mutex_exit(&soft_config_mutex); 225 kmem_free(tmp_mech_name_tab, n); 226 n = n << 1; 227 goto again; 228 } 229 (void) strncpy(tmp_mech_name_tab[count], 230 hint_mech, CRYPTO_MAX_MECH_NAME); 231 mech_name += CRYPTO_MAX_MECH_NAME; 232 count++; 233 } 234 } 235 p = p->ce_next; 236 } 237 mutex_exit(&soft_config_mutex); 238 239 /* 240 * Check if we have consumed all of the space. We are done if 241 * this is the case. 242 */ 243 ASSERT(mech_name <= end); 244 if (mech_name == end) { 245 mech_name_tab = tmp_mech_name_tab; 246 goto done; 247 } 248 249 /* 250 * Allocate a buffer of the right size now that we have the 251 * correct count. 252 */ 253 mech_name_tab = kmem_zalloc(count * CRYPTO_MAX_MECH_NAME, kmflag); 254 if (mech_name_tab == NULL) { 255 kmem_free(tmp_mech_name_tab, n); 256 *countp = 0; 257 return (NULL); 258 } 259 260 bcopy(tmp_mech_name_tab, mech_name_tab, count * CRYPTO_MAX_MECH_NAME); 261 kmem_free(tmp_mech_name_tab, n); 262 263 done: 264 *countp = count; 265 return (mech_name_tab); 266 } 267 268 /* 269 * crypto_free_mech_list() 270 * 271 * Arguments: 272 * . mech_names: An array of crypto_mech_name_t previously allocated by 273 * crypto_get_mech_list. 274 * . count: the number of mech names in mech_names 275 * 276 * Description: 277 * Frees the the mech_names array. 278 * 279 * Context: 280 * Process and interruption. 281 */ 282 void 283 crypto_free_mech_list(crypto_mech_name_t *mech_names, uint_t count) 284 { 285 if ((mech_names != NULL) && (count > 0)) 286 kmem_free(mech_names, count * CRYPTO_MAX_MECH_NAME); 287 } 288 289 /* 290 * crypto_notify_events() 291 * 292 * Arguments: 293 * . nf: Callback function to invoke when event occurs. 294 * . event_mask: Mask of events. 295 * 296 * Description: 297 * Allocates a new element and inserts it in to the notification 298 * list. 299 * 300 * Context: 301 * Process context. 302 * 303 * Returns: 304 * A handle is returned if the client is put on the notification list. 305 * NULL is returned otherwise. 306 */ 307 crypto_notify_handle_t 308 crypto_notify_events(crypto_notify_callback_t nf, uint32_t event_mask) 309 { 310 kcf_ntfy_elem_t *nep; 311 crypto_notify_handle_t hndl; 312 313 /* 314 * The only valid value for event_mask is CRYPTO_EVENT_PROVIDERS_CHANGE. 315 */ 316 if (nf == NULL || !(event_mask & CRYPTO_EVENT_PROVIDERS_CHANGE)) { 317 return (NULL); 318 } 319 320 nep = kmem_zalloc(sizeof (kcf_ntfy_elem_t), KM_SLEEP); 321 mutex_init(&nep->kn_lock, NULL, MUTEX_DEFAULT, NULL); 322 cv_init(&nep->kn_cv, NULL, CV_DEFAULT, NULL); 323 nep->kn_state = NTFY_WAITING; 324 nep->kn_func = nf; 325 nep->kn_event_mask = event_mask; 326 327 mutex_enter(&ntfy_list_lock); 328 if (ntfy_list_head == NULL) { 329 ntfy_list_head = ntfy_list_tail = nep; 330 } else { 331 ntfy_list_tail->kn_next = nep; 332 nep->kn_prev = ntfy_list_tail; 333 ntfy_list_tail = nep; 334 } 335 336 hndl = (crypto_notify_handle_t)nep; 337 mutex_exit(&ntfy_list_lock); 338 339 return (hndl); 340 } 341 342 /* 343 * crypto_unnotify_events() 344 * 345 * Arguments: 346 * . hndl - Handle returned from an earlier crypto_notify_events(). 347 * 348 * Description: 349 * Removes the element specified by hndl from the notification list. 350 * We wait for the notification routine to complete, if the routine 351 * is currently being called. We also free the element. 352 * 353 * Context: 354 * Process context. 355 */ 356 void 357 crypto_unnotify_events(crypto_notify_handle_t hndl) 358 { 359 kcf_ntfy_elem_t *nep = (kcf_ntfy_elem_t *)hndl; 360 361 if (hndl == NULL) 362 return; 363 364 retry: 365 mutex_enter(&ntfy_list_lock); 366 mutex_enter(&nep->kn_lock); 367 368 if (nep->kn_state == NTFY_WAITING) { 369 kcf_ntfy_elem_t *nextp = nep->kn_next; 370 kcf_ntfy_elem_t *prevp = nep->kn_prev; 371 372 if (nextp != NULL) 373 nextp->kn_prev = prevp; 374 else 375 ntfy_list_tail = prevp; 376 377 if (prevp != NULL) 378 prevp->kn_next = nextp; 379 else 380 ntfy_list_head = nextp; 381 } else { 382 ASSERT(nep->kn_state == NTFY_RUNNING); 383 384 /* 385 * We have to drop this lock as the client might call 386 * crypto_notify_events() in the callback routine resulting 387 * in a deadlock. 388 */ 389 mutex_exit(&ntfy_list_lock); 390 391 /* 392 * Another thread is working on this element. We will wait 393 * for that thread to signal us when done. No other thread 394 * will free this element. So, we can be sure it stays valid 395 * after the wait. 396 */ 397 while (nep->kn_state == NTFY_RUNNING) 398 cv_wait(&nep->kn_cv, &nep->kn_lock); 399 mutex_exit(&nep->kn_lock); 400 401 /* 402 * We have to remove the element from the notification list. 403 * So, start over and do the work (acquire locks etc.). This is 404 * safe (i.e. We won't be in this routine forever) as the 405 * CRYPTO_EVENT_PROVIDERS_CHANGE event does not happen 406 * frequently. We have to revisit this code if we 407 * add a new event that happens often. 408 */ 409 goto retry; 410 } 411 412 mutex_exit(&nep->kn_lock); 413 414 /* Free the element */ 415 mutex_destroy(&nep->kn_lock); 416 cv_destroy(&nep->kn_cv); 417 kmem_free(nep, sizeof (kcf_ntfy_elem_t)); 418 419 mutex_exit(&ntfy_list_lock); 420 } 421 422 /* 423 * This routine is called from crypto_register_provider() and 424 * crypto_unregister_provider() with the CRYPTO_EVENT_PROVIDERS_CHANGE event. 425 * 426 * We walk the notification list and do the callbacks. 427 */ 428 void 429 kcf_walk_ntfylist(uint32_t event, void *event_arg) 430 { 431 kcf_ntfy_elem_t *nep; 432 int nelem = 0; 433 434 mutex_enter(&ntfy_list_lock); 435 436 /* 437 * Count how many clients are on the notification list. We need 438 * this count to ensure that clients which joined the list after we 439 * have started this walk, are not wrongly notified. 440 */ 441 for (nep = ntfy_list_head; nep != NULL; nep = nep->kn_next) 442 nelem++; 443 444 for (nep = ntfy_list_head; (nep != NULL && nelem); nep = nep->kn_next) { 445 nelem--; 446 447 /* 448 * Check if this client is interested in the 449 * event. 450 */ 451 if (!(nep->kn_event_mask & event)) 452 continue; 453 454 mutex_enter(&nep->kn_lock); 455 nep->kn_state = NTFY_RUNNING; 456 mutex_exit(&nep->kn_lock); 457 mutex_exit(&ntfy_list_lock); 458 459 /* 460 * We invoke the callback routine with no locks held. Another 461 * client could have joined the list meanwhile. This is fine 462 * as we maintain nelem as stated above. The NULL check in the 463 * for loop guards against shrinkage. Also, any callers of 464 * crypto_unnotify_events() at this point cv_wait till kn_state 465 * changes to NTFY_WAITING. Hence, nep is assured to be valid. 466 */ 467 (*nep->kn_func)(event, event_arg); 468 469 mutex_enter(&nep->kn_lock); 470 nep->kn_state = NTFY_WAITING; 471 cv_broadcast(&nep->kn_cv); 472 mutex_exit(&nep->kn_lock); 473 474 mutex_enter(&ntfy_list_lock); 475 } 476 477 mutex_exit(&ntfy_list_lock); 478 } 479 480 /* 481 * crypto_key_check() 482 * 483 * Arguments: 484 * . mech: the mechanism to check the key with. 485 * . key: the key to check for validity and weakness. 486 * 487 * Description: 488 * Checks the validity and strength of the key for the mechanism. 489 * CRYPTO_KEY_REFERENCE is not supported for this routine. 490 * If more than one provider is capable of key checking for the mechanism, 491 * then run the key through them all. 492 * A conservative approach is adopted here: New weak keys may be 493 * discovered with more recent providers. If at least one provider is 494 * not happy with a key, then it is no good. 495 * 496 * Context: 497 * Process and interruption. 498 */ 499 int 500 crypto_key_check(crypto_mechanism_t *mech, crypto_key_t *key) 501 { 502 int error; 503 kcf_mech_entry_t *me; 504 kcf_provider_desc_t *pd; 505 kcf_prov_mech_desc_t *prov_chain; 506 507 /* when mech is a valid mechanism, me will be its mech_entry */ 508 if ((mech == NULL) || (key == NULL) || 509 (key->ck_format == CRYPTO_KEY_REFERENCE)) 510 return (CRYPTO_ARGUMENTS_BAD); 511 512 if ((error = kcf_get_mech_entry(mech->cm_type, &me)) != KCF_SUCCESS) { 513 /* error is one of the KCF_INVALID_MECH_XXX's */ 514 return (CRYPTO_MECHANISM_INVALID); 515 } 516 517 mutex_enter(&me->me_mutex); 518 519 /* First let the software provider check this key */ 520 if (me->me_sw_prov != NULL) { 521 pd = me->me_sw_prov->pm_prov_desc; 522 KCF_PROV_REFHOLD(pd); 523 524 if ((KCF_PROV_KEY_OPS(pd) != NULL) && 525 (KCF_PROV_KEY_OPS(pd)->key_check != NULL)) { 526 crypto_mechanism_t lmech; 527 528 mutex_exit(&me->me_mutex); 529 lmech = *mech; 530 KCF_SET_PROVIDER_MECHNUM(mech->cm_type, pd, &lmech); 531 error = KCF_PROV_KEY_CHECK(pd, &lmech, key); 532 533 if (error != CRYPTO_SUCCESS) { 534 KCF_PROV_REFRELE(pd); 535 return (error); 536 } 537 538 mutex_enter(&me->me_mutex); 539 } 540 KCF_PROV_REFRELE(pd); 541 } 542 543 prov_chain = me->me_hw_prov_chain; 544 while (prov_chain != NULL) { 545 pd = prov_chain->pm_prov_desc; 546 KCF_PROV_REFHOLD(pd); 547 548 if ((KCF_PROV_KEY_OPS(pd) != NULL) && 549 (KCF_PROV_KEY_OPS(pd)->key_check != NULL)) { 550 crypto_mechanism_t lmech; 551 552 mutex_exit(&me->me_mutex); 553 lmech = *mech; 554 KCF_SET_PROVIDER_MECHNUM(mech->cm_type, pd, 555 &lmech); 556 error = KCF_PROV_KEY_CHECK(pd, &lmech, key); 557 558 if (error != CRYPTO_SUCCESS) { 559 KCF_PROV_REFRELE(pd); 560 return (error); 561 } 562 mutex_enter(&me->me_mutex); 563 } 564 KCF_PROV_REFRELE(pd); 565 prov_chain = prov_chain->pm_next; 566 } 567 568 mutex_exit(&me->me_mutex); 569 570 /* All are happy with this key */ 571 return (CRYPTO_SUCCESS); 572 } 573 574 /* 575 * Initialize the specified crypto_mechanism_info_t structure for 576 * the specified mechanism provider descriptor. Used by 577 * crypto_get_all_mech_info(). 578 */ 579 static void 580 init_mechanism_info(crypto_mechanism_info_t *mech_info, 581 kcf_prov_mech_desc_t *pmd) 582 { 583 crypto_func_group_t fg = pmd->pm_mech_info.cm_func_group_mask; 584 585 /* min/max key sizes */ 586 mech_info->mi_keysize_unit = 587 pmd->pm_mech_info.cm_keysize_unit; 588 mech_info->mi_min_key_size = 589 (size_t)pmd->pm_mech_info.cm_min_key_length; 590 mech_info->mi_max_key_size = 591 (size_t)pmd->pm_mech_info.cm_max_key_length; 592 593 /* usage flag */ 594 mech_info->mi_usage = 0; 595 if (fg & (CRYPTO_FG_ENCRYPT | CRYPTO_FG_ENCRYPT_ATOMIC)) 596 mech_info->mi_usage |= CRYPTO_MECH_USAGE_ENCRYPT; 597 if (fg & (CRYPTO_FG_DECRYPT | CRYPTO_FG_DECRYPT_ATOMIC)) 598 mech_info->mi_usage |= CRYPTO_MECH_USAGE_DECRYPT; 599 if (fg & (CRYPTO_FG_MAC | CRYPTO_FG_MAC_ATOMIC)) 600 mech_info->mi_usage |= CRYPTO_MECH_USAGE_MAC; 601 } 602 603 /* 604 * Return the mechanism info for the specified mechanism. 605 */ 606 int 607 crypto_get_all_mech_info(crypto_mech_type_t mech_type, 608 crypto_mechanism_info_t **mech_infos, uint_t *num_mech_infos, 609 int km_flag) 610 { 611 uint_t ninfos, cur_info; 612 kcf_mech_entry_t *me; 613 int rv; 614 kcf_prov_mech_desc_t *hwp; 615 crypto_mechanism_info_t *infos; 616 size_t infos_size; 617 618 /* get to the mech entry corresponding to the specified mech type */ 619 if ((rv = kcf_get_mech_entry(mech_type, &me)) != CRYPTO_SUCCESS) { 620 return (rv); 621 } 622 623 /* compute the number of key size ranges to return */ 624 mutex_enter(&me->me_mutex); 625 again: 626 ninfos = PROV_COUNT(me); 627 mutex_exit(&me->me_mutex); 628 629 if (ninfos == 0) { 630 infos = NULL; 631 rv = CRYPTO_SUCCESS; 632 goto bail; 633 } 634 infos_size = ninfos * sizeof (crypto_mechanism_info_t); 635 infos = kmem_alloc(infos_size, km_flag); 636 if (infos == NULL) { 637 rv = CRYPTO_HOST_MEMORY; 638 goto bail; 639 } 640 641 mutex_enter(&me->me_mutex); 642 if (ninfos != PROV_COUNT(me)) { 643 kmem_free(infos, infos_size); 644 goto again; 645 } 646 647 /* populate array of crypto mechanism infos */ 648 cur_info = 0; 649 650 /* software provider, if present */ 651 if (me->me_sw_prov != NULL) 652 init_mechanism_info(&infos[cur_info++], me->me_sw_prov); 653 654 /* hardware providers */ 655 for (hwp = me->me_hw_prov_chain; hwp != NULL; hwp = hwp->pm_next) 656 init_mechanism_info(&infos[cur_info++], hwp); 657 658 mutex_exit(&me->me_mutex); 659 ASSERT(cur_info == ninfos); 660 bail: 661 *mech_infos = infos; 662 *num_mech_infos = ninfos; 663 return (rv); 664 } 665