1 /* 2 * CDDL HEADER START 3 * 4 * The contents of this file are subject to the terms of the 5 * Common Development and Distribution License (the "License"). 6 * You may not use this file except in compliance with the License. 7 * 8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9 * or http://www.opensolaris.org/os/licensing. 10 * See the License for the specific language governing permissions 11 * and limitations under the License. 12 * 13 * When distributing Covered Code, include this CDDL HEADER in each 14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15 * If applicable, add the following below this CDDL HEADER, with the 16 * fields enclosed by brackets "[]" replaced with your own identifying 17 * information: Portions Copyright [yyyy] [name of copyright owner] 18 * 19 * CDDL HEADER END 20 */ 21 /* 22 * Copyright 2007 Sun Microsystems, Inc. All rights reserved. 23 * Use is subject to license terms. 24 */ 25 26 #pragma ident "%Z%%M% %I% %E% SMI" 27 28 #include <sys/types.h> 29 #include <sys/sunddi.h> 30 #include <sys/errno.h> 31 #include <sys/disp.h> 32 #include <sys/modctl.h> 33 #include <sys/modhash.h> 34 #include <sys/crypto/common.h> 35 #include <sys/crypto/api.h> 36 #include <sys/crypto/impl.h> 37 38 /* Cryptographic mechanisms tables and their access functions */ 39 40 /* 41 * Internal numbers assigned to mechanisms are coded as follows: 42 * 43 * +----------------+----------------+ 44 * | mech. class | mech. index | 45 * <--- 32-bits --->+<--- 32-bits ---> 46 * 47 * the mech_class identifies the table the mechanism belongs to. 48 * mech_index is the index for that mechanism in the table. 49 * A mechanism belongs to exactly 1 table. 50 * The tables are: 51 * . digest_mechs_tab[] for the msg digest mechs. 52 * . cipher_mechs_tab[] for encrypt/decrypt and wrap/unwrap mechs. 53 * . mac_mechs_tab[] for MAC mechs. 54 * . sign_mechs_tab[] for sign & verify mechs. 55 * . keyops_mechs_tab[] for key/key pair generation, and key derivation. 56 * . misc_mechs_tab[] for mechs that don't belong to any of the above. 57 * 58 * There are no holes in the tables. 59 */ 60 61 /* 62 * Locking conventions: 63 * -------------------- 64 * A global mutex, kcf_mech_tabs_lock, serializes writes to the 65 * mechanism table via kcf_create_mech_entry(). 66 * 67 * A mutex is associated with every entry of the tables. 68 * The mutex is acquired whenever the entry is accessed for 69 * 1) retrieving the mech_id (comparing the mech name) 70 * 2) finding a provider for an xxx_init() or atomic operation. 71 * 3) altering the mechs entry to add or remove a provider. 72 * 73 * In 2), after a provider is chosen, its prov_desc is held and the 74 * entry's mutex must be dropped. The provider's working function (SPI) is 75 * called outside the mech_entry's mutex. 76 * 77 * The number of providers for a particular mechanism is not expected to be 78 * long enough to justify the cost of using rwlocks, so the per-mechanism 79 * entry mutex won't be very *hot*. 80 * 81 * When both kcf_mech_tabs_lock and a mech_entry mutex need to be held, 82 * kcf_mech_tabs_lock must always be acquired first. 83 * 84 */ 85 86 /* Mechanisms tables */ 87 88 89 /* RFE 4687834 Will deal with the extensibility of these tables later */ 90 91 kcf_mech_entry_t kcf_digest_mechs_tab[KCF_MAXDIGEST]; 92 kcf_mech_entry_t kcf_cipher_mechs_tab[KCF_MAXCIPHER]; 93 kcf_mech_entry_t kcf_mac_mechs_tab[KCF_MAXMAC]; 94 kcf_mech_entry_t kcf_sign_mechs_tab[KCF_MAXSIGN]; 95 kcf_mech_entry_t kcf_keyops_mechs_tab[KCF_MAXKEYOPS]; 96 kcf_mech_entry_t kcf_misc_mechs_tab[KCF_MAXMISC]; 97 98 kcf_mech_entry_tab_t kcf_mech_tabs_tab[KCF_LAST_OPSCLASS + 1] = { 99 {0, NULL}, /* No class zero */ 100 {KCF_MAXDIGEST, kcf_digest_mechs_tab}, 101 {KCF_MAXCIPHER, kcf_cipher_mechs_tab}, 102 {KCF_MAXMAC, kcf_mac_mechs_tab}, 103 {KCF_MAXSIGN, kcf_sign_mechs_tab}, 104 {KCF_MAXKEYOPS, kcf_keyops_mechs_tab}, 105 {KCF_MAXMISC, kcf_misc_mechs_tab} 106 }; 107 108 /* 109 * Per-algorithm internal threasholds for the minimum input size of before 110 * offloading to hardware provider. 111 * Dispatching a crypto operation to a hardware provider entails paying the 112 * cost of an additional context switch. Measurments with Sun Accelerator 4000 113 * shows that 512-byte jobs or smaller are better handled in software. 114 * There is room for refinement here. 115 * 116 */ 117 int kcf_md5_threshold = 512; 118 int kcf_sha1_threshold = 512; 119 int kcf_des_threshold = 512; 120 int kcf_des3_threshold = 512; 121 int kcf_aes_threshold = 512; 122 int kcf_bf_threshold = 512; 123 int kcf_rc4_threshold = 512; 124 125 kmutex_t kcf_mech_tabs_lock; 126 static uint32_t kcf_gen_swprov = 0; 127 128 int kcf_mech_hash_size = 256; 129 mod_hash_t *kcf_mech_hash; /* mech name to id hash */ 130 131 static crypto_mech_type_t 132 kcf_mech_hash_find(char *mechname) 133 { 134 mod_hash_val_t hv; 135 crypto_mech_type_t mt; 136 137 mt = CRYPTO_MECH_INVALID; 138 if (mod_hash_find(kcf_mech_hash, (mod_hash_key_t)mechname, &hv) == 0) { 139 mt = *(crypto_mech_type_t *)hv; 140 ASSERT(mt != CRYPTO_MECH_INVALID); 141 } 142 143 return (mt); 144 } 145 146 /* 147 * kcf_init_mech_tabs() 148 * 149 * Called by the misc/kcf's _init() routine to initialize the tables 150 * of mech_entry's. 151 */ 152 void 153 kcf_init_mech_tabs() 154 { 155 int i, max; 156 kcf_ops_class_t class; 157 kcf_mech_entry_t *me_tab; 158 159 /* Initializes the mutex locks. */ 160 161 mutex_init(&kcf_mech_tabs_lock, NULL, MUTEX_DEFAULT, NULL); 162 163 /* Then the pre-defined mechanism entries */ 164 165 /* Two digests */ 166 (void) strncpy(kcf_digest_mechs_tab[0].me_name, SUN_CKM_MD5, 167 CRYPTO_MAX_MECH_NAME); 168 kcf_digest_mechs_tab[0].me_threshold = kcf_md5_threshold; 169 170 (void) strncpy(kcf_digest_mechs_tab[1].me_name, SUN_CKM_SHA1, 171 CRYPTO_MAX_MECH_NAME); 172 kcf_digest_mechs_tab[1].me_threshold = kcf_sha1_threshold; 173 174 /* The symmetric ciphers in various modes */ 175 (void) strncpy(kcf_cipher_mechs_tab[0].me_name, SUN_CKM_DES_CBC, 176 CRYPTO_MAX_MECH_NAME); 177 kcf_cipher_mechs_tab[0].me_threshold = kcf_des_threshold; 178 179 (void) strncpy(kcf_cipher_mechs_tab[1].me_name, SUN_CKM_DES3_CBC, 180 CRYPTO_MAX_MECH_NAME); 181 kcf_cipher_mechs_tab[1].me_threshold = kcf_des3_threshold; 182 183 (void) strncpy(kcf_cipher_mechs_tab[2].me_name, SUN_CKM_DES_ECB, 184 CRYPTO_MAX_MECH_NAME); 185 kcf_cipher_mechs_tab[2].me_threshold = kcf_des_threshold; 186 187 (void) strncpy(kcf_cipher_mechs_tab[3].me_name, SUN_CKM_DES3_ECB, 188 CRYPTO_MAX_MECH_NAME); 189 kcf_cipher_mechs_tab[3].me_threshold = kcf_des3_threshold; 190 191 (void) strncpy(kcf_cipher_mechs_tab[4].me_name, SUN_CKM_BLOWFISH_CBC, 192 CRYPTO_MAX_MECH_NAME); 193 kcf_cipher_mechs_tab[4].me_threshold = kcf_bf_threshold; 194 195 (void) strncpy(kcf_cipher_mechs_tab[5].me_name, SUN_CKM_BLOWFISH_ECB, 196 CRYPTO_MAX_MECH_NAME); 197 kcf_cipher_mechs_tab[5].me_threshold = kcf_bf_threshold; 198 199 (void) strncpy(kcf_cipher_mechs_tab[6].me_name, SUN_CKM_AES_CBC, 200 CRYPTO_MAX_MECH_NAME); 201 kcf_cipher_mechs_tab[6].me_threshold = kcf_aes_threshold; 202 203 (void) strncpy(kcf_cipher_mechs_tab[7].me_name, SUN_CKM_AES_ECB, 204 CRYPTO_MAX_MECH_NAME); 205 kcf_cipher_mechs_tab[7].me_threshold = kcf_aes_threshold; 206 207 (void) strncpy(kcf_cipher_mechs_tab[8].me_name, SUN_CKM_RC4, 208 CRYPTO_MAX_MECH_NAME); 209 kcf_cipher_mechs_tab[8].me_threshold = kcf_rc4_threshold; 210 211 212 /* 4 HMACs */ 213 (void) strncpy(kcf_mac_mechs_tab[0].me_name, SUN_CKM_MD5_HMAC, 214 CRYPTO_MAX_MECH_NAME); 215 kcf_mac_mechs_tab[0].me_threshold = kcf_md5_threshold; 216 217 (void) strncpy(kcf_mac_mechs_tab[1].me_name, SUN_CKM_MD5_HMAC_GENERAL, 218 CRYPTO_MAX_MECH_NAME); 219 kcf_mac_mechs_tab[1].me_threshold = kcf_md5_threshold; 220 221 (void) strncpy(kcf_mac_mechs_tab[2].me_name, SUN_CKM_SHA1_HMAC, 222 CRYPTO_MAX_MECH_NAME); 223 kcf_mac_mechs_tab[2].me_threshold = kcf_sha1_threshold; 224 225 (void) strncpy(kcf_mac_mechs_tab[3].me_name, SUN_CKM_SHA1_HMAC_GENERAL, 226 CRYPTO_MAX_MECH_NAME); 227 kcf_mac_mechs_tab[3].me_threshold = kcf_sha1_threshold; 228 229 230 /* 1 random number generation pseudo mechanism */ 231 (void) strncpy(kcf_misc_mechs_tab[0].me_name, SUN_RANDOM, 232 CRYPTO_MAX_MECH_NAME); 233 234 kcf_mech_hash = mod_hash_create_strhash("kcf mech2id hash", 235 kcf_mech_hash_size, mod_hash_null_valdtor); 236 237 for (class = KCF_FIRST_OPSCLASS; class <= KCF_LAST_OPSCLASS; class++) { 238 max = kcf_mech_tabs_tab[class].met_size; 239 me_tab = kcf_mech_tabs_tab[class].met_tab; 240 for (i = 0; i < max; i++) { 241 mutex_init(&(me_tab[i].me_mutex), NULL, 242 MUTEX_DEFAULT, NULL); 243 if (me_tab[i].me_name[0] != 0) { 244 me_tab[i].me_mechid = KCF_MECHID(class, i); 245 (void) mod_hash_insert(kcf_mech_hash, 246 (mod_hash_key_t)me_tab[i].me_name, 247 (mod_hash_val_t)&(me_tab[i].me_mechid)); 248 } 249 } 250 } 251 } 252 253 /* 254 * kcf_create_mech_entry() 255 * 256 * Arguments: 257 * . The class of mechanism. 258 * . the name of the new mechanism. 259 * 260 * Description: 261 * Creates a new mech_entry for a mechanism not yet known to the 262 * framework. 263 * This routine is called by kcf_add_mech_provider, which is 264 * in turn invoked for each mechanism supported by a provider. 265 * The'class' argument depends on the crypto_func_group_t bitmask 266 * in the registering provider's mech_info struct for this mechanism. 267 * When there is ambiguity in the mapping between the crypto_func_group_t 268 * and a class (dual ops, ...) the KCF_MISC_CLASS should be used. 269 * 270 * Context: 271 * User context only. 272 * 273 * Returns: 274 * KCF_INVALID_MECH_CLASS or KCF_INVALID_MECH_NAME if the class or 275 * the mechname is bogus. 276 * KCF_MECH_TAB_FULL when there is no room left in the mech. tabs. 277 * KCF_SUCCESS otherwise. 278 */ 279 static int 280 kcf_create_mech_entry(kcf_ops_class_t class, char *mechname) 281 { 282 crypto_mech_type_t mt; 283 kcf_mech_entry_t *me_tab; 284 int i = 0, size; 285 286 if ((class < KCF_FIRST_OPSCLASS) || (class > KCF_LAST_OPSCLASS)) 287 return (KCF_INVALID_MECH_CLASS); 288 289 if ((mechname == NULL) || (mechname[0] == 0)) 290 return (KCF_INVALID_MECH_NAME); 291 /* 292 * First check if the mechanism is already in one of the tables. 293 * The mech_entry could be in another class. 294 */ 295 mutex_enter(&kcf_mech_tabs_lock); 296 mt = kcf_mech_hash_find(mechname); 297 if (mt != CRYPTO_MECH_INVALID) { 298 /* Nothing to do, regardless the suggested class. */ 299 mutex_exit(&kcf_mech_tabs_lock); 300 return (KCF_SUCCESS); 301 } 302 /* Now take the next unused mech entry in the class's tab */ 303 me_tab = kcf_mech_tabs_tab[class].met_tab; 304 size = kcf_mech_tabs_tab[class].met_size; 305 306 while (i < size) { 307 mutex_enter(&(me_tab[i].me_mutex)); 308 if (me_tab[i].me_name[0] == 0) { 309 /* Found an empty spot */ 310 (void) strncpy(me_tab[i].me_name, mechname, 311 CRYPTO_MAX_MECH_NAME); 312 me_tab[i].me_name[CRYPTO_MAX_MECH_NAME-1] = '\0'; 313 me_tab[i].me_mechid = KCF_MECHID(class, i); 314 /* 315 * No a-priori information about the new mechanism, so 316 * the threshold is set to zero. 317 */ 318 me_tab[i].me_threshold = 0; 319 320 mutex_exit(&(me_tab[i].me_mutex)); 321 /* Add the new mechanism to the hash table */ 322 (void) mod_hash_insert(kcf_mech_hash, 323 (mod_hash_key_t)me_tab[i].me_name, 324 (mod_hash_val_t)&(me_tab[i].me_mechid)); 325 break; 326 } 327 mutex_exit(&(me_tab[i].me_mutex)); 328 i++; 329 } 330 331 mutex_exit(&kcf_mech_tabs_lock); 332 333 if (i == size) { 334 return (KCF_MECH_TAB_FULL); 335 } 336 337 return (KCF_SUCCESS); 338 } 339 340 /* 341 * kcf_add_mech_provider() 342 * 343 * Arguments: 344 * . An index in to the provider mechanism array 345 * . A pointer to the provider descriptor 346 * . A storage for the kcf_prov_mech_desc_t the entry was added at. 347 * 348 * Description: 349 * Adds a new provider of a mechanism to the mechanism's mech_entry 350 * chain. 351 * 352 * Context: 353 * User context only. 354 * 355 * Returns 356 * KCF_SUCCESS on success 357 * KCF_MECH_TAB_FULL otherwise. 358 */ 359 int 360 kcf_add_mech_provider(short mech_indx, 361 kcf_provider_desc_t *prov_desc, kcf_prov_mech_desc_t **pmdpp) 362 { 363 int error; 364 kcf_mech_entry_t *mech_entry; 365 crypto_mech_info_t *mech_info; 366 crypto_mech_type_t kcf_mech_type, mt; 367 kcf_prov_mech_desc_t *prov_mech, *prov_mech2; 368 crypto_func_group_t simple_fg_mask, dual_fg_mask; 369 crypto_mech_info_t *dmi; 370 crypto_mech_info_list_t *mil, *mil2; 371 kcf_mech_entry_t *me; 372 int i; 373 374 ASSERT(prov_desc->pd_prov_type != CRYPTO_LOGICAL_PROVIDER); 375 376 mech_info = &prov_desc->pd_mechanisms[mech_indx]; 377 /* 378 * Do not use the provider for the mechanism if 379 * policy does not allow it. 380 */ 381 if (is_mech_disabled(prov_desc, mech_info->cm_mech_name)) { 382 *pmdpp = NULL; 383 return (KCF_SUCCESS); 384 } 385 386 /* 387 * A mechanism belongs to exactly one mechanism table. 388 * Find the class corresponding to the function group flag of 389 * the mechanism. 390 */ 391 kcf_mech_type = kcf_mech_hash_find(mech_info->cm_mech_name); 392 if (kcf_mech_type == CRYPTO_MECH_INVALID) { 393 crypto_func_group_t fg = mech_info->cm_func_group_mask; 394 kcf_ops_class_t class; 395 396 if (fg & CRYPTO_FG_DIGEST || fg & CRYPTO_FG_DIGEST_ATOMIC) 397 class = KCF_DIGEST_CLASS; 398 else if (fg & CRYPTO_FG_ENCRYPT || fg & CRYPTO_FG_DECRYPT || 399 fg & CRYPTO_FG_ENCRYPT_ATOMIC || 400 fg & CRYPTO_FG_DECRYPT_ATOMIC) 401 class = KCF_CIPHER_CLASS; 402 else if (fg & CRYPTO_FG_MAC || fg & CRYPTO_FG_MAC_ATOMIC) 403 class = KCF_MAC_CLASS; 404 else if (fg & CRYPTO_FG_SIGN || fg & CRYPTO_FG_VERIFY || 405 fg & CRYPTO_FG_SIGN_ATOMIC || 406 fg & CRYPTO_FG_VERIFY_ATOMIC || 407 fg & CRYPTO_FG_SIGN_RECOVER || 408 fg & CRYPTO_FG_VERIFY_RECOVER) 409 class = KCF_SIGN_CLASS; 410 else if (fg & CRYPTO_FG_GENERATE || 411 fg & CRYPTO_FG_GENERATE_KEY_PAIR || 412 fg & CRYPTO_FG_WRAP || fg & CRYPTO_FG_UNWRAP || 413 fg & CRYPTO_FG_DERIVE) 414 class = KCF_KEYOPS_CLASS; 415 else 416 class = KCF_MISC_CLASS; 417 418 /* 419 * Attempt to create a new mech_entry for the specified 420 * mechanism. kcf_create_mech_entry() can handle the case 421 * where such an entry already exists. 422 */ 423 if ((error = kcf_create_mech_entry(class, 424 mech_info->cm_mech_name)) != KCF_SUCCESS) { 425 return (error); 426 } 427 /* get the KCF mech type that was assigned to the mechanism */ 428 kcf_mech_type = kcf_mech_hash_find(mech_info->cm_mech_name); 429 ASSERT(kcf_mech_type != CRYPTO_MECH_INVALID); 430 } 431 432 error = kcf_get_mech_entry(kcf_mech_type, &mech_entry); 433 ASSERT(error == KCF_SUCCESS); 434 435 /* allocate and initialize new kcf_prov_mech_desc */ 436 prov_mech = kmem_zalloc(sizeof (kcf_prov_mech_desc_t), KM_SLEEP); 437 bcopy(mech_info, &prov_mech->pm_mech_info, sizeof (crypto_mech_info_t)); 438 prov_mech->pm_prov_desc = prov_desc; 439 prov_desc->pd_mech_indx[KCF_MECH2CLASS(kcf_mech_type)] 440 [KCF_MECH2INDEX(kcf_mech_type)] = mech_indx; 441 442 KCF_PROV_REFHOLD(prov_desc); 443 KCF_PROV_IREFHOLD(prov_desc); 444 445 dual_fg_mask = mech_info->cm_func_group_mask & CRYPTO_FG_DUAL_MASK; 446 447 if (dual_fg_mask == ((crypto_func_group_t)0)) 448 goto add_entry; 449 450 simple_fg_mask = mech_info->cm_func_group_mask & 451 CRYPTO_FG_SIMPLEOP_MASK | CRYPTO_FG_RANDOM; 452 453 for (i = 0; i < prov_desc->pd_mech_list_count; i++) { 454 dmi = &prov_desc->pd_mechanisms[i]; 455 456 /* skip self */ 457 if (dmi->cm_mech_number == mech_info->cm_mech_number) 458 continue; 459 460 /* skip if policy doesn't allow mechanism */ 461 if (is_mech_disabled(prov_desc, dmi->cm_mech_name)) 462 continue; 463 464 /* skip if not a dual operation mechanism */ 465 if (!(dmi->cm_func_group_mask & dual_fg_mask) || 466 (dmi->cm_func_group_mask & simple_fg_mask)) 467 continue; 468 469 mt = kcf_mech_hash_find(dmi->cm_mech_name); 470 if (mt == CRYPTO_MECH_INVALID) 471 continue; 472 473 if (kcf_get_mech_entry(mt, &me) != KCF_SUCCESS) 474 continue; 475 476 mil = kmem_zalloc(sizeof (*mil), KM_SLEEP); 477 mil2 = kmem_zalloc(sizeof (*mil2), KM_SLEEP); 478 479 /* 480 * Ignore hard-coded entries in the mech table 481 * if the provider hasn't registered. 482 */ 483 mutex_enter(&me->me_mutex); 484 if (me->me_hw_prov_chain == NULL && me->me_sw_prov == NULL) { 485 mutex_exit(&me->me_mutex); 486 kmem_free(mil, sizeof (*mil)); 487 kmem_free(mil2, sizeof (*mil2)); 488 continue; 489 } 490 491 /* 492 * Add other dual mechanisms that have registered 493 * with the framework to this mechanism's 494 * cross-reference list. 495 */ 496 mil->ml_mech_info = *dmi; /* struct assignment */ 497 mil->ml_kcf_mechid = mt; 498 499 /* add to head of list */ 500 mil->ml_next = prov_mech->pm_mi_list; 501 prov_mech->pm_mi_list = mil; 502 503 if (prov_desc->pd_prov_type == CRYPTO_HW_PROVIDER) 504 prov_mech2 = me->me_hw_prov_chain; 505 else 506 prov_mech2 = me->me_sw_prov; 507 508 if (prov_mech2 == NULL) { 509 kmem_free(mil2, sizeof (*mil2)); 510 mutex_exit(&me->me_mutex); 511 continue; 512 } 513 514 /* 515 * Update all other cross-reference lists by 516 * adding this new mechanism. 517 */ 518 while (prov_mech2 != NULL) { 519 if (prov_mech2->pm_prov_desc == prov_desc) { 520 /* struct assignment */ 521 mil2->ml_mech_info = *mech_info; 522 mil2->ml_kcf_mechid = kcf_mech_type; 523 524 /* add to head of list */ 525 mil2->ml_next = prov_mech2->pm_mi_list; 526 prov_mech2->pm_mi_list = mil2; 527 break; 528 } 529 prov_mech2 = prov_mech2->pm_next; 530 } 531 if (prov_mech2 == NULL) 532 kmem_free(mil2, sizeof (*mil2)); 533 534 mutex_exit(&me->me_mutex); 535 } 536 537 add_entry: 538 /* 539 * Add new kcf_prov_mech_desc at the front of HW providers 540 * chain. 541 */ 542 switch (prov_desc->pd_prov_type) { 543 544 case CRYPTO_HW_PROVIDER: 545 mutex_enter(&mech_entry->me_mutex); 546 prov_mech->pm_me = mech_entry; 547 prov_mech->pm_next = mech_entry->me_hw_prov_chain; 548 mech_entry->me_hw_prov_chain = prov_mech; 549 mech_entry->me_num_hwprov++; 550 mutex_exit(&mech_entry->me_mutex); 551 break; 552 553 case CRYPTO_SW_PROVIDER: 554 mutex_enter(&mech_entry->me_mutex); 555 if (mech_entry->me_sw_prov != NULL) { 556 /* 557 * There is already a SW provider for this mechanism. 558 * Since we allow only one SW provider per mechanism, 559 * report this condition. 560 */ 561 cmn_err(CE_WARN, "The cryptographic software provider " 562 "\"%s\" will not be used for %s. The provider " 563 "\"%s\" will be used for this mechanism " 564 "instead.", prov_desc->pd_description, 565 mech_info->cm_mech_name, 566 mech_entry->me_sw_prov->pm_prov_desc-> 567 pd_description); 568 KCF_PROV_REFRELE(prov_desc); 569 kmem_free(prov_mech, sizeof (kcf_prov_mech_desc_t)); 570 prov_mech = NULL; 571 } else { 572 /* 573 * Set the provider as the software provider for 574 * this mechanism. 575 */ 576 mech_entry->me_sw_prov = prov_mech; 577 578 /* We'll wrap around after 4 billion registrations! */ 579 mech_entry->me_gen_swprov = kcf_gen_swprov++; 580 } 581 mutex_exit(&mech_entry->me_mutex); 582 break; 583 } 584 585 *pmdpp = prov_mech; 586 587 return (KCF_SUCCESS); 588 } 589 590 /* 591 * kcf_remove_mech_provider() 592 * 593 * Arguments: 594 * . mech_name: the name of the mechanism. 595 * . prov_desc: The provider descriptor 596 * 597 * Description: 598 * Removes a provider from chain of provider descriptors. 599 * The provider is made unavailable to kernel consumers for the specified 600 * mechanism. 601 * 602 * Context: 603 * User context only. 604 */ 605 void 606 kcf_remove_mech_provider(char *mech_name, kcf_provider_desc_t *prov_desc) 607 { 608 crypto_mech_type_t mech_type; 609 kcf_prov_mech_desc_t *prov_mech, *prov_chain; 610 kcf_prov_mech_desc_t **prev_entry_next; 611 kcf_mech_entry_t *mech_entry; 612 crypto_mech_info_list_t *mil, *mil2, *next, **prev_next; 613 614 ASSERT(prov_desc->pd_prov_type != CRYPTO_LOGICAL_PROVIDER); 615 616 /* get the KCF mech type that was assigned to the mechanism */ 617 if ((mech_type = kcf_mech_hash_find(mech_name)) == 618 CRYPTO_MECH_INVALID) { 619 /* 620 * Provider was not allowed for this mech due to policy or 621 * configuration. 622 */ 623 return; 624 } 625 626 /* get a ptr to the mech_entry that was created */ 627 if (kcf_get_mech_entry(mech_type, &mech_entry) != KCF_SUCCESS) { 628 /* 629 * Provider was not allowed for this mech due to policy or 630 * configuration. 631 */ 632 return; 633 } 634 635 mutex_enter(&mech_entry->me_mutex); 636 637 switch (prov_desc->pd_prov_type) { 638 639 case CRYPTO_HW_PROVIDER: 640 /* find the provider in the mech_entry chain */ 641 prev_entry_next = &mech_entry->me_hw_prov_chain; 642 prov_mech = mech_entry->me_hw_prov_chain; 643 while (prov_mech != NULL && 644 prov_mech->pm_prov_desc != prov_desc) { 645 prev_entry_next = &prov_mech->pm_next; 646 prov_mech = prov_mech->pm_next; 647 } 648 649 if (prov_mech == NULL) { 650 /* entry not found, simply return */ 651 mutex_exit(&mech_entry->me_mutex); 652 return; 653 } 654 655 /* remove provider entry from mech_entry chain */ 656 *prev_entry_next = prov_mech->pm_next; 657 ASSERT(mech_entry->me_num_hwprov > 0); 658 mech_entry->me_num_hwprov--; 659 break; 660 661 case CRYPTO_SW_PROVIDER: 662 if (mech_entry->me_sw_prov == NULL || 663 mech_entry->me_sw_prov->pm_prov_desc != prov_desc) { 664 /* not the software provider for this mechanism */ 665 mutex_exit(&mech_entry->me_mutex); 666 return; 667 } 668 prov_mech = mech_entry->me_sw_prov; 669 mech_entry->me_sw_prov = NULL; 670 break; 671 } 672 673 mutex_exit(&mech_entry->me_mutex); 674 675 /* Free the dual ops cross-reference lists */ 676 mil = prov_mech->pm_mi_list; 677 while (mil != NULL) { 678 next = mil->ml_next; 679 if (kcf_get_mech_entry(mil->ml_kcf_mechid, 680 &mech_entry) != KCF_SUCCESS) { 681 mil = next; 682 continue; 683 } 684 685 mutex_enter(&mech_entry->me_mutex); 686 if (prov_desc->pd_prov_type == CRYPTO_HW_PROVIDER) 687 prov_chain = mech_entry->me_hw_prov_chain; 688 else 689 prov_chain = mech_entry->me_sw_prov; 690 691 while (prov_chain != NULL) { 692 if (prov_chain->pm_prov_desc == prov_desc) { 693 prev_next = &prov_chain->pm_mi_list; 694 mil2 = prov_chain->pm_mi_list; 695 while (mil2 != NULL && 696 mil2->ml_kcf_mechid != mech_type) { 697 prev_next = &mil2->ml_next; 698 mil2 = mil2->ml_next; 699 } 700 if (mil2 != NULL) { 701 *prev_next = mil2->ml_next; 702 kmem_free(mil2, sizeof (*mil2)); 703 } 704 break; 705 } 706 prov_chain = prov_chain->pm_next; 707 } 708 709 mutex_exit(&mech_entry->me_mutex); 710 kmem_free(mil, sizeof (crypto_mech_info_list_t)); 711 mil = next; 712 } 713 714 /* free entry */ 715 KCF_PROV_REFRELE(prov_mech->pm_prov_desc); 716 KCF_PROV_IREFRELE(prov_mech->pm_prov_desc); 717 kmem_free(prov_mech, sizeof (kcf_prov_mech_desc_t)); 718 } 719 720 /* 721 * kcf_get_mech_entry() 722 * 723 * Arguments: 724 * . The framework mechanism type 725 * . Storage for the mechanism entry 726 * 727 * Description: 728 * Retrieves the mechanism entry for the mech. 729 * 730 * Context: 731 * User and interrupt contexts. 732 * 733 * Returns: 734 * KCF_MECHANISM_XXX appropriate error code. 735 * KCF_SUCCESS otherwise. 736 */ 737 int 738 kcf_get_mech_entry(crypto_mech_type_t mech_type, kcf_mech_entry_t **mep) 739 { 740 kcf_ops_class_t class; 741 int index; 742 kcf_mech_entry_tab_t *me_tab; 743 744 ASSERT(mep != NULL); 745 746 class = KCF_MECH2CLASS(mech_type); 747 748 if ((class < KCF_FIRST_OPSCLASS) || (class > KCF_LAST_OPSCLASS)) { 749 /* the caller won't need to know it's an invalid class */ 750 return (KCF_INVALID_MECH_NUMBER); 751 } 752 753 me_tab = &kcf_mech_tabs_tab[class]; 754 index = KCF_MECH2INDEX(mech_type); 755 756 if ((index < 0) || (index >= me_tab->met_size)) { 757 return (KCF_INVALID_MECH_NUMBER); 758 } 759 760 *mep = &((me_tab->met_tab)[index]); 761 762 return (KCF_SUCCESS); 763 } 764 765 /* 766 * Utility routine to save the crypto_mechanism_t structure passed 767 * by a caller. 768 */ 769 extern void 770 kcf_dup_mech(crypto_mechanism_t *src_mech, crypto_mechanism_t *dst_mech, 771 crypto_mech_type_t *save_mechtype) 772 { 773 ASSERT(dst_mech != NULL); 774 775 if (src_mech != NULL) { 776 /* Note that this is a struct-to-struct assignment. */ 777 *dst_mech = *src_mech; 778 *save_mechtype = src_mech->cm_type; 779 } 780 } 781 782 /* 783 * Returns TRUE if the provider is usable and the MOD_NOAUTOUNLOAD flag 784 * is set in the modctl structure. 785 */ 786 static boolean_t 787 auto_unload_flag_set(kcf_prov_mech_desc_t *pm) 788 { 789 kcf_provider_desc_t *pd; 790 struct modctl *mp; 791 boolean_t ret = B_FALSE; 792 793 if (pm != NULL) { 794 pd = pm->pm_prov_desc; 795 KCF_PROV_REFHOLD(pd); 796 797 if (KCF_IS_PROV_USABLE(pd)) { 798 mp = pd->pd_mctlp; 799 if (mp->mod_loadflags & MOD_NOAUTOUNLOAD) { 800 ret = B_TRUE; 801 } 802 } 803 KCF_PROV_REFRELE(pd); 804 } 805 806 return (ret); 807 } 808 809 /* 810 * Lookup the hash table for an entry that matches the mechname. 811 * If there are no hardware or software providers for the mechanism, 812 * but there is an unloaded software provider, this routine will attempt 813 * to load it. 814 * 815 * If the MOD_NOAUTOUNLOAD flag is not set, a software provider is 816 * in constant danger of being unloaded. For consumers that call 817 * crypto_mech2id() only once, the provider will not be reloaded 818 * if it becomes unloaded. If a provider gets loaded elsewhere 819 * without the MOD_NOAUTOUNLOAD flag being set, we set it now. 820 */ 821 crypto_mech_type_t 822 crypto_mech2id_common(char *mechname, boolean_t load_module) 823 { 824 crypto_mech_type_t mt; 825 kcf_mech_entry_t *me; 826 int i; 827 kcf_ops_class_t class; 828 boolean_t second_time = B_FALSE; 829 boolean_t try_to_load_software_provider = B_FALSE; 830 831 try_again: 832 mt = kcf_mech_hash_find(mechname); 833 if (!load_module || second_time == B_TRUE || servicing_interrupt()) 834 return (mt); 835 836 if (mt != CRYPTO_MECH_INVALID) { 837 class = KCF_MECH2CLASS(mt); 838 i = KCF_MECH2INDEX(mt); 839 me = &(kcf_mech_tabs_tab[class].met_tab[i]); 840 mutex_enter(&(me->me_mutex)); 841 if (load_module && !auto_unload_flag_set(me->me_sw_prov)) { 842 try_to_load_software_provider = B_TRUE; 843 } 844 mutex_exit(&(me->me_mutex)); 845 } 846 847 if (mt == CRYPTO_MECH_INVALID || try_to_load_software_provider) { 848 struct modctl *mcp; 849 boolean_t load_again = B_FALSE; 850 char *module_name; 851 int module_name_size; 852 853 /* try to find a software provider for the mechanism */ 854 if (get_sw_provider_for_mech(mechname, &module_name) 855 != CRYPTO_SUCCESS) { 856 /* mt may already be set for a hw provider */ 857 return (mt); 858 } 859 860 module_name_size = strlen(module_name) + 1; 861 if (modload("crypto", module_name) == -1 || 862 (mcp = mod_hold_by_name(module_name)) == NULL) { 863 kmem_free(module_name, module_name_size); 864 /* mt may already be set for a hw provider */ 865 return (mt); 866 } 867 868 mcp->mod_loadflags |= MOD_NOAUTOUNLOAD; 869 870 /* memory pressure may have unloaded the module */ 871 if (!mcp->mod_installed) 872 load_again = B_TRUE; 873 mod_release_mod(mcp); 874 875 if (load_again) 876 (void) modload("crypto", module_name); 877 878 kmem_free(module_name, module_name_size); 879 880 /* mt may already be set for a hw provider */ 881 if (mt != CRYPTO_MECH_INVALID) 882 return (mt); 883 884 /* 885 * Try again. Should find a software provider in the 886 * table this time around. 887 */ 888 second_time = B_TRUE; 889 goto try_again; 890 } 891 892 return (mt); 893 } 894