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

Split Close
Expand all
Collapse all
          --- old/usr/src/uts/common/crypto/core/kcf_cryptoadm.c
          +++ new/usr/src/uts/common/crypto/core/kcf_cryptoadm.c
↓ open down ↓ 15 lines elided ↑ open up ↑
  16   16   * fields enclosed by brackets "[]" replaced with your own identifying
  17   17   * information: Portions Copyright [yyyy] [name of copyright owner]
  18   18   *
  19   19   * CDDL HEADER END
  20   20   */
  21   21  /*
  22   22   * Copyright 2008 Sun Microsystems, Inc.  All rights reserved.
  23   23   * Use is subject to license terms.
  24   24   */
  25   25  
  26      -#pragma ident   "%Z%%M% %I%     %E% SMI"
  27      -
  28   26  /*
  29   27   * Core KCF (Kernel Cryptographic Framework). This file implements
  30   28   * the cryptoadm entry points.
  31   29   */
  32   30  
  33   31  #include <sys/systm.h>
  34   32  #include <sys/errno.h>
  35   33  #include <sys/cmn_err.h>
  36   34  #include <sys/rwlock.h>
  37   35  #include <sys/kmem.h>
↓ open down ↓ 3 lines elided ↑ open up ↑
  41   39  #include <sys/crypto/common.h>
  42   40  #include <sys/crypto/api.h>
  43   41  #include <sys/crypto/spi.h>
  44   42  #include <sys/crypto/impl.h>
  45   43  #include <sys/crypto/sched_impl.h>
  46   44  
  47   45  /* protects the the soft_config_list. */
  48   46  kmutex_t soft_config_mutex;
  49   47  
  50   48  /*
  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.
       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.
  54   56   */
  55   57  kcf_soft_conf_entry_t *soft_config_list;
  56   58  
  57   59  static int add_soft_config(char *, uint_t, crypto_mech_name_t *);
  58   60  static int dup_mech_names(kcf_provider_desc_t *, crypto_mech_name_t **,
  59   61      uint_t *, int);
  60   62  static void free_soft_config_entry(kcf_soft_conf_entry_t *);
  61   63  
  62   64  #define KCF_MAX_CONFIG_ENTRIES 512 /* maximum entries in soft_config_list */
  63   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 + */
  64   87  void
  65   88  kcf_soft_config_init(void)
  66   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 +
  67  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 */
  68  208  }
  69  209  
  70  210  
      211 +#if DEBUG
  71  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 +/*
  72  245   * Utility routine to identify the providers to filter out and
  73  246   * present only one provider. This happens when a hardware provider
  74  247   * registers multiple units of the same device instance.
      248 + *
      249 + * Called from crypto_get_dev_list().
  75  250   */
  76  251  static void
  77  252  filter_providers(uint_t count, kcf_provider_desc_t **provider_array,
  78  253          char *skip_providers, int *mech_counts, int *new_count)
  79  254  {
  80  255          int i, j;
  81  256          kcf_provider_desc_t *prov1, *prov2;
  82  257          int n = 0;
  83  258  
  84  259          for (i = 0; i < count; i++) {
↓ open down ↓ 11 lines elided ↑ open up ↑
  96  271                                  mech_counts[i] += prov2->pd_mech_list_count;
  97  272                          }
  98  273                  }
  99  274                  n++;
 100  275          }
 101  276  
 102  277          *new_count = n;
 103  278  }
 104  279  
 105  280  
 106      -/* called from the CRYPTO_GET_DEV_LIST ioctl */
      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 + */
 107  286  int
 108  287  crypto_get_dev_list(uint_t *count, crypto_dev_list_entry_t **array)
 109  288  {
 110  289          kcf_provider_desc_t **provider_array;
 111  290          kcf_provider_desc_t *pd;
 112  291          crypto_dev_list_entry_t *p;
 113  292          size_t skip_providers_size, mech_counts_size;
 114  293          char *skip_providers;
 115  294          uint_t provider_count;
 116  295          int rval, i, j, new_count, *mech_counts;
 117  296  
 118  297          /*
 119  298           * Take snapshot of provider table returning only hardware providers
 120  299           * that are in a usable state. Logical providers not included.
 121  300           */
 122      -        rval =  kcf_get_hw_prov_tab(&provider_count, &provider_array, KM_SLEEP,
      301 +        rval = kcf_get_hw_prov_tab(&provider_count, &provider_array, KM_SLEEP,
 123  302              NULL, 0, B_FALSE);
 124  303          if (rval != CRYPTO_SUCCESS)
 125  304                  return (rval);
 126  305  
 127  306          if (provider_count == 0) {
 128  307                  *array = NULL;
 129  308                  *count = 0;
 130  309                  return (CRYPTO_SUCCESS);
 131  310          }
 132  311  
↓ open down ↓ 21 lines elided ↑ open up ↑
 154  333          kcf_free_provider_tab(provider_count, provider_array);
 155  334          kmem_free(skip_providers, skip_providers_size);
 156  335          kmem_free(mech_counts, mech_counts_size);
 157  336  
 158  337          *array = p;
 159  338          *count = new_count;
 160  339          return (CRYPTO_SUCCESS);
 161  340  }
 162  341  
 163  342  /*
 164      - * Called from the CRYPTO_GET_SOFT_LIST ioctl, this routine returns
 165      - * a buffer containing the null terminated names of software providers
      343 + * Return a buffer containing the null terminated names of software providers
 166  344   * loaded by CRYPTO_LOAD_SOFT_CONFIG.
      345 + * Called from the CRYPTO_GET_SOFT_LIST ioctl.
 167  346   */
 168  347  int
 169  348  crypto_get_soft_list(uint_t *count, char **array, size_t *len)
 170  349  {
 171  350          char *names = NULL, *namep, *end;
 172  351          kcf_soft_conf_entry_t *p;
 173  352          uint_t n = 0, cnt = 0, final_count = 0;
 174  353          size_t name_len, final_size = 0;
 175  354  
 176  355          /* first estimate */
↓ open down ↓ 41 lines elided ↑ open up ↑
 218  397                  kmem_free(names, n);
 219  398                  names = final_buffer;
 220  399          }
 221  400  out:
 222  401          *array = names;
 223  402          *count = final_count;
 224  403          *len = final_size;
 225  404          return (CRYPTO_SUCCESS);
 226  405  }
 227  406  
      407 +/*
      408 + * Check if a mechanism name is already in a mechanism name array
      409 + * Called by crypto_get_dev_info().
      410 + */
 228  411  static boolean_t
 229  412  duplicate(char *name, crypto_mech_name_t *array, int count)
 230  413  {
 231  414          int i;
 232  415  
 233  416          for (i = 0; i < count; i++) {
 234  417                  if (strncmp(name, &array[i][0],
 235  418                      sizeof (crypto_mech_name_t)) == 0)
 236  419                          return (B_TRUE);
 237  420          }
 238  421          return (B_FALSE);
 239  422  }
 240  423  
 241      -/* called from the CRYPTO_GET_DEV_INFO ioctl */
      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 + */
 242  429  int
 243  430  crypto_get_dev_info(char *name, uint_t instance, uint_t *count,
 244  431      crypto_mech_name_t **array)
 245  432  {
 246  433          int rv;
 247  434          crypto_mech_name_t *mech_names, *resized_array;
 248  435          int i, j, k = 0, max_count;
 249  436          uint_t provider_count;
 250  437          kcf_provider_desc_t **provider_array;
 251  438          kcf_provider_desc_t *pd;
 252  439  
 253  440          /*
 254  441           * Get provider table entries matching name and instance
 255  442           * for hardware providers that are in a usable state.
 256  443           * Logical providers not included. NULL name matches
 257  444           * all hardware providers.
 258  445           */
 259      -        rv =  kcf_get_hw_prov_tab(&provider_count, &provider_array, KM_SLEEP,
      446 +        rv = kcf_get_hw_prov_tab(&provider_count, &provider_array, KM_SLEEP,
 260  447              name, instance, B_FALSE);
 261  448          if (rv != CRYPTO_SUCCESS)
 262  449                  return (rv);
 263  450  
 264  451          if (provider_count == 0)
 265  452                  return (CRYPTO_ARGUMENTS_BAD);
 266  453  
 267  454          /* Count all mechanisms supported by all providers */
 268  455          max_count = 0;
 269  456          for (i = 0; i < provider_count; i++)
↓ open down ↓ 34 lines elided ↑ open up ↑
 304  491          }
 305  492  
 306  493  out:
 307  494          kcf_free_provider_tab(provider_count, provider_array);
 308  495          *count = k;
 309  496          *array = mech_names;
 310  497  
 311  498          return (CRYPTO_SUCCESS);
 312  499  }
 313  500  
 314      -/* called from the CRYPTO_GET_SOFT_INFO ioctl */
      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 + */
 315  506  int
 316  507  crypto_get_soft_info(caddr_t name, uint_t *count, crypto_mech_name_t **array)
 317  508  {
 318  509          ddi_modhandle_t modh = NULL;
 319  510          kcf_provider_desc_t *provider;
 320  511          int rv;
 321  512  
 322  513          provider = kcf_prov_tab_lookup_by_name(name);
 323  514          if (provider == NULL) {
 324      -                if (in_soft_config_list(name)) {
 325      -                        char *tmp;
 326      -                        int name_len;
      515 +                char *tmp;
      516 +                int name_len;
 327  517  
 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';
      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';
 334  524  
 335      -                        modh = ddi_modopen(tmp, KRTLD_MODE_FIRST, NULL);
 336      -                        kmem_free(tmp, name_len + 8);
      525 +                modh = ddi_modopen(tmp, KRTLD_MODE_FIRST, NULL);
      526 +                kmem_free(tmp, name_len + 8);
 337  527  
 338      -                        if (modh == NULL) {
 339      -                                return (CRYPTO_ARGUMENTS_BAD);
 340      -                        }
      528 +                if (modh == NULL) {
      529 +                        return (CRYPTO_ARGUMENTS_BAD);
      530 +                }
 341  531  
 342      -                        provider = kcf_prov_tab_lookup_by_name(name);
 343      -                        if (provider == NULL) {
 344      -                                return (CRYPTO_ARGUMENTS_BAD);
 345      -                        }
 346      -                } else {
      532 +                provider = kcf_prov_tab_lookup_by_name(name);
      533 +                if (provider == NULL) {
 347  534                          return (CRYPTO_ARGUMENTS_BAD);
 348  535                  }
 349  536          }
 350  537  
 351  538          rv = dup_mech_names(provider, array, count, KM_SLEEP);
 352  539          KCF_PROV_REFRELE(provider);
 353  540          if (modh != NULL)
 354  541                  (void) ddi_modclose(modh);
 355  542          return (rv);
 356  543  }
 357  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 + */
 358  552  static void
 359  553  kcf_change_mechs(kcf_provider_desc_t *provider, uint_t count,
 360  554      crypto_mech_name_t *array, crypto_event_change_t direction)
 361  555  {
 362  556          crypto_notify_event_change_t ec;
 363  557          crypto_mech_info_t *mi;
 364  558          kcf_prov_mech_desc_t *pmd;
 365  559          char *mech;
 366  560          int i, j, n;
 367  561  
↓ open down ↓ 88 lines elided ↑ open up ↑
 456  650                      &prev_array);
 457  651          } else if ((rv = kcf_policy_load_dev_disabled(name, instance, new_count,
 458  652              new_array, &prev_count, &prev_array)) != CRYPTO_SUCCESS) {
 459  653                  return (rv);
 460  654          }
 461  655  
 462  656          /*
 463  657           * Get provider table entries matching name and instance
 464  658           * for providers that are are in a usable or unverified state.
 465  659           */
 466      -        rv =  kcf_get_hw_prov_tab(&provider_count, &provider_array, KM_SLEEP,
      660 +        rv = kcf_get_hw_prov_tab(&provider_count, &provider_array, KM_SLEEP,
 467  661              name, instance, B_TRUE);
 468  662          if (rv != CRYPTO_SUCCESS)
 469  663                  return (rv);
 470  664  
 471  665          for (i = 0; i < provider_count; i++) {
 472  666                  provider = provider_array[i];
 473  667  
 474  668                  /* previously disabled mechanisms may become enabled */
 475  669                  if (prev_array != NULL) {
 476  670                          kcf_compare_mechs(new_count, new_array,
↓ open down ↓ 77 lines elided ↑ open up ↑
 554  748                  /*
 555  749                   * There are some cases where it is useful to kCF clients
 556  750                   * to have a provider whose mechanism is enabled now to be
 557  751                   * available. So, we attempt to load it here.
 558  752                   *
 559  753                   * The check, new_count < prev_count, ensures that we do this
 560  754                   * only in the case where a mechanism(s) is now enabled.
 561  755                   * This check assumes that enable and disable are separate
 562  756                   * administrative actions and are not done in a single action.
 563  757                   */
 564      -                if (new_count < prev_count && (in_soft_config_list(name)) &&
      758 +                if ((new_count < prev_count) &&
 565  759                      (modload("crypto", name) != -1)) {
 566  760                          struct modctl *mcp;
 567  761                          boolean_t load_again = B_FALSE;
 568  762  
 569  763                          if ((mcp = mod_hold_by_name(name)) != NULL) {
 570  764                                  mcp->mod_loadflags |= MOD_NOAUTOUNLOAD;
 571  765  
 572  766                                  /* memory pressure may have unloaded module */
 573  767                                  if (!mcp->mod_installed)
 574  768                                          load_again = B_TRUE;
↓ open down ↓ 8 lines elided ↑ open up ↑
 583  777          return (rv);
 584  778  }
 585  779  
 586  780  /* called from the CRYPTO_LOAD_SOFT_CONFIG ioctl */
 587  781  int
 588  782  crypto_load_soft_config(caddr_t name, uint_t count, crypto_mech_name_t *array)
 589  783  {
 590  784          return (add_soft_config(name, count, array));
 591  785  }
 592  786  
 593      -/* called from the CRYPTO_UNLOAD_SOFT_MODULE ioctl */
      787 +/*
      788 + * Unload a kernel software crypto module.
      789 + * Called from the CRYPTO_UNLOAD_SOFT_MODULE ioctl.
      790 + */
 594  791  int
 595  792  crypto_unload_soft_module(caddr_t name)
 596  793  {
 597  794          int error;
 598  795          modid_t id;
 599  796          kcf_provider_desc_t *provider;
 600  797          struct modctl *mcp;
 601  798  
 602  799          /* verify that 'name' refers to a registered crypto provider */
 603  800          if ((provider = kcf_prov_tab_lookup_by_name(name)) == NULL)
↓ open down ↓ 12 lines elided ↑ open up ↑
 616  813                  mod_release_mod(mcp);
 617  814          }
 618  815  
 619  816          if ((error = modunload(id)) != 0) {
 620  817                  return (error == EBUSY ? CRYPTO_BUSY : CRYPTO_FAILED);
 621  818          }
 622  819  
 623  820          return (CRYPTO_SUCCESS);
 624  821  }
 625  822  
 626      -/* called from CRYPTO_GET_DEV_LIST ioctl */
      823 +/*
      824 + * Free the list of kernel hardware crypto providers.
      825 + * Called by get_dev_list() for the CRYPTO_GET_DEV_LIST ioctl.
      826 + */
 627  827  void
 628  828  crypto_free_dev_list(crypto_dev_list_entry_t *array, uint_t count)
 629  829  {
 630      -        if (count ==  0 || array == NULL)
      830 +        if (count == 0 || array == NULL)
 631  831                  return;
 632  832  
 633  833          kmem_free(array, count * sizeof (crypto_dev_list_entry_t));
 634  834  }
 635  835  
 636  836  /*
 637  837   * Returns duplicate array of mechanisms.  The array is allocated and
 638  838   * must be freed by the caller.
 639  839   */
 640  840  static int
↓ open down ↓ 165 lines elided ↑ open up ↑
 806 1006                          bcopy(&provider->pd_mechanisms[i].cm_mech_name[0],
 807 1007                              p++, sizeof (crypto_mech_name_t));
 808 1008                  }
 809 1009          }
 810 1010  
 811 1011          *count = scnt - dcnt;
 812 1012          *array = mech_names;
 813 1013          return (CRYPTO_SUCCESS);
 814 1014  }
 815 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 + */
 816 1020  static void
 817 1021  free_soft_config_entry(kcf_soft_conf_entry_t *p)
 818 1022  {
 819 1023          kmem_free(p->ce_name, strlen(p->ce_name) + 1);
 820 1024          crypto_free_mech_list(p->ce_mechs, p->ce_count);
 821 1025          kmem_free(p, sizeof (kcf_soft_conf_entry_t));
 822 1026  }
 823 1027  
 824 1028  /*
 825      - * Called from the CRYPTO_LOAD_SOFT_CONFIG ioctl, this routine stores
 826      - * configuration information for software providers in a linked list.
     1029 + * Store configuration information for software providers in a linked list.
 827 1030   * If the list already contains an entry for the specified provider
 828 1031   * and the specified mechanism list has at least one mechanism, then
 829 1032   * the mechanism list for the provider is updated. If the mechanism list
 830 1033   * is empty, the entry for the provider is removed.
 831 1034   *
 832      - * Important note: the array argument is consumed.
     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.
 833 1041   */
 834 1042  static int
 835 1043  add_soft_config(char *name, uint_t count, crypto_mech_name_t *array)
 836 1044  {
 837 1045          static uint_t soft_config_count = 0;
 838 1046          kcf_soft_conf_entry_t *prev = NULL, *entry = NULL, *new_entry, *p;
 839 1047          size_t name_len;
 840 1048  
 841 1049          /*
 842 1050           * Allocate storage for a new entry.
↓ open down ↓ 31 lines elided ↑ open up ↑
 874 1082                          kmem_free(new_entry, sizeof (kcf_soft_conf_entry_t));
 875 1083                          cmn_err(CE_WARN, "out of soft_config_list entries");
 876 1084                          return (CRYPTO_FAILED);
 877 1085                  }
 878 1086  
 879 1087                  /* add to head of list */
 880 1088                  new_entry->ce_next = soft_config_list;
 881 1089                  soft_config_list = new_entry;
 882 1090                  soft_config_count++;
 883 1091                  entry = new_entry;
 884      -        } else {
     1092 +        } else { /* mechanism already in list */
 885 1093                  kmem_free(new_entry->ce_name, name_len);
 886 1094                  kmem_free(new_entry, sizeof (kcf_soft_conf_entry_t));
 887 1095          }
 888 1096  
 889 1097          /* mechanism count == 0 means remove entry from list */
 890 1098          if (count == 0) {
 891 1099                  if (prev == NULL) {
 892 1100                          /* remove first in list */
 893 1101                          soft_config_list = entry->ce_next;
 894 1102                  } else {
↓ open down ↓ 48 lines elided ↑ open up ↑
 943 1151                  p = next;
 944 1152          }
 945 1153          mutex_exit(&soft_config_mutex);
 946 1154  
 947 1155          if (name_len == 0)
 948 1156                  return (CRYPTO_FAILED);
 949 1157  
 950 1158          *name = kmem_alloc(name_len, KM_SLEEP);
 951 1159          bcopy(tmp_name, *name, name_len);
 952 1160          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 1161  }
    
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX