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 2009 Sun Microsystems, Inc. All rights reserved.
23 * Use is subject to license terms.
26 #include <sys/types.h>
27 #include <sys/sunddi.h>
28 #include <sys/errno.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>
36 /* Cryptographic mechanisms tables and their access functions */
39 * Internal numbers assigned to mechanisms are coded as follows:
41 * +----------------+----------------+
42 * | mech. class | mech. index |
43 * <--- 32-bits --->+<--- 32-bits --->
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.
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.
56 * There are no holes in the tables.
60 * Locking conventions:
61 * --------------------
62 * A global mutex, kcf_mech_tabs_lock, serializes writes to the
63 * mechanism table via kcf_create_mech_entry().
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.
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.
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*.
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.
84 /* Mechanisms tables */
87 /* RFE 4687834 Will deal with the extensibility of these tables later */
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
];
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
}
107 * Protects fields in kcf_mech_entry. This is an array
108 * of locks indexed by the cpuid. A reader needs to hold
109 * a single lock while a writer needs to hold all locks.
110 * krwlock_t is not an option here because the hold time
111 * is very small for these locks.
113 kcf_lock_withpad_t
*me_mutexes
;
115 #define ME_MUTEXES_ENTER_ALL() \
116 for (int i = 0; i < max_ncpus; i++) \
117 mutex_enter(&me_mutexes[i].kl_lock);
119 #define ME_MUTEXES_EXIT_ALL() \
120 for (int i = 0; i < max_ncpus; i++) \
121 mutex_exit(&me_mutexes[i].kl_lock);
124 * Per-algorithm internal thresholds for the minimum input size of before
125 * offloading to hardware provider.
126 * Dispatching a crypto operation to a hardware provider entails paying the
127 * cost of an additional context switch. Measurments with Sun Accelerator 4000
128 * shows that 512-byte jobs or smaller are better handled in software.
129 * There is room for refinement here.
132 int kcf_md5_threshold
= 512;
133 int kcf_sha1_threshold
= 512;
134 int kcf_des_threshold
= 512;
135 int kcf_des3_threshold
= 512;
136 int kcf_aes_threshold
= 512;
137 int kcf_bf_threshold
= 512;
138 int kcf_rc4_threshold
= 512;
140 kmutex_t kcf_mech_tabs_lock
;
141 static uint32_t kcf_gen_swprov
= 0;
143 int kcf_mech_hash_size
= 256;
144 mod_hash_t
*kcf_mech_hash
; /* mech name to id hash */
146 static crypto_mech_type_t
147 kcf_mech_hash_find(char *mechname
)
150 crypto_mech_type_t mt
;
152 mt
= CRYPTO_MECH_INVALID
;
153 if (mod_hash_find(kcf_mech_hash
, (mod_hash_key_t
)mechname
, &hv
) == 0) {
154 mt
= *(crypto_mech_type_t
*)hv
;
155 ASSERT(mt
!= CRYPTO_MECH_INVALID
);
162 * kcf_init_mech_tabs()
164 * Called by the misc/kcf's _init() routine to initialize the tables
171 kcf_ops_class_t
class;
172 kcf_mech_entry_t
*me_tab
;
174 /* Initializes the mutex locks. */
176 mutex_init(&kcf_mech_tabs_lock
, NULL
, MUTEX_DEFAULT
, NULL
);
178 /* Then the pre-defined mechanism entries */
181 (void) strncpy(kcf_digest_mechs_tab
[0].me_name
, SUN_CKM_MD5
,
182 CRYPTO_MAX_MECH_NAME
);
183 kcf_digest_mechs_tab
[0].me_threshold
= kcf_md5_threshold
;
185 (void) strncpy(kcf_digest_mechs_tab
[1].me_name
, SUN_CKM_SHA1
,
186 CRYPTO_MAX_MECH_NAME
);
187 kcf_digest_mechs_tab
[1].me_threshold
= kcf_sha1_threshold
;
189 /* The symmetric ciphers in various modes */
190 (void) strncpy(kcf_cipher_mechs_tab
[0].me_name
, SUN_CKM_DES_CBC
,
191 CRYPTO_MAX_MECH_NAME
);
192 kcf_cipher_mechs_tab
[0].me_threshold
= kcf_des_threshold
;
194 (void) strncpy(kcf_cipher_mechs_tab
[1].me_name
, SUN_CKM_DES3_CBC
,
195 CRYPTO_MAX_MECH_NAME
);
196 kcf_cipher_mechs_tab
[1].me_threshold
= kcf_des3_threshold
;
198 (void) strncpy(kcf_cipher_mechs_tab
[2].me_name
, SUN_CKM_DES_ECB
,
199 CRYPTO_MAX_MECH_NAME
);
200 kcf_cipher_mechs_tab
[2].me_threshold
= kcf_des_threshold
;
202 (void) strncpy(kcf_cipher_mechs_tab
[3].me_name
, SUN_CKM_DES3_ECB
,
203 CRYPTO_MAX_MECH_NAME
);
204 kcf_cipher_mechs_tab
[3].me_threshold
= kcf_des3_threshold
;
206 (void) strncpy(kcf_cipher_mechs_tab
[4].me_name
, SUN_CKM_BLOWFISH_CBC
,
207 CRYPTO_MAX_MECH_NAME
);
208 kcf_cipher_mechs_tab
[4].me_threshold
= kcf_bf_threshold
;
210 (void) strncpy(kcf_cipher_mechs_tab
[5].me_name
, SUN_CKM_BLOWFISH_ECB
,
211 CRYPTO_MAX_MECH_NAME
);
212 kcf_cipher_mechs_tab
[5].me_threshold
= kcf_bf_threshold
;
214 (void) strncpy(kcf_cipher_mechs_tab
[6].me_name
, SUN_CKM_AES_CBC
,
215 CRYPTO_MAX_MECH_NAME
);
216 kcf_cipher_mechs_tab
[6].me_threshold
= kcf_aes_threshold
;
218 (void) strncpy(kcf_cipher_mechs_tab
[7].me_name
, SUN_CKM_AES_ECB
,
219 CRYPTO_MAX_MECH_NAME
);
220 kcf_cipher_mechs_tab
[7].me_threshold
= kcf_aes_threshold
;
222 (void) strncpy(kcf_cipher_mechs_tab
[8].me_name
, SUN_CKM_RC4
,
223 CRYPTO_MAX_MECH_NAME
);
224 kcf_cipher_mechs_tab
[8].me_threshold
= kcf_rc4_threshold
;
228 (void) strncpy(kcf_mac_mechs_tab
[0].me_name
, SUN_CKM_MD5_HMAC
,
229 CRYPTO_MAX_MECH_NAME
);
230 kcf_mac_mechs_tab
[0].me_threshold
= kcf_md5_threshold
;
232 (void) strncpy(kcf_mac_mechs_tab
[1].me_name
, SUN_CKM_MD5_HMAC_GENERAL
,
233 CRYPTO_MAX_MECH_NAME
);
234 kcf_mac_mechs_tab
[1].me_threshold
= kcf_md5_threshold
;
236 (void) strncpy(kcf_mac_mechs_tab
[2].me_name
, SUN_CKM_SHA1_HMAC
,
237 CRYPTO_MAX_MECH_NAME
);
238 kcf_mac_mechs_tab
[2].me_threshold
= kcf_sha1_threshold
;
240 (void) strncpy(kcf_mac_mechs_tab
[3].me_name
, SUN_CKM_SHA1_HMAC_GENERAL
,
241 CRYPTO_MAX_MECH_NAME
);
242 kcf_mac_mechs_tab
[3].me_threshold
= kcf_sha1_threshold
;
244 (void) strncpy(kcf_mac_mechs_tab
[4].me_name
, SUN_CKM_AES_GMAC
,
245 CRYPTO_MAX_MECH_NAME
);
246 kcf_mac_mechs_tab
[4].me_threshold
= kcf_sha1_threshold
;
248 (void) strncpy(kcf_mac_mechs_tab
[5].me_name
, SUN_CKM_AES_CMAC
,
249 CRYPTO_MAX_MECH_NAME
);
250 kcf_mac_mechs_tab
[5].me_threshold
= kcf_sha1_threshold
;
252 /* 1 random number generation pseudo mechanism */
253 (void) strncpy(kcf_misc_mechs_tab
[0].me_name
, SUN_RANDOM
,
254 CRYPTO_MAX_MECH_NAME
);
256 kcf_mech_hash
= mod_hash_create_strhash("kcf mech2id hash",
257 kcf_mech_hash_size
, mod_hash_null_valdtor
);
259 for (class = KCF_FIRST_OPSCLASS
; class <= KCF_LAST_OPSCLASS
; class++) {
260 max
= kcf_mech_tabs_tab
[class].met_size
;
261 me_tab
= kcf_mech_tabs_tab
[class].met_tab
;
262 for (i
= 0; i
< max
; i
++) {
263 if (me_tab
[i
].me_name
[0] != 0) {
264 me_tab
[i
].me_mechid
= KCF_MECHID(class, i
);
265 (void) mod_hash_insert(kcf_mech_hash
,
266 (mod_hash_key_t
)me_tab
[i
].me_name
,
267 (mod_hash_val_t
)&(me_tab
[i
].me_mechid
));
272 me_mutexes
= kmem_zalloc(max_ncpus
* sizeof (kcf_lock_withpad_t
),
274 for (i
= 0; i
< max_ncpus
; i
++) {
275 mutex_init(&me_mutexes
[i
].kl_lock
, NULL
, MUTEX_DEFAULT
, NULL
);
280 * kcf_create_mech_entry()
283 * . The class of mechanism.
284 * . the name of the new mechanism.
287 * Creates a new mech_entry for a mechanism not yet known to the
289 * This routine is called by kcf_add_mech_provider, which is
290 * in turn invoked for each mechanism supported by a provider.
291 * The'class' argument depends on the crypto_func_group_t bitmask
292 * in the registering provider's mech_info struct for this mechanism.
293 * When there is ambiguity in the mapping between the crypto_func_group_t
294 * and a class (dual ops, ...) the KCF_MISC_CLASS should be used.
300 * KCF_INVALID_MECH_CLASS or KCF_INVALID_MECH_NAME if the class or
301 * the mechname is bogus.
302 * KCF_MECH_TAB_FULL when there is no room left in the mech. tabs.
303 * KCF_SUCCESS otherwise.
306 kcf_create_mech_entry(kcf_ops_class_t
class, char *mechname
)
308 crypto_mech_type_t mt
;
309 kcf_mech_entry_t
*me_tab
;
312 if ((class < KCF_FIRST_OPSCLASS
) || (class > KCF_LAST_OPSCLASS
))
313 return (KCF_INVALID_MECH_CLASS
);
315 if ((mechname
== NULL
) || (mechname
[0] == 0))
316 return (KCF_INVALID_MECH_NAME
);
318 * First check if the mechanism is already in one of the tables.
319 * The mech_entry could be in another class.
321 mutex_enter(&kcf_mech_tabs_lock
);
322 mt
= kcf_mech_hash_find(mechname
);
323 if (mt
!= CRYPTO_MECH_INVALID
) {
324 /* Nothing to do, regardless the suggested class. */
325 mutex_exit(&kcf_mech_tabs_lock
);
326 return (KCF_SUCCESS
);
328 /* Now take the next unused mech entry in the class's tab */
329 me_tab
= kcf_mech_tabs_tab
[class].met_tab
;
330 size
= kcf_mech_tabs_tab
[class].met_size
;
333 ME_MUTEXES_ENTER_ALL();
334 if (me_tab
[i
].me_name
[0] == 0) {
335 /* Found an empty spot */
336 (void) strncpy(me_tab
[i
].me_name
, mechname
,
337 CRYPTO_MAX_MECH_NAME
);
338 me_tab
[i
].me_name
[CRYPTO_MAX_MECH_NAME
-1] = '\0';
339 me_tab
[i
].me_mechid
= KCF_MECHID(class, i
);
341 * No a-priori information about the new mechanism, so
342 * the threshold is set to zero.
344 me_tab
[i
].me_threshold
= 0;
346 ME_MUTEXES_EXIT_ALL();
347 /* Add the new mechanism to the hash table */
348 (void) mod_hash_insert(kcf_mech_hash
,
349 (mod_hash_key_t
)me_tab
[i
].me_name
,
350 (mod_hash_val_t
)&(me_tab
[i
].me_mechid
));
353 ME_MUTEXES_EXIT_ALL();
357 mutex_exit(&kcf_mech_tabs_lock
);
360 return (KCF_MECH_TAB_FULL
);
363 return (KCF_SUCCESS
);
367 * kcf_add_mech_provider()
370 * . An index in to the provider mechanism array
371 * . A pointer to the provider descriptor
372 * . A storage for the kcf_prov_mech_desc_t the entry was added at.
375 * Adds a new provider of a mechanism to the mechanism's mech_entry
382 * KCF_SUCCESS on success
383 * KCF_MECH_TAB_FULL otherwise.
386 kcf_add_mech_provider(short mech_indx
,
387 kcf_provider_desc_t
*prov_desc
, kcf_prov_mech_desc_t
**pmdpp
)
390 kcf_mech_entry_t
*mech_entry
;
391 crypto_mech_info_t
*mech_info
;
392 crypto_mech_type_t kcf_mech_type
, mt
;
393 kcf_prov_mech_desc_t
*prov_mech
, *prov_mech2
;
394 crypto_func_group_t simple_fg_mask
, dual_fg_mask
;
395 crypto_mech_info_t
*dmi
;
396 crypto_mech_info_list_t
*mil
, *mil2
;
397 kcf_mech_entry_t
*me
;
400 ASSERT(prov_desc
->pd_prov_type
!= CRYPTO_LOGICAL_PROVIDER
);
402 mech_info
= &prov_desc
->pd_mechanisms
[mech_indx
];
404 * Do not use the provider for the mechanism if
405 * policy does not allow it.
407 if (is_mech_disabled(prov_desc
, mech_info
->cm_mech_name
)) {
409 return (KCF_SUCCESS
);
413 * A mechanism belongs to exactly one mechanism table.
414 * Find the class corresponding to the function group flag of
417 kcf_mech_type
= kcf_mech_hash_find(mech_info
->cm_mech_name
);
418 if (kcf_mech_type
== CRYPTO_MECH_INVALID
) {
419 crypto_func_group_t fg
= mech_info
->cm_func_group_mask
;
420 kcf_ops_class_t
class;
422 if (fg
& CRYPTO_FG_DIGEST
|| fg
& CRYPTO_FG_DIGEST_ATOMIC
)
423 class = KCF_DIGEST_CLASS
;
424 else if (fg
& CRYPTO_FG_ENCRYPT
|| fg
& CRYPTO_FG_DECRYPT
||
425 fg
& CRYPTO_FG_ENCRYPT_ATOMIC
||
426 fg
& CRYPTO_FG_DECRYPT_ATOMIC
)
427 class = KCF_CIPHER_CLASS
;
428 else if (fg
& CRYPTO_FG_MAC
|| fg
& CRYPTO_FG_MAC_ATOMIC
)
429 class = KCF_MAC_CLASS
;
430 else if (fg
& CRYPTO_FG_SIGN
|| fg
& CRYPTO_FG_VERIFY
||
431 fg
& CRYPTO_FG_SIGN_ATOMIC
||
432 fg
& CRYPTO_FG_VERIFY_ATOMIC
||
433 fg
& CRYPTO_FG_SIGN_RECOVER
||
434 fg
& CRYPTO_FG_VERIFY_RECOVER
)
435 class = KCF_SIGN_CLASS
;
436 else if (fg
& CRYPTO_FG_GENERATE
||
437 fg
& CRYPTO_FG_GENERATE_KEY_PAIR
||
438 fg
& CRYPTO_FG_WRAP
|| fg
& CRYPTO_FG_UNWRAP
||
439 fg
& CRYPTO_FG_DERIVE
)
440 class = KCF_KEYOPS_CLASS
;
442 class = KCF_MISC_CLASS
;
445 * Attempt to create a new mech_entry for the specified
446 * mechanism. kcf_create_mech_entry() can handle the case
447 * where such an entry already exists.
449 if ((error
= kcf_create_mech_entry(class,
450 mech_info
->cm_mech_name
)) != KCF_SUCCESS
) {
453 /* get the KCF mech type that was assigned to the mechanism */
454 kcf_mech_type
= kcf_mech_hash_find(mech_info
->cm_mech_name
);
455 ASSERT(kcf_mech_type
!= CRYPTO_MECH_INVALID
);
458 error
= kcf_get_mech_entry(kcf_mech_type
, &mech_entry
);
459 ASSERT(error
== KCF_SUCCESS
);
461 /* allocate and initialize new kcf_prov_mech_desc */
462 prov_mech
= kmem_zalloc(sizeof (kcf_prov_mech_desc_t
), KM_SLEEP
);
463 bcopy(mech_info
, &prov_mech
->pm_mech_info
, sizeof (crypto_mech_info_t
));
464 prov_mech
->pm_prov_desc
= prov_desc
;
465 prov_desc
->pd_mech_indx
[KCF_MECH2CLASS(kcf_mech_type
)]
466 [KCF_MECH2INDEX(kcf_mech_type
)] = mech_indx
;
468 KCF_PROV_REFHOLD(prov_desc
);
470 dual_fg_mask
= mech_info
->cm_func_group_mask
& CRYPTO_FG_DUAL_MASK
;
472 if (dual_fg_mask
== ((crypto_func_group_t
)0))
475 simple_fg_mask
= mech_info
->cm_func_group_mask
&
476 CRYPTO_FG_SIMPLEOP_MASK
| CRYPTO_FG_RANDOM
;
478 for (i
= 0; i
< prov_desc
->pd_mech_list_count
; i
++) {
479 dmi
= &prov_desc
->pd_mechanisms
[i
];
482 if (dmi
->cm_mech_number
== mech_info
->cm_mech_number
)
485 /* skip if policy doesn't allow mechanism */
486 if (is_mech_disabled(prov_desc
, dmi
->cm_mech_name
))
489 /* skip if not a dual operation mechanism */
490 if (!(dmi
->cm_func_group_mask
& dual_fg_mask
) ||
491 (dmi
->cm_func_group_mask
& simple_fg_mask
))
494 mt
= kcf_mech_hash_find(dmi
->cm_mech_name
);
495 if (mt
== CRYPTO_MECH_INVALID
)
498 if (kcf_get_mech_entry(mt
, &me
) != KCF_SUCCESS
)
501 mil
= kmem_zalloc(sizeof (*mil
), KM_SLEEP
);
502 mil2
= kmem_zalloc(sizeof (*mil2
), KM_SLEEP
);
505 * Ignore hard-coded entries in the mech table
506 * if the provider hasn't registered.
508 ME_MUTEXES_ENTER_ALL();
509 if (me
->me_hw_prov_chain
== NULL
&& me
->me_sw_prov
== NULL
) {
510 ME_MUTEXES_EXIT_ALL();
511 kmem_free(mil
, sizeof (*mil
));
512 kmem_free(mil2
, sizeof (*mil2
));
517 * Add other dual mechanisms that have registered
518 * with the framework to this mechanism's
519 * cross-reference list.
521 mil
->ml_mech_info
= *dmi
; /* struct assignment */
522 mil
->ml_kcf_mechid
= mt
;
524 /* add to head of list */
525 mil
->ml_next
= prov_mech
->pm_mi_list
;
526 prov_mech
->pm_mi_list
= mil
;
528 if (prov_desc
->pd_prov_type
== CRYPTO_HW_PROVIDER
)
529 prov_mech2
= me
->me_hw_prov_chain
;
531 prov_mech2
= me
->me_sw_prov
;
533 if (prov_mech2
== NULL
) {
534 kmem_free(mil2
, sizeof (*mil2
));
535 ME_MUTEXES_EXIT_ALL();
540 * Update all other cross-reference lists by
541 * adding this new mechanism.
543 while (prov_mech2
!= NULL
) {
544 if (prov_mech2
->pm_prov_desc
== prov_desc
) {
545 /* struct assignment */
546 mil2
->ml_mech_info
= *mech_info
;
547 mil2
->ml_kcf_mechid
= kcf_mech_type
;
549 /* add to head of list */
550 mil2
->ml_next
= prov_mech2
->pm_mi_list
;
551 prov_mech2
->pm_mi_list
= mil2
;
554 prov_mech2
= prov_mech2
->pm_next
;
556 if (prov_mech2
== NULL
)
557 kmem_free(mil2
, sizeof (*mil2
));
559 ME_MUTEXES_EXIT_ALL();
564 * Add new kcf_prov_mech_desc at the front of HW providers
567 switch (prov_desc
->pd_prov_type
) {
569 case CRYPTO_HW_PROVIDER
:
570 ME_MUTEXES_ENTER_ALL();
571 prov_mech
->pm_me
= mech_entry
;
572 prov_mech
->pm_next
= mech_entry
->me_hw_prov_chain
;
573 mech_entry
->me_hw_prov_chain
= prov_mech
;
574 mech_entry
->me_num_hwprov
++;
575 ME_MUTEXES_EXIT_ALL();
578 case CRYPTO_SW_PROVIDER
:
579 ME_MUTEXES_ENTER_ALL();
580 if (mech_entry
->me_sw_prov
!= NULL
) {
582 * There is already a SW provider for this mechanism.
583 * Since we allow only one SW provider per mechanism,
584 * report this condition.
586 cmn_err(CE_WARN
, "The cryptographic software provider "
587 "\"%s\" will not be used for %s. The provider "
588 "\"%s\" will be used for this mechanism "
589 "instead.", prov_desc
->pd_description
,
590 mech_info
->cm_mech_name
,
591 mech_entry
->me_sw_prov
->pm_prov_desc
->
593 KCF_PROV_REFRELE(prov_desc
);
594 kmem_free(prov_mech
, sizeof (kcf_prov_mech_desc_t
));
598 * Set the provider as the software provider for
601 mech_entry
->me_sw_prov
= prov_mech
;
603 /* We'll wrap around after 4 billion registrations! */
604 mech_entry
->me_gen_swprov
= kcf_gen_swprov
++;
606 ME_MUTEXES_EXIT_ALL();
612 return (KCF_SUCCESS
);
616 * kcf_remove_mech_provider()
619 * . mech_name: the name of the mechanism.
620 * . prov_desc: The provider descriptor
623 * Removes a provider from chain of provider descriptors.
624 * The provider is made unavailable to kernel consumers for the specified
631 kcf_remove_mech_provider(char *mech_name
, kcf_provider_desc_t
*prov_desc
)
633 crypto_mech_type_t mech_type
;
634 kcf_prov_mech_desc_t
*prov_mech
, *prov_chain
;
635 kcf_prov_mech_desc_t
**prev_entry_next
;
636 kcf_mech_entry_t
*mech_entry
;
637 crypto_mech_info_list_t
*mil
, *mil2
, *next
, **prev_next
;
639 ASSERT(prov_desc
->pd_prov_type
!= CRYPTO_LOGICAL_PROVIDER
);
641 /* get the KCF mech type that was assigned to the mechanism */
642 if ((mech_type
= kcf_mech_hash_find(mech_name
)) ==
643 CRYPTO_MECH_INVALID
) {
645 * Provider was not allowed for this mech due to policy or
651 /* get a ptr to the mech_entry that was created */
652 if (kcf_get_mech_entry(mech_type
, &mech_entry
) != KCF_SUCCESS
) {
654 * Provider was not allowed for this mech due to policy or
660 ME_MUTEXES_ENTER_ALL();
662 switch (prov_desc
->pd_prov_type
) {
664 case CRYPTO_HW_PROVIDER
:
665 /* find the provider in the mech_entry chain */
666 prev_entry_next
= &mech_entry
->me_hw_prov_chain
;
667 prov_mech
= mech_entry
->me_hw_prov_chain
;
668 while (prov_mech
!= NULL
&&
669 prov_mech
->pm_prov_desc
!= prov_desc
) {
670 prev_entry_next
= &prov_mech
->pm_next
;
671 prov_mech
= prov_mech
->pm_next
;
674 if (prov_mech
== NULL
) {
675 /* entry not found, simply return */
676 ME_MUTEXES_EXIT_ALL();
680 /* remove provider entry from mech_entry chain */
681 *prev_entry_next
= prov_mech
->pm_next
;
682 ASSERT(mech_entry
->me_num_hwprov
> 0);
683 mech_entry
->me_num_hwprov
--;
686 case CRYPTO_SW_PROVIDER
:
687 if (mech_entry
->me_sw_prov
== NULL
||
688 mech_entry
->me_sw_prov
->pm_prov_desc
!= prov_desc
) {
689 /* not the software provider for this mechanism */
690 ME_MUTEXES_EXIT_ALL();
693 prov_mech
= mech_entry
->me_sw_prov
;
694 mech_entry
->me_sw_prov
= NULL
;
698 ME_MUTEXES_EXIT_ALL();
700 /* Free the dual ops cross-reference lists */
701 mil
= prov_mech
->pm_mi_list
;
702 while (mil
!= NULL
) {
704 if (kcf_get_mech_entry(mil
->ml_kcf_mechid
,
705 &mech_entry
) != KCF_SUCCESS
) {
710 ME_MUTEXES_ENTER_ALL();
711 if (prov_desc
->pd_prov_type
== CRYPTO_HW_PROVIDER
)
712 prov_chain
= mech_entry
->me_hw_prov_chain
;
714 prov_chain
= mech_entry
->me_sw_prov
;
716 while (prov_chain
!= NULL
) {
717 if (prov_chain
->pm_prov_desc
== prov_desc
) {
718 prev_next
= &prov_chain
->pm_mi_list
;
719 mil2
= prov_chain
->pm_mi_list
;
720 while (mil2
!= NULL
&&
721 mil2
->ml_kcf_mechid
!= mech_type
) {
722 prev_next
= &mil2
->ml_next
;
723 mil2
= mil2
->ml_next
;
726 *prev_next
= mil2
->ml_next
;
727 kmem_free(mil2
, sizeof (*mil2
));
731 prov_chain
= prov_chain
->pm_next
;
734 ME_MUTEXES_EXIT_ALL();
735 kmem_free(mil
, sizeof (crypto_mech_info_list_t
));
740 KCF_PROV_REFRELE(prov_mech
->pm_prov_desc
);
741 kmem_free(prov_mech
, sizeof (kcf_prov_mech_desc_t
));
745 * kcf_get_mech_entry()
748 * . The framework mechanism type
749 * . Storage for the mechanism entry
752 * Retrieves the mechanism entry for the mech.
755 * User and interrupt contexts.
758 * KCF_MECHANISM_XXX appropriate error code.
759 * KCF_SUCCESS otherwise.
762 kcf_get_mech_entry(crypto_mech_type_t mech_type
, kcf_mech_entry_t
**mep
)
764 kcf_ops_class_t
class;
766 kcf_mech_entry_tab_t
*me_tab
;
770 class = KCF_MECH2CLASS(mech_type
);
772 if ((class < KCF_FIRST_OPSCLASS
) || (class > KCF_LAST_OPSCLASS
)) {
773 /* the caller won't need to know it's an invalid class */
774 return (KCF_INVALID_MECH_NUMBER
);
777 me_tab
= &kcf_mech_tabs_tab
[class];
778 index
= KCF_MECH2INDEX(mech_type
);
780 if ((index
< 0) || (index
>= me_tab
->met_size
)) {
781 return (KCF_INVALID_MECH_NUMBER
);
784 *mep
= &((me_tab
->met_tab
)[index
]);
786 return (KCF_SUCCESS
);
790 * Returns TRUE if the provider is usable and the MOD_NOAUTOUNLOAD flag
791 * is set in the modctl structure.
794 auto_unload_flag_set(kcf_prov_mech_desc_t
*pm
)
796 kcf_provider_desc_t
*pd
;
798 boolean_t ret
= B_FALSE
;
801 pd
= pm
->pm_prov_desc
;
802 KCF_PROV_REFHOLD(pd
);
804 if (KCF_IS_PROV_USABLE(pd
)) {
806 if (mp
->mod_loadflags
& MOD_NOAUTOUNLOAD
) {
810 KCF_PROV_REFRELE(pd
);
817 * Lookup the hash table for an entry that matches the mechname.
818 * If there are no hardware or software providers for the mechanism,
819 * but there is an unloaded software provider, this routine will attempt
822 * If the MOD_NOAUTOUNLOAD flag is not set, a software provider is
823 * in constant danger of being unloaded. For consumers that call
824 * crypto_mech2id() only once, the provider will not be reloaded
825 * if it becomes unloaded. If a provider gets loaded elsewhere
826 * without the MOD_NOAUTOUNLOAD flag being set, we set it now.
829 crypto_mech2id_common(char *mechname
, boolean_t load_module
)
831 crypto_mech_type_t mt
;
832 kcf_mech_entry_t
*me
;
834 kcf_ops_class_t
class;
835 boolean_t second_time
= B_FALSE
;
836 boolean_t try_to_load_software_provider
= B_FALSE
;
837 kcf_lock_withpad_t
*mp
;
840 mt
= kcf_mech_hash_find(mechname
);
841 if (!load_module
|| second_time
== B_TRUE
|| servicing_interrupt())
844 if (mt
!= CRYPTO_MECH_INVALID
) {
845 class = KCF_MECH2CLASS(mt
);
846 i
= KCF_MECH2INDEX(mt
);
847 me
= &(kcf_mech_tabs_tab
[class].met_tab
[i
]);
848 mp
= &me_mutexes
[CPU_SEQID
];
849 mutex_enter(&mp
->kl_lock
);
851 if (load_module
&& !auto_unload_flag_set(me
->me_sw_prov
)) {
852 try_to_load_software_provider
= B_TRUE
;
854 mutex_exit(&mp
->kl_lock
);
857 if (mt
== CRYPTO_MECH_INVALID
|| try_to_load_software_provider
) {
859 boolean_t load_again
= B_FALSE
;
861 int module_name_size
;
863 /* try to find a software provider for the mechanism */
864 if (get_sw_provider_for_mech(mechname
, &module_name
)
866 /* mt may already be set for a hw provider */
870 module_name_size
= strlen(module_name
) + 1;
871 if (modload("crypto", module_name
) == -1 ||
872 (mcp
= mod_hold_by_name(module_name
)) == NULL
) {
873 kmem_free(module_name
, module_name_size
);
874 /* mt may already be set for a hw provider */
878 mcp
->mod_loadflags
|= MOD_NOAUTOUNLOAD
;
880 /* memory pressure may have unloaded the module */
881 if (!mcp
->mod_installed
)
883 mod_release_mod(mcp
);
886 (void) modload("crypto", module_name
);
888 kmem_free(module_name
, module_name_size
);
890 /* mt may already be set for a hw provider */
891 if (mt
!= CRYPTO_MECH_INVALID
)
895 * Try again. Should find a software provider in the
896 * table this time around.
898 second_time
= B_TRUE
;