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.
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.
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]
22 * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
23 * Use is subject to license terms.
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>
32 /* Cryptographic mechanisms tables and their access functions */
35 * Internal numbers assigned to mechanisms are coded as follows:
37 * +----------------+----------------+
38 * | mech. class | mech. index |
39 * <--- 32-bits --->+<--- 32-bits --->
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.
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.
52 * There are no holes in the tables.
56 * Locking conventions:
57 * --------------------
58 * A global mutex, kcf_mech_tabs_lock, serializes writes to the
59 * mechanism table via kcf_create_mech_entry().
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.
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.
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*.
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.
80 /* Mechanisms tables */
83 /* RFE 4687834 Will deal with the extensibility of these tables later */
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
];
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
}
103 * Per-algorithm internal threasholds 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. Measurments with Sun Accelerator 4000
107 * shows that 512-byte jobs or smaller are better handled in software.
108 * There is room for refinement here.
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;
119 kmutex_t kcf_mech_tabs_lock
;
120 static uint32_t kcf_gen_swprov
= 0;
122 int kcf_mech_hash_size
= 256;
123 mod_hash_t
*kcf_mech_hash
; /* mech name to id hash */
125 static crypto_mech_type_t
126 kcf_mech_hash_find(char *mechname
)
129 crypto_mech_type_t mt
;
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
);
141 kcf_destroy_mech_tabs(void)
143 if (kcf_mech_hash
) mod_hash_destroy_hash(kcf_mech_hash
);
147 * kcf_init_mech_tabs()
149 * Called by the misc/kcf's _init() routine to initialize the tables
153 kcf_init_mech_tabs(void)
156 kcf_ops_class_t
class;
157 kcf_mech_entry_t
*me_tab
;
159 /* Initializes the mutex locks. */
161 mutex_init(&kcf_mech_tabs_lock
, NULL
, MUTEX_DEFAULT
, NULL
);
163 /* Then the pre-defined mechanism entries */
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
;
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
;
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
;
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
;
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
;
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
;
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
;
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
;
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
;
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
;
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
;
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
;
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
;
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
;
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
;
230 /* 1 random number generation pseudo mechanism */
231 (void) strncpy(kcf_misc_mechs_tab
[0].me_name
, SUN_RANDOM
,
232 CRYPTO_MAX_MECH_NAME
);
234 kcf_mech_hash
= mod_hash_create_strhash_nodtr("kcf mech2id hash",
235 kcf_mech_hash_size
, mod_hash_null_valdtor
);
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
));
254 * kcf_create_mech_entry()
257 * . The class of mechanism.
258 * . the name of the new mechanism.
261 * Creates a new mech_entry for a mechanism not yet known to the
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.
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.
280 kcf_create_mech_entry(kcf_ops_class_t
class, char *mechname
)
282 crypto_mech_type_t mt
;
283 kcf_mech_entry_t
*me_tab
;
286 if ((class < KCF_FIRST_OPSCLASS
) || (class > KCF_LAST_OPSCLASS
))
287 return (KCF_INVALID_MECH_CLASS
);
289 if ((mechname
== NULL
) || (mechname
[0] == 0))
290 return (KCF_INVALID_MECH_NAME
);
292 * First check if the mechanism is already in one of the tables.
293 * The mech_entry could be in another class.
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
);
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
;
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
);
315 * No a-priori information about the new mechanism, so
316 * the threshold is set to zero.
318 me_tab
[i
].me_threshold
= 0;
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
));
327 mutex_exit(&(me_tab
[i
].me_mutex
));
331 mutex_exit(&kcf_mech_tabs_lock
);
334 return (KCF_MECH_TAB_FULL
);
337 return (KCF_SUCCESS
);
341 * kcf_add_mech_provider()
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.
349 * Adds a new provider of a mechanism to the mechanism's mech_entry
356 * KCF_SUCCESS on success
357 * KCF_MECH_TAB_FULL otherwise.
360 kcf_add_mech_provider(short mech_indx
,
361 kcf_provider_desc_t
*prov_desc
, kcf_prov_mech_desc_t
**pmdpp
)
364 kcf_mech_entry_t
*mech_entry
= NULL
;
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
;
374 ASSERT(prov_desc
->pd_prov_type
!= CRYPTO_LOGICAL_PROVIDER
);
376 mech_info
= &prov_desc
->pd_mechanisms
[mech_indx
];
379 * A mechanism belongs to exactly one mechanism table.
380 * Find the class corresponding to the function group flag of
383 kcf_mech_type
= kcf_mech_hash_find(mech_info
->cm_mech_name
);
384 if (kcf_mech_type
== CRYPTO_MECH_INVALID
) {
385 crypto_func_group_t fg
= mech_info
->cm_func_group_mask
;
386 kcf_ops_class_t
class;
388 if (fg
& CRYPTO_FG_DIGEST
|| fg
& CRYPTO_FG_DIGEST_ATOMIC
)
389 class = KCF_DIGEST_CLASS
;
390 else if (fg
& CRYPTO_FG_ENCRYPT
|| fg
& CRYPTO_FG_DECRYPT
||
391 fg
& CRYPTO_FG_ENCRYPT_ATOMIC
||
392 fg
& CRYPTO_FG_DECRYPT_ATOMIC
)
393 class = KCF_CIPHER_CLASS
;
394 else if (fg
& CRYPTO_FG_MAC
|| fg
& CRYPTO_FG_MAC_ATOMIC
)
395 class = KCF_MAC_CLASS
;
396 else if (fg
& CRYPTO_FG_SIGN
|| fg
& CRYPTO_FG_VERIFY
||
397 fg
& CRYPTO_FG_SIGN_ATOMIC
||
398 fg
& CRYPTO_FG_VERIFY_ATOMIC
||
399 fg
& CRYPTO_FG_SIGN_RECOVER
||
400 fg
& CRYPTO_FG_VERIFY_RECOVER
)
401 class = KCF_SIGN_CLASS
;
402 else if (fg
& CRYPTO_FG_GENERATE
||
403 fg
& CRYPTO_FG_GENERATE_KEY_PAIR
||
404 fg
& CRYPTO_FG_WRAP
|| fg
& CRYPTO_FG_UNWRAP
||
405 fg
& CRYPTO_FG_DERIVE
)
406 class = KCF_KEYOPS_CLASS
;
408 class = KCF_MISC_CLASS
;
411 * Attempt to create a new mech_entry for the specified
412 * mechanism. kcf_create_mech_entry() can handle the case
413 * where such an entry already exists.
415 if ((error
= kcf_create_mech_entry(class,
416 mech_info
->cm_mech_name
)) != KCF_SUCCESS
) {
419 /* get the KCF mech type that was assigned to the mechanism */
420 kcf_mech_type
= kcf_mech_hash_find(mech_info
->cm_mech_name
);
421 ASSERT(kcf_mech_type
!= CRYPTO_MECH_INVALID
);
424 error
= kcf_get_mech_entry(kcf_mech_type
, &mech_entry
);
425 ASSERT(error
== KCF_SUCCESS
);
427 /* allocate and initialize new kcf_prov_mech_desc */
428 prov_mech
= kmem_zalloc(sizeof (kcf_prov_mech_desc_t
), KM_SLEEP
);
429 bcopy(mech_info
, &prov_mech
->pm_mech_info
, sizeof (crypto_mech_info_t
));
430 prov_mech
->pm_prov_desc
= prov_desc
;
431 prov_desc
->pd_mech_indx
[KCF_MECH2CLASS(kcf_mech_type
)]
432 [KCF_MECH2INDEX(kcf_mech_type
)] = mech_indx
;
434 KCF_PROV_REFHOLD(prov_desc
);
435 KCF_PROV_IREFHOLD(prov_desc
);
437 dual_fg_mask
= mech_info
->cm_func_group_mask
& CRYPTO_FG_DUAL_MASK
;
439 if (dual_fg_mask
== ((crypto_func_group_t
)0))
442 simple_fg_mask
= (mech_info
->cm_func_group_mask
&
443 CRYPTO_FG_SIMPLEOP_MASK
) | CRYPTO_FG_RANDOM
;
445 for (i
= 0; i
< prov_desc
->pd_mech_list_count
; i
++) {
446 dmi
= &prov_desc
->pd_mechanisms
[i
];
449 if (dmi
->cm_mech_number
== mech_info
->cm_mech_number
)
452 /* skip if not a dual operation mechanism */
453 if (!(dmi
->cm_func_group_mask
& dual_fg_mask
) ||
454 (dmi
->cm_func_group_mask
& simple_fg_mask
))
457 mt
= kcf_mech_hash_find(dmi
->cm_mech_name
);
458 if (mt
== CRYPTO_MECH_INVALID
)
461 if (kcf_get_mech_entry(mt
, &me
) != KCF_SUCCESS
)
464 mil
= kmem_zalloc(sizeof (*mil
), KM_SLEEP
);
465 mil2
= kmem_zalloc(sizeof (*mil2
), KM_SLEEP
);
468 * Ignore hard-coded entries in the mech table
469 * if the provider hasn't registered.
471 mutex_enter(&me
->me_mutex
);
472 if (me
->me_hw_prov_chain
== NULL
&& me
->me_sw_prov
== NULL
) {
473 mutex_exit(&me
->me_mutex
);
474 kmem_free(mil
, sizeof (*mil
));
475 kmem_free(mil2
, sizeof (*mil2
));
480 * Add other dual mechanisms that have registered
481 * with the framework to this mechanism's
482 * cross-reference list.
484 mil
->ml_mech_info
= *dmi
; /* struct assignment */
485 mil
->ml_kcf_mechid
= mt
;
487 /* add to head of list */
488 mil
->ml_next
= prov_mech
->pm_mi_list
;
489 prov_mech
->pm_mi_list
= mil
;
491 if (prov_desc
->pd_prov_type
== CRYPTO_HW_PROVIDER
)
492 prov_mech2
= me
->me_hw_prov_chain
;
494 prov_mech2
= me
->me_sw_prov
;
496 if (prov_mech2
== NULL
) {
497 kmem_free(mil2
, sizeof (*mil2
));
498 mutex_exit(&me
->me_mutex
);
503 * Update all other cross-reference lists by
504 * adding this new mechanism.
506 while (prov_mech2
!= NULL
) {
507 if (prov_mech2
->pm_prov_desc
== prov_desc
) {
508 /* struct assignment */
509 mil2
->ml_mech_info
= *mech_info
;
510 mil2
->ml_kcf_mechid
= kcf_mech_type
;
512 /* add to head of list */
513 mil2
->ml_next
= prov_mech2
->pm_mi_list
;
514 prov_mech2
->pm_mi_list
= mil2
;
517 prov_mech2
= prov_mech2
->pm_next
;
519 if (prov_mech2
== NULL
)
520 kmem_free(mil2
, sizeof (*mil2
));
522 mutex_exit(&me
->me_mutex
);
527 * Add new kcf_prov_mech_desc at the front of HW providers
530 switch (prov_desc
->pd_prov_type
) {
532 case CRYPTO_HW_PROVIDER
:
533 mutex_enter(&mech_entry
->me_mutex
);
534 prov_mech
->pm_me
= mech_entry
;
535 prov_mech
->pm_next
= mech_entry
->me_hw_prov_chain
;
536 mech_entry
->me_hw_prov_chain
= prov_mech
;
537 mech_entry
->me_num_hwprov
++;
538 mutex_exit(&mech_entry
->me_mutex
);
541 case CRYPTO_SW_PROVIDER
:
542 mutex_enter(&mech_entry
->me_mutex
);
543 if (mech_entry
->me_sw_prov
!= NULL
) {
545 * There is already a SW provider for this mechanism.
546 * Since we allow only one SW provider per mechanism,
547 * report this condition.
549 cmn_err(CE_WARN
, "The cryptographic software provider "
550 "\"%s\" will not be used for %s. The provider "
551 "\"%s\" will be used for this mechanism "
552 "instead.", prov_desc
->pd_description
,
553 mech_info
->cm_mech_name
,
554 mech_entry
->me_sw_prov
->pm_prov_desc
->
556 KCF_PROV_REFRELE(prov_desc
);
557 kmem_free(prov_mech
, sizeof (kcf_prov_mech_desc_t
));
561 * Set the provider as the software provider for
564 mech_entry
->me_sw_prov
= prov_mech
;
566 /* We'll wrap around after 4 billion registrations! */
567 mech_entry
->me_gen_swprov
= kcf_gen_swprov
++;
569 mutex_exit(&mech_entry
->me_mutex
);
577 return (KCF_SUCCESS
);
581 * kcf_remove_mech_provider()
584 * . mech_name: the name of the mechanism.
585 * . prov_desc: The provider descriptor
588 * Removes a provider from chain of provider descriptors.
589 * The provider is made unavailable to kernel consumers for the specified
596 kcf_remove_mech_provider(char *mech_name
, kcf_provider_desc_t
*prov_desc
)
598 crypto_mech_type_t mech_type
;
599 kcf_prov_mech_desc_t
*prov_mech
= NULL
, *prov_chain
;
600 kcf_prov_mech_desc_t
**prev_entry_next
;
601 kcf_mech_entry_t
*mech_entry
;
602 crypto_mech_info_list_t
*mil
, *mil2
, *next
, **prev_next
;
604 ASSERT(prov_desc
->pd_prov_type
!= CRYPTO_LOGICAL_PROVIDER
);
606 /* get the KCF mech type that was assigned to the mechanism */
607 if ((mech_type
= kcf_mech_hash_find(mech_name
)) ==
608 CRYPTO_MECH_INVALID
) {
610 * Provider was not allowed for this mech due to policy or
616 /* get a ptr to the mech_entry that was created */
617 if (kcf_get_mech_entry(mech_type
, &mech_entry
) != KCF_SUCCESS
) {
619 * Provider was not allowed for this mech due to policy or
625 mutex_enter(&mech_entry
->me_mutex
);
627 switch (prov_desc
->pd_prov_type
) {
629 case CRYPTO_HW_PROVIDER
:
630 /* find the provider in the mech_entry chain */
631 prev_entry_next
= &mech_entry
->me_hw_prov_chain
;
632 prov_mech
= mech_entry
->me_hw_prov_chain
;
633 while (prov_mech
!= NULL
&&
634 prov_mech
->pm_prov_desc
!= prov_desc
) {
635 prev_entry_next
= &prov_mech
->pm_next
;
636 prov_mech
= prov_mech
->pm_next
;
639 if (prov_mech
== NULL
) {
640 /* entry not found, simply return */
641 mutex_exit(&mech_entry
->me_mutex
);
645 /* remove provider entry from mech_entry chain */
646 *prev_entry_next
= prov_mech
->pm_next
;
647 ASSERT(mech_entry
->me_num_hwprov
> 0);
648 mech_entry
->me_num_hwprov
--;
651 case CRYPTO_SW_PROVIDER
:
652 if (mech_entry
->me_sw_prov
== NULL
||
653 mech_entry
->me_sw_prov
->pm_prov_desc
!= prov_desc
) {
654 /* not the software provider for this mechanism */
655 mutex_exit(&mech_entry
->me_mutex
);
658 prov_mech
= mech_entry
->me_sw_prov
;
659 mech_entry
->me_sw_prov
= NULL
;
665 mutex_exit(&mech_entry
->me_mutex
);
667 /* Free the dual ops cross-reference lists */
668 mil
= prov_mech
->pm_mi_list
;
669 while (mil
!= NULL
) {
671 if (kcf_get_mech_entry(mil
->ml_kcf_mechid
,
672 &mech_entry
) != KCF_SUCCESS
) {
677 mutex_enter(&mech_entry
->me_mutex
);
678 if (prov_desc
->pd_prov_type
== CRYPTO_HW_PROVIDER
)
679 prov_chain
= mech_entry
->me_hw_prov_chain
;
681 prov_chain
= mech_entry
->me_sw_prov
;
683 while (prov_chain
!= NULL
) {
684 if (prov_chain
->pm_prov_desc
== prov_desc
) {
685 prev_next
= &prov_chain
->pm_mi_list
;
686 mil2
= prov_chain
->pm_mi_list
;
687 while (mil2
!= NULL
&&
688 mil2
->ml_kcf_mechid
!= mech_type
) {
689 prev_next
= &mil2
->ml_next
;
690 mil2
= mil2
->ml_next
;
693 *prev_next
= mil2
->ml_next
;
694 kmem_free(mil2
, sizeof (*mil2
));
698 prov_chain
= prov_chain
->pm_next
;
701 mutex_exit(&mech_entry
->me_mutex
);
702 kmem_free(mil
, sizeof (crypto_mech_info_list_t
));
707 KCF_PROV_REFRELE(prov_mech
->pm_prov_desc
);
708 KCF_PROV_IREFRELE(prov_mech
->pm_prov_desc
);
709 kmem_free(prov_mech
, sizeof (kcf_prov_mech_desc_t
));
713 * kcf_get_mech_entry()
716 * . The framework mechanism type
717 * . Storage for the mechanism entry
720 * Retrieves the mechanism entry for the mech.
723 * User and interrupt contexts.
726 * KCF_MECHANISM_XXX appropriate error code.
727 * KCF_SUCCESS otherwise.
730 kcf_get_mech_entry(crypto_mech_type_t mech_type
, kcf_mech_entry_t
**mep
)
732 kcf_ops_class_t
class;
734 kcf_mech_entry_tab_t
*me_tab
;
738 class = KCF_MECH2CLASS(mech_type
);
740 if ((class < KCF_FIRST_OPSCLASS
) || (class > KCF_LAST_OPSCLASS
)) {
741 /* the caller won't need to know it's an invalid class */
742 return (KCF_INVALID_MECH_NUMBER
);
745 me_tab
= &kcf_mech_tabs_tab
[class];
746 index
= KCF_MECH2INDEX(mech_type
);
748 if ((index
< 0) || (index
>= me_tab
->met_size
)) {
749 return (KCF_INVALID_MECH_NUMBER
);
752 *mep
= &((me_tab
->met_tab
)[index
]);
754 return (KCF_SUCCESS
);
757 /* CURRENTLY UNSUPPORTED: attempting to load the module if it isn't found */
759 * Lookup the hash table for an entry that matches the mechname.
760 * If there are no hardware or software providers for the mechanism,
761 * but there is an unloaded software provider, this routine will attempt
764 * If the MOD_NOAUTOUNLOAD flag is not set, a software provider is
765 * in constant danger of being unloaded. For consumers that call
766 * crypto_mech2id() only once, the provider will not be reloaded
767 * if it becomes unloaded. If a provider gets loaded elsewhere
768 * without the MOD_NOAUTOUNLOAD flag being set, we set it now.
771 crypto_mech2id_common(char *mechname
, boolean_t load_module
)
773 crypto_mech_type_t mt
= kcf_mech_hash_find(mechname
);