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 * 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 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 */ 208 } 209 210 211 #if DEBUG 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 /* 245 * Utility routine to identify the providers to filter out and 246 * present only one provider. This happens when a hardware provider 247 * registers multiple units of the same device instance. 248 * 249 * Called from crypto_get_dev_list(). 250 */ 251 static void 252 filter_providers(uint_t count, kcf_provider_desc_t **provider_array, 253 char *skip_providers, int *mech_counts, int *new_count) 254 { 255 int i, j; 256 kcf_provider_desc_t *prov1, *prov2; 257 int n = 0; 258 259 for (i = 0; i < count; i++) { 260 if (skip_providers[i] == 1) 261 continue; 262 263 prov1 = provider_array[i]; 264 mech_counts[i] = prov1->pd_mech_list_count; 265 for (j = i + 1; j < count; j++) { 266 prov2 = provider_array[j]; 267 if (strncmp(prov1->pd_name, prov2->pd_name, 268 MAXNAMELEN) == 0 && 269 prov1->pd_instance == prov2->pd_instance) { 270 skip_providers[j] = 1; 271 mech_counts[i] += prov2->pd_mech_list_count; 272 } 273 } 274 n++; 275 } 276 277 *new_count = n; 278 } 279 280 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 */ 286 int 287 crypto_get_dev_list(uint_t *count, crypto_dev_list_entry_t **array) 288 { 289 kcf_provider_desc_t **provider_array; 290 kcf_provider_desc_t *pd; 291 crypto_dev_list_entry_t *p; 292 size_t skip_providers_size, mech_counts_size; 293 char *skip_providers; 294 uint_t provider_count; 295 int rval, i, j, new_count, *mech_counts; 296 297 /* 298 * Take snapshot of provider table returning only hardware providers 299 * that are in a usable state. Logical providers not included. 300 */ 301 rval = kcf_get_hw_prov_tab(&provider_count, &provider_array, KM_SLEEP, 302 NULL, 0, B_FALSE); 303 if (rval != CRYPTO_SUCCESS) 304 return (rval); 305 306 if (provider_count == 0) { 307 *array = NULL; 308 *count = 0; 309 return (CRYPTO_SUCCESS); 310 } 311 312 skip_providers_size = provider_count * sizeof (char); 313 mech_counts_size = provider_count * sizeof (int); 314 315 skip_providers = kmem_zalloc(skip_providers_size, KM_SLEEP); 316 mech_counts = kmem_zalloc(mech_counts_size, KM_SLEEP); 317 filter_providers(provider_count, provider_array, skip_providers, 318 mech_counts, &new_count); 319 320 p = kmem_alloc(new_count * sizeof (crypto_dev_list_entry_t), KM_SLEEP); 321 for (i = 0, j = 0; i < provider_count; i++) { 322 if (skip_providers[i] == 1) { 323 ASSERT(mech_counts[i] == 0); 324 continue; 325 } 326 pd = provider_array[i]; 327 p[j].le_mechanism_count = mech_counts[i]; 328 p[j].le_dev_instance = pd->pd_instance; 329 (void) strncpy(p[j].le_dev_name, pd->pd_name, MAXNAMELEN); 330 j++; 331 } 332 333 kcf_free_provider_tab(provider_count, provider_array); 334 kmem_free(skip_providers, skip_providers_size); 335 kmem_free(mech_counts, mech_counts_size); 336 337 *array = p; 338 *count = new_count; 339 return (CRYPTO_SUCCESS); 340 } 341 342 /* 343 * Return a buffer containing the null terminated names of software providers 344 * loaded by CRYPTO_LOAD_SOFT_CONFIG. 345 * Called from the CRYPTO_GET_SOFT_LIST ioctl. 346 */ 347 int 348 crypto_get_soft_list(uint_t *count, char **array, size_t *len) 349 { 350 char *names = NULL, *namep, *end; 351 kcf_soft_conf_entry_t *p; 352 uint_t n = 0, cnt = 0, final_count = 0; 353 size_t name_len, final_size = 0; 354 355 /* first estimate */ 356 mutex_enter(&soft_config_mutex); 357 for (p = soft_config_list; p != NULL; p = p->ce_next) { 358 n += strlen(p->ce_name) + 1; 359 cnt++; 360 } 361 mutex_exit(&soft_config_mutex); 362 363 if (cnt == 0) 364 goto out; 365 366 again: 367 namep = names = kmem_alloc(n, KM_SLEEP); 368 end = names + n; 369 final_size = 0; 370 final_count = 0; 371 372 mutex_enter(&soft_config_mutex); 373 for (p = soft_config_list; p != NULL; p = p->ce_next) { 374 name_len = strlen(p->ce_name) + 1; 375 /* check for enough space */ 376 if ((namep + name_len) > end) { 377 mutex_exit(&soft_config_mutex); 378 kmem_free(names, n); 379 n = n << 1; 380 goto again; 381 } 382 (void) strcpy(namep, p->ce_name); 383 namep += name_len; 384 final_size += name_len; 385 final_count++; 386 } 387 mutex_exit(&soft_config_mutex); 388 389 ASSERT(final_size <= n); 390 391 /* check if buffer we allocated is too large */ 392 if (final_size < n) { 393 char *final_buffer; 394 395 final_buffer = kmem_alloc(final_size, KM_SLEEP); 396 bcopy(names, final_buffer, final_size); 397 kmem_free(names, n); 398 names = final_buffer; 399 } 400 out: 401 *array = names; 402 *count = final_count; 403 *len = final_size; 404 return (CRYPTO_SUCCESS); 405 } 406 407 /* 408 * Check if a mechanism name is already in a mechanism name array 409 * Called by crypto_get_dev_info(). 410 */ 411 static boolean_t 412 duplicate(char *name, crypto_mech_name_t *array, int count) 413 { 414 int i; 415 416 for (i = 0; i < count; i++) { 417 if (strncmp(name, &array[i][0], 418 sizeof (crypto_mech_name_t)) == 0) 419 return (B_TRUE); 420 } 421 return (B_FALSE); 422 } 423 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 */ 429 int 430 crypto_get_dev_info(char *name, uint_t instance, uint_t *count, 431 crypto_mech_name_t **array) 432 { 433 int rv; 434 crypto_mech_name_t *mech_names, *resized_array; 435 int i, j, k = 0, max_count; 436 uint_t provider_count; 437 kcf_provider_desc_t **provider_array; 438 kcf_provider_desc_t *pd; 439 440 /* 441 * Get provider table entries matching name and instance 442 * for hardware providers that are in a usable state. 443 * Logical providers not included. NULL name matches 444 * all hardware providers. 445 */ 446 rv = kcf_get_hw_prov_tab(&provider_count, &provider_array, KM_SLEEP, 447 name, instance, B_FALSE); 448 if (rv != CRYPTO_SUCCESS) 449 return (rv); 450 451 if (provider_count == 0) 452 return (CRYPTO_ARGUMENTS_BAD); 453 454 /* Count all mechanisms supported by all providers */ 455 max_count = 0; 456 for (i = 0; i < provider_count; i++) 457 max_count += provider_array[i]->pd_mech_list_count; 458 459 if (max_count == 0) { 460 mech_names = NULL; 461 goto out; 462 } 463 464 /* Allocate space and copy mech names */ 465 mech_names = kmem_alloc(max_count * sizeof (crypto_mech_name_t), 466 KM_SLEEP); 467 468 k = 0; 469 for (i = 0; i < provider_count; i++) { 470 pd = provider_array[i]; 471 for (j = 0; j < pd->pd_mech_list_count; j++) { 472 /* check for duplicate */ 473 if (duplicate(&pd->pd_mechanisms[j].cm_mech_name[0], 474 mech_names, k)) 475 continue; 476 bcopy(&pd->pd_mechanisms[j].cm_mech_name[0], 477 &mech_names[k][0], sizeof (crypto_mech_name_t)); 478 k++; 479 } 480 } 481 482 /* resize */ 483 if (k != max_count) { 484 resized_array = 485 kmem_alloc(k * sizeof (crypto_mech_name_t), KM_SLEEP); 486 bcopy(mech_names, resized_array, 487 k * sizeof (crypto_mech_name_t)); 488 kmem_free(mech_names, 489 max_count * sizeof (crypto_mech_name_t)); 490 mech_names = resized_array; 491 } 492 493 out: 494 kcf_free_provider_tab(provider_count, provider_array); 495 *count = k; 496 *array = mech_names; 497 498 return (CRYPTO_SUCCESS); 499 } 500 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 */ 506 int 507 crypto_get_soft_info(caddr_t name, uint_t *count, crypto_mech_name_t **array) 508 { 509 ddi_modhandle_t modh = NULL; 510 kcf_provider_desc_t *provider; 511 int rv; 512 513 provider = kcf_prov_tab_lookup_by_name(name); 514 if (provider == NULL) { 515 char *tmp; 516 int name_len; 517 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'; 524 525 modh = ddi_modopen(tmp, KRTLD_MODE_FIRST, NULL); 526 kmem_free(tmp, name_len + 8); 527 528 if (modh == NULL) { 529 return (CRYPTO_ARGUMENTS_BAD); 530 } 531 532 provider = kcf_prov_tab_lookup_by_name(name); 533 if (provider == NULL) { 534 return (CRYPTO_ARGUMENTS_BAD); 535 } 536 } 537 538 rv = dup_mech_names(provider, array, count, KM_SLEEP); 539 KCF_PROV_REFRELE(provider); 540 if (modh != NULL) 541 (void) ddi_modclose(modh); 542 return (rv); 543 } 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 */ 552 static void 553 kcf_change_mechs(kcf_provider_desc_t *provider, uint_t count, 554 crypto_mech_name_t *array, crypto_event_change_t direction) 555 { 556 crypto_notify_event_change_t ec; 557 crypto_mech_info_t *mi; 558 kcf_prov_mech_desc_t *pmd; 559 char *mech; 560 int i, j, n; 561 562 ASSERT(direction == CRYPTO_MECH_ADDED || 563 direction == CRYPTO_MECH_REMOVED); 564 565 if (provider == NULL) { 566 /* 567 * Nothing to add or remove from the tables since 568 * the provider isn't registered. 569 */ 570 return; 571 } 572 573 for (i = 0; i < count; i++) { 574 if (array[i][0] == '\0') 575 continue; 576 577 mech = &array[i][0]; 578 579 n = provider->pd_mech_list_count; 580 for (j = 0; j < n; j++) { 581 mi = &provider->pd_mechanisms[j]; 582 if (strncmp(mi->cm_mech_name, mech, 583 CRYPTO_MAX_MECH_NAME) == 0) 584 break; 585 } 586 if (j == n) 587 continue; 588 589 switch (direction) { 590 case CRYPTO_MECH_ADDED: 591 (void) kcf_add_mech_provider(j, provider, &pmd); 592 break; 593 594 case CRYPTO_MECH_REMOVED: 595 kcf_remove_mech_provider(mech, provider); 596 break; 597 } 598 599 /* Inform interested clients of the event */ 600 ec.ec_provider_type = provider->pd_prov_type; 601 ec.ec_change = direction; 602 603 (void) strncpy(ec.ec_mech_name, mech, CRYPTO_MAX_MECH_NAME); 604 kcf_walk_ntfylist(CRYPTO_EVENT_MECHS_CHANGED, &ec); 605 } 606 } 607 608 /* 609 * If a mech name in the second array (prev_array) is also in the 610 * first array, then a NULL character is written into the first byte 611 * of the mech name in the second array. This effectively removes 612 * the mech name from the second array. 613 */ 614 static void 615 kcf_compare_mechs(uint_t count, crypto_mech_name_t *array, uint_t prev_count, 616 crypto_mech_name_t *prev_array) 617 { 618 int i, j; 619 620 for (i = 0; i < prev_count; i++) { 621 for (j = 0; j < count; j++) { 622 if (strncmp(&prev_array[i][0], &array[j][0], 623 CRYPTO_MAX_MECH_NAME) == 0) { 624 prev_array[i][0] = '\0'; 625 } 626 } 627 } 628 } 629 630 /* 631 * Called from CRYPTO_LOAD_DEV_DISABLED ioctl. 632 * If new_count is 0, then completely remove the entry. 633 */ 634 int 635 crypto_load_dev_disabled(char *name, uint_t instance, uint_t new_count, 636 crypto_mech_name_t *new_array) 637 { 638 kcf_provider_desc_t *provider = NULL; 639 kcf_provider_desc_t **provider_array; 640 crypto_mech_name_t *prev_array; 641 uint_t provider_count, prev_count; 642 int i, rv = CRYPTO_SUCCESS; 643 644 /* 645 * Remove the policy entry if new_count is 0, otherwise put disabled 646 * mechanisms into policy table. 647 */ 648 if (new_count == 0) { 649 kcf_policy_remove_by_dev(name, instance, &prev_count, 650 &prev_array); 651 } else if ((rv = kcf_policy_load_dev_disabled(name, instance, new_count, 652 new_array, &prev_count, &prev_array)) != CRYPTO_SUCCESS) { 653 return (rv); 654 } 655 656 /* 657 * Get provider table entries matching name and instance 658 * for providers that are are in a usable or unverified state. 659 */ 660 rv = kcf_get_hw_prov_tab(&provider_count, &provider_array, KM_SLEEP, 661 name, instance, B_TRUE); 662 if (rv != CRYPTO_SUCCESS) 663 return (rv); 664 665 for (i = 0; i < provider_count; i++) { 666 provider = provider_array[i]; 667 668 /* previously disabled mechanisms may become enabled */ 669 if (prev_array != NULL) { 670 kcf_compare_mechs(new_count, new_array, 671 prev_count, prev_array); 672 kcf_change_mechs(provider, prev_count, prev_array, 673 CRYPTO_MECH_ADDED); 674 } 675 676 kcf_change_mechs(provider, new_count, new_array, 677 CRYPTO_MECH_REMOVED); 678 } 679 680 kcf_free_provider_tab(provider_count, provider_array); 681 crypto_free_mech_list(prev_array, prev_count); 682 return (rv); 683 } 684 685 /* 686 * Called from CRYPTO_LOAD_SOFT_DISABLED ioctl. 687 * If new_count is 0, then completely remove the entry. 688 */ 689 int 690 crypto_load_soft_disabled(char *name, uint_t new_count, 691 crypto_mech_name_t *new_array) 692 { 693 kcf_provider_desc_t *provider = NULL; 694 crypto_mech_name_t *prev_array; 695 uint_t prev_count = 0; 696 int rv; 697 698 provider = kcf_prov_tab_lookup_by_name(name); 699 if (provider != NULL) { 700 mutex_enter(&provider->pd_lock); 701 /* 702 * Check if any other thread is disabling or removing 703 * this provider. We return if this is the case. 704 */ 705 if (provider->pd_state >= KCF_PROV_DISABLED) { 706 mutex_exit(&provider->pd_lock); 707 KCF_PROV_REFRELE(provider); 708 return (CRYPTO_BUSY); 709 } 710 provider->pd_state = KCF_PROV_DISABLED; 711 mutex_exit(&provider->pd_lock); 712 713 undo_register_provider(provider, B_TRUE); 714 KCF_PROV_REFRELE(provider); 715 if (provider->pd_kstat != NULL) 716 KCF_PROV_REFRELE(provider); 717 718 mutex_enter(&provider->pd_lock); 719 /* Wait till the existing requests complete. */ 720 while (provider->pd_state != KCF_PROV_FREED) { 721 cv_wait(&provider->pd_remove_cv, &provider->pd_lock); 722 } 723 mutex_exit(&provider->pd_lock); 724 } 725 726 if (new_count == 0) { 727 kcf_policy_remove_by_name(name, &prev_count, &prev_array); 728 crypto_free_mech_list(prev_array, prev_count); 729 rv = CRYPTO_SUCCESS; 730 goto out; 731 } 732 733 /* put disabled mechanisms into policy table */ 734 if ((rv = kcf_policy_load_soft_disabled(name, new_count, new_array, 735 &prev_count, &prev_array)) == CRYPTO_SUCCESS) { 736 crypto_free_mech_list(prev_array, prev_count); 737 } 738 739 out: 740 if (provider != NULL) { 741 redo_register_provider(provider); 742 if (provider->pd_kstat != NULL) 743 KCF_PROV_REFHOLD(provider); 744 mutex_enter(&provider->pd_lock); 745 provider->pd_state = KCF_PROV_READY; 746 mutex_exit(&provider->pd_lock); 747 } else if (rv == CRYPTO_SUCCESS) { 748 /* 749 * There are some cases where it is useful to kCF clients 750 * to have a provider whose mechanism is enabled now to be 751 * available. So, we attempt to load it here. 752 * 753 * The check, new_count < prev_count, ensures that we do this 754 * only in the case where a mechanism(s) is now enabled. 755 * This check assumes that enable and disable are separate 756 * administrative actions and are not done in a single action. 757 */ 758 if ((new_count < prev_count) && 759 (modload("crypto", name) != -1)) { 760 struct modctl *mcp; 761 boolean_t load_again = B_FALSE; 762 763 if ((mcp = mod_hold_by_name(name)) != NULL) { 764 mcp->mod_loadflags |= MOD_NOAUTOUNLOAD; 765 766 /* memory pressure may have unloaded module */ 767 if (!mcp->mod_installed) 768 load_again = B_TRUE; 769 mod_release_mod(mcp); 770 771 if (load_again) 772 (void) modload("crypto", name); 773 } 774 } 775 } 776 777 return (rv); 778 } 779 780 /* called from the CRYPTO_LOAD_SOFT_CONFIG ioctl */ 781 int 782 crypto_load_soft_config(caddr_t name, uint_t count, crypto_mech_name_t *array) 783 { 784 return (add_soft_config(name, count, array)); 785 } 786 787 /* 788 * Unload a kernel software crypto module. 789 * Called from the CRYPTO_UNLOAD_SOFT_MODULE ioctl. 790 */ 791 int 792 crypto_unload_soft_module(caddr_t name) 793 { 794 int error; 795 modid_t id; 796 kcf_provider_desc_t *provider; 797 struct modctl *mcp; 798 799 /* verify that 'name' refers to a registered crypto provider */ 800 if ((provider = kcf_prov_tab_lookup_by_name(name)) == NULL) 801 return (CRYPTO_UNKNOWN_PROVIDER); 802 803 /* 804 * We save the module id and release the reference. We need to 805 * do this as modunload() calls unregister which waits for the 806 * refcnt to drop to zero. 807 */ 808 id = provider->pd_module_id; 809 KCF_PROV_REFRELE(provider); 810 811 if ((mcp = mod_hold_by_name(name)) != NULL) { 812 mcp->mod_loadflags &= ~(MOD_NOAUTOUNLOAD); 813 mod_release_mod(mcp); 814 } 815 816 if ((error = modunload(id)) != 0) { 817 return (error == EBUSY ? CRYPTO_BUSY : CRYPTO_FAILED); 818 } 819 820 return (CRYPTO_SUCCESS); 821 } 822 823 /* 824 * Free the list of kernel hardware crypto providers. 825 * Called by get_dev_list() for the CRYPTO_GET_DEV_LIST ioctl. 826 */ 827 void 828 crypto_free_dev_list(crypto_dev_list_entry_t *array, uint_t count) 829 { 830 if (count == 0 || array == NULL) 831 return; 832 833 kmem_free(array, count * sizeof (crypto_dev_list_entry_t)); 834 } 835 836 /* 837 * Returns duplicate array of mechanisms. The array is allocated and 838 * must be freed by the caller. 839 */ 840 static int 841 dup_mech_names(kcf_provider_desc_t *provider, crypto_mech_name_t **array, 842 uint_t *count, int kmflag) 843 { 844 crypto_mech_name_t *mech_names; 845 uint_t n; 846 uint_t i; 847 848 if ((n = provider->pd_mech_list_count) == 0) { 849 *count = 0; 850 *array = NULL; 851 return (CRYPTO_SUCCESS); 852 } 853 854 mech_names = kmem_alloc(n * sizeof (crypto_mech_name_t), kmflag); 855 if (mech_names == NULL) 856 return (CRYPTO_HOST_MEMORY); 857 858 for (i = 0; i < n; i++) { 859 bcopy(&provider->pd_mechanisms[i].cm_mech_name[0], 860 &mech_names[i][0], sizeof (crypto_mech_name_t)); 861 } 862 863 *count = n; 864 *array = mech_names; 865 return (CRYPTO_SUCCESS); 866 } 867 868 /* 869 * Returns B_TRUE if the specified mechanism is disabled, B_FALSE otherwise. 870 */ 871 boolean_t 872 is_mech_disabled_byname(crypto_provider_type_t prov_type, char *pd_name, 873 uint_t pd_instance, crypto_mech_name_t mech_name) 874 { 875 kcf_policy_desc_t *policy; 876 uint_t i; 877 878 ASSERT(prov_type == CRYPTO_SW_PROVIDER || 879 prov_type == CRYPTO_HW_PROVIDER); 880 881 switch (prov_type) { 882 case CRYPTO_SW_PROVIDER: 883 policy = kcf_policy_lookup_by_name(pd_name); 884 /* no policy for provider - so mechanism can't be disabled */ 885 if (policy == NULL) 886 return (B_FALSE); 887 break; 888 889 case CRYPTO_HW_PROVIDER: 890 policy = kcf_policy_lookup_by_dev(pd_name, pd_instance); 891 /* no policy for provider - so mechanism can't be disabled */ 892 if (policy == NULL) 893 return (B_FALSE); 894 break; 895 } 896 897 mutex_enter(&policy->pd_mutex); 898 for (i = 0; i < policy->pd_disabled_count; i ++) { 899 if (strncmp(mech_name, &policy->pd_disabled_mechs[i][0], 900 CRYPTO_MAX_MECH_NAME) == 0) { 901 mutex_exit(&policy->pd_mutex); 902 KCF_POLICY_REFRELE(policy); 903 return (B_TRUE); 904 } 905 } 906 mutex_exit(&policy->pd_mutex); 907 KCF_POLICY_REFRELE(policy); 908 return (B_FALSE); 909 } 910 911 /* 912 * Returns B_TRUE if the specified mechanism is disabled, B_FALSE otherwise. 913 * 914 * This is a wrapper routine around is_mech_disabled_byname() above and 915 * takes a pointer kcf_provider_desc structure as argument. 916 */ 917 boolean_t 918 is_mech_disabled(kcf_provider_desc_t *provider, crypto_mech_name_t name) 919 { 920 kcf_provider_list_t *e; 921 kcf_provider_desc_t *pd; 922 boolean_t found = B_FALSE; 923 uint_t count, i; 924 925 if (provider->pd_prov_type != CRYPTO_LOGICAL_PROVIDER) { 926 return (is_mech_disabled_byname(provider->pd_prov_type, 927 provider->pd_name, provider->pd_instance, name)); 928 } 929 930 /* 931 * Lock the logical provider just in case one of its hardware 932 * provider members unregisters. 933 */ 934 mutex_enter(&provider->pd_lock); 935 for (e = provider->pd_provider_list; e != NULL; e = e->pl_next) { 936 937 pd = e->pl_provider; 938 ASSERT(pd->pd_prov_type == CRYPTO_HW_PROVIDER); 939 940 /* find out if mechanism is offered by hw provider */ 941 count = pd->pd_mech_list_count; 942 for (i = 0; i < count; i++) { 943 if (strncmp(&pd->pd_mechanisms[i].cm_mech_name[0], 944 name, MAXNAMELEN) == 0) { 945 break; 946 } 947 } 948 if (i == count) 949 continue; 950 951 found = !is_mech_disabled_byname(pd->pd_prov_type, 952 pd->pd_name, pd->pd_instance, name); 953 954 if (found) 955 break; 956 } 957 mutex_exit(&provider->pd_lock); 958 /* 959 * If we found the mechanism, then it means it is still enabled for 960 * at least one hardware provider, so the mech can't be disabled 961 * for the logical provider. 962 */ 963 return (!found); 964 } 965 966 /* 967 * Builds array of permitted mechanisms. The array is allocated and 968 * must be freed by the caller. 969 */ 970 int 971 crypto_build_permitted_mech_names(kcf_provider_desc_t *provider, 972 crypto_mech_name_t **array, uint_t *count, int kmflag) 973 { 974 crypto_mech_name_t *mech_names, *p; 975 uint_t i; 976 uint_t scnt = provider->pd_mech_list_count; 977 uint_t dcnt = 0; 978 979 /* 980 * Compute number of 'permitted mechanisms', which is 981 * 'supported mechanisms' - 'disabled mechanisms'. 982 */ 983 for (i = 0; i < scnt; i++) { 984 if (is_mech_disabled(provider, 985 &provider->pd_mechanisms[i].cm_mech_name[0])) { 986 dcnt++; 987 } 988 } 989 990 /* all supported mechanisms have been disabled */ 991 if (scnt == dcnt) { 992 *count = 0; 993 *array = NULL; 994 return (CRYPTO_SUCCESS); 995 } 996 997 mech_names = kmem_alloc((scnt - dcnt) * sizeof (crypto_mech_name_t), 998 kmflag); 999 if (mech_names == NULL) 1000 return (CRYPTO_HOST_MEMORY); 1001 1002 /* build array of permitted mechanisms */ 1003 for (i = 0, p = mech_names; i < scnt; i++) { 1004 if (!is_mech_disabled(provider, 1005 &provider->pd_mechanisms[i].cm_mech_name[0])) { 1006 bcopy(&provider->pd_mechanisms[i].cm_mech_name[0], 1007 p++, sizeof (crypto_mech_name_t)); 1008 } 1009 } 1010 1011 *count = scnt - dcnt; 1012 *array = mech_names; 1013 return (CRYPTO_SUCCESS); 1014 } 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 */ 1020 static void 1021 free_soft_config_entry(kcf_soft_conf_entry_t *p) 1022 { 1023 kmem_free(p->ce_name, strlen(p->ce_name) + 1); 1024 crypto_free_mech_list(p->ce_mechs, p->ce_count); 1025 kmem_free(p, sizeof (kcf_soft_conf_entry_t)); 1026 } 1027 1028 /* 1029 * Store configuration information for software providers in a linked list. 1030 * If the list already contains an entry for the specified provider 1031 * and the specified mechanism list has at least one mechanism, then 1032 * the mechanism list for the provider is updated. If the mechanism list 1033 * is empty, the entry for the provider is removed. 1034 * 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. 1041 */ 1042 static int 1043 add_soft_config(char *name, uint_t count, crypto_mech_name_t *array) 1044 { 1045 static uint_t soft_config_count = 0; 1046 kcf_soft_conf_entry_t *prev = NULL, *entry = NULL, *new_entry, *p; 1047 size_t name_len; 1048 1049 /* 1050 * Allocate storage for a new entry. 1051 * Free later if an entry already exists. 1052 */ 1053 name_len = strlen(name) + 1; 1054 new_entry = kmem_zalloc(sizeof (kcf_soft_conf_entry_t), KM_SLEEP); 1055 new_entry->ce_name = kmem_alloc(name_len, KM_SLEEP); 1056 (void) strcpy(new_entry->ce_name, name); 1057 1058 mutex_enter(&soft_config_mutex); 1059 p = soft_config_list; 1060 if (p != NULL) { 1061 do { 1062 if (strncmp(name, p->ce_name, MAXNAMELEN) == 0) { 1063 entry = p; 1064 break; 1065 } 1066 prev = p; 1067 1068 } while ((p = p->ce_next) != NULL); 1069 } 1070 1071 if (entry == NULL) { 1072 if (count == 0) { 1073 mutex_exit(&soft_config_mutex); 1074 kmem_free(new_entry->ce_name, name_len); 1075 kmem_free(new_entry, sizeof (kcf_soft_conf_entry_t)); 1076 return (CRYPTO_SUCCESS); 1077 } 1078 1079 if (soft_config_count > KCF_MAX_CONFIG_ENTRIES) { 1080 mutex_exit(&soft_config_mutex); 1081 kmem_free(new_entry->ce_name, name_len); 1082 kmem_free(new_entry, sizeof (kcf_soft_conf_entry_t)); 1083 cmn_err(CE_WARN, "out of soft_config_list entries"); 1084 return (CRYPTO_FAILED); 1085 } 1086 1087 /* add to head of list */ 1088 new_entry->ce_next = soft_config_list; 1089 soft_config_list = new_entry; 1090 soft_config_count++; 1091 entry = new_entry; 1092 } else { /* mechanism already in list */ 1093 kmem_free(new_entry->ce_name, name_len); 1094 kmem_free(new_entry, sizeof (kcf_soft_conf_entry_t)); 1095 } 1096 1097 /* mechanism count == 0 means remove entry from list */ 1098 if (count == 0) { 1099 if (prev == NULL) { 1100 /* remove first in list */ 1101 soft_config_list = entry->ce_next; 1102 } else { 1103 prev->ce_next = entry->ce_next; 1104 } 1105 soft_config_count--; 1106 mutex_exit(&soft_config_mutex); 1107 1108 /* free entry */ 1109 free_soft_config_entry(entry); 1110 1111 return (CRYPTO_SUCCESS); 1112 } 1113 1114 1115 /* replace mechanisms */ 1116 if (entry->ce_mechs != NULL) 1117 crypto_free_mech_list(entry->ce_mechs, entry->ce_count); 1118 1119 entry->ce_mechs = array; 1120 entry->ce_count = count; 1121 mutex_exit(&soft_config_mutex); 1122 1123 return (CRYPTO_SUCCESS); 1124 } 1125 1126 /* 1127 * This routine searches the soft_config_list for the first entry that 1128 * has the specified mechanism in its mechanism list. If found, 1129 * a buffer containing the name of the software module that implements 1130 * the mechanism is allocated and stored in 'name'. 1131 */ 1132 int 1133 get_sw_provider_for_mech(crypto_mech_name_t mech, char **name) 1134 { 1135 kcf_soft_conf_entry_t *p, *next; 1136 char tmp_name[MAXNAMELEN]; 1137 size_t name_len = 0; 1138 int i; 1139 1140 mutex_enter(&soft_config_mutex); 1141 p = soft_config_list; 1142 while (p != NULL) { 1143 next = p->ce_next; 1144 for (i = 0; i < p->ce_count; i++) { 1145 if (strcmp(mech, &p->ce_mechs[i][0]) == 0) { 1146 name_len = strlen(p->ce_name) + 1; 1147 bcopy(p->ce_name, tmp_name, name_len); 1148 break; 1149 } 1150 } 1151 p = next; 1152 } 1153 mutex_exit(&soft_config_mutex); 1154 1155 if (name_len == 0) 1156 return (CRYPTO_FAILED); 1157 1158 *name = kmem_alloc(name_len, KM_SLEEP); 1159 bcopy(tmp_name, *name, name_len); 1160 return (CRYPTO_SUCCESS); 1161 }