Print this page
6414175 kcf.conf's supportedlist not providing much usefulness


   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 #pragma ident   "%Z%%M% %I%     %E% SMI"
  27 
  28 /*
  29  * Core KCF (Kernel Cryptographic Framework). This file implements
  30  * the cryptoadm entry points.
  31  */
  32 
  33 #include <sys/systm.h>
  34 #include <sys/errno.h>
  35 #include <sys/cmn_err.h>
  36 #include <sys/rwlock.h>
  37 #include <sys/kmem.h>
  38 #include <sys/modctl.h>
  39 #include <sys/sunddi.h>
  40 #include <sys/door.h>
  41 #include <sys/crypto/common.h>
  42 #include <sys/crypto/api.h>
  43 #include <sys/crypto/spi.h>
  44 #include <sys/crypto/impl.h>
  45 #include <sys/crypto/sched_impl.h>
  46 
  47 /* protects the the soft_config_list. */
  48 kmutex_t soft_config_mutex;
  49 
  50 /*
  51  * This linked list contains software configuration entries that
  52  * are loaded into the kernel by the CRYPTO_LOAD_SOFT_CONFIG ioctl.
  53  * It is protected by the soft_config_mutex.




  54  */
  55 kcf_soft_conf_entry_t *soft_config_list;
  56 
  57 static int add_soft_config(char *, uint_t, crypto_mech_name_t *);
  58 static int dup_mech_names(kcf_provider_desc_t *, crypto_mech_name_t **,
  59     uint_t *, int);
  60 static void free_soft_config_entry(kcf_soft_conf_entry_t *);
  61 
  62 #define KCF_MAX_CONFIG_ENTRIES 512 /* maximum entries in soft_config_list */
  63 





















  64 void
  65 kcf_soft_config_init(void)
  66 {






















































































  67         mutex_init(&soft_config_mutex, NULL, MUTEX_DRIVER, NULL);































  68 }
  69 
  70 

  71 /*
































  72  * Utility routine to identify the providers to filter out and
  73  * present only one provider. This happens when a hardware provider
  74  * registers multiple units of the same device instance.


  75  */
  76 static void
  77 filter_providers(uint_t count, kcf_provider_desc_t **provider_array,
  78         char *skip_providers, int *mech_counts, int *new_count)
  79 {
  80         int i, j;
  81         kcf_provider_desc_t *prov1, *prov2;
  82         int n = 0;
  83 
  84         for (i = 0; i < count; i++) {
  85                 if (skip_providers[i] == 1)
  86                         continue;
  87 
  88                 prov1 = provider_array[i];
  89                 mech_counts[i] = prov1->pd_mech_list_count;
  90                 for (j = i + 1; j < count; j++) {
  91                         prov2 = provider_array[j];
  92                         if (strncmp(prov1->pd_name, prov2->pd_name,
  93                             MAXNAMELEN) == 0 &&
  94                             prov1->pd_instance == prov2->pd_instance) {
  95                                 skip_providers[j] = 1;
  96                                 mech_counts[i] += prov2->pd_mech_list_count;
  97                         }
  98                 }
  99                 n++;
 100         }
 101 
 102         *new_count = n;
 103 }
 104 
 105 
 106 /* called from the CRYPTO_GET_DEV_LIST ioctl */




 107 int
 108 crypto_get_dev_list(uint_t *count, crypto_dev_list_entry_t **array)
 109 {
 110         kcf_provider_desc_t **provider_array;
 111         kcf_provider_desc_t *pd;
 112         crypto_dev_list_entry_t *p;
 113         size_t skip_providers_size, mech_counts_size;
 114         char *skip_providers;
 115         uint_t provider_count;
 116         int rval, i, j, new_count, *mech_counts;
 117 
 118         /*
 119          * Take snapshot of provider table returning only hardware providers
 120          * that are in a usable state. Logical providers not included.
 121          */
 122         rval =  kcf_get_hw_prov_tab(&provider_count, &provider_array, KM_SLEEP,
 123             NULL, 0, B_FALSE);
 124         if (rval != CRYPTO_SUCCESS)
 125                 return (rval);
 126 


 144                         ASSERT(mech_counts[i] == 0);
 145                         continue;
 146                 }
 147                 pd = provider_array[i];
 148                 p[j].le_mechanism_count = mech_counts[i];
 149                 p[j].le_dev_instance = pd->pd_instance;
 150                 (void) strncpy(p[j].le_dev_name, pd->pd_name, MAXNAMELEN);
 151                 j++;
 152         }
 153 
 154         kcf_free_provider_tab(provider_count, provider_array);
 155         kmem_free(skip_providers, skip_providers_size);
 156         kmem_free(mech_counts, mech_counts_size);
 157 
 158         *array = p;
 159         *count = new_count;
 160         return (CRYPTO_SUCCESS);
 161 }
 162 
 163 /*
 164  * Called from the CRYPTO_GET_SOFT_LIST ioctl, this routine returns
 165  * a buffer containing the null terminated names of software providers
 166  * loaded by CRYPTO_LOAD_SOFT_CONFIG.

 167  */
 168 int
 169 crypto_get_soft_list(uint_t *count, char **array, size_t *len)
 170 {
 171         char *names = NULL, *namep, *end;
 172         kcf_soft_conf_entry_t *p;
 173         uint_t n = 0, cnt = 0, final_count = 0;
 174         size_t name_len, final_size = 0;
 175 
 176         /* first estimate */
 177         mutex_enter(&soft_config_mutex);
 178         for (p = soft_config_list; p != NULL; p = p->ce_next) {
 179                 n += strlen(p->ce_name) + 1;
 180                 cnt++;
 181         }
 182         mutex_exit(&soft_config_mutex);
 183 
 184         if (cnt == 0)
 185                 goto out;
 186 


 208         mutex_exit(&soft_config_mutex);
 209 
 210         ASSERT(final_size <= n);
 211 
 212         /* check if buffer we allocated is too large */
 213         if (final_size < n) {
 214                 char *final_buffer;
 215 
 216                 final_buffer = kmem_alloc(final_size, KM_SLEEP);
 217                 bcopy(names, final_buffer, final_size);
 218                 kmem_free(names, n);
 219                 names = final_buffer;
 220         }
 221 out:
 222         *array = names;
 223         *count = final_count;
 224         *len = final_size;
 225         return (CRYPTO_SUCCESS);
 226 }
 227 




 228 static boolean_t
 229 duplicate(char *name, crypto_mech_name_t *array, int count)
 230 {
 231         int i;
 232 
 233         for (i = 0; i < count; i++) {
 234                 if (strncmp(name, &array[i][0],
 235                     sizeof (crypto_mech_name_t)) == 0)
 236                         return (B_TRUE);
 237         }
 238         return (B_FALSE);
 239 }
 240 
 241 /* called from the CRYPTO_GET_DEV_INFO ioctl */




 242 int
 243 crypto_get_dev_info(char *name, uint_t instance, uint_t *count,
 244     crypto_mech_name_t **array)
 245 {
 246         int rv;
 247         crypto_mech_name_t *mech_names, *resized_array;
 248         int i, j, k = 0, max_count;
 249         uint_t provider_count;
 250         kcf_provider_desc_t **provider_array;
 251         kcf_provider_desc_t *pd;
 252 
 253         /*
 254          * Get provider table entries matching name and instance
 255          * for hardware providers that are in a usable state.
 256          * Logical providers not included. NULL name matches
 257          * all hardware providers.
 258          */
 259         rv =  kcf_get_hw_prov_tab(&provider_count, &provider_array, KM_SLEEP,
 260             name, instance, B_FALSE);
 261         if (rv != CRYPTO_SUCCESS)


 294 
 295         /* resize */
 296         if (k != max_count) {
 297                 resized_array =
 298                     kmem_alloc(k * sizeof (crypto_mech_name_t), KM_SLEEP);
 299                 bcopy(mech_names, resized_array,
 300                     k * sizeof (crypto_mech_name_t));
 301                 kmem_free(mech_names,
 302                     max_count * sizeof (crypto_mech_name_t));
 303                 mech_names = resized_array;
 304         }
 305 
 306 out:
 307         kcf_free_provider_tab(provider_count, provider_array);
 308         *count = k;
 309         *array = mech_names;
 310 
 311         return (CRYPTO_SUCCESS);
 312 }
 313 
 314 /* called from the CRYPTO_GET_SOFT_INFO ioctl */




 315 int
 316 crypto_get_soft_info(caddr_t name, uint_t *count, crypto_mech_name_t **array)
 317 {
 318         ddi_modhandle_t modh = NULL;
 319         kcf_provider_desc_t *provider;
 320         int rv;
 321 
 322         provider = kcf_prov_tab_lookup_by_name(name);
 323         if (provider == NULL) {
 324                 if (in_soft_config_list(name)) {
 325                         char *tmp;
 326                         int name_len;
 327 
 328                         /* strlen("crypto/") + NULL terminator == 8 */
 329                         name_len = strlen(name);
 330                         tmp = kmem_alloc(name_len + 8, KM_SLEEP);
 331                         bcopy("crypto/", tmp, 7);
 332                         bcopy(name, &tmp[7], name_len);
 333                         tmp[name_len + 7] = '\0';
 334 
 335                         modh = ddi_modopen(tmp, KRTLD_MODE_FIRST, NULL);
 336                         kmem_free(tmp, name_len + 8);
 337 
 338                         if (modh == NULL) {
 339                                 return (CRYPTO_ARGUMENTS_BAD);
 340                         }
 341 
 342                         provider = kcf_prov_tab_lookup_by_name(name);
 343                         if (provider == NULL) {
 344                                 return (CRYPTO_ARGUMENTS_BAD);
 345                         }
 346                 } else {
 347                         return (CRYPTO_ARGUMENTS_BAD);
 348                 }
 349         }
 350 
 351         rv = dup_mech_names(provider, array, count, KM_SLEEP);
 352         KCF_PROV_REFRELE(provider);
 353         if (modh != NULL)
 354                 (void) ddi_modclose(modh);
 355         return (rv);
 356 }
 357 







 358 static void
 359 kcf_change_mechs(kcf_provider_desc_t *provider, uint_t count,
 360     crypto_mech_name_t *array, crypto_event_change_t direction)
 361 {
 362         crypto_notify_event_change_t ec;
 363         crypto_mech_info_t *mi;
 364         kcf_prov_mech_desc_t *pmd;
 365         char *mech;
 366         int i, j, n;
 367 
 368         ASSERT(direction == CRYPTO_MECH_ADDED ||
 369             direction == CRYPTO_MECH_REMOVED);
 370 
 371         if (provider == NULL) {
 372                 /*
 373                  * Nothing to add or remove from the tables since
 374                  * the provider isn't registered.
 375                  */
 376                 return;
 377         }


 544 
 545 out:
 546         if (provider != NULL) {
 547                 redo_register_provider(provider);
 548                 if (provider->pd_kstat != NULL)
 549                         KCF_PROV_REFHOLD(provider);
 550                 mutex_enter(&provider->pd_lock);
 551                 provider->pd_state = KCF_PROV_READY;
 552                 mutex_exit(&provider->pd_lock);
 553         } else if (rv == CRYPTO_SUCCESS) {
 554                 /*
 555                  * There are some cases where it is useful to kCF clients
 556                  * to have a provider whose mechanism is enabled now to be
 557                  * available. So, we attempt to load it here.
 558                  *
 559                  * The check, new_count < prev_count, ensures that we do this
 560                  * only in the case where a mechanism(s) is now enabled.
 561                  * This check assumes that enable and disable are separate
 562                  * administrative actions and are not done in a single action.
 563                  */
 564                 if (new_count < prev_count && (in_soft_config_list(name)) &&
 565                     (modload("crypto", name) != -1)) {
 566                         struct modctl *mcp;
 567                         boolean_t load_again = B_FALSE;
 568 
 569                         if ((mcp = mod_hold_by_name(name)) != NULL) {
 570                                 mcp->mod_loadflags |= MOD_NOAUTOUNLOAD;
 571 
 572                                 /* memory pressure may have unloaded module */
 573                                 if (!mcp->mod_installed)
 574                                         load_again = B_TRUE;
 575                                 mod_release_mod(mcp);
 576 
 577                                 if (load_again)
 578                                         (void) modload("crypto", name);
 579                         }
 580                 }
 581         }
 582 
 583         return (rv);
 584 }
 585 
 586 /* called from the CRYPTO_LOAD_SOFT_CONFIG ioctl */
 587 int
 588 crypto_load_soft_config(caddr_t name, uint_t count, crypto_mech_name_t *array)
 589 {
 590         return (add_soft_config(name, count, array));
 591 }
 592 
 593 /* called from the CRYPTO_UNLOAD_SOFT_MODULE ioctl */



 594 int
 595 crypto_unload_soft_module(caddr_t name)
 596 {
 597         int error;
 598         modid_t id;
 599         kcf_provider_desc_t *provider;
 600         struct modctl *mcp;
 601 
 602         /* verify that 'name' refers to a registered crypto provider */
 603         if ((provider = kcf_prov_tab_lookup_by_name(name)) == NULL)
 604                 return (CRYPTO_UNKNOWN_PROVIDER);
 605 
 606         /*
 607          * We save the module id and release the reference. We need to
 608          * do this as modunload() calls unregister which waits for the
 609          * refcnt to drop to zero.
 610          */
 611         id = provider->pd_module_id;
 612         KCF_PROV_REFRELE(provider);
 613 
 614         if ((mcp = mod_hold_by_name(name)) != NULL) {
 615                 mcp->mod_loadflags &= ~(MOD_NOAUTOUNLOAD);
 616                 mod_release_mod(mcp);
 617         }
 618 
 619         if ((error = modunload(id)) != 0) {
 620                 return (error == EBUSY ? CRYPTO_BUSY : CRYPTO_FAILED);
 621         }
 622 
 623         return (CRYPTO_SUCCESS);
 624 }
 625 
 626 /* called from CRYPTO_GET_DEV_LIST ioctl */



 627 void
 628 crypto_free_dev_list(crypto_dev_list_entry_t *array, uint_t count)
 629 {
 630         if (count ==  0 || array == NULL)
 631                 return;
 632 
 633         kmem_free(array, count * sizeof (crypto_dev_list_entry_t));
 634 }
 635 
 636 /*
 637  * Returns duplicate array of mechanisms.  The array is allocated and
 638  * must be freed by the caller.
 639  */
 640 static int
 641 dup_mech_names(kcf_provider_desc_t *provider, crypto_mech_name_t **array,
 642     uint_t *count, int kmflag)
 643 {
 644         crypto_mech_name_t *mech_names;
 645         uint_t n;
 646         uint_t i;


 796 
 797         mech_names = kmem_alloc((scnt - dcnt) * sizeof (crypto_mech_name_t),
 798             kmflag);
 799         if (mech_names == NULL)
 800                 return (CRYPTO_HOST_MEMORY);
 801 
 802         /* build array of permitted mechanisms */
 803         for (i = 0, p = mech_names; i < scnt; i++) {
 804                 if (!is_mech_disabled(provider,
 805                     &provider->pd_mechanisms[i].cm_mech_name[0])) {
 806                         bcopy(&provider->pd_mechanisms[i].cm_mech_name[0],
 807                             p++, sizeof (crypto_mech_name_t));
 808                 }
 809         }
 810 
 811         *count = scnt - dcnt;
 812         *array = mech_names;
 813         return (CRYPTO_SUCCESS);
 814 }
 815 




 816 static void
 817 free_soft_config_entry(kcf_soft_conf_entry_t *p)
 818 {
 819         kmem_free(p->ce_name, strlen(p->ce_name) + 1);
 820         crypto_free_mech_list(p->ce_mechs, p->ce_count);
 821         kmem_free(p, sizeof (kcf_soft_conf_entry_t));
 822 }
 823 
 824 /*
 825  * Called from the CRYPTO_LOAD_SOFT_CONFIG ioctl, this routine stores
 826  * configuration information for software providers in a linked list.
 827  * If the list already contains an entry for the specified provider
 828  * and the specified mechanism list has at least one mechanism, then
 829  * the mechanism list for the provider is updated. If the mechanism list
 830  * is empty, the entry for the provider is removed.
 831  *
 832  * Important note: the array argument is consumed.





 833  */
 834 static int
 835 add_soft_config(char *name, uint_t count, crypto_mech_name_t *array)
 836 {
 837         static uint_t soft_config_count = 0;
 838         kcf_soft_conf_entry_t *prev = NULL, *entry = NULL, *new_entry, *p;
 839         size_t name_len;
 840 
 841         /*
 842          * Allocate storage for a new entry.
 843          * Free later if an entry already exists.
 844          */
 845         name_len = strlen(name) + 1;
 846         new_entry = kmem_zalloc(sizeof (kcf_soft_conf_entry_t), KM_SLEEP);
 847         new_entry->ce_name = kmem_alloc(name_len, KM_SLEEP);
 848         (void) strcpy(new_entry->ce_name, name);
 849 
 850         mutex_enter(&soft_config_mutex);
 851         p = soft_config_list;
 852         if (p != NULL) {


 864                 if (count == 0) {
 865                         mutex_exit(&soft_config_mutex);
 866                         kmem_free(new_entry->ce_name, name_len);
 867                         kmem_free(new_entry, sizeof (kcf_soft_conf_entry_t));
 868                         return (CRYPTO_SUCCESS);
 869                 }
 870 
 871                 if (soft_config_count > KCF_MAX_CONFIG_ENTRIES) {
 872                         mutex_exit(&soft_config_mutex);
 873                         kmem_free(new_entry->ce_name, name_len);
 874                         kmem_free(new_entry, sizeof (kcf_soft_conf_entry_t));
 875                         cmn_err(CE_WARN, "out of soft_config_list entries");
 876                         return (CRYPTO_FAILED);
 877                 }
 878 
 879                 /* add to head of list */
 880                 new_entry->ce_next = soft_config_list;
 881                 soft_config_list = new_entry;
 882                 soft_config_count++;
 883                 entry = new_entry;
 884         } else {
 885                 kmem_free(new_entry->ce_name, name_len);
 886                 kmem_free(new_entry, sizeof (kcf_soft_conf_entry_t));
 887         }
 888 
 889         /* mechanism count == 0 means remove entry from list */
 890         if (count == 0) {
 891                 if (prev == NULL) {
 892                         /* remove first in list */
 893                         soft_config_list = entry->ce_next;
 894                 } else {
 895                         prev->ce_next = entry->ce_next;
 896                 }
 897                 soft_config_count--;
 898                 mutex_exit(&soft_config_mutex);
 899 
 900                 /* free entry */
 901                 free_soft_config_entry(entry);
 902 
 903                 return (CRYPTO_SUCCESS);
 904         }


 933         p = soft_config_list;
 934         while (p != NULL) {
 935                 next = p->ce_next;
 936                 for (i = 0; i < p->ce_count; i++) {
 937                         if (strcmp(mech, &p->ce_mechs[i][0]) == 0) {
 938                                 name_len = strlen(p->ce_name) + 1;
 939                                 bcopy(p->ce_name, tmp_name, name_len);
 940                                 break;
 941                         }
 942                 }
 943                 p = next;
 944         }
 945         mutex_exit(&soft_config_mutex);
 946 
 947         if (name_len == 0)
 948                 return (CRYPTO_FAILED);
 949 
 950         *name = kmem_alloc(name_len, KM_SLEEP);
 951         bcopy(tmp_name, *name, name_len);
 952         return (CRYPTO_SUCCESS);
 953 }
 954 
 955 /*
 956  * This routine searches the soft_config_list for the specified
 957  * software provider, returning B_TRUE if it is in the list.
 958  */
 959 boolean_t
 960 in_soft_config_list(char *provider_name)
 961 {
 962         kcf_soft_conf_entry_t *p;
 963         boolean_t rv = B_FALSE;
 964 
 965         mutex_enter(&soft_config_mutex);
 966         for (p = soft_config_list; p != NULL; p = p->ce_next) {
 967                 if (strcmp(provider_name, p->ce_name) == 0) {
 968                         rv = B_TRUE;
 969                         break;
 970                 }
 971         }
 972         mutex_exit(&soft_config_mutex);
 973         return (rv);
 974 }


   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 


 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 


 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)


 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         }


 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;


 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) {


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         }


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 }