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