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