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