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