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