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


   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 2007 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  * This file is part of the core Kernel Cryptographic Framework.
  30  * It implements the management of tables of Providers. Entries to
  31  * added and removed when cryptographic providers register with
  32  * and unregister from the framework, respectively. The KCF scheduler
  33  * and ioctl pseudo driver call this function to obtain the list
  34  * of available providers.
  35  *
  36  * The provider table is indexed by crypto_provider_id_t. Each
  37  * element of the table contains a pointer to a provider descriptor,
  38  * or NULL if the entry is free.
  39  *
  40  * This file also implements helper functions to allocate and free
  41  * provider descriptors.
  42  */
  43 
  44 #include <sys/types.h>
  45 #include <sys/kmem.h>
  46 #include <sys/cmn_err.h>
  47 #include <sys/ddi.h>
  48 #include <sys/sunddi.h>
  49 #include <sys/ksynch.h>
  50 #include <sys/crypto/common.h>
  51 #include <sys/crypto/impl.h>
  52 #include <sys/crypto/sched_impl.h>
  53 #include <sys/crypto/spi.h>
  54 
  55 #define KCF_MAX_PROVIDERS       512     /* max number of providers */
  56 
  57 static kmutex_t prov_tab_mutex; /* ensure exclusive access to the table */











  58 static kcf_provider_desc_t **prov_tab = NULL;

  59 static uint_t prov_tab_num = 0; /* number of providers in table */
  60 static uint_t prov_tab_max = KCF_MAX_PROVIDERS;
  61 
  62 #if DEBUG
  63 extern int kcf_frmwrk_debug;
  64 static void kcf_prov_tab_dump(void);
  65 #endif /* DEBUG */
  66 

  67 /*
  68  * Initialize the providers table. The providers table is dynamically
  69  * allocated with prov_tab_max entries.

  70  */
  71 void
  72 kcf_prov_tab_init(void)
  73 {
  74         mutex_init(&prov_tab_mutex, NULL, MUTEX_DRIVER, NULL);
  75 
  76         prov_tab = kmem_zalloc(prov_tab_max * sizeof (kcf_provider_desc_t *),
  77             KM_SLEEP);
  78 }
  79 
  80 /*
  81  * Add a provider to the provider table. If no free entry can be found
  82  * for the new provider, returns CRYPTO_HOST_MEMORY. Otherwise, add
  83  * the provider to the table, initialize the pd_prov_id field
  84  * of the specified provider descriptor to the index in that table,
  85  * and return CRYPTO_SUCCESS. Note that a REFHOLD is done on the
  86  * provider when pointed to by a table entry.
  87  */
  88 int
  89 kcf_prov_tab_add_provider(kcf_provider_desc_t *prov_desc)


 107         /* initialize entry */
 108         prov_tab[i] = prov_desc;
 109         KCF_PROV_REFHOLD(prov_desc);
 110         KCF_PROV_IREFHOLD(prov_desc);
 111         prov_tab_num++;
 112 
 113         mutex_exit(&prov_tab_mutex);
 114 
 115         /* update provider descriptor */
 116         prov_desc->pd_prov_id = i;
 117 
 118         /*
 119          * The KCF-private provider handle is defined as the internal
 120          * provider id.
 121          */
 122         prov_desc->pd_kcf_prov_handle =
 123             (crypto_kcf_provider_handle_t)prov_desc->pd_prov_id;
 124 
 125 #if DEBUG
 126         if (kcf_frmwrk_debug >= 1)
 127                 kcf_prov_tab_dump();
 128 #endif /* DEBUG */
 129 
 130         return (CRYPTO_SUCCESS);
 131 }
 132 
 133 /*
 134  * Remove the provider specified by its id. A REFRELE is done on the
 135  * corresponding provider descriptor before this function returns.
 136  * Returns CRYPTO_UNKNOWN_PROVIDER if the provider id is not valid.
 137  */
 138 int
 139 kcf_prov_tab_rem_provider(crypto_provider_id_t prov_id)
 140 {
 141         kcf_provider_desc_t *prov_desc;
 142 
 143         ASSERT(prov_tab != NULL);
 144         ASSERT(prov_tab_num >= 0);
 145 
 146         /*
 147          * Validate provider id, since it can be specified by a 3rd-party


 153             ((prov_desc = prov_tab[prov_id]) == NULL)) {
 154                 mutex_exit(&prov_tab_mutex);
 155                 return (CRYPTO_INVALID_PROVIDER_ID);
 156         }
 157         mutex_exit(&prov_tab_mutex);
 158 
 159         /*
 160          * The provider id must remain valid until the associated provider
 161          * descriptor is freed. For this reason, we simply release our
 162          * reference to the descriptor here. When the reference count
 163          * reaches zero, kcf_free_provider_desc() will be invoked and
 164          * the associated entry in the providers table will be released
 165          * at that time.
 166          */
 167 
 168         KCF_PROV_REFRELE(prov_desc);
 169         KCF_PROV_IREFRELE(prov_desc);
 170 
 171 #if DEBUG
 172         if (kcf_frmwrk_debug >= 1)
 173                 kcf_prov_tab_dump();
 174 #endif /* DEBUG */
 175 
 176         return (CRYPTO_SUCCESS);
 177 }
 178 
 179 /*
 180  * Returns the provider descriptor corresponding to the specified
 181  * provider id. A REFHOLD is done on the descriptor before it is
 182  * returned to the caller. It is the responsibility of the caller
 183  * to do a REFRELE once it is done with the provider descriptor.
 184  */
 185 kcf_provider_desc_t *
 186 kcf_prov_tab_lookup(crypto_provider_id_t prov_id)
 187 {
 188         kcf_provider_desc_t *prov_desc;
 189 
 190         mutex_enter(&prov_tab_mutex);
 191 
 192         prov_desc = prov_tab[prov_id];
 193 


 800         if (me->me_sw_prov == NULL ||
 801             (*pd = me->me_sw_prov->pm_prov_desc) == NULL) {
 802                 /* no SW provider for this mechanism */
 803                 if (log_warn)
 804                         cmn_err(CE_WARN, "no SW provider for \"%s\"\n",
 805                             me->me_name);
 806                 mutex_exit(&me->me_mutex);
 807                 return (CRYPTO_MECH_NOT_SUPPORTED);
 808         }
 809 
 810         KCF_PROV_REFHOLD(*pd);
 811         mutex_exit(&me->me_mutex);
 812 
 813         if (mep != NULL)
 814                 *mep = me;
 815 
 816         return (CRYPTO_SUCCESS);
 817 }
 818 
 819 #if DEBUG
 820 



 821 static void
 822 kcf_prov_tab_dump(void)
 823 {
 824         uint_t i;
 825 
 826         mutex_enter(&prov_tab_mutex);


 827 
 828         printf("Providers table:\n");
 829         for (i = 0; i < KCF_MAX_PROVIDERS; i++) {
 830                 if (prov_tab[i] != NULL) {
 831                         printf("[%d]: (%s) %s\n",
 832                             i, (prov_tab[i]->pd_prov_type ==
 833                             CRYPTO_HW_PROVIDER) ? "HW" : "SW",
 834                             prov_tab[i]->pd_description);






 835                 }

 836         }


 837         printf("(end of providers table)\n");
 838 
 839         mutex_exit(&prov_tab_mutex);
 840 }
 841 
 842 #endif /* DEBUG */
 843 
 844 /*
 845  * This function goes through the provider table and verifies
 846  * any unverified providers.
 847  *
 848  * This is called when kcfd is up and the door handle is ready.
 849  */
 850 void
 851 verify_unverified_providers()
 852 {
 853         int i;
 854         kcf_provider_desc_t *pd;
 855         boolean_t need_verify;
 856 




   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  * This file is part of the core Kernel Cryptographic Framework.
  28  * It implements the management of tables of Providers. Entries to
  29  * added and removed when cryptographic providers register with
  30  * and unregister from the framework, respectively. The KCF scheduler
  31  * and ioctl pseudo driver call this function to obtain the list
  32  * of available providers.
  33  *
  34  * The provider table is indexed by crypto_provider_id_t. Each
  35  * element of the table contains a pointer to a provider descriptor,
  36  * or NULL if the entry is free.
  37  *
  38  * This file also implements helper functions to allocate and free
  39  * provider descriptors.
  40  */
  41 
  42 #include <sys/types.h>
  43 #include <sys/kmem.h>
  44 #include <sys/cmn_err.h>
  45 #include <sys/ddi.h>
  46 #include <sys/sunddi.h>
  47 #include <sys/ksynch.h>
  48 #include <sys/crypto/common.h>
  49 #include <sys/crypto/impl.h>
  50 #include <sys/crypto/sched_impl.h>
  51 #include <sys/crypto/spi.h>
  52 
  53 #define KCF_MAX_PROVIDERS       512     /* max number of providers */
  54 
  55 /*
  56  * Prov_tab is an array of providers which is updated when
  57  * a crypto provider registers with kcf. The provider calls the
  58  * SPI routine, crypto_register_provider(), which in turn calls
  59  * kcf_prov_tab_add_provider().
  60  *
  61  * A provider unregisters by calling crypto_unregister_provider()
  62  * which triggers the removal of the prov_tab entry.
  63  * It also calls kcf_remove_mech_provider().
  64  *
  65  * prov_tab entries are not updated from kcf.conf or by cryptoadm(1M).
  66  */
  67 static kcf_provider_desc_t **prov_tab = NULL;
  68 static kmutex_t prov_tab_mutex; /* ensure exclusive access to the table */
  69 static uint_t prov_tab_num = 0; /* number of providers in table */
  70 static uint_t prov_tab_max = KCF_MAX_PROVIDERS;
  71 
  72 #if DEBUG
  73 extern int kcf_frmwrk_debug;
  74 static void kcf_prov_tab_dump(char *message);
  75 #endif /* DEBUG */
  76 
  77 
  78 /*
  79  * Initialize a mutex and the KCF providers table, prov_tab.
  80  * The providers table is dynamically allocated with prov_tab_max entries.
  81  * Called from kcf module _init().
  82  */
  83 void
  84 kcf_prov_tab_init(void)
  85 {
  86         mutex_init(&prov_tab_mutex, NULL, MUTEX_DRIVER, NULL);
  87 
  88         prov_tab = kmem_zalloc(prov_tab_max * sizeof (kcf_provider_desc_t *),
  89             KM_SLEEP);
  90 }
  91 
  92 /*
  93  * Add a provider to the provider table. If no free entry can be found
  94  * for the new provider, returns CRYPTO_HOST_MEMORY. Otherwise, add
  95  * the provider to the table, initialize the pd_prov_id field
  96  * of the specified provider descriptor to the index in that table,
  97  * and return CRYPTO_SUCCESS. Note that a REFHOLD is done on the
  98  * provider when pointed to by a table entry.
  99  */
 100 int
 101 kcf_prov_tab_add_provider(kcf_provider_desc_t *prov_desc)


 119         /* initialize entry */
 120         prov_tab[i] = prov_desc;
 121         KCF_PROV_REFHOLD(prov_desc);
 122         KCF_PROV_IREFHOLD(prov_desc);
 123         prov_tab_num++;
 124 
 125         mutex_exit(&prov_tab_mutex);
 126 
 127         /* update provider descriptor */
 128         prov_desc->pd_prov_id = i;
 129 
 130         /*
 131          * The KCF-private provider handle is defined as the internal
 132          * provider id.
 133          */
 134         prov_desc->pd_kcf_prov_handle =
 135             (crypto_kcf_provider_handle_t)prov_desc->pd_prov_id;
 136 
 137 #if DEBUG
 138         if (kcf_frmwrk_debug >= 1)
 139                 kcf_prov_tab_dump("kcf_prov_tab_add_provider");
 140 #endif /* DEBUG */
 141 
 142         return (CRYPTO_SUCCESS);
 143 }
 144 
 145 /*
 146  * Remove the provider specified by its id. A REFRELE is done on the
 147  * corresponding provider descriptor before this function returns.
 148  * Returns CRYPTO_UNKNOWN_PROVIDER if the provider id is not valid.
 149  */
 150 int
 151 kcf_prov_tab_rem_provider(crypto_provider_id_t prov_id)
 152 {
 153         kcf_provider_desc_t *prov_desc;
 154 
 155         ASSERT(prov_tab != NULL);
 156         ASSERT(prov_tab_num >= 0);
 157 
 158         /*
 159          * Validate provider id, since it can be specified by a 3rd-party


 165             ((prov_desc = prov_tab[prov_id]) == NULL)) {
 166                 mutex_exit(&prov_tab_mutex);
 167                 return (CRYPTO_INVALID_PROVIDER_ID);
 168         }
 169         mutex_exit(&prov_tab_mutex);
 170 
 171         /*
 172          * The provider id must remain valid until the associated provider
 173          * descriptor is freed. For this reason, we simply release our
 174          * reference to the descriptor here. When the reference count
 175          * reaches zero, kcf_free_provider_desc() will be invoked and
 176          * the associated entry in the providers table will be released
 177          * at that time.
 178          */
 179 
 180         KCF_PROV_REFRELE(prov_desc);
 181         KCF_PROV_IREFRELE(prov_desc);
 182 
 183 #if DEBUG
 184         if (kcf_frmwrk_debug >= 1)
 185                 kcf_prov_tab_dump("kcf_prov_tab_rem_provider");
 186 #endif /* DEBUG */
 187 
 188         return (CRYPTO_SUCCESS);
 189 }
 190 
 191 /*
 192  * Returns the provider descriptor corresponding to the specified
 193  * provider id. A REFHOLD is done on the descriptor before it is
 194  * returned to the caller. It is the responsibility of the caller
 195  * to do a REFRELE once it is done with the provider descriptor.
 196  */
 197 kcf_provider_desc_t *
 198 kcf_prov_tab_lookup(crypto_provider_id_t prov_id)
 199 {
 200         kcf_provider_desc_t *prov_desc;
 201 
 202         mutex_enter(&prov_tab_mutex);
 203 
 204         prov_desc = prov_tab[prov_id];
 205 


 812         if (me->me_sw_prov == NULL ||
 813             (*pd = me->me_sw_prov->pm_prov_desc) == NULL) {
 814                 /* no SW provider for this mechanism */
 815                 if (log_warn)
 816                         cmn_err(CE_WARN, "no SW provider for \"%s\"\n",
 817                             me->me_name);
 818                 mutex_exit(&me->me_mutex);
 819                 return (CRYPTO_MECH_NOT_SUPPORTED);
 820         }
 821 
 822         KCF_PROV_REFHOLD(*pd);
 823         mutex_exit(&me->me_mutex);
 824 
 825         if (mep != NULL)
 826                 *mep = me;
 827 
 828         return (CRYPTO_SUCCESS);
 829 }
 830 
 831 #if DEBUG
 832 /*
 833  * Dump the Kernel crypto providers table, prov_tab.
 834  * If kcf_frmwrk_debug is >=2, also dump the mechanism lists.
 835  */
 836 static void
 837 kcf_prov_tab_dump(char *message)
 838 {
 839         uint_t i, j;
 840 
 841         mutex_enter(&prov_tab_mutex);
 842         printf("Providers table prov_tab at %s:\n",
 843             message != NULL ? message : "");
 844 

 845         for (i = 0; i < KCF_MAX_PROVIDERS; i++) {
 846                 kcf_provider_desc_t *p = prov_tab[i];
 847                 if (p != NULL) {
 848                         printf("[%d]: (%s) %d mechanisms, %s\n", i,
 849                             (p->pd_prov_type == CRYPTO_HW_PROVIDER) ?
 850                             "HW" : "SW",
 851                             p->pd_mech_list_count, p->pd_description);
 852                         if (kcf_frmwrk_debug >= 2) {
 853                                 printf("\tpd_mechanisms: ");
 854                                 for (j = 0; j < p->pd_mech_list_count; ++j) {
 855                                         printf("%s \n",
 856                                             p->pd_mechanisms[j].cm_mech_name);
 857                                 }
 858                                 printf("\n");
 859                         }
 860                 }
 861         }
 862         printf("(end of providers table)\n");
 863 
 864         mutex_exit(&prov_tab_mutex);
 865 }
 866 
 867 #endif /* DEBUG */
 868 
 869 /*
 870  * This function goes through the provider table and verifies
 871  * any unverified providers.
 872  *
 873  * This is called when kcfd is up and the door handle is ready.
 874  */
 875 void
 876 verify_unverified_providers()
 877 {
 878         int i;
 879         kcf_provider_desc_t *pd;
 880         boolean_t need_verify;
 881