Print this page
6414175 kcf.conf's supportedlist not providing much usefulness
Split |
Close |
Expand all |
Collapse all |
--- old/usr/src/uts/common/crypto/core/kcf_cryptoadm.c
+++ new/usr/src/uts/common/crypto/core/kcf_cryptoadm.c
1 1 /*
2 2 * CDDL HEADER START
3 3 *
4 4 * The contents of this file are subject to the terms of the
5 5 * Common Development and Distribution License (the "License").
6 6 * You may not use this file except in compliance with the License.
7 7 *
8 8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 9 * or http://www.opensolaris.org/os/licensing.
10 10 * See the License for the specific language governing permissions
11 11 * and limitations under the License.
12 12 *
13 13 * When distributing Covered Code, include this CDDL HEADER in each
14 14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 15 * If applicable, add the following below this CDDL HEADER, with the
↓ open down ↓ |
15 lines elided |
↑ open up ↑ |
16 16 * fields enclosed by brackets "[]" replaced with your own identifying
17 17 * information: Portions Copyright [yyyy] [name of copyright owner]
18 18 *
19 19 * CDDL HEADER END
20 20 */
21 21 /*
22 22 * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
23 23 * Use is subject to license terms.
24 24 */
25 25
26 -#pragma ident "%Z%%M% %I% %E% SMI"
27 -
28 26 /*
29 27 * Core KCF (Kernel Cryptographic Framework). This file implements
30 28 * the cryptoadm entry points.
31 29 */
32 30
33 31 #include <sys/systm.h>
34 32 #include <sys/errno.h>
35 33 #include <sys/cmn_err.h>
36 34 #include <sys/rwlock.h>
37 35 #include <sys/kmem.h>
38 36 #include <sys/modctl.h>
39 37 #include <sys/sunddi.h>
40 38 #include <sys/door.h>
↓ open down ↓ |
3 lines elided |
↑ open up ↑ |
41 39 #include <sys/crypto/common.h>
42 40 #include <sys/crypto/api.h>
43 41 #include <sys/crypto/spi.h>
44 42 #include <sys/crypto/impl.h>
45 43 #include <sys/crypto/sched_impl.h>
46 44
47 45 /* protects the the soft_config_list. */
48 46 kmutex_t soft_config_mutex;
49 47
50 48 /*
51 - * This linked list contains software configuration entries that
52 - * are loaded into the kernel by the CRYPTO_LOAD_SOFT_CONFIG ioctl.
53 - * It is protected by the soft_config_mutex.
49 + * This linked list contains software configuration entries.
50 + * The initial list is just software providers loaded by kcf_soft_config_init().
51 + * Additional entries may appear for both hardware and software providers
52 + * from kcf.conf. These come from "cryptoadm start", which reads file kcf.conf
53 + * and updates this table using the CRYPTO_LOAD_SOFT_CONFIG ioctl.
54 + * Further cryptoadm commands modify this file and update this table with ioctl.
55 + * This list is protected by the soft_config_mutex.
54 56 */
55 57 kcf_soft_conf_entry_t *soft_config_list;
56 58
57 59 static int add_soft_config(char *, uint_t, crypto_mech_name_t *);
58 60 static int dup_mech_names(kcf_provider_desc_t *, crypto_mech_name_t **,
59 61 uint_t *, int);
60 62 static void free_soft_config_entry(kcf_soft_conf_entry_t *);
61 63
62 64 #define KCF_MAX_CONFIG_ENTRIES 512 /* maximum entries in soft_config_list */
63 65
66 +#if DEBUG
67 +extern int kcf_frmwrk_debug;
68 +static void kcf_soft_config_dump(char *message);
69 +#endif /* DEBUG */
70 +
71 +/*
72 + * Count and return the number of mechanisms in an array of crypto_mech_name_t
73 + * (excluding final NUL-character string element).
74 + */
75 +static int
76 +count_mechanisms(crypto_mech_name_t mechs[]) {
77 + int count;
78 + for (count = 0; mechs[count][0] != '\0'; ++count);
79 + return (count);
80 +}
81 +
82 +/*
83 + * Initialize a mutex and populate soft_config_list with default entries
84 + * of kernel software providers.
85 + * Called from kcf module _init().
86 + */
64 87 void
65 88 kcf_soft_config_init(void)
66 89 {
90 + typedef struct {
91 + char *name;
92 + crypto_mech_name_t *mechs;
93 + } initial_soft_config_entry_t;
94 +
95 + /*
96 + * This provides initial default values to soft_config_list.
97 + * It is equivalent to these lines in /etc/crypto/kcf.conf
98 + * (without line breaks and indenting):
99 + *
100 + * # /etc/crypto/kcf.conf
101 + * des:supportedlist=CKM_DES_CBC,CKM_DES_ECB,CKM_DES3_CBC,CKM_DES3_ECB
102 + * aes:supportedlist=CKM_AES_ECB,CKM_AES_CBC,CKM_AES_CTR,CKM_AES_CCM
103 + * arcfour:supportedlist=CKM_RC4
104 + * blowfish:supportedlist=CKM_BLOWFISH_ECB,CKM_BLOWFISH_CBC
105 + * ecc:supportedlist=CKM_EC_KEY_PAIR_GEN,CKM_ECDH1_DERIVE,CKM_ECDSA,\
106 + * CKM_ECDSA_SHA1
107 + * sha1:supportedlist=CKM_SHA_1,CKM_SHA_1_HMAC_GENERAL,CKM_SHA_1_HMAC
108 + * sha2:supportedlist=CKM_SHA256,CKM_SHA256_HMAC,
109 + * CKM_SHA256_HMAC_GENERAL,CKM_SHA384,CKM_SHA384_HMAC,\
110 + * CKM_SHA384_HMAC_GENERAL,CKM_SHA512,CKM_SHA512_HMAC,\
111 + * CKM_SHA512_HMAC_GENERAL
112 + * md4:supportedlist=CKM_MD4
113 + * md5:supportedlist=CKM_MD5,CKM_MD5_HMAC_GENERAL,CKM_MD5_HMAC
114 + * rsa:supportedlist=CKM_RSA_PKCS,CKM_RSA_X_509,CKM_MD5_RSA_PKCS,\
115 + * CKM_SHA1_RSA_PKCS,CKM_SHA256_RSA_PKCS,CKM_SHA384_RSA_PKCS,\
116 + * CKM_SHA512_RSA_PKCS
117 + * swrand:supportedlist=random
118 + *
119 + * WARNING: If you add a new kernel crypto provider or mechanism,
120 + * you must update these constants.
121 + *
122 + * 1. To add a new mechanism to a provider add the string to the
123 + * appropriate array below.
124 + *
125 + * 2. To add a new provider, create a new *_mechs array listing the
126 + * provider's mechanism(s). For example:
127 + * sha3_mechs[SHA3_MECH_COUNT] = {"CKM_SHA_3"};
128 + * Add the new *_mechs array to initial_soft_config_entry[].
129 + */
130 + static crypto_mech_name_t des_mechs[] = {
131 + "CKM_DES_CBC", "CKM_DES_ECB", "CKM_DES3_CBC", "CKM_DES3_ECB", ""};
132 + static crypto_mech_name_t aes_mechs[] = {
133 + "CKM_AES_ECB", "CKM_AES_CBC", "CKM_AES_CTR", "CKM_AES_CCM", ""};
134 + static crypto_mech_name_t arcfour_mechs[] = {
135 + "CKM_RC4", ""};
136 + static crypto_mech_name_t blowfish_mechs[] = {
137 + "CKM_BLOWFISH_ECB", "CKM_BLOWFISH_CBC", ""};
138 + static crypto_mech_name_t ecc_mechs[] = {
139 + "CKM_EC_KEY_PAIR_GEN", "CKM_ECDH1_DERIVE", "CKM_ECDSA",
140 + "CKM_ECDSA_SHA1", ""};
141 + static crypto_mech_name_t sha1_mechs[] = {
142 + "CKM_SHA_1", "CKM_SHA_1_HMAC_GENERAL", "CKM_SHA_1_HMAC", ""};
143 + static crypto_mech_name_t sha2_mechs[] = {
144 + "CKM_SHA256", "CKM_SHA256_HMAC", "CKM_SHA256_HMAC_GENERAL",
145 + "CKM_SHA384", "CKM_SHA384_HMAC", "CKM_SHA384_HMAC_GENERAL",
146 + "CKM_SHA512", "CKM_SHA512_HMAC", "CKM_SHA512_HMAC_GENERAL", ""};
147 + static crypto_mech_name_t md4_mechs[] = {
148 + "CKM_MD4", ""};
149 + static crypto_mech_name_t md5_mechs[] = {
150 + "CKM_MD5", "CKM_MD5_HMAC_GENERAL", "CKM_MD5_HMAC", ""};
151 + static crypto_mech_name_t rsa_mechs[] = {
152 + "CKM_RSA_PKCS", "CKM_RSA_X_509", "CKM_MD5_RSA_PKCS",
153 + "CKM_SHA1_RSA_PKCS", "CKM_SHA256_RSA_PKCS", "CKM_SHA384_RSA_PKCS",
154 + "CKM_SHA512_RSA_PKCS", ""};
155 + static crypto_mech_name_t swrand_mechs[] = {
156 + "random", NULL};
157 + static initial_soft_config_entry_t
158 + initial_soft_config_entry[] = {
159 + "des", des_mechs,
160 + "aes", aes_mechs,
161 + "arcfour", arcfour_mechs,
162 + "blowfish", blowfish_mechs,
163 + "ecc", ecc_mechs,
164 + "sha1", sha1_mechs,
165 + "sha2", sha2_mechs,
166 + "md4", md4_mechs,
167 + "md5", md5_mechs,
168 + "rsa", rsa_mechs,
169 + "swrand", swrand_mechs
170 + };
171 + const int initial_soft_config_entries =
172 + sizeof (initial_soft_config_entry)
173 + / sizeof (initial_soft_config_entry_t);
174 + int i;
175 +
67 176 mutex_init(&soft_config_mutex, NULL, MUTEX_DRIVER, NULL);
177 +
178 + /*
179 + * Initialize soft_config_list with default providers.
180 + * Populate the linked list backwards so the first entry appears first.
181 + */
182 + for (i = initial_soft_config_entries - 1; i >= 0; --i) {
183 + initial_soft_config_entry_t *p = &initial_soft_config_entry[i];
184 + crypto_mech_name_t *mechsp;
185 + char *namep;
186 + uint_t namelen, alloc_size;
187 + int mech_count, r;
188 +
189 + /* allocate/initialize memory for name and mechanism list */
190 + namelen = strlen(p->name) + 1;
191 + namep = kmem_alloc(namelen, KM_SLEEP);
192 + (void) strlcpy(namep, p->name, namelen);
193 + mech_count = count_mechanisms(p->mechs);
194 + alloc_size = mech_count * CRYPTO_MAX_MECH_NAME;
195 + mechsp = kmem_alloc(alloc_size, KM_SLEEP);
196 + bcopy(p->mechs, mechsp, alloc_size);
197 +
198 + r = add_soft_config(namep, mech_count, mechsp);
199 + if (r != 0)
200 + cmn_err(CE_WARN,
201 + "add_soft_config(%s) failed; returned %d\n",
202 + namep, r);
203 + }
204 +#if DEBUG
205 + if (kcf_frmwrk_debug >= 1)
206 + kcf_soft_config_dump("kcf_soft_config_init");
207 +#endif /* DEBUG */
68 208 }
69 209
70 210
211 +#if DEBUG
71 212 /*
213 + * Dump soft_config_list, containing a list of kernel software providers
214 + * and (optionally) hardware providers, with updates from kcf.conf.
215 + * Dump mechanism lists too if kcf_frmwrk_debug is >= 2.
216 + */
217 +static void
218 +kcf_soft_config_dump(char *message)
219 +{
220 + kcf_soft_conf_entry_t *p;
221 + uint_t i;
222 +
223 + mutex_enter(&soft_config_mutex);
224 + printf("Soft provider config list soft_config_list: %s\n",
225 + message != NULL ? message : "");
226 +
227 + for (p = soft_config_list; p != NULL; p = p->ce_next) {
228 + printf("ce_name: %s, %d ce_mechs\n", p->ce_name, p->ce_count);
229 + if (kcf_frmwrk_debug >= 2) {
230 + printf("\tce_mechs: ");
231 + for (i = 0; i < p->ce_count; i++) {
232 + printf("%s ", p->ce_mechs[i]);
233 + }
234 + printf("\n");
235 + }
236 + }
237 + printf("(end of soft_config_list)\n");
238 +
239 + mutex_exit(&soft_config_mutex);
240 +}
241 +#endif /* DEBUG */
242 +
243 +
244 +/*
72 245 * Utility routine to identify the providers to filter out and
73 246 * present only one provider. This happens when a hardware provider
74 247 * registers multiple units of the same device instance.
248 + *
249 + * Called from crypto_get_dev_list().
75 250 */
76 251 static void
77 252 filter_providers(uint_t count, kcf_provider_desc_t **provider_array,
78 253 char *skip_providers, int *mech_counts, int *new_count)
79 254 {
80 255 int i, j;
81 256 kcf_provider_desc_t *prov1, *prov2;
82 257 int n = 0;
83 258
84 259 for (i = 0; i < count; i++) {
85 260 if (skip_providers[i] == 1)
86 261 continue;
87 262
88 263 prov1 = provider_array[i];
89 264 mech_counts[i] = prov1->pd_mech_list_count;
90 265 for (j = i + 1; j < count; j++) {
91 266 prov2 = provider_array[j];
92 267 if (strncmp(prov1->pd_name, prov2->pd_name,
93 268 MAXNAMELEN) == 0 &&
94 269 prov1->pd_instance == prov2->pd_instance) {
95 270 skip_providers[j] = 1;
↓ open down ↓ |
11 lines elided |
↑ open up ↑ |
96 271 mech_counts[i] += prov2->pd_mech_list_count;
97 272 }
98 273 }
99 274 n++;
100 275 }
101 276
102 277 *new_count = n;
103 278 }
104 279
105 280
106 -/* called from the CRYPTO_GET_DEV_LIST ioctl */
281 +/*
282 + * Return a list of kernel hardware providers and a count of each
283 + * provider's supported mechanisms.
284 + * Called from the CRYPTO_GET_DEV_LIST ioctl.
285 + */
107 286 int
108 287 crypto_get_dev_list(uint_t *count, crypto_dev_list_entry_t **array)
109 288 {
110 289 kcf_provider_desc_t **provider_array;
111 290 kcf_provider_desc_t *pd;
112 291 crypto_dev_list_entry_t *p;
113 292 size_t skip_providers_size, mech_counts_size;
114 293 char *skip_providers;
115 294 uint_t provider_count;
116 295 int rval, i, j, new_count, *mech_counts;
117 296
118 297 /*
119 298 * Take snapshot of provider table returning only hardware providers
120 299 * that are in a usable state. Logical providers not included.
121 300 */
122 - rval = kcf_get_hw_prov_tab(&provider_count, &provider_array, KM_SLEEP,
301 + rval = kcf_get_hw_prov_tab(&provider_count, &provider_array, KM_SLEEP,
123 302 NULL, 0, B_FALSE);
124 303 if (rval != CRYPTO_SUCCESS)
125 304 return (rval);
126 305
127 306 if (provider_count == 0) {
128 307 *array = NULL;
129 308 *count = 0;
130 309 return (CRYPTO_SUCCESS);
131 310 }
132 311
133 312 skip_providers_size = provider_count * sizeof (char);
134 313 mech_counts_size = provider_count * sizeof (int);
135 314
136 315 skip_providers = kmem_zalloc(skip_providers_size, KM_SLEEP);
137 316 mech_counts = kmem_zalloc(mech_counts_size, KM_SLEEP);
138 317 filter_providers(provider_count, provider_array, skip_providers,
139 318 mech_counts, &new_count);
140 319
141 320 p = kmem_alloc(new_count * sizeof (crypto_dev_list_entry_t), KM_SLEEP);
142 321 for (i = 0, j = 0; i < provider_count; i++) {
143 322 if (skip_providers[i] == 1) {
144 323 ASSERT(mech_counts[i] == 0);
145 324 continue;
146 325 }
147 326 pd = provider_array[i];
148 327 p[j].le_mechanism_count = mech_counts[i];
149 328 p[j].le_dev_instance = pd->pd_instance;
150 329 (void) strncpy(p[j].le_dev_name, pd->pd_name, MAXNAMELEN);
151 330 j++;
152 331 }
153 332
↓ open down ↓ |
21 lines elided |
↑ open up ↑ |
154 333 kcf_free_provider_tab(provider_count, provider_array);
155 334 kmem_free(skip_providers, skip_providers_size);
156 335 kmem_free(mech_counts, mech_counts_size);
157 336
158 337 *array = p;
159 338 *count = new_count;
160 339 return (CRYPTO_SUCCESS);
161 340 }
162 341
163 342 /*
164 - * Called from the CRYPTO_GET_SOFT_LIST ioctl, this routine returns
165 - * a buffer containing the null terminated names of software providers
343 + * Return a buffer containing the null terminated names of software providers
166 344 * loaded by CRYPTO_LOAD_SOFT_CONFIG.
345 + * Called from the CRYPTO_GET_SOFT_LIST ioctl.
167 346 */
168 347 int
169 348 crypto_get_soft_list(uint_t *count, char **array, size_t *len)
170 349 {
171 350 char *names = NULL, *namep, *end;
172 351 kcf_soft_conf_entry_t *p;
173 352 uint_t n = 0, cnt = 0, final_count = 0;
174 353 size_t name_len, final_size = 0;
175 354
176 355 /* first estimate */
177 356 mutex_enter(&soft_config_mutex);
178 357 for (p = soft_config_list; p != NULL; p = p->ce_next) {
179 358 n += strlen(p->ce_name) + 1;
180 359 cnt++;
181 360 }
182 361 mutex_exit(&soft_config_mutex);
183 362
184 363 if (cnt == 0)
185 364 goto out;
186 365
187 366 again:
188 367 namep = names = kmem_alloc(n, KM_SLEEP);
189 368 end = names + n;
190 369 final_size = 0;
191 370 final_count = 0;
192 371
193 372 mutex_enter(&soft_config_mutex);
194 373 for (p = soft_config_list; p != NULL; p = p->ce_next) {
195 374 name_len = strlen(p->ce_name) + 1;
196 375 /* check for enough space */
197 376 if ((namep + name_len) > end) {
198 377 mutex_exit(&soft_config_mutex);
199 378 kmem_free(names, n);
200 379 n = n << 1;
201 380 goto again;
202 381 }
203 382 (void) strcpy(namep, p->ce_name);
204 383 namep += name_len;
205 384 final_size += name_len;
206 385 final_count++;
207 386 }
208 387 mutex_exit(&soft_config_mutex);
209 388
210 389 ASSERT(final_size <= n);
211 390
212 391 /* check if buffer we allocated is too large */
213 392 if (final_size < n) {
214 393 char *final_buffer;
215 394
216 395 final_buffer = kmem_alloc(final_size, KM_SLEEP);
217 396 bcopy(names, final_buffer, final_size);
↓ open down ↓ |
41 lines elided |
↑ open up ↑ |
218 397 kmem_free(names, n);
219 398 names = final_buffer;
220 399 }
221 400 out:
222 401 *array = names;
223 402 *count = final_count;
224 403 *len = final_size;
225 404 return (CRYPTO_SUCCESS);
226 405 }
227 406
407 +/*
408 + * Check if a mechanism name is already in a mechanism name array
409 + * Called by crypto_get_dev_info().
410 + */
228 411 static boolean_t
229 412 duplicate(char *name, crypto_mech_name_t *array, int count)
230 413 {
231 414 int i;
232 415
233 416 for (i = 0; i < count; i++) {
234 417 if (strncmp(name, &array[i][0],
235 418 sizeof (crypto_mech_name_t)) == 0)
236 419 return (B_TRUE);
237 420 }
238 421 return (B_FALSE);
239 422 }
240 423
241 -/* called from the CRYPTO_GET_DEV_INFO ioctl */
424 +/*
425 + * Return a list of kernel hardware providers for a given name and instance.
426 + * For each entry, also return a list of their supported mechanisms.
427 + * Called from the CRYPTO_GET_DEV_INFO ioctl.
428 + */
242 429 int
243 430 crypto_get_dev_info(char *name, uint_t instance, uint_t *count,
244 431 crypto_mech_name_t **array)
245 432 {
246 433 int rv;
247 434 crypto_mech_name_t *mech_names, *resized_array;
248 435 int i, j, k = 0, max_count;
249 436 uint_t provider_count;
250 437 kcf_provider_desc_t **provider_array;
251 438 kcf_provider_desc_t *pd;
252 439
253 440 /*
254 441 * Get provider table entries matching name and instance
255 442 * for hardware providers that are in a usable state.
256 443 * Logical providers not included. NULL name matches
257 444 * all hardware providers.
258 445 */
259 - rv = kcf_get_hw_prov_tab(&provider_count, &provider_array, KM_SLEEP,
446 + rv = kcf_get_hw_prov_tab(&provider_count, &provider_array, KM_SLEEP,
260 447 name, instance, B_FALSE);
261 448 if (rv != CRYPTO_SUCCESS)
262 449 return (rv);
263 450
264 451 if (provider_count == 0)
265 452 return (CRYPTO_ARGUMENTS_BAD);
266 453
267 454 /* Count all mechanisms supported by all providers */
268 455 max_count = 0;
269 456 for (i = 0; i < provider_count; i++)
270 457 max_count += provider_array[i]->pd_mech_list_count;
271 458
272 459 if (max_count == 0) {
273 460 mech_names = NULL;
274 461 goto out;
275 462 }
276 463
277 464 /* Allocate space and copy mech names */
278 465 mech_names = kmem_alloc(max_count * sizeof (crypto_mech_name_t),
279 466 KM_SLEEP);
280 467
281 468 k = 0;
282 469 for (i = 0; i < provider_count; i++) {
283 470 pd = provider_array[i];
284 471 for (j = 0; j < pd->pd_mech_list_count; j++) {
285 472 /* check for duplicate */
286 473 if (duplicate(&pd->pd_mechanisms[j].cm_mech_name[0],
287 474 mech_names, k))
288 475 continue;
289 476 bcopy(&pd->pd_mechanisms[j].cm_mech_name[0],
290 477 &mech_names[k][0], sizeof (crypto_mech_name_t));
291 478 k++;
292 479 }
293 480 }
294 481
295 482 /* resize */
296 483 if (k != max_count) {
297 484 resized_array =
298 485 kmem_alloc(k * sizeof (crypto_mech_name_t), KM_SLEEP);
299 486 bcopy(mech_names, resized_array,
300 487 k * sizeof (crypto_mech_name_t));
301 488 kmem_free(mech_names,
302 489 max_count * sizeof (crypto_mech_name_t));
303 490 mech_names = resized_array;
↓ open down ↓ |
34 lines elided |
↑ open up ↑ |
304 491 }
305 492
306 493 out:
307 494 kcf_free_provider_tab(provider_count, provider_array);
308 495 *count = k;
309 496 *array = mech_names;
310 497
311 498 return (CRYPTO_SUCCESS);
312 499 }
313 500
314 -/* called from the CRYPTO_GET_SOFT_INFO ioctl */
501 +/*
502 + * Given a kernel software provider name, return a list of mechanisms
503 + * it supports.
504 + * Called from the CRYPTO_GET_SOFT_INFO ioctl.
505 + */
315 506 int
316 507 crypto_get_soft_info(caddr_t name, uint_t *count, crypto_mech_name_t **array)
317 508 {
318 509 ddi_modhandle_t modh = NULL;
319 510 kcf_provider_desc_t *provider;
320 511 int rv;
321 512
322 513 provider = kcf_prov_tab_lookup_by_name(name);
323 514 if (provider == NULL) {
324 - if (in_soft_config_list(name)) {
325 - char *tmp;
326 - int name_len;
515 + char *tmp;
516 + int name_len;
327 517
328 - /* strlen("crypto/") + NULL terminator == 8 */
329 - name_len = strlen(name);
330 - tmp = kmem_alloc(name_len + 8, KM_SLEEP);
331 - bcopy("crypto/", tmp, 7);
332 - bcopy(name, &tmp[7], name_len);
333 - tmp[name_len + 7] = '\0';
518 + /* strlen("crypto/") + NULL terminator == 8 */
519 + name_len = strlen(name);
520 + tmp = kmem_alloc(name_len + 8, KM_SLEEP);
521 + bcopy("crypto/", tmp, 7);
522 + bcopy(name, &tmp[7], name_len);
523 + tmp[name_len + 7] = '\0';
334 524
335 - modh = ddi_modopen(tmp, KRTLD_MODE_FIRST, NULL);
336 - kmem_free(tmp, name_len + 8);
525 + modh = ddi_modopen(tmp, KRTLD_MODE_FIRST, NULL);
526 + kmem_free(tmp, name_len + 8);
337 527
338 - if (modh == NULL) {
339 - return (CRYPTO_ARGUMENTS_BAD);
340 - }
528 + if (modh == NULL) {
529 + return (CRYPTO_ARGUMENTS_BAD);
530 + }
341 531
342 - provider = kcf_prov_tab_lookup_by_name(name);
343 - if (provider == NULL) {
344 - return (CRYPTO_ARGUMENTS_BAD);
345 - }
346 - } else {
532 + provider = kcf_prov_tab_lookup_by_name(name);
533 + if (provider == NULL) {
347 534 return (CRYPTO_ARGUMENTS_BAD);
348 535 }
349 536 }
350 537
351 538 rv = dup_mech_names(provider, array, count, KM_SLEEP);
352 539 KCF_PROV_REFRELE(provider);
353 540 if (modh != NULL)
354 541 (void) ddi_modclose(modh);
355 542 return (rv);
356 543 }
357 544
545 +
546 +/*
547 + * Change the mechanism list for a provider.
548 + * If "direction" is CRYPTO_MECH_ADDED, add new mechanisms.
549 + * If "direction" is CRYPTO_MECH_REMOVED, remove the mechanism list.
550 + * Called from crypto_load_dev_disabled().
551 + */
358 552 static void
359 553 kcf_change_mechs(kcf_provider_desc_t *provider, uint_t count,
360 554 crypto_mech_name_t *array, crypto_event_change_t direction)
361 555 {
362 556 crypto_notify_event_change_t ec;
363 557 crypto_mech_info_t *mi;
364 558 kcf_prov_mech_desc_t *pmd;
365 559 char *mech;
366 560 int i, j, n;
367 561
368 562 ASSERT(direction == CRYPTO_MECH_ADDED ||
369 563 direction == CRYPTO_MECH_REMOVED);
370 564
371 565 if (provider == NULL) {
372 566 /*
373 567 * Nothing to add or remove from the tables since
374 568 * the provider isn't registered.
375 569 */
376 570 return;
377 571 }
378 572
379 573 for (i = 0; i < count; i++) {
380 574 if (array[i][0] == '\0')
381 575 continue;
382 576
383 577 mech = &array[i][0];
384 578
385 579 n = provider->pd_mech_list_count;
386 580 for (j = 0; j < n; j++) {
387 581 mi = &provider->pd_mechanisms[j];
388 582 if (strncmp(mi->cm_mech_name, mech,
389 583 CRYPTO_MAX_MECH_NAME) == 0)
390 584 break;
391 585 }
392 586 if (j == n)
393 587 continue;
394 588
395 589 switch (direction) {
396 590 case CRYPTO_MECH_ADDED:
397 591 (void) kcf_add_mech_provider(j, provider, &pmd);
398 592 break;
399 593
400 594 case CRYPTO_MECH_REMOVED:
401 595 kcf_remove_mech_provider(mech, provider);
402 596 break;
403 597 }
404 598
405 599 /* Inform interested clients of the event */
406 600 ec.ec_provider_type = provider->pd_prov_type;
407 601 ec.ec_change = direction;
408 602
409 603 (void) strncpy(ec.ec_mech_name, mech, CRYPTO_MAX_MECH_NAME);
410 604 kcf_walk_ntfylist(CRYPTO_EVENT_MECHS_CHANGED, &ec);
411 605 }
412 606 }
413 607
414 608 /*
415 609 * If a mech name in the second array (prev_array) is also in the
416 610 * first array, then a NULL character is written into the first byte
417 611 * of the mech name in the second array. This effectively removes
418 612 * the mech name from the second array.
419 613 */
420 614 static void
421 615 kcf_compare_mechs(uint_t count, crypto_mech_name_t *array, uint_t prev_count,
422 616 crypto_mech_name_t *prev_array)
423 617 {
424 618 int i, j;
425 619
426 620 for (i = 0; i < prev_count; i++) {
427 621 for (j = 0; j < count; j++) {
428 622 if (strncmp(&prev_array[i][0], &array[j][0],
429 623 CRYPTO_MAX_MECH_NAME) == 0) {
430 624 prev_array[i][0] = '\0';
431 625 }
432 626 }
433 627 }
434 628 }
435 629
436 630 /*
437 631 * Called from CRYPTO_LOAD_DEV_DISABLED ioctl.
438 632 * If new_count is 0, then completely remove the entry.
439 633 */
440 634 int
441 635 crypto_load_dev_disabled(char *name, uint_t instance, uint_t new_count,
442 636 crypto_mech_name_t *new_array)
443 637 {
444 638 kcf_provider_desc_t *provider = NULL;
445 639 kcf_provider_desc_t **provider_array;
446 640 crypto_mech_name_t *prev_array;
447 641 uint_t provider_count, prev_count;
448 642 int i, rv = CRYPTO_SUCCESS;
449 643
450 644 /*
451 645 * Remove the policy entry if new_count is 0, otherwise put disabled
452 646 * mechanisms into policy table.
453 647 */
454 648 if (new_count == 0) {
455 649 kcf_policy_remove_by_dev(name, instance, &prev_count,
↓ open down ↓ |
88 lines elided |
↑ open up ↑ |
456 650 &prev_array);
457 651 } else if ((rv = kcf_policy_load_dev_disabled(name, instance, new_count,
458 652 new_array, &prev_count, &prev_array)) != CRYPTO_SUCCESS) {
459 653 return (rv);
460 654 }
461 655
462 656 /*
463 657 * Get provider table entries matching name and instance
464 658 * for providers that are are in a usable or unverified state.
465 659 */
466 - rv = kcf_get_hw_prov_tab(&provider_count, &provider_array, KM_SLEEP,
660 + rv = kcf_get_hw_prov_tab(&provider_count, &provider_array, KM_SLEEP,
467 661 name, instance, B_TRUE);
468 662 if (rv != CRYPTO_SUCCESS)
469 663 return (rv);
470 664
471 665 for (i = 0; i < provider_count; i++) {
472 666 provider = provider_array[i];
473 667
474 668 /* previously disabled mechanisms may become enabled */
475 669 if (prev_array != NULL) {
476 670 kcf_compare_mechs(new_count, new_array,
477 671 prev_count, prev_array);
478 672 kcf_change_mechs(provider, prev_count, prev_array,
479 673 CRYPTO_MECH_ADDED);
480 674 }
481 675
482 676 kcf_change_mechs(provider, new_count, new_array,
483 677 CRYPTO_MECH_REMOVED);
484 678 }
485 679
486 680 kcf_free_provider_tab(provider_count, provider_array);
487 681 crypto_free_mech_list(prev_array, prev_count);
488 682 return (rv);
489 683 }
490 684
491 685 /*
492 686 * Called from CRYPTO_LOAD_SOFT_DISABLED ioctl.
493 687 * If new_count is 0, then completely remove the entry.
494 688 */
495 689 int
496 690 crypto_load_soft_disabled(char *name, uint_t new_count,
497 691 crypto_mech_name_t *new_array)
498 692 {
499 693 kcf_provider_desc_t *provider = NULL;
500 694 crypto_mech_name_t *prev_array;
501 695 uint_t prev_count = 0;
502 696 int rv;
503 697
504 698 provider = kcf_prov_tab_lookup_by_name(name);
505 699 if (provider != NULL) {
506 700 mutex_enter(&provider->pd_lock);
507 701 /*
508 702 * Check if any other thread is disabling or removing
509 703 * this provider. We return if this is the case.
510 704 */
511 705 if (provider->pd_state >= KCF_PROV_DISABLED) {
512 706 mutex_exit(&provider->pd_lock);
513 707 KCF_PROV_REFRELE(provider);
514 708 return (CRYPTO_BUSY);
515 709 }
516 710 provider->pd_state = KCF_PROV_DISABLED;
517 711 mutex_exit(&provider->pd_lock);
518 712
519 713 undo_register_provider(provider, B_TRUE);
520 714 KCF_PROV_REFRELE(provider);
521 715 if (provider->pd_kstat != NULL)
522 716 KCF_PROV_REFRELE(provider);
523 717
524 718 mutex_enter(&provider->pd_lock);
525 719 /* Wait till the existing requests complete. */
526 720 while (provider->pd_state != KCF_PROV_FREED) {
527 721 cv_wait(&provider->pd_remove_cv, &provider->pd_lock);
528 722 }
529 723 mutex_exit(&provider->pd_lock);
530 724 }
531 725
532 726 if (new_count == 0) {
533 727 kcf_policy_remove_by_name(name, &prev_count, &prev_array);
534 728 crypto_free_mech_list(prev_array, prev_count);
535 729 rv = CRYPTO_SUCCESS;
536 730 goto out;
537 731 }
538 732
539 733 /* put disabled mechanisms into policy table */
540 734 if ((rv = kcf_policy_load_soft_disabled(name, new_count, new_array,
541 735 &prev_count, &prev_array)) == CRYPTO_SUCCESS) {
542 736 crypto_free_mech_list(prev_array, prev_count);
543 737 }
544 738
545 739 out:
546 740 if (provider != NULL) {
547 741 redo_register_provider(provider);
548 742 if (provider->pd_kstat != NULL)
549 743 KCF_PROV_REFHOLD(provider);
550 744 mutex_enter(&provider->pd_lock);
551 745 provider->pd_state = KCF_PROV_READY;
552 746 mutex_exit(&provider->pd_lock);
553 747 } else if (rv == CRYPTO_SUCCESS) {
↓ open down ↓ |
77 lines elided |
↑ open up ↑ |
554 748 /*
555 749 * There are some cases where it is useful to kCF clients
556 750 * to have a provider whose mechanism is enabled now to be
557 751 * available. So, we attempt to load it here.
558 752 *
559 753 * The check, new_count < prev_count, ensures that we do this
560 754 * only in the case where a mechanism(s) is now enabled.
561 755 * This check assumes that enable and disable are separate
562 756 * administrative actions and are not done in a single action.
563 757 */
564 - if (new_count < prev_count && (in_soft_config_list(name)) &&
758 + if ((new_count < prev_count) &&
565 759 (modload("crypto", name) != -1)) {
566 760 struct modctl *mcp;
567 761 boolean_t load_again = B_FALSE;
568 762
569 763 if ((mcp = mod_hold_by_name(name)) != NULL) {
570 764 mcp->mod_loadflags |= MOD_NOAUTOUNLOAD;
571 765
572 766 /* memory pressure may have unloaded module */
573 767 if (!mcp->mod_installed)
574 768 load_again = B_TRUE;
575 769 mod_release_mod(mcp);
576 770
577 771 if (load_again)
578 772 (void) modload("crypto", name);
579 773 }
580 774 }
581 775 }
582 776
↓ open down ↓ |
8 lines elided |
↑ open up ↑ |
583 777 return (rv);
584 778 }
585 779
586 780 /* called from the CRYPTO_LOAD_SOFT_CONFIG ioctl */
587 781 int
588 782 crypto_load_soft_config(caddr_t name, uint_t count, crypto_mech_name_t *array)
589 783 {
590 784 return (add_soft_config(name, count, array));
591 785 }
592 786
593 -/* called from the CRYPTO_UNLOAD_SOFT_MODULE ioctl */
787 +/*
788 + * Unload a kernel software crypto module.
789 + * Called from the CRYPTO_UNLOAD_SOFT_MODULE ioctl.
790 + */
594 791 int
595 792 crypto_unload_soft_module(caddr_t name)
596 793 {
597 794 int error;
598 795 modid_t id;
599 796 kcf_provider_desc_t *provider;
600 797 struct modctl *mcp;
601 798
602 799 /* verify that 'name' refers to a registered crypto provider */
603 800 if ((provider = kcf_prov_tab_lookup_by_name(name)) == NULL)
604 801 return (CRYPTO_UNKNOWN_PROVIDER);
605 802
606 803 /*
607 804 * We save the module id and release the reference. We need to
608 805 * do this as modunload() calls unregister which waits for the
609 806 * refcnt to drop to zero.
610 807 */
611 808 id = provider->pd_module_id;
612 809 KCF_PROV_REFRELE(provider);
613 810
614 811 if ((mcp = mod_hold_by_name(name)) != NULL) {
615 812 mcp->mod_loadflags &= ~(MOD_NOAUTOUNLOAD);
↓ open down ↓ |
12 lines elided |
↑ open up ↑ |
616 813 mod_release_mod(mcp);
617 814 }
618 815
619 816 if ((error = modunload(id)) != 0) {
620 817 return (error == EBUSY ? CRYPTO_BUSY : CRYPTO_FAILED);
621 818 }
622 819
623 820 return (CRYPTO_SUCCESS);
624 821 }
625 822
626 -/* called from CRYPTO_GET_DEV_LIST ioctl */
823 +/*
824 + * Free the list of kernel hardware crypto providers.
825 + * Called by get_dev_list() for the CRYPTO_GET_DEV_LIST ioctl.
826 + */
627 827 void
628 828 crypto_free_dev_list(crypto_dev_list_entry_t *array, uint_t count)
629 829 {
630 - if (count == 0 || array == NULL)
830 + if (count == 0 || array == NULL)
631 831 return;
632 832
633 833 kmem_free(array, count * sizeof (crypto_dev_list_entry_t));
634 834 }
635 835
636 836 /*
637 837 * Returns duplicate array of mechanisms. The array is allocated and
638 838 * must be freed by the caller.
639 839 */
640 840 static int
641 841 dup_mech_names(kcf_provider_desc_t *provider, crypto_mech_name_t **array,
642 842 uint_t *count, int kmflag)
643 843 {
644 844 crypto_mech_name_t *mech_names;
645 845 uint_t n;
646 846 uint_t i;
647 847
648 848 if ((n = provider->pd_mech_list_count) == 0) {
649 849 *count = 0;
650 850 *array = NULL;
651 851 return (CRYPTO_SUCCESS);
652 852 }
653 853
654 854 mech_names = kmem_alloc(n * sizeof (crypto_mech_name_t), kmflag);
655 855 if (mech_names == NULL)
656 856 return (CRYPTO_HOST_MEMORY);
657 857
658 858 for (i = 0; i < n; i++) {
659 859 bcopy(&provider->pd_mechanisms[i].cm_mech_name[0],
660 860 &mech_names[i][0], sizeof (crypto_mech_name_t));
661 861 }
662 862
663 863 *count = n;
664 864 *array = mech_names;
665 865 return (CRYPTO_SUCCESS);
666 866 }
667 867
668 868 /*
669 869 * Returns B_TRUE if the specified mechanism is disabled, B_FALSE otherwise.
670 870 */
671 871 boolean_t
672 872 is_mech_disabled_byname(crypto_provider_type_t prov_type, char *pd_name,
673 873 uint_t pd_instance, crypto_mech_name_t mech_name)
674 874 {
675 875 kcf_policy_desc_t *policy;
676 876 uint_t i;
677 877
678 878 ASSERT(prov_type == CRYPTO_SW_PROVIDER ||
679 879 prov_type == CRYPTO_HW_PROVIDER);
680 880
681 881 switch (prov_type) {
682 882 case CRYPTO_SW_PROVIDER:
683 883 policy = kcf_policy_lookup_by_name(pd_name);
684 884 /* no policy for provider - so mechanism can't be disabled */
685 885 if (policy == NULL)
686 886 return (B_FALSE);
687 887 break;
688 888
689 889 case CRYPTO_HW_PROVIDER:
690 890 policy = kcf_policy_lookup_by_dev(pd_name, pd_instance);
691 891 /* no policy for provider - so mechanism can't be disabled */
692 892 if (policy == NULL)
693 893 return (B_FALSE);
694 894 break;
695 895 }
696 896
697 897 mutex_enter(&policy->pd_mutex);
698 898 for (i = 0; i < policy->pd_disabled_count; i ++) {
699 899 if (strncmp(mech_name, &policy->pd_disabled_mechs[i][0],
700 900 CRYPTO_MAX_MECH_NAME) == 0) {
701 901 mutex_exit(&policy->pd_mutex);
702 902 KCF_POLICY_REFRELE(policy);
703 903 return (B_TRUE);
704 904 }
705 905 }
706 906 mutex_exit(&policy->pd_mutex);
707 907 KCF_POLICY_REFRELE(policy);
708 908 return (B_FALSE);
709 909 }
710 910
711 911 /*
712 912 * Returns B_TRUE if the specified mechanism is disabled, B_FALSE otherwise.
713 913 *
714 914 * This is a wrapper routine around is_mech_disabled_byname() above and
715 915 * takes a pointer kcf_provider_desc structure as argument.
716 916 */
717 917 boolean_t
718 918 is_mech_disabled(kcf_provider_desc_t *provider, crypto_mech_name_t name)
719 919 {
720 920 kcf_provider_list_t *e;
721 921 kcf_provider_desc_t *pd;
722 922 boolean_t found = B_FALSE;
723 923 uint_t count, i;
724 924
725 925 if (provider->pd_prov_type != CRYPTO_LOGICAL_PROVIDER) {
726 926 return (is_mech_disabled_byname(provider->pd_prov_type,
727 927 provider->pd_name, provider->pd_instance, name));
728 928 }
729 929
730 930 /*
731 931 * Lock the logical provider just in case one of its hardware
732 932 * provider members unregisters.
733 933 */
734 934 mutex_enter(&provider->pd_lock);
735 935 for (e = provider->pd_provider_list; e != NULL; e = e->pl_next) {
736 936
737 937 pd = e->pl_provider;
738 938 ASSERT(pd->pd_prov_type == CRYPTO_HW_PROVIDER);
739 939
740 940 /* find out if mechanism is offered by hw provider */
741 941 count = pd->pd_mech_list_count;
742 942 for (i = 0; i < count; i++) {
743 943 if (strncmp(&pd->pd_mechanisms[i].cm_mech_name[0],
744 944 name, MAXNAMELEN) == 0) {
745 945 break;
746 946 }
747 947 }
748 948 if (i == count)
749 949 continue;
750 950
751 951 found = !is_mech_disabled_byname(pd->pd_prov_type,
752 952 pd->pd_name, pd->pd_instance, name);
753 953
754 954 if (found)
755 955 break;
756 956 }
757 957 mutex_exit(&provider->pd_lock);
758 958 /*
759 959 * If we found the mechanism, then it means it is still enabled for
760 960 * at least one hardware provider, so the mech can't be disabled
761 961 * for the logical provider.
762 962 */
763 963 return (!found);
764 964 }
765 965
766 966 /*
767 967 * Builds array of permitted mechanisms. The array is allocated and
768 968 * must be freed by the caller.
769 969 */
770 970 int
771 971 crypto_build_permitted_mech_names(kcf_provider_desc_t *provider,
772 972 crypto_mech_name_t **array, uint_t *count, int kmflag)
773 973 {
774 974 crypto_mech_name_t *mech_names, *p;
775 975 uint_t i;
776 976 uint_t scnt = provider->pd_mech_list_count;
777 977 uint_t dcnt = 0;
778 978
779 979 /*
780 980 * Compute number of 'permitted mechanisms', which is
781 981 * 'supported mechanisms' - 'disabled mechanisms'.
782 982 */
783 983 for (i = 0; i < scnt; i++) {
784 984 if (is_mech_disabled(provider,
785 985 &provider->pd_mechanisms[i].cm_mech_name[0])) {
786 986 dcnt++;
787 987 }
788 988 }
789 989
790 990 /* all supported mechanisms have been disabled */
791 991 if (scnt == dcnt) {
792 992 *count = 0;
793 993 *array = NULL;
794 994 return (CRYPTO_SUCCESS);
795 995 }
796 996
797 997 mech_names = kmem_alloc((scnt - dcnt) * sizeof (crypto_mech_name_t),
798 998 kmflag);
799 999 if (mech_names == NULL)
800 1000 return (CRYPTO_HOST_MEMORY);
801 1001
802 1002 /* build array of permitted mechanisms */
803 1003 for (i = 0, p = mech_names; i < scnt; i++) {
804 1004 if (!is_mech_disabled(provider,
805 1005 &provider->pd_mechanisms[i].cm_mech_name[0])) {
↓ open down ↓ |
165 lines elided |
↑ open up ↑ |
806 1006 bcopy(&provider->pd_mechanisms[i].cm_mech_name[0],
807 1007 p++, sizeof (crypto_mech_name_t));
808 1008 }
809 1009 }
810 1010
811 1011 *count = scnt - dcnt;
812 1012 *array = mech_names;
813 1013 return (CRYPTO_SUCCESS);
814 1014 }
815 1015
1016 +/*
1017 + * Free memory for elements in a kcf_soft_config_entry_t. This entry must
1018 + * have been previously removed from the soft_config_list linked list.
1019 + */
816 1020 static void
817 1021 free_soft_config_entry(kcf_soft_conf_entry_t *p)
818 1022 {
819 1023 kmem_free(p->ce_name, strlen(p->ce_name) + 1);
820 1024 crypto_free_mech_list(p->ce_mechs, p->ce_count);
821 1025 kmem_free(p, sizeof (kcf_soft_conf_entry_t));
822 1026 }
823 1027
824 1028 /*
825 - * Called from the CRYPTO_LOAD_SOFT_CONFIG ioctl, this routine stores
826 - * configuration information for software providers in a linked list.
1029 + * Store configuration information for software providers in a linked list.
827 1030 * If the list already contains an entry for the specified provider
828 1031 * and the specified mechanism list has at least one mechanism, then
829 1032 * the mechanism list for the provider is updated. If the mechanism list
830 1033 * is empty, the entry for the provider is removed.
831 1034 *
832 - * Important note: the array argument is consumed.
1035 + * Called from kcf_soft_config_init() (to initially populate the list
1036 + * with default kernel providers) and from crypto_load_soft_config() for
1037 + * the CRYPTO_LOAD_SOFT_CONFIG ioctl (for third-party kernel modules).
1038 + *
1039 + * Important note: the name and array arguments must be allocated memory
1040 + * and are consumed in soft_config_list.
833 1041 */
834 1042 static int
835 1043 add_soft_config(char *name, uint_t count, crypto_mech_name_t *array)
836 1044 {
837 1045 static uint_t soft_config_count = 0;
838 1046 kcf_soft_conf_entry_t *prev = NULL, *entry = NULL, *new_entry, *p;
839 1047 size_t name_len;
840 1048
841 1049 /*
842 1050 * Allocate storage for a new entry.
843 1051 * Free later if an entry already exists.
844 1052 */
845 1053 name_len = strlen(name) + 1;
846 1054 new_entry = kmem_zalloc(sizeof (kcf_soft_conf_entry_t), KM_SLEEP);
847 1055 new_entry->ce_name = kmem_alloc(name_len, KM_SLEEP);
848 1056 (void) strcpy(new_entry->ce_name, name);
849 1057
850 1058 mutex_enter(&soft_config_mutex);
851 1059 p = soft_config_list;
852 1060 if (p != NULL) {
853 1061 do {
854 1062 if (strncmp(name, p->ce_name, MAXNAMELEN) == 0) {
855 1063 entry = p;
856 1064 break;
857 1065 }
858 1066 prev = p;
859 1067
860 1068 } while ((p = p->ce_next) != NULL);
861 1069 }
862 1070
863 1071 if (entry == NULL) {
864 1072 if (count == 0) {
865 1073 mutex_exit(&soft_config_mutex);
866 1074 kmem_free(new_entry->ce_name, name_len);
867 1075 kmem_free(new_entry, sizeof (kcf_soft_conf_entry_t));
868 1076 return (CRYPTO_SUCCESS);
869 1077 }
870 1078
871 1079 if (soft_config_count > KCF_MAX_CONFIG_ENTRIES) {
872 1080 mutex_exit(&soft_config_mutex);
873 1081 kmem_free(new_entry->ce_name, name_len);
↓ open down ↓ |
31 lines elided |
↑ open up ↑ |
874 1082 kmem_free(new_entry, sizeof (kcf_soft_conf_entry_t));
875 1083 cmn_err(CE_WARN, "out of soft_config_list entries");
876 1084 return (CRYPTO_FAILED);
877 1085 }
878 1086
879 1087 /* add to head of list */
880 1088 new_entry->ce_next = soft_config_list;
881 1089 soft_config_list = new_entry;
882 1090 soft_config_count++;
883 1091 entry = new_entry;
884 - } else {
1092 + } else { /* mechanism already in list */
885 1093 kmem_free(new_entry->ce_name, name_len);
886 1094 kmem_free(new_entry, sizeof (kcf_soft_conf_entry_t));
887 1095 }
888 1096
889 1097 /* mechanism count == 0 means remove entry from list */
890 1098 if (count == 0) {
891 1099 if (prev == NULL) {
892 1100 /* remove first in list */
893 1101 soft_config_list = entry->ce_next;
894 1102 } else {
895 1103 prev->ce_next = entry->ce_next;
896 1104 }
897 1105 soft_config_count--;
898 1106 mutex_exit(&soft_config_mutex);
899 1107
900 1108 /* free entry */
901 1109 free_soft_config_entry(entry);
902 1110
903 1111 return (CRYPTO_SUCCESS);
904 1112 }
905 1113
906 1114
907 1115 /* replace mechanisms */
908 1116 if (entry->ce_mechs != NULL)
909 1117 crypto_free_mech_list(entry->ce_mechs, entry->ce_count);
910 1118
911 1119 entry->ce_mechs = array;
912 1120 entry->ce_count = count;
913 1121 mutex_exit(&soft_config_mutex);
914 1122
915 1123 return (CRYPTO_SUCCESS);
916 1124 }
917 1125
918 1126 /*
919 1127 * This routine searches the soft_config_list for the first entry that
920 1128 * has the specified mechanism in its mechanism list. If found,
921 1129 * a buffer containing the name of the software module that implements
922 1130 * the mechanism is allocated and stored in 'name'.
923 1131 */
924 1132 int
925 1133 get_sw_provider_for_mech(crypto_mech_name_t mech, char **name)
926 1134 {
927 1135 kcf_soft_conf_entry_t *p, *next;
928 1136 char tmp_name[MAXNAMELEN];
929 1137 size_t name_len = 0;
930 1138 int i;
931 1139
932 1140 mutex_enter(&soft_config_mutex);
933 1141 p = soft_config_list;
934 1142 while (p != NULL) {
935 1143 next = p->ce_next;
936 1144 for (i = 0; i < p->ce_count; i++) {
937 1145 if (strcmp(mech, &p->ce_mechs[i][0]) == 0) {
938 1146 name_len = strlen(p->ce_name) + 1;
939 1147 bcopy(p->ce_name, tmp_name, name_len);
940 1148 break;
941 1149 }
942 1150 }
↓ open down ↓ |
48 lines elided |
↑ open up ↑ |
943 1151 p = next;
944 1152 }
945 1153 mutex_exit(&soft_config_mutex);
946 1154
947 1155 if (name_len == 0)
948 1156 return (CRYPTO_FAILED);
949 1157
950 1158 *name = kmem_alloc(name_len, KM_SLEEP);
951 1159 bcopy(tmp_name, *name, name_len);
952 1160 return (CRYPTO_SUCCESS);
953 -}
954 -
955 -/*
956 - * This routine searches the soft_config_list for the specified
957 - * software provider, returning B_TRUE if it is in the list.
958 - */
959 -boolean_t
960 -in_soft_config_list(char *provider_name)
961 -{
962 - kcf_soft_conf_entry_t *p;
963 - boolean_t rv = B_FALSE;
964 -
965 - mutex_enter(&soft_config_mutex);
966 - for (p = soft_config_list; p != NULL; p = p->ce_next) {
967 - if (strcmp(provider_name, p->ce_name) == 0) {
968 - rv = B_TRUE;
969 - break;
970 - }
971 - }
972 - mutex_exit(&soft_config_mutex);
973 - return (rv);
974 1161 }
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX