]> git.proxmox.com Git - mirror_zfs-debian.git/blob - module/icp/core/kcf_mech_tabs.c
723bfdb601a49d425eed0d366d1b276b2d2b7487
[mirror_zfs-debian.git] / module / icp / core / kcf_mech_tabs.c
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. 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.
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) strncpy(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 }