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